1 /* $NetBSD: armadaxp.c,v 1.21 2017/02/26 09:33:27 skrll Exp $ */ 2 /******************************************************************************* 3 Copyright (C) Marvell International Ltd. and its affiliates 4 5 Developed by Semihalf 6 7 ******************************************************************************** 8 Marvell BSD License 9 10 If you received this File from Marvell, you may opt to use, redistribute and/or 11 modify this File under the following licensing terms. 12 Redistribution and use in source and binary forms, with or without modification, 13 are permitted provided that the following conditions are met: 14 15 * Redistributions of source code must retain the above copyright notice, 16 this list of conditions and the following disclaimer. 17 18 * Redistributions in binary form must reproduce the above copyright 19 notice, this list of conditions and the following disclaimer in the 20 documentation and/or other materials provided with the distribution. 21 22 * Neither the name of Marvell nor the names of its contributors may be 23 used to endorse or promote products derived from this software without 24 specific prior written permission. 25 26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 27 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 28 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 29 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 30 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 31 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 32 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 33 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 37 *******************************************************************************/ 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: armadaxp.c,v 1.21 2017/02/26 09:33:27 skrll Exp $"); 41 42 #define _INTR_PRIVATE 43 44 #include "opt_mvsoc.h" 45 46 #include <sys/param.h> 47 #include <sys/bus.h> 48 49 #include <machine/intr.h> 50 51 #include <arm/pic/picvar.h> 52 53 #include <arm/armreg.h> 54 #include <arm/cpu.h> 55 #include <arm/cpufunc.h> 56 57 #include <arm/marvell/mvsocreg.h> 58 #include <arm/marvell/mvsocvar.h> 59 #include <arm/marvell/armadaxpreg.h> 60 #include <arm/marvell/armadaxpvar.h> 61 62 #include <dev/marvell/marvellreg.h> 63 64 #define EXTRACT_XP_CPU_FREQ_FIELD(sar) (((0x01 & (sar >> 52)) << 3) | \ 65 (0x07 & (sar >> 21))) 66 #define EXTRACT_XP_FAB_FREQ_FIELD(sar) (((0x01 & (sar >> 51)) << 4) | \ 67 (0x0F & (sar >> 24))) 68 #define EXTRACT_370_CPU_FREQ_FIELD(sar) ((sar >> 11) & 0xf) 69 #define EXTRACT_370_FAB_FREQ_FIELD(sar) ((sar >> 15) & 0x1f) 70 71 #define MPIC_WRITE(reg, val) (bus_space_write_4(&mvsoc_bs_tag, \ 72 mpic_handle, reg, val)) 73 #define MPIC_CPU_WRITE(reg, val) (bus_space_write_4(&mvsoc_bs_tag, \ 74 mpic_cpu_handle, reg, val)) 75 76 #define MPIC_READ(reg) (bus_space_read_4(&mvsoc_bs_tag, \ 77 mpic_handle, reg)) 78 #define MPIC_CPU_READ(reg) (bus_space_read_4(&mvsoc_bs_tag, \ 79 mpic_cpu_handle, reg)) 80 81 #define L2_WRITE(reg, val) (bus_space_write_4(&mvsoc_bs_tag, \ 82 l2_handle, reg, val)) 83 #define L2_READ(reg) (bus_space_read_4(&mvsoc_bs_tag, \ 84 l2_handle, reg)) 85 bus_space_handle_t mpic_cpu_handle; 86 static bus_space_handle_t mpic_handle, l2_handle; 87 int l2cache_state = 0; 88 int iocc_state = 0; 89 #define read_miscreg(r) (*(volatile uint32_t *)(misc_base + (r))) 90 vaddr_t misc_base; 91 vaddr_t armadaxp_l2_barrier_reg; 92 93 static void armadaxp_intr_init(void); 94 95 static void armadaxp_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t); 96 static void armadaxp_pic_block_irqs(struct pic_softc *, size_t, uint32_t); 97 static void armadaxp_pic_establish_irq(struct pic_softc *, struct intrsource *); 98 static void armadaxp_pic_set_priority(struct pic_softc *, int); 99 static void armadaxp_pic_source_name(struct pic_softc *, int, char*, size_t); 100 101 static int armadaxp_find_pending_irqs(void); 102 static void armadaxp_pic_block_irq(struct pic_softc *, size_t); 103 104 /* handle error cause */ 105 static void armadaxp_err_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t); 106 static void armadaxp_err_pic_block_irqs(struct pic_softc *, size_t, uint32_t); 107 static void armadaxp_err_pic_establish_irq(struct pic_softc *, 108 struct intrsource *); 109 static void armadaxp_err_pic_source_name(struct pic_softc *, 110 int, char*, size_t); 111 static int armadaxp_err_pic_pending_irqs(struct pic_softc *); 112 113 static void armadaxp_getclks(void); 114 static void armada370_getclks(void); 115 static int armadaxp_clkgating(struct marvell_attach_args *); 116 117 static int armadaxp_l2_init(bus_addr_t); 118 static paddr_t armadaxp_sdcache_wbalign_base(vaddr_t, paddr_t, psize_t); 119 static paddr_t armadaxp_sdcache_wbalign_end(vaddr_t, paddr_t, psize_t); 120 #ifdef AURORA_IO_CACHE_COHERENCY 121 static void armadaxp_io_coherency_init(void); 122 #endif 123 124 struct vco_freq_ratio { 125 uint8_t vco_cpu; /* VCO to CLK0(CPU) clock ratio */ 126 uint8_t vco_l2c; /* VCO to NB(L2 cache) clock ratio */ 127 uint8_t vco_hcl; /* VCO to HCLK(DDR controller) clock ratio */ 128 uint8_t vco_ddr; /* VCO to DR(DDR memory) clock ratio */ 129 }; 130 131 /* 132 * Interrupt names for ARMADA XP 133 */ 134 static const char * const armadaxp_pic_source_names[] = { 135 /* Main Interrupt Cause Per-CPU (IRQ 0-29) */ 136 "InDBLowSum", "InDBHighSum", "OutDBSum", "CFU_LocalSum", 137 "SoC_ErrorSum", "LTimer0", "LTimer1", "LWDT", "GbE0_TH_RxTx", 138 "GbE0_RxTx", "GbE1_RxTxTh", "GbE1_RxTx", "GbE2_RxTxTh", "GbE2_RxTx", 139 "GbE3_RxTxTh", "GbE3_RxTx", "GPIO0_7", "GPIO8_15", "GPIO16_23", 140 "GPIO24_31", "GPIO32_39", "GPIO40_47", "GPIO48_55", "GPIO56_63", 141 "GPIO64_66", "SCNT", "PCNT", "Reserved27", "VCNT", "Reserved29", 142 /* Main Interrupt Cause Global-Shared (IRQ 30-115) */ 143 "SPI0", "I2C0", "I2C1", "IDMA0", "IDMA1", "IDMA2", "IDMA3", "GTimer0", 144 "GTimer1", "GTimer2", "GTimer3", "UART0", "UART1", "UART2", "UART3", 145 "USB0", "USB1", "USB2", "CESA0", "CESA1", "RTC", "XOR0_Ch0", 146 "XOR0_Ch1", "BM", "SDIO", "SATA0", "TDM", "SATA1", "PEX0_0", "PEX0_1", 147 "PEX0_2", "PEX0_3", "PEX1_0", "PEX1_1", "PEX1_2", "PEX1_3", 148 "GbE0_Sum", "GbE0_Rx", "GbE0_Tx", "GbE0_Misc", "GbE1_Sum", "GbE1_Rx", 149 "GbE1_Tx", "GbE1_Misc", "GbE2_Sum", "GbE2_Rx", "GbE2_Tx", "GbE2_Misc", 150 "GbE3_Sum", "GbE3_Rx", "GbE3_Tx", "GbE3_Misc", "GPIO0_7", "GPIO8_15", 151 "GPIO16_23", "GPIO24_31", "Reserved86", "GPIO32_39", "GPIO40_47", 152 "GPIO48_55", "GPIO56_63", "GPIO64_66", "SPI1", "WDT", "XOR1_Ch2", 153 "XOR1_Ch3", "SharedDB1Sum", "SharedDB2Sum", "SharedDB3Sum", "PEX2_0", 154 "Reserved100", "Reserved101", "Reserved102", "PEX3_0", "Reserved104", 155 "Reserved105", "Reserved106", "PMU", "DRAM", "GbE0_Wakeup", 156 "GbE1_Wakeup", "GbE2_Wakeup", "GbE3_Wakeup", "NAND", "Reserved114", 157 "Reserved115" 158 }; 159 static const char * const armadaxp_err_pic_source_names[] = { 160 /* 161 * IRQ 120-151 (bit 0-31 in SoC Error Interrupt Cause register) 162 * connected to SoC_ErrorSum in Main Interrupt Cause 163 */ 164 "ERR_CESA0", "ERR_DevBus", "ERR_IDMA", "ERR_XOR1", 165 "ERR_PEX0", "ERR_PEX1", "ERR_GbE", "ERR_CESA1", 166 "ERR_USB", "ERR_DRAM", "ERR_XOR0", "ERR_Reserved11", 167 "ERR_BM", "ERR_CIB", "ERR_Reserved14", "ERR_PEX2", 168 "ERR_PEX3", "ERR_SATA0", "ERR_SATA1", "ERR_Reserved19", 169 "ERR_TDM", "ERR_NAND", "ERR_Reserved22", 170 "ERR_Reserved23", "ERR_Reserved24", "ERR_Reserved25", 171 "ERR_Reserved26", "ERR_Reserved27", "ERR_Reserved28", 172 "ERR_Reserved29", "ERR_Reserved30", "ERR_Reserved31", 173 }; 174 175 /* 176 * Mbus Target and Attribute bindings for ARMADA XP 177 */ 178 static struct mbus_description { 179 uint8_t target; 180 uint8_t attr; 181 const char *string; 182 } mbus_desc[] = { 183 /* DDR */ 184 { ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS0, 185 "DDR(M_CS[0])" }, 186 { ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS1, 187 "DDR(M_CS[1])" }, 188 { ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS2, 189 "DDR(M_CS[2])" }, 190 { ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS3, 191 "DDR(M_CS[3])" }, 192 193 /* DEVBUS */ 194 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS0, 195 "DEVBUS(SPI0 CS0)" }, 196 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS1, 197 "DEVBUS(SPI0 CS1)" }, 198 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS2, 199 "DEVBUS(SPI0 CS2)" }, 200 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS3, 201 "DEVBUS(SPI0 CS3)" }, 202 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS4, 203 "DEVBUS(SPI0 CS4)" }, 204 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS5, 205 "DEVBUS(SPI0 CS5)" }, 206 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS6, 207 "DEVBUS(SPI0 CS6)" }, 208 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS7, 209 "DEVBUS(SPI0 CS7)" }, 210 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS0, 211 "DEVBUS(SPI1 CS0)" }, 212 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS1, 213 "DEVBUS(SPI1 CS1)" }, 214 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS2, 215 "DEVBUS(SPI1 CS2)" }, 216 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS3, 217 "DEVBUS(SPI1 CS3)" }, 218 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS4, 219 "DEVBUS(SPI1 CS4)" }, 220 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS5, 221 "DEVBUS(SPI1 CS5)" }, 222 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS6, 223 "DEVBUS(SPI1 CS6)" }, 224 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS7, 225 "DEVBUS(SPI1 CS7)" }, 226 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS0, 227 "DEVBUS(DevCS[0])" }, 228 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS1, 229 "DEVBUS(DevCS[1])" }, 230 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS2, 231 "DEVBUS(DevCS[2])" }, 232 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS3, 233 "DEVBUS(DevCS[3])" }, 234 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_BOOT_CS, 235 "DEVBUS(BootCS)" }, 236 { ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_BOOT_ROM, 237 "DEVBUS(BootROM)" }, 238 239 /* GbE */ 240 { ARMADAXP_UNITID_GBE0, ARMADAXP_ATTR_GBE_RESERVED, 241 "GBE0 GBE1" }, 242 { ARMADAXP_UNITID_GBE2, ARMADAXP_ATTR_GBE_RESERVED, 243 "GBE2 GBE3" }, 244 245 /* PEX(PCIe) */ 246 { ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx0_MEM, 247 "PEX0(Lane0, Memory)" }, 248 { ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx1_MEM, 249 "PEX0(Lane1, Memory)" }, 250 { ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx2_MEM, 251 "PEX0(Lane2, Memory)" }, 252 { ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx3_MEM, 253 "PEX0(Lane3, Memory)" }, 254 { ARMADAXP_UNITID_PEX2, ARMADAXP_ATTR_PEX2_MEM, 255 "PEX2(Lane0, Memory)" }, 256 { ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx0_MEM, 257 "PEX1(Lane0, Memory)" }, 258 { ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx1_MEM, 259 "PEX1(Lane1, Memory)" }, 260 { ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx2_MEM, 261 "PEX1(Lane2, Memory)" }, 262 { ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx3_MEM, 263 "PEX1(Lane3, Memory)" }, 264 { ARMADAXP_UNITID_PEX3, ARMADAXP_ATTR_PEX3_MEM, 265 "PEX3(Lane0, Memory)" }, 266 { ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx0_IO, 267 "PEX0(Lane0, I/O)" }, 268 { ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx1_IO, 269 "PEX0(Lane1, I/O)" }, 270 { ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx2_IO, 271 "PEX0(Lane2, I/O)" }, 272 { ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx3_IO, 273 "PEX0(Lane3, I/O)" }, 274 { ARMADAXP_UNITID_PEX2, ARMADAXP_ATTR_PEX2_IO, 275 "PEX2(Lane0, I/O)" }, 276 { ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx0_IO, 277 "PEX1(Lane0, I/O)" }, 278 { ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx1_IO, 279 "PEX1(Lane1, I/O)" }, 280 { ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx2_IO, 281 "PEX1(Lane2, I/O)" }, 282 { ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx3_IO, 283 "PEX1(Lane3, I/O)" }, 284 { ARMADAXP_UNITID_PEX3, ARMADAXP_ATTR_PEX3_IO, 285 "PEX3(Lane0, I/O)" }, 286 287 /* CRYPT */ 288 { ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_NOSWAP, 289 "CESA0(No swap)" }, 290 { ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_SWAP_BYTE, 291 "CESA0(Byte swap)" }, 292 { ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_SWAP_BYTE_WORD, 293 "CESA0(Byte and word swap)" }, 294 { ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_SWAP_WORD, 295 "CESA0(Word swap)" }, 296 { ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_NOSWAP, 297 "CESA1(No swap)" }, 298 { ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_SWAP_BYTE, 299 "CESA1(Byte swap)" }, 300 { ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_SWAP_BYTE_WORD, 301 "CESA1(Byte and word swap)" }, 302 { ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_SWAP_WORD, 303 "CESA1(Word swap)" }, 304 305 /* BM */ 306 { ARMADAXP_UNITID_BM, ARMADAXP_ATTR_BM_RESERVED, 307 "BM" }, 308 309 /* NAND */ 310 { ARMADAXP_UNITID_NAND, ARMADAXP_ATTR_NAND_RESERVED, 311 "NAND" }, 312 }; 313 314 /* 315 * Default Mbus address decoding table for ARMADA XP 316 * this table may changed by device drivers. 317 * 318 * NOTE: some version of u-boot is broken. it writes old decoding table. 319 * probably, it's designed for Kirkwood SoC or older. we need to restore 320 * ARMADA XP's parameter set. 321 */ 322 static struct mbus_table_def { 323 int window; /* index of address decoding window registers */ 324 uint32_t base; /* base address of the window */ 325 uint32_t size; /* size of the window */ 326 uint8_t target; /* target unit of the window */ 327 uint8_t attr; /* target attribute of the window */ 328 } mbus_table[] = { 329 /* 330 * based on 'default address mapping' described in Marvell's document 331 * 'ARMADA XP Functional Specifications.' 332 * 333 * some windows are modified to get compatibility with old codes. 334 */ 335 { 336 /* PCIe 0 lane0 MEM */ 337 /* MODIFIED (moved to MARVELL_PEXMEM_PBASE) */ 338 0, 0xe0000000, 0x01000000, 339 ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx0_MEM 340 }, 341 { 342 /* PCIe 0 lane1 MEM */ 343 1, 0x88000000, 0x08000000, 344 ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx1_MEM 345 }, 346 { 347 /* PCIe 0 lane2 MEM */ 348 2, 0x90000000, 0x08000000, 349 ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx2_MEM 350 }, 351 { 352 /* PCIe 0 lane3 MEM */ 353 3, 0x98000000, 0x08000000, 354 ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx3_MEM 355 }, 356 { 357 /* PCIe 1 lane0 MEM */ 358 4, 0xa0000000, 0x08000000, 359 ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx0_MEM 360 }, 361 { 5, 0, 0, 0, 0 /* disabled */ }, 362 { 6, 0, 0, 0, 0 /* disabled */ }, 363 { 7, 0, 0, 0, 0 /* disabled */ }, 364 { 365 /* Security Accelerator SRAM, Engine 0, no data swap */ 366 8, 0xc8010000, 0x00010000, 367 ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_NOSWAP, 368 }, 369 { 370 /* Device bus, BOOT_CS */ 371 9, 0xd8000000, 0x08000000, 372 ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_BOOT_CS, 373 }, 374 { 375 /* Device bus, DEV_CS[0] */ 376 /* MODIFIED (moved, conflict to MARVELL_PEXMEM_PBASE here.) */ 377 10, 0x80000000, 0x08000000, 378 ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS0 379 }, 380 { 381 /* Device bus, DEV_CS[1] */ 382 11, 0xe8000000, 0x08000000, 383 ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS1 384 }, 385 { 386 /* Device bus, DEV_CS[2] */ 387 /* MODIFIED: (disabled, conflict to MARVELL_PEXIO_PBASE) */ 388 12, 0xf0000000, 0x00000000, 389 ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS2 390 }, 391 { 392 /* Device bus, BOOT_ROM */ 393 13, 0xf8000000, 0x08000000, 394 ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_BOOT_ROM 395 }, 396 { 397 /* Device bus, SPI0_CS[0] */ 398 14, 0xd4000000, 0x04000000, 399 ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS0 400 }, 401 { 402 /* Security Accelerator SRAM, Engine 1, no data swap */ 403 /* MODIFIED (added, 0xd0300000-0xd030ffff) */ 404 15, 0xd0300000, 0x00010000, 405 ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_NOSWAP 406 }, 407 { 408 /* PCIe 0 lane 0 I/O */ 409 /* MODIFIED (added, MARVELL_PEXIO_PBASE) */ 410 16, 0xf2000000, 0x00100000, 411 ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx0_IO 412 }, 413 { 17, 0xd0320000, 0, 0, 0 /* disabled */ }, 414 { 415 /* Buffer Manamgement unit */ 416 18, 0xd3800000, 0x00800000, 417 ARMADAXP_UNITID_BM, ARMADAXP_ATTR_BM_RESERVED 418 }, 419 { 420 /* DDR */ 421 /* MODIFIED (up to 2GB memory space) */ 422 19, 0x00000000, 0x80000000, 423 ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS0 424 }, 425 426 }; 427 428 static struct vco_freq_ratio freq_conf_table[] = { 429 /*00*/ { 1, 1, 4, 2 }, 430 /*01*/ { 1, 2, 2, 2 }, 431 /*02*/ { 2, 2, 6, 3 }, 432 /*03*/ { 2, 2, 3, 3 }, 433 /*04*/ { 1, 2, 3, 3 }, 434 /*05*/ { 1, 2, 4, 2 }, 435 /*06*/ { 1, 1, 2, 2 }, 436 /*07*/ { 2, 3, 6, 6 }, 437 /*08*/ { 2, 3, 5, 5 }, 438 /*09*/ { 1, 2, 6, 3 }, 439 /*10*/ { 2, 4, 10, 5 }, 440 /*11*/ { 1, 3, 6, 6 }, 441 /*12*/ { 1, 2, 5, 5 }, 442 /*13*/ { 1, 3, 6, 3 }, 443 /*14*/ { 1, 2, 5, 5 }, 444 /*15*/ { 2, 2, 5, 5 }, 445 /*16*/ { 1, 1, 3, 3 }, 446 /*17*/ { 2, 5, 10, 10 }, 447 /*18*/ { 1, 3, 8, 4 }, 448 /*19*/ { 1, 1, 2, 1 }, 449 /*20*/ { 2, 3, 6, 3 }, 450 /*21*/ { 1, 2, 8, 4 }, 451 /*22*/ { 2, 5, 10, 5 } 452 }; 453 454 static uint16_t clock_table_xp[] = { 455 1000, 1066, 1200, 1333, 1500, 1666, 1800, 2000, 456 600, 667, 800, 1600, 2133, 2200, 2400 457 }; 458 static uint16_t clock_table_370[] = { 459 400, 533, 667, 800, 1000, 1067, 1200, 1333, 460 1500, 1600, 1667, 1800, 2000, 333, 600, 900, 461 0 462 }; 463 464 static struct pic_ops armadaxp_picops = { 465 .pic_unblock_irqs = armadaxp_pic_unblock_irqs, 466 .pic_block_irqs = armadaxp_pic_block_irqs, 467 .pic_establish_irq = armadaxp_pic_establish_irq, 468 .pic_set_priority = armadaxp_pic_set_priority, 469 .pic_source_name = armadaxp_pic_source_name, 470 }; 471 472 static struct pic_softc armadaxp_pic = { 473 .pic_ops = &armadaxp_picops, 474 .pic_name = "armadaxp", 475 }; 476 477 static struct pic_ops armadaxp_err_picops = { 478 .pic_unblock_irqs = armadaxp_err_pic_unblock_irqs, 479 .pic_block_irqs = armadaxp_err_pic_block_irqs, 480 .pic_establish_irq = armadaxp_err_pic_establish_irq, 481 .pic_find_pending_irqs = armadaxp_err_pic_pending_irqs, 482 .pic_source_name = armadaxp_err_pic_source_name, 483 }; 484 485 static struct pic_softc armadaxp_err_pic = { 486 .pic_ops = &armadaxp_err_picops, 487 .pic_name = "armadaxp_err", 488 }; 489 490 static struct { 491 bus_size_t offset; 492 uint32_t bits; 493 } clkgatings[]= { 494 { ARMADAXP_GBE3_BASE, (1 << 1) }, 495 { ARMADAXP_GBE2_BASE, (1 << 2) }, 496 { ARMADAXP_GBE1_BASE, (1 << 3) }, 497 { ARMADAXP_GBE0_BASE, (1 << 4) }, 498 { MVSOC_PEX_BASE, (1 << 5) }, 499 { ARMADAXP_PEX01_BASE, (1 << 6) }, 500 { ARMADAXP_PEX02_BASE, (1 << 7) }, 501 { ARMADAXP_PEX03_BASE, (1 << 8) }, 502 { ARMADAXP_PEX10_BASE, (1 << 9) }, 503 { ARMADAXP_PEX11_BASE, (1 << 10) }, 504 { ARMADAXP_PEX12_BASE, (1 << 11) }, 505 { ARMADAXP_PEX13_BASE, (1 << 12) }, 506 #if 0 507 { NetA, (1 << 13) }, 508 #endif 509 { ARMADAXP_SATAHC_BASE, (1 << 14) | (1 << 15) | (1 << 29) | (1 << 30) }, 510 { ARMADAXP_LCD_BASE, (1 << 16) }, 511 { ARMADAXP_SDIO_BASE, (1 << 17) }, 512 { ARMADAXP_USB1_BASE, (1 << 19) }, 513 { ARMADAXP_USB2_BASE, (1 << 20) }, 514 { ARMADAXP_CESA0_BASE, (1 << 23) }, 515 { ARMADAXP_CESA1_BASE, (1 << 23) }, 516 { ARMADAXP_PEX2_BASE, (1 << 26) }, 517 { ARMADAXP_PEX3_BASE, (1 << 27) }, 518 #if 0 519 { DDR, (1 << 28) }, 520 #endif 521 }; 522 523 /* 524 * armadaxp_bootstrap: 525 * 526 * Initialize the rest of the Armada XP dependencies, making it 527 * ready to handle interrupts from devices. 528 */ 529 void 530 armadaxp_bootstrap(vaddr_t vbase, bus_addr_t pbase) 531 { 532 int i; 533 534 /* Map MPIC base and MPIC percpu base registers */ 535 if (bus_space_map(&mvsoc_bs_tag, pbase + ARMADAXP_MLMB_MPIC_BASE, 536 0x500, 0, &mpic_handle) != 0) 537 panic("%s: Could not map MPIC registers", __func__); 538 if (bus_space_map(&mvsoc_bs_tag, pbase + ARMADAXP_MLMB_MPIC_CPU_BASE, 539 0x800, 0, &mpic_cpu_handle) != 0) 540 panic("%s: Could not map MPIC percpu registers", __func__); 541 542 /* Disable all interrupts */ 543 for (i = 0; i < ARMADAXP_IRQ_SOURCES; i++) 544 MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, i); 545 546 mvsoc_intr_init = armadaxp_intr_init; 547 548 mvsoc_clkgating = armadaxp_clkgating; 549 550 misc_base = vbase + ARMADAXP_MISC_BASE; 551 switch (mvsoc_model()) { 552 case MARVELL_ARMADAXP_MV78130: 553 case MARVELL_ARMADAXP_MV78160: 554 case MARVELL_ARMADAXP_MV78230: 555 case MARVELL_ARMADAXP_MV78260: 556 case MARVELL_ARMADAXP_MV78460: 557 armadaxp_getclks(); 558 break; 559 560 case MARVELL_ARMADA370_MV6707: 561 case MARVELL_ARMADA370_MV6710: 562 case MARVELL_ARMADA370_MV6W11: 563 armada370_getclks(); 564 break; 565 } 566 567 #ifdef L2CACHE_ENABLE 568 /* Initialize L2 Cache */ 569 armadaxp_l2_init(pbase); 570 #endif 571 572 #ifdef AURORA_IO_CACHE_COHERENCY 573 /* Initialize cache coherency */ 574 armadaxp_io_coherency_init(); 575 #endif 576 } 577 578 static void 579 armadaxp_intr_init(void) 580 { 581 int ctrl; 582 void *ih __diagused; 583 584 /* Get max interrupts */ 585 armadaxp_pic.pic_maxsources = 586 ((MPIC_READ(ARMADAXP_MLMB_MPIC_CTRL) >> 2) & 0x7FF); 587 588 if (!armadaxp_pic.pic_maxsources) 589 armadaxp_pic.pic_maxsources = ARMADAXP_IRQ_SOURCES; 590 591 pic_add(&armadaxp_pic, 0); 592 593 /* Chain error interrupts controller */ 594 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, 0); 595 armadaxp_err_pic.pic_maxsources = ARMADAXP_IRQ_ERROR_SOURCES; 596 pic_add(&armadaxp_err_pic, ARMADAXP_IRQ_ERROR_BASE); 597 ih = intr_establish(ARMADAXP_IRQ_ERR_SUMMARY, IPL_HIGH, IST_LEVEL_HIGH, 598 pic_handle_intr, &armadaxp_err_pic); 599 KASSERT(ih != NULL); 600 601 ctrl = MPIC_READ(ARMADAXP_MLMB_MPIC_CTRL); 602 /* Enable IRQ prioritization */ 603 ctrl |= (1 << 0); 604 MPIC_WRITE(ARMADAXP_MLMB_MPIC_CTRL, ctrl); 605 606 find_pending_irqs = armadaxp_find_pending_irqs; 607 } 608 609 static void 610 armadaxp_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase, 611 uint32_t irq_mask) 612 { 613 int n; 614 615 while (irq_mask != 0) { 616 n = ffs(irq_mask) - 1; 617 KASSERT(pic->pic_maxsources >= n + irqbase); 618 MPIC_WRITE(ARMADAXP_MLMB_MPIC_ISE, n + irqbase); 619 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ICM, n + irqbase); 620 if ((n + irqbase) == 0) 621 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_DOORBELL_MASK, 622 0xffffffff); 623 irq_mask &= ~__BIT(n); 624 } 625 } 626 627 static void 628 armadaxp_pic_block_irqs(struct pic_softc *pic, size_t irqbase, 629 uint32_t irq_mask) 630 { 631 int n; 632 633 while (irq_mask != 0) { 634 n = ffs(irq_mask) - 1; 635 KASSERT(pic->pic_maxsources >= n + irqbase); 636 MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, n + irqbase); 637 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ISM, n + irqbase); 638 irq_mask &= ~__BIT(n); 639 } 640 } 641 642 static void 643 armadaxp_pic_establish_irq(struct pic_softc *pic, struct intrsource *is) 644 { 645 int tmp; 646 KASSERT(pic->pic_maxsources >= is->is_irq); 647 tmp = MPIC_READ(ARMADAXP_MLMB_MPIC_ISCR_BASE + is->is_irq * 4); 648 /* Clear previous priority */ 649 tmp &= ~(0xf << MPIC_ISCR_SHIFT); 650 MPIC_WRITE(ARMADAXP_MLMB_MPIC_ISCR_BASE + is->is_irq * 4, 651 tmp | (is->is_ipl << MPIC_ISCR_SHIFT)); 652 } 653 654 static void 655 armadaxp_pic_set_priority(struct pic_softc *pic, int ipl) 656 { 657 int ctp; 658 659 ctp = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_CTP); 660 ctp &= ~(0xf << MPIC_CTP_SHIFT); 661 ctp |= (ipl << MPIC_CTP_SHIFT); 662 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_CTP, ctp); 663 } 664 665 static void 666 armadaxp_pic_source_name(struct pic_softc *pic, int irq, char *buf, size_t len) 667 { 668 if (irq >= __arraycount(armadaxp_pic_source_names)) { 669 snprintf(buf, len, "Unknown IRQ %d", irq); 670 return; 671 } 672 strlcpy(buf, armadaxp_pic_source_names[irq], len); 673 } 674 675 static int 676 armadaxp_find_pending_irqs(void) 677 { 678 struct intrsource *is; 679 int irq; 680 681 irq = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_IIACK) & 0x3ff; 682 683 /* Is it a spurious interrupt ?*/ 684 if (irq == 0x3ff) 685 return 0; 686 is = armadaxp_pic.pic_sources[irq]; 687 if (is == NULL) { 688 printf("stray interrupt: %d\n", irq); 689 return 0; 690 } 691 692 armadaxp_pic_block_irq(&armadaxp_pic, irq); 693 pic_mark_pending(&armadaxp_pic, irq); 694 695 return is->is_ipl; 696 } 697 698 static void 699 armadaxp_pic_block_irq(struct pic_softc *pic, size_t irq) 700 { 701 702 KASSERT(pic->pic_maxsources >= irq); 703 MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, irq); 704 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ISM, irq); 705 } 706 707 static void 708 armadaxp_err_pic_source_name(struct pic_softc *pic, int irq, 709 char *buf, size_t len) 710 { 711 if (irq >= __arraycount(armadaxp_err_pic_source_names)) { 712 snprintf(buf, len, "Unknown IRQ %d", irq); 713 return; 714 } 715 strlcpy(buf, armadaxp_err_pic_source_names[irq], len); 716 } 717 718 719 /* 720 * ARMADAXP_MLMB_MPIC_ERR_CAUSE 721 */ 722 static void 723 armadaxp_err_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase, 724 uint32_t irq_mask) 725 { 726 uint32_t reg; 727 728 KASSERT(irqbase == 0); /* XXX: support offset */ 729 730 reg = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_ERR_MASK); 731 reg |= irq_mask; 732 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, reg); 733 } 734 735 static void 736 armadaxp_err_pic_block_irqs(struct pic_softc *pic, size_t irqbase, 737 uint32_t irq_mask) 738 { 739 uint32_t reg; 740 741 KASSERT(irqbase == 0); /* XXX: support offset */ 742 743 reg = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_ERR_MASK); 744 reg &= ~irq_mask; 745 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, reg); 746 } 747 748 static void 749 armadaxp_err_pic_establish_irq(struct pic_softc *pic, struct intrsource *is) 750 { 751 uint32_t reg; 752 753 KASSERT(pic->pic_maxsources >= is->is_irq); 754 755 reg = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_ERR_MASK); 756 reg |= ARMADAXP_IRQ_ERROR_BIT(is->is_irq); 757 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, reg); 758 } 759 760 static int 761 armadaxp_err_pic_pending_irqs(struct pic_softc *pic) 762 { 763 struct intrsource *is; 764 uint32_t reg; 765 int irq; 766 767 reg = MPIC_READ(ARMADAXP_MLMB_MPIC_ERR_CAUSE); 768 irq = ffs(reg); 769 if (irq == 0) 770 return 0; 771 irq--; /* bit number to index */ 772 773 is = pic->pic_sources[irq]; 774 if (is == NULL) { 775 printf("stray interrupt: %d\n", irq); 776 return 0; 777 } 778 return pic_mark_pending_sources(pic, 0, irq); 779 } 780 781 782 /* 783 * Clock functions 784 */ 785 786 static void 787 armadaxp_getclks(void) 788 { 789 uint64_t sar_reg; 790 uint8_t sar_cpu_freq, sar_fab_freq; 791 792 if (cputype == CPU_ID_MV88SV584X_V7) 793 mvTclk = 250000000; /* 250 MHz */ 794 else 795 mvTclk = 200000000; /* 200 MHz */ 796 797 sar_reg = (read_miscreg(ARMADAXP_MISC_SAR_HI) << 31) | 798 read_miscreg(ARMADAXP_MISC_SAR_LO); 799 800 sar_cpu_freq = EXTRACT_XP_CPU_FREQ_FIELD(sar_reg); 801 sar_fab_freq = EXTRACT_XP_FAB_FREQ_FIELD(sar_reg); 802 803 /* Check if CPU frequency field has correct value */ 804 if (sar_cpu_freq >= __arraycount(clock_table_xp)) 805 panic("Reserved value in cpu frequency configuration field: " 806 "%d", sar_cpu_freq); 807 808 /* Check if fabric frequency field has correct value */ 809 if (sar_fab_freq >= __arraycount(freq_conf_table)) 810 panic("Reserved value in fabric frequency configuration field: " 811 "%d", sar_fab_freq); 812 813 /* Get CPU clock frequency */ 814 mvPclk = clock_table_xp[sar_cpu_freq] * 815 freq_conf_table[sar_fab_freq].vco_cpu; 816 817 /* Get L2CLK clock frequency and use as system clock (mvSysclk) */ 818 mvSysclk = mvPclk / freq_conf_table[sar_fab_freq].vco_l2c; 819 820 /* Round mvSysclk value to integer MHz */ 821 if (((mvPclk % freq_conf_table[sar_fab_freq].vco_l2c) * 10 / 822 freq_conf_table[sar_fab_freq].vco_l2c) >= 5) 823 mvSysclk++; 824 825 mvPclk *= 1000000; 826 mvSysclk *= 1000000; 827 828 curcpu()->ci_data.cpu_cc_freq = mvPclk; 829 } 830 831 static void 832 armada370_getclks(void) 833 { 834 uint32_t sar; 835 uint8_t cpu_freq, fab_freq; 836 837 sar = read_miscreg(ARMADAXP_MISC_SAR_LO); 838 if (sar & 0x00100000) 839 mvTclk = 200000000; /* 200 MHz */ 840 else 841 mvTclk = 166666667; /* 166 MHz */ 842 843 cpu_freq = EXTRACT_370_CPU_FREQ_FIELD(sar); 844 fab_freq = EXTRACT_370_FAB_FREQ_FIELD(sar); 845 846 /* Check if CPU frequency field has correct value */ 847 if (cpu_freq >= __arraycount(clock_table_370)) 848 panic("Reserved value in cpu frequency configuration field: " 849 "%d", cpu_freq); 850 851 /* Check if fabric frequency field has correct value */ 852 if (fab_freq >= __arraycount(freq_conf_table)) 853 panic("Reserved value in fabric frequency configuration field: " 854 "%d", fab_freq); 855 856 /* Get CPU clock frequency */ 857 mvPclk = clock_table_370[cpu_freq] * 858 freq_conf_table[fab_freq].vco_cpu; 859 860 /* Get L2CLK clock frequency and use as system clock (mvSysclk) */ 861 mvSysclk = mvPclk / freq_conf_table[fab_freq].vco_l2c; 862 863 /* Round mvSysclk value to integer MHz */ 864 if (((mvPclk % freq_conf_table[fab_freq].vco_l2c) * 10 / 865 freq_conf_table[fab_freq].vco_l2c) >= 5) 866 mvSysclk++; 867 868 mvPclk *= 1000000; 869 mvSysclk *= 1000000; 870 } 871 872 /* 873 * L2 Cache initialization 874 */ 875 876 static int 877 armadaxp_l2_init(bus_addr_t pbase) 878 { 879 u_int32_t reg; 880 int ret; 881 882 /* Map L2 space */ 883 ret = bus_space_map(&mvsoc_bs_tag, pbase + ARMADAXP_L2_BASE, 884 0x1000, 0, &l2_handle); 885 if (ret) { 886 printf("%s: Cannot map L2 register space, ret:%d\n", 887 __func__, ret); 888 return (-1); 889 } 890 891 /* Variables for cpufunc_asm_pj4b.S */ 892 /* XXX: per cpu register. need to support SMP */ 893 armadaxp_l2_barrier_reg = mlmb_base + MVSOC_MLMB_CIB_BARRIER(0); 894 895 /* Set L2 policy */ 896 reg = L2_READ(ARMADAXP_L2_AUX_CTRL); 897 reg &= ~(L2_AUX_WBWT_MODE_MASK); 898 reg &= ~(L2_AUX_REP_STRAT_MASK); 899 reg |= L2_AUX_ECC_ENABLE; 900 reg |= L2_AUX_PARITY_ENABLE; 901 reg |= L2_AUX_WBWT_MODE_BY_ATTR; 902 reg |= L2_AUX_FORCE_WA_BY_ATTR; 903 reg |= L2_AUX_REP_STRAT_SEMIPLRU; 904 L2_WRITE(ARMADAXP_L2_AUX_CTRL, reg); 905 906 /* Invalidate L2 cache */ 907 L2_WRITE(ARMADAXP_L2_INV_WAY, L2_ALL_WAYS); 908 909 /* Clear pending L2 interrupts */ 910 L2_WRITE(ARMADAXP_L2_INT_CAUSE, 0x1ff); 911 912 /* Enable Cache and TLB maintenance broadcast */ 913 __asm__ __volatile__ ("mrc p15, 1, %0, c15, c2, 0" : "=r"(reg)); 914 reg |= (1 << 8); 915 __asm__ __volatile__ ("mcr p15, 1, %0, c15, c2, 0" : :"r"(reg)); 916 917 /* 918 * Set the Point of Coherency and Point of Unification to DRAM. 919 * This is a reset value but anyway, configure this just in case. 920 */ 921 reg = read_mlmbreg(ARMADAXP_L2_CFU); 922 reg |= (1 << 17) | (1 << 18); 923 write_mlmbreg(ARMADAXP_L2_CFU, reg); 924 925 /* Enable L2 cache */ 926 reg = L2_READ(ARMADAXP_L2_CTRL); 927 L2_WRITE(ARMADAXP_L2_CTRL, reg | L2_CTRL_ENABLE); 928 929 /* Mark as enabled */ 930 l2cache_state = 1; 931 932 #ifdef DEBUG 933 /* Configure and enable counter */ 934 L2_WRITE(ARMADAXP_L2_CNTR_CONF(0), 0xf0000 | (4 << 2)); 935 L2_WRITE(ARMADAXP_L2_CNTR_CONF(1), 0xf0000 | (2 << 2)); 936 L2_WRITE(ARMADAXP_L2_CNTR_CTRL, 0x303); 937 #endif 938 939 return (0); 940 } 941 942 void 943 armadaxp_sdcache_inv_all(void) 944 { 945 L2_WRITE(ARMADAXP_L2_INV_WAY, L2_ALL_WAYS); 946 } 947 948 void 949 armadaxp_sdcache_wb_all(void) 950 { 951 L2_WRITE(ARMADAXP_L2_WB_WAY, L2_ALL_WAYS); 952 L2_WRITE(ARMADAXP_L2_SYNC, 0); 953 __asm__ __volatile__("dsb"); 954 } 955 956 void 957 armadaxp_sdcache_wbinv_all(void) 958 { 959 L2_WRITE(ARMADAXP_L2_WBINV_WAY, L2_ALL_WAYS); 960 L2_WRITE(ARMADAXP_L2_SYNC, 0); 961 __asm__ __volatile__("dsb"); 962 } 963 964 static paddr_t 965 armadaxp_sdcache_wbalign_base(vaddr_t va, paddr_t pa, psize_t sz) 966 { 967 paddr_t line_start = pa & ~ARMADAXP_L2_ALIGN; 968 vaddr_t save_start; 969 uint8_t save_buf[ARMADAXP_L2_LINE_SIZE]; 970 size_t unalign; 971 972 unalign = va & ARMADAXP_L2_ALIGN; 973 if (unalign == 0) 974 return line_start; /* request is aligned to cache line size */ 975 976 /* save data that is not intended to invalidate */ 977 save_start = va & ~ARMADAXP_L2_ALIGN; 978 memcpy(save_buf, (void *)save_start, unalign); 979 980 /* invalidate include saved data */ 981 L2_WRITE(ARMADAXP_L2_INV_PHYS, line_start); 982 983 /* write back saved data */ 984 memcpy((void *)save_start, save_buf, unalign); 985 L2_WRITE(ARMADAXP_L2_WB_PHYS, line_start); 986 L2_WRITE(ARMADAXP_L2_SYNC, 0); 987 __asm__ __volatile__("dsb"); 988 989 return line_start; 990 } 991 992 static paddr_t 993 armadaxp_sdcache_wbalign_end(vaddr_t va, paddr_t pa, psize_t sz) 994 { 995 paddr_t line_start = (pa + sz - 1) & ~ARMADAXP_L2_ALIGN; 996 vaddr_t save_start = va + sz; 997 uint8_t save_buf[ARMADAXP_L2_LINE_SIZE]; 998 size_t save_len; 999 size_t unalign; 1000 1001 unalign = save_start & ARMADAXP_L2_ALIGN; 1002 if (unalign == 0) 1003 return line_start; /* request is aligned to cache line size */ 1004 1005 /* save data that is not intended to invalidate */ 1006 save_len = ARMADAXP_L2_LINE_SIZE - unalign; 1007 memcpy(save_buf, (void *)save_start, save_len); 1008 1009 /* invalidate include saved data */ 1010 L2_WRITE(ARMADAXP_L2_INV_PHYS, line_start); 1011 1012 /* write back saved data */ 1013 memcpy((void *)save_start, save_buf, save_len); 1014 L2_WRITE(ARMADAXP_L2_WB_PHYS, line_start); 1015 __asm__ __volatile__("dsb"); 1016 1017 return line_start; 1018 } 1019 1020 void 1021 armadaxp_sdcache_inv_range(vaddr_t va, paddr_t pa, psize_t sz) 1022 { 1023 paddr_t pa_base; 1024 paddr_t pa_end; 1025 1026 /* align and write-back the boundary */ 1027 pa_base = armadaxp_sdcache_wbalign_base(va, pa, sz); 1028 pa_end = armadaxp_sdcache_wbalign_end(va, pa, sz); 1029 1030 /* invalidate other cache */ 1031 if (pa_base == pa_end) { 1032 L2_WRITE(ARMADAXP_L2_INV_PHYS, pa_base); 1033 return; 1034 } 1035 1036 L2_WRITE(ARMADAXP_L2_RANGE_BASE, pa_base); 1037 L2_WRITE(ARMADAXP_L2_INV_RANGE, pa_end); 1038 } 1039 1040 void 1041 armadaxp_sdcache_wb_range(vaddr_t va, paddr_t pa, psize_t sz) 1042 { 1043 paddr_t pa_base = pa & ~ARMADAXP_L2_ALIGN; 1044 paddr_t pa_end = (pa + sz - 1) & ~ARMADAXP_L2_ALIGN; 1045 1046 if (pa_base == pa_end) 1047 L2_WRITE(ARMADAXP_L2_WB_PHYS, pa_base); 1048 else { 1049 L2_WRITE(ARMADAXP_L2_RANGE_BASE, pa_base); 1050 L2_WRITE(ARMADAXP_L2_WB_RANGE, pa_end); 1051 } 1052 L2_WRITE(ARMADAXP_L2_SYNC, 0); 1053 __asm__ __volatile__("dsb"); 1054 } 1055 1056 void 1057 armadaxp_sdcache_wbinv_range(vaddr_t va, paddr_t pa, psize_t sz) 1058 { 1059 paddr_t pa_base = pa & ~ARMADAXP_L2_ALIGN;; 1060 paddr_t pa_end = (pa + sz - 1) & ~ARMADAXP_L2_ALIGN; 1061 1062 if (pa_base == pa_end) 1063 L2_WRITE(ARMADAXP_L2_WBINV_PHYS, pa_base); 1064 else { 1065 L2_WRITE(ARMADAXP_L2_RANGE_BASE, pa_base); 1066 L2_WRITE(ARMADAXP_L2_WBINV_RANGE, pa_end); 1067 } 1068 L2_WRITE(ARMADAXP_L2_SYNC, 0); 1069 __asm__ __volatile__("dsb"); 1070 } 1071 1072 #ifdef AURORA_IO_CACHE_COHERENCY 1073 static void 1074 armadaxp_io_coherency_init(void) 1075 { 1076 uint32_t reg; 1077 1078 /* set CIB read snoop command to ReadUnique */ 1079 reg = read_mlmbreg(MVSOC_MLMB_CIB_CTRL_CFG); 1080 reg |= MVSOC_MLMB_CIB_CTRL_CFG_WB_EN; 1081 write_mlmbreg(MVSOC_MLMB_CIB_CTRL_CFG, reg); 1082 1083 /* enable CPUs in SMP group on Fabric coherency */ 1084 reg = read_mlmbreg(MVSOC_MLMB_CFU_FAB_CTRL); 1085 reg |= MVSOC_MLMB_CFU_FAB_CTRL_SNOOP_CPU0; 1086 write_mlmbreg(MVSOC_MLMB_CFU_FAB_CTRL, reg); 1087 1088 /* send all snoop request to L2 cache */ 1089 reg = read_mlmbreg(MVSOC_MLMB_CFU_CFG); 1090 #ifdef L2CACHE_ENABLE 1091 reg |= MVSOC_MLMB_CFU_CFG_L2_NOTIFY; 1092 #else 1093 reg &= ~MVSOC_MLMB_CFU_CFG_L2_NOTIFY; 1094 #endif 1095 write_mlmbreg(MVSOC_MLMB_CFU_CFG, reg); 1096 1097 /* Mark as enabled */ 1098 iocc_state = 1; 1099 } 1100 #endif 1101 1102 static int 1103 armadaxp_clkgating(struct marvell_attach_args *mva) 1104 { 1105 uint32_t val; 1106 int i; 1107 1108 for (i = 0; i < __arraycount(clkgatings); i++) { 1109 if (clkgatings[i].offset == mva->mva_offset) { 1110 val = read_miscreg(ARMADAXP_MISC_PMCGC); 1111 if ((val & clkgatings[i].bits) == clkgatings[i].bits) 1112 /* Clock enabled */ 1113 return 0; 1114 return 1; 1115 } 1116 } 1117 /* Clock Gating not support */ 1118 return 0; 1119 } 1120 1121 int 1122 armadaxp_init_mbus(void) 1123 { 1124 struct mbus_table_def *def; 1125 uint32_t reg; 1126 int i; 1127 1128 for (i = 0; i < nwindow; i++) { 1129 /* disable all windows */ 1130 reg = read_mlmbreg(MVSOC_MLMB_WCR(i)); 1131 reg &= ~MVSOC_MLMB_WCR_WINEN; 1132 write_mlmbreg(MVSOC_MLMB_WCR(i), reg); 1133 write_mlmbreg(MVSOC_MLMB_WBR(i), 0); 1134 } 1135 1136 for (i = 0; i < __arraycount(mbus_table); i++) { 1137 def = &mbus_table[i]; 1138 if (def->window >= nwindow) 1139 continue; 1140 if (def->size == 0) 1141 continue; 1142 1143 /* restore window base */ 1144 reg = def->base & MVSOC_MLMB_WBR_BASE_MASK; 1145 write_mlmbreg(MVSOC_MLMB_WBR(def->window), reg); 1146 1147 /* restore window configuration */ 1148 reg = MVSOC_MLMB_WCR_SIZE(def->size); 1149 reg |= MVSOC_MLMB_WCR_TARGET(def->target); 1150 reg |= MVSOC_MLMB_WCR_ATTR(def->attr); 1151 #ifdef AURORA_IO_CACHE_COHERENCY 1152 reg |= MVSOC_MLMB_WCR_SYNC; /* enbale I/O coherency barrior */ 1153 #endif 1154 reg |= MVSOC_MLMB_WCR_WINEN; 1155 write_mlmbreg(MVSOC_MLMB_WCR(def->window), reg); 1156 } 1157 1158 return 0; 1159 } 1160 1161 int 1162 armadaxp_attr_dump(struct mvsoc_softc *sc, uint32_t target, uint32_t attr) 1163 { 1164 struct mbus_description *desc; 1165 int i; 1166 1167 for (i = 0; i < __arraycount(mbus_desc); i++) { 1168 desc = &mbus_desc[i]; 1169 if (desc->target != target) 1170 continue; 1171 if (desc->attr != attr) 1172 continue; 1173 aprint_verbose_dev(sc->sc_dev, "%s", desc->string); 1174 return 0; 1175 } 1176 1177 /* unknown decoding target/attribute pair */ 1178 aprint_verbose_dev(sc->sc_dev, "target 0x%x(attr 0x%x)", target, attr); 1179 return -1; 1180 } 1181