ARM: uniphier: simplify SoC ID get function
[project/bcm63xx/u-boot.git] / arch / arm / mach-uniphier / boot-mode / spl_board.c
1 /*
2 * Copyright (C) 2016 Socionext Inc.
3 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8 #include <common.h>
9 #include <spl.h>
10 #include <linux/io.h>
11 #include <asm/processor.h>
12
13 #include "../soc-info.h"
14
15 struct uniphier_romfunc_table {
16 void *mmc_send_cmd;
17 void *mmc_card_blockaddr;
18 void *mmc_switch_part;
19 void *mmc_load_image;
20 };
21
22 static const struct uniphier_romfunc_table uniphier_ld11_romfunc_table = {
23 .mmc_send_cmd = (void *)0x20d8,
24 .mmc_card_blockaddr = (void *)0x1b68,
25 .mmc_switch_part = (void *)0x1c38,
26 .mmc_load_image = (void *)0x2e48,
27 };
28
29 static const struct uniphier_romfunc_table uniphier_ld20_romfunc_table = {
30 .mmc_send_cmd = (void *)0x2130,
31 .mmc_card_blockaddr = (void *)0x1ba0,
32 .mmc_switch_part = (void *)0x1c70,
33 .mmc_load_image = (void *)0x2ef0,
34 };
35
36 int uniphier_rom_get_mmc_funcptr(int (**send_cmd)(u32, u32),
37 int (**card_blockaddr)(u32),
38 int (**switch_part)(int),
39 int (**load_image)(u32, uintptr_t, u32))
40 {
41 const struct uniphier_romfunc_table *table;
42
43 switch (uniphier_get_soc_id()) {
44 case UNIPHIER_LD11_ID:
45 table = &uniphier_ld11_romfunc_table;
46 break;
47 case UNIPHIER_LD20_ID:
48 table = &uniphier_ld20_romfunc_table;
49 break;
50 default:
51 printf("unsupported SoC\n");
52 return -EINVAL;
53 }
54
55 *send_cmd = table->mmc_send_cmd;
56 *card_blockaddr = table->mmc_card_blockaddr;
57 *switch_part = table->mmc_switch_part;
58 *load_image = table->mmc_load_image;
59
60 return 0;
61 }
62
63 static int spl_board_load_image(struct spl_image_info *spl_image,
64 struct spl_boot_device *bootdev)
65 {
66 int (*send_cmd)(u32 cmd, u32 arg);
67 int (*card_blockaddr)(u32 rca);
68 int (*switch_part)(int part);
69 int (*load_image)(u32 dev_addr, uintptr_t load_addr, u32 block_cnt);
70 u32 dev_addr = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR;
71 const u32 rca = 0x1000; /* RCA assigned by Boot ROM */
72 int ret;
73
74 ret = uniphier_rom_get_mmc_funcptr(&send_cmd, &card_blockaddr,
75 &switch_part, &load_image);
76 if (ret)
77 return ret;
78
79 /*
80 * deselect card before SEND_CSD command.
81 * Do not check the return code. It fails, but it is OK.
82 */
83 (*send_cmd)(0x071a0000, 0); /* CMD7 (arg=0) */
84
85 /* reset CMD Line */
86 writeb(0x6, 0x5a00022f);
87 while (readb(0x5a00022f))
88 cpu_relax();
89
90 ret = (*card_blockaddr)(rca);
91 if (ret) {
92 debug("card is block addressing\n");
93 } else {
94 debug("card is byte addressing\n");
95 dev_addr *= 512;
96 }
97
98 ret = (*send_cmd)(0x071a0000, rca << 16); /* CMD7: select card again */
99 if (ret)
100 printf("failed to select card\n");
101
102 ret = (*switch_part)(1); /* Switch to Boot Partition 1 */
103 if (ret)
104 printf("failed to switch partition\n");
105
106 ret = (*load_image)(dev_addr, CONFIG_SYS_TEXT_BASE, 1);
107 if (ret) {
108 printf("failed to load image\n");
109 return ret;
110 }
111
112 ret = spl_parse_image_header(spl_image, (void *)CONFIG_SYS_TEXT_BASE);
113 if (ret)
114 return ret;
115
116 ret = (*load_image)(dev_addr, spl_image->load_addr,
117 spl_image->size / 512);
118 if (ret) {
119 printf("failed to load image\n");
120 return ret;
121 }
122
123 return 0;
124 }
125 SPL_LOAD_IMAGE_METHOD("eMMC", 0, BOOT_DEVICE_BOARD, spl_board_load_image);