1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2021 NXP 4 */ 5 6#include <common.h> 7#include <div64.h> 8#include <asm/io.h> 9#include <errno.h> 10#include <asm/arch/imx-regs.h> 11#include <asm/arch/pcc.h> 12#include <asm/arch/cgc.h> 13#include <asm/arch/sys_proto.h> 14 15#define cgc_clk_TYPES 2 16#define cgc_clk_NUM 8 17 18static enum cgc_clk pcc1_clksrc[][8] = { 19 { 20 }, 21 { 22 DUMMY0_CLK, 23 LPOSC, 24 SOSC_DIV2, 25 FRO_DIV2, 26 CM33_BUSCLK, 27 PLL1_VCO_DIV, 28 PLL0_PFD2_DIV, 29 PLL0_PFD1_DIV, 30 } 31}; 32 33static enum cgc_clk pcc3_clksrc[][8] = { 34 { 35 }, 36 { DUMMY0_CLK, 37 LPOSC, 38 SOSC_DIV2, 39 FRO_DIV2, 40 XBAR_BUSCLK, 41 PLL3_PFD1_DIV1, 42 PLL3_PFD0_DIV2, 43 PLL3_PFD0_DIV1 44 } 45}; 46 47static enum cgc_clk pcc4_clksrc[][8] = { 48 { 49 DUMMY0_CLK, 50 SOSC_DIV1, 51 FRO_DIV1, 52 PLL3_PFD3_DIV2, 53 PLL3_PFD3_DIV1, 54 PLL3_PFD2_DIV2, 55 PLL3_PFD2_DIV1, 56 PLL3_PFD1_DIV2 57 }, 58 { 59 DUMMY0_CLK, 60 DUMMY1_CLK, 61 LPOSC, 62 SOSC_DIV2, 63 FRO_DIV2, 64 XBAR_BUSCLK, 65 PLL3_VCODIV, 66 PLL3_PFD0_DIV1 67 } 68}; 69 70static enum cgc_clk pcc5_clksrc[][8] = { 71 { 72 DUMMY0_CLK, 73 PLL4_PFD3_DIV2, 74 PLL4_PFD2_DIV2, 75 PLL4_PFD2_DIV1, 76 PLL4_PFD1_DIV2, 77 PLL4_PFD1_DIV1, 78 PLL4_PFD0_DIV2, 79 PLL4_PFD0_DIV1 80 }, 81 { 82 DUMMY0_CLK, 83 DUMMY1_CLK, 84 LPOSC, 85 SOSC_DIV2, 86 FRO_DIV2, 87 LPAV_BUSCLK, 88 PLL4_VCODIV, 89 PLL4_PFD3_DIV1 90 } 91}; 92 93static struct pcc_entry pcc1_arrays[] = { 94 {PCC1_RBASE, ADC1_PCC1_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV, PCC_HAS_RST_B}, 95 {} 96}; 97 98static struct pcc_entry pcc3_arrays[] = { 99 {PCC3_RBASE, DMA1_MP_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 100 {PCC3_RBASE, DMA1_CH0_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 101 {PCC3_RBASE, DMA1_CH1_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 102 {PCC3_RBASE, DMA1_CH2_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 103 {PCC3_RBASE, DMA1_CH3_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 104 {PCC3_RBASE, DMA1_CH4_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 105 {PCC3_RBASE, DMA1_CH5_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 106 {PCC3_RBASE, DMA1_CH6_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 107 {PCC3_RBASE, DMA1_CH7_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 108 {PCC3_RBASE, DMA1_CH8_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 109 {PCC3_RBASE, DMA1_CH9_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 110 {PCC3_RBASE, DMA1_CH10_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 111 {PCC3_RBASE, DMA1_CH11_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 112 {PCC3_RBASE, DMA1_CH12_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 113 {PCC3_RBASE, DMA1_CH13_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 114 {PCC3_RBASE, DMA1_CH14_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 115 {PCC3_RBASE, DMA1_CH15_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 116 {PCC3_RBASE, DMA1_CH16_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 117 {PCC3_RBASE, DMA1_CH17_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 118 {PCC3_RBASE, DMA1_CH18_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 119 {PCC3_RBASE, DMA1_CH19_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 120 {PCC3_RBASE, DMA1_CH20_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 121 {PCC3_RBASE, DMA1_CH21_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 122 {PCC3_RBASE, DMA1_CH22_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 123 {PCC3_RBASE, DMA1_CH23_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 124 {PCC3_RBASE, DMA1_CH24_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 125 {PCC3_RBASE, DMA1_CH25_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 126 {PCC3_RBASE, DMA1_CH26_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 127 {PCC3_RBASE, DMA1_CH27_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 128 {PCC3_RBASE, DMA1_CH28_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 129 {PCC3_RBASE, DMA1_CH29_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 130 {PCC3_RBASE, DMA1_CH30_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 131 {PCC3_RBASE, DMA1_CH31_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 132 {PCC3_RBASE, MU0_B_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 133 {PCC3_RBASE, MU3_A_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 134 {PCC3_RBASE, LLWU1_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 135 {PCC3_RBASE, UPOWER_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 136 {PCC3_RBASE, WDOG3_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, 137 {PCC3_RBASE, WDOG4_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, 138 {PCC3_RBASE, CAAM_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B}, 139 {PCC3_RBASE, XRDC_MGR_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 140 {PCC3_RBASE, SEMA42_1_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV, PCC_NO_RST_B}, 141 {PCC3_RBASE, ROMCP1_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 142 {PCC3_RBASE, LPIT1_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, 143 {PCC3_RBASE, TPM4_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, 144 {PCC3_RBASE, TPM5_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, 145 {PCC3_RBASE, FLEXIO1_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, 146 {PCC3_RBASE, I3C2_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, 147 {PCC3_RBASE, LPI2C4_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, 148 {PCC3_RBASE, LPI2C5_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, 149 {PCC3_RBASE, LPUART4_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, 150 {PCC3_RBASE, LPUART5_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, 151 {PCC3_RBASE, LPSPI4_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, 152 {PCC3_RBASE, LPSPI5_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, 153 {} 154}; 155 156static struct pcc_entry pcc4_arrays[] = { 157 {PCC4_RBASE, FLEXSPI2_PCC4_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B }, 158 {PCC4_RBASE, TPM6_PCC4_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B }, 159 {PCC4_RBASE, TPM7_PCC4_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B }, 160 {PCC4_RBASE, LPI2C6_PCC4_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B }, 161 {PCC4_RBASE, LPI2C7_PCC4_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B }, 162 {PCC4_RBASE, LPUART6_PCC4_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B }, 163 {PCC4_RBASE, LPUART7_PCC4_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B }, 164 {PCC4_RBASE, SAI4_PCC4_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 165 {PCC4_RBASE, SAI5_PCC4_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 166 {PCC4_RBASE, PCTLE_PCC4_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 167 {PCC4_RBASE, PCTLF_PCC4_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 168 {PCC4_RBASE, SDHC0_PCC4_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B }, 169 {PCC4_RBASE, SDHC1_PCC4_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B }, 170 {PCC4_RBASE, SDHC2_PCC4_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B }, 171 {PCC4_RBASE, USB0_PCC4_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 172 {PCC4_RBASE, USBPHY_PCC4_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 173 {PCC4_RBASE, USB1_PCC4_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 174 {PCC4_RBASE, USB1PHY_PCC4_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 175 {PCC4_RBASE, USB_XBAR_PCC4_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 176 {PCC4_RBASE, ENET_PCC4_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 177 {PCC4_RBASE, SFA1_PCC4_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 178 {PCC4_RBASE, RGPIOE_PCC4_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 179 {PCC4_RBASE, RGPIOF_PCC4_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 180 {} 181}; 182 183static struct pcc_entry pcc5_arrays[] = { 184 {PCC5_RBASE, DMA2_MP_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 185 {PCC5_RBASE, DMA2_CH0_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 186 {PCC5_RBASE, DMA2_CH1_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 187 {PCC5_RBASE, DMA2_CH2_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 188 {PCC5_RBASE, DMA2_CH3_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 189 {PCC5_RBASE, DMA2_CH4_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 190 {PCC5_RBASE, DMA2_CH5_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 191 {PCC5_RBASE, DMA2_CH6_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 192 {PCC5_RBASE, DMA2_CH7_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 193 {PCC5_RBASE, DMA2_CH8_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 194 {PCC5_RBASE, DMA2_CH9_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 195 {PCC5_RBASE, DMA2_CH10_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 196 {PCC5_RBASE, DMA2_CH11_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 197 {PCC5_RBASE, DMA2_CH12_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 198 {PCC5_RBASE, DMA2_CH13_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 199 {PCC5_RBASE, DMA2_CH14_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 200 {PCC5_RBASE, DMA2_CH15_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 201 {PCC5_RBASE, DMA2_CH16_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 202 {PCC5_RBASE, DMA2_CH17_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 203 {PCC5_RBASE, DMA2_CH18_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 204 {PCC5_RBASE, DMA2_CH19_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 205 {PCC5_RBASE, DMA2_CH20_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 206 {PCC5_RBASE, DMA2_CH21_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 207 {PCC5_RBASE, DMA2_CH22_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 208 {PCC5_RBASE, DMA2_CH23_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 209 {PCC5_RBASE, DMA2_CH24_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 210 {PCC5_RBASE, DMA2_CH25_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 211 {PCC5_RBASE, DMA2_CH26_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 212 {PCC5_RBASE, DMA2_CH27_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 213 {PCC5_RBASE, DMA2_CH28_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 214 {PCC5_RBASE, DMA2_CH29_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 215 {PCC5_RBASE, DMA2_CH30_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 216 {PCC5_RBASE, DMA2_CH31_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 217 {PCC5_RBASE, MU2_B_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 218 {PCC5_RBASE, MU3_B_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 219 {PCC5_RBASE, SEMA42_2_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 220 {PCC5_RBASE, CMC2_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 221 {PCC5_RBASE, AVD_SIM_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 222 {PCC5_RBASE, LPAV_CGC_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 223 {PCC5_RBASE, PCC5_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 224 {PCC5_RBASE, TPM8_PCC5_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B }, 225 {PCC5_RBASE, SAI6_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 226 {PCC5_RBASE, SAI7_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 227 {PCC5_RBASE, SPDIF_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 228 {PCC5_RBASE, ISI_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 229 {PCC5_RBASE, CSI_REGS_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 230 {PCC5_RBASE, CSI_PCC5_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B }, 231 {PCC5_RBASE, DSI_PCC5_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B }, 232 {PCC5_RBASE, WDOG5_PCC5_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B }, 233 {PCC5_RBASE, EPDC_PCC5_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B }, 234 {PCC5_RBASE, PXP_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 235 {PCC5_RBASE, SFA2_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 236 {PCC5_RBASE, GPU2D_PCC5_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B }, 237 {PCC5_RBASE, GPU3D_PCC5_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B }, 238 {PCC5_RBASE, DCNANO_PCC5_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B }, 239 {PCC5_RBASE, LPDDR4_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B }, 240 {PCC5_RBASE, CSI_CLK_UI_PCC5_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_NO_RST_B }, 241 {PCC5_RBASE, CSI_CLK_ESC_PCC5_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_NO_RST_B }, 242 {PCC5_RBASE, RGPIOD_PCC5_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B }, 243 {} 244}; 245 246static int find_pcc_entry(int pcc_controller, int pcc_clk_slot, struct pcc_entry **out) 247{ 248 struct pcc_entry *pcc_array; 249 int index = 0; 250 251 switch (pcc_controller) { 252 case 1: 253 pcc_array = pcc1_arrays; 254 *out = &pcc1_arrays[0]; 255 break; 256 case 3: 257 pcc_array = pcc3_arrays; 258 *out = &pcc3_arrays[0]; 259 break; 260 case 4: 261 pcc_array = pcc4_arrays; 262 *out = &pcc4_arrays[0]; 263 break; 264 case 5: 265 pcc_array = pcc5_arrays; 266 *out = &pcc5_arrays[0]; 267 break; 268 default: 269 printf("Not supported pcc_controller: %d\n", pcc_controller); 270 return -EINVAL; 271 } 272 273 while (pcc_array->pcc_base) { 274 if (pcc_array->pcc_slot == pcc_clk_slot) 275 return index; 276 277 pcc_array++; 278 index++; 279 } 280 281 return -ENOENT; 282} 283 284int pcc_clock_enable(int pcc_controller, int pcc_clk_slot, bool enable) 285{ 286 u32 val; 287 void __iomem *reg; 288 int clk; 289 struct pcc_entry *pcc_array; 290 291 clk = find_pcc_entry(pcc_controller, pcc_clk_slot, &pcc_array); 292 if (clk < 0) 293 return -EINVAL; 294 295 reg = (void __iomem *)(uintptr_t)(pcc_array[clk].pcc_base + pcc_array[clk].pcc_slot * 4); 296 297 val = readl(reg); 298 299 debug("%s: clk %d, reg 0x%p, val 0x%x, enable %d\n", __func__, clk, reg, val, enable); 300 301 if (!(val & PCC_PR_MASK) || (val & PCC_INUSE_MASK)) 302 return -EPERM; 303 304 if (enable) 305 val |= PCC_CGC_MASK; 306 else 307 val &= ~PCC_CGC_MASK; 308 309 writel(val, reg); 310 311 debug("%s: val 0x%x\n", __func__, val); 312 313 return 0; 314} 315 316/* The clock source select needs clock is disabled */ 317int pcc_clock_sel(int pcc_controller, int pcc_clk_slot, enum cgc_clk src) 318{ 319 u32 val, i, clksrc_type; 320 void __iomem *reg; 321 struct pcc_entry *pcc_array; 322 enum cgc_clk *cgc_clk_array; 323 int clk; 324 325 clk = find_pcc_entry(pcc_controller, pcc_clk_slot, &pcc_array); 326 if (clk < 0) 327 return -EINVAL; 328 329 reg = (void __iomem *)(uintptr_t)(pcc_array[clk].pcc_base + pcc_array[clk].pcc_slot * 4); 330 331 clksrc_type = pcc_array[clk].clksrc; 332 if (clksrc_type >= CLKSRC_NO_PCS) { 333 printf("No PCS field for the PCC %d, clksrc type %d\n", 334 clk, clksrc_type); 335 return -EPERM; 336 } 337 338 if (pcc_controller == 1) 339 cgc_clk_array = pcc1_clksrc[clksrc_type]; 340 else if (pcc_controller == 3) 341 cgc_clk_array = pcc3_clksrc[clksrc_type]; 342 else if (pcc_controller == 4) 343 cgc_clk_array = pcc4_clksrc[clksrc_type]; 344 else 345 cgc_clk_array = pcc5_clksrc[clksrc_type]; 346 347 for (i = 0; i < cgc_clk_NUM; i++) { 348 if (cgc_clk_array[i] == src) { 349 /* Find the clock src, then set it to PCS */ 350 break; 351 } 352 } 353 354 if (i == cgc_clk_NUM) { 355 printf("No parent in PCS of PCC %d, invalid scg_clk %d\n", clk, src); 356 return -EINVAL; 357 } 358 359 val = readl(reg); 360 361 debug("%s: clk %d, reg 0x%p, val 0x%x, clksrc_type %d\n", 362 __func__, clk, reg, val, clksrc_type); 363 364 if (!(val & PCC_PR_MASK) || (val & PCC_INUSE_MASK) || 365 (val & PCC_CGC_MASK)) { 366 printf("Not permit to select clock source val = 0x%x\n", val); 367 return -EPERM; 368 } 369 370 val &= ~PCC_PCS_MASK; 371 val |= i << PCC_PCS_OFFSET; 372 373 writel(val, reg); 374 375 debug("%s: val 0x%x\n", __func__, val); 376 377 return 0; 378} 379 380int pcc_clock_div_config(int pcc_controller, int pcc_clk_slot, bool frac, u8 div) 381{ 382 u32 val; 383 void __iomem *reg; 384 struct pcc_entry *pcc_array; 385 int clk; 386 387 clk = find_pcc_entry(pcc_controller, pcc_clk_slot, &pcc_array); 388 if (clk < 0) 389 return -EINVAL; 390 391 reg = (void __iomem *)(uintptr_t)(pcc_array[clk].pcc_base + pcc_array[clk].pcc_slot * 4); 392 393 if (div > 8 || (div == 1 && frac != 0)) 394 return -EINVAL; 395 396 if (pcc_array[clk].div >= PCC_NO_DIV) { 397 printf("No DIV/FRAC field for the PCC %d\n", clk); 398 return -EPERM; 399 } 400 401 val = readl(reg); 402 403 if (!(val & PCC_PR_MASK) || (val & PCC_INUSE_MASK) || 404 (val & PCC_CGC_MASK)) { 405 printf("Not permit to set div/frac val = 0x%x\n", val); 406 return -EPERM; 407 } 408 409 if (frac) 410 val |= PCC_FRAC_MASK; 411 else 412 val &= ~PCC_FRAC_MASK; 413 414 val &= ~PCC_PCD_MASK; 415 val |= (div - 1) & PCC_PCD_MASK; 416 417 writel(val, reg); 418 419 return 0; 420} 421 422bool pcc_clock_is_enable(int pcc_controller, int pcc_clk_slot) 423{ 424 u32 val; 425 void __iomem *reg; 426 struct pcc_entry *pcc_array; 427 int clk; 428 429 clk = find_pcc_entry(pcc_controller, pcc_clk_slot, &pcc_array); 430 if (clk < 0) 431 return -EINVAL; 432 433 reg = (void __iomem *)(uintptr_t)(pcc_array[clk].pcc_base + pcc_array[clk].pcc_slot * 4); 434 val = readl(reg); 435 436 if ((val & PCC_INUSE_MASK) || (val & PCC_CGC_MASK)) 437 return true; 438 439 return false; 440} 441 442int pcc_clock_get_clksrc(int pcc_controller, int pcc_clk_slot, enum cgc_clk *src) 443{ 444 u32 val, clksrc_type; 445 void __iomem *reg; 446 struct pcc_entry *pcc_array; 447 int clk; 448 enum cgc_clk *cgc_clk_array; 449 450 clk = find_pcc_entry(pcc_controller, pcc_clk_slot, &pcc_array); 451 if (clk < 0) 452 return -EINVAL; 453 454 clksrc_type = pcc_array[clk].clksrc; 455 if (clksrc_type >= CLKSRC_NO_PCS) { 456 printf("No PCS field for the PCC %d, clksrc type %d\n", 457 pcc_clk_slot, clksrc_type); 458 return -EPERM; 459 } 460 461 reg = (void __iomem *)(uintptr_t)(pcc_array[clk].pcc_base + pcc_array[clk].pcc_slot * 4); 462 463 val = readl(reg); 464 465 debug("%s: clk %d, reg 0x%p, val 0x%x, type %d\n", 466 __func__, pcc_clk_slot, reg, val, clksrc_type); 467 468 if (!(val & PCC_PR_MASK)) { 469 printf("This pcc slot is not present = 0x%x\n", val); 470 return -EPERM; 471 } 472 473 val &= PCC_PCS_MASK; 474 val = (val >> PCC_PCS_OFFSET); 475 476 if (!val) { 477 printf("Clock source is off\n"); 478 return -EIO; 479 } 480 481 if (pcc_controller == 3) 482 cgc_clk_array = pcc3_clksrc[clksrc_type]; 483 else if (pcc_controller == 4) 484 cgc_clk_array = pcc4_clksrc[clksrc_type]; 485 else 486 cgc_clk_array = pcc5_clksrc[clksrc_type]; 487 488 *src = cgc_clk_array[val]; 489 490 debug("%s: parent cgc1 clk %d\n", __func__, *src); 491 492 return 0; 493} 494 495int pcc_reset_peripheral(int pcc_controller, int pcc_clk_slot, bool reset) 496{ 497 u32 val; 498 void __iomem *reg; 499 struct pcc_entry *pcc_array; 500 int clk; 501 502 clk = find_pcc_entry(pcc_controller, pcc_clk_slot, &pcc_array); 503 if (clk < 0) 504 return -EINVAL; 505 506 if (pcc_array[clk].rst_b == PCC_NO_RST_B) 507 return 0; 508 509 reg = (void __iomem *)(uintptr_t)(pcc_array[clk].pcc_base + pcc_array[clk].pcc_slot * 4); 510 511 val = readl(reg); 512 513 debug("%s: clk %d, reg 0x%p, val 0x%x\n", __func__, pcc_clk_slot, reg, val); 514 515 if (!(val & PCC_PR_MASK)) { 516 printf("This pcc slot is not present = 0x%x\n", val); 517 return -EPERM; 518 } 519 520 if (reset) 521 val &= ~BIT(28); 522 else 523 val |= BIT(28); 524 525 writel(val, reg); 526 527 debug("%s: clk %d, reg 0x%p, val 0x%x\n", __func__, pcc_clk_slot, reg, val); 528 529 return 0; 530} 531 532u32 pcc_clock_get_rate(int pcc_controller, int pcc_clk_slot) 533{ 534 u32 val, rate, frac, div; 535 void __iomem *reg; 536 enum cgc_clk parent; 537 int ret; 538 int clk; 539 struct pcc_entry *pcc_array; 540 541 clk = find_pcc_entry(pcc_controller, pcc_clk_slot, &pcc_array); 542 if (clk < 0) 543 return -EINVAL; 544 545 ret = pcc_clock_get_clksrc(pcc_controller, pcc_clk_slot, &parent); 546 if (ret) 547 return 0; 548 549 rate = cgc_clk_get_rate(parent); 550 551 debug("%s: parent rate %u\n", __func__, rate); 552 553 if (pcc_array[clk].div == PCC_HAS_DIV) { 554 reg = (void __iomem *)(uintptr_t)(pcc_array[clk].pcc_base + 555 pcc_array[clk].pcc_slot * 4); 556 val = readl(reg); 557 558 frac = (val & PCC_FRAC_MASK) >> PCC_FRAC_OFFSET; 559 div = (val & PCC_PCD_MASK) >> PCC_PCD_OFFSET; 560 561 /* 562 * Theoretically don't have overflow in the calc, 563 * the rate won't exceed 2G 564 */ 565 rate = rate * (frac + 1) / (div + 1); 566 } 567 568 debug("%s: rate %u\n", __func__, rate); 569 return rate; 570} 571