From patchwork Fri Jul 19 15:10:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 807 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-pf1-f200.google.com (mail-pf1-f200.google.com [209.85.210.200]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id C75B63F053 for ; Fri, 19 Jul 2019 17:10:46 +0200 (CEST) Received: by mail-pf1-f200.google.com with SMTP id i27sf18890448pfk.12 for ; Fri, 19 Jul 2019 08:10:46 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1563549045; cv=pass; d=google.com; s=arc-20160816; b=towxwVF3JgDtEIJEnUXo6W9xCSn1y0SB+CPnaXzjVgKlM4vpLApcR5x9eAKyTREMj/ 6852u6sZUbKlR7HsZm8q00PaLMms7O7EiA7Pe35FQPIxvx3Nq3/1e0eX30KIuSDt1G2d BL4sd/YWb6qbnvFkRZElL3ftOW1hPsaiQ9eQ62NcrBF6nF9QAwrB0wKGHrehrCfG7ZUa uUZf6J54tPD4MuJRgVXM9/VrtdPNvvk4DT+CNS1PkOtZzQXFv3b2b7LCq+ac3AXV4Cfr WnkF3mjQuDCShStvQQLs2F17M2TkY9I/nOpOpu0BNCkUvECrL2TMTIUsHkWuBSrVJqC4 Tz9w== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:mime-version:message-id:date:subject:cc:to :from:dkim-signature; bh=1ZP6b4B9O5b5wkPP8kvkaR6ZzI01iw2+sm3ej04SxPg=; b=ubnFHEbxFPqky9MaLRB29nzxO4lltXt+le80HgC9+I32kh5wi3DZtumWHMfDJx3pfD l1i/+T6EjA+BLXlZAK9B3J3LAmB8K8b0OjNTYpn2CZFNfZPsipXzEMizidQx0XUN5bCE s/Ur1D+d5aA2pNy+z5nN4C0jhFCBxVSUy/BVEYI5Zwspu190RO/blr83oRZRdblkRNrY ql1J0DIba8n2zzKDP4mBVJmIhK5aGJrpDNwB1TkRH82t5kcldYZeKvushAla7WKV4M1M bTM3+OtZmCTOtlL+XuBFHDwRzmzMo1c7G9Nk6PmxQDFtfDUXKY33vwMFOWUAEPfei5OO 7YAQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=YHoqQF7N; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=from:to:cc:subject:date:message-id:mime-version:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=1ZP6b4B9O5b5wkPP8kvkaR6ZzI01iw2+sm3ej04SxPg=; b=VK+7rtnstmITawNGTyBENr8Zt4K8K6TMbBn5S+xluHvcy7kv8pVKKnZlwE8XD4Gu9r klvzoVRFeumM2Xho+GA9b5lPXE++err62oSVvpwsY4Z2OLn5qi/jxzaqjmFelfAGgmw0 sRVD589JP+8lALvHE88bIbebzPCHedTjXmUYs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :x-original-sender:x-original-authentication-results:precedence :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help :list-archive:list-unsubscribe; bh=1ZP6b4B9O5b5wkPP8kvkaR6ZzI01iw2+sm3ej04SxPg=; b=LHLs9WCrBDa/9SEX10xF1X8ESQP+TiqbM8Z+M6K7ZqCHzjbFAA8E6p3XnRt5TqDBEX MlsAjN3ed+nef0m4zHa69eAr2xswZ8hELmiT3eQekKBFuZQILsAAirYgyCSJd0EuyAEi iQhiVJftgggnqKpVWQEeuxspCzq+78o+UshODPtj8UktXxFCY0f2rUXjVJ4ziU7ZAZH3 ZERQUmGlQf3SJLe6oKA6e6eSa1ZDXBX+KYjei67noeUZ/H20qvcbl1M/TiU3KapvGCCC IjgoxGGWmZ1oTYJ3f7UCBuhmGNqY0QCkzyH9NbyYsA3thG7gy/ca3AdUBQZ8igwu5ajw j3lQ== X-Gm-Message-State: APjAAAWvx/merK8QvA9fIoMdCN99BplCoTobBrXtDolYCpZUhrDxVo0y gupzDWriU0ikD02jN95vDkxMF2Q/ X-Google-Smtp-Source: APXvYqysvKOblGPg5oAqA4W1KcRAJn9UXn9NAa1Ch0i3hcNUXOXqAqYrOFDumz4O2kY9cc3sHaVgrQ== X-Received: by 2002:a65:448a:: with SMTP id l10mr29996003pgq.327.1563549044607; Fri, 19 Jul 2019 08:10:44 -0700 (PDT) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a62:18c1:: with SMTP id 184ls5457267pfy.10.gmail; Fri, 19 Jul 2019 08:10:44 -0700 (PDT) X-Received: by 2002:a63:9c5:: with SMTP id 188mr22547416pgj.2.1563549044131; Fri, 19 Jul 2019 08:10:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1563549044; cv=none; d=google.com; s=arc-20160816; b=S7iJXIZAEMXZvQOAJd0rFLN36ZlDiGOKJyDvtu8Grg5EgY/hNqT2nYLAY8QPxP5d8t A02OIWVXRqMmUtXIoaCi2on9+Hcs5G92gmWAO4XPaMciseXOr0V93jCFChraUhMpE4yd O9npd55GQi00alngPfClgb7fojT8BUieLsXd+h7WdZfQufK5PYdYw2tidNL+DawNWOGQ YfGpXXfG9gfn4WZB+mHfNWxsYCUJM9CnvJOGn2mb5FG/zJ4wEG7xPPlZE90/p521FmcA iGHExL5ofL4/Ph4k4duzz5e7P7cSahLSzpRg6I3suhr5WrKgMISQS55/J0krdi/iZRhD sWVA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:dkim-signature; bh=NeLfIdfK7H9VA7YCSPes36VLCiljfy+v8RT7YHrSbrE=; b=hGv75Yj8EibJ1HrWOR8JfWKW8vttjMamAsfUW0I4RAAq/Q0gkQDdPDTxdCXOJxArTN DdAY0eVWBGYm6gjDsf+E6w02pEGWha0T40A/XZuprVH9lYn0diWvk/5SqTkG/3X1J7p9 PBmpuUUdH03Y1TFCtwknI0XX/+huRZ6cV/IurSbY4/Hor10JU9vJVivCaFWahDZ1JHai eD77wJhxAa6LXxsITMam08BFumelQ6uHN+PEBY3E4kQPD/W5AMNJLnZRH6d86EXiyoHR OfFjaoG54a8p/GLdrhiUc3Joiyx81jJkGP3ED8oDB+Wm4/KLeROWhkIWC5o9gfvjWliN k1iA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=YHoqQF7N; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id j2sor37134756pll.35.2019.07.19.08.10.43 for (Google Transport Security); Fri, 19 Jul 2019 08:10:43 -0700 (PDT) Received-SPF: pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; X-Received: by 2002:a17:902:b48f:: with SMTP id y15mr58454105plr.268.1563549043290; Fri, 19 Jul 2019 08:10:43 -0700 (PDT) Received: from localhost.localdomain ([49.206.201.222]) by smtp.gmail.com with ESMTPSA id b136sm30711299pfb.73.2019.07.19.08.10.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 19 Jul 2019 08:10:42 -0700 (PDT) From: Jagan Teki To: Simon Glass , Philipp Tomsich , Kever Yang , YouMin Chen , u-boot@lists.denx.de Cc: Manivannan Sadhasivam , gajjar04akash@gmail.com, linux-rockchip@lists.infradead.org, linux-amarula@amarulasolutions.com, Jagan Teki , Kever Yang Subject: [PATCH v4 16/18] ram: rk3399: Add rank detection support Date: Fri, 19 Jul 2019 20:40:30 +0530 Message-Id: <20190719151031.14684-1-jagan@amarulasolutions.com> X-Mailer: git-send-email 2.18.0.321.gffc6fa0e3 MIME-Version: 1.0 X-Original-Sender: jagan@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=YHoqQF7N; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com Content-Type: text/plain; charset="UTF-8" Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Right now the rk3399 sdram driver assume that the board has configured with 2 channels, so any possibility to enable single channel on the same driver will encounter channel #1 data training failure. Log: U-Boot TPL board init sdram_init: data training failed rk3399_dmc_init DRAM init failed -5 So, add an algorithm that can capable to compute the active or configured rank with associated channel like a) do rank loop to compute the active rank, with associated channel numbers b) then, succeed the data training only for configured channel c) preserve the rank for given channel d) do channel loop for setting the active channel e) if given rank is zero or inactive on the specific channel, clear the timings for the associated channel f) finally, return error if number of channels is zero Tested in NanoPI-NEO4 since it support single channel sdram configuration. Signed-off-by: Jagan Teki Signed-off-by: YouMin Chen Reviewed-by: Kever Yang (add PI_READ_GATE_TRAINING for LPDDR3 to support rk3399-evb case) Signed-off-by: Kever Yang --- Changes for v4: - add PI_READ_GATE_TRAINING, PI_WRITE_LEVELING for LPDDR3 and PI_READ_GATE_TRAINING for other dram types. drivers/ram/rockchip/sdram_rk3399.c | 122 +++++++++++++++++++++++----- 1 file changed, 100 insertions(+), 22 deletions(-) diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c index 8bbacb5275..9df2f840ab 100644 --- a/drivers/ram/rockchip/sdram_rk3399.c +++ b/drivers/ram/rockchip/sdram_rk3399.c @@ -1254,13 +1254,52 @@ static unsigned char calculate_stride(struct rk3399_sdram_params *params) return stride; } +static void clear_channel_params(struct rk3399_sdram_params *params, u8 channel) +{ + params->ch[channel].cap_info.rank = 0; + params->ch[channel].cap_info.col = 0; + params->ch[channel].cap_info.bk = 0; + params->ch[channel].cap_info.bw = 32; + params->ch[channel].cap_info.dbw = 32; + params->ch[channel].cap_info.row_3_4 = 0; + params->ch[channel].cap_info.cs0_row = 0; + params->ch[channel].cap_info.cs1_row = 0; + params->ch[channel].cap_info.ddrconfig = 0; +} + +static int pctl_init(struct dram_info *dram, struct rk3399_sdram_params *params) +{ + int channel; + int ret; + + for (channel = 0; channel < 2; channel++) { + const struct chan_info *chan = &dram->chan[channel]; + struct rk3399_cru *cru = dram->cru; + struct rk3399_ddr_publ_regs *publ = chan->publ; + + phy_pctrl_reset(cru, channel); + phy_dll_bypass_set(publ, params->base.ddr_freq); + + ret = pctl_cfg(dram, chan, channel, params); + if (ret < 0) { + printf("%s: pctl config failed\n", __func__); + return ret; + } + + /* start to trigger initialization */ + pctl_start(dram, channel); + } + + return 0; +} + static int sdram_init(struct dram_info *dram, struct rk3399_sdram_params *params) { unsigned char dramtype = params->base.dramtype; unsigned int ddr_freq = params->base.ddr_freq; - struct rk3399_cru *cru = dram->cru; - int channel; + u32 training_flag = PI_READ_GATE_TRAINING; + int channel, ch, rank; int ret; debug("Starting SDRAM initialization...\n"); @@ -1272,36 +1311,75 @@ static int sdram_init(struct dram_info *dram, return -E2BIG; } + for (ch = 0; ch < 2; ch++) { + params->ch[ch].cap_info.rank = 2; + for (rank = 2; rank != 0; rank--) { + ret = pctl_init(dram, params); + if (ret < 0) { + printf("%s: pctl init failed\n", __func__); + return ret; + } + + /* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */ + if (dramtype == LPDDR3) + udelay(10); + + params->ch[ch].cap_info.rank = rank; + + /* + * LPDDR3 CA training msut be trigger before + * other training. + * DDR3 is not have CA training. + */ + if (params->base.dramtype == LPDDR3) + training_flag |= PI_CA_TRAINING; + + if (!(data_training(&dram->chan[ch], ch, + params, training_flag))) + break; + } + /* Computed rank with associated channel number */ + params->ch[ch].cap_info.rank = rank; + } + + params->base.num_channels = 0; for (channel = 0; channel < 2; channel++) { const struct chan_info *chan = &dram->chan[channel]; - struct rk3399_ddr_publ_regs *publ = chan->publ; - - phy_pctrl_reset(cru, channel); - phy_dll_bypass_set(publ, ddr_freq); + struct sdram_cap_info *cap_info = ¶ms->ch[channel].cap_info; + u8 training_flag = PI_FULL_TRAINING; - if (channel >= params->base.num_channels) + if (cap_info->rank == 0) { + clear_channel_params(params, channel); continue; - - ret = pctl_cfg(dram, chan, channel, params); - if (ret < 0) { - printf("%s: pctl config failed\n", __func__); - return ret; + } else { + params->base.num_channels++; } - /* start to trigger initialization */ - pctl_start(dram, channel); + debug("Channel "); + debug(channel ? "1: " : "0: "); - /* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */ - if (dramtype == LPDDR3) - udelay(10); + /* LPDDR3 should have write and read gate training */ + if (params->base.dramtype == LPDDR3) + training_flag = PI_WRITE_LEVELING | + PI_READ_GATE_TRAINING; - if (data_training(chan, channel, params, PI_FULL_TRAINING)) { - printf("%s: data training failed\n", __func__); - return -EIO; + if (params->base.dramtype != LPDDR4) { + ret = data_training(dram, channel, params, + training_flag); + if (!ret) { + debug("%s: data train failed for channel %d\n", + __func__, ret); + continue; + } } - set_ddrconfig(chan, params, channel, - params->ch[channel].cap_info.ddrconfig); + set_ddrconfig(chan, params, channel, cap_info->ddrconfig); + } + + if (params->base.num_channels == 0) { + printf("%s: ", __func__); + printf(" - %dMHz failed!\n", params->base.ddr_freq); + return -EINVAL; } params->base.stride = calculate_stride(params);