blob: 804abe8a1b7cffe8e09c19d16016ec18343f4a61 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Kever Yang52ead2f2016-08-12 17:58:12 +08002/*
3 * Copyright (c) 2016 Rockchip Electronics Co., Ltd
Kever Yang52ead2f2016-08-12 17:58:12 +08004 */
Kever Yangd1078ea2019-07-22 20:02:10 +08005#include <common.h>
Simon Glassed38aef2020-05-10 11:40:03 -06006#include <command.h>
Kever Yangbbea4932019-07-22 20:02:13 +08007#include <dm.h>
Simon Glass5e6201b2019-08-01 09:46:51 -06008#include <env.h>
Kever Yangbbea4932019-07-22 20:02:13 +08009#include <clk.h>
Simon Glassa7b51302019-11-14 12:57:46 -070010#include <init.h>
Simon Glass9bc15642020-02-03 07:36:16 -070011#include <malloc.h>
Kever Yang1f145142019-07-09 21:58:44 +080012#include <asm/armv7.h>
Kever Yang52ead2f2016-08-12 17:58:12 +080013#include <asm/io.h>
Kever Yang882b2a42019-07-22 19:59:30 +080014#include <asm/arch-rockchip/bootrom.h>
Kever Yangbbea4932019-07-22 20:02:13 +080015#include <asm/arch-rockchip/clock.h>
Jagan Teki783acfd2020-01-09 14:22:17 +053016#include <asm/arch-rockchip/cru.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +080017#include <asm/arch-rockchip/hardware.h>
Kever Yang655f2a72019-03-29 09:09:03 +080018#include <asm/arch-rockchip/grf_rk3288.h>
Kever Yang66dd5942019-07-22 19:59:26 +080019#include <asm/arch-rockchip/pmu_rk3288.h>
Kever Yangd1078ea2019-07-22 20:02:10 +080020#include <asm/arch-rockchip/qos_rk3288.h>
Kever Yange47db832019-11-15 11:04:33 +080021#include <asm/arch-rockchip/sdram.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070022#include <linux/err.h>
Kever Yang66dd5942019-07-22 19:59:26 +080023
24DECLARE_GLOBAL_DATA_PTR;
Kever Yang52ead2f2016-08-12 17:58:12 +080025
Kever Yang655f2a72019-03-29 09:09:03 +080026#define GRF_BASE 0xff770000
Kever Yang52ead2f2016-08-12 17:58:12 +080027
Kever Yang882b2a42019-07-22 19:59:30 +080028const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
Levin Du27df5072019-10-17 15:22:38 +080029 [BROM_BOOTSOURCE_EMMC] = "/dwmmc@ff0f0000",
30 [BROM_BOOTSOURCE_SD] = "/dwmmc@ff0c0000",
Kever Yang882b2a42019-07-22 19:59:30 +080031};
32
Kever Yang1f145142019-07-09 21:58:44 +080033#ifdef CONFIG_SPL_BUILD
34static void configure_l2ctlr(void)
35{
36 u32 l2ctlr;
37
38 l2ctlr = read_l2ctlr();
39 l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
40
41 /*
42 * Data RAM write latency: 2 cycles
43 * Data RAM read latency: 2 cycles
44 * Data RAM setup latency: 1 cycle
45 * Tag RAM write latency: 1 cycle
46 * Tag RAM read latency: 1 cycle
47 * Tag RAM setup latency: 1 cycle
48 */
49 l2ctlr |= (1 << 3 | 1 << 0);
50 write_l2ctlr(l2ctlr);
51}
52#endif
53
Kever Yangd1078ea2019-07-22 20:02:10 +080054int rk3288_qos_init(void)
55{
56 int val = 2 << PRIORITY_HIGH_SHIFT | 2 << PRIORITY_LOW_SHIFT;
57 /* set vop qos to higher priority */
58 writel(val, CPU_AXI_QOS_PRIORITY + VIO0_VOP_QOS);
59 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_VOP_QOS);
60
61 if (!fdt_node_check_compatible(gd->fdt_blob, 0,
62 "rockchip,rk3288-tinker")) {
63 /* set isp qos to higher priority */
64 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_R_QOS);
65 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W0_QOS);
66 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W1_QOS);
67 }
68
69 return 0;
70}
71
Kever Yang52ead2f2016-08-12 17:58:12 +080072int arch_cpu_init(void)
73{
Kever Yanga3eff932019-07-09 21:58:43 +080074#ifdef CONFIG_SPL_BUILD
75 configure_l2ctlr();
76#else
Kever Yang52ead2f2016-08-12 17:58:12 +080077 /* We do some SoC one time setting here. */
Kever Yang655f2a72019-03-29 09:09:03 +080078 struct rk3288_grf * const grf = (void *)GRF_BASE;
Kever Yang52ead2f2016-08-12 17:58:12 +080079
80 /* Use rkpwm by default */
Kever Yang655f2a72019-03-29 09:09:03 +080081 rk_setreg(&grf->soc_con2, 1 << 0);
Kever Yangd1078ea2019-07-22 20:02:10 +080082
83 /*
84 * Disable JTAG on sdmmc0 IO. The SDMMC won't work until this bit is
85 * cleared
86 */
87 rk_clrreg(&grf->soc_con0, 1 << 12);
88
89 rk3288_qos_init();
Kever Yanga3eff932019-07-09 21:58:43 +080090#endif
Kever Yang52ead2f2016-08-12 17:58:12 +080091
92 return 0;
93}
Kever Yangabfed9b2019-03-29 09:09:04 +080094
95#ifdef CONFIG_DEBUG_UART_BOARD_INIT
96void board_debug_uart_init(void)
97{
98 /* Enable early UART on the RK3288 */
99 struct rk3288_grf * const grf = (void *)GRF_BASE;
100
101 rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C7_MASK << GPIO7C7_SHIFT |
102 GPIO7C6_MASK << GPIO7C6_SHIFT,
103 GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
104 GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
105}
106#endif
Kever Yangbbea4932019-07-22 20:02:13 +0800107
Kever Yangb7da2712019-07-22 20:02:14 +0800108__weak int rk3288_board_late_init(void)
109{
110 return 0;
111}
112
113int rk_board_late_init(void)
114{
Kever Yangb7da2712019-07-22 20:02:14 +0800115 return rk3288_board_late_init();
116}
117
Simon Glassed38aef2020-05-10 11:40:03 -0600118static int do_clock(struct cmd_tbl *cmdtp, int flag, int argc,
119 char *const argv[])
Kever Yangbbea4932019-07-22 20:02:13 +0800120{
121 static const struct {
122 char *name;
123 int id;
124 } clks[] = {
125 { "osc", CLK_OSC },
126 { "apll", CLK_ARM },
127 { "dpll", CLK_DDR },
128 { "cpll", CLK_CODEC },
129 { "gpll", CLK_GENERAL },
130#ifdef CONFIG_ROCKCHIP_RK3036
131 { "mpll", CLK_NEW },
132#else
133 { "npll", CLK_NEW },
134#endif
135 };
136 int ret, i;
137 struct udevice *dev;
138
139 ret = rockchip_get_clk(&dev);
140 if (ret) {
141 printf("clk-uclass not found\n");
142 return 0;
143 }
144
145 for (i = 0; i < ARRAY_SIZE(clks); i++) {
146 struct clk clk;
147 ulong rate;
148
149 clk.id = clks[i].id;
150 ret = clk_request(dev, &clk);
151 if (ret < 0)
152 continue;
153
154 rate = clk_get_rate(&clk);
155 printf("%s: %lu\n", clks[i].name, rate);
156
157 clk_free(&clk);
158 }
159
160 return 0;
161}
162
163U_BOOT_CMD(
164 clock, 2, 1, do_clock,
165 "display information about clocks",
166 ""
167);