dect
/
linux-2.6
Archived
13
0
Fork 0

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus

Pull MIPS updates from Ralf Baechle:
 "The whole series has been sitting in -next for quite a while with no
  complaints.  The last change to the series was before the weekend the
  removal of an SPI patch which Grant - even though previously acked by
  himself - appeared to raise objections.  So I removed it until the
  situation is clarified.  Other than that all the patches have the acks
  from their respective maintainers, all MIPS and x86 defconfigs are
  building fine and I'm not aware of any problems introduced by this
  series.

  Among the key features for this patch series is a sizable patchset for
  Lantiq which among other things introduces support for Lantiq's
  flagship product, the FALCON SOC.  It also means that the opensource
  developers behind this patchset have overtaken Lantiq's competing
  inhouse development team that was working behind closed doors.

  Less noteworthy the ath79 patchset which adds support for a few more
  chip variants, cleanups and fixes.  Finally the usual dose of tweaking
  of generic code."

Fix up trivial conflicts in arch/mips/lantiq/xway/gpio_{ebu,stp}.c where
printk spelling fixes clashed with file move and eventual removal of the
printk.

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (81 commits)
  MIPS: lantiq: remove orphaned code
  MIPS: Remove all -Wall and almost all -Werror usage from arch/mips.
  MIPS: lantiq: implement support for FALCON soc
  MTD: MIPS: lantiq: verify that the NOR interface is available on falcon soc
  MTD: MIPS: lantiq: implement OF support
  watchdog: MIPS: lantiq: implement OF support and minor fixes
  SERIAL: MIPS: lantiq: implement OF support
  GPIO: MIPS: lantiq: convert gpio-stp-xway to OF
  GPIO: MIPS: lantiq: convert gpio-mm-lantiq to OF and of_mm_gpio
  GPIO: MIPS: lantiq: move gpio-stp and gpio-ebu to the subsystem folder
  MIPS: pci: convert lantiq driver to OF
  MIPS: lantiq: convert dma to platform driver
  MIPS: lantiq: implement support for clkdev api
  MIPS: lantiq: drop ltq_gpio_request() and gpio_to_irq()
  OF: MIPS: lantiq: implement irq_domain support
  OF: MIPS: lantiq: implement OF support
  MIPS: lantiq: drop mips_machine support
  OF: PCI: const usage needed by MIPS
  MIPS: Cavium: Remove smp_reserve_lock.
  MIPS: Move cache setup to setup_arch().
  ...
This commit is contained in:
Linus Torvalds 2012-05-29 18:27:19 -07:00
commit 7e5b2db77b
133 changed files with 4509 additions and 3741 deletions

View 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>
};
}

View 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; */
};

View File

@ -233,8 +233,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"
@ -1783,10 +1784,12 @@ endchoice
config FORCE_MAX_ZONEORDER
int "Maximum zone order"
range 13 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
default "13" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
range 12 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
default "12" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
range 14 64 if HUGETLB_PAGE && PAGE_SIZE_64KB
default "14" if HUGETLB_PAGE && PAGE_SIZE_64KB
range 13 64 if HUGETLB_PAGE && PAGE_SIZE_32KB
default "13" if HUGETLB_PAGE && PAGE_SIZE_32KB
range 12 64 if HUGETLB_PAGE && PAGE_SIZE_16KB
default "12" if HUGETLB_PAGE && PAGE_SIZE_16KB
range 11 64
default "11"
help

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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();

View File

@ -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()) {

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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)

View File

@ -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();
}

View 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);

View File

@ -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",

View File

@ -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,

View File

@ -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
View 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
View 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 */

View File

@ -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);
}

View File

@ -1,3 +1 @@
obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o
ccflags-y := -Werror

View File

@ -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>

View File

@ -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;
}

View File

@ -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

View 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

View File

@ -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 */

View File

@ -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;

View File

@ -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)

View File

@ -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 */

View 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 */

View File

@ -2,6 +2,7 @@
#define BCM63XX_GPIO_H
#include <linux/init.h>
#include <bcm63xx_cpu.h>
int __init bcm63xx_gpio_init(void);

View 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__ */

View 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

View 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__ */

View 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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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__ */

View File

@ -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 */

View File

