U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
December 2014
- 159 participants
- 619 discussions

[U-Boot] [PATCH] spl: mmc: Fix raw boot mode (related to commit 4c5bbc2328a24f5e1ee990c9a9527e48e5fb3b5f)
by Guillaume GARDET 05 Jan '15
by Guillaume GARDET 05 Jan '15
05 Jan '15
As reported by Robert Nelson, commit 4c5bbc2328a24f5e1ee990c9a9527e48e5fb3b5f
may break MMC RAW boot mode.
This patch fixes the check path to fix MMC Raw boot mode.
Tested raw boot mode and FS boot mode on a pandaboard (rev. A3).
Reported-by: Robert Nelson <robertcnelson(a)gmail.com>
Signed-off-by: Guillaume GARDET <guillaume.gardet(a)free.fr>
Cc: Tom Rini <trini(a)ti.com>
Cc: Robert Nelson <robertcnelson(a)gmail.com>
---
common/spl/spl_mmc.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index 7bae16b..c2e596b 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -172,11 +172,24 @@ void spl_mmc_load_image(void)
err = mmc_load_image_raw_sector(mmc,
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
#endif
- } else {
+ }
+
+ switch(boot_mode){
+ case MMCSD_MODE_RAW:
+#if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT)
+ case MMCSD_MODE_FS:
+#endif
+#ifdef CONFIG_SUPPORT_EMMC_BOOT
+ case MMCSD_MODE_EMMCBOOT:
+#endif
+ /* Boot mode is ok. Nothing to do. */
+ break;
+ case MMCSD_MODE_UNDEFINED:
+ default:
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
- puts("spl: wrong MMC boot mode\n");
+ puts("spl: wrong MMC boot mode\n");
#endif
- hang();
+ hang();
}
if (err)
--
1.8.4.5
4
5

[U-Boot] [PATCH v2] mmc: rmobile: Add SDHC support for Renesas rmobile ARM SoC
by Nobuhiro Iwamatsu 05 Jan '15
by Nobuhiro Iwamatsu 05 Jan '15
05 Jan '15
This adds Renesas rmobile ARM SoC's SD/MMC host support.
This drivers tested with Gose board and Koelsch board.
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj(a)renesas.com>
---
v2: - Remove global variable, and move to sh_sdhi_host.
- Remove define for each SoCs, use instead of quirks.
- Add timeout control for loop.
- Change printf to debug for some debug messages.
- Remove volatile declaration.
arch/arm/include/asm/arch-rmobile/r8a7790.h | 6 +
arch/arm/include/asm/arch-rmobile/r8a7791.h | 5 +
arch/arm/include/asm/arch-rmobile/r8a7793.h | 5 +
arch/arm/include/asm/arch-rmobile/r8a7794.h | 5 +
arch/arm/include/asm/arch-rmobile/rcar-base.h | 3 +
arch/arm/include/asm/arch-rmobile/sh_sdhi.h | 168 +++++++
drivers/mmc/Kconfig | 9 +
drivers/mmc/Makefile | 1 +
drivers/mmc/sh_sdhi.c | 696 ++++++++++++++++++++++++++
9 files changed, 898 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rmobile/sh_sdhi.h
create mode 100644 drivers/mmc/sh_sdhi.c
diff --git a/arch/arm/include/asm/arch-rmobile/r8a7790.h b/arch/arm/include/asm/arch-rmobile/r8a7790.h
index de14869..a70adc6 100644
--- a/arch/arm/include/asm/arch-rmobile/r8a7790.h
+++ b/arch/arm/include/asm/arch-rmobile/r8a7790.h
@@ -15,6 +15,12 @@
#define CONFIG_SYS_I2C_SH_BASE2 0xE6520000
#define CONFIG_SYS_I2C_SH_BASE3 0xE60B0000
+/* SDHI */
+#define CONFIG_SYS_SH_SDHI1_BASE 0xEE120000
+#define CONFIG_SYS_SH_SDHI2_BASE 0xEE140000
+#define CONFIG_SYS_SH_SDHI3_BASE 0xEE160000
+#define CONFIG_SYS_SH_SDHI_NR_CHANNEL 4
+
#define R8A7790_CUT_ES2X 2
#define IS_R8A7790_ES2() \
(rmobile_get_cpu_rev_integer() == R8A7790_CUT_ES2X)
diff --git a/arch/arm/include/asm/arch-rmobile/r8a7791.h b/arch/arm/include/asm/arch-rmobile/r8a7791.h
index 26a0bd5..658d435 100644
--- a/arch/arm/include/asm/arch-rmobile/r8a7791.h
+++ b/arch/arm/include/asm/arch-rmobile/r8a7791.h
@@ -17,6 +17,11 @@
/* SH-I2C */
#define CONFIG_SYS_I2C_SH_BASE2 0xE60B0000
+/* SDHI */
+#define CONFIG_SYS_SH_SDHI1_BASE 0xEE140000
+#define CONFIG_SYS_SH_SDHI2_BASE 0xEE160000
+#define CONFIG_SYS_SH_SDHI_NR_CHANNEL 3
+
#define DBSC3_1_QOS_R0_BASE 0xE67A1000
#define DBSC3_1_QOS_R1_BASE 0xE67A1100
#define DBSC3_1_QOS_R2_BASE 0xE67A1200
diff --git a/arch/arm/include/asm/arch-rmobile/r8a7793.h b/arch/arm/include/asm/arch-rmobile/r8a7793.h
index 778812e..505c812 100644
--- a/arch/arm/include/asm/arch-rmobile/r8a7793.h
+++ b/arch/arm/include/asm/arch-rmobile/r8a7793.h
@@ -18,6 +18,11 @@
/* SH-I2C */
#define CONFIG_SYS_I2C_SH_BASE2 0xE60B0000
+/* SDHI */
+#define CONFIG_SYS_SH_SDHI1_BASE 0xEE140000
+#define CONFIG_SYS_SH_SDHI2_BASE 0xEE160000
+#define CONFIG_SYS_SH_SDHI_NR_CHANNEL 3
+
#define DBSC3_1_QOS_R0_BASE 0xE67A1000
#define DBSC3_1_QOS_R1_BASE 0xE67A1100
#define DBSC3_1_QOS_R2_BASE 0xE67A1200
diff --git a/arch/arm/include/asm/arch-rmobile/r8a7794.h b/arch/arm/include/asm/arch-rmobile/r8a7794.h
index 66d5a29..e8f1d1d 100644
--- a/arch/arm/include/asm/arch-rmobile/r8a7794.h
+++ b/arch/arm/include/asm/arch-rmobile/r8a7794.h
@@ -14,4 +14,9 @@
/* SH-I2C */
#define CONFIG_SYS_I2C_SH_BASE2 0xE60B0000
+/* SDHI */
+#define CONFIG_SYS_SH_SDHI1_BASE 0xEE140000
+#define CONFIG_SYS_SH_SDHI2_BASE 0xEE160000
+#define CONFIG_SYS_SH_SDHI_NR_CHANNEL 3
+
#endif /* __ASM_ARCH_R8A7794_H */
diff --git a/arch/arm/include/asm/arch-rmobile/rcar-base.h b/arch/arm/include/asm/arch-rmobile/rcar-base.h
index dbbebcf..0bae173 100644
--- a/arch/arm/include/asm/arch-rmobile/rcar-base.h
+++ b/arch/arm/include/asm/arch-rmobile/rcar-base.h
@@ -43,6 +43,9 @@
#define CONFIG_SYS_RCAR_I2C2_BASE 0xE6530000
#define CONFIG_SYS_RCAR_I2C3_BASE 0xE6540000
+/* SDHI */
+#define CONFIG_SYS_SH_SDHI0_BASE 0xEE100000
+
#define S3C_BASE 0xE6784000
#define S3C_INT_BASE 0xE6784A00
#define S3C_MEDIA_BASE 0xE6784B00
diff --git a/arch/arm/include/asm/arch-rmobile/sh_sdhi.h b/arch/arm/include/asm/arch-rmobile/sh_sdhi.h
new file mode 100644
index 0000000..057bf3f
--- /dev/null
+++ b/arch/arm/include/asm/arch-rmobile/sh_sdhi.h
@@ -0,0 +1,168 @@
+/*
+ * drivers/mmc/sh-sdhi.h
+ *
+ * SD/MMC driver for Reneas rmobile ARM SoCs
+ *
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
+ * Copyright (C) 2008-2009 Renesas Solutions Corp.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SH_SDHI_H
+#define _SH_SDHI_H
+
+#define SDHI_CMD (0x0000 >> 1)
+#define SDHI_PORTSEL (0x0004 >> 1)
+#define SDHI_ARG0 (0x0008 >> 1)
+#define SDHI_ARG1 (0x000C >> 1)
+#define SDHI_STOP (0x0010 >> 1)
+#define SDHI_SECCNT (0x0014 >> 1)
+#define SDHI_RSP00 (0x0018 >> 1)
+#define SDHI_RSP01 (0x001C >> 1)
+#define SDHI_RSP02 (0x0020 >> 1)
+#define SDHI_RSP03 (0x0024 >> 1)
+#define SDHI_RSP04 (0x0028 >> 1)
+#define SDHI_RSP05 (0x002C >> 1)
+#define SDHI_RSP06 (0x0030 >> 1)
+#define SDHI_RSP07 (0x0034 >> 1)
+#define SDHI_INFO1 (0x0038 >> 1)
+#define SDHI_INFO2 (0x003C >> 1)
+#define SDHI_INFO1_MASK (0x0040 >> 1)
+#define SDHI_INFO2_MASK (0x0044 >> 1)
+#define SDHI_CLK_CTRL (0x0048 >> 1)
+#define SDHI_SIZE (0x004C >> 1)
+#define SDHI_OPTION (0x0050 >> 1)
+#define SDHI_ERR_STS1 (0x0058 >> 1)
+#define SDHI_ERR_STS2 (0x005C >> 1)
+#define SDHI_BUF0 (0x0060 >> 1)
+#define SDHI_SDIO_MODE (0x0068 >> 1)
+#define SDHI_SDIO_INFO1 (0x006C >> 1)
+#define SDHI_SDIO_INFO1_MASK (0x0070 >> 1)
+#define SDHI_CC_EXT_MODE (0x01B0 >> 1)
+#define SDHI_SOFT_RST (0x01C0 >> 1)
+#define SDHI_VERSION (0x01C4 >> 1)
+#define SDHI_HOST_MODE (0x01C8 >> 1)
+#define SDHI_SDIF_MODE (0x01CC >> 1)
+#define SDHI_EXT_SWAP (0x01E0 >> 1)
+#define SDHI_SD_DMACR (0x0324 >> 1)
+
+/* SDHI CMD VALUE */
+#define CMD_MASK 0x0000ffff
+#define SDHI_APP 0x0040
+#define SDHI_SD_APP_SEND_SCR 0x0073
+#define SDHI_SD_SWITCH 0x1C06
+
+/* SDHI_PORTSEL */
+#define USE_1PORT (1 << 8) /* 1 port */
+
+/* SDHI_ARG */
+#define ARG0_MASK 0x0000ffff
+#define ARG1_MASK 0x0000ffff
+
+/* SDHI_STOP */
+#define STOP_SEC_ENABLE (1 << 8)
+
+/* SDHI_INFO1 */
+#define INFO1_RESP_END (1 << 0)
+#define INFO1_ACCESS_END (1 << 2)
+#define INFO1_CARD_RE (1 << 3)
+#define INFO1_CARD_IN (1 << 4)
+#define INFO1_ISD0CD (1 << 5)
+#define INFO1_WRITE_PRO (1 << 7)
+#define INFO1_DATA3_CARD_RE (1 << 8)
+#define INFO1_DATA3_CARD_IN (1 << 9)
+#define INFO1_DATA3 (1 << 10)
+
+/* SDHI_INFO2 */
+#define INFO2_CMD_ERROR (1 << 0)
+#define INFO2_CRC_ERROR (1 << 1)
+#define INFO2_END_ERROR (1 << 2)
+#define INFO2_TIMEOUT (1 << 3)
+#define INFO2_BUF_ILL_WRITE (1 << 4)
+#define INFO2_BUF_ILL_READ (1 << 5)
+#define INFO2_RESP_TIMEOUT (1 << 6)
+#define INFO2_SDDAT0 (1 << 7)
+#define INFO2_BRE_ENABLE (1 << 8)
+#define INFO2_BWE_ENABLE (1 << 9)
+#define INFO2_CBUSY (1 << 14)
+#define INFO2_ILA (1 << 15)
+#define INFO2_ALL_ERR (0x807f)
+
+/* SDHI_INFO1_MASK */
+#define INFO1M_RESP_END (1 << 0)
+#define INFO1M_ACCESS_END (1 << 2)
+#define INFO1M_CARD_RE (1 << 3)
+#define INFO1M_CARD_IN (1 << 4)
+#define INFO1M_DATA3_CARD_RE (1 << 8)
+#define INFO1M_DATA3_CARD_IN (1 << 9)
+#define INFO1M_ALL (0xffff)
+#define INFO1M_SET (INFO1M_RESP_END | \
+ INFO1M_ACCESS_END | \
+ INFO1M_DATA3_CARD_RE | \
+ INFO1M_DATA3_CARD_IN)
+
+/* SDHI_INFO2_MASK */
+#define INFO2M_CMD_ERROR (1 << 0)
+#define INFO2M_CRC_ERROR (1 << 1)
+#define INFO2M_END_ERROR (1 << 2)
+#define INFO2M_TIMEOUT (1 << 3)
+#define INFO2M_BUF_ILL_WRITE (1 << 4)
+#define INFO2M_BUF_ILL_READ (1 << 5)
+#define INFO2M_RESP_TIMEOUT (1 << 6)
+#define INFO2M_BRE_ENABLE (1 << 8)
+#define INFO2M_BWE_ENABLE (1 << 9)
+#define INFO2M_ILA (1 << 15)
+#define INFO2M_ALL (0xffff)
+#define INFO2M_ALL_ERR (0x807f)
+
+/* SDHI_CLK_CTRL */
+#define CLK_ENABLE (1 << 8)
+
+/* SDHI_OPTION */
+#define OPT_BUS_WIDTH_1 (1 << 15) /* bus width = 1 bit */
+
+/* SDHI_ERR_STS1 */
+#define ERR_STS1_CRC_ERROR ((1 << 11) | (1 << 10) | (1 << 9) | \
+ (1 << 8) | (1 << 5))
+#define ERR_STS1_CMD_ERROR ((1 << 4) | (1 << 3) | (1 << 2) | \
+ (1 << 1) | (1 << 0))
+
+/* SDHI_ERR_STS2 */
+#define ERR_STS2_RES_TIMEOUT (1 << 0)
+#define ERR_STS2_RES_STOP_TIMEOUT ((1 << 0) | (1 << 1))
+#define ERR_STS2_SYS_ERROR ((1 << 6) | (1 << 5) | (1 << 4) | \
+ (1 << 3) | (1 << 2) | (1 << 1) | \
+ (1 << 0))
+
+/* SDHI_SDIO_MODE */
+#define SDIO_MODE_ON (1 << 0)
+#define SDIO_MODE_OFF (0 << 0)
+
+/* SDHI_SDIO_INFO1 */
+#define SDIO_INFO1_IOIRQ (1 << 0)
+#define SDIO_INFO1_EXPUB52 (1 << 14)
+#define SDIO_INFO1_EXWT (1 << 15)
+
+/* SDHI_SDIO_INFO1_MASK */
+#define SDIO_INFO1M_CLEAR ((1 << 1) | (1 << 2))
+#define SDIO_INFO1M_ON ((1 << 15) | (1 << 14) | (1 << 2) | \
+ (1 << 1) | (1 << 0))
+
+/* SDHI_EXT_SWAP */
+#define SET_SWAP ((1 << 6) | (1 << 7)) /* SWAP */
+
+/* SDHI_SOFT_RST */
+#define SOFT_RST_ON (0 << 0)
+#define SOFT_RST_OFF (1 << 0)
+
+#define CLKDEV_SD_DATA 25000000 /* 25 MHz */
+#define CLKDEV_HS_DATA 50000000 /* 50 MHz */
+#define CLKDEV_MMC_DATA 20000000 /* 20MHz */
+#define CLKDEV_INIT 400000 /* 100 - 400 KHz */
+
+/* For quirk */
+#define SH_SDHI_QUIRK_16BIT_BUF (1)
+int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks);
+
+#endif /* _SH_SDHI_H */
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index e69de29..7ba85a2 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -0,0 +1,9 @@
+menu "MMC Host controller Support"
+
+config SH_SDHI
+ bool "SuperH/Renesas ARM SoCs on-chip SDHI host controller support"
+ depends on RMOBILE
+ help
+ Support for the on-chip SDHI host controller on SuperH/Renesas ARM SoCs platform
+
+endmenu
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 461d7d8..4ba5878 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_S3C_SDI) += s3c_sdi.o
obj-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
obj-$(CONFIG_SDHCI) += sdhci.o
obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
+obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o
obj-$(CONFIG_SPEAR_SDHCI) += spear_sdhci.o
obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
diff --git a/drivers/mmc/sh_sdhi.c b/drivers/mmc/sh_sdhi.c
new file mode 100644
index 0000000..51b6d92
--- /dev/null
+++ b/drivers/mmc/sh_sdhi.c
@@ -0,0 +1,696 @@
+/*
+ * drivers/mmc/sh_sdhi.c
+ *
+ * SD/MMC driver for Renesas rmobile ARM SoCs.
+ *
+ * Copyright (C) 2011,2013-2014 Renesas Electronics Corporation
+ * Copyright (C) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj(a)renesas.com>
+ * Copyright (C) 2008-2009 Renesas Solutions Corp.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/arch/rmobile.h>
+#include <asm/arch/sh_sdhi.h>
+
+#define DRIVER_NAME "sh-sdhi"
+
+struct sh_sdhi_host {
+ unsigned long addr;
+ int ch;
+ int bus_shift;
+ unsigned long quirks;
+ unsigned char wait_int;
+ unsigned char sd_error;
+ unsigned char detect_waiting;
+};
+static inline void sh_sdhi_writew(struct sh_sdhi_host *host, int reg, u16 val)
+{
+ writew(val, host->addr + (reg << host->bus_shift));
+}
+
+static inline u16 sh_sdhi_readw(struct sh_sdhi_host *host, int reg)
+{
+ return readw(host->addr + (reg << host->bus_shift));
+}
+
+static void *mmc_priv(struct mmc *mmc)
+{
+ return (void *)mmc->priv;
+}
+
+static void sh_sdhi_detect(struct sh_sdhi_host *host)
+{
+ sh_sdhi_writew(host, SDHI_OPTION,
+ OPT_BUS_WIDTH_1 | sh_sdhi_readw(host, SDHI_OPTION));
+
+ host->detect_waiting = 0;
+}
+
+static int sh_sdhi_intr(void *dev_id)
+{
+ struct sh_sdhi_host *host = dev_id;
+ int state1 = 0, state2 = 0;
+
+ state1 = sh_sdhi_readw(host, SDHI_INFO1);
+ state2 = sh_sdhi_readw(host, SDHI_INFO2);
+
+ debug("%s: state1 = %x, state2 = %x\n", __func__, state1, state2);
+
+ /* CARD Insert */
+ if (state1 & INFO1_CARD_IN) {
+ sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_CARD_IN);
+ if (!host->detect_waiting) {
+ host->detect_waiting = 1;
+ sh_sdhi_detect(host);
+ }
+ sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END |
+ INFO1M_ACCESS_END | INFO1M_CARD_IN |
+ INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
+ return -EAGAIN;
+ }
+ /* CARD Removal */
+ if (state1 & INFO1_CARD_RE) {
+ sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_CARD_RE);
+ if (!host->detect_waiting) {
+ host->detect_waiting = 1;
+ sh_sdhi_detect(host);
+ }
+ sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END |
+ INFO1M_ACCESS_END | INFO1M_CARD_RE |
+ INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
+ sh_sdhi_writew(host, SDHI_SDIO_INFO1_MASK, SDIO_INFO1M_ON);
+ sh_sdhi_writew(host, SDHI_SDIO_MODE, SDIO_MODE_OFF);
+ return -EAGAIN;
+ }
+
+ if (state2 & INFO2_ALL_ERR) {
+ sh_sdhi_writew(host, SDHI_INFO2,
+ (unsigned short)~(INFO2_ALL_ERR));
+ sh_sdhi_writew(host, SDHI_INFO2_MASK,
+ INFO2M_ALL_ERR |
+ sh_sdhi_readw(host, SDHI_INFO2_MASK));
+ host->sd_error = 1;
+ host->wait_int = 1;
+ return 0;
+ }
+ /* Respons End */
+ if (state1 & INFO1_RESP_END) {
+ sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END);
+ sh_sdhi_writew(host, SDHI_INFO1_MASK,
+ INFO1M_RESP_END |
+ sh_sdhi_readw(host, SDHI_INFO1_MASK));
+ host->wait_int = 1;
+ return 0;
+ }
+ /* SD_BUF Read Enable */
+ if (state2 & INFO2_BRE_ENABLE) {
+ sh_sdhi_writew(host, SDHI_INFO2, ~INFO2_BRE_ENABLE);
+ sh_sdhi_writew(host, SDHI_INFO2_MASK,
+ INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ |
+ sh_sdhi_readw(host, SDHI_INFO2_MASK));
+ host->wait_int = 1;
+ return 0;
+ }
+ /* SD_BUF Write Enable */
+ if (state2 & INFO2_BWE_ENABLE) {
+ sh_sdhi_writew(host, SDHI_INFO2, ~INFO2_BWE_ENABLE);
+ sh_sdhi_writew(host, SDHI_INFO2_MASK,
+ INFO2_BWE_ENABLE | INFO2M_BUF_ILL_WRITE |
+ sh_sdhi_readw(host, SDHI_INFO2_MASK));
+ host->wait_int = 1;
+ return 0;
+ }
+ /* Access End */
+ if (state1 & INFO1_ACCESS_END) {
+ sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_ACCESS_END);
+ sh_sdhi_writew(host, SDHI_INFO1_MASK,
+ INFO1_ACCESS_END |
+ sh_sdhi_readw(host, SDHI_INFO1_MASK));
+ host->wait_int = 1;
+ return 0;
+ }
+ return -EAGAIN;
+}
+
+static int sh_sdhi_wait_interrupt_flag(struct sh_sdhi_host *host)
+{
+ int timeout = 10000000;
+
+ while (1) {
+ timeout--;
+ if (timeout < 0) {
+ debug(DRIVER_NAME": %s timeout\n", __func__);
+ return 0;
+ }
+
+ if (!sh_sdhi_intr(host))
+ break;
+
+ udelay(1); /* 1 usec */
+ }
+
+ return 1; /* Return value: NOT 0 = complete waiting */
+}
+
+static int sh_sdhi_clock_control(struct sh_sdhi_host *host, unsigned long clk)
+{
+ u32 clkdiv, i, timeout;
+
+ if (sh_sdhi_readw(host, SDHI_INFO2) & (1 << 14)) {
+ printf(DRIVER_NAME": Busy state ! Cannot change the clock\n");
+ return -EBUSY;
+ }
+
+ sh_sdhi_writew(host, SDHI_CLK_CTRL,
+ ~CLK_ENABLE & sh_sdhi_readw(host, SDHI_CLK_CTRL));
+
+ if (clk == 0)
+ return -EIO;
+
+ clkdiv = 0x80;
+ i = CONFIG_SH_SDHI_FREQ >> (0x8 + 1);
+ for (; clkdiv && clk >= (i << 1); (clkdiv >>= 1))
+ i <<= 1;
+
+ sh_sdhi_writew(host, SDHI_CLK_CTRL, clkdiv);
+
+ timeout = 100000;
+ /* Waiting for SD Bus busy to be cleared */
+ while (timeout--) {
+ if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000))
+ break;
+ }
+
+ if (timeout)
+ sh_sdhi_writew(host, SDHI_CLK_CTRL,
+ CLK_ENABLE | sh_sdhi_readw(host, SDHI_CLK_CTRL));
+ else
+ return -EBUSY;
+
+ return 0;
+}
+
+static int sh_sdhi_sync_reset(struct sh_sdhi_host *host)
+{
+ u32 timeout;
+ sh_sdhi_writew(host, SDHI_SOFT_RST, SOFT_RST_ON);
+ sh_sdhi_writew(host, SDHI_SOFT_RST, SOFT_RST_OFF);
+ sh_sdhi_writew(host, SDHI_CLK_CTRL,
+ CLK_ENABLE | sh_sdhi_readw(host, SDHI_CLK_CTRL));
+
+ timeout = 100000;
+ while (timeout--) {
+ if (!(sh_sdhi_readw(host, SDHI_INFO2) & INFO2_CBUSY))
+ break;
+ udelay(100);
+ }
+
+ if (!timeout)
+ return -EBUSY;
+
+ if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
+ sh_sdhi_writew(host, SDHI_HOST_MODE, 1);
+
+ return 0;
+}
+
+static int sh_sdhi_error_manage(struct sh_sdhi_host *host)
+{
+ unsigned short e_state1, e_state2;
+ int ret;
+
+ host->sd_error = 0;
+ host->wait_int = 0;
+
+ e_state1 = sh_sdhi_readw(host, SDHI_ERR_STS1);
+ e_state2 = sh_sdhi_readw(host, SDHI_ERR_STS2);
+ if (e_state2 & ERR_STS2_SYS_ERROR) {
+ if (e_state2 & ERR_STS2_RES_STOP_TIMEOUT)
+ ret = TIMEOUT;
+ else
+ ret = -EILSEQ;
+ debug("%s: ERR_STS2 = %04x\n",
+ DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS2));
+ sh_sdhi_sync_reset(host);
+
+ sh_sdhi_writew(host, SDHI_INFO1_MASK,
+ INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
+ return ret;
+ }
+ if (e_state1 & ERR_STS1_CRC_ERROR || e_state1 & ERR_STS1_CMD_ERROR)
+ ret = -EILSEQ;
+ else
+ ret = TIMEOUT;
+
+ debug("%s: ERR_STS1 = %04x\n",
+ DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS1));
+ sh_sdhi_sync_reset(host);
+ sh_sdhi_writew(host, SDHI_INFO1_MASK,
+ INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
+ return ret;
+}
+
+static int sh_sdhi_single_read(struct sh_sdhi_host *host, struct mmc_data *data)
+{
+ long time;
+ unsigned short blocksize, i;
+ unsigned short *p = (unsigned short *)data->dest;
+
+ if ((unsigned long)p & 0x00000001) {
+ debug(DRIVER_NAME": %s: The data pointer is unaligned.",
+ __func__);
+ return -EIO;
+ }
+
+ host->wait_int = 0;
+ sh_sdhi_writew(host, SDHI_INFO2_MASK,
+ ~(INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ) &
+ sh_sdhi_readw(host, SDHI_INFO2_MASK));
+ sh_sdhi_writew(host, SDHI_INFO1_MASK,
+ ~INFO1M_ACCESS_END &
+ sh_sdhi_readw(host, SDHI_INFO1_MASK));
+ time = sh_sdhi_wait_interrupt_flag(host);
+ if (time == 0 || host->sd_error != 0)
+ return sh_sdhi_error_manage(host);
+
+ host->wait_int = 0;
+ blocksize = sh_sdhi_readw(host, SDHI_SIZE);
+ for (i = 0; i < blocksize / 2; i++)
+ *p++ = sh_sdhi_readw(host, SDHI_BUF0);
+
+ time = sh_sdhi_wait_interrupt_flag(host);
+ if (time == 0 || host->sd_error != 0)
+ return sh_sdhi_error_manage(host);
+
+ host->wait_int = 0;
+ return 0;
+}
+
+static int sh_sdhi_multi_read(struct sh_sdhi_host *host, struct mmc_data *data)
+{
+ long time;
+ unsigned short blocksize, i, sec;
+ unsigned short *p = (unsigned short *)data->dest;
+
+ if ((unsigned long)p & 0x00000001) {
+ debug(DRIVER_NAME": %s: The data pointer is unaligned.",
+ __func__);
+ return -EIO;
+ }
+
+ debug("%s: blocks = %d, blocksize = %d\n",
+ __func__, data->blocks, data->blocksize);
+
+ host->wait_int = 0;
+ for (sec = 0; sec < data->blocks; sec++) {
+ sh_sdhi_writew(host, SDHI_INFO2_MASK,
+ ~(INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ) &
+ sh_sdhi_readw(host, SDHI_INFO2_MASK));
+
+ time = sh_sdhi_wait_interrupt_flag(host);
+ if (time == 0 || host->sd_error != 0)
+ return sh_sdhi_error_manage(host);
+
+ host->wait_int = 0;
+ blocksize = sh_sdhi_readw(host, SDHI_SIZE);
+ for (i = 0; i < blocksize / 2; i++)
+ *p++ = sh_sdhi_readw(host, SDHI_BUF0);
+ }
+
+ return 0;
+}
+
+static int sh_sdhi_single_write(struct sh_sdhi_host *host,
+ struct mmc_data *data)
+{
+ long time;
+ unsigned short blocksize, i;
+ const unsigned short *p = (const unsigned short *)data->src;
+
+ if ((unsigned long)p & 0x00000001) {
+ debug(DRIVER_NAME": %s: The data pointer is unaligned.",
+ __func__);
+ return -EIO;
+ }
+
+ debug("%s: blocks = %d, blocksize = %d\n",
+ __func__, data->blocks, data->blocksize);
+
+ host->wait_int = 0;
+ sh_sdhi_writew(host, SDHI_INFO2_MASK,
+ ~(INFO2M_BWE_ENABLE | INFO2M_BUF_ILL_WRITE) &
+ sh_sdhi_readw(host, SDHI_INFO2_MASK));
+ sh_sdhi_writew(host, SDHI_INFO1_MASK,
+ ~INFO1M_ACCESS_END &
+ sh_sdhi_readw(host, SDHI_INFO1_MASK));
+
+ time = sh_sdhi_wait_interrupt_flag(host);
+ if (time == 0 || host->sd_error != 0)
+ return sh_sdhi_error_manage(host);
+
+ host->wait_int = 0;
+ blocksize = sh_sdhi_readw(host, SDHI_SIZE);
+ for (i = 0; i < blocksize / 2; i++)
+ sh_sdhi_writew(host, SDHI_BUF0, *p++);
+
+ time = sh_sdhi_wait_interrupt_flag(host);
+ if (time == 0 || host->sd_error != 0)
+ return sh_sdhi_error_manage(host);
+
+ host->wait_int = 0;
+ return 0;
+}
+
+static int sh_sdhi_multi_write(struct sh_sdhi_host *host, struct mmc_data *data)
+{
+ long time;
+ unsigned short i, sec, blocksize;
+ const unsigned short *p = (const unsigned short *)data->src;
+
+ debug("%s: blocks = %d, blocksize = %d\n",
+ __func__, data->blocks, data->blocksize);
+
+ host->wait_int = 0;
+ for (sec = 0; sec < data->blocks; sec++) {
+ sh_sdhi_writew(host, SDHI_INFO2_MASK,
+ ~(INFO2M_BWE_ENABLE | INFO2M_BUF_ILL_WRITE) &
+ sh_sdhi_readw(host, SDHI_INFO2_MASK));
+
+ time = sh_sdhi_wait_interrupt_flag(host);
+ if (time == 0 || host->sd_error != 0)
+ return sh_sdhi_error_manage(host);
+
+ host->wait_int = 0;
+ blocksize = sh_sdhi_readw(host, SDHI_SIZE);
+ for (i = 0; i < blocksize / 2; i++)
+ sh_sdhi_writew(host, SDHI_BUF0, *p++);
+ }
+
+ return 0;
+}
+
+static void sh_sdhi_get_response(struct sh_sdhi_host *host, struct mmc_cmd *cmd)
+{
+ unsigned short i, j, cnt = 1;
+ unsigned short resp[8];
+ unsigned long *p1, *p2;
+
+ if (cmd->resp_type & MMC_RSP_136) {
+ cnt = 4;
+ resp[0] = sh_sdhi_readw(host, SDHI_RSP00);
+ resp[1] = sh_sdhi_readw(host, SDHI_RSP01);
+ resp[2] = sh_sdhi_readw(host, SDHI_RSP02);
+ resp[3] = sh_sdhi_readw(host, SDHI_RSP03);
+ resp[4] = sh_sdhi_readw(host, SDHI_RSP04);
+ resp[5] = sh_sdhi_readw(host, SDHI_RSP05);
+ resp[6] = sh_sdhi_readw(host, SDHI_RSP06);
+ resp[7] = sh_sdhi_readw(host, SDHI_RSP07);
+
+ /* SDHI REGISTER SPECIFICATION */
+ for (i = 7, j = 6; i > 0; i--) {
+ resp[i] = (resp[i] << 8) & 0xff00;
+ resp[i] |= (resp[j--] >> 8) & 0x00ff;
+ }
+ resp[0] = (resp[0] << 8) & 0xff00;
+
+ /* SDHI REGISTER SPECIFICATION */
+ p1 = ((unsigned long *)resp) + 3;
+
+ } else {
+ resp[0] = sh_sdhi_readw(host, SDHI_RSP00);
+ resp[1] = sh_sdhi_readw(host, SDHI_RSP01);
+
+ p1 = ((unsigned long *)resp);
+ }
+
+ p2 = (unsigned long *)cmd->response;
+#if defined(__BIG_ENDIAN_BITFIELD)
+ for (i = 0; i < cnt; i++) {
+ *p2++ = ((*p1 >> 16) & 0x0000ffff) |
+ ((*p1 << 16) & 0xffff0000);
+ p1--;
+ }
+#else
+ for (i = 0; i < cnt; i++)
+ *p2++ = *p1--;
+#endif /* __BIG_ENDIAN_BITFIELD */
+}
+
+static unsigned short sh_sdhi_set_cmd(struct sh_sdhi_host *host,
+ struct mmc_data *data, unsigned short opc)
+{
+ switch (opc) {
+ case SD_CMD_APP_SEND_OP_COND:
+ case SD_CMD_APP_SEND_SCR:
+ opc |= SDHI_APP;
+ break;
+ case SD_CMD_APP_SET_BUS_WIDTH:
+ /* SD_APP_SET_BUS_WIDTH*/
+ if (!data)
+ opc |= SDHI_APP;
+ else /* SD_SWITCH */
+ opc = SDHI_SD_SWITCH;
+ break;
+ default:
+ break;
+ }
+ return opc;
+}
+
+static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host *host,
+ struct mmc_data *data, unsigned short opc)
+{
+ unsigned short ret;
+
+ switch (opc) {
+ case MMC_CMD_READ_MULTIPLE_BLOCK:
+ ret = sh_sdhi_multi_read(host, data);
+ break;
+ case MMC_CMD_WRITE_MULTIPLE_BLOCK:
+ ret = sh_sdhi_multi_write(host, data);
+ break;
+ case MMC_CMD_WRITE_SINGLE_BLOCK:
+ ret = sh_sdhi_single_write(host, data);
+ break;
+ case MMC_CMD_READ_SINGLE_BLOCK:
+ case SDHI_SD_APP_SEND_SCR:
+ case SDHI_SD_SWITCH: /* SD_SWITCH */
+ ret = sh_sdhi_single_read(host, data);
+ break;
+ default:
+ printf(DRIVER_NAME": SD: NOT SUPPORT CMD = d'%04d\n", opc);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static int sh_sdhi_start_cmd(struct sh_sdhi_host *host,
+ struct mmc_data *data, struct mmc_cmd *cmd)
+{
+ long time;
+ unsigned short opc = cmd->cmdidx;
+ int ret = 0;
+ unsigned long timeout;
+
+ debug("opc = %d, arg = %x, resp_type = %x\n",
+ opc, cmd->cmdarg, cmd->resp_type);
+
+ if (opc == MMC_CMD_STOP_TRANSMISSION) {
+ /* SDHI sends the STOP command automatically by STOP reg */
+ sh_sdhi_writew(host, SDHI_INFO1_MASK, ~INFO1M_ACCESS_END &
+ sh_sdhi_readw(host, SDHI_INFO1_MASK));
+
+ time = sh_sdhi_wait_interrupt_flag(host);
+ if (time == 0 || host->sd_error != 0)
+ return sh_sdhi_error_manage(host);
+
+ sh_sdhi_get_response(host, cmd);
+ return 0;
+ }
+
+ if (data) {
+ if ((opc == MMC_CMD_READ_MULTIPLE_BLOCK) ||
+ opc == MMC_CMD_WRITE_MULTIPLE_BLOCK) {
+ sh_sdhi_writew(host, SDHI_STOP, STOP_SEC_ENABLE);
+ sh_sdhi_writew(host, SDHI_SECCNT, data->blocks);
+ }
+ sh_sdhi_writew(host, SDHI_SIZE, data->blocksize);
+ }
+ opc = sh_sdhi_set_cmd(host, data, opc);
+
+ /*
+ * U-boot cannot use interrupt.
+ * So this flag may not be clear by timing
+ */
+ sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END);
+
+ sh_sdhi_writew(host, SDHI_INFO1_MASK,
+ INFO1M_RESP_END | sh_sdhi_readw(host, SDHI_INFO1_MASK));
+ sh_sdhi_writew(host, SDHI_ARG0,
+ (unsigned short)(cmd->cmdarg & ARG0_MASK));
+ sh_sdhi_writew(host, SDHI_ARG1,
+ (unsigned short)((cmd->cmdarg >> 16) & ARG1_MASK));
+
+ timeout = 100000;
+ /* Waiting for SD Bus busy to be cleared */
+ while (timeout--) {
+ if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000))
+ break;
+ }
+
+ sh_sdhi_writew(host, SDHI_CMD, (unsigned short)(opc & CMD_MASK));
+
+ host->wait_int = 0;
+ sh_sdhi_writew(host, SDHI_INFO1_MASK,
+ ~INFO1M_RESP_END & sh_sdhi_readw(host, SDHI_INFO1_MASK));
+ sh_sdhi_writew(host, SDHI_INFO2_MASK,
+ ~(INFO2M_CMD_ERROR | INFO2M_CRC_ERROR |
+ INFO2M_END_ERROR | INFO2M_TIMEOUT |
+ INFO2M_RESP_TIMEOUT | INFO2M_ILA) &
+ sh_sdhi_readw(host, SDHI_INFO2_MASK));
+
+ time = sh_sdhi_wait_interrupt_flag(host);
+ if (!time)
+ return sh_sdhi_error_manage(host);
+
+ if (host->sd_error) {
+ switch (cmd->cmdidx) {
+ case MMC_CMD_ALL_SEND_CID:
+ case MMC_CMD_SELECT_CARD:
+ case SD_CMD_SEND_IF_COND:
+ case MMC_CMD_APP_CMD:
+ ret = TIMEOUT;
+ break;
+ default:
+ debug(DRIVER_NAME": Cmd(d'%d) err\n", opc);
+ debug(DRIVER_NAME": cmdidx = %d\n", cmd->cmdidx);
+ ret = sh_sdhi_error_manage(host);
+ break;
+ }
+ host->sd_error = 0;
+ host->wait_int = 0;
+ return ret;
+ }
+ if (sh_sdhi_readw(host, SDHI_INFO1) & INFO1_RESP_END)
+ return -EINVAL;
+
+ if (host->wait_int) {
+ sh_sdhi_get_response(host, cmd);
+ host->wait_int = 0;
+ }
+ if (data)
+ ret = sh_sdhi_data_trans(host, data, opc);
+
+ debug("ret = %d, resp = %08x, %08x, %08x, %08x\n",
+ ret, cmd->response[0], cmd->response[1],
+ cmd->response[2], cmd->response[3]);
+ return ret;
+}
+
+static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ struct sh_sdhi_host *host = mmc_priv(mmc);
+ int ret;
+
+ host->sd_error = 0;
+
+ ret = sh_sdhi_start_cmd(host, data, cmd);
+
+ return ret;
+}
+
+static void sh_sdhi_set_ios(struct mmc *mmc)
+{
+ int ret;
+ struct sh_sdhi_host *host = mmc_priv(mmc);
+
+ ret = sh_sdhi_clock_control(host, mmc->clock);
+ if (ret)
+ return;
+
+ if (mmc->bus_width == 4)
+ sh_sdhi_writew(host, SDHI_OPTION, ~OPT_BUS_WIDTH_1 &
+ sh_sdhi_readw(host, SDHI_OPTION));
+ else
+ sh_sdhi_writew(host, SDHI_OPTION, OPT_BUS_WIDTH_1 |
+ sh_sdhi_readw(host, SDHI_OPTION));
+
+ debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width);
+}
+
+static int sh_sdhi_initialize(struct mmc *mmc)
+{
+ struct sh_sdhi_host *host = mmc_priv(mmc);
+ int ret = sh_sdhi_sync_reset(host);
+
+ sh_sdhi_writew(host, SDHI_PORTSEL, USE_1PORT);
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+ sh_sdhi_writew(host, SDHI_EXT_SWAP, SET_SWAP);
+#endif
+
+ sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END |
+ INFO1M_ACCESS_END | INFO1M_CARD_RE |
+ INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
+
+ return ret;
+}
+
+static const struct mmc_ops sh_sdhi_ops = {
+ .send_cmd = sh_sdhi_send_cmd,
+ .set_ios = sh_sdhi_set_ios,
+ .init = sh_sdhi_initialize,
+};
+
+static struct mmc_config sh_sdhi_cfg = {
+ .name = DRIVER_NAME,
+ .ops = &sh_sdhi_ops,
+ .f_min = CLKDEV_INIT,
+ .f_max = CLKDEV_HS_DATA,
+ .voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .host_caps = MMC_MODE_4BIT | MMC_MODE_HS,
+ .part_type = PART_TYPE_DOS,
+ .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
+};
+
+int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks)
+{
+ int ret = 0;
+ struct mmc *mmc;
+ struct sh_sdhi_host *host = NULL;
+
+ if (ch >= CONFIG_SYS_SH_SDHI_NR_CHANNEL)
+ return -ENODEV;
+
+ host = malloc(sizeof(struct sh_sdhi_host));
+ if (!host)
+ return -ENOMEM;
+
+ mmc = mmc_create(&sh_sdhi_cfg, host);
+ if (!mmc) {
+ ret = -1;
+ goto error;
+ }
+
+ host->ch = ch;
+ host->addr = addr;
+ host->quirks = quirks;
+
+ if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
+ host->bus_shift = 1;
+
+ return ret;
+error:
+ if (host)
+ free(host);
+ return ret;
+}
+
--
2.1.3
2
1

