From: Andrey Smirnov <andrew.smirnov@gmail.com>
To: barebox@lists.infradead.org
Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
Subject: [PATCH v2 7/8] ARM: i.MX: esdctl: Add memory size detection for i.MX8MQ
Date: Wed, 19 Sep 2018 08:45:40 -0700 [thread overview]
Message-ID: <20180919154541.29861-8-andrew.smirnov@gmail.com> (raw)
In-Reply-To: <20180919154541.29861-1-andrew.smirnov@gmail.com>
Add memory size detection for i.MX8MQ. Only basic LPDDR4
configurations are supported for now. Support for other types of
memory can be added later once we have any boards that use it.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
arch/arm/dts/imx8mq-ddrc.dtsi | 17 +++++
arch/arm/mach-imx/esdctl.c | 98 +++++++++++++++++++++++++
arch/arm/mach-imx/include/mach/esdctl.h | 1 +
3 files changed, 116 insertions(+)
create mode 100644 arch/arm/dts/imx8mq-ddrc.dtsi
diff --git a/arch/arm/dts/imx8mq-ddrc.dtsi b/arch/arm/dts/imx8mq-ddrc.dtsi
new file mode 100644
index 000000000..26d3da857
--- /dev/null
+++ b/arch/arm/dts/imx8mq-ddrc.dtsi
@@ -0,0 +1,17 @@
+/*
+ * Include file to switch board DTS form using hardcoded memory node
+ * to dynamic memory size detection based on DDR controller settings
+ */
+
+/ {
+
+ /delete-node/ memory@40000000;
+
+ peripherals@0 {
+ ddrc@3d400000 {
+ compatible = "fsl,imx8mq-ddrc";
+ reg = <0x3d400000 0x400000>;
+ };
+ };
+};
+
diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c
index 875e942de..af90c87bb 100644
--- a/arch/arm/mach-imx/esdctl.c
+++ b/arch/arm/mach-imx/esdctl.c
@@ -23,6 +23,7 @@
#include <init.h>
#include <of.h>
#include <linux/err.h>
+#include <linux/bitfield.h>
#include <asm/barebox-arm.h>
#include <asm/memory.h>
#include <mach/esdctl.h>
@@ -38,6 +39,7 @@
#include <mach/imx53-regs.h>
#include <mach/imx6-regs.h>
#include <mach/vf610-ddrmc.h>
+#include <mach/imx8mq-regs.h>
struct imx_esdctl_data {
unsigned long base0;
@@ -319,6 +321,76 @@ static void vf610_ddrmc_add_mem(void *mmdcbase, struct imx_esdctl_data *data)
vf610_ddrmc_sdram_size(mmdcbase));
}
+#define DDRC_ADDRMAP(n) (0x200 + 4 * (n))
+#define DDRC_ADDRMAP6_LPDDR4_6GB_12GB_24GB GENMASK(30, 29)
+#define DDRC_ADDRMAP0_CS_BIT0 GENMASK(4, 0)
+
+#define DDRC_MSTR 0x0000
+#define DDRC_MSTR_LPDDR4 BIT(5)
+#define DDRC_MSTR_DATA_BUS_WIDTH GENMASK(13, 12)
+#define DDRC_MSTR_ACTIVE_RANKS GENMASK(27, 24)
+
+static resource_size_t imx8mq_ddrc_sdram_size(void __iomem *ddrc)
+{
+ const u32 addrmap6 = readl(ddrc + DDRC_ADDRMAP(6));
+ const u32 addrmap0 = readl(ddrc + DDRC_ADDRMAP(0));
+ const u32 mstr = readl(ddrc + DDRC_MSTR);
+ resource_size_t size = 0;
+ unsigned long dbw, cs0, r;
+
+ BUG_ON(!(mstr & DDRC_MSTR_LPDDR4));
+
+ switch (FIELD_GET(DDRC_ADDRMAP6_LPDDR4_6GB_12GB_24GB, addrmap6)) {
+ case 0b00:
+ cs0 = FIELD_GET(DDRC_ADDRMAP0_CS_BIT0, addrmap0) + 6;
+
+ switch (FIELD_GET(DDRC_MSTR_DATA_BUS_WIDTH, mstr)) {
+ case 0b00: /* Full DQ bus */
+ dbw = 1;
+ break;
+ case 0b01: /* Half DQ bus */
+ dbw = 0;
+ break;
+ case 0b10: /* Quarter DQ bus */
+ case 0b11: /* Reserved */
+ BUG();
+ }
+
+ switch (FIELD_GET(DDRC_MSTR_ACTIVE_RANKS, mstr)) {
+ case 0b0001:
+ r = 0;
+ break;
+ case 0b0011:
+ r = 1;
+ break;
+ case 0b1111:
+ r = 2;
+ break;
+ default:
+ BUG();
+ }
+
+ size = 1UL << (cs0 + 1 + dbw + r);
+ break;
+ case 0b01:
+ size = SZ_1G + SZ_512M;
+ break;
+ case 0b10:
+ size = SZ_2G + SZ_1G;
+ break;
+ default:
+ BUG();
+ }
+
+ return size;
+}
+
+static void imx8mq_ddrc_add_mem(void *mmdcbase, struct imx_esdctl_data *data)
+{
+ arm_add_mem_device("ram0", data->base0,
+ imx8mq_ddrc_sdram_size(mmdcbase));
+}
+
static int imx_esdctl_probe(struct device_d *dev)
{
struct resource *iores;
@@ -405,6 +477,11 @@ static __maybe_unused struct imx_esdctl_data vf610_data = {
.add_mem = vf610_ddrmc_add_mem,
};
+static __maybe_unused struct imx_esdctl_data imx8mq_data = {
+ .base0 = MX8MQ_DDR_CSD1_BASE_ADDR,
+ .add_mem = imx8mq_ddrc_add_mem,
+};
+
static struct platform_device_id imx_esdctl_ids[] = {
#ifdef CONFIG_ARCH_IMX1
{
@@ -469,6 +546,9 @@ static __maybe_unused struct of_device_id imx_esdctl_dt_ids[] = {
}, {
.compatible = "fsl,vf610-ddrmc",
.data = &vf610_data
+ }, {
+ .compatible = "fsl,imx8mq-ddrc",
+ .data = &imx8mq_data
}, {
/* sentinel */
}
@@ -643,3 +723,21 @@ void __noreturn vf610_barebox_entry(void *boarddata)
vf610_ddrmc_sdram_size(IOMEM(VF610_DDR_BASE_ADDR)),
boarddata);
}
+
+void __noreturn imx8mq_barebox_entry(void *boarddata)
+{
+ resource_size_t size;
+
+ size = imx8mq_ddrc_sdram_size(IOMEM(MX8MQ_DDRC_CTL_BASE_ADDR));
+ /*
+ * We artificially limit detected memory size to force malloc
+ * pool placement to be within 4GiB address space, so as to
+ * make it accessible to 32-bit limited DMA.
+ *
+ * This limitation affects only early boot code and malloc
+ * pool placement. The rest of the system should be able to
+ * detect and utilize full amount of memory.
+ */
+ size = min_t(resource_size_t, SZ_4G - MX8MQ_DDR_CSD1_BASE_ADDR, size);
+ barebox_arm_entry(MX8MQ_DDR_CSD1_BASE_ADDR, size, boarddata);
+}
diff --git a/arch/arm/mach-imx/include/mach/esdctl.h b/arch/arm/mach-imx/include/mach/esdctl.h
index 117e2bbad..ff109aa10 100644
--- a/arch/arm/mach-imx/include/mach/esdctl.h
+++ b/arch/arm/mach-imx/include/mach/esdctl.h
@@ -139,6 +139,7 @@ void __noreturn imx53_barebox_entry(void *boarddata);
void __noreturn imx6q_barebox_entry(void *boarddata);
void __noreturn imx6ul_barebox_entry(void *boarddata);
void __noreturn vf610_barebox_entry(void *boarddata);
+void __noreturn imx8mq_barebox_entry(void *boarddata);
void imx_esdctl_disable(void);
#endif
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2018-09-19 15:46 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-19 15:45 [PATCH v2 0/8] i.MX8MQ EVK miscellanea Andrey Smirnov
2018-09-19 15:45 ` [PATCH v2 1/8] clk: i.MX8MQ: Bump refcounters of various important clocks Andrey Smirnov
2018-09-19 15:45 ` [PATCH v2 2/8] ARM: i.MX8MQ: Add missing node for ECSPI1 Andrey Smirnov
2018-09-19 15:45 ` [PATCH v2 3/8] ARM: i.MX8MQ: Configure USDHC1,2 clocks Andrey Smirnov
2018-09-19 15:45 ` [PATCH v2 4/8] ARM: i.MX8MQ: Configure FEC1 clocks Andrey Smirnov
2018-09-19 15:45 ` [PATCH v2 5/8] ARM: nxp-imx8mq-evk: Add missing compatibility check Andrey Smirnov
2018-09-19 15:45 ` [PATCH v2 6/8] ARM: nxp-imx8mq-evk: Add FEC's PHY configuration code Andrey Smirnov
2018-09-19 15:45 ` Andrey Smirnov [this message]
2018-09-20 23:22 ` [PATCH v2 7/8] ARM: i.MX: esdctl: Add memory size detection for i.MX8MQ Andrey Smirnov
2018-09-19 15:45 ` [PATCH v2 8/8] ARM: nxp-imx8mq-evk: Make use of memory size detection code Andrey Smirnov
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=20180919154541.29861-8-andrew.smirnov@gmail.com \
--to=andrew.smirnov@gmail.com \
--cc=barebox@lists.infradead.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox