162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 362306a36Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 462306a36Sopenharmony_ci * for more details. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. 762306a36Sopenharmony_ci * Copyright (C) 2006 FON Technology, SL. 862306a36Sopenharmony_ci * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> 962306a36Sopenharmony_ci * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> 1062306a36Sopenharmony_ci * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com> 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* 1462306a36Sopenharmony_ci * Platform devices for Atheros AR2315 SoCs 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include <linux/init.h> 1862306a36Sopenharmony_ci#include <linux/kernel.h> 1962306a36Sopenharmony_ci#include <linux/bitops.h> 2062306a36Sopenharmony_ci#include <linux/irqdomain.h> 2162306a36Sopenharmony_ci#include <linux/interrupt.h> 2262306a36Sopenharmony_ci#include <linux/memblock.h> 2362306a36Sopenharmony_ci#include <linux/platform_device.h> 2462306a36Sopenharmony_ci#include <linux/reboot.h> 2562306a36Sopenharmony_ci#include <asm/bootinfo.h> 2662306a36Sopenharmony_ci#include <asm/reboot.h> 2762306a36Sopenharmony_ci#include <asm/time.h> 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#include <ath25_platform.h> 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#include "devices.h" 3262306a36Sopenharmony_ci#include "ar2315.h" 3362306a36Sopenharmony_ci#include "ar2315_regs.h" 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic void __iomem *ar2315_rst_base; 3662306a36Sopenharmony_cistatic struct irq_domain *ar2315_misc_irq_domain; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic inline u32 ar2315_rst_reg_read(u32 reg) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci return __raw_readl(ar2315_rst_base + reg); 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic inline void ar2315_rst_reg_write(u32 reg, u32 val) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci __raw_writel(val, ar2315_rst_base + reg); 4662306a36Sopenharmony_ci} 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistatic inline void ar2315_rst_reg_mask(u32 reg, u32 mask, u32 val) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci u32 ret = ar2315_rst_reg_read(reg); 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci ret &= ~mask; 5362306a36Sopenharmony_ci ret |= val; 5462306a36Sopenharmony_ci ar2315_rst_reg_write(reg, ret); 5562306a36Sopenharmony_ci} 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_cistatic irqreturn_t ar2315_ahb_err_handler(int cpl, void *dev_id) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET); 6062306a36Sopenharmony_ci ar2315_rst_reg_read(AR2315_AHB_ERR1); 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci pr_emerg("AHB fatal error\n"); 6362306a36Sopenharmony_ci machine_restart("AHB error"); /* Catastrophic failure */ 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci return IRQ_HANDLED; 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cistatic void ar2315_misc_irq_handler(struct irq_desc *desc) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci u32 pending = ar2315_rst_reg_read(AR2315_ISR) & 7162306a36Sopenharmony_ci ar2315_rst_reg_read(AR2315_IMR); 7262306a36Sopenharmony_ci unsigned nr; 7362306a36Sopenharmony_ci int ret = 0; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci if (pending) { 7662306a36Sopenharmony_ci struct irq_domain *domain = irq_desc_get_handler_data(desc); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci nr = __ffs(pending); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci if (nr == AR2315_MISC_IRQ_GPIO) 8162306a36Sopenharmony_ci ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_GPIO); 8262306a36Sopenharmony_ci else if (nr == AR2315_MISC_IRQ_WATCHDOG) 8362306a36Sopenharmony_ci ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_WD); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci ret = generic_handle_domain_irq(domain, nr); 8662306a36Sopenharmony_ci } 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci if (!pending || ret) 8962306a36Sopenharmony_ci spurious_interrupt(); 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cistatic void ar2315_misc_irq_unmask(struct irq_data *d) 9362306a36Sopenharmony_ci{ 9462306a36Sopenharmony_ci ar2315_rst_reg_mask(AR2315_IMR, 0, BIT(d->hwirq)); 9562306a36Sopenharmony_ci} 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cistatic void ar2315_misc_irq_mask(struct irq_data *d) 9862306a36Sopenharmony_ci{ 9962306a36Sopenharmony_ci ar2315_rst_reg_mask(AR2315_IMR, BIT(d->hwirq), 0); 10062306a36Sopenharmony_ci} 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistatic struct irq_chip ar2315_misc_irq_chip = { 10362306a36Sopenharmony_ci .name = "ar2315-misc", 10462306a36Sopenharmony_ci .irq_unmask = ar2315_misc_irq_unmask, 10562306a36Sopenharmony_ci .irq_mask = ar2315_misc_irq_mask, 10662306a36Sopenharmony_ci}; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic int ar2315_misc_irq_map(struct irq_domain *d, unsigned irq, 10962306a36Sopenharmony_ci irq_hw_number_t hw) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci irq_set_chip_and_handler(irq, &ar2315_misc_irq_chip, handle_level_irq); 11262306a36Sopenharmony_ci return 0; 11362306a36Sopenharmony_ci} 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_cistatic const struct irq_domain_ops ar2315_misc_irq_domain_ops = { 11662306a36Sopenharmony_ci .map = ar2315_misc_irq_map, 11762306a36Sopenharmony_ci}; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci/* 12062306a36Sopenharmony_ci * Called when an interrupt is received, this function 12162306a36Sopenharmony_ci * determines exactly which interrupt it was, and it 12262306a36Sopenharmony_ci * invokes the appropriate handler. 12362306a36Sopenharmony_ci * 12462306a36Sopenharmony_ci * Implicitly, we also define interrupt priority by 12562306a36Sopenharmony_ci * choosing which to dispatch first. 12662306a36Sopenharmony_ci */ 12762306a36Sopenharmony_cistatic void ar2315_irq_dispatch(void) 12862306a36Sopenharmony_ci{ 12962306a36Sopenharmony_ci u32 pending = read_c0_status() & read_c0_cause(); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci if (pending & CAUSEF_IP3) 13262306a36Sopenharmony_ci do_IRQ(AR2315_IRQ_WLAN0); 13362306a36Sopenharmony_ci#ifdef CONFIG_PCI_AR2315 13462306a36Sopenharmony_ci else if (pending & CAUSEF_IP5) 13562306a36Sopenharmony_ci do_IRQ(AR2315_IRQ_LCBUS_PCI); 13662306a36Sopenharmony_ci#endif 13762306a36Sopenharmony_ci else if (pending & CAUSEF_IP2) 13862306a36Sopenharmony_ci do_IRQ(AR2315_IRQ_MISC); 13962306a36Sopenharmony_ci else if (pending & CAUSEF_IP7) 14062306a36Sopenharmony_ci do_IRQ(ATH25_IRQ_CPU_CLOCK); 14162306a36Sopenharmony_ci else 14262306a36Sopenharmony_ci spurious_interrupt(); 14362306a36Sopenharmony_ci} 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_civoid __init ar2315_arch_init_irq(void) 14662306a36Sopenharmony_ci{ 14762306a36Sopenharmony_ci struct irq_domain *domain; 14862306a36Sopenharmony_ci unsigned irq; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci ath25_irq_dispatch = ar2315_irq_dispatch; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci domain = irq_domain_add_linear(NULL, AR2315_MISC_IRQ_COUNT, 15362306a36Sopenharmony_ci &ar2315_misc_irq_domain_ops, NULL); 15462306a36Sopenharmony_ci if (!domain) 15562306a36Sopenharmony_ci panic("Failed to add IRQ domain"); 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci irq = irq_create_mapping(domain, AR2315_MISC_IRQ_AHB); 15862306a36Sopenharmony_ci if (request_irq(irq, ar2315_ahb_err_handler, 0, "ar2315-ahb-error", 15962306a36Sopenharmony_ci NULL)) 16062306a36Sopenharmony_ci pr_err("Failed to register ar2315-ahb-error interrupt\n"); 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci irq_set_chained_handler_and_data(AR2315_IRQ_MISC, 16362306a36Sopenharmony_ci ar2315_misc_irq_handler, domain); 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci ar2315_misc_irq_domain = domain; 16662306a36Sopenharmony_ci} 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_civoid __init ar2315_init_devices(void) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci /* Find board configuration */ 17162306a36Sopenharmony_ci ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE); 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci ath25_add_wmac(0, AR2315_WLAN0_BASE, AR2315_IRQ_WLAN0); 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cistatic void ar2315_restart(char *command) 17762306a36Sopenharmony_ci{ 17862306a36Sopenharmony_ci void (*mips_reset_vec)(void) = (void *)0xbfc00000; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci local_irq_disable(); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci /* try reset the system via reset control */ 18362306a36Sopenharmony_ci ar2315_rst_reg_write(AR2315_COLD_RESET, AR2317_RESET_SYSTEM); 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci /* Cold reset does not work on the AR2315/6, use the GPIO reset bits 18662306a36Sopenharmony_ci * a workaround. Give it some time to attempt a gpio based hardware 18762306a36Sopenharmony_ci * reset (atheros reference design workaround) */ 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci /* TODO: implement the GPIO reset workaround */ 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci /* Some boards (e.g. Senao EOC-2610) don't implement the reset logic 19262306a36Sopenharmony_ci * workaround. Attempt to jump to the mips reset location - 19362306a36Sopenharmony_ci * the boot loader itself might be able to recover the system */ 19462306a36Sopenharmony_ci mips_reset_vec(); 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci/* 19862306a36Sopenharmony_ci * This table is indexed by bits 5..4 of the CLOCKCTL1 register 19962306a36Sopenharmony_ci * to determine the predevisor value. 20062306a36Sopenharmony_ci */ 20162306a36Sopenharmony_cistatic int clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 }; 20262306a36Sopenharmony_cistatic int pllc_divide_table[5] __initdata = { 2, 3, 4, 6, 3 }; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_cistatic unsigned __init ar2315_sys_clk(u32 clock_ctl) 20562306a36Sopenharmony_ci{ 20662306a36Sopenharmony_ci unsigned int pllc_ctrl, cpu_div; 20762306a36Sopenharmony_ci unsigned int pllc_out, refdiv, fdiv, divby2; 20862306a36Sopenharmony_ci unsigned int clk_div; 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci pllc_ctrl = ar2315_rst_reg_read(AR2315_PLLC_CTL); 21162306a36Sopenharmony_ci refdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_REF_DIV); 21262306a36Sopenharmony_ci refdiv = clockctl1_predivide_table[refdiv]; 21362306a36Sopenharmony_ci fdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_FDBACK_DIV); 21462306a36Sopenharmony_ci divby2 = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_ADD_FDBACK_DIV) + 1; 21562306a36Sopenharmony_ci pllc_out = (40000000 / refdiv) * (2 * divby2) * fdiv; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci /* clkm input selected */ 21862306a36Sopenharmony_ci switch (clock_ctl & AR2315_CPUCLK_CLK_SEL_M) { 21962306a36Sopenharmony_ci case 0: 22062306a36Sopenharmony_ci case 1: 22162306a36Sopenharmony_ci clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKM_DIV); 22262306a36Sopenharmony_ci clk_div = pllc_divide_table[clk_div]; 22362306a36Sopenharmony_ci break; 22462306a36Sopenharmony_ci case 2: 22562306a36Sopenharmony_ci clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKC_DIV); 22662306a36Sopenharmony_ci clk_div = pllc_divide_table[clk_div]; 22762306a36Sopenharmony_ci break; 22862306a36Sopenharmony_ci default: 22962306a36Sopenharmony_ci pllc_out = 40000000; 23062306a36Sopenharmony_ci clk_div = 1; 23162306a36Sopenharmony_ci break; 23262306a36Sopenharmony_ci } 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci cpu_div = ATH25_REG_MS(clock_ctl, AR2315_CPUCLK_CLK_DIV); 23562306a36Sopenharmony_ci cpu_div = cpu_div * 2 ?: 1; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci return pllc_out / (clk_div * cpu_div); 23862306a36Sopenharmony_ci} 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_cistatic inline unsigned ar2315_cpu_frequency(void) 24162306a36Sopenharmony_ci{ 24262306a36Sopenharmony_ci return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_CPUCLK)); 24362306a36Sopenharmony_ci} 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_cistatic inline unsigned ar2315_apb_frequency(void) 24662306a36Sopenharmony_ci{ 24762306a36Sopenharmony_ci return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_AMBACLK)); 24862306a36Sopenharmony_ci} 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_civoid __init ar2315_plat_time_init(void) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci mips_hpt_frequency = ar2315_cpu_frequency() / 2; 25362306a36Sopenharmony_ci} 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_civoid __init ar2315_plat_mem_setup(void) 25662306a36Sopenharmony_ci{ 25762306a36Sopenharmony_ci void __iomem *sdram_base; 25862306a36Sopenharmony_ci u32 memsize, memcfg; 25962306a36Sopenharmony_ci u32 devid; 26062306a36Sopenharmony_ci u32 config; 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci /* Detect memory size */ 26362306a36Sopenharmony_ci sdram_base = ioremap(AR2315_SDRAMCTL_BASE, 26462306a36Sopenharmony_ci AR2315_SDRAMCTL_SIZE); 26562306a36Sopenharmony_ci memcfg = __raw_readl(sdram_base + AR2315_MEM_CFG); 26662306a36Sopenharmony_ci memsize = 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_DATA_WIDTH); 26762306a36Sopenharmony_ci memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_COL_WIDTH); 26862306a36Sopenharmony_ci memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_ROW_WIDTH); 26962306a36Sopenharmony_ci memsize <<= 3; 27062306a36Sopenharmony_ci memblock_add(0, memsize); 27162306a36Sopenharmony_ci iounmap(sdram_base); 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci ar2315_rst_base = ioremap(AR2315_RST_BASE, AR2315_RST_SIZE); 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci /* Detect the hardware based on the device ID */ 27662306a36Sopenharmony_ci devid = ar2315_rst_reg_read(AR2315_SREV) & AR2315_REV_CHIP; 27762306a36Sopenharmony_ci switch (devid) { 27862306a36Sopenharmony_ci case 0x91: /* Need to check */ 27962306a36Sopenharmony_ci ath25_soc = ATH25_SOC_AR2318; 28062306a36Sopenharmony_ci break; 28162306a36Sopenharmony_ci case 0x90: 28262306a36Sopenharmony_ci ath25_soc = ATH25_SOC_AR2317; 28362306a36Sopenharmony_ci break; 28462306a36Sopenharmony_ci case 0x87: 28562306a36Sopenharmony_ci ath25_soc = ATH25_SOC_AR2316; 28662306a36Sopenharmony_ci break; 28762306a36Sopenharmony_ci case 0x86: 28862306a36Sopenharmony_ci default: 28962306a36Sopenharmony_ci ath25_soc = ATH25_SOC_AR2315; 29062306a36Sopenharmony_ci break; 29162306a36Sopenharmony_ci } 29262306a36Sopenharmony_ci ath25_board.devid = devid; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci /* Clear any lingering AHB errors */ 29562306a36Sopenharmony_ci config = read_c0_config(); 29662306a36Sopenharmony_ci write_c0_config(config & ~0x3); 29762306a36Sopenharmony_ci ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET); 29862306a36Sopenharmony_ci ar2315_rst_reg_read(AR2315_AHB_ERR1); 29962306a36Sopenharmony_ci ar2315_rst_reg_write(AR2315_WDT_CTRL, AR2315_WDT_CTRL_IGNORE); 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci _machine_restart = ar2315_restart; 30262306a36Sopenharmony_ci} 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci#ifdef CONFIG_PCI_AR2315 30562306a36Sopenharmony_cistatic struct resource ar2315_pci_res[] = { 30662306a36Sopenharmony_ci { 30762306a36Sopenharmony_ci .name = "ar2315-pci-ctrl", 30862306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 30962306a36Sopenharmony_ci .start = AR2315_PCI_BASE, 31062306a36Sopenharmony_ci .end = AR2315_PCI_BASE + AR2315_PCI_SIZE - 1, 31162306a36Sopenharmony_ci }, 31262306a36Sopenharmony_ci { 31362306a36Sopenharmony_ci .name = "ar2315-pci-ext", 31462306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 31562306a36Sopenharmony_ci .start = AR2315_PCI_EXT_BASE, 31662306a36Sopenharmony_ci .end = AR2315_PCI_EXT_BASE + AR2315_PCI_EXT_SIZE - 1, 31762306a36Sopenharmony_ci }, 31862306a36Sopenharmony_ci { 31962306a36Sopenharmony_ci .name = "ar2315-pci", 32062306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 32162306a36Sopenharmony_ci .start = AR2315_IRQ_LCBUS_PCI, 32262306a36Sopenharmony_ci .end = AR2315_IRQ_LCBUS_PCI, 32362306a36Sopenharmony_ci }, 32462306a36Sopenharmony_ci}; 32562306a36Sopenharmony_ci#endif 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_civoid __init ar2315_arch_init(void) 32862306a36Sopenharmony_ci{ 32962306a36Sopenharmony_ci unsigned irq = irq_create_mapping(ar2315_misc_irq_domain, 33062306a36Sopenharmony_ci AR2315_MISC_IRQ_UART0); 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci ath25_serial_setup(AR2315_UART0_BASE, irq, ar2315_apb_frequency()); 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci#ifdef CONFIG_PCI_AR2315 33562306a36Sopenharmony_ci if (ath25_soc == ATH25_SOC_AR2315) { 33662306a36Sopenharmony_ci /* Reset PCI DMA logic */ 33762306a36Sopenharmony_ci ar2315_rst_reg_mask(AR2315_RESET, 0, AR2315_RESET_PCIDMA); 33862306a36Sopenharmony_ci msleep(20); 33962306a36Sopenharmony_ci ar2315_rst_reg_mask(AR2315_RESET, AR2315_RESET_PCIDMA, 0); 34062306a36Sopenharmony_ci msleep(20); 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci /* Configure endians */ 34362306a36Sopenharmony_ci ar2315_rst_reg_mask(AR2315_ENDIAN_CTL, 0, AR2315_CONFIG_PCIAHB | 34462306a36Sopenharmony_ci AR2315_CONFIG_PCIAHB_BRIDGE); 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci /* Configure as PCI host with DMA */ 34762306a36Sopenharmony_ci ar2315_rst_reg_write(AR2315_PCICLK, AR2315_PCICLK_PLLC_CLKM | 34862306a36Sopenharmony_ci (AR2315_PCICLK_IN_FREQ_DIV_6 << 34962306a36Sopenharmony_ci AR2315_PCICLK_DIV_S)); 35062306a36Sopenharmony_ci ar2315_rst_reg_mask(AR2315_AHB_ARB_CTL, 0, AR2315_ARB_PCI); 35162306a36Sopenharmony_ci ar2315_rst_reg_mask(AR2315_IF_CTL, AR2315_IF_PCI_CLK_MASK | 35262306a36Sopenharmony_ci AR2315_IF_MASK, AR2315_IF_PCI | 35362306a36Sopenharmony_ci AR2315_IF_PCI_HOST | AR2315_IF_PCI_INTR | 35462306a36Sopenharmony_ci (AR2315_IF_PCI_CLK_OUTPUT_CLK << 35562306a36Sopenharmony_ci AR2315_IF_PCI_CLK_SHIFT)); 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci platform_device_register_simple("ar2315-pci", -1, 35862306a36Sopenharmony_ci ar2315_pci_res, 35962306a36Sopenharmony_ci ARRAY_SIZE(ar2315_pci_res)); 36062306a36Sopenharmony_ci } 36162306a36Sopenharmony_ci#endif 36262306a36Sopenharmony_ci} 363