All of lore.kernel.org
 help / color / mirror / Atom feed
From: Aswath Govindraju <a-govindraju@ti.com>
Cc: <u-boot@lists.denx.de>, Wolfgang Denk <wd@denx.de>,
	Hari Nagalla <hnagalla@ti.com>, David Huang <d-huang@ti.com>,
	Keerthy <j-keerthy@ti.com>, Dave Gerlach <d-gerlach@ti.com>,
	Suman Anna <s-anna@ti.com>, Nishanth Menon <nm@ti.com>,
	Tero Kristo <kristo@kernel.org>,
	Kishon Vijay Abraham I <kishon@ti.com>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	Christian Hewitt <christianshewitt@gmail.com>,
	Tim Harvey <tharvey@gateworks.com>,
	Peter Robinson <pbrobinson@gmail.com>,
	Kever Yang <kever.yang@rock-chips.com>,
	Neil Armstrong <narmstrong@baylibre.com>,
	Fabio Estevam <festevam@denx.de>,
	Andre Przywara <andre.przywara@arm.com>,
	Jaehoon Chung <jh80.chung@samsung.com>,
	Sean Anderson <seanga2@gmail.com>,
	Lukasz Majewski <lukma@denx.de>,
	Aswath Govindraju <a-govindraju@ti.com>
Subject: [PATCH v2 03/20] ram: k3-ddrss: Add support for multiple instances of DDR subsystems
Date: Tue, 11 Jan 2022 13:25:28 +0530	[thread overview]
Message-ID: <20220111075545.1880-4-a-govindraju@ti.com> (raw)
In-Reply-To: <20220111075545.1880-1-a-govindraju@ti.com>

The current driver only supports single instance of DRR subsystem. Add
support for probing multiple instances of DDR subsystem.

Signed-off-by: Aswath Govindraju <a-govindraju@ti.com>
---
 drivers/ram/k3-ddrss/k3-ddrss.c | 138 ++++++++++++++++++++------------
 1 file changed, 87 insertions(+), 51 deletions(-)

diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
index 95b5cf9128b0..96084d0b83d9 100644
--- a/drivers/ram/k3-ddrss/k3-ddrss.c
+++ b/drivers/ram/k3-ddrss/k3-ddrss.c
@@ -30,6 +30,9 @@
 #define DDRSS_V2A_R1_MAT_REG			0x0020
 #define DDRSS_ECC_CTRL_REG			0x0120
 
+#define SINGLE_DDR_SUBSYSTEM	0x1
+#define MULTI_DDR_SUBSYSTEM	0x2
+
 struct k3_ddrss_desc {
 	struct udevice *dev;
 	void __iomem *ddrss_ss_cfg;
@@ -42,14 +45,12 @@ struct k3_ddrss_desc {
 	u32 ddr_freq2;
 	u32 ddr_fhs_cnt;
 	struct udevice *vtt_supply;
+	u32 instance;
+	lpddr4_obj *driverdt;
+	lpddr4_config config;
+	lpddr4_privatedata pd;
 };
 
-static lpddr4_obj *driverdt;
-static lpddr4_config config;
-static lpddr4_privatedata pd;
-
-static struct k3_ddrss_desc *ddrss;
-
 struct reginitdata {
 	u32 ctl_regs[LPDDR4_INTR_CTL_REG_COUNT];
 	u16 ctl_regs_offs[LPDDR4_INTR_CTL_REG_COUNT];
@@ -83,15 +84,16 @@ struct reginitdata {
 		offset = offset * 10 + (*i - '0'); } \
 	} while (0)
 
-static u32 k3_lpddr4_read_ddr_type(void)
+static u32 k3_lpddr4_read_ddr_type(const lpddr4_privatedata *pd)
 {
 	u32 status = 0U;
 	u32 offset = 0U;
 	u32 regval = 0U;
 	u32 dram_class = 0U;
+	struct k3_ddrss_desc *ddrss = (struct k3_ddrss_desc *)pd->ddr_instance;
 
 	TH_OFFSET_FROM_REG(LPDDR4__DRAM_CLASS__REG, CTL_SHIFT, offset);
-	status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, &regval);
+	status = ddrss->driverdt->readreg(pd, LPDDR4_CTL_REGS, offset, &regval);
 	if (status > 0U) {
 		printf("%s: Failed to read DRAM_CLASS\n", __func__);
 		hang();
@@ -102,23 +104,23 @@ static u32 k3_lpddr4_read_ddr_type(void)
 	return dram_class;
 }
 
-static void k3_lpddr4_freq_update(void)
+static void k3_lpddr4_freq_update(struct k3_ddrss_desc *ddrss)
 {
 	unsigned int req_type, counter;
 
 	for (counter = 0; counter < ddrss->ddr_fhs_cnt; counter++) {
 		if (wait_for_bit_le32(ddrss->ddrss_ctrl_mmr +
-				      CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS, 0x80,
+				      CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS + ddrss->instance * 0x10, 0x80,
 				      true, 10000, false)) {
 			printf("Timeout during frequency handshake\n");
 			hang();
 		}
 
 		req_type = readl(ddrss->ddrss_ctrl_mmr +
-				 CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS) & 0x03;
+				 CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS + ddrss->instance * 0x10) & 0x03;
 
-		debug("%s: received freq change req: req type = %d, req no. = %d\n",
-		      __func__, req_type, counter);
+		debug("%s: received freq change req: req type = %d, req no. = %d, instance = %d\n",
+		      __func__, req_type, counter, ddrss->instance);
 
 		if (req_type == 1)
 			clk_set_rate(&ddrss->ddr_clk, ddrss->ddr_freq1);
@@ -132,31 +134,32 @@ static void k3_lpddr4_freq_update(void)
 			printf("%s: Invalid freq request type\n", __func__);
 
 		writel(0x1, ddrss->ddrss_ctrl_mmr +
-		       CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS);
+		       CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS + ddrss->instance * 0x10);
 		if (wait_for_bit_le32(ddrss->ddrss_ctrl_mmr +
-				      CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS, 0x80,
+				      CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS + ddrss->instance * 0x10, 0x80,
 				      false, 10, false)) {
 			printf("Timeout during frequency handshake\n");
 			hang();
 		}
 		writel(0x0, ddrss->ddrss_ctrl_mmr +
-		       CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS);
+		       CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS + ddrss->instance * 0x10);
 	}
 }
 
