Merge branch 'mips-next-3.9' of git://git.linux-mips.org/pub/scm/john/linux-john into mips-for-linux-next
This commit is contained in:
commit
8bfc245f9a
|
@ -0,0 +1,47 @@
|
|||
MIPS CPU interrupt controller
|
||||
|
||||
On MIPS the mips_cpu_intc_init() helper can be used to initialize the 8 CPU
|
||||
IRQs from a devicetree file and create a irq_domain for IRQ controller.
|
||||
|
||||
With the irq_domain in place we can describe how the 8 IRQs are wired to the
|
||||
platforms internal interrupt controller cascade.
|
||||
|
||||
Below is an example of a platform describing the cascade inside the devicetree
|
||||
and the code used to load it inside arch_init_irq().
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "mti,cpu-interrupt-controller"
|
||||
|
||||
Example devicetree:
|
||||
cpu-irq: cpu-irq@0 {
|
||||
#address-cells = <0>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
compatible = "mti,cpu-interrupt-controller";
|
||||
};
|
||||
|
||||
intc: intc@200 {
|
||||
compatible = "ralink,rt2880-intc";
|
||||
reg = <0x200 0x100>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interrupt-parent = <&cpu-irq>;
|
||||
interrupts = <2>;
|
||||
};
|
||||
|
||||
|
||||
Example platform irq.c:
|
||||
static struct of_device_id __initdata of_irq_ids[] = {
|
||||
{ .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init },
|
||||
{ .compatible = "ralink,rt2880-intc", .data = intc_of_init },
|
||||
{},
|
||||
};
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
of_irq_init(of_irq_ids);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
Lantiq SoC ASC serial controller
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "lantiq,asc"
|
||||
- reg : Address and length of the register set for the device
|
||||
- interrupts: the 3 (tx rx err) interrupt numbers. The interrupt specifier
|
||||
depends on the interrupt-parent interrupt controller.
|
||||
|
||||
Example:
|
||||
|
||||
asc1: serial@E100C00 {
|
||||
compatible = "lantiq,asc";
|
||||
reg = <0xE100C00 0x400>;
|
||||
interrupt-parent = <&icu0>;
|
||||
interrupts = <112 113 114>;
|
||||
};
|
|
@ -2438,7 +2438,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
real-time workloads. It can also improve energy
|
||||
efficiency for asymmetric multiprocessors.
|
||||
|
||||
rcu_nocbs_poll [KNL,BOOT]
|
||||
rcu_nocb_poll [KNL,BOOT]
|
||||
Rather than requiring that offloaded CPUs
|
||||
(specified by rcu_nocbs= above) explicitly
|
||||
awaken the corresponding "rcuoN" kthreads,
|
||||
|
|
|
@ -57,7 +57,7 @@ Protocol 2.10: (Kernel 2.6.31) Added a protocol for relaxed alignment
|
|||
Protocol 2.11: (Kernel 3.6) Added a field for offset of EFI handover
|
||||
protocol entry point.
|
||||
|
||||
Protocol 2.12: (Kernel 3.9) Added the xloadflags field and extension fields
|
||||
Protocol 2.12: (Kernel 3.8) Added the xloadflags field and extension fields
|
||||
to struct boot_params for for loading bzImage and ramdisk
|
||||
above 4G in 64bit.
|
||||
|
||||
|
|
|
@ -1489,7 +1489,7 @@ AVR32 ARCHITECTURE
|
|||
M: Haavard Skinnemoen <hskinnemoen@gmail.com>
|
||||
M: Hans-Christian Egtvedt <egtvedt@samfundet.no>
|
||||
W: http://www.atmel.com/products/AVR32/
|
||||
W: http://avr32linux.org/
|
||||
W: http://mirror.egtvedt.no/avr32linux.org/
|
||||
W: http://avrfreaks.net/
|
||||
S: Maintained
|
||||
F: arch/avr32/
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 8
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc6
|
||||
EXTRAVERSION = -rc7
|
||||
NAME = Unicycling Gorilla
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -351,6 +351,25 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
|
|||
irq_set_chained_handler(irq, gic_handle_cascade_irq);
|
||||
}
|
||||
|
||||
static u8 gic_get_cpumask(struct gic_chip_data *gic)
|
||||
{
|
||||
void __iomem *base = gic_data_dist_base(gic);
|
||||
u32 mask, i;
|
||||
|
||||
for (i = mask = 0; i < 32; i += 4) {
|
||||
mask = readl_relaxed(base + GIC_DIST_TARGET + i);
|
||||
mask |= mask >> 16;
|
||||
mask |= mask >> 8;
|
||||
if (mask)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mask)
|
||||
pr_crit("GIC CPU mask not found - kernel will fail to boot.\n");
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static void __init gic_dist_init(struct gic_chip_data *gic)
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -369,7 +388,9 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
|
|||
/*
|
||||
* Set all global interrupts to this CPU only.
|
||||
*/
|
||||
cpumask = readl_relaxed(base + GIC_DIST_TARGET + 0);
|
||||
cpumask = gic_get_cpumask(gic);
|
||||
cpumask |= cpumask << 8;
|
||||
cpumask |= cpumask << 16;
|
||||
for (i = 32; i < gic_irqs; i += 4)
|
||||
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
|
||||
|
||||
|
@ -400,7 +421,7 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
|
|||
* Get what the GIC says our CPU mask is.
|
||||
*/
|
||||
BUG_ON(cpu >= NR_GIC_CPU_IF);
|
||||
cpu_mask = readl_relaxed(dist_base + GIC_DIST_TARGET + 0);
|
||||
cpu_mask = gic_get_cpumask(gic);
|
||||
gic_cpu_map[cpu] = cpu_mask;
|
||||
|
||||
/*
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
#define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET)
|
||||
#define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(0x01000000))
|
||||
#define TASK_UNMAPPED_BASE (UL(CONFIG_PAGE_OFFSET) / 3)
|
||||
#define TASK_UNMAPPED_BASE ALIGN(TASK_SIZE / 3, SZ_16M)
|
||||
|
||||
/*
|
||||
* The maximum size of a 26-bit user space task.
|
||||
|
|
|
@ -414,7 +414,7 @@ config MACH_EXYNOS4_DT
|
|||
select CPU_EXYNOS4210
|
||||
select HAVE_SAMSUNG_KEYPAD if INPUT_KEYBOARD
|
||||
select PINCTRL
|
||||
select PINCTRL_EXYNOS4
|
||||
select PINCTRL_EXYNOS
|
||||
select USE_OF
|
||||
help
|
||||
Machine support for Samsung Exynos4 machine with device tree enabled.
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
/*
|
||||
* Only define NR_IRQS if less than NR_IRQS_EB
|
||||
*/
|
||||
#define NR_IRQS_EB (IRQ_EB_GIC_START + 96)
|
||||
#define NR_IRQS_EB (IRQ_EB_GIC_START + 128)
|
||||
|
||||
#if defined(CONFIG_MACH_REALVIEW_EB) \
|
||||
&& (!defined(NR_IRQS) || (NR_IRQS < NR_IRQS_EB))
|
||||
|
|
|
@ -640,7 +640,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
|
|||
|
||||
if (is_coherent || nommu())
|
||||
addr = __alloc_simple_buffer(dev, size, gfp, &page);
|
||||
else if (gfp & GFP_ATOMIC)
|
||||
else if (!(gfp & __GFP_WAIT))
|
||||
addr = __alloc_from_pool(size, &page);
|
||||
else if (!IS_ENABLED(CONFIG_CMA))
|
||||
addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller);
|
||||
|
|
|
@ -336,4 +336,14 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
|
|||
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
|
||||
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
|
||||
|
||||
/* drivers/base/dma-mapping.c */
|
||||
extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
|
||||
void *cpu_addr, dma_addr_t dma_addr, size_t size);
|
||||
extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
|
||||
void *cpu_addr, dma_addr_t dma_addr,
|
||||
size_t size);
|
||||
|
||||
#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
|
||||
#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
|
||||
|
||||
#endif /* __ASM_AVR32_DMA_MAPPING_H */
|
||||
|
|
|
@ -154,4 +154,14 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
|||
_dma_sync((dma_addr_t)vaddr, size, dir);
|
||||
}
|
||||
|
||||
/* drivers/base/dma-mapping.c */
|
||||
extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
|
||||
void *cpu_addr, dma_addr_t dma_addr, size_t size);
|
||||
extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
|
||||
void *cpu_addr, dma_addr_t dma_addr,
|
||||
size_t size);
|
||||
|
||||
#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
|
||||
#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
|
||||
|
||||
#endif /* _BLACKFIN_DMA_MAPPING_H */
|
||||
|
|
|
@ -89,4 +89,19 @@ extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t);
|
|||
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f))
|
||||
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent((d), (s), (v), (h))
|
||||
|
||||
/* Not supported for now */
|
||||
static inline int dma_mmap_coherent(struct device *dev,
|
||||
struct vm_area_struct *vma, void *cpu_addr,
|
||||
dma_addr_t dma_addr, size_t size)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
|
||||
void *cpu_addr, dma_addr_t dma_addr,
|
||||
size_t size)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#endif /* _ASM_C6X_DMA_MAPPING_H */
|
||||
|
|
|
@ -158,5 +158,15 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
|||
{
|
||||
}
|
||||
|
||||
/* drivers/base/dma-mapping.c */
|
||||
extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
|
||||
void *cpu_addr, dma_addr_t dma_addr, size_t size);
|
||||
extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
|
||||
void *cpu_addr, dma_addr_t dma_addr,
|
||||
size_t size);
|
||||
|
||||
#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
|
||||
#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -132,4 +132,19 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
|||
flush_write_buffers();
|
||||
}
|
||||
|
||||
/* Not supported for now */
|
||||
static inline int dma_mmap_coherent(struct device *dev,
|
||||
struct vm_area_struct *vma, void *cpu_addr,
|
||||
dma_addr_t dma_addr, size_t size)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
|
||||
void *cpu_addr, dma_addr_t dma_addr,
|
||||
size_t size)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#endif /* _ASM_DMA_MAPPING_H */
|
||||
|
|
|
@ -115,4 +115,14 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
|
|||
#include <asm-generic/dma-mapping-broken.h>
|
||||
#endif
|
||||
|
||||
/* drivers/base/dma-mapping.c */
|
||||
extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
|
||||
void *cpu_addr, dma_addr_t dma_addr, size_t size);
|
||||
extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
|
||||
void *cpu_addr, dma_addr_t dma_addr,
|
||||
size_t size);
|
||||
|
||||
#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
|
||||
#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
|
||||
|
||||
#endif /* _M68K_DMA_MAPPING_H */
|
||||
|
|
|
@ -21,6 +21,7 @@ platforms += netlogic
|
|||
platforms += pmcs-msp71xx
|
||||
platforms += pnx833x
|
||||
platforms += powertv
|
||||
platforms += ralink
|
||||
platforms += rb532
|
||||
platforms += sgi-ip22
|
||||
platforms += sgi-ip27
|
||||
|
|
|
@ -107,12 +107,14 @@ config ATH79
|
|||
config BCM47XX
|
||||
bool "Broadcom BCM47XX based boards"
|
||||
select ARCH_WANT_OPTIONAL_GPIOLIB
|
||||
select BOOT_RAW
|
||||
select CEVT_R4K
|
||||
select CSRC_R4K
|
||||
select DMA_NONCOHERENT
|
||||
select FW_CFE
|
||||
select HW_HAS_PCI
|
||||
select IRQ_CPU
|
||||
select NO_EXCEPT_FILL
|
||||
select SYS_SUPPORTS_32BIT_KERNEL
|
||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||
select SYS_HAS_EARLY_PRINTK
|
||||
|
@ -294,6 +296,7 @@ config MIPS_MALTA
|
|||
select BOOT_RAW
|
||||
select CEVT_R4K
|
||||
select CSRC_R4K
|
||||
select CSRC_GIC
|
||||
select DMA_NONCOHERENT
|
||||
select GENERIC_ISA_DMA
|
||||
select HAVE_PCSPKR_PLATFORM
|
||||
|
@ -425,6 +428,22 @@ config POWERTV
|
|||
help
|
||||
This enables support for the Cisco PowerTV Platform.
|
||||
|
||||
config RALINK
|
||||
bool "Ralink based machines"
|
||||
select CEVT_R4K
|
||||
select CSRC_R4K
|
||||
select BOOT_RAW
|
||||
select DMA_NONCOHERENT
|
||||
select IRQ_CPU
|
||||
select USE_OF
|
||||
select SYS_HAS_CPU_MIPS32_R1
|
||||
select SYS_HAS_CPU_MIPS32_R2
|
||||
select SYS_SUPPORTS_32BIT_KERNEL
|
||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||
select SYS_HAS_EARLY_PRINTK
|
||||
select HAVE_MACH_CLKDEV
|
||||
select CLKDEV_LOOKUP
|
||||
|
||||
config SGI_IP22
|
||||
bool "SGI IP22 (Indy/Indigo2)"
|
||||
select FW_ARC
|
||||
|
@ -837,6 +856,7 @@ source "arch/mips/lantiq/Kconfig"
|
|||
source "arch/mips/lasat/Kconfig"
|
||||
source "arch/mips/pmcs-msp71xx/Kconfig"
|
||||
source "arch/mips/powertv/Kconfig"
|
||||
source "arch/mips/ralink/Kconfig"
|
||||
source "arch/mips/sgi-ip27/Kconfig"
|
||||
source "arch/mips/sibyte/Kconfig"
|
||||
source "arch/mips/txx9/Kconfig"
|
||||
|
@ -917,6 +937,9 @@ config CSRC_POWERTV
|
|||
config CSRC_R4K
|
||||
bool
|
||||
|
||||
config CSRC_GIC
|
||||
bool
|
||||
|
||||
config CSRC_SB1250
|
||||
bool
|
||||
|
||||
|
|
|
@ -14,6 +14,18 @@ config ATH79_MACH_AP121
|
|||
Say 'Y' here if you want your kernel to support the
|
||||
Atheros AP121 reference board.
|
||||
|
||||
config ATH79_MACH_AP136
|
||||
bool "Atheros AP136 reference board"
|
||||
select SOC_QCA955X
|
||||
select ATH79_DEV_GPIO_BUTTONS
|
||||
select ATH79_DEV_LEDS_GPIO
|
||||
select ATH79_DEV_SPI
|
||||
select ATH79_DEV_USB
|
||||
select ATH79_DEV_WMAC
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Atheros AP136 reference board.
|
||||
|
||||
config ATH79_MACH_AP81
|
||||
bool "Atheros AP81 reference board"
|
||||
select SOC_AR913X
|
||||
|
@ -88,6 +100,12 @@ config SOC_AR934X
|
|||
select PCI_AR724X if PCI
|
||||
def_bool n
|
||||
|
||||
config SOC_QCA955X
|
||||
select USB_ARCH_HAS_EHCI
|
||||
select HW_HAS_PCI
|
||||
select PCI_AR724X if PCI
|
||||
def_bool n
|
||||
|
||||
config PCI_AR724X
|
||||
def_bool n
|
||||
|
||||
|
@ -104,7 +122,7 @@ config ATH79_DEV_USB
|
|||
def_bool n
|
||||
|
||||
config ATH79_DEV_WMAC
|
||||
depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X)
|
||||
depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA955X)
|
||||
def_bool n
|
||||
|
||||
endif
|
||||
|
|
|
@ -27,6 +27,7 @@ obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wmac.o
|
|||
# Machines
|
||||
#
|
||||
obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o
|
||||
obj-$(CONFIG_ATH79_MACH_AP136) += mach-ap136.o
|
||||
obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o
|
||||
obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o
|
||||
obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o
|
||||
|
|
|
@ -295,6 +295,82 @@ static void __init ar934x_clocks_init(void)
|
|||
iounmap(dpll_base);
|
||||
}
|
||||
|
||||
static void __init qca955x_clocks_init(void)
|
||||
{
|
||||
u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
|
||||
u32 cpu_pll, ddr_pll;
|
||||
u32 bootstrap;
|
||||
|
||||
bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP);
|
||||
if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40)
|
||||
ath79_ref_clk.rate = 40 * 1000 * 1000;
|
||||
else
|
||||
ath79_ref_clk.rate = 25 * 1000 * 1000;
|
||||
|
||||
pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG);
|
||||
out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
|
||||
QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK;
|
||||
ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
|
||||
QCA955X_PLL_CPU_CONFIG_REFDIV_MASK;
|
||||
nint = (pll >> QCA955X_PLL_CPU_CONFIG_NINT_SHIFT) &
|
||||
QCA955X_PLL_CPU_CONFIG_NINT_MASK;
|
||||
frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
|
||||
QCA955X_PLL_CPU_CONFIG_NFRAC_MASK;
|
||||
|
||||
cpu_pll = nint * ath79_ref_clk.rate / ref_div;
|
||||
cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 6));
|
||||
cpu_pll /= (1 << out_div);
|
||||
|
||||
pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG);
|
||||
out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
|
||||
QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK;
|
||||
ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
|
||||
QCA955X_PLL_DDR_CONFIG_REFDIV_MASK;
|
||||
nint = (pll >> QCA955X_PLL_DDR_CONFIG_NINT_SHIFT) &
|
||||
QCA955X_PLL_DDR_CONFIG_NINT_MASK;
|
||||
frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
|
||||
QCA955X_PLL_DDR_CONFIG_NFRAC_MASK;
|
||||
|
||||
ddr_pll = nint * ath79_ref_clk.rate / ref_div;
|
||||
ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 10));
|
||||
ddr_pll /= (1 << out_div);
|
||||
|
||||
clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG);
|
||||
|
||||
postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
|
||||
QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
|
||||
|
||||
if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
|
||||
ath79_cpu_clk.rate = ath79_ref_clk.rate;
|
||||
else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL)
|
||||
ath79_cpu_clk.rate = ddr_pll / (postdiv + 1);
|
||||
else
|
||||
ath79_cpu_clk.rate = cpu_pll / (postdiv + 1);
|
||||
|
||||
postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
|
||||
QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
|
||||
|
||||
if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
|
||||
ath79_ddr_clk.rate = ath79_ref_clk.rate;
|
||||
else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
|
||||
ath79_ddr_clk.rate = cpu_pll / (postdiv + 1);
|
||||
else
|
||||
ath79_ddr_clk.rate = ddr_pll / (postdiv + 1);
|
||||
|
||||
postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
|
||||
QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
|
||||
|
||||
if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
|
||||
ath79_ahb_clk.rate = ath79_ref_clk.rate;
|
||||
else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
|
||||
ath79_ahb_clk.rate = ddr_pll / (postdiv + 1);
|
||||
else
|
||||
ath79_ahb_clk.rate = cpu_pll / (postdiv + 1);
|
||||
|
||||
ath79_wdt_clk.rate = ath79_ref_clk.rate;
|
||||
ath79_uart_clk.rate = ath79_ref_clk.rate;
|
||||
}
|
||||
|
||||
void __init ath79_clocks_init(void)
|
||||
{
|
||||
if (soc_is_ar71xx())
|
||||
|
@ -307,6 +383,8 @@ void __init ath79_clocks_init(void)
|
|||
ar933x_clocks_init();
|
||||
else if (soc_is_ar934x())
|
||||
ar934x_clocks_init();
|
||||
else if (soc_is_qca955x())
|
||||
qca955x_clocks_init();
|
||||
else
|
||||
BUG();
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ void ath79_device_reset_set(u32 mask)
|
|||
reg = AR933X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_ar934x())
|
||||
reg = AR934X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_qca955x())
|
||||
reg = QCA955X_RESET_REG_RESET_MODULE;
|
||||
else
|
||||
BUG();
|
||||
|
||||
|
@ -98,6 +100,8 @@ void ath79_device_reset_clear(u32 mask)
|
|||
reg = AR933X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_ar934x())
|
||||
reg = AR934X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_qca955x())
|
||||
reg = QCA955X_RESET_REG_RESET_MODULE;
|
||||
else
|
||||
BUG();
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ static struct resource ath79_uart_resources[] = {
|
|||
static struct plat_serial8250_port ath79_uart_data[] = {
|
||||
{
|
||||
.mapbase = AR71XX_UART_BASE,
|
||||
.irq = ATH79_MISC_IRQ_UART,
|
||||
.irq = ATH79_MISC_IRQ(3),
|
||||
.flags = AR71XX_UART_FLAGS,
|
||||
.iotype = UPIO_MEM32,
|
||||
.regshift = 2,
|
||||
|
@ -62,8 +62,8 @@ static struct resource ar933x_uart_resources[] = {
|
|||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = ATH79_MISC_IRQ_UART,
|
||||
.end = ATH79_MISC_IRQ_UART,
|
||||
.start = ATH79_MISC_IRQ(3),
|
||||
.end = ATH79_MISC_IRQ(3),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
@ -90,7 +90,8 @@ void __init ath79_register_uart(void)
|
|||
if (soc_is_ar71xx() ||
|
||||
soc_is_ar724x() ||
|
||||
soc_is_ar913x() ||
|
||||
soc_is_ar934x()) {
|
||||
soc_is_ar934x() ||
|
||||
soc_is_qca955x()) {
|
||||
ath79_uart_data[0].uartclk = clk_get_rate(clk);
|
||||
platform_device_register(&ath79_uart_device);
|
||||
} else if (soc_is_ar933x()) {
|
||||
|
|
|
@ -25,29 +25,11 @@
|
|||
#include "common.h"
|
||||
#include "dev-usb.h"
|
||||
|
||||
static struct resource ath79_ohci_resources[2];
|
||||
|
||||
static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32);
|
||||
static u64 ath79_usb_dmamask = DMA_BIT_MASK(32);
|
||||
|
||||
static struct usb_ohci_pdata ath79_ohci_pdata = {
|
||||
};
|
||||
|
||||
static struct platform_device ath79_ohci_device = {
|
||||
.name = "ohci-platform",
|
||||
.id = -1,
|
||||
.resource = ath79_ohci_resources,
|
||||
.num_resources = ARRAY_SIZE(ath79_ohci_resources),
|
||||
.dev = {
|
||||
.dma_mask = &ath79_ohci_dmamask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
.platform_data = &ath79_ohci_pdata,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource ath79_ehci_resources[2];
|
||||
|
||||
static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32);
|
||||
|
||||
static struct usb_ehci_pdata ath79_ehci_pdata_v1 = {
|
||||
.has_synopsys_hc_bug = 1,
|
||||
};
|
||||
|
@ -57,22 +39,16 @@ static struct usb_ehci_pdata ath79_ehci_pdata_v2 = {
|
|||
.has_tt = 1,
|
||||
};
|
||||
|
||||
static struct platform_device ath79_ehci_device = {
|
||||
.name = "ehci-platform",
|
||||
.id = -1,
|
||||
.resource = ath79_ehci_resources,
|
||||
.num_resources = ARRAY_SIZE(ath79_ehci_resources),
|
||||
.dev = {
|
||||
.dma_mask = &ath79_ehci_dmamask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
},
|
||||
};
|
||||
|
||||
static void __init ath79_usb_init_resource(struct resource res[2],
|
||||
unsigned long base,
|
||||
unsigned long size,
|
||||
int irq)
|
||||
static void __init ath79_usb_register(const char *name, int id,
|
||||
unsigned long base, unsigned long size,
|
||||
int irq, const void *data,
|
||||
size_t data_size)
|
||||
{
|
||||
struct resource res[2];
|
||||
struct platform_device *pdev;
|
||||
|
||||
memset(res, 0, sizeof(res));
|
||||
|
||||
res[0].flags = IORESOURCE_MEM;
|
||||
res[0].start = base;
|
||||
res[0].end = base + size - 1;
|
||||
|
@ -80,6 +56,19 @@ static void __init ath79_usb_init_resource(struct resource res[2],
|
|||
res[1].flags = IORESOURCE_IRQ;
|
||||
res[1].start = irq;
|
||||
res[1].end = irq;
|
||||
|
||||
pdev = platform_device_register_resndata(NULL, name, id,
|
||||
res, ARRAY_SIZE(res),
|
||||
data, data_size);
|
||||
|
||||
if (IS_ERR(pdev)) {
|
||||
pr_err("ath79: unable to register USB at %08lx, err=%d\n",
|
||||
base, (int) PTR_ERR(pdev));
|
||||
return;
|
||||
}
|
||||
|
||||
pdev->dev.dma_mask = &ath79_usb_dmamask;
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
}
|
||||
|
||||
#define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \
|
||||
|
@ -106,14 +95,15 @@ static void __init ath79_usb_setup(void)
|
|||
|
||||
mdelay(900);
|
||||
|
||||
ath79_usb_init_resource(ath79_ohci_resources, AR71XX_OHCI_BASE,
|
||||
AR71XX_OHCI_SIZE, ATH79_MISC_IRQ_OHCI);
|
||||
platform_device_register(&ath79_ohci_device);
|
||||
ath79_usb_register("ohci-platform", -1,
|
||||
AR71XX_OHCI_BASE, AR71XX_OHCI_SIZE,
|
||||
ATH79_MISC_IRQ(6),
|
||||
&ath79_ohci_pdata, sizeof(ath79_ohci_pdata));
|
||||
|
||||
ath79_usb_init_resource(ath79_ehci_resources, AR71XX_EHCI_BASE,
|
||||
AR71XX_EHCI_SIZE, ATH79_CPU_IRQ_USB);
|
||||
ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v1;
|
||||
platform_device_register(&ath79_ehci_device);
|
||||
ath79_usb_register("ehci-platform", -1,
|
||||
AR71XX_EHCI_BASE, AR71XX_EHCI_SIZE,
|
||||
ATH79_CPU_IRQ(3),
|
||||
&ath79_ehci_pdata_v1, sizeof(ath79_ehci_pdata_v1));
|
||||
}
|
||||
|
||||
static void __init ar7240_usb_setup(void)
|
||||
|
@ -135,9 +125,10 @@ static void __init ar7240_usb_setup(void)
|
|||
|
||||
iounmap(usb_ctrl_base);
|
||||
|
||||
ath79_usb_init_resource(ath79_ohci_resources, AR7240_OHCI_BASE,
|
||||
AR7240_OHCI_SIZE, ATH79_CPU_IRQ_USB);
|
||||
platform_device_register(&ath79_ohci_device);
|
||||
ath79_usb_register("ohci-platform", -1,
|
||||
AR7240_OHCI_BASE, AR7240_OHCI_SIZE,
|
||||
ATH79_CPU_IRQ(3),
|
||||
&ath79_ohci_pdata, sizeof(ath79_ohci_pdata));
|
||||
}
|
||||
|
||||
static void __init ar724x_usb_setup(void)
|
||||
|
@ -151,10 +142,10 @@ static void __init ar724x_usb_setup(void)
|
|||
ath79_device_reset_clear(AR724X_RESET_USB_PHY);
|
||||
mdelay(10);
|
||||
|
||||
ath79_usb_init_resource(ath79_ehci_resources, AR724X_EHCI_BASE,
|
||||
AR724X_EHCI_SIZE, ATH79_CPU_IRQ_USB);
|
||||
ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
|
||||
platform_device_register(&ath79_ehci_device);
|
||||
ath79_usb_register("ehci-platform", -1,
|
||||
AR724X_EHCI_BASE, AR724X_EHCI_SIZE,
|
||||
ATH79_CPU_IRQ(3),
|
||||
&ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
|
||||
}
|
||||
|
||||
static void __init ar913x_usb_setup(void)
|
||||
|
@ -168,10 +159,10 @@ static void __init ar913x_usb_setup(void)
|
|||
ath79_device_reset_clear(AR913X_RESET_USB_PHY);
|
||||
mdelay(10);
|
||||
|
||||
ath79_usb_init_resource(ath79_ehci_resources, AR913X_EHCI_BASE,
|
||||
AR913X_EHCI_SIZE, ATH79_CPU_IRQ_USB);
|
||||
ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
|
||||
platform_device_register(&ath79_ehci_device);
|
||||
ath79_usb_register("ehci-platform", -1,
|
||||
AR913X_EHCI_BASE, AR913X_EHCI_SIZE,
|
||||
ATH79_CPU_IRQ(3),
|
||||
&ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
|
||||
}
|
||||
|
||||
static void __init ar933x_usb_setup(void)
|
||||
|
@ -185,10 +176,10 @@ static void __init ar933x_usb_setup(void)
|
|||
ath79_device_reset_clear(AR933X_RESET_USB_PHY);
|
||||
mdelay(10);
|
||||
|
||||
ath79_usb_init_resource(ath79_ehci_resources, AR933X_EHCI_BASE,
|
||||
AR933X_EHCI_SIZE, ATH79_CPU_IRQ_USB);
|
||||
ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
|
||||
platform_device_register(&ath79_ehci_device);
|
||||
ath79_usb_register("ehci-platform", -1,
|
||||
AR933X_EHCI_BASE, AR933X_EHCI_SIZE,
|
||||
ATH79_CPU_IRQ(3),
|
||||
&ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
|
||||
}
|
||||
|
||||
static void __init ar934x_usb_setup(void)
|
||||
|
@ -211,10 +202,23 @@ static void __init ar934x_usb_setup(void)
|
|||
ath79_device_reset_clear(AR934X_RESET_USB_HOST);
|
||||
udelay(1000);
|
||||
|
||||
ath79_usb_init_resource(ath79_ehci_resources, AR934X_EHCI_BASE,
|
||||
AR934X_EHCI_SIZE, ATH79_CPU_IRQ_USB);
|
||||
ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
|
||||
platform_device_register(&ath79_ehci_device);
|
||||
ath79_usb_register("ehci-platform", -1,
|
||||
AR934X_EHCI_BASE, AR934X_EHCI_SIZE,
|
||||
ATH79_CPU_IRQ(3),
|
||||
&ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
|
||||
}
|
||||
|
||||
static void __init qca955x_usb_setup(void)
|
||||
{
|
||||
ath79_usb_register("ehci-platform", 0,
|
||||
QCA955X_EHCI0_BASE, QCA955X_EHCI_SIZE,
|
||||
ATH79_IP3_IRQ(0),
|
||||
&ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
|
||||
|
||||
ath79_usb_register("ehci-platform", 1,
|
||||
QCA955X_EHCI1_BASE, QCA955X_EHCI_SIZE,
|
||||
ATH79_IP3_IRQ(1),
|
||||
&ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
|
||||
}
|
||||
|
||||
void __init ath79_register_usb(void)
|
||||
|
@ -231,6 +235,8 @@ void __init ath79_register_usb(void)
|
|||
ar933x_usb_setup();
|
||||
else if (soc_is_ar934x())
|
||||
ar934x_usb_setup();
|
||||
else if (soc_is_qca955x())
|
||||
qca955x_usb_setup();
|
||||
else
|
||||
BUG();
|
||||
}
|
||||
|
|
|
@ -55,8 +55,8 @@ static void __init ar913x_wmac_setup(void)
|
|||
|
||||
ath79_wmac_resources[0].start = AR913X_WMAC_BASE;
|
||||
ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1;
|
||||
ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2;
|
||||
ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2;
|
||||
ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2);
|
||||
ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -83,8 +83,8 @@ static void __init ar933x_wmac_setup(void)
|
|||
|
||||
ath79_wmac_resources[0].start = AR933X_WMAC_BASE;
|
||||
ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1;
|
||||
ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2;
|
||||
ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2;
|
||||
ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2);
|
||||
ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2);
|
||||
|
||||
t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
|
||||
if (t & AR933X_BOOTSTRAP_REF_CLK_40)
|
||||
|
@ -107,7 +107,7 @@ static void ar934x_wmac_setup(void)
|
|||
ath79_wmac_resources[0].start = AR934X_WMAC_BASE;
|
||||
ath79_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1;
|
||||
ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1);
|
||||
ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1);
|
||||
ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1);
|
||||
|
||||
t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
|
||||
if (t & AR934X_BOOTSTRAP_REF_CLK_40)
|
||||
|
@ -116,6 +116,24 @@ static void ar934x_wmac_setup(void)
|
|||
ath79_wmac_data.is_clk_25mhz = true;
|
||||
}
|
||||
|
||||
static void qca955x_wmac_setup(void)
|
||||
{
|
||||
u32 t;
|
||||
|
||||
ath79_wmac_device.name = "qca955x_wmac";
|
||||
|
||||
ath79_wmac_resources[0].start = QCA955X_WMAC_BASE;
|
||||
ath79_wmac_resources[0].end = QCA955X_WMAC_BASE + QCA955X_WMAC_SIZE - 1;
|
||||
ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1);
|
||||
ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1);
|
||||
|
||||
t = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP);
|
||||
if (t & QCA955X_BOOTSTRAP_REF_CLK_40)
|
||||
ath79_wmac_data.is_clk_25mhz = false;
|
||||
else
|
||||
ath79_wmac_data.is_clk_25mhz = true;
|
||||
}
|
||||
|
||||
void __init ath79_register_wmac(u8 *cal_data)
|
||||
{
|
||||
if (soc_is_ar913x())
|
||||
|
@ -124,6 +142,8 @@ void __init ath79_register_wmac(u8 *cal_data)
|
|||
ar933x_wmac_setup();
|
||||
else if (soc_is_ar934x())
|
||||
ar934x_wmac_setup();
|
||||
else if (soc_is_qca955x())
|
||||
qca955x_wmac_setup();
|
||||
else
|
||||
BUG();
|
||||
|
||||
|
|
|
@ -74,6 +74,8 @@ static void prom_putchar_init(void)
|
|||
case REV_ID_MAJOR_AR9341:
|
||||
case REV_ID_MAJOR_AR9342:
|
||||
case REV_ID_MAJOR_AR9344:
|
||||
case REV_ID_MAJOR_QCA9556:
|
||||
case REV_ID_MAJOR_QCA9558:
|
||||
_prom_putchar = prom_putchar_ar71xx;
|
||||
break;
|
||||
|
||||
|
|
|
@ -137,51 +137,47 @@ static struct gpio_chip ath79_gpio_chip = {
|
|||
.base = 0,
|
||||
};
|
||||
|
||||
void ath79_gpio_function_enable(u32 mask)
|
||||
static void __iomem *ath79_gpio_get_function_reg(void)
|
||||
{
|
||||
void __iomem *base = ath79_gpio_base;
|
||||
unsigned long flags;
|
||||
u32 reg = 0;
|
||||
|
||||
spin_lock_irqsave(&ath79_gpio_lock, flags);
|
||||
if (soc_is_ar71xx() ||
|
||||
soc_is_ar724x() ||
|
||||
soc_is_ar913x() ||
|
||||
soc_is_ar933x())
|
||||
reg = AR71XX_GPIO_REG_FUNC;
|
||||
else if (soc_is_ar934x())
|
||||
reg = AR934X_GPIO_REG_FUNC;
|
||||
else
|
||||
BUG();
|
||||
|
||||
__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) | mask,
|
||||
base + AR71XX_GPIO_REG_FUNC);
|
||||
/* flush write */
|
||||
__raw_readl(base + AR71XX_GPIO_REG_FUNC);
|
||||
|
||||
spin_unlock_irqrestore(&ath79_gpio_lock, flags);
|
||||
}
|
||||
|
||||
void ath79_gpio_function_disable(u32 mask)
|
||||
{
|
||||
void __iomem *base = ath79_gpio_base;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ath79_gpio_lock, flags);
|
||||
|
||||
__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~mask,
|
||||
base + AR71XX_GPIO_REG_FUNC);
|
||||
/* flush write */
|
||||
__raw_readl(base + AR71XX_GPIO_REG_FUNC);
|
||||
|
||||
spin_unlock_irqrestore(&ath79_gpio_lock, flags);
|
||||
return ath79_gpio_base + reg;
|
||||
}
|
||||
|
||||
void ath79_gpio_function_setup(u32 set, u32 clear)
|
||||
{
|
||||
void __iomem *base = ath79_gpio_base;
|
||||
void __iomem *reg = ath79_gpio_get_function_reg();
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ath79_gpio_lock, flags);
|
||||
|
||||
__raw_writel((__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~clear) | set,
|
||||
base + AR71XX_GPIO_REG_FUNC);
|
||||
__raw_writel((__raw_readl(reg) & ~clear) | set, reg);
|
||||
/* flush write */
|
||||
__raw_readl(base + AR71XX_GPIO_REG_FUNC);
|
||||
__raw_readl(reg);
|
||||
|
||||
spin_unlock_irqrestore(&ath79_gpio_lock, flags);
|
||||
}
|
||||
|
||||
void ath79_gpio_function_enable(u32 mask)
|
||||
{
|
||||
ath79_gpio_function_setup(mask, 0);
|
||||
}
|
||||
|
||||
void ath79_gpio_function_disable(u32 mask)
|
||||
{
|
||||
ath79_gpio_function_setup(0, mask);
|
||||
}
|
||||
|
||||
void __init ath79_gpio_init(void)
|
||||
{
|
||||
int err;
|
||||
|
@ -198,12 +194,14 @@ void __init ath79_gpio_init(void)
|
|||
ath79_gpio_count = AR933X_GPIO_COUNT;
|
||||
else if (soc_is_ar934x())
|
||||
ath79_gpio_count = AR934X_GPIO_COUNT;
|
||||
else if (soc_is_qca955x())
|
||||
ath79_gpio_count = QCA955X_GPIO_COUNT;
|
||||
else
|
||||
BUG();
|
||||
|
||||
ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
|
||||
ath79_gpio_chip.ngpio = ath79_gpio_count;
|
||||
if (soc_is_ar934x()) {
|
||||
if (soc_is_ar934x() || soc_is_qca955x()) {
|
||||
ath79_gpio_chip.direction_input = ar934x_gpio_direction_input;
|
||||
ath79_gpio_chip.direction_output = ar934x_gpio_direction_output;
|
||||
}
|
||||
|
|
|
@ -35,44 +35,17 @@ static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|||
pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
|
||||
__raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
|
||||
|
||||
if (pending & MISC_INT_UART)
|
||||
generic_handle_irq(ATH79_MISC_IRQ_UART);
|
||||
|
||||
else if (pending & MISC_INT_DMA)
|
||||
generic_handle_irq(ATH79_MISC_IRQ_DMA);
|
||||
|
||||
else if (pending & MISC_INT_PERFC)
|
||||
generic_handle_irq(ATH79_MISC_IRQ_PERFC);
|
||||
|
||||
else if (pending & MISC_INT_TIMER)
|
||||
generic_handle_irq(ATH79_MISC_IRQ_TIMER);
|
||||
|
||||
else if (pending & MISC_INT_TIMER2)
|
||||
generic_handle_irq(ATH79_MISC_IRQ_TIMER2);
|
||||
|
||||
else if (pending & MISC_INT_TIMER3)
|
||||
generic_handle_irq(ATH79_MISC_IRQ_TIMER3);
|
||||
|
||||
else if (pending & MISC_INT_TIMER4)
|
||||
generic_handle_irq(ATH79_MISC_IRQ_TIMER4);
|
||||
|
||||
else if (pending & MISC_INT_OHCI)
|
||||
generic_handle_irq(ATH79_MISC_IRQ_OHCI);
|
||||
|
||||
else if (pending & MISC_INT_ERROR)
|
||||
generic_handle_irq(ATH79_MISC_IRQ_ERROR);
|
||||
|
||||
else if (pending & MISC_INT_GPIO)
|
||||
generic_handle_irq(ATH79_MISC_IRQ_GPIO);
|
||||
|
||||
else if (pending & MISC_INT_WDOG)
|
||||
generic_handle_irq(ATH79_MISC_IRQ_WDOG);
|
||||
|
||||
else if (pending & MISC_INT_ETHSW)
|
||||
generic_handle_irq(ATH79_MISC_IRQ_ETHSW);
|
||||
|
||||
else
|
||||
if (!pending) {
|
||||
spurious_interrupt();
|
||||
return;
|
||||
}
|
||||
|
||||
while (pending) {
|
||||
int bit = __ffs(pending);
|
||||
|
||||
generic_handle_irq(ATH79_MISC_IRQ(bit));
|
||||
pending &= ~BIT(bit);
|
||||
}
|
||||
}
|
||||
|
||||
static void ar71xx_misc_irq_unmask(struct irq_data *d)
|
||||
|
@ -130,7 +103,10 @@ static void __init ath79_misc_irq_init(void)
|
|||
|
||||
if (soc_is_ar71xx() || soc_is_ar913x())
|
||||
ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
|
||||
else if (soc_is_ar724x() || soc_is_ar933x() || soc_is_ar934x())
|
||||
else if (soc_is_ar724x() ||
|
||||
soc_is_ar933x() ||
|
||||
soc_is_ar934x() ||
|
||||
soc_is_qca955x())
|
||||
ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
|
||||
else
|
||||
BUG();
|
||||
|
@ -141,7 +117,7 @@ static void __init ath79_misc_irq_init(void)
|
|||
handle_level_irq);
|
||||
}
|
||||
|
||||
irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler);
|
||||
irq_set_chained_handler(ATH79_CPU_IRQ(6), ath79_misc_irq_handler);
|
||||
}
|
||||
|
||||
static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc)
|
||||
|
@ -174,7 +150,89 @@ static void ar934x_ip2_irq_init(void)
|
|||
irq_set_chip_and_handler(i, &dummy_irq_chip,
|
||||
handle_level_irq);
|
||||
|
||||
irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar934x_ip2_irq_dispatch);
|
||||
irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch);
|
||||
}
|
||||
|
||||
static void qca955x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
u32 status;
|
||||
|
||||
disable_irq_nosync(irq);
|
||||
|
||||
status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);
|
||||
status &= QCA955X_EXT_INT_PCIE_RC1_ALL | QCA955X_EXT_INT_WMAC_ALL;
|
||||
|
||||
if (status == 0) {
|
||||
spurious_interrupt();
|
||||
goto enable;
|
||||
}
|
||||
|
||||
if (status & QCA955X_EXT_INT_PCIE_RC1_ALL) {
|
||||
/* TODO: flush DDR? */
|
||||
generic_handle_irq(ATH79_IP2_IRQ(0));
|
||||
}
|
||||
|
||||
if (status & QCA955X_EXT_INT_WMAC_ALL) {
|
||||
/* TODO: flush DDR? */
|
||||
generic_handle_irq(ATH79_IP2_IRQ(1));
|
||||
}
|
||||
|
||||
enable:
|
||||
enable_irq(irq);
|
||||
}
|
||||
|
||||
static void qca955x_ip3_irq_dispatch(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
u32 status;
|
||||
|
||||
disable_irq_nosync(irq);
|
||||
|
||||
status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);
|
||||
status &= QCA955X_EXT_INT_PCIE_RC2_ALL |
|
||||
QCA955X_EXT_INT_USB1 |
|
||||
QCA955X_EXT_INT_USB2;
|
||||
|
||||
if (status == 0) {
|
||||
spurious_interrupt();
|
||||
goto enable;
|
||||
}
|
||||
|
||||
if (status & QCA955X_EXT_INT_USB1) {
|
||||
/* TODO: flush DDR? */
|
||||
generic_handle_irq(ATH79_IP3_IRQ(0));
|
||||
}
|
||||
|
||||
if (status & QCA955X_EXT_INT_USB2) {
|
||||
/* TODO: flush DDR? */
|
||||
generic_handle_irq(ATH79_IP3_IRQ(1));
|
||||
}
|
||||
|
||||
if (status & QCA955X_EXT_INT_PCIE_RC2_ALL) {
|
||||
/* TODO: flush DDR? */
|
||||
generic_handle_irq(ATH79_IP3_IRQ(2));
|
||||
}
|
||||
|
||||
enable:
|
||||
enable_irq(irq);
|
||||
}
|
||||
|
||||
static void qca955x_irq_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = ATH79_IP2_IRQ_BASE;
|
||||
i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
|
||||
irq_set_chip_and_handler(i, &dummy_irq_chip,
|
||||
handle_level_irq);
|
||||
|
||||
irq_set_chained_handler(ATH79_CPU_IRQ(2), qca955x_ip2_irq_dispatch);
|
||||
|
||||
for (i = ATH79_IP3_IRQ_BASE;
|
||||
i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++)
|
||||
irq_set_chip_and_handler(i, &dummy_irq_chip,
|
||||
handle_level_irq);
|
||||
|
||||
irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch);
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(void)
|
||||
|
@ -184,22 +242,22 @@ asmlinkage void plat_irq_dispatch(void)
|
|||
pending = read_c0_status() & read_c0_cause() & ST0_IM;
|
||||
|
||||
if (pending & STATUSF_IP7)
|
||||
do_IRQ(ATH79_CPU_IRQ_TIMER);
|
||||
do_IRQ(ATH79_CPU_IRQ(7));
|
||||
|
||||
else if (pending & STATUSF_IP2)
|
||||
ath79_ip2_handler();
|
||||
|
||||
else if (pending & STATUSF_IP4)
|
||||
do_IRQ(ATH79_CPU_IRQ_GE0);
|
||||
do_IRQ(ATH79_CPU_IRQ(4));
|
||||
|
||||
else if (pending & STATUSF_IP5)
|
||||
do_IRQ(ATH79_CPU_IRQ_GE1);
|
||||
do_IRQ(ATH79_CPU_IRQ(5));
|
||||
|
||||
else if (pending & STATUSF_IP3)
|
||||
ath79_ip3_handler();
|
||||
|
||||
else if (pending & STATUSF_IP6)
|
||||
do_IRQ(ATH79_CPU_IRQ_MISC);
|
||||
do_IRQ(ATH79_CPU_IRQ(6));
|
||||
|
||||
else
|
||||
spurious_interrupt();
|
||||
|
@ -212,63 +270,69 @@ asmlinkage void plat_irq_dispatch(void)
|
|||
* Issue a flush in the handlers to ensure that the driver sees
|
||||
* the update.
|
||||
*/
|
||||
|
||||
static void ath79_default_ip2_handler(void)
|
||||
{
|
||||
do_IRQ(ATH79_CPU_IRQ(2));
|
||||
}
|
||||
|
||||
static void ath79_default_ip3_handler(void)
|
||||
{
|
||||
do_IRQ(ATH79_CPU_IRQ(3));
|
||||
}
|
||||
|
||||
static void ar71xx_ip2_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI);
|
||||
do_IRQ(ATH79_CPU_IRQ_IP2);
|
||||
do_IRQ(ATH79_CPU_IRQ(2));
|
||||
}
|
||||
|
||||
static void ar724x_ip2_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE);
|
||||
do_IRQ(ATH79_CPU_IRQ_IP2);
|
||||
do_IRQ(ATH79_CPU_IRQ(2));
|
||||
}
|
||||
|
||||
static void ar913x_ip2_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC);
|
||||
do_IRQ(ATH79_CPU_IRQ_IP2);
|
||||
do_IRQ(ATH79_CPU_IRQ(2));
|
||||
}
|
||||
|
||||
static void ar933x_ip2_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC);
|
||||
do_IRQ(ATH79_CPU_IRQ_IP2);
|
||||
}
|
||||
|
||||
static void ar934x_ip2_handler(void)
|
||||
{
|
||||
do_IRQ(ATH79_CPU_IRQ_IP2);
|
||||
do_IRQ(ATH79_CPU_IRQ(2));
|
||||
}
|
||||
|
||||
static void ar71xx_ip3_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ(3));
|
||||
}
|
||||
|
||||
static void ar724x_ip3_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ(3));
|
||||
}
|
||||
|
||||
static void ar913x_ip3_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ(3));
|
||||
}
|
||||
|
||||
static void ar933x_ip3_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ(3));
|
||||
}
|
||||
|
||||
static void ar934x_ip3_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ(3));
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
|
@ -286,16 +350,21 @@ void __init arch_init_irq(void)
|
|||
ath79_ip2_handler = ar933x_ip2_handler;
|
||||
ath79_ip3_handler = ar933x_ip3_handler;
|
||||
} else if (soc_is_ar934x()) {
|
||||
ath79_ip2_handler = ar934x_ip2_handler;
|
||||
ath79_ip2_handler = ath79_default_ip2_handler;
|
||||
ath79_ip3_handler = ar934x_ip3_handler;
|
||||
} else if (soc_is_qca955x()) {
|
||||
ath79_ip2_handler = ath79_default_ip2_handler;
|
||||
ath79_ip3_handler = ath79_default_ip3_handler;
|
||||
} else {
|
||||
BUG();
|
||||
}
|
||||
|
||||
cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC;
|
||||
cp0_perfcount_irq = ATH79_MISC_IRQ(5);
|
||||
mips_cpu_irq_init();
|
||||
ath79_misc_irq_init();
|
||||
|
||||
if (soc_is_ar934x())
|
||||
ar934x_ip2_irq_init();
|
||||
else if (soc_is_qca955x())
|
||||
qca955x_irq_init();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Qualcomm Atheros AP136 reference board support
|
||||
*
|
||||
* Copyright (c) 2012 Qualcomm Atheros
|
||||
* Copyright (c) 2012-2013 Gabor Juhos <juhosg@openwrt.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/ath9k_platform.h>
|
||||
|
||||
#include "machtypes.h"
|
||||
#include "dev-gpio-buttons.h"
|
||||
#include "dev-leds-gpio.h"
|
||||
#include "dev-spi.h"
|
||||
#include "dev-usb.h"
|
||||
#include "dev-wmac.h"
|
||||
#include "pci.h"
|
||||
|
||||
#define AP136_GPIO_LED_STATUS_RED 14
|
||||
#define AP136_GPIO_LED_STATUS_GREEN 19
|
||||
#define AP136_GPIO_LED_USB 4
|
||||
#define AP136_GPIO_LED_WLAN_2G 13
|
||||
#define AP136_GPIO_LED_WLAN_5G 12
|
||||
#define AP136_GPIO_LED_WPS_RED 15
|
||||
#define AP136_GPIO_LED_WPS_GREEN 20
|
||||
|
||||
#define AP136_GPIO_BTN_WPS 16
|
||||
#define AP136_GPIO_BTN_RFKILL 21
|
||||
|
||||
#define AP136_KEYS_POLL_INTERVAL 20 /* msecs */
|
||||
#define AP136_KEYS_DEBOUNCE_INTERVAL (3 * AP136_KEYS_POLL_INTERVAL)
|
||||
|
||||
#define AP136_WMAC_CALDATA_OFFSET 0x1000
|
||||
#define AP136_PCIE_CALDATA_OFFSET 0x5000
|
||||
|
||||
static struct gpio_led ap136_leds_gpio[] __initdata = {
|
||||
{
|
||||
.name = "qca:green:status",
|
||||
.gpio = AP136_GPIO_LED_STATUS_GREEN,
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.name = "qca:red:status",
|
||||
.gpio = AP136_GPIO_LED_STATUS_RED,
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.name = "qca:green:wps",
|
||||
.gpio = AP136_GPIO_LED_WPS_GREEN,
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.name = "qca:red:wps",
|
||||
.gpio = AP136_GPIO_LED_WPS_RED,
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.name = "qca:red:wlan-2g",
|
||||
.gpio = AP136_GPIO_LED_WLAN_2G,
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.name = "qca:red:usb",
|
||||
.gpio = AP136_GPIO_LED_USB,
|
||||
.active_low = 1,
|
||||
}
|
||||
};
|
||||
|
||||
static struct gpio_keys_button ap136_gpio_keys[] __initdata = {
|
||||
{
|
||||
.desc = "WPS button",
|
||||
.type = EV_KEY,
|
||||
.code = KEY_WPS_BUTTON,
|
||||
.debounce_interval = AP136_KEYS_DEBOUNCE_INTERVAL,
|
||||
.gpio = AP136_GPIO_BTN_WPS,
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.desc = "RFKILL button",
|
||||
.type = EV_KEY,
|
||||
.code = KEY_RFKILL,
|
||||
.debounce_interval = AP136_KEYS_DEBOUNCE_INTERVAL,
|
||||
.gpio = AP136_GPIO_BTN_RFKILL,
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct spi_board_info ap136_spi_info[] = {
|
||||
{
|
||||
.bus_num = 0,
|
||||
.chip_select = 0,
|
||||
.max_speed_hz = 25000000,
|
||||
.modalias = "mx25l6405d",
|
||||
}
|
||||
};
|
||||
|
||||
static struct ath79_spi_platform_data ap136_spi_data = {
|
||||
.bus_num = 0,
|
||||
.num_chipselect = 1,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static struct ath9k_platform_data ap136_ath9k_data;
|
||||
|
||||
static int ap136_pci_plat_dev_init(struct pci_dev *dev)
|
||||
{
|
||||
if (dev->bus->number == 1 && (PCI_SLOT(dev->devfn)) == 0)
|
||||
dev->dev.platform_data = &ap136_ath9k_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init ap136_pci_init(u8 *eeprom)
|
||||
{
|
||||
memcpy(ap136_ath9k_data.eeprom_data, eeprom,
|
||||
sizeof(ap136_ath9k_data.eeprom_data));
|
||||
|
||||
ath79_pci_set_plat_dev_init(ap136_pci_plat_dev_init);
|
||||
ath79_register_pci();
|
||||
}
|
||||
#else
|
||||
static inline void ap136_pci_init(void) {}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
static void __init ap136_setup(void)
|
||||
{
|
||||
u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
|
||||
|
||||
ath79_register_leds_gpio(-1, ARRAY_SIZE(ap136_leds_gpio),
|
||||
ap136_leds_gpio);
|
||||
ath79_register_gpio_keys_polled(-1, AP136_KEYS_POLL_INTERVAL,
|
||||
ARRAY_SIZE(ap136_gpio_keys),
|
||||
ap136_gpio_keys);
|
||||
ath79_register_spi(&ap136_spi_data, ap136_spi_info,
|
||||
ARRAY_SIZE(ap136_spi_info));
|
||||
ath79_register_usb();
|
||||
ath79_register_wmac(art + AP136_WMAC_CALDATA_OFFSET);
|
||||
ap136_pci_init(art + AP136_PCIE_CALDATA_OFFSET);
|
||||
}
|
||||
|
||||
MIPS_MACHINE(ATH79_MACH_AP136_010, "AP136-010",
|
||||
"Atheros AP136-010 reference board",
|
||||
ap136_setup);
|
|
@ -17,6 +17,7 @@
|
|||
enum ath79_mach_type {
|
||||
ATH79_MACH_GENERIC = 0,
|
||||
ATH79_MACH_AP121, /* Atheros AP121 reference board */
|
||||
ATH79_MACH_AP136_010, /* Atheros AP136-010 reference board */
|
||||
ATH79_MACH_AP81, /* Atheros AP81 reference board */
|
||||
ATH79_MACH_DB120, /* Atheros DB120 reference board */
|
||||
ATH79_MACH_PB44, /* Atheros PB44 reference board */
|
||||
|
|
|
@ -14,10 +14,11 @@
|
|||
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/resource.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/mach-ath79/ar71xx_regs.h>
|
||||
#include <asm/mach-ath79/ath79.h>
|
||||
#include <asm/mach-ath79/irq.h>
|
||||
#include <asm/mach-ath79/pci.h>
|
||||
#include "pci.h"
|
||||
|
||||
static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev);
|
||||
|
@ -48,6 +49,21 @@ static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct ath79_pci_irq qca955x_pci_irq_map[] __initconst = {
|
||||
{
|
||||
.bus = 0,
|
||||
.slot = 0,
|
||||
.pin = 1,
|
||||
.irq = ATH79_PCI_IRQ(0),
|
||||
},
|
||||
{
|
||||
.bus = 1,
|
||||
.slot = 0,
|
||||
.pin = 1,
|
||||
.irq = ATH79_PCI_IRQ(1),
|
||||
},
|
||||
};
|
||||
|
||||
int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
|
||||
{
|
||||
int irq = -1;
|
||||
|
@ -63,6 +79,9 @@ int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
|
|||
soc_is_ar9344()) {
|
||||
ath79_pci_irq_map = ar724x_pci_irq_map;
|
||||
ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map);
|
||||
} else if (soc_is_qca955x()) {
|
||||
ath79_pci_irq_map = qca955x_pci_irq_map;
|
||||
ath79_pci_nr_irqs = ARRAY_SIZE(qca955x_pci_irq_map);
|
||||
} else {
|
||||
pr_crit("pci %s: invalid irq map\n",
|
||||
pci_name((struct pci_dev *) dev));
|
||||
|
@ -74,7 +93,9 @@ int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
|
|||
const struct ath79_pci_irq *entry;
|
||||
|
||||
entry = &ath79_pci_irq_map[i];
|
||||
if (entry->slot == slot && entry->pin == pin) {
|
||||
if (entry->bus == dev->bus->number &&
|
||||
entry->slot == slot &&
|
||||
entry->pin == pin) {
|
||||
irq = entry->irq;
|
||||
break;
|
||||
}
|
||||
|
@ -110,21 +131,143 @@ void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev))
|
|||
ath79_pci_plat_dev_init = func;
|
||||
}
|
||||
|
||||
static struct platform_device *
|
||||
ath79_register_pci_ar71xx(void)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct resource res[4];
|
||||
|
||||
memset(res, 0, sizeof(res));
|
||||
|
||||
res[0].name = "cfg_base";
|
||||
res[0].flags = IORESOURCE_MEM;
|
||||
res[0].start = AR71XX_PCI_CFG_BASE;
|
||||
res[0].end = AR71XX_PCI_CFG_BASE + AR71XX_PCI_CFG_SIZE - 1;
|
||||
|
||||
res[1].flags = IORESOURCE_IRQ;
|
||||
res[1].start = ATH79_CPU_IRQ(2);
|
||||
res[1].end = ATH79_CPU_IRQ(2);
|
||||
|
||||
res[2].name = "io_base";
|
||||
res[2].flags = IORESOURCE_IO;
|
||||
res[2].start = 0;
|
||||
res[2].end = 0;
|
||||
|
||||
res[3].name = "mem_base";
|
||||
res[3].flags = IORESOURCE_MEM;
|
||||
res[3].start = AR71XX_PCI_MEM_BASE;
|
||||
res[3].end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1;
|
||||
|
||||
pdev = platform_device_register_simple("ar71xx-pci", -1,
|
||||
res, ARRAY_SIZE(res));
|
||||
return pdev;
|
||||
}
|
||||
|
||||
static struct platform_device *
|
||||
ath79_register_pci_ar724x(int id,
|
||||
unsigned long cfg_base,
|
||||
unsigned long ctrl_base,
|
||||
unsigned long crp_base,
|
||||
unsigned long mem_base,
|
||||
unsigned long mem_size,
|
||||
unsigned long io_base,
|
||||
int irq)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct resource res[6];
|
||||
|
||||
memset(res, 0, sizeof(res));
|
||||
|
||||
res[0].name = "cfg_base";
|
||||
res[0].flags = IORESOURCE_MEM;
|
||||
res[0].start = cfg_base;
|
||||
res[0].end = cfg_base + AR724X_PCI_CFG_SIZE - 1;
|
||||
|
||||
res[1].name = "ctrl_base";
|
||||
res[1].flags = IORESOURCE_MEM;
|
||||
res[1].start = ctrl_base;
|
||||
res[1].end = ctrl_base + AR724X_PCI_CTRL_SIZE - 1;
|
||||
|
||||
res[2].flags = IORESOURCE_IRQ;
|
||||
res[2].start = irq;
|
||||
res[2].end = irq;
|
||||
|
||||
res[3].name = "mem_base";
|
||||
res[3].flags = IORESOURCE_MEM;
|
||||
res[3].start = mem_base;
|
||||
res[3].end = mem_base + mem_size - 1;
|
||||
|
||||
res[4].name = "io_base";
|
||||
res[4].flags = IORESOURCE_IO;
|
||||
res[4].start = io_base;
|
||||
res[4].end = io_base;
|
||||
|
||||
res[5].name = "crp_base";
|
||||
res[5].flags = IORESOURCE_MEM;
|
||||
res[5].start = crp_base;
|
||||
res[5].end = crp_base + AR724X_PCI_CRP_SIZE - 1;
|
||||
|
||||
pdev = platform_device_register_simple("ar724x-pci", id,
|
||||
res, ARRAY_SIZE(res));
|
||||
return pdev;
|
||||
}
|
||||
|
||||
int __init ath79_register_pci(void)
|
||||
{
|
||||
if (soc_is_ar71xx())
|
||||
return ar71xx_pcibios_init();
|
||||
struct platform_device *pdev = NULL;
|
||||
|
||||
if (soc_is_ar724x())
|
||||
return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2);
|
||||
|
||||
if (soc_is_ar9342() || soc_is_ar9344()) {
|
||||
if (soc_is_ar71xx()) {
|
||||
pdev = ath79_register_pci_ar71xx();
|
||||
} else if (soc_is_ar724x()) {
|
||||
pdev = ath79_register_pci_ar724x(-1,
|
||||
AR724X_PCI_CFG_BASE,
|
||||
AR724X_PCI_CTRL_BASE,
|
||||
AR724X_PCI_CRP_BASE,
|
||||
AR724X_PCI_MEM_BASE,
|
||||
AR724X_PCI_MEM_SIZE,
|
||||
0,
|
||||
ATH79_CPU_IRQ(2));
|
||||
} else if (soc_is_ar9342() ||
|
||||
soc_is_ar9344()) {
|
||||
u32 bootstrap;
|
||||
|
||||
bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
|
||||
if (bootstrap & AR934X_BOOTSTRAP_PCIE_RC)
|
||||
return ar724x_pcibios_init(ATH79_IP2_IRQ(0));
|
||||
}
|
||||
if ((bootstrap & AR934X_BOOTSTRAP_PCIE_RC) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
pdev = ath79_register_pci_ar724x(-1,
|
||||
AR724X_PCI_CFG_BASE,
|
||||
AR724X_PCI_CTRL_BASE,
|
||||
AR724X_PCI_CRP_BASE,
|
||||
AR724X_PCI_MEM_BASE,
|
||||
AR724X_PCI_MEM_SIZE,
|
||||
0,
|
||||
ATH79_IP2_IRQ(0));
|
||||
} else if (soc_is_qca9558()) {
|
||||
pdev = ath79_register_pci_ar724x(0,
|
||||
QCA955X_PCI_CFG_BASE0,
|
||||
QCA955X_PCI_CTRL_BASE0,
|
||||
QCA955X_PCI_CRP_BASE0,
|
||||
QCA955X_PCI_MEM_BASE0,
|
||||
QCA955X_PCI_MEM_SIZE,
|
||||
0,
|
||||
ATH79_IP2_IRQ(0));
|
||||
|
||||
pdev = ath79_register_pci_ar724x(1,
|
||||
QCA955X_PCI_CFG_BASE1,
|
||||
QCA955X_PCI_CTRL_BASE1,
|
||||
QCA955X_PCI_CRP_BASE1,
|
||||
QCA955X_PCI_MEM_BASE1,
|
||||
QCA955X_PCI_MEM_SIZE,
|
||||
1,
|
||||
ATH79_IP3_IRQ(2));
|
||||
} else {
|
||||
/* No PCI support */
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!pdev)
|
||||
pr_err("unable to register PCI controller device\n");
|
||||
|
||||
return pdev ? 0 : -ENODEV;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define _ATH79_PCI_H
|
||||
|
||||
struct ath79_pci_irq {
|
||||
int bus;
|
||||
u8 slot;
|
||||
u8 pin;
|
||||
int irq;
|
||||
|
|
|
@ -164,12 +164,28 @@ static void __init ath79_detect_sys_type(void)
|
|||
rev = id & AR934X_REV_ID_REVISION_MASK;
|
||||
break;
|
||||
|
||||
case REV_ID_MAJOR_QCA9556:
|
||||
ath79_soc = ATH79_SOC_QCA9556;
|
||||
chip = "9556";
|
||||
rev = id & QCA955X_REV_ID_REVISION_MASK;
|
||||
break;
|
||||
|
||||
case REV_ID_MAJOR_QCA9558:
|
||||
ath79_soc = ATH79_SOC_QCA9558;
|
||||
chip = "9558";
|
||||
rev = id & QCA955X_REV_ID_REVISION_MASK;
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("ath79: unknown SoC, id:0x%08x", id);
|
||||
}
|
||||
|
||||
ath79_soc_rev = rev;
|
||||
|
||||
if (soc_is_qca955x())
|
||||
sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s rev %u",
|
||||
chip, rev);
|
||||
else
|
||||
sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev);
|
||||
pr_info("SoC: %s\n", ath79_sys_type);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2005 Broadcom Corporation
|
||||
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
|
||||
* Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de>
|
||||
* Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
|
@ -18,83 +18,160 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/mach-bcm47xx/nvram.h>
|
||||
#include <bcm47xx_nvram.h>
|
||||
#include <asm/mach-bcm47xx/bcm47xx.h>
|
||||
|
||||
static char nvram_buf[NVRAM_SPACE];
|
||||
|
||||
/* Probe for NVRAM header */
|
||||
static void early_nvram_init(void)
|
||||
static u32 find_nvram_size(u32 end)
|
||||
{
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
struct ssb_mipscore *mcore_ssb;
|
||||
#endif
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
struct bcma_drv_cc *bcma_cc;
|
||||
#endif
|
||||
struct nvram_header *header;
|
||||
u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000};
|
||||
int i;
|
||||
u32 base = 0;
|
||||
u32 lim = 0;
|
||||
u32 off;
|
||||
u32 *src, *dst;
|
||||
|
||||
switch (bcm47xx_bus_type) {
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
case BCM47XX_BUS_TYPE_SSB:
|
||||
mcore_ssb = &bcm47xx_bus.ssb.mipscore;
|
||||
base = mcore_ssb->pflash.window;
|
||||
lim = mcore_ssb->pflash.window_size;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
case BCM47XX_BUS_TYPE_BCMA:
|
||||
bcma_cc = &bcm47xx_bus.bcma.bus.drv_cc;
|
||||
base = bcma_cc->pflash.window;
|
||||
lim = bcma_cc->pflash.window_size;
|
||||
break;
|
||||
#endif
|
||||
for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
|
||||
header = (struct nvram_header *)KSEG1ADDR(end - nvram_sizes[i]);
|
||||
if (header->magic == NVRAM_HEADER)
|
||||
return nvram_sizes[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Probe for NVRAM header */
|
||||
static int nvram_find_and_copy(u32 base, u32 lim)
|
||||
{
|
||||
struct nvram_header *header;
|
||||
int i;
|
||||
u32 off;
|
||||
u32 *src, *dst;
|
||||
u32 size;
|
||||
|
||||
/* TODO: when nvram is on nand flash check for bad blocks first. */
|
||||
off = FLASH_MIN;
|
||||
while (off <= lim) {
|
||||
/* Windowed flash access */
|
||||
header = (struct nvram_header *)
|
||||
KSEG1ADDR(base + off - NVRAM_SPACE);
|
||||
if (header->magic == NVRAM_HEADER)
|
||||
size = find_nvram_size(base + off);
|
||||
if (size) {
|
||||
header = (struct nvram_header *)KSEG1ADDR(base + off -
|
||||
size);
|
||||
goto found;
|
||||
}
|
||||
off <<= 1;
|
||||
}
|
||||
|
||||
/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
|
||||
header = (struct nvram_header *) KSEG1ADDR(base + 4096);
|
||||
if (header->magic == NVRAM_HEADER)
|
||||
if (header->magic == NVRAM_HEADER) {
|
||||
size = NVRAM_SPACE;
|
||||
goto found;
|
||||
}
|
||||
|
||||
header = (struct nvram_header *) KSEG1ADDR(base + 1024);
|
||||
if (header->magic == NVRAM_HEADER)
|
||||
if (header->magic == NVRAM_HEADER) {
|
||||
size = NVRAM_SPACE;
|
||||
goto found;
|
||||
}
|
||||
|
||||
return;
|
||||
pr_err("no nvram found\n");
|
||||
return -ENXIO;
|
||||
|
||||
found:
|
||||
|
||||
if (header->len > size)
|
||||
pr_err("The nvram size accoridng to the header seems to be bigger than the partition on flash\n");
|
||||
if (header->len > NVRAM_SPACE)
|
||||
pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
|
||||
header->len, NVRAM_SPACE);
|
||||
|
||||
src = (u32 *) header;
|
||||
dst = (u32 *) nvram_buf;
|
||||
for (i = 0; i < sizeof(struct nvram_header); i += 4)
|
||||
*dst++ = *src++;
|
||||
for (; i < header->len && i < NVRAM_SPACE; i += 4)
|
||||
for (; i < header->len && i < NVRAM_SPACE && i < size; i += 4)
|
||||
*dst++ = le32_to_cpu(*src++);
|
||||
memset(dst, 0x0, NVRAM_SPACE - i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nvram_getenv(char *name, char *val, size_t val_len)
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
static int nvram_init_ssb(void)
|
||||
{
|
||||
struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore;
|
||||
u32 base;
|
||||
u32 lim;
|
||||
|
||||
if (mcore->pflash.present) {
|
||||
base = mcore->pflash.window;
|
||||
lim = mcore->pflash.window_size;
|
||||
} else {
|
||||
pr_err("Couldn't find supported flash memory\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return nvram_find_and_copy(base, lim);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
static int nvram_init_bcma(void)
|
||||
{
|
||||
struct bcma_drv_cc *cc = &bcm47xx_bus.bcma.bus.drv_cc;
|
||||
u32 base;
|
||||
u32 lim;
|
||||
|
||||
#ifdef CONFIG_BCMA_NFLASH
|
||||
if (cc->nflash.boot) {
|
||||
base = BCMA_SOC_FLASH1;
|
||||
lim = BCMA_SOC_FLASH1_SZ;
|
||||
} else
|
||||
#endif
|
||||
if (cc->pflash.present) {
|
||||
base = cc->pflash.window;
|
||||
lim = cc->pflash.window_size;
|
||||
#ifdef CONFIG_BCMA_SFLASH
|
||||
} else if (cc->sflash.present) {
|
||||
base = cc->sflash.window;
|
||||
lim = cc->sflash.size;
|
||||
#endif
|
||||
} else {
|
||||
pr_err("Couldn't find supported flash memory\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return nvram_find_and_copy(base, lim);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int nvram_init(void)
|
||||
{
|
||||
switch (bcm47xx_bus_type) {
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
case BCM47XX_BUS_TYPE_SSB:
|
||||
return nvram_init_ssb();
|
||||
#endif
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
case BCM47XX_BUS_TYPE_BCMA:
|
||||
return nvram_init_bcma();
|
||||
#endif
|
||||
}
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len)
|
||||
{
|
||||
char *var, *value, *end, *eq;
|
||||
int err;
|
||||
|
||||
if (!name)
|
||||
return NVRAM_ERR_INV_PARAM;
|
||||
return -EINVAL;
|
||||
|
||||
if (!nvram_buf[0])
|
||||
early_nvram_init();
|
||||
if (!nvram_buf[0]) {
|
||||
err = nvram_init();
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Look for name=value and return value */
|
||||
var = &nvram_buf[sizeof(struct nvram_header)];
|
||||
|
@ -110,6 +187,6 @@ int nvram_getenv(char *name, char *val, size_t val_len)
|
|||
return snprintf(val, val_len, "%s", value);
|
||||
}
|
||||
}
|
||||
return NVRAM_ERR_ENVNOTFOUND;
|
||||
return -ENOENT;
|
||||
}
|
||||
EXPORT_SYMBOL(nvram_getenv);
|
||||
EXPORT_SYMBOL(bcm47xx_nvram_getenv);
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <asm/reboot.h>
|
||||
#include <asm/time.h>
|
||||
#include <bcm47xx.h>
|
||||
#include <asm/mach-bcm47xx/nvram.h>
|
||||
#include <bcm47xx_nvram.h>
|
||||
|
||||
union bcm47xx_bus bcm47xx_bus;
|
||||
EXPORT_SYMBOL(bcm47xx_bus);
|
||||
|
@ -115,7 +115,7 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
|
|||
memset(&iv->sprom, 0, sizeof(struct ssb_sprom));
|
||||
bcm47xx_fill_sprom(&iv->sprom, NULL, false);
|
||||
|
||||
if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
|
||||
if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
|
||||
iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
|
||||
|
||||
return 0;
|
||||
|
@ -138,7 +138,7 @@ static void __init bcm47xx_register_ssb(void)
|
|||
panic("Failed to initialize SSB bus (err %d)", err);
|
||||
|
||||
mcore = &bcm47xx_bus.ssb.mipscore;
|
||||
if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
|
||||
if (bcm47xx_nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
|
||||
if (strstr(buf, "console=ttyS1")) {
|
||||
struct ssb_serial_port port;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <bcm47xx.h>
|
||||
#include <nvram.h>
|
||||
#include <bcm47xx_nvram.h>
|
||||
|
||||
static void create_key(const char *prefix, const char *postfix,
|
||||
const char *name, char *buf, int len)
|
||||
|
@ -50,10 +50,10 @@ static int get_nvram_var(const char *prefix, const char *postfix,
|
|||
|
||||
create_key(prefix, postfix, name, key, sizeof(key));
|
||||
|
||||
err = nvram_getenv(key, buf, len);
|
||||
if (fallback && err == NVRAM_ERR_ENVNOTFOUND && prefix) {
|
||||
err = bcm47xx_nvram_getenv(key, buf, len);
|
||||
if (fallback && err == -ENOENT && prefix) {
|
||||
create_key(NULL, postfix, name, key, sizeof(key));
|
||||
err = nvram_getenv(key, buf, len);
|
||||
err = bcm47xx_nvram_getenv(key, buf, len);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ static void nvram_read_ ## type (const char *prefix, \
|
|||
fallback); \
|
||||
if (err < 0) \
|
||||
return; \
|
||||
err = kstrto ## type (buf, 0, &var); \
|
||||
err = kstrto ## type(strim(buf), 0, &var); \
|
||||
if (err) { \
|
||||
pr_warn("can not parse nvram name %s%s%s with value %s got %i\n", \
|
||||
prefix, name, postfix, buf, err); \
|
||||
|
@ -99,7 +99,7 @@ static void nvram_read_u32_2(const char *prefix, const char *name,
|
|||
err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback);
|
||||
if (err < 0)
|
||||
return;
|
||||
err = kstrtou32(buf, 0, &val);
|
||||
err = kstrtou32(strim(buf), 0, &val);
|
||||
if (err) {
|
||||
pr_warn("can not parse nvram name %s%s with value %s got %i\n",
|
||||
prefix, name, buf, err);
|
||||
|
@ -120,7 +120,7 @@ static void nvram_read_leddc(const char *prefix, const char *name,
|
|||
err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback);
|
||||
if (err < 0)
|
||||
return;
|
||||
err = kstrtou32(buf, 0, &val);
|
||||
err = kstrtou32(strim(buf), 0, &val);
|
||||
if (err) {
|
||||
pr_warn("can not parse nvram name %s%s with value %s got %i\n",
|
||||
prefix, name, buf, err);
|
||||
|
@ -144,7 +144,7 @@ static void nvram_read_macaddr(const char *prefix, const char *name,
|
|||
if (err < 0)
|
||||
return;
|
||||
|
||||
nvram_parse_macaddr(buf, *val);
|
||||
bcm47xx_nvram_parse_macaddr(buf, *val);
|
||||
}
|
||||
|
||||
static void nvram_read_alpha2(const char *prefix, const char *name,
|
||||
|
@ -652,12 +652,10 @@ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
|
|||
static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix,
|
||||
bool fallback)
|
||||
{
|
||||
nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0, true);
|
||||
nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0, true);
|
||||
nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo,
|
||||
&sprom->boardflags_hi, fallback);
|
||||
nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo,
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <bcm63xx_io.h>
|
||||
#include <bcm63xx_regs.h>
|
||||
|
||||
static void __init wait_xfered(void)
|
||||
static void wait_xfered(void)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
|
@ -22,7 +22,7 @@ static void __init wait_xfered(void)
|
|||
} while (1);
|
||||
}
|
||||
|
||||
void __init prom_putchar(char c)
|
||||
void prom_putchar(char c)
|
||||
{
|
||||
wait_xfered();
|
||||
bcm_uart0_writel(c, UART_FIFO_REG);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
CONFIG_ATH79=y
|
||||
CONFIG_ATH79_MACH_AP121=y
|
||||
CONFIG_ATH79_MACH_AP136=y
|
||||
CONFIG_ATH79_MACH_AP81=y
|
||||
CONFIG_ATH79_MACH_DB120=y
|
||||
CONFIG_ATH79_MACH_PB44=y
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
CONFIG_RALINK=y
|
||||
CONFIG_DTB_RT305X_EVAL=y
|
||||
CONFIG_CPU_MIPS32_R2=y
|
||||
# CONFIG_COMPACTION is not set
|
||||
# CONFIG_CROSS_MEMORY_ATTACH is not set
|
||||
CONFIG_HZ_100=y
|
||||
# CONFIG_SECCOMP is not set
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_INITRAMFS_ROOT_UID=1000
|
||||
CONFIG_INITRAMFS_ROOT_GID=1000
|
||||
# CONFIG_RD_GZIP is not set
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
# CONFIG_AIO is not set
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_VM_EVENT_COUNTERS is not set
|
||||
# CONFIG_SLUB_DEBUG is not set
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
# CONFIG_COREDUMP is not set
|
||||
# CONFIG_SUSPEND is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_ROUTE_MULTIPATH=y
|
||||
CONFIG_IP_ROUTE_VERBOSE=y
|
||||
CONFIG_IP_MROUTE=y
|
||||
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
|
||||
CONFIG_ARPD=y
|
||||
CONFIG_SYN_COOKIES=y
|
||||
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
|
||||
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
|
||||
# CONFIG_INET_XFRM_MODE_BEET is not set
|
||||
# CONFIG_INET_LRO is not set
|
||||
# CONFIG_INET_DIAG is not set
|
||||
CONFIG_TCP_CONG_ADVANCED=y
|
||||
# CONFIG_TCP_CONG_BIC is not set
|
||||
# CONFIG_TCP_CONG_WESTWOOD is not set
|
||||
# CONFIG_TCP_CONG_HTCP is not set
|
||||
# CONFIG_IPV6 is not set
|
||||
CONFIG_NETFILTER=y
|
||||
# CONFIG_BRIDGE_NETFILTER is not set
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_IRC=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_STATE=m
|
||||
CONFIG_NF_CONNTRACK_IPV4=m
|
||||
# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
|
||||
CONFIG_IP_NF_IPTABLES=m
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_IP_NF_TARGET_REJECT=m
|
||||
CONFIG_IP_NF_MANGLE=m
|
||||
CONFIG_IP_NF_RAW=m
|
||||
CONFIG_BRIDGE=y
|
||||
# CONFIG_BRIDGE_IGMP_SNOOPING is not set
|
||||
CONFIG_VLAN_8021Q=y
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_HAMRADIO=y
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
# CONFIG_FIRMWARE_IN_KERNEL is not set
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
CONFIG_MTD_CHAR=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
CONFIG_MTD_CFI=y
|
||||
CONFIG_MTD_CFI_AMDSTD=y
|
||||
CONFIG_MTD_COMPLEX_MAPPINGS=y
|
||||
CONFIG_MTD_PHYSMAP=y
|
||||
CONFIG_MTD_PHYSMAP_OF=y
|
||||
CONFIG_MTD_M25P80=y
|
||||
CONFIG_EEPROM_93CX6=m
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_NETDEVICES=y
|
||||
# CONFIG_NET_VENDOR_WIZNET is not set
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PPP=m
|
||||
CONFIG_PPP_FILTER=y
|
||||
CONFIG_PPP_MULTILINK=y
|
||||
CONFIG_PPPOE=m
|
||||
CONFIG_PPP_ASYNC=m
|
||||
CONFIG_ISDN=y
|
||||
CONFIG_INPUT=m
|
||||
CONFIG_INPUT_POLLDEV=m
|
||||
# CONFIG_INPUT_MOUSEDEV is not set
|
||||
# CONFIG_KEYBOARD_ATKBD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_INPUT_MISC=y
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_DEVKMEM is not set
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=2
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
CONFIG_SPI=y
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_WATCHDOG=y
|
||||
# CONFIG_HID is not set
|
||||
# CONFIG_USB_HID is not set
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_STORAGE_DEBUG=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_TRIGGERS=y
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
|
||||
CONFIG_STAGING=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
# CONFIG_DNOTIFY is not set
|
||||
# CONFIG_PROC_PAGE_MONITOR is not set
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_XATTR=y
|
||||
CONFIG_JFFS2_FS=y
|
||||
CONFIG_JFFS2_SUMMARY=y
|
||||
CONFIG_JFFS2_FS_XATTR=y
|
||||
# CONFIG_JFFS2_FS_POSIX_ACL is not set
|
||||
# CONFIG_JFFS2_FS_SECURITY is not set
|
||||
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
|
||||
# CONFIG_JFFS2_ZLIB is not set
|
||||
CONFIG_SQUASHFS=y
|
||||
# CONFIG_SQUASHFS_ZLIB is not set
|
||||
CONFIG_SQUASHFS_XZ=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
# CONFIG_ENABLE_MUST_CHECK is not set
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_STRIP_ASM_SYMS=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
# CONFIG_FTRACE is not set
|
||||
CONFIG_CMDLINE_BOOL=y
|
||||
CONFIG_CRYPTO_MANAGER=m
|
||||
CONFIG_CRYPTO_ARC4=m
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
CONFIG_CRC_ITU_T=m
|
||||
CONFIG_CRC32_SARWATE=y
|
||||
# CONFIG_XZ_DEC_X86 is not set
|
||||
# CONFIG_XZ_DEC_POWERPC is not set
|
||||
# CONFIG_XZ_DEC_IA64 is not set
|
||||
# CONFIG_XZ_DEC_ARM is not set
|
||||
# CONFIG_XZ_DEC_ARMTHUMB is not set
|
||||
# CONFIG_XZ_DEC_SPARC is not set
|
||||
CONFIG_AVERAGE=y
|
|
@ -98,6 +98,9 @@
|
|||
#ifndef cpu_has_rixi
|
||||
#define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI)
|
||||
#endif
|
||||
#ifndef cpu_has_mmips
|
||||
#define cpu_has_mmips (cpu_data[0].options & MIPS_CPU_MICROMIPS)
|
||||
#endif
|
||||
#ifndef cpu_has_vtag_icache
|
||||
#define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
|
||||
#endif
|
||||
|
@ -273,4 +276,8 @@
|
|||
#define cpu_has_perf_cntr_intr_bit (cpu_data[0].options & MIPS_CPU_PCI)
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_vz
|
||||
#define cpu_has_vz (cpu_data[0].ases & MIPS_ASE_VZ)
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_CPU_FEATURES_H */
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
#define PRID_IMP_1004K 0x9900
|
||||
#define PRID_IMP_1074K 0x9a00
|
||||
#define PRID_IMP_M14KC 0x9c00
|
||||
#define PRID_IMP_M14KEC 0x9e00
|
||||
|
||||
/*
|
||||
* These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
|
||||
|
@ -264,6 +265,7 @@ enum cpu_type_enum {
|
|||
CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
|
||||
CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
|
||||
CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC,
|
||||
CPU_M14KEC,
|
||||
|
||||
/*
|
||||
* MIPS64 class processors
|
||||
|
@ -322,6 +324,7 @@ enum cpu_type_enum {
|
|||
#define MIPS_CPU_ULRI 0x00200000 /* CPU has ULRI feature */
|
||||
#define MIPS_CPU_PCI 0x00400000 /* CPU has Perf Ctr Int indicator */
|
||||
#define MIPS_CPU_RIXI 0x00800000 /* CPU has TLB Read/eXec Inhibit */
|
||||
#define MIPS_CPU_MICROMIPS 0x01000000 /* CPU has microMIPS capability */
|
||||
|
||||
/*
|
||||
* CPU ASE encodings
|
||||
|
@ -333,6 +336,6 @@ enum cpu_type_enum {
|
|||
#define MIPS_ASE_DSP 0x00000010 /* Signal Processing ASE */
|
||||
#define MIPS_ASE_MIPSMT 0x00000020 /* CPU supports MIPS MT */
|
||||
#define MIPS_ASE_DSP2P 0x00000040 /* Signal Processing ASE Rev 2 */
|
||||
|
||||
#define MIPS_ASE_VZ 0x00000080 /* Virtualization ASE */
|
||||
|
||||
#endif /* _ASM_CPU_H */
|
||||
|
|
|
@ -359,6 +359,7 @@ struct gic_shared_intr_map {
|
|||
/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
|
||||
#define GIC_PIN_TO_VEC_OFFSET (1)
|
||||
|
||||
extern int gic_present;
|
||||
extern unsigned long _gic_base;
|
||||
extern unsigned int gic_irq_base;
|
||||
extern unsigned int gic_irq_flags[];
|
||||
|
|
|
@ -141,7 +141,7 @@ do { \
|
|||
|
||||
#elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \
|
||||
defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \
|
||||
defined(CONFIG_CPU_R5500)
|
||||
defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_XLR)
|
||||
|
||||
/*
|
||||
* R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
|
||||
|
|
|
@ -17,4 +17,10 @@ extern void mips_cpu_irq_init(void);
|
|||
extern void rm7k_cpu_irq_init(void);
|
||||
extern void rm9k_cpu_irq_init(void);
|
||||
|
||||
#ifdef CONFIG_IRQ_DOMAIN
|
||||
struct device_node;
|
||||
extern int mips_cpu_intc_init(struct device_node *of_node,
|
||||
struct device_node *parent);
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_IRQ_CPU_H */
|
||||
|
|
|
@ -41,11 +41,37 @@
|
|||
#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
|
||||
#define AR71XX_RESET_SIZE 0x100
|
||||
|
||||
#define AR71XX_PCI_MEM_BASE 0x10000000
|
||||
#define AR71XX_PCI_MEM_SIZE 0x07000000
|
||||
|
||||
#define AR71XX_PCI_WIN0_OFFS 0x10000000
|
||||
#define AR71XX_PCI_WIN1_OFFS 0x11000000
|
||||
#define AR71XX_PCI_WIN2_OFFS 0x12000000
|
||||
#define AR71XX_PCI_WIN3_OFFS 0x13000000
|
||||
#define AR71XX_PCI_WIN4_OFFS 0x14000000
|
||||
#define AR71XX_PCI_WIN5_OFFS 0x15000000
|
||||
#define AR71XX_PCI_WIN6_OFFS 0x16000000
|
||||
#define AR71XX_PCI_WIN7_OFFS 0x07000000
|
||||
|
||||
#define AR71XX_PCI_CFG_BASE \
|
||||
(AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000)
|
||||
#define AR71XX_PCI_CFG_SIZE 0x100
|
||||
|
||||
#define AR7240_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000)
|
||||
#define AR7240_USB_CTRL_SIZE 0x100
|
||||
#define AR7240_OHCI_BASE 0x1b000000
|
||||
#define AR7240_OHCI_SIZE 0x1000
|
||||
|
||||
#define AR724X_PCI_MEM_BASE 0x10000000
|
||||
#define AR724X_PCI_MEM_SIZE 0x04000000
|
||||
|
||||
#define AR724X_PCI_CFG_BASE 0x14000000
|
||||
#define AR724X_PCI_CFG_SIZE 0x1000
|
||||
#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000c0000)
|
||||
#define AR724X_PCI_CRP_SIZE 0x1000
|
||||
#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000)
|
||||
#define AR724X_PCI_CTRL_SIZE 0x100
|
||||
|
||||
#define AR724X_EHCI_BASE 0x1b000000
|
||||
#define AR724X_EHCI_SIZE 0x1000
|
||||
|
||||
|
@ -68,6 +94,25 @@
|
|||
#define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000)
|
||||
#define AR934X_SRIF_SIZE 0x1000
|
||||
|
||||
#define QCA955X_PCI_MEM_BASE0 0x10000000
|
||||
#define QCA955X_PCI_MEM_BASE1 0x12000000
|
||||
#define QCA955X_PCI_MEM_SIZE 0x02000000
|
||||
#define QCA955X_PCI_CFG_BASE0 0x14000000
|
||||
#define QCA955X_PCI_CFG_BASE1 0x16000000
|
||||
#define QCA955X_PCI_CFG_SIZE 0x1000
|
||||
#define QCA955X_PCI_CRP_BASE0 (AR71XX_APB_BASE + 0x000c0000)
|
||||
#define QCA955X_PCI_CRP_BASE1 (AR71XX_APB_BASE + 0x00250000)
|
||||
#define QCA955X_PCI_CRP_SIZE 0x1000
|
||||
#define QCA955X_PCI_CTRL_BASE0 (AR71XX_APB_BASE + 0x000f0000)
|
||||
#define QCA955X_PCI_CTRL_BASE1 (AR71XX_APB_BASE + 0x00280000)
|
||||
#define QCA955X_PCI_CTRL_SIZE 0x100
|
||||
|
||||
#define QCA955X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000)
|
||||
#define QCA955X_WMAC_SIZE 0x20000
|
||||
#define QCA955X_EHCI0_BASE 0x1b000000
|
||||
#define QCA955X_EHCI1_BASE 0x1b400000
|
||||
#define QCA955X_EHCI_SIZE 0x1000
|
||||
|
||||
/*
|
||||
* DDR_CTRL block
|
||||
*/
|
||||
|
@ -199,6 +244,41 @@
|
|||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
|
||||
|
||||
#define QCA955X_PLL_CPU_CONFIG_REG 0x00
|
||||
#define QCA955X_PLL_DDR_CONFIG_REG 0x04
|
||||
#define QCA955X_PLL_CLK_CTRL_REG 0x08
|
||||
|
||||
#define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
|
||||
#define QCA955X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f
|
||||
#define QCA955X_PLL_CPU_CONFIG_NINT_SHIFT 6
|
||||
#define QCA955X_PLL_CPU_CONFIG_NINT_MASK 0x3f
|
||||
#define QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
|
||||
#define QCA955X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
|
||||
#define QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
|
||||
#define QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3
|
||||
|
||||
#define QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT 0
|
||||
#define QCA955X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff
|
||||
#define QCA955X_PLL_DDR_CONFIG_NINT_SHIFT 10
|
||||
#define QCA955X_PLL_DDR_CONFIG_NINT_MASK 0x3f
|
||||
#define QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
|
||||
#define QCA955X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
|
||||
#define QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
|
||||
#define QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
|
||||
|
||||
#define QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
|
||||
#define QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
|
||||
#define QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4)
|
||||
#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5
|
||||
#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f
|
||||
#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10
|
||||
#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f
|
||||
#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15
|
||||
#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f
|
||||
#define QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20)
|
||||
#define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
|
||||
#define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
|
||||
|
||||
/*
|
||||
* USB_CONFIG block
|
||||
*/
|
||||
|
@ -238,6 +318,10 @@
|
|||
#define AR934X_RESET_REG_BOOTSTRAP 0xb0
|
||||
#define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac
|
||||
|
||||
#define QCA955X_RESET_REG_RESET_MODULE 0x1c
|
||||
#define QCA955X_RESET_REG_BOOTSTRAP 0xb0
|
||||
#define QCA955X_RESET_REG_EXT_INT_STATUS 0xac
|
||||
|
||||
#define MISC_INT_ETHSW BIT(12)
|
||||
#define MISC_INT_TIMER4 BIT(10)
|
||||
#define MISC_INT_TIMER3 BIT(9)
|
||||
|
@ -315,6 +399,8 @@
|
|||
#define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1)
|
||||
#define AR934X_BOOTSTRAP_DDR1 BIT(0)
|
||||
|
||||
#define QCA955X_BOOTSTRAP_REF_CLK_40 BIT(4)
|
||||
|
||||
#define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0)
|
||||
#define AR934X_PCIE_WMAC_INT_WMAC_TX BIT(1)
|
||||
#define AR934X_PCIE_WMAC_INT_WMAC_RXLP BIT(2)
|
||||
|
@ -333,6 +419,37 @@
|
|||
AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \
|
||||
AR934X_PCIE_WMAC_INT_PCIE_RC3)
|
||||
|
||||
#define QCA955X_EXT_INT_WMAC_MISC BIT(0)
|
||||
#define QCA955X_EXT_INT_WMAC_TX BIT(1)
|
||||
#define QCA955X_EXT_INT_WMAC_RXLP BIT(2)
|
||||
#define QCA955X_EXT_INT_WMAC_RXHP BIT(3)
|
||||
#define QCA955X_EXT_INT_PCIE_RC1 BIT(4)
|
||||
#define QCA955X_EXT_INT_PCIE_RC1_INT0 BIT(5)
|
||||
#define QCA955X_EXT_INT_PCIE_RC1_INT1 BIT(6)
|
||||
#define QCA955X_EXT_INT_PCIE_RC1_INT2 BIT(7)
|
||||
#define QCA955X_EXT_INT_PCIE_RC1_INT3 BIT(8)
|
||||
#define QCA955X_EXT_INT_PCIE_RC2 BIT(12)
|
||||
#define QCA955X_EXT_INT_PCIE_RC2_INT0 BIT(13)
|
||||
#define QCA955X_EXT_INT_PCIE_RC2_INT1 BIT(14)
|
||||
#define QCA955X_EXT_INT_PCIE_RC2_INT2 BIT(15)
|
||||
#define QCA955X_EXT_INT_PCIE_RC2_INT3 BIT(16)
|
||||
#define QCA955X_EXT_INT_USB1 BIT(24)
|
||||
#define QCA955X_EXT_INT_USB2 BIT(28)
|
||||
|
||||
#define QCA955X_EXT_INT_WMAC_ALL \
|
||||
(QCA955X_EXT_INT_WMAC_MISC | QCA955X_EXT_INT_WMAC_TX | \
|
||||
QCA955X_EXT_INT_WMAC_RXLP | QCA955X_EXT_INT_WMAC_RXHP)
|
||||
|
||||
#define QCA955X_EXT_INT_PCIE_RC1_ALL \
|
||||
(QCA955X_EXT_INT_PCIE_RC1 | QCA955X_EXT_INT_PCIE_RC1_INT0 | \
|
||||
QCA955X_EXT_INT_PCIE_RC1_INT1 | QCA955X_EXT_INT_PCIE_RC1_INT2 | \
|
||||
QCA955X_EXT_INT_PCIE_RC1_INT3)
|
||||
|
||||
#define QCA955X_EXT_INT_PCIE_RC2_ALL \
|
||||
(QCA955X_EXT_INT_PCIE_RC2 | QCA955X_EXT_INT_PCIE_RC2_INT0 | \
|
||||
QCA955X_EXT_INT_PCIE_RC2_INT1 | QCA955X_EXT_INT_PCIE_RC2_INT2 | \
|
||||
QCA955X_EXT_INT_PCIE_RC2_INT3)
|
||||
|
||||
#define REV_ID_MAJOR_MASK 0xfff0
|
||||
#define REV_ID_MAJOR_AR71XX 0x00a0
|
||||
#define REV_ID_MAJOR_AR913X 0x00b0
|
||||
|
@ -344,6 +461,8 @@
|
|||
#define REV_ID_MAJOR_AR9341 0x0120
|
||||
#define REV_ID_MAJOR_AR9342 0x1120
|
||||
#define REV_ID_MAJOR_AR9344 0x2120
|
||||
#define REV_ID_MAJOR_QCA9556 0x0130
|
||||
#define REV_ID_MAJOR_QCA9558 0x1130
|
||||
|
||||
#define AR71XX_REV_ID_MINOR_MASK 0x3
|
||||
#define AR71XX_REV_ID_MINOR_AR7130 0x0
|
||||
|
@ -364,6 +483,8 @@
|
|||
|
||||
#define AR934X_REV_ID_REVISION_MASK 0xf
|
||||
|
||||
#define QCA955X_REV_ID_REVISION_MASK 0xf
|
||||
|
||||
/*
|
||||
* SPI block
|
||||
*/
|
||||
|
@ -401,12 +522,15 @@
|
|||
#define AR71XX_GPIO_REG_INT_ENABLE 0x24
|
||||
#define AR71XX_GPIO_REG_FUNC 0x28
|
||||
|
||||
#define AR934X_GPIO_REG_FUNC 0x6c
|
||||
|
||||
#define AR71XX_GPIO_COUNT 16
|
||||
#define AR7240_GPIO_COUNT 18
|
||||
#define AR7241_GPIO_COUNT 20
|
||||
#define AR913X_GPIO_COUNT 22
|
||||
#define AR933X_GPIO_COUNT 30
|
||||
#define AR934X_GPIO_COUNT 23
|
||||
#define QCA955X_GPIO_COUNT 24
|
||||
|
||||
/*
|
||||
* SRIF block
|
||||
|
|
|
@ -32,6 +32,8 @@ enum ath79_soc_type {
|
|||
ATH79_SOC_AR9341,
|
||||
ATH79_SOC_AR9342,
|
||||
ATH79_SOC_AR9344,
|
||||
ATH79_SOC_QCA9556,
|
||||
ATH79_SOC_QCA9558,
|
||||
};
|
||||
|
||||
extern enum ath79_soc_type ath79_soc;
|
||||
|
@ -98,6 +100,21 @@ static inline int soc_is_ar934x(void)
|
|||
return soc_is_ar9341() || soc_is_ar9342() || soc_is_ar9344();
|
||||
}
|
||||
|
||||
static inline int soc_is_qca9556(void)
|
||||
{
|
||||
return ath79_soc == ATH79_SOC_QCA9556;
|
||||
}
|
||||
|
||||
static inline int soc_is_qca9558(void)
|
||||
{
|
||||
return ath79_soc == ATH79_SOC_QCA9558;
|
||||
}
|
||||
|
||||
static inline int soc_is_qca955x(void)
|
||||
{
|
||||
return soc_is_qca9556() || soc_is_qca9558();
|
||||
}
|
||||
|
||||
extern void __iomem *ath79_ddr_base;
|
||||
extern void __iomem *ath79_pll_base;
|
||||
extern void __iomem *ath79_reset_base;
|
||||
|
|
|
@ -10,10 +10,13 @@
|
|||
#define __ASM_MACH_ATH79_IRQ_H
|
||||
|
||||
#define MIPS_CPU_IRQ_BASE 0
|
||||
#define NR_IRQS 48
|
||||
#define NR_IRQS 51
|
||||
|
||||
#define ATH79_CPU_IRQ(_x) (MIPS_CPU_IRQ_BASE + (_x))
|
||||
|
||||
#define ATH79_MISC_IRQ_BASE 8
|
||||
#define ATH79_MISC_IRQ_COUNT 32
|
||||
#define ATH79_MISC_IRQ(_x) (ATH79_MISC_IRQ_BASE + (_x))
|
||||
|
||||
#define ATH79_PCI_IRQ_BASE (ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT)
|
||||
#define ATH79_PCI_IRQ_COUNT 6
|
||||
|
@ -23,25 +26,9 @@
|
|||
#define ATH79_IP2_IRQ_COUNT 2
|
||||
#define ATH79_IP2_IRQ(_x) (ATH79_IP2_IRQ_BASE + (_x))
|
||||
|
||||
#define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2)
|
||||
#define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3)
|
||||
#define ATH79_CPU_IRQ_GE0 (MIPS_CPU_IRQ_BASE + 4)
|
||||
#define ATH79_CPU_IRQ_GE1 (MIPS_CPU_IRQ_BASE + 5)
|
||||
#define ATH79_CPU_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6)
|
||||
#define ATH79_CPU_IRQ_TIMER (MIPS_CPU_IRQ_BASE + 7)
|
||||
|
||||
#define ATH79_MISC_IRQ_TIMER (ATH79_MISC_IRQ_BASE + 0)
|
||||
#define ATH79_MISC_IRQ_ERROR (ATH79_MISC_IRQ_BASE + 1)
|
||||
#define ATH79_MISC_IRQ_GPIO (ATH79_MISC_IRQ_BASE + 2)
|
||||
#define ATH79_MISC_IRQ_UART (ATH79_MISC_IRQ_BASE + 3)
|
||||
#define ATH79_MISC_IRQ_WDOG (ATH79_MISC_IRQ_BASE + 4)
|
||||
#define ATH79_MISC_IRQ_PERFC (ATH79_MISC_IRQ_BASE + 5)
|
||||
#define ATH79_MISC_IRQ_OHCI (ATH79_MISC_IRQ_BASE + 6)
|
||||
#define ATH79_MISC_IRQ_DMA (ATH79_MISC_IRQ_BASE + 7)
|
||||
#define ATH79_MISC_IRQ_TIMER2 (ATH79_MISC_IRQ_BASE + 8)
|
||||
#define ATH79_MISC_IRQ_TIMER3 (ATH79_MISC_IRQ_BASE + 9)
|
||||
#define ATH79_MISC_IRQ_TIMER4 (ATH79_MISC_IRQ_BASE + 10)
|
||||
#define ATH79_MISC_IRQ_ETHSW (ATH79_MISC_IRQ_BASE + 12)
|
||||
#define ATH79_IP3_IRQ_BASE (ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT)
|
||||
#define ATH79_IP3_IRQ_COUNT 3
|
||||
#define ATH79_IP3_IRQ(_x) (ATH79_IP3_IRQ_BASE + (_x))
|
||||
|
||||
#include_next <irq.h>
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Atheros AR71XX/AR724X PCI support
|
||||
*
|
||||
* Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
|
||||
* Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_MACH_ATH79_PCI_H
|
||||
#define __ASM_MACH_ATH79_PCI_H
|
||||
|
||||
#if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR71XX)
|
||||
int ar71xx_pcibios_init(void);
|
||||
#else
|
||||
static inline int ar71xx_pcibios_init(void) { return 0; }
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PCI_AR724X)
|
||||
int ar724x_pcibios_init(int irq);
|
||||
#else
|
||||
static inline int ar724x_pcibios_init(int irq) { return 0; }
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_MACH_ATH79_PCI_H */
|
|
@ -8,8 +8,8 @@
|
|||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __NVRAM_H
|
||||
#define __NVRAM_H
|
||||
#ifndef __BCM47XX_NVRAM_H
|
||||
#define __BCM47XX_NVRAM_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
|
@ -32,12 +32,9 @@ struct nvram_header {
|
|||
#define NVRAM_MAX_VALUE_LEN 255
|
||||
#define NVRAM_MAX_PARAM_LEN 64
|
||||
|
||||
#define NVRAM_ERR_INV_PARAM -8
|
||||
#define NVRAM_ERR_ENVNOTFOUND -9
|
||||
extern int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len);
|
||||
|
||||
extern int nvram_getenv(char *name, char *val, size_t val_len);
|
||||
|
||||
static inline void nvram_parse_macaddr(char *buf, u8 macaddr[6])
|
||||
static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6])
|
||||
{
|
||||
if (strchr(buf, ':'))
|
||||
sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
|
||||
|
@ -51,4 +48,4 @@ static inline void nvram_parse_macaddr(char *buf, u8 macaddr[6])
|
|||
printk(KERN_WARNING "Can not parse mac address: %s\n", buf);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* __BCM47XX_NVRAM_H */
|
|
@ -34,6 +34,7 @@ extern spinlock_t ebu_lock;
|
|||
extern void ltq_disable_irq(struct irq_data *data);
|
||||
extern void ltq_mask_and_ack_irq(struct irq_data *data);
|
||||
extern void ltq_enable_irq(struct irq_data *data);
|
||||
extern int ltq_eiu_get_irq(int exin);
|
||||
|
||||
/* clock handling */
|
||||
extern int clk_activate(struct clk *clk);
|
||||
|
@ -41,6 +42,7 @@ extern void clk_deactivate(struct clk *clk);
|
|||
extern struct clk *clk_get_cpu(void);
|
||||
extern struct clk *clk_get_fpi(void);
|
||||
extern struct clk *clk_get_io(void);
|
||||
extern struct clk *clk_get_ppe(void);
|
||||
|
||||
/* find out what bootsource we have */
|
||||
extern unsigned char ltq_boot_select(void);
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Ralink SoC register definitions
|
||||
*
|
||||
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _RALINK_REGS_H_
|
||||
#define _RALINK_REGS_H_
|
||||
|
||||
extern __iomem void *rt_sysc_membase;
|
||||
extern __iomem void *rt_memc_membase;
|
||||
|
||||
static inline void rt_sysc_w32(u32 val, unsigned reg)
|
||||
{
|
||||
__raw_writel(val, rt_sysc_membase + reg);
|
||||
}
|
||||
|
||||
static inline u32 rt_sysc_r32(unsigned reg)
|
||||
{
|
||||
return __raw_readl(rt_sysc_membase + reg);
|
||||
}
|
||||
|
||||
static inline void rt_memc_w32(u32 val, unsigned reg)
|
||||
{
|
||||
__raw_writel(val, rt_memc_membase + reg);
|
||||
}
|
||||
|
||||
static inline u32 rt_memc_r32(unsigned reg)
|
||||
{
|
||||
return __raw_readl(rt_memc_membase + reg);
|
||||
}
|
||||
|
||||
#endif /* _RALINK_REGS_H_ */
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* Parts of this file are based on Ralink's 2.6.21 BSP
|
||||
*
|
||||
* Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#ifndef _RT305X_REGS_H_
|
||||
#define _RT305X_REGS_H_
|
||||
|
||||
enum rt305x_soc_type {
|
||||
RT305X_SOC_UNKNOWN = 0,
|
||||
RT305X_SOC_RT3050,
|
||||
RT305X_SOC_RT3052,
|
||||
RT305X_SOC_RT3350,
|
||||
RT305X_SOC_RT3352,
|
||||
RT305X_SOC_RT5350,
|
||||
};
|
||||
|
||||
extern enum rt305x_soc_type rt305x_soc;
|
||||
|
||||
static inline int soc_is_rt3050(void)
|
||||
{
|
||||
return rt305x_soc == RT305X_SOC_RT3050;
|
||||
}
|
||||
|
||||
static inline int soc_is_rt3052(void)
|
||||
{
|
||||
return rt305x_soc == RT305X_SOC_RT3052;
|
||||
}
|
||||
|
||||
static inline int soc_is_rt305x(void)
|
||||
{
|
||||
return soc_is_rt3050() || soc_is_rt3052();
|
||||
}
|
||||
|
||||
static inline int soc_is_rt3350(void)
|
||||
{
|
||||
return rt305x_soc == RT305X_SOC_RT3350;
|
||||
}
|
||||
|
||||
static inline int soc_is_rt3352(void)
|
||||
{
|
||||
return rt305x_soc == RT305X_SOC_RT3352;
|
||||
}
|
||||
|
||||
static inline int soc_is_rt5350(void)
|
||||
{
|
||||
return rt305x_soc == RT305X_SOC_RT5350;
|
||||
}
|
||||
|
||||
#define RT305X_SYSC_BASE 0x10000000
|
||||
|
||||
#define SYSC_REG_CHIP_NAME0 0x00
|
||||
#define SYSC_REG_CHIP_NAME1 0x04
|
||||
#define SYSC_REG_CHIP_ID 0x0c
|
||||
#define SYSC_REG_SYSTEM_CONFIG 0x10
|
||||
|
||||
#define RT3052_CHIP_NAME0 0x30335452
|
||||
#define RT3052_CHIP_NAME1 0x20203235
|
||||
|
||||
#define RT3350_CHIP_NAME0 0x33335452
|
||||
#define RT3350_CHIP_NAME1 0x20203035
|
||||
|
||||
#define RT3352_CHIP_NAME0 0x33335452
|
||||
#define RT3352_CHIP_NAME1 0x20203235
|
||||
|
||||
#define RT5350_CHIP_NAME0 0x33355452
|
||||
#define RT5350_CHIP_NAME1 0x20203035
|
||||
|
||||
#define CHIP_ID_ID_MASK 0xff
|
||||
#define CHIP_ID_ID_SHIFT 8
|
||||
#define CHIP_ID_REV_MASK 0xff
|
||||
|
||||
#define RT305X_SYSCFG_CPUCLK_SHIFT 18
|
||||
#define RT305X_SYSCFG_CPUCLK_MASK 0x1
|
||||
#define RT305X_SYSCFG_CPUCLK_LOW 0x0
|
||||
#define RT305X_SYSCFG_CPUCLK_HIGH 0x1
|
||||
|
||||
#define RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT 2
|
||||
#define RT305X_SYSCFG_CPUCLK_MASK 0x1
|
||||
#define RT305X_SYSCFG_SRAM_CS0_MODE_WDT 0x1
|
||||
|
||||
#define RT3352_SYSCFG0_CPUCLK_SHIFT 8
|
||||
#define RT3352_SYSCFG0_CPUCLK_MASK 0x1
|
||||
#define RT3352_SYSCFG0_CPUCLK_LOW 0x0
|
||||
#define RT3352_SYSCFG0_CPUCLK_HIGH 0x1
|
||||
|
||||
#define RT5350_SYSCFG0_CPUCLK_SHIFT 8
|
||||
#define RT5350_SYSCFG0_CPUCLK_MASK 0x3
|
||||
#define RT5350_SYSCFG0_CPUCLK_360 0x0
|
||||
#define RT5350_SYSCFG0_CPUCLK_320 0x2
|
||||
#define RT5350_SYSCFG0_CPUCLK_300 0x3
|
||||
|
||||
/* multi function gpio pins */
|
||||
#define RT305X_GPIO_I2C_SD 1
|
||||
#define RT305X_GPIO_I2C_SCLK 2
|
||||
#define RT305X_GPIO_SPI_EN 3
|
||||
#define RT305X_GPIO_SPI_CLK 4
|
||||
/* GPIO 7-14 is shared between UART0, PCM and I2S interfaces */
|
||||
#define RT305X_GPIO_7 7
|
||||
#define RT305X_GPIO_10 10
|
||||
#define RT305X_GPIO_14 14
|
||||
#define RT305X_GPIO_UART1_TXD 15
|
||||
#define RT305X_GPIO_UART1_RXD 16
|
||||
#define RT305X_GPIO_JTAG_TDO 17
|
||||
#define RT305X_GPIO_JTAG_TDI 18
|
||||
#define RT305X_GPIO_MDIO_MDC 22
|
||||
#define RT305X_GPIO_MDIO_MDIO 23
|
||||
#define RT305X_GPIO_SDRAM_MD16 24
|
||||
#define RT305X_GPIO_SDRAM_MD31 39
|
||||
#define RT305X_GPIO_GE0_TXD0 40
|
||||
#define RT305X_GPIO_GE0_RXCLK 51
|
||||
|
||||
#define RT305X_GPIO_MODE_I2C BIT(0)
|
||||
#define RT305X_GPIO_MODE_SPI BIT(1)
|
||||
#define RT305X_GPIO_MODE_UART0_SHIFT 2
|
||||
#define RT305X_GPIO_MODE_UART0_MASK 0x7
|
||||
#define RT305X_GPIO_MODE_UART0(x) ((x) << RT305X_GPIO_MODE_UART0_SHIFT)
|
||||
#define RT305X_GPIO_MODE_UARTF 0x0
|
||||
#define RT305X_GPIO_MODE_PCM_UARTF 0x1
|
||||
#define RT305X_GPIO_MODE_PCM_I2S 0x2
|
||||
#define RT305X_GPIO_MODE_I2S_UARTF 0x3
|
||||
#define RT305X_GPIO_MODE_PCM_GPIO 0x4
|
||||
#define RT305X_GPIO_MODE_GPIO_UARTF 0x5
|
||||
#define RT305X_GPIO_MODE_GPIO_I2S 0x6
|
||||
#define RT305X_GPIO_MODE_GPIO 0x7
|
||||
#define RT305X_GPIO_MODE_UART1 BIT(5)
|
||||
#define RT305X_GPIO_MODE_JTAG BIT(6)
|
||||
#define RT305X_GPIO_MODE_MDIO BIT(7)
|
||||
#define RT305X_GPIO_MODE_SDRAM BIT(8)
|
||||
#define RT305X_GPIO_MODE_RGMII BIT(9)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
|
||||
*/
|
||||
#ifndef __ASM_MACH_RALINK_WAR_H
|
||||
#define __ASM_MACH_RALINK_WAR_H
|
||||
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
#define MIPS_CACHE_SYNC_WAR 0
|
||||
#define TX49XX_ICACHE_INDEX_INV_WAR 0
|
||||
#define RM9000_CDEX_SMP_WAR 0
|
||||
#define ICACHE_REFILLS_WORKAROUND_WAR 0
|
||||
#define R10000_LLSC_WAR 0
|
||||
#define MIPS34K_MISSED_ITLB_WAR 0
|
||||
|
||||
#endif /* __ASM_MACH_RALINK_WAR_H */
|
|
@ -1,21 +1,14 @@
|
|||
/*
|
||||
* Carsten Langgaard, carstenl@mips.com
|
||||
* Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can distribute it and/or modify it
|
||||
* under the terms of the GNU General Public License (Version 2) as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
*
|
||||
* Defines of the MIPS boards specific address-MAP, registers, etc.
|
||||
*
|
||||
* Copyright (C) 2000,2012 MIPS Technologies, Inc.
|
||||
* All rights reserved.
|
||||
* Authors: Carsten Langgaard <carstenl@mips.com>
|
||||
* Steven J. Hill <sjhill@mips.com>
|
||||
*/
|
||||
#ifndef __ASM_MIPS_BOARDS_GENERIC_H
|
||||
#define __ASM_MIPS_BOARDS_GENERIC_H
|
||||
|
@ -30,13 +23,6 @@
|
|||
#define ASCII_DISPLAY_WORD_BASE 0x1f000410
|
||||
#define ASCII_DISPLAY_POS_BASE 0x1f000418
|
||||
|
||||
|
||||
/*
|
||||
* Yamon Prom print address.
|
||||
*/
|
||||
#define YAMON_PROM_PRINT_ADDR 0x1fc00504
|
||||
|
||||
|
||||
/*
|
||||
* Reset register.
|
||||
*/
|
||||
|
|
|
@ -595,6 +595,8 @@
|
|||
#define MIPS_CONF3_DSP2P (_ULCAST_(1) << 11)
|
||||
#define MIPS_CONF3_RXI (_ULCAST_(1) << 12)
|
||||
#define MIPS_CONF3_ULRI (_ULCAST_(1) << 13)
|
||||
#define MIPS_CONF3_ISA (_ULCAST_(3) << 14)
|
||||
#define MIPS_CONF3_VZ (_ULCAST_(1) << 23)
|
||||
|
||||
#define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0)
|
||||
#define MIPS_CONF4_MMUEXTDEF (_ULCAST_(3) << 14)
|
||||
|
@ -1158,6 +1160,136 @@ do { \
|
|||
__res; \
|
||||
})
|
||||
|
||||
#ifdef HAVE_AS_DSP
|
||||
#define rddsp(mask) \
|
||||
({ \
|
||||
unsigned int __dspctl; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" rddsp %0, %x1 \n" \
|
||||
: "=r" (__dspctl) \
|
||||
: "i" (mask)); \
|
||||
__dspctl; \
|
||||
})
|
||||
|
||||
#define wrdsp(val, mask) \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" wrdsp %0, %x1 \n" \
|
||||
: \
|
||||
: "r" (val), "i" (mask)); \
|
||||
} while (0)
|
||||
|
||||
#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;})
|
||||
#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;})
|
||||
#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;})
|
||||
#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;})
|
||||
|
||||
#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;})
|
||||
#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;})
|
||||
#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;})
|
||||
#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;})
|
||||
|
||||
#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x))
|
||||
#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x))
|
||||
#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x))
|
||||
#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x))
|
||||
|
||||
#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x))
|
||||
#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x))
|
||||
#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x))
|
||||
#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x))
|
||||
|
||||
#else
|
||||
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
#define rddsp(mask) \
|
||||
({ \
|
||||
unsigned int __res; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" # rddsp $1, %x1 \n" \
|
||||
" .hword ((0x0020067c | (%x1 << 14)) >> 16) \n" \
|
||||
" .hword ((0x0020067c | (%x1 << 14)) & 0xffff) \n" \
|
||||
" move %0, $1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (__res) \
|
||||
: "i" (mask)); \
|
||||
__res; \
|
||||
})
|
||||
|
||||
#define wrdsp(val, mask) \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" move $1, %0 \n" \
|
||||
" # wrdsp $1, %x1 \n" \
|
||||
" .hword ((0x0020167c | (%x1 << 14)) >> 16) \n" \
|
||||
" .hword ((0x0020167c | (%x1 << 14)) & 0xffff) \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (val), "i" (mask)); \
|
||||
} while (0)
|
||||
|
||||
#define _umips_dsp_mfxxx(ins) \
|
||||
({ \
|
||||
unsigned long __treg; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" .hword 0x0001 \n" \
|
||||
" .hword %x1 \n" \
|
||||
" move %0, $1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (__treg) \
|
||||
: "i" (ins)); \
|
||||
__treg; \
|
||||
})
|
||||
|
||||
#define _umips_dsp_mtxxx(val, ins) \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" move $1, %0 \n" \
|
||||
" .hword 0x0001 \n" \
|
||||
" .hword %x1 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (val), "i" (ins)); \
|
||||
} while (0)
|
||||
|
||||
#define _umips_dsp_mflo(reg) _umips_dsp_mfxxx((reg << 14) | 0x107c)
|
||||
#define _umips_dsp_mfhi(reg) _umips_dsp_mfxxx((reg << 14) | 0x007c)
|
||||
|
||||
#define _umips_dsp_mtlo(val, reg) _umips_dsp_mtxxx(val, ((reg << 14) | 0x307c))
|
||||
#define _umips_dsp_mthi(val, reg) _umips_dsp_mtxxx(val, ((reg << 14) | 0x207c))
|
||||
|
||||
#define mflo0() _umips_dsp_mflo(0)
|
||||
#define mflo1() _umips_dsp_mflo(1)
|
||||
#define mflo2() _umips_dsp_mflo(2)
|
||||
#define mflo3() _umips_dsp_mflo(3)
|
||||
|
||||
#define mfhi0() _umips_dsp_mfhi(0)
|
||||
#define mfhi1() _umips_dsp_mfhi(1)
|
||||
#define mfhi2() _umips_dsp_mfhi(2)
|
||||
#define mfhi3() _umips_dsp_mfhi(3)
|
||||
|
||||
#define mtlo0(x) _umips_dsp_mtlo(x, 0)
|
||||
#define mtlo1(x) _umips_dsp_mtlo(x, 1)
|
||||
#define mtlo2(x) _umips_dsp_mtlo(x, 2)
|
||||
#define mtlo3(x) _umips_dsp_mtlo(x, 3)
|
||||
|
||||
#define mthi0(x) _umips_dsp_mthi(x, 0)
|
||||
#define mthi1(x) _umips_dsp_mthi(x, 1)
|
||||
#define mthi2(x) _umips_dsp_mthi(x, 2)
|
||||
#define mthi3(x) _umips_dsp_mthi(x, 3)
|
||||
|
||||
#else /* !CONFIG_CPU_MICROMIPS */
|
||||
#define rddsp(mask) \
|
||||
({ \
|
||||
unsigned int __res; \
|
||||
|
@ -1187,253 +1319,60 @@ do { \
|
|||
: "r" (val), "i" (mask)); \
|
||||
} while (0)
|
||||
|
||||
#if 0 /* Need DSP ASE capable assembler ... */
|
||||
#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;})
|
||||
#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;})
|
||||
#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;})
|
||||
#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;})
|
||||
|
||||
#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;})
|
||||
#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;})
|
||||
#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;})
|
||||
#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;})
|
||||
|
||||
#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x))
|
||||
#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x))
|
||||
#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x))
|
||||
#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x))
|
||||
|
||||
#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x))
|
||||
#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x))
|
||||
#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x))
|
||||
#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x))
|
||||
|
||||
#else
|
||||
|
||||
#define mfhi0() \
|
||||
#define _dsp_mfxxx(ins) \
|
||||
({ \
|
||||
unsigned long __treg; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" # mfhi %0, $ac0 \n" \
|
||||
" .word 0x00000810 \n" \
|
||||
" .word (0x00000810 | %1) \n" \
|
||||
" move %0, $1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (__treg)); \
|
||||
: "=r" (__treg) \
|
||||
: "i" (ins)); \
|
||||
__treg; \
|
||||
})
|
||||
|
||||
#define mfhi1() \
|
||||
({ \
|
||||
unsigned long __treg; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" # mfhi %0, $ac1 \n" \
|
||||
" .word 0x00200810 \n" \
|
||||
" move %0, $1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (__treg)); \
|
||||
__treg; \
|
||||
})
|
||||
|
||||
#define mfhi2() \
|
||||
({ \
|
||||
unsigned long __treg; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" # mfhi %0, $ac2 \n" \
|
||||
" .word 0x00400810 \n" \
|
||||
" move %0, $1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (__treg)); \
|
||||
__treg; \
|
||||
})
|
||||
|
||||
#define mfhi3() \
|
||||
({ \
|
||||
unsigned long __treg; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" # mfhi %0, $ac3 \n" \
|
||||
" .word 0x00600810 \n" \
|
||||
" move %0, $1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (__treg)); \
|
||||
__treg; \
|
||||
})
|
||||
|
||||
#define mflo0() \
|
||||
({ \
|
||||
unsigned long __treg; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" # mflo %0, $ac0 \n" \
|
||||
" .word 0x00000812 \n" \
|
||||
" move %0, $1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (__treg)); \
|
||||
__treg; \
|
||||
})
|
||||
|
||||
#define mflo1() \
|
||||
({ \
|
||||
unsigned long __treg; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" # mflo %0, $ac1 \n" \
|
||||
" .word 0x00200812 \n" \
|
||||
" move %0, $1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (__treg)); \
|
||||
__treg; \
|
||||
})
|
||||
|
||||
#define mflo2() \
|
||||
({ \
|
||||
unsigned long __treg; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" # mflo %0, $ac2 \n" \
|
||||
" .word 0x00400812 \n" \
|
||||
" move %0, $1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (__treg)); \
|
||||
__treg; \
|
||||
})
|
||||
|
||||
#define mflo3() \
|
||||
({ \
|
||||
unsigned long __treg; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" # mflo %0, $ac3 \n" \
|
||||
" .word 0x00600812 \n" \
|
||||
" move %0, $1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (__treg)); \
|
||||
__treg; \
|
||||
})
|
||||
|
||||
#define mthi0(x) \
|
||||
#define _dsp_mtxxx(val, ins) \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" move $1, %0 \n" \
|
||||
" # mthi $1, $ac0 \n" \
|
||||
" .word 0x00200011 \n" \
|
||||
" .word (0x00200011 | %1) \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
: "r" (val), "i" (ins)); \
|
||||
} while (0)
|
||||
|
||||
#define mthi1(x) \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" move $1, %0 \n" \
|
||||
" # mthi $1, $ac1 \n" \
|
||||
" .word 0x00200811 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
} while (0)
|
||||
#define _dsp_mflo(reg) _dsp_mfxxx((reg << 21) | 0x0002)
|
||||
#define _dsp_mfhi(reg) _dsp_mfxxx((reg << 21) | 0x0000)
|
||||
|
||||
#define mthi2(x) \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" move $1, %0 \n" \
|
||||
" # mthi $1, $ac2 \n" \
|
||||
" .word 0x00201011 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
} while (0)
|
||||
#define _dsp_mtlo(val, reg) _dsp_mtxxx(val, ((reg << 11) | 0x0002))
|
||||
#define _dsp_mthi(val, reg) _dsp_mtxxx(val, ((reg << 11) | 0x0000))
|
||||
|
||||
#define mthi3(x) \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" move $1, %0 \n" \
|
||||
" # mthi $1, $ac3 \n" \
|
||||
" .word 0x00201811 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
} while (0)
|
||||
#define mflo0() _dsp_mflo(0)
|
||||
#define mflo1() _dsp_mflo(1)
|
||||
#define mflo2() _dsp_mflo(2)
|
||||
#define mflo3() _dsp_mflo(3)
|
||||
|
||||
#define mtlo0(x) \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" move $1, %0 \n" \
|
||||
" # mtlo $1, $ac0 \n" \
|
||||
" .word 0x00200013 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
} while (0)
|
||||
#define mfhi0() _dsp_mfhi(0)
|
||||
#define mfhi1() _dsp_mfhi(1)
|
||||
#define mfhi2() _dsp_mfhi(2)
|
||||
#define mfhi3() _dsp_mfhi(3)
|
||||
|
||||
#define mtlo1(x) \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" move $1, %0 \n" \
|
||||
" # mtlo $1, $ac1 \n" \
|
||||
" .word 0x00200813 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
} while (0)
|
||||
#define mtlo0(x) _dsp_mtlo(x, 0)
|
||||
#define mtlo1(x) _dsp_mtlo(x, 1)
|
||||
#define mtlo2(x) _dsp_mtlo(x, 2)
|
||||
#define mtlo3(x) _dsp_mtlo(x, 3)
|
||||
|
||||
#define mtlo2(x) \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" move $1, %0 \n" \
|
||||
" # mtlo $1, $ac2 \n" \
|
||||
" .word 0x00201013 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
} while (0)
|
||||
|
||||
#define mtlo3(x) \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" move $1, %0 \n" \
|
||||
" # mtlo $1, $ac3 \n" \
|
||||
" .word 0x00201813 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
} while (0)
|
||||
#define mthi0(x) _dsp_mthi(x, 0)
|
||||
#define mthi1(x) _dsp_mthi(x, 1)
|
||||
#define mthi2(x) _dsp_mthi(x, 2)
|
||||
#define mthi3(x) _dsp_mthi(x, 3)
|
||||
|
||||
#endif /* CONFIG_CPU_MICROMIPS */
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -68,6 +68,85 @@ do { \
|
|||
__write_64bit_c0_register($9, 7, (val)); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Handling the 64 bit EIMR and EIRR registers in 32-bit mode with
|
||||
* standard functions will be very inefficient. This provides
|
||||
* optimized functions for the normal operations on the registers.
|
||||
*
|
||||
* Call with interrupts disabled.
|
||||
*/
|
||||
static inline void ack_c0_eirr(int irq)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
".set push\n\t"
|
||||
".set mips64\n\t"
|
||||
".set noat\n\t"
|
||||
"li $1, 1\n\t"
|
||||
"dsllv $1, $1, %0\n\t"
|
||||
"dmtc0 $1, $9, 6\n\t"
|
||||
".set pop"
|
||||
: : "r" (irq));
|
||||
}
|
||||
|
||||
static inline void set_c0_eimr(int irq)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
".set push\n\t"
|
||||
".set mips64\n\t"
|
||||
".set noat\n\t"
|
||||
"li $1, 1\n\t"
|
||||
"dsllv %0, $1, %0\n\t"
|
||||
"dmfc0 $1, $9, 7\n\t"
|
||||
"or $1, %0\n\t"
|
||||
"dmtc0 $1, $9, 7\n\t"
|
||||
".set pop"
|
||||
: "+r" (irq));
|
||||
}
|
||||
|
||||
static inline void clear_c0_eimr(int irq)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
".set push\n\t"
|
||||
".set mips64\n\t"
|
||||
".set noat\n\t"
|
||||
"li $1, 1\n\t"
|
||||
"dsllv %0, $1, %0\n\t"
|
||||
"dmfc0 $1, $9, 7\n\t"
|
||||
"or $1, %0\n\t"
|
||||
"xor $1, %0\n\t"
|
||||
"dmtc0 $1, $9, 7\n\t"
|
||||
".set pop"
|
||||
: "+r" (irq));
|
||||
}
|
||||
|
||||
/*
|
||||
* Read c0 eimr and c0 eirr, do AND of the two values, the result is
|
||||
* the interrupts which are raised and are not masked.
|
||||
*/
|
||||
static inline uint64_t read_c0_eirr_and_eimr(void)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
val = read_c0_eimr() & read_c0_eirr();
|
||||
#else
|
||||
__asm__ __volatile__(
|
||||
".set push\n\t"
|
||||
".set mips64\n\t"
|
||||
".set noat\n\t"
|
||||
"dmfc0 %M0, $9, 6\n\t"
|
||||
"dmfc0 %L0, $9, 7\n\t"
|
||||
"and %M0, %L0\n\t"
|
||||
"dsll %L0, %M0, 32\n\t"
|
||||
"dsra %M0, %M0, 32\n\t"
|
||||
"dsra %L0, %L0, 32\n\t"
|
||||
".set pop"
|
||||
: "=r" (val));
|
||||
#endif
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline int hard_smp_processor_id(void)
|
||||
{
|
||||
return __read_32bit_c0_register($15, 1) & 0x3ff;
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#define CPU_BLOCKID_FPU 9
|
||||
#define CPU_BLOCKID_MAP 10
|
||||
|
||||
#define ICU_DEFEATURE 0x100
|
||||
|
||||
#define LSU_DEFEATURE 0x304
|
||||
#define LSU_DEBUG_ADDR 0x305
|
||||
#define LSU_DEBUG_DATA0 0x306
|
||||
|
|
|
@ -261,6 +261,8 @@
|
|||
#define PIC_LOCAL_SCHEDULING 1
|
||||
#define PIC_GLOBAL_SCHEDULING 0
|
||||
|
||||
#define PIC_CLK_HZ 133333333
|
||||
|
||||
#define nlm_read_pic_reg(b, r) nlm_read_reg64(b, r)
|
||||
#define nlm_write_pic_reg(b, r, v) nlm_write_reg64(b, r, v)
|
||||
#define nlm_get_pic_pcibase(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node))
|
||||
|
@ -315,6 +317,12 @@ nlm_pic_read_timer(uint64_t base, int timer)
|
|||
return nlm_read_pic_reg(base, PIC_TIMER_COUNT(timer));
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
nlm_pic_read_timer32(uint64_t base, int timer)
|
||||
{
|
||||
return (uint32_t)nlm_read_pic_reg(base, PIC_TIMER_COUNT(timer));
|
||||
}
|
||||
|
||||
static inline void
|
||||
nlm_pic_write_timer(uint64_t base, int timer, uint64_t value)
|
||||
{
|
||||
|
@ -376,9 +384,9 @@ nlm_pic_ack(uint64_t base, int irt_num)
|
|||
}
|
||||
|
||||
static inline void
|
||||
nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt)
|
||||
nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt, int en)
|
||||
{
|
||||
nlm_pic_write_irt_direct(base, irt, 0, 0, 0, irq, hwt);
|
||||
nlm_pic_write_irt_direct(base, irt, en, 0, 0, irq, hwt);
|
||||
}
|
||||
|
||||
int nlm_irq_to_irt(int irq);
|
||||
|
|
|
@ -35,10 +35,11 @@
|
|||
#ifndef _ASM_NLM_XLR_PIC_H
|
||||
#define _ASM_NLM_XLR_PIC_H
|
||||
|
||||
#define PIC_CLKS_PER_SEC 66666666ULL
|
||||
#define PIC_CLK_HZ 66666666
|
||||
/* PIC hardware interrupt numbers */
|
||||
#define PIC_IRT_WD_INDEX 0
|
||||
#define PIC_IRT_TIMER_0_INDEX 1
|
||||
#define PIC_IRT_TIMER_INDEX(i) ((i) + PIC_IRT_TIMER_0_INDEX)
|
||||
#define PIC_IRT_TIMER_1_INDEX 2
|
||||
#define PIC_IRT_TIMER_2_INDEX 3
|
||||
#define PIC_IRT_TIMER_3_INDEX 4
|
||||
|
@ -99,6 +100,7 @@
|
|||
|
||||
/* PIC Registers */
|
||||
#define PIC_CTRL 0x00
|
||||
#define PIC_CTRL_STE 8 /* timer enable start bit */
|
||||
#define PIC_IPI 0x04
|
||||
#define PIC_INT_ACK 0x06
|
||||
|
||||
|
@ -251,12 +253,52 @@ nlm_pic_ack(uint64_t base, int irt)
|
|||
}
|
||||
|
||||
static inline void
|
||||
nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt)
|
||||
nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt, int en)
|
||||
{
|
||||
nlm_write_reg(base, PIC_IRT_0(irt), (1u << hwt));
|
||||
/* local scheduling, invalid, level by default */
|
||||
nlm_write_reg(base, PIC_IRT_1(irt),
|
||||
(1 << 30) | (1 << 6) | irq);
|
||||
(en << 30) | (1 << 6) | irq);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
nlm_pic_read_timer(uint64_t base, int timer)
|
||||
{
|
||||
uint32_t up1, up2, low;
|
||||
|
||||
up1 = nlm_read_reg(base, PIC_TIMER_COUNT_1(timer));
|
||||
low = nlm_read_reg(base, PIC_TIMER_COUNT_0(timer));
|
||||
up2 = nlm_read_reg(base, PIC_TIMER_COUNT_1(timer));
|
||||
|
||||
if (up1 != up2) /* wrapped, get the new low */
|
||||
low = nlm_read_reg(base, PIC_TIMER_COUNT_0(timer));
|
||||
return ((uint64_t)up2 << 32) | low;
|
||||
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
nlm_pic_read_timer32(uint64_t base, int timer)
|
||||
{
|
||||
return nlm_read_reg(base, PIC_TIMER_COUNT_0(timer));
|
||||
}
|
||||
|
||||
static inline void
|
||||
nlm_pic_set_timer(uint64_t base, int timer, uint64_t value, int irq, int cpu)
|
||||
{
|
||||
uint32_t up, low;
|
||||
uint64_t pic_ctrl = nlm_read_reg(base, PIC_CTRL);
|
||||
int en;
|
||||
|
||||
en = (irq > 0);
|
||||
up = value >> 32;
|
||||
low = value & 0xFFFFFFFF;
|
||||
nlm_write_reg(base, PIC_TIMER_MAXVAL_0(timer), low);
|
||||
nlm_write_reg(base, PIC_TIMER_MAXVAL_1(timer), up);
|
||||
nlm_pic_init_irt(base, PIC_IRT_TIMER_INDEX(timer), irq, cpu, 0);
|
||||
|
||||
/* enable the timer */
|
||||
pic_ctrl |= (1 << (PIC_CTRL_STE + timer));
|
||||
nlm_write_reg(base, PIC_CTRL, pic_ctrl);
|
||||
}
|
||||
#endif
|
||||
#endif /* _ASM_NLM_XLR_PIC_H */
|
||||
|
|
|
@ -144,8 +144,13 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
|
|||
|
||||
extern char * (*pcibios_plat_setup)(char *str);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/* this function parses memory ranges from a device node */
|
||||
extern void pci_load_of_ranges(struct pci_controller *hose,
|
||||
struct device_node *node);
|
||||
#else
|
||||
static inline void pci_load_of_ranges(struct pci_controller *hose,
|
||||
struct device_node *node) {}
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_PCI_H */
|
||||
|
|
|
@ -75,7 +75,7 @@ extern int init_r4k_clocksource(void);
|
|||
|
||||
static inline int init_mips_clocksource(void)
|
||||
{
|
||||
#ifdef CONFIG_CSRC_R4K
|
||||
#if defined(CONFIG_CSRC_R4K) && !defined(CONFIG_CSRC_GIC)
|
||||
return init_r4k_clocksource();
|
||||
#else
|
||||
return 0;
|
||||
|
|
|
@ -27,6 +27,7 @@ obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o
|
|||
obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o
|
||||
obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o
|
||||
obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
|
||||
obj-$(CONFIG_CSRC_GIC) += csrc-gic.o
|
||||
obj-$(CONFIG_SYNC_R4K) += sync-r4k.o
|
||||
|
||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||
|
@ -98,4 +99,35 @@ obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_mipsxx.o
|
|||
|
||||
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
|
||||
|
||||
#
|
||||
# DSP ASE supported for MIPS32 or MIPS64 Release 2 cores only. It is safe
|
||||
# to enable DSP assembler support here even if the MIPS Release 2 CPU we
|
||||
# are targetting does not support DSP because all code-paths making use of
|
||||
# it properly check that the running CPU *actually does* support these
|
||||
# instructions.
|
||||
#
|
||||
ifeq ($(CONFIG_CPU_MIPSR2), y)
|
||||
CFLAGS_DSP = -DHAVE_AS_DSP
|
||||
|
||||
#
|
||||
# Check if assembler supports DSP ASE
|
||||
#
|
||||
ifeq ($(call cc-option-yn,-mdsp), y)
|
||||
CFLAGS_DSP += -mdsp
|
||||
endif
|
||||
|
||||
#
|
||||
# Check if assembler supports DSP ASE Rev2
|
||||
#
|
||||
ifeq ($(call cc-option-yn,-mdspr2), y)
|
||||
CFLAGS_DSP += -mdspr2
|
||||
endif
|
||||
|
||||
CFLAGS_signal.o = $(CFLAGS_DSP)
|
||||
CFLAGS_signal32.o = $(CFLAGS_DSP)
|
||||
CFLAGS_process.o = $(CFLAGS_DSP)
|
||||
CFLAGS_branch.o = $(CFLAGS_DSP)
|
||||
CFLAGS_ptrace.o = $(CFLAGS_DSP)
|
||||
endif
|
||||
|
||||
CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
|
||||
|
|
|
@ -201,6 +201,7 @@ void __init check_wait(void)
|
|||
break;
|
||||
|
||||
case CPU_M14KC:
|
||||
case CPU_M14KEC:
|
||||
case CPU_24K:
|
||||
case CPU_34K:
|
||||
case CPU_1004K:
|
||||
|
@ -467,6 +468,10 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
|
|||
c->ases |= MIPS_ASE_MIPSMT;
|
||||
if (config3 & MIPS_CONF3_ULRI)
|
||||
c->options |= MIPS_CPU_ULRI;
|
||||
if (config3 & MIPS_CONF3_ISA)
|
||||
c->options |= MIPS_CPU_MICROMIPS;
|
||||
if (config3 & MIPS_CONF3_VZ)
|
||||
c->ases |= MIPS_ASE_VZ;
|
||||
|
||||
return config3 & MIPS_CONF_M;
|
||||
}
|
||||
|
@ -866,10 +871,13 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
|
|||
__cpu_name[cpu] = "MIPS 20Kc";
|
||||
break;
|
||||
case PRID_IMP_24K:
|
||||
case PRID_IMP_24KE:
|
||||
c->cputype = CPU_24K;
|
||||
__cpu_name[cpu] = "MIPS 24Kc";
|
||||
break;
|
||||
case PRID_IMP_24KE:
|
||||
c->cputype = CPU_24K;
|
||||
__cpu_name[cpu] = "MIPS 24KEc";
|
||||
break;
|
||||
case PRID_IMP_25KF:
|
||||
c->cputype = CPU_25KF;
|
||||
__cpu_name[cpu] = "MIPS 25Kc";
|
||||
|
@ -886,6 +894,10 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
|
|||
c->cputype = CPU_M14KC;
|
||||
__cpu_name[cpu] = "MIPS M14Kc";
|
||||
break;
|
||||
case PRID_IMP_M14KEC:
|
||||
c->cputype = CPU_M14KEC;
|
||||
__cpu_name[cpu] = "MIPS M14KEc";
|
||||
break;
|
||||
case PRID_IMP_1004K:
|
||||
c->cputype = CPU_1004K;
|
||||
__cpu_name[cpu] = "MIPS 1004Kc";
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/gic.h>
|
||||
|
||||
static cycle_t gic_hpt_read(struct clocksource *cs)
|
||||
{
|
||||
unsigned int hi, hi2, lo;
|
||||
|
||||
do {
|
||||
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi);
|
||||
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo);
|
||||
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2);
|
||||
} while (hi2 != hi);
|
||||
|
||||
return (((cycle_t) hi) << 32) + lo;
|
||||
}
|
||||
|
||||
static struct clocksource gic_clocksource = {
|
||||
.name = "GIC",
|
||||
.read = gic_hpt_read,
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
void __init gic_clocksource_init(unsigned int frequency)
|
||||
{
|
||||
unsigned int config, bits;
|
||||
|
||||
/* Calculate the clocksource mask. */
|
||||
GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config);
|
||||
bits = 32 + ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >>
|
||||
(GIC_SH_CONFIG_COUNTBITS_SHF - 2));
|
||||
|
||||
/* Set clocksource mask. */
|
||||
gic_clocksource.mask = CLOCKSOURCE_MASK(bits);
|
||||
|
||||
/* Calculate a somewhat reasonable rating value. */
|
||||
gic_clocksource.rating = 200 + frequency / 10000000;
|
||||
|
||||
clocksource_register_hz(&gic_clocksource, frequency);
|
||||
}
|
|
@ -14,8 +14,7 @@
|
|||
|
||||
extern void prom_putchar(char);
|
||||
|
||||
static void __init
|
||||
early_console_write(struct console *con, const char *s, unsigned n)
|
||||
static void early_console_write(struct console *con, const char *s, unsigned n)
|
||||
{
|
||||
while (n-- && *s) {
|
||||
if (*s == '\n')
|
||||
|
@ -25,7 +24,7 @@ early_console_write(struct console *con, const char *s, unsigned n)
|
|||
}
|
||||
}
|
||||
|
||||
static struct console early_console __initdata = {
|
||||
static struct console early_console = {
|
||||
.name = "early",
|
||||
.write = early_console_write,
|
||||
.flags = CON_PRINTBUFFER | CON_BOOT,
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
|
||||
#include <asm/irq_cpu.h>
|
||||
#include <asm/mipsregs.h>
|
||||
|
@ -113,3 +114,44 @@ void __init mips_cpu_irq_init(void)
|
|||
irq_set_chip_and_handler(i, &mips_cpu_irq_controller,
|
||||
handle_percpu_irq);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IRQ_DOMAIN
|
||||
static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq,
|
||||
irq_hw_number_t hw)
|
||||
{
|
||||
static struct irq_chip *chip;
|
||||
|
||||
if (hw < 2 && cpu_has_mipsmt) {
|
||||
/* Software interrupts are used for MT/CMT IPI */
|
||||
chip = &mips_mt_cpu_irq_controller;
|
||||
} else {
|
||||
chip = &mips_cpu_irq_controller;
|
||||
}
|
||||
|
||||
irq_set_chip_and_handler(irq, chip, handle_percpu_irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = {
|
||||
.map = mips_cpu_intc_map,
|
||||
.xlate = irq_domain_xlate_onecell,
|
||||
};
|
||||
|
||||
int __init mips_cpu_intc_init(struct device_node *of_node,
|
||||
struct device_node *parent)
|
||||
{
|
||||
struct irq_domain *domain;
|
||||
|
||||
/* Mask interrupts. */
|
||||
clear_c0_status(ST0_IM);
|
||||
clear_c0_cause(CAUSEF_IP);
|
||||
|
||||
domain = irq_domain_add_legacy(of_node, 8, MIPS_CPU_IRQ_BASE, 0,
|
||||
&mips_cpu_intc_irq_domain_ops, NULL);
|
||||
if (!domain)
|
||||
panic("Failed to add irqdomain for MIPS CPU\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_IRQ_DOMAIN */
|
||||
|
|
|
@ -95,6 +95,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
|||
if (cpu_has_dsp) seq_printf(m, "%s", " dsp");
|
||||
if (cpu_has_dsp2) seq_printf(m, "%s", " dsp2");
|
||||
if (cpu_has_mipsmt) seq_printf(m, "%s", " mt");
|
||||
if (cpu_has_mmips) seq_printf(m, "%s", " micromips");
|
||||
if (cpu_has_vz) seq_printf(m, "%s", " vz");
|
||||
seq_printf(m, "\n");
|
||||
|
||||
seq_printf(m, "shadow register sets\t: %d\n",
|
||||
|
|
|
@ -480,34 +480,75 @@ static int __init early_parse_mem(char *p)
|
|||
}
|
||||
early_param("mem", early_parse_mem);
|
||||
|
||||
#ifdef CONFIG_PROC_VMCORE
|
||||
unsigned long setup_elfcorehdr, setup_elfcorehdr_size;
|
||||
static int __init early_parse_elfcorehdr(char *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
setup_elfcorehdr = memparse(p, &p);
|
||||
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
unsigned long start = boot_mem_map.map[i].addr;
|
||||
unsigned long end = (boot_mem_map.map[i].addr +
|
||||
boot_mem_map.map[i].size);
|
||||
if (setup_elfcorehdr >= start && setup_elfcorehdr < end) {
|
||||
/*
|
||||
* Reserve from the elf core header to the end of
|
||||
* the memory segment, that should all be kdump
|
||||
* reserved memory.
|
||||
*/
|
||||
setup_elfcorehdr_size = end - setup_elfcorehdr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If we don't find it in the memory map, then we shouldn't
|
||||
* have to worry about it, as the new kernel won't use it.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
early_param("elfcorehdr", early_parse_elfcorehdr);
|
||||
#endif
|
||||
|
||||
static void __init arch_mem_addpart(phys_t mem, phys_t end, int type)
|
||||
{
|
||||
phys_t size;
|
||||
int i;
|
||||
|
||||
size = end - mem;
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
/* Make sure it is in the boot_mem_map */
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
if (mem >= boot_mem_map.map[i].addr &&
|
||||
mem < (boot_mem_map.map[i].addr +
|
||||
boot_mem_map.map[i].size))
|
||||
return;
|
||||
}
|
||||
add_memory_region(mem, size, type);
|
||||
}
|
||||
|
||||
static void __init arch_mem_init(char **cmdline_p)
|
||||
{
|
||||
phys_t init_mem, init_end, init_size;
|
||||
|
||||
extern void plat_mem_setup(void);
|
||||
|
||||
/* call board setup routine */
|
||||
plat_mem_setup();
|
||||
|
||||
init_mem = PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT;
|
||||
init_end = PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT;
|
||||
init_size = init_end - init_mem;
|
||||
if (init_size) {
|
||||
/* Make sure it is in the boot_mem_map */
|
||||
int i, found;
|
||||
found = 0;
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
if (init_mem >= boot_mem_map.map[i].addr &&
|
||||
init_mem < (boot_mem_map.map[i].addr +
|
||||
boot_mem_map.map[i].size)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
add_memory_region(init_mem, init_size,
|
||||
/*
|
||||
* Make sure all kernel memory is in the maps. The "UP" and
|
||||
* "DOWN" are opposite for initdata since if it crosses over
|
||||
* into another memory section you don't want that to be
|
||||
* freed when the initdata is freed.
|
||||
*/
|
||||
arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT,
|
||||
PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT,
|
||||
BOOT_MEM_RAM);
|
||||
arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT,
|
||||
PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT,
|
||||
BOOT_MEM_INIT_RAM);
|
||||
}
|
||||
|
||||
pr_info("Determined physical RAM map:\n");
|
||||
print_memory_map();
|
||||
|
@ -537,6 +578,14 @@ static void __init arch_mem_init(char **cmdline_p)
|
|||
}
|
||||
|
||||
bootmem_init();
|
||||
#ifdef CONFIG_PROC_VMCORE
|
||||
if (setup_elfcorehdr && setup_elfcorehdr_size) {
|
||||
printk(KERN_INFO "kdump reserved memory at %lx-%lx\n",
|
||||
setup_elfcorehdr, setup_elfcorehdr_size);
|
||||
reserve_bootmem(setup_elfcorehdr, setup_elfcorehdr_size,
|
||||
BOOTMEM_DEFAULT);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_KEXEC
|
||||
if (crashk_res.start != crashk_res.end)
|
||||
reserve_bootmem(crashk_res.start,
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <asm/addrspace.h>
|
||||
#include <asm/smtc.h>
|
||||
#include <asm/smtc_proc.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
/*
|
||||
* SMTC Kernel needs to manipulate low-level CPU interrupt mask
|
||||
|
|
|
@ -697,18 +697,7 @@ static int vpe_run(struct vpe * v)
|
|||
dmt_flag = dmt();
|
||||
vpeflags = dvpe();
|
||||
|
||||
if (!list_empty(&v->tc)) {
|
||||
if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
|
||||
evpe(vpeflags);
|
||||
emt(dmt_flag);
|
||||
local_irq_restore(flags);
|
||||
|
||||
printk(KERN_WARNING
|
||||
"VPE loader: TC %d is already in use.\n",
|
||||
v->tc->index);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
} else {
|
||||
if (list_empty(&v->tc)) {
|
||||
evpe(vpeflags);
|
||||
emt(dmt_flag);
|
||||
local_irq_restore(flags);
|
||||
|
@ -720,6 +709,8 @@ static int vpe_run(struct vpe * v)
|
|||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
t = list_first_entry(&v->tc, struct tc, tc);
|
||||
|
||||
/* Put MVPE's into 'configuration state' */
|
||||
set_c0_mvpcontrol(MVPCONTROL_VPC);
|
||||
|
||||
|
|
|
@ -26,13 +26,15 @@
|
|||
#include "prom.h"
|
||||
|
||||
/* lantiq socs have 3 static clocks */
|
||||
static struct clk cpu_clk_generic[3];
|
||||
static struct clk cpu_clk_generic[4];
|
||||
|
||||
void clkdev_add_static(unsigned long cpu, unsigned long fpi, unsigned long io)
|
||||
void clkdev_add_static(unsigned long cpu, unsigned long fpi,
|
||||
unsigned long io, unsigned long ppe)
|
||||
{
|
||||
cpu_clk_generic[0].rate = cpu;
|
||||
cpu_clk_generic[1].rate = fpi;
|
||||
cpu_clk_generic[2].rate = io;
|
||||
cpu_clk_generic[3].rate = ppe;
|
||||
}
|
||||
|
||||
struct clk *clk_get_cpu(void)
|
||||
|
@ -51,6 +53,12 @@ struct clk *clk_get_io(void)
|
|||
return &cpu_clk_generic[2];
|
||||
}
|
||||
|
||||
struct clk *clk_get_ppe(void)
|
||||
{
|
||||
return &cpu_clk_generic[3];
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_get_ppe);
|
||||
|
||||
static inline int clk_good(struct clk *clk)
|
||||
{
|
||||
return clk && !IS_ERR(clk);
|
||||
|
|
|
@ -27,12 +27,15 @@
|
|||
#define CLOCK_167M 166666667
|
||||
#define CLOCK_196_608M 196608000
|
||||
#define CLOCK_200M 200000000
|
||||
#define CLOCK_222M 222000000
|
||||
#define CLOCK_240M 240000000
|
||||
#define CLOCK_250M 250000000
|
||||
#define CLOCK_266M 266666666
|
||||
#define CLOCK_300M 300000000
|
||||
#define CLOCK_333M 333333333
|
||||
#define CLOCK_393M 393215332
|
||||
#define CLOCK_400M 400000000
|
||||
#define CLOCK_450M 450000000
|
||||
#define CLOCK_500M 500000000
|
||||
#define CLOCK_600M 600000000
|
||||
|
||||
|
@ -64,15 +67,17 @@ struct clk {
|
|||
};
|
||||
|
||||
extern void clkdev_add_static(unsigned long cpu, unsigned long fpi,
|
||||
unsigned long io);
|
||||
unsigned long io, unsigned long ppe);
|
||||
|
||||
extern unsigned long ltq_danube_cpu_hz(void);
|
||||
extern unsigned long ltq_danube_fpi_hz(void);
|
||||
extern unsigned long ltq_danube_pp32_hz(void);
|
||||
|
||||
extern unsigned long ltq_ar9_cpu_hz(void);
|
||||
extern unsigned long ltq_ar9_fpi_hz(void);
|
||||
|
||||
extern unsigned long ltq_vr9_cpu_hz(void);
|
||||
extern unsigned long ltq_vr9_fpi_hz(void);
|
||||
extern unsigned long ltq_vr9_pp32_hz(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -241,9 +241,9 @@ void __init ltq_soc_init(void)
|
|||
|
||||
/* get our 3 static rates for cpu, fpi and io clocks */
|
||||
if (ltq_sys1_r32(SYS1_CPU0CC) & CPU0CC_CPUDIV)
|
||||
clkdev_add_static(CLOCK_200M, CLOCK_100M, CLOCK_200M);
|
||||
clkdev_add_static(CLOCK_200M, CLOCK_100M, CLOCK_200M, 0);
|
||||
else
|
||||
clkdev_add_static(CLOCK_400M, CLOCK_100M, CLOCK_200M);
|
||||
clkdev_add_static(CLOCK_400M, CLOCK_100M, CLOCK_200M, 0);
|
||||
|
||||
/* add our clock domains */
|
||||
clkdev_add_sys("1d810000.gpio", SYSCTL_SYSETH, ACTS_P0);
|
||||
|
|
|
@ -33,17 +33,10 @@
|
|||
/* register definitions - external irqs */
|
||||
#define LTQ_EIU_EXIN_C 0x0000
|
||||
#define LTQ_EIU_EXIN_INIC 0x0004
|
||||
#define LTQ_EIU_EXIN_INC 0x0008
|
||||
#define LTQ_EIU_EXIN_INEN 0x000C
|
||||
|
||||
/* irq numbers used by the external interrupt unit (EIU) */
|
||||
#define LTQ_EIU_IR0 (INT_NUM_IM4_IRL0 + 30)
|
||||
#define LTQ_EIU_IR1 (INT_NUM_IM3_IRL0 + 31)
|
||||
#define LTQ_EIU_IR2 (INT_NUM_IM1_IRL0 + 26)
|
||||
#define LTQ_EIU_IR3 INT_NUM_IM1_IRL0
|
||||
#define LTQ_EIU_IR4 (INT_NUM_IM1_IRL0 + 1)
|
||||
#define LTQ_EIU_IR5 (INT_NUM_IM1_IRL0 + 2)
|
||||
#define LTQ_EIU_IR6 (INT_NUM_IM2_IRL0 + 30)
|
||||
#define XWAY_EXIN_COUNT 3
|
||||
/* number of external interrupts */
|
||||
#define MAX_EIU 6
|
||||
|
||||
/* the performance counter */
|
||||
|
@ -72,20 +65,19 @@
|
|||
int gic_present;
|
||||
#endif
|
||||
|
||||
static unsigned short ltq_eiu_irq[MAX_EIU] = {
|
||||
LTQ_EIU_IR0,
|
||||
LTQ_EIU_IR1,
|
||||
LTQ_EIU_IR2,
|
||||
LTQ_EIU_IR3,
|
||||
LTQ_EIU_IR4,
|
||||
LTQ_EIU_IR5,
|
||||
};
|
||||
|
||||
static int exin_avail;
|
||||
static struct resource ltq_eiu_irq[MAX_EIU];
|
||||
static void __iomem *ltq_icu_membase[MAX_IM];
|
||||
static void __iomem *ltq_eiu_membase;
|
||||
static struct irq_domain *ltq_domain;
|
||||
|
||||
int ltq_eiu_get_irq(int exin)
|
||||
{
|
||||
if (exin < exin_avail)
|
||||
return ltq_eiu_irq[exin].start;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ltq_disable_irq(struct irq_data *d)
|
||||
{
|
||||
u32 ier = LTQ_ICU_IM0_IER;
|
||||
|
@ -128,19 +120,65 @@ void ltq_enable_irq(struct irq_data *d)
|
|||
ltq_icu_w32(im, ltq_icu_r32(im, ier) | BIT(offset), ier);
|
||||
}
|
||||
|
||||
static int ltq_eiu_settype(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_EIU; i++) {
|
||||
if (d->hwirq == ltq_eiu_irq[i].start) {
|
||||
int val = 0;
|
||||
int edge = 0;
|
||||
|
||||
switch (type) {
|
||||
case IRQF_TRIGGER_NONE:
|
||||
break;
|
||||
case IRQF_TRIGGER_RISING:
|
||||
val = 1;
|
||||
edge = 1;
|
||||
break;
|
||||
case IRQF_TRIGGER_FALLING:
|
||||
val = 2;
|
||||
edge = 1;
|
||||
break;
|
||||
case IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING:
|
||||
val = 3;
|
||||
edge = 1;
|
||||
break;
|
||||
case IRQF_TRIGGER_HIGH:
|
||||
val = 5;
|
||||
break;
|
||||
case IRQF_TRIGGER_LOW:
|
||||
val = 6;
|
||||
break;
|
||||
default:
|
||||
pr_err("invalid type %d for irq %ld\n",
|
||||
type, d->hwirq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (edge)
|
||||
irq_set_handler(d->hwirq, handle_edge_irq);
|
||||
|
||||
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) |
|
||||
(val << (i * 4)), LTQ_EIU_EXIN_C);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
|
||||
{
|
||||
int i;
|
||||
|
||||
ltq_enable_irq(d);
|
||||
for (i = 0; i < MAX_EIU; i++) {
|
||||
if (d->hwirq == ltq_eiu_irq[i]) {
|
||||
/* low level - we should really handle set_type */
|
||||
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) |
|
||||
(0x6 << (i * 4)), LTQ_EIU_EXIN_C);
|
||||
if (d->hwirq == ltq_eiu_irq[i].start) {
|
||||
/* by default we are low level triggered */
|
||||
ltq_eiu_settype(d, IRQF_TRIGGER_LOW);
|
||||
/* clear all pending */
|
||||
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~BIT(i),
|
||||
LTQ_EIU_EXIN_INIC);
|
||||
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INC) & ~BIT(i),
|
||||
LTQ_EIU_EXIN_INC);
|
||||
/* enable */
|
||||
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | BIT(i),
|
||||
LTQ_EIU_EXIN_INEN);
|
||||
|
@ -157,7 +195,7 @@ static void ltq_shutdown_eiu_irq(struct irq_data *d)
|
|||
|
||||
ltq_disable_irq(d);
|
||||
for (i = 0; i < MAX_EIU; i++) {
|
||||
if (d->hwirq == ltq_eiu_irq[i]) {
|
||||
if (d->hwirq == ltq_eiu_irq[i].start) {
|
||||
/* disable */
|
||||
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~BIT(i),
|
||||
LTQ_EIU_EXIN_INEN);
|
||||
|
@ -186,6 +224,7 @@ static struct irq_chip ltq_eiu_type = {
|
|||
.irq_ack = ltq_ack_irq,
|
||||
.irq_mask = ltq_disable_irq,
|
||||
.irq_mask_ack = ltq_mask_and_ack_irq,
|
||||
.irq_set_type = ltq_eiu_settype,
|
||||
};
|
||||
|
||||
static void ltq_hw_irqdispatch(int module)
|
||||
|
@ -301,7 +340,7 @@ static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
|
|||
return 0;
|
||||
|
||||
for (i = 0; i < exin_avail; i++)
|
||||
if (hw == ltq_eiu_irq[i])
|
||||
if (hw == ltq_eiu_irq[i].start)
|
||||
chip = <q_eiu_type;
|
||||
|
||||
irq_set_chip_and_handler(hw, chip, handle_level_irq);
|
||||
|
@ -323,7 +362,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
|||
{
|
||||
struct device_node *eiu_node;
|
||||
struct resource res;
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < MAX_IM; i++) {
|
||||
if (of_address_to_resource(node, i, &res))
|
||||
|
@ -340,17 +379,19 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
|||
}
|
||||
|
||||
/* the external interrupts are optional and xway only */
|
||||
eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu");
|
||||
eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway");
|
||||
if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
|
||||
/* find out how many external irq sources we have */
|
||||
const __be32 *count = of_get_property(node,
|
||||
"lantiq,count", NULL);
|
||||
exin_avail = of_irq_count(eiu_node);
|
||||
|
||||
if (count)
|
||||
exin_avail = *count;
|
||||
if (exin_avail > MAX_EIU)
|
||||
exin_avail = MAX_EIU;
|
||||
|
||||
ret = of_irq_to_resource_table(eiu_node,
|
||||
ltq_eiu_irq, exin_avail);
|
||||
if (ret != exin_avail)
|
||||
panic("failed to load external irq resources\n");
|
||||
|
||||
if (request_mem_region(res.start, resource_size(&res),
|
||||
res.name) < 0)
|
||||
pr_err("Failed to request eiu memory");
|
||||
|
|
|
@ -53,6 +53,29 @@ unsigned long ltq_danube_cpu_hz(void)
|
|||
}
|
||||
}
|
||||
|
||||
unsigned long ltq_danube_pp32_hz(void)
|
||||
{
|
||||
unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 7) & 3;
|
||||
unsigned long clk;
|
||||
|
||||
switch (clksys) {
|
||||
case 1:
|
||||
clk = CLOCK_240M;
|
||||
break;
|
||||
case 2:
|
||||
clk = CLOCK_222M;
|
||||
break;
|
||||
case 3:
|
||||
clk = CLOCK_133M;
|
||||
break;
|
||||
default:
|
||||
clk = CLOCK_266M;
|
||||
break;
|
||||
}
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
unsigned long ltq_ar9_sys_hz(void)
|
||||
{
|
||||
if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2)
|
||||
|
@ -149,3 +172,23 @@ unsigned long ltq_vr9_fpi_hz(void)
|
|||
|
||||
return clk;
|
||||
}
|
||||
|
||||
unsigned long ltq_vr9_pp32_hz(void)
|
||||
{
|
||||
unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 3;
|
||||
unsigned long clk;
|
||||
|
||||
switch (clksys) {
|
||||
case 1:
|
||||
clk = CLOCK_450M;
|
||||
break;
|
||||
case 2:
|
||||
clk = CLOCK_300M;
|
||||
break;
|
||||
default:
|
||||
clk = CLOCK_500M;
|
||||
break;
|
||||
}
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
|
|
@ -78,10 +78,19 @@ static struct ltq_xrx200_gphy_reset {
|
|||
/* reset and boot a gphy. these phys only exist on xrx200 SoC */
|
||||
int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
if (!of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) {
|
||||
dev_err(dev, "this SoC has no GPHY\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
clk = clk_get_sys("1f203000.rcu", "gphy");
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
clk_enable(clk);
|
||||
|
||||
if (id > 1) {
|
||||
dev_err(dev, "%u is an invalid gphy id\n", id);
|
||||
return -EINVAL;
|
||||
|
|
|
@ -305,7 +305,7 @@ void __init ltq_soc_init(void)
|
|||
|
||||
/* check if all the core register ranges are available */
|
||||
if (!np_pmu || !np_cgu || !np_ebu)
|
||||
panic("Failed to load core nodess from devicetree");
|
||||
panic("Failed to load core nodes from devicetree");
|
||||
|
||||
if (of_address_to_resource(np_pmu, 0, &res_pmu) ||
|
||||
of_address_to_resource(np_cgu, 0, &res_cgu) ||
|
||||
|
@ -356,14 +356,16 @@ void __init ltq_soc_init(void)
|
|||
|
||||
if (of_machine_is_compatible("lantiq,ase")) {
|
||||
if (ltq_cgu_r32(CGU_SYS) & (1 << 5))
|
||||
clkdev_add_static(CLOCK_266M, CLOCK_133M, CLOCK_133M);
|
||||
clkdev_add_static(CLOCK_266M, CLOCK_133M,
|
||||
CLOCK_133M, CLOCK_266M);
|
||||
else
|
||||
clkdev_add_static(CLOCK_133M, CLOCK_133M, CLOCK_133M);
|
||||
clkdev_add_static(CLOCK_133M, CLOCK_133M,
|
||||
CLOCK_133M, CLOCK_133M);
|
||||
clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY),
|
||||
clkdev_add_pmu("1e180000.etop", "ephy", 0, PMU_EPHY);
|
||||
} else if (of_machine_is_compatible("lantiq,vr9")) {
|
||||
clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(),
|
||||
ltq_vr9_fpi_hz());
|
||||
ltq_vr9_fpi_hz(), ltq_vr9_pp32_hz());
|
||||
clkdev_add_pmu("1d900000.pcie", "phy", 1, PMU1_PCIE_PHY);
|
||||
clkdev_add_pmu("1d900000.pcie", "bus", 0, PMU_PCIE_CLK);
|
||||
clkdev_add_pmu("1d900000.pcie", "msi", 1, PMU1_PCIE_MSI);
|
||||
|
@ -374,12 +376,13 @@ void __init ltq_soc_init(void)
|
|||
PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
|
||||
PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
|
||||
PMU_PPE_QSB | PMU_PPE_TOP);
|
||||
clkdev_add_pmu("1f203000.rcu", "gphy", 0, PMU_GPHY);
|
||||
} else if (of_machine_is_compatible("lantiq,ar9")) {
|
||||
clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
|
||||
ltq_ar9_fpi_hz());
|
||||
ltq_ar9_fpi_hz(), CLOCK_250M);
|
||||
clkdev_add_pmu("1e180000.etop", "switch", 0, PMU_SWITCH);
|
||||
} else {
|
||||
clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
|
||||
ltq_danube_fpi_hz());
|
||||
ltq_danube_fpi_hz(), ltq_danube_pp32_hz());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ void __init prom_free_prom_memory(void)
|
|||
|
||||
#define PORT(offset) (u8 *)(KSEG1ADDR(LS1X_UART0_BASE + offset))
|
||||
|
||||
void __init prom_putchar(char c)
|
||||
void prom_putchar(char c)
|
||||
{
|
||||
int timeout;
|
||||
|
||||
|
|
|
@ -1057,6 +1057,7 @@ static void __cpuinit probe_pcache(void)
|
|||
break;
|
||||
|
||||
case CPU_M14KC:
|
||||
case CPU_M14KEC:
|
||||
case CPU_24K:
|
||||
case CPU_34K:
|
||||
case CPU_74K:
|
||||
|
|
|
@ -581,6 +581,7 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
|
|||
case CPU_4KC:
|
||||
case CPU_4KEC:
|
||||
case CPU_M14KC:
|
||||
case CPU_M14KEC:
|
||||
case CPU_SB1:
|
||||
case CPU_SB1A:
|
||||
case CPU_4KSC:
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
*
|
||||
* Setting up the clock on the MIPS boards.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/i8253.h>
|
||||
#include <linux/init.h>
|
||||
|
@ -25,7 +24,6 @@
|
|||
#include <linux/sched.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/mc146818rtc.h>
|
||||
|
||||
|
@ -34,11 +32,11 @@
|
|||
#include <asm/hardirq.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/div64.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/mc146818-time.h>
|
||||
#include <asm/msc01_ic.h>
|
||||
#include <asm/gic.h>
|
||||
|
||||
#include <asm/mips-boards/generic.h>
|
||||
#include <asm/mips-boards/prom.h>
|
||||
|
@ -46,6 +44,7 @@
|
|||
#include <asm/mips-boards/maltaint.h>
|
||||
|
||||
unsigned long cpu_khz;
|
||||
int gic_frequency;
|
||||
|
||||
static int mips_cpu_timer_irq;
|
||||
static int mips_cpu_perf_irq;
|
||||
|
@ -61,44 +60,50 @@ static void mips_perf_dispatch(void)
|
|||
do_IRQ(mips_cpu_perf_irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
|
||||
*/
|
||||
static unsigned int __init estimate_cpu_frequency(void)
|
||||
static unsigned int freqround(unsigned int freq, unsigned int amount)
|
||||
{
|
||||
unsigned int prid = read_c0_prid() & 0xffff00;
|
||||
unsigned int count;
|
||||
freq += amount;
|
||||
freq -= freq % (amount*2);
|
||||
return freq;
|
||||
}
|
||||
|
||||
/*
|
||||
* Estimate CPU and GIC frequencies.
|
||||
*/
|
||||
static void __init estimate_frequencies(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int start;
|
||||
unsigned int count, start;
|
||||
unsigned int giccount = 0, gicstart = 0;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
/* Start counter exactly on falling edge of update flag */
|
||||
/* Start counter exactly on falling edge of update flag. */
|
||||
while (CMOS_READ(RTC_REG_A) & RTC_UIP);
|
||||
while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
|
||||
|
||||
/* Start r4k counter. */
|
||||
/* Initialize counters. */
|
||||
start = read_c0_count();
|
||||
if (gic_present)
|
||||
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart);
|
||||
|
||||
/* Read counter exactly on falling edge of update flag */
|
||||
/* Read counter exactly on falling edge of update flag. */
|
||||
while (CMOS_READ(RTC_REG_A) & RTC_UIP);
|
||||
while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
|
||||
|
||||
count = read_c0_count() - start;
|
||||
count = read_c0_count();
|
||||
if (gic_present)
|
||||
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount);
|
||||
|
||||
/* restore interrupts */
|
||||
local_irq_restore(flags);
|
||||
|
||||
count -= start;
|
||||
if (gic_present)
|
||||
giccount -= gicstart;
|
||||
|
||||
mips_hpt_frequency = count;
|
||||
if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
|
||||
(prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
|
||||
count *= 2;
|
||||
|
||||
count += 5000; /* round */
|
||||
count -= count%10000;
|
||||
|
||||
return count;
|
||||
if (gic_present)
|
||||
gic_frequency = giccount;
|
||||
}
|
||||
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
|
@ -144,22 +149,34 @@ unsigned int __cpuinit get_c0_compare_int(void)
|
|||
|
||||
void __init plat_time_init(void)
|
||||
{
|
||||
unsigned int est_freq;
|
||||
unsigned int prid = read_c0_prid() & 0xffff00;
|
||||
unsigned int freq;
|
||||
|
||||
/* Set Data mode - binary. */
|
||||
CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
|
||||
estimate_frequencies();
|
||||
|
||||
est_freq = estimate_cpu_frequency();
|
||||
freq = mips_hpt_frequency;
|
||||
if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
|
||||
(prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
|
||||
freq *= 2;
|
||||
freq = freqround(freq, 5000);
|
||||
pr_debug("CPU frequency %d.%02d MHz\n", freq/1000000,
|
||||
(freq%1000000)*100/1000000);
|
||||
cpu_khz = freq / 1000;
|
||||
|
||||
printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
|
||||
(est_freq%1000000)*100/1000000);
|
||||
if (gic_present) {
|
||||
freq = freqround(gic_frequency, 5000);
|
||||
pr_debug("GIC frequency %d.%02d MHz\n", freq/1000000,
|
||||
(freq%1000000)*100/1000000);
|
||||
gic_clocksource_init(gic_frequency);
|
||||
} else
|
||||
init_r4k_clocksource();
|
||||
|
||||
cpu_khz = est_freq / 1000;
|
||||
|
||||
mips_scroll_message();
|
||||
#ifdef CONFIG_I8253 /* Only Malta has a PIT */
|
||||
#ifdef CONFIG_I8253
|
||||
/* Only Malta has a PIT. */
|
||||
setup_pit_timer();
|
||||
#endif
|
||||
|
||||
mips_scroll_message();
|
||||
|
||||
plat_perf_setup();
|
||||
}
|
||||
|
|
|
@ -105,21 +105,23 @@ static void xlp_pic_disable(struct irq_data *d)
|
|||
static void xlp_pic_mask_ack(struct irq_data *d)
|
||||
{
|
||||
struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
|
||||
uint64_t mask = 1ull << pd->picirq;
|
||||
|
||||
write_c0_eirr(mask); /* ack by writing EIRR */
|
||||
clear_c0_eimr(pd->picirq);
|
||||
ack_c0_eirr(pd->picirq);
|
||||
}
|
||||
|
||||
static void xlp_pic_unmask(struct irq_data *d)
|
||||
{
|
||||
struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
|
||||
|
||||
if (!pd)
|
||||
return;
|
||||
BUG_ON(!pd);
|
||||
|
||||
if (pd->extra_ack)
|
||||
pd->extra_ack(d);
|
||||
|
||||
/* re-enable the intr on this cpu */
|
||||
set_c0_eimr(pd->picirq);
|
||||
|
||||
/* Ack is a single write, no need to lock */
|
||||
nlm_pic_ack(pd->node->picbase, pd->irt);
|
||||
}
|
||||
|
@ -134,32 +136,17 @@ static struct irq_chip xlp_pic = {
|
|||
|
||||
static void cpuintr_disable(struct irq_data *d)
|
||||
{
|
||||
uint64_t eimr;
|
||||
uint64_t mask = 1ull << d->irq;
|
||||
|
||||
eimr = read_c0_eimr();
|
||||
write_c0_eimr(eimr & ~mask);
|
||||
clear_c0_eimr(d->irq);
|
||||
}
|
||||
|
||||
static void cpuintr_enable(struct irq_data *d)
|
||||
{
|
||||
uint64_t eimr;
|
||||
uint64_t mask = 1ull << d->irq;
|
||||
|
||||
eimr = read_c0_eimr();
|
||||
write_c0_eimr(eimr | mask);
|
||||
set_c0_eimr(d->irq);
|
||||
}
|
||||
|
||||
static void cpuintr_ack(struct irq_data *d)
|
||||
{
|
||||
uint64_t mask = 1ull << d->irq;
|
||||
|
||||
write_c0_eirr(mask);
|
||||
}
|
||||
|
||||
static void cpuintr_nop(struct irq_data *d)
|
||||
{
|
||||
WARN(d->irq >= PIC_IRQ_BASE, "Bad irq %d", d->irq);
|
||||
ack_c0_eirr(d->irq);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -170,9 +157,9 @@ struct irq_chip nlm_cpu_intr = {
|
|||
.name = "XLP-CPU-INTR",
|
||||
.irq_enable = cpuintr_enable,
|
||||
.irq_disable = cpuintr_disable,
|
||||
.irq_mask = cpuintr_nop,
|
||||
.irq_ack = cpuintr_nop,
|
||||
.irq_eoi = cpuintr_ack,
|
||||
.irq_mask = cpuintr_disable,
|
||||
.irq_ack = cpuintr_ack,
|
||||
.irq_eoi = cpuintr_enable,
|
||||
};
|
||||
|
||||
static void __init nlm_init_percpu_irqs(void)
|
||||
|
@ -230,7 +217,7 @@ static void nlm_init_node_irqs(int node)
|
|||
nlm_setup_pic_irq(node, i, i, irt);
|
||||
/* set interrupts to first cpu in node */
|
||||
nlm_pic_init_irt(nodep->picbase, irt, i,
|
||||
node * NLM_CPUS_PER_NODE);
|
||||
node * NLM_CPUS_PER_NODE, 0);
|
||||
irqmask |= (1ull << i);
|
||||
}
|
||||
nodep->irqmask = irqmask;
|
||||
|
@ -265,7 +252,7 @@ asmlinkage void plat_irq_dispatch(void)
|
|||
int i, node;
|
||||
|
||||
node = nlm_nodeid();
|
||||
eirr = read_c0_eirr() & read_c0_eimr();
|
||||
eirr = read_c0_eirr_and_eimr();
|
||||
|
||||
i = __ilog2_u64(eirr);
|
||||
if (i == -1)
|
||||
|
|
|
@ -84,15 +84,19 @@ void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action)
|
|||
/* IRQ_IPI_SMP_FUNCTION Handler */
|
||||
void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
write_c0_eirr(1ull << irq);
|
||||
clear_c0_eimr(irq);
|
||||
ack_c0_eirr(irq);
|
||||
smp_call_function_interrupt();
|
||||
set_c0_eimr(irq);
|
||||
}
|
||||
|
||||
/* IRQ_IPI_SMP_RESCHEDULE handler */
|
||||
void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
write_c0_eirr(1ull << irq);
|
||||
clear_c0_eimr(irq);
|
||||
ack_c0_eirr(irq);
|
||||
scheduler_ipi();
|
||||
set_c0_eimr(irq);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -69,6 +69,12 @@
|
|||
#endif
|
||||
mtcr t1, t0
|
||||
|
||||
li t0, ICU_DEFEATURE
|
||||
mfcr t1, t0
|
||||
ori t1, 0x1000 /* Enable Icache partitioning */
|
||||
mtcr t1, t0
|
||||
|
||||
|
||||
#ifdef XLP_AX_WORKAROUND
|
||||
li t0, SCHED_DEFEATURE
|
||||
lui t1, 0x0100 /* Disable BRU accepting ALU ops */
|
||||
|
|
|
@ -35,17 +35,73 @@
|
|||
#include <linux/init.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/cpu-features.h>
|
||||
|
||||
#include <asm/netlogic/interrupt.h>
|
||||
#include <asm/netlogic/common.h>
|
||||
#include <asm/netlogic/haldefs.h>
|
||||
#include <asm/netlogic/common.h>
|
||||
|
||||
#if defined(CONFIG_CPU_XLP)
|
||||
#include <asm/netlogic/xlp-hal/iomap.h>
|
||||
#include <asm/netlogic/xlp-hal/xlp.h>
|
||||
#include <asm/netlogic/xlp-hal/pic.h>
|
||||
#elif defined(CONFIG_CPU_XLR)
|
||||
#include <asm/netlogic/xlr/iomap.h>
|
||||
#include <asm/netlogic/xlr/pic.h>
|
||||
#include <asm/netlogic/xlr/xlr.h>
|
||||
#else
|
||||
#error "Unknown CPU"
|
||||
#endif
|
||||
|
||||
unsigned int __cpuinit get_c0_compare_int(void)
|
||||
{
|
||||
return IRQ_TIMER;
|
||||
}
|
||||
|
||||
static cycle_t nlm_get_pic_timer(struct clocksource *cs)
|
||||
{
|
||||
uint64_t picbase = nlm_get_node(0)->picbase;
|
||||
|
||||
return ~nlm_pic_read_timer(picbase, PIC_CLOCK_TIMER);
|
||||
}
|
||||
|
||||
static cycle_t nlm_get_pic_timer32(struct clocksource *cs)
|
||||
{
|
||||
uint64_t picbase = nlm_get_node(0)->picbase;
|
||||
|
||||
return ~nlm_pic_read_timer32(picbase, PIC_CLOCK_TIMER);
|
||||
}
|
||||
|
||||
static struct clocksource csrc_pic = {
|
||||
.name = "PIC",
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
static void nlm_init_pic_timer(void)
|
||||
{
|
||||
uint64_t picbase = nlm_get_node(0)->picbase;
|
||||
|
||||
nlm_pic_set_timer(picbase, PIC_CLOCK_TIMER, ~0ULL, 0, 0);
|
||||
if (current_cpu_data.cputype == CPU_XLR) {
|
||||
csrc_pic.mask = CLOCKSOURCE_MASK(32);
|
||||
csrc_pic.read = nlm_get_pic_timer32;
|
||||
} else {
|
||||
csrc_pic.mask = CLOCKSOURCE_MASK(64);
|
||||
csrc_pic.read = nlm_get_pic_timer;
|
||||
}
|
||||
csrc_pic.rating = 1000;
|
||||
clocksource_register_hz(&csrc_pic, PIC_CLK_HZ);
|
||||
}
|
||||
|
||||
void __init plat_time_init(void)
|
||||
{
|
||||
nlm_init_pic_timer();
|
||||
mips_hpt_frequency = nlm_get_cpu_frequency();
|
||||
if (current_cpu_type() == CPU_XLR)
|
||||
preset_lpj = mips_hpt_frequency / (3 * HZ);
|
||||
else
|
||||
preset_lpj = mips_hpt_frequency / (2 * HZ);
|
||||
pr_info("MIPS counter frequency [%ld]\n",
|
||||
(unsigned long)mips_hpt_frequency);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#include <asm/netlogic/xlp-hal/xlp.h>
|
||||
#include <asm/netlogic/xlp-hal/sys.h>
|
||||
|
||||
static int xlp_wakeup_core(uint64_t sysbase, int core)
|
||||
static int xlp_wakeup_core(uint64_t sysbase, int node, int core)
|
||||
{
|
||||
uint32_t coremask, value;
|
||||
int count;
|
||||
|
@ -82,36 +82,51 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
|
|||
struct nlm_soc_info *nodep;
|
||||
uint64_t syspcibase;
|
||||
uint32_t syscoremask;
|
||||
int core, n, cpu;
|
||||
int core, n, cpu, count, val;
|
||||
|
||||
for (n = 0; n < NLM_NR_NODES; n++) {
|
||||
syspcibase = nlm_get_sys_pcibase(n);
|
||||
if (nlm_read_reg(syspcibase, 0) == 0xffffffff)
|
||||
break;
|
||||
|
||||
/* read cores in reset from SYS and account for boot cpu */
|
||||
/* read cores in reset from SYS */
|
||||
if (n != 0)
|
||||
nlm_node_init(n);
|
||||
nodep = nlm_get_node(n);
|
||||
syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET);
|
||||
if (n == 0)
|
||||
/* The boot cpu */
|
||||
if (n == 0) {
|
||||
syscoremask |= 1;
|
||||
nodep->coremask = 1;
|
||||
}
|
||||
|
||||
for (core = 0; core < NLM_CORES_PER_NODE; core++) {
|
||||
/* we will be on node 0 core 0 */
|
||||
if (n == 0 && core == 0)
|
||||
continue;
|
||||
|
||||
/* see if the core exists */
|
||||
if ((syscoremask & (1 << core)) == 0)
|
||||
continue;
|
||||
|
||||
/* see if at least the first thread is enabled */
|
||||
/* see if at least the first hw thread is enabled */
|
||||
cpu = (n * NLM_CORES_PER_NODE + core)
|
||||
* NLM_THREADS_PER_CORE;
|
||||
if (!cpumask_test_cpu(cpu, wakeup_mask))
|
||||
continue;
|
||||
|
||||
/* wake up the core */
|
||||
if (xlp_wakeup_core(nodep->sysbase, core))
|
||||
if (!xlp_wakeup_core(nodep->sysbase, n, core))
|
||||
continue;
|
||||
|
||||
/* core is up */
|
||||
nodep->coremask |= 1u << core;
|
||||
else
|
||||
pr_err("Failed to enable core %d\n", core);
|
||||
|
||||
/* spin until the first hw thread sets its ready */
|
||||
count = 0x20000000;
|
||||
do {
|
||||
val = *(volatile int *)&nlm_cpu_ready[cpu];
|
||||
} while (val == 0 && --count > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -216,6 +216,8 @@ void xlr_board_info_setup(void)
|
|||
case PRID_IMP_NETLOGIC_XLS404B:
|
||||
case PRID_IMP_NETLOGIC_XLS408B:
|
||||
case PRID_IMP_NETLOGIC_XLS416B:
|
||||
case PRID_IMP_NETLOGIC_XLS608B:
|
||||
case PRID_IMP_NETLOGIC_XLS616B:
|
||||
setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,
|
||||
FMN_STNID_GMAC0_TX3, 8, 8, 32);
|
||||
setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0,
|
||||
|
|
|
@ -64,7 +64,7 @@ void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
|
|||
.iotype = UPIO_MEM32, \
|
||||
.flags = (UPF_SKIP_TEST | \
|
||||
UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\
|
||||
.uartclk = PIC_CLKS_PER_SEC, \
|
||||
.uartclk = PIC_CLK_HZ, \
|
||||
.type = PORT_16550A, \
|
||||
.serial_in = nlm_xlr_uart_in, \
|
||||
.serial_out = nlm_xlr_uart_out, \
|
||||
|
|
|
@ -70,7 +70,7 @@ static void __init nlm_early_serial_setup(void)
|
|||
s.iotype = UPIO_MEM32;
|
||||
s.regshift = 2;
|
||||
s.irq = PIC_UART_0_IRQ;
|
||||
s.uartclk = PIC_CLKS_PER_SEC;
|
||||
s.uartclk = PIC_CLK_HZ;
|
||||
s.serial_in = nlm_xlr_uart_in;
|
||||
s.serial_out = nlm_xlr_uart_out;
|
||||
s.mapbase = uart_base;
|
||||
|
|
|
@ -78,6 +78,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
|
|||
switch (current_cpu_type()) {
|
||||
case CPU_5KC:
|
||||
case CPU_M14KC:
|
||||
case CPU_M14KEC:
|
||||
case CPU_20KC:
|
||||
case CPU_24K:
|
||||
case CPU_25KF:
|
||||
|
|
|
@ -351,6 +351,10 @@ static int __init mipsxx_init(void)
|
|||
op_model_mipsxx_ops.cpu_type = "mips/M14Kc";
|
||||
break;
|
||||
|
||||
case CPU_M14KEC:
|
||||
op_model_mipsxx_ops.cpu_type = "mips/M14KEc";
|
||||
break;
|
||||
|
||||
case CPU_20KC:
|
||||
op_model_mipsxx_ops.cpu_type = "mips/20K";
|
||||
break;
|
||||
|
|
|
@ -18,26 +18,11 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/pci_regs.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/mach-ath79/ar71xx_regs.h>
|
||||
#include <asm/mach-ath79/ath79.h>
|
||||
#include <asm/mach-ath79/pci.h>
|
||||
|
||||
#define AR71XX_PCI_MEM_BASE 0x10000000
|
||||
#define AR71XX_PCI_MEM_SIZE 0x07000000
|
||||
|
||||
#define AR71XX_PCI_WIN0_OFFS 0x10000000
|
||||
#define AR71XX_PCI_WIN1_OFFS 0x11000000
|
||||
#define AR71XX_PCI_WIN2_OFFS 0x12000000
|
||||
#define AR71XX_PCI_WIN3_OFFS 0x13000000
|
||||
#define AR71XX_PCI_WIN4_OFFS 0x14000000
|
||||
#define AR71XX_PCI_WIN5_OFFS 0x15000000
|
||||
#define AR71XX_PCI_WIN6_OFFS 0x16000000
|
||||
#define AR71XX_PCI_WIN7_OFFS 0x07000000
|
||||
|
||||
#define AR71XX_PCI_CFG_BASE \
|
||||
(AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000)
|
||||
#define AR71XX_PCI_CFG_SIZE 0x100
|
||||
|
||||
#define AR71XX_PCI_REG_CRP_AD_CBE 0x00
|
||||
#define AR71XX_PCI_REG_CRP_WRDATA 0x04
|
||||
|
@ -63,8 +48,15 @@
|
|||
|
||||
#define AR71XX_PCI_IRQ_COUNT 5
|
||||
|
||||
static DEFINE_SPINLOCK(ar71xx_pci_lock);
|
||||
static void __iomem *ar71xx_pcicfg_base;
|
||||
struct ar71xx_pci_controller {
|
||||
void __iomem *cfg_base;
|
||||
spinlock_t lock;
|
||||
int irq;
|
||||
int irq_base;
|
||||
struct pci_controller pci_ctrl;
|
||||
struct resource io_res;
|
||||
struct resource mem_res;
|
||||
};
|
||||
|
||||
/* Byte lane enable bits */
|
||||
static const u8 ar71xx_pci_ble_table[4][4] = {
|
||||
|
@ -107,9 +99,18 @@ static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ar71xx_pci_check_error(int quiet)
|
||||
static inline struct ar71xx_pci_controller *
|
||||
pci_bus_to_ar71xx_controller(struct pci_bus *bus)
|
||||
{
|
||||
void __iomem *base = ar71xx_pcicfg_base;
|
||||
struct pci_controller *hose;
|
||||
|
||||
hose = (struct pci_controller *) bus->sysdata;
|
||||
return container_of(hose, struct ar71xx_pci_controller, pci_ctrl);
|
||||
}
|
||||
|
||||
static int ar71xx_pci_check_error(struct ar71xx_pci_controller *apc, int quiet)
|
||||
{
|
||||
void __iomem *base = apc->cfg_base;
|
||||
u32 pci_err;
|
||||
u32 ahb_err;
|
||||
|
||||
|
@ -144,9 +145,10 @@ static int ar71xx_pci_check_error(int quiet)
|
|||
return !!(ahb_err | pci_err);
|
||||
}
|
||||
|
||||
static inline void ar71xx_pci_local_write(int where, int size, u32 value)
|
||||
static inline void ar71xx_pci_local_write(struct ar71xx_pci_controller *apc,
|
||||
int where, int size, u32 value)
|
||||
{
|
||||
void __iomem *base = ar71xx_pcicfg_base;
|
||||
void __iomem *base = apc->cfg_base;
|
||||
u32 ad_cbe;
|
||||
|
||||
value = value << (8 * (where & 3));
|
||||
|
@ -162,7 +164,8 @@ static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus,
|
|||
unsigned int devfn,
|
||||
int where, int size, u32 cmd)
|
||||
{
|
||||
void __iomem *base = ar71xx_pcicfg_base;
|
||||
struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus);
|
||||
void __iomem *base = apc->cfg_base;
|
||||
u32 addr;
|
||||
|
||||
addr = ar71xx_pci_bus_addr(bus, devfn, where);
|
||||
|
@ -171,13 +174,14 @@ static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus,
|
|||
__raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0),
|
||||
base + AR71XX_PCI_REG_CFG_CBE);
|
||||
|
||||
return ar71xx_pci_check_error(1);
|
||||
return ar71xx_pci_check_error(apc, 1);
|
||||
}
|
||||
|
||||
static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *value)
|
||||
{
|
||||
void __iomem *base = ar71xx_pcicfg_base;
|
||||
struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus);
|
||||
void __iomem *base = apc->cfg_base;
|
||||
unsigned long flags;
|
||||
u32 data;
|
||||
int err;
|
||||
|
@ -186,7 +190,7 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
|
|||
ret = PCIBIOS_SUCCESSFUL;
|
||||
data = ~0;
|
||||
|
||||
spin_lock_irqsave(&ar71xx_pci_lock, flags);
|
||||
spin_lock_irqsave(&apc->lock, flags);
|
||||
|
||||
err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
|
||||
AR71XX_PCI_CFG_CMD_READ);
|
||||
|
@ -195,7 +199,7 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
|
|||
else
|
||||
data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA);
|
||||
|
||||
spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
|
||||
spin_unlock_irqrestore(&apc->lock, flags);
|
||||
|
||||
*value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7];
|
||||
|
||||
|
@ -205,7 +209,8 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
|
|||
static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 value)
|
||||
{
|
||||
void __iomem *base = ar71xx_pcicfg_base;
|
||||
struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus);
|
||||
void __iomem *base = apc->cfg_base;
|
||||
unsigned long flags;
|
||||
int err;
|
||||
int ret;
|
||||
|
@ -213,7 +218,7 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
|||
value = value << (8 * (where & 3));
|
||||
ret = PCIBIOS_SUCCESSFUL;
|
||||
|
||||
spin_lock_irqsave(&ar71xx_pci_lock, flags);
|
||||
spin_lock_irqsave(&apc->lock, flags);
|
||||
|
||||
err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
|
||||
AR71XX_PCI_CFG_CMD_WRITE);
|
||||
|
@ -222,7 +227,7 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
|||
else
|
||||
__raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA);
|
||||
|
||||
spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
|
||||
spin_unlock_irqrestore(&apc->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -232,45 +237,28 @@ static struct pci_ops ar71xx_pci_ops = {
|
|||
.write = ar71xx_pci_write_config,
|
||||
};
|
||||
|
||||
static struct resource ar71xx_pci_io_resource = {
|
||||
.name = "PCI IO space",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_IO,
|
||||
};
|
||||
|
||||
static struct resource ar71xx_pci_mem_resource = {
|
||||
.name = "PCI memory space",
|
||||
.start = AR71XX_PCI_MEM_BASE,
|
||||
.end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM
|
||||
};
|
||||
|
||||
static struct pci_controller ar71xx_pci_controller = {
|
||||
.pci_ops = &ar71xx_pci_ops,
|
||||
.mem_resource = &ar71xx_pci_mem_resource,
|
||||
.io_resource = &ar71xx_pci_io_resource,
|
||||
};
|
||||
|
||||
static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct ar71xx_pci_controller *apc;
|
||||
void __iomem *base = ath79_reset_base;
|
||||
u32 pending;
|
||||
|
||||
apc = irq_get_handler_data(irq);
|
||||
|
||||
pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
|
||||
__raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
|
||||
|
||||
if (pending & AR71XX_PCI_INT_DEV0)
|
||||
generic_handle_irq(ATH79_PCI_IRQ(0));
|
||||
generic_handle_irq(apc->irq_base + 0);
|
||||
|
||||
else if (pending & AR71XX_PCI_INT_DEV1)
|
||||
generic_handle_irq(ATH79_PCI_IRQ(1));
|
||||
generic_handle_irq(apc->irq_base + 1);
|
||||
|
||||
else if (pending & AR71XX_PCI_INT_DEV2)
|
||||
generic_handle_irq(ATH79_PCI_IRQ(2));
|
||||
generic_handle_irq(apc->irq_base + 2);
|
||||
|
||||
else if (pending & AR71XX_PCI_INT_CORE)
|
||||
generic_handle_irq(ATH79_PCI_IRQ(4));
|
||||
generic_handle_irq(apc->irq_base + 4);
|
||||
|
||||
else
|
||||
spurious_interrupt();
|
||||
|
@ -278,10 +266,14 @@ static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|||
|
||||
static void ar71xx_pci_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - ATH79_PCI_IRQ_BASE;
|
||||
struct ar71xx_pci_controller *apc;
|
||||
unsigned int irq;
|
||||
void __iomem *base = ath79_reset_base;
|
||||
u32 t;
|
||||
|
||||
apc = irq_data_get_irq_chip_data(d);
|
||||
irq = d->irq - apc->irq_base;
|
||||
|
||||
t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
|
||||
__raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
|
||||
|
||||
|
@ -291,10 +283,14 @@ static void ar71xx_pci_irq_unmask(struct irq_data *d)
|
|||
|
||||
static void ar71xx_pci_irq_mask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - ATH79_PCI_IRQ_BASE;
|
||||
struct ar71xx_pci_controller *apc;
|
||||
unsigned int irq;
|
||||
void __iomem *base = ath79_reset_base;
|
||||
u32 t;
|
||||
|
||||
apc = irq_data_get_irq_chip_data(d);
|
||||
irq = d->irq - apc->irq_base;
|
||||
|
||||
t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
|
||||
__raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
|
||||
|
||||
|
@ -309,7 +305,7 @@ static struct irq_chip ar71xx_pci_irq_chip = {
|
|||
.irq_mask_ack = ar71xx_pci_irq_mask,
|
||||
};
|
||||
|
||||
static __init void ar71xx_pci_irq_init(void)
|
||||
static void ar71xx_pci_irq_init(struct ar71xx_pci_controller *apc)
|
||||
{
|
||||
void __iomem *base = ath79_reset_base;
|
||||
int i;
|
||||
|
@ -319,15 +315,19 @@ static __init void ar71xx_pci_irq_init(void)
|
|||
|
||||
BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR71XX_PCI_IRQ_COUNT);
|
||||
|
||||
for (i = ATH79_PCI_IRQ_BASE;
|
||||
i < ATH79_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++)
|
||||
apc->irq_base = ATH79_PCI_IRQ_BASE;
|
||||
for (i = apc->irq_base;
|
||||
i < apc->irq_base + AR71XX_PCI_IRQ_COUNT; i++) {
|
||||
irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip,
|
||||
handle_level_irq);
|
||||
|
||||
irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar71xx_pci_irq_handler);
|
||||
irq_set_chip_data(i, apc);
|
||||
}
|
||||
|
||||
static __init void ar71xx_pci_reset(void)
|
||||
irq_set_handler_data(apc->irq, apc);
|
||||
irq_set_chained_handler(apc->irq, ar71xx_pci_irq_handler);
|
||||
}
|
||||
|
||||
static void ar71xx_pci_reset(void)
|
||||
{
|
||||
void __iomem *ddr_base = ath79_ddr_base;
|
||||
|
||||
|
@ -349,27 +349,83 @@ static __init void ar71xx_pci_reset(void)
|
|||
mdelay(100);
|
||||
}
|
||||
|
||||
__init int ar71xx_pcibios_init(void)
|
||||
static int ar71xx_pci_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ar71xx_pci_controller *apc;
|
||||
struct resource *res;
|
||||
u32 t;
|
||||
|
||||
ar71xx_pcicfg_base = ioremap(AR71XX_PCI_CFG_BASE, AR71XX_PCI_CFG_SIZE);
|
||||
if (ar71xx_pcicfg_base == NULL)
|
||||
apc = devm_kzalloc(&pdev->dev, sizeof(struct ar71xx_pci_controller),
|
||||
GFP_KERNEL);
|
||||
if (!apc)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&apc->lock);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
||||
apc->cfg_base = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (!apc->cfg_base)
|
||||
return -ENOMEM;
|
||||
|
||||
apc->irq = platform_get_irq(pdev, 0);
|
||||
if (apc->irq < 0)
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base");
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
||||
apc->io_res.parent = res;
|
||||
apc->io_res.name = "PCI IO space";
|
||||
apc->io_res.start = res->start;
|
||||
apc->io_res.end = res->end;
|
||||
apc->io_res.flags = IORESOURCE_IO;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base");
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
||||
apc->mem_res.parent = res;
|
||||
apc->mem_res.name = "PCI memory space";
|
||||
apc->mem_res.start = res->start;
|
||||
apc->mem_res.end = res->end;
|
||||
apc->mem_res.flags = IORESOURCE_MEM;
|
||||
|
||||
ar71xx_pci_reset();
|
||||
|
||||
/* setup COMMAND register */
|
||||
t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
|
||||
| PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
|
||||
ar71xx_pci_local_write(PCI_COMMAND, 4, t);
|
||||
ar71xx_pci_local_write(apc, PCI_COMMAND, 4, t);
|
||||
|
||||
/* clear bus errors */
|
||||
ar71xx_pci_check_error(1);
|
||||
ar71xx_pci_check_error(apc, 1);
|
||||
|
||||
ar71xx_pci_irq_init();
|
||||
ar71xx_pci_irq_init(apc);
|
||||
|
||||
register_pci_controller(&ar71xx_pci_controller);
|
||||
apc->pci_ctrl.pci_ops = &ar71xx_pci_ops;
|
||||
apc->pci_ctrl.mem_resource = &apc->mem_res;
|
||||
apc->pci_ctrl.io_resource = &apc->io_res;
|
||||
|
||||
register_pci_controller(&apc->pci_ctrl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ar71xx_pci_driver = {
|
||||
.probe = ar71xx_pci_probe,
|
||||
.driver = {
|
||||
.name = "ar71xx-pci",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init ar71xx_pci_init(void)
|
||||
{
|
||||
return platform_driver_register(&ar71xx_pci_driver);
|
||||
}
|
||||
|
||||
postcore_initcall(ar71xx_pci_init);
|
||||
|
|
|
@ -9,19 +9,13 @@
|
|||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/mach-ath79/ath79.h>
|
||||
#include <asm/mach-ath79/ar71xx_regs.h>
|
||||
#include <asm/mach-ath79/pci.h>
|
||||
|
||||
#define AR724X_PCI_CFG_BASE 0x14000000
|
||||
#define AR724X_PCI_CFG_SIZE 0x1000
|
||||
#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000)
|
||||
#define AR724X_PCI_CTRL_SIZE 0x100
|
||||
|
||||
#define AR724X_PCI_MEM_BASE 0x10000000
|
||||
#define AR724X_PCI_MEM_SIZE 0x04000000
|
||||
|
||||
#define AR724X_PCI_REG_RESET 0x18
|
||||
#define AR724X_PCI_REG_INT_STATUS 0x4c
|
||||
|
@ -35,38 +29,112 @@
|
|||
|
||||
#define AR7240_BAR0_WAR_VALUE 0xffff
|
||||
|
||||
static DEFINE_SPINLOCK(ar724x_pci_lock);
|
||||
static void __iomem *ar724x_pci_devcfg_base;
|
||||
static void __iomem *ar724x_pci_ctrl_base;
|
||||
#define AR724X_PCI_CMD_INIT (PCI_COMMAND_MEMORY | \
|
||||
PCI_COMMAND_MASTER | \
|
||||
PCI_COMMAND_INVALIDATE | \
|
||||
PCI_COMMAND_PARITY | \
|
||||
PCI_COMMAND_SERR | \
|
||||
PCI_COMMAND_FAST_BACK)
|
||||
|
||||
static u32 ar724x_pci_bar0_value;
|
||||
static bool ar724x_pci_bar0_is_cached;
|
||||
static bool ar724x_pci_link_up;
|
||||
struct ar724x_pci_controller {
|
||||
void __iomem *devcfg_base;
|
||||
void __iomem *ctrl_base;
|
||||
void __iomem *crp_base;
|
||||
|
||||
static inline bool ar724x_pci_check_link(void)
|
||||
int irq;
|
||||
int irq_base;
|
||||
|
||||
bool link_up;
|
||||
bool bar0_is_cached;
|
||||
u32 bar0_value;
|
||||
|
||||
spinlock_t lock;
|
||||
|
||||
struct pci_controller pci_controller;
|
||||
struct resource io_res;
|
||||
struct resource mem_res;
|
||||
};
|
||||
|
||||
static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc)
|
||||
{
|
||||
u32 reset;
|
||||
|
||||
reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET);
|
||||
reset = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_RESET);
|
||||
return reset & AR724X_PCI_RESET_LINK_UP;
|
||||
}
|
||||
|
||||
static inline struct ar724x_pci_controller *
|
||||
pci_bus_to_ar724x_controller(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
|
||||
hose = (struct pci_controller *) bus->sysdata;
|
||||
return container_of(hose, struct ar724x_pci_controller, pci_controller);
|
||||
}
|
||||
|
||||
static int ar724x_pci_local_write(struct ar724x_pci_controller *apc,
|
||||
int where, int size, u32 value)
|
||||
{
|
||||
unsigned long flags;
|
||||
void __iomem *base;
|
||||
u32 data;
|
||||
int s;
|
||||
|
||||
WARN_ON(where & (size - 1));
|
||||
|
||||
if (!apc->link_up)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
base = apc->crp_base;
|
||||
|
||||
spin_lock_irqsave(&apc->lock, flags);
|
||||
data = __raw_readl(base + (where & ~3));
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
s = ((where & 3) * 8);
|
||||
data &= ~(0xff << s);
|
||||
data |= ((value & 0xff) << s);
|
||||
break;
|
||||
case 2:
|
||||
s = ((where & 2) * 8);
|
||||
data &= ~(0xffff << s);
|
||||
data |= ((value & 0xffff) << s);
|
||||
break;
|
||||
case 4:
|
||||
data = value;
|
||||
break;
|
||||
default:
|
||||
spin_unlock_irqrestore(&apc->lock, flags);
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
}
|
||||
|
||||
__raw_writel(data, base + (where & ~3));
|
||||
/* flush write */
|
||||
__raw_readl(base + (where & ~3));
|
||||
spin_unlock_irqrestore(&apc->lock, flags);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
int size, uint32_t *value)
|
||||
{
|
||||
struct ar724x_pci_controller *apc;
|
||||
unsigned long flags;
|
||||
void __iomem *base;
|
||||
u32 data;
|
||||
|
||||
if (!ar724x_pci_link_up)
|
||||
apc = pci_bus_to_ar724x_controller(bus);
|
||||
if (!apc->link_up)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
if (devfn)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
base = ar724x_pci_devcfg_base;
|
||||
base = apc->devcfg_base;
|
||||
|
||||
spin_lock_irqsave(&ar724x_pci_lock, flags);
|
||||
spin_lock_irqsave(&apc->lock, flags);
|
||||
data = __raw_readl(base + (where & ~3));
|
||||
|
||||
switch (size) {
|
||||
|
@ -85,17 +153,17 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
|
|||
case 4:
|
||||
break;
|
||||
default:
|
||||
spin_unlock_irqrestore(&ar724x_pci_lock, flags);
|
||||
spin_unlock_irqrestore(&apc->lock, flags);
|
||||
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&ar724x_pci_lock, flags);
|
||||
spin_unlock_irqrestore(&apc->lock, flags);
|
||||
|
||||
if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
|
||||
ar724x_pci_bar0_is_cached) {
|
||||
apc->bar0_is_cached) {
|
||||
/* use the cached value */
|
||||
*value = ar724x_pci_bar0_value;
|
||||
*value = apc->bar0_value;
|
||||
} else {
|
||||
*value = data;
|
||||
}
|
||||
|
@ -106,12 +174,14 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
|
|||
static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
int size, uint32_t value)
|
||||
{
|
||||
struct ar724x_pci_controller *apc;
|
||||
unsigned long flags;
|
||||
void __iomem *base;
|
||||
u32 data;
|
||||
int s;
|
||||
|
||||
if (!ar724x_pci_link_up)
|
||||
apc = pci_bus_to_ar724x_controller(bus);
|
||||
if (!apc->link_up)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
if (devfn)
|
||||
|
@ -129,18 +199,18 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
|
|||
* BAR0 register in order to make the device memory
|
||||
* accessible.
|
||||
*/
|
||||
ar724x_pci_bar0_is_cached = true;
|
||||
ar724x_pci_bar0_value = value;
|
||||
apc->bar0_is_cached = true;
|
||||
apc->bar0_value = value;
|
||||
|
||||
value = AR7240_BAR0_WAR_VALUE;
|
||||
} else {
|
||||
ar724x_pci_bar0_is_cached = false;
|
||||
apc->bar0_is_cached = false;
|
||||
}
|
||||
}
|
||||
|
||||
base = ar724x_pci_devcfg_base;
|
||||
base = apc->devcfg_base;
|
||||
|
||||
spin_lock_irqsave(&ar724x_pci_lock, flags);
|
||||
spin_lock_irqsave(&apc->lock, flags);
|
||||
data = __raw_readl(base + (where & ~3));
|
||||
|
||||
switch (size) {
|
||||
|
@ -158,7 +228,7 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
|
|||
data = value;
|
||||
break;
|
||||
default:
|
||||
spin_unlock_irqrestore(&ar724x_pci_lock, flags);
|
||||
spin_unlock_irqrestore(&apc->lock, flags);
|
||||
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
}
|
||||
|
@ -166,7 +236,7 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
|
|||
__raw_writel(data, base + (where & ~3));
|
||||
/* flush write */
|
||||
__raw_readl(base + (where & ~3));
|
||||
spin_unlock_irqrestore(&ar724x_pci_lock, flags);
|
||||
spin_unlock_irqrestore(&apc->lock, flags);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
@ -176,38 +246,20 @@ static struct pci_ops ar724x_pci_ops = {
|
|||
.write = ar724x_pci_write,
|
||||
};
|
||||
|
||||
static struct resource ar724x_io_resource = {
|
||||
.name = "PCI IO space",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_IO,
|
||||
};
|
||||
|
||||
static struct resource ar724x_mem_resource = {
|
||||
.name = "PCI memory space",
|
||||
.start = AR724X_PCI_MEM_BASE,
|
||||
.end = AR724X_PCI_MEM_BASE + AR724X_PCI_MEM_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct pci_controller ar724x_pci_controller = {
|
||||
.pci_ops = &ar724x_pci_ops,
|
||||
.io_resource = &ar724x_io_resource,
|
||||
.mem_resource = &ar724x_mem_resource,
|
||||
};
|
||||
|
||||
static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct ar724x_pci_controller *apc;
|
||||
void __iomem *base;
|
||||
u32 pending;
|
||||
|
||||
base = ar724x_pci_ctrl_base;
|
||||
apc = irq_get_handler_data(irq);
|
||||
base = apc->ctrl_base;
|
||||
|
||||
pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
|
||||
__raw_readl(base + AR724X_PCI_REG_INT_MASK);
|
||||
|
||||
if (pending & AR724X_PCI_INT_DEV0)
|
||||
generic_handle_irq(ATH79_PCI_IRQ(0));
|
||||
generic_handle_irq(apc->irq_base + 0);
|
||||
|
||||
else
|
||||
spurious_interrupt();
|
||||
|
@ -215,13 +267,17 @@ static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|||
|
||||
static void ar724x_pci_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct ar724x_pci_controller *apc;
|
||||
void __iomem *base;
|
||||
int offset;
|
||||
u32 t;
|
||||
|
||||
base = ar724x_pci_ctrl_base;
|
||||
apc = irq_data_get_irq_chip_data(d);
|
||||
base = apc->ctrl_base;
|
||||
offset = apc->irq_base - d->irq;
|
||||
|
||||
switch (d->irq) {
|
||||
case ATH79_PCI_IRQ(0):
|
||||
switch (offset) {
|
||||
case 0:
|
||||
t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
|
||||
__raw_writel(t | AR724X_PCI_INT_DEV0,
|
||||
base + AR724X_PCI_REG_INT_MASK);
|
||||
|
@ -232,13 +288,17 @@ static void ar724x_pci_irq_unmask(struct irq_data *d)
|
|||
|
||||
static void ar724x_pci_irq_mask(struct irq_data *d)
|
||||
{
|
||||
struct ar724x_pci_controller *apc;
|
||||
void __iomem *base;
|
||||
int offset;
|
||||
u32 t;
|
||||
|
||||
base = ar724x_pci_ctrl_base;
|
||||
apc = irq_data_get_irq_chip_data(d);
|
||||
base = apc->ctrl_base;
|
||||
offset = apc->irq_base - d->irq;
|
||||
|
||||
switch (d->irq) {
|
||||
case ATH79_PCI_IRQ(0):
|
||||
switch (offset) {
|
||||
case 0:
|
||||
t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
|
||||
__raw_writel(t & ~AR724X_PCI_INT_DEV0,
|
||||
base + AR724X_PCI_REG_INT_MASK);
|
||||
|
@ -262,53 +322,123 @@ static struct irq_chip ar724x_pci_irq_chip = {
|
|||
.irq_mask_ack = ar724x_pci_irq_mask,
|
||||
};
|
||||
|
||||
static void __init ar724x_pci_irq_init(int irq)
|
||||
static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc,
|
||||
int id)
|
||||
{
|
||||
void __iomem *base;
|
||||
int i;
|
||||
|
||||
base = ar724x_pci_ctrl_base;
|
||||
base = apc->ctrl_base;
|
||||
|
||||
__raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
|
||||
__raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
|
||||
|
||||
BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT);
|
||||
apc->irq_base = ATH79_PCI_IRQ_BASE + (id * AR724X_PCI_IRQ_COUNT);
|
||||
|
||||
for (i = ATH79_PCI_IRQ_BASE;
|
||||
i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++)
|
||||
for (i = apc->irq_base;
|
||||
i < apc->irq_base + AR724X_PCI_IRQ_COUNT; i++) {
|
||||
irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
|
||||
handle_level_irq);
|
||||
|
||||
irq_set_chained_handler(irq, ar724x_pci_irq_handler);
|
||||
irq_set_chip_data(i, apc);
|
||||
}
|
||||
|
||||
int __init ar724x_pcibios_init(int irq)
|
||||
irq_set_handler_data(apc->irq, apc);
|
||||
irq_set_chained_handler(apc->irq, ar724x_pci_irq_handler);
|
||||
}
|
||||
|
||||
static int ar724x_pci_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
struct ar724x_pci_controller *apc;
|
||||
struct resource *res;
|
||||
int id;
|
||||
|
||||
ret = -ENOMEM;
|
||||
id = pdev->id;
|
||||
if (id == -1)
|
||||
id = 0;
|
||||
|
||||
ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE,
|
||||
AR724X_PCI_CFG_SIZE);
|
||||
if (ar724x_pci_devcfg_base == NULL)
|
||||
goto err;
|
||||
apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller),
|
||||
GFP_KERNEL);
|
||||
if (!apc)
|
||||
return -ENOMEM;
|
||||
|
||||
ar724x_pci_ctrl_base = ioremap(AR724X_PCI_CTRL_BASE,
|
||||
AR724X_PCI_CTRL_SIZE);
|
||||
if (ar724x_pci_ctrl_base == NULL)
|
||||
goto err_unmap_devcfg;
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base");
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
||||
ar724x_pci_link_up = ar724x_pci_check_link();
|
||||
if (!ar724x_pci_link_up)
|
||||
pr_warn("ar724x: PCIe link is down\n");
|
||||
apc->ctrl_base = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (apc->ctrl_base == NULL)
|
||||
return -EBUSY;
|
||||
|
||||
ar724x_pci_irq_init(irq);
|
||||
register_pci_controller(&ar724x_pci_controller);
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
apc->devcfg_base = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (!apc->devcfg_base)
|
||||
return -EBUSY;
|
||||
|
||||
err_unmap_devcfg:
|
||||
iounmap(ar724x_pci_devcfg_base);
|
||||
err:
|
||||
return ret;
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "crp_base");
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
||||
apc->crp_base = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (apc->crp_base == NULL)
|
||||
return -EBUSY;
|
||||
|
||||
apc->irq = platform_get_irq(pdev, 0);
|
||||
if (apc->irq < 0)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_init(&apc->lock);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base");
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
||||
apc->io_res.parent = res;
|
||||
apc->io_res.name = "PCI IO space";
|
||||
apc->io_res.start = res->start;
|
||||
apc->io_res.end = res->end;
|
||||
apc->io_res.flags = IORESOURCE_IO;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base");
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
||||
apc->mem_res.parent = res;
|
||||
apc->mem_res.name = "PCI memory space";
|
||||
apc->mem_res.start = res->start;
|
||||
apc->mem_res.end = res->end;
|
||||
apc->mem_res.flags = IORESOURCE_MEM;
|
||||
|
||||
apc->pci_controller.pci_ops = &ar724x_pci_ops;
|
||||
apc->pci_controller.io_resource = &apc->io_res;
|
||||
apc->pci_controller.mem_resource = &apc->mem_res;
|
||||
|
||||
apc->link_up = ar724x_pci_check_link(apc);
|
||||
if (!apc->link_up)
|
||||
dev_warn(&pdev->dev, "PCIe link is down\n");
|
||||
|
||||
ar724x_pci_irq_init(apc, id);
|
||||
|
||||
ar724x_pci_local_write(apc, PCI_COMMAND, 4, AR724X_PCI_CMD_INIT);
|
||||
|
||||
register_pci_controller(&apc->pci_controller);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ar724x_pci_driver = {
|
||||
.probe = ar724x_pci_probe,
|
||||
.driver = {
|
||||
.name = "ar724x-pci",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init ar724x_pci_init(void)
|
||||
{
|
||||
return platform_driver_register(&ar724x_pci_driver);
|
||||
}
|
||||
|
||||
postcore_initcall(ar724x_pci_init);
|
||||
|
|
|
@ -129,8 +129,16 @@ static int ltq_pci_startup(struct platform_device *pdev)
|
|||
|
||||
/* setup reset gpio used by pci */
|
||||
reset_gpio = of_get_named_gpio(node, "gpio-reset", 0);
|
||||
if (gpio_is_valid(reset_gpio))
|
||||
devm_gpio_request(&pdev->dev, reset_gpio, "pci-reset");
|
||||
if (gpio_is_valid(reset_gpio)) {
|
||||
int ret = devm_gpio_request(&pdev->dev,
|
||||
reset_gpio, "pci-reset");
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to request gpio %d\n", reset_gpio);
|
||||
return ret;
|
||||
}
|
||||
gpio_direction_output(reset_gpio, 1);
|
||||
}
|
||||
|
||||
/* enable auto-switching between PCI and EBU */
|
||||
ltq_pci_w32(0xa, PCI_CR_CLK_CTRL);
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
#include <asm/netlogic/interrupt.h>
|
||||
#include <asm/netlogic/haldefs.h>
|
||||
#include <asm/netlogic/common.h>
|
||||
|
||||
#include <asm/netlogic/xlp-hal/iomap.h>
|
||||
#include <asm/netlogic/xlp-hal/pic.h>
|
||||
|
@ -64,8 +65,12 @@ static inline u32 pci_cfg_read_32bit(struct pci_bus *bus, unsigned int devfn,
|
|||
u32 data;
|
||||
u32 *cfgaddr;
|
||||
|
||||
where &= ~3;
|
||||
if (bus->number == 0 && PCI_SLOT(devfn) == 1 && where == 0x954)
|
||||
return 0xffffffff;
|
||||
|
||||
cfgaddr = (u32 *)(pci_config_base +
|
||||
pci_cfg_addr(bus->number, devfn, where & ~3));
|
||||
pci_cfg_addr(bus->number, devfn, where));
|
||||
data = *cfgaddr;
|
||||
return data;
|
||||
}
|
||||
|
@ -157,32 +162,38 @@ struct pci_controller nlm_pci_controller = {
|
|||
.io_offset = 0x00000000UL,
|
||||
};
|
||||
|
||||
static int get_irq_vector(const struct pci_dev *dev)
|
||||
static struct pci_dev *xlp_get_pcie_link(const struct pci_dev *dev)
|
||||
{
|
||||
/*
|
||||
* For XLP PCIe, there is an IRQ per Link, find out which
|
||||
* link the device is on to assign interrupts
|
||||
*/
|
||||
if (dev->bus->self == NULL)
|
||||
return 0;
|
||||
struct pci_bus *bus, *p;
|
||||
|
||||
switch (dev->bus->self->devfn) {
|
||||
case 0x8:
|
||||
return PIC_PCIE_LINK_0_IRQ;
|
||||
case 0x9:
|
||||
return PIC_PCIE_LINK_1_IRQ;
|
||||
case 0xa:
|
||||
return PIC_PCIE_LINK_2_IRQ;
|
||||
case 0xb:
|
||||
return PIC_PCIE_LINK_3_IRQ;
|
||||
/* Find the bridge on bus 0 */
|
||||
bus = dev->bus;
|
||||
for (p = bus->parent; p && p->number != 0; p = p->parent)
|
||||
bus = p;
|
||||
|
||||
return p ? bus->self : NULL;
|
||||
}
|
||||
WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn);
|
||||
return 0;
|
||||
|
||||
static inline int nlm_pci_link_to_irq(int link)
|
||||
{
|
||||
return PIC_PCIE_LINK_0_IRQ + link;
|
||||
}
|
||||
|
||||
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
return get_irq_vector(dev);
|
||||
struct pci_dev *lnkdev;
|
||||
int lnkslot, lnkfunc;
|
||||
|
||||
/*
|
||||
* For XLP PCIe, there is an IRQ per Link, find out which
|
||||
* link the device is on to assign interrupts
|
||||
*/
|
||||
lnkdev = xlp_get_pcie_link(dev);
|
||||
if (lnkdev == NULL)
|
||||
return 0;
|
||||
lnkfunc = PCI_FUNC(lnkdev->devfn);
|
||||
lnkslot = PCI_SLOT(lnkdev->devfn);
|
||||
return nlm_irq_to_xirq(lnkslot / 8, nlm_pci_link_to_irq(lnkfunc));
|
||||
}
|
||||
|
||||
/* Do platform specific device initialization at pci_enable_device() time */
|
||||
|
@ -191,42 +202,48 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int xlp_enable_pci_bswap(void)
|
||||
/*
|
||||
* If big-endian, enable hardware byteswap on the PCIe bridges.
|
||||
* This will make both the SoC and PCIe devices behave consistently with
|
||||
* readl/writel.
|
||||
*/
|
||||
#ifdef __BIG_ENDIAN
|
||||
static void xlp_config_pci_bswap(int node, int link)
|
||||
{
|
||||
uint64_t pciebase, sysbase;
|
||||
int node, i;
|
||||
uint64_t nbubase, lnkbase;
|
||||
u32 reg;
|
||||
|
||||
/* Chip-0 so node set to 0 */
|
||||
node = 0;
|
||||
sysbase = nlm_get_bridge_regbase(node);
|
||||
nbubase = nlm_get_bridge_regbase(node);
|
||||
lnkbase = nlm_get_pcie_base(node, link);
|
||||
|
||||
/*
|
||||
* Enable byte swap in hardware. Program each link's PCIe SWAP regions
|
||||
* from the link's address ranges.
|
||||
*/
|
||||
for (i = 0; i < 4; i++) {
|
||||
pciebase = nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node, i));
|
||||
if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff)
|
||||
continue;
|
||||
reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_BASE0 + link);
|
||||
nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_BASE, reg);
|
||||
|
||||
reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_BASE0 + i);
|
||||
nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_BASE, reg);
|
||||
reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_LIMIT0 + link);
|
||||
nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_LIM, reg | 0xfff);
|
||||
|
||||
reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_LIMIT0 + i);
|
||||
nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_LIM,
|
||||
reg | 0xfff);
|
||||
reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_BASE0 + link);
|
||||
nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_BASE, reg);
|
||||
|
||||
reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_BASE0 + i);
|
||||
nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_BASE, reg);
|
||||
|
||||
reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_LIMIT0 + i);
|
||||
nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
|
||||
}
|
||||
return 0;
|
||||
reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_LIMIT0 + link);
|
||||
nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
|
||||
}
|
||||
#else
|
||||
/* Swap configuration not needed in little-endian mode */
|
||||
static inline void xlp_config_pci_bswap(int node, int link) {}
|
||||
#endif /* __BIG_ENDIAN */
|
||||
|
||||
static int __init pcibios_init(void)
|
||||
{
|
||||
struct nlm_soc_info *nodep;
|
||||
uint64_t pciebase;
|
||||
int link, n;
|
||||
u32 reg;
|
||||
|
||||
/* Firmware assigns PCI resources */
|
||||
pci_set_flags(PCI_PROBE_ONLY);
|
||||
pci_config_base = ioremap(XLP_DEFAULT_PCI_ECFG_BASE, 64 << 20);
|
||||
|
@ -235,7 +252,26 @@ static int __init pcibios_init(void)
|
|||
ioport_resource.start = 0;
|
||||
ioport_resource.end = ~0;
|
||||
|
||||
xlp_enable_pci_bswap();
|
||||
for (n = 0; n < NLM_NR_NODES; n++) {
|
||||
nodep = nlm_get_node(n);
|
||||
if (!nodep->coremask)
|
||||
continue; /* node does not exist */
|
||||
|
||||
for (link = 0; link < 4; link++) {
|
||||
pciebase = nlm_get_pcie_base(n, link);
|
||||
if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff)
|
||||
continue;
|
||||
xlp_config_pci_bswap(n, link);
|
||||
|
||||
/* put in intpin and irq - u-boot does not */
|
||||
reg = nlm_read_pci_reg(pciebase, 0xf);
|
||||
reg &= ~0x1fu;
|
||||
reg |= (1 << 8) | nlm_pci_link_to_irq(link);
|
||||
nlm_write_pci_reg(pciebase, 0xf, reg);
|
||||
pr_info("XLP PCIe: Link %d-%d initialized.\n", n, link);
|
||||
}
|
||||
}
|
||||
|
||||
set_io_port_base(CKSEG1);
|
||||
nlm_pci_controller.io_map_base = CKSEG1;
|
||||
|
||||
|
|
|
@ -175,9 +175,20 @@ static DEFINE_MUTEX(pci_scan_mutex);
|
|||
|
||||
void register_pci_controller(struct pci_controller *hose)
|
||||
{
|
||||
if (request_resource(&iomem_resource, hose->mem_resource) < 0)
|
||||
struct resource *parent;
|
||||
|
||||
parent = hose->mem_resource->parent;
|
||||
if (!parent)
|
||||
parent = &iomem_resource;
|
||||
|
||||
if (request_resource(parent, hose->mem_resource) < 0)
|
||||
goto out;
|
||||
if (request_resource(&ioport_resource, hose->io_resource) < 0) {
|
||||
|
||||
parent = hose->io_resource->parent;
|
||||
if (!parent)
|
||||
parent = &ioport_resource;
|
||||
|
||||
if (request_resource(parent, hose->io_resource) < 0) {
|
||||
release_resource(hose->mem_resource);
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
if RALINK
|
||||
|
||||
choice
|
||||
prompt "Ralink SoC selection"
|
||||
default SOC_RT305X
|
||||
help
|
||||
Select Ralink MIPS SoC type.
|
||||
|
||||
config SOC_RT305X
|
||||
bool "RT305x"
|
||||
select USB_ARCH_HAS_HCD
|
||||
select USB_ARCH_HAS_OHCI
|
||||
select USB_ARCH_HAS_EHCI
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Devicetree selection"
|
||||
default DTB_RT_NONE
|
||||
help
|
||||
Select the devicetree.
|
||||
|
||||
config DTB_RT_NONE
|
||||
bool "None"
|
||||
|
||||
config DTB_RT305X_EVAL
|
||||
bool "RT305x eval kit"
|
||||
depends on SOC_RT305X
|
||||
|
||||
endchoice
|
||||
|
||||
endif
|
|
@ -0,0 +1,15 @@
|
|||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 as published
|
||||
# by the Free Software Foundation.#
|
||||
# Makefile for the Ralink common stuff
|
||||
#
|
||||
# Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
# Copyright (C) 2013 John Crispin <blogic@openwrt.org>
|
||||
|
||||
obj-y := prom.o of.o reset.o clk.o irq.o
|
||||
|
||||
obj-$(CONFIG_SOC_RT305X) += rt305x.o
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
|
||||
obj-y += dts/
|
|
@ -0,0 +1,10 @@
|
|||
#
|
||||
# Ralink SoC common stuff
|
||||
#
|
||||
core-$(CONFIG_RALINK) += arch/mips/ralink/
|
||||
cflags-$(CONFIG_RALINK) += -I$(srctree)/arch/mips/include/asm/mach-ralink
|
||||
|
||||
#
|
||||
# Ralink RT305x
|
||||
#
|
||||
load-$(CONFIG_SOC_RT305X) += 0xffffffff80000000
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue