Commit 3ed7a2a7 authored by Sergey Ryazanov's avatar Sergey Ryazanov Committed by Ralf Baechle

MIPS: ath25: add AR2315 PCI host controller driver

Add PCI host controller driver and DMA address calculation hook.
Signed-off-by: default avatarSergey Ryazanov <ryazanov.s.a@gmail.com>
Cc: Linux MIPS <linux-mips@linux-mips.org>
Patchwork: https://patchwork.linux-mips.org/patch/8246/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent d58eaa7f
...@@ -7,3 +7,10 @@ config SOC_AR2315 ...@@ -7,3 +7,10 @@ config SOC_AR2315
bool "Atheros AR2315+ SoC support" bool "Atheros AR2315+ SoC support"
depends on ATH25 depends on ATH25
default y default y
config PCI_AR2315
bool "Atheros AR2315 PCI controller support"
depends on SOC_AR2315
select HW_HAS_PCI
select PCI
default y
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <asm/reboot.h> #include <asm/reboot.h>
...@@ -133,6 +134,10 @@ static void ar2315_irq_dispatch(void) ...@@ -133,6 +134,10 @@ static void ar2315_irq_dispatch(void)
if (pending & CAUSEF_IP3) if (pending & CAUSEF_IP3)
do_IRQ(AR2315_IRQ_WLAN0); do_IRQ(AR2315_IRQ_WLAN0);
#ifdef CONFIG_PCI_AR2315
else if (pending & CAUSEF_IP5)
do_IRQ(AR2315_IRQ_LCBUS_PCI);
#endif
else if (pending & CAUSEF_IP2) else if (pending & CAUSEF_IP2)
do_IRQ(AR2315_IRQ_MISC); do_IRQ(AR2315_IRQ_MISC);
else if (pending & CAUSEF_IP7) else if (pending & CAUSEF_IP7)
...@@ -296,10 +301,62 @@ void __init ar2315_plat_mem_setup(void) ...@@ -296,10 +301,62 @@ void __init ar2315_plat_mem_setup(void)
_machine_restart = ar2315_restart; _machine_restart = ar2315_restart;
} }
#ifdef CONFIG_PCI_AR2315
static struct resource ar2315_pci_res[] = {
{
.name = "ar2315-pci-ctrl",
.flags = IORESOURCE_MEM,
.start = AR2315_PCI_BASE,
.end = AR2315_PCI_BASE + AR2315_PCI_SIZE - 1,
},
{
.name = "ar2315-pci-ext",
.flags = IORESOURCE_MEM,
.start = AR2315_PCI_EXT_BASE,
.end = AR2315_PCI_EXT_BASE + AR2315_PCI_EXT_SIZE - 1,
},
{
.name = "ar2315-pci",
.flags = IORESOURCE_IRQ,
.start = AR2315_IRQ_LCBUS_PCI,
.end = AR2315_IRQ_LCBUS_PCI,
},
};
#endif
void __init ar2315_arch_init(void) void __init ar2315_arch_init(void)
{ {
unsigned irq = irq_create_mapping(ar2315_misc_irq_domain, unsigned irq = irq_create_mapping(ar2315_misc_irq_domain,
AR2315_MISC_IRQ_UART0); AR2315_MISC_IRQ_UART0);
ath25_serial_setup(AR2315_UART0_BASE, irq, ar2315_apb_frequency()); ath25_serial_setup(AR2315_UART0_BASE, irq, ar2315_apb_frequency());
#ifdef CONFIG_PCI_AR2315
if (ath25_soc == ATH25_SOC_AR2315) {
/* Reset PCI DMA logic */
ar2315_rst_reg_mask(AR2315_RESET, 0, AR2315_RESET_PCIDMA);
msleep(20);
ar2315_rst_reg_mask(AR2315_RESET, AR2315_RESET_PCIDMA, 0);
msleep(20);
/* Configure endians */
ar2315_rst_reg_mask(AR2315_ENDIAN_CTL, 0, AR2315_CONFIG_PCIAHB |
AR2315_CONFIG_PCIAHB_BRIDGE);
/* Configure as PCI host with DMA */
ar2315_rst_reg_write(AR2315_PCICLK, AR2315_PCICLK_PLLC_CLKM |
(AR2315_PCICLK_IN_FREQ_DIV_6 <<
AR2315_PCICLK_DIV_S));
ar2315_rst_reg_mask(AR2315_AHB_ARB_CTL, 0, AR2315_ARB_PCI);
ar2315_rst_reg_mask(AR2315_IF_CTL, AR2315_IF_PCI_CLK_MASK |
AR2315_IF_MASK, AR2315_IF_PCI |
AR2315_IF_PCI_HOST | AR2315_IF_PCI_INTR |
(AR2315_IF_PCI_CLK_OUTPUT_CLK <<
AR2315_IF_PCI_CLK_SHIFT));
platform_device_register_simple("ar2315-pci", -1,
ar2315_pci_res,
ARRAY_SIZE(ar2315_pci_res));
}
#endif
} }
...@@ -12,22 +12,40 @@ ...@@ -12,22 +12,40 @@
#include <linux/device.h> #include <linux/device.h>
/*
* We need some arbitrary non-zero value to be programmed to the BAR1 register
* of PCI host controller to enable DMA. The same value should be used as the
* offset to calculate the physical address of DMA buffer for PCI devices.
*/
#define AR2315_PCI_HOST_SDRAM_BASEADDR 0x20000000
static inline dma_addr_t ath25_dev_offset(struct device *dev)
{
#ifdef CONFIG_PCI
extern struct bus_type pci_bus_type;
if (dev && dev->bus == &pci_bus_type)
return AR2315_PCI_HOST_SDRAM_BASEADDR;
#endif
return 0;
}
static inline dma_addr_t static inline dma_addr_t
plat_map_dma_mem(struct device *dev, void *addr, size_t size) plat_map_dma_mem(struct device *dev, void *addr, size_t size)
{ {
return virt_to_phys(addr); return virt_to_phys(addr) + ath25_dev_offset(dev);
} }
static inline dma_addr_t static inline dma_addr_t
plat_map_dma_mem_page(struct device *dev, struct page *page) plat_map_dma_mem_page(struct device *dev, struct page *page)
{ {
return page_to_phys(page); return page_to_phys(page) + ath25_dev_offset(dev);
} }
static inline unsigned long static inline unsigned long
plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr)
{ {
return dma_addr; return dma_addr - ath25_dev_offset(dev);
} }
static inline void static inline void
......
...@@ -19,6 +19,7 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o ...@@ -19,6 +19,7 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
ops-bcm63xx.o ops-bcm63xx.o
obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o
obj-$(CONFIG_PCI_AR2315) += pci-ar2315.o
obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o
obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o
obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment