18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 38c2ecf20Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 48c2ecf20Sopenharmony_ci * for more details. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. 78c2ecf20Sopenharmony_ci * Copyright (C) 2006 FON Technology, SL. 88c2ecf20Sopenharmony_ci * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> 98c2ecf20Sopenharmony_ci * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> 108c2ecf20Sopenharmony_ci * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com> 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/* 148c2ecf20Sopenharmony_ci * Platform devices for Atheros AR2315 SoCs 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <linux/init.h> 188c2ecf20Sopenharmony_ci#include <linux/kernel.h> 198c2ecf20Sopenharmony_ci#include <linux/bitops.h> 208c2ecf20Sopenharmony_ci#include <linux/irqdomain.h> 218c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 228c2ecf20Sopenharmony_ci#include <linux/memblock.h> 238c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 248c2ecf20Sopenharmony_ci#include <linux/reboot.h> 258c2ecf20Sopenharmony_ci#include <asm/bootinfo.h> 268c2ecf20Sopenharmony_ci#include <asm/reboot.h> 278c2ecf20Sopenharmony_ci#include <asm/time.h> 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#include <ath25_platform.h> 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#include "devices.h" 328c2ecf20Sopenharmony_ci#include "ar2315.h" 338c2ecf20Sopenharmony_ci#include "ar2315_regs.h" 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic void __iomem *ar2315_rst_base; 368c2ecf20Sopenharmony_cistatic struct irq_domain *ar2315_misc_irq_domain; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistatic inline u32 ar2315_rst_reg_read(u32 reg) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci return __raw_readl(ar2315_rst_base + reg); 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistatic inline void ar2315_rst_reg_write(u32 reg, u32 val) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci __raw_writel(val, ar2315_rst_base + reg); 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic inline void ar2315_rst_reg_mask(u32 reg, u32 mask, u32 val) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci u32 ret = ar2315_rst_reg_read(reg); 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci ret &= ~mask; 538c2ecf20Sopenharmony_ci ret |= val; 548c2ecf20Sopenharmony_ci ar2315_rst_reg_write(reg, ret); 558c2ecf20Sopenharmony_ci} 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic irqreturn_t ar2315_ahb_err_handler(int cpl, void *dev_id) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET); 608c2ecf20Sopenharmony_ci ar2315_rst_reg_read(AR2315_AHB_ERR1); 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci pr_emerg("AHB fatal error\n"); 638c2ecf20Sopenharmony_ci machine_restart("AHB error"); /* Catastrophic failure */ 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci return IRQ_HANDLED; 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistatic void ar2315_misc_irq_handler(struct irq_desc *desc) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci u32 pending = ar2315_rst_reg_read(AR2315_ISR) & 718c2ecf20Sopenharmony_ci ar2315_rst_reg_read(AR2315_IMR); 728c2ecf20Sopenharmony_ci unsigned nr, misc_irq = 0; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci if (pending) { 758c2ecf20Sopenharmony_ci struct irq_domain *domain = irq_desc_get_handler_data(desc); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci nr = __ffs(pending); 788c2ecf20Sopenharmony_ci misc_irq = irq_find_mapping(domain, nr); 798c2ecf20Sopenharmony_ci } 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci if (misc_irq) { 828c2ecf20Sopenharmony_ci if (nr == AR2315_MISC_IRQ_GPIO) 838c2ecf20Sopenharmony_ci ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_GPIO); 848c2ecf20Sopenharmony_ci else if (nr == AR2315_MISC_IRQ_WATCHDOG) 858c2ecf20Sopenharmony_ci ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_WD); 868c2ecf20Sopenharmony_ci generic_handle_irq(misc_irq); 878c2ecf20Sopenharmony_ci } else { 888c2ecf20Sopenharmony_ci spurious_interrupt(); 898c2ecf20Sopenharmony_ci } 908c2ecf20Sopenharmony_ci} 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cistatic void ar2315_misc_irq_unmask(struct irq_data *d) 938c2ecf20Sopenharmony_ci{ 948c2ecf20Sopenharmony_ci ar2315_rst_reg_mask(AR2315_IMR, 0, BIT(d->hwirq)); 958c2ecf20Sopenharmony_ci} 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_cistatic void ar2315_misc_irq_mask(struct irq_data *d) 988c2ecf20Sopenharmony_ci{ 998c2ecf20Sopenharmony_ci ar2315_rst_reg_mask(AR2315_IMR, BIT(d->hwirq), 0); 1008c2ecf20Sopenharmony_ci} 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_cistatic struct irq_chip ar2315_misc_irq_chip = { 1038c2ecf20Sopenharmony_ci .name = "ar2315-misc", 1048c2ecf20Sopenharmony_ci .irq_unmask = ar2315_misc_irq_unmask, 1058c2ecf20Sopenharmony_ci .irq_mask = ar2315_misc_irq_mask, 1068c2ecf20Sopenharmony_ci}; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistatic int ar2315_misc_irq_map(struct irq_domain *d, unsigned irq, 1098c2ecf20Sopenharmony_ci irq_hw_number_t hw) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci irq_set_chip_and_handler(irq, &ar2315_misc_irq_chip, handle_level_irq); 1128c2ecf20Sopenharmony_ci return 0; 1138c2ecf20Sopenharmony_ci} 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cistatic struct irq_domain_ops ar2315_misc_irq_domain_ops = { 1168c2ecf20Sopenharmony_ci .map = ar2315_misc_irq_map, 1178c2ecf20Sopenharmony_ci}; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci/* 1208c2ecf20Sopenharmony_ci * Called when an interrupt is received, this function 1218c2ecf20Sopenharmony_ci * determines exactly which interrupt it was, and it 1228c2ecf20Sopenharmony_ci * invokes the appropriate handler. 1238c2ecf20Sopenharmony_ci * 1248c2ecf20Sopenharmony_ci * Implicitly, we also define interrupt priority by 1258c2ecf20Sopenharmony_ci * choosing which to dispatch first. 1268c2ecf20Sopenharmony_ci */ 1278c2ecf20Sopenharmony_cistatic void ar2315_irq_dispatch(void) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci u32 pending = read_c0_status() & read_c0_cause(); 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci if (pending & CAUSEF_IP3) 1328c2ecf20Sopenharmony_ci do_IRQ(AR2315_IRQ_WLAN0); 1338c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_AR2315 1348c2ecf20Sopenharmony_ci else if (pending & CAUSEF_IP5) 1358c2ecf20Sopenharmony_ci do_IRQ(AR2315_IRQ_LCBUS_PCI); 1368c2ecf20Sopenharmony_ci#endif 1378c2ecf20Sopenharmony_ci else if (pending & CAUSEF_IP2) 1388c2ecf20Sopenharmony_ci do_IRQ(AR2315_IRQ_MISC); 1398c2ecf20Sopenharmony_ci else if (pending & CAUSEF_IP7) 1408c2ecf20Sopenharmony_ci do_IRQ(ATH25_IRQ_CPU_CLOCK); 1418c2ecf20Sopenharmony_ci else 1428c2ecf20Sopenharmony_ci spurious_interrupt(); 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_civoid __init ar2315_arch_init_irq(void) 1468c2ecf20Sopenharmony_ci{ 1478c2ecf20Sopenharmony_ci struct irq_domain *domain; 1488c2ecf20Sopenharmony_ci unsigned irq; 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci ath25_irq_dispatch = ar2315_irq_dispatch; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci domain = irq_domain_add_linear(NULL, AR2315_MISC_IRQ_COUNT, 1538c2ecf20Sopenharmony_ci &ar2315_misc_irq_domain_ops, NULL); 1548c2ecf20Sopenharmony_ci if (!domain) 1558c2ecf20Sopenharmony_ci panic("Failed to add IRQ domain"); 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci irq = irq_create_mapping(domain, AR2315_MISC_IRQ_AHB); 1588c2ecf20Sopenharmony_ci if (request_irq(irq, ar2315_ahb_err_handler, 0, "ar2315-ahb-error", 1598c2ecf20Sopenharmony_ci NULL)) 1608c2ecf20Sopenharmony_ci pr_err("Failed to register ar2315-ahb-error interrupt\n"); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci irq_set_chained_handler_and_data(AR2315_IRQ_MISC, 1638c2ecf20Sopenharmony_ci ar2315_misc_irq_handler, domain); 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci ar2315_misc_irq_domain = domain; 1668c2ecf20Sopenharmony_ci} 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_civoid __init ar2315_init_devices(void) 1698c2ecf20Sopenharmony_ci{ 1708c2ecf20Sopenharmony_ci /* Find board configuration */ 1718c2ecf20Sopenharmony_ci ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci ath25_add_wmac(0, AR2315_WLAN0_BASE, AR2315_IRQ_WLAN0); 1748c2ecf20Sopenharmony_ci} 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_cistatic void ar2315_restart(char *command) 1778c2ecf20Sopenharmony_ci{ 1788c2ecf20Sopenharmony_ci void (*mips_reset_vec)(void) = (void *)0xbfc00000; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci local_irq_disable(); 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci /* try reset the system via reset control */ 1838c2ecf20Sopenharmony_ci ar2315_rst_reg_write(AR2315_COLD_RESET, AR2317_RESET_SYSTEM); 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci /* Cold reset does not work on the AR2315/6, use the GPIO reset bits 1868c2ecf20Sopenharmony_ci * a workaround. Give it some time to attempt a gpio based hardware 1878c2ecf20Sopenharmony_ci * reset (atheros reference design workaround) */ 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci /* TODO: implement the GPIO reset workaround */ 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci /* Some boards (e.g. Senao EOC-2610) don't implement the reset logic 1928c2ecf20Sopenharmony_ci * workaround. Attempt to jump to the mips reset location - 1938c2ecf20Sopenharmony_ci * the boot loader itself might be able to recover the system */ 1948c2ecf20Sopenharmony_ci mips_reset_vec(); 1958c2ecf20Sopenharmony_ci} 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci/* 1988c2ecf20Sopenharmony_ci * This table is indexed by bits 5..4 of the CLOCKCTL1 register 1998c2ecf20Sopenharmony_ci * to determine the predevisor value. 2008c2ecf20Sopenharmony_ci */ 2018c2ecf20Sopenharmony_cistatic int clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 }; 2028c2ecf20Sopenharmony_cistatic int pllc_divide_table[5] __initdata = { 2, 3, 4, 6, 3 }; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cistatic unsigned __init ar2315_sys_clk(u32 clock_ctl) 2058c2ecf20Sopenharmony_ci{ 2068c2ecf20Sopenharmony_ci unsigned int pllc_ctrl, cpu_div; 2078c2ecf20Sopenharmony_ci unsigned int pllc_out, refdiv, fdiv, divby2; 2088c2ecf20Sopenharmony_ci unsigned int clk_div; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci pllc_ctrl = ar2315_rst_reg_read(AR2315_PLLC_CTL); 2118c2ecf20Sopenharmony_ci refdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_REF_DIV); 2128c2ecf20Sopenharmony_ci refdiv = clockctl1_predivide_table[refdiv]; 2138c2ecf20Sopenharmony_ci fdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_FDBACK_DIV); 2148c2ecf20Sopenharmony_ci divby2 = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_ADD_FDBACK_DIV) + 1; 2158c2ecf20Sopenharmony_ci pllc_out = (40000000 / refdiv) * (2 * divby2) * fdiv; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci /* clkm input selected */ 2188c2ecf20Sopenharmony_ci switch (clock_ctl & AR2315_CPUCLK_CLK_SEL_M) { 2198c2ecf20Sopenharmony_ci case 0: 2208c2ecf20Sopenharmony_ci case 1: 2218c2ecf20Sopenharmony_ci clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKM_DIV); 2228c2ecf20Sopenharmony_ci clk_div = pllc_divide_table[clk_div]; 2238c2ecf20Sopenharmony_ci break; 2248c2ecf20Sopenharmony_ci case 2: 2258c2ecf20Sopenharmony_ci clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKC_DIV); 2268c2ecf20Sopenharmony_ci clk_div = pllc_divide_table[clk_div]; 2278c2ecf20Sopenharmony_ci break; 2288c2ecf20Sopenharmony_ci default: 2298c2ecf20Sopenharmony_ci pllc_out = 40000000; 2308c2ecf20Sopenharmony_ci clk_div = 1; 2318c2ecf20Sopenharmony_ci break; 2328c2ecf20Sopenharmony_ci } 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci cpu_div = ATH25_REG_MS(clock_ctl, AR2315_CPUCLK_CLK_DIV); 2358c2ecf20Sopenharmony_ci cpu_div = cpu_div * 2 ?: 1; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci return pllc_out / (clk_div * cpu_div); 2388c2ecf20Sopenharmony_ci} 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_cistatic inline unsigned ar2315_cpu_frequency(void) 2418c2ecf20Sopenharmony_ci{ 2428c2ecf20Sopenharmony_ci return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_CPUCLK)); 2438c2ecf20Sopenharmony_ci} 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_cistatic inline unsigned ar2315_apb_frequency(void) 2468c2ecf20Sopenharmony_ci{ 2478c2ecf20Sopenharmony_ci return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_AMBACLK)); 2488c2ecf20Sopenharmony_ci} 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_civoid __init ar2315_plat_time_init(void) 2518c2ecf20Sopenharmony_ci{ 2528c2ecf20Sopenharmony_ci mips_hpt_frequency = ar2315_cpu_frequency() / 2; 2538c2ecf20Sopenharmony_ci} 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_civoid __init ar2315_plat_mem_setup(void) 2568c2ecf20Sopenharmony_ci{ 2578c2ecf20Sopenharmony_ci void __iomem *sdram_base; 2588c2ecf20Sopenharmony_ci u32 memsize, memcfg; 2598c2ecf20Sopenharmony_ci u32 devid; 2608c2ecf20Sopenharmony_ci u32 config; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci /* Detect memory size */ 2638c2ecf20Sopenharmony_ci sdram_base = ioremap(AR2315_SDRAMCTL_BASE, 2648c2ecf20Sopenharmony_ci AR2315_SDRAMCTL_SIZE); 2658c2ecf20Sopenharmony_ci memcfg = __raw_readl(sdram_base + AR2315_MEM_CFG); 2668c2ecf20Sopenharmony_ci memsize = 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_DATA_WIDTH); 2678c2ecf20Sopenharmony_ci memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_COL_WIDTH); 2688c2ecf20Sopenharmony_ci memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_ROW_WIDTH); 2698c2ecf20Sopenharmony_ci memsize <<= 3; 2708c2ecf20Sopenharmony_ci memblock_add(0, memsize); 2718c2ecf20Sopenharmony_ci iounmap(sdram_base); 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci ar2315_rst_base = ioremap(AR2315_RST_BASE, AR2315_RST_SIZE); 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci /* Detect the hardware based on the device ID */ 2768c2ecf20Sopenharmony_ci devid = ar2315_rst_reg_read(AR2315_SREV) & AR2315_REV_CHIP; 2778c2ecf20Sopenharmony_ci switch (devid) { 2788c2ecf20Sopenharmony_ci case 0x91: /* Need to check */ 2798c2ecf20Sopenharmony_ci ath25_soc = ATH25_SOC_AR2318; 2808c2ecf20Sopenharmony_ci break; 2818c2ecf20Sopenharmony_ci case 0x90: 2828c2ecf20Sopenharmony_ci ath25_soc = ATH25_SOC_AR2317; 2838c2ecf20Sopenharmony_ci break; 2848c2ecf20Sopenharmony_ci case 0x87: 2858c2ecf20Sopenharmony_ci ath25_soc = ATH25_SOC_AR2316; 2868c2ecf20Sopenharmony_ci break; 2878c2ecf20Sopenharmony_ci case 0x86: 2888c2ecf20Sopenharmony_ci default: 2898c2ecf20Sopenharmony_ci ath25_soc = ATH25_SOC_AR2315; 2908c2ecf20Sopenharmony_ci break; 2918c2ecf20Sopenharmony_ci } 2928c2ecf20Sopenharmony_ci ath25_board.devid = devid; 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci /* Clear any lingering AHB errors */ 2958c2ecf20Sopenharmony_ci config = read_c0_config(); 2968c2ecf20Sopenharmony_ci write_c0_config(config & ~0x3); 2978c2ecf20Sopenharmony_ci ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET); 2988c2ecf20Sopenharmony_ci ar2315_rst_reg_read(AR2315_AHB_ERR1); 2998c2ecf20Sopenharmony_ci ar2315_rst_reg_write(AR2315_WDT_CTRL, AR2315_WDT_CTRL_IGNORE); 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci _machine_restart = ar2315_restart; 3028c2ecf20Sopenharmony_ci} 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_AR2315 3058c2ecf20Sopenharmony_cistatic struct resource ar2315_pci_res[] = { 3068c2ecf20Sopenharmony_ci { 3078c2ecf20Sopenharmony_ci .name = "ar2315-pci-ctrl", 3088c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 3098c2ecf20Sopenharmony_ci .start = AR2315_PCI_BASE, 3108c2ecf20Sopenharmony_ci .end = AR2315_PCI_BASE + AR2315_PCI_SIZE - 1, 3118c2ecf20Sopenharmony_ci }, 3128c2ecf20Sopenharmony_ci { 3138c2ecf20Sopenharmony_ci .name = "ar2315-pci-ext", 3148c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 3158c2ecf20Sopenharmony_ci .start = AR2315_PCI_EXT_BASE, 3168c2ecf20Sopenharmony_ci .end = AR2315_PCI_EXT_BASE + AR2315_PCI_EXT_SIZE - 1, 3178c2ecf20Sopenharmony_ci }, 3188c2ecf20Sopenharmony_ci { 3198c2ecf20Sopenharmony_ci .name = "ar2315-pci", 3208c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 3218c2ecf20Sopenharmony_ci .start = AR2315_IRQ_LCBUS_PCI, 3228c2ecf20Sopenharmony_ci .end = AR2315_IRQ_LCBUS_PCI, 3238c2ecf20Sopenharmony_ci }, 3248c2ecf20Sopenharmony_ci}; 3258c2ecf20Sopenharmony_ci#endif 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_civoid __init ar2315_arch_init(void) 3288c2ecf20Sopenharmony_ci{ 3298c2ecf20Sopenharmony_ci unsigned irq = irq_create_mapping(ar2315_misc_irq_domain, 3308c2ecf20Sopenharmony_ci AR2315_MISC_IRQ_UART0); 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci ath25_serial_setup(AR2315_UART0_BASE, irq, ar2315_apb_frequency()); 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_AR2315 3358c2ecf20Sopenharmony_ci if (ath25_soc == ATH25_SOC_AR2315) { 3368c2ecf20Sopenharmony_ci /* Reset PCI DMA logic */ 3378c2ecf20Sopenharmony_ci ar2315_rst_reg_mask(AR2315_RESET, 0, AR2315_RESET_PCIDMA); 3388c2ecf20Sopenharmony_ci msleep(20); 3398c2ecf20Sopenharmony_ci ar2315_rst_reg_mask(AR2315_RESET, AR2315_RESET_PCIDMA, 0); 3408c2ecf20Sopenharmony_ci msleep(20); 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci /* Configure endians */ 3438c2ecf20Sopenharmony_ci ar2315_rst_reg_mask(AR2315_ENDIAN_CTL, 0, AR2315_CONFIG_PCIAHB | 3448c2ecf20Sopenharmony_ci AR2315_CONFIG_PCIAHB_BRIDGE); 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci /* Configure as PCI host with DMA */ 3478c2ecf20Sopenharmony_ci ar2315_rst_reg_write(AR2315_PCICLK, AR2315_PCICLK_PLLC_CLKM | 3488c2ecf20Sopenharmony_ci (AR2315_PCICLK_IN_FREQ_DIV_6 << 3498c2ecf20Sopenharmony_ci AR2315_PCICLK_DIV_S)); 3508c2ecf20Sopenharmony_ci ar2315_rst_reg_mask(AR2315_AHB_ARB_CTL, 0, AR2315_ARB_PCI); 3518c2ecf20Sopenharmony_ci ar2315_rst_reg_mask(AR2315_IF_CTL, AR2315_IF_PCI_CLK_MASK | 3528c2ecf20Sopenharmony_ci AR2315_IF_MASK, AR2315_IF_PCI | 3538c2ecf20Sopenharmony_ci AR2315_IF_PCI_HOST | AR2315_IF_PCI_INTR | 3548c2ecf20Sopenharmony_ci (AR2315_IF_PCI_CLK_OUTPUT_CLK << 3558c2ecf20Sopenharmony_ci AR2315_IF_PCI_CLK_SHIFT)); 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci platform_device_register_simple("ar2315-pci", -1, 3588c2ecf20Sopenharmony_ci ar2315_pci_res, 3598c2ecf20Sopenharmony_ci ARRAY_SIZE(ar2315_pci_res)); 3608c2ecf20Sopenharmony_ci } 3618c2ecf20Sopenharmony_ci#endif 3628c2ecf20Sopenharmony_ci} 363