1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (C) 2018 Marvell International Ltd. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu * https://spdx.org/licenses 6*91f16700Schasinglulu */ 7*91f16700Schasinglulu 8*91f16700Schasinglulu #include <arch_helpers.h> 9*91f16700Schasinglulu #include <common/debug.h> 10*91f16700Schasinglulu #include <drivers/marvell/cache_llc.h> 11*91f16700Schasinglulu #include <lib/mmio.h> 12*91f16700Schasinglulu #include <plat/common/platform.h> 13*91f16700Schasinglulu 14*91f16700Schasinglulu #define CCU_HTC_ASET (MVEBU_CCU_BASE(MVEBU_AP0) + 0x264) 15*91f16700Schasinglulu #define MVEBU_IO_AFFINITY (0xF00) 16*91f16700Schasinglulu #define MVEBU_SF_REG (MVEBU_REGS_BASE + 0x40) 17*91f16700Schasinglulu #define MVEBU_SF_EN BIT(8) 18*91f16700Schasinglulu #define MVEBU_DFX_REG(cluster_id) (MVEBU_REGS_BASE + 0x6F82A0 + \ 19*91f16700Schasinglulu (cluster_id) * 0x4) 20*91f16700Schasinglulu #define MVEBU_DFX_CLK_EN_POS 0x3 21*91f16700Schasinglulu #define MVEBU_DFX_CL0_CLK_OFFS 16 22*91f16700Schasinglulu #define MVEBU_DFX_CL0_CLK_MASK (0xF << MVEBU_DFX_CL0_CLK_OFFS) 23*91f16700Schasinglulu #define MVEBU_DFX_CL1_CLK_OFFS 8 24*91f16700Schasinglulu #define MVEBU_DFX_CL1_CLK_MASK (0xF << MVEBU_DFX_CL1_CLK_OFFS) 25*91f16700Schasinglulu 26*91f16700Schasinglulu #ifdef MVEBU_SOC_AP807 27*91f16700Schasinglulu static void plat_enable_snoop_filter(void) 28*91f16700Schasinglulu { 29*91f16700Schasinglulu int cpu_id = plat_my_core_pos(); 30*91f16700Schasinglulu 31*91f16700Schasinglulu /* Snoop filter needs to be enabled once per cluster */ 32*91f16700Schasinglulu if (cpu_id % 2) 33*91f16700Schasinglulu return; 34*91f16700Schasinglulu 35*91f16700Schasinglulu mmio_setbits_32(MVEBU_SF_REG, MVEBU_SF_EN); 36*91f16700Schasinglulu } 37*91f16700Schasinglulu #endif 38*91f16700Schasinglulu 39*91f16700Schasinglulu #ifndef MVEBU_SOC_AP807 40*91f16700Schasinglulu static void plat_config_dfx_clock(void) 41*91f16700Schasinglulu { 42*91f16700Schasinglulu int cluster_id = plat_my_core_pos(); 43*91f16700Schasinglulu uint32_t val; 44*91f16700Schasinglulu 45*91f16700Schasinglulu /* DFX clock needs to be configured once per cluster */ 46*91f16700Schasinglulu if ((cluster_id % PLAT_MAX_CPUS_PER_CLUSTER) != 0) { 47*91f16700Schasinglulu return; 48*91f16700Schasinglulu } 49*91f16700Schasinglulu 50*91f16700Schasinglulu val = mmio_read_32(MVEBU_DFX_REG(cluster_id / PLAT_MAX_CPUS_PER_CLUSTER)); 51*91f16700Schasinglulu if (cluster_id == 0) { 52*91f16700Schasinglulu val &= ~MVEBU_DFX_CL0_CLK_MASK; 53*91f16700Schasinglulu val |= (MVEBU_DFX_CLK_EN_POS << MVEBU_DFX_CL0_CLK_OFFS); 54*91f16700Schasinglulu } else { 55*91f16700Schasinglulu val &= ~MVEBU_DFX_CL1_CLK_MASK; 56*91f16700Schasinglulu val |= (MVEBU_DFX_CLK_EN_POS << MVEBU_DFX_CL1_CLK_OFFS); 57*91f16700Schasinglulu } 58*91f16700Schasinglulu mmio_write_32(MVEBU_DFX_REG(cluster_id / PLAT_MAX_CPUS_PER_CLUSTER), val); 59*91f16700Schasinglulu } 60*91f16700Schasinglulu #endif 61*91f16700Schasinglulu 62*91f16700Schasinglulu static void plat_enable_affinity(void) 63*91f16700Schasinglulu { 64*91f16700Schasinglulu int cluster_id; 65*91f16700Schasinglulu int affinity; 66*91f16700Schasinglulu 67*91f16700Schasinglulu /* set CPU Affinity */ 68*91f16700Schasinglulu cluster_id = plat_my_core_pos() / PLAT_MARVELL_CLUSTER_CORE_COUNT; 69*91f16700Schasinglulu affinity = (MVEBU_IO_AFFINITY | (1 << cluster_id)); 70*91f16700Schasinglulu mmio_write_32(CCU_HTC_ASET, affinity); 71*91f16700Schasinglulu 72*91f16700Schasinglulu /* set barier */ 73*91f16700Schasinglulu isb(); 74*91f16700Schasinglulu } 75*91f16700Schasinglulu 76*91f16700Schasinglulu void marvell_psci_arch_init(int die_index) 77*91f16700Schasinglulu { 78*91f16700Schasinglulu #if LLC_ENABLE 79*91f16700Schasinglulu /* check if LLC is in exclusive mode 80*91f16700Schasinglulu * as L2 is configured to UniqueClean eviction 81*91f16700Schasinglulu * (in a8k reset handler) 82*91f16700Schasinglulu */ 83*91f16700Schasinglulu if (llc_is_exclusive(0) == 0) 84*91f16700Schasinglulu ERROR("LLC should be configured to exclusice mode\n"); 85*91f16700Schasinglulu #endif 86*91f16700Schasinglulu 87*91f16700Schasinglulu /* Enable Affinity */ 88*91f16700Schasinglulu plat_enable_affinity(); 89*91f16700Schasinglulu 90*91f16700Schasinglulu #ifdef MVEBU_SOC_AP807 91*91f16700Schasinglulu plat_enable_snoop_filter(); 92*91f16700Schasinglulu #else 93*91f16700Schasinglulu plat_config_dfx_clock(); 94*91f16700Schasinglulu #endif 95*91f16700Schasinglulu } 96