rk3288.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2016 Rockchip Electronics Co., Ltd
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <env.h>
  8. #include <clk.h>
  9. #include <init.h>
  10. #include <asm/armv7.h>
  11. #include <asm/io.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>
  20. DECLARE_GLOBAL_DATA_PTR;
  21. #define GRF_BASE 0xff770000
  22. const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
  23. [BROM_BOOTSOURCE_EMMC] = "/dwmmc@ff0f0000",
  24. [BROM_BOOTSOURCE_SD] = "/dwmmc@ff0c0000",
  25. };
  26. #ifdef CONFIG_SPL_BUILD
  27. static void configure_l2ctlr(void)
  28. {
  29. u32 l2ctlr;
  30. l2ctlr = read_l2ctlr();
  31. l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
  32. /*
  33. * Data RAM write latency: 2 cycles
  34. * Data RAM read latency: 2 cycles
  35. * Data RAM setup latency: 1 cycle
  36. * Tag RAM write latency: 1 cycle
  37. * Tag RAM read latency: 1 cycle
  38. * Tag RAM setup latency: 1 cycle
  39. */
  40. l2ctlr |= (1 << 3 | 1 << 0);
  41. write_l2ctlr(l2ctlr);
  42. }
  43. #endif
  44. int rk3288_qos_init(void)
  45. {
  46. int val = 2 << PRIORITY_HIGH_SHIFT | 2 << PRIORITY_LOW_SHIFT;
  47. /* set vop qos to higher priority */
  48. writel(val, CPU_AXI_QOS_PRIORITY + VIO0_VOP_QOS);
  49. writel(val, CPU_AXI_QOS_PRIORITY + VIO1_VOP_QOS);
  50. if (!fdt_node_check_compatible(gd->fdt_blob, 0,
  51. "rockchip,rk3288-tinker")) {
  52. /* set isp qos to higher priority */
  53. writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_R_QOS);
  54. writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W0_QOS);
  55. writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W1_QOS);
  56. }
  57. return 0;
  58. }
  59. int arch_cpu_init(void)
  60. {
  61. #ifdef CONFIG_SPL_BUILD
  62. configure_l2ctlr();
  63. #else
  64. /* We do some SoC one time setting here. */
  65. struct rk3288_grf * const grf = (void *)GRF_BASE;
  66. /* Use rkpwm by default */
  67. rk_setreg(&grf->soc_con2, 1 << 0);
  68. /*
  69. * Disable JTAG on sdmmc0 IO. The SDMMC won't work until this bit is
  70. * cleared
  71. */
  72. rk_clrreg(&grf->soc_con0, 1 << 12);
  73. rk3288_qos_init();
  74. #endif
  75. return 0;
  76. }
  77. #ifdef CONFIG_DEBUG_UART_BOARD_INIT
  78. void board_debug_uart_init(void)
  79. {
  80. /* Enable early UART on the RK3288 */
  81. struct rk3288_grf * const grf = (void *)GRF_BASE;
  82. rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C7_MASK << GPIO7C7_SHIFT |
  83. GPIO7C6_MASK << GPIO7C6_SHIFT,
  84. GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
  85. GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
  86. }
  87. #endif
  88. static void rk3288_detect_reset_reason(void)
  89. {
  90. struct rk3288_cru *cru = rockchip_get_cru();
  91. const char *reason;
  92. if (IS_ERR(cru))
  93. return;
  94. switch (cru->cru_glb_rst_st) {
  95. case GLB_POR_RST:
  96. reason = "POR";
  97. break;
  98. case FST_GLB_RST_ST:
  99. case SND_GLB_RST_ST:
  100. reason = "RST";
  101. break;
  102. case FST_GLB_TSADC_RST_ST:
  103. case SND_GLB_TSADC_RST_ST:
  104. reason = "THERMAL";
  105. break;
  106. case FST_GLB_WDT_RST_ST:
  107. case SND_GLB_WDT_RST_ST:
  108. reason = "WDOG";
  109. break;
  110. default:
  111. reason = "unknown reset";
  112. }
  113. env_set("reset_reason", reason);
  114. /*
  115. * Clear cru_glb_rst_st, so we can determine the last reset cause
  116. * for following resets.
  117. */
  118. rk_clrreg(&cru->cru_glb_rst_st, GLB_RST_ST_MASK);
  119. }
  120. __weak int rk3288_board_late_init(void)
  121. {
  122. return 0;
  123. }
  124. int rk_board_late_init(void)
  125. {
  126. rk3288_detect_reset_reason();
  127. return rk3288_board_late_init();
  128. }
  129. static int do_clock(cmd_tbl_t *cmdtp, int flag, int argc,
  130. char * const argv[])
  131. {
  132. static const struct {
  133. char *name;
  134. int id;
  135. } clks[] = {
  136. { "osc", CLK_OSC },
  137. { "apll", CLK_ARM },
  138. { "dpll", CLK_DDR },
  139. { "cpll", CLK_CODEC },
  140. { "gpll", CLK_GENERAL },
  141. #ifdef CONFIG_ROCKCHIP_RK3036
  142. { "mpll", CLK_NEW },
  143. #else
  144. { "npll", CLK_NEW },
  145. #endif
  146. };
  147. int ret, i;
  148. struct udevice *dev;
  149. ret = rockchip_get_clk(&dev);
  150. if (ret) {
  151. printf("clk-uclass not found\n");
  152. return 0;
  153. }
  154. for (i = 0; i < ARRAY_SIZE(clks); i++) {
  155. struct clk clk;
  156. ulong rate;
  157. clk.id = clks[i].id;
  158. ret = clk_request(dev, &clk);
  159. if (ret < 0)
  160. continue;
  161. rate = clk_get_rate(&clk);
  162. printf("%s: %lu\n", clks[i].name, rate);
  163. clk_free(&clk);
  164. }
  165. return 0;
  166. }
  167. U_BOOT_CMD(
  168. clock, 2, 1, do_clock,
  169. "display information about clocks",
  170. ""
  171. );