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