1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2016 Rockchip Electronics Co., Ltd
10 #include <asm/armv7.h>
12 #include <asm/arch-rockchip/bootrom.h>
13 #include <asm/arch-rockchip/clock.h>
14 #include <asm/arch-rockchip/cru_rk3288.h>
15 #include <asm/arch-rockchip/hardware.h>
16 #include <asm/arch-rockchip/grf_rk3288.h>
17 #include <asm/arch-rockchip/pmu_rk3288.h>
18 #include <asm/arch-rockchip/qos_rk3288.h>
19 #include <asm/arch-rockchip/sdram.h>
21 DECLARE_GLOBAL_DATA_PTR;
23 #define GRF_BASE 0xff770000
25 const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
26 [BROM_BOOTSOURCE_EMMC] = "/dwmmc@ff0f0000",
27 [BROM_BOOTSOURCE_SD] = "/dwmmc@ff0c0000",
30 #ifdef CONFIG_SPL_BUILD
31 static void configure_l2ctlr(void)
35 l2ctlr = read_l2ctlr();
36 l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
39 * Data RAM write latency: 2 cycles
40 * Data RAM read latency: 2 cycles
41 * Data RAM setup latency: 1 cycle
42 * Tag RAM write latency: 1 cycle
43 * Tag RAM read latency: 1 cycle
44 * Tag RAM setup latency: 1 cycle
46 l2ctlr |= (1 << 3 | 1 << 0);
51 int rk3288_qos_init(void)
53 int val = 2 << PRIORITY_HIGH_SHIFT | 2 << PRIORITY_LOW_SHIFT;
54 /* set vop qos to higher priority */
55 writel(val, CPU_AXI_QOS_PRIORITY + VIO0_VOP_QOS);
56 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_VOP_QOS);
58 if (!fdt_node_check_compatible(gd->fdt_blob, 0,
59 "rockchip,rk3288-tinker")) {
60 /* set isp qos to higher priority */
61 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_R_QOS);
62 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W0_QOS);
63 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W1_QOS);
69 int arch_cpu_init(void)
71 #ifdef CONFIG_SPL_BUILD
74 /* We do some SoC one time setting here. */
75 struct rk3288_grf * const grf = (void *)GRF_BASE;
77 /* Use rkpwm by default */
78 rk_setreg(&grf->soc_con2, 1 << 0);
81 * Disable JTAG on sdmmc0 IO. The SDMMC won't work until this bit is
84 rk_clrreg(&grf->soc_con0, 1 << 12);
92 #ifdef CONFIG_DEBUG_UART_BOARD_INIT
93 void board_debug_uart_init(void)
95 /* Enable early UART on the RK3288 */
96 struct rk3288_grf * const grf = (void *)GRF_BASE;
98 rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C7_MASK << GPIO7C7_SHIFT |
99 GPIO7C6_MASK << GPIO7C6_SHIFT,
100 GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
101 GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
105 static void rk3288_detect_reset_reason(void)
107 struct rk3288_cru *cru = rockchip_get_cru();
113 switch (cru->cru_glb_rst_st) {
121 case FST_GLB_TSADC_RST_ST:
122 case SND_GLB_TSADC_RST_ST:
125 case FST_GLB_WDT_RST_ST:
126 case SND_GLB_WDT_RST_ST:
130 reason = "unknown reset";
133 env_set("reset_reason", reason);
136 * Clear cru_glb_rst_st, so we can determine the last reset cause
137 * for following resets.
139 rk_clrreg(&cru->cru_glb_rst_st, GLB_RST_ST_MASK);
142 __weak int rk3288_board_late_init(void)
147 int rk_board_late_init(void)
149 rk3288_detect_reset_reason();
151 return rk3288_board_late_init();
154 static int do_clock(cmd_tbl_t *cmdtp, int flag, int argc,
157 static const struct {
164 { "cpll", CLK_CODEC },
165 { "gpll", CLK_GENERAL },
166 #ifdef CONFIG_ROCKCHIP_RK3036
175 ret = rockchip_get_clk(&dev);
177 printf("clk-uclass not found\n");
181 for (i = 0; i < ARRAY_SIZE(clks); i++) {
186 ret = clk_request(dev, &clk);
190 rate = clk_get_rate(&clk);
191 printf("%s: %lu\n", clks[i].name, rate);
200 clock, 2, 1, do_clock,
201 "display information about clocks",