summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2020-02-14 11:53:38 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2020-02-19 08:30:32 +0100
commit0266042714b2e0a17e397fe5d8a29a4487785df4 (patch)
tree3ec6d49a15181e40d14ef2349afdbd84438acd2d /arch/arm/mach-imx
parent5973ed7e2196aac7df53f81033cd46b51acba09c (diff)
downloadbarebox-0266042714b2e0a17e397fe5d8a29a4487785df4.tar.gz
barebox-0266042714b2e0a17e397fe5d8a29a4487785df4.tar.xz
ARM: i.MX8M: Add DDR controller support
This adds the DDR driver for the i.MX8MQ/i.MX8MM. It's taken from U-Boot v2020.04-rc1 with slight modifications for barebox The i.MX8MQ boards in the tree currently use the output of an earlier version of the NXP i.MX8M DDR Tool which doesn't use a controller driver but instead does most stuff in board code. It seems this can coexist with the new driver, only a few helper functions that previously lived in arch/arm/mach-imx/imx8-ddrc.c are now provided by the new driver. Tested on an i.MX8MM EVK Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/Kconfig1
-rw-r--r--arch/arm/mach-imx/Makefile2
-rw-r--r--arch/arm/mach-imx/imx8-ddrc.c91
-rw-r--r--arch/arm/mach-imx/include/mach/imx8-ddrc.h66
4 files changed, 2 insertions, 158 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index d717d83865..7b79d80748 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -183,6 +183,7 @@ config ARCH_IMX8M
select COMMON_CLK_OF_PROVIDER
select ARCH_HAS_FEC_IMX
select HW_HAS_PCI
+ select IMX8M_DRAM
select PBL_VERIFY_PIGGY if HABV4
config ARCH_IMX8MQ
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 862dc78ff2..105785ba1b 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -16,7 +16,7 @@ lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o
obj-$(CONFIG_ARCH_IMX7) += imx7.o
obj-$(CONFIG_ARCH_VF610) += vf610.o
obj-$(CONFIG_ARCH_IMX8M) += imx8m.o
-lwl-$(CONFIG_ARCH_IMX8MQ) += imx8-ddrc.o atf.o
+lwl-$(CONFIG_ARCH_IMX8MQ) += atf.o
obj-$(CONFIG_IMX_IIM) += iim.o
obj-$(CONFIG_NAND_IMX) += nand.o
lwl-$(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND) += external-nand-boot.o
diff --git a/arch/arm/mach-imx/imx8-ddrc.c b/arch/arm/mach-imx/imx8-ddrc.c
deleted file mode 100644
index 8bb2672102..0000000000
--- a/arch/arm/mach-imx/imx8-ddrc.c
+++ /dev/null
@@ -1,91 +0,0 @@
-#include <common.h>
-#include <linux/iopoll.h>
-#include <mach/imx8-ddrc.h>
-#include <debug_ll.h>
-
-void ddrc_phy_load_firmware(void __iomem *phy,
- enum ddrc_phy_firmware_offset offset,
- const u16 *blob, size_t size)
-{
- while (size) {
- writew(*blob++, phy + DDRC_PHY_REG(offset));
- offset++;
- size -= sizeof(*blob);
- }
-}
-
-enum pmc_constants {
- PMC_MESSAGE_ID,
- PMC_MESSAGE_STREAM,
-
- PMC_TRAIN_SUCCESS = 0x07,
- PMC_TRAIN_STREAM_START = 0x08,
- PMC_TRAIN_FAIL = 0xff,
-};
-
-static u32 ddrc_phy_get_message(void __iomem *phy, int type)
-{
- u32 r, message;
-
- /*
- * When BIT0 set to 0, the PMU has a message for the user
- * Wait for it indefinitely.
- */
- readl_poll_timeout(phy + DDRC_PHY_REG(0xd0004),
- r, !(r & BIT(0)), 0);
-
- switch (type) {
- case PMC_MESSAGE_ID:
- /*
- * Get the major message ID
- */
- message = readl(phy + DDRC_PHY_REG(0xd0032));
- break;
- case PMC_MESSAGE_STREAM:
- message = readl(phy + DDRC_PHY_REG(0xd0034));
- message <<= 16;
- message |= readl(phy + DDRC_PHY_REG(0xd0032));
- break;
- }
-
- /*
- * By setting this register to 0, the user acknowledges the
- * receipt of the message.
- */
- writel(0x00000000, phy + DDRC_PHY_REG(0xd0031));
- /*
- * When BIT0 set to 0, the PMU has a message for the user
- */
- readl_poll_timeout(phy + DDRC_PHY_REG(0xd0004),
- r, r & BIT(0), 0);
-
- writel(0x00000001, phy + DDRC_PHY_REG(0xd0031));
-
- return message;
-}
-
-static void ddrc_phy_fetch_streaming_message(void __iomem *phy)
-{
- const u16 index = ddrc_phy_get_message(phy, PMC_MESSAGE_STREAM);
- u16 i;
-
- for (i = 0; i < index; i++)
- ddrc_phy_get_message(phy, PMC_MESSAGE_STREAM);
-}
-
-void ddrc_phy_wait_training_complete(void __iomem *phy)
-{
- for (;;) {
- const u32 m = ddrc_phy_get_message(phy, PMC_MESSAGE_ID);
-
- switch (m) {
- case PMC_TRAIN_STREAM_START:
- ddrc_phy_fetch_streaming_message(phy);
- break;
- case PMC_TRAIN_SUCCESS:
- return;
- case PMC_TRAIN_FAIL:
- hang();
- }
- }
-}
diff --git a/arch/arm/mach-imx/include/mach/imx8-ddrc.h b/arch/arm/mach-imx/include/mach/imx8-ddrc.h
deleted file mode 100644
index d49e29f263..0000000000
--- a/arch/arm/mach-imx/include/mach/imx8-ddrc.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef __IMX8_DDRC_H__
-#define __IMX8_DDRC_H__
-
-#include <mach/imx8mq-regs.h>
-#include <io.h>
-#include <firmware.h>
-#include <linux/compiler.h>
-
-enum ddrc_phy_firmware_offset {
- DDRC_PHY_IMEM = 0x00050000U,
- DDRC_PHY_DMEM = 0x00054000U,
-};
-
-void ddrc_phy_load_firmware(void __iomem *,
- enum ddrc_phy_firmware_offset,
- const u16 *, size_t);
-
-#define DDRC_PHY_REG(x) ((x) * 4)
-
-void ddrc_phy_wait_training_complete(void __iomem *phy);
-
-
-/*
- * i.MX8M DDR Tool compatibility layer
- */
-
-#define reg32_write(a, v) writel(v, a)
-#define reg32_read(a) readl(a)
-
-static inline void wait_ddrphy_training_complete(void)
-{
- ddrc_phy_wait_training_complete(IOMEM(MX8MQ_DDRC_PHY_BASE_ADDR));
-}
-
-#define __ddr_load_train_code(imem, dmem) \
- do { \
- const u16 *__mem; \
- size_t __size; \
- \
- get_builtin_firmware(imem, &__mem, &__size); \
- ddrc_phy_load_firmware(IOMEM(MX8MQ_DDRC_PHY_BASE_ADDR), \
- DDRC_PHY_IMEM, __mem, __size); \
- \
- get_builtin_firmware(dmem, &__mem, &__size); \
- ddrc_phy_load_firmware(IOMEM(MX8MQ_DDRC_PHY_BASE_ADDR), \
- DDRC_PHY_DMEM, __mem, __size); \
- } while (0)
-
-#define ddr_load_train_code(imem_dmem) __ddr_load_train_code(imem_dmem)
-
-#define DDRC_IPS_BASE_ADDR(X) (0x3d400000 + (X * 0x2000000))
-
-#define DDRC_STAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x04)
-#define DDRC_MRSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x18)
-#define DDRC_PWRCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x30)
-#define DDRC_RFSHCTL3(X) (DDRC_IPS_BASE_ADDR(X) + 0x60)
-#define DDRC_CRCPARSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0xcc)
-#define DDRC_DFIMISC(X) (DDRC_IPS_BASE_ADDR(X) + 0x1b0)
-#define DDRC_DFISTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x1bc)
-#define DDRC_SWCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x320)
-#define DDRC_SWSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x324)
-#define DDRC_PCTRL_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x490)
-
-#define IP2APB_DDRPHY_IPS_BASE_ADDR(X) (0x3c000000 + (X * 0x2000000))
-
-#endif \ No newline at end of file