Commit 5a7d8a28 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull MIPS updates from Ralf Baechle:
 "This has been sitting in -next for a while with no objections and all
  MIPS defconfigs except one are building fine; that one platform got
  broken by another patch in your tree and I'm going to submit a patch
  separately.

   - a handful of fixes that didn't make 3.11
   - a few bits of Octeon 3 support with more to come for a later
     release
   - platform enhancements for Octeon, ath79, Lantiq, Netlogic and
     Ralink SOCs
   - a GPIO driver for the Octeon
   - some dusting off of the DECstation code
   - the usual dose of cleanups"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (65 commits)
  MIPS: DMA: Fix BUG due to smp_processor_id() in preemptible code
  MIPS: kexec: Fix random crashes while loading crashkernel
  MIPS: kdump: Skip walking indirection page for crashkernels
  MIPS: DECstation HRT calibration bug fixes
  MIPS: Export copy_from_user_page() (needed by lustre)
  MIPS: Add driver for the built-in PCI controller of the RT3883 SoC
  MIPS: DMA: For BMIPS5000 cores flush region just like non-coherent R10000
  MIPS: ralink: Add support for reset-controller API
  MIPS: ralink: mt7620: Add cpu-feature-override header
  MIPS: ralink: mt7620: Add spi clock definition
  MIPS: ralink: mt7620: Add wdt clock definition
  MIPS: ralink: mt7620: Improve clock frequency detection
  MIPS: ralink: mt7620: This SoC has EHCI and OHCI hosts
  MIPS: ralink: mt7620: Add verbose ram info
  MIPS: ralink: Probe clocksources from OF
  MIPS: ralink: Add support for systick timer found on newer ralink SoC
  MIPS: ralink: Add support for periodic timer irq
  MIPS: Netlogic: Built-in DTB for XLP2xx SoC boards
  MIPS: Netlogic: Add support for USB on XLP2xx
  MIPS: Netlogic: XLP2xx update for I2C controller
  ...