-static void k3_lpddr4_ack_freq_upd_req(void)
+static void k3_lpddr4_ack_freq_upd_req(const lpddr4_privatedata *pd)
 {
 	u32 dram_class;
+	struct k3_ddrss_desc *ddrss = (struct k3_ddrss_desc *)pd->ddr_instance;
 
 	debug("--->>> LPDDR4 Initialization is in progress ... <<<---\n");
 
-	dram_class = k3_lpddr4_read_ddr_type();
+	dram_class = k3_lpddr4_read_ddr_type(pd);
 
 	switch (dram_class) {
 	case DENALI_CTL_0_DRAM_CLASS_DDR4:
 		break;
 	case DENALI_CTL_0_DRAM_CLASS_LPDDR4:
-		k3_lpddr4_freq_update();
+		k3_lpddr4_freq_update(ddrss);
 		break;
 	default:
 		printf("Unrecognized dram_class cannot update frequency!\n");
@@ -167,8 +170,9 @@ static int k3_ddrss_init_freq(struct k3_ddrss_desc *ddrss)
 {
 	u32 dram_class;
 	int ret;
+	lpddr4_privatedata *pd = &ddrss->pd;
 
-	dram_class = k3_lpddr4_read_ddr_type();
+	dram_class = k3_lpddr4_read_ddr_type(pd);
 
 	switch (dram_class) {
 	case DENALI_CTL_0_DRAM_CLASS_DDR4:
@@ -196,7 +200,7 @@ static void k3_lpddr4_info_handler(const lpddr4_privatedata *pd,
 				   lpddr4_infotype infotype)
 {
 	if (infotype == LPDDR4_DRV_SOC_PLL_UPDATE)
-		k3_lpddr4_ack_freq_upd_req();
+		k3_lpddr4_ack_freq_upd_req(pd);
 }
 
 static int k3_ddrss_power_on(struct k3_ddrss_desc *ddrss)
@@ -235,6 +239,7 @@ static int k3_ddrss_power_on(struct k3_ddrss_desc *ddrss)
 static int k3_ddrss_ofdata_to_priv(struct udevice *dev)
 {
 	struct k3_ddrss_desc *ddrss = dev_get_priv(dev);
+	struct k3_ddrss_data *ddrss_data = (struct k3_ddrss_data *)dev_get_driver_data(dev);
 	phys_addr_t reg;
 	int ret;
 
@@ -274,6 +279,17 @@ static int k3_ddrss_ofdata_to_priv(struct udevice *dev)
 	if (ret)
 		dev_err(dev, "clk get failed for osc clk %d\n", ret);
 
+	/* Reading instance number for multi ddr subystems */
+	if (ddrss_data->flags & MULTI_DDR_SUBSYSTEM) {
+		ret = dev_read_u32(dev, "instance", &ddrss->instance);
+		if (ret) {
+			dev_err(dev, "missing instance property");
+			return -EINVAL;
+		}
+	} else {
+		ddrss->instance = 0;
+	}
+
 	ret = dev_read_u32(dev, "ti,ddr-freq1", &ddrss->ddr_freq1);
 	if (ret)
 		dev_err(dev, "ddr freq1 not populated %d\n", ret);
@@ -289,12 +305,13 @@ static int k3_ddrss_ofdata_to_priv(struct udevice *dev)
 	return ret;
 }
 
-void k3_lpddr4_probe(void)
+void k3_lpddr4_probe(struct k3_ddrss_desc *ddrss)
 {
 	u32 status = 0U;
 	u16 configsize = 0U;
+	lpddr4_config *config = &ddrss->config;
 
-	status = driverdt->probe(&config, &configsize);
+	status = ddrss->driverdt->probe(config, &configsize);
 
 	if ((status != 0) || (configsize != sizeof(lpddr4_privatedata))
 	    || (configsize > SRAM_MAX)) {
@@ -305,25 +322,30 @@ void k3_lpddr4_probe(void)
 	}
 }
 
-void k3_lpddr4_init(void)
+void k3_lpddr4_init(struct k3_ddrss_desc *ddrss)
 {
 	u32 status = 0U;
+	lpddr4_config *config = &ddrss->config;
+	lpddr4_obj *driverdt = ddrss->driverdt;
+	lpddr4_privatedata *pd = &ddrss->pd;
 
-	if ((sizeof(pd) != sizeof(lpddr4_privatedata))
-	    || (sizeof(pd) > SRAM_MAX)) {
+	if ((sizeof(*pd) != sizeof(lpddr4_privatedata)) || (sizeof(*pd) > SRAM_MAX)) {
 		printf("%s: FAIL\n", __func__);
 		hang();
 	}
 
-	config.ctlbase = (struct lpddr4_ctlregs_s *)ddrss->ddrss_ss_cfg;
-	config.infohandler = (lpddr4_infocallback) k3_lpddr4_info_handler;
+	config->ctlbase = (struct lpddr4_ctlregs_s *)ddrss->ddrss_ss_cfg;
+	config->infohandler = (lpddr4_infocallback) k3_lpddr4_info_handler;
+
+	status = driverdt->init(pd, config);
 
-	status = driverdt->init(&pd, &config);
+	/* linking ddr instance to lpddr4  */
+	pd->ddr_instance = (void *)ddrss;
 
 	if ((status > 0U) ||
-	    (pd.ctlbase != (struct lpddr4_ctlregs_s *)config.ctlbase) ||
-	    (pd.ctlinterrupthandler != config.ctlinterrupthandler) ||
-	    (pd.phyindepinterrupthandler != config.phyindepinterrupthandler)) {
+	    (pd->ctlbase != (struct lpddr4_ctlregs_s *)config->ctlbase) ||
+	    (pd->ctlinterrupthandler != config->ctlinterrupthandler) ||
+	    (pd->phyindepinterrupthandler != config->phyindepinterrupthandler)) {
 		printf("%s: FAIL\n", __func__);
 		hang();
 	} else {
@@ -331,7 +353,8 @@ void k3_lpddr4_init(void)
 	}
 }
 
-void populate_data_array_from_dt(struct reginitdata *reginit_data)
+void populate_data_array_from_dt(struct k3_ddrss_desc *ddrss,
+				 struct reginitdata *reginit_data)
 {
 	int ret, i;
 
@@ -363,22 +386,24 @@ void populate_data_array_from_dt(struct reginitdata *reginit_data)
 		reginit_data->phy_regs_offs[i] = i;
 }
 
-void k3_lpddr4_hardware_reg_init(void)
+void k3_lpddr4_hardware_reg_init(struct k3_ddrss_desc *ddrss)
 {
 	u32 status = 0U;
 	struct reginitdata reginitdata;
+	lpddr4_obj *driverdt = ddrss->driverdt;
+	lpddr4_privatedata *pd = &ddrss->pd;
 
-	populate_data_array_from_dt(&reginitdata);
+	populate_data_array_from_dt(ddrss, &reginitdata);
 
-	status = driverdt->writectlconfig(&pd, reginitdata.ctl_regs,
+	status = driverdt->writectlconfig(pd, reginitdata.ctl_regs,
 					  reginitdata.ctl_regs_offs,
 					  LPDDR4_INTR_CTL_REG_COUNT);
 	if (!status)
-		status = driverdt->writephyindepconfig(&pd, reginitdata.pi_regs,
+		status = driverdt->writephyindepconfig(pd, reginitdata.pi_regs,
 						       reginitdata.pi_regs_offs,
 						       LPDDR4_INTR_PHY_INDEP_REG_COUNT);
 	if (!status)
-		status = driverdt->writephyconfig(&pd, reginitdata.phy_regs,
+		status = driverdt->writephyconfig(pd, reginitdata.phy_regs,
 						  reginitdata.phy_regs_offs,
 						  LPDDR4_INTR_PHY_REG_COUNT);
 	if (status) {
@@ -387,27 +412,29 @@ void k3_lpddr4_hardware_reg_init(void)
 	}
 }
 
-void k3_lpddr4_start(void)
+void k3_lpddr4_start(struct k3_ddrss_desc *ddrss)
 {
 	u32 status = 0U;
 	u32 regval = 0U;
 	u32 offset = 0U;
+	lpddr4_obj *driverdt = ddrss->driverdt;
+	lpddr4_privatedata *pd = &ddrss->pd;
 
 	TH_OFFSET_FROM_REG(LPDDR4__START__REG, CTL_SHIFT, offset);
 
-	status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, &regval);
+	status = driverdt->readreg(pd, LPDDR4_CTL_REGS, offset, &regval);
 	if ((status > 0U) || ((regval & TH_FLD_MASK(LPDDR4__START__FLD)) != 0U)) {
 		printf("%s: Pre start FAIL\n", __func__);
 		hang();
 	}
 
-	status = driverdt->start(&pd);
+	status = driverdt->start(pd);
 	if (status > 0U) {
 		printf("%s: FAIL\n", __func__);
 		hang();
 	}
 
-	status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, &regval);
+	status = driverdt->readreg(pd, LPDDR4_CTL_REGS, offset, &regval);
 	if ((status > 0U) || ((regval & TH_FLD_MASK(LPDDR4__START__FLD)) != 1U)) {
 		printf("%s: Post start FAIL\n", __func__);
 		hang();
@@ -419,8 +446,7 @@ void k3_lpddr4_start(void)
 static int k3_ddrss_probe(struct udevice *dev)
 {
 	int ret;
-
-	ddrss = dev_get_priv(dev);
+	struct k3_ddrss_desc *ddrss = dev_get_priv(dev);
 
 	debug("%s(dev=%p)\n", __func__, dev);
 
@@ -439,16 +465,17 @@ static int k3_ddrss_probe(struct udevice *dev)
 	writel(0x0, ddrss->ddrss_ss_cfg + DDRSS_ECC_CTRL_REG);
 #endif
 
-	driverdt = lpddr4_getinstance();
-	k3_lpddr4_probe();
-	k3_lpddr4_init();
-	k3_lpddr4_hardware_reg_init();
+	ddrss->driverdt = lpddr4_getinstance();
+
+	k3_lpddr4_probe(ddrss);
+	k3_lpddr4_init(ddrss);
+	k3_lpddr4_hardware_reg_init(ddrss);
 
 	ret = k3_ddrss_init_freq(ddrss);
 	if (ret)
 		return ret;
 
-	k3_lpddr4_start();
+	k3_lpddr4_start(ddrss);
 
 	return ret;
 }
@@ -462,9 +489,18 @@ static struct ram_ops k3_ddrss_ops = {
 	.get_info = k3_ddrss_get_info,
 };
 
+static const struct k3_ddrss_data k3_data = {
+	.flags = SINGLE_DDR_SUBSYSTEM,
+};
+
+static const struct k3_ddrss_data j721s2_data = {
+	.flags = MULTI_DDR_SUBSYSTEM,
+};
+
 static const struct udevice_id k3_ddrss_ids[] = {
-	{.compatible = "ti,am64-ddrss"},
-	{.compatible = "ti,j721e-ddrss"},
+	{.compatible = "ti,am64-ddrss", .data = (ulong)&k3_data, },
+	{.compatible = "ti,j721e-ddrss", .data = (ulong)&k3_data, },
+	{.compatible = "ti,j721s2-ddrss", .data = (ulong)&j721s2_data, },
 	{}
 };
 
-- 
2.17.1


  parent reply	other threads:[~2022-01-11  7:56 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-11  7:55 [PATCH v2 00/20] J721S2: Add initial support Aswath Govindraju
2022-01-11  7:55 ` [PATCH v2 01/20] remoteproc: k3_system_controller: Support optional boot_notification channel Aswath Govindraju
2022-01-13 14:12   ` Tom Rini
2022-01-17  5:31     ` Aswath Govindraju
2022-01-17  6:52       ` Aswath Govindraju
2022-01-17 13:54         ` Tom Rini
2022-01-18  5:56           ` Aswath Govindraju
2022-01-18 12:50             ` Tom Rini
2022-01-18 13:50               ` Nishanth Menon
2022-01-18 14:17                 ` Tom Rini
2022-01-11  7:55 ` [PATCH v2 02/20] ram: k3-ddrss: lpddr4_structs_if.h: Add a pointer to ddr instance Aswath Govindraju
2022-01-11  7:55 ` Aswath Govindraju [this message]
2022-01-11  7:55 ` [PATCH v2 04/20] ram: k3-ddrss: Add support for configuring MSMC subsystem in case of Multiple DDR subsystems Aswath Govindraju
2022-01-11  7:55 ` [PATCH v2 05/20] arm: K3: Add basic support for J721S2 SoC definition Aswath Govindraju
2022-01-13 14:13   ` Tom Rini
2022-01-11  7:55 ` [PATCH v2 06/20] drivers: dma: Add support for J721S2 Aswath Govindraju
2022-01-11  7:55 ` [PATCH v2 07/20] clk: clk-k3: Add support for J721S2 SoC Aswath Govindraju
2022-01-11  7:55 ` [PATCH v2 08/20] power: domain: ti: " Aswath Govindraju
2022-01-11  7:55 ` [PATCH v2 09/20] ram: k3-ddrss: " Aswath Govindraju
2022-01-13 14:15   ` Tom Rini
2022-01-17  6:31     ` Aswath Govindraju
2022-01-11  7:55 ` [PATCH v2 10/20] soc: ti: k3-socinfo: Add entry " Aswath Govindraju
2022-01-11  7:55 ` [PATCH v2 11/20] board: ti: j721s2: Add board support for J721S2 Aswath Govindraju
2022-01-13 14:16   ` Tom Rini
2022-01-17  6:42     ` Aswath Govindraju
2022-01-17 13:54       ` Tom Rini
2022-01-11  7:55 ` [PATCH v2 12/20] dt-bindings: ti-serdes-mux: Add defines for J721S2 SoC Aswath Govindraju
2022-01-13 14:17   ` Tom Rini
2022-01-17  5:41     ` Aswath Govindraju
2022-01-11  7:55 ` [PATCH v2 13/20] dt-bindings: pinctrl: k3: Introduce pinmux definitions for J721S2 Aswath Govindraju
2022-01-11  7:55 ` [PATCH v2 14/20] arm: dts: Add initial support for J721S2 SoC Aswath Govindraju
2022-01-13 14:08   ` Tom Rini
2022-01-13 14:16     ` Aswath Govindraju
2022-01-13 14:23       ` Tom Rini
2022-01-11  7:55 ` [PATCH v2 15/20] arm: dts: Add initial support for J721S2 System on Module Aswath Govindraju
2022-01-11  7:55 ` [PATCH v2 16/20] arm: dts: Add support for A72 specific J721S2 Common Processor Board Aswath Govindraju
2022-01-11  7:55 ` [PATCH v2 17/20] arm: dts: k3-j721s2: Add r5 specific dt support Aswath Govindraju
2022-01-13 14:11   ` Tom Rini
2022-01-11  7:55 ` [PATCH v2 18/20] arm: dts: k3-j721s2-ddr: Add DDR support Aswath Govindraju
2022-01-11  7:55 ` [PATCH v2 19/20] configs: j721s2_evm_r5_defconfig: Add R5 SPL specific defconfig Aswath Govindraju
2022-01-11  7:55 ` [PATCH v2 20/20] configs: j721s2_evm_a72_defconfig: Add A72 " Aswath Govindraju
2022-01-18  7:30 ` [PATCH v2 00/20] J721S2: Add initial support Aswath Govindraju

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220111075545.1880-4-a-govindraju@ti.com \
    --to=a-govindraju@ti.com \
    --cc=andre.przywara@arm.com \
    --cc=christianshewitt@gmail.com \
    --cc=d-gerlach@ti.com \
    --cc=d-huang@ti.com \
    --cc=festevam@denx.de \
    --cc=hnagalla@ti.com \
    --cc=j-keerthy@ti.com \
    --cc=jh80.chung@samsung.com \
    --cc=kever.yang@rock-chips.com \
    --cc=kishon@ti.com \
    --cc=kristo@kernel.org \
    --cc=lukma@denx.de \
    --cc=narmstrong@baylibre.com \
    --cc=nm@ti.com \
    --cc=pbrobinson@gmail.com \
    --cc=s-anna@ti.com \
    --cc=seanga2@gmail.com \
    --cc=tharvey@gateworks.com \
    --cc=u-boot@lists.denx.de \
    --cc=vigneshr@ti.com \
    --cc=wd@denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.