Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved.
0007  * Copyright (C) 2006 FON Technology, SL.
0008  * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
0009  * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
0010  * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com>
0011  */
0012 
0013 /*
0014  * Platform devices for Atheros AR5312 SoCs
0015  */
0016 
0017 #include <linux/init.h>
0018 #include <linux/kernel.h>
0019 #include <linux/bitops.h>
0020 #include <linux/irqdomain.h>
0021 #include <linux/interrupt.h>
0022 #include <linux/memblock.h>
0023 #include <linux/platform_device.h>
0024 #include <linux/mtd/physmap.h>
0025 #include <linux/reboot.h>
0026 #include <asm/bootinfo.h>
0027 #include <asm/reboot.h>
0028 #include <asm/time.h>
0029 
0030 #include <ath25_platform.h>
0031 
0032 #include "devices.h"
0033 #include "ar5312.h"
0034 #include "ar5312_regs.h"
0035 
0036 static void __iomem *ar5312_rst_base;
0037 static struct irq_domain *ar5312_misc_irq_domain;
0038 
0039 static inline u32 ar5312_rst_reg_read(u32 reg)
0040 {
0041     return __raw_readl(ar5312_rst_base + reg);
0042 }
0043 
0044 static inline void ar5312_rst_reg_write(u32 reg, u32 val)
0045 {
0046     __raw_writel(val, ar5312_rst_base + reg);
0047 }
0048 
0049 static inline void ar5312_rst_reg_mask(u32 reg, u32 mask, u32 val)
0050 {
0051     u32 ret = ar5312_rst_reg_read(reg);
0052 
0053     ret &= ~mask;
0054     ret |= val;
0055     ar5312_rst_reg_write(reg, ret);
0056 }
0057 
0058 static irqreturn_t ar5312_ahb_err_handler(int cpl, void *dev_id)
0059 {
0060     u32 proc1 = ar5312_rst_reg_read(AR5312_PROC1);
0061     u32 proc_addr = ar5312_rst_reg_read(AR5312_PROCADDR); /* clears error */
0062     u32 dma1 = ar5312_rst_reg_read(AR5312_DMA1);
0063     u32 dma_addr = ar5312_rst_reg_read(AR5312_DMAADDR);   /* clears error */
0064 
0065     pr_emerg("AHB interrupt: PROCADDR=0x%8.8x PROC1=0x%8.8x DMAADDR=0x%8.8x DMA1=0x%8.8x\n",
0066          proc_addr, proc1, dma_addr, dma1);
0067 
0068     machine_restart("AHB error"); /* Catastrophic failure */
0069     return IRQ_HANDLED;
0070 }
0071 
0072 static void ar5312_misc_irq_handler(struct irq_desc *desc)
0073 {
0074     u32 pending = ar5312_rst_reg_read(AR5312_ISR) &
0075               ar5312_rst_reg_read(AR5312_IMR);
0076     unsigned nr;
0077     int ret = 0;
0078 
0079     if (pending) {
0080         struct irq_domain *domain = irq_desc_get_handler_data(desc);
0081 
0082         nr = __ffs(pending);
0083 
0084         ret = generic_handle_domain_irq(domain, nr);
0085         if (nr == AR5312_MISC_IRQ_TIMER)
0086             ar5312_rst_reg_read(AR5312_TIMER);
0087     }
0088 
0089     if (!pending || ret)
0090         spurious_interrupt();
0091 }
0092 
0093 /* Enable the specified AR5312_MISC_IRQ interrupt */
0094 static void ar5312_misc_irq_unmask(struct irq_data *d)
0095 {
0096     ar5312_rst_reg_mask(AR5312_IMR, 0, BIT(d->hwirq));
0097 }
0098 
0099 /* Disable the specified AR5312_MISC_IRQ interrupt */
0100 static void ar5312_misc_irq_mask(struct irq_data *d)
0101 {
0102     ar5312_rst_reg_mask(AR5312_IMR, BIT(d->hwirq), 0);
0103     ar5312_rst_reg_read(AR5312_IMR); /* flush write buffer */
0104 }
0105 
0106 static struct irq_chip ar5312_misc_irq_chip = {
0107     .name       = "ar5312-misc",
0108     .irq_unmask = ar5312_misc_irq_unmask,
0109     .irq_mask   = ar5312_misc_irq_mask,
0110 };
0111 
0112 static int ar5312_misc_irq_map(struct irq_domain *d, unsigned irq,
0113                    irq_hw_number_t hw)
0114 {
0115     irq_set_chip_and_handler(irq, &ar5312_misc_irq_chip, handle_level_irq);
0116     return 0;
0117 }
0118 
0119 static const struct irq_domain_ops ar5312_misc_irq_domain_ops = {
0120     .map = ar5312_misc_irq_map,
0121 };
0122 
0123 static void ar5312_irq_dispatch(void)
0124 {
0125     u32 pending = read_c0_status() & read_c0_cause();
0126 
0127     if (pending & CAUSEF_IP2)
0128         do_IRQ(AR5312_IRQ_WLAN0);
0129     else if (pending & CAUSEF_IP5)
0130         do_IRQ(AR5312_IRQ_WLAN1);
0131     else if (pending & CAUSEF_IP6)
0132         do_IRQ(AR5312_IRQ_MISC);
0133     else if (pending & CAUSEF_IP7)
0134         do_IRQ(ATH25_IRQ_CPU_CLOCK);
0135     else
0136         spurious_interrupt();
0137 }
0138 
0139 void __init ar5312_arch_init_irq(void)
0140 {
0141     struct irq_domain *domain;
0142     unsigned irq;
0143 
0144     ath25_irq_dispatch = ar5312_irq_dispatch;
0145 
0146     domain = irq_domain_add_linear(NULL, AR5312_MISC_IRQ_COUNT,
0147                        &ar5312_misc_irq_domain_ops, NULL);
0148     if (!domain)
0149         panic("Failed to add IRQ domain");
0150 
0151     irq = irq_create_mapping(domain, AR5312_MISC_IRQ_AHB_PROC);
0152     if (request_irq(irq, ar5312_ahb_err_handler, 0, "ar5312-ahb-error",
0153             NULL))
0154         pr_err("Failed to register ar5312-ahb-error interrupt\n");
0155 
0156     irq_set_chained_handler_and_data(AR5312_IRQ_MISC,
0157                      ar5312_misc_irq_handler, domain);
0158 
0159     ar5312_misc_irq_domain = domain;
0160 }
0161 
0162 static struct physmap_flash_data ar5312_flash_data = {
0163     .width = 2,
0164 };
0165 
0166 static struct resource ar5312_flash_resource = {
0167     .start = AR5312_FLASH_BASE,
0168     .end = AR5312_FLASH_BASE + AR5312_FLASH_SIZE - 1,
0169     .flags = IORESOURCE_MEM,
0170 };
0171 
0172 static struct platform_device ar5312_physmap_flash = {
0173     .name = "physmap-flash",
0174     .id = 0,
0175     .dev.platform_data = &ar5312_flash_data,
0176     .resource = &ar5312_flash_resource,
0177     .num_resources = 1,
0178 };
0179 
0180 static void __init ar5312_flash_init(void)
0181 {
0182     void __iomem *flashctl_base;
0183     u32 ctl;
0184 
0185     flashctl_base = ioremap(AR5312_FLASHCTL_BASE,
0186                     AR5312_FLASHCTL_SIZE);
0187 
0188     ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL0);
0189     ctl &= AR5312_FLASHCTL_MW;
0190 
0191     /* fixup flash width */
0192     switch (ctl) {
0193     case AR5312_FLASHCTL_MW16:
0194         ar5312_flash_data.width = 2;
0195         break;
0196     case AR5312_FLASHCTL_MW8:
0197     default:
0198         ar5312_flash_data.width = 1;
0199         break;
0200     }
0201 
0202     /*
0203      * Configure flash bank 0.
0204      * Assume 8M window size. Flash will be aliased if it's smaller
0205      */
0206     ctl |= AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC_8M | AR5312_FLASHCTL_RBLE;
0207     ctl |= 0x01 << AR5312_FLASHCTL_IDCY_S;
0208     ctl |= 0x07 << AR5312_FLASHCTL_WST1_S;
0209     ctl |= 0x07 << AR5312_FLASHCTL_WST2_S;
0210     __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL0);
0211 
0212     /* Disable other flash banks */
0213     ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL1);
0214     ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC);
0215     __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL1);
0216     ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL2);
0217     ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC);
0218     __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL2);
0219 
0220     iounmap(flashctl_base);
0221 }
0222 
0223 void __init ar5312_init_devices(void)
0224 {
0225     struct ath25_boarddata *config;
0226 
0227     ar5312_flash_init();
0228 
0229     /* Locate board/radio config data */
0230     ath25_find_config(AR5312_FLASH_BASE, AR5312_FLASH_SIZE);
0231     config = ath25_board.config;
0232 
0233     /* AR2313 has CPU minor rev. 10 */
0234     if ((current_cpu_data.processor_id & 0xff) == 0x0a)
0235         ath25_soc = ATH25_SOC_AR2313;
0236 
0237     /* AR2312 shares the same Silicon ID as AR5312 */
0238     else if (config->flags & BD_ISCASPER)
0239         ath25_soc = ATH25_SOC_AR2312;
0240 
0241     /* Everything else is probably AR5312 or compatible */
0242     else
0243         ath25_soc = ATH25_SOC_AR5312;
0244 
0245     platform_device_register(&ar5312_physmap_flash);
0246 
0247     switch (ath25_soc) {
0248     case ATH25_SOC_AR5312:
0249         if (!ath25_board.radio)
0250             return;
0251 
0252         if (!(config->flags & BD_WLAN0))
0253             break;
0254 
0255         ath25_add_wmac(0, AR5312_WLAN0_BASE, AR5312_IRQ_WLAN0);
0256         break;
0257     case ATH25_SOC_AR2312:
0258     case ATH25_SOC_AR2313:
0259         if (!ath25_board.radio)
0260             return;
0261         break;
0262     default:
0263         break;
0264     }
0265 
0266     if (config->flags & BD_WLAN1)
0267         ath25_add_wmac(1, AR5312_WLAN1_BASE, AR5312_IRQ_WLAN1);
0268 }
0269 
0270 static void ar5312_restart(char *command)
0271 {
0272     /* reset the system */
0273     local_irq_disable();
0274     while (1)
0275         ar5312_rst_reg_write(AR5312_RESET, AR5312_RESET_SYSTEM);
0276 }
0277 
0278 /*
0279  * This table is indexed by bits 5..4 of the CLOCKCTL1 register
0280  * to determine the predevisor value.
0281  */
0282 static unsigned clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 };
0283 
0284 static unsigned __init ar5312_cpu_frequency(void)
0285 {
0286     u32 scratch, devid, clock_ctl1;
0287     u32 predivide_mask, multiplier_mask, doubler_mask;
0288     unsigned predivide_shift, multiplier_shift;
0289     unsigned predivide_select, predivisor, multiplier;
0290 
0291     /* Trust the bootrom's idea of cpu frequency. */
0292     scratch = ar5312_rst_reg_read(AR5312_SCRATCH);
0293     if (scratch)
0294         return scratch;
0295 
0296     devid = ar5312_rst_reg_read(AR5312_REV);
0297     devid = (devid & AR5312_REV_MAJ) >> AR5312_REV_MAJ_S;
0298     if (devid == AR5312_REV_MAJ_AR2313) {
0299         predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK;
0300         predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT;
0301         multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK;
0302         multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT;
0303         doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK;
0304     } else { /* AR5312 and AR2312 */
0305         predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK;
0306         predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT;
0307         multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK;
0308         multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT;
0309         doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK;
0310     }
0311 
0312     /*
0313      * Clocking is derived from a fixed 40MHz input clock.
0314      *
0315      *  cpu_freq = input_clock * MULT (where MULT is PLL multiplier)
0316      *  sys_freq = cpu_freq / 4   (used for APB clock, serial,
0317      *                 flash, Timer, Watchdog Timer)
0318      *
0319      *  cnt_freq = cpu_freq / 2   (use for CPU count/compare)
0320      *
0321      * So, for example, with a PLL multiplier of 5, we have
0322      *
0323      *  cpu_freq = 200MHz
0324      *  sys_freq = 50MHz
0325      *  cnt_freq = 100MHz
0326      *
0327      * We compute the CPU frequency, based on PLL settings.
0328      */
0329 
0330     clock_ctl1 = ar5312_rst_reg_read(AR5312_CLOCKCTL1);
0331     predivide_select = (clock_ctl1 & predivide_mask) >> predivide_shift;
0332     predivisor = clockctl1_predivide_table[predivide_select];
0333     multiplier = (clock_ctl1 & multiplier_mask) >> multiplier_shift;
0334 
0335     if (clock_ctl1 & doubler_mask)
0336         multiplier <<= 1;
0337 
0338     return (40000000 / predivisor) * multiplier;
0339 }
0340 
0341 static inline unsigned ar5312_sys_frequency(void)
0342 {
0343     return ar5312_cpu_frequency() / 4;
0344 }
0345 
0346 void __init ar5312_plat_time_init(void)
0347 {
0348     mips_hpt_frequency = ar5312_cpu_frequency() / 2;
0349 }
0350 
0351 void __init ar5312_plat_mem_setup(void)
0352 {
0353     void __iomem *sdram_base;
0354     u32 memsize, memcfg, bank0_ac, bank1_ac;
0355     u32 devid;
0356 
0357     /* Detect memory size */
0358     sdram_base = ioremap(AR5312_SDRAMCTL_BASE,
0359                      AR5312_SDRAMCTL_SIZE);
0360     memcfg = __raw_readl(sdram_base + AR5312_MEM_CFG1);
0361     bank0_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC0);
0362     bank1_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC1);
0363     memsize = (bank0_ac ? (1 << (bank0_ac + 1)) : 0) +
0364           (bank1_ac ? (1 << (bank1_ac + 1)) : 0);
0365     memsize <<= 20;
0366     memblock_add(0, memsize);
0367     iounmap(sdram_base);
0368 
0369     ar5312_rst_base = ioremap(AR5312_RST_BASE, AR5312_RST_SIZE);
0370 
0371     devid = ar5312_rst_reg_read(AR5312_REV);
0372     devid >>= AR5312_REV_WMAC_MIN_S;
0373     devid &= AR5312_REV_CHIP;
0374     ath25_board.devid = (u16)devid;
0375 
0376     /* Clear any lingering AHB errors */
0377     ar5312_rst_reg_read(AR5312_PROCADDR);
0378     ar5312_rst_reg_read(AR5312_DMAADDR);
0379     ar5312_rst_reg_write(AR5312_WDT_CTRL, AR5312_WDT_CTRL_IGNORE);
0380 
0381     _machine_restart = ar5312_restart;
0382 }
0383 
0384 void __init ar5312_arch_init(void)
0385 {
0386     unsigned irq = irq_create_mapping(ar5312_misc_irq_domain,
0387                       AR5312_MISC_IRQ_UART0);
0388 
0389     ath25_serial_setup(AR5312_UART0_BASE, irq, ar5312_sys_frequency());
0390 }