1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2015 Google, Inc 4 */ 5 6 #include <common.h> 7 #include <clk.h> 8 #include <dm.h> 9 #include <ram.h> 10 #include <syscon.h> 11 #include <asm/io.h> 12 #include <asm/arch/clock.h> 13 #include <asm/arch/cru_rk3288.h> 14 #include <asm/arch/periph.h> 15 #include <asm/arch/pmu_rk3288.h> 16 #include <asm/arch/qos_rk3288.h> 17 #include <asm/arch/boot_mode.h> 18 #include <asm/gpio.h> 19 #include <dm/pinctrl.h> 20 #include <dt-bindings/clock/rk3288-cru.h> 21 #include <power/regulator.h> 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 __weak int rk_board_late_init(void) 26 { 27 return 0; 28 } 29 30 int rk3288_qos_init(void) 31 { 32 int val = 2 << PRIORITY_HIGH_SHIFT | 2 << PRIORITY_LOW_SHIFT; 33 /* set vop qos to higher priority */ 34 writel(val, CPU_AXI_QOS_PRIORITY + VIO0_VOP_QOS); 35 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_VOP_QOS); 36 37 if (!fdt_node_check_compatible(gd->fdt_blob, 0, 38 "rockchip,rk3288-tinker")) 39 { 40 /* set isp qos to higher priority */ 41 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_R_QOS); 42 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W0_QOS); 43 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W1_QOS); 44 } 45 return 0; 46 } 47 48 static void rk3288_detect_reset_reason(void) 49 { 50 struct rk3288_cru *cru = rockchip_get_cru(); 51 const char *reason; 52 53 if (IS_ERR(cru)) 54 return; 55 56 switch (cru->cru_glb_rst_st) { 57 case GLB_POR_RST: 58 reason = "POR"; 59 break; 60 case FST_GLB_RST_ST: 61 case SND_GLB_RST_ST: 62 reason = "RST"; 63 break; 64 case FST_GLB_TSADC_RST_ST: 65 case SND_GLB_TSADC_RST_ST: 66 reason = "THERMAL"; 67 break; 68 case FST_GLB_WDT_RST_ST: 69 case SND_GLB_WDT_RST_ST: 70 reason = "WDOG"; 71 break; 72 default: 73 reason = "unknown reset"; 74 } 75 76 env_set("reset_reason", reason); 77 78 /* 79 * Clear cru_glb_rst_st, so we can determine the last reset cause 80 * for following resets. 81 */ 82 rk_clrreg(&cru->cru_glb_rst_st, GLB_RST_ST_MASK); 83 } 84 85 int board_late_init(void) 86 { 87 setup_boot_mode(); 88 rk3288_qos_init(); 89 rk3288_detect_reset_reason(); 90 91 return rk_board_late_init(); 92 } 93 94 #if !CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) 95 static int veyron_init(void) 96 { 97 struct udevice *dev; 98 struct clk clk; 99 int ret; 100 101 ret = regulator_get_by_platname("vdd_arm", &dev); 102 if (ret) { 103 debug("Cannot set regulator name\n"); 104 return ret; 105 } 106 107 /* Slowly raise to max CPU voltage to prevent overshoot */ 108 ret = regulator_set_value(dev, 1200000); 109 if (ret) 110 return ret; 111 udelay(175); /* Must wait for voltage to stabilize, 2mV/us */ 112 ret = regulator_set_value(dev, 1400000); 113 if (ret) 114 return ret; 115 udelay(100); /* Must wait for voltage to stabilize, 2mV/us */ 116 117 ret = rockchip_get_clk(&clk.dev); 118 if (ret) 119 return ret; 120 clk.id = PLL_APLL; 121 ret = clk_set_rate(&clk, 1800000000); 122 if (IS_ERR_VALUE(ret)) 123 return ret; 124 125 ret = regulator_get_by_platname("vcc33_sd", &dev); 126 if (ret) { 127 debug("Cannot get regulator name\n"); 128 return ret; 129 } 130 131 ret = regulator_set_value(dev, 3300000); 132 if (ret) 133 return ret; 134 135 ret = regulators_enable_boot_on(false); 136 if (ret) { 137 debug("%s: Cannot enable boot on regulators\n", __func__); 138 return ret; 139 } 140 141 return 0; 142 } 143 #endif 144 145 int board_init(void) 146 { 147 #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) 148 struct udevice *pinctrl; 149 int ret; 150 151 /* 152 * We need to implement sdcard iomux here for the further 153 * initlization, otherwise, it'll hit sdcard command sending 154 * timeout exception. 155 */ 156 ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); 157 if (ret) { 158 debug("%s: Cannot find pinctrl device\n", __func__); 159 goto err; 160 } 161 ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD); 162 if (ret) { 163 debug("%s: Failed to set up SD card\n", __func__); 164 goto err; 165 } 166 167 return 0; 168 err: 169 printf("board_init: Error %d\n", ret); 170 171 /* No way to report error here */ 172 hang(); 173 174 return -1; 175 #else 176 int ret; 177 178 /* We do some SoC one time setting here */ 179 if (!fdt_node_check_compatible(gd->fdt_blob, 0, "google,veyron")) { 180 ret = veyron_init(); 181 if (ret) 182 return ret; 183 } 184 185 return 0; 186 #endif 187 } 188 189 #ifndef CONFIG_SYS_DCACHE_OFF 190 void enable_caches(void) 191 { 192 /* Enable D-cache. I-cache is already enabled in start.S */ 193 dcache_enable(); 194 } 195 #endif 196 197 #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) 198 #include <usb.h> 199 #include <usb/dwc2_udc.h> 200 201 static struct dwc2_plat_otg_data rk3288_otg_data = { 202 .rx_fifo_sz = 512, 203 .np_tx_fifo_sz = 16, 204 .tx_fifo_sz = 128, 205 }; 206 207 int board_usb_init(int index, enum usb_init_type init) 208 { 209 int node, phy_node; 210 const char *mode; 211 bool matched = false; 212 const void *blob = gd->fdt_blob; 213 u32 grf_phy_offset; 214 215 /* find the usb_otg node */ 216 node = fdt_node_offset_by_compatible(blob, -1, 217 "rockchip,rk3288-usb"); 218 219 while (node > 0) { 220 mode = fdt_getprop(blob, node, "dr_mode", NULL); 221 if (mode && strcmp(mode, "otg") == 0) { 222 matched = true; 223 break; 224 } 225 226 node = fdt_node_offset_by_compatible(blob, node, 227 "rockchip,rk3288-usb"); 228 } 229 if (!matched) { 230 debug("Not found usb_otg device\n"); 231 return -ENODEV; 232 } 233 rk3288_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg"); 234 235 node = fdtdec_lookup_phandle(blob, node, "phys"); 236 if (node <= 0) { 237 debug("Not found usb phy device\n"); 238 return -ENODEV; 239 } 240 241 phy_node = fdt_parent_offset(blob, node); 242 if (phy_node <= 0) { 243 debug("Not found usb phy device\n"); 244 return -ENODEV; 245 } 246 247 rk3288_otg_data.phy_of_node = phy_node; 248 grf_phy_offset = fdtdec_get_addr(blob, node, "reg"); 249 250 /* find the grf node */ 251 node = fdt_node_offset_by_compatible(blob, -1, 252 "rockchip,rk3288-grf"); 253 if (node <= 0) { 254 debug("Not found grf device\n"); 255 return -ENODEV; 256 } 257 rk3288_otg_data.regs_phy = grf_phy_offset + 258 fdtdec_get_addr(blob, node, "reg"); 259 260 return dwc2_udc_probe(&rk3288_otg_data); 261 } 262 263 int board_usb_cleanup(int index, enum usb_init_type init) 264 { 265 return 0; 266 } 267 #endif 268 269 static int do_clock(cmd_tbl_t *cmdtp, int flag, int argc, 270 char * const argv[]) 271 { 272 static const struct { 273 char *name; 274 int id; 275 } clks[] = { 276 { "osc", CLK_OSC }, 277 { "apll", CLK_ARM }, 278 { "dpll", CLK_DDR }, 279 { "cpll", CLK_CODEC }, 280 { "gpll", CLK_GENERAL }, 281 #ifdef CONFIG_ROCKCHIP_RK3036 282 { "mpll", CLK_NEW }, 283 #else 284 { "npll", CLK_NEW }, 285 #endif 286 }; 287 int ret, i; 288 struct udevice *dev; 289 290 ret = rockchip_get_clk(&dev); 291 if (ret) { 292 printf("clk-uclass not found\n"); 293 return 0; 294 } 295 296 for (i = 0; i < ARRAY_SIZE(clks); i++) { 297 struct clk clk; 298 ulong rate; 299 300 clk.id = clks[i].id; 301 ret = clk_request(dev, &clk); 302 if (ret < 0) 303 continue; 304 305 rate = clk_get_rate(&clk); 306 printf("%s: %lu\n", clks[i].name, rate); 307 308 clk_free(&clk); 309 } 310 311 return 0; 312 } 313 314 U_BOOT_CMD( 315 clock, 2, 1, do_clock, 316 "display information about clocks", 317 "" 318 ); 319 320 int board_early_init_f(void) 321 { 322 const uintptr_t GRF_SOC_CON0 = 0xff770244; 323 const uintptr_t GRF_SOC_CON2 = 0xff77024c; 324 struct udevice *pinctrl; 325 struct udevice *dev; 326 int ret; 327 328 /* 329 * This init is done in SPL, but when chain-loading U-Boot SPL will 330 * have been skipped. Allow the clock driver to check if it needs 331 * setting up. 332 */ 333 ret = rockchip_get_clk(&dev); 334 if (ret) { 335 debug("CLK init failed: %d\n", ret); 336 return ret; 337 } 338 ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); 339 if (ret) { 340 debug("%s: Cannot find pinctrl device\n", __func__); 341 return ret; 342 } 343 344 /* Enable debug UART */ 345 ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG); 346 if (ret) { 347 debug("%s: Failed to set up console UART\n", __func__); 348 return ret; 349 } 350 rk_setreg(GRF_SOC_CON2, 1 << 0); 351 352 /* 353 * Disable JTAG on sdmmc0 IO. The SDMMC won't work until this bit is 354 * cleared 355 */ 356 rk_clrreg(GRF_SOC_CON0, 1 << 12); 357 358 return 0; 359 } 360