05 Jan '15
Review delays and timeouts.
Get around 20 x faster access on Sheevaplug tests.
Changes in v2:
- increase number of loops
- remove initial delay
Changes in v1:
- review all loops, delays and timeouts
Signed-off-by: Gérald Kerma <drEagle(a)doukki.net>
---
drivers/mmc/mvebu_mmc.c | 66 +++++++++++++++++++++++++++++--------------------
1 file changed, 39 insertions(+), 27 deletions(-)
diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c
index 9f98c3f..b636be6 100644
--- a/drivers/mmc/mvebu_mmc.c
+++ b/drivers/mmc/mvebu_mmc.c
@@ -23,6 +23,10 @@ DECLARE_GLOBAL_DATA_PTR;
#define MVEBU_TARGET_DRAM 0
+#define TIMEOUT_LOOP 1000000000000000000 /* maximum loops */
+#define TIMEOUT_WAIT 100 /* wait 100 us */
+#define TIMEOUT_START 100 /* wait 100 us */
+
static void mvebu_mmc_write(u32 offs, u32 val)
{
writel(val, CONFIG_SYS_MMC_BASE + (offs));
@@ -63,7 +67,7 @@ static int mvebu_mmc_setup_data(struct mmc_data *data)
static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
- int timeout = 10;
+ u64 timeout = TIMEOUT_LOOP;
ushort waittype = 0;
ushort resptype = 0;
ushort xfertype = 0;
@@ -72,27 +76,32 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
debug("cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n",
cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
- udelay(10*1000);
-
debug("%s: cmd %d (hw state 0x%04x)\n", DRIVER_NAME,
cmd->cmdidx, mvebu_mmc_read(SDIO_HW_STATE));
+ /* Clear status */
+ mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
+ mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
+
/* Checking if card is busy */
while ((mvebu_mmc_read(SDIO_HW_STATE) & CARD_BUSY)) {
+ timeout--;
+ udelay(TIMEOUT_START);
if (timeout == 0) {
printf("%s: card busy!\n", DRIVER_NAME);
return -1;
}
- timeout--;
- udelay(1000);
}
/* Set up for a data transfer if we have one */
if (data) {
int err = mvebu_mmc_setup_data(data);
- if (err)
+ if (err){
+ debug("%s: command DATA error :%x\n",
+ DRIVER_NAME, err);
return err;
+ }
}
resptype = SDIO_CMD_INDEX(cmd->cmdidx);
@@ -148,7 +157,7 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
mvebu_mmc_write(SDIO_ERR_INTR_EN, SDIO_POLL_MASK);
/* Waiting for completion */
- timeout = 1000000;
+ timeout = TIMEOUT_LOOP;
while (!((mvebu_mmc_read(SDIO_NOR_INTR_STATUS)) & waittype)) {
if (mvebu_mmc_read(SDIO_NOR_INTR_STATUS) & SDIO_NOR_ERROR) {
@@ -156,21 +165,22 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
DRIVER_NAME, cmd->cmdidx,
mvebu_mmc_read(SDIO_ERR_INTR_STATUS));
if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
- (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT))
+ (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)){
+ debug("%s: command READ timed out\n",
+ DRIVER_NAME);
return TIMEOUT;
+ }
+ debug("%s: command READ error\n", DRIVER_NAME);
return COMM_ERR;
}
timeout--;
- udelay(1);
- if (timeout <= 0) {
- printf("%s: command timed out\n", DRIVER_NAME);
+ udelay(TIMEOUT_WAIT);
+ if (timeout == 0) {
+ debug("%s: command timed out\n", DRIVER_NAME);
return TIMEOUT;
}
}
- if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
- (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT))
- return TIMEOUT;
/* Handling response */
if (cmd->resp_type & MMC_RSP_136) {
@@ -213,6 +223,11 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
debug("[0x%x] ", cmd->response[3]);
debug("\n");
+ if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) & SDIO_ERR_CMD_TIMEOUT){
+ debug("%s: command STATUS timed out\n", DRIVER_NAME);
+ return TIMEOUT;
+ }
+
return 0;
}
@@ -236,33 +251,30 @@ static void mvebu_mmc_power_up(void)
/* enable interrupts status */
mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
+
+ udelay(10*1000);
}
static void mvebu_mmc_set_clk(unsigned int clock)
{
- unsigned int m;
-
if (clock == 0) {
debug("%s: clock off\n", DRIVER_NAME);
mvebu_mmc_write(SDIO_XFER_MODE, SDIO_XFER_MODE_STOP_CLK);
mvebu_mmc_write(SDIO_CLK_DIV, MVEBU_MMC_BASE_DIV_MAX);
} else {
- m = MVEBU_MMC_BASE_FAST_CLOCK/(2*clock) - 1;
+ u32 m = DIV_ROUND_UP(MVEBU_MMC_BASE_FAST_CLOCK,
+ (2 * clock)) - 1;
if (m > MVEBU_MMC_BASE_DIV_MAX)
m = MVEBU_MMC_BASE_DIV_MAX;
- mvebu_mmc_write(SDIO_CLK_DIV, m & MVEBU_MMC_BASE_DIV_MAX);
+ mvebu_mmc_write(SDIO_CLK_DIV, m);
+ debug("%s: clock (%d) div : %d\n", DRIVER_NAME, clock, m);
}
-
- udelay(10*1000);
}
static void mvebu_mmc_set_bus(unsigned int bus)
{
u32 ctrl_reg = 0;
- ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL);
- ctrl_reg &= ~SDIO_HOST_CTRL_DATA_WIDTH_4_BITS;
-
switch (bus) {
case 4:
ctrl_reg |= SDIO_HOST_CTRL_DATA_WIDTH_4_BITS;
@@ -277,7 +289,7 @@ static void mvebu_mmc_set_bus(unsigned int bus)
ctrl_reg &= ~SDIO_HOST_CTRL_LSB_FIRST;
/* default to maximum timeout */
- ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX);
+ ctrl_reg |= SDIO_HOST_CTRL_TMOUT_MAX;
ctrl_reg |= SDIO_HOST_CTRL_TMOUT_EN;
ctrl_reg |= SDIO_HOST_CTRL_PUSH_PULL_EN;
@@ -293,7 +305,6 @@ static void mvebu_mmc_set_bus(unsigned int bus)
"high-speed" : "");
mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg);
- udelay(10*1000);
}
static void mvebu_mmc_set_ios(struct mmc *mmc)
@@ -355,7 +366,7 @@ static void mvebu_window_setup(void)
static int mvebu_mmc_initialize(struct mmc *mmc)
{
- debug("%s: mvebu_mmc_initialize", DRIVER_NAME);
+ debug("%s: mvebu_mmc_initialize\n", DRIVER_NAME);
/*
* Setting host parameters
@@ -398,7 +409,8 @@ static const struct mmc_ops mvebu_mmc_ops = {
static struct mmc_config mvebu_mmc_cfg = {
.name = DRIVER_NAME,
.ops = &mvebu_mmc_ops,
- .f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX,
+ .f_min = DIV_ROUND_UP(MVEBU_MMC_BASE_FAST_CLOCK,
+ MVEBU_MMC_BASE_DIV_MAX),
.f_max = MVEBU_MMC_CLOCKRATE_MAX,
.voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
.host_caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HC |
--
2.1.3
4
19
As doc/README.generic-board says, the dead line has already expired
and we are supposed to remove all the non-generic boards by the
end of this year.
This series removes non-generic boards of mpc8xx, mpc8260, mpc824x
platform.
Masahiro Yamada (26):
mpc8xx: remove FPS{850,860}L, NSCU, SM850, TK885D, virtlab2 support
powerpc: manroland: remove uc100, uc101, mucmc52, hmi1001 support
mpc8xx: remove ELPT860 board support
mpc8xx: remove KUP4X, KUP4K board support
mpc8xx: remove SPD823TS board support
mpc8xx: remove RRvision board support
mpc8xx: remove R360MPI board support
mpc8xx: remove NETVIA board support
mpc8xx: remove lwmon board support
mpc8xx: remove IVMS8, IVML24 board support
mpc8xx: remove IP860 board support
mpc8xx: remove ESTEEM192E board support
powerpc: remove cogent_8xx, cogent_mpc8260 board support
mpc8260: remove sacsng board support
mpc8260: remove ppmc8260 board support
mpc8260: remove ep8260 board support
mpc8260: remove VoVPN-GW board support
mpc8260: remove MPC8266ADS board support
mpc8260: remove PM825, PM826, PM828 board support
mpc8260: remove muas3001 board support
mpc8260: remove IPHASE4539 board support
mpc8260: remove gw8260 board support
mpc8260: remove ep82xxm board support
mpc8260: remove CPU86, CPU87 board support
mpc8260: remove atc board support
powerpc: mpc824x: remove MPC824X cpu support
MAKEALL | 6 -
README | 5 -
arch/powerpc/Kconfig | 4 -
arch/powerpc/cpu/mpc5xxx/Kconfig | 12 -
arch/powerpc/cpu/mpc5xxx/ide.c | 8 -
arch/powerpc/cpu/mpc824x/Kconfig | 48 -
arch/powerpc/cpu/mpc824x/Makefile | 11 -
arch/powerpc/cpu/mpc824x/config.mk | 8 -
arch/powerpc/cpu/mpc824x/cpu.c | 262 -----
arch/powerpc/cpu/mpc824x/cpu_init.c | 311 ------
arch/powerpc/cpu/mpc824x/drivers/epic.h | 1 -
arch/powerpc/cpu/mpc824x/drivers/epic/README | 102 --
arch/powerpc/cpu/mpc824x/drivers/epic/epic.h | 163 ----
arch/powerpc/cpu/mpc824x/drivers/epic/epic1.c | 517 ----------
arch/powerpc/cpu/mpc824x/drivers/epic/epic2.S | 196 ----
arch/powerpc/cpu/mpc824x/drivers/epic/epicutil.S | 57 --
arch/powerpc/cpu/mpc824x/drivers/errors.h | 212 ----
arch/powerpc/cpu/mpc824x/drivers/i2c/i2c.c | 254 -----
arch/powerpc/cpu/mpc824x/interrupts.c | 77 --
arch/powerpc/cpu/mpc824x/pci.c | 75 --
arch/powerpc/cpu/mpc824x/speed.c | 102 --
arch/powerpc/cpu/mpc824x/start.S | 724 --------------
arch/powerpc/cpu/mpc824x/traps.c | 194 ----
arch/powerpc/cpu/mpc824x/u-boot.lds | 76 --
arch/powerpc/cpu/mpc8260/Kconfig | 60 --
arch/powerpc/cpu/mpc8260/cpu_init.c | 4 -
arch/powerpc/cpu/mpc8260/pci.c | 64 --
arch/powerpc/cpu/mpc8260/start.S | 61 --
arch/powerpc/cpu/mpc8xx/Kconfig | 73 --
arch/powerpc/cpu/mpc8xx/cpu.c | 57 +-
arch/powerpc/cpu/mpc8xx/cpu_init.c | 15 -
arch/powerpc/cpu/mpc8xx/i2c.c | 7 -
arch/powerpc/cpu/mpc8xx/scc.c | 24 -
arch/powerpc/cpu/mpc8xx/serial.c | 23 +-
arch/powerpc/cpu/mpc8xx/video.c | 148 ---
arch/powerpc/include/asm/global_data.h | 2 +-
arch/powerpc/include/asm/processor.h | 2 -
board/LEOX/elpt860/Kconfig | 12 -
board/LEOX/elpt860/MAINTAINERS | 6 -
board/LEOX/elpt860/Makefile | 21 -
board/LEOX/elpt860/README.LEOX | 423 --------
board/LEOX/elpt860/elpt860.c | 336 -------
board/LEOX/elpt860/flash.c | 602 ------------
board/LEOX/elpt860/u-boot.lds | 103 --
board/LEOX/elpt860/u-boot.lds.debug | 126 ---
board/RRvision/Kconfig | 9 -
board/RRvision/MAINTAINERS | 7 -
board/RRvision/Makefile | 8 -
board/RRvision/RRvision.c | 222 -----
board/RRvision/flash.c | 506 ----------
board/RRvision/u-boot.lds | 87 --
board/RRvision/video_ad7179.h | 52 -
board/a3000/Kconfig | 9 -
board/a3000/MAINTAINERS | 6 -
board/a3000/Makefile | 8 -
board/a3000/README | 17 -
board/a3000/a3000.c | 101 --
board/a3000/flash.c | 438 ---------
board/atc/Kconfig | 9 -
board/atc/MAINTAINERS | 6 -
board/atc/Makefile | 8 -
board/atc/atc.c | 382 --------
board/atc/flash.c | 647 -------------
board/atc/ti113x.c | 620 ------------
board/cogent/Kconfig | 19 -
board/cogent/MAINTAINERS | 8 -
board/cogent/Makefile | 8 -
board/cogent/README | 118 ---
board/cogent/README.cma286 | 69 --
board/cogent/dipsw.c | 50 -
board/cogent/dipsw.h | 3 -
board/cogent/flash.c | 633 ------------
board/cogent/flash.h | 305 ------
board/cogent/kbm.c | 3 -
board/cogent/lcd.c | 245 -----
board/cogent/lcd.h | 84 --
board/cogent/mb.c | 280 ------
board/cogent/mb.h | 513 ----------
board/cogent/par.c | 3 -
board/cogent/par.h | 3 -
board/cogent/pci.c | 3 -
board/cogent/pci.h | 3 -
board/cogent/rtc.c | 3 -
board/cogent/rtc.h | 3 -
board/cogent/serial.c | 189 ----
board/cogent/serial.h | 15 -
board/cogent/u-boot.lds | 86 --
board/cogent/u-boot.lds.debug | 121 ---
board/cpc45/Kconfig | 9 -
board/cpc45/MAINTAINERS | 7 -
board/cpc45/Makefile | 8 -
board/cpc45/cpc45.c | 250 -----
board/cpc45/flash.c | 506 ----------
board/cpc45/ide.c | 128 ---
board/cpc45/pd67290.c | 797 ---------------
board/cpc45/plx9030.c | 156 ---
board/cpu86/Kconfig | 9 -
board/cpu86/MAINTAINERS | 7 -
board/cpu86/Makefile | 8 -
board/cpu86/cpu86.c | 304 ------
board/cpu86/cpu86.h | 27 -
board/cpu86/flash.c | 599 ------------
board/cpu87/Kconfig | 9 -
board/cpu87/MAINTAINERS | 7 -
board/cpu87/Makefile | 8 -
board/cpu87/cpu87.c | 330 -------
board/cpu87/cpu87.h | 27 -
board/cpu87/flash.c | 608 ------------
board/cu824/Kconfig | 9 -
board/cu824/MAINTAINERS | 6 -
board/cu824/Makefile | 8 -
board/cu824/README | 453 ---------
board/cu824/cu824.c | 83 --
board/cu824/flash.c | 470 ---------
board/eXalion/Kconfig | 9 -
board/eXalion/MAINTAINERS | 6 -
board/eXalion/Makefile | 8 -
board/eXalion/eXalion.c | 283 ------
board/eXalion/eXalion.h | 36 -
board/eXalion/piix_pci.h | 156 ---
board/ep8260/Kconfig | 9 -
board/ep8260/MAINTAINERS | 6 -
board/ep8260/Makefile | 8 -
board/ep8260/ep8260.c | 304 ------
board/ep8260/ep8260.h | 24 -
board/ep8260/flash.c | 395 --------
board/ep8260/mii_phy.c | 107 ---
board/ep82xxm/Kconfig | 9 -
board/ep82xxm/MAINTAINERS | 6 -
board/ep82xxm/Makefile | 8 -
board/ep82xxm/ep82xxm.c | 274 ------
board/esteem192e/Kconfig | 9 -
board/esteem192e/MAINTAINERS | 6 -
board/esteem192e/Makefile | 8 -
board/esteem192e/esteem192e.c | 225 -----
board/esteem192e/flash.c | 1119 ----------------------
board/esteem192e/u-boot.lds | 90 --
board/freescale/mpc8266ads/Kconfig | 12 -
board/freescale/mpc8266ads/MAINTAINERS | 6 -
board/freescale/mpc8266ads/Makefile | 8 -
board/freescale/mpc8266ads/flash.c | 493 ----------
board/freescale/mpc8266ads/mpc8266ads.c | 582 -----------
board/funkwerk/vovpn-gw/Kconfig | 12 -
board/funkwerk/vovpn-gw/MAINTAINERS | 6 -
board/funkwerk/vovpn-gw/Makefile | 8 -
board/funkwerk/vovpn-gw/flash.c | 436 ---------
board/funkwerk/vovpn-gw/m88e6060.c | 249 -----
board/funkwerk/vovpn-gw/m88e6060.h | 75 --
board/funkwerk/vovpn-gw/vovpn-gw.c | 363 -------
board/gw8260/Kconfig | 9 -
board/gw8260/MAINTAINERS | 6 -
board/gw8260/Makefile | 8 -
board/gw8260/flash.c | 502 ----------
board/gw8260/gw8260.c | 639 ------------
board/ip860/Kconfig | 9 -
board/ip860/MAINTAINERS | 6 -
board/ip860/Makefile | 8 -
board/ip860/flash.c | 440 ---------
board/ip860/ip860.c | 340 -------
board/ip860/u-boot.lds.debug | 122 ---
board/iphase4539/Kconfig | 9 -
board/iphase4539/MAINTAINERS | 6 -
board/iphase4539/Makefile | 10 -
board/iphase4539/README | 358 -------
board/iphase4539/flash.c | 474 ---------
board/iphase4539/iphase4539.c | 408 --------
board/ivm/Kconfig | 19 -
board/ivm/MAINTAINERS | 12 -
board/ivm/Makefile | 8 -
board/ivm/flash.c | 582 -----------
board/ivm/ivm.c | 382 --------
board/ivm/u-boot.lds.debug | 122 ---
board/kup/common/flash.c | 499 ----------
board/kup/common/kup.c | 68 --
board/kup/common/kup.h | 40 -
board/kup/common/load_sernum_ethaddr.c | 78 --
board/kup/common/pcmcia.c | 221 -----
board/kup/kup4k/Kconfig | 12 -
board/kup/kup4k/MAINTAINERS | 6 -
board/kup/kup4k/Makefile | 8 -
board/kup/kup4k/kup4k.c | 289 ------
board/kup/kup4k/u-boot.lds.debug | 121 ---
board/kup/kup4x/Kconfig | 12 -
board/kup/kup4x/MAINTAINERS | 6 -
board/kup/kup4x/Makefile | 8 -
board/kup/kup4x/kup4x.c | 185 ----
board/kup/kup4x/u-boot.lds | 82 --
board/kup/kup4x/u-boot.lds.debug | 121 ---
board/lwmon/Kconfig | 9 -
board/lwmon/MAINTAINERS | 6 -
board/lwmon/Makefile | 8 -
board/lwmon/README.keybd | 126 ---
board/lwmon/flash.c | 632 ------------
board/lwmon/lwmon.c | 1071 ---------------------
board/lwmon/pcmcia.c | 234 -----
board/lwmon/u-boot.lds.debug | 122 ---
board/manroland/hmi1001/Kconfig | 12 -
board/manroland/hmi1001/MAINTAINERS | 6 -
board/manroland/hmi1001/Makefile | 8 -
board/manroland/hmi1001/hmi1001.c | 301 ------
board/manroland/mucmc52/Kconfig | 12 -
board/manroland/mucmc52/MAINTAINERS | 6 -
board/manroland/mucmc52/Makefile | 11 -
board/manroland/mucmc52/mucmc52.c | 394 --------
board/manroland/uc100/Kconfig | 12 -
board/manroland/uc100/MAINTAINERS | 6 -
board/manroland/uc100/Makefile | 8 -
board/manroland/uc100/pcmcia.c | 192 ----
board/manroland/uc100/uc100.c | 254 -----
board/manroland/uc101/Kconfig | 12 -
board/manroland/uc101/MAINTAINERS | 6 -
board/manroland/uc101/Makefile | 8 -
board/manroland/uc101/uc101.c | 367 -------
board/muas3001/Kconfig | 9 -
board/muas3001/MAINTAINERS | 7 -
board/muas3001/Makefile | 8 -
board/muas3001/muas3001.c | 335 -------
board/musenki/Kconfig | 9 -
board/musenki/MAINTAINERS | 6 -
board/musenki/Makefile | 8 -
board/musenki/README | 298 ------
board/musenki/flash.c | 496 ----------
board/musenki/musenki.c | 94 --
board/mvblue/Kconfig | 9 -
board/mvblue/MAINTAINERS | 6 -
board/mvblue/Makefile | 8 -
board/mvblue/flash.c | 570 -----------
board/mvblue/mvblue.c | 253 -----
board/mvblue/u-boot.lds | 86 --
board/netvia/Kconfig | 9 -
board/netvia/MAINTAINERS | 7 -
board/netvia/Makefile | 8 -
board/netvia/flash.c | 495 ----------
board/netvia/netvia.c | 401 --------
board/netvia/u-boot.lds.debug | 121 ---
board/pm826/Kconfig | 9 -
board/pm826/MAINTAINERS | 13 -
board/pm826/Makefile | 8 -
board/pm826/flash.c | 370 -------
board/pm826/pm826.c | 319 ------
board/pm828/Kconfig | 9 -
board/pm828/MAINTAINERS | 9 -
board/pm828/Makefile | 8 -
board/pm828/flash.c | 370 -------
board/pm828/pm828.c | 352 -------
board/ppmc8260/Kconfig | 9 -
board/ppmc8260/MAINTAINERS | 6 -
board/ppmc8260/Makefile | 8 -
board/ppmc8260/ppmc8260.c | 291 ------
board/r360mpi/Kconfig | 9 -
board/r360mpi/MAINTAINERS | 6 -
board/r360mpi/Makefile | 8 -
board/r360mpi/flash.c | 468 ---------
board/r360mpi/pcmcia.c | 232 -----
board/r360mpi/r360mpi.c | 403 --------
board/r360mpi/u-boot.lds | 89 --
board/sacsng/Kconfig | 9 -
board/sacsng/MAINTAINERS | 6 -
board/sacsng/Makefile | 8 -
board/sacsng/clkinit.c | 1009 -------------------
board/sacsng/clkinit.h | 103 --
board/sacsng/flash.c | 507 ----------
board/sacsng/ioconfig.h | 217 -----
board/sacsng/sacsng.c | 848 ----------------
board/sandpoint/Kconfig | 19 -
board/sandpoint/MAINTAINERS | 12 -
board/sandpoint/Makefile | 8 -
board/sandpoint/README | 411 --------
board/sandpoint/dinkdl | 2 -
board/sandpoint/flash.c | 748 ---------------
board/sandpoint/sandpoint.c | 91 --
board/sandpoint/u-boot.lds | 84 --
board/spd8xx/Kconfig | 9 -
board/spd8xx/MAINTAINERS | 6 -
board/spd8xx/Makefile | 8 -
board/spd8xx/flash.c | 41 -
board/spd8xx/spd8xx.c | 278 ------
board/spd8xx/u-boot.lds | 91 --
board/spd8xx/u-boot.lds.debug | 122 ---
board/tqc/tqm8xx/Kconfig | 78 --
board/tqc/tqm8xx/MAINTAINERS | 16 -
board/tqc/tqm8xx/tqm8xx.c | 58 +-
board/utx8245/Kconfig | 9 -
board/utx8245/MAINTAINERS | 6 -
board/utx8245/Makefile | 13 -
board/utx8245/flash.c | 544 -----------
board/utx8245/utx8245.c | 119 ---
common/cmd_pcmcia.c | 3 -
common/flash.c | 6 -
configs/A3000_defconfig | 3 -
configs/CPC45_ROMBOOT_defconfig | 4 -
configs/CPC45_defconfig | 3 -
configs/CPU86_ROMBOOT_defconfig | 4 -
configs/CPU86_defconfig | 3 -
configs/CPU87_ROMBOOT_defconfig | 4 -
configs/CPU87_defconfig | 3 -
configs/CU824_defconfig | 3 -
configs/ELPT860_defconfig | 3 -
configs/ESTEEM192E_defconfig | 3 -
configs/FPS850L_defconfig | 3 -
configs/FPS860L_defconfig | 3 -
configs/IP860_defconfig | 3 -
configs/IPHASE4539_defconfig | 3 -
configs/IVML24_128_defconfig | 4 -
configs/IVML24_256_defconfig | 4 -
configs/IVML24_defconfig | 4 -
configs/IVMS8_128_defconfig | 4 -
configs/IVMS8_256_defconfig | 4 -
configs/IVMS8_defconfig | 4 -
configs/KUP4K_defconfig | 3 -
configs/KUP4X_defconfig | 3 -
configs/MPC8266ADS_defconfig | 3 -
configs/MUSENKI_defconfig | 3 -
configs/MVBLUE_defconfig | 3 -
configs/NETVIA_V2_defconfig | 4 -
configs/NETVIA_defconfig | 4 -
configs/NSCU_defconfig | 3 -
configs/PM825_BIGFLASH_defconfig | 4 -
configs/PM825_ROMBOOT_BIGFLASH_defconfig | 4 -
configs/PM825_ROMBOOT_defconfig | 4 -
configs/PM825_defconfig | 4 -
configs/PM826_BIGFLASH_defconfig | 4 -
configs/PM826_ROMBOOT_BIGFLASH_defconfig | 4 -
configs/PM826_ROMBOOT_defconfig | 4 -
configs/PM826_defconfig | 4 -
configs/PM828_PCI_defconfig | 4 -
configs/PM828_ROMBOOT_PCI_defconfig | 4 -
configs/PM828_ROMBOOT_defconfig | 4 -
configs/PM828_defconfig | 3 -
configs/R360MPI_defconfig | 3 -
configs/RRvision_LCD_defconfig | 4 -
configs/RRvision_defconfig | 3 -
configs/SM850_defconfig | 3 -
configs/SPD823TS_defconfig | 3 -
configs/Sandpoint8240_defconfig | 3 -
configs/Sandpoint8245_defconfig | 3 -
configs/TK885D_defconfig | 3 -
configs/VoVPN-GW_66MHz_defconfig | 4 -
configs/atc_defconfig | 3 -
configs/cogent_mpc8260_defconfig | 3 -
configs/cogent_mpc8xx_defconfig | 3 -
configs/eXalion_defconfig | 3 -
configs/ep8260_defconfig | 3 -
configs/ep82xxm_defconfig | 3 -
configs/gw8260_defconfig | 3 -
configs/hmi1001_defconfig | 3 -
configs/lwmon_defconfig | 3 -
configs/muas3001_defconfig | 3 -
configs/muas3001_dev_defconfig | 4 -
configs/mucmc52_defconfig | 3 -
configs/ppmc8260_defconfig | 3 -
configs/sacsng_defconfig | 3 -
configs/uc100_defconfig | 3 -
configs/uc101_defconfig | 3 -
configs/utx8245_defconfig | 3 -
configs/virtlab2_defconfig | 3 -
doc/README.scrapyard | 50 +-
drivers/net/mpc5xxx_fec.c | 5 -
drivers/pcmcia/Makefile | 1 -
drivers/pcmcia/i82365.c | 989 -------------------
drivers/pcmcia/mpc8xx_pcmcia.c | 6 -
drivers/pcmcia/tqm8xx_pcmcia.c | 51 +-
drivers/rtc/Makefile | 1 -
drivers/rtc/ds12887.c | 217 -----
drivers/video/mpc8xx_lcd.c | 53 -
drivers/video/smiLynxEM.c | 3 -
examples/standalone/test_burst.c | 19 -
include/common.h | 4 -
include/commproc.h | 293 +-----
include/configs/A3000.h | 293 ------
include/configs/CPC45.h | 489 ----------
include/configs/CPU86.h | 629 ------------
include/configs/CPU87.h | 676 -------------
include/configs/CU824.h | 286 ------
include/configs/ELPT860.h | 374 --------
include/configs/ESTEEM192E.h | 292 ------
include/configs/FPS850L.h | 413 --------
include/configs/FPS860L.h | 415 --------
include/configs/IP860.h | 438 ---------
include/configs/IPHASE4539.h | 328 -------
include/configs/IVML24.h | 458 ---------
include/configs/IVMS8.h | 441 ---------
include/configs/KUP4K.h | 488 ----------
include/configs/KUP4X.h | 440 ---------
include/configs/MPC8266ADS.h | 563 -----------
include/configs/MUSENKI.h | 275 ------
include/configs/MVBLUE.h | 325 -------
include/configs/NETVIA.h | 435 ---------
include/configs/NSCU.h | 463 ---------
include/configs/PM826.h | 534 -----------
include/configs/PM828.h | 528 ----------
include/configs/R360MPI.h | 464 ---------
include/configs/RRvision.h | 450 ---------
include/configs/SM850.h | 351 -------
include/configs/SPD823TS.h | 402 --------
include/configs/Sandpoint8240.h | 398 --------
include/configs/Sandpoint8245.h | 376 --------
include/configs/TK885D.h | 490 ----------
include/configs/VoVPN-GW.h | 399 --------
include/configs/atc.h | 489 ----------
include/configs/cogent_common.h | 192 ----
include/configs/cogent_mpc8260.h | 392 --------
include/configs/cogent_mpc8xx.h | 349 -------
include/configs/eXalion.h | 433 ---------
include/configs/ep8260.h | 744 --------------
include/configs/ep82xxm.h | 383 --------
include/configs/gw8260.h | 800 ----------------
include/configs/hmi1001.h | 339 -------
include/configs/lwmon.h | 587 ------------
include/configs/muas3001.h | 391 --------
include/configs/mucmc52.h | 126 ---
include/configs/ppmc8260.h | 986 -------------------
include/configs/sacsng.h | 1038 --------------------
include/configs/uc100.h | 482 ----------
include/configs/uc101.h | 103 --
include/configs/utx8245.h | 408 --------
include/configs/virtlab2.h | 469 ---------
include/mpc824x.h | 523 ----------
include/pci.h | 4 -
include/pcmcia.h | 12 -
include/pcmcia/cirrus.h | 180 ----
include/pcmcia/i82365.h | 154 ---
include/pcmcia/ss.h | 133 ---
include/pcmcia/ti113x.h | 234 -----
include/ppc_asm.tmpl | 4 +-
include/status_led.h | 97 --
include/video_ad7176.h | 89 --
include/video_ad7177.h | 133 ---
include/video_ad7179.h | 20 -
post/drivers/memory.c | 2 +-
430 files changed, 59 insertions(+), 68545 deletions(-)
delete mode 100644 arch/powerpc/cpu/mpc824x/Kconfig
delete mode 100644 arch/powerpc/cpu/mpc824x/Makefile
delete mode 100644 arch/powerpc/cpu/mpc824x/config.mk
delete mode 100644 arch/powerpc/cpu/mpc824x/cpu.c
delete mode 100644 arch/powerpc/cpu/mpc824x/cpu_init.c
delete mode 100644 arch/powerpc/cpu/mpc824x/drivers/epic.h
delete mode 100644 arch/powerpc/cpu/mpc824x/drivers/epic/README
delete mode 100644 arch/powerpc/cpu/mpc824x/drivers/epic/epic.h
delete mode 100644 arch/powerpc/cpu/mpc824x/drivers/epic/epic1.c
delete mode 100644 arch/powerpc/cpu/mpc824x/drivers/epic/epic2.S
delete mode 100644 arch/powerpc/cpu/mpc824x/drivers/epic/epicutil.S
delete mode 100644 arch/powerpc/cpu/mpc824x/drivers/errors.h
delete mode 100644 arch/powerpc/cpu/mpc824x/drivers/i2c/i2c.c
delete mode 100644 arch/powerpc/cpu/mpc824x/interrupts.c
delete mode 100644 arch/powerpc/cpu/mpc824x/pci.c
delete mode 100644 arch/powerpc/cpu/mpc824x/speed.c
delete mode 100644 arch/powerpc/cpu/mpc824x/start.S
delete mode 100644 arch/powerpc/cpu/mpc824x/traps.c
delete mode 100644 arch/powerpc/cpu/mpc824x/u-boot.lds
delete mode 100644 board/LEOX/elpt860/Kconfig
delete mode 100644 board/LEOX/elpt860/MAINTAINERS
delete mode 100644 board/LEOX/elpt860/Makefile
delete mode 100644 board/LEOX/elpt860/README.LEOX
delete mode 100644 board/LEOX/elpt860/elpt860.c
delete mode 100644 board/LEOX/elpt860/flash.c
delete mode 100644 board/LEOX/elpt860/u-boot.lds
delete mode 100644 board/LEOX/elpt860/u-boot.lds.debug
delete mode 100644 board/RRvision/Kconfig
delete mode 100644 board/RRvision/MAINTAINERS
delete mode 100644 board/RRvision/Makefile
delete mode 100644 board/RRvision/RRvision.c
delete mode 100644 board/RRvision/flash.c
delete mode 100644 board/RRvision/u-boot.lds
delete mode 100644 board/RRvision/video_ad7179.h
delete mode 100644 board/a3000/Kconfig
delete mode 100644 board/a3000/MAINTAINERS
delete mode 100644 board/a3000/Makefile
delete mode 100644 board/a3000/README
delete mode 100644 board/a3000/a3000.c
delete mode 100644 board/a3000/flash.c
delete mode 100644 board/atc/Kconfig
delete mode 100644 board/atc/MAINTAINERS
delete mode 100644 board/atc/Makefile
delete mode 100644 board/atc/atc.c
delete mode 100644 board/atc/flash.c
delete mode 100644 board/atc/ti113x.c
delete mode 100644 board/cogent/Kconfig
delete mode 100644 board/cogent/MAINTAINERS
delete mode 100644 board/cogent/Makefile
delete mode 100644 board/cogent/README
delete mode 100644 board/cogent/README.cma286
delete mode 100644 board/cogent/dipsw.c
delete mode 100644 board/cogent/dipsw.h
delete mode 100644 board/cogent/flash.c
delete mode 100644 board/cogent/flash.h
delete mode 100644 board/cogent/kbm.c
delete mode 100644 board/cogent/lcd.c
delete mode 100644 board/cogent/lcd.h
delete mode 100644 board/cogent/mb.c
delete mode 100644 board/cogent/mb.h
delete mode 100644 board/cogent/par.c
delete mode 100644 board/cogent/par.h
delete mode 100644 board/cogent/pci.c
delete mode 100644 board/cogent/pci.h
delete mode 100644 board/cogent/rtc.c
delete mode 100644 board/cogent/rtc.h
delete mode 100644 board/cogent/serial.c
delete mode 100644 board/cogent/serial.h
delete mode 100644 board/cogent/u-boot.lds
delete mode 100644 board/cogent/u-boot.lds.debug
delete mode 100644 board/cpc45/Kconfig
delete mode 100644 board/cpc45/MAINTAINERS
delete mode 100644 board/cpc45/Makefile
delete mode 100644 board/cpc45/cpc45.c
delete mode 100644 board/cpc45/flash.c
delete mode 100644 board/cpc45/ide.c
delete mode 100644 board/cpc45/pd67290.c
delete mode 100644 board/cpc45/plx9030.c
delete mode 100644 board/cpu86/Kconfig
delete mode 100644 board/cpu86/MAINTAINERS
delete mode 100644 board/cpu86/Makefile
delete mode 100644 board/cpu86/cpu86.c
delete mode 100644 board/cpu86/cpu86.h
delete mode 100644 board/cpu86/flash.c
delete mode 100644 board/cpu87/Kconfig
delete mode 100644 board/cpu87/MAINTAINERS
delete mode 100644 board/cpu87/Makefile
delete mode 100644 board/cpu87/cpu87.c
delete mode 100644 board/cpu87/cpu87.h
delete mode 100644 board/cpu87/flash.c
delete mode 100644 board/cu824/Kconfig
delete mode 100644 board/cu824/MAINTAINERS
delete mode 100644 board/cu824/Makefile
delete mode 100644 board/cu824/README
delete mode 100644 board/cu824/cu824.c
delete mode 100644 board/cu824/flash.c
delete mode 100644 board/eXalion/Kconfig
delete mode 100644 board/eXalion/MAINTAINERS
delete mode 100644 board/eXalion/Makefile
delete mode 100644 board/eXalion/eXalion.c
delete mode 100644 board/eXalion/eXalion.h
delete mode 100644 board/eXalion/piix_pci.h
delete mode 100644 board/ep8260/Kconfig
delete mode 100644 board/ep8260/MAINTAINERS
delete mode 100644 board/ep8260/Makefile
delete mode 100644 board/ep8260/ep8260.c
delete mode 100644 board/ep8260/ep8260.h
delete mode 100644 board/ep8260/flash.c
delete mode 100644 board/ep8260/mii_phy.c
delete mode 100644 board/ep82xxm/Kconfig
delete mode 100644 board/ep82xxm/MAINTAINERS
delete mode 100644 board/ep82xxm/Makefile
delete mode 100644 board/ep82xxm/ep82xxm.c
delete mode 100644 board/esteem192e/Kconfig
delete mode 100644 board/esteem192e/MAINTAINERS
delete mode 100644 board/esteem192e/Makefile
delete mode 100644 board/esteem192e/esteem192e.c
delete mode 100644 board/esteem192e/flash.c
delete mode 100644 board/esteem192e/u-boot.lds
delete mode 100644 board/freescale/mpc8266ads/Kconfig
delete mode 100644 board/freescale/mpc8266ads/MAINTAINERS
delete mode 100644 board/freescale/mpc8266ads/Makefile
delete mode 100644 board/freescale/mpc8266ads/flash.c
delete mode 100644 board/freescale/mpc8266ads/mpc8266ads.c
delete mode 100644 board/funkwerk/vovpn-gw/Kconfig
delete mode 100644 board/funkwerk/vovpn-gw/MAINTAINERS
delete mode 100644 board/funkwerk/vovpn-gw/Makefile
delete mode 100644 board/funkwerk/vovpn-gw/flash.c
delete mode 100644 board/funkwerk/vovpn-gw/m88e6060.c
delete mode 100644 board/funkwerk/vovpn-gw/m88e6060.h
delete mode 100644 board/funkwerk/vovpn-gw/vovpn-gw.c
delete mode 100644 board/gw8260/Kconfig
delete mode 100644 board/gw8260/MAINTAINERS
delete mode 100644 board/gw8260/Makefile
delete mode 100644 board/gw8260/flash.c
delete mode 100644 board/gw8260/gw8260.c
delete mode 100644 board/ip860/Kconfig
delete mode 100644 board/ip860/MAINTAINERS
delete mode 100644 board/ip860/Makefile
delete mode 100644 board/ip860/flash.c
delete mode 100644 board/ip860/ip860.c
delete mode 100644 board/ip860/u-boot.lds.debug
delete mode 100644 board/iphase4539/Kconfig
delete mode 100644 board/iphase4539/MAINTAINERS
delete mode 100644 board/iphase4539/Makefile
delete mode 100644 board/iphase4539/README
delete mode 100644 board/iphase4539/flash.c
delete mode 100644 board/iphase4539/iphase4539.c
delete mode 100644 board/ivm/Kconfig
delete mode 100644 board/ivm/MAINTAINERS
delete mode 100644 board/ivm/Makefile
delete mode 100644 board/ivm/flash.c
delete mode 100644 board/ivm/ivm.c
delete mode 100644 board/ivm/u-boot.lds.debug
delete mode 100644 board/kup/common/flash.c
delete mode 100644 board/kup/common/kup.c
delete mode 100644 board/kup/common/kup.h
delete mode 100644 board/kup/common/load_sernum_ethaddr.c
delete mode 100644 board/kup/common/pcmcia.c
delete mode 100644 board/kup/kup4k/Kconfig
delete mode 100644 board/kup/kup4k/MAINTAINERS
delete mode 100644 board/kup/kup4k/Makefile
delete mode 100644 board/kup/kup4k/kup4k.c
delete mode 100644 board/kup/kup4k/u-boot.lds.debug
delete mode 100644 board/kup/kup4x/Kconfig
delete mode 100644 board/kup/kup4x/MAINTAINERS
delete mode 100644 board/kup/kup4x/Makefile
delete mode 100644 board/kup/kup4x/kup4x.c
delete mode 100644 board/kup/kup4x/u-boot.lds
delete mode 100644 board/kup/kup4x/u-boot.lds.debug
delete mode 100644 board/lwmon/Kconfig
delete mode 100644 board/lwmon/MAINTAINERS
delete mode 100644 board/lwmon/Makefile
delete mode 100644 board/lwmon/README.keybd
delete mode 100644 board/lwmon/flash.c
delete mode 100644 board/lwmon/lwmon.c
delete mode 100644 board/lwmon/pcmcia.c
delete mode 100644 board/lwmon/u-boot.lds.debug
delete mode 100644 board/manroland/hmi1001/Kconfig
delete mode 100644 board/manroland/hmi1001/MAINTAINERS
delete mode 100644 board/manroland/hmi1001/Makefile
delete mode 100644 board/manroland/hmi1001/hmi1001.c
delete mode 100644 board/manroland/mucmc52/Kconfig
delete mode 100644 board/manroland/mucmc52/MAINTAINERS
delete mode 100644 board/manroland/mucmc52/Makefile
delete mode 100644 board/manroland/mucmc52/mucmc52.c
delete mode 100644 board/manroland/uc100/Kconfig
delete mode 100644 board/manroland/uc100/MAINTAINERS
delete mode 100644 board/manroland/uc100/Makefile
delete mode 100644 board/manroland/uc100/pcmcia.c
delete mode 100644 board/manroland/uc100/uc100.c
delete mode 100644 board/manroland/uc101/Kconfig
delete mode 100644 board/manroland/uc101/MAINTAINERS
delete mode 100644 board/manroland/uc101/Makefile
delete mode 100644 board/manroland/uc101/uc101.c
delete mode 100644 board/muas3001/Kconfig
delete mode 100644 board/muas3001/MAINTAINERS
delete mode 100644 board/muas3001/Makefile
delete mode 100644 board/muas3001/muas3001.c
delete mode 100644 board/musenki/Kconfig
delete mode 100644 board/musenki/MAINTAINERS
delete mode 100644 board/musenki/Makefile
delete mode 100644 board/musenki/README
delete mode 100644 board/musenki/flash.c
delete mode 100644 board/musenki/musenki.c
delete mode 100644 board/mvblue/Kconfig
delete mode 100644 board/mvblue/MAINTAINERS
delete mode 100644 board/mvblue/Makefile
delete mode 100644 board/mvblue/flash.c
delete mode 100644 board/mvblue/mvblue.c
delete mode 100644 board/mvblue/u-boot.lds
delete mode 100644 board/netvia/Kconfig
delete mode 100644 board/netvia/MAINTAINERS
delete mode 100644 board/netvia/Makefile
delete mode 100644 board/netvia/flash.c
delete mode 100644 board/netvia/netvia.c
delete mode 100644 board/netvia/u-boot.lds.debug
delete mode 100644 board/pm826/Kconfig
delete mode 100644 board/pm826/MAINTAINERS
delete mode 100644 board/pm826/Makefile
delete mode 100644 board/pm826/flash.c
delete mode 100644 board/pm826/pm826.c
delete mode 100644 board/pm828/Kconfig
delete mode 100644 board/pm828/MAINTAINERS
delete mode 100644 board/pm828/Makefile
delete mode 100644 board/pm828/flash.c
delete mode 100644 board/pm828/pm828.c
delete mode 100644 board/ppmc8260/Kconfig
delete mode 100644 board/ppmc8260/MAINTAINERS
delete mode 100644 board/ppmc8260/Makefile
delete mode 100644 board/ppmc8260/ppmc8260.c
delete mode 100644 board/r360mpi/Kconfig
delete mode 100644 board/r360mpi/MAINTAINERS
delete mode 100644 board/r360mpi/Makefile
delete mode 100644 board/r360mpi/flash.c
delete mode 100644 board/r360mpi/pcmcia.c
delete mode 100644 board/r360mpi/r360mpi.c
delete mode 100644 board/r360mpi/u-boot.lds
delete mode 100644 board/sacsng/Kconfig
delete mode 100644 board/sacsng/MAINTAINERS
delete mode 100644 board/sacsng/Makefile
delete mode 100644 board/sacsng/clkinit.c
delete mode 100644 board/sacsng/clkinit.h
delete mode 100644 board/sacsng/flash.c
delete mode 100644 board/sacsng/ioconfig.h
delete mode 100644 board/sacsng/sacsng.c
delete mode 100644 board/sandpoint/Kconfig
delete mode 100644 board/sandpoint/MAINTAINERS
delete mode 100644 board/sandpoint/Makefile
delete mode 100644 board/sandpoint/README
delete mode 100644 board/sandpoint/dinkdl
delete mode 100644 board/sandpoint/flash.c
delete mode 100644 board/sandpoint/sandpoint.c
delete mode 100644 board/sandpoint/u-boot.lds
delete mode 100644 board/spd8xx/Kconfig
delete mode 100644 board/spd8xx/MAINTAINERS
delete mode 100644 board/spd8xx/Makefile
delete mode 100644 board/spd8xx/flash.c
delete mode 100644 board/spd8xx/spd8xx.c
delete mode 100644 board/spd8xx/u-boot.lds
delete mode 100644 board/spd8xx/u-boot.lds.debug
delete mode 100644 board/utx8245/Kconfig
delete mode 100644 board/utx8245/MAINTAINERS
delete mode 100644 board/utx8245/Makefile
delete mode 100644 board/utx8245/flash.c
delete mode 100644 board/utx8245/utx8245.c
delete mode 100644 configs/A3000_defconfig
delete mode 100644 configs/CPC45_ROMBOOT_defconfig
delete mode 100644 configs/CPC45_defconfig
delete mode 100644 configs/CPU86_ROMBOOT_defconfig
delete mode 100644 configs/CPU86_defconfig
delete mode 100644 configs/CPU87_ROMBOOT_defconfig
delete mode 100644 configs/CPU87_defconfig
delete mode 100644 configs/CU824_defconfig
delete mode 100644 configs/ELPT860_defconfig
delete mode 100644 configs/ESTEEM192E_defconfig
delete mode 100644 configs/FPS850L_defconfig
delete mode 100644 configs/FPS860L_defconfig
delete mode 100644 configs/IP860_defconfig
delete mode 100644 configs/IPHASE4539_defconfig
delete mode 100644 configs/IVML24_128_defconfig
delete mode 100644 configs/IVML24_256_defconfig
delete mode 100644 configs/IVML24_defconfig
delete mode 100644 configs/IVMS8_128_defconfig
delete mode 100644 configs/IVMS8_256_defconfig
delete mode 100644 configs/IVMS8_defconfig
delete mode 100644 configs/KUP4K_defconfig
delete mode 100644 configs/KUP4X_defconfig
delete mode 100644 configs/MPC8266ADS_defconfig
delete mode 100644 configs/MUSENKI_defconfig
delete mode 100644 configs/MVBLUE_defconfig
delete mode 100644 configs/NETVIA_V2_defconfig
delete mode 100644 configs/NETVIA_defconfig
delete mode 100644 configs/NSCU_defconfig
delete mode 100644 configs/PM825_BIGFLASH_defconfig
delete mode 100644 configs/PM825_ROMBOOT_BIGFLASH_defconfig
delete mode 100644 configs/PM825_ROMBOOT_defconfig
delete mode 100644 configs/PM825_defconfig
delete mode 100644 configs/PM826_BIGFLASH_defconfig
delete mode 100644 configs/PM826_ROMBOOT_BIGFLASH_defconfig
delete mode 100644 configs/PM826_ROMBOOT_defconfig
delete mode 100644 configs/PM826_defconfig
delete mode 100644 configs/PM828_PCI_defconfig
delete mode 100644 configs/PM828_ROMBOOT_PCI_defconfig
delete mode 100644 configs/PM828_ROMBOOT_defconfig
delete mode 100644 configs/PM828_defconfig
delete mode 100644 configs/R360MPI_defconfig
delete mode 100644 configs/RRvision_LCD_defconfig
delete mode 100644 configs/RRvision_defconfig
delete mode 100644 configs/SM850_defconfig
delete mode 100644 configs/SPD823TS_defconfig
delete mode 100644 configs/Sandpoint8240_defconfig
delete mode 100644 configs/Sandpoint8245_defconfig
delete mode 100644 configs/TK885D_defconfig
delete mode 100644 configs/VoVPN-GW_66MHz_defconfig
delete mode 100644 configs/atc_defconfig
delete mode 100644 configs/cogent_mpc8260_defconfig
delete mode 100644 configs/cogent_mpc8xx_defconfig
delete mode 100644 configs/eXalion_defconfig
delete mode 100644 configs/ep8260_defconfig
delete mode 100644 configs/ep82xxm_defconfig
delete mode 100644 configs/gw8260_defconfig
delete mode 100644 configs/hmi1001_defconfig
delete mode 100644 configs/lwmon_defconfig
delete mode 100644 configs/muas3001_defconfig
delete mode 100644 configs/muas3001_dev_defconfig
delete mode 100644 configs/mucmc52_defconfig
delete mode 100644 configs/ppmc8260_defconfig
delete mode 100644 configs/sacsng_defconfig
delete mode 100644 configs/uc100_defconfig
delete mode 100644 configs/uc101_defconfig
delete mode 100644 configs/utx8245_defconfig
delete mode 100644 configs/virtlab2_defconfig
delete mode 100644 drivers/pcmcia/i82365.c
delete mode 100644 drivers/rtc/ds12887.c
delete mode 100644 include/configs/A3000.h
delete mode 100644 include/configs/CPC45.h
delete mode 100644 include/configs/CPU86.h
delete mode 100644 include/configs/CPU87.h
delete mode 100644 include/configs/CU824.h
delete mode 100644 include/configs/ELPT860.h
delete mode 100644 include/configs/ESTEEM192E.h
delete mode 100644 include/configs/FPS850L.h
delete mode 100644 include/configs/FPS860L.h
delete mode 100644 include/configs/IP860.h
delete mode 100644 include/configs/IPHASE4539.h
delete mode 100644 include/configs/IVML24.h
delete mode 100644 include/configs/IVMS8.h
delete mode 100644 include/configs/KUP4K.h
delete mode 100644 include/configs/KUP4X.h
delete mode 100644 include/configs/MPC8266ADS.h
delete mode 100644 include/configs/MUSENKI.h
delete mode 100644 include/configs/MVBLUE.h
delete mode 100644 include/configs/NETVIA.h
delete mode 100644 include/configs/NSCU.h
delete mode 100644 include/configs/PM826.h
delete mode 100644 include/configs/PM828.h
delete mode 100644 include/configs/R360MPI.h
delete mode 100644 include/configs/RRvision.h
delete mode 100644 include/configs/SM850.h
delete mode 100644 include/configs/SPD823TS.h
delete mode 100644 include/configs/Sandpoint8240.h
delete mode 100644 include/configs/Sandpoint8245.h
delete mode 100644 include/configs/TK885D.h
delete mode 100644 include/configs/VoVPN-GW.h
delete mode 100644 include/configs/atc.h
delete mode 100644 include/configs/cogent_common.h
delete mode 100644 include/configs/cogent_mpc8260.h
delete mode 100644 include/configs/cogent_mpc8xx.h
delete mode 100644 include/configs/eXalion.h
delete mode 100644 include/configs/ep8260.h
delete mode 100644 include/configs/ep82xxm.h
delete mode 100644 include/configs/gw8260.h
delete mode 100644 include/configs/hmi1001.h
delete mode 100644 include/configs/lwmon.h
delete mode 100644 include/configs/muas3001.h
delete mode 100644 include/configs/mucmc52.h
delete mode 100644 include/configs/ppmc8260.h
delete mode 100644 include/configs/sacsng.h
delete mode 100644 include/configs/uc100.h
delete mode 100644 include/configs/uc101.h
delete mode 100644 include/configs/utx8245.h
delete mode 100644 include/configs/virtlab2.h
delete mode 100644 include/mpc824x.h
delete mode 100644 include/pcmcia/cirrus.h
delete mode 100644 include/pcmcia/i82365.h
delete mode 100644 include/pcmcia/ss.h
delete mode 100644 include/pcmcia/ti113x.h
delete mode 100644 include/video_ad7176.h
delete mode 100644 include/video_ad7177.h
delete mode 100644 include/video_ad7179.h
--
1.9.1
4
54
One of the four items left to fix up for bare ivybridge support in U-Boot
is MTRRs. These are an important part of the x86 platform since they provide
a means to control the cache behaviour for areas of memory.
Memory areas can be marked as uncacheable or cacheable. For cacheable the
write behaviour can be controlled:
- write-back: data is not written back from the cache until evicted
- write-though: data goes into the cache but is also written to memory
- write-protect: data cannot be written to this area
- write-combining: multiple writes to this area can be combined
This series adds support for deciding the MTRR setup that should be used,
commiting it to registers before relocation, updating it for the video frame
buffer, disabling CAR (cache-as-RAM) when needed and making sure that the
faster possible execution speed is provided. In addition an 'mtrr' command
is added to permit inspection and adjustment of MTRR registers from the
command line.
Simon Glass (22):
x86: Correct XIP_ROM_SIZE
x86: Drop RAMTOP Kconfig
x86: Correct ifdtool microcode calculation
x86: video: Add support for CONFIG_CONSOLE_SCROLL_LINES
x86: config: Always scroll the display by 5 lines, for speed
x86: video: Add a debug() to display the frame buffer address
x86: pci: Don't return a vesa mode when there is not video
x86: video: Add debug option to time the BIOS copy
x86: ivybridge: Only run the Video BIOS when video is enabled
x86: Use cache, don't clear the display in video BIOS
x86: Tidy up VESA mode numbers
x86: pci: Display vesa modes in hex
x86: ivybridge: Drop support for ROM caching
x86: Add support for MTRRs
x86: ivybridge: Set up an MTRR for the video frame buffer
x86: board_f: Adjust x86 boot order for performance
x86: ivybridge: Request MTRRs for DRAM regions
x86: Commit the current MTRRs before relocation
x86: ivybridge: Add a way to turn off the CAR
x86: Disable CAR before relocation on platforms that need it
x86: ivybridge: Update microcode early in boot
x86: Add an 'mtrr' command to list and adjust MTRRs
arch/x86/Kconfig | 6 +-
arch/x86/cpu/Makefile | 1 +
arch/x86/cpu/coreboot/coreboot.c | 22 ++---
arch/x86/cpu/ivybridge/car.S | 78 +++++++++++++--
arch/x86/cpu/ivybridge/cpu.c | 27 +----
arch/x86/cpu/ivybridge/gma.c | 25 ++++-
arch/x86/cpu/ivybridge/microcode_intel.c | 9 +-
arch/x86/cpu/ivybridge/sdram.c | 10 ++
arch/x86/cpu/mtrr.c | 81 +++++++++++++++
arch/x86/cpu/start.S | 10 ++
arch/x86/dts/link.dts | 3 -
arch/x86/include/asm/global_data.h | 15 +++
arch/x86/include/asm/mtrr.h | 163 ++++++++++++++-----------------
arch/x86/lib/bios.c | 14 +--
arch/x86/lib/init_helpers.c | 8 ++
common/Makefile | 1 +
common/board_f.c | 8 +-
common/cmd_mtrr.c | 138 ++++++++++++++++++++++++++
doc/README.x86 | 18 +++-
drivers/pci/pci_rom.c | 9 +-
drivers/video/cfb_console.c | 26 +++--
drivers/video/x86_fb.c | 1 +
include/configs/x86-common.h | 1 +
tools/ifdtool.c | 4 +-
24 files changed, 509 insertions(+), 169 deletions(-)
create mode 100644 arch/x86/cpu/mtrr.c
create mode 100644 common/cmd_mtrr.c
--
2.2.0.rc0.207.ga3a616c
4
45
From: Oliver Schinagl <oliver(a)schinagl.nl>
The A31 uses the AXP221 pmic for various voltages.
Signed-off-by: Oliver Schinagl <oliver(a)schinagl.nl>
Signed-off-by: Hans de Goede <hdegoede(a)redhat.com>
--
Changes in v2:
-Rebase
Changes in v3:
-Add support for all dldo and aldo-s
-Add Kconfig option to select building AXP221 and to select voltage of
dldo and aldo-s
Changes in v4:
-Add axp221_setbits helper function
-Use symbolic names for enabled bits in CTRL1 - CTRL3 registers
---
board/sunxi/board.c | 26 +++++++
drivers/power/Kconfig | 47 +++++++++++++
drivers/power/Makefile | 1 +
drivers/power/axp221.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++
include/axp221.h | 50 +++++++++++++
5 files changed, 310 insertions(+)
create mode 100644 drivers/power/axp221.c
create mode 100644 include/axp221.h
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 03890c8..e6ec5b8 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -19,6 +19,9 @@
#ifdef CONFIG_AXP209_POWER
#include <axp209.h>
#endif
+#ifdef CONFIG_AXP221_POWER
+#include <axp221.h>
+#endif
#include <asm/arch/clock.h>
#include <asm/arch/cpu.h>
#include <asm/arch/dram.h>
@@ -169,6 +172,29 @@ void sunxi_board_init(void)
power_failed |= axp209_set_ldo3(2800);
power_failed |= axp209_set_ldo4(2800);
#endif
+#ifdef CONFIG_AXP221_POWER
+ power_failed = axp221_init();
+ power_failed |= axp221_set_dcdc1(3000);
+ power_failed |= axp221_set_dcdc2(1200);
+ power_failed |= axp221_set_dcdc3(1200);
+ power_failed |= axp221_set_dcdc4(1200);
+ power_failed |= axp221_set_dcdc5(1500);
+#if CONFIG_AXP221_DLDO1_VOLT != -1
+ power_failed |= axp221_set_dldo1(CONFIG_AXP221_DLDO1_VOLT);
+#endif
+#if CONFIG_AXP221_DLDO4_VOLT != -1
+ power_failed |= axp221_set_dldo4(CONFIG_AXP221_DLDO4_VOLT);
+#endif
+#if CONFIG_AXP221_ALDO1_VOLT != -1
+ power_failed |= axp221_set_aldo1(CONFIG_AXP221_ALDO1_VOLT);
+#endif
+#if CONFIG_AXP221_ALDO2_VOLT != -1
+ power_failed |= axp221_set_aldo2(CONFIG_AXP221_ALDO2_VOLT);
+#endif
+#if CONFIG_AXP221_ALDO3_VOLT != -1
+ power_failed |= axp221_set_aldo3(CONFIG_AXP221_ALDO3_VOLT);
+#endif
+#endif
printf("DRAM:");
ramsize = sunxi_dram_init();
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index e69de29..1ec7c0e 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -0,0 +1,47 @@
+config AXP221_POWER
+ boolean "axp221 pmic support"
+ depends on MACH_SUN6I
+ default y
+ ---help---
+ Say y here to enable support for the axp221 pmic found on most sun6i
+ (A31) boards.
+
+config AXP221_DLDO1_VOLT
+ int "axp221 dldo1 voltage"
+ depends on AXP221_POWER
+ default -1
+ ---help---
+ Set the voltage (mV) to program the axp221 dldo1 at, set to -1 to
+ disable dldo1.
+
+config AXP221_DLDO4_VOLT
+ int "axp221 dldo4 voltage"
+ depends on AXP221_POWER
+ default -1
+ ---help---
+ Set the voltage (mV) to program the axp221 dldo4 at, set to -1 to
+ disable dldo4.
+
+config AXP221_ALDO1_VOLT
+ int "axp221 aldo1 voltage"
+ depends on AXP221_POWER
+ default -1
+ ---help---
+ Set the voltage (mV) to program the axp221 aldo1 at, set to -1 to
+ disable aldo1.
+
+config AXP221_ALDO2_VOLT
+ int "axp221 aldo2 voltage"
+ depends on AXP221_POWER
+ default -1
+ ---help---
+ Set the voltage (mV) to program the axp221 aldo2 at, set to -1 to
+ disable aldo2.
+
+config AXP221_ALDO3_VOLT
+ int "axp221 aldo3 voltage"
+ depends on AXP221_POWER
+ default -1
+ ---help---
+ Set the voltage (mV) to program the axp221 aldo3 at, set to -1 to
+ disable aldo3.
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index dc64e4d..04bd996 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -7,6 +7,7 @@
obj-$(CONFIG_AXP152_POWER) += axp152.o
obj-$(CONFIG_AXP209_POWER) += axp209.o
+obj-$(CONFIG_AXP221_POWER) += axp221.o
obj-$(CONFIG_EXYNOS_TMU) += exynos-tmu.o
obj-$(CONFIG_FTPMU010_POWER) += ftpmu010.o
obj-$(CONFIG_TPS6586X_POWER) += tps6586x.o
diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c
new file mode 100644
index 0000000..941193a
--- /dev/null
+++ b/drivers/power/axp221.c
@@ -0,0 +1,186 @@
+/*
+ * (C) Copyright 2013 Oliver Schinagl <oliver(a)schinagl.nl>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/arch/p2wi.h>
+#include <axp221.h>
+
+static u8 axp221_mvolt_to_cfg(int mvolt, int min, int max, int div)
+{
+ if (mvolt < min)
+ mvolt = min;
+ else if (mvolt > max)
+ mvolt = max;
+
+ return (mvolt - min) / div;
+}
+
+static int axp221_setbits(u8 reg, u8 bits)
+{
+ int ret;
+ u8 val;
+
+ ret = p2wi_read(reg, &val);
+ if (ret)
+ return ret;
+
+ val |= bits;
+ return p2wi_write(reg, val);
+}
+
+int axp221_set_dcdc1(unsigned int mvolt)
+{
+ int ret;
+ u8 cfg = axp221_mvolt_to_cfg(mvolt, 1600, 3400, 100);
+
+ ret = p2wi_write(AXP221_DCDC1_CTRL, cfg);
+ if (ret)
+ return ret;
+
+ return axp221_setbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DCDC1_EN);
+}
+
+int axp221_set_dcdc2(unsigned int mvolt)
+{
+ u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20);
+
+ return p2wi_write(AXP221_DCDC2_CTRL, cfg);
+}
+
+int axp221_set_dcdc3(unsigned int mvolt)
+{
+ u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1860, 20);
+
+ return p2wi_write(AXP221_DCDC3_CTRL, cfg);
+}
+
+int axp221_set_dcdc4(unsigned int mvolt)
+{
+ u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20);
+
+ return p2wi_write(AXP221_DCDC4_CTRL, cfg);
+}
+
+int axp221_set_dcdc5(unsigned int mvolt)
+{
+ u8 cfg = axp221_mvolt_to_cfg(mvolt, 1000, 2550, 50);
+
+ return p2wi_write(AXP221_DCDC5_CTRL, cfg);
+}
+
+int axp221_set_dldo1(unsigned int mvolt)
+{
+ int ret;
+ u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
+
+ ret = p2wi_write(AXP221_DLDO1_CTRL, cfg);
+ if (ret)
+ return ret;
+
+ return axp221_setbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DLDO1_EN);
+}
+
+int axp221_set_dldo2(unsigned int mvolt)
+{
+ int ret;
+ u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
+
+ ret = p2wi_write(AXP221_DLDO2_CTRL, cfg);
+ if (ret)
+ return ret;
+
+ return axp221_setbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DLDO2_EN);
+}
+
+int axp221_set_dldo3(unsigned int mvolt)
+{
+ int ret;
+ u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
+
+ ret = p2wi_write(AXP221_DLDO3_CTRL, cfg);
+ if (ret)
+ return ret;
+
+ return axp221_setbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DLDO3_EN);
+}
+
+int axp221_set_dldo4(unsigned int mvolt)
+{
+ int ret;
+ u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
+
+ ret = p2wi_write(AXP221_DLDO4_CTRL, cfg);
+ if (ret)
+ return ret;
+
+ return axp221_setbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DLDO4_EN);
+}
+
+int axp221_set_aldo1(unsigned int mvolt)
+{
+ int ret;
+ u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
+
+ ret = p2wi_write(AXP221_ALDO1_CTRL, cfg);
+ if (ret)
+ return ret;
+
+ return axp221_setbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_ALDO1_EN);
+}
+
+int axp221_set_aldo2(unsigned int mvolt)
+{
+ int ret;
+ u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
+
+ ret = p2wi_write(AXP221_ALDO2_CTRL, cfg);
+ if (ret)
+ return ret;
+
+ return axp221_setbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_ALDO2_EN);
+}
+
+int axp221_set_aldo3(unsigned int mvolt)
+{
+ int ret;
+ u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
+
+ ret = p2wi_write(AXP221_ALDO3_CTRL, cfg);
+ if (ret)
+ return ret;
+
+ return axp221_setbits(AXP221_OUTPUT_CTRL3,
+ AXP221_OUTPUT_CTRL3_ALDO3_EN);
+}
+
+int axp221_init(void)
+{
+ u8 axp_chip_id;
+ int ret;
+
+ p2wi_init();
+ ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR,
+ AXP221_INIT_DATA);
+ if (ret)
+ return ret;
+
+ ret = p2wi_read(AXP221_CHIP_ID, &axp_chip_id);
+ if (ret)
+ return ret;
+
+ if (!(axp_chip_id == 0x6 || axp_chip_id == 0x7 || axp_chip_id == 0x17))
+ return -ENODEV;
+
+ return 0;
+}
diff --git a/include/axp221.h b/include/axp221.h
new file mode 100644
index 0000000..e3b4409
--- /dev/null
+++ b/include/axp221.h
@@ -0,0 +1,50 @@
+/*
+ * (C) Copyright 2013 Oliver Schinagl <oliver(a)schinagl.nl>
+ *
+ * X-Powers AXP221 Power Management IC driver
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#define AXP221_CHIP_ADDR 0x68
+#define AXP221_CTRL_ADDR 0x3e
+#define AXP221_INIT_DATA 0x3e
+
+#define AXP221_CHIP_ID 0x03
+#define AXP221_OUTPUT_CTRL1 0x10
+#define AXP221_OUTPUT_CTRL1_ALDO1_EN (1 << 6)
+#define AXP221_OUTPUT_CTRL1_ALDO2_EN (1 << 7)
+#define AXP221_OUTPUT_CTRL2 0x12
+#define AXP221_OUTPUT_CTRL2_DLDO1_EN (1 << 3)
+#define AXP221_OUTPUT_CTRL2_DLDO2_EN (1 << 4)
+#define AXP221_OUTPUT_CTRL2_DLDO3_EN (1 << 5)
+#define AXP221_OUTPUT_CTRL2_DLDO4_EN (1 << 6)
+#define AXP221_OUTPUT_CTRL2_DCDC1_EN (1 << 7)
+#define AXP221_OUTPUT_CTRL3 0x13
+#define AXP221_OUTPUT_CTRL3_ALDO3_EN (1 << 7)
+#define AXP221_DLDO1_CTRL 0x15
+#define AXP221_DLDO2_CTRL 0x16
+#define AXP221_DLDO3_CTRL 0x17
+#define AXP221_DLDO4_CTRL 0x18
+#define AXP221_DCDC1_CTRL 0x21
+#define AXP221_DCDC2_CTRL 0x22
+#define AXP221_DCDC3_CTRL 0x23
+#define AXP221_DCDC4_CTRL 0x24
+#define AXP221_DCDC5_CTRL 0x25
+#define AXP221_ALDO1_CTRL 0x28
+#define AXP221_ALDO2_CTRL 0x28
+#define AXP221_ALDO3_CTRL 0x2a
+
+int axp221_set_dcdc1(unsigned int mvolt);
+int axp221_set_dcdc2(unsigned int mvolt);
+int axp221_set_dcdc3(unsigned int mvolt);
+int axp221_set_dcdc4(unsigned int mvolt);
+int axp221_set_dcdc5(unsigned int mvolt);
+int axp221_set_dldo1(unsigned int mvolt);
+int axp221_set_dldo2(unsigned int mvolt);
+int axp221_set_dldo3(unsigned int mvolt);
+int axp221_set_dldo4(unsigned int mvolt);
+int axp221_set_aldo1(unsigned int mvolt);
+int axp221_set_aldo2(unsigned int mvolt);
+int axp221_set_aldo3(unsigned int mvolt);
+int axp221_init(void);
--
2.1.0
3
6
Hi Tom,
Please pull this PR.
thanks!
Jagan.
The following changes since commit e3bf81b1e841ecabe7c8b3d48621256db8b8623e:
Merge branch 'master' of git://git.denx.de/u-boot-mpc85xx (2014-12-16 15:20:02 -0500)
are available in the git repository at:
git://git.denx.de/u-boot-spi.git master
for you to fetch changes up to babe6994ca28e5a354ee32b33b7a54b0276d9df1:
sf: sf_params: Add S25FL164K flash identifier info (2014-12-18 18:48:30 +0530)
----------------------------------------------------------------
Adnan Ali (2):
sf: sf_params: Add S25FL116K flash support
sf: sf_params: Add S25FL164K flash identifier info
Jagannadha Sutradharudu Teki (1):
mtd: sf: Zap ramtron driver
Shengzhou Liu (1):
mtd/spi: Add support for SST25WF040B
drivers/mtd/spi/Makefile | 1 -
drivers/mtd/spi/ramtron.c | 404 --------------------------------------------
drivers/mtd/spi/sf_params.c | 3 +
3 files changed, 3 insertions(+), 405 deletions(-)
delete mode 100644 drivers/mtd/spi/ramtron.c
2
1
This is an early preview of some recent work to support PCI in driver model.
It was prompted by fiddling with bare x86 support and finding that PCI has
its own device model, but no actual storage as to what devices exist in
the system. It is not possible to specify configuration information for
devices other than in board code.
This patch is a collection of changes in core DM, sandbox and PCI code to
implement a PCI uclass and associated operations. Some basic tests are
provided but they are incomplete.
As is becoming common with DM conversions, the existing structure (here
struct pci_controller) becomes per-bus uclass data. This allows the concept
of a 'hose' (generally a PCI host controller and a bus) to continue to exist
in the interim, even if it should not be needed in the end. This makes it
much easier to convert over existing code.
There is one major core DM change tacked into this patch. The core DM
code is updated to move allocation of platform data into the bind()
stage instead of probe(). This is because with PCI we need to know the
bus address of a device (in PCI speak: device and function or devfn) before
we can probe it. Actually a similar problem arose with SPI and I2C and I
worked around it, but with evidence from PCI also it seems we should make
this change.
PCI buses are not scanned in the bind() method but only later when probe()
is called. This will be automatic if you access a bus, but it does mean that
if PCI is not used it will not be touched, in keeping with U-Boot's lazy-
init philosophy.
The existing 'pciauto' bus configuration code is still used, although it now
uses DM underneath. It works exclusively by reading and writing PCI config
and does not refer to DM data structures. In fact that file is not touched
in this patch which is an indication that a good level of compatibility is
achieved between DM and legacy PCI.
In order to support testing of PCI I/O and memory space, support has been
added to sandbox to allow mapping of these. This allows commands like 'md'
and 'iod' to display data from mapped PCI devices. Similarly, it is possible
to make changes to this space. This support relies on the existing
map_sysmem() and unmap_sysmem() calls which are now fairly widespread in
U-Boot.
Apart from the driver model tests (run with ./test/dm/test-dm.sh) you can
try out these commands which use the new 'swap_case' test device:
../u-boot -d b/sandbox/u-boot.dtb
....
=> iow.b 20000000 2
=> iod.b 20000000
0000: 02
=> mw.l 10000000 64436241
=> md.l 10000000 1
10000000: 44634261 aBcD
=>
This shows an I/O access to 20000000, setting the value 2 which means to
swap the case. Then 'AbCd' is written to the memory space at 10000000 and
'aBcD' is read back.
The 'pci' command works to some extent.
Most existing PCI functions still work, but route through driver model.
The file drivers/pci/pci.c is replaced when driver model is enabled so not
everything is present. Also multiple bus support is untested and probably
broken. A new pci_common.c file holds functions common to driver model and
the old system, and pci_compat.c contains functions I would like to
eventually deprecate.
This series is not tested on any real hardware at this stage. Once the bare
x86 support is merged I will tidy this patch up and move it over, fix up
Kconfig, etc.
This patch is available at u-boot-dm.git branch pci-working.
Signed-off-by: Simon Glass <sjg(a)chromium.org>
---
arch/sandbox/Kconfig | 6 +
arch/sandbox/cpu/cpu.c | 37 ++-
arch/sandbox/dts/sandbox.dts | 26 ++-
arch/sandbox/include/asm/io.h | 16 +-
arch/sandbox/include/asm/processor.h | 12 +
arch/sandbox/include/asm/test.h | 7 +-
arch/sandbox/include/asm/u-boot-sandbox.h | 7 +
arch/sandbox/lib/Makefile | 2 +-
arch/sandbox/lib/pci_io.c | 137 +++++++++++
common/board_r.c | 2 +
common/cmd_mem.c | 7 +-
common/cmd_pci.c | 14 +-
configs/sandbox_defconfig | 4 +
doc/driver-model/pci-info.txt | 52 +++++
drivers/core/device.c | 92 ++++++--
drivers/core/root.c | 3 +
drivers/misc/Makefile | 1 +
drivers/misc/swap_case.c | 284 +++++++++++++++++++++++
drivers/pci/Kconfig | 22 ++
drivers/pci/Makefile | 10 +-
drivers/pci/pci-emul-uclass.c | 66 ++++++
drivers/pci/pci-uclass.c | 374 ++++++++++++++++++++++++++++++
drivers/pci/pci.c | 72 +-----
drivers/pci/pci_common.c | 72 ++++++
drivers/pci/pci_compat.c | 67 ++++++
drivers/pci/pci_sandbox.c | 171 ++++++++++++++
include/configs/sandbox.h | 5 +-
include/dm/device.h | 32 +++
include/dm/uclass-id.h | 3 +
include/dm/uclass.h | 4 +
include/fdtdec.h | 11 +
include/pci.h | 156 ++++++++++++-
lib/fdtdec.c | 2 +-
test/dm/Makefile | 1 +
test/dm/test-fdt.c | 4 +-
test/dm/test.dts | 17 ++
36 files changed, 1687 insertions(+), 111 deletions(-)
create mode 100644 arch/sandbox/include/asm/processor.h
create mode 100644 arch/sandbox/lib/pci_io.c
create mode 100644 doc/driver-model/pci-info.txt
create mode 100644 drivers/misc/swap_case.c
create mode 100644 drivers/pci/pci-emul-uclass.c
create mode 100644 drivers/pci/pci-uclass.c
create mode 100644 drivers/pci/pci_common.c
create mode 100644 drivers/pci/pci_compat.c
create mode 100644 drivers/pci/pci_sandbox.c
diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
index 3057325..8d1ec1d 100644
--- a/arch/sandbox/Kconfig
+++ b/arch/sandbox/Kconfig
@@ -10,4 +10,10 @@ config SYS_BOARD
config SYS_CONFIG_NAME
default "sandbox"
+config PCI
+ bool "PCI support"
+ help
+ Enable support for PCI (Peripheral Interconnect Bus), a type of bus
+ used on some devices to allow the CPU to communicate with
+
endmenu
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index 1aa397c..1e67a31 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -2,7 +2,7 @@
* Copyright (c) 2011 The Chromium OS Authors.
* SPDX-License-Identifier: GPL-2.0+
*/
-
+#define DEBUG
#include <common.h>
#include <dm/root.h>
#include <os.h>
@@ -10,6 +10,13 @@
DECLARE_GLOBAL_DATA_PTR;
+/* Enable access to PCI memory with map_sysmem() */
+static bool enable_pci_map;
+
+/* Last device that was mapped into memory, and length of mapping */
+static struct udevice *map_dev;
+unsigned long map_len;
+
void reset_cpu(ulong ignored)
{
if (state_uninit())
@@ -59,9 +66,37 @@ int cleanup_before_linux(void)
void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
{
+#ifdef CONFIG_PCI
+ unsigned long plen = len;
+ void *ptr;
+
+ map_dev = NULL;
+ if (enable_pci_map && !pci_map_physmem(paddr, &len, &map_dev, &ptr)) {
+ if (plen != len) {
+ printf("%s: Warning: partial map at %x, wanted %lx, got %lx\n",
+ __func__, paddr, len, plen);
+ }
+ map_len = len;
+ return ptr;
+ }
+#endif
+
return (void *)(gd->arch.ram_buf + paddr);
}
+void unmap_physmem(const void *vaddr, unsigned long flags)
+{
+ if (map_dev) {
+ pci_unmap_physmem(vaddr, map_len, map_dev);
+ map_dev = NULL;
+ }
+}
+
+void sandbox_set_enable_pci_map(int enable)
+{
+ enable_pci_map = enable;
+}
+
phys_addr_t map_to_sysmem(const void *ptr)
{
return (u8 *)ptr - gd->arch.ram_buf;
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 7614715..c8df40b 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -1,8 +1,14 @@
/dts-v1/;
+#define MBUS_ID(target, attributes) (((target) << 24) | ((attributes) << 16))
+
/ {
#address-cells = <1>;
- #size-cells = <0>;
+ #size-cells = <1>;
+
+ aliases {
+ pci0 = &pci;
+ };
chosen {
stdout-path = "/serial";
@@ -137,7 +143,7 @@
spi@0 {
#address-cells = <1>;
#size-cells = <0>;
- reg = <0>;
+ reg = <0 0>;
compatible = "sandbox,spi";
cs-gpios = <0>, <&gpio_a 0>;
flash@0 {
@@ -157,4 +163,20 @@
};
};
+ pci: pci-controller {
+ compatible = "sandbox,pci";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000
+ 0x01000000 0 0x20000000 0x20000000 0 0x2000>;
+ pci@1f,0 {
+ compatible = "pci-generic";
+ reg = <0xf800 0 0 0 0>;
+ emul@1f,0 {
+ compatible = "sandbox,swap-case";
+ };
+ };
+ };
+
};
diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h
index 895fcb8..5b87fde 100644
--- a/arch/sandbox/include/asm/io.h
+++ b/arch/sandbox/include/asm/io.h
@@ -22,10 +22,7 @@ void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags);
/*
* Take down a mapping set up by map_physmem().
*/
-static inline void unmap_physmem(void *vaddr, unsigned long flags)
-{
-
-}
+void unmap_physmem(const void *vaddr, unsigned long flags);
/* For sandbox, we want addresses to point into our RAM buffer */
static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
@@ -33,8 +30,10 @@ static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
return map_physmem(paddr, len, MAP_WRBACK);
}
+/* Remove a previous mapping */
static inline void unmap_sysmem(const void *vaddr)
{
+ unmap_physmem(vaddr, MAP_WRBACK);
}
/* Map from a pointer to our RAM buffer */
@@ -48,6 +47,15 @@ phys_addr_t map_to_sysmem(const void *ptr);
#define writew(v, addr)
#define writel(v, addr)
+/* I/O access functions */
+int inl(unsigned int addr);
+int inw(unsigned int addr);
+int inb(unsigned int addr);
+
+void outl(unsigned int value, unsigned int addr);
+void outw(unsigned int value, unsigned int addr);
+void outb(unsigned int value, unsigned int addr);
+
#include <iotrace.h>
#endif
diff --git a/arch/sandbox/include/asm/processor.h b/arch/sandbox/include/asm/processor.h
new file mode 100644
index 0000000..3c1794e
--- /dev/null
+++ b/arch/sandbox/include/asm/processor.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ASM_PROCESSOR_H
+#define _ASM_PROCESSOR_H
+
+/* This file is required for PCI */
+
+#endif
diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h
index d7f7bb5..fa61b5e 100644
--- a/arch/sandbox/include/asm/test.h
+++ b/arch/sandbox/include/asm/test.h
@@ -10,6 +10,11 @@
#define __ASM_TEST_H
/* The sandbox driver always permits an I2C device with this address */
-#define SANDBOX_I2C_TEST_ADDR 0x59
+#define SANDBOX_I2C_TEST_ADDR 0x59
+
+#define SANDBOX_PCI_VENDOR_ID 0x1234
+#define SANDBOX_PCI_DEVICE_ID 0x5678
+#define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM
+#define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL
#endif
diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h
index d2f1b65..1a29cf1 100644
--- a/arch/sandbox/include/asm/u-boot-sandbox.h
+++ b/arch/sandbox/include/asm/u-boot-sandbox.h
@@ -28,4 +28,11 @@ int cleanup_before_linux(void);
/* drivers/video/sandbox_sdl.c */
int sandbox_lcd_sdl_early_init(void);
+int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
+ struct udevice **devp, void **ptrp);
+int pci_unmap_physmem(const void *addr, unsigned long len,
+ struct udevice *dev);
+
+void sandbox_set_enable_pci_map(int enable);
+
#endif /* _U_BOOT_SANDBOX_H_ */
diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile
index 4c1a38d..dedc752 100644
--- a/arch/sandbox/lib/Makefile
+++ b/arch/sandbox/lib/Makefile
@@ -7,5 +7,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
-
obj-y += interrupts.o
+obj-y += pci_io.o
diff --git a/arch/sandbox/lib/pci_io.c b/arch/sandbox/lib/pci_io.c
new file mode 100644
index 0000000..601d969
--- /dev/null
+++ b/arch/sandbox/lib/pci_io.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*
+ * IO space access commands.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <asm/io.h>
+
+int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
+ struct udevice **devp, void **ptrp)
+{
+ struct udevice *dev;
+ int ret;
+
+ *ptrp = 0;
+ for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
+ dev;
+ uclass_next_device(&dev)) {
+ struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
+
+ if (!ops || !ops->map_physmem)
+ continue;
+ ret = (ops->map_physmem)(dev, paddr, lenp, ptrp);
+ if (ret)
+ continue;
+ *devp = dev;
+ return 0;
+ }
+
+ debug("%s: failed: addr=%x\n", __func__, paddr);
+ return -ENOSYS;
+}
+
+int pci_unmap_physmem(const void *vaddr, unsigned long len,
+ struct udevice *dev)
+{
+ struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
+
+ if (!ops || !ops->unmap_physmem)
+ return -ENOSYS;
+ return (ops->unmap_physmem)(vaddr, len, dev);
+}
+
+static int pci_io_read(unsigned int addr, ulong *valuep, pci_size_t size)
+{
+ struct udevice *dev;
+ int ret;
+
+ *valuep = pci_get_ff(size);
+ for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
+ dev;
+ uclass_next_device(&dev)) {
+ struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
+
+ if (ops && ops->read_io) {
+ ret = (ops->read_io)(dev, addr, valuep, size);
+ if (!ret)
+ return 0;
+ }
+ }
+
+ debug("%s: failed: addr=%x\n", __func__, addr);
+ return -ENOSYS;
+}
+
+static int pci_io_write(unsigned int addr, ulong value, pci_size_t size)
+{
+ struct udevice *dev;
+ int ret;
+
+ for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
+ dev;
+ uclass_next_device(&dev)) {
+ struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
+
+ if (ops && ops->write_io) {
+ ret = (ops->write_io)(dev, addr, value, size);
+ if (!ret)
+ return 0;
+ }
+ }
+
+ debug("%s: failed: addr=%x, value=%lx\n", __func__, addr, value);
+ return -ENOSYS;
+}
+
+int inl(unsigned int addr)
+{
+ unsigned long value;
+ int ret;
+
+ ret = pci_io_read(addr, &value, PCI_SIZE_32);
+
+ return ret ? 0 : value;
+}
+
+int inw(unsigned int addr)
+{
+ unsigned long value;
+ int ret;
+
+ ret = pci_io_read(addr, &value, PCI_SIZE_16);
+
+ return ret ? 0 : value;
+}
+
+int inb(unsigned int addr)
+{
+ unsigned long value;
+ int ret;
+
+ ret = pci_io_read(addr, &value, PCI_SIZE_8);
+
+ return ret ? 0 : value;
+}
+
+void outl(unsigned int value, unsigned int addr)
+{
+ pci_io_write(addr, value, PCI_SIZE_32);
+}
+
+void outw(unsigned int value, unsigned int addr)
+{
+ pci_io_write(addr, value, PCI_SIZE_16);
+}
+
+void outb(unsigned int value, unsigned int addr)
+{
+ pci_io_write(addr, value, PCI_SIZE_8);
+}
diff --git a/common/board_r.c b/common/board_r.c
index 8625a90..1448f42 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -223,7 +223,9 @@ static int initr_unlock_ram_in_cache(void)
#ifdef CONFIG_PCI
static int initr_pci(void)
{
+#ifndef CONFIG_DM_PCI
pci_init();
+#endif
return 0;
}
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index bcb3ee3..855aa57 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -165,7 +165,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#endif
ulong addr, count;
int size;
- void *buf;
+ void *buf, *start;
ulong bytes;
if ((argc < 3) || (argc > 4))
@@ -197,7 +197,8 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
bytes = size * count;
- buf = map_sysmem(addr, bytes);
+ start = map_sysmem(addr, bytes);
+ buf = start;
while (count-- > 0) {
if (size == 4)
*((u32 *)buf) = (u32)writeval;
@@ -211,7 +212,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
*((u8 *)buf) = (u8)writeval;
buf += size;
}
- unmap_sysmem(buf);
+ unmap_sysmem(start);
return 0;
}
diff --git a/common/cmd_pci.c b/common/cmd_pci.c
index a1ba42e..e847ada 100644
--- a/common/cmd_pci.c
+++ b/common/cmd_pci.c
@@ -47,6 +47,7 @@ void pciinfo(int BusNum, int ShortPCIListing)
unsigned char HeaderType;
unsigned short VendorID;
pci_dev_t dev;
+ int ret;
printf("Scanning PCI devices on bus %d\n", BusNum);
@@ -67,7 +68,10 @@ void pciinfo(int BusNum, int ShortPCIListing)
dev = PCI_BDF(BusNum, Device, Function);
- pci_read_config_word(dev, PCI_VENDOR_ID, &VendorID);
+ ret = pci_read_config_word(dev, PCI_VENDOR_ID,
+ &VendorID);
+ if (ret)
+ goto error;
if ((VendorID == 0xFFFF) || (VendorID == 0x0000))
continue;
@@ -84,8 +88,12 @@ void pciinfo(int BusNum, int ShortPCIListing)
BusNum, Device, Function);
pci_header_show(dev);
}
- }
- }
+ }
+ }
+
+ return;
+error:
+ printf("Cannot read bus configuration: %d\n", ret);
}
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 47d8400..ca47480 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -1,3 +1,7 @@
CONFIG_OF_CONTROL=y
CONFIG_OF_HOSTFILE=y
CONFIG_DEFAULT_DEVICE_TREE="sandbox"
+CONFIG_DM=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_SANDBOX=y
diff --git a/doc/driver-model/pci-info.txt b/doc/driver-model/pci-info.txt
new file mode 100644
index 0000000..ac82e7e
--- /dev/null
+++ b/doc/driver-model/pci-info.txt
@@ -0,0 +1,52 @@
+PCI with Driver Model
+=====================
+
+How busses are scanned
+----------------------
+
+Any config read will end up at pci_read_config(). This uses uclass_get_device by seq() to get the PCI bus for a particular bus number. Bus number 0 will need to be requested first, and the alias in the device tree file will point to the correct device:
+
+
+ aliases {
+ pci0 = &pci;
+ };
+
+ pci: pci-controller {
+ compatible = "sandbox,pci";
+ ...
+ };
+
+The call to uclass_get_device by seq() will caus the PCI bus to be probed. This does a scan of the bus to locate available devices. These devices are bound to their appropriate driver if availbale. If there is no driver, then they are bound to a generic PCI driver which does nothing.
+
+After probing a bus the available devices will appear in the device tree under that bus.
+
+Note that this is all done on a lazy basis, as needed, so until something is touched on PCI it will not be probed.
+
+PCI devices can appear in the device tree. If they do this servers to specify the driver to use for the device. In this case they will be bound at start-up.
+
+
+Sandbox
+-------
+
+With sandbox we need a device emulator for each device on the bus since there is no real PCI bus. This works by looking in the device tree node for a driver. For example:
+
+
+ pci@1f,0 {
+ compatible = "pci-generic";
+ reg = <0xf800 0 0 0 0>;
+ emul@1f,0 {
+ compatible = "sandbox,swap-case";
+ };
+ };
+
+This means that there is a 'sandbox,swap-case' driver at that bus position.
+Note that the first cell in the 'reg' value is the bus/device/function. See
+PCI_BDF() for the encoding.
+
+When this bus is scanned we will end up with something like this:
+
+`- * pci-controller @ 05c660c8, 0
+ `- pci@1f,0 @ 05c661c8, 63488
+ `- emul@1f,0 @ 05c662c8
+
+When accesses go to the pci@1f,0 device they are forwarded to its child, the emulator.
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 49faa29..5faf2d7 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -118,8 +118,27 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name,
#else
dev->req_seq = -1;
#endif
- if (!dev->platdata && drv->platdata_auto_alloc_size)
+ if (!dev->platdata && drv->platdata_auto_alloc_size) {
dev->flags |= DM_FLAG_ALLOC_PDATA;
+ dev->platdata = calloc(1, drv->platdata_auto_alloc_size);
+ if (!dev->platdata) {
+ ret = -ENOMEM;
+ goto fail_alloc1;
+ }
+ }
+ if (dev->parent && !dev->parent_platdata) {
+ int size = dev->parent->driver->
+ per_child_platdata_auto_alloc_size;
+
+ if (size) {
+ dev->flags |= DM_FLAG_ALLOC_PARENT_PDATA;
+ dev->parent_platdata = calloc(1, size);
+ if (!dev->parent_platdata) {
+ ret = -ENOMEM;
+ goto fail_alloc2;
+ }
+ }
+ }
/* put dev into parent's successor list */
if (parent)
@@ -127,27 +146,50 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name,
ret = uclass_bind_device(dev);
if (ret)
- goto fail_bind;
+ goto fail_uclass_bind;
/* if we fail to bind we remove device from successors and free it */
if (drv->bind) {
ret = drv->bind(dev);
- if (ret) {
- if (uclass_unbind_device(dev)) {
- dm_warn("Failed to unbind dev '%s' on error path\n",
- dev->name);
- }
+ if (ret)
goto fail_bind;
- }
}
+ if (dev->parent && dev->parent->driver->child_post_bind) {
+ ret = dev->parent->driver->child_post_bind(dev);
+ if (ret)
+ goto fail_child_post_bind;
+ }
+
if (parent)
dm_dbg("Bound device %s to %s\n", dev->name, parent->name);
*devp = dev;
return 0;
+fail_child_post_bind:
+ if (drv->unbind && drv->unbind(dev)) {
+ dm_warn("unbind() method failed on dev '%s' on error path\n",
+ dev->name);
+ }
+
fail_bind:
+ if (uclass_unbind_device(dev)) {
+ dm_warn("Failed to unbind dev '%s' on error path\n",
+ dev->name);
+ }
+
+fail_uclass_bind:
list_del(&dev->sibling_node);
+ if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) {
+ free(dev->parent_platdata);
+ dev->parent_platdata = NULL;
+ }
+fail_alloc2:
+ if (dev->flags & DM_FLAG_ALLOC_PDATA) {
+ free(dev->platdata);
+ dev->platdata = NULL;
+ }
+fail_alloc1:
free(dev);
return ret;
}
@@ -191,6 +233,14 @@ int device_unbind(struct udevice *dev)
if (ret)
return ret;
+ if (dev->flags & DM_FLAG_ALLOC_PDATA) {
+ free(dev->platdata);
+ dev->platdata = NULL;
+ }
+ if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) {
+ free(dev->parent_platdata);
+ dev->parent_platdata = NULL;
+ }
ret = uclass_unbind_device(dev);
if (ret)
return ret;
@@ -214,10 +264,6 @@ static void device_free(struct udevice *dev)
free(dev->priv);
dev->priv = NULL;
}
- if (dev->flags & DM_FLAG_ALLOC_PDATA) {
- free(dev->platdata);
- dev->platdata = NULL;
- }
size = dev->uclass->uc_drv->per_device_auto_alloc_size;
if (size) {
free(dev->uclass_priv);
@@ -257,13 +303,6 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
}
}
/* Allocate private data if requested */
- if (dev->flags & DM_FLAG_ALLOC_PDATA) {
- dev->platdata = calloc(1, drv->platdata_auto_alloc_size);
- if (!dev->platdata) {
- ret = -ENOMEM;
- goto fail;
- }
- }
size = dev->uclass->uc_drv->per_device_auto_alloc_size;
if (size) {
dev->uclass_priv = calloc(1, size);
@@ -409,6 +448,16 @@ void *dev_get_platdata(struct udevice *dev)
return dev->platdata;
}
+void *dev_get_parent_platdata(struct udevice *dev)
+{
+ if (!dev) {
+ dm_warn("%s: null device", __func__);
+ return NULL;
+ }
+
+ return dev->parent_platdata;
+}
+
void *dev_get_priv(struct udevice *dev)
{
if (!dev) {
@@ -548,3 +597,8 @@ int device_find_next_child(struct udevice **devp)
return 0;
}
+
+enum uclass_id device_get_uclass_id(struct udevice *dev)
+{
+ return dev->uclass->uc_drv->id;
+}
diff --git a/drivers/core/root.c b/drivers/core/root.c
index a328a48..8dc615a 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -49,6 +49,9 @@ int dm_init(void)
ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);
if (ret)
return ret;
+#ifdef CONFIG_OF_CONTROL
+ DM_ROOT_NON_CONST->of_offset = 0;
+#endif
ret = device_probe(DM_ROOT_NON_CONST);
if (ret)
return ret;
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 2f2e48f..01ecf30 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -21,5 +21,6 @@ obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
obj-$(CONFIG_NS87308) += ns87308.o
obj-$(CONFIG_PDSP188x) += pdsp188x.o
obj-$(CONFIG_STATUS_LED) += status_led.o
+obj-$(CONFIG_SANDBOX) += swap_case.o
obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
diff --git a/drivers/misc/swap_case.c b/drivers/misc/swap_case.c
new file mode 100644
index 0000000..50f3b1d
--- /dev/null
+++ b/drivers/misc/swap_case.c
@@ -0,0 +1,284 @@
+/*
+ * PCI emulation device which swaps the case of text
+ *
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <pci.h>
+#include <asm/test.h>
+#include <linux/ctype.h>
+
+/**
+ * struct swap_case_platdata - platform data for this device
+ *
+ * @command: Current PCI command value
+ * @bar: Current base address values
+ */
+struct swap_case_platdata {
+ u16 command;
+ u32 bar[2];
+};
+
+#define offset_to_barnum(offset) \
+ (((offset) - PCI_BASE_ADDRESS_0) / sizeof(u32))
+
+enum {
+ MEM_TEXT_SIZE = 0x100,
+};
+
+enum swap_case_op {
+ OP_TO_LOWER,
+ OP_TO_UPPER,
+ OP_SWAP,
+};
+
+static struct pci_bar {
+ int type;
+ u32 size;
+} barinfo[] = {
+ { PCI_BASE_ADDRESS_SPACE_IO, 1 },
+ { PCI_BASE_ADDRESS_MEM_TYPE_32, MEM_TEXT_SIZE },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+};
+
+struct swap_case_priv {
+ enum swap_case_op op;
+ char mem_text[MEM_TEXT_SIZE];
+};
+
+static int sandbox_swap_case_get_devfn(struct udevice *dev)
+{
+ struct pci_child_platdata *plat = dev_get_parent_platdata(dev);
+
+ return plat->devfn;
+}
+
+static int sandbox_swap_case_read_config(struct udevice *emul, uint offset,
+ ulong *valuep, enum pci_size_t size)
+{
+ struct swap_case_platdata *plat = dev_get_platdata(emul);
+
+ switch (offset) {
+ case PCI_COMMAND:
+ *valuep = plat->command;
+ break;
+ case PCI_HEADER_TYPE:
+ *valuep = 0;
+ break;
+ case PCI_VENDOR_ID:
+ *valuep = SANDBOX_PCI_VENDOR_ID;
+ break;
+ case PCI_DEVICE_ID:
+ *valuep = SANDBOX_PCI_DEVICE_ID;
+ break;
+ case PCI_CLASS_DEVICE:
+ if (size == PCI_SIZE_8) {
+ *valuep = SANDBOX_PCI_CLASS_SUB_CODE;
+ } else {
+ *valuep = (SANDBOX_PCI_CLASS_CODE << 8) |
+ SANDBOX_PCI_CLASS_SUB_CODE;
+ }
+ break;
+ case PCI_CLASS_CODE:
+ *valuep = SANDBOX_PCI_CLASS_CODE;
+ break;
+ case PCI_BASE_ADDRESS_0:
+ case PCI_BASE_ADDRESS_1:
+ case PCI_BASE_ADDRESS_2:
+ case PCI_BASE_ADDRESS_3:
+ case PCI_BASE_ADDRESS_4:
+ case PCI_BASE_ADDRESS_5: {
+ int barnum;
+ u32 *bar, result;
+
+ barnum = offset_to_barnum(offset);
+ bar = &plat->bar[barnum];
+
+ result = *bar;
+ if (*bar == 0xffffffff) {
+ if (barinfo[barnum].type) {
+ result = (~(barinfo[barnum].size - 1) &
+ PCI_BASE_ADDRESS_IO_MASK) |
+ PCI_BASE_ADDRESS_SPACE_IO;
+ } else {
+ result = (~(barinfo[barnum].size - 1) &
+ PCI_BASE_ADDRESS_MEM_MASK) |
+ PCI_BASE_ADDRESS_MEM_TYPE_32;
+ }
+ }
+ debug("r bar %d=%x\n", barnum, result);
+ *valuep = result;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int sandbox_swap_case_write_config(struct udevice *emul, uint offset,
+ ulong value, enum pci_size_t size)
+{
+ struct swap_case_platdata *plat = dev_get_platdata(emul);
+
+ switch (offset) {
+ case PCI_COMMAND:
+ plat->command = value;
+ break;
+ case PCI_BASE_ADDRESS_0:
+ case PCI_BASE_ADDRESS_1: {
+ int barnum;
+ u32 *bar;
+
+ barnum = offset_to_barnum(offset);
+ bar = &plat->bar[barnum];
+
+ debug("w bar %d=%lx\n", barnum, value);
+ *bar = value;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int sandbox_swap_case_find_bar(struct udevice *emul, unsigned int addr,
+ int *barnump, unsigned int *offsetp)
+{
+ struct swap_case_platdata *plat = dev_get_platdata(emul);
+ int barnum;
+
+ for (barnum = 0; barnum < ARRAY_SIZE(barinfo); barnum++) {
+ unsigned int size = barinfo[barnum].size;
+
+ if (addr >= plat->bar[barnum] &&
+ addr < plat->bar[barnum] + size) {
+ *barnump = barnum;
+ *offsetp = addr - plat->bar[barnum];
+ return 0;
+ }
+ }
+ *barnump = -1;
+
+ return -ENOENT;
+}
+
+static void sandbox_swap_case_do_op(enum swap_case_op op, char *str, int len)
+{
+ for (; len > 0; len--, str++) {
+ switch (op) {
+ case OP_TO_UPPER:
+ *str = toupper(*str);
+ break;
+ case OP_TO_LOWER:
+ *str = tolower(*str);
+ break;
+ case OP_SWAP:
+ if (isupper(*str))
+ *str = tolower(*str);
+ else
+ *str = toupper(*str);
+ break;
+ }
+ }
+}
+
+int sandbox_swap_case_read_io(struct udevice *dev, unsigned int addr,
+ ulong *valuep, enum pci_size_t size)
+{
+ struct swap_case_priv *priv = dev_get_priv(dev);
+ unsigned int offset;
+ int barnum;
+ int ret;
+
+ ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
+ if (ret)
+ return ret;
+
+ if (barnum == 0 && offset == 0)
+ *valuep = (*valuep & ~0xff) | priv->op;
+
+ return 0;
+}
+
+int sandbox_swap_case_write_io(struct udevice *dev, unsigned int addr,
+ ulong value, enum pci_size_t size)
+{
+ struct swap_case_priv *priv = dev_get_priv(dev);
+ unsigned int offset;
+ int barnum;
+ int ret;
+
+ ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
+ if (ret)
+ return ret;
+ if (barnum == 0 && offset == 0)
+ priv->op = value;
+
+ return 0;
+}
+
+static int sandbox_swap_case_map_physmem(struct udevice *dev,
+ phys_addr_t addr, unsigned long *lenp, void **ptrp)
+{
+ struct swap_case_priv *priv = dev_get_priv(dev);
+ unsigned int offset, avail;
+ int barnum;
+ int ret;
+
+ ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
+ if (ret)
+ return ret;
+ if (barnum == 1) {
+ *ptrp = priv->mem_text + offset;
+ avail = barinfo[1].size - offset;
+ if (avail > barinfo[1].size)
+ *lenp = 0;
+ else
+ *lenp = min(*lenp, avail);
+
+ return 0;
+ }
+
+ return -ENOENT;
+}
+
+static int sandbox_swap_case_unmap_physmem(const void *vaddr,
+ unsigned long len, struct udevice *dev)
+{
+ struct swap_case_priv *priv = dev_get_priv(dev);
+
+ sandbox_swap_case_do_op(priv->op, (void *)vaddr, len);
+
+ return 0;
+}
+
+struct dm_pci_emul_ops sandbox_swap_case_emul_ops = {
+ .get_devfn = sandbox_swap_case_get_devfn,
+ .read_config = sandbox_swap_case_read_config,
+ .write_config = sandbox_swap_case_write_config,
+ .read_io = sandbox_swap_case_read_io,
+ .write_io = sandbox_swap_case_write_io,
+ .map_physmem = sandbox_swap_case_map_physmem,
+ .unmap_physmem = sandbox_swap_case_unmap_physmem,
+};
+
+static const struct udevice_id sandbox_swap_case_ids[] = {
+ { .compatible = "sandbox,swap-case" },
+ { }
+};
+
+U_BOOT_DRIVER(sandbox_swap_case_emul) = {
+ .name = "sandbox_swap_case_emul",
+ .id = UCLASS_PCI_EMUL,
+ .of_match = sandbox_swap_case_ids,
+ .ops = &sandbox_swap_case_emul_ops,
+ .priv_auto_alloc_size = sizeof(struct swap_case_priv),
+ .platdata_auto_alloc_size = sizeof(struct swap_case_platdata),
+};
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index e69de29..167d405 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -0,0 +1,22 @@
+menu "PCI"
+
+config DM_PCI
+ bool "Enable driver mode for PCI"
+ depends on DM
+ help
+ Use driver model for PCI. Driver model is the new method for
+ orgnising devices in U-Boot. For PCI, driver model keeps track of
+ available PCI devices, allows scanning of PCI buses and provides
+ device configuration support.
+
+config PCI_SANDBOX
+ bool "Sandbox PCI support"
+ depends on SANDBOX && DM_PCI
+ help
+ Support PCI on sandbox, as an emulated bus. This permits testing of
+ PCI feature such as bus scanning, device configuration and device
+ access. The available (emulated) devices are defined statically in
+ the device tree but the normal PCI scan technique is used to find
+ then.
+
+endmenu
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 55d6a9b..11bae12 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -5,13 +5,21 @@
# SPDX-License-Identifier: GPL-2.0+
#
+ifneq ($(CONFIG_DM_PCI),)
+obj-$(CONFIG_PCI) += pci-uclass.o pci_compat.o
+obj-$(CONFIG_SANDBOX) += pci-emul-uclass.o
+else
+obj-$(CONFIG_PCI) += pci.o pci_rom.o
+endif
+obj-$(CONFIG_PCI) += pci_common.o pci_auto.o
+
obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o
-obj-$(CONFIG_PCI) += pci.o pci_auto.o pci_rom.o
obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o
obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o
obj-$(CONFIG_PCI_MSC01) += pci_msc01.o
obj-$(CONFIG_PCIE_IMX) += pcie_imx.o
obj-$(CONFIG_FTPCI100) += pci_ftpci100.o
+obj-$(CONFIG_PCI_SANDBOX) += pci_sandbox.o
obj-$(CONFIG_SH4_PCI) += pci_sh4.o
obj-$(CONFIG_SH7751_PCI) +=pci_sh7751.o
obj-$(CONFIG_SH7780_PCI) +=pci_sh7780.o
diff --git a/drivers/pci/pci-emul-uclass.c b/drivers/pci/pci-emul-uclass.c
new file mode 100644
index 0000000..2baeab6
--- /dev/null
+++ b/drivers/pci/pci-emul-uclass.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <libfdt.h>
+#include <pci.h>
+#include <dm/lists.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct sandbox_pci_priv {
+ int dev_count;
+};
+
+int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn,
+ struct udevice **emulp)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = pci_bus_find_devfn(bus, find_devfn, &dev);
+ if (ret) {
+ debug("%s: Could not find emulator for dev %x\n", __func__,
+ find_devfn);
+ return ret;
+ }
+
+ ret = device_find_first_child(dev, emulp);
+ if (ret)
+ return ret;
+
+ return *emulp ? 0 : -ENODEV;
+}
+
+static int sandbox_pci_emul_post_probe(struct udevice *dev)
+{
+ struct sandbox_pci_priv *priv = dev->uclass->priv;
+
+ priv->dev_count++;
+ sandbox_set_enable_pci_map(true);
+
+ return 0;
+}
+
+static int sandbox_pci_emul_pre_remove(struct udevice *dev)
+{
+ struct sandbox_pci_priv *priv = dev->uclass->priv;
+
+ priv->dev_count--;
+ sandbox_set_enable_pci_map(priv->dev_count > 0);
+
+ return 0;
+}
+
+UCLASS_DRIVER(pci_emul) = {
+ .id = UCLASS_PCI_EMUL,
+ .name = "pci_emul",
+ .post_probe = sandbox_pci_emul_post_probe,
+ .pre_remove = sandbox_pci_emul_pre_remove,
+ .priv_auto_alloc_size = sizeof(struct sandbox_pci_priv),
+};
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
new file mode 100644
index 0000000..a5bd8df
--- /dev/null
+++ b/drivers/pci/pci-uclass.c
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <pci.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int pci_get_ff(enum pci_size_t size)
+{
+ switch (size) {
+ case PCI_SIZE_8:
+ return 0xff;
+ case PCI_SIZE_16:
+ return 0xffff;
+ default:
+ return 0xffffffff;
+ }
+}
+
+int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn,
+ struct udevice **devp)
+{
+ struct udevice *dev;
+
+ for (device_find_first_child(bus, &dev);
+ dev;
+ device_find_next_child(&dev)) {
+ struct pci_child_platdata *pplat;
+
+ pplat = dev_get_parent_platdata(dev);
+ if (pplat && pplat->devfn == find_devfn) {
+ *devp = dev;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp)
+{
+ struct udevice *bus;
+ int ret;
+
+ ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+ if (ret)
+ return ret;
+ return pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), devp);
+}
+
+static int pci_device_matches_ids(struct udevice *dev,
+ struct pci_device_id *ids)
+{
+ struct pci_child_platdata *pplat;
+ int i;
+
+ pplat = dev_get_parent_platdata(dev);
+ if (!pplat)
+ return -EINVAL;
+ for (i = 0; ids[i].vendor != 0; i++) {
+ if (pplat->vendor == ids[i].vendor &&
+ pplat->device == ids[i].device)
+ return i;
+ }
+
+ return -EINVAL;
+}
+
+int pci_bus_find_devices(struct udevice *bus, struct pci_device_id *ids,
+ int *indexp, struct udevice **devp)
+{
+ struct udevice *dev;
+
+ /* Scan all devices on this bus */
+ for (device_find_first_child(bus, &dev);
+ dev;
+ device_find_next_child(&dev)) {
+ if (pci_device_matches_ids(dev, ids) >= 0) {
+ if ((*indexp)-- <= 0) {
+ *devp = dev;
+ return 0;
+ }
+ }
+ }
+
+ return -ENODEV;
+}
+
+int pci_find_device_id(struct pci_device_id *ids, int index,
+ struct udevice **devp)
+{
+ struct udevice *bus;
+
+ /* Scan all known buses */
+ for (uclass_first_device(UCLASS_PCI, &bus);
+ bus;
+ uclass_next_device(&bus)) {
+ if (!pci_bus_find_devices(bus, ids, &index, devp))
+ return 0;
+ }
+ *devp = NULL;
+
+ return -ENODEV;
+}
+
+int pci_bus_write_config(struct udevice *bus, pci_dev_t devfn, int offset,
+ unsigned long value, enum pci_size_t size)
+{
+ struct dm_pci_ops *ops;
+
+ ops = pci_get_ops(bus);
+ if (!ops->write_config)
+ return -ENOSYS;
+ return ops->write_config(bus, devfn, offset, value, size);
+}
+
+int pci_write_config(pci_dev_t bdf, int offset, unsigned long value,
+ enum pci_size_t size)
+{
+ struct udevice *bus;
+ int ret;
+
+ ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+ if (ret)
+ return ret;
+
+ return pci_bus_write_config(bus, PCI_MASK_BUS(bdf), offset, value,
+ size);
+}
+
+int pci_write_config32(pci_dev_t devfn, int offset, u32 value)
+{
+ return pci_write_config(devfn, offset, value, PCI_SIZE_8);
+}
+
+int pci_write_config16(pci_dev_t devfn, int offset, u16 value)
+{
+ return pci_write_config(devfn, offset, value, PCI_SIZE_16);
+}
+
+int pci_write_config8(pci_dev_t devfn, int offset, u8 value)
+{
+ return pci_write_config(devfn, offset, value, PCI_SIZE_8);
+}
+
+int pci_bus_read_config(struct udevice *bus, pci_dev_t devfn, int offset,
+ unsigned long *valuep, enum pci_size_t size)
+{
+ struct dm_pci_ops *ops;
+
+ ops = pci_get_ops(bus);
+ if (!ops->read_config)
+ return -ENOSYS;
+ return ops->read_config(bus, devfn, offset, valuep, size);
+}
+
+int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep,
+ enum pci_size_t size)
+{
+ struct udevice *bus;
+ int ret;
+
+ ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+ if (ret)
+ return ret;
+
+ return pci_bus_read_config(bus, PCI_MASK_BUS(bdf), offset, valuep,
+ size);
+}
+
+int pci_read_config32(pci_dev_t bdf, int offset, u32 *valuep)
+{
+ unsigned long value;
+ int ret;
+
+ ret = pci_read_config(bdf, offset, &value, PCI_SIZE_32);
+ if (ret)
+ return ret;
+ *valuep = value;
+
+ return 0;
+}
+
+int pci_read_config16(pci_dev_t bdf, int offset, u16 *valuep)
+{
+ unsigned long value;
+ int ret;
+
+ ret = pci_read_config(bdf, offset, &value, PCI_SIZE_16);
+ if (ret)
+ return ret;
+ *valuep = value;
+
+ return 0;
+}
+
+int pci_read_config8(pci_dev_t bdf, int offset, u8 *valuep)
+{
+ unsigned long value;
+ int ret;
+
+ ret = pci_read_config(bdf, offset, &value, PCI_SIZE_8);
+ if (ret)
+ return ret;
+ *valuep = value;
+
+ return 0;
+}
+
+int pci_auto_config_devices(struct udevice *bus)
+{
+ struct pci_controller *hose = bus->uclass_priv;
+ struct pci_platdata *bus_plat;
+ unsigned int sub_bus;
+ struct udevice *dev;
+ int ret;
+
+ bus_plat = dev_get_platdata(bus);
+ sub_bus = bus_plat->busnum;
+ debug("%s: start\n", __func__);
+ pciauto_config_init(hose);
+ for (ret = device_find_first_child(bus, &dev);
+ !ret && dev;
+ ret = device_find_next_child(&dev)) {
+ struct pci_child_platdata *pplat;
+
+ pplat = dev_get_parent_platdata(dev);
+ int max_bus;
+ pci_dev_t bdf;
+
+ bdf = PCI_ADD_BUS(bus_plat->busnum, pplat->devfn);
+ debug("%s: device %s\n", __func__, dev->name);
+ max_bus = pciauto_config_device(hose, bdf);
+ sub_bus = max(sub_bus, max_bus);
+ }
+ debug("%s: done\n", __func__);
+
+ return sub_bus;
+}
+
+int pci_bind_bus_devices(struct udevice *bus)
+{
+ struct pci_platdata *bus_plat;
+ ulong vendor, device;
+ ulong header_type;
+ pci_dev_t devfn, end;
+ bool found_multi;
+ int ret;
+
+ bus_plat = dev_get_platdata(bus);
+ found_multi = false;
+ end = PCI_DEVFN(PCI_MAX_PCI_DEVICES - 1, PCI_MAX_PCI_FUNCTIONS - 1);
+ for (devfn = PCI_DEVFN(0, 0); devfn < end; devfn += PCI_DEVFN(0, 1)) {
+ struct pci_child_platdata *pplat;
+ struct udevice *dev;
+ ulong val;
+
+ if (PCI_FUNC(devfn) && !found_multi)
+ continue;
+ /* Check only the first access, we don't expect problems */
+ ret = pci_bus_read_config(bus, devfn, PCI_HEADER_TYPE,
+ &header_type, PCI_SIZE_8);
+ if (ret)
+ goto error;
+ pci_bus_read_config(bus, devfn, PCI_VENDOR_ID, &vendor,
+ PCI_SIZE_16);
+ if (vendor == 0xffff || vendor == 0x0000)
+ continue;
+
+ if (!PCI_FUNC(devfn))
+ found_multi = header_type & 0x80;
+
+ debug("%s: bus %s: found device %d, function %d\n", __func__,
+ bus->name, PCI_DEV(devfn), PCI_FUNC(devfn));
+ pci_bus_read_config(bus, devfn, PCI_DEVICE_ID, &device,
+ PCI_SIZE_16);
+
+ /* Find this device in the device tree */
+ ret = pci_bus_find_devfn(bus, devfn, &dev);
+ /*
+ if (ret == -ENODEV) {
+ u32 vendev = PCI_VENDEV(vendor, device);
+
+ ret = pci_bus_find_vendev(bus, vendev, &dev);
+ }
+*/
+ /* If nothing in the device tree, bind a generic device */
+ if (ret == -ENODEV) {
+ char name[30], *str;
+
+ sprintf(name, "pci_%x:%x.%x", bus_plat->busnum,
+ PCI_DEV(devfn), PCI_FUNC(devfn));
+ str = strdup(name);
+ if (!str)
+ return -ENOMEM;
+ ret = device_bind_driver(bus, "pci_generic_drv", str,
+ &dev);
+ }
+ if (ret)
+ return ret;
+
+ /* Update the platform data */
+ pplat = dev_get_parent_platdata(dev);
+ pplat->devfn = devfn;
+ pplat->vendor = vendor;
+ pplat->device = device;
+ pci_bus_read_config(bus, devfn, PCI_CLASS_DEVICE, &val,
+ PCI_SIZE_16);
+ pplat->class = val;
+ }
+
+ return 0;
+error:
+ printf("Cannot read bus configuration: %d\n", ret);
+
+ return ret;
+}
+
+static int pci_uclass_post_bind(struct udevice *bus)
+{
+ /*
+ * Scan the device tree for devices. This does not probe the PCI bus,
+ * as this is not permitted while binding. It just finds devices
+ * mentioned in the device tree.
+ */
+ return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset, false);
+}
+
+static int pci_uclass_post_probe(struct udevice *bus)
+{
+ int ret;
+
+ debug("%s: probing\n", __func__);
+ ret = pci_bind_bus_devices(bus);
+ if (ret)
+ return ret;
+
+#ifdef CONFIG_PCI_PNP
+ ret = pci_auto_config_devices(bus);
+#endif
+
+ return ret;
+}
+
+UCLASS_DRIVER(pci) = {
+ .id = UCLASS_PCI,
+ .name = "pci",
+ .post_bind = pci_uclass_post_bind,
+ .post_probe = pci_uclass_post_probe,
+ .per_device_auto_alloc_size = sizeof(struct pci_controller),
+};
+
+UCLASS_DRIVER(pci_generic) = {
+ .id = UCLASS_PCI_GENERIC,
+ .name = "pci_generic",
+};
+
+static const struct udevice_id pci_generic_ids[] = {
+ { .compatible = "pci-generic" },
+ { }
+};
+
+U_BOOT_DRIVER(pci_generic_drv) = {
+ .name = "pci_generic_drv",
+ .id = UCLASS_PCI_GENERIC,
+ .of_match = pci_generic_ids,
+};
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 332df61..9ccee7b 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -15,6 +15,7 @@
#include <common.h>
#include <command.h>
+#include <inttypes.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <pci.h>
@@ -398,8 +399,8 @@ int pci_hose_config_device(struct pci_controller *hose,
unsigned char pin;
int bar, found_mem64;
- debug("PCI Config: I/O=0x%lx, Memory=0x%llx, Command=0x%lx\n", io,
- (u64)mem, command);
+ debug("PCI Config: I/O=0x%lx, Memory=0x%" PRIx64 ", Command=0x%lx\n",
+ io, (u64)mem, command);
pci_hose_write_config_dword(hose, dev, PCI_COMMAND, 0);
@@ -525,71 +526,6 @@ void pci_cfgfunc_do_nothing(struct pci_controller *hose,
*/
extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
-#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI_SCAN_SHOW)
-const char * pci_class_str(u8 class)
-{
- switch (class) {
- case PCI_CLASS_NOT_DEFINED:
- return "Build before PCI Rev2.0";
- break;
- case PCI_BASE_CLASS_STORAGE:
- return "Mass storage controller";
- break;
- case PCI_BASE_CLASS_NETWORK:
- return "Network controller";
- break;
- case PCI_BASE_CLASS_DISPLAY:
- return "Display controller";
- break;
- case PCI_BASE_CLASS_MULTIMEDIA:
- return "Multimedia device";
- break;
- case PCI_BASE_CLASS_MEMORY:
- return "Memory controller";
- break;
- case PCI_BASE_CLASS_BRIDGE:
- return "Bridge device";
- break;
- case PCI_BASE_CLASS_COMMUNICATION:
- return "Simple comm. controller";
- break;
- case PCI_BASE_CLASS_SYSTEM:
- return "Base system peripheral";
- break;
- case PCI_BASE_CLASS_INPUT:
- return "Input device";
- break;
- case PCI_BASE_CLASS_DOCKING:
- return "Docking station";
- break;
- case PCI_BASE_CLASS_PROCESSOR:
- return "Processor";
- break;
- case PCI_BASE_CLASS_SERIAL:
- return "Serial bus controller";
- break;
- case PCI_BASE_CLASS_INTELLIGENT:
- return "Intelligent controller";
- break;
- case PCI_BASE_CLASS_SATELLITE:
- return "Satellite controller";
- break;
- case PCI_BASE_CLASS_CRYPT:
- return "Cryptographic device";
- break;
- case PCI_BASE_CLASS_SIGNAL_PROCESSING:
- return "DSP";
- break;
- case PCI_CLASS_OTHERS:
- return "Does not fit any class";
- break;
- default:
- return "???";
- break;
- };
-}
-#endif /* CONFIG_CMD_PCI || CONFIG_PCI_SCAN_SHOW */
-
__weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
{
/*
@@ -733,6 +669,7 @@ int pci_hose_scan(struct pci_controller *hose)
return pci_hose_scan_bus(hose, hose->current_busno);
}
+#ifndef CONFIG_DM_PCI
void pci_init(void)
{
hose_head = NULL;
@@ -740,6 +677,7 @@ void pci_init(void)
/* now call board specific pci_init()... */
pci_init_board();
}
+#endif
/* Returns the address of the requested capability structure within the
* device's PCI configuration space or 0 in case the device does not
diff --git a/drivers/pci/pci_common.c b/drivers/pci/pci_common.c
new file mode 100644
index 0000000..4d01373
--- /dev/null
+++ b/drivers/pci/pci_common.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI_SCAN_SHOW)
+const char *pci_class_str(u8 class)
+{
+ switch (class) {
+ case PCI_CLASS_NOT_DEFINED:
+ return "Build before PCI Rev2.0";
+ break;
+ case PCI_BASE_CLASS_STORAGE:
+ return "Mass storage controller";
+ break;
+ case PCI_BASE_CLASS_NETWORK:
+ return "Network controller";
+ break;
+ case PCI_BASE_CLASS_DISPLAY:
+ return "Display controller";
+ break;
+ case PCI_BASE_CLASS_MULTIMEDIA:
+ return "Multimedia device";
+ break;
+ case PCI_BASE_CLASS_MEMORY:
+ return "Memory controller";
+ break;
+ case PCI_BASE_CLASS_BRIDGE:
+ return "Bridge device";
+ break;
+ case PCI_BASE_CLASS_COMMUNICATION:
+ return "Simple comm. controller";
+ break;
+ case PCI_BASE_CLASS_SYSTEM:
+ return "Base system peripheral";
+ break;
+ case PCI_BASE_CLASS_INPUT:
+ return "Input device";
+ break;
+ case PCI_BASE_CLASS_DOCKING:
+ return "Docking station";
+ break;
+ case PCI_BASE_CLASS_PROCESSOR:
+ return "Processor";
+ break;
+ case PCI_BASE_CLASS_SERIAL:
+ return "Serial bus controller";
+ break;
+ case PCI_BASE_CLASS_INTELLIGENT:
+ return "Intelligent controller";
+ break;
+ case PCI_BASE_CLASS_SATELLITE:
+ return "Satellite controller";
+ break;
+ case PCI_BASE_CLASS_CRYPT:
+ return "Cryptographic device";
+ break;
+ case PCI_BASE_CLASS_SIGNAL_PROCESSING:
+ return "DSP";
+ break;
+ case PCI_CLASS_OTHERS:
+ return "Does not fit any class";
+ break;
+ default:
+ return "???";
+ break;
+ };
+}
+#endif /* CONFIG_CMD_PCI || CONFIG_PCI_SCAN_SHOW */
diff --git a/drivers/pci/pci_compat.c b/drivers/pci/pci_compat.c
new file mode 100644
index 0000000..ed8a67d
--- /dev/null
+++ b/drivers/pci/pci_compat.c
@@ -0,0 +1,67 @@
+/*
+ * Compatibility functions for pre-driver-model code
+ *
+ * Copyright (C) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <pci.h>
+
+#define PCI_HOSE_OP(rw, name, size, type) \
+int pci_hose_##rw##_config_##name(struct pci_controller *hose, \
+ pci_dev_t dev, \
+ int offset, type value) \
+{ \
+ return pci_##rw##_config##size(dev, offset, value); \
+}
+
+PCI_HOSE_OP(read, byte, 8, u8 *)
+PCI_HOSE_OP(read, word, 16, u16 *)
+PCI_HOSE_OP(read, dword, 32, u32 *)
+PCI_HOSE_OP(write, byte, 8, u8)
+PCI_HOSE_OP(write, word, 16, u16)
+PCI_HOSE_OP(write, dword, 32, u32)
+
+int pci_hose_scan_bus(struct pci_controller *hose, int busnum)
+{
+ struct pci_platdata *bus_plat;
+ struct udevice *bus;
+ int sub_bus;
+ int ret;
+
+ ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus);
+ if (ret)
+ return ret;
+
+ ret = pci_bind_bus_devices(bus);
+ if (ret)
+ return ret;
+ bus_plat = dev_get_platdata(bus);
+ sub_bus = bus_plat->busnum;
+
+#ifdef CONFIG_PCI_PNP
+ sub_bus = pci_auto_config_devices(bus);
+#else
+ /* TODO(sjg(a)chromium.org): Configure from device tree */
+#endif
+
+ return sub_bus;
+}
+
+pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
+{
+ struct pci_child_platdata *pplat;
+ struct pci_platdata *bus_plat;
+ struct udevice *bus, *dev;
+
+ if (pci_find_device_id(ids, index, &dev))
+ return -1;
+ bus = dev->parent;
+ bus_plat = dev_get_platdata(bus);
+ pplat = dev_get_parent_platdata(dev);
+
+ return PCI_ADD_BUS(bus_plat->busnum, pplat->devfn);
+}
diff --git a/drivers/pci/pci_sandbox.c b/drivers/pci/pci_sandbox.c
new file mode 100644
index 0000000..435f2a4
--- /dev/null
+++ b/drivers/pci/pci_sandbox.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <inttypes.h>
+#include <pci.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int sandbox_pci_write_config(struct udevice *bus, pci_dev_t devfn,
+ uint offset, ulong value,
+ enum pci_size_t size)
+{
+ struct dm_pci_emul_ops *ops;
+ struct udevice *emul;
+ int ret;
+
+ ret = sandbox_pci_get_emul(bus, devfn, &emul);
+ if (ret)
+ return ret == -ENODEV ? 0 : ret;
+ ops = pci_get_emul_ops(emul);
+ if (!ops || !ops->write_config)
+ return -ENOSYS;
+
+ return ops->write_config(emul, offset, value, size);
+}
+
+static int sandbox_pci_read_config(struct udevice *bus, pci_dev_t devfn,
+ uint offset, ulong *valuep,
+ enum pci_size_t size)
+{
+ struct dm_pci_emul_ops *ops;
+ struct udevice *emul;
+ int ret;
+
+ /* Prepare the default response */
+ *valuep = pci_get_ff(size);
+ ret = sandbox_pci_get_emul(bus, devfn, &emul);
+ if (ret)
+ return ret == -ENODEV ? 0 : ret;
+ ops = pci_get_emul_ops(emul);
+ if (!ops || !ops->read_config)
+ return -ENOSYS;
+
+ return ops->read_config(emul, offset, valuep, size);
+}
+
+static int sandbox_pci_child_pre_probe(struct udevice *dev)
+{
+ return 0;
+}
+
+static int sandbox_pci_child_post_bind(struct udevice *dev)
+{
+ struct pci_child_platdata *pplat;
+
+ /*
+ * We could read vendor, device, class if available. But we must have
+ * the device/function
+ */
+ pplat = dev_get_parent_platdata(dev);
+ if (fdtdec_pci_get_bdf(gd->fdt_blob, dev->of_offset, &pplat->devfn)) {
+ debug("Cannot decode reg property from '%s'\n", dev->name);
+ return -EINVAL;
+ }
+
+ /* Attach an emulator if we can */
+ return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+static int decode_regions(struct pci_controller *hose, const void *blob,
+ int parent_node, int node)
+{
+ int pci_addr_cells, addr_cells, size_cells;
+ int cells_per_record;
+ const u32 *prop;
+ int len;
+ int i;
+
+ prop = fdt_getprop(blob, node, "ranges", &len);
+ if (!prop)
+ return -EINVAL;
+ pci_addr_cells = fdt_address_cells(blob, node);
+ addr_cells = fdt_address_cells(blob, parent_node);
+ size_cells = fdt_size_cells(blob, node);
+
+ /* PCI addresses are always 3 cells */
+ len /= sizeof(u32);
+ cells_per_record = pci_addr_cells + addr_cells + size_cells;
+ hose->region_count = 0;
+ debug("%s: len=%d, cells_per_record=%d\n", __func__, len,
+ cells_per_record);
+ for (i = 0; i < MAX_PCI_REGIONS; i++, len -= cells_per_record) {
+ u64 pci_addr, addr, size;
+ int space_code;
+ int type;
+
+ if (len < cells_per_record)
+ break;
+ space_code = (fdt32_to_cpu(prop[0]) >> 24) & 3;
+ pci_addr = fdtdec_get_number(prop + 1, 2);
+ prop += pci_addr_cells;
+ addr = fdtdec_get_number(prop, addr_cells);
+ prop += addr_cells;
+ size = fdtdec_get_number(prop, size_cells);
+ prop += size_cells;
+ if (space_code & 2)
+ type = PCI_REGION_MEM;
+ else if (space_code & 1)
+ type = PCI_REGION_IO;
+ else
+ continue;
+ debug("%s: region %d, pci_addr=%" PRIx64 ", addr=%" PRIx64
+ ", size=%" PRIx64 ", type=%d\n", __func__,
+ hose->region_count, pci_addr, addr, size, type);
+ pci_set_region(hose->regions + hose->region_count++, pci_addr,
+ addr, size, type);
+ }
+
+ return 0;
+}
+
+static int sandbox_pci_probe(struct udevice *bus)
+{
+ struct pci_controller *hose;
+ int ret;
+
+ debug("%s, bus=%s, parent=%s\n", __func__, bus->name,
+ bus->parent->name);
+ hose = bus->uclass_priv;
+ ret = decode_regions(hose, gd->fdt_blob, bus->parent->of_offset,
+ bus->of_offset);
+ if (ret) {
+ debug("%s: Cannot decode regions\n", __func__);
+ return ret;
+ }
+ hose->bus = bus;
+ hose->first_busno = 0;
+ hose->last_busno = 0;
+
+ return 0;
+}
+
+static const struct dm_pci_ops sandbox_pci_ops = {
+ .read_config = sandbox_pci_read_config,
+ .write_config = sandbox_pci_write_config,
+};
+
+static const struct udevice_id sandbox_pci_ids[] = {
+ { .compatible = "sandbox,pci" },
+ { }
+};
+
+U_BOOT_DRIVER(pci_sandbox) = {
+ .name = "pci_sandbox",
+ .id = UCLASS_PCI,
+ .of_match = sandbox_pci_ids,
+ .ops = &sandbox_pci_ops,
+ .probe = sandbox_pci_probe,
+ .child_post_bind = sandbox_pci_child_post_bind,
+ .child_pre_probe = sandbox_pci_child_pre_probe,
+ .platdata_auto_alloc_size = sizeof(struct pci_platdata),
+ .per_child_platdata_auto_alloc_size =
+ sizeof(struct pci_child_platdata),
+};
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index ee4b244..d8e6535 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -23,7 +23,6 @@
#define CONFIG_BOOTSTAGE
#define CONFIG_BOOTSTAGE_REPORT
-#define CONFIG_DM
#define CONFIG_CMD_DEMO
#define CONFIG_CMD_DM
#define CONFIG_DM_DEMO
@@ -47,6 +46,10 @@
#define CONFIG_CMD_FDT
#define CONFIG_ANDROID_BOOT_IMAGE
+#define CONFIG_CMD_PCI
+#define CONFIG_PCI_PNP
+#define CONFIG_CMD_IO
+
#define CONFIG_FS_FAT
#define CONFIG_FS_EXT4
#define CONFIG_EXT4_WRITE
diff --git a/include/dm/device.h b/include/dm/device.h
index 9ce95a8..90779e6 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -26,6 +26,9 @@ struct driver_info;
/* DM should init this device prior to relocation */
#define DM_FLAG_PRE_RELOC (1 << 2)
+/* DM is responsible for allocating and freeing parent_platdata */
+#define DM_FLAG_ALLOC_PARENT_PDATA (1 << 3)
+
/**
* struct udevice - An instance of a driver
*
@@ -46,6 +49,7 @@ struct driver_info;
* @driver: The driver used by this device
* @name: Name of device, typically the FDT node name
* @platdata: Configuration data for this device
+ * @parent_platdata: The parent bus's configuration data for this device
* @of_offset: Device tree node offset for this device (- for none)
* @parent: Parent of this device, or NULL for the top level device
* @priv: Private data for this device
@@ -61,9 +65,13 @@ struct driver_info;
* when the device is probed and will be unique within the device's uclass.
*/
struct udevice {
+#ifdef CONFIG_DM_PCI
+ struct udevice *bus;
+#endif
struct driver *driver;
const char *name;
void *platdata;
+ void *parent_platdata;
int of_offset;
struct udevice *parent;
void *priv;
@@ -125,6 +133,7 @@ struct udevice_id {
* @remove: Called to remove a device, i.e. de-activate it
* @unbind: Called to unbind a device from its driver
* @ofdata_to_platdata: Called before probe to decode device tree data
+ * @child_post_bind: Called after a new child has been bound
* @child_pre_probe: Called before a child device is probed. The device has
* memory allocated but it has not yet been probed.
* @child_post_remove: Called after a child device is removed. The device
@@ -144,6 +153,9 @@ struct udevice_id {
* device_probe_child() pass it in. So far the use case for allocating it
* is SPI, but I found that unsatisfactory. Since it is here I will leave it
* until things are clearer.
+ * @per_child_platdata_auto_alloc_size: A bus likes to store information about
+ * its children. If non-zero this is the size of this data, to be allocated
+ * in the child's parent_platdata pointer.
* @ops: Driver-specific operations. This is typically a list of function
* pointers defined by the driver, to implement driver functions required by
* the uclass.
@@ -158,11 +170,13 @@ struct driver {
int (*remove)(struct udevice *dev);
int (*unbind)(struct udevice *dev);
int (*ofdata_to_platdata)(struct udevice *dev);
+ int (*child_post_bind)(struct udevice *dev);
int (*child_pre_probe)(struct udevice *dev);
int (*child_post_remove)(struct udevice *dev);
int priv_auto_alloc_size;
int platdata_auto_alloc_size;
int per_child_auto_alloc_size;
+ int per_child_platdata_auto_alloc_size;
const void *ops; /* driver-specific operations */
uint32_t flags;
};
@@ -182,6 +196,16 @@ struct driver {
void *dev_get_platdata(struct udevice *dev);
/**
+ * dev_get_parent_latdata() - Get the parent platform data for a device
+ *
+ * This checks that dev is not NULL, but no other checks for now
+ *
+ * @dev Device to check
+ * @return parent's platform data, or NULL if none
+ */
+void *dev_get_parent_platdata(struct udevice *dev);
+
+/**
* dev_get_parentdata() - Get the parent data for a device
*
* The parent data is data stored in the device but owned by the parent.
@@ -206,6 +230,14 @@ void *dev_get_parentdata(struct udevice *dev);
void *dev_get_priv(struct udevice *dev);
/**
+ * device_get_uclass_id() - return the uclass ID of a device
+ *
+ * @dev: Device to check
+ * @return uclass ID for the device
+ */
+enum uclass_id device_get_uclass_id(struct udevice *dev);
+
+/**
* device_get_child() - Get the child of a device by index
*
* Returns the numbered child, 0 being the first. This does not use
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index a8944c9..364921e 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -19,6 +19,7 @@ enum uclass_id {
UCLASS_TEST_FDT,
UCLASS_TEST_BUS,
UCLASS_SPI_EMUL, /* sandbox SPI device emulator */
+ UCLASS_PCI_EMUL, /* sandbox PCI device emulator */
UCLASS_SIMPLE_BUS,
/* U-Boot uclasses start here */
@@ -28,6 +29,8 @@ enum uclass_id {
UCLASS_SPI_GENERIC, /* Generic SPI flash target */
UCLASS_SPI_FLASH, /* SPI flash */
UCLASS_CROS_EC, /* Chrome OS EC */
+ UCLASS_PCI, /* PCI bus */
+ UCLASS_PCI_GENERIC, /* Generic PCI bus device */
UCLASS_COUNT,
UCLASS_INVALID = -1,
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index f6ec6d7..2577ae6 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -141,6 +141,8 @@ int uclass_get_device_by_of_offset(enum uclass_id id, int node,
/**
* uclass_first_device() - Get the first device in a uclass
*
+ * The device returned is probed if necessary, and ready for use
+ *
* @id: Uclass ID to look up
* @devp: Returns pointer to the first device in that uclass, or NULL if none
* @return 0 if OK (found or not found), -1 on error
@@ -150,6 +152,8 @@ int uclass_first_device(enum uclass_id id, struct udevice **devp);
/**
* uclass_next_device() - Get the next device in a uclass
*
+ * The device returned is probed if necessary, and ready for use
+ *
* @devp: On entry, pointer to device to lookup. On exit, returns pointer
* to the next device in the same uclass, or NULL if none
* @return 0 if OK (found or not found), -1 on error
diff --git a/include/fdtdec.h b/include/fdtdec.h
index ea92894..01bf82c 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -266,6 +266,17 @@ s32 fdtdec_get_int(const void *blob, int node, const char *prop_name,
s32 default_val);
/**
+ * Get a variable-sized number from a property
+ *
+ * This reads a number from one or more cells.
+ *
+ * @param ptr Pointer to property
+ * @param cells Number of cells containing the number
+ * @return the value in the cells
+ */
+u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells);
+
+/**
* Look up a 64-bit integer property in a node and return it. The property
* must have at least 8 bytes of data (2 cells). The first two cells are
* concatenated to form a 8 bytes value, where the first cell is top half and
diff --git a/include/pci.h b/include/pci.h
index ccda2c5..4412dd3 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -460,8 +460,11 @@ typedef int pci_dev_t;
#define PCI_BUS(d) (((d) >> 16) & 0xff)
#define PCI_DEV(d) (((d) >> 11) & 0x1f)
#define PCI_FUNC(d) (((d) >> 8) & 0x7)
-#define PCI_BDF(b,d,f) ((b) << 16 | (d) << 11 | (f) << 8)
-
+#define PCI_DEVFN(d, f) ((d) << 11 | (f) << 8)
+#define PCI_MASK_BUS(bdf) ((bdf) & 0xffff)
+#define PCI_ADD_BUS(bus, devfn) (((bus) << 16) | (devfn))
+#define PCI_BDF(b, d, f) ((b) << 16 | PCI_DEVFN(d, f))
+#define PCI_VENDEV(v, d) (((v) << 16) | (d))
#define PCI_ANY_ID (~0)
struct pci_device_id {
@@ -495,6 +498,9 @@ extern void pci_cfgfunc_config_device(struct pci_controller* hose, pci_dev_t dev
* Structure of a PCI controller (host bridge)
*/
struct pci_controller {
+#ifdef CONFIG_DM_PCI
+ struct udevice *bus;
+#endif
struct pci_controller *next;
int first_busno;
@@ -511,7 +517,7 @@ struct pci_controller {
struct pci_config_table *config_table;
void (*fixup_irq)(struct pci_controller *, pci_dev_t);
-
+#ifndef CONFIG_DM_PCI
/* Low-level architecture-dependent routines */
int (*read_byte)(struct pci_controller*, pci_dev_t, int where, u8 *);
int (*read_word)(struct pci_controller*, pci_dev_t, int where, u16 *);
@@ -519,6 +525,7 @@ struct pci_controller {
int (*write_byte)(struct pci_controller*, pci_dev_t, int where, u8);
int (*write_word)(struct pci_controller*, pci_dev_t, int where, u16);
int (*write_dword)(struct pci_controller*, pci_dev_t, int where, u32);
+#endif
/* Used by auto config */
struct pci_region *pci_mem, *pci_io, *pci_prefetch;
@@ -530,6 +537,7 @@ struct pci_controller {
void *priv_data;
};
+#ifndef CONFIG_DM_PCI
static inline void pci_set_ops(struct pci_controller *hose,
int (*read_byte)(struct pci_controller*,
pci_dev_t, int where, u8 *),
@@ -550,6 +558,7 @@ static inline void pci_set_ops(struct pci_controller *hose,
hose->write_word = write_word;
hose->write_dword = write_dword;
}
+#endif
#ifdef CONFIG_PCI_INDIRECT_BRIDGE
extern void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data);
@@ -602,12 +611,14 @@ extern int pci_hose_write_config_word(struct pci_controller *hose,
extern int pci_hose_write_config_dword(struct pci_controller *hose,
pci_dev_t dev, int where, u32 val);
+#ifndef CONFIG_DM_PCI
extern int pci_read_config_byte(pci_dev_t dev, int where, u8 *val);
extern int pci_read_config_word(pci_dev_t dev, int where, u16 *val);
extern int pci_read_config_dword(pci_dev_t dev, int where, u32 *val);
extern int pci_write_config_byte(pci_dev_t dev, int where, u8 val);
extern int pci_write_config_word(pci_dev_t dev, int where, u16 val);
extern int pci_write_config_dword(pci_dev_t dev, int where, u32 val);
+#endif
extern int pci_hose_read_config_byte_via_dword(struct pci_controller *hose,
pci_dev_t dev, int where, u8 *val);
@@ -643,8 +654,6 @@ extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
extern pci_dev_t pci_find_device (unsigned int vendor, unsigned int device, int index);
extern pci_dev_t pci_find_devices (struct pci_device_id *ids, int index);
-extern pci_dev_t pci_find_class(int wanted_class, int wanted_sub_code,
- int wanted_prog_if, int index);
extern int pci_hose_config_device(struct pci_controller *hose,
pci_dev_t dev,
@@ -700,5 +709,142 @@ void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
* */
u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum);
+#ifdef CONFIG_DM_PCI
+struct pci_child_platdata {
+ int devfn; /* encoded device & function index */
+ unsigned short vendor;
+ unsigned short device;
+ unsigned int class; /* 3 bytes: (base,sub,prog-if) */
+};
+
+struct pci_platdata {
+ unsigned int busnum;
+ unsigned int devfn; /* encoded device & function index */
+};
+
+enum pci_size_t {
+ PCI_SIZE_8,
+ PCI_SIZE_16,
+ PCI_SIZE_32,
+};
+
+struct udevice;
+
+struct dm_pci_ops {
+ int (*write_config)(struct udevice *bus, pci_dev_t devfn, uint offset,
+ ulong value, enum pci_size_t size);
+ int (*read_config)(struct udevice *bus, pci_dev_t devfn, uint offset,
+ ulong *valuep, enum pci_size_t size);
+};
+
+#define pci_get_ops(dev) ((struct dm_pci_ops *)(dev)->driver->ops)
+
+int pci_bind_bus_devices(struct udevice *bus);
+
+int pci_auto_config_devices(struct udevice *bus);
+
+int pci_bus_read_config(struct udevice *bus, pci_dev_t devfn, int offset,
+ unsigned long *valuep, enum pci_size_t size);
+
+int pci_bus_write_config(struct udevice *bus, pci_dev_t devfn, int offset,
+ unsigned long value, enum pci_size_t size);
+
+int pci_write_config32(pci_dev_t pcidev, int offset, u32 value);
+
+/* Compatibility with old naming */
+static inline int pci_write_config_dword(pci_dev_t pcidev, int offset,
+ u32 value)
+{
+ return pci_write_config32(pcidev, offset, value);
+}
+
+int pci_write_config16(pci_dev_t pcidev, int offset, u16 value);
+
+/* Compatibility with old naming */
+static inline int pci_write_config_word(pci_dev_t pcidev, int offset,
+ u16 value)
+{
+ return pci_write_config16(pcidev, offset, value);
+}
+
+int pci_write_config8(pci_dev_t pcidev, int offset, u8 value);
+
+/* Compatibility with old naming */
+static inline int pci_write_config_byte(pci_dev_t pcidev, int offset,
+ u8 value)
+{
+ return pci_write_config8(pcidev, offset, value);
+}
+
+int pci_read_config32(pci_dev_t pcidev, int offset, u32 *valuep);
+
+/* Compatibility with old naming */
+static inline int pci_read_config_dword(pci_dev_t pcidev, int offset,
+ u32 *valuep)
+{
+ return pci_read_config32(pcidev, offset, valuep);
+}
+
+int pci_read_config16(pci_dev_t pcidev, int offset, u16 *valuep);
+
+/* Compatibility with old naming */
+static inline int pci_read_config_word(pci_dev_t pcidev, int offset,
+ u16 *valuep)
+{
+ return pci_read_config16(pcidev, offset, valuep);
+}
+
+int pci_read_config8(pci_dev_t pcidev, int offset, u8 *valuep);
+
+/* Compatibility with old naming */
+static inline int pci_read_config_byte(pci_dev_t pcidev, int offset,
+ u8 *valuep)
+{
+ return pci_read_config8(pcidev, offset, valuep);
+}
+
+struct dm_pci_emul_ops {
+ /**
+ * get_devfn(): Check which device and function this emulators
+ *
+ * @return the device and function this emulatoes, or -ve on error
+ */
+ int (*get_devfn)(struct udevice *dev);
+
+ int (*read_config)(struct udevice *emul, uint offset, ulong *valuep,
+ enum pci_size_t size);
+
+ int (*write_config)(struct udevice *emul, uint offset, ulong value,
+ enum pci_size_t size);
+ int (*write_io)(struct udevice *dev, unsigned int addr,
+ ulong value, enum pci_size_t size);
+ int (*read_io)(struct udevice *dev, unsigned int addr, ulong *valuep,
+ enum pci_size_t size);
+ int (*map_physmem)(struct udevice *dev, phys_addr_t addr,
+ unsigned long *lenp, void **ptrp);
+ int (*unmap_physmem)(const void *vaddr, unsigned long len,
+ struct udevice *dev);
+};
+
+int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp);
+
+int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn,
+ struct udevice **devp);
+
+#define pci_get_emul_ops(dev) ((struct dm_pci_emul_ops *)(dev)->driver->ops)
+
+int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn,
+ struct udevice **emulp);
+
+int pci_get_ff(enum pci_size_t size);
+
+int pci_bus_find_devices(struct udevice *bus, struct pci_device_id *ids,
+ int *indexp, struct udevice **devp);
+
+int pci_find_device_id(struct pci_device_id *ids, int index,
+ struct udevice **devp);
+
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* _PCI_H */
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 2345df4..b622ba2 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -735,7 +735,7 @@ int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
return 0;
}
-static u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells)
+u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells)
{
u64 number = 0;
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 612aa95..8281779 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -21,4 +21,5 @@ obj-$(CONFIG_DM_GPIO) += gpio.o
obj-$(CONFIG_DM_SPI) += spi.o
obj-$(CONFIG_DM_SPI_FLASH) += sf.o
obj-$(CONFIG_DM_I2C) += i2c.o
+obj-$(CONFIG_DM_PCI) += pci.o
endif
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index cd2c389..3341a08 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -143,12 +143,12 @@ static int dm_test_fdt(struct dm_test_state *dms)
/* These are num_devices compatible root-level device tree nodes */
ut_asserteq(num_devices, list_count_items(&uc->dev_head));
- /* Each should have no platdata / priv */
+ /* Each should have platdata but no priv */
for (i = 0; i < num_devices; i++) {
ret = uclass_find_device(UCLASS_TEST_FDT, i, &dev);
ut_assert(!ret);
ut_assert(!dev_get_priv(dev));
- ut_assert(!dev->platdata);
+ ut_assert(dev->platdata);
}
ut_assertok(dm_check_devices(dms, num_devices));
diff --git a/test/dm/test.dts b/test/dm/test.dts
index 69991a3..af2fb2c 100644
--- a/test/dm/test.dts
+++ b/test/dm/test.dts
@@ -8,6 +8,7 @@
aliases {
console = &uart0;
+ pci0 = &pci;
testfdt6 = "/e-test";
};
@@ -110,6 +111,22 @@
};
};
+ pci: pci-controller {
+ compatible = "sandbox,pci";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000
+ 0x01000000 0 0x20000000 0x20000000 0 0x2000>;
+ pci@1f,0 {
+ compatible = "pci-generic";
+ reg = <0xf800 0 0 0 0>;
+ emul@1f,0 {
+ compatible = "sandbox,swap-case";
+ };
+ };
+ };
+
spi@0 {
#address-cells = <1>;
#size-cells = <0>;
--
2.1.0.rc2.206.gedb03e5
2
2
Supports boot up from NAND flash with software ECC eanbled.
And supports boot up from SD/MMC card with FAT file system.
As the boot from SD/MMC card with FAT file system, the BSS
segment is too big to fit into SRAM, so, use the lds to put
it into SDRAM. So, we need to initialize the SDRAM as soon
as possible. Borrow the low level init code from
<arm/arm/cpu/armv7/lowlevel_init.S> for this purpose.
Signed-off-by: Bo Shen <voice.shen(a)atmel.com>
---
arch/arm/Kconfig | 1 +
arch/arm/cpu/arm926ejs/at91/Makefile | 4 ++
arch/arm/cpu/arm926ejs/at91/spl_lowlevel_init.S | 37 ++++++++++++
arch/arm/cpu/at91-common/spl_at91.c | 10 ++++
arch/arm/cpu/at91-common/u-boot-spl-arm9.lds | 48 +++++++++++++++
board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c | 80 +++++++++++++++++++++++++
configs/at91sam9m10g45ek_mmc_defconfig | 5 +-
configs/at91sam9m10g45ek_nandflash_defconfig | 5 +-
include/configs/at91sam9m10g45ek.h | 64 ++++++++++++++++++++
9 files changed, 250 insertions(+), 4 deletions(-)
create mode 100644 arch/arm/cpu/arm926ejs/at91/spl_lowlevel_init.S
create mode 100644 arch/arm/cpu/at91-common/u-boot-spl-arm9.lds
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5eb1d03..f4788c6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -141,6 +141,7 @@ config TARGET_AT91SAM9263EK
config TARGET_AT91SAM9M10G45EK
bool "Support at91sam9m10g45ek"
select CPU_ARM926EJS
+ select SUPPORT_SPL
config TARGET_AT91SAM9N12EK
bool "Support at91sam9n12ek"
diff --git a/arch/arm/cpu/arm926ejs/at91/Makefile b/arch/arm/cpu/arm926ejs/at91/Makefile
index 698a28d..238434b 100644
--- a/arch/arm/cpu/arm926ejs/at91/Makefile
+++ b/arch/arm/cpu/arm926ejs/at91/Makefile
@@ -25,5 +25,9 @@ obj-y += reset.o
obj-y += timer.o
ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ifdef CONFIG_SPL_BUILD
+obj-y += spl_lowlevel_init.o
+else
obj-y += lowlevel_init.o
endif
+endif
diff --git a/arch/arm/cpu/arm926ejs/at91/spl_lowlevel_init.S b/arch/arm/cpu/arm926ejs/at91/spl_lowlevel_init.S
new file mode 100644
index 0000000..f1b2ec9
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/at91/spl_lowlevel_init.S
@@ -0,0 +1,37 @@
+/*
+ * A lowlevel_init function that sets up the stack to call a C function to
+ * perform further init.
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ * Aneesh V <aneesh(a)ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+ /*
+ * Setup a temporary stack
+ */
+ ldr sp, =CONFIG_SYS_INIT_SP_ADDR
+ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
+
+ ldr r9, =gdata
+
+ /*
+ * Save the old lr(passed in ip) and the current lr to stack
+ */
+ push {ip, lr}
+
+ /*
+ * go setup pll, mux, memory
+ */
+ bl s_init
+ pop {ip, pc}
+ENDPROC(lowlevel_init)
diff --git a/arch/arm/cpu/at91-common/spl_at91.c b/arch/arm/cpu/at91-common/spl_at91.c
index 89f588b..f044117 100644
--- a/arch/arm/cpu/at91-common/spl_at91.c
+++ b/arch/arm/cpu/at91-common/spl_at91.c
@@ -71,7 +71,17 @@ void __weak at91_spl_board_init(void)
{
}
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+__weak void spl_board_init(void)
+{
+}
+#endif
+
+#ifdef CONFIG_SKIP_LOWLEVEL_INIT
void spl_board_init(void)
+#else
+void s_init(void)
+#endif
{
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
diff --git a/arch/arm/cpu/at91-common/u-boot-spl-arm9.lds b/arch/arm/cpu/at91-common/u-boot-spl-arm9.lds
new file mode 100644
index 0000000..6f350a9
--- /dev/null
+++ b/arch/arm/cpu/at91-common/u-boot-spl-arm9.lds
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 Atmel Corporation
+ * Bo Shen <voice.shen(a)atmel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE, \
+ LENGTH = CONFIG_SPL_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
+ LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ .text :
+ {
+ __start = .;
+ *(.vectors)
+ arch/arm/cpu/arm926ejs/start.o (.text*)
+ *(.text*)
+ } >.sram
+
+ . = ALIGN(4);
+ .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
+
+ . = ALIGN(4);
+ .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
+
+ . = ALIGN(4);
+ __image_copy_end = .;
+
+ .end :
+ {
+ *(.__end)
+ } >.sram
+
+ .bss :
+ {
+ . = ALIGN(4);
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_end = .;
+ } >.sdram
+}
diff --git a/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c b/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c
index b807ef9..4289179 100644
--- a/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c
+++ b/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c
@@ -8,6 +8,7 @@
#include <common.h>
#include <asm/io.h>
+#include <asm/arch/clk.h>
#include <asm/arch/at91sam9g45_matrix.h>
#include <asm/arch/at91sam9_smc.h>
#include <asm/arch/at91_common.h>
@@ -15,6 +16,7 @@
#include <asm/arch/gpio.h>
#include <asm/arch/clk.h>
#include <lcd.h>
+#include <linux/mtd/nand.h>
#include <atmel_lcdc.h>
#include <atmel_mci.h>
#if defined(CONFIG_RESET_PHY_R) && defined(CONFIG_MACB)
@@ -71,6 +73,84 @@ void at91sam9m10g45ek_nand_hw_init(void)
}
#endif
+#if defined(CONFIG_SPL_BUILD)
+#include <spl.h>
+#include <nand.h>
+
+void at91_spl_board_init(void)
+{
+ /*
+ * On the at91sam9m10g45ek board, the chip wm9711 stays in the
+ * test mode, so it needs do some action to exit test mode.
+ */
+ at91_periph_clk_enable(ATMEL_ID_PIODE);
+ at91_set_gpio_output(AT91_PIN_PD7, 0);
+ at91_set_gpio_output(AT91_PIN_PD8, 0);
+ at91_set_pio_pullup(AT91_PIO_PORTD, 7, 1);
+ at91_set_pio_pullup(AT91_PIO_PORTD, 8, 1);
+
+#ifdef CONFIG_SYS_USE_MMC
+ at91_mci_hw_init();
+#elif CONFIG_SYS_USE_NANDFLASH
+ at91sam9m10g45ek_nand_hw_init();
+#endif
+}
+
+#include <asm/arch/atmel_mpddrc.h>
+static void ddr2_conf(struct atmel_mpddr *ddr2)
+{
+ ddr2->md = (ATMEL_MPDDRC_MD_DBW_16_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM);
+
+ ddr2->cr = (ATMEL_MPDDRC_CR_NC_COL_10 |
+ ATMEL_MPDDRC_CR_NR_ROW_14 |
+ ATMEL_MPDDRC_CR_DQMS_SHARED |
+ ATMEL_MPDDRC_CR_CAS_DDR_CAS3);
+
+ ddr2->rtr = 0x24b;
+
+ ddr2->tpr0 = (6 << ATMEL_MPDDRC_TPR0_TRAS_OFFSET |/* 6*7.5 = 45 ns */
+ 2 << ATMEL_MPDDRC_TPR0_TRCD_OFFSET |/* 2*7.5 = 15 ns */
+ 2 << ATMEL_MPDDRC_TPR0_TWR_OFFSET | /* 2*7.5 = 15 ns */
+ 8 << ATMEL_MPDDRC_TPR0_TRC_OFFSET | /* 8*7.5 = 60 ns */
+ 2 << ATMEL_MPDDRC_TPR0_TRP_OFFSET | /* 2*7.5 = 15 ns */
+ 1 << ATMEL_MPDDRC_TPR0_TRRD_OFFSET | /* 1*7.5= 7.5 ns*/
+ 1 << ATMEL_MPDDRC_TPR0_TWTR_OFFSET | /* 1 clk cycle */
+ 2 << ATMEL_MPDDRC_TPR0_TMRD_OFFSET); /* 2 clk cycles */
+
+ ddr2->tpr1 = (2 << ATMEL_MPDDRC_TPR1_TXP_OFFSET | /* 2*7.5 = 15 ns */
+ 200 << ATMEL_MPDDRC_TPR1_TXSRD_OFFSET |
+ 16 << ATMEL_MPDDRC_TPR1_TXSNR_OFFSET |
+ 14 << ATMEL_MPDDRC_TPR1_TRFC_OFFSET);
+
+ ddr2->tpr2 = (1 << ATMEL_MPDDRC_TPR2_TRTP_OFFSET |
+ 0 << ATMEL_MPDDRC_TPR2_TRPA_OFFSET |
+ 7 << ATMEL_MPDDRC_TPR2_TXARDS_OFFSET |
+ 2 << ATMEL_MPDDRC_TPR2_TXARD_OFFSET);
+}
+
+void mem_init(void)
+{
+ struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+ struct at91_matrix *mat = (struct at91_matrix *)ATMEL_BASE_MATRIX;
+ struct atmel_mpddr ddr2;
+ unsigned long csa;
+
+ ddr2_conf(&ddr2);
+
+ /* enable DDR2 clock */
+ writel(0x4, &pmc->scer);
+
+ /* Chip select 1 is for DDR2/SDRAM */
+ csa = readl(&mat->ebicsa);
+ csa |= AT91_MATRIX_EBI_CS1A_SDRAMC;
+ csa &= ~AT91_MATRIX_EBI_VDDIOMSEL_3_3V;
+ writel(csa, &mat->ebicsa);
+
+ /* DDRAM2 Controller initialize */
+ ddr2_init(ATMEL_BASE_CS6, &ddr2);
+}
+#endif
+
#ifdef CONFIG_CMD_USB
static void at91sam9m10g45ek_usb_hw_init(void)
{
diff --git a/configs/at91sam9m10g45ek_mmc_defconfig b/configs/at91sam9m10g45ek_mmc_defconfig
index 1681bc8..30d632d 100644
--- a/configs/at91sam9m10g45ek_mmc_defconfig
+++ b/configs/at91sam9m10g45ek_mmc_defconfig
@@ -1,3 +1,4 @@
+CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9M10G45,SYS_USE_MMC"
-CONFIG_ARM=y
-CONFIG_TARGET_AT91SAM9M10G45EK=y
++S:CONFIG_ARM=y
++S:CONFIG_TARGET_AT91SAM9M10G45EK=y
diff --git a/configs/at91sam9m10g45ek_nandflash_defconfig b/configs/at91sam9m10g45ek_nandflash_defconfig
index 61ae56e..b3de8a1 100644
--- a/configs/at91sam9m10g45ek_nandflash_defconfig
+++ b/configs/at91sam9m10g45ek_nandflash_defconfig
@@ -1,3 +1,4 @@
+CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9M10G45,SYS_USE_NANDFLASH"
-CONFIG_ARM=y
-CONFIG_TARGET_AT91SAM9M10G45EK=y
++S:CONFIG_ARM=y
++S:CONFIG_TARGET_AT91SAM9M10G45EK=y
diff --git a/include/configs/at91sam9m10g45ek.h b/include/configs/at91sam9m10g45ek.h
index db5d5ea..cb9a8f0 100644
--- a/include/configs/at91sam9m10g45ek.h
+++ b/include/configs/at91sam9m10g45ek.h
@@ -26,7 +26,9 @@
#define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG
+#ifndef CONFIG_SPL_BUILD
#define CONFIG_SKIP_LOWLEVEL_INIT
+#endif
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_DISPLAY_CPUINFO
@@ -98,8 +100,12 @@
#define CONFIG_SYS_SDRAM_BASE ATMEL_BASE_CS6
#define CONFIG_SYS_SDRAM_SIZE 0x08000000
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_INIT_SP_ADDR 0x310000
+#else
#define CONFIG_SYS_INIT_SP_ADDR \
(CONFIG_SYS_SDRAM_BASE + 4 * 1024 - GENERATED_GBL_DATA_SIZE)
+#endif
/* NAND flash */
#ifdef CONFIG_CMD_NAND
@@ -203,4 +209,62 @@
*/
#define CONFIG_SYS_MALLOC_LEN ROUND(3 * CONFIG_ENV_SIZE + 128*1024, 0x1000)
+/* Defines for SPL */
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_TEXT_BASE 0x300000
+#define CONFIG_SPL_MAX_SIZE 0x010000
+
+#define CONFIG_SPL_BSS_START_ADDR 0x70000000
+#define CONFIG_SPL_BSS_MAX_SIZE 0x00080000
+#define CONFIG_SYS_SPL_MALLOC_START 0x70080000
+#define CONFIG_SYS_SPL_MALLOC_SIZE 0x00080000
+
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
+
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SYS_MONITOR_LEN 0x80000
+
+#ifdef CONFIG_SYS_USE_MMC
+#define CONFIG_SPL_LDSCRIPT arch/arm/cpu/at91-common/u-boot-spl-arm9.lds
+#define CONFIG_SPL_MMC_SUPPORT
+#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x400
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x200
+#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1
+#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img"
+#define CONFIG_SPL_FAT_SUPPORT
+#define CONFIG_SPL_LIBDISK_SUPPORT
+
+#elif CONFIG_SYS_USE_NANDFLASH
+#define CONFIG_SYS_NAND_ENABLE_PIN_SPL (2*32 + 14)
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_ECC
+#define CONFIG_SPL_NAND_SOFTECC
+#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x40000
+#define CONFIG_SYS_NAND_U_BOOT_SIZE 0x80000
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+
+#define CONFIG_SYS_NAND_PAGE_SIZE 0x800
+#define CONFIG_SYS_NAND_BLOCK_SIZE 0x20000
+#define CONFIG_SYS_NAND_PAGE_COUNT 64
+#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS
+#define CONFIG_SYS_NAND_ECCSIZE 256
+#define CONFIG_SYS_NAND_ECCBYTES 3
+#define CONFIG_SYS_NAND_OOBSIZE 64
+#define CONFIG_SYS_NAND_ECCPOS { 40, 41, 42, 43, 44, 45, 46, 47, \
+ 48, 49, 50, 51, 52, 53, 54, 55, \
+ 56, 57, 58, 59, 60, 61, 62, 63, }
+#endif
+
+#define CONFIG_SPL_ATMEL_SIZE
+#define CONFIG_SYS_MASTER_CLOCK 132096000
+#define CONFIG_SYS_AT91_PLLA 0x20c73f03
+#define CONFIG_SYS_MCKR 0x1301
+#define CONFIG_SYS_MCKR_CSS 0x1302
+
+#define ATMEL_BASE_MPDDRC ATMEL_BASE_DDRSDRC0
#endif
--
2.1.0.24.g4109c28
2
3
This serie of patch prepare SHEEVAPLUG for latest kernels
Gérald Kerma (5):
SHEEVAPLUG : FIX typo
SHEEVAPLUG : FIX multiple defines
SHEEVAPLUG : ADD generic board define
SHEEVAPLUG : ADD CONFIG_CMD_FAT
SHEEVAPLUG : ADD FDT support
include/configs/sheevaplug.h | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
--
2.1.3
3
24