@ -2,6 +2,7 @@
#define _ASM_MODULE_H
#include <linux/list.h>
#include <linux/elf.h>
#include <asm/uaccess.h>
struct mod_arch_specific {

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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 */

View File

@ -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__ */

View File

@ -6,7 +6,11 @@
* SECTION_SIZE_BITS 2^N: how big each section will be
* MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space
*/
#define SECTION_SIZE_BITS 28
#if defined(CONFIG_HUGETLB_PAGE) && defined(CONFIG_PAGE_SIZE_64KB)
# define SECTION_SIZE_BITS 29
#else
# define SECTION_SIZE_BITS 28
#endif
#define MAX_PHYSMEM_BITS 35
#endif /* CONFIG_SPARSEMEM */

View File

@ -60,7 +60,7 @@ struct termio {
};
#ifdef __KERNEL__
#include <linux/module.h>
#include <asm/uaccess.h>
/*
* intr=^C quit=^\ erase=del kill=^U

View File

@ -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);

View File

@ -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)

View File

@ -16,5 +16,3 @@ obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
# PM support
obj-$(CONFIG_PM) += pm.o
ccflags-y := -Werror -Wall

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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);
}

View File

@ -605,6 +605,8 @@ void __init setup_arch(char **cmdline_p)
resource_init();
plat_smp_setup();
cpu_cache_init();
}
unsigned long kernelsp[NR_CPUS];

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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/

View File

@ -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

View File

@ -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, &ltq_cgu_resource) < 0)
panic("Failed to insert cgu memory");
ltq_soc_init();
if (request_mem_region(ltq_cgu_resource.start,
resource_size(&ltq_cgu_resource), "cgu") < 0)
panic("Failed to request cgu memory");
ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
resource_size(&ltq_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);
}

View File

@ -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

View File

@ -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 = &ltq_nor_resource,
.num_resources = 1,
};
void __init ltq_register_nor(struct physmap_flash_data *data)
{
ltq_nor.dev.platform_data = data;
platform_device_register(&ltq_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, &ltq_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(&ltq_pci);
}
#else
void __init ltq_register_pci(struct ltq_pci_data *data)
{
pr_err("kernel is compiled without PCI support\n");
}
#endif

View File

@ -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

View File

@ -0,0 +1,4 @@
obj-$(CONFIG_DT_EASY50712) := easy50712.dtb.o
$(obj)/%.dtb: $(obj)/%.dts
$(call if_changed,dtc)

View 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 */
};
};
};

View 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 */
};
};
};

View File

@ -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);
}

View File

@ -0,0 +1 @@
obj-y := prom.o reset.o sysctrl.o

View 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;
}
}

View 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);

View 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);
}

View File

@ -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 = &ltq_irq_type;
int i;
for (i = 0; i < exin_avail; i++)
if (hw == ltq_eiu_irq[i])
chip = &ltq_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, &ltq_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(&ltq_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(&ltq_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, &ltq_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(&ltq_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(&ltq_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, &ltq_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, &ltq_eiu_type,
handle_level_irq);
else
irq_set_chip_and_handler(i, &ltq_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);
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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
View 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;
}

View File

@ -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,
&ltq_gpio_resource[0], 1);
platform_device_register_simple("ltq_gpio", 1,
&ltq_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,
&ltq_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, &ltq_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 = &ltq_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(&ltq_etop);
}
}

View File

@ -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

View File

@ -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, &ltq_dma_resource) < 0)
panic("Failed to insert dma memory");
if (request_mem_region(ltq_dma_resource.start,
resource_size(&ltq_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(&ltq_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);

View File

@ -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, &ltq_ebu_resource) < 0)
panic("Failed to insert ebu memory");
if (request_mem_region(ltq_ebu_resource.start,
resource_size(&ltq_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(&ltq_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);

View File

@ -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)
{

View File

@ -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(&ltq_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(&ltq_ebu_driver);
if (ret)
pr_info("ltq_ebu : Error registering platform driver!");
return ret;
}
postcore_initcall(ltq_ebu_init);

View File

@ -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(&ltq_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(&ltq_stp_driver);
if (ret)
pr_info("ltq_stp: error registering platform driver");
return ret;
}
postcore_initcall(ltq_stp_init);

View File

@ -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);

View File

@ -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(&ltq_pci_data);
ltq_register_etop(&ltq_eth_data);
}
MIPS_MACHINE(LTQ_MACH_EASY50712,
"EASY50712",
"EASY50712 Eval Board",
easy50712_init);

View File

@ -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, &ltq_pmu_resource) < 0)
panic("Failed to insert pmu memory");
if (request_mem_region(ltq_pmu_resource.start,
resource_size(&ltq_pmu_resource), "pmu") < 0)
panic("Failed to request pmu memory");
ltq_pmu_membase = ioremap_nocache(ltq_pmu_resource.start,
resource_size(&ltq_pmu_resource));
if (!ltq_pmu_membase)
panic("Failed to remap pmu memory");
return 0;
}
core_initcall(ltq_pmu_init);

View File

@ -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;
}
}

View File

@ -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;
}
}

View 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;
}
}

View File

@ -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, &ltq_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(&ltq_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(&ltq_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;

View File

@ -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();
}

View File

@ -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();
}

Some files were not shown because too many files have changed in this diff Show More