1 /* 2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <platform_def.h> 8 9 #include <arch_helpers.h> 10 #include <common/debug.h> 11 #include <lib/mmio.h> 12 13 #include <plat_private.h> 14 #include <rk3288_def.h> 15 #include <soc.h> 16 #include <secure.h> 17 18 /* sleep data for pll suspend */ 19 static struct deepsleep_data_s slp_data; 20 21 /* Table of regions to map using the MMU. */ 22 const mmap_region_t plat_rk_mmap[] = { 23 MAP_REGION_FLAT(GIC400_BASE, GIC400_SIZE, 24 MT_DEVICE | MT_RW | MT_SECURE), 25 MAP_REGION_FLAT(STIME_BASE, STIME_SIZE, 26 MT_DEVICE | MT_RW | MT_SECURE), 27 MAP_REGION_FLAT(SGRF_BASE, SGRF_SIZE, 28 MT_DEVICE | MT_RW | MT_SECURE), 29 MAP_REGION_FLAT(TZPC_BASE, TZPC_SIZE, 30 MT_DEVICE | MT_RW | MT_SECURE), 31 MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE, 32 MT_MEMORY | MT_RW | MT_SECURE), 33 MAP_REGION_FLAT(SRAM_BASE, SRAM_SIZE, 34 MT_DEVICE | MT_RW | MT_SECURE), 35 MAP_REGION_FLAT(PMU_BASE, PMU_SIZE, 36 MT_DEVICE | MT_RW | MT_SECURE), 37 MAP_REGION_FLAT(UART_DBG_BASE, UART_DBG_SIZE, 38 MT_DEVICE | MT_RW | MT_SECURE), 39 MAP_REGION_FLAT(CRU_BASE, CRU_SIZE, 40 MT_DEVICE | MT_RW | MT_SECURE), 41 MAP_REGION_FLAT(GRF_BASE, GRF_SIZE, 42 MT_DEVICE | MT_RW | MT_SECURE), 43 MAP_REGION_FLAT(DDR_PCTL0_BASE, DDR_PCTL0_SIZE, 44 MT_DEVICE | MT_RW | MT_SECURE), 45 MAP_REGION_FLAT(DDR_PHY0_BASE, DDR_PHY0_SIZE, 46 MT_DEVICE | MT_RW | MT_SECURE), 47 MAP_REGION_FLAT(DDR_PCTL1_BASE, DDR_PCTL1_SIZE, 48 MT_DEVICE | MT_RW | MT_SECURE), 49 MAP_REGION_FLAT(DDR_PHY1_BASE, DDR_PHY1_SIZE, 50 MT_DEVICE | MT_RW | MT_SECURE), 51 MAP_REGION_FLAT(SERVICE_BUS_BASE, SERVICE_BUS_SIZE, 52 MT_DEVICE | MT_RW | MT_SECURE), 53 MAP_REGION_FLAT(CORE_AXI_BUS_BASE, CORE_AXI_BUS_SIZE, 54 MT_DEVICE | MT_RW | MT_SECURE), 55 { 0 } 56 }; 57 58 /* The RockChip power domain tree descriptor */ 59 const unsigned char rockchip_power_domain_tree_desc[] = { 60 /* No of root nodes */ 61 PLATFORM_SYSTEM_COUNT, 62 /* No of children for the root node */ 63 PLATFORM_CLUSTER_COUNT, 64 /* No of children for the first cluster node */ 65 PLATFORM_CLUSTER0_CORE_COUNT, 66 }; 67 68 void plat_rockchip_soc_init(void) 69 { 70 secure_timer_init(); 71 secure_sgrf_init(); 72 /* 73 * We cannot enable ddr security at this point, as the kernel 74 * seems to have an issue with it even living in the same 128MB 75 * memory block. Only when moving the kernel to the second 76 * 128MB block does it not conflict, but then we'd loose this 77 * memory area for use. Late maybe enable 78 * secure_sgrf_ddr_rgn_init(); 79 */ 80 } 81 82 void regs_update_bits(uintptr_t addr, uint32_t val, 83 uint32_t mask, uint32_t shift) 84 { 85 uint32_t tmp, orig; 86 87 orig = mmio_read_32(addr); 88 89 tmp = orig & ~(mask << shift); 90 tmp |= (val & mask) << shift; 91 92 if (tmp != orig) 93 mmio_write_32(addr, tmp); 94 dsb(); 95 } 96 97 static void pll_save(uint32_t pll_id) 98 { 99 uint32_t *pll = slp_data.pll_con[pll_id]; 100 101 pll[0] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 0)); 102 pll[1] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 1)); 103 pll[2] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 2)); 104 pll[3] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 3)); 105 } 106 107 void clk_plls_suspend(void) 108 { 109 pll_save(NPLL_ID); 110 pll_save(CPLL_ID); 111 pll_save(GPLL_ID); 112 pll_save(APLL_ID); 113 slp_data.pll_mode = mmio_read_32(CRU_BASE + PLL_MODE_CON); 114 115 /* 116 * Switch PLLs other than DPLL (for SDRAM) to slow mode to 117 * avoid crashes on resume. The Mask ROM on the system will 118 * put APLL, CPLL, and GPLL into slow mode at resume time 119 * anyway (which is why we restore them), but we might not 120 * even make it to the Mask ROM if this isn't done at suspend 121 * time. 122 * 123 * NOTE: only APLL truly matters here, but we'll do them all. 124 */ 125 mmio_write_32(CRU_BASE + PLL_MODE_CON, 0xf3030000); 126 } 127 128 void clk_plls_resume(void) 129 { 130 /* restore pll-modes */ 131 mmio_write_32(CRU_BASE + PLL_MODE_CON, 132 slp_data.pll_mode | REG_SOC_WMSK); 133 } 134 135 void clk_gate_con_save(void) 136 { 137 uint32_t i = 0; 138 139 for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) 140 slp_data.cru_gate_con[i] = 141 mmio_read_32(CRU_BASE + CRU_CLKGATES_CON(i)); 142 } 143 144 void clk_gate_con_disable(void) 145 { 146 uint32_t i; 147 148 for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) 149 mmio_write_32(CRU_BASE + CRU_CLKGATES_CON(i), REG_SOC_WMSK); 150 } 151 152 void clk_gate_con_restore(void) 153 { 154 uint32_t i; 155 156 for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) 157 mmio_write_32(CRU_BASE + CRU_CLKGATES_CON(i), 158 REG_SOC_WMSK | slp_data.cru_gate_con[i]); 159 } 160 161 void clk_sel_con_save(void) 162 { 163 uint32_t i = 0; 164 165 for (i = 0; i < CRU_CLKSELS_CON_CNT; i++) 166 slp_data.cru_sel_con[i] = 167 mmio_read_32(CRU_BASE + CRU_CLKSELS_CON(i)); 168 } 169 170 void clk_sel_con_restore(void) 171 { 172 uint32_t i, val; 173 174 for (i = 0; i < CRU_CLKSELS_CON_CNT; i++) { 175 /* fractional dividers don't have write-masks */ 176 if ((i >= 7 && i <= 9) || 177 (i >= 17 && i <= 20) || 178 (i == 23) || (i == 41)) 179 val = slp_data.cru_sel_con[i]; 180 else 181 val = slp_data.cru_sel_con[i] | REG_SOC_WMSK; 182 183 mmio_write_32(CRU_BASE + CRU_CLKSELS_CON(i), val); 184 } 185 } 186 187 void __dead2 rockchip_soc_soft_reset(void) 188 { 189 uint32_t temp_val; 190 191 /* 192 * Switch PLLs other than DPLL (for SDRAM) to slow mode to 193 * avoid crashes on resume. The Mask ROM on the system will 194 * put APLL, CPLL, and GPLL into slow mode at resume time 195 * anyway (which is why we restore them), but we might not 196 * even make it to the Mask ROM if this isn't done at suspend 197 * time. 198 * 199 * NOTE: only APLL truly matters here, but we'll do them all. 200 */ 201 mmio_write_32(CRU_BASE + PLL_MODE_CON, 0xf3030000); 202 203 temp_val = mmio_read_32(CRU_BASE + CRU_GLB_RST_CON); 204 temp_val &= ~PMU_RST_MASK; 205 temp_val |= PMU_RST_BY_SECOND_SFT; 206 mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, temp_val); 207 mmio_write_32(CRU_BASE + CRU_GLB_SRST_SND, 0xeca8); 208 209 /* 210 * Maybe the HW needs some times to reset the system, 211 * so we do not hope the core to excute valid codes. 212 */ 213 while (1) 214 ; 215 } 216