]> git.sur5r.net Git - u-boot/blob - arch/arm/mach-rockchip/rk3288-board.c
rockchip: add boot-mode support for rk3288, rk3036
[u-boot] / arch / arm / mach-rockchip / rk3288-board.c
1 /*
2  * (C) Copyright 2015 Google, Inc
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <clk.h>
9 #include <dm.h>
10 #include <ram.h>
11 #include <syscon.h>
12 #include <asm/io.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/periph.h>
15 #include <asm/arch/pmu_rk3288.h>
16 #include <asm/arch/boot_mode.h>
17 #include <asm/gpio.h>
18 #include <dm/pinctrl.h>
19
20 DECLARE_GLOBAL_DATA_PTR;
21
22 #define PMU_BASE        0xff730000
23
24 static void setup_boot_mode(void)
25 {
26         struct rk3288_pmu *const pmu = (void *)PMU_BASE;
27         int boot_mode = readl(&pmu->sys_reg[0]);
28
29         debug("boot mode %x.\n", boot_mode);
30
31         /* Clear boot mode */
32         writel(BOOT_NORMAL, &pmu->sys_reg[0]);
33
34         switch (boot_mode) {
35         case BOOT_FASTBOOT:
36                 printf("enter fastboot!\n");
37                 setenv("preboot", "setenv preboot; fastboot usb0");
38                 break;
39         case BOOT_UMS:
40                 printf("enter UMS!\n");
41                 setenv("preboot", "setenv preboot; if mmc dev 0;"
42                        "then ums mmc 0; else ums mmc 1;fi");
43                 break;
44         }
45 }
46
47 __weak int rk_board_late_init(void)
48 {
49         return 0;
50 }
51
52 int board_late_init(void)
53 {
54         setup_boot_mode();
55
56         return rk_board_late_init();
57 }
58
59 int board_init(void)
60 {
61 #ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
62         struct udevice *pinctrl;
63         int ret;
64
65         /*
66          * We need to implement sdcard iomux here for the further
67          * initlization, otherwise, it'll hit sdcard command sending
68          * timeout exception.
69          */
70         ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
71         if (ret) {
72                 debug("%s: Cannot find pinctrl device\n", __func__);
73                 goto err;
74         }
75         ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
76         if (ret) {
77                 debug("%s: Failed to set up SD card\n", __func__);
78                 goto err;
79         }
80
81         return 0;
82 err:
83         printf("board_init: Error %d\n", ret);
84
85         /* No way to report error here */
86         hang();
87
88         return -1;
89 #else
90         return 0;
91 #endif
92 }
93
94 int dram_init(void)
95 {
96         struct ram_info ram;
97         struct udevice *dev;
98         int ret;
99
100         ret = uclass_get_device(UCLASS_RAM, 0, &dev);
101         if (ret) {
102                 debug("DRAM init failed: %d\n", ret);
103                 return ret;
104         }
105         ret = ram_get_info(dev, &ram);
106         if (ret) {
107                 debug("Cannot get DRAM size: %d\n", ret);
108                 return ret;
109         }
110         debug("SDRAM base=%lx, size=%x\n", ram.base, ram.size);
111         gd->ram_size = ram.size;
112
113         return 0;
114 }
115
116 #ifndef CONFIG_SYS_DCACHE_OFF
117 void enable_caches(void)
118 {
119         /* Enable D-cache. I-cache is already enabled in start.S */
120         dcache_enable();
121 }
122 #endif
123
124 #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
125 #include <usb.h>
126 #include <usb/dwc2_udc.h>
127
128 static struct dwc2_plat_otg_data rk3288_otg_data = {
129         .rx_fifo_sz     = 512,
130         .np_tx_fifo_sz  = 16,
131         .tx_fifo_sz     = 128,
132 };
133
134 int board_usb_init(int index, enum usb_init_type init)
135 {
136         int node, phy_node;
137         const char *mode;
138         bool matched = false;
139         const void *blob = gd->fdt_blob;
140         u32 grf_phy_offset;
141
142         /* find the usb_otg node */
143         node = fdt_node_offset_by_compatible(blob, -1,
144                                         "rockchip,rk3288-usb");
145
146         while (node > 0) {
147                 mode = fdt_getprop(blob, node, "dr_mode", NULL);
148                 if (mode && strcmp(mode, "otg") == 0) {
149                         matched = true;
150                         break;
151                 }
152
153                 node = fdt_node_offset_by_compatible(blob, node,
154                                         "rockchip,rk3288-usb");
155         }
156         if (!matched) {
157                 debug("Not found usb_otg device\n");
158                 return -ENODEV;
159         }
160         rk3288_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
161
162         node = fdtdec_lookup_phandle(blob, node, "phys");
163         if (node <= 0) {
164                 debug("Not found usb phy device\n");
165                 return -ENODEV;
166         }
167
168         phy_node = fdt_parent_offset(blob, node);
169         if (phy_node <= 0) {
170                 debug("Not found usb phy device\n");
171                 return -ENODEV;
172         }
173
174         rk3288_otg_data.phy_of_node = phy_node;
175         grf_phy_offset = fdtdec_get_addr(blob, node, "reg");
176
177         /* find the grf node */
178         node = fdt_node_offset_by_compatible(blob, -1,
179                                         "rockchip,rk3288-grf");
180         if (node <= 0) {
181                 debug("Not found grf device\n");
182                 return -ENODEV;
183         }
184         rk3288_otg_data.regs_phy = grf_phy_offset +
185                                 fdtdec_get_addr(blob, node, "reg");
186
187         return dwc2_udc_probe(&rk3288_otg_data);
188 }
189
190 int board_usb_cleanup(int index, enum usb_init_type init)
191 {
192         return 0;
193 }
194 #endif
195
196 static int do_clock(cmd_tbl_t *cmdtp, int flag, int argc,
197                        char * const argv[])
198 {
199         static const struct {
200                 char *name;
201                 int id;
202         } clks[] = {
203                 { "osc", CLK_OSC },
204                 { "apll", CLK_ARM },
205                 { "dpll", CLK_DDR },
206                 { "cpll", CLK_CODEC },
207                 { "gpll", CLK_GENERAL },
208 #ifdef CONFIG_ROCKCHIP_RK3036
209                 { "mpll", CLK_NEW },
210 #else
211                 { "npll", CLK_NEW },
212 #endif
213         };
214         int ret, i;
215         struct udevice *dev;
216
217         ret = rockchip_get_clk(&dev);
218         if (ret) {
219                 printf("clk-uclass not found\n");
220                 return 0;
221         }
222
223         for (i = 0; i < ARRAY_SIZE(clks); i++) {
224                 struct clk clk;
225                 ulong rate;
226
227                 clk.id = clks[i].id;
228                 ret = clk_request(dev, &clk);
229                 if (ret < 0)
230                         continue;
231
232                 rate = clk_get_rate(&clk);
233                 printf("%s: %lu\n", clks[i].name, rate);
234
235                 clk_free(&clk);
236         }
237
238         return 0;
239 }
240
241 U_BOOT_CMD(
242         clock, 2, 1, do_clock,
243         "display information about clocks",
244         ""
245 );