summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-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
38 files changed, 782 insertions, 636 deletions
diff --git a/arch/arm/dts/uniphier-ld11-ref.dts b/arch/arm/dts/uniphier-ld11-ref.dts
index ea11198..7693bf2 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 044e000..41ee07e 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 166b41f..124a1c6 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 7557880..a16b24e 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 64efd37..99b318f 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 e89a4c5..2564a02 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 ece761f..92dd610 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 0596451..db7d192 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 0000000..a54d2ac
--- /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 2992fd7..f1a467c 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 b066ed9..b5d2321 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 450c43b..47221ee 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 20ff773..20a9511 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 ddf8259..2b36494 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 0000000..5ec0b5b
--- /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 0000000..f3fb2f3
--- /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 0000000..bd47ac8
--- /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 a898021..0000000
--- 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 bd44d73..0000000
--- 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 a552770..0000000
--- 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 670d4f6..0000000
--- 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 0aac924..0000000
--- 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 43df670..4134197 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 58069cb..a4dcde7 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 0000000..5bb560c
--- /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 c66f083..697eb7a 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 7746deb..02befa2 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 d7e9303..5eefc4e 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 97a9fef..69aa4f2 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 157b915..500c1c1 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 05a62de..7fa29f1 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 881062d..d9f6c16 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 453e68a..5c45f2d 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 dcfc645..4ced2cb 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 2b231ac..8a30341 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 0000000..d60c578
--- /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 0000000..8c45229
--- /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 da749a3..0079a08 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
}