1*010d6ae3SXiaoDong Huang /* 2*010d6ae3SXiaoDong Huang * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. 3*010d6ae3SXiaoDong Huang * 4*010d6ae3SXiaoDong Huang * SPDX-License-Identifier: BSD-3-Clause 5*010d6ae3SXiaoDong Huang */ 6*010d6ae3SXiaoDong Huang 7*010d6ae3SXiaoDong Huang #include <platform_def.h> 8*010d6ae3SXiaoDong Huang 9*010d6ae3SXiaoDong Huang #include <arch_helpers.h> 10*010d6ae3SXiaoDong Huang #include <common/debug.h> 11*010d6ae3SXiaoDong Huang #include <drivers/console.h> 12*010d6ae3SXiaoDong Huang #include <drivers/delay_timer.h> 13*010d6ae3SXiaoDong Huang #include <lib/mmio.h> 14*010d6ae3SXiaoDong Huang 15*010d6ae3SXiaoDong Huang #include <ddr_parameter.h> 16*010d6ae3SXiaoDong Huang #include <platform_def.h> 17*010d6ae3SXiaoDong Huang #include <pmu.h> 18*010d6ae3SXiaoDong Huang #include <px30_def.h> 19*010d6ae3SXiaoDong Huang #include <soc.h> 20*010d6ae3SXiaoDong Huang #include <rockchip_sip_svc.h> 21*010d6ae3SXiaoDong Huang 22*010d6ae3SXiaoDong Huang /* Aggregate of all devices in the first GB */ 23*010d6ae3SXiaoDong Huang #define PX30_DEV_RNG0_BASE 0xff000000 24*010d6ae3SXiaoDong Huang #define PX30_DEV_RNG0_SIZE 0x00ff0000 25*010d6ae3SXiaoDong Huang 26*010d6ae3SXiaoDong Huang const mmap_region_t plat_rk_mmap[] = { 27*010d6ae3SXiaoDong Huang MAP_REGION_FLAT(PX30_DEV_RNG0_BASE, PX30_DEV_RNG0_SIZE, 28*010d6ae3SXiaoDong Huang MT_DEVICE | MT_RW | MT_SECURE), 29*010d6ae3SXiaoDong Huang MAP_REGION_FLAT(SHARE_MEM_BASE, SHARE_MEM_SIZE, 30*010d6ae3SXiaoDong Huang MT_DEVICE | MT_RW | MT_SECURE), 31*010d6ae3SXiaoDong Huang MAP_REGION_FLAT(DDR_PARAM_BASE, DDR_PARAM_SIZE, 32*010d6ae3SXiaoDong Huang MT_DEVICE | MT_RW | MT_SECURE), 33*010d6ae3SXiaoDong Huang { 0 } 34*010d6ae3SXiaoDong Huang }; 35*010d6ae3SXiaoDong Huang 36*010d6ae3SXiaoDong Huang /* The RockChip power domain tree descriptor */ 37*010d6ae3SXiaoDong Huang const unsigned char rockchip_power_domain_tree_desc[] = { 38*010d6ae3SXiaoDong Huang /* No of root nodes */ 39*010d6ae3SXiaoDong Huang PLATFORM_SYSTEM_COUNT, 40*010d6ae3SXiaoDong Huang /* No of children for the root node */ 41*010d6ae3SXiaoDong Huang PLATFORM_CLUSTER_COUNT, 42*010d6ae3SXiaoDong Huang /* No of children for the first cluster node */ 43*010d6ae3SXiaoDong Huang PLATFORM_CLUSTER0_CORE_COUNT, 44*010d6ae3SXiaoDong Huang }; 45*010d6ae3SXiaoDong Huang 46*010d6ae3SXiaoDong Huang void clk_gate_con_save(uint32_t *clkgt_save) 47*010d6ae3SXiaoDong Huang { 48*010d6ae3SXiaoDong Huang uint32_t i, j; 49*010d6ae3SXiaoDong Huang 50*010d6ae3SXiaoDong Huang for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) 51*010d6ae3SXiaoDong Huang clkgt_save[i] = 52*010d6ae3SXiaoDong Huang mmio_read_32(CRU_BASE + CRU_CLKGATES_CON(i)); 53*010d6ae3SXiaoDong Huang j = i; 54*010d6ae3SXiaoDong Huang for (i = 0; i < CRU_PMU_CLKGATE_CON_CNT; i++, j++) 55*010d6ae3SXiaoDong Huang clkgt_save[j] = 56*010d6ae3SXiaoDong Huang mmio_read_32(PMUCRU_BASE + CRU_PMU_CLKGATES_CON(i)); 57*010d6ae3SXiaoDong Huang } 58*010d6ae3SXiaoDong Huang 59*010d6ae3SXiaoDong Huang void clk_gate_con_restore(uint32_t *clkgt_save) 60*010d6ae3SXiaoDong Huang { 61*010d6ae3SXiaoDong Huang uint32_t i, j; 62*010d6ae3SXiaoDong Huang 63*010d6ae3SXiaoDong Huang for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) 64*010d6ae3SXiaoDong Huang mmio_write_32(CRU_BASE + CRU_CLKGATES_CON(i), 65*010d6ae3SXiaoDong Huang WITH_16BITS_WMSK(clkgt_save[i])); 66*010d6ae3SXiaoDong Huang 67*010d6ae3SXiaoDong Huang j = i; 68*010d6ae3SXiaoDong Huang for (i = 0; i < CRU_PMU_CLKGATE_CON_CNT; i++, j++) 69*010d6ae3SXiaoDong Huang mmio_write_32(PMUCRU_BASE + CRU_PMU_CLKGATES_CON(i), 70*010d6ae3SXiaoDong Huang WITH_16BITS_WMSK(clkgt_save[j])); 71*010d6ae3SXiaoDong Huang } 72*010d6ae3SXiaoDong Huang 73*010d6ae3SXiaoDong Huang void clk_gate_con_disable(void) 74*010d6ae3SXiaoDong Huang { 75*010d6ae3SXiaoDong Huang uint32_t i; 76*010d6ae3SXiaoDong Huang 77*010d6ae3SXiaoDong Huang for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) 78*010d6ae3SXiaoDong Huang mmio_write_32(CRU_BASE + CRU_CLKGATES_CON(i), 79*010d6ae3SXiaoDong Huang 0xffff0000); 80*010d6ae3SXiaoDong Huang 81*010d6ae3SXiaoDong Huang for (i = 0; i < CRU_PMU_CLKGATE_CON_CNT; i++) 82*010d6ae3SXiaoDong Huang mmio_write_32(PMUCRU_BASE + CRU_PMU_CLKGATES_CON(i), 83*010d6ae3SXiaoDong Huang 0xffff0000); 84*010d6ae3SXiaoDong Huang } 85*010d6ae3SXiaoDong Huang 86*010d6ae3SXiaoDong Huang void secure_timer_init(void) 87*010d6ae3SXiaoDong Huang { 88*010d6ae3SXiaoDong Huang mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG, 89*010d6ae3SXiaoDong Huang TIMER_DIS); 90*010d6ae3SXiaoDong Huang 91*010d6ae3SXiaoDong Huang mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT0, 0xffffffff); 92*010d6ae3SXiaoDong Huang mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT1, 0xffffffff); 93*010d6ae3SXiaoDong Huang 94*010d6ae3SXiaoDong Huang /* auto reload & enable the timer */ 95*010d6ae3SXiaoDong Huang mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG, 96*010d6ae3SXiaoDong Huang TIMER_EN | TIMER_FMODE); 97*010d6ae3SXiaoDong Huang } 98*010d6ae3SXiaoDong Huang 99*010d6ae3SXiaoDong Huang static void sgrf_init(void) 100*010d6ae3SXiaoDong Huang { 101*010d6ae3SXiaoDong Huang uint32_t i, val; 102*010d6ae3SXiaoDong Huang struct param_ddr_usage usg; 103*010d6ae3SXiaoDong Huang 104*010d6ae3SXiaoDong Huang /* general secure regions */ 105*010d6ae3SXiaoDong Huang usg = ddr_region_usage_parse(DDR_PARAM_BASE, 106*010d6ae3SXiaoDong Huang PLAT_MAX_DDR_CAPACITY_MB); 107*010d6ae3SXiaoDong Huang for (i = 0; i < usg.s_nr; i++) { 108*010d6ae3SXiaoDong Huang /* enable secure */ 109*010d6ae3SXiaoDong Huang val = mmio_read_32(FIREWALL_DDR_BASE + 110*010d6ae3SXiaoDong Huang FIREWALL_DDR_FW_DDR_CON_REG); 111*010d6ae3SXiaoDong Huang val |= BIT(7 - i); 112*010d6ae3SXiaoDong Huang mmio_write_32(FIREWALL_DDR_BASE + 113*010d6ae3SXiaoDong Huang FIREWALL_DDR_FW_DDR_CON_REG, val); 114*010d6ae3SXiaoDong Huang /* map top and base */ 115*010d6ae3SXiaoDong Huang mmio_write_32(FIREWALL_DDR_BASE + 116*010d6ae3SXiaoDong Huang FIREWALL_DDR_FW_DDR_RGN(7 - i), 117*010d6ae3SXiaoDong Huang RG_MAP_SECURE(usg.s_top[i], usg.s_base[i])); 118*010d6ae3SXiaoDong Huang } 119*010d6ae3SXiaoDong Huang 120*010d6ae3SXiaoDong Huang /* set ddr rgn0_top and rga0_top as 0 */ 121*010d6ae3SXiaoDong Huang mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_FW_DDR_RGN(0), 0x0); 122*010d6ae3SXiaoDong Huang 123*010d6ae3SXiaoDong Huang /* set all slave ip into no-secure, except stimer */ 124*010d6ae3SXiaoDong Huang mmio_write_32(SGRF_BASE + SGRF_SOC_CON(4), SGRF_SLV_S_ALL_NS); 125*010d6ae3SXiaoDong Huang mmio_write_32(SGRF_BASE + SGRF_SOC_CON(5), SGRF_SLV_S_ALL_NS); 126*010d6ae3SXiaoDong Huang mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6), SGRF_SLV_S_ALL_NS); 127*010d6ae3SXiaoDong Huang mmio_write_32(SGRF_BASE + SGRF_SOC_CON(7), SGRF_SLV_S_ALL_NS); 128*010d6ae3SXiaoDong Huang mmio_write_32(SGRF_BASE + SGRF_SOC_CON(8), 0x00030000); 129*010d6ae3SXiaoDong Huang 130*010d6ae3SXiaoDong Huang /* set master crypto to no-secure, dcf to secure */ 131*010d6ae3SXiaoDong Huang mmio_write_32(SGRF_BASE + SGRF_SOC_CON(3), 0x000f0003); 132*010d6ae3SXiaoDong Huang 133*010d6ae3SXiaoDong Huang /* set DMAC into no-secure */ 134*010d6ae3SXiaoDong Huang mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(0), DMA_IRQ_BOOT_NS); 135*010d6ae3SXiaoDong Huang mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(1), DMA_PERI_CH_NS_15_0); 136*010d6ae3SXiaoDong Huang mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(2), DMA_PERI_CH_NS_19_16); 137*010d6ae3SXiaoDong Huang mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(3), DMA_MANAGER_BOOT_NS); 138*010d6ae3SXiaoDong Huang 139*010d6ae3SXiaoDong Huang /* soft reset dma before use */ 140*010d6ae3SXiaoDong Huang mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_REQ); 141*010d6ae3SXiaoDong Huang udelay(5); 142*010d6ae3SXiaoDong Huang mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_RLS); 143*010d6ae3SXiaoDong Huang } 144*010d6ae3SXiaoDong Huang 145*010d6ae3SXiaoDong Huang static void soc_reset_config_all(void) 146*010d6ae3SXiaoDong Huang { 147*010d6ae3SXiaoDong Huang uint32_t tmp; 148*010d6ae3SXiaoDong Huang 149*010d6ae3SXiaoDong Huang /* tsadc and wdt can trigger a first rst */ 150*010d6ae3SXiaoDong Huang tmp = mmio_read_32(CRU_BASE + CRU_GLB_RST_CON); 151*010d6ae3SXiaoDong Huang tmp |= CRU_GLB_RST_TSADC_FST | CRU_GLB_RST_WDT_FST; 152*010d6ae3SXiaoDong Huang mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, tmp); 153*010d6ae3SXiaoDong Huang return; 154*010d6ae3SXiaoDong Huang tmp = mmio_read_32(PMUGRF_BASE + PMUGRF_SOC_CON(3)); 155*010d6ae3SXiaoDong Huang tmp &= ~(PMUGRF_FAILSAFE_SHTDN_TSADC | PMUGRF_FAILSAFE_SHTDN_WDT); 156*010d6ae3SXiaoDong Huang mmio_write_32(PMUGRF_BASE + PMUGRF_SOC_CON(3), tmp); 157*010d6ae3SXiaoDong Huang 158*010d6ae3SXiaoDong Huang /* wdt pin rst eable */ 159*010d6ae3SXiaoDong Huang mmio_write_32(GRF_BASE + GRF_SOC_CON(2), 160*010d6ae3SXiaoDong Huang BIT_WITH_WMSK(GRF_SOC_CON2_NSWDT_RST_EN)); 161*010d6ae3SXiaoDong Huang } 162*010d6ae3SXiaoDong Huang 163*010d6ae3SXiaoDong Huang void px30_soc_reset_config(void) 164*010d6ae3SXiaoDong Huang { 165*010d6ae3SXiaoDong Huang uint32_t tmp; 166*010d6ae3SXiaoDong Huang 167*010d6ae3SXiaoDong Huang /* enable soc ip rst hold time cfg */ 168*010d6ae3SXiaoDong Huang tmp = mmio_read_32(CRU_BASE + CRU_GLB_RST_CON); 169*010d6ae3SXiaoDong Huang tmp |= BIT(CRU_GLB_RST_TSADC_EXT) | BIT(CRU_GLB_RST_WDT_EXT); 170*010d6ae3SXiaoDong Huang mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, tmp); 171*010d6ae3SXiaoDong Huang /* soc ip rst hold time, 24m */ 172*010d6ae3SXiaoDong Huang tmp = mmio_read_32(CRU_BASE + CRU_GLB_CNT_TH); 173*010d6ae3SXiaoDong Huang tmp &= ~CRU_GLB_CNT_RST_MSK; 174*010d6ae3SXiaoDong Huang tmp |= (CRU_GLB_CNT_RST_1MS / 2); 175*010d6ae3SXiaoDong Huang mmio_write_32(CRU_BASE + CRU_GLB_CNT_TH, tmp); 176*010d6ae3SXiaoDong Huang 177*010d6ae3SXiaoDong Huang mmio_write_32(PMUSGRF_BASE + PMUSGRF_SOC_CON(0), 178*010d6ae3SXiaoDong Huang BIT_WITH_WMSK(PMUSGRF_RSTOUT_FST) | 179*010d6ae3SXiaoDong Huang BIT_WITH_WMSK(PMUSGRF_RSTOUT_TSADC) | 180*010d6ae3SXiaoDong Huang BIT_WITH_WMSK(PMUSGRF_RSTOUT_WDT)); 181*010d6ae3SXiaoDong Huang 182*010d6ae3SXiaoDong Huang /* rst_out pulse time */ 183*010d6ae3SXiaoDong Huang mmio_write_32(PMUGRF_BASE + PMUGRF_SOC_CON(2), 184*010d6ae3SXiaoDong Huang PMUGRF_SOC_CON2_MAX_341US | PMUGRF_SOC_CON2_US_WMSK); 185*010d6ae3SXiaoDong Huang 186*010d6ae3SXiaoDong Huang soc_reset_config_all(); 187*010d6ae3SXiaoDong Huang } 188*010d6ae3SXiaoDong Huang 189*010d6ae3SXiaoDong Huang void plat_rockchip_soc_init(void) 190*010d6ae3SXiaoDong Huang { 191*010d6ae3SXiaoDong Huang secure_timer_init(); 192*010d6ae3SXiaoDong Huang sgrf_init(); 193*010d6ae3SXiaoDong Huang } 194