1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. 7 * Copyright (C) 2006 FON Technology, SL. 8 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> 9 * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org> 10 * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com> 11 */ 12 13 /* 14 * Platform devices for Atheros AR5312 SoCs 15 */ 16 17 #include <linux/init.h> 18 #include <linux/kernel.h> 19 #include <linux/bitops.h> 20 #include <linux/irqdomain.h> 21 #include <linux/interrupt.h> 22 #include <linux/memblock.h> 23 #include <linux/platform_device.h> 24 #include <linux/mtd/physmap.h> 25 #include <linux/reboot.h> 26 #include <asm/bootinfo.h> 27 #include <asm/reboot.h> 28 #include <asm/time.h> 29 30 #include <ath25_platform.h> 31 32 #include "devices.h" 33 #include "ar5312.h" 34 #include "ar5312_regs.h" 35 36 static void __iomem *ar5312_rst_base; 37 static struct irq_domain *ar5312_misc_irq_domain; 38 39 static inline u32 ar5312_rst_reg_read(u32 reg) 40 { 41 return __raw_readl(ar5312_rst_base + reg); 42 } 43 44 static inline void ar5312_rst_reg_write(u32 reg, u32 val) 45 { 46 __raw_writel(val, ar5312_rst_base + reg); 47 } 48 49 static inline void ar5312_rst_reg_mask(u32 reg, u32 mask, u32 val) 50 { 51 u32 ret = ar5312_rst_reg_read(reg); 52 53 ret &= ~mask; 54 ret |= val; 55 ar5312_rst_reg_write(reg, ret); 56 } 57 58 static irqreturn_t ar5312_ahb_err_handler(int cpl, void *dev_id) 59 { 60 u32 proc1 = ar5312_rst_reg_read(AR5312_PROC1); 61 u32 proc_addr = ar5312_rst_reg_read(AR5312_PROCADDR); /* clears error */ 62 u32 dma1 = ar5312_rst_reg_read(AR5312_DMA1); 63 u32 dma_addr = ar5312_rst_reg_read(AR5312_DMAADDR); /* clears error */ 64 65 pr_emerg("AHB interrupt: PROCADDR=0x%8.8x PROC1=0x%8.8x DMAADDR=0x%8.8x DMA1=0x%8.8x\n", 66 proc_addr, proc1, dma_addr, dma1); 67 68 machine_restart("AHB error"); /* Catastrophic failure */ 69 return IRQ_HANDLED; 70 } 71 72 static void ar5312_misc_irq_handler(struct irq_desc *desc) 73 { 74 u32 pending = ar5312_rst_reg_read(AR5312_ISR) & 75 ar5312_rst_reg_read(AR5312_IMR); 76 unsigned nr; 77 int ret = 0; 78 79 if (pending) { 80 struct irq_domain *domain = irq_desc_get_handler_data(desc); 81 82 nr = __ffs(pending); 83 84 ret = generic_handle_domain_irq(domain, nr); 85 if (nr == AR5312_MISC_IRQ_TIMER) 86 ar5312_rst_reg_read(AR5312_TIMER); 87 } 88 89 if (!pending || ret) 90 spurious_interrupt(); 91 } 92 93 /* Enable the specified AR5312_MISC_IRQ interrupt */ 94 static void ar5312_misc_irq_unmask(struct irq_data *d) 95 { 96 ar5312_rst_reg_mask(AR5312_IMR, 0, BIT(d->hwirq)); 97 } 98 99 /* Disable the specified AR5312_MISC_IRQ interrupt */ 100 static void ar5312_misc_irq_mask(struct irq_data *d) 101 { 102 ar5312_rst_reg_mask(AR5312_IMR, BIT(d->hwirq), 0); 103 ar5312_rst_reg_read(AR5312_IMR); /* flush write buffer */ 104 } 105 106 static struct irq_chip ar5312_misc_irq_chip = { 107 .name = "ar5312-misc", 108 .irq_unmask = ar5312_misc_irq_unmask, 109 .irq_mask = ar5312_misc_irq_mask, 110 }; 111 112 static int ar5312_misc_irq_map(struct irq_domain *d, unsigned irq, 113 irq_hw_number_t hw) 114 { 115 irq_set_chip_and_handler(irq, &ar5312_misc_irq_chip, handle_level_irq); 116 return 0; 117 } 118 119 static const struct irq_domain_ops ar5312_misc_irq_domain_ops = { 120 .map = ar5312_misc_irq_map, 121 }; 122 123 static void ar5312_irq_dispatch(void) 124 { 125 u32 pending = read_c0_status() & read_c0_cause(); 126 127 if (pending & CAUSEF_IP2) 128 do_IRQ(AR5312_IRQ_WLAN0); 129 else if (pending & CAUSEF_IP5) 130 do_IRQ(AR5312_IRQ_WLAN1); 131 else if (pending & CAUSEF_IP6) 132 do_IRQ(AR5312_IRQ_MISC); 133 else if (pending & CAUSEF_IP7) 134 do_IRQ(ATH25_IRQ_CPU_CLOCK); 135 else 136 spurious_interrupt(); 137 } 138 139 void __init ar5312_arch_init_irq(void) 140 { 141 struct irq_domain *domain; 142 unsigned irq; 143 144 ath25_irq_dispatch = ar5312_irq_dispatch; 145 146 domain = irq_domain_add_linear(NULL, AR5312_MISC_IRQ_COUNT, 147 &ar5312_misc_irq_domain_ops, NULL); 148 if (!domain) 149 panic("Failed to add IRQ domain"); 150 151 irq = irq_create_mapping(domain, AR5312_MISC_IRQ_AHB_PROC); 152 if (request_irq(irq, ar5312_ahb_err_handler, 0, "ar5312-ahb-error", 153 NULL)) 154 pr_err("Failed to register ar5312-ahb-error interrupt\n"); 155 156 irq_set_chained_handler_and_data(AR5312_IRQ_MISC, 157 ar5312_misc_irq_handler, domain); 158 159 ar5312_misc_irq_domain = domain; 160 } 161 162 static struct physmap_flash_data ar5312_flash_data = { 163 .width = 2, 164 }; 165 166 static struct resource ar5312_flash_resource = { 167 .start = AR5312_FLASH_BASE, 168 .end = AR5312_FLASH_BASE + AR5312_FLASH_SIZE - 1, 169 .flags = IORESOURCE_MEM, 170 }; 171 172 static struct platform_device ar5312_physmap_flash = { 173 .name = "physmap-flash", 174 .id = 0, 175 .dev.platform_data = &ar5312_flash_data, 176 .resource = &ar5312_flash_resource, 177 .num_resources = 1, 178 }; 179 180 static void __init ar5312_flash_init(void) 181 { 182 void __iomem *flashctl_base; 183 u32 ctl; 184 185 flashctl_base = ioremap(AR5312_FLASHCTL_BASE, 186 AR5312_FLASHCTL_SIZE); 187 188 ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL0); 189 ctl &= AR5312_FLASHCTL_MW; 190 191 /* fixup flash width */ 192 switch (ctl) { 193 case AR5312_FLASHCTL_MW16: 194 ar5312_flash_data.width = 2; 195 break; 196 case AR5312_FLASHCTL_MW8: 197 default: 198 ar5312_flash_data.width = 1; 199 break; 200 } 201 202 /* 203 * Configure flash bank 0. 204 * Assume 8M window size. Flash will be aliased if it's smaller 205 */ 206 ctl |= AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC_8M | AR5312_FLASHCTL_RBLE; 207 ctl |= 0x01 << AR5312_FLASHCTL_IDCY_S; 208 ctl |= 0x07 << AR5312_FLASHCTL_WST1_S; 209 ctl |= 0x07 << AR5312_FLASHCTL_WST2_S; 210 __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL0); 211 212 /* Disable other flash banks */ 213 ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL1); 214 ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC); 215 __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL1); 216 ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL2); 217 ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC); 218 __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL2); 219 220 iounmap(flashctl_base); 221 } 222 223 void __init ar5312_init_devices(void) 224 { 225 struct ath25_boarddata *config; 226 227 ar5312_flash_init(); 228 229 /* Locate board/radio config data */ 230 ath25_find_config(AR5312_FLASH_BASE, AR5312_FLASH_SIZE); 231 config = ath25_board.config; 232 233 /* AR2313 has CPU minor rev. 10 */ 234 if ((current_cpu_data.processor_id & 0xff) == 0x0a) 235 ath25_soc = ATH25_SOC_AR2313; 236 237 /* AR2312 shares the same Silicon ID as AR5312 */ 238 else if (config->flags & BD_ISCASPER) 239 ath25_soc = ATH25_SOC_AR2312; 240 241 /* Everything else is probably AR5312 or compatible */ 242 else 243 ath25_soc = ATH25_SOC_AR5312; 244 245 platform_device_register(&ar5312_physmap_flash); 246 247 switch (ath25_soc) { 248 case ATH25_SOC_AR5312: 249 if (!ath25_board.radio) 250 return; 251 252 if (!(config->flags & BD_WLAN0)) 253 break; 254 255 ath25_add_wmac(0, AR5312_WLAN0_BASE, AR5312_IRQ_WLAN0); 256 break; 257 case ATH25_SOC_AR2312: 258 case ATH25_SOC_AR2313: 259 if (!ath25_board.radio) 260 return; 261 break; 262 default: 263 break; 264 } 265 266 if (config->flags & BD_WLAN1) 267 ath25_add_wmac(1, AR5312_WLAN1_BASE, AR5312_IRQ_WLAN1); 268 } 269 270 static void ar5312_restart(char *command) 271 { 272 /* reset the system */ 273 local_irq_disable(); 274 while (1) 275 ar5312_rst_reg_write(AR5312_RESET, AR5312_RESET_SYSTEM); 276 } 277 278 /* 279 * This table is indexed by bits 5..4 of the CLOCKCTL1 register 280 * to determine the predevisor value. 281 */ 282 static unsigned clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 }; 283 284 static unsigned __init ar5312_cpu_frequency(void) 285 { 286 u32 scratch, devid, clock_ctl1; 287 u32 predivide_mask, multiplier_mask, doubler_mask; 288 unsigned predivide_shift, multiplier_shift; 289 unsigned predivide_select, predivisor, multiplier; 290 291 /* Trust the bootrom's idea of cpu frequency. */ 292 scratch = ar5312_rst_reg_read(AR5312_SCRATCH); 293 if (scratch) 294 return scratch; 295 296 devid = ar5312_rst_reg_read(AR5312_REV); 297 devid = (devid & AR5312_REV_MAJ) >> AR5312_REV_MAJ_S; 298 if (devid == AR5312_REV_MAJ_AR2313) { 299 predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK; 300 predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT; 301 multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK; 302 multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT; 303 doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK; 304 } else { /* AR5312 and AR2312 */ 305 predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK; 306 predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT; 307 multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK; 308 multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT; 309 doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK; 310 } 311 312 /* 313 * Clocking is derived from a fixed 40MHz input clock. 314 * 315 * cpu_freq = input_clock * MULT (where MULT is PLL multiplier) 316 * sys_freq = cpu_freq / 4 (used for APB clock, serial, 317 * flash, Timer, Watchdog Timer) 318 * 319 * cnt_freq = cpu_freq / 2 (use for CPU count/compare) 320 * 321 * So, for example, with a PLL multiplier of 5, we have 322 * 323 * cpu_freq = 200MHz 324 * sys_freq = 50MHz 325 * cnt_freq = 100MHz 326 * 327 * We compute the CPU frequency, based on PLL settings. 328 */ 329 330 clock_ctl1 = ar5312_rst_reg_read(AR5312_CLOCKCTL1); 331 predivide_select = (clock_ctl1 & predivide_mask) >> predivide_shift; 332 predivisor = clockctl1_predivide_table[predivide_select]; 333 multiplier = (clock_ctl1 & multiplier_mask) >> multiplier_shift; 334 335 if (clock_ctl1 & doubler_mask) 336 multiplier <<= 1; 337 338 return (40000000 / predivisor) * multiplier; 339 } 340 341 static inline unsigned ar5312_sys_frequency(void) 342 { 343 return ar5312_cpu_frequency() / 4; 344 } 345 346 void __init ar5312_plat_time_init(void) 347 { 348 mips_hpt_frequency = ar5312_cpu_frequency() / 2; 349 } 350 351 void __init ar5312_plat_mem_setup(void) 352 { 353 void __iomem *sdram_base; 354 u32 memsize, memcfg, bank0_ac, bank1_ac; 355 u32 devid; 356 357 /* Detect memory size */ 358 sdram_base = ioremap(AR5312_SDRAMCTL_BASE, 359 AR5312_SDRAMCTL_SIZE); 360 memcfg = __raw_readl(sdram_base + AR5312_MEM_CFG1); 361 bank0_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC0); 362 bank1_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC1); 363 memsize = (bank0_ac ? (1 << (bank0_ac + 1)) : 0) + 364 (bank1_ac ? (1 << (bank1_ac + 1)) : 0); 365 memsize <<= 20; 366 memblock_add(0, memsize); 367 iounmap(sdram_base); 368 369 ar5312_rst_base = ioremap(AR5312_RST_BASE, AR5312_RST_SIZE); 370 371 devid = ar5312_rst_reg_read(AR5312_REV); 372 devid >>= AR5312_REV_WMAC_MIN_S; 373 devid &= AR5312_REV_CHIP; 374 ath25_board.devid = (u16)devid; 375 376 /* Clear any lingering AHB errors */ 377 ar5312_rst_reg_read(AR5312_PROCADDR); 378 ar5312_rst_reg_read(AR5312_DMAADDR); 379 ar5312_rst_reg_write(AR5312_WDT_CTRL, AR5312_WDT_CTRL_IGNORE); 380 381 _machine_restart = ar5312_restart; 382 } 383 384 void __init ar5312_arch_init(void) 385 { 386 unsigned irq = irq_create_mapping(ar5312_misc_irq_domain, 387 AR5312_MISC_IRQ_UART0); 388 389 ath25_serial_setup(AR5312_UART0_BASE, irq, ar5312_sys_frequency()); 390 } 391
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.