aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2017-02-23 10:12:41 -0500
committerTom Rini <trini@konsulko.com>2017-02-23 10:12:41 -0500
commitd38de7cb03adf88e18c05d840c2528b7a5af2f9b (patch)
tree35be69932e53e4c58260af58ae841a3d1a2523b6
parentb24cf8540a85a9bf97975aadd6a7542f166c78a3 (diff)
parentbc647958047cd03193e19cd8c08a6771fea828b7 (diff)
Merge branch 'master' of git://git.denx.de/u-boot-uniphier
- Fix regressions caused by the previous reworks - Add pin configuration support - Re-work SPL code - Update DRAM and PLL setup code - Enable needed configs, disable unneeded configs
-rw-r--r--arch/arm/dts/uniphier-ld11-ref.dts4
-rw-r--r--arch/arm/dts/uniphier-ld20-ref.dts4
-rw-r--r--arch/arm/mach-uniphier/Makefile4
-rw-r--r--arch/arm/mach-uniphier/bcu/bcu-ld4.c2
-rw-r--r--arch/arm/mach-uniphier/bcu/bcu-sld3.c2
-rw-r--r--arch/arm/mach-uniphier/board_init.c1
-rw-r--r--arch/arm/mach-uniphier/board_late_init.c4
-rw-r--r--arch/arm/mach-uniphier/boards.c42
-rw-r--r--arch/arm/mach-uniphier/boot-device/Makefile19
-rw-r--r--arch/arm/mach-uniphier/boot-device/boot-device-ld11.c (renamed from arch/arm/mach-uniphier/boot-mode/boot-mode-ld20.c)52
-rw-r--r--arch/arm/mach-uniphier/boot-device/boot-device-ld4.c (renamed from arch/arm/mach-uniphier/boot-mode/boot-mode-ld4.c)36
-rw-r--r--arch/arm/mach-uniphier/boot-device/boot-device-pro5.c (renamed from arch/arm/mach-uniphier/boot-mode/boot-mode-pro5.c)36
-rw-r--r--arch/arm/mach-uniphier/boot-device/boot-device-pxs2.c (renamed from arch/arm/mach-uniphier/boot-mode/boot-mode-pxs2.c)37
-rw-r--r--arch/arm/mach-uniphier/boot-device/boot-device-sld3.c (renamed from arch/arm/mach-uniphier/boot-mode/boot-mode-sld3.c)36
-rw-r--r--arch/arm/mach-uniphier/boot-device/boot-device.c206
-rw-r--r--arch/arm/mach-uniphier/boot-device/boot-device.h35
-rw-r--r--arch/arm/mach-uniphier/boot-device/spl_board.c262
-rw-r--r--arch/arm/mach-uniphier/boot-mode/Makefile21
-rw-r--r--arch/arm/mach-uniphier/boot-mode/boot-device.h29
-rw-r--r--arch/arm/mach-uniphier/boot-mode/boot-mode.c140
-rw-r--r--arch/arm/mach-uniphier/boot-mode/cmd_pinmon.c59
-rw-r--r--arch/arm/mach-uniphier/boot-mode/spl_board.c125
-rw-r--r--arch/arm/mach-uniphier/clk/Makefile2
-rw-r--r--arch/arm/mach-uniphier/clk/clk-ld11.c8
-rw-r--r--arch/arm/mach-uniphier/clk/clk-ld20.c17
-rw-r--r--arch/arm/mach-uniphier/clk/pll-base-ld20.c21
-rw-r--r--arch/arm/mach-uniphier/clk/pll-ld11.c2
-rw-r--r--arch/arm/mach-uniphier/clk/pll.h1
-rw-r--r--arch/arm/mach-uniphier/dram/umc-ld11.c2
-rw-r--r--arch/arm/mach-uniphier/dram/umc-ld20.c25
-rw-r--r--arch/arm/mach-uniphier/dram/umc-pxs2.c14
-rw-r--r--arch/arm/mach-uniphier/dram_init.c64
-rw-r--r--arch/arm/mach-uniphier/init.h9
-rw-r--r--arch/arm/mach-uniphier/memconf.c2
-rw-r--r--arch/arm/mach-uniphier/micro-support-card.c11
-rw-r--r--arch/arm/mach-uniphier/mmc-boot-mode.c34
-rw-r--r--arch/arm/mach-uniphier/mmc-first-dev.c46
-rw-r--r--arch/arm/mach-uniphier/spl_board_init.c4
-rw-r--r--configs/uniphier_ld11_defconfig5
-rw-r--r--configs/uniphier_ld20_defconfig5
-rw-r--r--configs/uniphier_ld4_sld8_defconfig5
-rw-r--r--configs/uniphier_pro4_defconfig5
-rw-r--r--configs/uniphier_pxs2_ld6b_defconfig5
-rw-r--r--configs/uniphier_sld3_defconfig5
-rw-r--r--configs/uniphier_v8_defconfig5
-rw-r--r--doc/README.uniphier6
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-core.c134
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c3
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c3
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c1
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c3
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c1
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier.h1
-rw-r--r--include/configs/uniphier.h2
54 files changed, 948 insertions, 659 deletions
diff --git a/arch/arm/dts/uniphier-ld11-ref.dts b/arch/arm/dts/uniphier-ld11-ref.dts
index ea11198976..7693bf2736 100644
--- a/arch/arm/dts/uniphier-ld11-ref.dts
+++ b/arch/arm/dts/uniphier-ld11-ref.dts
@@ -71,7 +71,3 @@
&pinctrl_uart0 {
u-boot,dm-pre-reloc;
};
-
-&pinctrl_system_bus {
- u-boot,dm-pre-reloc;
-};
diff --git a/arch/arm/dts/uniphier-ld20-ref.dts b/arch/arm/dts/uniphier-ld20-ref.dts
index 044e000749..41ee07ebab 100644
--- a/arch/arm/dts/uniphier-ld20-ref.dts
+++ b/arch/arm/dts/uniphier-ld20-ref.dts
@@ -59,7 +59,3 @@
&pinctrl_uart0 {
u-boot,dm-pre-reloc;
};
-
-&pinctrl_system_bus {
- u-boot,dm-pre-reloc;
-};
diff --git a/arch/arm/mach-uniphier/Makefile b/arch/arm/mach-uniphier/Makefile
index 166b41f217..124a1c6e98 100644
--- a/arch/arm/mach-uniphier/Makefile
+++ b/arch/arm/mach-uniphier/Makefile
@@ -8,6 +8,7 @@ obj-y += boards.o
obj-y += spl_board_init.o
obj-y += memconf.o
obj-y += bcu/
+obj-$(CONFIG_SPL_MMC_SUPPORT) += mmc-boot-mode.o
else
@@ -19,11 +20,12 @@ obj-y += reset.o
obj-$(CONFIG_MICRO_SUPPORT_CARD) += sbc/ micro-support-card.o
obj-y += pinctrl-glue.o
+obj-$(CONFIG_MMC) += mmc-first-dev.o
endif
obj-y += soc-info.o
-obj-y += boot-mode/
+obj-y += boot-device/
obj-y += clk/
obj-y += dram/
diff --git a/arch/arm/mach-uniphier/bcu/bcu-ld4.c b/arch/arm/mach-uniphier/bcu/bcu-ld4.c
index 75578806f0..a16b24e7e5 100644
--- a/arch/arm/mach-uniphier/bcu/bcu-ld4.c
+++ b/arch/arm/mach-uniphier/bcu/bcu-ld4.c
@@ -24,7 +24,7 @@ void uniphier_ld4_bcu_init(const struct uniphier_board_data *bd)
writel(0x11111111, BCSCR5); /* 0xe0000000-0Xffffffff: IPPC/IPPD-bus */
/* Specify DDR channel */
- shift = (bd->dram_ch[1].base - bd->dram_ch[0].base) / 0x04000000 * 4;
+ shift = bd->dram_ch[0].size / 0x04000000 * 4;
writel(ch(shift), BCIPPCCHR2); /* 0x80000000-0x9fffffff */
shift -= 32;
diff --git a/arch/arm/mach-uniphier/bcu/bcu-sld3.c b/arch/arm/mach-uniphier/bcu/bcu-sld3.c
index 64efd37657..99b318fd8f 100644
--- a/arch/arm/mach-uniphier/bcu/bcu-sld3.c
+++ b/arch/arm/mach-uniphier/bcu/bcu-sld3.c
@@ -28,7 +28,7 @@ void uniphier_sld3_bcu_init(const struct uniphier_board_data *bd)
writel(0x24440000, BCSCR5);
/* Specify DDR channel */
- shift = (bd->dram_ch[1].base - bd->dram_ch[0].base) / 0x04000000 * 4;
+ shift = bd->dram_ch[0].size / 0x04000000 * 4;
writel(ch(shift), BCIPPCCHR2); /* 0x80000000-0x9fffffff */
shift -= 32;
diff --git a/arch/arm/mach-uniphier/board_init.c b/arch/arm/mach-uniphier/board_init.c
index e89a4c59e2..2564a02a62 100644
--- a/arch/arm/mach-uniphier/board_init.c
+++ b/arch/arm/mach-uniphier/board_init.c
@@ -165,6 +165,7 @@ static const struct uniphier_initdata uniphier_initdata[] = {
.nand_2cs = false,
.sbc_init = uniphier_ld11_sbc_init,
.pll_init = uniphier_ld20_pll_init,
+ .clk_init = uniphier_ld20_clk_init,
.misc_init = uniphier_ld20_misc_init,
},
#endif
diff --git a/arch/arm/mach-uniphier/board_late_init.c b/arch/arm/mach-uniphier/board_late_init.c
index ece761fb94..92dd6105e4 100644
--- a/arch/arm/mach-uniphier/board_late_init.c
+++ b/arch/arm/mach-uniphier/board_late_init.c
@@ -13,7 +13,7 @@
#include <linux/io.h>
#include <../drivers/mtd/nand/denali.h>
-#include "boot-mode/boot-device.h"
+#include "init.h"
static void nand_denali_wp_disable(void)
{
@@ -62,7 +62,7 @@ int board_late_init(void)
{
puts("MODE: ");
- switch (spl_boot_device_raw()) {
+ switch (uniphier_boot_device_raw()) {
case BOOT_DEVICE_MMC1:
printf("eMMC Boot\n");
setenv("bootmode", "emmcboot");
diff --git a/arch/arm/mach-uniphier/boards.c b/arch/arm/mach-uniphier/boards.c
index 059645171a..db7d192d68 100644
--- a/arch/arm/mach-uniphier/boards.c
+++ b/arch/arm/mach-uniphier/boards.c
@@ -16,36 +16,30 @@ DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_ARCH_UNIPHIER_SLD3)
static const struct uniphier_board_data uniphier_sld3_data = {
.dram_freq = 1600,
- .dram_nr_ch = 3,
.dram_ch[0] = {
- .base = 0x80000000,
.size = 0x20000000,
.width = 32,
},
.dram_ch[1] = {
- .base = 0xc0000000,
.size = 0x20000000,
.width = 16,
},
.dram_ch[2] = {
- .base = 0xc0000000,
.size = 0x10000000,
.width = 16,
},
+ .flags = UNIPHIER_BD_DRAM_SPARSE,
};
#endif
#if defined(CONFIG_ARCH_UNIPHIER_LD4)
static const struct uniphier_board_data uniphier_ld4_data = {
.dram_freq = 1600,
- .dram_nr_ch = 2,
.dram_ch[0] = {
- .base = 0x80000000,
.size = 0x10000000,
.width = 16,
},
.dram_ch[1] = {
- .base = 0x90000000,
.size = 0x10000000,
.width = 16,
},
@@ -57,14 +51,11 @@ static const struct uniphier_board_data uniphier_ld4_data = {
/* 1GB RAM board */
static const struct uniphier_board_data uniphier_pro4_data = {
.dram_freq = 1600,
- .dram_nr_ch = 2,
.dram_ch[0] = {
- .base = 0x80000000,
.size = 0x20000000,
.width = 32,
},
.dram_ch[1] = {
- .base = 0xa0000000,
.size = 0x20000000,
.width = 32,
},
@@ -73,14 +64,11 @@ static const struct uniphier_board_data uniphier_pro4_data = {
/* 2GB RAM board */
static const struct uniphier_board_data uniphier_pro4_2g_data = {
.dram_freq = 1600,
- .dram_nr_ch = 2,
.dram_ch[0] = {
- .base = 0x80000000,
.size = 0x40000000,
.width = 32,
},
.dram_ch[1] = {
- .base = 0xc0000000,
.size = 0x40000000,
.width = 32,
},
@@ -90,14 +78,11 @@ static const struct uniphier_board_data uniphier_pro4_2g_data = {
#if defined(CONFIG_ARCH_UNIPHIER_SLD8)
static const struct uniphier_board_data uniphier_sld8_data = {
.dram_freq = 1333,
- .dram_nr_ch = 2,
.dram_ch[0] = {
- .base = 0x80000000,
.size = 0x10000000,
.width = 16,
},
.dram_ch[1] = {
- .base = 0x90000000,
.size = 0x10000000,
.width = 16,
},
@@ -108,14 +93,11 @@ static const struct uniphier_board_data uniphier_sld8_data = {
#if defined(CONFIG_ARCH_UNIPHIER_PRO5)
static const struct uniphier_board_data uniphier_pro5_data = {
.dram_freq = 1866,
- .dram_nr_ch = 2,
.dram_ch[0] = {
- .base = 0x80000000,
.size = 0x20000000,
.width = 32,
},
.dram_ch[1] = {
- .base = 0xa0000000,
.size = 0x20000000,
.width = 32,
},
@@ -125,19 +107,15 @@ static const struct uniphier_board_data uniphier_pro5_data = {
#if defined(CONFIG_ARCH_UNIPHIER_PXS2)
static const struct uniphier_board_data uniphier_pxs2_data = {
.dram_freq = 2133,
- .dram_nr_ch = 3,
.dram_ch[0] = {
- .base = 0x80000000,
.size = 0x40000000,
.width = 32,
},
.dram_ch[1] = {
- .base = 0xc0000000,
.size = 0x20000000,
.width = 32,
},
.dram_ch[2] = {
- .base = 0xe0000000,
.size = 0x20000000,
.width = 16,
},
@@ -147,19 +125,15 @@ static const struct uniphier_board_data uniphier_pxs2_data = {
#if defined(CONFIG_ARCH_UNIPHIER_LD6B)
static const struct uniphier_board_data uniphier_ld6b_data = {
.dram_freq = 1866,
- .dram_nr_ch = 3,
.dram_ch[0] = {
- .base = 0x80000000,
.size = 0x40000000,
.width = 32,
},
.dram_ch[1] = {
- .base = 0xc0000000,
.size = 0x20000000,
.width = 32,
},
.dram_ch[2] = {
- .base = 0xe0000000,
.size = 0x20000000,
.width = 16,
},
@@ -169,14 +143,11 @@ static const struct uniphier_board_data uniphier_ld6b_data = {
#if defined(CONFIG_ARCH_UNIPHIER_LD11)
static const struct uniphier_board_data uniphier_ld11_data = {
.dram_freq = 1600,
- .dram_nr_ch = 2,
.dram_ch[0] = {
- .base = 0x80000000,
.size = 0x20000000,
.width = 16,
},
.dram_ch[1] = {
- .base = 0xa0000000,
.size = 0x20000000,
.width = 16,
},
@@ -186,19 +157,15 @@ static const struct uniphier_board_data uniphier_ld11_data = {
#if defined(CONFIG_ARCH_UNIPHIER_LD20)
static const struct uniphier_board_data uniphier_ld20_ref_data = {
.dram_freq = 1866,
- .dram_nr_ch = 3,
.dram_ch[0] = {
- .base = 0x80000000,
.size = 0x40000000,
.width = 32,
},
.dram_ch[1] = {
- .base = 0xc0000000,
.size = 0x40000000,
.width = 32,
},
.dram_ch[2] = {
- .base = 0x100000000UL,
.size = 0x40000000,
.width = 32,
},
@@ -207,19 +174,15 @@ static const struct uniphier_board_data uniphier_ld20_ref_data = {
static const struct uniphier_board_data uniphier_ld20_data = {
.dram_freq = 1866,
- .dram_nr_ch = 3,
.dram_ch[0] = {
- .base = 0x80000000,
.size = 0x40000000,
.width = 32,
},
.dram_ch[1] = {
- .base = 0xc0000000,
.size = 0x40000000,
.width = 32,
},
.dram_ch[2] = {
- .base = 0x100000000UL,
.size = 0x40000000,
.width = 32,
},
@@ -228,14 +191,11 @@ static const struct uniphier_board_data uniphier_ld20_data = {
static const struct uniphier_board_data uniphier_ld21_data = {
.dram_freq = 1866,
- .dram_nr_ch = 2,
.dram_ch[0] = {
- .base = 0x80000000,
.size = 0x20000000,
.width = 32,
},
.dram_ch[1] = {
- .base = 0xc0000000,
.size = 0x40000000,
.width = 32,
},
diff --git a/arch/arm/mach-uniphier/boot-device/Makefile b/arch/arm/mach-uniphier/boot-device/Makefile
new file mode 100644
index 0000000000..a54d2acb10
--- /dev/null
+++ b/arch/arm/mach-uniphier/boot-device/Makefile
@@ -0,0 +1,19 @@
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += boot-device.o
+
+obj-$(CONFIG_ARCH_UNIPHIER_SLD3) += boot-device-sld3.o
+obj-$(CONFIG_ARCH_UNIPHIER_LD4) += boot-device-ld4.o
+obj-$(CONFIG_ARCH_UNIPHIER_PRO4) += boot-device-ld4.o
+obj-$(CONFIG_ARCH_UNIPHIER_SLD8) += boot-device-ld4.o
+obj-$(CONFIG_ARCH_UNIPHIER_PRO5) += boot-device-pro5.o
+obj-$(CONFIG_ARCH_UNIPHIER_PXS2) += boot-device-pxs2.o
+obj-$(CONFIG_ARCH_UNIPHIER_LD6B) += boot-device-pxs2.o
+obj-$(CONFIG_ARCH_UNIPHIER_LD11) += boot-device-ld11.o
+obj-$(CONFIG_ARCH_UNIPHIER_LD20) += boot-device-ld11.o
+
+ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_SPL_BOARD_LOAD_IMAGE) += spl_board.o
+endif
diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode-ld20.c b/arch/arm/mach-uniphier/boot-device/boot-device-ld11.c
index 2992fd757f..f1a467c831 100644
--- a/arch/arm/mach-uniphier/boot-mode/boot-mode-ld20.c
+++ b/arch/arm/mach-uniphier/boot-device/boot-device-ld11.c
@@ -8,12 +8,11 @@
#include <common.h>
#include <spl.h>
#include <linux/io.h>
+#include <linux/kernel.h>
-#include "../sg-regs.h"
-#include "../soc-info.h"
#include "boot-device.h"
-static struct boot_device_info boot_device_table[] = {
+const struct uniphier_boot_device uniphier_ld11_boot_device_table[] = {
{BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 128KB, Addr 4)"},
{BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 128KB, Addr 4)"},
{BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 128KB, Addr 5)"},
@@ -48,48 +47,23 @@ static struct boot_device_info boot_device_table[] = {
{BOOT_DEVICE_NOR, "NOR (XECS1)"},
};
-static int get_boot_mode_sel(void)
+const unsigned uniphier_ld11_boot_device_count =
+ ARRAY_SIZE(uniphier_ld11_boot_device_table);
+
+int uniphier_ld11_boot_device_is_usb(u32 pinmon)
{
- return (readl(SG_PINMON0) >> 1) & 0x1f;
+ return !!(~pinmon & 0x00000080);
}
-u32 uniphier_ld20_boot_device(void)
+int uniphier_ld20_boot_device_is_usb(u32 pinmon)
{
- int boot_mode;
- u32 usb_boot_mask;
-
- switch (uniphier_get_soc_id()) {
-#if defined(CONFIG_ARCH_UNIPHIER_LD11)
- case UNIPHIER_LD11_ID:
- usb_boot_mask = 0x00000080;
- break;
-#endif
-#if defined(CONFIG_ARCH_UNIPHIER_LD20)
- case UNIPHIER_LD20_ID:
- usb_boot_mask = 0x00000780;
- break;
-#endif
- default:
- BUG();
- }
-
- if (~readl(SG_PINMON0) & usb_boot_mask)
- return BOOT_DEVICE_USB;
-
- boot_mode = get_boot_mode_sel();
-
- return boot_device_table[boot_mode].type;
+ return !!(~pinmon & 0x00000780);
}
-void uniphier_ld20_boot_mode_show(void)
+unsigned int uniphier_ld11_boot_device_fixup(unsigned int mode)
{
- int mode_sel, i;
-
- mode_sel = get_boot_mode_sel();
-
- puts("Boot Mode Pin:\n");
+ if (mode == BOOT_DEVICE_MMC1 || mode == BOOT_DEVICE_USB)
+ mode = BOOT_DEVICE_BOARD;
- for (i = 0; i < ARRAY_SIZE(boot_device_table); i++)
- printf(" %c %02x %s\n", i == mode_sel ? '*' : ' ', i,
- boot_device_table[i].info);
+ return mode;
}
diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode-ld4.c b/arch/arm/mach-uniphier/boot-device/boot-device-ld4.c
index b066ed9c4b..b5d23210b1 100644
--- a/arch/arm/mach-uniphier/boot-mode/boot-mode-ld4.c
+++ b/arch/arm/mach-uniphier/boot-device/boot-device-ld4.c
@@ -1,5 +1,7 @@
/*
- * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2014 Panasonic Corporation
+ * Copyright (C) 2015-2017 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -7,11 +9,11 @@
#include <common.h>
#include <spl.h>
#include <linux/io.h>
+#include <linux/kernel.h>
-#include "../sg-regs.h"
#include "boot-device.h"
-struct boot_device_info boot_device_table[] = {
+const struct uniphier_boot_device uniphier_ld4_boot_device_table[] = {
{BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 128KB, Addr 4)"},
{BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 128KB, Addr 5)"},
{BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 128KB, Addr 5)"},
@@ -46,29 +48,5 @@ struct boot_device_info boot_device_table[] = {
{BOOT_DEVICE_NOR, "NOR (XECS0)"},
};
-static int get_boot_mode_sel(void)
-{
- return (readl(SG_PINMON0) >> 1) & 0x1f;
-}
-
-u32 uniphier_ld4_boot_device(void)
-{
- int boot_mode;
-
- boot_mode = get_boot_mode_sel();
-
- return boot_device_table[boot_mode].type;
-}
-
-void uniphier_ld4_boot_mode_show(void)
-{
- int mode_sel, i;
-
- mode_sel = get_boot_mode_sel();
-
- puts("Boot Mode Pin:\n");
-
- for (i = 0; i < ARRAY_SIZE(boot_device_table); i++)
- printf(" %c %02x %s\n", i == mode_sel ? '*' : ' ', i,
- boot_device_table[i].info);
-}
+const unsigned uniphier_ld4_boot_device_count =
+ ARRAY_SIZE(uniphier_ld4_boot_device_table);
diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode-pro5.c b/arch/arm/mach-uniphier/boot-device/boot-device-pro5.c
index 450c43bba5..47221ee61d 100644
--- a/arch/arm/mach-uniphier/boot-mode/boot-mode-pro5.c
+++ b/arch/arm/mach-uniphier/boot-device/boot-device-pro5.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2017 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -7,11 +8,11 @@
#include <common.h>
#include <spl.h>
#include <linux/io.h>
+#include <linux/kernel.h>
-#include "../sg-regs.h"
#include "boot-device.h"
-static struct boot_device_info boot_device_table[] = {
+const struct uniphier_boot_device uniphier_pro5_boot_device_table[] = {
{BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 128KB, Addr 5)"},
{BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, EraseSize 128KB, Addr 5)"},
{BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 256KB, Addr 5)"},
@@ -44,32 +45,7 @@ static struct boot_device_info boot_device_table[] = {
{BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 128KB, Addr 5)"},
{BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 256KB, Addr 5)"},
{BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 256KB, Addr 5)"},
- { /* sentinel */ }
};
-static int get_boot_mode_sel(void)
-{
- return (readl(SG_PINMON0) >> 1) & 0x1f;
-}
-
-u32 uniphier_pro5_boot_device(void)
-{
- int boot_mode;
-
- boot_mode = get_boot_mode_sel();
-
- return boot_device_table[boot_mode].type;
-}
-
-void uniphier_pro5_boot_mode_show(void)
-{
- int mode_sel, i;
-
- mode_sel = get_boot_mode_sel();
-
- puts("Boot Mode Pin:\n");
-
- for (i = 0; i < ARRAY_SIZE(boot_device_table); i++)
- printf(" %c %02x %s\n", i == mode_sel ? '*' : ' ', i,
- boot_device_table[i].info);
-}
+const unsigned uniphier_pro5_boot_device_count =
+ ARRAY_SIZE(uniphier_pro5_boot_device_table);
diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode-pxs2.c b/arch/arm/mach-uniphier/boot-device/boot-device-pxs2.c
index 20ff7731d5..20a9511549 100644
--- a/arch/arm/mach-uniphier/boot-mode/boot-mode-pxs2.c
+++ b/arch/arm/mach-uniphier/boot-device/boot-device-pxs2.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2017 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -7,11 +8,11 @@
#include <common.h>
#include <spl.h>
#include <linux/io.h>
+#include <linux/kernel.h>
-#include "../sg-regs.h"
#include "boot-device.h"
-static struct boot_device_info boot_device_table[] = {
+const struct uniphier_boot_device uniphier_pxs2_boot_device_table[] = {
{BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 128KB, Addr 4)"},
{BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 128KB, Addr 5)"},
{BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 128KB, Addr 5)"},
@@ -46,32 +47,18 @@ static struct boot_device_info boot_device_table[] = {
{BOOT_DEVICE_NONE, "Reserved"},
};
-static int get_boot_mode_sel(void)
-{
- return (readl(SG_PINMON0) >> 1) & 0x1f;
-}
+const unsigned uniphier_pxs2_boot_device_count =
+ ARRAY_SIZE(uniphier_pxs2_boot_device_table);
-u32 uniphier_pxs2_boot_device(void)
+int uniphier_pxs2_boot_device_is_usb(u32 pinmon)
{
- int boot_mode;
-
- if (readl(SG_PINMON0) & BIT(6))
- return BOOT_DEVICE_USB;
-
- boot_mode = get_boot_mode_sel();
-
- return boot_device_table[boot_mode].type;
+ return !!(pinmon & 0x00000040);
}
-void uniphier_pxs2_boot_mode_show(void)
+unsigned int uniphier_pxs2_boot_device_fixup(unsigned int mode)
{
- int mode_sel, i;
-
- mode_sel = get_boot_mode_sel();
-
- puts("Boot Mode Pin:\n");
+ if (mode == BOOT_DEVICE_USB)
+ return BOOT_DEVICE_NOR;
- for (i = 0; i < ARRAY_SIZE(boot_device_table); i++)
- printf(" %c %02x %s\n", i == mode_sel ? '*' : ' ', i,
- boot_device_table[i].info);
+ return mode;
}
diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode-sld3.c b/arch/arm/mach-uniphier/boot-device/boot-device-sld3.c
index ddf8259c2c..2b36494f73 100644
--- a/arch/arm/mach-uniphier/boot-mode/boot-mode-sld3.c
+++ b/arch/arm/mach-uniphier/boot-device/boot-device-sld3.c
@@ -1,5 +1,7 @@
/*
- * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2014 Panasonic Corporation
+ * Copyright (C) 2015-2017 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -7,11 +9,11 @@
#include <common.h>
#include <spl.h>
#include <linux/io.h>
+#include <linux/kernel.h>
-#include "../sg-regs.h"
#include "boot-device.h"
-static struct boot_device_info boot_device_table[] = {
+const struct uniphier_boot_device uniphier_sld3_boot_device_table[] = {
{BOOT_DEVICE_NOR, "NOR (XECS0)"},
{BOOT_DEVICE_NONE, "External Master"},
{BOOT_DEVICE_NONE, "Reserved"},
@@ -78,29 +80,5 @@ static struct boot_device_info boot_device_table[] = {
{BOOT_DEVICE_NONE, "Reserved"},
};
-static int get_boot_mode_sel(void)
-{
- return readl(SG_PINMON0) & 0x3f;
-}
-
-u32 uniphier_sld3_boot_device(void)
-{
- int boot_mode;
-
- boot_mode = get_boot_mode_sel();
-
- return boot_device_table[boot_mode].type;
-}
-
-void uniphier_sld3_boot_mode_show(void)
-{
- int mode_sel, i;
-
- mode_sel = get_boot_mode_sel();
-
- puts("Boot Mode Pin:\n");
-
- for (i = 0; i < ARRAY_SIZE(boot_device_table); i++)
- printf(" %c %02x %s\n", i == mode_sel ? '*' : ' ', i,
- boot_device_table[i].info);
-}
+const unsigned uniphier_sld3_boot_device_count =
+ ARRAY_SIZE(uniphier_sld3_boot_device_table);
diff --git a/arch/arm/mach-uniphier/boot-device/boot-device.c b/arch/arm/mach-uniphier/boot-device/boot-device.c
new file mode 100644
index 0000000000..5ec0b5b87c
--- /dev/null
+++ b/arch/arm/mach-uniphier/boot-device/boot-device.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2015-2017 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <linux/log2.h>
+
+#include "../init.h"
+#include "../sbc/sbc-regs.h"
+#include "../sg-regs.h"
+#include "../soc-info.h"
+#include "boot-device.h"
+
+struct uniphier_boot_device_info {
+ unsigned int soc_id;
+ unsigned int boot_device_sel_shift;
+ const struct uniphier_boot_device *boot_device_table;
+ const unsigned int *boot_device_count;
+ int (*boot_device_is_usb)(u32 pinmon);
+ unsigned int (*boot_device_fixup)(unsigned int mode);
+};
+
+static const struct uniphier_boot_device_info uniphier_boot_device_info[] = {
+#if defined(CONFIG_ARCH_UNIPHIER_SLD3)
+ {
+ .soc_id = UNIPHIER_SLD3_ID,
+ .boot_device_sel_shift = 0,
+ .boot_device_table = uniphier_sld3_boot_device_table,
+ .boot_device_count = &uniphier_sld3_boot_device_count,
+ },
+#endif
+#if defined(CONFIG_ARCH_UNIPHIER_LD4)
+ {
+ .soc_id = UNIPHIER_LD4_ID,
+ .boot_device_sel_shift = 1,
+ .boot_device_table = uniphier_ld4_boot_device_table,
+ .boot_device_count = &uniphier_ld4_boot_device_count,
+ },
+#endif
+#if defined(CONFIG_ARCH_UNIPHIER_PRO4)
+ {
+ .soc_id = UNIPHIER_PRO4_ID,
+ .boot_device_sel_shift = 1,
+ .boot_device_table = uniphier_ld4_boot_device_table,
+ .boot_device_count = &uniphier_ld4_boot_device_count,
+ },
+#endif
+#if defined(CONFIG_ARCH_UNIPHIER_SLD8)
+ {
+ .soc_id = UNIPHIER_SLD8_ID,
+ .boot_device_sel_shift = 1,
+ .boot_device_table = uniphier_ld4_boot_device_table,
+ .boot_device_count = &uniphier_ld4_boot_device_count,
+ },
+#endif
+#if defined(CONFIG_ARCH_UNIPHIER_PRO5)
+ {
+ .soc_id = UNIPHIER_PRO5_ID,
+ .boot_device_sel_shift = 1,
+ .boot_device_table = uniphier_pro5_boot_device_table,
+ .boot_device_count = &uniphier_pro5_boot_device_count,
+ },
+#endif
+#if defined(CONFIG_ARCH_UNIPHIER_PXS2)
+ {
+ .soc_id = UNIPHIER_PXS2_ID,
+ .boot_device_sel_shift = 1,
+ .boot_device_table = uniphier_pxs2_boot_device_table,
+ .boot_device_count = &uniphier_pxs2_boot_device_count,
+ .boot_device_is_usb = uniphier_pxs2_boot_device_is_usb,
+ .boot_device_fixup = uniphier_pxs2_boot_device_fixup,
+ },
+#endif
+#if defined(CONFIG_ARCH_UNIPHIER_LD6B)
+ {
+ .soc_id = UNIPHIER_LD6B_ID,
+ .boot_device_sel_shift = 1,
+ .boot_device_table = uniphier_pxs2_boot_device_table,
+ .boot_device_count = &uniphier_pxs2_boot_device_count,
+ .boot_device_is_usb = uniphier_pxs2_boot_device_is_usb,
+ .boot_device_fixup = uniphier_pxs2_boot_device_fixup,
+ },
+#endif
+#if defined(CONFIG_ARCH_UNIPHIER_LD11)
+ {
+ .soc_id = UNIPHIER_LD11_ID,
+ .boot_device_sel_shift = 1,
+ .boot_device_table = uniphier_ld11_boot_device_table,
+ .boot_device_count = &uniphier_ld11_boot_device_count,
+ .boot_device_is_usb = uniphier_ld11_boot_device_is_usb,
+ .boot_device_fixup = uniphier_ld11_boot_device_fixup,
+ },
+#endif
+#if defined(CONFIG_ARCH_UNIPHIER_LD20)
+ {
+ .soc_id = UNIPHIER_LD20_ID,
+ .boot_device_sel_shift = 1,
+ .boot_device_table = uniphier_ld11_boot_device_table,
+ .boot_device_count = &uniphier_ld11_boot_device_count,
+ .boot_device_is_usb = uniphier_ld20_boot_device_is_usb,
+ .boot_device_fixup = uniphier_ld11_boot_device_fixup,
+ },
+#endif
+};
+UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_boot_device_info,
+ uniphier_boot_device_info)
+
+static unsigned int __uniphier_boot_device_raw(
+ const struct uniphier_boot_device_info *info)
+{
+ u32 pinmon;
+ unsigned int boot_sel;
+
+ if (boot_is_swapped())
+ return BOOT_DEVICE_NOR;
+
+ pinmon = readl(SG_PINMON0);
+
+ if (info->boot_device_is_usb && info->boot_device_is_usb(pinmon))
+ return BOOT_DEVICE_USB;
+
+ boot_sel = pinmon >> info->boot_device_sel_shift;
+
+ BUG_ON(!is_power_of_2(*info->boot_device_count));
+ boot_sel &= *info->boot_device_count - 1;
+
+ return info->boot_device_table[boot_sel].boot_device;
+}
+
+unsigned int uniphier_boot_device_raw(void)
+{
+ const struct uniphier_boot_device_info *info;
+
+ info = uniphier_get_boot_device_info();
+ if (!info) {
+ pr_err("unsupported SoC\n");
+ return BOOT_DEVICE_NONE;
+ }
+
+ return __uniphier_boot_device_raw(info);
+}
+
+u32 spl_boot_device(void)
+{
+ const struct uniphier_boot_device_info *info;
+ u32 raw_mode;
+
+ info = uniphier_get_boot_device_info();
+ if (!info) {
+ pr_err("unsupported SoC\n");
+ return BOOT_DEVICE_NONE;
+ }
+
+ raw_mode = __uniphier_boot_device_raw(info);
+
+ return info->boot_device_fixup ?
+ info->boot_device_fixup(raw_mode) : raw_mode;
+}
+
+#ifndef CONFIG_SPL_BUILD
+
+static int do_pinmon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ const struct uniphier_boot_device_info *info;
+ u32 pinmon;
+ unsigned int boot_device_count, boot_sel;
+ int i;
+
+ info = uniphier_get_boot_device_info();
+ if (!info) {
+ pr_err("unsupported SoC\n");
+ return CMD_RET_FAILURE;
+ }
+
+ printf("Boot Swap: %s\n\n", boot_is_swapped() ? "ON" : "OFF");
+
+ pinmon = readl(SG_PINMON0);
+
+ if (info->boot_device_is_usb)
+ printf("USB Boot: %s\n\n",
+ info->boot_device_is_usb(pinmon) ? "ON" : "OFF");
+
+ boot_device_count = *info->boot_device_count;
+
+ boot_sel = pinmon >> info->boot_device_sel_shift;
+ boot_sel &= boot_device_count - 1;
+
+ printf("Boot Mode Sel:\n");
+ for (i = 0; i < boot_device_count; i++)
+ printf(" %c %02x %s\n", i == boot_sel ? '*' : ' ', i,
+ info->boot_device_table[i].desc);
+
+ return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(
+ pinmon, 1, 1, do_pinmon,
+ "pin monitor",
+ ""
+);
+
+#endif /* !CONFIG_SPL_BUILD */
diff --git a/arch/arm/mach-uniphier/boot-device/boot-device.h b/arch/arm/mach-uniphier/boot-device/boot-device.h
new file mode 100644
index 0000000000..f3fb2f32a8
--- /dev/null
+++ b/arch/arm/mach-uniphier/boot-device/boot-device.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _UNIPHIER_BOOT_DEVICE_H_
+#define _UNIPHIER_BOOT_DEVICE_H_
+
+struct uniphier_boot_device {
+ unsigned int boot_device;
+ const char *desc;
+};
+
+extern const struct uniphier_boot_device uniphier_sld3_boot_device_table[];
+extern const struct uniphier_boot_device uniphier_ld4_boot_device_table[];
+extern const struct uniphier_boot_device uniphier_pro5_boot_device_table[];
+extern const struct uniphier_boot_device uniphier_pxs2_boot_device_table[];
+extern const struct uniphier_boot_device uniphier_ld11_boot_device_table[];
+
+extern const unsigned int uniphier_sld3_boot_device_count;
+extern const unsigned int uniphier_ld4_boot_device_count;
+extern const unsigned int uniphier_pro5_boot_device_count;
+extern const unsigned int uniphier_pxs2_boot_device_count;
+extern const unsigned int uniphier_ld11_boot_device_count;
+
+int uniphier_pxs2_boot_device_is_usb(u32 pinmon);
+int uniphier_ld11_boot_device_is_usb(u32 pinmon);
+int uniphier_ld20_boot_device_is_usb(u32 pinmon);
+
+unsigned int uniphier_pxs2_boot_device_fixup(unsigned int mode);
+unsigned int uniphier_ld11_boot_device_fixup(unsigned int mode);
+
+#endif /* _UNIPHIER_BOOT_DEVICE_H_ */
diff --git a/arch/arm/mach-uniphier/boot-device/spl_board.c b/arch/arm/mach-uniphier/boot-device/spl_board.c
new file mode 100644
index 0000000000..bd47ac874b
--- /dev/null
+++ b/arch/arm/mach-uniphier/boot-device/spl_board.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2017 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <linux/bitops.h>
+#include <linux/compat.h>
+#include <linux/io.h>
+#include <asm/processor.h>
+
+#include "../soc-info.h"
+
+#define MMC_CMD_SWITCH 6
+#define MMC_CMD_SELECT_CARD 7
+#define MMC_CMD_SEND_CSD 9
+#define MMC_CMD_READ_MULTIPLE_BLOCK 18
+
+#define EXT_CSD_PART_CONF 179 /* R/W */
+
+#define MMC_RSP_PRESENT BIT(0)
+#define MMC_RSP_136 BIT(1) /* 136 bit response */
+#define MMC_RSP_CRC BIT(2) /* expect valid crc */
+#define MMC_RSP_BUSY BIT(3) /* card may send busy */
+#define MMC_RSP_OPCODE BIT(4) /* response contains opcode */
+
+#define MMC_RSP_NONE (0)
+#define MMC_RSP_R1 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
+#define MMC_RSP_R1b (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | \
+ MMC_RSP_BUSY)
+#define MMC_RSP_R2 (MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC)
+#define MMC_RSP_R3 (MMC_RSP_PRESENT)
+#define MMC_RSP_R4 (MMC_RSP_PRESENT)
+#define MMC_RSP_R5 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
+#define MMC_RSP_R6 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
+#define MMC_RSP_R7 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
+
+#define SDHCI_DMA_ADDRESS 0x00
+#define SDHCI_BLOCK_SIZE 0x04
+#define SDHCI_MAKE_BLKSZ(dma, blksz) ((((dma) & 0x7) << 12) | ((blksz) & 0xFFF))
+#define SDHCI_BLOCK_COUNT 0x06
+#define SDHCI_ARGUMENT 0x08
+#define SDHCI_TRANSFER_MODE 0x0C
+#define SDHCI_TRNS_DMA BIT(0)
+#define SDHCI_TRNS_BLK_CNT_EN BIT(1)
+#define SDHCI_TRNS_ACMD12 BIT(2)
+#define SDHCI_TRNS_READ BIT(4)
+#define SDHCI_TRNS_MULTI BIT(5)
+#define SDHCI_COMMAND 0x0E
+#define SDHCI_CMD_RESP_MASK 0x03
+#define SDHCI_CMD_CRC 0x08
+#define SDHCI_CMD_INDEX 0x10
+#define SDHCI_CMD_DATA 0x20
+#define SDHCI_CMD_ABORTCMD 0xC0
+#define SDHCI_CMD_RESP_NONE 0x00
+#define SDHCI_CMD_RESP_LONG 0x01
+#define SDHCI_CMD_RESP_SHORT 0x02
+#define SDHCI_CMD_RESP_SHORT_BUSY 0x03
+#define SDHCI_MAKE_CMD(c, f) ((((c) & 0xff) << 8) | ((f) & 0xff))
+#define SDHCI_RESPONSE 0x10
+#define SDHCI_HOST_CONTROL 0x28
+#define SDHCI_CTRL_DMA_MASK 0x18
+#define SDHCI_CTRL_SDMA 0x00
+#define SDHCI_BLOCK_GAP_CONTROL 0x2A
+#define SDHCI_SOFTWARE_RESET 0x2F
+#define SDHCI_RESET_CMD 0x02
+#define SDHCI_RESET_DATA 0x04
+#define SDHCI_INT_STATUS 0x30
+#define SDHCI_INT_RESPONSE BIT(0)
+#define SDHCI_INT_DATA_END BIT(1)
+#define SDHCI_INT_ERROR BIT(15)
+#define SDHCI_SIGNAL_ENABLE 0x38
+
+/* RCA assigned by Boot ROM */
+#define UNIPHIER_EMMC_RCA 0x1000
+
+struct uniphier_mmc_cmd {
+ unsigned int cmdidx;
+ unsigned int resp_type;
+ unsigned int cmdarg;
+ unsigned int is_data;
+};
+
+static int uniphier_emmc_send_cmd(void __iomem *host_base,
+ struct uniphier_mmc_cmd *cmd)
+{
+ u32 mode = 0;
+ u32 mask = SDHCI_INT_RESPONSE;
+ u32 stat, flags;
+
+ writel(U32_MAX, host_base + SDHCI_INT_STATUS);
+ writel(0, host_base + SDHCI_SIGNAL_ENABLE);
+ writel(cmd->cmdarg, host_base + SDHCI_ARGUMENT);
+
+ if (cmd->is_data)
+ mode = SDHCI_TRNS_DMA | SDHCI_TRNS_BLK_CNT_EN |
+ SDHCI_TRNS_ACMD12 | SDHCI_TRNS_READ |
+ SDHCI_TRNS_MULTI;
+
+ writew(mode, host_base + SDHCI_TRANSFER_MODE);
+
+ if (!(cmd->resp_type & MMC_RSP_PRESENT))
+ flags = SDHCI_CMD_RESP_NONE;
+ else if (cmd->resp_type & MMC_RSP_136)
+ flags = SDHCI_CMD_RESP_LONG;
+ else if (cmd->resp_type & MMC_RSP_BUSY)
+ flags = SDHCI_CMD_RESP_SHORT_BUSY;
+ else
+ flags = SDHCI_CMD_RESP_SHORT;
+
+ if (cmd->resp_type & MMC_RSP_CRC)
+ flags |= SDHCI_CMD_CRC;
+ if (cmd->resp_type & MMC_RSP_OPCODE)
+ flags |= SDHCI_CMD_INDEX;
+ if (cmd->is_data)
+ flags |= SDHCI_CMD_DATA;
+
+ if (cmd->resp_type & MMC_RSP_BUSY || cmd->is_data)
+ mask |= SDHCI_INT_DATA_END;
+
+ writew(SDHCI_MAKE_CMD(cmd->cmdidx, flags), host_base + SDHCI_COMMAND);
+
+ do {
+ stat = readl(host_base + SDHCI_INT_STATUS);
+ if (stat & SDHCI_INT_ERROR)
+ return -EIO;
+
+ } while ((stat & mask) != mask);
+
+ return 0;
+}
+
+static int uniphier_emmc_switch_part(void __iomem *host_base, int part_num)
+{
+ struct uniphier_mmc_cmd cmd = {};
+
+ cmd.cmdidx = MMC_CMD_SWITCH;
+ cmd.resp_type = MMC_RSP_R1b;
+ cmd.cmdarg = (EXT_CSD_PART_CONF << 16) | (part_num << 8) | (3 << 24);
+
+ return uniphier_emmc_send_cmd(host_base, &cmd);
+}
+
+static int uniphier_emmc_is_over_2gb(void __iomem *host_base)
+{
+ struct uniphier_mmc_cmd cmd = {};
+ u32 csd40, csd72; /* CSD[71:40], CSD[103:72] */
+ int ret;
+
+ cmd.cmdidx = MMC_CMD_SEND_CSD;
+ cmd.resp_type = MMC_RSP_R2;
+ cmd.cmdarg = UNIPHIER_EMMC_RCA << 16;
+
+ ret = uniphier_emmc_send_cmd(host_base, &cmd);
+ if (ret)
+ return ret;
+
+ csd40 = readl(host_base + SDHCI_RESPONSE + 4);
+ csd72 = readl(host_base + SDHCI_RESPONSE + 8);
+
+ return !(~csd40 & 0xffc00380) && !(~csd72 & 0x3);
+}
+
+static int uniphier_emmc_load_image(void __iomem *host_base, u32 dev_addr,
+ unsigned long load_addr, u32 block_cnt)
+{
+ struct uniphier_mmc_cmd cmd = {};
+ u8 tmp;
+
+ WARN_ON(load_addr >> 32);
+
+ writel(load_addr, host_base + SDHCI_DMA_ADDRESS);
+ writew(SDHCI_MAKE_BLKSZ(7, 512), host_base + SDHCI_BLOCK_SIZE);
+ writew(block_cnt, host_base + SDHCI_BLOCK_COUNT);
+
+ tmp = readb(host_base + SDHCI_HOST_CONTROL);
+ tmp &= ~SDHCI_CTRL_DMA_MASK;
+ tmp |= SDHCI_CTRL_SDMA;
+ writeb(tmp, host_base + SDHCI_HOST_CONTROL);
+
+ tmp = readb(host_base + SDHCI_BLOCK_GAP_CONTROL);
+ tmp &= ~1; /* clear Stop At Block Gap Request */
+ writeb(tmp, host_base + SDHCI_BLOCK_GAP_CONTROL);
+
+ cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.cmdarg = dev_addr;
+ cmd.is_data = 1;
+
+ return uniphier_emmc_send_cmd(host_base, &cmd);
+}
+
+static int spl_board_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ u32 dev_addr = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR;
+ void __iomem *host_base = (void __iomem *)0x5a000200;
+ struct uniphier_mmc_cmd cmd = {};
+ int ret;
+
+ /*
+ * deselect card before SEND_CSD command.
+ * Do not check the return code. It fails, but it is OK.
+ */
+ cmd.cmdidx = MMC_CMD_SELECT_CARD;
+ cmd.resp_type = MMC_RSP_R1;
+
+ uniphier_emmc_send_cmd(host_base, &cmd); /* CMD7 (arg=0) */
+
+ /* reset CMD Line */
+ writeb(SDHCI_RESET_CMD | SDHCI_RESET_DATA,
+ host_base + SDHCI_SOFTWARE_RESET);
+ while (readb(host_base + SDHCI_SOFTWARE_RESET))
+ cpu_relax();
+
+ ret = uniphier_emmc_is_over_2gb(host_base);
+ if (ret < 0)
+ return ret;
+ if (ret) {
+ debug("card is block addressing\n");
+ } else {
+ debug("card is byte addressing\n");
+ dev_addr *= 512;
+ }
+
+ cmd.cmdarg = UNIPHIER_EMMC_RCA << 16;
+
+ /* select card again */
+ ret = uniphier_emmc_send_cmd(host_base, &cmd);
+ if (ret)
+ printf("failed to select card\n");
+
+ /* Switch to Boot Partition 1 */
+ ret = uniphier_emmc_switch_part(host_base, 1);
+ if (ret)
+ printf("failed to switch partition\n");
+
+ ret = uniphier_emmc_load_image(host_base, dev_addr,
+ CONFIG_SYS_TEXT_BASE, 1);
+ if (ret) {
+ printf("failed to load image\n");
+ return ret;
+ }
+
+ ret = spl_parse_image_header(spl_image, (void *)CONFIG_SYS_TEXT_BASE);
+ if (ret)
+ return ret;
+
+ ret = uniphier_emmc_load_image(host_base, dev_addr,
+ spl_image->load_addr,
+ spl_image->size / 512);
+ if (ret) {
+ printf("failed to load image\n");
+ return ret;
+ }
+
+ return 0;
+}
+SPL_LOAD_IMAGE_METHOD("eMMC", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
diff --git a/arch/arm/mach-uniphier/boot-mode/Makefile b/arch/arm/mach-uniphier/boot-mode/Makefile
deleted file mode 100644
index a8980210b1..0000000000
--- a/arch/arm/mach-uniphier/boot-mode/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# SPDX-License-Identifier: GPL-2.0+
-#
-
-obj-y += boot-mode.o
-
-obj-$(CONFIG_ARCH_UNIPHIER_SLD3) += boot-mode-sld3.o
-obj-$(CONFIG_ARCH_UNIPHIER_LD4) += boot-mode-ld4.o
-obj-$(CONFIG_ARCH_UNIPHIER_PRO4) += boot-mode-ld4.o
-obj-$(CONFIG_ARCH_UNIPHIER_SLD8) += boot-mode-ld4.o
-obj-$(CONFIG_ARCH_UNIPHIER_PRO5) += boot-mode-pro5.o
-obj-$(CONFIG_ARCH_UNIPHIER_PXS2) += boot-mode-pxs2.o
-obj-$(CONFIG_ARCH_UNIPHIER_LD6B) += boot-mode-pxs2.o
-obj-$(CONFIG_ARCH_UNIPHIER_LD11) += boot-mode-ld20.o
-obj-$(CONFIG_ARCH_UNIPHIER_LD20) += boot-mode-ld20.o
-
-ifdef CONFIG_SPL_BUILD
-obj-$(CONFIG_SPL_BOARD_LOAD_IMAGE) += spl_board.o
-else
-obj-$(CONFIG_CMD_PINMON) += cmd_pinmon.o
-endif
diff --git a/arch/arm/mach-uniphier/boot-mode/boot-device.h b/arch/arm/mach-uniphier/boot-mode/boot-device.h
deleted file mode 100644
index bd44d73416..0000000000
--- a/arch/arm/mach-uniphier/boot-mode/boot-device.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef _ASM_BOOT_DEVICE_H_
-#define _ASM_BOOT_DEVICE_H_
-
-struct boot_device_info {
- u32 type;
- char *info;
-};
-
-u32 uniphier_sld3_boot_device(void);
-u32 uniphier_ld4_boot_device(void);
-u32 uniphier_pro5_boot_device(void);
-u32 uniphier_pxs2_boot_device(void);
-u32 uniphier_ld20_boot_device(void);
-
-void uniphier_sld3_boot_mode_show(void);
-void uniphier_ld4_boot_mode_show(void);
-void uniphier_pro5_boot_mode_show(void);
-void uniphier_pxs2_boot_mode_show(void);
-void uniphier_ld20_boot_mode_show(void);
-
-u32 spl_boot_device_raw(void);
-
-#endif /* _ASM_BOOT_DEVICE_H_ */
diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode.c b/arch/arm/mach-uniphier/boot-mode/boot-mode.c
deleted file mode 100644
index a5527704df..0000000000
--- a/arch/arm/mach-uniphier/boot-mode/boot-mode.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <mmc.h>
-#include <spl.h>
-#include <linux/errno.h>
-
-#include "../sbc/sbc-regs.h"
-#include "../soc-info.h"
-#include "boot-device.h"
-
-u32 spl_boot_device_raw(void)
-{
- if (boot_is_swapped())
- return BOOT_DEVICE_NOR;
-
- switch (uniphier_get_soc_id()) {
-#if defined(CONFIG_ARCH_UNIPHIER_SLD3)
- case UNIPHIER_SLD3_ID:
- return uniphier_sld3_boot_device();
-#endif
-#if defined(CONFIG_ARCH_UNIPHIER_LD4) || defined(CONFIG_ARCH_UNIPHIER_PRO4) || \
- defined(CONFIG_ARCH_UNIPHIER_SLD8)
- case UNIPHIER_LD4_ID:
- case UNIPHIER_PRO4_ID:
- case UNIPHIER_SLD8_ID:
- return uniphier_ld4_boot_device();
-#endif
-#if defined(CONFIG_ARCH_UNIPHIER_PRO5)
- case UNIPHIER_PRO5_ID:
- return uniphier_pro5_boot_device();
-#endif
-#if defined(CONFIG_ARCH_UNIPHIER_PXS2) || defined(CONFIG_ARCH_UNIPHIER_LD6B)
- case UNIPHIER_PXS2_ID:
- case UNIPHIER_LD6B_ID:
- return uniphier_pxs2_boot_device();
-#endif
-#if defined(CONFIG_ARCH_UNIPHIER_LD11) || defined(CONFIG_ARCH_UNIPHIER_LD20)
- case UNIPHIER_LD11_ID:
- case UNIPHIER_LD20_ID:
- return uniphier_ld20_boot_device();
-#endif
- default:
- return BOOT_DEVICE_NONE;
- }
-}
-
-u32 spl_boot_device(void)
-{
- u32 mode;
-
- mode = spl_boot_device_raw();
-
- switch (uniphier_get_soc_id()) {
-#if defined(CONFIG_ARCH_UNIPHIER_PXS2) || defined(CONFIG_ARCH_UNIPHIER_LD6B)
- case UNIPHIER_PXS2_ID:
- case UNIPHIER_LD6B_ID:
- if (mode == BOOT_DEVICE_USB)
- mode = BOOT_DEVICE_NOR;
- break;
-#endif
-#if defined(CONFIG_ARCH_UNIPHIER_LD11) || defined(CONFIG_ARCH_UNIPHIER_LD20)
- case UNIPHIER_LD11_ID:
- case UNIPHIER_LD20_ID:
- if (mode == BOOT_DEVICE_MMC1 || mode == BOOT_DEVICE_USB)
- mode = BOOT_DEVICE_BOARD;
- break;
-#endif
- default:
- break;
- }
-
- return mode;
-}
-
-u32 spl_boot_mode(const u32 boot_device)
-{
- struct mmc *mmc;
-
- /*
- * work around a bug in the Boot ROM of PH1-sLD3, LD4, Pro4, and sLD8:
- *
- * The boot ROM in these SoCs breaks the PARTITION_CONFIG [179] of
- * Extended CSD register; when switching to the Boot Partition 1, the
- * Boot ROM should issue the SWITCH command (CMD6) with Set Bits for
- * the Access Bits, but in fact it uses Write Byte for the Access Bits.
- * As a result, the BOOT_PARTITION_ENABLE field of the PARTITION_CONFIG
- * is lost. This bug was fixed for PH1-Pro5 and later SoCs.
- *
- * Fixup mmc->part_config here because it is used to determine the
- * partition which the U-Boot image is read from.
- */
- mmc = find_mmc_device(0);
- mmc->part_config &= ~EXT_CSD_BOOT_PART_NUM(PART_ACCESS_MASK);
- mmc->part_config |= EXT_CSD_BOOT_PARTITION_ENABLE;
-
- return MMCSD_MODE_EMMCBOOT;
-}
-
-#if defined(CONFIG_DM_MMC) && !defined(CONFIG_SPL_BUILD)
-static int find_first_mmc_device(void)
-{
- struct mmc *mmc;
- int i;
-
- for (i = 0; (mmc = find_mmc_device(i)); i++) {
- if (!mmc_init(mmc) && IS_MMC(mmc))
- return i;
- }
-
- return -ENODEV;
-}
-
-int mmc_get_env_dev(void)
-{
- return find_first_mmc_device();
-}
-
-static int do_mmcsetn(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- int dev;
-
- dev = find_first_mmc_device();
- if (dev < 0)
- return CMD_RET_FAILURE;
-
- setenv_ulong("mmc_first_dev", dev);
- return CMD_RET_SUCCESS;
-}
-
-U_BOOT_CMD(
- mmcsetn, 1, 1, do_mmcsetn,
- "Set the first MMC (not SD) dev number to \"mmc_first_dev\" environment",
- ""
-);
-#endif
diff --git a/arch/arm/mach-uniphier/boot-mode/cmd_pinmon.c b/arch/arm/mach-uniphier/boot-mode/cmd_pinmon.c
deleted file mode 100644
index 670d4f6bff..0000000000
--- a/arch/arm/mach-uniphier/boot-mode/cmd_pinmon.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-
-#include "../sbc/sbc-regs.h"
-#include "../soc-info.h"
-#include "boot-device.h"
-
-static int do_pinmon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- printf("Boot Swap: %s\n\n", boot_is_swapped() ? "ON" : "OFF");
-
- switch (uniphier_get_soc_id()) {
-#if defined(CONFIG_ARCH_UNIPHIER_SLD3)
- case UNIPHIER_SLD3_ID:
- uniphier_sld3_boot_mode_show();
- break;
-#endif
-#if defined(CONFIG_ARCH_UNIPHIER_LD4) || defined(CONFIG_ARCH_UNIPHIER_PRO4) || \
- defined(CONFIG_ARCH_UNIPHIER_SLD8)
- case UNIPHIER_LD4_ID:
- case UNIPHIER_PRO4_ID:
- case UNIPHIER_SLD8_ID:
- uniphier_ld4_boot_mode_show();
- break;
-#endif
-#if defined(CONFIG_ARCH_UNIPHIER_PRO5)
- case UNIPHIER_PRO5_ID:
- uniphier_pro5_boot_mode_show();
- break;
-#endif
-#if defined(CONFIG_ARCH_UNIPHIER_PXS2) || defined(CONFIG_ARCH_UNIPHIER_LD6B)
- case UNIPHIER_PXS2_ID:
- case UNIPHIER_LD6B_ID:
- uniphier_pxs2_boot_mode_show();
- break;
-#endif
-#if defined(CONFIG_ARCH_UNIPHIER_LD11) || defined(CONFIG_ARCH_UNIPHIER_LD20)
- case UNIPHIER_LD11_ID:
- case UNIPHIER_LD20_ID:
- uniphier_ld20_boot_mode_show();
- break;
-#endif
- default:
- break;
- }
-
- return 0;
-}
-
-U_BOOT_CMD(
- pinmon, 1, 1, do_pinmon,
- "pin monitor",
- ""
-);
diff --git a/arch/arm/mach-uniphier/boot-mode/spl_board.c b/arch/arm/mach-uniphier/boot-mode/spl_board.c
deleted file mode 100644
index 0aac9241c3..0000000000
--- a/arch/arm/mach-uniphier/boot-mode/spl_board.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2016 Socionext Inc.
- * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <spl.h>
-#include <linux/io.h>
-#include <asm/processor.h>
-
-#include "../soc-info.h"
-
-struct uniphier_romfunc_table {
- void *mmc_send_cmd;
- void *mmc_card_blockaddr;
- void *mmc_switch_part;
- void *mmc_load_image;
-};
-
-static const struct uniphier_romfunc_table uniphier_ld11_romfunc_table = {
- .mmc_send_cmd = (void *)0x20d8,
- .mmc_card_blockaddr = (void *)0x1b68,
- .mmc_switch_part = (void *)0x1c38,
- .mmc_load_image = (void *)0x2e48,
-};
-
-static const struct uniphier_romfunc_table uniphier_ld20_romfunc_table = {
- .mmc_send_cmd = (void *)0x2130,
- .mmc_card_blockaddr = (void *)0x1ba0,
- .mmc_switch_part = (void *)0x1c70,
- .mmc_load_image = (void *)0x2ef0,
-};
-
-int uniphier_rom_get_mmc_funcptr(int (**send_cmd)(u32, u32),
- int (**card_blockaddr)(u32),
- int (**switch_part)(int),
- int (**load_image)(u32, uintptr_t, u32))
-{
- const struct uniphier_romfunc_table *table;
-
- switch (uniphier_get_soc_id()) {
- case UNIPHIER_LD11_ID:
- table = &uniphier_ld11_romfunc_table;
- break;
- case UNIPHIER_LD20_ID:
- table = &uniphier_ld20_romfunc_table;
- break;
- default:
- printf("unsupported SoC\n");
- return -EINVAL;
- }
-
- *send_cmd = table->mmc_send_cmd;
- *card_blockaddr = table->mmc_card_blockaddr;
- *switch_part = table->mmc_switch_part;
- *load_image = table->mmc_load_image;
-
- return 0;
-}
-
-static int spl_board_load_image(struct spl_image_info *spl_image,
- struct spl_boot_device *bootdev)
-{
- int (*send_cmd)(u32 cmd, u32 arg);
- int (*card_blockaddr)(u32 rca);
- int (*switch_part)(int part);
- int (*load_image)(u32 dev_addr, uintptr_t load_addr, u32 block_cnt);
- u32 dev_addr = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR;
- const u32 rca = 0x1000; /* RCA assigned by Boot ROM */
- int ret;
-
- ret = uniphier_rom_get_mmc_funcptr(&send_cmd, &card_blockaddr,
- &switch_part, &load_image);
- if (ret)
- return ret;
-
- /*
- * deselect card before SEND_CSD command.
- * Do not check the return code. It fails, but it is OK.
- */
- (*send_cmd)(0x071a0000, 0); /* CMD7 (arg=0) */
-
- /* reset CMD Line */
- writeb(0x6, 0x5a00022f);
- while (readb(0x5a00022f))
- cpu_relax();
-
- ret = (*card_blockaddr)(rca);
- if (ret) {
- debug("card is block addressing\n");
- } else {
- debug("card is byte addressing\n");
- dev_addr *= 512;
- }
-
- ret = (*send_cmd)(0x071a0000, rca << 16); /* CMD7: select card again */
- if (ret)
- printf("failed to select card\n");
-
- ret = (*switch_part)(1); /* Switch to Boot Partition 1 */
- if (ret)
- printf("failed to switch partition\n");
-
- ret = (*load_image)(dev_addr, CONFIG_SYS_TEXT_BASE, 1);
- if (ret) {
- printf("failed to load image\n");
- return ret;
- }
-
- ret = spl_parse_image_header(spl_image, (void *)CONFIG_SYS_TEXT_BASE);
- if (ret)
- return ret;
-
- ret = (*load_image)(dev_addr, spl_image->load_addr,
- spl_image->size / 512);
- if (ret) {
- printf("failed to load image\n");
- return ret;
- }
-
- return 0;
-}
-SPL_LOAD_IMAGE_METHOD("eMMC", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
diff --git a/arch/arm/mach-uniphier/clk/Makefile b/arch/arm/mach-uniphier/clk/Makefile
index 43df670ca0..41341970ec 100644
--- a/arch/arm/mach-uniphier/clk/Makefile
+++ b/arch/arm/mach-uniphier/clk/Makefile
@@ -24,7 +24,7 @@ obj-$(CONFIG_ARCH_UNIPHIER_PRO5) += clk-pro5.o
obj-$(CONFIG_ARCH_UNIPHIER_PXS2) += clk-pxs2.o
obj-$(CONFIG_ARCH_UNIPHIER_LD6B) += clk-pxs2.o
obj-$(CONFIG_ARCH_UNIPHIER_LD11) += clk-ld11.o pll-ld11.o
-obj-$(CONFIG_ARCH_UNIPHIER_LD20) += pll-ld20.o
+obj-$(CONFIG_ARCH_UNIPHIER_LD20) += clk-ld20.o pll-ld20.o
obj-$(CONFIG_ARCH_UNIPHIER_PXS3) += pll-pxs3.o
endif
diff --git a/arch/arm/mach-uniphier/clk/clk-ld11.c b/arch/arm/mach-uniphier/clk/clk-ld11.c
index 58069cbf15..a4dcde743b 100644
--- a/arch/arm/mach-uniphier/clk/clk-ld11.c
+++ b/arch/arm/mach-uniphier/clk/clk-ld11.c
@@ -9,16 +9,17 @@
#include <linux/bitops.h>
#include <linux/io.h>
-#include "../boot-mode/boot-device.h"
#include "../init.h"
#include "../sc64-regs.h"
#include "../sg-regs.h"
+#define SDCTRL_EMMC_HW_RESET 0x59810280
+
void uniphier_ld11_clk_init(void)
{
/* if booted from a device other than USB, without stand-by MPU */
if ((readl(SG_PINMON0) & BIT(27)) &&
- spl_boot_device_raw() != BOOT_DEVICE_USB) {
+ uniphier_boot_device_raw() != BOOT_DEVICE_USB) {
writel(1, SG_ETPHYPSHUT);
writel(1, SG_ETPHYCNT);
@@ -29,6 +30,9 @@ void uniphier_ld11_clk_init(void)
writel(7, SG_ETPHYCNT);
}
+ /* TODO: use "mmc-pwrseq-emmc" */
+ writel(1, SDCTRL_EMMC_HW_RESET);
+
#ifdef CONFIG_USB_EHCI
{
/* FIXME: the current clk driver can not handle parents */
diff --git a/arch/arm/mach-uniphier/clk/clk-ld20.c b/arch/arm/mach-uniphier/clk/clk-ld20.c
new file mode 100644
index 0000000000..5bb560cafe
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/clk-ld20.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2017 Socionext Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/io.h>
+
+#include "../init.h"
+
+#define SDCTRL_EMMC_HW_RESET 0x59810280
+
+void uniphier_ld20_clk_init(void)
+{
+ /* TODO: use "mmc-pwrseq-emmc" */
+ writel(1, SDCTRL_EMMC_HW_RESET);
+}
diff --git a/arch/arm/mach-uniphier/clk/pll-base-ld20.c b/arch/arm/mach-uniphier/clk/pll-base-ld20.c
index c66f083fae..697eb7aabf 100644
--- a/arch/arm/mach-uniphier/clk/pll-base-ld20.c
+++ b/arch/arm/mach-uniphier/clk/pll-base-ld20.c
@@ -18,6 +18,8 @@
#define SC_PLLCTRL_SSC_EN BIT(31)
#define SC_PLLCTRL2_NRSTDS BIT(28)
#define SC_PLLCTRL2_SSC_JK_MASK GENMASK(26, 0)
+#define SC_PLLCTRL3_REGI_SHIFT 16
+#define SC_PLLCTRL3_REGI_MASK GENMASK(19, 16)
/* PLL type: VPLL27 */
#define SC_VPLL27CTRL_WP BIT(0)
@@ -77,6 +79,25 @@ int uniphier_ld20_sscpll_ssc_en(unsigned long reg_base)
return 0;
}
+int uniphier_ld20_sscpll_set_regi(unsigned long reg_base, unsigned regi)
+{
+ void __iomem *base;
+ u32 tmp;
+
+ base = ioremap(reg_base, SZ_16);
+ if (!base)
+ return -ENOMEM;
+
+ tmp = readl(base + 8); /* SSCPLLCTRL */
+ tmp &= ~SC_PLLCTRL3_REGI_MASK;
+ tmp |= regi << SC_PLLCTRL3_REGI_SHIFT;
+ writel(tmp, base + 8);
+
+ iounmap(base);
+
+ return 0;
+}
+
int uniphier_ld20_vpll27_init(unsigned long reg_base)
{
void __iomem *base;
diff --git a/arch/arm/mach-uniphier/clk/pll-ld11.c b/arch/arm/mach-uniphier/clk/pll-ld11.c
index 7746deb72d..02befa298b 100644
--- a/arch/arm/mach-uniphier/clk/pll-ld11.c
+++ b/arch/arm/mach-uniphier/clk/pll-ld11.c
@@ -18,6 +18,8 @@ void uniphier_ld11_pll_init(void)
uniphier_ld20_sscpll_init(SC_MPLLCTRL, 1600, 1, 2); /* 1500MHz -> 1600MHz */
uniphier_ld20_sscpll_init(SC_VSPLLCTRL, UNIPHIER_PLL_FREQ_DEFAULT, 0, 2);
+ uniphier_ld20_sscpll_set_regi(SC_MPLLCTRL, 5);
+
mdelay(1);
uniphier_ld20_sscpll_ssc_en(SC_CPLLCTRL);
diff --git a/arch/arm/mach-uniphier/clk/pll.h b/arch/arm/mach-uniphier/clk/pll.h
index d7e93037d6..5eefc4ee31 100644
--- a/arch/arm/mach-uniphier/clk/pll.h
+++ b/arch/arm/mach-uniphier/clk/pll.h
@@ -15,6 +15,7 @@ void uniphier_ld4_dpll_ssc_en(void);
int uniphier_ld20_sscpll_init(unsigned long reg_base, unsigned int freq,
unsigned int ssc_rate, unsigned int divn);
int uniphier_ld20_sscpll_ssc_en(unsigned long reg_base);
+int uniphier_ld20_sscpll_set_regi(unsigned long reg_base, unsigned regi);
int uniphier_ld20_vpll27_init(unsigned long reg_base);
int uniphier_ld20_dspll_init(unsigned long reg_base);
diff --git a/arch/arm/mach-uniphier/dram/umc-ld11.c b/arch/arm/mach-uniphier/dram/umc-ld11.c
index 97a9fef24c..69aa4f2eeb 100644
--- a/arch/arm/mach-uniphier/dram/umc-ld11.c
+++ b/arch/arm/mach-uniphier/dram/umc-ld11.c
@@ -471,7 +471,7 @@ int uniphier_ld11_umc_init(const struct uniphier_board_data *bd)
ddrphy_init(phy_base, freq);
- for (ch = 0; ch < bd->dram_nr_ch; ch++) {
+ for (ch = 0; ch < DRAM_CH_NR; ch++) {
unsigned long size = bd->dram_ch[ch].size;
unsigned int width = bd->dram_ch[ch].width;
diff --git a/arch/arm/mach-uniphier/dram/umc-ld20.c b/arch/arm/mach-uniphier/dram/umc-ld20.c
index 157b915a7b..500c1c11ba 100644
--- a/arch/arm/mach-uniphier/dram/umc-ld20.c
+++ b/arch/arm/mach-uniphier/dram/umc-ld20.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2016-2017 Socionext Inc.
*
- * based on commit e732175d0b0dbc2a3855cb8ac791c538666b6fd4 of Diag
+ * based on commit 5ffd75ecd4929f22361ef65a35f0331d2fbc0f35 of Diag
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -177,12 +177,18 @@ static void ddrphy_select_lane(void __iomem *phy_base, unsigned int lane,
phy_base + PHY_LANE_SEL);
}
+#define DDRPHY_EFUSEMON (void *)0x5f900118
+
static void ddrphy_init(void __iomem *phy_base, enum dram_board board, int ch)
{
writel(0x0C001001, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
while (!(readl(phy_base + PHY_UNIQUIFY_TSMC_IO_1) & BIT(1)))
cpu_relax();
- writel(0x0C001000, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
+
+ if (readl(DDRPHY_EFUSEMON) & BIT(ch))
+ writel(0x00000000, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
+ else
+ writel(0x0C001000, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_3);
writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_1);
@@ -606,15 +612,18 @@ int uniphier_ld20_umc_init(const struct uniphier_board_data *bd)
return -EINVAL;
}
- for (ch = 0; ch < bd->dram_nr_ch; ch++) {
+ for (ch = 0; ch < DRAM_CH_NR; ch++) {
unsigned long size = bd->dram_ch[ch].size;
unsigned int width = bd->dram_ch[ch].width;
- ret = umc_ch_init(umc_ch_base, phy_ch_base, board,
- bd->dram_freq, size / (width / 16), ch);
- if (ret) {
- pr_err("failed to initialize UMC ch%d\n", ch);
- return ret;
+ if (size) {
+ ret = umc_ch_init(umc_ch_base, phy_ch_base, board,
+ bd->dram_freq, size / (width / 16),
+ ch);
+ if (ret) {
+ pr_err("failed to initialize UMC ch%d\n", ch);
+ return ret;
+ }
}
umc_ch_base += 0x00200000;
diff --git a/arch/arm/mach-uniphier/dram/umc-pxs2.c b/arch/arm/mach-uniphier/dram/umc-pxs2.c
index 05a62de45a..7fa29f119d 100644
--- a/arch/arm/mach-uniphier/dram/umc-pxs2.c
+++ b/arch/arm/mach-uniphier/dram/umc-pxs2.c
@@ -619,15 +619,17 @@ int uniphier_pxs2_umc_init(const struct uniphier_board_data *bd)
return -EINVAL;
}
- for (ch = 0; ch < bd->dram_nr_ch; ch++) {
+ for (ch = 0; ch < DRAM_CH_NR; ch++) {
unsigned long size = bd->dram_ch[ch].size;
unsigned int width = bd->dram_ch[ch].width;
- ret = umc_ch_init(umc_ch_base, freq, size / (width / 16),
- width, ch);
- if (ret) {
- pr_err("failed to initialize UMC ch%d\n", ch);
- return ret;
+ if (size) {
+ ret = umc_ch_init(umc_ch_base, freq,
+ size / (width / 16), width, ch);
+ if (ret) {
+ pr_err("failed to initialize UMC ch%d\n", ch);
+ return ret;
+ }
}
umc_ch_base += 0x00200000;
diff --git a/arch/arm/mach-uniphier/dram_init.c b/arch/arm/mach-uniphier/dram_init.c
index 881062d9b6..d9f6c16fdc 100644
--- a/arch/arm/mach-uniphier/dram_init.c
+++ b/arch/arm/mach-uniphier/dram_init.c
@@ -11,10 +11,12 @@
#include <linux/errno.h>
#include <linux/sizes.h>
-#include "init.h"
#include "sg-regs.h"
#include "soc-info.h"
+#define pr_warn(fmt, args...) printf(fmt, ##args)
+#define pr_err(fmt, args...) printf(fmt, ##args)
+
DECLARE_GLOBAL_DATA_PTR;
struct uniphier_memif_data {
@@ -76,7 +78,12 @@ static const struct uniphier_memif_data uniphier_memif_data[] = {
};
UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_memif_data, uniphier_memif_data)
-static int uniphier_memconf_decode(struct uniphier_dram_ch *dram_ch)
+struct uniphier_dram_map {
+ unsigned long base;
+ unsigned long size;
+};
+
+static int uniphier_memconf_decode(struct uniphier_dram_map *dram_map)
{
const struct uniphier_memif_data *data;
unsigned long size;
@@ -91,7 +98,7 @@ static int uniphier_memconf_decode(struct uniphier_dram_ch *dram_ch)
val = readl(SG_MEMCONF);
/* set up ch0 */
- dram_ch[0].base = CONFIG_SYS_SDRAM_BASE;
+ dram_map[0].base = CONFIG_SYS_SDRAM_BASE;
switch (val & SG_MEMCONF_CH0_SZ_MASK) {
case SG_MEMCONF_CH0_SZ_64M:
@@ -110,27 +117,27 @@ static int uniphier_memconf_decode(struct uniphier_dram_ch *dram_ch)
size = SZ_1G;
break;
default:
- pr_err("error: invald value is set to MEMCONF ch0 size\n");
+ pr_err("error: invalid value is set to MEMCONF ch0 size\n");
return -EINVAL;
}
if ((val & SG_MEMCONF_CH0_NUM_MASK) == SG_MEMCONF_CH0_NUM_2)
size *= 2;
- dram_ch[0].size = size;
+ dram_map[0].size = size;
/* set up ch1 */
- dram_ch[1].base = dram_ch[0].base + size;
+ dram_map[1].base = dram_map[0].base + size;
if (val & SG_MEMCONF_SPARSEMEM) {
- if (dram_ch[1].base > data->sparse_ch1_base) {
+ if (dram_map[1].base > data->sparse_ch1_base) {
pr_warn("Sparse mem is enabled, but ch0 and ch1 overlap\n");
pr_warn("Only ch0 is available\n");
- dram_ch[1].base = 0;
+ dram_map[1].base = 0;
return 0;
}
- dram_ch[1].base = data->sparse_ch1_base;
+ dram_map[1].base = data->sparse_ch1_base;
}
switch (val & SG_MEMCONF_CH1_SZ_MASK) {
@@ -150,20 +157,20 @@ static int uniphier_memconf_decode(struct uniphier_dram_ch *dram_ch)
size = SZ_1G;
break;
default:
- pr_err("error: invald value is set to MEMCONF ch1 size\n");
+ pr_err("error: invalid value is set to MEMCONF ch1 size\n");
return -EINVAL;
}
if ((val & SG_MEMCONF_CH1_NUM_MASK) == SG_MEMCONF_CH1_NUM_2)
size *= 2;
- dram_ch[1].size = size;
+ dram_map[1].size = size;
- if (!data->have_ch2)
+ if (!data->have_ch2 || val & SG_MEMCONF_CH2_DISABLE)
return 0;
/* set up ch2 */
- dram_ch[2].base = dram_ch[1].base + size;
+ dram_map[2].base = dram_map[1].base + size;
switch (val & SG_MEMCONF_CH2_SZ_MASK) {
case SG_MEMCONF_CH2_SZ_64M:
@@ -182,32 +189,32 @@ static int uniphier_memconf_decode(struct uniphier_dram_ch *dram_ch)
size = SZ_1G;
break;
default:
- pr_err("error: invald value is set to MEMCONF ch2 size\n");
+ pr_err("error: invalid value is set to MEMCONF ch2 size\n");
return -EINVAL;
}
if ((val & SG_MEMCONF_CH2_NUM_MASK) == SG_MEMCONF_CH2_NUM_2)
size *= 2;
- dram_ch[2].size = size;
+ dram_map[2].size = size;
return 0;
}
int dram_init(void)
{
- struct uniphier_dram_ch dram_ch[UNIPHIER_MAX_NR_DRAM_CH] = {};
+ struct uniphier_dram_map dram_map[3] = {};
int ret, i;
gd->ram_size = 0;
- ret = uniphier_memconf_decode(dram_ch);
+ ret = uniphier_memconf_decode(dram_map);
if (ret)
return ret;
- for (i = 0; i < ARRAY_SIZE(dram_ch); i++) {
+ for (i = 0; i < ARRAY_SIZE(dram_map); i++) {
- if (!dram_ch[i].size)
+ if (!dram_map[i].size)
break;
/*
@@ -215,11 +222,11 @@ int dram_init(void)
* but it does not expect sparse memory. We use the first
* contiguous chunk here.
*/
- if (i > 0 &&
- dram_ch[i - 1].base + dram_ch[i - 1].size < dram_ch[i].base)
+ if (i > 0 && dram_map[i - 1].base + dram_map[i - 1].size <
+ dram_map[i].base)
break;
- gd->ram_size += dram_ch[i].size;
+ gd->ram_size += dram_map[i].size;
}
return 0;
@@ -227,17 +234,17 @@ int dram_init(void)
void dram_init_banksize(void)
{
- struct uniphier_dram_ch dram_ch[UNIPHIER_MAX_NR_DRAM_CH] = {};
+ struct uniphier_dram_map dram_map[3] = {};
int i;
- uniphier_memconf_decode(dram_ch);
+ uniphier_memconf_decode(dram_map);
- for (i = 0; i < ARRAY_SIZE(dram_ch); i++) {
+ for (i = 0; i < ARRAY_SIZE(dram_map); i++) {
if (i >= ARRAY_SIZE(gd->bd->bi_dram))
break;
- gd->bd->bi_dram[i].start = dram_ch[i].base;
- gd->bd->bi_dram[i].size = dram_ch[i].size;
+ gd->bd->bi_dram[i].start = dram_map[i].base;
+ gd->bd->bi_dram[i].size = dram_map[i].size;
}
}
@@ -256,6 +263,9 @@ int ft_board_setup(void *fdt, bd_t *bd)
return 0;
for (i = 0; i < ARRAY_SIZE(gd->bd->bi_dram); i++) {
+ if (!gd->bd->bi_dram[i].size)
+ continue;
+
rsv_addr = gd->bd->bi_dram[i].start + gd->bd->bi_dram[i].size;
rsv_addr -= rsv_size;
diff --git a/arch/arm/mach-uniphier/init.h b/arch/arm/mach-uniphier/init.h
index 453e68a43e..5c45f2d31b 100644
--- a/arch/arm/mach-uniphier/init.h
+++ b/arch/arm/mach-uniphier/init.h
@@ -13,18 +13,17 @@
#define UNIPHIER_MAX_NR_DRAM_CH 3
struct uniphier_dram_ch {
- unsigned long base;
unsigned long size;
unsigned int width;
};
struct uniphier_board_data {
unsigned int dram_freq;
- unsigned int dram_nr_ch;
struct uniphier_dram_ch dram_ch[UNIPHIER_MAX_NR_DRAM_CH];
unsigned int flags;
-#define UNIPHIER_BD_DDR3PLUS BIT(2)
+#define UNIPHIER_BD_DRAM_SPARSE BIT(9)
+#define UNIPHIER_BD_DDR3PLUS BIT(8)
#define UNIPHIER_BD_BOARD_GET_TYPE(f) ((f) & 0x7)
#define UNIPHIER_BD_BOARD_LD20_REF 0 /* LD20 reference */
@@ -119,12 +118,16 @@ void uniphier_pro4_clk_init(void);
void uniphier_pro5_clk_init(void);
void uniphier_pxs2_clk_init(void);
void uniphier_ld11_clk_init(void);
+void uniphier_ld20_clk_init(void);
+unsigned int uniphier_boot_device_raw(void);
int uniphier_pin_init(const char *pinconfig_name);
void uniphier_smp_kick_all_cpus(void);
void cci500_init(int nr_slaves);
+#undef pr_warn
#define pr_warn(fmt, args...) printf(fmt, ##args)
+#undef pr_err
#define pr_err(fmt, args...) printf(fmt, ##args)
#endif /* __MACH_INIT_H */
diff --git a/arch/arm/mach-uniphier/memconf.c b/arch/arm/mach-uniphier/memconf.c
index dcfc6455ba..4ced2cbace 100644
--- a/arch/arm/mach-uniphier/memconf.c
+++ b/arch/arm/mach-uniphier/memconf.c
@@ -93,7 +93,7 @@ static int __uniphier_memconf_init(const struct uniphier_board_data *bd,
}
/* is sparse mem? */
- if (bd->dram_ch[0].base + bd->dram_ch[0].size < bd->dram_ch[1].base)
+ if (bd->flags & UNIPHIER_BD_DRAM_SPARSE)
val |= SG_MEMCONF_SPARSEMEM;
if (!have_ch2)
diff --git a/arch/arm/mach-uniphier/micro-support-card.c b/arch/arm/mach-uniphier/micro-support-card.c
index 2b231ac187..8a3034114f 100644
--- a/arch/arm/mach-uniphier/micro-support-card.c
+++ b/arch/arm/mach-uniphier/micro-support-card.c
@@ -43,18 +43,13 @@ static int support_card_show_revision(void)
revision &= 0xff;
/* revision 3.6.x card changed the revision format */
- printf("(CPLD version %s%d.%d)\n", revision >> 4 == 6 ? "3." : "",
+ printf("SC: Micro Support Card (CPLD version %s%d.%d)\n",
+ revision >> 4 == 6 ? "3." : "",
revision >> 4, revision & 0xf);
return 0;
}
-int checkboard(void)
-{
- printf("SC: Micro Support Card ");
- return support_card_show_revision();
-}
-
void support_card_init(void)
{
support_card_reset();
@@ -64,6 +59,8 @@ void support_card_init(void)
*/
udelay(200);
support_card_reset_deassert();
+
+ support_card_show_revision();
}
#if defined(CONFIG_SMC911X)
diff --git a/arch/arm/mach-uniphier/mmc-boot-mode.c b/arch/arm/mach-uniphier/mmc-boot-mode.c
new file mode 100644
index 0000000000..d60c578ce7
--- /dev/null
+++ b/arch/arm/mach-uniphier/mmc-boot-mode.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <mmc.h>
+#include <spl.h>
+
+u32 spl_boot_mode(const u32 boot_device)
+{
+ struct mmc *mmc;
+
+ /*
+ * work around a bug in the Boot ROM of PH1-sLD3, LD4, Pro4, and sLD8:
+ *
+ * The boot ROM in these SoCs breaks the PARTITION_CONFIG [179] of
+ * Extended CSD register; when switching to the Boot Partition 1, the
+ * Boot ROM should issue the SWITCH command (CMD6) with Set Bits for
+ * the Access Bits, but in fact it uses Write Byte for the Access Bits.
+ * As a result, the BOOT_PARTITION_ENABLE field of the PARTITION_CONFIG
+ * is lost. This bug was fixed for PH1-Pro5 and later SoCs.
+ *
+ * Fixup mmc->part_config here because it is used to determine the
+ * partition which the U-Boot image is read from.
+ */
+ mmc = find_mmc_device(0);
+ mmc->part_config &= ~EXT_CSD_BOOT_PART_NUM(PART_ACCESS_MASK);
+ mmc->part_config |= EXT_CSD_BOOT_PARTITION_ENABLE;
+
+ return MMCSD_MODE_EMMCBOOT;
+}
diff --git a/arch/arm/mach-uniphier/mmc-first-dev.c b/arch/arm/mach-uniphier/mmc-first-dev.c
new file mode 100644
index 0000000000..8c45229a89
--- /dev/null
+++ b/arch/arm/mach-uniphier/mmc-first-dev.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <mmc.h>
+#include <linux/errno.h>
+
+static int find_first_mmc_device(void)
+{
+ struct mmc *mmc;
+ int i;
+
+ for (i = 0; (mmc = find_mmc_device(i)); i++) {
+ if (!mmc_init(mmc) && IS_MMC(mmc))
+ return i;
+ }
+
+ return -ENODEV;
+}
+
+int mmc_get_env_dev(void)
+{
+ return find_first_mmc_device();
+}
+
+static int do_mmcsetn(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int dev;
+
+ dev = find_first_mmc_device();
+ if (dev < 0)
+ return CMD_RET_FAILURE;
+
+ setenv_ulong("mmc_first_dev", dev);
+ return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(
+ mmcsetn, 1, 1, do_mmcsetn,
+ "Set the first MMC (not SD) dev number to \"mmc_first_dev\" environment",
+ ""
+);
diff --git a/arch/arm/mach-uniphier/spl_board_init.c b/arch/arm/mach-uniphier/spl_board_init.c
index da749a3d6d..0079a083e8 100644
--- a/arch/arm/mach-uniphier/spl_board_init.c
+++ b/arch/arm/mach-uniphier/spl_board_init.c
@@ -168,4 +168,8 @@ void spl_board_init(void)
pr_err("failed to init DRAM\n");
hang();
}
+
+#ifdef CONFIG_ARM64
+ dcache_disable();
+#endif
}
diff --git a/configs/uniphier_ld11_defconfig b/configs/uniphier_ld11_defconfig
index f14ae0430b..e5cfab6687 100644
--- a/configs/uniphier_ld11_defconfig
+++ b/configs/uniphier_ld11_defconfig
@@ -10,8 +10,10 @@ CONFIG_DEFAULT_DEVICE_TREE="uniphier-ld11-ref"
CONFIG_SPL=y
CONFIG_SPL_NOR_SUPPORT=y
CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CONFIG=y
# CONFIG_CMD_XIMG is not set
# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_I2C=y
CONFIG_CMD_USB=y
@@ -23,6 +25,8 @@ CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
# CONFIG_CMD_MISC is not set
CONFIG_CMD_FAT=y
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_OF_TRANSLATE=y
CONFIG_GPIO_UNIPHIER=y
@@ -31,7 +35,6 @@ CONFIG_I2C_EEPROM=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_SDMA=y
CONFIG_MMC_SDHCI_CADENCE=y
-CONFIG_MTD_NOR_FLASH=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
diff --git a/configs/uniphier_ld20_defconfig b/configs/uniphier_ld20_defconfig
index c065bf28c8..62513597a6 100644
--- a/configs/uniphier_ld20_defconfig
+++ b/configs/uniphier_ld20_defconfig
@@ -10,8 +10,10 @@ CONFIG_DEFAULT_DEVICE_TREE="uniphier-ld20-ref"
CONFIG_SPL=y
CONFIG_SPL_NOR_SUPPORT=y
CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CONFIG=y
# CONFIG_CMD_XIMG is not set
# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_I2C=y
CONFIG_CMD_USB=y
@@ -23,6 +25,8 @@ CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
# CONFIG_CMD_MISC is not set
CONFIG_CMD_FAT=y
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_OF_TRANSLATE=y
CONFIG_GPIO_UNIPHIER=y
@@ -31,7 +35,6 @@ CONFIG_I2C_EEPROM=y
CONFIG_MMC_UNIPHIER=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_CADENCE=y
-CONFIG_MTD_NOR_FLASH=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_STORAGE=y
diff --git a/configs/uniphier_ld4_sld8_defconfig b/configs/uniphier_ld4_sld8_defconfig
index b9a9524f19..68bca1942b 100644
--- a/configs/uniphier_ld4_sld8_defconfig
+++ b/configs/uniphier_ld4_sld8_defconfig
@@ -12,9 +12,11 @@ CONFIG_DEFAULT_DEVICE_TREE="uniphier-ld4-ref"
CONFIG_SPL=y
CONFIG_SPL_NOR_SUPPORT=y
CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CONFIG=y
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_XIMG is not set
# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_NAND=y
CONFIG_CMD_I2C=y
@@ -27,12 +29,13 @@ CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
# CONFIG_CMD_MISC is not set
CONFIG_CMD_FAT=y
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_GPIO_UNIPHIER=y
CONFIG_MISC=y
CONFIG_I2C_EEPROM=y
CONFIG_MMC_UNIPHIER=y
-CONFIG_MTD_NOR_FLASH=y
CONFIG_NAND_DENALI=y
CONFIG_SYS_NAND_DENALI_64BIT=y
CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
diff --git a/configs/uniphier_pro4_defconfig b/configs/uniphier_pro4_defconfig
index 0b83a1bda5..fc72889dbf 100644
--- a/configs/uniphier_pro4_defconfig
+++ b/configs/uniphier_pro4_defconfig
@@ -11,9 +11,11 @@ CONFIG_DEFAULT_DEVICE_TREE="uniphier-pro4-ref"
CONFIG_SPL=y
CONFIG_SPL_NOR_SUPPORT=y
CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CONFIG=y
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_XIMG is not set
# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_NAND=y
CONFIG_CMD_I2C=y
@@ -26,12 +28,13 @@ CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
# CONFIG_CMD_MISC is not set
CONFIG_CMD_FAT=y
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_GPIO_UNIPHIER=y
CONFIG_MISC=y
CONFIG_I2C_EEPROM=y
CONFIG_MMC_UNIPHIER=y
-CONFIG_MTD_NOR_FLASH=y
CONFIG_NAND_DENALI=y
CONFIG_SYS_NAND_DENALI_64BIT=y
CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
diff --git a/configs/uniphier_pxs2_ld6b_defconfig b/configs/uniphier_pxs2_ld6b_defconfig
index 7e6f0a0154..7a358e321c 100644
--- a/configs/uniphier_pxs2_ld6b_defconfig
+++ b/configs/uniphier_pxs2_ld6b_defconfig
@@ -12,9 +12,11 @@ CONFIG_DEFAULT_DEVICE_TREE="uniphier-pxs2-vodka"
CONFIG_SPL=y
CONFIG_SPL_NOR_SUPPORT=y
CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CONFIG=y
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_XIMG is not set
# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_NAND=y
CONFIG_CMD_I2C=y
@@ -27,12 +29,13 @@ CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
# CONFIG_CMD_MISC is not set
CONFIG_CMD_FAT=y
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_GPIO_UNIPHIER=y
CONFIG_MISC=y
CONFIG_I2C_EEPROM=y
CONFIG_MMC_UNIPHIER=y
-CONFIG_MTD_NOR_FLASH=y
CONFIG_NAND_DENALI=y
CONFIG_SYS_NAND_DENALI_64BIT=y
CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
diff --git a/configs/uniphier_sld3_defconfig b/configs/uniphier_sld3_defconfig
index f1f2a3fd65..ef5d1e4190 100644
--- a/configs/uniphier_sld3_defconfig
+++ b/configs/uniphier_sld3_defconfig
@@ -12,9 +12,11 @@ CONFIG_DEFAULT_DEVICE_TREE="uniphier-sld3-ref"
CONFIG_SPL=y
CONFIG_SPL_NOR_SUPPORT=y
CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CONFIG=y
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_XIMG is not set
# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_NAND=y
CONFIG_CMD_I2C=y
@@ -27,12 +29,13 @@ CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
# CONFIG_CMD_MISC is not set
CONFIG_CMD_FAT=y
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_GPIO_UNIPHIER=y
CONFIG_MISC=y
CONFIG_I2C_EEPROM=y
CONFIG_MMC_UNIPHIER=y
-CONFIG_MTD_NOR_FLASH=y
CONFIG_NAND_DENALI=y
CONFIG_SYS_NAND_DENALI_64BIT=y
CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
diff --git a/configs/uniphier_v8_defconfig b/configs/uniphier_v8_defconfig
index a8f2816f1b..85f8da5a46 100644
--- a/configs/uniphier_v8_defconfig
+++ b/configs/uniphier_v8_defconfig
@@ -7,8 +7,10 @@ CONFIG_SYS_TEXT_BASE=0x84000000
CONFIG_DEFAULT_DEVICE_TREE="uniphier-ld20-ref"
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CONFIG=y
# CONFIG_CMD_XIMG is not set
# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_I2C=y
CONFIG_CMD_USB=y
@@ -27,8 +29,9 @@ CONFIG_I2C_EEPROM=y
CONFIG_MMC_UNIPHIER=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_CADENCE=y
-CONFIG_MTD_NOR_FLASH=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_STORAGE=y
diff --git a/doc/README.uniphier b/doc/README.uniphier
index 539b1f20a1..f79659c9ca 100644
--- a/doc/README.uniphier
+++ b/doc/README.uniphier
@@ -75,7 +75,7 @@ Burn U-Boot images to NAND
Write the following to the NAND device:
- spl/u-boot-spl.bin at the offset address 0x00000000
- - u-boot.bin at the offset address 0x00010000
+ - u-boot.bin at the offset address 0x00020000
or
@@ -94,7 +94,7 @@ Burn U-Boot images to eMMC
Write the following to the Boot partition 1 of the eMMC device:
- spl/u-boot-spl.bin at the offset address 0x00000000
- - u-boot.bin at the offset address 0x00010000
+ - u-boot.bin at the offset address 0x00020000
or
@@ -179,4 +179,4 @@ newer SoCs. Even if it is, EA[25] is not connected on most of the boards.
--
Masahiro Yamada <yamada.masahiro@socionext.com>
-Oct. 2016
+Jan. 2017
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
index 51144b8e73..d8e9948ee7 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
@@ -5,6 +5,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <common.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/sizes.h>
@@ -15,6 +16,7 @@
#define UNIPHIER_PINCTRL_PINMUX_BASE 0x1000
#define UNIPHIER_PINCTRL_LOAD_PINMUX 0x1700
+#define UNIPHIER_PINCTRL_PUPDCTRL_BASE 0x1a00
#define UNIPHIER_PINCTRL_IECTRL 0x1d00
static const char *uniphier_pinctrl_dummy_name = "_dummy";
@@ -55,8 +57,8 @@ static const char *uniphier_pinmux_get_function_name(struct udevice *dev,
return priv->socdata->functions[selector];
}
-static void uniphier_pinconf_input_enable_perpin(struct udevice *dev,
- unsigned pin)
+static int uniphier_pinconf_input_enable_perpin(struct udevice *dev,
+ unsigned int pin, int enable)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
unsigned reg;
@@ -66,18 +68,30 @@ static void uniphier_pinconf_input_enable_perpin(struct udevice *dev,
mask = BIT(pin % 32);
tmp = readl(priv->base + reg);
- tmp |= mask;
+ if (enable)
+ tmp |= mask;
+ else
+ tmp &= ~mask;
writel(tmp, priv->base + reg);
+
+ return 0;
}
-static void uniphier_pinconf_input_enable_legacy(struct udevice *dev,
- unsigned pin)
+static int uniphier_pinconf_input_enable_legacy(struct udevice *dev,
+ unsigned int pin, int enable)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
int pins_count = priv->socdata->pins_count;
const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
int i;
+ /*
+ * Multiple pins share one input enable, per-pin disabling is
+ * impossible.
+ */
+ if (!enable)
+ return -EINVAL;
+
for (i = 0; i < pins_count; i++) {
if (pins[i].number == pin) {
unsigned int iectrl;
@@ -89,18 +103,115 @@ static void uniphier_pinconf_input_enable_legacy(struct udevice *dev,
writel(tmp, priv->base + UNIPHIER_PINCTRL_IECTRL);
}
}
+
+ return 0;
}
-static void uniphier_pinconf_input_enable(struct udevice *dev, unsigned pin)
+static int uniphier_pinconf_input_enable(struct udevice *dev,
+ unsigned int pin, int enable)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL)
- uniphier_pinconf_input_enable_perpin(dev, pin);
+ return uniphier_pinconf_input_enable_perpin(dev, pin, enable);
+ else
+ return uniphier_pinconf_input_enable_legacy(dev, pin, enable);
+}
+
+#if CONFIG_IS_ENABLED(PINCONF)
+
+static const struct pinconf_param uniphier_pinconf_params[] = {
+ { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+ { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
+ { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
+ { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
+ { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
+ { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
+};
+
+static int uniphier_pinconf_bias_set(struct udevice *dev, unsigned int pin,
+ unsigned int param, unsigned int arg)
+{
+ struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
+ unsigned int enable = 1;
+ unsigned int reg;
+ u32 mask, tmp;
+
+ if (!(priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE))
+ return -ENOTSUPP;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ enable = 0;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (arg == 0) /* total bias is not supported */
+ return -EINVAL;
+ break;
+ case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+ if (arg == 0) /* configuration ignored */
+ return 0;
+ default:
+ BUG();
+ }
+
+ reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pin / 32 * 4;
+ mask = BIT(pin % 32);
+
+ tmp = readl(priv->base + reg);
+ if (enable)
+ tmp |= mask;
else
- uniphier_pinconf_input_enable_legacy(dev, pin);
+ tmp &= ~mask;
+ writel(tmp, priv->base + reg);
+
+ return 0;
+}
+
+static int uniphier_pinconf_set_one(struct udevice *dev, unsigned int pin,
+ unsigned int param, unsigned int arg)
+{
+ int ret;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+ ret = uniphier_pinconf_bias_set(dev, pin, param, arg);
+ break;
+ case PIN_CONFIG_INPUT_ENABLE:
+ ret = uniphier_pinconf_input_enable(dev, pin, arg);
+ break;
+ default:
+ printf("unsupported configuration parameter %u\n", param);
+ return -EINVAL;
+ }
+
+ return ret;
}
+static int uniphier_pinconf_group_set(struct udevice *dev,
+ unsigned int group_selector,
+ unsigned int param, unsigned int arg)
+{
+ struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
+ const struct uniphier_pinctrl_group *grp =
+ &priv->socdata->groups[group_selector];
+ int i, ret;
+
+ for (i = 0; i < grp->num_pins; i++) {
+ ret = uniphier_pinconf_set_one(dev, grp->pins[i], param, arg);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+#endif /* CONFIG_IS_ENABLED(PINCONF) */
+
static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin,
int muxval)
{
@@ -112,7 +223,7 @@ static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin,
u32 tmp;
/* some pins need input-enabling */
- uniphier_pinconf_input_enable(dev, pin);
+ uniphier_pinconf_input_enable(dev, pin, 1);
if (muxval < 0)
return; /* dedicated pin; nothing to do for pin-mux */
@@ -174,6 +285,11 @@ const struct pinctrl_ops uniphier_pinctrl_ops = {
.get_functions_count = uniphier_pinmux_get_functions_count,
.get_function_name = uniphier_pinmux_get_function_name,
.pinmux_group_set = uniphier_pinmux_group_set,
+#if CONFIG_IS_ENABLED(PINCONF)
+ .pinconf_num_params = ARRAY_SIZE(uniphier_pinconf_params),
+ .pinconf_params = uniphier_pinconf_params,
+ .pinconf_group_set = uniphier_pinconf_group_set,
+#endif
.set_state = pinctrl_generic_set_state,
};
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c
index 1d318d824c..53c37cda7a 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c
@@ -92,7 +92,8 @@ static struct uniphier_pinctrl_socdata uniphier_ld11_pinctrl_socdata = {
.groups_count = ARRAY_SIZE(uniphier_ld11_groups),
.functions = uniphier_ld11_functions,
.functions_count = ARRAY_SIZE(uniphier_ld11_functions),
- .caps = UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL,
+ .caps = UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE |
+ UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL,
};
static int uniphier_ld11_pinctrl_probe(struct udevice *dev)
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
index 0c46450d36..5a7d142865 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
@@ -106,7 +106,8 @@ static struct uniphier_pinctrl_socdata uniphier_ld20_pinctrl_socdata = {
.groups_count = ARRAY_SIZE(uniphier_ld20_groups),
.functions = uniphier_ld20_functions,
.functions_count = ARRAY_SIZE(uniphier_ld20_functions),
- .caps = UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL,
+ .caps = UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE |
+ UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL,
};
static int uniphier_ld20_pinctrl_probe(struct udevice *dev)
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c
index 80d782c8d6..b25c7ea16e 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c
@@ -140,6 +140,7 @@ static struct uniphier_pinctrl_socdata uniphier_ld6b_pinctrl_socdata = {
.groups_count = ARRAY_SIZE(uniphier_ld6b_groups),
.functions = uniphier_ld6b_functions,
.functions_count = ARRAY_SIZE(uniphier_ld6b_functions),
+ .caps = UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE,
};
static int uniphier_ld6b_pinctrl_probe(struct udevice *dev)
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c
index 9670f254e2..70c90bae54 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c
@@ -147,7 +147,8 @@ static struct uniphier_pinctrl_socdata uniphier_pro5_pinctrl_socdata = {
.groups_count = ARRAY_SIZE(uniphier_pro5_groups),
.functions = uniphier_pro5_functions,
.functions_count = ARRAY_SIZE(uniphier_pro5_functions),
- .caps = UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE,
+ .caps = UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE |
+ UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE,
};
static int uniphier_pro5_pinctrl_probe(struct udevice *dev)
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
index 1d291703f4..60777c3045 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
@@ -140,6 +140,7 @@ static struct uniphier_pinctrl_socdata uniphier_pxs2_pinctrl_socdata = {
.groups_count = ARRAY_SIZE(uniphier_pxs2_groups),
.functions = uniphier_pxs2_functions,
.functions_count = ARRAY_SIZE(uniphier_pxs2_functions),
+ .caps = UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE,
};
static int uniphier_pxs2_pinctrl_probe(struct udevice *dev)
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier.h b/drivers/pinctrl/uniphier/pinctrl-uniphier.h
index 21e2d377b4..a0eccf8d4a 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier.h
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier.h
@@ -67,6 +67,7 @@ struct uniphier_pinctrl_socdata {
const char * const *functions;
int functions_count;
unsigned caps;
+#define UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE BIT(3)
#define UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL BIT(2)
#define UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE BIT(1)
#define UNIPHIER_PINCTRL_CAPS_MUX_4BIT BIT(0)
diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h
index ab35191d92..2976d6313c 100644
--- a/include/configs/uniphier.h
+++ b/include/configs/uniphier.h
@@ -142,7 +142,7 @@
#if defined(CONFIG_ARM64) && !defined(CONFIG_ARMV8_MULTIENTRY)
/* ARM Trusted Firmware */
#define BOOT_IMAGES \
- "second_image=bl1.bin\0" \
+ "second_image=unph_bl.bin\0" \
"third_image=fip.bin\0"
#else
#define BOOT_IMAGES \