Merge branches 'fixes-for-linus', 'generic', 'cavium', 'module.h-fixes', 'next/ath79' and 'next/lantiq' into mips-for-linux-next
This commit is contained in:
commit
c819baf31f
38
Documentation/devicetree/bindings/gpio/gpio-mm-lantiq.txt
Normal file
38
Documentation/devicetree/bindings/gpio/gpio-mm-lantiq.txt
Normal file
@ -0,0 +1,38 @@
|
||||
Lantiq SoC External Bus memory mapped GPIO controller
|
||||
|
||||
By attaching hardware latches to the EBU it is possible to create output
|
||||
only gpios. This driver configures a special memory address, which when
|
||||
written to outputs 16 bit to the latches.
|
||||
|
||||
The node describing the memory mapped GPIOs needs to be a child of the node
|
||||
describing the "lantiq,localbus".
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "lantiq,gpio-mm-lantiq"
|
||||
- reg : Address and length of the register set for the device
|
||||
- #gpio-cells : Should be two. The first cell is the pin number and
|
||||
the second cell is used to specify optional parameters (currently
|
||||
unused).
|
||||
- gpio-controller : Marks the device node as a gpio controller.
|
||||
|
||||
Optional properties:
|
||||
- lantiq,shadow : The default value that we shall assume as already set on the
|
||||
shift register cascade.
|
||||
|
||||
Example:
|
||||
|
||||
localbus@0 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0 0 0x0 0x3ffffff /* addrsel0 */
|
||||
1 0 0x4000000 0x4000010>; /* addsel1 */
|
||||
compatible = "lantiq,localbus", "simple-bus";
|
||||
|
||||
gpio_mm0: gpio@4000000 {
|
||||
compatible = "lantiq,gpio-mm";
|
||||
reg = <1 0x0 0x10>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
lantiq,shadow = <0x77f>
|
||||
};
|
||||
}
|
42
Documentation/devicetree/bindings/gpio/gpio-stp-xway.txt
Normal file
42
Documentation/devicetree/bindings/gpio/gpio-stp-xway.txt
Normal file
@ -0,0 +1,42 @@
|
||||
Lantiq SoC Serial To Parallel (STP) GPIO controller
|
||||
|
||||
The Serial To Parallel (STP) is found on MIPS based Lantiq socs. It is a
|
||||
peripheral controller used to drive external shift register cascades. At most
|
||||
3 groups of 8 bits can be driven. The hardware is able to allow the DSL modem
|
||||
to drive the 2 LSBs of the cascade automatically.
|
||||
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "lantiq,gpio-stp-xway"
|
||||
- reg : Address and length of the register set for the device
|
||||
- #gpio-cells : Should be two. The first cell is the pin number and
|
||||
the second cell is used to specify optional parameters (currently
|
||||
unused).
|
||||
- gpio-controller : Marks the device node as a gpio controller.
|
||||
|
||||
Optional properties:
|
||||
- lantiq,shadow : The default value that we shall assume as already set on the
|
||||
shift register cascade.
|
||||
- lantiq,groups : Set the 3 bit mask to select which of the 3 groups are enabled
|
||||
in the shift register cascade.
|
||||
- lantiq,dsl : The dsl core can control the 2 LSBs of the gpio cascade. This 2 bit
|
||||
property can enable this feature.
|
||||
- lantiq,phy1 : The gphy1 core can control 3 bits of the gpio cascade.
|
||||
- lantiq,phy2 : The gphy2 core can control 3 bits of the gpio cascade.
|
||||
- lantiq,rising : use rising instead of falling edge for the shift register
|
||||
|
||||
Example:
|
||||
|
||||
gpio1: stp@E100BB0 {
|
||||
compatible = "lantiq,gpio-stp-xway";
|
||||
reg = <0xE100BB0 0x40>;
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
|
||||
lantiq,shadow = <0xffff>;
|
||||
lantiq,groups = <0x7>;
|
||||
lantiq,dsl = <0x3>;
|
||||
lantiq,phy1 = <0x7>;
|
||||
lantiq,phy2 = <0x7>;
|
||||
/* lantiq,rising; */
|
||||
};
|
@ -228,8 +228,9 @@ config LANTIQ
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select SWAP_IO_SPACE
|
||||
select BOOT_RAW
|
||||
select HAVE_CLK
|
||||
select MIPS_MACHINE
|
||||
select HAVE_MACH_CLKDEV
|
||||
select CLKDEV_LOOKUP
|
||||
select USE_OF
|
||||
|
||||
config LASAT
|
||||
bool "LASAT Networks platforms"
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/leds.h>
|
||||
|
@ -26,6 +26,18 @@ config ATH79_MACH_AP81
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Atheros AP81 reference board.
|
||||
|
||||
config ATH79_MACH_DB120
|
||||
bool "Atheros DB120 reference board"
|
||||
select SOC_AR934X
|
||||
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 DB120 reference board.
|
||||
|
||||
config ATH79_MACH_PB44
|
||||
bool "Atheros PB44 reference board"
|
||||
select SOC_AR71XX
|
||||
@ -52,12 +64,14 @@ endmenu
|
||||
config SOC_AR71XX
|
||||
select USB_ARCH_HAS_EHCI
|
||||
select USB_ARCH_HAS_OHCI
|
||||
select HW_HAS_PCI
|
||||
def_bool n
|
||||
|
||||
config SOC_AR724X
|
||||
select USB_ARCH_HAS_EHCI
|
||||
select USB_ARCH_HAS_OHCI
|
||||
select HW_HAS_PCI
|
||||
select PCI_AR724X if PCI
|
||||
def_bool n
|
||||
|
||||
config SOC_AR913X
|
||||
@ -68,6 +82,15 @@ config SOC_AR933X
|
||||
select USB_ARCH_HAS_EHCI
|
||||
def_bool n
|
||||
|
||||
config SOC_AR934X
|
||||
select USB_ARCH_HAS_EHCI
|
||||
select HW_HAS_PCI
|
||||
select PCI_AR724X if PCI
|
||||
def_bool n
|
||||
|
||||
config PCI_AR724X
|
||||
def_bool n
|
||||
|
||||
config ATH79_DEV_GPIO_BUTTONS
|
||||
def_bool n
|
||||
|
||||
@ -81,7 +104,7 @@ config ATH79_DEV_USB
|
||||
def_bool n
|
||||
|
||||
config ATH79_DEV_WMAC
|
||||
depends on (SOC_AR913X || SOC_AR933X)
|
||||
depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X)
|
||||
def_bool n
|
||||
|
||||
endif
|
||||
|
@ -11,6 +11,7 @@
|
||||
obj-y := prom.o setup.o irq.o common.o clock.o gpio.o
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
obj-$(CONFIG_PCI) += pci.o
|
||||
|
||||
#
|
||||
# Devices
|
||||
@ -27,5 +28,6 @@ obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wmac.o
|
||||
#
|
||||
obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.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
|
||||
obj-$(CONFIG_ATH79_MACH_UBNT_XM) += mach-ubnt-xm.o
|
||||
|
@ -1,8 +1,11 @@
|
||||
/*
|
||||
* Atheros AR71XX/AR724X/AR913X common routines
|
||||
*
|
||||
* Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
|
||||
* Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
*
|
||||
* Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
|
||||
*
|
||||
* 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.
|
||||
@ -163,6 +166,82 @@ static void __init ar933x_clocks_init(void)
|
||||
ath79_uart_clk.rate = ath79_ref_clk.rate;
|
||||
}
|
||||
|
||||
static void __init ar934x_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(AR934X_RESET_REG_BOOTSTRAP);
|
||||
if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40)
|
||||
ath79_ref_clk.rate = 40 * 1000 * 1000;
|
||||
else
|
||||
ath79_ref_clk.rate = 25 * 1000 * 1000;
|
||||
|
||||
pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG);
|
||||
out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
|
||||
AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
|
||||
ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
|
||||
AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
|
||||
nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
|
||||
AR934X_PLL_CPU_CONFIG_NINT_MASK;
|
||||
frac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
|
||||
AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
|
||||
|
||||
cpu_pll = nint * ath79_ref_clk.rate / ref_div;
|
||||
cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 6));
|
||||
cpu_pll /= (1 << out_div);
|
||||
|
||||
pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG);
|
||||
out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
|
||||
AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
|
||||
ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
|
||||
AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
|
||||
nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
|
||||
AR934X_PLL_DDR_CONFIG_NINT_MASK;
|
||||
frac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
|
||||
AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
|
||||
|
||||
ddr_pll = nint * ath79_ref_clk.rate / ref_div;
|
||||
ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 10));
|
||||
ddr_pll /= (1 << out_div);
|
||||
|
||||
clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
|
||||
|
||||
postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) &
|
||||
AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK;
|
||||
|
||||
if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS)
|
||||
ath79_cpu_clk.rate = ath79_ref_clk.rate;
|
||||
else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL)
|
||||
ath79_cpu_clk.rate = cpu_pll / (postdiv + 1);
|
||||
else
|
||||
ath79_cpu_clk.rate = ddr_pll / (postdiv + 1);
|
||||
|
||||
postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) &
|
||||
AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK;
|
||||
|
||||
if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS)
|
||||
ath79_ddr_clk.rate = ath79_ref_clk.rate;
|
||||
else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL)
|
||||
ath79_ddr_clk.rate = ddr_pll / (postdiv + 1);
|
||||
else
|
||||
ath79_ddr_clk.rate = cpu_pll / (postdiv + 1);
|
||||
|
||||
postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) &
|
||||
AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK;
|
||||
|
||||
if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS)
|
||||
ath79_ahb_clk.rate = ath79_ref_clk.rate;
|
||||
else if (clk_ctrl & AR934X_PLL_CPU_DDR_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())
|
||||
@ -173,6 +252,8 @@ void __init ath79_clocks_init(void)
|
||||
ar913x_clocks_init();
|
||||
else if (soc_is_ar933x())
|
||||
ar933x_clocks_init();
|
||||
else if (soc_is_ar934x())
|
||||
ar934x_clocks_init();
|
||||
else
|
||||
BUG();
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
/*
|
||||
* Atheros AR71XX/AR724X/AR913X common routines
|
||||
*
|
||||
* Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
|
||||
* Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
|
||||
*
|
||||
* 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.
|
||||
@ -67,6 +70,8 @@ void ath79_device_reset_set(u32 mask)
|
||||
reg = AR913X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_ar933x())
|
||||
reg = AR933X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_ar934x())
|
||||
reg = AR934X_RESET_REG_RESET_MODULE;
|
||||
else
|
||||
BUG();
|
||||
|
||||
@ -91,6 +96,8 @@ void ath79_device_reset_clear(u32 mask)
|
||||
reg = AR913X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_ar933x())
|
||||
reg = AR933X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_ar934x())
|
||||
reg = AR934X_RESET_REG_RESET_MODULE;
|
||||
else
|
||||
BUG();
|
||||
|
||||
|
@ -89,7 +89,8 @@ void __init ath79_register_uart(void)
|
||||
|
||||
if (soc_is_ar71xx() ||
|
||||
soc_is_ar724x() ||
|
||||
soc_is_ar913x()) {
|
||||
soc_is_ar913x() ||
|
||||
soc_is_ar934x()) {
|
||||
ath79_uart_data[0].uartclk = clk_get_rate(clk);
|
||||
platform_device_register(&ath79_uart_device);
|
||||
} else if (soc_is_ar933x()) {
|
||||
|
@ -25,12 +25,10 @@ void __init ath79_register_gpio_keys_polled(int id,
|
||||
struct gpio_keys_button *p;
|
||||
int err;
|
||||
|
||||
p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
|
||||
p = kmemdup(buttons, nbuttons * sizeof(*p), GFP_KERNEL);
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
memcpy(p, buttons, nbuttons * sizeof(*p));
|
||||
|
||||
pdev = platform_device_alloc("gpio-keys-polled", id);
|
||||
if (!pdev)
|
||||
goto err_free_buttons;
|
||||
|
@ -24,12 +24,10 @@ void __init ath79_register_leds_gpio(int id,
|
||||
struct gpio_led *p;
|
||||
int err;
|
||||
|
||||
p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
|
||||
p = kmemdup(leds, num_leds * sizeof(*p), GFP_KERNEL);
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
memcpy(p, leds, num_leds * sizeof(*p));
|
||||
|
||||
pdev = platform_device_alloc("leds-gpio", id);
|
||||
if (!pdev)
|
||||
goto err_free_leds;
|
||||
|
@ -1,9 +1,12 @@
|
||||
/*
|
||||
* Atheros AR913X/AR933X SoC built-in WMAC device support
|
||||
*
|
||||
* Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
|
||||
* Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* Parts of this file are based on Atheros 2.6.15/2.6.31 BSP
|
||||
*
|
||||
* 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.
|
||||
@ -26,8 +29,7 @@ static struct resource ath79_wmac_resources[] = {
|
||||
/* .start and .end fields are filled dynamically */
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.start = ATH79_CPU_IRQ_IP2,
|
||||
.end = ATH79_CPU_IRQ_IP2,
|
||||
/* .start and .end fields are filled dynamically */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
@ -53,6 +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;
|
||||
}
|
||||
|
||||
|
||||
@ -79,6 +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;
|
||||
|
||||
t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
|
||||
if (t & AR933X_BOOTSTRAP_REF_CLK_40)
|
||||
@ -92,12 +98,32 @@ static void __init ar933x_wmac_setup(void)
|
||||
ath79_wmac_data.external_reset = ar933x_wmac_reset;
|
||||
}
|
||||
|
||||
static void ar934x_wmac_setup(void)
|
||||
{
|
||||
u32 t;
|
||||
|
||||
ath79_wmac_device.name = "ar934x_wmac";
|
||||
|
||||
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);
|
||||
|
||||
t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
|
||||
if (t & AR934X_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())
|
||||
ar913x_wmac_setup();
|
||||
else if (soc_is_ar933x())
|
||||
ar933x_wmac_setup();
|
||||
else if (soc_is_ar934x())
|
||||
ar934x_wmac_setup();
|
||||
else
|
||||
BUG();
|
||||
|
||||
|
@ -71,6 +71,9 @@ static void prom_putchar_init(void)
|
||||
case REV_ID_MAJOR_AR7241:
|
||||
case REV_ID_MAJOR_AR7242:
|
||||
case REV_ID_MAJOR_AR913X:
|
||||
case REV_ID_MAJOR_AR9341:
|
||||
case REV_ID_MAJOR_AR9342:
|
||||
case REV_ID_MAJOR_AR9344:
|
||||
_prom_putchar = prom_putchar_ar71xx;
|
||||
break;
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
/*
|
||||
* Atheros AR71XX/AR724X/AR913X GPIO API support
|
||||
*
|
||||
* Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
|
||||
* Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
|
||||
*
|
||||
* 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.
|
||||
@ -89,6 +92,42 @@ static int ath79_gpio_direction_output(struct gpio_chip *chip,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
void __iomem *base = ath79_gpio_base;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ath79_gpio_lock, flags);
|
||||
|
||||
__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
|
||||
base + AR71XX_GPIO_REG_OE);
|
||||
|
||||
spin_unlock_irqrestore(&ath79_gpio_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
|
||||
int value)
|
||||
{
|
||||
void __iomem *base = ath79_gpio_base;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ath79_gpio_lock, flags);
|
||||
|
||||
if (value)
|
||||
__raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
|
||||
else
|
||||
__raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
|
||||
|
||||
__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
|
||||
base + AR71XX_GPIO_REG_OE);
|
||||
|
||||
spin_unlock_irqrestore(&ath79_gpio_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct gpio_chip ath79_gpio_chip = {
|
||||
.label = "ath79",
|
||||
.get = ath79_gpio_get_value,
|
||||
@ -155,11 +194,17 @@ void __init ath79_gpio_init(void)
|
||||
ath79_gpio_count = AR913X_GPIO_COUNT;
|
||||
else if (soc_is_ar933x())
|
||||
ath79_gpio_count = AR933X_GPIO_COUNT;
|
||||
else if (soc_is_ar934x())
|
||||
ath79_gpio_count = AR934X_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()) {
|
||||
ath79_gpio_chip.direction_input = ar934x_gpio_direction_input;
|
||||
ath79_gpio_chip.direction_output = ar934x_gpio_direction_output;
|
||||
}
|
||||
|
||||
err = gpiochip_add(&ath79_gpio_chip);
|
||||
if (err)
|
||||
|
@ -1,10 +1,11 @@
|
||||
/*
|
||||
* Atheros AR71xx/AR724x/AR913x specific interrupt handling
|
||||
*
|
||||
* Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
|
||||
* Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* Parts of this file are based on Atheros' 2.6.15 BSP
|
||||
* Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
|
||||
*
|
||||
* 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
|
||||
@ -23,8 +24,8 @@
|
||||
#include <asm/mach-ath79/ar71xx_regs.h>
|
||||
#include "common.h"
|
||||
|
||||
static unsigned int ath79_ip2_flush_reg;
|
||||
static unsigned int ath79_ip3_flush_reg;
|
||||
static void (*ath79_ip2_handler)(void);
|
||||
static void (*ath79_ip3_handler)(void);
|
||||
|
||||
static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
@ -129,7 +130,7 @@ 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())
|
||||
else if (soc_is_ar724x() || soc_is_ar933x() || soc_is_ar934x())
|
||||
ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
|
||||
else
|
||||
BUG();
|
||||
@ -143,6 +144,39 @@ static void __init ath79_misc_irq_init(void)
|
||||
irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler);
|
||||
}
|
||||
|
||||
static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
u32 status;
|
||||
|
||||
disable_irq_nosync(irq);
|
||||
|
||||
status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS);
|
||||
|
||||
if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) {
|
||||
ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_PCIE);
|
||||
generic_handle_irq(ATH79_IP2_IRQ(0));
|
||||
} else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) {
|
||||
ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_WMAC);
|
||||
generic_handle_irq(ATH79_IP2_IRQ(1));
|
||||
} else {
|
||||
spurious_interrupt();
|
||||
}
|
||||
|
||||
enable_irq(irq);
|
||||
}
|
||||
|
||||
static void ar934x_ip2_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_IP2, ar934x_ip2_irq_dispatch);
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(void)
|
||||
{
|
||||
unsigned long pending;
|
||||
@ -152,10 +186,8 @@ asmlinkage void plat_irq_dispatch(void)
|
||||
if (pending & STATUSF_IP7)
|
||||
do_IRQ(ATH79_CPU_IRQ_TIMER);
|
||||
|
||||
else if (pending & STATUSF_IP2) {
|
||||
ath79_ddr_wb_flush(ath79_ip2_flush_reg);
|
||||
do_IRQ(ATH79_CPU_IRQ_IP2);
|
||||
}
|
||||
else if (pending & STATUSF_IP2)
|
||||
ath79_ip2_handler();
|
||||
|
||||
else if (pending & STATUSF_IP4)
|
||||
do_IRQ(ATH79_CPU_IRQ_GE0);
|
||||
@ -163,10 +195,8 @@ asmlinkage void plat_irq_dispatch(void)
|
||||
else if (pending & STATUSF_IP5)
|
||||
do_IRQ(ATH79_CPU_IRQ_GE1);
|
||||
|
||||
else if (pending & STATUSF_IP3) {
|
||||
ath79_ddr_wb_flush(ath79_ip3_flush_reg);
|
||||
do_IRQ(ATH79_CPU_IRQ_USB);
|
||||
}
|
||||
else if (pending & STATUSF_IP3)
|
||||
ath79_ip3_handler();
|
||||
|
||||
else if (pending & STATUSF_IP6)
|
||||
do_IRQ(ATH79_CPU_IRQ_MISC);
|
||||
@ -175,24 +205,97 @@ asmlinkage void plat_irq_dispatch(void)
|
||||
spurious_interrupt();
|
||||
}
|
||||
|
||||
/*
|
||||
* The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for
|
||||
* these devices typically allocate coherent DMA memory, however the
|
||||
* DMA controller may still have some unsynchronized data in the FIFO.
|
||||
* Issue a flush in the handlers to ensure that the driver sees
|
||||
* the update.
|
||||
*/
|
||||
static void ar71xx_ip2_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI);
|
||||
do_IRQ(ATH79_CPU_IRQ_IP2);
|
||||
}
|
||||
|
||||
static void ar724x_ip2_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE);
|
||||
do_IRQ(ATH79_CPU_IRQ_IP2);
|
||||
}
|
||||
|
||||
static void ar913x_ip2_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC);
|
||||
do_IRQ(ATH79_CPU_IRQ_IP2);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void ar71xx_ip3_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ_USB);
|
||||
}
|
||||
|
||||
static void ar724x_ip3_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ_USB);
|
||||
}
|
||||
|
||||
static void ar913x_ip3_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ_USB);
|
||||
}
|
||||
|
||||
static void ar933x_ip3_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ_USB);
|
||||
}
|
||||
|
||||
static void ar934x_ip3_handler(void)
|
||||
{
|
||||
ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_USB);
|
||||
do_IRQ(ATH79_CPU_IRQ_USB);
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
if (soc_is_ar71xx()) {
|
||||
ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI;
|
||||
ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB;
|
||||
ath79_ip2_handler = ar71xx_ip2_handler;
|
||||
ath79_ip3_handler = ar71xx_ip3_handler;
|
||||
} else if (soc_is_ar724x()) {
|
||||
ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE;
|
||||
ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB;
|
||||
ath79_ip2_handler = ar724x_ip2_handler;
|
||||
ath79_ip3_handler = ar724x_ip3_handler;
|
||||
} else if (soc_is_ar913x()) {
|
||||
ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC;
|
||||
ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB;
|
||||
ath79_ip2_handler = ar913x_ip2_handler;
|
||||
ath79_ip3_handler = ar913x_ip3_handler;
|
||||
} else if (soc_is_ar933x()) {
|
||||
ath79_ip2_flush_reg = AR933X_DDR_REG_FLUSH_WMAC;
|
||||
ath79_ip3_flush_reg = AR933X_DDR_REG_FLUSH_USB;
|
||||
} else
|
||||
ath79_ip2_handler = ar933x_ip2_handler;
|
||||
ath79_ip3_handler = ar933x_ip3_handler;
|
||||
} else if (soc_is_ar934x()) {
|
||||
ath79_ip2_handler = ar934x_ip2_handler;
|
||||
ath79_ip3_handler = ar934x_ip3_handler;
|
||||
} else {
|
||||
BUG();
|
||||
}
|
||||
|
||||
cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC;
|
||||
mips_cpu_irq_init();
|
||||
ath79_misc_irq_init();
|
||||
|
||||
if (soc_is_ar934x())
|
||||
ar934x_ip2_irq_init();
|
||||
}
|
||||
|
134
arch/mips/ath79/mach-db120.c
Normal file
134
arch/mips/ath79/mach-db120.c
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Atheros DB120 reference board support
|
||||
*
|
||||
* Copyright (c) 2011 Qualcomm Atheros
|
||||
* Copyright (c) 2011 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-wmac.h"
|
||||
#include "pci.h"
|
||||
|
||||
#define DB120_GPIO_LED_WLAN_5G 12
|
||||
#define DB120_GPIO_LED_WLAN_2G 13
|
||||
#define DB120_GPIO_LED_STATUS 14
|
||||
#define DB120_GPIO_LED_WPS 15
|
||||
|
||||
#define DB120_GPIO_BTN_WPS 16
|
||||
|
||||
#define DB120_KEYS_POLL_INTERVAL 20 /* msecs */
|
||||
#define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL)
|
||||
|
||||
#define DB120_WMAC_CALDATA_OFFSET 0x1000
|
||||
#define DB120_PCIE_CALDATA_OFFSET 0x5000
|
||||
|
||||
static struct gpio_led db120_leds_gpio[] __initdata = {
|
||||
{
|
||||
.name = "db120:green:status",
|
||||
.gpio = DB120_GPIO_LED_STATUS,
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.name = "db120:green:wps",
|
||||
.gpio = DB120_GPIO_LED_WPS,
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.name = "db120:green:wlan-5g",
|
||||
.gpio = DB120_GPIO_LED_WLAN_5G,
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.name = "db120:green:wlan-2g",
|
||||
.gpio = DB120_GPIO_LED_WLAN_2G,
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_button db120_gpio_keys[] __initdata = {
|
||||
{
|
||||
.desc = "WPS button",
|
||||
.type = EV_KEY,
|
||||
.code = KEY_WPS_BUTTON,
|
||||
.debounce_interval = DB120_KEYS_DEBOUNCE_INTERVAL,
|
||||
.gpio = DB120_GPIO_BTN_WPS,
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct spi_board_info db120_spi_info[] = {
|
||||
{
|
||||
.bus_num = 0,
|
||||
.chip_select = 0,
|
||||
.max_speed_hz = 25000000,
|
||||
.modalias = "s25sl064a",
|
||||
}
|
||||
};
|
||||
|
||||
static struct ath79_spi_platform_data db120_spi_data = {
|
||||
.bus_num = 0,
|
||||
.num_chipselect = 1,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static struct ath9k_platform_data db120_ath9k_data;
|
||||
|
||||
static int db120_pci_plat_dev_init(struct pci_dev *dev)
|
||||
{
|
||||
switch (PCI_SLOT(dev->devfn)) {
|
||||
case 0:
|
||||
dev->dev.platform_data = &db120_ath9k_data;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init db120_pci_init(u8 *eeprom)
|
||||
{
|
||||
memcpy(db120_ath9k_data.eeprom_data, eeprom,
|
||||
sizeof(db120_ath9k_data.eeprom_data));
|
||||
|
||||
ath79_pci_set_plat_dev_init(db120_pci_plat_dev_init);
|
||||
ath79_register_pci();
|
||||
}
|
||||
#else
|
||||
static inline void db120_pci_init(void) {}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
static void __init db120_setup(void)
|
||||
{
|
||||
u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
|
||||
|
||||
ath79_register_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio),
|
||||
db120_leds_gpio);
|
||||
ath79_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL,
|
||||
ARRAY_SIZE(db120_gpio_keys),
|
||||
db120_gpio_keys);
|
||||
ath79_register_spi(&db120_spi_data, db120_spi_info,
|
||||
ARRAY_SIZE(db120_spi_info));
|
||||
ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET);
|
||||
db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET);
|
||||
}
|
||||
|
||||
MIPS_MACHINE(ATH79_MACH_DB120, "DB120", "Atheros DB120 reference board",
|
||||
db120_setup);
|
@ -19,6 +19,7 @@
|
||||
#include "dev-leds-gpio.h"
|
||||
#include "dev-spi.h"
|
||||
#include "dev-usb.h"
|
||||
#include "pci.h"
|
||||
|
||||
#define PB44_GPIO_I2C_SCL 0
|
||||
#define PB44_GPIO_I2C_SDA 1
|
||||
@ -114,6 +115,7 @@ static void __init pb44_init(void)
|
||||
ath79_register_spi(&pb44_spi_data, pb44_spi_info,
|
||||
ARRAY_SIZE(pb44_spi_info));
|
||||
ath79_register_usb();
|
||||
ath79_register_pci();
|
||||
}
|
||||
|
||||
MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
|
||||
|
@ -12,16 +12,15 @@
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
#include <linux/ath9k_platform.h>
|
||||
#include <asm/mach-ath79/pci-ath724x.h>
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
#include <asm/mach-ath79/irq.h>
|
||||
|
||||
#include "machtypes.h"
|
||||
#include "dev-gpio-buttons.h"
|
||||
#include "dev-leds-gpio.h"
|
||||
#include "dev-spi.h"
|
||||
#include "pci.h"
|
||||
|
||||
#define UBNT_XM_GPIO_LED_L1 0
|
||||
#define UBNT_XM_GPIO_LED_L2 1
|
||||
@ -33,7 +32,6 @@
|
||||
#define UBNT_XM_KEYS_POLL_INTERVAL 20
|
||||
#define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL)
|
||||
|
||||
#define UBNT_XM_PCI_IRQ 48
|
||||
#define UBNT_XM_EEPROM_ADDR (u8 *) KSEG1ADDR(0x1fff1000)
|
||||
|
||||
static struct gpio_led ubnt_xm_leds_gpio[] __initdata = {
|
||||
@ -84,12 +82,27 @@ static struct ath79_spi_platform_data ubnt_xm_spi_data = {
|
||||
#ifdef CONFIG_PCI
|
||||
static struct ath9k_platform_data ubnt_xm_eeprom_data;
|
||||
|
||||
static struct ath724x_pci_data ubnt_xm_pci_data[] = {
|
||||
{
|
||||
.irq = UBNT_XM_PCI_IRQ,
|
||||
.pdata = &ubnt_xm_eeprom_data,
|
||||
},
|
||||
};
|
||||
static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev)
|
||||
{
|
||||
switch (PCI_SLOT(dev->devfn)) {
|
||||
case 0:
|
||||
dev->dev.platform_data = &ubnt_xm_eeprom_data;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init ubnt_xm_pci_init(void)
|
||||
{
|
||||
memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
|
||||
sizeof(ubnt_xm_eeprom_data.eeprom_data));
|
||||
|
||||
ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init);
|
||||
ath79_register_pci();
|
||||
}
|
||||
#else
|
||||
static inline void ubnt_xm_pci_init(void) {}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
static void __init ubnt_xm_init(void)
|
||||
@ -104,13 +117,7 @@ static void __init ubnt_xm_init(void)
|
||||
ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info,
|
||||
ARRAY_SIZE(ubnt_xm_spi_info));
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
|
||||
sizeof(ubnt_xm_eeprom_data.eeprom_data));
|
||||
|
||||
ath724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data));
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
ubnt_xm_pci_init();
|
||||
}
|
||||
|
||||
MIPS_MACHINE(ATH79_MACH_UBNT_XM,
|
||||
|
@ -18,6 +18,7 @@ enum ath79_mach_type {
|
||||
ATH79_MACH_GENERIC = 0,
|
||||
ATH79_MACH_AP121, /* Atheros AP121 reference board */
|
||||
ATH79_MACH_AP81, /* Atheros AP81 reference board */
|
||||
ATH79_MACH_DB120, /* Atheros DB120 reference board */
|
||||
ATH79_MACH_PB44, /* Atheros PB44 reference board */
|
||||
ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */
|
||||
};
|
||||
|
130
arch/mips/ath79/pci.c
Normal file
130
arch/mips/ath79/pci.c
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Atheros AR71XX/AR724X specific PCI setup code
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
* Parts of this file are based on Atheros' 2.6.15 BSP
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.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);
|
||||
static const struct ath79_pci_irq *ath79_pci_irq_map __initdata;
|
||||
static unsigned ath79_pci_nr_irqs __initdata;
|
||||
|
||||
static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = {
|
||||
{
|
||||
.slot = 17,
|
||||
.pin = 1,
|
||||
.irq = ATH79_PCI_IRQ(0),
|
||||
}, {
|
||||
.slot = 18,
|
||||
.pin = 1,
|
||||
.irq = ATH79_PCI_IRQ(1),
|
||||
}, {
|
||||
.slot = 19,
|
||||
.pin = 1,
|
||||
.irq = ATH79_PCI_IRQ(2),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = {
|
||||
{
|
||||
.slot = 0,
|
||||
.pin = 1,
|
||||
.irq = ATH79_PCI_IRQ(0),
|
||||
}
|
||||
};
|
||||
|
||||
int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
|
||||
{
|
||||
int irq = -1;
|
||||
int i;
|
||||
|
||||
if (ath79_pci_nr_irqs == 0 ||
|
||||
ath79_pci_irq_map == NULL) {
|
||||
if (soc_is_ar71xx()) {
|
||||
ath79_pci_irq_map = ar71xx_pci_irq_map;
|
||||
ath79_pci_nr_irqs = ARRAY_SIZE(ar71xx_pci_irq_map);
|
||||
} else if (soc_is_ar724x() ||
|
||||
soc_is_ar9342() ||
|
||||
soc_is_ar9344()) {
|
||||
ath79_pci_irq_map = ar724x_pci_irq_map;
|
||||
ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map);
|
||||
} else {
|
||||
pr_crit("pci %s: invalid irq map\n",
|
||||
pci_name((struct pci_dev *) dev));
|
||||
return irq;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ath79_pci_nr_irqs; i++) {
|
||||
const struct ath79_pci_irq *entry;
|
||||
|
||||
entry = &ath79_pci_irq_map[i];
|
||||
if (entry->slot == slot && entry->pin == pin) {
|
||||
irq = entry->irq;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (irq < 0)
|
||||
pr_crit("pci %s: no irq found for pin %u\n",
|
||||
pci_name((struct pci_dev *) dev), pin);
|
||||
else
|
||||
pr_info("pci %s: using irq %d for pin %u\n",
|
||||
pci_name((struct pci_dev *) dev), irq, pin);
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
int pcibios_plat_dev_init(struct pci_dev *dev)
|
||||
{
|
||||
if (ath79_pci_plat_dev_init)
|
||||
return ath79_pci_plat_dev_init(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init ath79_pci_set_irq_map(unsigned nr_irqs,
|
||||
const struct ath79_pci_irq *map)
|
||||
{
|
||||
ath79_pci_nr_irqs = nr_irqs;
|
||||
ath79_pci_irq_map = map;
|
||||
}
|
||||
|
||||
void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev))
|
||||
{
|
||||
ath79_pci_plat_dev_init = func;
|
||||
}
|
||||
|
||||
int __init ath79_register_pci(void)
|
||||
{
|
||||
if (soc_is_ar71xx())
|
||||
return ar71xx_pcibios_init();
|
||||
|
||||
if (soc_is_ar724x())
|
||||
return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
34
arch/mips/ath79/pci.h
Normal file
34
arch/mips/ath79/pci.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 _ATH79_PCI_H
|
||||
#define _ATH79_PCI_H
|
||||
|
||||
struct ath79_pci_irq {
|
||||
u8 slot;
|
||||
u8 pin;
|
||||
int irq;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
void ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map);
|
||||
void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev));
|
||||
int ath79_register_pci(void);
|
||||
#else
|
||||
static inline void
|
||||
ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map) {}
|
||||
static inline void
|
||||
ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {}
|
||||
static inline int ath79_register_pci(void) { return 0; }
|
||||
#endif
|
||||
|
||||
#endif /* _ATH79_PCI_H */
|
@ -1,10 +1,11 @@
|
||||
/*
|
||||
* Atheros AR71XX/AR724X/AR913X specific setup
|
||||
*
|
||||
* Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
|
||||
* Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* Parts of this file are based on Atheros' 2.6.15 BSP
|
||||
* Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
|
||||
*
|
||||
* 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
|
||||
@ -116,18 +117,6 @@ static void __init ath79_detect_sys_type(void)
|
||||
rev = id & AR724X_REV_ID_REVISION_MASK;
|
||||
break;
|
||||
|
||||
case REV_ID_MAJOR_AR9330:
|
||||
ath79_soc = ATH79_SOC_AR9330;
|
||||
chip = "9330";
|
||||
rev = id & AR933X_REV_ID_REVISION_MASK;
|
||||
break;
|
||||
|
||||
case REV_ID_MAJOR_AR9331:
|
||||
ath79_soc = ATH79_SOC_AR9331;
|
||||
chip = "9331";
|
||||
rev = id & AR933X_REV_ID_REVISION_MASK;
|
||||
break;
|
||||
|
||||
case REV_ID_MAJOR_AR913X:
|
||||
minor = id & AR913X_REV_ID_MINOR_MASK;
|
||||
rev = id >> AR913X_REV_ID_REVISION_SHIFT;
|
||||
@ -145,6 +134,36 @@ static void __init ath79_detect_sys_type(void)
|
||||
}
|
||||
break;
|
||||
|
||||
case REV_ID_MAJOR_AR9330:
|
||||
ath79_soc = ATH79_SOC_AR9330;
|
||||
chip = "9330";
|
||||
rev = id & AR933X_REV_ID_REVISION_MASK;
|
||||
break;
|
||||
|
||||
case REV_ID_MAJOR_AR9331:
|
||||
ath79_soc = ATH79_SOC_AR9331;
|
||||
chip = "9331";
|
||||
rev = id & AR933X_REV_ID_REVISION_MASK;
|
||||
break;
|
||||
|
||||
case REV_ID_MAJOR_AR9341:
|
||||
ath79_soc = ATH79_SOC_AR9341;
|
||||
chip = "9341";
|
||||
rev = id & AR934X_REV_ID_REVISION_MASK;
|
||||
break;
|
||||
|
||||
case REV_ID_MAJOR_AR9342:
|
||||
ath79_soc = ATH79_SOC_AR9342;
|
||||
chip = "9342";
|
||||
rev = id & AR934X_REV_ID_REVISION_MASK;
|
||||
break;
|
||||
|
||||
case REV_ID_MAJOR_AR9344:
|
||||
ath79_soc = ATH79_SOC_AR9344;
|
||||
chip = "9344";
|
||||
rev = id & AR934X_REV_ID_REVISION_MASK;
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("ath79: unknown SoC, id:0x%08x", id);
|
||||
}
|
||||
|
@ -1,3 +1 @@
|
||||
obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o
|
||||
|
||||
ccflags-y := -Werror
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/serial.h>
|
||||
|
@ -257,8 +257,6 @@ DEFINE_PER_CPU(int, cpu_state);
|
||||
|
||||
extern void fixup_irqs(void);
|
||||
|
||||
static DEFINE_SPINLOCK(smp_reserve_lock);
|
||||
|
||||
static int octeon_cpu_disable(void)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
@ -266,8 +264,6 @@ static int octeon_cpu_disable(void)
|
||||
if (cpu == 0)
|
||||
return -EBUSY;
|
||||
|
||||
spin_lock(&smp_reserve_lock);
|
||||
|
||||
set_cpu_online(cpu, false);
|
||||
cpu_clear(cpu, cpu_callin_map);
|
||||
local_irq_disable();
|
||||
@ -277,8 +273,6 @@ static int octeon_cpu_disable(void)
|
||||
flush_cache_all();
|
||||
local_flush_tlb_all();
|
||||
|
||||
spin_unlock(&smp_reserve_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -8,5 +8,3 @@ lib-y += cmdline.o env.o file.o identify.o init.o \
|
||||
lib-$(CONFIG_ARC_MEMORY) += memory.o
|
||||
lib-$(CONFIG_ARC_CONSOLE) += arc_con.o
|
||||
lib-$(CONFIG_ARC_PROMLIB) += promlib.o
|
||||
|
||||
ccflags-y := -Werror
|
||||
|
25
arch/mips/include/asm/clkdev.h
Normal file
25
arch/mips/include/asm/clkdev.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* based on arch/arm/include/asm/clkdev.h
|
||||
*
|
||||
* Copyright (C) 2008 Russell King.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Helper for the clk API to assist looking up a struct clk.
|
||||
*/
|
||||
#ifndef __ASM_CLKDEV_H
|
||||
#define __ASM_CLKDEV_H
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define __clk_get(clk) ({ 1; })
|
||||
#define __clk_put(clk) do { } while (0)
|
||||
|
||||
static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
|
||||
{
|
||||
return kzalloc(size, GFP_KERNEL);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,10 +1,11 @@
|
||||
/*
|
||||
* Atheros AR71XX/AR724X/AR913X SoC register definitions
|
||||
*
|
||||
* Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
|
||||
* Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* Parts of this file are based on Atheros' 2.6.15 BSP
|
||||
* Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
|
||||
*
|
||||
* 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
|
||||
@ -60,6 +61,9 @@
|
||||
#define AR933X_EHCI_BASE 0x1b000000
|
||||
#define AR933X_EHCI_SIZE 0x1000
|
||||
|
||||
#define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000)
|
||||
#define AR934X_WMAC_SIZE 0x20000
|
||||
|
||||
/*
|
||||
* DDR_CTRL block
|
||||
*/
|
||||
@ -91,6 +95,12 @@
|
||||
#define AR933X_DDR_REG_FLUSH_USB 0x84
|
||||
#define AR933X_DDR_REG_FLUSH_WMAC 0x88
|
||||
|
||||
#define AR934X_DDR_REG_FLUSH_GE0 0x9c
|
||||
#define AR934X_DDR_REG_FLUSH_GE1 0xa0
|
||||
#define AR934X_DDR_REG_FLUSH_USB 0xa4
|
||||
#define AR934X_DDR_REG_FLUSH_PCIE 0xa8
|
||||
#define AR934X_DDR_REG_FLUSH_WMAC 0xac
|
||||
|
||||
/*
|
||||
* PLL block
|
||||
*/
|
||||
@ -150,6 +160,41 @@
|
||||
#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15
|
||||
#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7
|
||||
|
||||
#define AR934X_PLL_CPU_CONFIG_REG 0x00
|
||||
#define AR934X_PLL_DDR_CONFIG_REG 0x04
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_REG 0x08
|
||||
|
||||
#define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
|
||||
#define AR934X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f
|
||||
#define AR934X_PLL_CPU_CONFIG_NINT_SHIFT 6
|
||||
#define AR934X_PLL_CPU_CONFIG_NINT_MASK 0x3f
|
||||
#define AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
|
||||
#define AR934X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
|
||||
#define AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
|
||||
#define AR934X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3
|
||||
|
||||
#define AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT 0
|
||||
#define AR934X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff
|
||||
#define AR934X_PLL_DDR_CONFIG_NINT_SHIFT 10
|
||||
#define AR934X_PLL_DDR_CONFIG_NINT_MASK 0x3f
|
||||
#define AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
|
||||
#define AR934X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
|
||||
#define AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
|
||||
#define AR934X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
|
||||
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS BIT(4)
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT 5
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK 0x1f
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT 10
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK 0x1f
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT 15
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK 0x1f
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20)
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
|
||||
#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
|
||||
|
||||
/*
|
||||
* USB_CONFIG block
|
||||
*/
|
||||
@ -185,6 +230,10 @@
|
||||
#define AR933X_RESET_REG_RESET_MODULE 0x1c
|
||||
#define AR933X_RESET_REG_BOOTSTRAP 0xac
|
||||
|
||||
#define AR934X_RESET_REG_RESET_MODULE 0x1c
|
||||
#define AR934X_RESET_REG_BOOTSTRAP 0xb0
|
||||
#define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac
|
||||
|
||||
#define MISC_INT_ETHSW BIT(12)
|
||||
#define MISC_INT_TIMER4 BIT(10)
|
||||
#define MISC_INT_TIMER3 BIT(9)
|
||||
@ -241,6 +290,40 @@
|
||||
|
||||
#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0)
|
||||
|
||||
#define AR934X_BOOTSTRAP_SW_OPTION8 BIT(23)
|
||||
#define AR934X_BOOTSTRAP_SW_OPTION7 BIT(22)
|
||||
#define AR934X_BOOTSTRAP_SW_OPTION6 BIT(21)
|
||||
#define AR934X_BOOTSTRAP_SW_OPTION5 BIT(20)
|
||||
#define AR934X_BOOTSTRAP_SW_OPTION4 BIT(19)
|
||||
#define AR934X_BOOTSTRAP_SW_OPTION3 BIT(18)
|
||||
#define AR934X_BOOTSTRAP_SW_OPTION2 BIT(17)
|
||||
#define AR934X_BOOTSTRAP_SW_OPTION1 BIT(16)
|
||||
#define AR934X_BOOTSTRAP_USB_MODE_DEVICE BIT(7)
|
||||
#define AR934X_BOOTSTRAP_PCIE_RC BIT(6)
|
||||
#define AR934X_BOOTSTRAP_EJTAG_MODE BIT(5)
|
||||
#define AR934X_BOOTSTRAP_REF_CLK_40 BIT(4)
|
||||
#define AR934X_BOOTSTRAP_BOOT_FROM_SPI BIT(2)
|
||||
#define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1)
|
||||
#define AR934X_BOOTSTRAP_DDR1 BIT(0)
|
||||
|
||||
#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)
|
||||
#define AR934X_PCIE_WMAC_INT_WMAC_RXHP BIT(3)
|
||||
#define AR934X_PCIE_WMAC_INT_PCIE_RC BIT(4)
|
||||
#define AR934X_PCIE_WMAC_INT_PCIE_RC0 BIT(5)
|
||||
#define AR934X_PCIE_WMAC_INT_PCIE_RC1 BIT(6)
|
||||
#define AR934X_PCIE_WMAC_INT_PCIE_RC2 BIT(7)
|
||||
#define AR934X_PCIE_WMAC_INT_PCIE_RC3 BIT(8)
|
||||
#define AR934X_PCIE_WMAC_INT_WMAC_ALL \
|
||||
(AR934X_PCIE_WMAC_INT_WMAC_MISC | AR934X_PCIE_WMAC_INT_WMAC_TX | \
|
||||
AR934X_PCIE_WMAC_INT_WMAC_RXLP | AR934X_PCIE_WMAC_INT_WMAC_RXHP)
|
||||
|
||||
#define AR934X_PCIE_WMAC_INT_PCIE_ALL \
|
||||
(AR934X_PCIE_WMAC_INT_PCIE_RC | AR934X_PCIE_WMAC_INT_PCIE_RC0 | \
|
||||
AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \
|
||||
AR934X_PCIE_WMAC_INT_PCIE_RC3)
|
||||
|
||||
#define REV_ID_MAJOR_MASK 0xfff0
|
||||
#define REV_ID_MAJOR_AR71XX 0x00a0
|
||||
#define REV_ID_MAJOR_AR913X 0x00b0
|
||||
@ -249,6 +332,9 @@
|
||||
#define REV_ID_MAJOR_AR7242 0x1100
|
||||
#define REV_ID_MAJOR_AR9330 0x0110
|
||||
#define REV_ID_MAJOR_AR9331 0x1110
|
||||
#define REV_ID_MAJOR_AR9341 0x0120
|
||||
#define REV_ID_MAJOR_AR9342 0x1120
|
||||
#define REV_ID_MAJOR_AR9344 0x2120
|
||||
|
||||
#define AR71XX_REV_ID_MINOR_MASK 0x3
|
||||
#define AR71XX_REV_ID_MINOR_AR7130 0x0
|
||||
@ -267,6 +353,8 @@
|
||||
|
||||
#define AR724X_REV_ID_REVISION_MASK 0x3
|
||||
|
||||
#define AR934X_REV_ID_REVISION_MASK 0xf
|
||||
|
||||
/*
|
||||
* SPI block
|
||||
*/
|
||||
@ -308,5 +396,6 @@
|
||||
#define AR724X_GPIO_COUNT 18
|
||||
#define AR913X_GPIO_COUNT 22
|
||||
#define AR933X_GPIO_COUNT 30
|
||||
#define AR934X_GPIO_COUNT 23
|
||||
|
||||
#endif /* __ASM_MACH_AR71XX_REGS_H */
|
||||
|
@ -29,6 +29,9 @@ enum ath79_soc_type {
|
||||
ATH79_SOC_AR9132,
|
||||
ATH79_SOC_AR9330,
|
||||
ATH79_SOC_AR9331,
|
||||
ATH79_SOC_AR9341,
|
||||
ATH79_SOC_AR9342,
|
||||
ATH79_SOC_AR9344,
|
||||
};
|
||||
|
||||
extern enum ath79_soc_type ath79_soc;
|
||||
@ -75,6 +78,26 @@ static inline int soc_is_ar933x(void)
|
||||
ath79_soc == ATH79_SOC_AR9331);
|
||||
}
|
||||
|
||||
static inline int soc_is_ar9341(void)
|
||||
{
|
||||
return (ath79_soc == ATH79_SOC_AR9341);
|
||||
}
|
||||
|
||||
static inline int soc_is_ar9342(void)
|
||||
{
|
||||
return (ath79_soc == ATH79_SOC_AR9342);
|
||||
}
|
||||
|
||||
static inline int soc_is_ar9344(void)
|
||||
{
|
||||
return (ath79_soc == ATH79_SOC_AR9344);
|
||||
}
|
||||
|
||||
static inline int soc_is_ar934x(void)
|
||||
{
|
||||
return soc_is_ar9341() || soc_is_ar9342() || soc_is_ar9344();
|
||||
}
|
||||
|
||||
extern void __iomem *ath79_ddr_base;
|
||||
extern void __iomem *ath79_pll_base;
|
||||
extern void __iomem *ath79_reset_base;
|
||||
|
@ -10,11 +10,19 @@
|
||||
#define __ASM_MACH_ATH79_IRQ_H
|
||||
|
||||
#define MIPS_CPU_IRQ_BASE 0
|
||||
#define NR_IRQS 40
|
||||
#define NR_IRQS 48
|
||||
|
||||
#define ATH79_MISC_IRQ_BASE 8
|
||||
#define ATH79_MISC_IRQ_COUNT 32
|
||||
|
||||
#define ATH79_PCI_IRQ_BASE (ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT)
|
||||
#define ATH79_PCI_IRQ_COUNT 6
|
||||
#define ATH79_PCI_IRQ(_x) (ATH79_PCI_IRQ_BASE + (_x))
|
||||
|
||||
#define ATH79_IP2_IRQ_BASE (ATH79_PCI_IRQ_BASE + ATH79_PCI_IRQ_COUNT)
|
||||
#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)
|
||||
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Atheros 724x PCI support
|
||||
*
|
||||
* Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
|
||||
*
|
||||
* 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_ATH724X_H
|
||||
#define __ASM_MACH_ATH79_PCI_ATH724X_H
|
||||
|
||||
struct ath724x_pci_data {
|
||||
int irq;
|
||||
void *pdata;
|
||||
};
|
||||
|
||||
void ath724x_pci_add_data(struct ath724x_pci_data *data, int size);
|
||||
|
||||
#endif /* __ASM_MACH_ATH79_PCI_ATH724X_H */
|
28
arch/mips/include/asm/mach-ath79/pci.h
Normal file
28
arch/mips/include/asm/mach-ath79/pci.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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 */
|
23
arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
Normal file
23
arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
|
||||
*/
|
||||
|
||||
#ifndef _FALCON_IRQ__
|
||||
#define _FALCON_IRQ__
|
||||
|
||||
#define INT_NUM_IRQ0 8
|
||||
#define INT_NUM_IM0_IRL0 (INT_NUM_IRQ0 + 0)
|
||||
#define INT_NUM_IM1_IRL0 (INT_NUM_IM0_IRL0 + 32)
|
||||
#define INT_NUM_IM2_IRL0 (INT_NUM_IM1_IRL0 + 32)
|
||||
#define INT_NUM_IM3_IRL0 (INT_NUM_IM2_IRL0 + 32)
|
||||
#define INT_NUM_IM4_IRL0 (INT_NUM_IM3_IRL0 + 32)
|
||||
#define INT_NUM_EXTRA_START (INT_NUM_IM4_IRL0 + 32)
|
||||
#define INT_NUM_IM_OFFSET (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0)
|
||||
|
||||
#define MIPS_CPU_TIMER_IRQ 7
|
||||
|
||||
#endif /* _FALCON_IRQ__ */
|
18
arch/mips/include/asm/mach-lantiq/falcon/irq.h
Normal file
18
arch/mips/include/asm/mach-lantiq/falcon/irq.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
|
||||
*/
|
||||
|
||||
#ifndef __FALCON_IRQ_H
|
||||
#define __FALCON_IRQ_H
|
||||
|
||||
#include <falcon_irq.h>
|
||||
|
||||
#define NR_IRQS 328
|
||||
|
||||
#include_next <irq.h>
|
||||
|
||||
#endif
|
67
arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
Normal file
67
arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#ifndef _LTQ_FALCON_H__
|
||||
#define _LTQ_FALCON_H__
|
||||
|
||||
#ifdef CONFIG_SOC_FALCON
|
||||
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <lantiq.h>
|
||||
|
||||
/* Chip IDs */
|
||||
#define SOC_ID_FALCON 0x01B8
|
||||
|
||||
/* SoC Types */
|
||||
#define SOC_TYPE_FALCON 0x01
|
||||
|
||||
/*
|
||||
* during early_printk no ioremap possible at this early stage
|
||||
* lets use KSEG1 instead
|
||||
*/
|
||||
#define LTQ_ASC0_BASE_ADDR 0x1E100C00
|
||||
#define LTQ_EARLY_ASC KSEG1ADDR(LTQ_ASC0_BASE_ADDR)
|
||||
|
||||
/* WDT */
|
||||
#define LTQ_RST_CAUSE_WDTRST 0x0002
|
||||
|
||||
/* CHIP ID */
|
||||
#define LTQ_STATUS_BASE_ADDR 0x1E802000
|
||||
|
||||
#define FALCON_CHIPID ((u32 *)(KSEG1 + LTQ_STATUS_BASE_ADDR + 0x0c))
|
||||
#define FALCON_CHIPTYPE ((u32 *)(KSEG1 + LTQ_STATUS_BASE_ADDR + 0x38))
|
||||
#define FALCON_CHIPCONF ((u32 *)(KSEG1 + LTQ_STATUS_BASE_ADDR + 0x40))
|
||||
|
||||
/* SYSCTL - start/stop/restart/configure/... different parts of the Soc */
|
||||
#define SYSCTL_SYS1 0
|
||||
#define SYSCTL_SYSETH 1
|
||||
#define SYSCTL_SYSGPE 2
|
||||
|
||||
/* BOOT_SEL - find what boot media we have */
|
||||
#define BS_FLASH 0x1
|
||||
#define BS_SPI 0x4
|
||||
|
||||
/* global register ranges */
|
||||
extern __iomem void *ltq_ebu_membase;
|
||||
extern __iomem void *ltq_sys1_membase;
|
||||
#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y))
|
||||
#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x))
|
||||
|
||||
#define ltq_sys1_w32(x, y) ltq_w32((x), ltq_sys1_membase + (y))
|
||||
#define ltq_sys1_r32(x) ltq_r32(ltq_sys1_membase + (x))
|
||||
#define ltq_sys1_w32_mask(clear, set, reg) \
|
||||
ltq_sys1_w32((ltq_sys1_r32(reg) & ~(clear)) | (set), reg)
|
||||
|
||||
/*
|
||||
* to keep the irq code generic we need to define this to 0 as falcon
|
||||
* has no EIU/EBU
|
||||
*/
|
||||
#define LTQ_EBU_PCC_ISTAT 0
|
||||
|
||||
#endif /* CONFIG_SOC_FALCON */
|
||||
#endif /* _LTQ_XWAY_H__ */
|
16
arch/mips/include/asm/mach-lantiq/gpio.h
Normal file
16
arch/mips/include/asm/mach-lantiq/gpio.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef __ASM_MIPS_MACH_LANTIQ_GPIO_H
|
||||
#define __ASM_MIPS_MACH_LANTIQ_GPIO_H
|
||||
|
||||
static inline int gpio_to_irq(unsigned int gpio)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define gpio_get_value __gpio_get_value
|
||||
#define gpio_set_value __gpio_set_value
|
||||
|
||||
#define gpio_cansleep __gpio_cansleep
|
||||
|
||||
#include <asm-generic/gpio.h>
|
||||
|
||||
#endif
|
@ -9,6 +9,8 @@
|
||||
#define _LANTIQ_H__
|
||||
|
||||
#include <linux/irq.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
/* generic reg access functions */
|
||||
#define ltq_r32(reg) __raw_readl(reg)
|
||||
@ -21,25 +23,9 @@
|
||||
/* register access macros for EBU and CGU */
|
||||
#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y))
|
||||
#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x))
|
||||
#define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y))
|
||||
#define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x))
|
||||
|
||||
#define ltq_ebu_w32_mask(x, y, z) \
|
||||
ltq_w32_mask(x, y, ltq_ebu_membase + (z))
|
||||
extern __iomem void *ltq_ebu_membase;
|
||||
extern __iomem void *ltq_cgu_membase;
|
||||
|
||||
extern unsigned int ltq_get_cpu_ver(void);
|
||||
extern unsigned int ltq_get_soc_type(void);
|
||||
|
||||
/* clock speeds */
|
||||
#define CLOCK_60M 60000000
|
||||
#define CLOCK_83M 83333333
|
||||
#define CLOCK_111M 111111111
|
||||
#define CLOCK_133M 133333333
|
||||
#define CLOCK_167M 166666667
|
||||
#define CLOCK_200M 200000000
|
||||
#define CLOCK_266M 266666666
|
||||
#define CLOCK_333M 333333333
|
||||
#define CLOCK_400M 400000000
|
||||
|
||||
/* spinlock all ebu i/o */
|
||||
extern spinlock_t ebu_lock;
|
||||
@ -49,15 +35,21 @@ 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);
|
||||
|
||||
/* clock handling */
|
||||
extern int clk_activate(struct clk *clk);
|
||||
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);
|
||||
|
||||
/* find out what bootsource we have */
|
||||
extern unsigned char ltq_boot_select(void);
|
||||
/* find out what caused the last cpu reset */
|
||||
extern int ltq_reset_cause(void);
|
||||
#define LTQ_RST_CAUSE_WDTRST 0x20
|
||||
|
||||
#define IOPORT_RESOURCE_START 0x10000000
|
||||
#define IOPORT_RESOURCE_END 0xffffffff
|
||||
#define IOMEM_RESOURCE_START 0x10000000
|
||||
#define IOMEM_RESOURCE_END 0xffffffff
|
||||
#define LTQ_FLASH_START 0x10000000
|
||||
#define LTQ_FLASH_MAX 0x04000000
|
||||
|
||||
#endif
|
||||
|
@ -9,41 +9,8 @@
|
||||
#ifndef _LANTIQ_PLATFORM_H__
|
||||
#define _LANTIQ_PLATFORM_H__
|
||||
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/socket.h>
|
||||
|
||||
/* struct used to pass info to the pci core */
|
||||
enum {
|
||||
PCI_CLOCK_INT = 0,
|
||||
PCI_CLOCK_EXT
|
||||
};
|
||||
|
||||
#define PCI_EXIN0 0x0001
|
||||
#define PCI_EXIN1 0x0002
|
||||
#define PCI_EXIN2 0x0004
|
||||
#define PCI_EXIN3 0x0008
|
||||
#define PCI_EXIN4 0x0010
|
||||
#define PCI_EXIN5 0x0020
|
||||
#define PCI_EXIN_MAX 6
|
||||
|
||||
#define PCI_GNT1 0x0040
|
||||
#define PCI_GNT2 0x0080
|
||||
#define PCI_GNT3 0x0100
|
||||
#define PCI_GNT4 0x0200
|
||||
|
||||
#define PCI_REQ1 0x0400
|
||||
#define PCI_REQ2 0x0800
|
||||
#define PCI_REQ3 0x1000
|
||||
#define PCI_REQ4 0x2000
|
||||
#define PCI_REQ_SHIFT 10
|
||||
#define PCI_REQ_MASK 0xf
|
||||
|
||||
struct ltq_pci_data {
|
||||
int clock;
|
||||
int gpio;
|
||||
int irq[16];
|
||||
};
|
||||
|
||||
/* struct used to pass info to network drivers */
|
||||
struct ltq_eth_data {
|
||||
struct sockaddr mac;
|
||||
|
@ -17,50 +17,8 @@
|
||||
#define INT_NUM_IM4_IRL0 (INT_NUM_IRQ0 + 128)
|
||||
#define INT_NUM_IM_OFFSET (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0)
|
||||
|
||||
#define LTQ_ASC_TIR(x) (INT_NUM_IM3_IRL0 + (x * 8))
|
||||
#define LTQ_ASC_RIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 1)
|
||||
#define LTQ_ASC_EIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 2)
|
||||
|
||||
#define LTQ_ASC_ASE_TIR INT_NUM_IM2_IRL0
|
||||
#define LTQ_ASC_ASE_RIR (INT_NUM_IM2_IRL0 + 2)
|
||||
#define LTQ_ASC_ASE_EIR (INT_NUM_IM2_IRL0 + 3)
|
||||
|
||||
#define LTQ_SSC_TIR (INT_NUM_IM0_IRL0 + 15)
|
||||
#define LTQ_SSC_RIR (INT_NUM_IM0_IRL0 + 14)
|
||||
#define LTQ_SSC_EIR (INT_NUM_IM0_IRL0 + 16)
|
||||
|
||||
#define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
|
||||
#define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
|
||||
|
||||
#define LTQ_TIMER6_INT (INT_NUM_IM1_IRL0 + 23)
|
||||
#define LTQ_USB_INT (INT_NUM_IM1_IRL0 + 22)
|
||||
#define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23)
|
||||
|
||||
#define MIPS_CPU_TIMER_IRQ 7
|
||||
|
||||
#define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0)
|
||||
#define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1)
|
||||
#define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2)
|
||||
#define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3)
|
||||
#define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4)
|
||||
#define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5)
|
||||
#define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6)
|
||||
#define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7)
|
||||
#define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8)
|
||||
#define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9)
|
||||
#define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10)
|
||||
#define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11)
|
||||
#define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25)
|
||||
#define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26)
|
||||
#define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27)
|
||||
#define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28)
|
||||
#define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29)
|
||||
#define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30)
|
||||
#define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16)
|
||||
#define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21)
|
||||
|
||||
#define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24)
|
||||
|
||||
#define INT_NUM_IM4_IRL14 (INT_NUM_IM4_IRL0 + 14)
|
||||
#define MIPS_CPU_TIMER_IRQ 7
|
||||
|
||||
#endif
|
||||
|
@ -17,38 +17,56 @@
|
||||
#define SOC_ID_DANUBE1 0x129
|
||||
#define SOC_ID_DANUBE2 0x12B
|
||||
#define SOC_ID_TWINPASS 0x12D
|
||||
#define SOC_ID_AMAZON_SE 0x152
|
||||
#define SOC_ID_AMAZON_SE_1 0x152 /* 50601 */
|
||||
#define SOC_ID_AMAZON_SE_2 0x153 /* 50600 */
|
||||
#define SOC_ID_ARX188 0x16C
|
||||
#define SOC_ID_ARX168 0x16D
|
||||
#define SOC_ID_ARX168_1 0x16D
|
||||
#define SOC_ID_ARX168_2 0x16E
|
||||
#define SOC_ID_ARX182 0x16F
|
||||
#define SOC_ID_GRX188 0x170
|
||||
#define SOC_ID_GRX168 0x171
|
||||
|
||||
/* SoC Types */
|
||||
#define SOC_ID_VRX288 0x1C0 /* v1.1 */
|
||||
#define SOC_ID_VRX282 0x1C1 /* v1.1 */
|
||||
#define SOC_ID_VRX268 0x1C2 /* v1.1 */
|
||||
#define SOC_ID_GRX268 0x1C8 /* v1.1 */
|
||||
#define SOC_ID_GRX288 0x1C9 /* v1.1 */
|
||||
#define SOC_ID_VRX288_2 0x00B /* v1.2 */
|
||||
#define SOC_ID_VRX268_2 0x00C /* v1.2 */
|
||||
#define SOC_ID_GRX288_2 0x00D /* v1.2 */
|
||||
#define SOC_ID_GRX282_2 0x00E /* v1.2 */
|
||||
|
||||
/* SoC Types */
|
||||
#define SOC_TYPE_DANUBE 0x01
|
||||
#define SOC_TYPE_TWINPASS 0x02
|
||||
#define SOC_TYPE_AR9 0x03
|
||||
#define SOC_TYPE_VR9 0x04
|
||||
#define SOC_TYPE_AMAZON_SE 0x05
|
||||
#define SOC_TYPE_VR9 0x04 /* v1.1 */
|
||||
#define SOC_TYPE_VR9_2 0x05 /* v1.2 */
|
||||
#define SOC_TYPE_AMAZON_SE 0x06
|
||||
|
||||
/* ASC0/1 - serial port */
|
||||
#define LTQ_ASC0_BASE_ADDR 0x1E100400
|
||||
/* BOOT_SEL - find what boot media we have */
|
||||
#define BS_EXT_ROM 0x0
|
||||
#define BS_FLASH 0x1
|
||||
#define BS_MII0 0x2
|
||||
#define BS_PCI 0x3
|
||||
#define BS_UART1 0x4
|
||||
#define BS_SPI 0x5
|
||||
#define BS_NAND 0x6
|
||||
#define BS_RMII0 0x7
|
||||
|
||||
/* helpers used to access the cgu */
|
||||
#define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y))
|
||||
#define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x))
|
||||
extern __iomem void *ltq_cgu_membase;
|
||||
|
||||
/*
|
||||
* during early_printk no ioremap is possible
|
||||
* lets use KSEG1 instead
|
||||
*/
|
||||
#define LTQ_ASC1_BASE_ADDR 0x1E100C00
|
||||
#define LTQ_ASC_SIZE 0x400
|
||||
|
||||
/* RCU - reset control unit */
|
||||
#define LTQ_RCU_BASE_ADDR 0x1F203000
|
||||
#define LTQ_RCU_SIZE 0x1000
|
||||
|
||||
/* GPTU - general purpose timer unit */
|
||||
#define LTQ_GPTU_BASE_ADDR 0x18000300
|
||||
#define LTQ_GPTU_SIZE 0x100
|
||||
#define LTQ_EARLY_ASC KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
|
||||
|
||||
/* EBU - external bus unit */
|
||||
#define LTQ_EBU_GPIO_START 0x14000000
|
||||
#define LTQ_EBU_GPIO_SIZE 0x1000
|
||||
|
||||
#define LTQ_EBU_BASE_ADDR 0x1E105300
|
||||
#define LTQ_EBU_SIZE 0x100
|
||||
|
||||
#define LTQ_EBU_BUSCON0 0x0060
|
||||
#define LTQ_EBU_PCC_CON 0x0090
|
||||
#define LTQ_EBU_PCC_IEN 0x00A4
|
||||
@ -57,85 +75,17 @@
|
||||
#define LTQ_EBU_ADDRSEL1 0x0024
|
||||
#define EBU_WRDIS 0x80000000
|
||||
|
||||
/* CGU - clock generation unit */
|
||||
#define LTQ_CGU_BASE_ADDR 0x1F103000
|
||||
#define LTQ_CGU_SIZE 0x1000
|
||||
|
||||
/* ICU - interrupt control unit */
|
||||
#define LTQ_ICU_BASE_ADDR 0x1F880200
|
||||
#define LTQ_ICU_SIZE 0x100
|
||||
|
||||
/* EIU - external interrupt unit */
|
||||
#define LTQ_EIU_BASE_ADDR 0x1F101000
|
||||
#define LTQ_EIU_SIZE 0x1000
|
||||
|
||||
/* PMU - power management unit */
|
||||
#define LTQ_PMU_BASE_ADDR 0x1F102000
|
||||
#define LTQ_PMU_SIZE 0x1000
|
||||
|
||||
#define PMU_DMA 0x0020
|
||||
#define PMU_USB 0x8041
|
||||
#define PMU_LED 0x0800
|
||||
#define PMU_GPT 0x1000
|
||||
#define PMU_PPE 0x2000
|
||||
#define PMU_FPI 0x4000
|
||||
#define PMU_SWITCH 0x10000000
|
||||
|
||||
/* ETOP - ethernet */
|
||||
#define LTQ_ETOP_BASE_ADDR 0x1E180000
|
||||
#define LTQ_ETOP_SIZE 0x40000
|
||||
|
||||
/* DMA */
|
||||
#define LTQ_DMA_BASE_ADDR 0x1E104100
|
||||
#define LTQ_DMA_SIZE 0x800
|
||||
|
||||
/* PCI */
|
||||
#define PCI_CR_BASE_ADDR 0x1E105400
|
||||
#define PCI_CR_SIZE 0x400
|
||||
|
||||
/* WDT */
|
||||
#define LTQ_WDT_BASE_ADDR 0x1F8803F0
|
||||
#define LTQ_WDT_SIZE 0x10
|
||||
|
||||
/* STP - serial to parallel conversion unit */
|
||||
#define LTQ_STP_BASE_ADDR 0x1E100BB0
|
||||
#define LTQ_STP_SIZE 0x40
|
||||
|
||||
/* GPIO */
|
||||
#define LTQ_GPIO0_BASE_ADDR 0x1E100B10
|
||||
#define LTQ_GPIO1_BASE_ADDR 0x1E100B40
|
||||
#define LTQ_GPIO2_BASE_ADDR 0x1E100B70
|
||||
#define LTQ_GPIO_SIZE 0x30
|
||||
|
||||
/* SSC */
|
||||
#define LTQ_SSC_BASE_ADDR 0x1e100800
|
||||
#define LTQ_SSC_SIZE 0x100
|
||||
|
||||
/* MEI - dsl core */
|
||||
#define LTQ_MEI_BASE_ADDR 0x1E116000
|
||||
|
||||
/* DEU - data encryption unit */
|
||||
#define LTQ_DEU_BASE_ADDR 0x1E103100
|
||||
#define LTQ_RST_CAUSE_WDTRST 0x20
|
||||
|
||||
/* MPS - multi processor unit (voice) */
|
||||
#define LTQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000)
|
||||
#define LTQ_MPS_CHIPID ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344))
|
||||
|
||||
/* request a non-gpio and set the PIO config */
|
||||
extern int ltq_gpio_request(unsigned int pin, unsigned int alt0,
|
||||
unsigned int alt1, unsigned int dir, const char *name);
|
||||
#define PMU_PPE BIT(13)
|
||||
extern void ltq_pmu_enable(unsigned int module);
|
||||
extern void ltq_pmu_disable(unsigned int module);
|
||||
|
||||
static inline int ltq_is_ar9(void)
|
||||
{
|
||||
return (ltq_get_soc_type() == SOC_TYPE_AR9);
|
||||
}
|
||||
|
||||
static inline int ltq_is_vr9(void)
|
||||
{
|
||||
return (ltq_get_soc_type() == SOC_TYPE_VR9);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SOC_TYPE_XWAY */
|
||||
#endif /* _LTQ_XWAY_H__ */
|
||||
|
@ -93,8 +93,4 @@ extern void mips_pcibios_init(void);
|
||||
#define mips_pcibios_init() do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
extern void kgdb_config(void);
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_MIPS_BOARDS_GENERIC_H */
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define _ASM_MODULE_H
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/elf.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
struct mod_arch_specific {
|
||||
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
/*
|
||||
* Each pci channel is a top-level PCI bus seem by CPU. A machine with
|
||||
@ -26,6 +27,7 @@
|
||||
struct pci_controller {
|
||||
struct pci_controller *next;
|
||||
struct pci_bus *bus;
|
||||
struct device_node *of_node;
|
||||
|
||||
struct pci_ops *pci_ops;
|
||||
struct resource *mem_resource;
|
||||
@ -142,4 +144,8 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
|
||||
|
||||
extern char * (*pcibios_plat_setup)(char *str);
|
||||
|
||||
/* this function parses memory ranges from a device node */
|
||||
extern void __devinit pci_load_of_ranges(struct pci_controller *hose,
|
||||
struct device_node *node);
|
||||
|
||||
#endif /* _ASM_PCI_H */
|
||||
|
@ -12,6 +12,9 @@
|
||||
#define __ASM_PROM_H
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
#include <linux/bug.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/bootinfo.h>
|
||||
|
||||
extern int early_init_dt_scan_memory_arch(unsigned long node,
|
||||
@ -21,6 +24,29 @@ extern int reserve_mem_mach(unsigned long addr, unsigned long size);
|
||||
extern void free_mem_mach(unsigned long addr, unsigned long size);
|
||||
|
||||
extern void device_tree_init(void);
|
||||
|
||||
static inline unsigned long pci_address_to_pio(phys_addr_t address)
|
||||
{
|
||||
/*
|
||||
* The ioport address can be directly used by inX() / outX()
|
||||
*/
|
||||
BUG_ON(address > IO_SPACE_LIMIT);
|
||||
|
||||
return (unsigned long) address;
|
||||
}
|
||||
#define pci_address_to_pio pci_address_to_pio
|
||||
|
||||
struct boot_param_header;
|
||||
|
||||
extern void __dt_setup_arch(struct boot_param_header *bph);
|
||||
|
||||
#define dt_setup_arch(sym) \
|
||||
({ \
|
||||
extern struct boot_param_header __dtb_##sym##_begin; \
|
||||
\
|
||||
__dt_setup_arch(&__dtb_##sym##_begin); \
|
||||
})
|
||||
|
||||
#else /* CONFIG_OF */
|
||||
static inline void device_tree_init(void) { }
|
||||
#endif /* CONFIG_OF */
|
||||
|
@ -14,7 +14,8 @@ extern void *set_vi_handler(int n, vi_handler_t addr);
|
||||
|
||||
extern void *set_except_vector(int n, void *addr);
|
||||
extern unsigned long ebase;
|
||||
extern void per_cpu_trap_init(void);
|
||||
extern void per_cpu_trap_init(bool);
|
||||
extern void cpu_cache_init(void);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
@ -60,7 +60,7 @@ struct termio {
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/module.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
/*
|
||||
* intr=^C quit=^\ erase=del kill=^U
|
||||
|
@ -25,6 +25,7 @@ extern void (*board_nmi_handler_setup)(void);
|
||||
extern void (*board_ejtag_handler_setup)(void);
|
||||
extern void (*board_bind_eic_interrupt)(int irq, int regset);
|
||||
extern void (*board_ebase_setup)(void);
|
||||
extern void (*board_cache_error_setup)(void);
|
||||
|
||||
extern int register_nmi_notifier(struct notifier_block *nb);
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef CONFIG_EXPORT_UASM
|
||||
#include <linux/module.h>
|
||||
#include <linux/export.h>
|
||||
#define __uasminit
|
||||
#define __uasminitdata
|
||||
#define UASM_EXPORT_SYMBOL(sym) EXPORT_SYMBOL(sym)
|
||||
|
@ -16,5 +16,3 @@ obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
|
||||
# PM support
|
||||
|
||||
obj-$(CONFIG_PM) += pm.o
|
||||
|
||||
ccflags-y := -Werror -Wall
|
||||
|
@ -340,7 +340,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "R2000";
|
||||
c->isa_level = MIPS_CPU_ISA_I;
|
||||
c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
|
||||
MIPS_CPU_NOFPUEX;
|
||||
MIPS_CPU_NOFPUEX;
|
||||
if (__cpu_has_fpu())
|
||||
c->options |= MIPS_CPU_FPU;
|
||||
c->tlbsize = 64;
|
||||
@ -361,7 +361,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
}
|
||||
c->isa_level = MIPS_CPU_ISA_I;
|
||||
c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
|
||||
MIPS_CPU_NOFPUEX;
|
||||
MIPS_CPU_NOFPUEX;
|
||||
if (__cpu_has_fpu())
|
||||
c->options |= MIPS_CPU_FPU;
|
||||
c->tlbsize = 64;
|
||||
@ -387,8 +387,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
|
||||
c->isa_level = MIPS_CPU_ISA_III;
|
||||
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_WATCH | MIPS_CPU_VCE |
|
||||
MIPS_CPU_LLSC;
|
||||
MIPS_CPU_WATCH | MIPS_CPU_VCE |
|
||||
MIPS_CPU_LLSC;
|
||||
c->tlbsize = 48;
|
||||
break;
|
||||
case PRID_IMP_VR41XX:
|
||||
@ -434,7 +434,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "R4300";
|
||||
c->isa_level = MIPS_CPU_ISA_III;
|
||||
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_LLSC;
|
||||
MIPS_CPU_LLSC;
|
||||
c->tlbsize = 32;
|
||||
break;
|
||||
case PRID_IMP_R4600:
|
||||
@ -446,7 +446,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
c->tlbsize = 48;
|
||||
break;
|
||||
#if 0
|
||||
case PRID_IMP_R4650:
|
||||
case PRID_IMP_R4650:
|
||||
/*
|
||||
* This processor doesn't have an MMU, so it's not
|
||||
* "real easy" to run Linux on it. It is left purely
|
||||
@ -455,9 +455,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
*/
|
||||
c->cputype = CPU_R4650;
|
||||
__cpu_name[cpu] = "R4650";
|
||||
c->isa_level = MIPS_CPU_ISA_III;
|
||||
c->isa_level = MIPS_CPU_ISA_III;
|
||||
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
|
||||
c->tlbsize = 48;
|
||||
c->tlbsize = 48;
|
||||
break;
|
||||
#endif
|
||||
case PRID_IMP_TX39:
|
||||
@ -488,7 +488,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "R4700";
|
||||
c->isa_level = MIPS_CPU_ISA_III;
|
||||
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_LLSC;
|
||||
MIPS_CPU_LLSC;
|
||||
c->tlbsize = 48;
|
||||
break;
|
||||
case PRID_IMP_TX49:
|
||||
@ -505,7 +505,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "R5000";
|
||||
c->isa_level = MIPS_CPU_ISA_IV;
|
||||
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_LLSC;
|
||||
MIPS_CPU_LLSC;
|
||||
c->tlbsize = 48;
|
||||
break;
|
||||
case PRID_IMP_R5432:
|
||||
@ -513,7 +513,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "R5432";
|
||||
c->isa_level = MIPS_CPU_ISA_IV;
|
||||
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_WATCH | MIPS_CPU_LLSC;
|
||||
MIPS_CPU_WATCH | MIPS_CPU_LLSC;
|
||||
c->tlbsize = 48;
|
||||
break;
|
||||
case PRID_IMP_R5500:
|
||||
@ -521,7 +521,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "R5500";
|
||||
c->isa_level = MIPS_CPU_ISA_IV;
|
||||
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_WATCH | MIPS_CPU_LLSC;
|
||||
MIPS_CPU_WATCH | MIPS_CPU_LLSC;
|
||||
c->tlbsize = 48;
|
||||
break;
|
||||
case PRID_IMP_NEVADA:
|
||||
@ -529,7 +529,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "Nevada";
|
||||
c->isa_level = MIPS_CPU_ISA_IV;
|
||||
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_DIVEC | MIPS_CPU_LLSC;
|
||||
MIPS_CPU_DIVEC | MIPS_CPU_LLSC;
|
||||
c->tlbsize = 48;
|
||||
break;
|
||||
case PRID_IMP_R6000:
|
||||
@ -537,7 +537,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "R6000";
|
||||
c->isa_level = MIPS_CPU_ISA_II;
|
||||
c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
|
||||
MIPS_CPU_LLSC;
|
||||
MIPS_CPU_LLSC;
|
||||
c->tlbsize = 32;
|
||||
break;
|
||||
case PRID_IMP_R6000A:
|
||||
@ -545,7 +545,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "R6000A";
|
||||
c->isa_level = MIPS_CPU_ISA_II;
|
||||
c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
|
||||
MIPS_CPU_LLSC;
|
||||
MIPS_CPU_LLSC;
|
||||
c->tlbsize = 32;
|
||||
break;
|
||||
case PRID_IMP_RM7000:
|
||||
@ -553,7 +553,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "RM7000";
|
||||
c->isa_level = MIPS_CPU_ISA_IV;
|
||||
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_LLSC;
|
||||
MIPS_CPU_LLSC;
|
||||
/*
|
||||
* Undocumented RM7000: Bit 29 in the info register of
|
||||
* the RM7000 v2.0 indicates if the TLB has 48 or 64
|
||||
@ -569,7 +569,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "RM9000";
|
||||
c->isa_level = MIPS_CPU_ISA_IV;
|
||||
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_LLSC;
|
||||
MIPS_CPU_LLSC;
|
||||
/*
|
||||
* Bit 29 in the info register of the RM9000
|
||||
* indicates if the TLB has 48 or 64 entries.
|
||||
@ -584,8 +584,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "RM8000";
|
||||
c->isa_level = MIPS_CPU_ISA_IV;
|
||||
c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
|
||||
MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_LLSC;
|
||||
MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_LLSC;
|
||||
c->tlbsize = 384; /* has weird TLB: 3-way x 128 */
|
||||
break;
|
||||
case PRID_IMP_R10000:
|
||||
@ -593,9 +593,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "R10000";
|
||||
c->isa_level = MIPS_CPU_ISA_IV;
|
||||
c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
|
||||
MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
|
||||
MIPS_CPU_LLSC;
|
||||
MIPS_CPU_LLSC;
|
||||
c->tlbsize = 64;
|
||||
break;
|
||||
case PRID_IMP_R12000:
|
||||
@ -603,9 +603,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "R12000";
|
||||
c->isa_level = MIPS_CPU_ISA_IV;
|
||||
c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
|
||||
MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
|
||||
MIPS_CPU_LLSC;
|
||||
MIPS_CPU_LLSC;
|
||||
c->tlbsize = 64;
|
||||
break;
|
||||
case PRID_IMP_R14000:
|
||||
@ -613,9 +613,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "R14000";
|
||||
c->isa_level = MIPS_CPU_ISA_IV;
|
||||
c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
|
||||
MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
|
||||
MIPS_CPU_LLSC;
|
||||
MIPS_CPU_LLSC;
|
||||
c->tlbsize = 64;
|
||||
break;
|
||||
case PRID_IMP_LOONGSON2:
|
||||
@ -739,7 +739,7 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
|
||||
if (config3 & MIPS_CONF3_VEIC)
|
||||
c->options |= MIPS_CPU_VEIC;
|
||||
if (config3 & MIPS_CONF3_MT)
|
||||
c->ases |= MIPS_ASE_MIPSMT;
|
||||
c->ases |= MIPS_ASE_MIPSMT;
|
||||
if (config3 & MIPS_CONF3_ULRI)
|
||||
c->options |= MIPS_CPU_ULRI;
|
||||
|
||||
@ -767,7 +767,7 @@ static void __cpuinit decode_configs(struct cpuinfo_mips *c)
|
||||
|
||||
/* MIPS32 or MIPS64 compliant CPU. */
|
||||
c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER |
|
||||
MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
|
||||
MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
|
||||
|
||||
c->scache.flags = MIPS_CACHE_NOT_PRESENT;
|
||||
|
||||
|
@ -1532,7 +1532,8 @@ init_hw_perf_events(void)
|
||||
irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
|
||||
} else {
|
||||
#endif
|
||||
if (cp0_perfcount_irq >= 0)
|
||||
if ((cp0_perfcount_irq >= 0) &&
|
||||
(cp0_compare_irq != cp0_perfcount_irq))
|
||||
irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
|
||||
else
|
||||
irq = -1;
|
||||
|
@ -41,27 +41,27 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
|
||||
seq_printf(m, "processor\t\t: %ld\n", n);
|
||||
sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
|
||||
cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : "");
|
||||
cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : "");
|
||||
seq_printf(m, fmt, __cpu_name[n],
|
||||
(version >> 4) & 0x0f, version & 0x0f,
|
||||
(fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
|
||||
(version >> 4) & 0x0f, version & 0x0f,
|
||||
(fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
|
||||
seq_printf(m, "BogoMIPS\t\t: %u.%02u\n",
|
||||
cpu_data[n].udelay_val / (500000/HZ),
|
||||
(cpu_data[n].udelay_val / (5000/HZ)) % 100);
|
||||
cpu_data[n].udelay_val / (500000/HZ),
|
||||
(cpu_data[n].udelay_val / (5000/HZ)) % 100);
|
||||
seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
|
||||
seq_printf(m, "microsecond timers\t: %s\n",
|
||||
cpu_has_counter ? "yes" : "no");
|
||||
cpu_has_counter ? "yes" : "no");
|
||||
seq_printf(m, "tlb_entries\t\t: %d\n", cpu_data[n].tlbsize);
|
||||
seq_printf(m, "extra interrupt vector\t: %s\n",
|
||||
cpu_has_divec ? "yes" : "no");
|
||||
cpu_has_divec ? "yes" : "no");
|
||||
seq_printf(m, "hardware watchpoint\t: %s",
|
||||
cpu_has_watch ? "yes, " : "no\n");
|
||||
cpu_has_watch ? "yes, " : "no\n");
|
||||
if (cpu_has_watch) {
|
||||
seq_printf(m, "count: %d, address/irw mask: [",
|
||||
cpu_data[n].watch_reg_count);
|
||||
cpu_data[n].watch_reg_count);
|
||||
for (i = 0; i < cpu_data[n].watch_reg_count; i++)
|
||||
seq_printf(m, "%s0x%04x", i ? ", " : "" ,
|
||||
cpu_data[n].watch_reg_masks[i]);
|
||||
cpu_data[n].watch_reg_masks[i]);
|
||||
seq_printf(m, "]\n");
|
||||
}
|
||||
seq_printf(m, "ASEs implemented\t:%s%s%s%s%s%s\n",
|
||||
@ -73,13 +73,13 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
cpu_has_mipsmt ? " mt" : ""
|
||||
);
|
||||
seq_printf(m, "shadow register sets\t: %d\n",
|
||||
cpu_data[n].srsets);
|
||||
cpu_data[n].srsets);
|
||||
seq_printf(m, "kscratch registers\t: %d\n",
|
||||
hweight8(cpu_data[n].kscratch_mask));
|
||||
hweight8(cpu_data[n].kscratch_mask));
|
||||
seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
|
||||
|
||||
sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
|
||||
cpu_has_vce ? "%u" : "not available");
|
||||
cpu_has_vce ? "%u" : "not available");
|
||||
seq_printf(m, fmt, 'D', vced_count);
|
||||
seq_printf(m, fmt, 'I', vcei_count);
|
||||
seq_printf(m, "\n");
|
||||
|
@ -95,3 +95,16 @@ void __init device_tree_init(void)
|
||||
/* free the space reserved for the dt blob */
|
||||
free_mem_mach(base, size);
|
||||
}
|
||||
|
||||
void __init __dt_setup_arch(struct boot_param_header *bph)
|
||||
{
|
||||
if (be32_to_cpu(bph->magic) != OF_DT_HEADER) {
|
||||
pr_err("DTB has bad magic, ignoring builtin OF DTB\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
initial_boot_params = bph;
|
||||
|
||||
early_init_devtree(initial_boot_params);
|
||||
}
|
||||
|
@ -605,6 +605,8 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
resource_init();
|
||||
plat_smp_setup();
|
||||
|
||||
cpu_cache_init();
|
||||
}
|
||||
|
||||
unsigned long kernelsp[NR_CPUS];
|
||||
|
@ -106,7 +106,7 @@ asmlinkage __cpuinit void start_secondary(void)
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
cpu_probe();
|
||||
cpu_report();
|
||||
per_cpu_trap_init();
|
||||
per_cpu_trap_init(false);
|
||||
mips_clockevent_init();
|
||||
mp_ops->init_secondary();
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/smp.h>
|
||||
@ -91,7 +92,7 @@ void (*board_nmi_handler_setup)(void);
|
||||
void (*board_ejtag_handler_setup)(void);
|
||||
void (*board_bind_eic_interrupt)(int irq, int regset);
|
||||
void (*board_ebase_setup)(void);
|
||||
|
||||
void __cpuinitdata(*board_cache_error_setup)(void);
|
||||
|
||||
static void show_raw_backtrace(unsigned long reg29)
|
||||
{
|
||||
@ -1490,7 +1491,6 @@ void *set_vi_handler(int n, vi_handler_t addr)
|
||||
return set_vi_srs_handler(n, addr, 0);
|
||||
}
|
||||
|
||||
extern void cpu_cache_init(void);
|
||||
extern void tlb_init(void);
|
||||
extern void flush_tlb_handlers(void);
|
||||
|
||||
@ -1517,7 +1517,7 @@ static int __init ulri_disable(char *s)
|
||||
}
|
||||
__setup("noulri", ulri_disable);
|
||||
|
||||
void __cpuinit per_cpu_trap_init(void)
|
||||
void __cpuinit per_cpu_trap_init(bool is_boot_cpu)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
unsigned int status_set = ST0_CU0;
|
||||
@ -1616,7 +1616,9 @@ void __cpuinit per_cpu_trap_init(void)
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
if (bootTC) {
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
cpu_cache_init();
|
||||
/* Boot CPU's cache setup in setup_arch(). */
|
||||
if (!is_boot_cpu)
|
||||
cpu_cache_init();
|
||||
tlb_init();
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
} else if (!secondaryTC) {
|
||||
@ -1632,7 +1634,7 @@ void __cpuinit per_cpu_trap_init(void)
|
||||
}
|
||||
|
||||
/* Install CPU exception handler */
|
||||
void __init set_handler(unsigned long offset, void *addr, unsigned long size)
|
||||
void __cpuinit set_handler(unsigned long offset, void *addr, unsigned long size)
|
||||
{
|
||||
memcpy((void *)(ebase + offset), addr, size);
|
||||
local_flush_icache_range(ebase + offset, ebase + offset + size);
|
||||
@ -1693,7 +1695,7 @@ void __init trap_init(void)
|
||||
|
||||
if (board_ebase_setup)
|
||||
board_ebase_setup();
|
||||
per_cpu_trap_init();
|
||||
per_cpu_trap_init(true);
|
||||
|
||||
/*
|
||||
* Copy the generic exception handlers to their final destination.
|
||||
@ -1797,6 +1799,9 @@ void __init trap_init(void)
|
||||
|
||||
set_except_vector(26, handle_dsp);
|
||||
|
||||
if (board_cache_error_setup)
|
||||
board_cache_error_setup();
|
||||
|
||||
if (cpu_has_vce)
|
||||
/* Special exception: R4[04]00 uses also the divec space. */
|
||||
memcpy((void *)(ebase + 0x180), &except_vec3_r4000, 0x100);
|
||||
|
@ -16,8 +16,22 @@ config SOC_XWAY
|
||||
bool "XWAY"
|
||||
select SOC_TYPE_XWAY
|
||||
select HW_HAS_PCI
|
||||
|
||||
config SOC_FALCON
|
||||
bool "FALCON"
|
||||
|
||||
endchoice
|
||||
|
||||
source "arch/mips/lantiq/xway/Kconfig"
|
||||
choice
|
||||
prompt "Devicetree"
|
||||
|
||||
config DT_EASY50712
|
||||
bool "Easy50712"
|
||||
depends on SOC_XWAY
|
||||
endchoice
|
||||
|
||||
config PCI_LANTIQ
|
||||
bool "PCI Support"
|
||||
depends on SOC_XWAY && PCI
|
||||
|
||||
endif
|
||||
|
@ -4,8 +4,11 @@
|
||||
# under the terms of the GNU General Public License version 2 as published
|
||||
# by the Free Software Foundation.
|
||||
|
||||
obj-y := irq.o setup.o clk.o prom.o devices.o
|
||||
obj-y := irq.o clk.o prom.o
|
||||
|
||||
obj-y += dts/
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
|
||||
obj-$(CONFIG_SOC_TYPE_XWAY) += xway/
|
||||
obj-$(CONFIG_SOC_FALCON) += falcon/
|
||||
|
@ -6,3 +6,4 @@ platform-$(CONFIG_LANTIQ) += lantiq/
|
||||
cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq
|
||||
load-$(CONFIG_LANTIQ) = 0xffffffff80002000
|
||||
cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway
|
||||
cflags-$(CONFIG_SOC_FALCON) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/falcon
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
@ -22,44 +23,32 @@
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
struct clk {
|
||||
const char *name;
|
||||
unsigned long rate;
|
||||
unsigned long (*get_rate) (void);
|
||||
};
|
||||
|
||||
static struct clk *cpu_clk;
|
||||
static int cpu_clk_cnt;
|
||||
#include "prom.h"
|
||||
|
||||
/* lantiq socs have 3 static clocks */
|
||||
static struct clk cpu_clk_generic[] = {
|
||||
{
|
||||
.name = "cpu",
|
||||
.get_rate = ltq_get_cpu_hz,
|
||||
}, {
|
||||
.name = "fpi",
|
||||
.get_rate = ltq_get_fpi_hz,
|
||||
}, {
|
||||
.name = "io",
|
||||
.get_rate = ltq_get_io_region_clock,
|
||||
},
|
||||
};
|
||||
static struct clk cpu_clk_generic[3];
|
||||
|
||||
static struct resource ltq_cgu_resource = {
|
||||
.name = "cgu",
|
||||
.start = LTQ_CGU_BASE_ADDR,
|
||||
.end = LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
/* remapped clock register range */
|
||||
void __iomem *ltq_cgu_membase;
|
||||
|
||||
void clk_init(void)
|
||||
void clkdev_add_static(unsigned long cpu, unsigned long fpi, unsigned long io)
|
||||
{
|
||||
cpu_clk = cpu_clk_generic;
|
||||
cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic);
|
||||
cpu_clk_generic[0].rate = cpu;
|
||||
cpu_clk_generic[1].rate = fpi;
|
||||
cpu_clk_generic[2].rate = io;
|
||||
}
|
||||
|
||||
struct clk *clk_get_cpu(void)
|
||||
{
|
||||
return &cpu_clk_generic[0];
|
||||
}
|
||||
|
||||
struct clk *clk_get_fpi(void)
|
||||
{
|
||||
return &cpu_clk_generic[1];
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_get_fpi);
|
||||
|
||||
struct clk *clk_get_io(void)
|
||||
{
|
||||
return &cpu_clk_generic[2];
|
||||
}
|
||||
|
||||
static inline int clk_good(struct clk *clk)
|
||||
@ -82,38 +71,71 @@ unsigned long clk_get_rate(struct clk *clk)
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get_rate);
|
||||
|
||||
struct clk *clk_get(struct device *dev, const char *id)
|
||||
int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
int i;
|
||||
if (unlikely(!clk_good(clk)))
|
||||
return 0;
|
||||
if (clk->rates && *clk->rates) {
|
||||
unsigned long *r = clk->rates;
|
||||
|
||||
for (i = 0; i < cpu_clk_cnt; i++)
|
||||
if (!strcmp(id, cpu_clk[i].name))
|
||||
return &cpu_clk[i];
|
||||
BUG();
|
||||
return ERR_PTR(-ENOENT);
|
||||
while (*r && (*r != rate))
|
||||
r++;
|
||||
if (!*r) {
|
||||
pr_err("clk %s.%s: trying to set invalid rate %ld\n",
|
||||
clk->cl.dev_id, clk->cl.con_id, rate);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
clk->rate = rate;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get);
|
||||
|
||||
void clk_put(struct clk *clk)
|
||||
{
|
||||
/* not used */
|
||||
}
|
||||
EXPORT_SYMBOL(clk_put);
|
||||
EXPORT_SYMBOL(clk_set_rate);
|
||||
|
||||
int clk_enable(struct clk *clk)
|
||||
{
|
||||
/* not used */
|
||||
return 0;
|
||||
if (unlikely(!clk_good(clk)))
|
||||
return -1;
|
||||
|
||||
if (clk->enable)
|
||||
return clk->enable(clk);
|
||||
|
||||
return -1;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_enable);
|
||||
|
||||
void clk_disable(struct clk *clk)
|
||||
{
|
||||
/* not used */
|
||||
if (unlikely(!clk_good(clk)))
|
||||
return;
|
||||
|
||||
if (clk->disable)
|
||||
clk->disable(clk);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_disable);
|
||||
|
||||
static inline u32 ltq_get_counter_resolution(void)
|
||||
int clk_activate(struct clk *clk)
|
||||
{
|
||||
if (unlikely(!clk_good(clk)))
|
||||
return -1;
|
||||
|
||||
if (clk->activate)
|
||||
return clk->activate(clk);
|
||||
|
||||
return -1;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_activate);
|
||||
|
||||
void clk_deactivate(struct clk *clk)
|
||||
{
|
||||
if (unlikely(!clk_good(clk)))
|
||||
return;
|
||||
|
||||
if (clk->deactivate)
|
||||
clk->deactivate(clk);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_deactivate);
|
||||
|
||||
static inline u32 get_counter_resolution(void)
|
||||
{
|
||||
u32 res;
|
||||
|
||||
@ -133,21 +155,11 @@ void __init plat_time_init(void)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
if (insert_resource(&iomem_resource, <q_cgu_resource) < 0)
|
||||
panic("Failed to insert cgu memory");
|
||||
ltq_soc_init();
|
||||
|
||||
if (request_mem_region(ltq_cgu_resource.start,
|
||||
resource_size(<q_cgu_resource), "cgu") < 0)
|
||||
panic("Failed to request cgu memory");
|
||||
|
||||
ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
|
||||
resource_size(<q_cgu_resource));
|
||||
if (!ltq_cgu_membase) {
|
||||
pr_err("Failed to remap cgu memory\n");
|
||||
unreachable();
|
||||
}
|
||||
clk = clk_get(0, "cpu");
|
||||
mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution();
|
||||
clk = clk_get_cpu();
|
||||
mips_hpt_frequency = clk_get_rate(clk) / get_counter_resolution();
|
||||
write_c0_compare(read_c0_count());
|
||||
pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
|
||||
clk_put(clk);
|
||||
}
|
||||
|
@ -9,10 +9,70 @@
|
||||
#ifndef _LTQ_CLK_H__
|
||||
#define _LTQ_CLK_H__
|
||||
|
||||
extern void clk_init(void);
|
||||
#include <linux/clkdev.h>
|
||||
|
||||
extern unsigned long ltq_get_cpu_hz(void);
|
||||
extern unsigned long ltq_get_fpi_hz(void);
|
||||
extern unsigned long ltq_get_io_region_clock(void);
|
||||
/* clock speeds */
|
||||
#define CLOCK_33M 33333333
|
||||
#define CLOCK_60M 60000000
|
||||
#define CLOCK_62_5M 62500000
|
||||
#define CLOCK_83M 83333333
|
||||
#define CLOCK_83_5M 83500000
|
||||
#define CLOCK_98_304M 98304000
|
||||
#define CLOCK_100M 100000000
|
||||
#define CLOCK_111M 111111111
|
||||
#define CLOCK_125M 125000000
|
||||
#define CLOCK_133M 133333333
|
||||
#define CLOCK_150M 150000000
|
||||
#define CLOCK_166M 166666666
|
||||
#define CLOCK_167M 166666667
|
||||
#define CLOCK_196_608M 196608000
|
||||
#define CLOCK_200M 200000000
|
||||
#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_500M 500000000
|
||||
#define CLOCK_600M 600000000
|
||||
|
||||
/* clock out speeds */
|
||||
#define CLOCK_32_768K 32768
|
||||
#define CLOCK_1_536M 1536000
|
||||
#define CLOCK_2_5M 2500000
|
||||
#define CLOCK_12M 12000000
|
||||
#define CLOCK_24M 24000000
|
||||
#define CLOCK_25M 25000000
|
||||
#define CLOCK_30M 30000000
|
||||
#define CLOCK_40M 40000000
|
||||
#define CLOCK_48M 48000000
|
||||
#define CLOCK_50M 50000000
|
||||
#define CLOCK_60M 60000000
|
||||
|
||||
struct clk {
|
||||
struct clk_lookup cl;
|
||||
unsigned long rate;
|
||||
unsigned long *rates;
|
||||
unsigned int module;
|
||||
unsigned int bits;
|
||||
unsigned long (*get_rate) (void);
|
||||
int (*enable) (struct clk *clk);
|
||||
void (*disable) (struct clk *clk);
|
||||
int (*activate) (struct clk *clk);
|
||||
void (*deactivate) (struct clk *clk);
|
||||
void (*reboot) (struct clk *clk);
|
||||
};
|
||||
|
||||
extern void clkdev_add_static(unsigned long cpu, unsigned long fpi,
|
||||
unsigned long io);
|
||||
|
||||
extern unsigned long ltq_danube_cpu_hz(void);
|
||||
extern unsigned long ltq_danube_fpi_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);
|
||||
|
||||
#endif
|
||||
|
@ -1,120 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
/* nor flash */
|
||||
static struct resource ltq_nor_resource = {
|
||||
.name = "nor",
|
||||
.start = LTQ_FLASH_START,
|
||||
.end = LTQ_FLASH_START + LTQ_FLASH_MAX - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device ltq_nor = {
|
||||
.name = "ltq_nor",
|
||||
.resource = <q_nor_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
void __init ltq_register_nor(struct physmap_flash_data *data)
|
||||
{
|
||||
ltq_nor.dev.platform_data = data;
|
||||
platform_device_register(<q_nor);
|
||||
}
|
||||
|
||||
/* watchdog */
|
||||
static struct resource ltq_wdt_resource = {
|
||||
.name = "watchdog",
|
||||
.start = LTQ_WDT_BASE_ADDR,
|
||||
.end = LTQ_WDT_BASE_ADDR + LTQ_WDT_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
void __init ltq_register_wdt(void)
|
||||
{
|
||||
platform_device_register_simple("ltq_wdt", 0, <q_wdt_resource, 1);
|
||||
}
|
||||
|
||||
/* asc ports */
|
||||
static struct resource ltq_asc0_resources[] = {
|
||||
{
|
||||
.name = "asc0",
|
||||
.start = LTQ_ASC0_BASE_ADDR,
|
||||
.end = LTQ_ASC0_BASE_ADDR + LTQ_ASC_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
IRQ_RES(tx, LTQ_ASC_TIR(0)),
|
||||
IRQ_RES(rx, LTQ_ASC_RIR(0)),
|
||||
IRQ_RES(err, LTQ_ASC_EIR(0)),
|
||||
};
|
||||
|
||||
static struct resource ltq_asc1_resources[] = {
|
||||
{
|
||||
.name = "asc1",
|
||||
.start = LTQ_ASC1_BASE_ADDR,
|
||||
.end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
IRQ_RES(tx, LTQ_ASC_TIR(1)),
|
||||
IRQ_RES(rx, LTQ_ASC_RIR(1)),
|
||||
IRQ_RES(err, LTQ_ASC_EIR(1)),
|
||||
};
|
||||
|
||||
void __init ltq_register_asc(int port)
|
||||
{
|
||||
switch (port) {
|
||||
case 0:
|
||||
platform_device_register_simple("ltq_asc", 0,
|
||||
ltq_asc0_resources, ARRAY_SIZE(ltq_asc0_resources));
|
||||
break;
|
||||
case 1:
|
||||
platform_device_register_simple("ltq_asc", 1,
|
||||
ltq_asc1_resources, ARRAY_SIZE(ltq_asc1_resources));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/* pci */
|
||||
static struct platform_device ltq_pci = {
|
||||
.name = "ltq_pci",
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
void __init ltq_register_pci(struct ltq_pci_data *data)
|
||||
{
|
||||
ltq_pci.dev.platform_data = data;
|
||||
platform_device_register(<q_pci);
|
||||
}
|
||||
#else
|
||||
void __init ltq_register_pci(struct ltq_pci_data *data)
|
||||
{
|
||||
pr_err("kernel is compiled without PCI support\n");
|
||||
}
|
||||
#endif
|
@ -1,23 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#ifndef _LTQ_DEVICES_H__
|
||||
#define _LTQ_DEVICES_H__
|
||||
|
||||
#include <lantiq_platform.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
|
||||
#define IRQ_RES(resname, irq) \
|
||||
{.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ}
|
||||
|
||||
extern void ltq_register_nor(struct physmap_flash_data *data);
|
||||
extern void ltq_register_wdt(void);
|
||||
extern void ltq_register_asc(int port);
|
||||
extern void ltq_register_pci(struct ltq_pci_data *data);
|
||||
|
||||
#endif
|
4
arch/mips/lantiq/dts/Makefile
Normal file
4
arch/mips/lantiq/dts/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
obj-$(CONFIG_DT_EASY50712) := easy50712.dtb.o
|
||||
|
||||
$(obj)/%.dtb: $(obj)/%.dts
|
||||
$(call if_changed,dtc)
|
105
arch/mips/lantiq/dts/danube.dtsi
Normal file
105
arch/mips/lantiq/dts/danube.dtsi
Normal file
@ -0,0 +1,105 @@
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "lantiq,xway", "lantiq,danube";
|
||||
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "mips,mips24Kc";
|
||||
};
|
||||
};
|
||||
|
||||
biu@1F800000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "lantiq,biu", "simple-bus";
|
||||
reg = <0x1F800000 0x800000>;
|
||||
ranges = <0x0 0x1F800000 0x7FFFFF>;
|
||||
|
||||
icu0: icu@80200 {
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
compatible = "lantiq,icu";
|
||||
reg = <0x80200 0x120>;
|
||||
};
|
||||
|
||||
watchdog@803F0 {
|
||||
compatible = "lantiq,wdt";
|
||||
reg = <0x803F0 0x10>;
|
||||
};
|
||||
};
|
||||
|
||||
sram@1F000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "lantiq,sram";
|
||||
reg = <0x1F000000 0x800000>;
|
||||
ranges = <0x0 0x1F000000 0x7FFFFF>;
|
||||
|
||||
eiu0: eiu@101000 {
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
interrupt-parent;
|
||||
compatible = "lantiq,eiu-xway";
|
||||
reg = <0x101000 0x1000>;
|
||||
};
|
||||
|
||||
pmu0: pmu@102000 {
|
||||
compatible = "lantiq,pmu-xway";
|
||||
reg = <0x102000 0x1000>;
|
||||
};
|
||||
|
||||
cgu0: cgu@103000 {
|
||||
compatible = "lantiq,cgu-xway";
|
||||
reg = <0x103000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
rcu0: rcu@203000 {
|
||||
compatible = "lantiq,rcu-xway";
|
||||
reg = <0x203000 0x1000>;
|
||||
};
|
||||
};
|
||||
|
||||
fpi@10000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "lantiq,fpi", "simple-bus";
|
||||
ranges = <0x0 0x10000000 0xEEFFFFF>;
|
||||
reg = <0x10000000 0xEF00000>;
|
||||
|
||||
gptu@E100A00 {
|
||||
compatible = "lantiq,gptu-xway";
|
||||
reg = <0xE100A00 0x100>;
|
||||
};
|
||||
|
||||
serial@E100C00 {
|
||||
compatible = "lantiq,asc";
|
||||
reg = <0xE100C00 0x400>;
|
||||
interrupt-parent = <&icu0>;
|
||||
interrupts = <112 113 114>;
|
||||
};
|
||||
|
||||
dma0: dma@E104100 {
|
||||
compatible = "lantiq,dma-xway";
|
||||
reg = <0xE104100 0x800>;
|
||||
};
|
||||
|
||||
ebu0: ebu@E105300 {
|
||||
compatible = "lantiq,ebu-xway";
|
||||
reg = <0xE105300 0x100>;
|
||||
};
|
||||
|
||||
pci0: pci@E105400 {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "lantiq,pci-xway";
|
||||
bus-range = <0x0 0x0>;
|
||||
ranges = <0x2000000 0 0x8000000 0x8000000 0 0x2000000 /* pci memory */
|
||||
0x1000000 0 0x00000000 0xAE00000 0 0x200000>; /* io space */
|
||||
reg = <0x7000000 0x8000 /* config space */
|
||||
0xE105400 0x400>; /* pci bridge */
|
||||
};
|
||||
};
|
||||
};
|
113
arch/mips/lantiq/dts/easy50712.dts
Normal file
113
arch/mips/lantiq/dts/easy50712.dts
Normal file
@ -0,0 +1,113 @@
|
||||
/dts-v1/;
|
||||
|
||||
/include/ "danube.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
bootargs = "console=ttyLTQ0,115200 init=/etc/preinit";
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
reg = <0x0 0x2000000>;
|
||||
};
|
||||
|
||||
fpi@10000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
localbus@0 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0 0 0x0 0x3ffffff /* addrsel0 */
|
||||
1 0 0x4000000 0x4000010>; /* addsel1 */
|
||||
compatible = "lantiq,localbus", "simple-bus";
|
||||
|
||||
nor-boot@0 {
|
||||
compatible = "lantiq,nor";
|
||||
bank-width = <2>;
|
||||
reg = <0 0x0 0x2000000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "uboot";
|
||||
reg = <0x00000 0x10000>; /* 64 KB */
|
||||
};
|
||||
|
||||
partition@10000 {
|
||||
label = "uboot_env";
|
||||
reg = <0x10000 0x10000>; /* 64 KB */
|
||||
};
|
||||
|
||||
partition@20000 {
|
||||
label = "linux";
|
||||
reg = <0x20000 0x3d0000>;
|
||||
};
|
||||
|
||||
partition@400000 {
|
||||
label = "rootfs";
|
||||
reg = <0x400000 0x400000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
gpio: pinmux@E100B10 {
|
||||
compatible = "lantiq,pinctrl-xway";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&state_default>;
|
||||
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
reg = <0xE100B10 0xA0>;
|
||||
|
||||
state_default: pinmux {
|
||||
stp {
|
||||
lantiq,groups = "stp";
|
||||
lantiq,function = "stp";
|
||||
};
|
||||
exin {
|
||||
lantiq,groups = "exin1";
|
||||
lantiq,function = "exin";
|
||||
};
|
||||
pci {
|
||||
lantiq,groups = "gnt1";
|
||||
lantiq,function = "pci";
|
||||
};
|
||||
conf_out {
|
||||
lantiq,pins = "io4", "io5", "io6"; /* stp */
|
||||
lantiq,open-drain;
|
||||
lantiq,pull = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
etop@E180000 {
|
||||
compatible = "lantiq,etop-xway";
|
||||
reg = <0xE180000 0x40000>;
|
||||
interrupt-parent = <&icu0>;
|
||||
interrupts = <73 78>;
|
||||
phy-mode = "rmii";
|
||||
mac-address = [ 00 11 22 33 44 55 ];
|
||||
};
|
||||
|
||||
stp0: stp@E100BB0 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "lantiq,gpio-stp-xway";
|
||||
gpio-controller;
|
||||
reg = <0xE100BB0 0x40>;
|
||||
|
||||
lantiq,shadow = <0xfff>;
|
||||
lantiq,groups = <0x3>;
|
||||
};
|
||||
|
||||
pci@E105400 {
|
||||
lantiq,bus-clock = <33333333>;
|
||||
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
|
||||
interrupt-map = <
|
||||
0x7000 0 0 1 &icu0 29 1 // slot 14, irq 29
|
||||
>;
|
||||
gpios-reset = <&gpio 21 0>;
|
||||
req-mask = <0x1>; /* GNT1 */
|
||||
};
|
||||
|
||||
};
|
||||
};
|
@ -6,17 +6,16 @@
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/cpu.h>
|
||||
|
||||
#include <lantiq.h>
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
/* no ioremap possible at this early stage, lets use KSEG1 instead */
|
||||
#define LTQ_ASC_BASE KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
|
||||
#define ASC_BUF 1024
|
||||
#define LTQ_ASC_FSTAT ((u32 *)(LTQ_ASC_BASE + 0x0048))
|
||||
#define LTQ_ASC_TBUF ((u32 *)(LTQ_ASC_BASE + 0x0020))
|
||||
#define LTQ_ASC_FSTAT ((u32 *)(LTQ_EARLY_ASC + 0x0048))
|
||||
#ifdef __BIG_ENDIAN
|
||||
#define LTQ_ASC_TBUF ((u32 *)(LTQ_EARLY_ASC + 0x0020 + 3))
|
||||
#else
|
||||
#define LTQ_ASC_TBUF ((u32 *)(LTQ_EARLY_ASC + 0x0020))
|
||||
#endif
|
||||
#define TXMASK 0x3F00
|
||||
#define TXOFFSET 8
|
||||
|
||||
@ -27,7 +26,7 @@ void prom_putchar(char c)
|
||||
local_irq_save(flags);
|
||||
do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET);
|
||||
if (c == '\n')
|
||||
ltq_w32('\r', LTQ_ASC_TBUF);
|
||||
ltq_w32(c, LTQ_ASC_TBUF);
|
||||
ltq_w8('\r', LTQ_ASC_TBUF);
|
||||
ltq_w8(c, LTQ_ASC_TBUF);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
1
arch/mips/lantiq/falcon/Makefile
Normal file
1
arch/mips/lantiq/falcon/Makefile
Normal file
@ -0,0 +1 @@
|
||||
obj-y := prom.o reset.o sysctrl.o
|
87
arch/mips/lantiq/falcon/prom.c
Normal file
87
arch/mips/lantiq/falcon/prom.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
|
||||
* Copyright (C) 2012 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#include "../prom.h"
|
||||
|
||||
#define SOC_FALCON "Falcon"
|
||||
#define SOC_FALCON_D "Falcon-D"
|
||||
#define SOC_FALCON_V "Falcon-V"
|
||||
#define SOC_FALCON_M "Falcon-M"
|
||||
|
||||
#define COMP_FALCON "lantiq,falcon"
|
||||
|
||||
#define PART_SHIFT 12
|
||||
#define PART_MASK 0x0FFFF000
|
||||
#define REV_SHIFT 28
|
||||
#define REV_MASK 0xF0000000
|
||||
#define SREV_SHIFT 22
|
||||
#define SREV_MASK 0x03C00000
|
||||
#define TYPE_SHIFT 26
|
||||
#define TYPE_MASK 0x3C000000
|
||||
|
||||
/* reset, nmi and ejtag exception vectors */
|
||||
#define BOOT_REG_BASE (KSEG1 | 0x1F200000)
|
||||
#define BOOT_RVEC (BOOT_REG_BASE | 0x00)
|
||||
#define BOOT_NVEC (BOOT_REG_BASE | 0x04)
|
||||
#define BOOT_EVEC (BOOT_REG_BASE | 0x08)
|
||||
|
||||
void __init ltq_soc_nmi_setup(void)
|
||||
{
|
||||
extern void (*nmi_handler)(void);
|
||||
|
||||
ltq_w32((unsigned long)&nmi_handler, (void *)BOOT_NVEC);
|
||||
}
|
||||
|
||||
void __init ltq_soc_ejtag_setup(void)
|
||||
{
|
||||
extern void (*ejtag_debug_handler)(void);
|
||||
|
||||
ltq_w32((unsigned long)&ejtag_debug_handler, (void *)BOOT_EVEC);
|
||||
}
|
||||
|
||||
void __init ltq_soc_detect(struct ltq_soc_info *i)
|
||||
{
|
||||
u32 type;
|
||||
i->partnum = (ltq_r32(FALCON_CHIPID) & PART_MASK) >> PART_SHIFT;
|
||||
i->rev = (ltq_r32(FALCON_CHIPID) & REV_MASK) >> REV_SHIFT;
|
||||
i->srev = ((ltq_r32(FALCON_CHIPCONF) & SREV_MASK) >> SREV_SHIFT);
|
||||
i->compatible = COMP_FALCON;
|
||||
i->type = SOC_TYPE_FALCON;
|
||||
sprintf(i->rev_type, "%c%d%d", (i->srev & 0x4) ? ('B') : ('A'),
|
||||
i->rev & 0x7, (i->srev & 0x3) + 1);
|
||||
|
||||
switch (i->partnum) {
|
||||
case SOC_ID_FALCON:
|
||||
type = (ltq_r32(FALCON_CHIPTYPE) & TYPE_MASK) >> TYPE_SHIFT;
|
||||
switch (type) {
|
||||
case 0:
|
||||
i->name = SOC_FALCON_D;
|
||||
break;
|
||||
case 1:
|
||||
i->name = SOC_FALCON_V;
|
||||
break;
|
||||
case 2:
|
||||
i->name = SOC_FALCON_M;
|
||||
break;
|
||||
default:
|
||||
i->name = SOC_FALCON;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable();
|
||||
break;
|
||||
}
|
||||
}
|
90
arch/mips/lantiq/falcon/reset.c
Normal file
90
arch/mips/lantiq/falcon/reset.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
|
||||
* Copyright (C) 2012 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pm.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <linux/export.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
/* CPU0 Reset Source Register */
|
||||
#define SYS1_CPU0RS 0x0040
|
||||
/* reset cause mask */
|
||||
#define CPU0RS_MASK 0x0003
|
||||
/* CPU0 Boot Mode Register */
|
||||
#define SYS1_BM 0x00a0
|
||||
/* boot mode mask */
|
||||
#define BM_MASK 0x0005
|
||||
|
||||
/* allow platform code to find out what surce we booted from */
|
||||
unsigned char ltq_boot_select(void)
|
||||
{
|
||||
return ltq_sys1_r32(SYS1_BM) & BM_MASK;
|
||||
}
|
||||
|
||||
/* allow the watchdog driver to find out what the boot reason was */
|
||||
int ltq_reset_cause(void)
|
||||
{
|
||||
return ltq_sys1_r32(SYS1_CPU0RS) & CPU0RS_MASK;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ltq_reset_cause);
|
||||
|
||||
#define BOOT_REG_BASE (KSEG1 | 0x1F200000)
|
||||
#define BOOT_PW1_REG (BOOT_REG_BASE | 0x20)
|
||||
#define BOOT_PW2_REG (BOOT_REG_BASE | 0x24)
|
||||
#define BOOT_PW1 0x4C545100
|
||||
#define BOOT_PW2 0x0051544C
|
||||
|
||||
#define WDT_REG_BASE (KSEG1 | 0x1F8803F0)
|
||||
#define WDT_PW1 0x00BE0000
|
||||
#define WDT_PW2 0x00DC0000
|
||||
|
||||
static void machine_restart(char *command)
|
||||
{
|
||||
local_irq_disable();
|
||||
|
||||
/* reboot magic */
|
||||
ltq_w32(BOOT_PW1, (void *)BOOT_PW1_REG); /* 'LTQ\0' */
|
||||
ltq_w32(BOOT_PW2, (void *)BOOT_PW2_REG); /* '\0QTL' */
|
||||
ltq_w32(0, (void *)BOOT_REG_BASE); /* reset Bootreg RVEC */
|
||||
|
||||
/* watchdog magic */
|
||||
ltq_w32(WDT_PW1, (void *)WDT_REG_BASE);
|
||||
ltq_w32(WDT_PW2 |
|
||||
(0x3 << 26) | /* PWL */
|
||||
(0x2 << 24) | /* CLKDIV */
|
||||
(0x1 << 31) | /* enable */
|
||||
(1), /* reload */
|
||||
(void *)WDT_REG_BASE);
|
||||
unreachable();
|
||||
}
|
||||
|
||||
static void machine_halt(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
unreachable();
|
||||
}
|
||||
|
||||
static void machine_power_off(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
unreachable();
|
||||
}
|
||||
|
||||
static int __init mips_reboot_setup(void)
|
||||
{
|
||||
_machine_restart = machine_restart;
|
||||
_machine_halt = machine_halt;
|
||||
pm_power_off = machine_power_off;
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(mips_reboot_setup);
|
260
arch/mips/lantiq/falcon/sysctrl.c
Normal file
260
arch/mips/lantiq/falcon/sysctrl.c
Normal file
@ -0,0 +1,260 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
|
||||
* Copyright (C) 2011 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <asm/delay.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#include "../clk.h"
|
||||
|
||||
/* infrastructure control register */
|
||||
#define SYS1_INFRAC 0x00bc
|
||||
/* Configuration fuses for drivers and pll */
|
||||
#define STATUS_CONFIG 0x0040
|
||||
|
||||
/* GPE frequency selection */
|
||||
#define GPPC_OFFSET 24
|
||||
#define GPEFREQ_MASK 0x00000C0
|
||||
#define GPEFREQ_OFFSET 10
|
||||
/* Clock status register */
|
||||
#define SYSCTL_CLKS 0x0000
|
||||
/* Clock enable register */
|
||||
#define SYSCTL_CLKEN 0x0004
|
||||
/* Clock clear register */
|
||||
#define SYSCTL_CLKCLR 0x0008
|
||||
/* Activation Status Register */
|
||||
#define SYSCTL_ACTS 0x0020
|
||||
/* Activation Register */
|
||||
#define SYSCTL_ACT 0x0024
|
||||
/* Deactivation Register */
|
||||
#define SYSCTL_DEACT 0x0028
|
||||
/* reboot Register */
|
||||
#define SYSCTL_RBT 0x002c
|
||||
/* CPU0 Clock Control Register */
|
||||
#define SYS1_CPU0CC 0x0040
|
||||
/* HRST_OUT_N Control Register */
|
||||
#define SYS1_HRSTOUTC 0x00c0
|
||||
/* clock divider bit */
|
||||
#define CPU0CC_CPUDIV 0x0001
|
||||
|
||||
/* Activation Status Register */
|
||||
#define ACTS_ASC1_ACT 0x00000800
|
||||
#define ACTS_I2C_ACT 0x00004000
|
||||
#define ACTS_P0 0x00010000
|
||||
#define ACTS_P1 0x00010000
|
||||
#define ACTS_P2 0x00020000
|
||||
#define ACTS_P3 0x00020000
|
||||
#define ACTS_P4 0x00040000
|
||||
#define ACTS_PADCTRL0 0x00100000
|
||||
#define ACTS_PADCTRL1 0x00100000
|
||||
#define ACTS_PADCTRL2 0x00200000
|
||||
#define ACTS_PADCTRL3 0x00200000
|
||||
#define ACTS_PADCTRL4 0x00400000
|
||||
|
||||
#define sysctl_w32(m, x, y) ltq_w32((x), sysctl_membase[m] + (y))
|
||||
#define sysctl_r32(m, x) ltq_r32(sysctl_membase[m] + (x))
|
||||
#define sysctl_w32_mask(m, clear, set, reg) \
|
||||
sysctl_w32(m, (sysctl_r32(m, reg) & ~(clear)) | (set), reg)
|
||||
|
||||
#define status_w32(x, y) ltq_w32((x), status_membase + (y))
|
||||
#define status_r32(x) ltq_r32(status_membase + (x))
|
||||
|
||||
static void __iomem *sysctl_membase[3], *status_membase;
|
||||
void __iomem *ltq_sys1_membase, *ltq_ebu_membase;
|
||||
|
||||
void falcon_trigger_hrst(int level)
|
||||
{
|
||||
sysctl_w32(SYSCTL_SYS1, level & 1, SYS1_HRSTOUTC);
|
||||
}
|
||||
|
||||
static inline void sysctl_wait(struct clk *clk,
|
||||
unsigned int test, unsigned int reg)
|
||||
{
|
||||
int err = 1000000;
|
||||
|
||||
do {} while (--err && ((sysctl_r32(clk->module, reg)
|
||||
& clk->bits) != test));
|
||||
if (!err)
|
||||
pr_err("module de/activation failed %d %08X %08X %08X\n",
|
||||
clk->module, clk->bits, test,
|
||||
sysctl_r32(clk->module, reg) & clk->bits);
|
||||
}
|
||||
|
||||
static int sysctl_activate(struct clk *clk)
|
||||
{
|
||||
sysctl_w32(clk->module, clk->bits, SYSCTL_CLKEN);
|
||||
sysctl_w32(clk->module, clk->bits, SYSCTL_ACT);
|
||||
sysctl_wait(clk, clk->bits, SYSCTL_ACTS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sysctl_deactivate(struct clk *clk)
|
||||
{
|
||||
sysctl_w32(clk->module, clk->bits, SYSCTL_CLKCLR);
|
||||
sysctl_w32(clk->module, clk->bits, SYSCTL_DEACT);
|
||||
sysctl_wait(clk, 0, SYSCTL_ACTS);
|
||||
}
|
||||
|
||||
static int sysctl_clken(struct clk *clk)
|
||||
{
|
||||
sysctl_w32(clk->module, clk->bits, SYSCTL_CLKEN);
|
||||
sysctl_wait(clk, clk->bits, SYSCTL_CLKS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sysctl_clkdis(struct clk *clk)
|
||||
{
|
||||
sysctl_w32(clk->module, clk->bits, SYSCTL_CLKCLR);
|
||||
sysctl_wait(clk, 0, SYSCTL_CLKS);
|
||||
}
|
||||
|
||||
static void sysctl_reboot(struct clk *clk)
|
||||
{
|
||||
unsigned int act;
|
||||
unsigned int bits;
|
||||
|
||||
act = sysctl_r32(clk->module, SYSCTL_ACT);
|
||||
bits = ~act & clk->bits;
|
||||
if (bits != 0) {
|
||||
sysctl_w32(clk->module, bits, SYSCTL_CLKEN);
|
||||
sysctl_w32(clk->module, bits, SYSCTL_ACT);
|
||||
sysctl_wait(clk, bits, SYSCTL_ACTS);
|
||||
}
|
||||
sysctl_w32(clk->module, act & clk->bits, SYSCTL_RBT);
|
||||
sysctl_wait(clk, clk->bits, SYSCTL_ACTS);
|
||||
}
|
||||
|
||||
/* enable the ONU core */
|
||||
static void falcon_gpe_enable(void)
|
||||
{
|
||||
unsigned int freq;
|
||||
unsigned int status;
|
||||
|
||||
/* if if the clock is already enabled */
|
||||
status = sysctl_r32(SYSCTL_SYS1, SYS1_INFRAC);
|
||||
if (status & (1 << (GPPC_OFFSET + 1)))
|
||||
return;
|
||||
|
||||
if (status_r32(STATUS_CONFIG) == 0)
|
||||
freq = 1; /* use 625MHz on unfused chip */
|
||||
else
|
||||
freq = (status_r32(STATUS_CONFIG) &
|
||||
GPEFREQ_MASK) >>
|
||||
GPEFREQ_OFFSET;
|
||||
|
||||
/* apply new frequency */
|
||||
sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1),
|
||||
freq << (GPPC_OFFSET + 2) , SYS1_INFRAC);
|
||||
udelay(1);
|
||||
|
||||
/* enable new frequency */
|
||||
sysctl_w32_mask(SYSCTL_SYS1, 0, 1 << (GPPC_OFFSET + 1), SYS1_INFRAC);
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
static inline void clkdev_add_sys(const char *dev, unsigned int module,
|
||||
unsigned int bits)
|
||||
{
|
||||
struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
|
||||
|
||||
clk->cl.dev_id = dev;
|
||||
clk->cl.con_id = NULL;
|
||||
clk->cl.clk = clk;
|
||||
clk->module = module;
|
||||
clk->activate = sysctl_activate;
|
||||
clk->deactivate = sysctl_deactivate;
|
||||
clk->enable = sysctl_clken;
|
||||
clk->disable = sysctl_clkdis;
|
||||
clk->reboot = sysctl_reboot;
|
||||
clkdev_add(&clk->cl);
|
||||
}
|
||||
|
||||
void __init ltq_soc_init(void)
|
||||
{
|
||||
struct device_node *np_status =
|
||||
of_find_compatible_node(NULL, NULL, "lantiq,status-falcon");
|
||||
struct device_node *np_ebu =
|
||||
of_find_compatible_node(NULL, NULL, "lantiq,ebu-falcon");
|
||||
struct device_node *np_sys1 =
|
||||
of_find_compatible_node(NULL, NULL, "lantiq,sys1-falcon");
|
||||
struct device_node *np_syseth =
|
||||
of_find_compatible_node(NULL, NULL, "lantiq,syseth-falcon");
|
||||
struct device_node *np_sysgpe =
|
||||
of_find_compatible_node(NULL, NULL, "lantiq,sysgpe-falcon");
|
||||
struct resource res_status, res_ebu, res_sys[3];
|
||||
int i;
|
||||
|
||||
/* check if all the core register ranges are available */
|
||||
if (!np_status || !np_ebu || !np_sys1 || !np_syseth || !np_sysgpe)
|
||||
panic("Failed to load core nodes from devicetree");
|
||||
|
||||
if (of_address_to_resource(np_status, 0, &res_status) ||
|
||||
of_address_to_resource(np_ebu, 0, &res_ebu) ||
|
||||
of_address_to_resource(np_sys1, 0, &res_sys[0]) ||
|
||||
of_address_to_resource(np_syseth, 0, &res_sys[1]) ||
|
||||
of_address_to_resource(np_sysgpe, 0, &res_sys[2]))
|
||||
panic("Failed to get core resources");
|
||||
|
||||
if ((request_mem_region(res_status.start, resource_size(&res_status),
|
||||
res_status.name) < 0) ||
|
||||
(request_mem_region(res_ebu.start, resource_size(&res_ebu),
|
||||
res_ebu.name) < 0) ||
|
||||
(request_mem_region(res_sys[0].start,
|
||||
resource_size(&res_sys[0]),
|
||||
res_sys[0].name) < 0) ||
|
||||
(request_mem_region(res_sys[1].start,
|
||||
resource_size(&res_sys[1]),
|
||||
res_sys[1].name) < 0) ||
|
||||
(request_mem_region(res_sys[2].start,
|
||||
resource_size(&res_sys[2]),
|
||||
res_sys[2].name) < 0))
|
||||
pr_err("Failed to request core reources");
|
||||
|
||||
status_membase = ioremap_nocache(res_status.start,
|
||||
resource_size(&res_status));
|
||||
ltq_ebu_membase = ioremap_nocache(res_ebu.start,
|
||||
resource_size(&res_ebu));
|
||||
|
||||
if (!status_membase || !ltq_ebu_membase)
|
||||
panic("Failed to remap core resources");
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
sysctl_membase[i] = ioremap_nocache(res_sys[i].start,
|
||||
resource_size(&res_sys[i]));
|
||||
if (!sysctl_membase[i])
|
||||
panic("Failed to remap sysctrl resources");
|
||||
}
|
||||
ltq_sys1_membase = sysctl_membase[0];
|
||||
|
||||
falcon_gpe_enable();
|
||||
|
||||
/* 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);
|
||||
else
|
||||
clkdev_add_static(CLOCK_400M, CLOCK_100M, CLOCK_200M);
|
||||
|
||||
/* add our clock domains */
|
||||
clkdev_add_sys("1d810000.gpio", SYSCTL_SYSETH, ACTS_P0);
|
||||
clkdev_add_sys("1d810100.gpio", SYSCTL_SYSETH, ACTS_P2);
|
||||
clkdev_add_sys("1e800100.gpio", SYSCTL_SYS1, ACTS_P1);
|
||||
clkdev_add_sys("1e800200.gpio", SYSCTL_SYS1, ACTS_P3);
|
||||
clkdev_add_sys("1e800300.gpio", SYSCTL_SYS1, ACTS_P4);
|
||||
clkdev_add_sys("1db01000.pad", SYSCTL_SYSETH, ACTS_PADCTRL0);
|
||||
clkdev_add_sys("1db02000.pad", SYSCTL_SYSETH, ACTS_PADCTRL2);
|
||||
clkdev_add_sys("1e800400.pad", SYSCTL_SYS1, ACTS_PADCTRL1);
|
||||
clkdev_add_sys("1e800500.pad", SYSCTL_SYS1, ACTS_PADCTRL3);
|
||||
clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4);
|
||||
clkdev_add_sys("1e100C00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT);
|
||||
clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT);
|
||||
}
|
@ -9,6 +9,11 @@
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/irq_cpu.h>
|
||||
@ -16,7 +21,7 @@
|
||||
#include <lantiq_soc.h>
|
||||
#include <irq.h>
|
||||
|
||||
/* register definitions */
|
||||
/* register definitions - internal irqs */
|
||||
#define LTQ_ICU_IM0_ISR 0x0000
|
||||
#define LTQ_ICU_IM0_IER 0x0008
|
||||
#define LTQ_ICU_IM0_IOSR 0x0010
|
||||
@ -25,6 +30,7 @@
|
||||
#define LTQ_ICU_IM1_ISR 0x0028
|
||||
#define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
|
||||
|
||||
/* register definitions - external irqs */
|
||||
#define LTQ_EIU_EXIN_C 0x0000
|
||||
#define LTQ_EIU_EXIN_INIC 0x0004
|
||||
#define LTQ_EIU_EXIN_INEN 0x000C
|
||||
@ -37,10 +43,14 @@
|
||||
#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
|
||||
#define MAX_EIU 6
|
||||
|
||||
/* irqs generated by device attached to the EBU need to be acked in
|
||||
/* the performance counter */
|
||||
#define LTQ_PERF_IRQ (INT_NUM_IM4_IRL0 + 31)
|
||||
|
||||
/*
|
||||
* irqs generated by devices attached to the EBU need to be acked in
|
||||
* a special manner
|
||||
*/
|
||||
#define LTQ_ICU_EBU_IRQ 22
|
||||
@ -51,6 +61,17 @@
|
||||
#define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y))
|
||||
#define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x))
|
||||
|
||||
/* our 2 ipi interrupts for VSMP */
|
||||
#define MIPS_CPU_IPI_RESCHED_IRQ 0
|
||||
#define MIPS_CPU_IPI_CALL_IRQ 1
|
||||
|
||||
/* we have a cascade of 8 irqs */
|
||||
#define MIPS_CPU_IRQ_CASCADE 8
|
||||
|
||||
#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
|
||||
int gic_present;
|
||||
#endif
|
||||
|
||||
static unsigned short ltq_eiu_irq[MAX_EIU] = {
|
||||
LTQ_EIU_IR0,
|
||||
LTQ_EIU_IR1,
|
||||
@ -60,64 +81,51 @@ static unsigned short ltq_eiu_irq[MAX_EIU] = {
|
||||
LTQ_EIU_IR5,
|
||||
};
|
||||
|
||||
static struct resource ltq_icu_resource = {
|
||||
.name = "icu",
|
||||
.start = LTQ_ICU_BASE_ADDR,
|
||||
.end = LTQ_ICU_BASE_ADDR + LTQ_ICU_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct resource ltq_eiu_resource = {
|
||||
.name = "eiu",
|
||||
.start = LTQ_EIU_BASE_ADDR,
|
||||
.end = LTQ_EIU_BASE_ADDR + LTQ_ICU_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static int exin_avail;
|
||||
static void __iomem *ltq_icu_membase;
|
||||
static void __iomem *ltq_eiu_membase;
|
||||
|
||||
void ltq_disable_irq(struct irq_data *d)
|
||||
{
|
||||
u32 ier = LTQ_ICU_IM0_IER;
|
||||
int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
|
||||
|
||||
ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
irq_nr %= INT_NUM_IM_OFFSET;
|
||||
ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
|
||||
ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
|
||||
offset %= INT_NUM_IM_OFFSET;
|
||||
ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier);
|
||||
}
|
||||
|
||||
void ltq_mask_and_ack_irq(struct irq_data *d)
|
||||
{
|
||||
u32 ier = LTQ_ICU_IM0_IER;
|
||||
u32 isr = LTQ_ICU_IM0_ISR;
|
||||
int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
|
||||
|
||||
ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
irq_nr %= INT_NUM_IM_OFFSET;
|
||||
ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
|
||||
ltq_icu_w32((1 << irq_nr), isr);
|
||||
ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
|
||||
isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
|
||||
offset %= INT_NUM_IM_OFFSET;
|
||||
ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier);
|
||||
ltq_icu_w32(BIT(offset), isr);
|
||||
}
|
||||
|
||||
static void ltq_ack_irq(struct irq_data *d)
|
||||
{
|
||||
u32 isr = LTQ_ICU_IM0_ISR;
|
||||
int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
|
||||
|
||||
isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
irq_nr %= INT_NUM_IM_OFFSET;
|
||||
ltq_icu_w32((1 << irq_nr), isr);
|
||||
isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
|
||||
offset %= INT_NUM_IM_OFFSET;
|
||||
ltq_icu_w32(BIT(offset), isr);
|
||||
}
|
||||
|
||||
void ltq_enable_irq(struct irq_data *d)
|
||||
{
|
||||
u32 ier = LTQ_ICU_IM0_IER;
|
||||
int irq_nr = d->irq - INT_NUM_IRQ0;
|
||||
int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
|
||||
|
||||
ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
irq_nr %= INT_NUM_IM_OFFSET;
|
||||
ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier);
|
||||
ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
|
||||
offset %= INT_NUM_IM_OFFSET;
|
||||
ltq_icu_w32(ltq_icu_r32(ier) | BIT(offset), ier);
|
||||
}
|
||||
|
||||
static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
|
||||
@ -126,15 +134,15 @@ static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
|
||||
|
||||
ltq_enable_irq(d);
|
||||
for (i = 0; i < MAX_EIU; i++) {
|
||||
if (d->irq == ltq_eiu_irq[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);
|
||||
/* clear all pending */
|
||||
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~(1 << i),
|
||||
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~BIT(i),
|
||||
LTQ_EIU_EXIN_INIC);
|
||||
/* enable */
|
||||
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | (1 << i),
|
||||
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | BIT(i),
|
||||
LTQ_EIU_EXIN_INEN);
|
||||
break;
|
||||
}
|
||||
@ -149,9 +157,9 @@ static void ltq_shutdown_eiu_irq(struct irq_data *d)
|
||||
|
||||
ltq_disable_irq(d);
|
||||
for (i = 0; i < MAX_EIU; i++) {
|
||||
if (d->irq == ltq_eiu_irq[i]) {
|
||||
if (d->hwirq == ltq_eiu_irq[i]) {
|
||||
/* disable */
|
||||
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i),
|
||||
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~BIT(i),
|
||||
LTQ_EIU_EXIN_INEN);
|
||||
break;
|
||||
}
|
||||
@ -188,14 +196,15 @@ static void ltq_hw_irqdispatch(int module)
|
||||
if (irq == 0)
|
||||
return;
|
||||
|
||||
/* silicon bug causes only the msb set to 1 to be valid. all
|
||||
/*
|
||||
* silicon bug causes only the msb set to 1 to be valid. all
|
||||
* other bits might be bogus
|
||||
*/
|
||||
irq = __fls(irq);
|
||||
do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module));
|
||||
do_IRQ((int)irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module));
|
||||
|
||||
/* if this is a EBU irq, we need to ack it or get a deadlock */
|
||||
if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0))
|
||||
if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0) && LTQ_EBU_PCC_ISTAT)
|
||||
ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10,
|
||||
LTQ_EBU_PCC_ISTAT);
|
||||
}
|
||||
@ -216,6 +225,47 @@ static void ltq_hw5_irqdispatch(void)
|
||||
do_IRQ(MIPS_CPU_TIMER_IRQ);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMP
|
||||
void __init arch_init_ipiirq(int irq, struct irqaction *action)
|
||||
{
|
||||
setup_irq(irq, action);
|
||||
irq_set_handler(irq, handle_percpu_irq);
|
||||
}
|
||||
|
||||
static void ltq_sw0_irqdispatch(void)
|
||||
{
|
||||
do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
|
||||
}
|
||||
|
||||
static void ltq_sw1_irqdispatch(void)
|
||||
{
|
||||
do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
|
||||
}
|
||||
static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
scheduler_ipi();
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
smp_call_function_interrupt();
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction irq_resched = {
|
||||
.handler = ipi_resched_interrupt,
|
||||
.flags = IRQF_PERCPU,
|
||||
.name = "IPI_resched"
|
||||
};
|
||||
|
||||
static struct irqaction irq_call = {
|
||||
.handler = ipi_call_interrupt,
|
||||
.flags = IRQF_PERCPU,
|
||||
.name = "IPI_call"
|
||||
};
|
||||
#endif
|
||||
|
||||
asmlinkage void plat_irq_dispatch(void)
|
||||
{
|
||||
unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
|
||||
@ -238,45 +288,75 @@ out:
|
||||
return;
|
||||
}
|
||||
|
||||
static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
|
||||
{
|
||||
struct irq_chip *chip = <q_irq_type;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < exin_avail; i++)
|
||||
if (hw == ltq_eiu_irq[i])
|
||||
chip = <q_eiu_type;
|
||||
|
||||
irq_set_chip_and_handler(hw, chip, handle_level_irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops irq_domain_ops = {
|
||||
.xlate = irq_domain_xlate_onetwocell,
|
||||
.map = icu_map,
|
||||
};
|
||||
|
||||
static struct irqaction cascade = {
|
||||
.handler = no_action,
|
||||
.name = "cascade",
|
||||
};
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
||||
{
|
||||
struct device_node *eiu_node;
|
||||
struct resource res;
|
||||
int i;
|
||||
|
||||
if (insert_resource(&iomem_resource, <q_icu_resource) < 0)
|
||||
panic("Failed to insert icu memory");
|
||||
if (of_address_to_resource(node, 0, &res))
|
||||
panic("Failed to get icu memory range");
|
||||
|
||||
if (request_mem_region(ltq_icu_resource.start,
|
||||
resource_size(<q_icu_resource), "icu") < 0)
|
||||
panic("Failed to request icu memory");
|
||||
if (request_mem_region(res.start, resource_size(&res), res.name) < 0)
|
||||
pr_err("Failed to request icu memory");
|
||||
|
||||
ltq_icu_membase = ioremap_nocache(ltq_icu_resource.start,
|
||||
resource_size(<q_icu_resource));
|
||||
ltq_icu_membase = ioremap_nocache(res.start, resource_size(&res));
|
||||
if (!ltq_icu_membase)
|
||||
panic("Failed to remap icu memory");
|
||||
|
||||
if (insert_resource(&iomem_resource, <q_eiu_resource) < 0)
|
||||
panic("Failed to insert eiu memory");
|
||||
/* the external interrupts are optional and xway only */
|
||||
eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu");
|
||||
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);
|
||||
|
||||
if (request_mem_region(ltq_eiu_resource.start,
|
||||
resource_size(<q_eiu_resource), "eiu") < 0)
|
||||
panic("Failed to request eiu memory");
|
||||
if (count)
|
||||
exin_avail = *count;
|
||||
if (exin_avail > MAX_EIU)
|
||||
exin_avail = MAX_EIU;
|
||||
|
||||
ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start,
|
||||
resource_size(<q_eiu_resource));
|
||||
if (!ltq_eiu_membase)
|
||||
panic("Failed to remap eiu memory");
|
||||
if (request_mem_region(res.start, resource_size(&res),
|
||||
res.name) < 0)
|
||||
pr_err("Failed to request eiu memory");
|
||||
|
||||
/* make sure all irqs are turned off by default */
|
||||
for (i = 0; i < 5; i++)
|
||||
ltq_eiu_membase = ioremap_nocache(res.start,
|
||||
resource_size(&res));
|
||||
if (!ltq_eiu_membase)
|
||||
panic("Failed to remap eiu memory");
|
||||
}
|
||||
|
||||
/* turn off all irqs by default */
|
||||
for (i = 0; i < 5; i++) {
|
||||
/* make sure all irqs are turned off by default */
|
||||
ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET));
|
||||
|
||||
/* clear all possibly pending interrupts */
|
||||
ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
|
||||
/* clear all possibly pending interrupts */
|
||||
ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
|
||||
}
|
||||
|
||||
mips_cpu_irq_init();
|
||||
|
||||
@ -293,20 +373,19 @@ void __init arch_init_irq(void)
|
||||
set_vi_handler(7, ltq_hw5_irqdispatch);
|
||||
}
|
||||
|
||||
for (i = INT_NUM_IRQ0;
|
||||
i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++)
|
||||
if ((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) ||
|
||||
(i == LTQ_EIU_IR2))
|
||||
irq_set_chip_and_handler(i, <q_eiu_type,
|
||||
handle_level_irq);
|
||||
/* EIU3-5 only exist on ar9 and vr9 */
|
||||
else if (((i == LTQ_EIU_IR3) || (i == LTQ_EIU_IR4) ||
|
||||
(i == LTQ_EIU_IR5)) && (ltq_is_ar9() || ltq_is_vr9()))
|
||||
irq_set_chip_and_handler(i, <q_eiu_type,
|
||||
handle_level_irq);
|
||||
else
|
||||
irq_set_chip_and_handler(i, <q_irq_type,
|
||||
handle_level_irq);
|
||||
irq_domain_add_linear(node, 6 * INT_NUM_IM_OFFSET,
|
||||
&irq_domain_ops, 0);
|
||||
|
||||
#if defined(CONFIG_MIPS_MT_SMP)
|
||||
if (cpu_has_vint) {
|
||||
pr_info("Setting up IPI vectored interrupts\n");
|
||||
set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ltq_sw0_irqdispatch);
|
||||
set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ltq_sw1_irqdispatch);
|
||||
}
|
||||
arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ,
|
||||
&irq_resched);
|
||||
arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ, &irq_call);
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
|
||||
set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
|
||||
@ -315,9 +394,23 @@ void __init arch_init_irq(void)
|
||||
set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
|
||||
IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
|
||||
#endif
|
||||
|
||||
/* tell oprofile which irq to use */
|
||||
cp0_perfcount_irq = LTQ_PERF_IRQ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int __cpuinit get_c0_compare_int(void)
|
||||
{
|
||||
return CP0_LEGACY_COMPARE_IRQ;
|
||||
}
|
||||
|
||||
static struct of_device_id __initdata of_irq_ids[] = {
|
||||
{ .compatible = "lantiq,icu", .data = icu_of_init },
|
||||
{},
|
||||
};
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
of_irq_init(of_irq_ids);
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#ifndef _LANTIQ_MACH_H__
|
||||
#define _LANTIQ_MACH_H__
|
||||
|
||||
#include <asm/mips_machine.h>
|
||||
|
||||
enum lantiq_mach_type {
|
||||
LTQ_MACH_GENERIC = 0,
|
||||
LTQ_MACH_EASY50712, /* Danube evaluation board */
|
||||
LTQ_MACH_EASY50601, /* Amazon SE evaluation board */
|
||||
};
|
||||
|
||||
#endif
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
@ -16,20 +17,16 @@
|
||||
#include "prom.h"
|
||||
#include "clk.h"
|
||||
|
||||
/* access to the ebu needs to be locked between different drivers */
|
||||
DEFINE_SPINLOCK(ebu_lock);
|
||||
EXPORT_SYMBOL_GPL(ebu_lock);
|
||||
|
||||
/*
|
||||
* this struct is filled by the soc specific detection code and holds
|
||||
* information about the specific soc type, revision and name
|
||||
*/
|
||||
static struct ltq_soc_info soc_info;
|
||||
|
||||
unsigned int ltq_get_cpu_ver(void)
|
||||
{
|
||||
return soc_info.rev;
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_get_cpu_ver);
|
||||
|
||||
unsigned int ltq_get_soc_type(void)
|
||||
{
|
||||
return soc_info.type;
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_get_soc_type);
|
||||
|
||||
const char *get_system_type(void)
|
||||
{
|
||||
return soc_info.sys_type;
|
||||
@ -45,27 +42,62 @@ static void __init prom_init_cmdline(void)
|
||||
char **argv = (char **) KSEG1ADDR(fw_arg1);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
char *p = (char *) KSEG1ADDR(argv[i]);
|
||||
arcs_cmdline[0] = '\0';
|
||||
|
||||
if (p && *p) {
|
||||
for (i = 0; i < argc; i++) {
|
||||
char *p = (char *) KSEG1ADDR(argv[i]);
|
||||
|
||||
if (CPHYSADDR(p) && *p) {
|
||||
strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
|
||||
strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
ioport_resource.start = IOPORT_RESOURCE_START;
|
||||
ioport_resource.end = IOPORT_RESOURCE_END;
|
||||
iomem_resource.start = IOMEM_RESOURCE_START;
|
||||
iomem_resource.end = IOMEM_RESOURCE_END;
|
||||
|
||||
set_io_port_base((unsigned long) KSEG1);
|
||||
|
||||
/*
|
||||
* Load the builtin devicetree. This causes the chosen node to be
|
||||
* parsed resulting in our memory appearing
|
||||
*/
|
||||
__dt_setup_arch(&__dtb_start);
|
||||
}
|
||||
|
||||
void __init prom_init(void)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
/* call the soc specific detetcion code and get it to fill soc_info */
|
||||
ltq_soc_detect(&soc_info);
|
||||
clk_init();
|
||||
clk = clk_get(0, "cpu");
|
||||
snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev1.%d",
|
||||
soc_info.name, soc_info.rev);
|
||||
clk_put(clk);
|
||||
snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev %s",
|
||||
soc_info.name, soc_info.rev_type);
|
||||
soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
|
||||
pr_info("SoC: %s\n", soc_info.sys_type);
|
||||
prom_init_cmdline();
|
||||
|
||||
#if defined(CONFIG_MIPS_MT_SMP)
|
||||
if (register_vsmp_smp_ops())
|
||||
panic("failed to register_vsmp_smp_ops()");
|
||||
#endif
|
||||
}
|
||||
|
||||
int __init plat_of_setup(void)
|
||||
{
|
||||
static struct of_device_id of_ids[3];
|
||||
|
||||
if (!of_have_populated_dt())
|
||||
panic("device tree not present");
|
||||
|
||||
strncpy(of_ids[0].compatible, soc_info.compatible,
|
||||
sizeof(of_ids[0].compatible));
|
||||
strncpy(of_ids[1].compatible, "simple-bus",
|
||||
sizeof(of_ids[1].compatible));
|
||||
return of_platform_bus_probe(NULL, of_ids, NULL);
|
||||
}
|
||||
|
||||
arch_initcall(plat_of_setup);
|
||||
|
@ -10,16 +10,22 @@
|
||||
#define _LTQ_PROM_H__
|
||||
|
||||
#define LTQ_SYS_TYPE_LEN 0x100
|
||||
#define LTQ_SYS_REV_LEN 0x10
|
||||
|
||||
struct ltq_soc_info {
|
||||
unsigned char *name;
|
||||
unsigned int rev;
|
||||
unsigned char rev_type[LTQ_SYS_REV_LEN];
|
||||
unsigned int srev;
|
||||
unsigned int partnum;
|
||||
unsigned int type;
|
||||
unsigned char sys_type[LTQ_SYS_TYPE_LEN];
|
||||
unsigned char *compatible;
|
||||
};
|
||||
|
||||
extern void ltq_soc_detect(struct ltq_soc_info *i);
|
||||
extern void ltq_soc_setup(void);
|
||||
extern void ltq_soc_init(void);
|
||||
|
||||
extern struct boot_param_header __dtb_start;
|
||||
|
||||
#endif
|
||||
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <asm/bootinfo.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#include "machtypes.h"
|
||||
#include "devices.h"
|
||||
#include "prom.h"
|
||||
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
/* assume 16M as default incase uboot fails to pass proper ramsize */
|
||||
unsigned long memsize = 16;
|
||||
char **envp = (char **) KSEG1ADDR(fw_arg2);
|
||||
|
||||
ioport_resource.start = IOPORT_RESOURCE_START;
|
||||
ioport_resource.end = IOPORT_RESOURCE_END;
|
||||
iomem_resource.start = IOMEM_RESOURCE_START;
|
||||
iomem_resource.end = IOMEM_RESOURCE_END;
|
||||
|
||||
set_io_port_base((unsigned long) KSEG1);
|
||||
|
||||
while (*envp) {
|
||||
char *e = (char *)KSEG1ADDR(*envp);
|
||||
if (!strncmp(e, "memsize=", 8)) {
|
||||
e += 8;
|
||||
if (strict_strtoul(e, 0, &memsize))
|
||||
pr_warn("bad memsize specified\n");
|
||||
}
|
||||
envp++;
|
||||
}
|
||||
memsize *= 1024 * 1024;
|
||||
add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
|
||||
}
|
||||
|
||||
static int __init
|
||||
lantiq_setup(void)
|
||||
{
|
||||
ltq_soc_setup();
|
||||
mips_machine_setup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(lantiq_setup);
|
||||
|
||||
static void __init
|
||||
lantiq_generic_init(void)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
MIPS_MACHINE(LTQ_MACH_GENERIC,
|
||||
"Generic",
|
||||
"Generic Lantiq based board",
|
||||
lantiq_generic_init);
|
@ -1,23 +0,0 @@
|
||||
if SOC_XWAY
|
||||
|
||||
menu "MIPS Machine"
|
||||
|
||||
config LANTIQ_MACH_EASY50712
|
||||
bool "Easy50712 - Danube"
|
||||
default y
|
||||
|
||||
endmenu
|
||||
|
||||
endif
|
||||
|
||||
if SOC_AMAZON_SE
|
||||
|
||||
menu "MIPS Machine"
|
||||
|
||||
config LANTIQ_MACH_EASY50601
|
||||
bool "Easy50601 - Amazon SE"
|
||||
default y
|
||||
|
||||
endmenu
|
||||
|
||||
endif
|
@ -1,7 +1 @@
|
||||
obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o
|
||||
|
||||
obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o setup-xway.o
|
||||
obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o setup-ase.o
|
||||
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
|
||||
obj-y := prom.o sysctrl.o clk.o reset.o gpio.o dma.o
|
||||
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2011 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
/* cgu registers */
|
||||
#define LTQ_CGU_SYS 0x0010
|
||||
|
||||
unsigned int ltq_get_io_region_clock(void)
|
||||
{
|
||||
return CLOCK_133M;
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_get_io_region_clock);
|
||||
|
||||
unsigned int ltq_get_fpi_bus_clock(int fpi)
|
||||
{
|
||||
return CLOCK_133M;
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
|
||||
|
||||
unsigned int ltq_get_cpu_hz(void)
|
||||
{
|
||||
if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5))
|
||||
return CLOCK_266M;
|
||||
else
|
||||
return CLOCK_133M;
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_get_cpu_hz);
|
||||
|
||||
unsigned int ltq_get_fpi_hz(void)
|
||||
{
|
||||
return CLOCK_133M;
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_get_fpi_hz);
|
@ -1,223 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
static unsigned int ltq_ram_clocks[] = {
|
||||
CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
|
||||
#define DDR_HZ ltq_ram_clocks[ltq_cgu_r32(LTQ_CGU_SYS) & 0x3]
|
||||
|
||||
#define BASIC_FREQUENCY_1 35328000
|
||||
#define BASIC_FREQUENCY_2 36000000
|
||||
#define BASIS_REQUENCY_USB 12000000
|
||||
|
||||
#define GET_BITS(x, msb, lsb) \
|
||||
(((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
|
||||
|
||||
#define LTQ_CGU_PLL0_CFG 0x0004
|
||||
#define LTQ_CGU_PLL1_CFG 0x0008
|
||||
#define LTQ_CGU_PLL2_CFG 0x000C
|
||||
#define LTQ_CGU_SYS 0x0010
|
||||
#define LTQ_CGU_UPDATE 0x0014
|
||||
#define LTQ_CGU_IF_CLK 0x0018
|
||||
#define LTQ_CGU_OSC_CON 0x001C
|
||||
#define LTQ_CGU_SMD 0x0020
|
||||
#define LTQ_CGU_CT1SR 0x0028
|
||||
#define LTQ_CGU_CT2SR 0x002C
|
||||
#define LTQ_CGU_PCMCR 0x0030
|
||||
#define LTQ_CGU_PCI_CR 0x0034
|
||||
#define LTQ_CGU_PD_PC 0x0038
|
||||
#define LTQ_CGU_FMR 0x003C
|
||||
|
||||
#define CGU_PLL0_PHASE_DIVIDER_ENABLE \
|
||||
(ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 31))
|
||||
#define CGU_PLL0_BYPASS \
|
||||
(ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 30))
|
||||
#define CGU_PLL0_CFG_DSMSEL \
|
||||
(ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 28))
|
||||
#define CGU_PLL0_CFG_FRAC_EN \
|
||||
(ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 27))
|
||||
#define CGU_PLL1_SRC \
|
||||
(ltq_cgu_r32(LTQ_CGU_PLL1_CFG) & (1 << 31))
|
||||
#define CGU_PLL2_PHASE_DIVIDER_ENABLE \
|
||||
(ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & (1 << 20))
|
||||
#define CGU_SYS_FPI_SEL (1 << 6)
|
||||
#define CGU_SYS_DDR_SEL 0x3
|
||||
#define CGU_PLL0_SRC (1 << 29)
|
||||
|
||||
#define CGU_PLL0_CFG_PLLK GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 26, 17)
|
||||
#define CGU_PLL0_CFG_PLLN GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 12, 6)
|
||||
#define CGU_PLL0_CFG_PLLM GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 5, 2)
|
||||
#define CGU_PLL2_SRC GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 18, 17)
|
||||
#define CGU_PLL2_CFG_INPUT_DIV GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 16, 13)
|
||||
|
||||
static unsigned int ltq_get_pll0_fdiv(void);
|
||||
|
||||
static inline unsigned int get_input_clock(int pll)
|
||||
{
|
||||
switch (pll) {
|
||||
case 0:
|
||||
if (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC)
|
||||
return BASIS_REQUENCY_USB;
|
||||
else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
|
||||
return BASIC_FREQUENCY_1;
|
||||
else
|
||||
return BASIC_FREQUENCY_2;
|
||||
case 1:
|
||||
if (CGU_PLL1_SRC)
|
||||
return BASIS_REQUENCY_USB;
|
||||
else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
|
||||
return BASIC_FREQUENCY_1;
|
||||
else
|
||||
return BASIC_FREQUENCY_2;
|
||||
case 2:
|
||||
switch (CGU_PLL2_SRC) {
|
||||
case 0:
|
||||
return ltq_get_pll0_fdiv();
|
||||
case 1:
|
||||
return CGU_PLL2_PHASE_DIVIDER_ENABLE ?
|
||||
BASIC_FREQUENCY_1 :
|
||||
BASIC_FREQUENCY_2;
|
||||
case 2:
|
||||
return BASIS_REQUENCY_USB;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den)
|
||||
{
|
||||
u64 res, clock = get_input_clock(pll);
|
||||
|
||||
res = num * clock;
|
||||
do_div(res, den);
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N,
|
||||
unsigned int K)
|
||||
{
|
||||
unsigned int num = ((N + 1) << 10) + K;
|
||||
unsigned int den = (M + 1) << 10;
|
||||
|
||||
return cal_dsm(pll, num, den);
|
||||
}
|
||||
|
||||
static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N,
|
||||
unsigned int K)
|
||||
{
|
||||
unsigned int num = ((N + 1) << 11) + K + 512;
|
||||
unsigned int den = (M + 1) << 11;
|
||||
|
||||
return cal_dsm(pll, num, den);
|
||||
}
|
||||
|
||||
static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N,
|
||||
unsigned int K)
|
||||
{
|
||||
unsigned int num = K >= 512 ?
|
||||
((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;
|
||||
unsigned int den = (M + 1) << 12;
|
||||
|
||||
return cal_dsm(pll, num, den);
|
||||
}
|
||||
|
||||
static inline unsigned int dsm(int pll, unsigned int M, unsigned int N,
|
||||
unsigned int K, unsigned int dsmsel, unsigned int phase_div_en)
|
||||
{
|
||||
if (!dsmsel)
|
||||
return mash_dsm(pll, M, N, K);
|
||||
else if (!phase_div_en)
|
||||
return mash_dsm(pll, M, N, K);
|
||||
else
|
||||
return ssff_dsm_2(pll, M, N, K);
|
||||
}
|
||||
|
||||
static inline unsigned int ltq_get_pll0_fosc(void)
|
||||
{
|
||||
if (CGU_PLL0_BYPASS)
|
||||
return get_input_clock(0);
|
||||
else
|
||||
return !CGU_PLL0_CFG_FRAC_EN
|
||||
? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0,
|
||||
CGU_PLL0_CFG_DSMSEL,
|
||||
CGU_PLL0_PHASE_DIVIDER_ENABLE)
|
||||
: dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN,
|
||||
CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL,
|
||||
CGU_PLL0_PHASE_DIVIDER_ENABLE);
|
||||
}
|
||||
|
||||
static unsigned int ltq_get_pll0_fdiv(void)
|
||||
{
|
||||
unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
|
||||
|
||||
return (ltq_get_pll0_fosc() + (div >> 1)) / div;
|
||||
}
|
||||
|
||||
unsigned int ltq_get_io_region_clock(void)
|
||||
{
|
||||
unsigned int ret = ltq_get_pll0_fosc();
|
||||
|
||||
switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) {
|
||||
default:
|
||||
case 0:
|
||||
return (ret + 1) / 2;
|
||||
case 1:
|
||||
return (ret * 2 + 2) / 5;
|
||||
case 2:
|
||||
return (ret + 1) / 3;
|
||||
case 3:
|
||||
return (ret + 2) / 4;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_get_io_region_clock);
|
||||
|
||||
unsigned int ltq_get_fpi_bus_clock(int fpi)
|
||||
{
|
||||
unsigned int ret = ltq_get_io_region_clock();
|
||||
|
||||
if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL))
|
||||
ret >>= 1;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
|
||||
|
||||
unsigned int ltq_get_cpu_hz(void)
|
||||
{
|
||||
switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) {
|
||||
case 0:
|
||||
return CLOCK_333M;
|
||||
case 4:
|
||||
return DDR_HZ;
|
||||
case 8:
|
||||
return DDR_HZ << 1;
|
||||
default:
|
||||
return DDR_HZ >> 1;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_get_cpu_hz);
|
||||
|
||||
unsigned int ltq_get_fpi_hz(void)
|
||||
{
|
||||
unsigned int ddr_clock = DDR_HZ;
|
||||
|
||||
if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40)
|
||||
return ddr_clock >> 1;
|
||||
return ddr_clock;
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_get_fpi_hz);
|
151
arch/mips/lantiq/xway/clk.c
Normal file
151
arch/mips/lantiq/xway/clk.c
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#include "../clk.h"
|
||||
|
||||
static unsigned int ram_clocks[] = {
|
||||
CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
|
||||
#define DDR_HZ ram_clocks[ltq_cgu_r32(CGU_SYS) & 0x3]
|
||||
|
||||
/* legacy xway clock */
|
||||
#define CGU_SYS 0x10
|
||||
|
||||
/* vr9 clock */
|
||||
#define CGU_SYS_VR9 0x0c
|
||||
#define CGU_IF_CLK_VR9 0x24
|
||||
|
||||
unsigned long ltq_danube_fpi_hz(void)
|
||||
{
|
||||
unsigned long ddr_clock = DDR_HZ;
|
||||
|
||||
if (ltq_cgu_r32(CGU_SYS) & 0x40)
|
||||
return ddr_clock >> 1;
|
||||
return ddr_clock;
|
||||
}
|
||||
|
||||
unsigned long ltq_danube_cpu_hz(void)
|
||||
{
|
||||
switch (ltq_cgu_r32(CGU_SYS) & 0xc) {
|
||||
case 0:
|
||||
return CLOCK_333M;
|
||||
case 4:
|
||||
return DDR_HZ;
|
||||
case 8:
|
||||
return DDR_HZ << 1;
|
||||
default:
|
||||
return DDR_HZ >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long ltq_ar9_sys_hz(void)
|
||||
{
|
||||
if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2)
|
||||
return CLOCK_393M;
|
||||
return CLOCK_333M;
|
||||
}
|
||||
|
||||
unsigned long ltq_ar9_fpi_hz(void)
|
||||
{
|
||||
unsigned long sys = ltq_ar9_sys_hz();
|
||||
|
||||
if (ltq_cgu_r32(CGU_SYS) & BIT(0))
|
||||
return sys;
|
||||
return sys >> 1;
|
||||
}
|
||||
|
||||
unsigned long ltq_ar9_cpu_hz(void)
|
||||
{
|
||||
if (ltq_cgu_r32(CGU_SYS) & BIT(2))
|
||||
return ltq_ar9_fpi_hz();
|
||||
else
|
||||
return ltq_ar9_sys_hz();
|
||||
}
|
||||
|
||||
unsigned long ltq_vr9_cpu_hz(void)
|
||||
{
|
||||
unsigned int cpu_sel;
|
||||
unsigned long clk;
|
||||
|
||||
cpu_sel = (ltq_cgu_r32(CGU_SYS_VR9) >> 4) & 0xf;
|
||||
|
||||
switch (cpu_sel) {
|
||||
case 0:
|
||||
clk = CLOCK_600M;
|
||||
break;
|
||||
case 1:
|
||||
clk = CLOCK_500M;
|
||||
break;
|
||||
case 2:
|
||||
clk = CLOCK_393M;
|
||||
break;
|
||||
case 3:
|
||||
clk = CLOCK_333M;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
clk = CLOCK_196_608M;
|
||||
break;
|
||||
case 7:
|
||||
clk = CLOCK_167M;
|
||||
break;
|
||||
case 4:
|
||||
case 8:
|
||||
case 9:
|
||||
clk = CLOCK_125M;
|
||||
break;
|
||||
default:
|
||||
clk = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
unsigned long ltq_vr9_fpi_hz(void)
|
||||
{
|
||||
unsigned int ocp_sel, cpu_clk;
|
||||
unsigned long clk;
|
||||
|
||||
cpu_clk = ltq_vr9_cpu_hz();
|
||||
ocp_sel = ltq_cgu_r32(CGU_SYS_VR9) & 0x3;
|
||||
|
||||
switch (ocp_sel) {
|
||||
case 0:
|
||||
/* OCP ratio 1 */
|
||||
clk = cpu_clk;
|
||||
break;
|
||||
case 2:
|
||||
/* OCP ratio 2 */
|
||||
clk = cpu_clk / 2;
|
||||
break;
|
||||
case 3:
|
||||
/* OCP ratio 2.5 */
|
||||
clk = (cpu_clk * 2) / 5;
|
||||
break;
|
||||
case 4:
|
||||
/* OCP ratio 3 */
|
||||
clk = cpu_clk / 3;
|
||||
break;
|
||||
default:
|
||||
clk = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return clk;
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
#include <lantiq_irq.h>
|
||||
#include <lantiq_platform.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
/* gpio */
|
||||
static struct resource ltq_gpio_resource[] = {
|
||||
{
|
||||
.name = "gpio0",
|
||||
.start = LTQ_GPIO0_BASE_ADDR,
|
||||
.end = LTQ_GPIO0_BASE_ADDR + LTQ_GPIO_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.name = "gpio1",
|
||||
.start = LTQ_GPIO1_BASE_ADDR,
|
||||
.end = LTQ_GPIO1_BASE_ADDR + LTQ_GPIO_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.name = "gpio2",
|
||||
.start = LTQ_GPIO2_BASE_ADDR,
|
||||
.end = LTQ_GPIO2_BASE_ADDR + LTQ_GPIO_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
|
||||
void __init ltq_register_gpio(void)
|
||||
{
|
||||
platform_device_register_simple("ltq_gpio", 0,
|
||||
<q_gpio_resource[0], 1);
|
||||
platform_device_register_simple("ltq_gpio", 1,
|
||||
<q_gpio_resource[1], 1);
|
||||
|
||||
/* AR9 and VR9 have an extra gpio block */
|
||||
if (ltq_is_ar9() || ltq_is_vr9()) {
|
||||
platform_device_register_simple("ltq_gpio", 2,
|
||||
<q_gpio_resource[2], 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* serial to parallel conversion */
|
||||
static struct resource ltq_stp_resource = {
|
||||
.name = "stp",
|
||||
.start = LTQ_STP_BASE_ADDR,
|
||||
.end = LTQ_STP_BASE_ADDR + LTQ_STP_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
void __init ltq_register_gpio_stp(void)
|
||||
{
|
||||
platform_device_register_simple("ltq_stp", 0, <q_stp_resource, 1);
|
||||
}
|
||||
|
||||
/* asc ports - amazon se has its own serial mapping */
|
||||
static struct resource ltq_ase_asc_resources[] = {
|
||||
{
|
||||
.name = "asc0",
|
||||
.start = LTQ_ASC1_BASE_ADDR,
|
||||
.end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
IRQ_RES(tx, LTQ_ASC_ASE_TIR),
|
||||
IRQ_RES(rx, LTQ_ASC_ASE_RIR),
|
||||
IRQ_RES(err, LTQ_ASC_ASE_EIR),
|
||||
};
|
||||
|
||||
void __init ltq_register_ase_asc(void)
|
||||
{
|
||||
platform_device_register_simple("ltq_asc", 0,
|
||||
ltq_ase_asc_resources, ARRAY_SIZE(ltq_ase_asc_resources));
|
||||
}
|
||||
|
||||
/* ethernet */
|
||||
static struct resource ltq_etop_resources = {
|
||||
.name = "etop",
|
||||
.start = LTQ_ETOP_BASE_ADDR,
|
||||
.end = LTQ_ETOP_BASE_ADDR + LTQ_ETOP_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device ltq_etop = {
|
||||
.name = "ltq_etop",
|
||||
.resource = <q_etop_resources,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
void __init
|
||||
ltq_register_etop(struct ltq_eth_data *eth)
|
||||
{
|
||||
if (eth) {
|
||||
ltq_etop.dev.platform_data = eth;
|
||||
platform_device_register(<q_etop);
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#ifndef _LTQ_DEVICES_XWAY_H__
|
||||
#define _LTQ_DEVICES_XWAY_H__
|
||||
|
||||
#include "../devices.h"
|
||||
#include <linux/phy.h>
|
||||
|
||||
extern void ltq_register_gpio(void);
|
||||
extern void ltq_register_gpio_stp(void);
|
||||
extern void ltq_register_ase_asc(void);
|
||||
extern void ltq_register_etop(struct ltq_eth_data *eth);
|
||||
|
||||
#endif
|
@ -19,7 +19,8 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
#include <xway_dma.h>
|
||||
@ -55,13 +56,6 @@
|
||||
#define ltq_dma_w32_mask(x, y, z) ltq_w32_mask(x, y, \
|
||||
ltq_dma_membase + (z))
|
||||
|
||||
static struct resource ltq_dma_resource = {
|
||||
.name = "dma",
|
||||
.start = LTQ_DMA_BASE_ADDR,
|
||||
.end = LTQ_DMA_BASE_ADDR + LTQ_DMA_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static void __iomem *ltq_dma_membase;
|
||||
|
||||
void
|
||||
@ -215,27 +209,28 @@ ltq_dma_init_port(int p)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ltq_dma_init_port);
|
||||
|
||||
int __init
|
||||
ltq_dma_init(void)
|
||||
static int __devinit
|
||||
ltq_dma_init(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct resource *res;
|
||||
int i;
|
||||
|
||||
/* insert and request the memory region */
|
||||
if (insert_resource(&iomem_resource, <q_dma_resource) < 0)
|
||||
panic("Failed to insert dma memory");
|
||||
|
||||
if (request_mem_region(ltq_dma_resource.start,
|
||||
resource_size(<q_dma_resource), "dma") < 0)
|
||||
panic("Failed to request dma memory");
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
panic("Failed to get dma resource");
|
||||
|
||||
/* remap dma register range */
|
||||
ltq_dma_membase = ioremap_nocache(ltq_dma_resource.start,
|
||||
resource_size(<q_dma_resource));
|
||||
ltq_dma_membase = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (!ltq_dma_membase)
|
||||
panic("Failed to remap dma memory");
|
||||
panic("Failed to remap dma resource");
|
||||
|
||||
/* power up and reset the dma engine */
|
||||
ltq_pmu_enable(PMU_DMA);
|
||||
clk = clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(clk))
|
||||
panic("Failed to get dma clock");
|
||||
|
||||
clk_enable(clk);
|
||||
ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL);
|
||||
|
||||
/* disable all interrupts */
|
||||
@ -248,7 +243,29 @@ ltq_dma_init(void)
|
||||
ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL);
|
||||
ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
|
||||
}
|
||||
dev_info(&pdev->dev, "init done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
postcore_initcall(ltq_dma_init);
|
||||
static const struct of_device_id dma_match[] = {
|
||||
{ .compatible = "lantiq,dma-xway" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, dma_match);
|
||||
|
||||
static struct platform_driver dma_driver = {
|
||||
.probe = ltq_dma_init,
|
||||
.driver = {
|
||||
.name = "dma-xway",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = dma_match,
|
||||
},
|
||||
};
|
||||
|
||||
int __init
|
||||
dma_init(void)
|
||||
{
|
||||
return platform_driver_register(&dma_driver);
|
||||
}
|
||||
|
||||
postcore_initcall(dma_init);
|
||||
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* EBU - the external bus unit attaches PCI, NOR and NAND
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
/* all access to the ebu must be locked */
|
||||
DEFINE_SPINLOCK(ebu_lock);
|
||||
EXPORT_SYMBOL_GPL(ebu_lock);
|
||||
|
||||
static struct resource ltq_ebu_resource = {
|
||||
.name = "ebu",
|
||||
.start = LTQ_EBU_BASE_ADDR,
|
||||
.end = LTQ_EBU_BASE_ADDR + LTQ_EBU_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
/* remapped base addr of the clock unit and external bus unit */
|
||||
void __iomem *ltq_ebu_membase;
|
||||
|
||||
static int __init lantiq_ebu_init(void)
|
||||
{
|
||||
/* insert and request the memory region */
|
||||
if (insert_resource(&iomem_resource, <q_ebu_resource) < 0)
|
||||
panic("Failed to insert ebu memory");
|
||||
|
||||
if (request_mem_region(ltq_ebu_resource.start,
|
||||
resource_size(<q_ebu_resource), "ebu") < 0)
|
||||
panic("Failed to request ebu memory");
|
||||
|
||||
/* remap ebu register range */
|
||||
ltq_ebu_membase = ioremap_nocache(ltq_ebu_resource.start,
|
||||
resource_size(<q_ebu_resource));
|
||||
if (!ltq_ebu_membase)
|
||||
panic("Failed to remap ebu memory");
|
||||
|
||||
/* make sure to unprotect the memory region where flash is located */
|
||||
ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
postcore_initcall(lantiq_ebu_init);
|
@ -36,18 +36,6 @@ struct ltq_gpio {
|
||||
|
||||
static struct ltq_gpio ltq_gpio_port[MAX_PORTS];
|
||||
|
||||
int gpio_to_irq(unsigned int gpio)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_to_irq);
|
||||
|
||||
int irq_to_gpio(unsigned int gpio)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL(irq_to_gpio);
|
||||
|
||||
int ltq_gpio_request(unsigned int pin, unsigned int alt0,
|
||||
unsigned int alt1, unsigned int dir, const char *name)
|
||||
{
|
||||
|
@ -1,126 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
/*
|
||||
* By attaching hardware latches to the EBU it is possible to create output
|
||||
* only gpios. This driver configures a special memory address, which when
|
||||
* written to outputs 16 bit to the latches.
|
||||
*/
|
||||
|
||||
#define LTQ_EBU_BUSCON 0x1e7ff /* 16 bit access, slowest timing */
|
||||
#define LTQ_EBU_WP 0x80000000 /* write protect bit */
|
||||
|
||||
/* we keep a shadow value of the last value written to the ebu */
|
||||
static int ltq_ebu_gpio_shadow = 0x0;
|
||||
static void __iomem *ltq_ebu_gpio_membase;
|
||||
|
||||
static void ltq_ebu_apply(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ebu_lock, flags);
|
||||
ltq_ebu_w32(LTQ_EBU_BUSCON, LTQ_EBU_BUSCON1);
|
||||
*((__u16 *)ltq_ebu_gpio_membase) = ltq_ebu_gpio_shadow;
|
||||
ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1);
|
||||
spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
}
|
||||
|
||||
static void ltq_ebu_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
{
|
||||
if (value)
|
||||
ltq_ebu_gpio_shadow |= (1 << offset);
|
||||
else
|
||||
ltq_ebu_gpio_shadow &= ~(1 << offset);
|
||||
ltq_ebu_apply();
|
||||
}
|
||||
|
||||
static int ltq_ebu_direction_output(struct gpio_chip *chip, unsigned offset,
|
||||
int value)
|
||||
{
|
||||
ltq_ebu_set(chip, offset, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct gpio_chip ltq_ebu_chip = {
|
||||
.label = "ltq_ebu",
|
||||
.direction_output = ltq_ebu_direction_output,
|
||||
.set = ltq_ebu_set,
|
||||
.base = 72,
|
||||
.ngpio = 16,
|
||||
.can_sleep = 1,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int ltq_ebu_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "failed to get memory resource\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
res = devm_request_mem_region(&pdev->dev, res->start,
|
||||
resource_size(res), dev_name(&pdev->dev));
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "failed to request memory resource\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ltq_ebu_gpio_membase = devm_ioremap_nocache(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!ltq_ebu_gpio_membase) {
|
||||
dev_err(&pdev->dev, "Failed to ioremap mem region\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* grab the default shadow value passed form the platform code */
|
||||
ltq_ebu_gpio_shadow = (unsigned int) pdev->dev.platform_data;
|
||||
|
||||
/* tell the ebu controller which memory address we will be using */
|
||||
ltq_ebu_w32(pdev->resource->start | 0x1, LTQ_EBU_ADDRSEL1);
|
||||
|
||||
/* write protect the region */
|
||||
ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1);
|
||||
|
||||
ret = gpiochip_add(<q_ebu_chip);
|
||||
if (!ret)
|
||||
ltq_ebu_apply();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver ltq_ebu_driver = {
|
||||
.probe = ltq_ebu_probe,
|
||||
.driver = {
|
||||
.name = "ltq_ebu",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init ltq_ebu_init(void)
|
||||
{
|
||||
int ret = platform_driver_register(<q_ebu_driver);
|
||||
|
||||
if (ret)
|
||||
pr_info("ltq_ebu : Error registering platfom driver!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
postcore_initcall(ltq_ebu_init);
|
@ -1,157 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2007 John Crispin <blogic@openwrt.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#define LTQ_STP_CON0 0x00
|
||||
#define LTQ_STP_CON1 0x04
|
||||
#define LTQ_STP_CPU0 0x08
|
||||
#define LTQ_STP_CPU1 0x0C
|
||||
#define LTQ_STP_AR 0x10
|
||||
|
||||
#define LTQ_STP_CON_SWU (1 << 31)
|
||||
#define LTQ_STP_2HZ 0
|
||||
#define LTQ_STP_4HZ (1 << 23)
|
||||
#define LTQ_STP_8HZ (2 << 23)
|
||||
#define LTQ_STP_10HZ (3 << 23)
|
||||
#define LTQ_STP_SPEED_MASK (0xf << 23)
|
||||
#define LTQ_STP_UPD_FPI (1 << 31)
|
||||
#define LTQ_STP_UPD_MASK (3 << 30)
|
||||
#define LTQ_STP_ADSL_SRC (3 << 24)
|
||||
|
||||
#define LTQ_STP_GROUP0 (1 << 0)
|
||||
|
||||
#define LTQ_STP_RISING 0
|
||||
#define LTQ_STP_FALLING (1 << 26)
|
||||
#define LTQ_STP_EDGE_MASK (1 << 26)
|
||||
|
||||
#define ltq_stp_r32(reg) __raw_readl(ltq_stp_membase + reg)
|
||||
#define ltq_stp_w32(val, reg) __raw_writel(val, ltq_stp_membase + reg)
|
||||
#define ltq_stp_w32_mask(clear, set, reg) \
|
||||
ltq_w32((ltq_r32(ltq_stp_membase + reg) & ~(clear)) | (set), \
|
||||
ltq_stp_membase + (reg))
|
||||
|
||||
static int ltq_stp_shadow = 0xffff;
|
||||
static void __iomem *ltq_stp_membase;
|
||||
|
||||
static void ltq_stp_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
{
|
||||
if (value)
|
||||
ltq_stp_shadow |= (1 << offset);
|
||||
else
|
||||
ltq_stp_shadow &= ~(1 << offset);
|
||||
ltq_stp_w32(ltq_stp_shadow, LTQ_STP_CPU0);
|
||||
}
|
||||
|
||||
static int ltq_stp_direction_output(struct gpio_chip *chip, unsigned offset,
|
||||
int value)
|
||||
{
|
||||
ltq_stp_set(chip, offset, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct gpio_chip ltq_stp_chip = {
|
||||
.label = "ltq_stp",
|
||||
.direction_output = ltq_stp_direction_output,
|
||||
.set = ltq_stp_set,
|
||||
.base = 48,
|
||||
.ngpio = 24,
|
||||
.can_sleep = 1,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int ltq_stp_hw_init(void)
|
||||
{
|
||||
/* the 3 pins used to control the external stp */
|
||||
ltq_gpio_request(4, 1, 0, 1, "stp-st");
|
||||
ltq_gpio_request(5, 1, 0, 1, "stp-d");
|
||||
ltq_gpio_request(6, 1, 0, 1, "stp-sh");
|
||||
|
||||
/* sane defaults */
|
||||
ltq_stp_w32(0, LTQ_STP_AR);
|
||||
ltq_stp_w32(0, LTQ_STP_CPU0);
|
||||
ltq_stp_w32(0, LTQ_STP_CPU1);
|
||||
ltq_stp_w32(LTQ_STP_CON_SWU, LTQ_STP_CON0);
|
||||
ltq_stp_w32(0, LTQ_STP_CON1);
|
||||
|
||||
/* rising or falling edge */
|
||||
ltq_stp_w32_mask(LTQ_STP_EDGE_MASK, LTQ_STP_FALLING, LTQ_STP_CON0);
|
||||
|
||||
/* per default stp 15-0 are set */
|
||||
ltq_stp_w32_mask(0, LTQ_STP_GROUP0, LTQ_STP_CON1);
|
||||
|
||||
/* stp are update periodically by the FPI bus */
|
||||
ltq_stp_w32_mask(LTQ_STP_UPD_MASK, LTQ_STP_UPD_FPI, LTQ_STP_CON1);
|
||||
|
||||
/* set stp update speed */
|
||||
ltq_stp_w32_mask(LTQ_STP_SPEED_MASK, LTQ_STP_8HZ, LTQ_STP_CON1);
|
||||
|
||||
/* tell the hardware that pin (led) 0 and 1 are controlled
|
||||
* by the dsl arc
|
||||
*/
|
||||
ltq_stp_w32_mask(0, LTQ_STP_ADSL_SRC, LTQ_STP_CON0);
|
||||
|
||||
ltq_pmu_enable(PMU_LED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit ltq_stp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
int ret = 0;
|
||||
|
||||
if (!res)
|
||||
return -ENOENT;
|
||||
res = devm_request_mem_region(&pdev->dev, res->start,
|
||||
resource_size(res), dev_name(&pdev->dev));
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "failed to request STP memory\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
ltq_stp_membase = devm_ioremap_nocache(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!ltq_stp_membase) {
|
||||
dev_err(&pdev->dev, "failed to remap STP memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
ret = gpiochip_add(<q_stp_chip);
|
||||
if (!ret)
|
||||
ret = ltq_stp_hw_init();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver ltq_stp_driver = {
|
||||
.probe = ltq_stp_probe,
|
||||
.driver = {
|
||||
.name = "ltq_stp",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int __init ltq_stp_init(void)
|
||||
{
|
||||
int ret = platform_driver_register(<q_stp_driver);
|
||||
|
||||
if (ret)
|
||||
pr_info("ltq_stp: error registering platfom driver");
|
||||
return ret;
|
||||
}
|
||||
|
||||
postcore_initcall(ltq_stp_init);
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <lantiq.h>
|
||||
|
||||
#include "../machtypes.h"
|
||||
#include "devices.h"
|
||||
|
||||
static struct mtd_partition easy50601_partitions[] = {
|
||||
{
|
||||
.name = "uboot",
|
||||
.offset = 0x0,
|
||||
.size = 0x10000,
|
||||
},
|
||||
{
|
||||
.name = "uboot_env",
|
||||
.offset = 0x10000,
|
||||
.size = 0x10000,
|
||||
},
|
||||
{
|
||||
.name = "linux",
|
||||
.offset = 0x20000,
|
||||
.size = 0xE0000,
|
||||
},
|
||||
{
|
||||
.name = "rootfs",
|
||||
.offset = 0x100000,
|
||||
.size = 0x300000,
|
||||
},
|
||||
};
|
||||
|
||||
static struct physmap_flash_data easy50601_flash_data = {
|
||||
.nr_parts = ARRAY_SIZE(easy50601_partitions),
|
||||
.parts = easy50601_partitions,
|
||||
};
|
||||
|
||||
static void __init easy50601_init(void)
|
||||
{
|
||||
ltq_register_nor(&easy50601_flash_data);
|
||||
}
|
||||
|
||||
MIPS_MACHINE(LTQ_MACH_EASY50601,
|
||||
"EASY50601",
|
||||
"EASY50601 Eval Board",
|
||||
easy50601_init);
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
#include <irq.h>
|
||||
|
||||
#include "../machtypes.h"
|
||||
#include "devices.h"
|
||||
|
||||
static struct mtd_partition easy50712_partitions[] = {
|
||||
{
|
||||
.name = "uboot",
|
||||
.offset = 0x0,
|
||||
.size = 0x10000,
|
||||
},
|
||||
{
|
||||
.name = "uboot_env",
|
||||
.offset = 0x10000,
|
||||
.size = 0x10000,
|
||||
},
|
||||
{
|
||||
.name = "linux",
|
||||
.offset = 0x20000,
|
||||
.size = 0xe0000,
|
||||
},
|
||||
{
|
||||
.name = "rootfs",
|
||||
.offset = 0x100000,
|
||||
.size = 0x300000,
|
||||
},
|
||||
};
|
||||
|
||||
static struct physmap_flash_data easy50712_flash_data = {
|
||||
.nr_parts = ARRAY_SIZE(easy50712_partitions),
|
||||
.parts = easy50712_partitions,
|
||||
};
|
||||
|
||||
static struct ltq_pci_data ltq_pci_data = {
|
||||
.clock = PCI_CLOCK_INT,
|
||||
.gpio = PCI_GNT1 | PCI_REQ1,
|
||||
.irq = {
|
||||
[14] = INT_NUM_IM0_IRL0 + 22,
|
||||
},
|
||||
};
|
||||
|
||||
static struct ltq_eth_data ltq_eth_data = {
|
||||
.mii_mode = PHY_INTERFACE_MODE_MII,
|
||||
};
|
||||
|
||||
static void __init easy50712_init(void)
|
||||
{
|
||||
ltq_register_gpio_stp();
|
||||
ltq_register_nor(&easy50712_flash_data);
|
||||
ltq_register_pci(<q_pci_data);
|
||||
ltq_register_etop(<q_eth_data);
|
||||
}
|
||||
|
||||
MIPS_MACHINE(LTQ_MACH_EASY50712,
|
||||
"EASY50712",
|
||||
"EASY50712 Eval Board",
|
||||
easy50712_init);
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
/* PMU - the power management unit allows us to turn part of the core
|
||||
* on and off
|
||||
*/
|
||||
|
||||
/* the enable / disable registers */
|
||||
#define LTQ_PMU_PWDCR 0x1C
|
||||
#define LTQ_PMU_PWDSR 0x20
|
||||
|
||||
#define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y))
|
||||
#define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x))
|
||||
|
||||
static struct resource ltq_pmu_resource = {
|
||||
.name = "pmu",
|
||||
.start = LTQ_PMU_BASE_ADDR,
|
||||
.end = LTQ_PMU_BASE_ADDR + LTQ_PMU_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static void __iomem *ltq_pmu_membase;
|
||||
|
||||
void ltq_pmu_enable(unsigned int module)
|
||||
{
|
||||
int err = 1000000;
|
||||
|
||||
ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR);
|
||||
do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module));
|
||||
|
||||
if (!err)
|
||||
panic("activating PMU module failed!");
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_pmu_enable);
|
||||
|
||||
void ltq_pmu_disable(unsigned int module)
|
||||
{
|
||||
ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR);
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_pmu_disable);
|
||||
|
||||
int __init ltq_pmu_init(void)
|
||||
{
|
||||
if (insert_resource(&iomem_resource, <q_pmu_resource) < 0)
|
||||
panic("Failed to insert pmu memory");
|
||||
|
||||
if (request_mem_region(ltq_pmu_resource.start,
|
||||
resource_size(<q_pmu_resource), "pmu") < 0)
|
||||
panic("Failed to request pmu memory");
|
||||
|
||||
ltq_pmu_membase = ioremap_nocache(ltq_pmu_resource.start,
|
||||
resource_size(<q_pmu_resource));
|
||||
if (!ltq_pmu_membase)
|
||||
panic("Failed to remap pmu memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
core_initcall(ltq_pmu_init);
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/clk.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#include "../prom.h"
|
||||
|
||||
#define SOC_AMAZON_SE "Amazon_SE"
|
||||
|
||||
#define PART_SHIFT 12
|
||||
#define PART_MASK 0x0FFFFFFF
|
||||
#define REV_SHIFT 28
|
||||
#define REV_MASK 0xF0000000
|
||||
|
||||
void __init ltq_soc_detect(struct ltq_soc_info *i)
|
||||
{
|
||||
i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
|
||||
i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
|
||||
switch (i->partnum) {
|
||||
case SOC_ID_AMAZON_SE:
|
||||
i->name = SOC_AMAZON_SE;
|
||||
i->type = SOC_TYPE_AMAZON_SE;
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable();
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/clk.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#include "../prom.h"
|
||||
|
||||
#define SOC_DANUBE "Danube"
|
||||
#define SOC_TWINPASS "Twinpass"
|
||||
#define SOC_AR9 "AR9"
|
||||
|
||||
#define PART_SHIFT 12
|
||||
#define PART_MASK 0x0FFFFFFF
|
||||
#define REV_SHIFT 28
|
||||
#define REV_MASK 0xF0000000
|
||||
|
||||
void __init ltq_soc_detect(struct ltq_soc_info *i)
|
||||
{
|
||||
i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
|
||||
i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
|
||||
switch (i->partnum) {
|
||||
case SOC_ID_DANUBE1:
|
||||
case SOC_ID_DANUBE2:
|
||||
i->name = SOC_DANUBE;
|
||||
i->type = SOC_TYPE_DANUBE;
|
||||
break;
|
||||
|
||||
case SOC_ID_TWINPASS:
|
||||
i->name = SOC_TWINPASS;
|
||||
i->type = SOC_TYPE_DANUBE;
|
||||
break;
|
||||
|
||||
case SOC_ID_ARX188:
|
||||
case SOC_ID_ARX168:
|
||||
case SOC_ID_ARX182:
|
||||
i->name = SOC_AR9;
|
||||
i->type = SOC_TYPE_AR9;
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable();
|
||||
break;
|
||||
}
|
||||
}
|
115
arch/mips/lantiq/xway/prom.c
Normal file
115
arch/mips/lantiq/xway/prom.c
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/clk.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#include "../prom.h"
|
||||
|
||||
#define SOC_DANUBE "Danube"
|
||||
#define SOC_TWINPASS "Twinpass"
|
||||
#define SOC_AMAZON_SE "Amazon_SE"
|
||||
#define SOC_AR9 "AR9"
|
||||
#define SOC_GR9 "GR9"
|
||||
#define SOC_VR9 "VR9"
|
||||
|
||||
#define COMP_DANUBE "lantiq,danube"
|
||||
#define COMP_TWINPASS "lantiq,twinpass"
|
||||
#define COMP_AMAZON_SE "lantiq,ase"
|
||||
#define COMP_AR9 "lantiq,ar9"
|
||||
#define COMP_GR9 "lantiq,gr9"
|
||||
#define COMP_VR9 "lantiq,vr9"
|
||||
|
||||
#define PART_SHIFT 12
|
||||
#define PART_MASK 0x0FFFFFFF
|
||||
#define REV_SHIFT 28
|
||||
#define REV_MASK 0xF0000000
|
||||
|
||||
void __init ltq_soc_detect(struct ltq_soc_info *i)
|
||||
{
|
||||
i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
|
||||
i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
|
||||
sprintf(i->rev_type, "1.%d", i->rev);
|
||||
switch (i->partnum) {
|
||||
case SOC_ID_DANUBE1:
|
||||
case SOC_ID_DANUBE2:
|
||||
i->name = SOC_DANUBE;
|
||||
i->type = SOC_TYPE_DANUBE;
|
||||
i->compatible = COMP_DANUBE;
|
||||
break;
|
||||
|
||||
case SOC_ID_TWINPASS:
|
||||
i->name = SOC_TWINPASS;
|
||||
i->type = SOC_TYPE_DANUBE;
|
||||
i->compatible = COMP_TWINPASS;
|
||||
break;
|
||||
|
||||
case SOC_ID_ARX188:
|
||||
case SOC_ID_ARX168_1:
|
||||
case SOC_ID_ARX168_2:
|
||||
case SOC_ID_ARX182:
|
||||
i->name = SOC_AR9;
|
||||
i->type = SOC_TYPE_AR9;
|
||||
i->compatible = COMP_AR9;
|
||||
break;
|
||||
|
||||
case SOC_ID_GRX188:
|
||||
case SOC_ID_GRX168:
|
||||
i->name = SOC_GR9;
|
||||
i->type = SOC_TYPE_AR9;
|
||||
i->compatible = COMP_GR9;
|
||||
break;
|
||||
|
||||
case SOC_ID_AMAZON_SE_1:
|
||||
case SOC_ID_AMAZON_SE_2:
|
||||
#ifdef CONFIG_PCI
|
||||
panic("ase is only supported for non pci kernels");
|
||||
#endif
|
||||
i->name = SOC_AMAZON_SE;
|
||||
i->type = SOC_TYPE_AMAZON_SE;
|
||||
i->compatible = COMP_AMAZON_SE;
|
||||
break;
|
||||
|
||||
case SOC_ID_VRX282:
|
||||
case SOC_ID_VRX268:
|
||||
case SOC_ID_VRX288:
|
||||
i->name = SOC_VR9;
|
||||
i->type = SOC_TYPE_VR9;
|
||||
i->compatible = COMP_VR9;
|
||||
break;
|
||||
|
||||
case SOC_ID_GRX268:
|
||||
case SOC_ID_GRX288:
|
||||
i->name = SOC_GR9;
|
||||
i->type = SOC_TYPE_VR9;
|
||||
i->compatible = COMP_GR9;
|
||||
break;
|
||||
|
||||
case SOC_ID_VRX268_2:
|
||||
case SOC_ID_VRX288_2:
|
||||
i->name = SOC_VR9;
|
||||
i->type = SOC_TYPE_VR9_2;
|
||||
i->compatible = COMP_VR9;
|
||||
break;
|
||||
|
||||
case SOC_ID_GRX282_2:
|
||||
case SOC_ID_GRX288_2:
|
||||
i->name = SOC_GR9;
|
||||
i->type = SOC_TYPE_VR9_2;
|
||||
i->compatible = COMP_GR9;
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable();
|
||||
break;
|
||||
}
|
||||
}
|
@ -11,26 +11,31 @@
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/reboot.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#include "../prom.h"
|
||||
|
||||
#define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y))
|
||||
#define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x))
|
||||
|
||||
/* register definitions */
|
||||
#define LTQ_RCU_RST 0x0010
|
||||
#define LTQ_RCU_RST_ALL 0x40000000
|
||||
/* reset request register */
|
||||
#define RCU_RST_REQ 0x0010
|
||||
/* reset status register */
|
||||
#define RCU_RST_STAT 0x0014
|
||||
|
||||
#define LTQ_RCU_RST_STAT 0x0014
|
||||
#define LTQ_RCU_STAT_SHIFT 26
|
||||
|
||||
static struct resource ltq_rcu_resource = {
|
||||
.name = "rcu",
|
||||
.start = LTQ_RCU_BASE_ADDR,
|
||||
.end = LTQ_RCU_BASE_ADDR + LTQ_RCU_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
/* reboot bit */
|
||||
#define RCU_RD_SRST BIT(30)
|
||||
/* reset cause */
|
||||
#define RCU_STAT_SHIFT 26
|
||||
/* boot selection */
|
||||
#define RCU_BOOT_SEL_SHIFT 26
|
||||
#define RCU_BOOT_SEL_MASK 0x7
|
||||
|
||||
/* remapped base addr of the reset control unit */
|
||||
static void __iomem *ltq_rcu_membase;
|
||||
@ -38,48 +43,64 @@ static void __iomem *ltq_rcu_membase;
|
||||
/* This function is used by the watchdog driver */
|
||||
int ltq_reset_cause(void)
|
||||
{
|
||||
u32 val = ltq_rcu_r32(LTQ_RCU_RST_STAT);
|
||||
return val >> LTQ_RCU_STAT_SHIFT;
|
||||
u32 val = ltq_rcu_r32(RCU_RST_STAT);
|
||||
return val >> RCU_STAT_SHIFT;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ltq_reset_cause);
|
||||
|
||||
/* allow platform code to find out what source we booted from */
|
||||
unsigned char ltq_boot_select(void)
|
||||
{
|
||||
u32 val = ltq_rcu_r32(RCU_RST_STAT);
|
||||
return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK;
|
||||
}
|
||||
|
||||
/* reset a io domain for u micro seconds */
|
||||
void ltq_reset_once(unsigned int module, ulong u)
|
||||
{
|
||||
ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ);
|
||||
udelay(u);
|
||||
ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
|
||||
}
|
||||
|
||||
static void ltq_machine_restart(char *command)
|
||||
{
|
||||
pr_notice("System restart\n");
|
||||
local_irq_disable();
|
||||
ltq_rcu_w32(ltq_rcu_r32(LTQ_RCU_RST) | LTQ_RCU_RST_ALL, LTQ_RCU_RST);
|
||||
ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | RCU_RD_SRST, RCU_RST_REQ);
|
||||
unreachable();
|
||||
}
|
||||
|
||||
static void ltq_machine_halt(void)
|
||||
{
|
||||
pr_notice("System halted.\n");
|
||||
local_irq_disable();
|
||||
unreachable();
|
||||
}
|
||||
|
||||
static void ltq_machine_power_off(void)
|
||||
{
|
||||
pr_notice("Please turn off the power now.\n");
|
||||
local_irq_disable();
|
||||
unreachable();
|
||||
}
|
||||
|
||||
static int __init mips_reboot_setup(void)
|
||||
{
|
||||
/* insert and request the memory region */
|
||||
if (insert_resource(&iomem_resource, <q_rcu_resource) < 0)
|
||||
panic("Failed to insert rcu memory");
|
||||
struct resource res;
|
||||
struct device_node *np =
|
||||
of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway");
|
||||
|
||||
if (request_mem_region(ltq_rcu_resource.start,
|
||||
resource_size(<q_rcu_resource), "rcu") < 0)
|
||||
panic("Failed to request rcu memory");
|
||||
/* check if all the reset register range is available */
|
||||
if (!np)
|
||||
panic("Failed to load reset resources from devicetree");
|
||||
|
||||
/* remap rcu register range */
|
||||
ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start,
|
||||
resource_size(<q_rcu_resource));
|
||||
if (of_address_to_resource(np, 0, &res))
|
||||
panic("Failed to get rcu memory range");
|
||||
|
||||
if (request_mem_region(res.start, resource_size(&res), res.name) < 0)
|
||||
pr_err("Failed to request rcu memory");
|
||||
|
||||
ltq_rcu_membase = ioremap_nocache(res.start, resource_size(&res));
|
||||
if (!ltq_rcu_membase)
|
||||
panic("Failed to remap rcu memory");
|
||||
panic("Failed to remap core memory");
|
||||
|
||||
_machine_restart = ltq_machine_restart;
|
||||
_machine_halt = ltq_machine_halt;
|
||||
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2011 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#include "../prom.h"
|
||||
#include "devices.h"
|
||||
|
||||
void __init ltq_soc_setup(void)
|
||||
{
|
||||
ltq_register_ase_asc();
|
||||
ltq_register_gpio();
|
||||
ltq_register_wdt();
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2011 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#include "../prom.h"
|
||||
#include "devices.h"
|
||||
|
||||
void __init ltq_soc_setup(void)
|
||||
{
|
||||
ltq_register_asc(0);
|
||||
ltq_register_asc(1);
|
||||
ltq_register_gpio();
|
||||
ltq_register_wdt();
|
||||
}
|
371
arch/mips/lantiq/xway/sysctrl.c
Normal file
371
arch/mips/lantiq/xway/sysctrl.c
Normal file
@ -0,0 +1,371 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2011-2012 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#include "../clk.h"
|
||||
#include "../prom.h"
|
||||
|
||||
/* clock control register */
|
||||
#define CGU_IFCCR 0x0018
|
||||
/* system clock register */
|
||||
#define CGU_SYS 0x0010
|
||||
/* pci control register */
|
||||
#define CGU_PCICR 0x0034
|
||||
/* ephy configuration register */
|
||||
#define CGU_EPHY 0x10
|
||||
/* power control register */
|
||||
#define PMU_PWDCR 0x1C
|
||||
/* power status register */
|
||||
#define PMU_PWDSR 0x20
|
||||
/* power control register */
|
||||
#define PMU_PWDCR1 0x24
|
||||
/* power status register */
|
||||
#define PMU_PWDSR1 0x28
|
||||
/* power control register */
|
||||
#define PWDCR(x) ((x) ? (PMU_PWDCR1) : (PMU_PWDCR))
|
||||
/* power status register */
|
||||
#define PWDSR(x) ((x) ? (PMU_PWDSR1) : (PMU_PWDSR))
|
||||
|
||||
/* clock gates that we can en/disable */
|
||||
#define PMU_USB0_P BIT(0)
|
||||
#define PMU_PCI BIT(4)
|
||||
#define PMU_DMA BIT(5)
|
||||
#define PMU_USB0 BIT(6)
|
||||
#define PMU_ASC0 BIT(7)
|
||||
#define PMU_EPHY BIT(7) /* ase */
|
||||
#define PMU_SPI BIT(8)
|
||||
#define PMU_DFE BIT(9)
|
||||
#define PMU_EBU BIT(10)
|
||||
#define PMU_STP BIT(11)
|
||||
#define PMU_GPT BIT(12)
|
||||
#define PMU_AHBS BIT(13) /* vr9 */
|
||||
#define PMU_FPI BIT(14)
|
||||
#define PMU_AHBM BIT(15)
|
||||
#define PMU_ASC1 BIT(17)
|
||||
#define PMU_PPE_QSB BIT(18)
|
||||
#define PMU_PPE_SLL01 BIT(19)
|
||||
#define PMU_PPE_TC BIT(21)
|
||||
#define PMU_PPE_EMA BIT(22)
|
||||
#define PMU_PPE_DPLUM BIT(23)
|
||||
#define PMU_PPE_DPLUS BIT(24)
|
||||
#define PMU_USB1_P BIT(26)
|
||||
#define PMU_USB1 BIT(27)
|
||||
#define PMU_SWITCH BIT(28)
|
||||
#define PMU_PPE_TOP BIT(29)
|
||||
#define PMU_GPHY BIT(30)
|
||||
#define PMU_PCIE_CLK BIT(31)
|
||||
|
||||
#define PMU1_PCIE_PHY BIT(0)
|
||||
#define PMU1_PCIE_CTL BIT(1)
|
||||
#define PMU1_PCIE_PDI BIT(4)
|
||||
#define PMU1_PCIE_MSI BIT(5)
|
||||
|
||||
#define pmu_w32(x, y) ltq_w32((x), pmu_membase + (y))
|
||||
#define pmu_r32(x) ltq_r32(pmu_membase + (x))
|
||||
|
||||
static void __iomem *pmu_membase;
|
||||
void __iomem *ltq_cgu_membase;
|
||||
void __iomem *ltq_ebu_membase;
|
||||
|
||||
/* legacy function kept alive to ease clkdev transition */
|
||||
void ltq_pmu_enable(unsigned int module)
|
||||
{
|
||||
int err = 1000000;
|
||||
|
||||
pmu_w32(pmu_r32(PMU_PWDCR) & ~module, PMU_PWDCR);
|
||||
do {} while (--err && (pmu_r32(PMU_PWDSR) & module));
|
||||
|
||||
if (!err)
|
||||
panic("activating PMU module failed!");
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_pmu_enable);
|
||||
|
||||
/* legacy function kept alive to ease clkdev transition */
|
||||
void ltq_pmu_disable(unsigned int module)
|
||||
{
|
||||
pmu_w32(pmu_r32(PMU_PWDCR) | module, PMU_PWDCR);
|
||||
}
|
||||
EXPORT_SYMBOL(ltq_pmu_disable);
|
||||
|
||||
/* enable a hw clock */
|
||||
static int cgu_enable(struct clk *clk)
|
||||
{
|
||||
ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | clk->bits, CGU_IFCCR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* disable a hw clock */
|
||||
static void cgu_disable(struct clk *clk)
|
||||
{
|
||||
ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~clk->bits, CGU_IFCCR);
|
||||
}
|
||||
|
||||
/* enable a clock gate */
|
||||
static int pmu_enable(struct clk *clk)
|
||||
{
|
||||
int retry = 1000000;
|
||||
|
||||
pmu_w32(pmu_r32(PWDCR(clk->module)) & ~clk->bits,
|
||||
PWDCR(clk->module));
|
||||
do {} while (--retry && (pmu_r32(PWDSR(clk->module)) & clk->bits));
|
||||
|
||||
if (!retry)
|
||||
panic("activating PMU module failed!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* disable a clock gate */
|
||||
static void pmu_disable(struct clk *clk)
|
||||
{
|
||||
pmu_w32(pmu_r32(PWDCR(clk->module)) | clk->bits,
|
||||
PWDCR(clk->module));
|
||||
}
|
||||
|
||||
/* the pci enable helper */
|
||||
static int pci_enable(struct clk *clk)
|
||||
{
|
||||
unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR);
|
||||
/* set bus clock speed */
|
||||
if (of_machine_is_compatible("lantiq,ar9")) {
|
||||
ifccr &= ~0x1f00000;
|
||||
if (clk->rate == CLOCK_33M)
|
||||
ifccr |= 0xe00000;
|
||||
else
|
||||
ifccr |= 0x700000; /* 62.5M */
|
||||
} else {
|
||||
ifccr &= ~0xf00000;
|
||||
if (clk->rate == CLOCK_33M)
|
||||
ifccr |= 0x800000;
|
||||
else
|
||||
ifccr |= 0x400000; /* 62.5M */
|
||||
}
|
||||
ltq_cgu_w32(ifccr, CGU_IFCCR);
|
||||
pmu_enable(clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* enable the external clock as a source */
|
||||
static int pci_ext_enable(struct clk *clk)
|
||||
{
|
||||
ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~(1 << 16),
|
||||
CGU_IFCCR);
|
||||
ltq_cgu_w32((1 << 30), CGU_PCICR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* disable the external clock as a source */
|
||||
static void pci_ext_disable(struct clk *clk)
|
||||
{
|
||||
ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | (1 << 16),
|
||||
CGU_IFCCR);
|
||||
ltq_cgu_w32((1 << 31) | (1 << 30), CGU_PCICR);
|
||||
}
|
||||
|
||||
/* enable a clockout source */
|
||||
static int clkout_enable(struct clk *clk)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* get the correct rate */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (clk->rates[i] == clk->rate) {
|
||||
int shift = 14 - (2 * clk->module);
|
||||
unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR);
|
||||
|
||||
ifccr &= ~(3 << shift);
|
||||
ifccr |= i << shift;
|
||||
ltq_cgu_w32(ifccr, CGU_IFCCR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* manage the clock gates via PMU */
|
||||
static void clkdev_add_pmu(const char *dev, const char *con,
|
||||
unsigned int module, unsigned int bits)
|
||||
{
|
||||
struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
|
||||
|
||||
clk->cl.dev_id = dev;
|
||||
clk->cl.con_id = con;
|
||||
clk->cl.clk = clk;
|
||||
clk->enable = pmu_enable;
|
||||
clk->disable = pmu_disable;
|
||||
clk->module = module;
|
||||
clk->bits = bits;
|
||||
clkdev_add(&clk->cl);
|
||||
}
|
||||
|
||||
/* manage the clock generator */
|
||||
static void clkdev_add_cgu(const char *dev, const char *con,
|
||||
unsigned int bits)
|
||||
{
|
||||
struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
|
||||
|
||||
clk->cl.dev_id = dev;
|
||||
clk->cl.con_id = con;
|
||||
clk->cl.clk = clk;
|
||||
clk->enable = cgu_enable;
|
||||
clk->disable = cgu_disable;
|
||||
clk->bits = bits;
|
||||
clkdev_add(&clk->cl);
|
||||
}
|
||||
|
||||
/* pci needs its own enable function as the setup is a bit more complex */
|
||||
static unsigned long valid_pci_rates[] = {CLOCK_33M, CLOCK_62_5M, 0};
|
||||
|
||||
static void clkdev_add_pci(void)
|
||||
{
|
||||
struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
|
||||
struct clk *clk_ext = kzalloc(sizeof(struct clk), GFP_KERNEL);
|
||||
|
||||
/* main pci clock */
|
||||
clk->cl.dev_id = "17000000.pci";
|
||||
clk->cl.con_id = NULL;
|
||||
clk->cl.clk = clk;
|
||||
clk->rate = CLOCK_33M;
|
||||
clk->rates = valid_pci_rates;
|
||||
clk->enable = pci_enable;
|
||||
clk->disable = pmu_disable;
|
||||
clk->module = 0;
|
||||
clk->bits = PMU_PCI;
|
||||
clkdev_add(&clk->cl);
|
||||
|
||||
/* use internal/external bus clock */
|
||||
clk_ext->cl.dev_id = "17000000.pci";
|
||||
clk_ext->cl.con_id = "external";
|
||||
clk_ext->cl.clk = clk_ext;
|
||||
clk_ext->enable = pci_ext_enable;
|
||||
clk_ext->disable = pci_ext_disable;
|
||||
clkdev_add(&clk_ext->cl);
|
||||
}
|
||||
|
||||
/* xway socs can generate clocks on gpio pins */
|
||||
static unsigned long valid_clkout_rates[4][5] = {
|
||||
{CLOCK_32_768K, CLOCK_1_536M, CLOCK_2_5M, CLOCK_12M, 0},
|
||||
{CLOCK_40M, CLOCK_12M, CLOCK_24M, CLOCK_48M, 0},
|
||||
{CLOCK_25M, CLOCK_40M, CLOCK_30M, CLOCK_60M, 0},
|
||||
{CLOCK_12M, CLOCK_50M, CLOCK_32_768K, CLOCK_25M, 0},
|
||||
};
|
||||
|
||||
static void clkdev_add_clkout(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
struct clk *clk;
|
||||
char *name;
|
||||
|
||||
name = kzalloc(sizeof("clkout0"), GFP_KERNEL);
|
||||
sprintf(name, "clkout%d", i);
|
||||
|
||||
clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
|
||||
clk->cl.dev_id = "1f103000.cgu";
|
||||
clk->cl.con_id = name;
|
||||
clk->cl.clk = clk;
|
||||
clk->rate = 0;
|
||||
clk->rates = valid_clkout_rates[i];
|
||||
clk->enable = clkout_enable;
|
||||
clk->module = i;
|
||||
clkdev_add(&clk->cl);
|
||||
}
|
||||
}
|
||||
|
||||
/* bring up all register ranges that we need for basic system control */
|
||||
void __init ltq_soc_init(void)
|
||||
{
|
||||
struct resource res_pmu, res_cgu, res_ebu;
|
||||
struct device_node *np_pmu =
|
||||
of_find_compatible_node(NULL, NULL, "lantiq,pmu-xway");
|
||||
struct device_node *np_cgu =
|
||||
of_find_compatible_node(NULL, NULL, "lantiq,cgu-xway");
|
||||
struct device_node *np_ebu =
|
||||
of_find_compatible_node(NULL, NULL, "lantiq,ebu-xway");
|
||||
|
||||
/* check if all the core register ranges are available */
|
||||
if (!np_pmu || !np_cgu || !np_ebu)
|
||||
panic("Failed to load core nodess from devicetree");
|
||||
|
||||
if (of_address_to_resource(np_pmu, 0, &res_pmu) ||
|
||||
of_address_to_resource(np_cgu, 0, &res_cgu) ||
|
||||
of_address_to_resource(np_ebu, 0, &res_ebu))
|
||||
panic("Failed to get core resources");
|
||||
|
||||
if ((request_mem_region(res_pmu.start, resource_size(&res_pmu),
|
||||
res_pmu.name) < 0) ||
|
||||
(request_mem_region(res_cgu.start, resource_size(&res_cgu),
|
||||
res_cgu.name) < 0) ||
|
||||
(request_mem_region(res_ebu.start, resource_size(&res_ebu),
|
||||
res_ebu.name) < 0))
|
||||
pr_err("Failed to request core reources");
|
||||
|
||||
pmu_membase = ioremap_nocache(res_pmu.start, resource_size(&res_pmu));
|
||||
ltq_cgu_membase = ioremap_nocache(res_cgu.start,
|
||||
resource_size(&res_cgu));
|
||||
ltq_ebu_membase = ioremap_nocache(res_ebu.start,
|
||||
resource_size(&res_ebu));
|
||||
if (!pmu_membase || !ltq_cgu_membase || !ltq_ebu_membase)
|
||||
panic("Failed to remap core resources");
|
||||
|
||||
/* make sure to unprotect the memory region where flash is located */
|
||||
ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
|
||||
|
||||
/* add our generic xway clocks */
|
||||
clkdev_add_pmu("10000000.fpi", NULL, 0, PMU_FPI);
|
||||
clkdev_add_pmu("1e100400.serial", NULL, 0, PMU_ASC0);
|
||||
clkdev_add_pmu("1e100a00.gptu", NULL, 0, PMU_GPT);
|
||||
clkdev_add_pmu("1e100bb0.stp", NULL, 0, PMU_STP);
|
||||
clkdev_add_pmu("1e104100.dma", NULL, 0, PMU_DMA);
|
||||
clkdev_add_pmu("1e100800.spi", NULL, 0, PMU_SPI);
|
||||
clkdev_add_pmu("1e105300.ebu", NULL, 0, PMU_EBU);
|
||||
clkdev_add_clkout();
|
||||
|
||||
/* add the soc dependent clocks */
|
||||
if (!of_machine_is_compatible("lantiq,vr9"))
|
||||
clkdev_add_pmu("1e180000.etop", NULL, 0, PMU_PPE);
|
||||
|
||||
if (!of_machine_is_compatible("lantiq,ase")) {
|
||||
clkdev_add_pmu("1e100c00.serial", NULL, 0, PMU_ASC1);
|
||||
clkdev_add_pci();
|
||||
}
|
||||
|
||||
if (of_machine_is_compatible("lantiq,ase")) {
|
||||
if (ltq_cgu_r32(CGU_SYS) & (1 << 5))
|
||||
clkdev_add_static(CLOCK_266M, CLOCK_133M, CLOCK_133M);
|
||||
else
|
||||
clkdev_add_static(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());
|
||||
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);
|
||||
clkdev_add_pmu("1d900000.pcie", "pdi", 1, PMU1_PCIE_PDI);
|
||||
clkdev_add_pmu("1d900000.pcie", "ctl", 1, PMU1_PCIE_CTL);
|
||||
clkdev_add_pmu("1d900000.pcie", "ahb", 0, PMU_AHBM | PMU_AHBS);
|
||||
} else if (of_machine_is_compatible("lantiq,ar9")) {
|
||||
clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
|
||||
ltq_ar9_fpi_hz());
|
||||
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());
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/r4kcache.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/war.h>
|
||||
|
||||
@ -248,6 +249,11 @@ static void __cpuinit probe_octeon(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void __cpuinit octeon_cache_error_setup(void)
|
||||
{
|
||||
extern char except_vec2_octeon;
|
||||
set_handler(0x100, &except_vec2_octeon, 0x80);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the Octeon cache flush routines
|
||||
@ -255,12 +261,6 @@ static void __cpuinit probe_octeon(void)
|
||||
*/
|
||||
void __cpuinit octeon_cache_init(void)
|
||||
{
|
||||
extern unsigned long ebase;
|
||||
extern char except_vec2_octeon;
|
||||
|
||||
memcpy((void *)(ebase + 0x100), &except_vec2_octeon, 0x80);
|
||||
octeon_flush_cache_sigtramp(ebase + 0x100);
|
||||
|
||||
probe_octeon();
|
||||
|
||||
shm_align_mask = PAGE_SIZE - 1;
|
||||
@ -280,6 +280,8 @@ void __cpuinit octeon_cache_init(void)
|
||||
|
||||
build_clear_page();
|
||||
build_copy_page();
|
||||
|
||||
board_cache_error_setup = octeon_cache_error_setup;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/war.h>
|
||||
#include <asm/cacheflush.h> /* for run_uncached() */
|
||||
|
||||
#include <asm/traps.h>
|
||||
|
||||
/*
|
||||
* Special Variant of smp_call_function for use by cache functions:
|
||||
@ -1385,10 +1385,8 @@ static int __init setcoherentio(char *str)
|
||||
__setup("coherentio", setcoherentio);
|
||||
#endif
|
||||
|
||||
void __cpuinit r4k_cache_init(void)
|
||||
static void __cpuinit r4k_cache_error_setup(void)
|
||||
{
|
||||
extern void build_clear_page(void);
|
||||
extern void build_copy_page(void);
|
||||
extern char __weak except_vec2_generic;
|
||||
extern char __weak except_vec2_sb1;
|
||||
struct cpuinfo_mips *c = ¤t_cpu_data;
|
||||
@ -1403,6 +1401,13 @@ void __cpuinit r4k_cache_init(void)
|
||||
set_uncached_handler(0x100, &except_vec2_generic, 0x80);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void __cpuinit r4k_cache_init(void)
|
||||
{
|
||||
extern void build_clear_page(void);
|
||||
extern void build_copy_page(void);
|
||||
struct cpuinfo_mips *c = ¤t_cpu_data;
|
||||
|
||||
probe_pcache();
|
||||
setup_scache();
|
||||
@ -1465,4 +1470,5 @@ void __cpuinit r4k_cache_init(void)
|
||||
local_r4k___flush_cache_all(NULL);
|
||||
#endif
|
||||
coherency_setup();
|
||||
board_cache_error_setup = r4k_cache_error_setup;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user