1 /* 2 * Copyright (C) 2018-2020 Marvell International Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * https://spdx.org/licenses 6 */ 7 8 /* CP110 Marvell SoC driver */ 9 10 #include <common/debug.h> 11 #include <drivers/delay_timer.h> 12 #include <drivers/marvell/amb_adec.h> 13 #include <drivers/marvell/iob.h> 14 #include <drivers/marvell/mochi/cp110_setup.h> 15 #include <drivers/rambus/trng_ip_76.h> 16 17 #include <efuse_def.h> 18 #include <plat_marvell.h> 19 20 /* 21 * AXI Configuration. 22 */ 23 24 /* Used for Units of CP-110 (e.g. USB device, USB Host, and etc) */ 25 #define MVEBU_AXI_ATTR_OFFSET (0x441300) 26 #define MVEBU_AXI_ATTR_REG(index) (MVEBU_AXI_ATTR_OFFSET + \ 27 0x4 * index) 28 29 /* AXI Protection bits */ 30 #define MVEBU_AXI_PROT_OFFSET (0x441200) 31 32 /* AXI Protection regs */ 33 #define MVEBU_AXI_PROT_REG(index) ((index <= 4) ? \ 34 (MVEBU_AXI_PROT_OFFSET + \ 35 0x4 * index) : \ 36 (MVEBU_AXI_PROT_OFFSET + 0x18)) 37 #define MVEBU_AXI_PROT_REGS_NUM (6) 38 39 #define MVEBU_SOC_CFGS_OFFSET (0x441900) 40 #define MVEBU_SOC_CFG_REG(index) (MVEBU_SOC_CFGS_OFFSET + \ 41 0x4 * index) 42 #define MVEBU_SOC_CFG_REG_NUM (0) 43 #define MVEBU_SOC_CFG_GLOG_SECURE_EN_MASK (0xE) 44 45 /* SATA3 MBUS to AXI regs */ 46 #define MVEBU_BRIDGE_WIN_DIS_REG (MVEBU_SOC_CFGS_OFFSET + 0x10) 47 #define MVEBU_BRIDGE_WIN_DIS_OFF (0x0) 48 49 /* SATA3 MBUS to AXI regs */ 50 #define MVEBU_SATA_M2A_AXI_PORT_CTRL_REG (0x54ff04) 51 52 /* AXI to MBUS bridge registers */ 53 #define MVEBU_AMB_IP_OFFSET (0x13ff00) 54 #define MVEBU_AMB_IP_BRIDGE_WIN_REG(win) (MVEBU_AMB_IP_OFFSET + \ 55 (win * 0x8)) 56 #define MVEBU_AMB_IP_BRIDGE_WIN_EN_OFFSET 0 57 #define MVEBU_AMB_IP_BRIDGE_WIN_EN_MASK \ 58 (0x1 << MVEBU_AMB_IP_BRIDGE_WIN_EN_OFFSET) 59 #define MVEBU_AMB_IP_BRIDGE_WIN_SIZE_OFFSET 16 60 #define MVEBU_AMB_IP_BRIDGE_WIN_SIZE_MASK \ 61 (0xffffu << MVEBU_AMB_IP_BRIDGE_WIN_SIZE_OFFSET) 62 63 #define MVEBU_SAMPLE_AT_RESET_REG (0x440600) 64 #define SAR_PCIE1_CLK_CFG_OFFSET 31 65 #define SAR_PCIE1_CLK_CFG_MASK (0x1u << SAR_PCIE1_CLK_CFG_OFFSET) 66 #define SAR_PCIE0_CLK_CFG_OFFSET 30 67 #define SAR_PCIE0_CLK_CFG_MASK (0x1 << SAR_PCIE0_CLK_CFG_OFFSET) 68 #define SAR_I2C_INIT_EN_OFFSET 24 69 #define SAR_I2C_INIT_EN_MASK (1 << SAR_I2C_INIT_EN_OFFSET) 70 71 /******************************************************************************* 72 * PCIE clock buffer control 73 ******************************************************************************/ 74 #define MVEBU_PCIE_REF_CLK_BUF_CTRL (0x4404F0) 75 #define PCIE1_REFCLK_BUFF_SOURCE 0x800 76 #define PCIE0_REFCLK_BUFF_SOURCE 0x400 77 78 /******************************************************************************* 79 * MSS Device Push Set Register 80 ******************************************************************************/ 81 #define MVEBU_CP_MSS_DPSHSR_REG (0x280040) 82 #define MSS_DPSHSR_REG_PCIE_CLK_SEL 0x8 83 84 /******************************************************************************* 85 * RTC Configuration 86 ******************************************************************************/ 87 #define MVEBU_RTC_BASE (0x284000) 88 #define MVEBU_RTC_STATUS_REG (MVEBU_RTC_BASE + 0x0) 89 #define MVEBU_RTC_STATUS_ALARM1_MASK 0x1 90 #define MVEBU_RTC_STATUS_ALARM2_MASK 0x2 91 #define MVEBU_RTC_IRQ_1_CONFIG_REG (MVEBU_RTC_BASE + 0x4) 92 #define MVEBU_RTC_IRQ_2_CONFIG_REG (MVEBU_RTC_BASE + 0x8) 93 #define MVEBU_RTC_TIME_REG (MVEBU_RTC_BASE + 0xC) 94 #define MVEBU_RTC_ALARM_1_REG (MVEBU_RTC_BASE + 0x10) 95 #define MVEBU_RTC_ALARM_2_REG (MVEBU_RTC_BASE + 0x14) 96 #define MVEBU_RTC_CCR_REG (MVEBU_RTC_BASE + 0x18) 97 #define MVEBU_RTC_NOMINAL_TIMING 0x2000 98 #define MVEBU_RTC_NOMINAL_TIMING_MASK 0x7FFF 99 #define MVEBU_RTC_TEST_CONFIG_REG (MVEBU_RTC_BASE + 0x1C) 100 #define MVEBU_RTC_BRIDGE_TIMING_CTRL0_REG (MVEBU_RTC_BASE + 0x80) 101 #define MVEBU_RTC_WRCLK_PERIOD_MASK 0xFFFF 102 #define MVEBU_RTC_WRCLK_PERIOD_DEFAULT 0x3FF 103 #define MVEBU_RTC_WRCLK_SETUP_OFFS 16 104 #define MVEBU_RTC_WRCLK_SETUP_MASK 0xFFFF0000 105 #define MVEBU_RTC_WRCLK_SETUP_DEFAULT 0x29 106 #define MVEBU_RTC_BRIDGE_TIMING_CTRL1_REG (MVEBU_RTC_BASE + 0x84) 107 #define MVEBU_RTC_READ_OUTPUT_DELAY_MASK 0xFFFF 108 #define MVEBU_RTC_READ_OUTPUT_DELAY_DEFAULT 0x1F 109 110 /******************************************************************************* 111 * TRNG Configuration 112 ******************************************************************************/ 113 #define MVEBU_TRNG_BASE (0x760000) 114 #define MVEBU_EFUSE_TRNG_ENABLE_EFUSE_WORD MVEBU_AP_LDX_220_189_EFUSE_OFFS 115 #define MVEBU_EFUSE_TRNG_ENABLE_BIT_OFFSET 13 /* LD0[202] */ 116 117 enum axi_attr { 118 AXI_ADUNIT_ATTR = 0, 119 AXI_COMUNIT_ATTR, 120 AXI_EIP197_ATTR, 121 AXI_USB3D_ATTR, 122 AXI_USB3H0_ATTR, 123 AXI_USB3H1_ATTR, 124 AXI_SATA0_ATTR, 125 AXI_SATA1_ATTR, 126 AXI_DAP_ATTR, 127 AXI_DFX_ATTR, 128 AXI_DBG_TRC_ATTR = 12, 129 AXI_SDIO_ATTR, 130 AXI_MSS_ATTR, 131 AXI_MAX_ATTR, 132 }; 133 134 /* Most stream IDS are configured centrally in the CP-110 RFU 135 * but some are configured inside the unit registers 136 */ 137 #define RFU_STREAM_ID_BASE (0x450000) 138 #define USB3H_0_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0xC) 139 #define USB3H_1_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x10) 140 #define SATA_0_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x14) 141 #define SATA_1_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x18) 142 #define SDIO_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x28) 143 144 #define CP_DMA_0_STREAM_ID_REG (0x6B0010) 145 #define CP_DMA_1_STREAM_ID_REG (0x6D0010) 146 147 /* We allocate IDs 128-255 for PCIe */ 148 #define MAX_STREAM_ID (0x80) 149 150 static uintptr_t stream_id_reg[] = { 151 USB3H_0_STREAM_ID_REG, 152 USB3H_1_STREAM_ID_REG, 153 CP_DMA_0_STREAM_ID_REG, 154 CP_DMA_1_STREAM_ID_REG, 155 SATA_0_STREAM_ID_REG, 156 SATA_1_STREAM_ID_REG, 157 SDIO_STREAM_ID_REG, 158 0 159 }; 160 161 static void cp110_errata_wa_init(uintptr_t base) 162 { 163 uint32_t data; 164 165 /* ERRATA GL-4076863: 166 * Reset value for global_secure_enable inputs must be changed 167 * from '1' to '0'. 168 * When asserted, only "secured" transactions can enter IHB 169 * configuration space. 170 * However, blocking AXI transactions is performed by IOB. 171 * Performing it also at IHB/HB complicates programming model. 172 * 173 * Enable non-secure access in SOC configuration register 174 */ 175 data = mmio_read_32(base + MVEBU_SOC_CFG_REG(MVEBU_SOC_CFG_REG_NUM)); 176 data &= ~MVEBU_SOC_CFG_GLOG_SECURE_EN_MASK; 177 mmio_write_32(base + MVEBU_SOC_CFG_REG(MVEBU_SOC_CFG_REG_NUM), data); 178 } 179 180 static void cp110_pcie_clk_cfg(uintptr_t base) 181 { 182 uint32_t pcie0_clk, pcie1_clk, reg; 183 184 /* 185 * Determine the pcie0/1 clock direction (input/output) from the 186 * sample at reset. 187 */ 188 reg = mmio_read_32(base + MVEBU_SAMPLE_AT_RESET_REG); 189 pcie0_clk = (reg & SAR_PCIE0_CLK_CFG_MASK) >> SAR_PCIE0_CLK_CFG_OFFSET; 190 pcie1_clk = (reg & SAR_PCIE1_CLK_CFG_MASK) >> SAR_PCIE1_CLK_CFG_OFFSET; 191 192 /* CP110 revision A2 or CN913x */ 193 if (cp110_rev_id_get(base) == MVEBU_CP110_REF_ID_A2 || 194 cp110_device_id_get(base) == MVEBU_CN9130_DEV_ID) { 195 /* 196 * PCIe Reference Clock Buffer Control register must be 197 * set according to the clock direction (input/output) 198 */ 199 reg = mmio_read_32(base + MVEBU_PCIE_REF_CLK_BUF_CTRL); 200 reg &= ~(PCIE0_REFCLK_BUFF_SOURCE | PCIE1_REFCLK_BUFF_SOURCE); 201 if (!pcie0_clk) 202 reg |= PCIE0_REFCLK_BUFF_SOURCE; 203 if (!pcie1_clk) 204 reg |= PCIE1_REFCLK_BUFF_SOURCE; 205 206 mmio_write_32(base + MVEBU_PCIE_REF_CLK_BUF_CTRL, reg); 207 } 208 209 /* CP110 revision A1 */ 210 if (cp110_rev_id_get(base) == MVEBU_CP110_REF_ID_A1) { 211 if (!pcie0_clk || !pcie1_clk) { 212 /* 213 * if one of the pcie clocks is set to input, 214 * we need to set mss_push[131] field, otherwise, 215 * the pcie clock might not work. 216 */ 217 reg = mmio_read_32(base + MVEBU_CP_MSS_DPSHSR_REG); 218 reg |= MSS_DPSHSR_REG_PCIE_CLK_SEL; 219 mmio_write_32(base + MVEBU_CP_MSS_DPSHSR_REG, reg); 220 } 221 } 222 } 223 224 /* Set a unique stream id for all DMA capable devices */ 225 static void cp110_stream_id_init(uintptr_t base, uint32_t stream_id) 226 { 227 int i = 0; 228 229 while (stream_id_reg[i]) { 230 if (i > MAX_STREAM_ID_PER_CP) { 231 NOTICE("Only first %d (maximum) Stream IDs allocated\n", 232 MAX_STREAM_ID_PER_CP); 233 return; 234 } 235 236 if ((stream_id_reg[i] == CP_DMA_0_STREAM_ID_REG) || 237 (stream_id_reg[i] == CP_DMA_1_STREAM_ID_REG)) 238 mmio_write_32(base + stream_id_reg[i], 239 stream_id << 16 | stream_id); 240 else 241 mmio_write_32(base + stream_id_reg[i], stream_id); 242 243 /* SATA port 0/1 are in the same SATA unit, and they should use 244 * the same STREAM ID number 245 */ 246 if (stream_id_reg[i] != SATA_0_STREAM_ID_REG) 247 stream_id++; 248 249 i++; 250 } 251 } 252 253 static void cp110_axi_attr_init(uintptr_t base) 254 { 255 uint32_t index, data; 256 257 /* Initialize AXI attributes for Armada-7K/8K SoC */ 258 259 /* Go over the AXI attributes and set Ax-Cache and Ax-Domain */ 260 for (index = 0; index < AXI_MAX_ATTR; index++) { 261 switch (index) { 262 /* DFX and MSS unit works with no coherent only - 263 * there's no option to configure the Ax-Cache and Ax-Domain 264 */ 265 case AXI_DFX_ATTR: 266 case AXI_MSS_ATTR: 267 continue; 268 default: 269 /* Set Ax-Cache as cacheable, no allocate, modifiable, 270 * bufferable 271 * The values are different because Read & Write 272 * definition is different in Ax-Cache 273 */ 274 data = mmio_read_32(base + MVEBU_AXI_ATTR_REG(index)); 275 data &= ~MVEBU_AXI_ATTR_ARCACHE_MASK; 276 data |= (CACHE_ATTR_WRITE_ALLOC | 277 CACHE_ATTR_CACHEABLE | 278 CACHE_ATTR_BUFFERABLE) << 279 MVEBU_AXI_ATTR_ARCACHE_OFFSET; 280 data &= ~MVEBU_AXI_ATTR_AWCACHE_MASK; 281 data |= (CACHE_ATTR_READ_ALLOC | 282 CACHE_ATTR_CACHEABLE | 283 CACHE_ATTR_BUFFERABLE) << 284 MVEBU_AXI_ATTR_AWCACHE_OFFSET; 285 /* Set Ax-Domain as Outer domain */ 286 data &= ~MVEBU_AXI_ATTR_ARDOMAIN_MASK; 287 data |= DOMAIN_OUTER_SHAREABLE << 288 MVEBU_AXI_ATTR_ARDOMAIN_OFFSET; 289 data &= ~MVEBU_AXI_ATTR_AWDOMAIN_MASK; 290 data |= DOMAIN_OUTER_SHAREABLE << 291 MVEBU_AXI_ATTR_AWDOMAIN_OFFSET; 292 mmio_write_32(base + MVEBU_AXI_ATTR_REG(index), data); 293 } 294 } 295 296 /* SATA IOCC supported, cache attributes 297 * for SATA MBUS to AXI configuration. 298 */ 299 data = mmio_read_32(base + MVEBU_SATA_M2A_AXI_PORT_CTRL_REG); 300 data &= ~MVEBU_SATA_M2A_AXI_AWCACHE_MASK; 301 data |= (CACHE_ATTR_WRITE_ALLOC | 302 CACHE_ATTR_CACHEABLE | 303 CACHE_ATTR_BUFFERABLE) << 304 MVEBU_SATA_M2A_AXI_AWCACHE_OFFSET; 305 data &= ~MVEBU_SATA_M2A_AXI_ARCACHE_MASK; 306 data |= (CACHE_ATTR_READ_ALLOC | 307 CACHE_ATTR_CACHEABLE | 308 CACHE_ATTR_BUFFERABLE) << 309 MVEBU_SATA_M2A_AXI_ARCACHE_OFFSET; 310 mmio_write_32(base + MVEBU_SATA_M2A_AXI_PORT_CTRL_REG, data); 311 312 /* Set all IO's AXI attribute to non-secure access. */ 313 for (index = 0; index < MVEBU_AXI_PROT_REGS_NUM; index++) 314 mmio_write_32(base + MVEBU_AXI_PROT_REG(index), 315 DOMAIN_SYSTEM_SHAREABLE); 316 } 317 318 void cp110_amb_init(uintptr_t base) 319 { 320 uint32_t reg; 321 322 /* Open AMB bridge Window to Access COMPHY/MDIO registers */ 323 reg = mmio_read_32(base + MVEBU_AMB_IP_BRIDGE_WIN_REG(0)); 324 reg &= ~(MVEBU_AMB_IP_BRIDGE_WIN_SIZE_MASK | 325 MVEBU_AMB_IP_BRIDGE_WIN_EN_MASK); 326 reg |= (0x7ff << MVEBU_AMB_IP_BRIDGE_WIN_SIZE_OFFSET) | 327 (0x1 << MVEBU_AMB_IP_BRIDGE_WIN_EN_OFFSET); 328 mmio_write_32(base + MVEBU_AMB_IP_BRIDGE_WIN_REG(0), reg); 329 } 330 331 static void cp110_rtc_init(uintptr_t base) 332 { 333 /* Update MBus timing parameters before accessing RTC registers */ 334 mmio_clrsetbits_32(base + MVEBU_RTC_BRIDGE_TIMING_CTRL0_REG, 335 MVEBU_RTC_WRCLK_PERIOD_MASK, 336 MVEBU_RTC_WRCLK_PERIOD_DEFAULT); 337 338 mmio_clrsetbits_32(base + MVEBU_RTC_BRIDGE_TIMING_CTRL0_REG, 339 MVEBU_RTC_WRCLK_SETUP_MASK, 340 MVEBU_RTC_WRCLK_SETUP_DEFAULT << 341 MVEBU_RTC_WRCLK_SETUP_OFFS); 342 343 mmio_clrsetbits_32(base + MVEBU_RTC_BRIDGE_TIMING_CTRL1_REG, 344 MVEBU_RTC_READ_OUTPUT_DELAY_MASK, 345 MVEBU_RTC_READ_OUTPUT_DELAY_DEFAULT); 346 347 /* 348 * Issue reset to the RTC if Clock Correction register 349 * contents did not sustain the reboot/power-on. 350 */ 351 if ((mmio_read_32(base + MVEBU_RTC_CCR_REG) & 352 MVEBU_RTC_NOMINAL_TIMING_MASK) != MVEBU_RTC_NOMINAL_TIMING) { 353 /* Reset Test register */ 354 mmio_write_32(base + MVEBU_RTC_TEST_CONFIG_REG, 0); 355 mdelay(500); 356 357 /* Reset Status register */ 358 mmio_write_32(base + MVEBU_RTC_STATUS_REG, 359 (MVEBU_RTC_STATUS_ALARM1_MASK | 360 MVEBU_RTC_STATUS_ALARM2_MASK)); 361 udelay(62); 362 363 /* Turn off Int1 and Int2 sources & clear the Alarm count */ 364 mmio_write_32(base + MVEBU_RTC_IRQ_1_CONFIG_REG, 0); 365 mmio_write_32(base + MVEBU_RTC_IRQ_2_CONFIG_REG, 0); 366 mmio_write_32(base + MVEBU_RTC_ALARM_1_REG, 0); 367 mmio_write_32(base + MVEBU_RTC_ALARM_2_REG, 0); 368 369 /* Setup nominal register access timing */ 370 mmio_write_32(base + MVEBU_RTC_CCR_REG, 371 MVEBU_RTC_NOMINAL_TIMING); 372 373 /* Reset Status register */ 374 mmio_write_32(base + MVEBU_RTC_STATUS_REG, 375 (MVEBU_RTC_STATUS_ALARM1_MASK | 376 MVEBU_RTC_STATUS_ALARM2_MASK)); 377 udelay(50); 378 } 379 } 380 381 static void cp110_amb_adec_init(uintptr_t base) 382 { 383 /* enable AXI-MBUS by clearing "Bridge Windows Disable" */ 384 mmio_clrbits_32(base + MVEBU_BRIDGE_WIN_DIS_REG, 385 (1 << MVEBU_BRIDGE_WIN_DIS_OFF)); 386 387 /* configure AXI-MBUS windows for CP */ 388 init_amb_adec(base); 389 } 390 391 static void cp110_trng_init(uintptr_t base) 392 { 393 static bool done; 394 int ret; 395 uint32_t reg_val, efuse; 396 397 /* Set access to LD0 */ 398 reg_val = mmio_read_32(MVEBU_AP_EFUSE_SRV_CTRL_REG); 399 reg_val &= ~EFUSE_SRV_CTRL_LD_SELECT_MASK; 400 mmio_write_32(MVEBU_AP_EFUSE_SRV_CTRL_REG, reg_val); 401 402 /* Obtain the AP LD0 bit defining TRNG presence */ 403 efuse = mmio_read_32(MVEBU_EFUSE_TRNG_ENABLE_EFUSE_WORD); 404 efuse >>= MVEBU_EFUSE_TRNG_ENABLE_BIT_OFFSET; 405 efuse &= 1; 406 407 if (efuse == 0) { 408 VERBOSE("TRNG is not present, skipping"); 409 return; 410 } 411 412 if (!done) { 413 ret = eip76_rng_probe(base + MVEBU_TRNG_BASE); 414 if (ret != 0) { 415 ERROR("Failed to init TRNG @ 0x%lx\n", base); 416 return; 417 } 418 done = true; 419 } 420 } 421 void cp110_init(uintptr_t cp110_base, uint32_t stream_id) 422 { 423 INFO("%s: Initialize CPx - base = %lx\n", __func__, cp110_base); 424 425 /* configure IOB windows for CP0*/ 426 init_iob(cp110_base); 427 428 /* configure AXI-MBUS windows for CP0*/ 429 cp110_amb_adec_init(cp110_base); 430 431 /* configure axi for CP0*/ 432 cp110_axi_attr_init(cp110_base); 433 434 /* Execute SW WA for erratas */ 435 cp110_errata_wa_init(cp110_base); 436 437 /* Confiure pcie clock according to clock direction */ 438 cp110_pcie_clk_cfg(cp110_base); 439 440 /* configure stream id for CP0 */ 441 cp110_stream_id_init(cp110_base, stream_id); 442 443 /* Open AMB bridge for comphy for CP0 & CP1*/ 444 cp110_amb_init(cp110_base); 445 446 /* Reset RTC if needed */ 447 cp110_rtc_init(cp110_base); 448 449 /* TRNG init - for CP0 only */ 450 cp110_trng_init(cp110_base); 451 } 452 453 /* Do the minimal setup required to configure the CP in BLE */ 454 void cp110_ble_init(uintptr_t cp110_base) 455 { 456 #if PCI_EP_SUPPORT 457 INFO("%s: Initialize CPx - base = %lx\n", __func__, cp110_base); 458 459 cp110_amb_init(cp110_base); 460 461 /* Configure PCIe clock */ 462 cp110_pcie_clk_cfg(cp110_base); 463 464 /* Configure PCIe endpoint */ 465 ble_plat_pcie_ep_setup(); 466 #endif 467 } 468