parents e0ea4045 eb37e6dd
* Mediatek/Ralink RT3883 PCI controller
1) Main node
Required properties:
- compatible: must be "ralink,rt3883-pci"
- reg: specifies the physical base address of the controller and
the length of the memory mapped region.
- #address-cells: specifies the number of cells needed to encode an
address. The value must be 1.
- #size-cells: specifies the number of cells used to represent the size
of an address. The value must be 1.
- ranges: specifies the translation between child address space and parent
address space
Optional properties:
- status: indicates the operational status of the device.
Value must be either "disabled" or "okay".
2) Child nodes
The main node must have two child nodes which describes the built-in
interrupt controller and the PCI host bridge.
a) Interrupt controller:
Required properties:
- interrupt-controller: identifies the node as an interrupt controller
- #address-cells: specifies the number of cells needed to encode an
address. The value must be 0. As such, 'interrupt-map' nodes do not
have to specify a parent unit address.
- #interrupt-cells: specifies the number of cells needed to encode an
interrupt source. The value must be 1.
- interrupt-parent: the phandle for the interrupt controller that
services interrupts for this device.
- interrupts: specifies the interrupt source of the parent interrupt
controller. The format of the interrupt specifier depends on the
parent interrupt controller.
b) PCI host bridge:
Required properties:
- #address-cells: specifies the number of cells needed to encode an
address. The value must be 0.
- #size-cells: specifies the number of cells used to represent the size
of an address. The value must be 2.
- #interrupt-cells: specifies the number of cells needed to encode an
interrupt source. The value must be 1.
- device_type: must be "pci"
- bus-range: PCI bus numbers covered
- ranges: specifies the ranges for the PCI memory and I/O regions
- interrupt-map-mask,
- interrupt-map: standard PCI properties to define the mapping of the
PCI interface to interrupt numbers.
The PCI host bridge node migh have additional sub-nodes representing
the onboard PCI devices/PCI slots. Each such sub-node must have the
following mandatory properties:
- reg: used only for interrupt mapping, so only the first four bytes
are used to refer to the correct bus number and device number.
- device_type: must be "pci"
If a given sub-node represents a PCI bridge it must have following
mandatory properties as well:
- #address-cells: must be set to <3>
- #size-cells: must set to <2>
- #interrupt-cells: must be set to <1>
- interrupt-map-mask,
- interrupt-map: standard PCI properties to define the mapping of the
PCI interface to interrupt numbers.
Besides the required properties the sub-nodes may have these optional
properties:
- status: indicates the operational status of the sub-node.
Value must be either "disabled" or "okay".
3) Example:
a) SoC specific dtsi file:
pci@10140000 {
compatible = "ralink,rt3883-pci";
reg = <0x10140000 0x20000>;
#address-cells = <1>;
#size-cells = <1>;
ranges; /* direct mapping */
status = "disabled";
pciintc: interrupt-controller {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
interrupt-parent = <&cpuintc>;
interrupts = <4>;
};
host-bridge {
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
device_type = "pci";
bus-range = <0 255>;
ranges = <
0x02000000 0 0x00000000 0x20000000 0 0x10000000 /* pci memory */
0x01000000 0 0x00000000 0x10160000 0 0x00010000 /* io space */
>;
interrupt-map-mask = <0xf800 0 0 7>;
interrupt-map = <
/* IDSEL 17 */
0x8800 0 0 1 &pciintc 18
0x8800 0 0 2 &pciintc 18
0x8800 0 0 3 &pciintc 18
0x8800 0 0 4 &pciintc 18
/* IDSEL 18 */
0x9000 0 0 1 &pciintc 19
0x9000 0 0 2 &pciintc 19
0x9000 0 0 3 &pciintc 19
0x9000 0 0 4 &pciintc 19
>;
pci-bridge@1 {
reg = <0x0800 0 0 0 0>;
device_type = "pci";
#interrupt-cells = <1>;
#address-cells = <3>;
#size-cells = <2>;
interrupt-map-mask = <0x0 0 0 0>;
interrupt-map = <0x0 0 0 0 &pciintc 20>;
status = "disabled";
};
pci-slot@17 {
reg = <0x8800 0 0 0 0>;
device_type = "pci";
status = "disabled";
};
pci-slot@18 {
reg = <0x9000 0 0 0 0>;
device_type = "pci";
status = "disabled";
};
};
};
b) Board specific dts file:
pci@10140000 {
status = "okay";
host-bridge {
pci-bridge@1 {
status = "okay";
};
};
};
......@@ -95,6 +95,7 @@ config ATH79
select CSRC_R4K
select DMA_NONCOHERENT
select HAVE_CLK
select CLKDEV_LOOKUP
select IRQ_CPU
select MIPS_MACHINE
select SYS_HAS_CPU_MIPS32_R2
......@@ -131,7 +132,6 @@ config BCM63XX
select IRQ_CPU
select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_BMIPS4350 if !BCM63XX_CPU_6338 && !BCM63XX_CPU_6345 && !BCM63XX_CPU_6348
select NR_CPUS_DEFAULT_2
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_HAS_EARLY_PRINTK
......@@ -445,6 +445,8 @@ config RALINK
select SYS_HAS_EARLY_PRINTK
select HAVE_MACH_CLKDEV
select CLKDEV_LOOKUP
select ARCH_HAS_RESET_CONTROLLER
select RESET_CONTROLLER
config SGI_IP22
bool "SGI IP22 (Indy/Indigo2)"
......@@ -609,7 +611,6 @@ config SIBYTE_SWARM
select BOOT_ELF32
select DMA_COHERENT
select HAVE_PATA_PLATFORM
select NR_CPUS_DEFAULT_2
select SIBYTE_SB1250
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
......@@ -623,7 +624,6 @@ config SIBYTE_LITTLESUR
select BOOT_ELF32
select DMA_COHERENT
select HAVE_PATA_PLATFORM
select NR_CPUS_DEFAULT_2
select SIBYTE_SB1250
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
......@@ -635,7 +635,6 @@ config SIBYTE_SENTOSA
bool "Sibyte BCM91250E-Sentosa"
select BOOT_ELF32
select DMA_COHERENT
select NR_CPUS_DEFAULT_2
select SIBYTE_SB1250
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
......@@ -731,6 +730,7 @@ config CAVIUM_OCTEON_SOC
select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI
select HOLES_IN_ZONE
select ARCH_REQUIRE_GPIOLIB
help
This option supports all of the Octeon reference boards from Cavium
Networks. It builds a kernel that dynamically determines the Octeon
......@@ -1860,7 +1860,6 @@ config MIPS_MT_SMP
select CPU_MIPSR2_IRQ_VI
select CPU_MIPSR2_IRQ_EI
select MIPS_MT
select NR_CPUS_DEFAULT_2
select SMP
select SYS_SUPPORTS_SCHED_SMT if SMP
select SYS_SUPPORTS_SMP
......@@ -2171,12 +2170,6 @@ config SYS_SUPPORTS_MIPS_CMP
config SYS_SUPPORTS_SMP
bool
config NR_CPUS_DEFAULT_1
bool
config NR_CPUS_DEFAULT_2
bool
config NR_CPUS_DEFAULT_4
bool
......@@ -2194,10 +2187,8 @@ config NR_CPUS_DEFAULT_64
config NR_CPUS
int "Maximum number of CPUs (2-64)"
range 1 64 if NR_CPUS_DEFAULT_1
range 2 64
depends on SMP
default "1" if NR_CPUS_DEFAULT_1
default "2" if NR_CPUS_DEFAULT_2
default "4" if NR_CPUS_DEFAULT_4
default "8" if NR_CPUS_DEFAULT_8
default "16" if NR_CPUS_DEFAULT_16
......
......@@ -194,6 +194,8 @@ include $(srctree)/arch/mips/Kbuild.platforms
ifdef CONFIG_PHYSICAL_START
load-y = $(CONFIG_PHYSICAL_START)
endif
entry-y = 0x$(shell $(NM) vmlinux 2>/dev/null \
| grep "\bkernel_entry\b" | cut -f1 -d \ )
cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
drivers-$(CONFIG_PCI) += arch/mips/pci/
......@@ -225,6 +227,9 @@ KBUILD_CFLAGS += $(cflags-y)
KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y)
KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)
bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \
VMLINUX_ENTRY_ADDRESS=$(entry-y)
LDFLAGS += -m $(ld-emul)
ifdef CONFIG_CC_STACKPROTECTOR
......@@ -254,9 +259,25 @@ drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/
# suspend and hibernation support
drivers-$(CONFIG_PM) += arch/mips/power/
# boot image targets (arch/mips/boot/)
boot-y := vmlinux.bin
boot-y += vmlinux.ecoff
boot-y += vmlinux.srec
ifeq ($(shell expr $(load-y) \< 0xffffffff80000000 2> /dev/null), 0)
boot-y += uImage
boot-y += uImage.gz
endif
# compressed boot image targets (arch/mips/boot/compressed/)
bootz-y := vmlinuz
bootz-y += vmlinuz.bin
bootz-y += vmlinuz.ecoff
bootz-y += vmlinuz.srec
ifdef CONFIG_LASAT
rom.bin rom.sw: vmlinux
$(Q)$(MAKE) $(build)=arch/mips/lasat/image $@
$(Q)$(MAKE) $(build)=arch/mips/lasat/image \
$(bootvars-y) $@
endif
#
......@@ -280,13 +301,14 @@ vmlinux.64: vmlinux
all: $(all-y)
# boot
vmlinux.bin vmlinux.ecoff vmlinux.srec: $(vmlinux-32) FORCE
$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) arch/mips/boot/$@
$(boot-y): $(vmlinux-32) FORCE
$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) \
$(bootvars-y) arch/mips/boot/$@
# boot/compressed
vmlinuz vmlinuz.bin vmlinuz.ecoff vmlinuz.srec: $(vmlinux-32) FORCE
$(bootz-y): $(vmlinux-32) FORCE
$(Q)$(MAKE) $(build)=arch/mips/boot/compressed \
VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $@
$(bootvars-y) 32bit-bfd=$(32bit-bfd) $@
CLEAN_FILES += vmlinux.32 vmlinux.64
......@@ -323,6 +345,8 @@ define archhelp
echo ' vmlinuz.ecoff - ECOFF zboot image'
echo ' vmlinuz.bin - Raw binary zboot image'
echo ' vmlinuz.srec - SREC zboot image'
echo ' uImage - U-Boot image'
echo ' uImage.gz - U-Boot image (gzip)'
echo
echo ' These will be default as appropriate for a configured platform.'
endef
......@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <asm/div64.h>
......@@ -31,92 +32,132 @@ struct clk {
unsigned long rate;
};
static struct clk ath79_ref_clk;
static struct clk ath79_cpu_clk;
static struct clk ath79_ddr_clk;
static struct clk ath79_ahb_clk;
static struct clk ath79_wdt_clk;
static struct clk ath79_uart_clk;
static void __init ath79_add_sys_clkdev(const char *id, unsigned long rate)
{
struct clk *clk;
int err;
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
if (!clk)
panic("failed to allocate %s clock structure", id);
clk->rate = rate;
err = clk_register_clkdev(clk, id, NULL);
if (err)
panic("unable to register %s clock device", id);
}
static void __init ar71xx_clocks_init(void)
{
unsigned long ref_rate;
unsigned long cpu_rate;
unsigned long ddr_rate;
unsigned long ahb_rate;
u32 pll;
u32 freq;
u32 div;
ath79_ref_clk.rate = AR71XX_BASE_FREQ;
ref_rate = AR71XX_BASE_FREQ;
pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
freq = div * ath79_ref_clk.rate;
freq = div * ref_rate;
div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
ath79_cpu_clk.rate = freq / div;
cpu_rate = freq / div;
div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
ath79_ddr_clk.rate = freq / div;
ddr_rate = freq / div;
div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
ahb_rate = cpu_rate / div;
ath79_add_sys_clkdev("ref", ref_rate);
ath79_add_sys_clkdev("cpu", cpu_rate);
ath79_add_sys_clkdev("ddr", ddr_rate);
ath79_add_sys_clkdev("ahb", ahb_rate);
ath79_wdt_clk.rate = ath79_ahb_clk.rate;
ath79_uart_clk.rate = ath79_ahb_clk.rate;
clk_add_alias("wdt", NULL, "ahb", NULL);
clk_add_alias("uart", NULL, "ahb", NULL);
}
static void __init ar724x_clocks_init(void)
{
unsigned long ref_rate;
unsigned long cpu_rate;
unsigned long ddr_rate;
unsigned long ahb_rate;
u32 pll;
u32 freq;
u32 div;
ath79_ref_clk.rate = AR724X_BASE_FREQ;
ref_rate = AR724X_BASE_FREQ;
pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK);
freq = div * ath79_ref_clk.rate;
freq = div * ref_rate;
div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
freq *= div;
ath79_cpu_clk.rate = freq;
cpu_rate = freq;
div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
ath79_ddr_clk.rate = freq / div;
ddr_rate = freq / div;
div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
ahb_rate = cpu_rate / div;
ath79_add_sys_clkdev("ref", ref_rate);
ath79_add_sys_clkdev("cpu", cpu_rate);
ath79_add_sys_clkdev("ddr", ddr_rate);
ath79_add_sys_clkdev("ahb", ahb_rate);
ath79_wdt_clk.rate = ath79_ahb_clk.rate;
ath79_uart_clk.rate = ath79_ahb_clk.rate;
clk_add_alias("wdt", NULL, "ahb", NULL);
clk_add_alias("uart", NULL, "ahb", NULL);
}
static void __init ar913x_clocks_init(void)
{
unsigned long ref_rate;
unsigned long cpu_rate;
unsigned long ddr_rate;
unsigned long ahb_rate;
u32 pll;
u32 freq;
u32 div;
ath79_ref_clk.rate = AR913X_BASE_FREQ;
ref_rate = AR913X_BASE_FREQ;
pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG);
div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK);
freq = div * ath79_ref_clk.rate;
freq = div * ref_rate;
ath79_cpu_clk.rate = freq;
cpu_rate = freq;
div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1;
ath79_ddr_clk.rate = freq / div;
ddr_rate = freq / div;
div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2;
ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
ahb_rate = cpu_rate / div;
ath79_wdt_clk.rate = ath79_ahb_clk.rate;
ath79_uart_clk.rate = ath79_ahb_clk.rate;
ath79_add_sys_clkdev("ref", ref_rate);
ath79_add_sys_clkdev("cpu", cpu_rate);
ath79_add_sys_clkdev("ddr", ddr_rate);
ath79_add_sys_clkdev("ahb", ahb_rate);
clk_add_alias("wdt", NULL, "ahb", NULL);
clk_add_alias("uart", NULL, "ahb", NULL);
}
static void __init ar933x_clocks_init(void)
{
unsigned long ref_rate;
unsigned long cpu_rate;
unsigned long ddr_rate;
unsigned long ahb_rate;
u32 clock_ctrl;
u32 cpu_config;
u32 freq;
......@@ -124,21 +165,21 @@ static void __init ar933x_clocks_init(void)
t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
if (t & AR933X_BOOTSTRAP_REF_CLK_40)
ath79_ref_clk.rate = (40 * 1000 * 1000);
ref_rate = (40 * 1000 * 1000);
else
ath79_ref_clk.rate = (25 * 1000 * 1000);
ref_rate = (25 * 1000 * 1000);
clock_ctrl = ath79_pll_rr(AR933X_PLL_CLOCK_CTRL_REG);
if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
ath79_cpu_clk.rate = ath79_ref_clk.rate;
ath79_ahb_clk.rate = ath79_ref_clk.rate;
ath79_ddr_clk.rate = ath79_ref_clk.rate;
cpu_rate = ref_rate;
ahb_rate = ref_rate;
ddr_rate = ref_rate;
} else {
cpu_config = ath79_pll_rr(AR933X_PLL_CPU_CONFIG_REG);
t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
freq = ath79_ref_clk.rate / t;
freq = ref_rate / t;
t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) &
AR933X_PLL_CPU_CONFIG_NINT_MASK;
......@@ -153,19 +194,24 @@ static void __init ar933x_clocks_init(void)
t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) &
AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1;
ath79_cpu_clk.rate = freq / t;
cpu_rate = freq / t;
t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) &
AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1;
ath79_ddr_clk.rate = freq / t;
ddr_rate = freq / t;
t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) &
AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1;
ath79_ahb_clk.rate = freq / t;
ahb_rate = freq / t;
}
ath79_wdt_clk.rate = ath79_ref_clk.rate;
ath79_uart_clk.rate = ath79_ref_clk.rate;
ath79_add_sys_clkdev("ref", ref_rate);
ath79_add_sys_clkdev("cpu", cpu_rate);
ath79_add_sys_clkdev("ddr", ddr_rate);
ath79_add_sys_clkdev("ahb", ahb_rate);
clk_add_alias("wdt", NULL, "ahb", NULL);
clk_add_alias("uart", NULL, "ref", NULL);
}
static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
......@@ -174,12 +220,12 @@ static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
u64 t;
u32 ret;
t = ath79_ref_clk.rate;
t = ref;
t *= nint;
do_div(t, ref_div);
ret = t;
t = ath79_ref_clk.rate;
t = ref;
t *= nfrac;
do_div(t, ref_div * frac);
ret += t;
......@@ -190,6 +236,10 @@ static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
static void __init ar934x_clocks_init(void)
{
unsigned long ref_rate;
unsigned long cpu_rate;
unsigned long ddr_rate;
unsigned long ahb_rate;
u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv;
u32 cpu_pll, ddr_pll;
u32 bootstrap;
......@@ -199,9 +249,9 @@ static void __init ar934x_clocks_init(void)
bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40)
ath79_ref_clk.rate = 40 * 1000 * 1000;
ref_rate = 40 * 1000 * 1000;
else
ath79_ref_clk.rate = 25 * 1000 * 1000;
ref_rate = 25 * 1000 * 1000;
pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG);
if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
......@@ -227,7 +277,7 @@ static void __init ar934x_clocks_init(void)
frac = 1 << 6;
}
cpu_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint,
cpu_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint,
nfrac, frac, out_div);
pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG);
......@@ -254,7 +304,7 @@ static void __init ar934x_clocks_init(void)
frac = 1 << 10;
}
ddr_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint,
ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint,
nfrac, frac, out_div);
clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
......@@ -263,49 +313,58 @@ static void __init ar934x_clocks_init(void)
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;
cpu_rate = ref_rate;
else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL)
ath79_cpu_clk.rate = cpu_pll / (postdiv + 1);
cpu_rate = cpu_pll / (postdiv + 1);
else
ath79_cpu_clk.rate = ddr_pll / (postdiv + 1);
cpu_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;
ddr_rate = ref_rate;
else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL)
ath79_ddr_clk.rate = ddr_pll / (postdiv + 1);
ddr_rate = ddr_pll / (postdiv + 1);
else
ath79_ddr_clk.rate = cpu_pll / (postdiv + 1);
ddr_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;
ahb_rate = ref_rate;
else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL)
ath79_ahb_clk.rate = ddr_pll / (postdiv + 1);
ahb_rate = ddr_pll / (postdiv + 1);
else
ath79_ahb_clk.rate = cpu_pll / (postdiv + 1);
ahb_rate = cpu_pll / (postdiv + 1);
ath79_add_sys_clkdev("ref", ref_rate);
ath79_add_sys_clkdev("cpu", cpu_rate);
ath79_add_sys_clkdev("ddr", ddr_rate);
ath79_add_sys_clkdev("ahb", ahb_rate);
ath79_wdt_clk.rate = ath79_ref_clk.rate;
ath79_uart_clk.rate = ath79_ref_clk.rate;
clk_add_alias("wdt", NULL, "ref", NULL);
clk_add_alias("uart", NULL, "ref", NULL);
iounmap(dpll_base);
}
static void __init qca955x_clocks_init(void)
{
unsigned long ref_rate;
unsigned long cpu_rate;
unsigned long ddr_rate;
unsigned long ahb_rate;
u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
u32 cpu_pll, ddr_pll;
u32 bootstrap;
bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP);
if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40)
ath79_ref_clk.rate = 40 * 1000 * 1000;
ref_rate = 40 * 1000 * 1000;
else
ath79_ref_clk.rate = 25 * 1000 * 1000;
ref_rate = 25 * 1000 * 1000;
pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG);
out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
......@@ -317,8 +376,8 @@ static void __init qca955x_clocks_init(void)
frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
QCA955X_PLL_CPU_CONFIG_NFRAC_MASK;
cpu_pll = nint * ath79_ref_clk.rate / ref_div;
cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 6));
cpu_pll = nint * ref_rate / ref_div;
cpu_pll += frac * ref_rate / (ref_div * (1 << 6));
cpu_pll /= (1 << out_div);
pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG);
......@@ -331,8 +390,8 @@ static void __init qca955x_clocks_init(void)
frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
QCA955X_PLL_DDR_CONFIG_NFRAC_MASK;
ddr_pll = nint * ath79_ref_clk.rate / ref_div;
ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 10));
ddr_pll = nint * ref_rate / ref_div;
ddr_pll += frac * ref_rate / (ref_div * (1 << 10));
ddr_pll /= (1 << out_div);
clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG);
......@@ -341,34 +400,39 @@ static void __init qca955x_clocks_init(void)
QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
ath79_cpu_clk.rate = ath79_ref_clk.rate;
cpu_rate = ref_rate;
else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL)
ath79_cpu_clk.rate = ddr_pll / (postdiv + 1);
cpu_rate = ddr_pll / (postdiv + 1);
else
ath79_cpu_clk.rate = cpu_pll / (postdiv + 1);
cpu_rate = cpu_pll / (postdiv + 1);
postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
ath79_ddr_clk.rate = ath79_ref_clk.rate;
ddr_rate = ref_rate;
else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
ath79_ddr_clk.rate = cpu_pll / (postdiv + 1);
ddr_rate = cpu_pll / (postdiv + 1);
else
ath79_ddr_clk.rate = ddr_pll / (postdiv + 1);
ddr_rate = ddr_pll / (postdiv + 1);
postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
ath79_ahb_clk.rate = ath79_ref_clk.rate;
ahb_rate = ref_rate;
else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
ath79_ahb_clk.rate = ddr_pll / (postdiv + 1);
ahb_rate = ddr_pll / (postdiv + 1);
else
ath79_ahb_clk.rate = cpu_pll / (postdiv + 1);
ahb_rate = cpu_pll / (postdiv + 1);
ath79_wdt_clk.rate = ath79_ref_clk.rate;
ath79_uart_clk.rate = ath79_ref_clk.rate;
ath79_add_sys_clkdev("ref", ref_rate);
ath79_add_sys_clkdev("cpu", cpu_rate);
ath79_add_sys_clkdev("ddr", ddr_rate);
ath79_add_sys_clkdev("ahb", ahb_rate);
clk_add_alias("wdt", NULL, "ref", NULL);
clk_add_alias("uart", NULL, "ref", NULL);
}
void __init ath79_clocks_init(void)
......@@ -387,46 +451,27 @@ void __init ath79_clocks_init(void)
qca955x_clocks_init();
else
BUG();
pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, "
"Ref:%lu.%03luMHz",
ath79_cpu_clk.rate / 1000000,
(ath79_cpu_clk.rate / 1000) % 1000,
ath79_ddr_clk.rate / 1000000,
(ath79_ddr_clk.rate / 1000) % 1000,
ath79_ahb_clk.rate / 1000000,
(ath79_ahb_clk.rate / 1000) % 1000,
ath79_ref_clk.rate / 1000000,
(ath79_ref_clk.rate / 1000) % 1000);
}
/*
* Linux clock API
*/
struct clk *clk_get(struct device *dev, const char *id)
unsigned long __init
ath79_get_sys_clk_rate(const char *id)
{
if (!strcmp(id, "ref"))
return &ath79_ref_clk;
if (!strcmp(id, "cpu"))
return &ath79_cpu_clk;
if (!strcmp(id, "ddr"))
return &ath79_ddr_clk;
if (!strcmp(id, "ahb"))
return &ath79_ahb_clk;
struct clk *clk;
unsigned long rate;
if (!strcmp(id, "wdt"))
return &ath79_wdt_clk;
clk = clk_get(NULL, id);
if (IS_ERR(clk))
panic("unable to get %s clock, err=%d", id, (int) PTR_ERR(clk));
if (!strcmp(id, "uart"))
return &ath79_uart_clk;
rate = clk_get_rate(clk);
clk_put(clk);
return ERR_PTR(-ENOENT);
return rate;
}
EXPORT_SYMBOL(clk_get);
/*
* Linux clock API
*/
int clk_enable(struct clk *clk)
{
return 0;
......@@ -443,8 +488,3 @@ unsigned long clk_get_rate(struct clk *clk)
return clk->rate;
}
EXPORT_SYMBOL(clk_get_rate);
void clk_put(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_put);
......@@ -21,6 +21,8 @@
#define ATH79_MEM_SIZE_MAX (128 * 1024 * 1024)
void ath79_clocks_init(void);
unsigned long ath79_get_sys_clk_rate(const char *id);
void ath79_ddr_wb_flush(unsigned int reg);
void ath79_gpio_function_enable(u32 mask);
......
......@@ -81,21 +81,19 @@ static struct platform_device ar933x_uart_device = {
void __init ath79_register_uart(void)
{
struct clk *clk;
unsigned long uart_clk_rate;
clk = clk_get(NULL, "uart");
if (IS_ERR(clk))
panic("unable to get UART clock, err=%ld", PTR_ERR(clk));
uart_clk_rate = ath79_get_sys_clk_rate("uart");
if (soc_is_ar71xx() ||
soc_is_ar724x() ||
soc_is_ar913x() ||
soc_is_ar934x() ||
soc_is_qca955x()) {
ath79_uart_data[0].uartclk = clk_get_rate(clk);
ath79_uart_data[0].uartclk = uart_clk_rate;
platform_device_register(&ath79_uart_device);
} else if (soc_is_ar933x()) {
ar933x_uart_data.uartclk = clk_get_rate(clk);
ar933x_uart_data.uartclk = uart_clk_rate;
platform_device_register(&ar933x_uart_device);
} else {
BUG();
......
......@@ -200,7 +200,6 @@ void __init plat_mem_setup(void)
ath79_detect_sys_type();
detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX);
ath79_clocks_init();
_machine_restart = ath79_restart;
_machine_halt = ath79_halt;
......@@ -209,13 +208,25 @@ void __init plat_mem_setup(void)
void __init plat_time_init(void)
{
struct clk *clk;
unsigned long cpu_clk_rate;
unsigned long ahb_clk_rate;
unsigned long ddr_clk_rate;
unsigned long ref_clk_rate;
ath79_clocks_init();
cpu_clk_rate = ath79_get_sys_clk_rate("cpu");
ahb_clk_rate = ath79_get_sys_clk_rate("ahb");
ddr_clk_rate = ath79_get_sys_clk_rate("ddr");
ref_clk_rate = ath79_get_sys_clk_rate("ref");
clk = clk_get(NULL, "cpu");
if (IS_ERR(clk))
panic("unable to get CPU clock, err=%ld", PTR_ERR(clk));
pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz",
cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000,
ddr_clk_rate / 1000000, (ddr_clk_rate / 1000) % 1000,
ahb_clk_rate / 1000000, (ahb_clk_rate / 1000) % 1000,
ref_clk_rate / 1000000, (ref_clk_rate / 1000) % 1000);
mips_hpt_frequency = clk_get_rate(clk) / 2;
mips_hpt_frequency = cpu_clk_rate / 2;
}
static int __init ath79_setup(void)
......
......@@ -4,3 +4,4 @@ vmlinux.*
zImage
zImage.tmp
calc_vmlinuz_load_addr
uImage
......@@ -40,3 +40,18 @@ quiet_cmd_srec = OBJCOPY $@
cmd_srec = $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $@
$(obj)/vmlinux.srec: $(VMLINUX) FORCE
$(call if_changed,srec)
UIMAGE_LOADADDR = $(VMLINUX_LOAD_ADDRESS)
UIMAGE_ENTRYADDR = $(VMLINUX_ENTRY_ADDRESS)
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)
targets += uImage.gz
$(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE
$(call if_changed,uimage,gzip)
targets += uImage
$(obj)/uImage: $(obj)/uImage.gz FORCE
@ln -sf $(notdir $<) $@
@echo ' Image $@ is ready'
......@@ -25,7 +25,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \
KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
-DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ )
-DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS)
targets := head.o decompress.o dbg.o uart-16550.o uart-alchemy.o
......
../../../../../include/dt-bindings
......@@ -1776,7 +1776,7 @@ asmlinkage void plat_irq_dispatch(void)
#ifdef CONFIG_HOTPLUG_CPU
void fixup_irqs(void)
void octeon_fixup_irqs(void)
{
irq_cpu_offline();
}
......
......@@ -8,6 +8,7 @@
* written by Ralf Baechle <ralf@linux-mips.org>
*/
#include <linux/compiler.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/console.h>
......@@ -1139,3 +1140,30 @@ static int __init edac_devinit(void)
return err;
}
device_initcall(edac_devinit);
static void __initdata *octeon_dummy_iospace;
static int __init octeon_no_pci_init(void)
{
/*
* Initially assume there is no PCI. The PCI/PCIe platform code will
* later re-initialize these to correct values if they are present.
*/
octeon_dummy_iospace = vzalloc(IO_SPACE_LIMIT);
set_io_port_base((unsigned long)octeon_dummy_iospace);
ioport_resource.start = MAX_RESOURCE;
ioport_resource.end = 0;
return 0;
}
core_initcall(octeon_no_pci_init);
static int __init octeon_no_pci_release(void)
{
/*
* Release the allocated memory if a real IO space is there.
*/
if ((unsigned long)octeon_dummy_iospace != mips_io_port_base)
vfree(octeon_dummy_iospace);
return 0;
}
late_initcall(octeon_no_pci_release);
......@@ -255,8 +255,6 @@ static void octeon_cpus_done(void)
/* State of each CPU. */
DEFINE_PER_CPU(int, cpu_state);
extern void fixup_irqs(void);
static int octeon_cpu_disable(void)
{
unsigned int cpu = smp_processor_id();
......@@ -267,7 +265,7 @@ static int octeon_cpu_disable(void)
set_cpu_online(cpu, false);
cpu_clear(cpu, cpu_callin_map);
local_irq_disable();
fixup_irqs();
octeon_fixup_irqs();
local_irq_enable();
flush_cache_all();
......
CONFIG_LANTIQ=y
CONFIG_XRX200_PHY_FW=y
CONFIG_CPU_MIPS32_R2=y
# CONFIG_COMPACTION is not set
# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_HZ_100=y
# CONFIG_SECCOMP is not set
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_RD_GZIP is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_AIO is not set
CONFIG_EMBEDDED=y
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_SLUB_DEBUG is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
# CONFIG_IOSCHED_CFQ is not set
# CONFIG_COREDUMP is not set
# CONFIG_SUSPEND is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
CONFIG_ARPD=y
CONFIG_SYN_COOKIES=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
CONFIG_TCP_CONG_ADVANCED=y
# CONFIG_TCP_CONG_BIC is not set
# CONFIG_TCP_CONG_WESTWOOD is not set
# CONFIG_TCP_CONG_HTCP is not set
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
# CONFIG_BRIDGE_NETFILTER is not set
CONFIG_NF_CONNTRACK=m
CONFIG_NF_CONNTRACK_FTP=m
CONFIG_NF_CONNTRACK_IRC=m
CONFIG_NETFILTER_XT_TARGET_CT=m
CONFIG_NETFILTER_XT_TARGET_LOG=m
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
CONFIG_NETFILTER_XT_MATCH_MAC=m
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
CONFIG_NETFILTER_XT_MATCH_STATE=m
CONFIG_NF_CONNTRACK_IPV4=m
# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_RAW=m
CONFIG_BRIDGE=y
# CONFIG_BRIDGE_IGMP_SNOOPING is not set
CONFIG_VLAN_8021Q=y
CONFIG_NET_SCHED=y
CONFIG_HAMRADIO=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_FIRMWARE_IN_KERNEL is not set
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_LANTIQ=y
CONFIG_EEPROM_93CX6=m
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_NETDEVICES=y
CONFIG_LANTIQ_ETOP=y
# CONFIG_NET_VENDOR_WIZNET is not set
CONFIG_PHYLIB=y
CONFIG_PPP=m
CONFIG_PPP_FILTER=y
CONFIG_PPP_MULTILINK=y
CONFIG_PPPOE=m
CONFIG_PPP_ASYNC=m
CONFIG_ISDN=y
CONFIG_INPUT=m
CONFIG_INPUT_POLLDEV=m
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_KEYBOARD_ATKBD is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_MISC=y
# CONFIG_SERIO is not set
# CONFIG_VT is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_RUNTIME_UARTS=2
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SPI=y
CONFIG_GPIO_MM_LANTIQ=y
CONFIG_GPIO_STP_XWAY=y
# CONFIG_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_HID is not set
# CONFIG_USB_HID is not set
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_STORAGE=y
CONFIG_USB_STORAGE_DEBUG=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_STAGING=y
# CONFIG_IOMMU_SUPPORT is not set
# CONFIG_DNOTIFY is not set
# CONFIG_PROC_PAGE_MONITOR is not set
CONFIG_TMPFS=y
CONFIG_TMPFS_XATTR=y
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_SUMMARY=y
CONFIG_JFFS2_FS_XATTR=y
# CONFIG_JFFS2_FS_POSIX_ACL is not set
# CONFIG_JFFS2_FS_SECURITY is not set
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
# CONFIG_JFFS2_ZLIB is not set
CONFIG_SQUASHFS=y
# CONFIG_SQUASHFS_ZLIB is not set
CONFIG_SQUASHFS_XZ=y
CONFIG_PRINTK_TIME=y
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_STRIP_ASM_SYMS=y
CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_FTRACE is not set
CONFIG_CMDLINE_BOOL=y
CONFIG_CRYPTO_MANAGER=m
CONFIG_CRYPTO_ARC4=m
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRC_ITU_T=m
CONFIG_CRC32_SARWATE=y
CONFIG_AVERAGE=y
......@@ -126,12 +126,13 @@ int rtc_mips_set_mmss(unsigned long nowtime)
void __init plat_time_init(void)
{
u32 start, end;
int i = HZ / 10;
int i = HZ / 8;
/* Set up the rate of periodic DS1287 interrupts. */
ds1287_set_base_clock(HZ);
if (cpu_has_counter) {
ds1287_timer_state();
while (!ds1287_timer_state())
;
......@@ -143,7 +144,7 @@ void __init plat_time_init(void)
end = read_c0_count();
mips_hpt_frequency = (end - start) * 10;
mips_hpt_frequency = (end - start) * 8;
printk(KERN_INFO "MIPS counter frequency %dHz\n",
mips_hpt_frequency);
} else if (IOASIC)
......
# MIPS headers
generic-y += cputime.h
generic-y += current.h
generic-y += emergency-restart.h
generic-y += local64.h
generic-y += mutex.h
generic-y += parport.h
generic-y += percpu.h
generic-y += scatterlist.h
generic-y += sections.h
generic-y += segment.h
generic-y += serial.h
generic-y += trace_clock.h
generic-y += ucontext.h
generic-y += xor.h
......@@ -65,44 +65,33 @@ static inline unsigned long bmips_read_zscm_reg(unsigned int offset)
{
unsigned long ret;
__asm__ __volatile__(
".set push\n"
".set noreorder\n"
"cache %1, 0(%2)\n"
"sync\n"
"_ssnop\n"
"_ssnop\n"
"_ssnop\n"
"_ssnop\n"
"_ssnop\n"
"_ssnop\n"
"_ssnop\n"
"mfc0 %0, $28, 3\n"
"_ssnop\n"
".set pop\n"
: "=&r" (ret)
: "i" (Index_Load_Tag_S), "r" (ZSCM_REG_BASE + offset)
: "memory");
barrier();
cache_op(Index_Load_Tag_S, ZSCM_REG_BASE + offset);
__sync();
_ssnop();
_ssnop();
_ssnop();
_ssnop();
_ssnop();
_ssnop();
_ssnop();
ret = read_c0_ddatalo();
_ssnop();
return ret;
}
static inline void bmips_write_zscm_reg(unsigned int offset, unsigned long data)
{
__asm__ __volatile__(
".set push\n"
".set noreorder\n"
"mtc0 %0, $28, 3\n"
"_ssnop\n"
"_ssnop\n"
"_ssnop\n"
"cache %1, 0(%2)\n"
"_ssnop\n"
"_ssnop\n"
"_ssnop\n"
: /* no outputs */
: "r" (data),
"i" (Index_Store_Tag_S), "r" (ZSCM_REG_BASE + offset)
: "memory");
write_c0_ddatalo(data);
_ssnop();
_ssnop();
_ssnop();
cache_op(Index_Store_Tag_S, ZSCM_REG_BASE + offset);
_ssnop();
_ssnop();
_ssnop();
barrier();
}
#endif /* !defined(__ASSEMBLY__) */
......
......@@ -141,6 +141,9 @@
#define PRID_IMP_CAVIUM_CN68XX 0x9100
#define PRID_IMP_CAVIUM_CN66XX 0x9200
#define PRID_IMP_CAVIUM_CN61XX 0x9300
#define PRID_IMP_CAVIUM_CNF71XX 0x9400
#define PRID_IMP_CAVIUM_CN78XX 0x9500
#define PRID_IMP_CAVIUM_CN70XX 0x9600
/*
* These are the PRID's for when 23:16 == PRID_COMP_INGENIC
......@@ -176,6 +179,7 @@
#define PRID_IMP_NETLOGIC_XLP8XX 0x1000
#define PRID_IMP_NETLOGIC_XLP3XX 0x1100
#define PRID_IMP_NETLOGIC_XLP2XX 0x1200
/*
* Definitions for 7:0 on legacy processors
......@@ -272,7 +276,7 @@ enum cpu_type_enum {
*/
CPU_5KC, CPU_5KE, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2,
CPU_XLR, CPU_XLP,
CPU_CAVIUM_OCTEON3, CPU_XLR, CPU_XLP,
CPU_LAST
};
......
#ifndef __MIPS_CPUTIME_H
#define __MIPS_CPUTIME_H
#include <asm-generic/cputime.h>
#endif /* __MIPS_CPUTIME_H */
#include <asm-generic/current.h>
#ifndef _ASM_EMERGENCY_RESTART_H
#define _ASM_EMERGENCY_RESTART_H
#include <asm-generic/emergency-restart.h>
#endif /* _ASM_EMERGENCY_RESTART_H */
#include <asm-generic/local64.h>
......@@ -42,8 +42,6 @@
#define cpu_has_mips64r1 0
#define cpu_has_mips64r2 0
#define cpu_has_dsp 0
#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_64bits 0
......
#ifndef __ASM_MACH_CAVIUM_OCTEON_GPIO_H
#define __ASM_MACH_CAVIUM_OCTEON_GPIO_H
#ifdef CONFIG_GPIOLIB
#define gpio_get_value __gpio_get_value
#define gpio_set_value __gpio_set_value
#define gpio_cansleep __gpio_cansleep
#else
int gpio_request(unsigned gpio, const char *label);
void gpio_free(unsigned gpio);
int gpio_direction_input(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
int gpio_get_value(unsigned gpio);
void gpio_set_value(unsigned gpio, int value);
#endif
#include <asm-generic/gpio.h>
#define gpio_to_irq __gpio_to_irq
#endif /* __ASM_MACH_GENERIC_GPIO_H */
/*
* Lantiq FALCON specific CPU feature overrides
*
* Copyright (C) 2013 Thomas Langer, Lantiq Deutschland
*
* This file was derived from: include/asm-mips/cpu-features.h
* Copyright (C) 2003, 2004 Ralf Baechle
* Copyright (C) 2004 Maciej W. Rozycki
*
* 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_FALCON_CPU_FEATURE_OVERRIDES_H
#define __ASM_MACH_FALCON_CPU_FEATURE_OVERRIDES_H
#define cpu_has_tlb 1
#define cpu_has_4kex 1
#define cpu_has_3k_cache 0
#define cpu_has_4k_cache 1
#define cpu_has_tx39_cache 0
#define cpu_has_sb1_cache 0
#define cpu_has_fpu 0
#define cpu_has_32fpr 0
#define cpu_has_counter 1
#define cpu_has_watch 1
#define cpu_has_divec 1
#define cpu_has_prefetch 1
#define cpu_has_ejtag 1
#define cpu_has_llsc 1
#define cpu_has_mips16 1
#define cpu_has_mdmx 0
#define cpu_has_mips3d 0
#define cpu_has_smartmips 0
#define cpu_has_mips32r1 1
#define cpu_has_mips32r2 1
#define cpu_has_mips64r1 0
#define cpu_has_mips64r2 0
#define cpu_has_dsp 1
#define cpu_has_mipsmt 1
#define cpu_has_vint 1
#define cpu_has_veic 1
#define cpu_has_64bits 0
#define cpu_has_64bit_zero_reg 0
#define cpu_has_64bit_gp_regs 0
#define cpu_has_64bit_addresses 0
#define cpu_dcache_line_size() 32
#define cpu_icache_line_size() 32
#endif /* __ASM_MACH_FALCON_CPU_FEATURE_OVERRIDES_H */
......@@ -20,6 +20,8 @@
#define SYSC_REG_CHIP_REV 0x0c
#define SYSC_REG_SYSTEM_CONFIG0 0x10
#define SYSC_REG_SYSTEM_CONFIG1 0x14
#define SYSC_REG_CLKCFG0 0x2c
#define SYSC_REG_CPU_SYS_CLKCFG 0x3c
#define SYSC_REG_CPLL_CONFIG0 0x54
#define SYSC_REG_CPLL_CONFIG1 0x58
......@@ -29,20 +31,42 @@
#define MT7620A_CHIP_NAME0 0x3637544d
#define MT7620A_CHIP_NAME1 0x20203032
#define SYSCFG0_XTAL_FREQ_SEL BIT(6)
#define CHIP_REV_PKG_MASK 0x1
#define CHIP_REV_PKG_SHIFT 16
#define CHIP_REV_VER_MASK 0xf
#define CHIP_REV_VER_SHIFT 8
#define CHIP_REV_ECO_MASK 0xf
#define CPLL_SW_CONFIG_SHIFT 31
#define CPLL_SW_CONFIG_MASK 0x1
#define CPLL_CPU_CLK_SHIFT 24
#define CPLL_CPU_CLK_MASK 0x1
#define CPLL_MULT_RATIO_SHIFT 16
#define CPLL_MULT_RATIO 0x7
#define CPLL_DIV_RATIO_SHIFT 10
#define CPLL_DIV_RATIO 0x3
#define CLKCFG0_PERI_CLK_SEL BIT(4)
#define CPU_SYS_CLKCFG_OCP_RATIO_SHIFT 16
#define CPU_SYS_CLKCFG_OCP_RATIO_MASK 0xf
#define CPU_SYS_CLKCFG_OCP_RATIO_1 0 /* 1:1 (Reserved) */
#define CPU_SYS_CLKCFG_OCP_RATIO_1_5 1 /* 1:1.5 (Reserved) */
#define CPU_SYS_CLKCFG_OCP_RATIO_2 2 /* 1:2 */
#define CPU_SYS_CLKCFG_OCP_RATIO_2_5 3 /* 1:2.5 (Reserved) */
#define CPU_SYS_CLKCFG_OCP_RATIO_3 4 /* 1:3 */
#define CPU_SYS_CLKCFG_OCP_RATIO_3_5 5 /* 1:3.5 (Reserved) */
#define CPU_SYS_CLKCFG_OCP_RATIO_4 6 /* 1:4 */
#define CPU_SYS_CLKCFG_OCP_RATIO_5 7 /* 1:5 */
#define CPU_SYS_CLKCFG_OCP_RATIO_10 8 /* 1:10 */
#define CPU_SYS_CLKCFG_CPU_FDIV_SHIFT 8
#define CPU_SYS_CLKCFG_CPU_FDIV_MASK 0x1f
#define CPU_SYS_CLKCFG_CPU_FFRAC_SHIFT 0
#define CPU_SYS_CLKCFG_CPU_FFRAC_MASK 0x1f
#define CPLL_CFG0_SW_CFG BIT(31)
#define CPLL_CFG0_PLL_MULT_RATIO_SHIFT 16
#define CPLL_CFG0_PLL_MULT_RATIO_MASK 0x7
#define CPLL_CFG0_LC_CURFCK BIT(15)
#define CPLL_CFG0_BYPASS_REF_CLK BIT(14)
#define CPLL_CFG0_PLL_DIV_RATIO_SHIFT 10
#define CPLL_CFG0_PLL_DIV_RATIO_MASK 0x3
#define CPLL_CFG1_CPU_AUX1 BIT(25)
#define CPLL_CFG1_CPU_AUX0 BIT(24)
#define SYSCFG0_DRAM_TYPE_MASK 0x3
#define SYSCFG0_DRAM_TYPE_SHIFT 4
......
/*
* Ralink MT7620 specific CPU feature overrides
*
* Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
*
* This file was derived from: include/asm-mips/cpu-features.h
* Copyright (C) 2003, 2004 Ralf Baechle
* Copyright (C) 2004 Maciej W. Rozycki
*
* 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 _MT7620_CPU_FEATURE_OVERRIDES_H
#define _MT7620_CPU_FEATURE_OVERRIDES_H
#define cpu_has_tlb 1
#define cpu_has_4kex 1
#define cpu_has_3k_cache 0
#define cpu_has_4k_cache 1
#define cpu_has_tx39_cache 0
#define cpu_has_sb1_cache 0
#define cpu_has_fpu 0
#define cpu_has_32fpr 0
#define cpu_has_counter 1
#define cpu_has_watch 1
#define cpu_has_divec 1
#define cpu_has_prefetch 1
#define cpu_has_ejtag 1
#define cpu_has_llsc 1
#define cpu_has_mips16 1
#define cpu_has_mdmx 0
#define cpu_has_mips3d 0
#define cpu_has_smartmips 0
#define cpu_has_mips32r1 1
#define cpu_has_mips32r2 1
#define cpu_has_mips64r1 0
#define cpu_has_mips64r2 0
#define cpu_has_dsp 1
#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_64bits 0
#define cpu_has_64bit_zero_reg 0
#define cpu_has_64bit_gp_regs 0
#define cpu_has_64bit_addresses 0
#define cpu_dcache_line_size() 32
#define cpu_icache_line_size() 32
#endif /* _MT7620_CPU_FEATURE_OVERRIDES_H */
/*
* Pull in the generic implementation for the mutex fastpath.
*
* TODO: implement optimized primitives instead, or leave the generic
* implementation in place, or pick the atomic_xchg() based generic
* implementation. (see asm-generic/mutex-xchg.h for details)
*/
#include <asm-generic/mutex-dec.h>
......@@ -88,6 +88,7 @@
#define BRIDGE_DRAM_LIMIT6 0x22
#define BRIDGE_DRAM_LIMIT7 0x23
#define BRIDGE_DRAM_NODE_TRANSLN(i) (0x24 + (i))
#define BRIDGE_DRAM_NODE_TRANSLN0 0x24
#define BRIDGE_DRAM_NODE_TRANSLN1 0x25
#define BRIDGE_DRAM_NODE_TRANSLN2 0x26
......@@ -96,6 +97,8 @@
#define BRIDGE_DRAM_NODE_TRANSLN5 0x29
#define BRIDGE_DRAM_NODE_TRANSLN6 0x2a
#define BRIDGE_DRAM_NODE_TRANSLN7 0x2b
#define BRIDGE_DRAM_CHNL_TRANSLN(i) (0x2c + (i))
#define BRIDGE_DRAM_CHNL_TRANSLN0 0x2c
#define BRIDGE_DRAM_CHNL_TRANSLN1 0x2d
#define BRIDGE_DRAM_CHNL_TRANSLN2 0x2e
......@@ -104,6 +107,7 @@
#define BRIDGE_DRAM_CHNL_TRANSLN5 0x31
#define BRIDGE_DRAM_CHNL_TRANSLN6 0x32
#define BRIDGE_DRAM_CHNL_TRANSLN7 0x33
#define BRIDGE_PCIEMEM_BASE0 0x34
#define BRIDGE_PCIEMEM_BASE1 0x35
#define BRIDGE_PCIEMEM_BASE2 0x36
......
......@@ -72,6 +72,12 @@
#define XLP_IO_USB_OHCI2_OFFSET(node) XLP_HDR_OFFSET(node, 0, 2, 4)
#define XLP_IO_USB_OHCI3_OFFSET(node) XLP_HDR_OFFSET(node, 0, 2, 5)
/* XLP2xx has an updated USB block */
#define XLP2XX_IO_USB_OFFSET(node, i) XLP_HDR_OFFSET(node, 0, 4, i)
#define XLP2XX_IO_USB_XHCI0_OFFSET(node) XLP_HDR_OFFSET(node, 0, 4, 1)
#define XLP2XX_IO_USB_XHCI1_OFFSET(node) XLP_HDR_OFFSET(node, 0, 4, 2)
#define XLP2XX_IO_USB_XHCI2_OFFSET(node) XLP_HDR_OFFSET(node, 0, 4, 3)
#define XLP_IO_NAE_OFFSET(node) XLP_HDR_OFFSET(node, 0, 3, 0)
#define XLP_IO_POE_OFFSET(node) XLP_HDR_OFFSET(node, 0, 3, 1)
......@@ -88,6 +94,9 @@
#define XLP_IO_I2C0_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 2)
#define XLP_IO_I2C1_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 3)
#define XLP_IO_GPIO_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 4)
/* on 2XX, all I2C busses are on the same block */
#define XLP2XX_IO_I2C_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 7)
/* system management */
#define XLP_IO_SYS_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 5)
#define XLP_IO_JTAG_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 6)
......@@ -145,6 +154,7 @@
#define PCI_DEVICE_ID_NLM_NOR 0x1015
#define PCI_DEVICE_ID_NLM_NAND 0x1016
#define PCI_DEVICE_ID_NLM_MMC 0x1018
#define PCI_DEVICE_ID_NLM_XHCI 0x101d
#ifndef __ASSEMBLY__
......
......@@ -208,13 +208,14 @@
#define PIC_LOCAL_SCHEDULING 1
#define PIC_GLOBAL_SCHEDULING 0
#define PIC_CLK_HZ 133333333
#define nlm_read_pic_reg(b, r) nlm_read_reg64(b, r)
#define nlm_write_pic_reg(b, r, v) nlm_write_reg64(b, r, v)
#define nlm_get_pic_pcibase(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node))
#define nlm_get_pic_regbase(node) (nlm_get_pic_pcibase(node) + XLP_IO_PCI_HDRSZ)
/* We use PIC on node 0 as a timer */
#define pic_timer_freq() nlm_get_pic_frequency(0)
/* IRT and h/w interrupt routines */
static inline int
nlm_pic_read_irt(uint64_t base, int irt_index)
......
......@@ -117,6 +117,36 @@
#define SYS_SCRTCH2 0x4b
#define SYS_SCRTCH3 0x4c
/* PLL registers XLP2XX */
#define SYS_PLL_CTRL0 0x240
#define SYS_PLL_CTRL1 0x241
#define SYS_PLL_CTRL2 0x242
#define SYS_PLL_CTRL3 0x243
#define SYS_DMC_PLL_CTRL0 0x244
#define SYS_DMC_PLL_CTRL1 0x245
#define SYS_DMC_PLL_CTRL2 0x246
#define SYS_DMC_PLL_CTRL3 0x247
#define SYS_PLL_CTRL0_DEVX(x) (0x248 + (x) * 4)
#define SYS_PLL_CTRL1_DEVX(x) (0x249 + (x) * 4)
#define SYS_PLL_CTRL2_DEVX(x) (0x24a + (x) * 4)
#define SYS_PLL_CTRL3_DEVX(x) (0x24b + (x) * 4)
#define SYS_CPU_PLL_CHG_CTRL 0x288
#define SYS_PLL_CHG_CTRL 0x289
#define SYS_CLK_DEV_DIS 0x28a
#define SYS_CLK_DEV_SEL 0x28b
#define SYS_CLK_DEV_DIV 0x28c
#define SYS_CLK_DEV_CHG 0x28d
#define SYS_CLK_DEV_SEL_REG 0x28e
#define SYS_CLK_DEV_DIV_REG 0x28f
#define SYS_CPU_PLL_LOCK 0x29f
#define SYS_SYS_PLL_LOCK 0x2a0
#define SYS_PLL_MEM_CMD 0x2a1
#define SYS_CPU_PLL_MEM_REQ 0x2a2
#define SYS_SYS_PLL_MEM_REQ 0x2a3
#define SYS_PLL_MEM_STAT 0x2a4
#ifndef __ASSEMBLY__
#define nlm_read_sys_reg(b, r) nlm_read_reg(b, r)
......@@ -124,5 +154,6 @@
#define nlm_get_sys_pcibase(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node))
#define nlm_get_sys_regbase(node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ)
unsigned int nlm_get_pic_frequency(int node);
#endif
#endif
......@@ -41,15 +41,22 @@
#define PIC_PCIE_LINK_1_IRQ 20
#define PIC_PCIE_LINK_2_IRQ 21
#define PIC_PCIE_LINK_3_IRQ 22
#define PIC_EHCI_0_IRQ 23
#define PIC_EHCI_1_IRQ 24
#define PIC_OHCI_0_IRQ 25
#define PIC_OHCI_1_IRQ 26
#define PIC_OHCI_2_IRQ 27
#define PIC_OHCI_3_IRQ 28
#define PIC_2XX_XHCI_0_IRQ 23
#define PIC_2XX_XHCI_1_IRQ 24
#define PIC_2XX_XHCI_2_IRQ 25
#define PIC_MMC_IRQ 29
#define PIC_I2C_0_IRQ 30
#define PIC_I2C_1_IRQ 31
#define PIC_I2C_2_IRQ 32
#define PIC_I2C_3_IRQ 33
#ifndef __ASSEMBLY__
......@@ -59,7 +66,17 @@ void xlp_wakeup_secondary_cpus(void);
void xlp_mmu_init(void);
void nlm_hal_init(void);
int xlp_get_dram_map(int n, uint64_t *dram_map);
/* Device tree related */
void *xlp_dt_init(void *fdtp);
static inline int cpu_is_xlpii(void)
{
int chip = read_c0_prid() & 0xff00;
return chip == PRID_IMP_NETLOGIC_XLP2XX;
}
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_NLM_XLP_H */
......@@ -36,6 +36,8 @@
#define _ASM_NLM_XLR_PIC_H
#define PIC_CLK_HZ 66666666
#define pic_timer_freq() PIC_CLK_HZ
/* PIC hardware interrupt numbers */
#define PIC_IRT_WD_INDEX 0
#define PIC_IRT_TIMER_0_INDEX 1
......
......@@ -251,4 +251,6 @@ extern void (*octeon_irq_setup_secondary)(void);
typedef void (*octeon_irq_ip4_handler_t)(void);
void octeon_irq_set_ip4_handler(octeon_irq_ip4_handler_t);
extern void octeon_fixup_irqs(void);
#endif /* __ASM_OCTEON_OCTEON_H */
#include <asm-generic/parport.h>
#ifndef __ASM_PERCPU_H
#define __ASM_PERCPU_H
#include <asm-generic/percpu.h>
#endif /* __ASM_PERCPU_H */
#ifndef __ASM_SCATTERLIST_H
#define __ASM_SCATTERLIST_H
#include <asm-generic/scatterlist.h>
#endif /* __ASM_SCATTERLIST_H */
#ifndef _ASM_SECTIONS_H
#define _ASM_SECTIONS_H
#include <asm-generic/sections.h>
#endif /* _ASM_SECTIONS_H */
#ifndef _ASM_SEGMENT_H
#define _ASM_SEGMENT_H
/* Only here because we have some old header files that expect it.. */
#endif /* _ASM_SEGMENT_H */
#include <asm-generic/serial.h>
#include <asm-generic/ucontext.h>
#include <asm-generic/xor.h>
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
header-y += auxvec.h
generic-y += auxvec.h
generic-y += ipcbuf.h
header-y += bitsperlong.h
header-y += break.h
header-y += byteorder.h
......@@ -11,7 +13,6 @@ header-y += fcntl.h
header-y += inst.h
header-y += ioctl.h
header-y += ioctls.h
header-y += ipcbuf.h
header-y += kvm_para.h
header-y += mman.h
header-y += msgbuf.h
......
#ifndef _ASM_AUXVEC_H
#define _ASM_AUXVEC_H
#endif /* _ASM_AUXVEC_H */
#include <asm-generic/ipcbuf.h>
......@@ -852,10 +852,17 @@ static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu)
case PRID_IMP_CAVIUM_CN63XX:
case PRID_IMP_CAVIUM_CN66XX:
case PRID_IMP_CAVIUM_CN68XX:
case PRID_IMP_CAVIUM_CNF71XX:
c->cputype = CPU_CAVIUM_OCTEON2;
__cpu_name[cpu] = "Cavium Octeon II";
set_elf_platform(cpu, "octeon2");
break;
case PRID_IMP_CAVIUM_CN70XX:
case PRID_IMP_CAVIUM_CN78XX:
c->cputype = CPU_CAVIUM_OCTEON3;
__cpu_name[cpu] = "Cavium Octeon III";
set_elf_platform(cpu, "octeon3");
break;
default:
printk(KERN_INFO "Unknown Octeon chip!\n");
c->cputype = CPU_UNKNOWN;
......@@ -899,6 +906,11 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
MIPS_CPU_LLSC);
switch (c->processor_id & 0xff00) {
case PRID_IMP_NETLOGIC_XLP2XX:
c->cputype = CPU_XLP;
__cpu_name[cpu] = "Broadcom XLPII";
break;
case PRID_IMP_NETLOGIC_XLP8XX:
case PRID_IMP_NETLOGIC_XLP3XX:
c->cputype = CPU_XLP;
......
......@@ -41,9 +41,9 @@ void __init dec_ioasic_clocksource_init(void)
{
unsigned int freq;
u32 start, end;
int i = HZ / 10;
int i = HZ / 8;
ds1287_timer_state();
while (!ds1287_timer_state())
;
......@@ -55,7 +55,7 @@ void __init dec_ioasic_clocksource_init(void)
end = dec_ioasic_hpt_read(&clocksource_dec);
freq = (end - start) * 10;
freq = (end - start) * 8;
printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq);
clocksource_dec.rating = 200 + freq / 10000000;
......
......@@ -166,6 +166,7 @@ void __init check_wait(void)
case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2:
case CPU_CAVIUM_OCTEON3:
case CPU_JZRISC:
case CPU_LOONGSON1:
case CPU_XLR:
......
......@@ -83,7 +83,7 @@ _mcount:
PTR_S MCOUNT_RA_ADDRESS_REG, PT_R12(sp)
#endif
move a0, ra /* arg1: self return address */
PTR_SUBU a0, ra, 8 /* arg1: self address */
.globl ftrace_call
ftrace_call:
nop /* a placeholder for the call to a real tracing function */
......
......@@ -26,6 +26,12 @@ process_entry:
PTR_L s2, (s0)
PTR_ADD s0, s0, SZREG
/*
* In case of a kdump/crash kernel, the indirection page is not
* populated as the kernel is directly copied to a reserved location
*/
beqz s2, done
/* destination page */
and s3, s2, 0x1
beq s3, zero, 1f
......
......@@ -552,6 +552,52 @@ static void __init arch_mem_addpart(phys_t mem, phys_t end, int type)
add_memory_region(mem, size, type);
}
#ifdef CONFIG_KEXEC
static inline unsigned long long get_total_mem(void)
{
unsigned long long total;
total = max_pfn - min_low_pfn;
return total << PAGE_SHIFT;
}
static void __init mips_parse_crashkernel(void)
{
unsigned long long total_mem;
unsigned long long crash_size, crash_base;
int ret;
total_mem = get_total_mem();
ret = parse_crashkernel(boot_command_line, total_mem,
&crash_size, &crash_base);
if (ret != 0 || crash_size <= 0)
return;
crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1;
}
static void __init request_crashkernel(struct resource *res)
{
int ret;
ret = request_resource(res, &crashk_res);
if (!ret)
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel\n",
(unsigned long)((crashk_res.end -
crashk_res.start + 1) >> 20),
(unsigned long)(crashk_res.start >> 20));
}
#else /* !defined(CONFIG_KEXEC) */
static void __init mips_parse_crashkernel(void)
{
}
static void __init request_crashkernel(struct resource *res)
{
}
#endif /* !defined(CONFIG_KEXEC) */
static void __init arch_mem_init(char **cmdline_p)
{
extern void plat_mem_setup(void);
......@@ -608,6 +654,8 @@ static void __init arch_mem_init(char **cmdline_p)
BOOTMEM_DEFAULT);
}
#endif
mips_parse_crashkernel();
#ifdef CONFIG_KEXEC
if (crashk_res.start != crashk_res.end)
reserve_bootmem(crashk_res.start,
......@@ -620,52 +668,6 @@ static void __init arch_mem_init(char **cmdline_p)
paging_init();
}
#ifdef CONFIG_KEXEC
static inline unsigned long long get_total_mem(void)
{
unsigned long long total;
total = max_pfn - min_low_pfn;
return total << PAGE_SHIFT;
}
static void __init mips_parse_crashkernel(void)
{
unsigned long long total_mem;
unsigned long long crash_size, crash_base;
int ret;
total_mem = get_total_mem();
ret = parse_crashkernel(boot_command_line, total_mem,
&crash_size, &crash_base);
if (ret != 0 || crash_size <= 0)
return;
crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1;
}
static void __init request_crashkernel(struct resource *res)
{
int ret;
ret = request_resource(res, &crashk_res);
if (!ret)
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel\n",
(unsigned long)((crashk_res.end -
crashk_res.start + 1) >> 20),
(unsigned long)(crashk_res.start >> 20));
}
#else /* !defined(CONFIG_KEXEC) */
static void __init mips_parse_crashkernel(void)
{
}
static void __init request_crashkernel(struct resource *res)
{
}
#endif /* !defined(CONFIG_KEXEC) */
static void __init resource_init(void)
{
int i;
......@@ -678,11 +680,6 @@ static void __init resource_init(void)
data_resource.start = __pa_symbol(&_etext);
data_resource.end = __pa_symbol(&_edata) - 1;
/*
* Request address space for all standard RAM.
*/
mips_parse_crashkernel();
for (i = 0; i < boot_mem_map.nr_map; i++) {
struct resource *res;
unsigned long start, end;
......
......@@ -121,6 +121,14 @@ void __init time_init(void)
{
plat_time_init();
if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
/*
* The use of the R4k timer as a clock event takes precedence;
* if reading the Count register might interfere with the timer
* interrupt, then we don't use the timer as a clock source.
* We may still use the timer as a clock source though if the
* timer interrupt isn't reliable; the interference doesn't
* matter then, because we don't use the interrupt.
*/
if (mips_clockevent_init() != 0 || !cpu_has_mfc0_count_bug())
init_mips_clocksource();
}
......@@ -179,5 +179,6 @@ SECTIONS
*(.options)
*(.pdr)
*(.reginfo)
*(.eh_frame)
}
}
......@@ -48,6 +48,7 @@
#define CPU0CC_CPUDIV 0x0001
/* Activation Status Register */
#define ACTS_ASC0_ACT 0x00001000
#define ACTS_ASC1_ACT 0x00000800
#define ACTS_I2C_ACT 0x00004000
#define ACTS_P0 0x00010000
......@@ -108,6 +109,7 @@ static void sysctl_deactivate(struct clk *clk)
static int sysctl_clken(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_CLKS);
return 0;
}
......@@ -256,6 +258,7 @@ void __init ltq_soc_init(void)
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("1e100b00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT);
clkdev_add_sys("1e100c00.serial", SYSCTL_SYS1, ACTS_ASC0_ACT);
clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT);
}
obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o
obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o
obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o
/*
* 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 John Crispin <blogic@openwrt.org>
* Copyright (C) 2010 Sameer Ahmad, Lantiq GmbH
*/
#include <linux/ioport.h>
#include <linux/of_platform.h>
#include <lantiq_soc.h>
/* Bias and regulator Setup Register */
#define DCDC_BIAS_VREG0 0xa
/* Bias and regulator Setup Register */
#define DCDC_BIAS_VREG1 0xb
#define dcdc_w8(x, y) ltq_w8((x), dcdc_membase + (y))
#define dcdc_r8(x) ltq_r8(dcdc_membase + (x))
static void __iomem *dcdc_membase;
static int dcdc_probe(struct platform_device *pdev)
{
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dcdc_membase = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(dcdc_membase))
return PTR_ERR(dcdc_membase);
dev_info(&pdev->dev, "Core Voltage : %d mV\n",
dcdc_r8(DCDC_BIAS_VREG1) * 8);
return 0;
}
static const struct of_device_id dcdc_match[] = {
{ .compatible = "lantiq,dcdc-xrx200" },
{},
};
static struct platform_driver dcdc_driver = {
.probe = dcdc_probe,
.driver = {
.name = "dcdc-xrx200",
.owner = THIS_MODULE,
.of_match_table = dcdc_match,
},
};
int __init dcdc_init(void)
{
int ret = platform_driver_register(&dcdc_driver);
if (ret)
pr_info("dcdc: Error registering platform driver\n");
return ret;
}
arch_initcall(dcdc_init);
......@@ -13,13 +13,11 @@ endif
MKLASATIMG = mklasatimg
MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200
KERNEL_IMAGE = vmlinux
KERNEL_START = $(shell $(NM) $(KERNEL_IMAGE) | grep " _text" | cut -f1 -d\ )
KERNEL_ENTRY = $(shell $(NM) $(KERNEL_IMAGE) | grep kernel_entry | cut -f1 -d\ )
LDSCRIPT= -L$(srctree)/$(src) -Tromscript.normal
HEAD_DEFINES := -D_kernel_start=0x$(KERNEL_START) \
-D_kernel_entry=0x$(KERNEL_ENTRY) \
HEAD_DEFINES := -D_kernel_start=$(VMLINUX_LOAD_ADDRESS) \
-D_kernel_entry=$(VMLINUX_ENTRY_ADDRESS) \
-D VERSION="\"$(Version)\"" \
-D TIMESTAMP=$(shell date +%s)
......
......@@ -3,8 +3,9 @@
#
obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
pci.o bonito-irq.o mem.o machtype.o platform.o
bonito-irq.o mem.o machtype.o platform.o
obj-$(CONFIG_GPIOLIB) += gpio.o
obj-$(CONFIG_PCI) += pci.o
#
# Serial port support
......
......@@ -436,7 +436,6 @@ static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr)
break;
default:
return SIGILL;
break;
}
break;
case mm_32f_74_op: /* c.cond.fmt */
......@@ -451,12 +450,10 @@ static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr)
break;
default:
return SIGILL;
break;
}
break;
default:
return SIGILL;
break;
}
*insn_ptr = mips32_insn;
......@@ -491,7 +488,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.next_pc_inc;
*contpc = regs->regs[insn.mm_i_format.rs];
return 1;
break;
}
}
break;
......@@ -513,7 +509,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc +
dec_insn.next_pc_inc;
return 1;
break;
case mm_bgezals_op:
case mm_bgezal_op:
regs->regs[31] = regs->cp0_epc +
......@@ -530,7 +525,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc +
dec_insn.next_pc_inc;
return 1;
break;
case mm_blez_op:
if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
*contpc = regs->cp0_epc +
......@@ -541,7 +535,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc +
dec_insn.next_pc_inc;
return 1;
break;
case mm_bgtz_op:
if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
*contpc = regs->cp0_epc +
......@@ -552,7 +545,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc +
dec_insn.next_pc_inc;
return 1;
break;
case mm_bc2f_op:
case mm_bc1f_op:
bc_false = 1;
......@@ -580,7 +572,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
*contpc = regs->cp0_epc +
dec_insn.pc_inc + dec_insn.next_pc_inc;
return 1;
break;
}
break;
case mm_pool16c_op:
......@@ -593,7 +584,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
case mm_jr16_op:
*contpc = regs->regs[insn.mm_i_format.rs];
return 1;
break;
}
break;
case mm_beqz16_op:
......@@ -605,7 +595,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
*contpc = regs->cp0_epc +
dec_insn.pc_inc + dec_insn.next_pc_inc;
return 1;
break;
case mm_bnez16_op:
if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] != 0)
*contpc = regs->cp0_epc +
......@@ -615,12 +604,10 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
*contpc = regs->cp0_epc +
dec_insn.pc_inc + dec_insn.next_pc_inc;
return 1;
break;
case mm_b16_op:
*contpc = regs->cp0_epc + dec_insn.pc_inc +
(insn.mm_b0_format.simmediate << 1);
return 1;
break;
case mm_beq32_op:
if (regs->regs[insn.mm_i_format.rs] ==
regs->regs[insn.mm_i_format.rt])
......@@ -632,7 +619,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc +
dec_insn.next_pc_inc;
return 1;
break;
case mm_bne32_op:
if (regs->regs[insn.mm_i_format.rs] !=
regs->regs[insn.mm_i_format.rt])
......@@ -643,7 +629,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
*contpc = regs->cp0_epc +
dec_insn.pc_inc + dec_insn.next_pc_inc;
return 1;
break;
case mm_jalx32_op:
regs->regs[31] = regs->cp0_epc +
dec_insn.pc_inc + dec_insn.next_pc_inc;
......@@ -652,7 +637,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
*contpc <<= 28;
*contpc |= (insn.j_format.target << 2);
return 1;
break;
case mm_jals32_op:
case mm_jal32_op:
regs->regs[31] = regs->cp0_epc +
......@@ -665,7 +649,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
*contpc |= (insn.j_format.target << 1);
set_isa16_mode(*contpc);
return 1;
break;
}
return 0;
}
......@@ -694,7 +677,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
case jr_op:
*contpc = regs->regs[insn.r_format.rs];
return 1;
break;
}
break;
case bcond_op:
......@@ -716,7 +698,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc +
dec_insn.next_pc_inc;
return 1;
break;
case bgezal_op:
case bgezall_op:
regs->regs[31] = regs->cp0_epc +
......@@ -734,7 +715,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc +
dec_insn.next_pc_inc;
return 1;
break;
}
break;
case jalx_op:
......@@ -752,7 +732,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
/* Set microMIPS mode bit: XOR for jalx. */
*contpc ^= bit;
return 1;
break;
case beq_op:
case beql_op:
if (regs->regs[insn.i_format.rs] ==
......@@ -765,7 +744,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc +
dec_insn.next_pc_inc;
return 1;
break;
case bne_op:
case bnel_op:
if (regs->regs[insn.i_format.rs] !=
......@@ -778,7 +756,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc +
dec_insn.next_pc_inc;
return 1;
break;
case blez_op:
case blezl_op:
if ((long)regs->regs[insn.i_format.rs] <= 0)
......@@ -790,7 +767,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc +
dec_insn.next_pc_inc;
return 1;
break;
case bgtz_op:
case bgtzl_op:
if ((long)regs->regs[insn.i_format.rs] > 0)
......@@ -802,7 +778,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc +
dec_insn.next_pc_inc;
return 1;
break;
#ifdef CONFIG_CPU_CAVIUM_OCTEON
case lwc2_op: /* This is bbit0 on Octeon */
if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt)) == 0)
......@@ -856,7 +831,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc +
dec_insn.next_pc_inc;
return 1;
break;
case 1: /* bc1t */
case 3: /* bc1tl */
if (fcr31 & (1 << bit))
......@@ -868,7 +842,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc +
dec_insn.next_pc_inc;
return 1;
break;
}
}
break;
......
......@@ -224,6 +224,20 @@ static void probe_octeon(void)
c->options |= MIPS_CPU_PREFETCH;
break;
case CPU_CAVIUM_OCTEON3:
c->icache.linesz = 128;
c->icache.sets = 16;
c->icache.ways = 39;
c->icache.flags |= MIPS_CACHE_VTAG;
icache_size = c->icache.sets * c->icache.ways * c->icache.linesz;
c->dcache.linesz = 128;
c->dcache.ways = 32;
c->dcache.sets = 8;
dcache_size = c->dcache.sets * c->dcache.ways * c->dcache.linesz;
c->options |= MIPS_CPU_PREFETCH;
break;
default:
panic("Unsupported Cavium Networks CPU type");
break;
......
......@@ -50,16 +50,20 @@ static inline struct page *dma_addr_to_page(struct device *dev,
}
/*
* The affected CPUs below in 'cpu_needs_post_dma_flush()' can
* speculatively fill random cachelines with stale data at any time,
* requiring an extra flush post-DMA.
*
* Warning on the terminology - Linux calls an uncached area coherent;
* MIPS terminology calls memory areas with hardware maintained coherency
* coherent.
*/
static inline int cpu_is_noncoherent_r10000(struct device *dev)
static inline int cpu_needs_post_dma_flush(struct device *dev)
{
return !plat_device_is_coherent(dev) &&
(current_cpu_type() == CPU_R10000 ||
current_cpu_type() == CPU_R12000);
(boot_cpu_type() == CPU_R10000 ||
boot_cpu_type() == CPU_R12000 ||
boot_cpu_type() == CPU_BMIPS5000);
}
static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
......@@ -230,7 +234,7 @@ static inline void __dma_sync(struct page *page,
static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
{
if (cpu_is_noncoherent_r10000(dev))
if (cpu_needs_post_dma_flush(dev))
__dma_sync(dma_addr_to_page(dev, dma_addr),
dma_addr & ~PAGE_MASK, size, direction);
......@@ -284,7 +288,7 @@ static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
static void mips_dma_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
{
if (cpu_is_noncoherent_r10000(dev))
if (cpu_needs_post_dma_flush(dev))
__dma_sync(dma_addr_to_page(dev, dma_handle),
dma_handle & ~PAGE_MASK, size, direction);
}
......@@ -305,7 +309,7 @@ static void mips_dma_sync_sg_for_cpu(struct device *dev,
/* Make sure that gcc doesn't leave the empty loop body. */
for (i = 0; i < nelems; i++, sg++) {
if (cpu_is_noncoherent_r10000(dev))
if (cpu_needs_post_dma_flush(dev))
__dma_sync(sg_page(sg), sg->offset, sg->length,
direction);
}
......
......@@ -12,6 +12,7 @@
#include <linux/swap.h>
#include <linux/hugetlb.h>
#include <asm/cpu-features.h>
#include <asm/pgtable.h>
static inline pte_t gup_get_pte(pte_t *ptep)
......@@ -273,7 +274,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
len = (unsigned long) nr_pages << PAGE_SHIFT;
end = start + len;
if (end < start)
if (end < start || cpu_has_dc_aliases)
goto slow_irqon;
/* XXX: batch / limit 'nr' */
......
......@@ -254,6 +254,7 @@ void copy_from_user_page(struct vm_area_struct *vma,
SetPageDcacheDirty(page);
}
}
EXPORT_SYMBOL_GPL(copy_from_user_page);
void __init fixrange_init(unsigned long start, unsigned long end,
pgd_t *pgd_base)
......
......@@ -16,10 +16,12 @@
#define FASTPATH_SIZE 128
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
LEAF(tlbmiss_handler_setup_pgd)
.space 16 * 4
END(tlbmiss_handler_setup_pgd)
EXPORT(tlbmiss_handler_setup_pgd_end)
#endif
LEAF(handle_tlbm)
.space FASTPATH_SIZE * 4
......
......@@ -85,6 +85,7 @@ static int use_bbit_insns(void)
case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2:
case CPU_CAVIUM_OCTEON3:
return 1;
default:
return 0;
......@@ -95,6 +96,7 @@ static int use_lwx_insns(void)
{
switch (current_cpu_type()) {
case CPU_CAVIUM_OCTEON2:
case CPU_CAVIUM_OCTEON3:
return 1;
default:
return 0;
......
......@@ -19,6 +19,15 @@ config DT_XLP_SVP
pointer to the kernel. The corresponding DTS file is at
arch/mips/netlogic/dts/xlp_svp.dts
config DT_XLP_FVP
bool "Built-in device tree for XLP FVP boards"
default y
help
Add an FDT blob for XLP FVP board into the kernel.
This DTB will be used if the firmware does not pass in a DTB
pointer to the kernel. The corresponding DTS file is at
arch/mips/netlogic/dts/xlp_fvp.dts
config NLM_MULTINODE
bool "Support for multi-chip boards"
depends on NLM_XLP_BOARD
......
......@@ -106,8 +106,6 @@ void nlm_early_init_secondary(int cpu)
{
change_c0_config(CONF_CM_CMASK, 0x3);
#ifdef CONFIG_CPU_XLP
/* mmu init, once per core */
if (cpu % NLM_THREADS_PER_CORE == 0)
xlp_mmu_init();
#endif
write_c0_ebase(nlm_current_node()->ebase);
......
......@@ -45,6 +45,7 @@
#if defined(CONFIG_CPU_XLP)
#include <asm/netlogic/xlp-hal/iomap.h>
#include <asm/netlogic/xlp-hal/xlp.h>
#include <asm/netlogic/xlp-hal/sys.h>
#include <asm/netlogic/xlp-hal/pic.h>
#elif defined(CONFIG_CPU_XLR)
#include <asm/netlogic/xlr/iomap.h>
......@@ -91,7 +92,7 @@ static void nlm_init_pic_timer(void)
csrc_pic.read = nlm_get_pic_timer;
}
csrc_pic.rating = 1000;
clocksource_register_hz(&csrc_pic, PIC_CLK_HZ);
clocksource_register_hz(&csrc_pic, pic_timer_freq());
}
void __init plat_time_init(void)
......
obj-$(CONFIG_DT_XLP_EVP) := xlp_evp.dtb.o
obj-$(CONFIG_DT_XLP_SVP) += xlp_svp.dtb.o
obj-$(CONFIG_DT_XLP_FVP) += xlp_fvp.dtb.o
......@@ -9,19 +9,12 @@ / {
#address-cells = <2>;
#size-cells = <2>;
memory {
device_type = "memory";
reg = <0 0x00100000 0 0x0FF00000 // 255M at 1M
0 0x20000000 0 0xa0000000 // 2560M at 512M
0 0xe0000000 1 0x00000000>;
};
soc {
#address-cells = <2>;
#size-cells = <1>;
compatible = "simple-bus";
ranges = <0 0 0 0x18000000 0x04000000 // PCIe CFG
1 0 0 0x16000000 0x01000000>; // GBU chipselects
1 0 0 0x16000000 0x02000000>; // GBU chipselects
serial0: serial@30000 {
device_type = "serial";
......
/*
* XLP2XX Device Tree Source for FVP boards
*/
/dts-v1/;
/ {
model = "netlogic,XLP-FVP";
compatible = "netlogic,xlp";
#address-cells = <2>;
#size-cells = <2>;
soc {
#address-cells = <2>;
#size-cells = <1>;
compatible = "simple-bus";
ranges = <0 0 0 0x18000000 0x04000000 // PCIe CFG
1 0 0 0x16000000 0x02000000>; // GBU chipselects
serial0: serial@30000 {
device_type = "serial";
compatible = "ns16550";
reg = <0 0x30100 0xa00>;
reg-shift = <2>;
reg-io-width = <4>;
clock-frequency = <133333333>;
interrupt-parent = <&pic>;
interrupts = <17>;
};
serial1: serial@31000 {
device_type = "serial";
compatible = "ns16550";
reg = <0 0x31100 0xa00>;
reg-shift = <2>;
reg-io-width = <4>;
clock-frequency = <133333333>;
interrupt-parent = <&pic>;
interrupts = <18>;
};
i2c0: ocores@37100 {
compatible = "opencores,i2c-ocores";
#address-cells = <1>;
#size-cells = <0>;
reg = <0 0x37100 0x20>;
reg-shift = <2>;
reg-io-width = <4>;
clock-frequency = <32000000>;
interrupt-parent = <&pic>;
interrupts = <30>;
};
i2c1: ocores@37120 {
compatible = "opencores,i2c-ocores";
#address-cells = <1>;
#size-cells = <0>;
reg = <0 0x37120 0x20>;
reg-shift = <2>;
reg-io-width = <4>;
clock-frequency = <32000000>;
interrupt-parent = <&pic>;
interrupts = <31>;
rtc@68 {
compatible = "dallas,ds1374";
reg = <0x68>;
};
dtt@4c {
compatible = "national,lm90";
reg = <0x4c>;
};
};
pic: pic@4000 {
compatible = "netlogic,xlp-pic";
#address-cells = <0>;
#interrupt-cells = <1>;
reg = <0 0x4000 0x200>;
interrupt-controller;
};
nor_flash@1,0 {
compatible = "cfi-flash";
#address-cells = <1>;
#size-cells = <1>;
bank-width = <2>;
reg = <1 0 0x1000000>;
partition@0 {
label = "x-loader";
reg = <0x0 0x100000>; /* 1M */
read-only;
};
partition@100000 {
label = "u-boot";
reg = <0x100000 0x100000>; /* 1M */
};
partition@200000 {
label = "kernel";
reg = <0x200000 0x500000>; /* 5M */
};
partition@700000 {
label = "rootfs";
reg = <0x700000 0x800000>; /* 8M */
};
partition@f00000 {
label = "env";
reg = <0xf00000 0x100000>; /* 1M */
read-only;
};
};
};
chosen {
bootargs = "console=ttyS0,115200 rdinit=/sbin/init";
};
};
......@@ -9,19 +9,12 @@ / {
#address-cells = <2>;
#size-cells = <2>;
memory {
device_type = "memory";
reg = <0 0x00100000 0 0x0FF00000 // 255M at 1M
0 0x20000000 0 0xa0000000 // 2560M at 512M
0 0xe0000000 0 0x40000000>;
};
soc {
#address-cells = <2>;
#size-cells = <1>;
compatible = "simple-bus";
ranges = <0 0 0 0x18000000 0x04000000 // PCIe CFG
1 0 0 0x16000000 0x01000000>; // GBU chipselects
1 0 0 0x16000000 0x02000000>; // GBU chipselects
serial0: serial@30000 {
device_type = "serial";
......
obj-y += setup.o nlm_hal.o cop2-ex.o dt.o
obj-$(CONFIG_SMP) += wakeup.o
obj-$(CONFIG_USB) += usb-init.o
obj-$(CONFIG_USB) += usb-init-xlp2.o
......@@ -39,12 +39,18 @@
#include <linux/of_platform.h>
#include <linux/of_device.h>
extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[], __dtb_start[];
extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[],
__dtb_xlp_fvp_begin[], __dtb_start[];
void __init *xlp_dt_init(void *fdtp)
{
if (!fdtp) {
switch (current_cpu_data.processor_id & 0xff00) {
#ifdef CONFIG_DT_XLP_FVP
case PRID_IMP_NETLOGIC_XLP2XX:
fdtp = __dtb_xlp_fvp_begin;
break;
#endif
#ifdef CONFIG_DT_XLP_SVP
case PRID_IMP_NETLOGIC_XLP3XX:
fdtp = __dtb_xlp_svp_begin;
......
......@@ -44,6 +44,7 @@
#include <asm/netlogic/haldefs.h>
#include <asm/netlogic/xlp-hal/iomap.h>
#include <asm/netlogic/xlp-hal/xlp.h>
#include <asm/netlogic/xlp-hal/bridge.h>
#include <asm/netlogic/xlp-hal/pic.h>
#include <asm/netlogic/xlp-hal/sys.h>
......@@ -64,6 +65,7 @@ int nlm_irq_to_irt(int irq)
uint64_t pcibase;
int devoff, irt;
devoff = 0;
switch (irq) {
case PIC_UART_0_IRQ:
devoff = XLP_IO_UART0_OFFSET(0);
......@@ -71,6 +73,34 @@ int nlm_irq_to_irt(int irq)
case PIC_UART_1_IRQ:
devoff = XLP_IO_UART1_OFFSET(0);
break;
case PIC_MMC_IRQ:
devoff = XLP_IO_SD_OFFSET(0);
break;
case PIC_I2C_0_IRQ: /* I2C will be fixed up */
case PIC_I2C_1_IRQ:
case PIC_I2C_2_IRQ:
case PIC_I2C_3_IRQ:
if (cpu_is_xlpii())
devoff = XLP2XX_IO_I2C_OFFSET(0);
else
devoff = XLP_IO_I2C0_OFFSET(0);
break;
default:
if (cpu_is_xlpii()) {
switch (irq) {
/* XLP2XX has three XHCI USB controller */
case PIC_2XX_XHCI_0_IRQ:
devoff = XLP2XX_IO_USB_XHCI0_OFFSET(0);
break;
case PIC_2XX_XHCI_1_IRQ:
devoff = XLP2XX_IO_USB_XHCI1_OFFSET(0);
break;
case PIC_2XX_XHCI_2_IRQ:
devoff = XLP2XX_IO_USB_XHCI2_OFFSET(0);
break;
}
} else {
switch (irq) {
case PIC_EHCI_0_IRQ:
devoff = XLP_IO_USB_EHCI0_OFFSET(0);
break;
......@@ -89,26 +119,22 @@ int nlm_irq_to_irt(int irq)
case PIC_OHCI_3_IRQ:
devoff = XLP_IO_USB_OHCI3_OFFSET(0);
break;
case PIC_MMC_IRQ:
devoff = XLP_IO_SD_OFFSET(0);
break;
case PIC_I2C_0_IRQ:
devoff = XLP_IO_I2C0_OFFSET(0);
break;
case PIC_I2C_1_IRQ:
devoff = XLP_IO_I2C1_OFFSET(0);
break;
default:
devoff = 0;
break;
}
}
}
if (devoff != 0) {
pcibase = nlm_pcicfg_base(devoff);
irt = nlm_read_reg(pcibase, XLP_PCI_IRTINFO_REG) & 0xffff;
/* HW bug, I2C 1 irt entry is off by one */
if (irq == PIC_I2C_1_IRQ)
irt = irt + 1;
/* HW weirdness, I2C IRT entry has to be fixed up */
switch (irq) {
case PIC_I2C_1_IRQ:
irt = irt + 1; break;
case PIC_I2C_2_IRQ:
irt = irt + 2; break;
case PIC_I2C_3_IRQ:
irt = irt + 3; break;
}
} else if (irq >= PIC_PCIE_LINK_0_IRQ && irq <= PIC_PCIE_LINK_3_IRQ) {
/* HW bug, PCI IRT entries are bad on early silicon, fix */
irt = PIC_IRT_PCIE_LINK_INDEX(irq - PIC_PCIE_LINK_0_IRQ);
......@@ -126,6 +152,10 @@ unsigned int nlm_get_core_frequency(int node, int core)
sysbase = nlm_get_node(node)->sysbase;
rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);
if (cpu_is_xlpii()) {
num = 1000000ULL * (400 * 3 + 100 * (rstval >> 26));
denom = 3;
} else {
dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE);
pll_divf = ((rstval >> 10) & 0x7f) + 1;
pll_divr = ((rstval >> 8) & 0x3) + 1;
......@@ -134,11 +164,148 @@ unsigned int nlm_get_core_frequency(int node, int core)
num = 800000000ULL * pll_divf;
denom = 3 * pll_divr * ext_div * dfs_div;
}
do_div(num, denom);
return (unsigned int)num;
}
/* Calculate Frequency to the PIC from PLL.
* freq_out = ( ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13 ) /
* ((2^ctrl0[7:5]) * Table(ctrl0[26:24]))
*/
static unsigned int nlm_2xx_get_pic_frequency(int node)
{
u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div;
u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_div;
u64 ref_clk, sysbase, pll_out_freq_num, ref_clk_select;
sysbase = nlm_get_node(node)->sysbase;
/* Find ref_clk_base */
ref_clk_select =
(nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG) >> 18) & 0x3;
switch (ref_clk_select) {
case 0:
ref_clk = 200000000ULL;
ref_div = 3;
break;
case 1:
ref_clk = 100000000ULL;
ref_div = 1;
break;
case 2:
ref_clk = 125000000ULL;
ref_div = 1;
break;
case 3:
ref_clk = 400000000ULL;
ref_div = 3;
break;
}
/* Find the clock source PLL device for PIC */
reg_select = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_SEL) >> 22) & 0x3;
switch (reg_select) {
case 0:
ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0);
ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2);
break;
case 1:
ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(0));
ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(0));
break;
case 2:
ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(1));
ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(1));
break;
case 3:
ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(2));
ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(2));
break;
}
vco_post_div = (ctrl_val0 >> 5) & 0x7;
pll_post_div = (ctrl_val0 >> 24) & 0x7;
mdiv = ctrl_val2 & 0xff;
fdiv = (ctrl_val2 >> 8) & 0xfff;
/* Find PLL post divider value */
switch (pll_post_div) {
case 1:
pll_post_div = 2;
break;
case 3:
pll_post_div = 4;
break;
case 7:
pll_post_div = 8;
break;
case 6:
pll_post_div = 16;
break;
case 0:
default:
pll_post_div = 1;
break;
}
fdiv = fdiv/(1 << 13);
pll_out_freq_num = ((ref_clk >> 1) * (6 + mdiv)) + fdiv;
pll_out_freq_den = (1 << vco_post_div) * pll_post_div * 3;
if (pll_out_freq_den > 0)
do_div(pll_out_freq_num, pll_out_freq_den);
/* PIC post divider, which happens after PLL */
pic_div = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_DIV) >> 22) & 0x3;
do_div(pll_out_freq_num, 1 << pic_div);
return pll_out_freq_num;
}
unsigned int nlm_get_pic_frequency(int node)
{
if (cpu_is_xlpii())
return nlm_2xx_get_pic_frequency(node);
else
return 133333333;
}
unsigned int nlm_get_cpu_frequency(void)
{
return nlm_get_core_frequency(0, 0);
}
/*
* Fills upto 8 pairs of entries containing the DRAM map of a node
* if n < 0, get dram map for all nodes
*/
int xlp_get_dram_map(int n, uint64_t *dram_map)
{
uint64_t bridgebase, base, lim;
uint32_t val;
int i, node, rv;
/* Look only at mapping on Node 0, we don't handle crazy configs */
bridgebase = nlm_get_bridge_regbase(0);
rv = 0;
for (i = 0; i < 8; i++) {
val = nlm_read_bridge_reg(bridgebase,
BRIDGE_DRAM_NODE_TRANSLN(i));
node = (val >> 1) & 0x3;
if (n >= 0 && n != node)
continue;
val = nlm_read_bridge_reg(bridgebase, BRIDGE_DRAM_BAR(i));
val = (val >> 12) & 0xfffff;
base = (uint64_t) val << 20;
val = nlm_read_bridge_reg(bridgebase, BRIDGE_DRAM_LIMIT(i));
val = (val >> 12) & 0xfffff;
if (val == 0) /* BAR not used */
continue;
lim = ((uint64_t)val + 1) << 20;
dram_map[rv] = base;
dram_map[rv + 1] = lim;
rv += 2;
}
return rv;
}
......@@ -73,6 +73,23 @@ static void nlm_fixup_mem(void)
}
}
static void __init xlp_init_mem_from_bars(void)
{
uint64_t map[16];
int i, n;
n = xlp_get_dram_map(-1, map); /* -1: info for all nodes */
for (i = 0; i < n; i += 2) {
/* exclude 0x1000_0000-0x2000_0000, u-boot device */
if (map[i] <= 0x10000000 && map[i+1] > 0x10000000)
map[i+1] = 0x10000000;
if (map[i] > 0x10000000 && map[i] < 0x20000000)
map[i] = 0x20000000;
add_memory_region(map[i], map[i+1] - map[i], BOOT_MEM_RAM);
}
}
void __init plat_mem_setup(void)
{
panic_timeout = 5;
......@@ -82,12 +99,23 @@ void __init plat_mem_setup(void)
/* memory and bootargs from DT */
early_init_devtree(initial_boot_params);
if (boot_mem_map.nr_map == 0) {
pr_info("Using DRAM BARs for memory map.\n");
xlp_init_mem_from_bars();
}
/* Calculate and setup wired entries for mapped kernel */
nlm_fixup_mem();
}
const char *get_system_type(void)
{
switch (read_c0_prid() & 0xff00) {
case PRID_IMP_NETLOGIC_XLP2XX:
return "Broadcom XLPII Series";
default:
return "Netlogic XLP Series";
}
}
void __init prom_free_prom_memory(void)
......@@ -97,12 +125,20 @@ void __init prom_free_prom_memory(void)
void xlp_mmu_init(void)
{
u32 conf4;
if (cpu_is_xlpii()) {
/* XLPII series has extended pagesize in config 4 */
conf4 = read_c0_config4() & ~0x1f00u;
write_c0_config4(conf4 | ((PAGE_SHIFT - 10) / 2 << 8));
} else {
/* enable extended TLB and Large Fixed TLB */
write_c0_config6(read_c0_config6() | 0x24);
/* set page mask of Fixed TLB in config7 */
/* set page mask of extended Fixed TLB in config7 */
write_c0_config7(PM_DEFAULT_MASK >>
(13 + (ffz(PM_DEFAULT_MASK >> 13) / 2)));
}
}
void nlm_percpu_init(int hwcpuid)
......
/*
* Copyright (c) 2003-2013 Broadcom Corporation
* All Rights Reserved
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the Broadcom
* license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <asm/netlogic/common.h>
#include <asm/netlogic/haldefs.h>
#include <asm/netlogic/xlp-hal/iomap.h>
#include <asm/netlogic/xlp-hal/xlp.h>
#define XLPII_USB3_CTL_0 0xc0
#define XLPII_VAUXRST BIT(0)
#define XLPII_VCCRST BIT(1)
#define XLPII_NUM2PORT 9
#define XLPII_NUM3PORT 13
#define XLPII_RTUNEREQ BIT(20)
#define XLPII_MS_CSYSREQ BIT(21)
#define XLPII_XS_CSYSREQ BIT(22)
#define XLPII_RETENABLEN BIT(23)
#define XLPII_TX2RX BIT(24)
#define XLPII_XHCIREV BIT(25)
#define XLPII_ECCDIS BIT(26)
#define XLPII_USB3_INT_REG 0xc2
#define XLPII_USB3_INT_MASK 0xc3
#define XLPII_USB_PHY_TEST 0xc6
#define XLPII_PRESET BIT(0)
#define XLPII_ATERESET BIT(1)
#define XLPII_LOOPEN BIT(2)
#define XLPII_TESTPDHSP BIT(3)
#define XLPII_TESTPDSSP BIT(4)
#define XLPII_TESTBURNIN BIT(5)
#define XLPII_USB_PHY_LOS_LV 0xc9
#define XLPII_LOSLEV 0
#define XLPII_LOSBIAS 5
#define XLPII_SQRXTX 8
#define XLPII_TXBOOST 11
#define XLPII_RSLKSEL 16
#define XLPII_FSEL 20
#define XLPII_USB_RFCLK_REG 0xcc
#define XLPII_VVLD 30
#define nlm_read_usb_reg(b, r) nlm_read_reg(b, r)
#define nlm_write_usb_reg(b, r, v) nlm_write_reg(b, r, v)
#define nlm_xlpii_get_usb_pcibase(node, inst) \
nlm_pcicfg_base(XLP2XX_IO_USB_OFFSET(node, inst))
#define nlm_xlpii_get_usb_regbase(node, inst) \
(nlm_xlpii_get_usb_pcibase(node, inst) + XLP_IO_PCI_HDRSZ)
static void xlpii_usb_ack(struct irq_data *data)
{
u64 port_addr;
switch (data->irq) {
case PIC_2XX_XHCI_0_IRQ:
port_addr = nlm_xlpii_get_usb_regbase(0, 1);
break;
case PIC_2XX_XHCI_1_IRQ:
port_addr = nlm_xlpii_get_usb_regbase(0, 2);
break;
case PIC_2XX_XHCI_2_IRQ:
port_addr = nlm_xlpii_get_usb_regbase(0, 3);
break;
default:
pr_err("No matching USB irq!\n");
return;
}
nlm_write_usb_reg(port_addr, XLPII_USB3_INT_REG, 0xffffffff);
}
static void nlm_xlpii_usb_hw_reset(int node, int port)
{
u64 port_addr, xhci_base, pci_base;
void __iomem *corebase;
u32 val;
port_addr = nlm_xlpii_get_usb_regbase(node, port);
/* Set frequency */
val = nlm_read_usb_reg(port_addr, XLPII_USB_PHY_LOS_LV);
val &= ~(0x3f << XLPII_FSEL);
val |= (0x27 << XLPII_FSEL);
nlm_write_usb_reg(port_addr, XLPII_USB_PHY_LOS_LV, val);
val = nlm_read_usb_reg(port_addr, XLPII_USB_RFCLK_REG);
val |= (1 << XLPII_VVLD);
nlm_write_usb_reg(port_addr, XLPII_USB_RFCLK_REG, val);
/* PHY reset */
val = nlm_read_usb_reg(port_addr, XLPII_USB_PHY_TEST);
val &= (XLPII_ATERESET | XLPII_LOOPEN | XLPII_TESTPDHSP
| XLPII_TESTPDSSP | XLPII_TESTBURNIN);
nlm_write_usb_reg(port_addr, XLPII_USB_PHY_TEST, val);
/* Setup control register */
val = XLPII_VAUXRST | XLPII_VCCRST | (1 << XLPII_NUM2PORT)
| (1 << XLPII_NUM3PORT) | XLPII_MS_CSYSREQ | XLPII_XS_CSYSREQ
| XLPII_RETENABLEN | XLPII_XHCIREV;
nlm_write_usb_reg(port_addr, XLPII_USB3_CTL_0, val);
/* Enable interrupts */
nlm_write_usb_reg(port_addr, XLPII_USB3_INT_MASK, 0x00000001);
/* Clear all interrupts */
nlm_write_usb_reg(port_addr, XLPII_USB3_INT_REG, 0xffffffff);
udelay(2000);
/* XHCI configuration at PCI mem */
pci_base = nlm_xlpii_get_usb_pcibase(node, port);
xhci_base = nlm_read_usb_reg(pci_base, 0x4) & ~0xf;
corebase = ioremap(xhci_base, 0x10000);
if (!corebase)
return;
writel(0x240002, corebase + 0xc2c0);
/* GCTL 0xc110 */
val = readl(corebase + 0xc110);
val &= ~(0x3 << 12);
val |= (1 << 12);
writel(val, corebase + 0xc110);
udelay(100);
/* PHYCFG 0xc200 */
val = readl(corebase + 0xc200);
val &= ~(1 << 6);
writel(val, corebase + 0xc200);
udelay(100);
/* PIPECTL 0xc2c0 */
val = readl(corebase + 0xc2c0);
val &= ~(1 << 17);
writel(val, corebase + 0xc2c0);
iounmap(corebase);
}
static int __init nlm_platform_xlpii_usb_init(void)
{
if (!cpu_is_xlpii())
return 0;
pr_info("Initializing 2XX USB Interface\n");
nlm_xlpii_usb_hw_reset(0, 1);
nlm_xlpii_usb_hw_reset(0, 2);
nlm_xlpii_usb_hw_reset(0, 3);
nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_0_IRQ, xlpii_usb_ack);
nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_1_IRQ, xlpii_usb_ack);
nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_2_IRQ, xlpii_usb_ack);
return 0;
}
arch_initcall(nlm_platform_xlpii_usb_init);
static u64 xlp_usb_dmamask = ~(u32)0;
/* Fixup IRQ for USB devices on XLP the SoC PCIe bus */
static void nlm_usb_fixup_final(struct pci_dev *dev)
{
dev->dev.dma_mask = &xlp_usb_dmamask;
dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
switch (dev->devfn) {
case 0x21:
dev->irq = PIC_2XX_XHCI_0_IRQ;
break;
case 0x22:
dev->irq = PIC_2XX_XHCI_1_IRQ;
break;
case 0x23:
dev->irq = PIC_2XX_XHCI_2_IRQ;
break;
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_NETLOGIC, PCI_DEVICE_ID_NLM_XHCI,
nlm_usb_fixup_final);
......@@ -75,8 +75,7 @@ static void nlm_usb_intr_en(int node, int port)
port_addr = nlm_get_usb_regbase(node, port);
val = nlm_read_usb_reg(port_addr, USB_INT_EN);
val = USB_CTRL_INTERRUPT_EN | USB_OHCI_INTERRUPT_EN |
USB_OHCI_INTERRUPT1_EN | USB_CTRL_INTERRUPT_EN |
USB_OHCI_INTERRUPT_EN | USB_OHCI_INTERRUPT2_EN;
USB_OHCI_INTERRUPT1_EN | USB_OHCI_INTERRUPT2_EN;
nlm_write_usb_reg(port_addr, USB_INT_EN, val);
}
......@@ -100,6 +99,9 @@ static void nlm_usb_hw_reset(int node, int port)
static int __init nlm_platform_usb_init(void)
{
if (cpu_is_xlpii())
return 0;
pr_info("Initializing USB Interface\n");
nlm_usb_hw_reset(0, 0);
nlm_usb_hw_reset(0, 3);
......
......@@ -58,10 +58,12 @@ static int xlp_wakeup_core(uint64_t sysbase, int node, int core)
coremask = (1 << core);
/* Enable CPU clock */
/* Enable CPU clock in case of 8xx/3xx */
if (!cpu_is_xlpii()) {
value = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL);
value &= ~coremask;
nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value);
}
/* Remove CPU Reset */
value = nlm_read_sys_reg(sysbase, SYS_CPU_RESET);
......
......@@ -41,6 +41,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o
obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
......
......@@ -586,15 +586,16 @@ static int __init octeon_pci_setup(void)
else
octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_BIG;
/* PCI I/O and PCI MEM values */
set_io_port_base(OCTEON_PCI_IOSPACE_BASE);
ioport_resource.start = 0;
ioport_resource.end = OCTEON_PCI_IOSPACE_SIZE - 1;
if (!octeon_is_pci_host()) {
pr_notice("Not in host mode, PCI Controller not initialized\n");
return 0;
}
/* PCI I/O and PCI MEM values */
set_io_port_base(OCTEON_PCI_IOSPACE_BASE);
ioport_resource.start = 0;
ioport_resource.end = OCTEON_PCI_IOSPACE_SIZE - 1;
pr_notice("%s Octeon big bar support\n",
(octeon_dma_bar_type ==
OCTEON_DMA_BAR_TYPE_BIG) ? "Enabling" : "Disabling");
......
/*
* Ralink RT3662/RT3883 SoC PCI support
*
* Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
*
* Parts of this file are based on Ralink's 2.6.21 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/types.h>
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_pci.h>
#include <linux/platform_device.h>
#include <asm/mach-ralink/rt3883.h>
#include <asm/mach-ralink/ralink_regs.h>
#define RT3883_MEMORY_BASE 0x00000000
#define RT3883_MEMORY_SIZE 0x02000000
#define RT3883_PCI_REG_PCICFG 0x00
#define RT3883_PCICFG_P2P_BR_DEVNUM_M 0xf
#define RT3883_PCICFG_P2P_BR_DEVNUM_S 16
#define RT3883_PCICFG_PCIRST BIT(1)
#define RT3883_PCI_REG_PCIRAW 0x04
#define RT3883_PCI_REG_PCIINT 0x08
#define RT3883_PCI_REG_PCIENA 0x0c
#define RT3883_PCI_REG_CFGADDR 0x20
#define RT3883_PCI_REG_CFGDATA 0x24
#define RT3883_PCI_REG_MEMBASE 0x28
#define RT3883_PCI_REG_IOBASE 0x2c
#define RT3883_PCI_REG_ARBCTL 0x80
#define RT3883_PCI_REG_BASE(_x) (0x1000 + (_x) * 0x1000)
#define RT3883_PCI_REG_BAR0SETUP(_x) (RT3883_PCI_REG_BASE((_x)) + 0x10)
#define RT3883_PCI_REG_IMBASEBAR0(_x) (RT3883_PCI_REG_BASE((_x)) + 0x18)
#define RT3883_PCI_REG_ID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x30)
#define RT3883_PCI_REG_CLASS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x34)
#define RT3883_PCI_REG_SUBID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x38)
#define RT3883_PCI_REG_STATUS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x50)
#define RT3883_PCI_MODE_NONE 0
#define RT3883_PCI_MODE_PCI BIT(0)
#define RT3883_PCI_MODE_PCIE BIT(1)
#define RT3883_PCI_MODE_BOTH (RT3883_PCI_MODE_PCI | RT3883_PCI_MODE_PCIE)
#define RT3883_PCI_IRQ_COUNT 32
#define RT3883_P2P_BR_DEVNUM 1
struct rt3883_pci_controller {
void __iomem *base;
spinlock_t lock;
struct device_node *intc_of_node;
struct irq_domain *irq_domain;
struct pci_controller pci_controller;
struct resource io_res;
struct resource mem_res;
bool pcie_ready;
};
static inline struct rt3883_pci_controller *
pci_bus_to_rt3883_controller(struct pci_bus *bus)
{
struct pci_controller *hose;
hose = (struct pci_controller *) bus->sysdata;
return container_of(hose, struct rt3883_pci_controller, pci_controller);
}
static inline u32 rt3883_pci_r32(struct rt3883_pci_controller *rpc,
unsigned reg)
{
return ioread32(rpc->base + reg);
}
static inline void rt3883_pci_w32(struct rt3883_pci_controller *rpc,
u32 val, unsigned reg)
{
iowrite32(val, rpc->base + reg);
}
static inline u32 rt3883_pci_get_cfgaddr(unsigned int bus, unsigned int slot,
unsigned int func, unsigned int where)
{
return (bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) |
0x80000000;
}
static u32 rt3883_pci_read_cfg32(struct rt3883_pci_controller *rpc,
unsigned bus, unsigned slot,
unsigned func, unsigned reg)
{
unsigned long flags;
u32 address;
u32 ret;
address = rt3883_pci_get_cfgaddr(bus, slot, func, reg);
spin_lock_irqsave(&rpc->lock, flags);
rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA);
spin_unlock_irqrestore(&rpc->lock, flags);
return ret;
}
static void rt3883_pci_write_cfg32(struct rt3883_pci_controller *rpc,
unsigned bus, unsigned slot,
unsigned func, unsigned reg, u32 val)
{
unsigned long flags;
u32 address;
address = rt3883_pci_get_cfgaddr(bus, slot, func, reg);
spin_lock_irqsave(&rpc->lock, flags);
rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA);
spin_unlock_irqrestore(&rpc->lock, flags);
}
static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
{
struct rt3883_pci_controller *rpc;
u32 pending;
rpc = irq_get_handler_data(irq);
pending = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIINT) &
rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA);
if (!pending) {
spurious_interrupt();
return;
}
while (pending) {
unsigned bit = __ffs(pending);
irq = irq_find_mapping(rpc->irq_domain, bit);
generic_handle_irq(irq);
pending &= ~BIT(bit);
}
}
static void rt3883_pci_irq_unmask(struct irq_data *d)
{
struct rt3883_pci_controller *rpc;
u32 t;
rpc = irq_data_get_irq_chip_data(d);
t = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA);
rt3883_pci_w32(rpc, t | BIT(d->hwirq), RT3883_PCI_REG_PCIENA);
/* flush write */
rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA);
}
static void rt3883_pci_irq_mask(struct irq_data *d)
{
struct rt3883_pci_controller *rpc;
u32 t;
rpc = irq_data_get_irq_chip_data(d);
t = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA);
rt3883_pci_w32(rpc, t & ~BIT(d->hwirq), RT3883_PCI_REG_PCIENA);
/* flush write */
rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA);
}
static struct irq_chip rt3883_pci_irq_chip = {
.name = "RT3883 PCI",
.irq_mask = rt3883_pci_irq_mask,
.irq_unmask = rt3883_pci_irq_unmask,
.irq_mask_ack = rt3883_pci_irq_mask,
};
static int rt3883_pci_irq_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw)
{
irq_set_chip_and_handler(irq, &rt3883_pci_irq_chip, handle_level_irq);
irq_set_chip_data(irq, d->host_data);
return 0;
}
static const struct irq_domain_ops rt3883_pci_irq_domain_ops = {
.map = rt3883_pci_irq_map,
.xlate = irq_domain_xlate_onecell,
};
static int rt3883_pci_irq_init(struct device *dev,
struct rt3883_pci_controller *rpc)
{
int irq;
irq = irq_of_parse_and_map(rpc->intc_of_node, 0);
if (irq == 0) {
dev_err(dev, "%s has no IRQ",
of_node_full_name(rpc->intc_of_node));
return -EINVAL;
}
/* disable all interrupts */
rt3883_pci_w32(rpc, 0, RT3883_PCI_REG_PCIENA);
rpc->irq_domain =
irq_domain_add_linear(rpc->intc_of_node, RT3883_PCI_IRQ_COUNT,
&rt3883_pci_irq_domain_ops,
rpc);
if (!rpc->irq_domain) {
dev_err(dev, "unable to add IRQ domain\n");
return -ENODEV;
}
irq_set_handler_data(irq, rpc);
irq_set_chained_handler(irq, rt3883_pci_irq_handler);
return 0;
}
static int rt3883_pci_config_read(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
struct rt3883_pci_controller *rpc;
unsigned long flags;
u32 address;
u32 data;
rpc = pci_bus_to_rt3883_controller(bus);
if (!rpc->pcie_ready && bus->number == 1)
return PCIBIOS_DEVICE_NOT_FOUND;
address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where);
spin_lock_irqsave(&rpc->lock, flags);
rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA);
spin_unlock_irqrestore(&rpc->lock, flags);
switch (size) {
case 1:
*val = (data >> ((where & 3) << 3)) & 0xff;
break;
case 2:
*val = (data >> ((where & 3) << 3)) & 0xffff;
break;
case 4:
*val = data;
break;
}
return PCIBIOS_SUCCESSFUL;
}
static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 val)
{
struct rt3883_pci_controller *rpc;
unsigned long flags;
u32 address;
u32 data;
rpc = pci_bus_to_rt3883_controller(bus);
if (!rpc->pcie_ready && bus->number == 1)
return PCIBIOS_DEVICE_NOT_FOUND;
address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where);
spin_lock_irqsave(&rpc->lock, flags);
rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA);
switch (size) {
case 1:
data = (data & ~(0xff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
break;
case 2:
data = (data & ~(0xffff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
break;
case 4:
data = val;
break;
}
rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA);
spin_unlock_irqrestore(&rpc->lock, flags);
return PCIBIOS_SUCCESSFUL;
}
static struct pci_ops rt3883_pci_ops = {
.read = rt3883_pci_config_read,
.write = rt3883_pci_config_write,
};
static void rt3883_pci_preinit(struct rt3883_pci_controller *rpc, unsigned mode)
{
u32 syscfg1;
u32 rstctrl;
u32 clkcfg1;
u32 t;
rstctrl = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL);
syscfg1 = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1);
clkcfg1 = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1);
if (mode & RT3883_PCI_MODE_PCIE) {
rstctrl |= RT3883_RSTCTRL_PCIE;
rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL);
/* setup PCI PAD drive mode */
syscfg1 &= ~(0x30);
syscfg1 |= (2 << 4);
rt_sysc_w32(syscfg1, RT3883_SYSC_REG_SYSCFG1);
t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0);
t &= ~BIT(31);
rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0);
t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN1);
t &= 0x80ffffff;
rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN1);
t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN1);
t |= 0xa << 24;
rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN1);
t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0);
t |= BIT(31);
rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0);
msleep(50);
rstctrl &= ~RT3883_RSTCTRL_PCIE;
rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL);
}
syscfg1 |= (RT3883_SYSCFG1_PCIE_RC_MODE | RT3883_SYSCFG1_PCI_HOST_MODE);
clkcfg1 &= ~(RT3883_CLKCFG1_PCI_CLK_EN | RT3883_CLKCFG1_PCIE_CLK_EN);
if (mode & RT3883_PCI_MODE_PCI) {
clkcfg1 |= RT3883_CLKCFG1_PCI_CLK_EN;
rstctrl &= ~RT3883_RSTCTRL_PCI;
}
if (mode & RT3883_PCI_MODE_PCIE) {
clkcfg1 |= RT3883_CLKCFG1_PCIE_CLK_EN;
rstctrl &= ~RT3883_RSTCTRL_PCIE;
}
rt_sysc_w32(syscfg1, RT3883_SYSC_REG_SYSCFG1);
rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL);
rt_sysc_w32(clkcfg1, RT3883_SYSC_REG_CLKCFG1);
msleep(500);
/*
* setup the device number of the P2P bridge
* and de-assert the reset line
*/
t = (RT3883_P2P_BR_DEVNUM << RT3883_PCICFG_P2P_BR_DEVNUM_S);
rt3883_pci_w32(rpc, t, RT3883_PCI_REG_PCICFG);
/* flush write */
rt3883_pci_r32(rpc, RT3883_PCI_REG_PCICFG);
msleep(500);
if (mode & RT3883_PCI_MODE_PCIE) {
msleep(500);
t = rt3883_pci_r32(rpc, RT3883_PCI_REG_STATUS(1));
rpc->pcie_ready = t & BIT(0);
if (!rpc->pcie_ready) {
/* reset the PCIe block */
t = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL);
t |= RT3883_RSTCTRL_PCIE;
rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL);
t &= ~RT3883_RSTCTRL_PCIE;
rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL);
/* turn off PCIe clock */
t = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1);
t &= ~RT3883_CLKCFG1_PCIE_CLK_EN;
rt_sysc_w32(t, RT3883_SYSC_REG_CLKCFG1);
t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0);
t &= ~0xf000c080;
rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0);
}
}
/* enable PCI arbiter */
rt3883_pci_w32(rpc, 0x79, RT3883_PCI_REG_ARBCTL);
}
static int rt3883_pci_probe(struct platform_device *pdev)
{
struct rt3883_pci_controller *rpc;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct resource *res;
struct device_node *child;
u32 val;
int err;
int mode;
rpc = devm_kzalloc(dev, sizeof(*rpc), GFP_KERNEL);
if (!rpc)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -EINVAL;
rpc->base = devm_ioremap_resource(dev, res);
if (IS_ERR(rpc->base))
return PTR_ERR(rpc->base);
/* find the interrupt controller child node */
for_each_child_of_node(np, child) {
if (of_get_property(child, "interrupt-controller", NULL) &&
of_node_get(child)) {
rpc->intc_of_node = child;
break;
}
}
if (!rpc->intc_of_node) {
dev_err(dev, "%s has no %s child node",
of_node_full_name(rpc->intc_of_node),
"interrupt controller");
return -EINVAL;
}
/* find the PCI host bridge child node */
for_each_child_of_node(np, child) {
if (child->type &&
of_node_cmp(child->type, "pci") == 0 &&
of_node_get(child)) {
rpc->pci_controller.of_node = child;
break;
}
}
if (!rpc->pci_controller.of_node) {
dev_err(dev, "%s has no %s child node",
of_node_full_name(rpc->intc_of_node),
"PCI host bridge");
err = -EINVAL;
goto err_put_intc_node;
}
mode = RT3883_PCI_MODE_NONE;
for_each_available_child_of_node(rpc->pci_controller.of_node, child) {
int devfn;
if (!child->type ||
of_node_cmp(child->type, "pci") != 0)
continue;
devfn = of_pci_get_devfn(child);
if (devfn < 0)
continue;
switch (PCI_SLOT(devfn)) {
case 1:
mode |= RT3883_PCI_MODE_PCIE;
break;
case 17:
case 18:
mode |= RT3883_PCI_MODE_PCI;
break;
}
}
if (mode == RT3883_PCI_MODE_NONE) {
dev_err(dev, "unable to determine PCI mode\n");
err = -EINVAL;
goto err_put_hb_node;
}
dev_info(dev, "mode:%s%s\n",
(mode & RT3883_PCI_MODE_PCI) ? " PCI" : "",
(mode & RT3883_PCI_MODE_PCIE) ? " PCIe" : "");
rt3883_pci_preinit(rpc, mode);
rpc->pci_controller.pci_ops = &rt3883_pci_ops;
rpc->pci_controller.io_resource = &rpc->io_res;
rpc->pci_controller.mem_resource = &rpc->mem_res;
/* Load PCI I/O and memory resources from DT */
pci_load_of_ranges(&rpc->pci_controller,
rpc->pci_controller.of_node);
rt3883_pci_w32(rpc, rpc->mem_res.start, RT3883_PCI_REG_MEMBASE);
rt3883_pci_w32(rpc, rpc->io_res.start, RT3883_PCI_REG_IOBASE);
ioport_resource.start = rpc->io_res.start;
ioport_resource.end = rpc->io_res.end;
/* PCI */
rt3883_pci_w32(rpc, 0x03ff0000, RT3883_PCI_REG_BAR0SETUP(0));
rt3883_pci_w32(rpc, RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0(0));
rt3883_pci_w32(rpc, 0x08021814, RT3883_PCI_REG_ID(0));
rt3883_pci_w32(rpc, 0x00800001, RT3883_PCI_REG_CLASS(0));
rt3883_pci_w32(rpc, 0x28801814, RT3883_PCI_REG_SUBID(0));
/* PCIe */
rt3883_pci_w32(rpc, 0x03ff0000, RT3883_PCI_REG_BAR0SETUP(1));
rt3883_pci_w32(rpc, RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0(1));
rt3883_pci_w32(rpc, 0x08021814, RT3883_PCI_REG_ID(1));
rt3883_pci_w32(rpc, 0x06040001, RT3883_PCI_REG_CLASS(1));
rt3883_pci_w32(rpc, 0x28801814, RT3883_PCI_REG_SUBID(1));
err = rt3883_pci_irq_init(dev, rpc);
if (err)
goto err_put_hb_node;
/* PCIe */
val = rt3883_pci_read_cfg32(rpc, 0, 0x01, 0, PCI_COMMAND);
val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
rt3883_pci_write_cfg32(rpc, 0, 0x01, 0, PCI_COMMAND, val);
/* PCI */
val = rt3883_pci_read_cfg32(rpc, 0, 0x00, 0, PCI_COMMAND);
val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
rt3883_pci_write_cfg32(rpc, 0, 0x00, 0, PCI_COMMAND, val);
if (mode == RT3883_PCI_MODE_PCIE) {
rt3883_pci_w32(rpc, 0x03ff0001, RT3883_PCI_REG_BAR0SETUP(0));
rt3883_pci_w32(rpc, 0x03ff0001, RT3883_PCI_REG_BAR0SETUP(1));
rt3883_pci_write_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0,
PCI_BASE_ADDRESS_0,
RT3883_MEMORY_BASE);
/* flush write */
rt3883_pci_read_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0,
PCI_BASE_ADDRESS_0);
} else {
rt3883_pci_write_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0,
PCI_IO_BASE, 0x00000101);
}
register_pci_controller(&rpc->pci_controller);
return 0;
err_put_hb_node:
of_node_put(rpc->pci_controller.of_node);
err_put_intc_node:
of_node_put(rpc->intc_of_node);
return err;
}
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
struct of_irq dev_irq;
int err;
int irq;
err = of_irq_map_pci(dev, &dev_irq);
if (err) {
pr_err("pci %s: unable to get irq map, err=%d\n",
pci_name((struct pci_dev *) dev), err);
return 0;
}
irq = irq_create_of_mapping(dev_irq.controller,
dev_irq.specifier,
dev_irq.size);
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)
{
return 0;
}
static const struct of_device_id rt3883_pci_ids[] = {
{ .compatible = "ralink,rt3883-pci" },
{},
};
MODULE_DEVICE_TABLE(of, rt3883_pci_ids);
static struct platform_driver rt3883_pci_driver = {
.probe = rt3883_pci_probe,
.driver = {
.name = "rt3883-pci",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(rt3883_pci_ids),
},
};
static int __init rt3883_pci_init(void)
{
return platform_driver_register(&rt3883_pci_driver);
}
postcore_initcall(rt3883_pci_init);
config BOOTLOADER_DRIVER
bool "PowerTV Bootloader Driver Support"
default n
depends on POWERTV
help
Use this option if you want to load bootloader driver.
config BOOTLOADER_FAMILY
string "POWERTV Bootloader Family string"
default "85"
depends on POWERTV && !BOOTLOADER_DRIVER
depends on POWERTV
help
This value should be specified when the bootloader driver is disabled
and must be exactly two characters long. Families supported are:
......
......@@ -147,20 +147,10 @@ static __init noinline void platform_set_family(void)
if (check_forcefamily(forced_family) == 0)
bootldr_family = BOOTLDRFAMILY(forced_family[0],
forced_family[1]);
else {
#ifdef CONFIG_BOOTLOADER_DRIVER
bootldr_family = (unsigned short) kbldr_GetSWFamily();
#else
#if defined(CONFIG_BOOTLOADER_FAMILY)
else
bootldr_family = (unsigned short) BOOTLDRFAMILY(
CONFIG_BOOTLOADER_FAMILY[0],
CONFIG_BOOTLOADER_FAMILY[1]);
#else
#error "Unknown Bootloader Family"
#endif
#endif
}
pr_info("Bootloader Family = 0x%04X\n", bootldr_family);
......
......@@ -87,8 +87,4 @@ void __init prom_init(void)
configure_platform();
prom_meminit();
#ifndef CONFIG_BOOTLOADER_DRIVER
pr_info("\nBootloader driver isn't loaded...\n");
#endif
}
......@@ -21,24 +21,12 @@
#include <linux/io.h>
#include <asm/reboot.h> /* Not included by linux/reboot.h */
#ifdef CONFIG_BOOTLOADER_DRIVER
#include <asm/mach-powertv/kbldr.h>
#endif
#include <asm/mach-powertv/asic_regs.h>
#include "reset.h"
static void mips_machine_restart(char *command)
{
#ifdef CONFIG_BOOTLOADER_DRIVER
/*
* Call the bootloader's reset function to ensure
* that persistent data is flushed before hard reset
*/
kbldr_SetCauseAndReset();
#else
writel(0x1, asic_reg_addr(watchdog));
#endif
}
void mips_reboot_setup(void)
......
if RALINK
config CLKEVT_RT3352
bool
depends on SOC_RT305X || SOC_MT7620
default y
select CLKSRC_OF
select CLKSRC_MMIO
choice
prompt "Ralink SoC selection"
default SOC_RT305X
......@@ -19,9 +26,12 @@ choice
bool "RT3883"
select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI
select HW_HAS_PCI
config SOC_MT7620
bool "MT7620"
select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI
endchoice
......
......@@ -6,7 +6,9 @@
# Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
# Copyright (C) 2013 John Crispin <blogic@openwrt.org>
obj-y := prom.o of.o reset.o clk.o irq.o
obj-y := prom.o of.o reset.o clk.o irq.o timer.o
obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o
obj-$(CONFIG_SOC_RT288X) += rt288x.o
obj-$(CONFIG_SOC_RT305X) += rt305x.o
......
......@@ -26,3 +26,4 @@ cflags-$(CONFIG_SOC_RT3883) += -I$(srctree)/arch/mips/include/asm/mach-ralink/rt
# Ralink MT7620
#
load-$(CONFIG_SOC_MT7620) += 0xffffffff80000000
cflags-$(CONFIG_SOC_MT7620) += -I$(srctree)/arch/mips/include/asm/mach-ralink/mt7620
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2013 by John Crispin <blogic@openwrt.org>
*/
#include <linux/clockchips.h>
#include <linux/clocksource.h>
#include <linux/interrupt.h>
#include <linux/reset.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <asm/mach-ralink/ralink_regs.h>
#define SYSTICK_FREQ (50 * 1000)
#define SYSTICK_CONFIG 0x00
#define SYSTICK_COMPARE 0x04
#define SYSTICK_COUNT 0x08
/* route systick irq to mips irq 7 instead of the r4k-timer */
#define CFG_EXT_STK_EN 0x2
/* enable the counter */
#define CFG_CNT_EN 0x1
struct systick_device {
void __iomem *membase;
struct clock_event_device dev;
int irq_requested;
int freq_scale;
};
static void systick_set_clock_mode(enum clock_event_mode mode,
struct clock_event_device *evt);
static int systick_next_event(unsigned long delta,
struct clock_event_device *evt)
{
struct systick_device *sdev;
u32 count;
sdev = container_of(evt, struct systick_device, dev);
count = ioread32(sdev->membase + SYSTICK_COUNT);
count = (count + delta) % SYSTICK_FREQ;
iowrite32(count + delta, sdev->membase + SYSTICK_COMPARE);
return 0;
}
static void systick_event_handler(struct clock_event_device *dev)
{
/* noting to do here */
}
static irqreturn_t systick_interrupt(int irq, void *dev_id)
{
struct clock_event_device *dev = (struct clock_event_device *) dev_id;
dev->event_handler(dev);
return IRQ_HANDLED;
}
static struct systick_device systick = {
.dev = {
/*
* cevt-r4k uses 300, make sure systick
* gets used if available
*/
.rating = 310,
.features = CLOCK_EVT_FEAT_ONESHOT,
.set_next_event = systick_next_event,
.set_mode = systick_set_clock_mode,
.event_handler = systick_event_handler,
},
};
static struct irqaction systick_irqaction = {
.handler = systick_interrupt,
.flags = IRQF_PERCPU | IRQF_TIMER,
.dev_id = &systick.dev,
};
static void systick_set_clock_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
struct systick_device *sdev;
sdev = container_of(evt, struct systick_device, dev);
switch (mode) {
case CLOCK_EVT_MODE_ONESHOT:
if (!sdev->irq_requested)
setup_irq(systick.dev.irq, &systick_irqaction);
sdev->irq_requested = 1;
iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,
systick.membase + SYSTICK_CONFIG);
break;
case CLOCK_EVT_MODE_SHUTDOWN:
if (sdev->irq_requested)
free_irq(systick.dev.irq, &systick_irqaction);
sdev->irq_requested = 0;
iowrite32(0, systick.membase + SYSTICK_CONFIG);
break;
default:
pr_err("%s: Unhandeled mips clock_mode\n", systick.dev.name);
break;
}
}
static void __init ralink_systick_init(struct device_node *np)
{
systick.membase = of_iomap(np, 0);
if (!systick.membase)
return;
systick_irqaction.name = np->name;
systick.dev.name = np->name;
clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev);
systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev);
systick.dev.irq = irq_of_parse_and_map(np, 0);
if (!systick.dev.irq) {
pr_err("%s: request_irq failed", np->name);
return;
}
clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
SYSTICK_FREQ, 301, 16, clocksource_mmio_readl_up);
clockevents_register_device(&systick.dev);
pr_info("%s: runing - mult: %d, shift: %d\n",
np->name, systick.dev.mult, systick.dev.shift);
}
CLOCKSOURCE_OF_DECLARE(systick, "ralink,cevt-systick", ralink_systick_init);
......@@ -69,4 +69,5 @@ void __init plat_time_init(void)
pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
mips_hpt_frequency = clk_get_rate(clk) / 2;
clk_put(clk);
clocksource_of_init();
}
......@@ -46,6 +46,8 @@ extern void ralink_of_remap(void);
extern void ralink_clk_init(void);
extern void ralink_clk_add(const char *dev, unsigned long rate);
extern void ralink_rst_init(void);
extern void prom_soc_init(struct ralink_soc_info *soc_info);
__iomem void *plat_of_remap_node(const char *node);
......
......@@ -23,9 +23,6 @@
/* does the board have sdram or ddram */
static int dram_type;
/* the pll dividers */
static u32 mt7620_clk_divider[] = { 2, 3, 4, 8 };
static struct ralink_pinmux_grp mode_mux[] = {
{
.name = "i2c",
......@@ -140,34 +137,189 @@ struct ralink_pinmux rt_gpio_pinmux = {
.uart_mask = MT7620_GPIO_MODE_UART0_MASK,
};
void __init ralink_clk_init(void)
static __init u32
mt7620_calc_rate(u32 ref_rate, u32 mul, u32 div)
{
unsigned long cpu_rate, sys_rate;
u32 c0 = rt_sysc_r32(SYSC_REG_CPLL_CONFIG0);
u32 c1 = rt_sysc_r32(SYSC_REG_CPLL_CONFIG1);
u32 swconfig = (c0 >> CPLL_SW_CONFIG_SHIFT) & CPLL_SW_CONFIG_MASK;
u32 cpu_clk = (c1 >> CPLL_CPU_CLK_SHIFT) & CPLL_CPU_CLK_MASK;
if (cpu_clk) {
cpu_rate = 480000000;
} else if (!swconfig) {
cpu_rate = 600000000;
} else {
u32 m = (c0 >> CPLL_MULT_RATIO_SHIFT) & CPLL_MULT_RATIO;
u32 d = (c0 >> CPLL_DIV_RATIO_SHIFT) & CPLL_DIV_RATIO;
u64 t;
cpu_rate = ((40 * (m + 24)) / mt7620_clk_divider[d]) * 1000000;
}
t = ref_rate;
t *= mul;
do_div(t, div);
return t;
}
#define MHZ(x) ((x) * 1000 * 1000)
static __init unsigned long
mt7620_get_xtal_rate(void)
{
u32 reg;
reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
if (reg & SYSCFG0_XTAL_FREQ_SEL)
return MHZ(40);
return MHZ(20);
}
static __init unsigned long
mt7620_get_periph_rate(unsigned long xtal_rate)
{
u32 reg;
reg = rt_sysc_r32(SYSC_REG_CLKCFG0);
if (reg & CLKCFG0_PERI_CLK_SEL)
return xtal_rate;
return MHZ(40);
}
static const u32 mt7620_clk_divider[] __initconst = { 2, 3, 4, 8 };
static __init unsigned long
mt7620_get_cpu_pll_rate(unsigned long xtal_rate)
{
u32 reg;
u32 mul;
u32 div;
reg = rt_sysc_r32(SYSC_REG_CPLL_CONFIG0);
if (reg & CPLL_CFG0_BYPASS_REF_CLK)
return xtal_rate;
if ((reg & CPLL_CFG0_SW_CFG) == 0)
return MHZ(600);
mul = (reg >> CPLL_CFG0_PLL_MULT_RATIO_SHIFT) &
CPLL_CFG0_PLL_MULT_RATIO_MASK;
mul += 24;
if (reg & CPLL_CFG0_LC_CURFCK)
mul *= 2;
div = (reg >> CPLL_CFG0_PLL_DIV_RATIO_SHIFT) &
CPLL_CFG0_PLL_DIV_RATIO_MASK;
WARN_ON(div >= ARRAY_SIZE(mt7620_clk_divider));
return mt7620_calc_rate(xtal_rate, mul, mt7620_clk_divider[div]);
}
static __init unsigned long
mt7620_get_pll_rate(unsigned long xtal_rate, unsigned long cpu_pll_rate)
{
u32 reg;
reg = rt_sysc_r32(SYSC_REG_CPLL_CONFIG1);
if (reg & CPLL_CFG1_CPU_AUX1)
return xtal_rate;
if (reg & CPLL_CFG1_CPU_AUX0)
return MHZ(480);
return cpu_pll_rate;
}
static __init unsigned long
mt7620_get_cpu_rate(unsigned long pll_rate)
{
u32 reg;
u32 mul;
u32 div;
reg = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG);
mul = reg & CPU_SYS_CLKCFG_CPU_FFRAC_MASK;
div = (reg >> CPU_SYS_CLKCFG_CPU_FDIV_SHIFT) &
CPU_SYS_CLKCFG_CPU_FDIV_MASK;
return mt7620_calc_rate(pll_rate, mul, div);
}
static const u32 mt7620_ocp_dividers[16] __initconst = {
[CPU_SYS_CLKCFG_OCP_RATIO_2] = 2,
[CPU_SYS_CLKCFG_OCP_RATIO_3] = 3,
[CPU_SYS_CLKCFG_OCP_RATIO_4] = 4,
[CPU_SYS_CLKCFG_OCP_RATIO_5] = 5,
[CPU_SYS_CLKCFG_OCP_RATIO_10] = 10,
};
static __init unsigned long
mt7620_get_dram_rate(unsigned long pll_rate)
{
if (dram_type == SYSCFG0_DRAM_TYPE_SDRAM)
sys_rate = cpu_rate / 4;
else
sys_rate = cpu_rate / 3;
return pll_rate / 4;
return pll_rate / 3;
}
static __init unsigned long
mt7620_get_sys_rate(unsigned long cpu_rate)
{
u32 reg;
u32 ocp_ratio;
u32 div;
reg = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG);
ocp_ratio = (reg >> CPU_SYS_CLKCFG_OCP_RATIO_SHIFT) &
CPU_SYS_CLKCFG_OCP_RATIO_MASK;
if (WARN_ON(ocp_ratio >= ARRAY_SIZE(mt7620_ocp_dividers)))
return cpu_rate;
div = mt7620_ocp_dividers[ocp_ratio];
if (WARN(!div, "invalid divider for OCP ratio %u", ocp_ratio))
return cpu_rate;
return cpu_rate / div;
}
void __init ralink_clk_init(void)
{
unsigned long xtal_rate;
unsigned long cpu_pll_rate;
unsigned long pll_rate;
unsigned long cpu_rate;
unsigned long sys_rate;
unsigned long dram_rate;
unsigned long periph_rate;
xtal_rate = mt7620_get_xtal_rate();
cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate);
pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate);
cpu_rate = mt7620_get_cpu_rate(pll_rate);
dram_rate = mt7620_get_dram_rate(pll_rate);
sys_rate = mt7620_get_sys_rate(cpu_rate);
periph_rate = mt7620_get_periph_rate(xtal_rate);
#define RFMT(label) label ":%lu.%03luMHz "
#define RINT(x) ((x) / 1000000)
#define RFRAC(x) (((x) / 1000) % 1000)
pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"),
RINT(xtal_rate), RFRAC(xtal_rate),
RINT(cpu_pll_rate), RFRAC(cpu_pll_rate),
RINT(pll_rate), RFRAC(pll_rate));
pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"),
RINT(cpu_rate), RFRAC(cpu_rate),
RINT(dram_rate), RFRAC(dram_rate),
RINT(sys_rate), RFRAC(sys_rate),
RINT(periph_rate), RFRAC(periph_rate));
#undef RFRAC
#undef RINT
#undef RFMT
ralink_clk_add("cpu", cpu_rate);
ralink_clk_add("10000100.timer", 40000000);
ralink_clk_add("10000500.uart", 40000000);
ralink_clk_add("10000c00.uartlite", 40000000);
ralink_clk_add("10000100.timer", periph_rate);
ralink_clk_add("10000120.watchdog", periph_rate);
ralink_clk_add("10000500.uart", periph_rate);
ralink_clk_add("10000b00.spi", sys_rate);
ralink_clk_add("10000c00.uartlite", periph_rate);
}
void __init ralink_of_remap(void)
......@@ -214,16 +366,19 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
switch (dram_type) {
case SYSCFG0_DRAM_TYPE_SDRAM:
pr_info("Board has SDRAM\n");
soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN;
soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX;
break;
case SYSCFG0_DRAM_TYPE_DDR1:
pr_info("Board has DDR1\n");
soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN;
soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX;
break;
case SYSCFG0_DRAM_TYPE_DDR2:
pr_info("Board has DDR2\n");
soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN;
soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX;
break;
......
......@@ -110,6 +110,9 @@ static int __init plat_of_setup(void)
if (of_platform_populate(NULL, of_ids, NULL, NULL))
panic("failed to populate DT\n");
/* make sure ithat the reset controller is setup early */
ralink_rst_init();
return 0;
}
......
......@@ -10,6 +10,8 @@
#include <linux/pm.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/reset-controller.h>
#include <asm/reboot.h>
......@@ -19,6 +21,66 @@
#define SYSC_REG_RESET_CTRL 0x034
#define RSTCTL_RESET_SYSTEM BIT(0)
static int ralink_assert_device(struct reset_controller_dev *rcdev,
unsigned long id)
{
u32 val;
if (id < 8)
return -1;
val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
val |= BIT(id);
rt_sysc_w32(val, SYSC_REG_RESET_CTRL);
return 0;
}
static int ralink_deassert_device(struct reset_controller_dev *rcdev,
unsigned long id)
{
u32 val;
if (id < 8)
return -1;
val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
val &= ~BIT(id);
rt_sysc_w32(val, SYSC_REG_RESET_CTRL);
return 0;
}
static int ralink_reset_device(struct reset_controller_dev *rcdev,
unsigned long id)
{
ralink_assert_device(rcdev, id);
return ralink_deassert_device(rcdev, id);
}
static struct reset_control_ops reset_ops = {
.reset = ralink_reset_device,
.assert = ralink_assert_device,
.deassert = ralink_deassert_device,
};
static struct reset_controller_dev reset_dev = {
.ops = &reset_ops,
.owner = THIS_MODULE,
.nr_resets = 32,
.of_reset_n_cells = 1,
};
void ralink_rst_init(void)
{
reset_dev.of_node = of_find_compatible_node(NULL, NULL,
"ralink,rt2880-reset");
if (!reset_dev.of_node)
pr_err("Failed to find reset controller node");
else
reset_controller_register(&reset_dev);
}
static void ralink_restart(char *command)
{
local_irq_disable();
......
/*
* 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) 2013 John Crispin <blogic@openwrt.org>
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <linux/of_gpio.h>
#include <linux/clk.h>
#include <asm/mach-ralink/ralink_regs.h>
#define TIMER_REG_TMRSTAT 0x00
#define TIMER_REG_TMR0LOAD 0x10
#define TIMER_REG_TMR0CTL 0x18
#define TMRSTAT_TMR0INT BIT(0)
#define TMR0CTL_ENABLE BIT(7)
#define TMR0CTL_MODE_PERIODIC BIT(4)
#define TMR0CTL_PRESCALER 1
#define TMR0CTL_PRESCALE_VAL (0xf - TMR0CTL_PRESCALER)
#define TMR0CTL_PRESCALE_DIV (65536 / BIT(TMR0CTL_PRESCALER))
struct rt_timer {
struct device *dev;
void __iomem *membase;
int irq;
unsigned long timer_freq;
unsigned long timer_div;
};
static inline void rt_timer_w32(struct rt_timer *rt, u8 reg, u32 val)
{
__raw_writel(val, rt->membase + reg);
}
static inline u32 rt_timer_r32(struct rt_timer *rt, u8 reg)
{
return __raw_readl(rt->membase + reg);
}
static irqreturn_t rt_timer_irq(int irq, void *_rt)
{
struct rt_timer *rt = (struct rt_timer *) _rt;
rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div);
rt_timer_w32(rt, TIMER_REG_TMRSTAT, TMRSTAT_TMR0INT);
return IRQ_HANDLED;
}
static int rt_timer_request(struct rt_timer *rt)
{
int err = request_irq(rt->irq, rt_timer_irq, IRQF_DISABLED,
dev_name(rt->dev), rt);
if (err) {
dev_err(rt->dev, "failed to request irq\n");
} else {
u32 t = TMR0CTL_MODE_PERIODIC | TMR0CTL_PRESCALE_VAL;
rt_timer_w32(rt, TIMER_REG_TMR0CTL, t);
}
return err;
}
static void rt_timer_free(struct rt_timer *rt)
{
free_irq(rt->irq, rt);
}
static int rt_timer_config(struct rt_timer *rt, unsigned long divisor)
{
if (rt->timer_freq < divisor)
rt->timer_div = rt->timer_freq;
else
rt->timer_div = divisor;
rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div);
return 0;
}
static int rt_timer_enable(struct rt_timer *rt)
{
u32 t;
rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div);
t = rt_timer_r32(rt, TIMER_REG_TMR0CTL);
t |= TMR0CTL_ENABLE;
rt_timer_w32(rt, TIMER_REG_TMR0CTL, t);
return 0;
}
static void rt_timer_disable(struct rt_timer *rt)
{
u32 t;
t = rt_timer_r32(rt, TIMER_REG_TMR0CTL);
t &= ~TMR0CTL_ENABLE;
rt_timer_w32(rt, TIMER_REG_TMR0CTL, t);
}
static int rt_timer_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct rt_timer *rt;
struct clk *clk;
rt = devm_kzalloc(&pdev->dev, sizeof(*rt), GFP_KERNEL);
if (!rt) {
dev_err(&pdev->dev, "failed to allocate memory\n");
return -ENOMEM;
}
rt->irq = platform_get_irq(pdev, 0);
if (!rt->irq) {
dev_err(&pdev->dev, "failed to load irq\n");
return -ENOENT;
}
rt->membase = devm_request_and_ioremap(&pdev->dev, res);
if (IS_ERR(rt->membase))
return PTR_ERR(rt->membase);
clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(clk)) {
dev_err(&pdev->dev, "failed get clock rate\n");
return PTR_ERR(clk);
}
rt->timer_freq = clk_get_rate(clk) / TMR0CTL_PRESCALE_DIV;
if (!rt->timer_freq)
return -EINVAL;
rt->dev = &pdev->dev;
platform_set_drvdata(pdev, rt);
rt_timer_request(rt);
rt_timer_config(rt, 2);
rt_timer_enable(rt);
dev_info(&pdev->dev, "maximum frequncy is %luHz\n", rt->timer_freq);
return 0;
}
static int rt_timer_remove(struct platform_device *pdev)
{
struct rt_timer *rt = platform_get_drvdata(pdev);
rt_timer_disable(rt);
rt_timer_free(rt);
return 0;
}
static const struct of_device_id rt_timer_match[] = {
{ .compatible = "ralink,rt2880-timer" },
{},
};
MODULE_DEVICE_TABLE(of, rt_timer_match);
static struct platform_driver rt_timer_driver = {
.probe = rt_timer_probe,
.remove = rt_timer_remove,
.driver = {
.name = "rt-timer",
.owner = THIS_MODULE,
.of_match_table = rt_timer_match
},
};
module_platform_driver(rt_timer_driver);
MODULE_DESCRIPTION("Ralink RT2880 timer");
MODULE_AUTHOR("John Crispin <blogic@openwrt.org");
MODULE_LICENSE("GPL");
......@@ -350,7 +350,7 @@ static void __init select_board(void)
}
/* select "default" board */
#ifdef CONFIG_CPU_TX39XX
#ifdef CONFIG_TOSHIBA_JMR3927
txx9_board_vec = &jmr3927_vec;
#endif
#ifdef CONFIG_CPU_TX49XX
......
......@@ -203,6 +203,14 @@ config GPIO_MXS
select GPIO_GENERIC
select GENERIC_IRQ_CHIP
config GPIO_OCTEON
tristate "Cavium OCTEON GPIO"
depends on GPIOLIB && CAVIUM_OCTEON_SOC
default y
help
Say yes here to support the on-chip GPIO lines on the OCTEON
family of SOCs.
config GPIO_PL061
bool "PrimeCell PL061 GPIO support"
depends on ARM && ARM_AMBA
......
......@@ -52,6 +52,7 @@ obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o
obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o
obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o
obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o
obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o
obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o
......
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2011, 2012 Cavium Inc.
*/
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-gpio-defs.h>
#define RX_DAT 0x80
#define TX_SET 0x88
#define TX_CLEAR 0x90
/*
* The address offset of the GPIO configuration register for a given
* line.
*/
static unsigned int bit_cfg_reg(unsigned int offset)
{
/*
* The register stride is 8, with a discontinuity after the
* first 16.
*/
if (offset < 16)
return 8 * offset;
else
return 8 * (offset - 16) + 0x100;
}
struct octeon_gpio {
struct gpio_chip chip;
u64 register_base;
};
static int octeon_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
{
struct octeon_gpio *gpio = container_of(chip, struct octeon_gpio, chip);
cvmx_write_csr(gpio->register_base + bit_cfg_reg(offset), 0);
return 0;
}
static void octeon_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct octeon_gpio *gpio = container_of(chip, struct octeon_gpio, chip);
u64 mask = 1ull << offset;
u64 reg = gpio->register_base + (value ? TX_SET : TX_CLEAR);
cvmx_write_csr(reg, mask);
}
static int octeon_gpio_dir_out(struct gpio_chip *chip, unsigned offset,
int value)
{
struct octeon_gpio *gpio = container_of(chip, struct octeon_gpio, chip);
union cvmx_gpio_bit_cfgx cfgx;
octeon_gpio_set(chip, offset, value);
cfgx.u64 = 0;
cfgx.s.tx_oe = 1;
cvmx_write_csr(gpio->register_base + bit_cfg_reg(offset), cfgx.u64);
return 0;
}
static int octeon_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct octeon_gpio *gpio = container_of(chip, struct octeon_gpio, chip);
u64 read_bits = cvmx_read_csr(gpio->register_base + RX_DAT);
return ((1ull << offset) & read_bits) != 0;
}
static int octeon_gpio_probe(struct platform_device *pdev)
{
struct octeon_gpio *gpio;
struct gpio_chip *chip;
struct resource *res_mem;
int err = 0;
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
if (!gpio)
return -ENOMEM;
chip = &gpio->chip;
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res_mem == NULL) {
dev_err(&pdev->dev, "found no memory resource\n");
err = -ENXIO;
goto out;
}
if (!devm_request_mem_region(&pdev->dev, res_mem->start,
resource_size(res_mem),
res_mem->name)) {
dev_err(&pdev->dev, "request_mem_region failed\n");
err = -ENXIO;
goto out;
}
gpio->register_base = (u64)devm_ioremap(&pdev->dev, res_mem->start,
resource_size(res_mem));
pdev->dev.platform_data = chip;
chip->label = "octeon-gpio";
chip->dev = &pdev->dev;
chip->owner = THIS_MODULE;
chip->base = 0;
chip->can_sleep = 0;
chip->ngpio = 20;
chip->direction_input = octeon_gpio_dir_in;
chip->get = octeon_gpio_get;
chip->direction_output = octeon_gpio_dir_out;
chip->set = octeon_gpio_set;
err = gpiochip_add(chip);
if (err)
goto out;
dev_info(&pdev->dev, "OCTEON GPIO driver probed.\n");
out:
return err;
}
static int octeon_gpio_remove(struct platform_device *pdev)
{
struct gpio_chip *chip = pdev->dev.platform_data;
return gpiochip_remove(chip);
}
static struct of_device_id octeon_gpio_match[] = {
{
.compatible = "cavium,octeon-3860-gpio",
},
{},
};
MODULE_DEVICE_TABLE(of, octeon_gpio_match);
static struct platform_driver octeon_gpio_driver = {
.driver = {
.name = "octeon_gpio",
.owner = THIS_MODULE,
.of_match_table = octeon_gpio_match,
},
.probe = octeon_gpio_probe,
.remove = octeon_gpio_remove,
};
module_platform_driver(octeon_gpio_driver);
MODULE_DESCRIPTION("Cavium Inc. OCTEON GPIO Driver");
MODULE_AUTHOR("David Daney");
MODULE_LICENSE("GPL");
......@@ -87,6 +87,27 @@ case "${ARCH}" in
[ -f "${objtree}/vmlinux.SYS" ] && cp -v -- "${objtree}/vmlinux.SYS" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.SYS"
[ -f "${objtree}/vmlinux.dsk" ] && cp -v -- "${objtree}/vmlinux.dsk" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.dsk"
;;
mips)
if [ -f "${objtree}/arch/mips/boot/compressed/vmlinux.bin" ]; then
cp -v -- "${objtree}/arch/mips/boot/compressed/vmlinux.bin" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}"
elif [ -f "${objtree}/arch/mips/boot/compressed/vmlinux.ecoff" ]; then
cp -v -- "${objtree}/arch/mips/boot/compressed/vmlinux.ecoff" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}"
elif [ -f "${objtree}/arch/mips/boot/compressed/vmlinux.srec" ]; then
cp -v -- "${objtree}/arch/mips/boot/compressed/vmlinux.srec" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}"
elif [ -f "${objtree}/vmlinux.32" ]; then
cp -v -- "${objtree}/vmlinux.32" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
elif [ -f "${objtree}/vmlinux.64" ]; then
cp -v -- "${objtree}/vmlinux.64" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
elif [ -f "${objtree}/arch/mips/boot/vmlinux.bin" ]; then
cp -v -- "${objtree}/arch/mips/boot/vmlinux.bin" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
elif [ -f "${objtree}/arch/mips/boot/vmlinux.ecoff" ]; then
cp -v -- "${objtree}/arch/mips/boot/vmlinux.ecoff" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
elif [ -f "${objtree}/arch/mips/boot/vmlinux.srec" ]; then
cp -v -- "${objtree}/arch/mips/boot/vmlinux.srec" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
elif [ -f "${objtree}/vmlinux" ]; then
cp -v -- "${objtree}/vmlinux" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
fi
;;
*)
[ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-kbuild-${KERNELRELEASE}"
echo "" >&2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment