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 ...@@ -95,6 +95,7 @@ config ATH79
select CSRC_R4K select CSRC_R4K
select DMA_NONCOHERENT select DMA_NONCOHERENT
select HAVE_CLK select HAVE_CLK
select CLKDEV_LOOKUP
select IRQ_CPU select IRQ_CPU
select MIPS_MACHINE select MIPS_MACHINE
select SYS_HAS_CPU_MIPS32_R2 select SYS_HAS_CPU_MIPS32_R2
...@@ -131,7 +132,6 @@ config BCM63XX ...@@ -131,7 +132,6 @@ config BCM63XX
select IRQ_CPU select IRQ_CPU
select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_BMIPS4350 if !BCM63XX_CPU_6338 && !BCM63XX_CPU_6345 && !BCM63XX_CPU_6348 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_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_BIG_ENDIAN
select SYS_HAS_EARLY_PRINTK select SYS_HAS_EARLY_PRINTK
...@@ -445,6 +445,8 @@ config RALINK ...@@ -445,6 +445,8 @@ config RALINK
select SYS_HAS_EARLY_PRINTK select SYS_HAS_EARLY_PRINTK
select HAVE_MACH_CLKDEV select HAVE_MACH_CLKDEV
select CLKDEV_LOOKUP select CLKDEV_LOOKUP
select ARCH_HAS_RESET_CONTROLLER
select RESET_CONTROLLER
config SGI_IP22 config SGI_IP22
bool "SGI IP22 (Indy/Indigo2)" bool "SGI IP22 (Indy/Indigo2)"
...@@ -609,7 +611,6 @@ config SIBYTE_SWARM ...@@ -609,7 +611,6 @@ config SIBYTE_SWARM
select BOOT_ELF32 select BOOT_ELF32
select DMA_COHERENT select DMA_COHERENT
select HAVE_PATA_PLATFORM select HAVE_PATA_PLATFORM
select NR_CPUS_DEFAULT_2
select SIBYTE_SB1250 select SIBYTE_SB1250
select SWAP_IO_SPACE select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1 select SYS_HAS_CPU_SB1
...@@ -623,7 +624,6 @@ config SIBYTE_LITTLESUR ...@@ -623,7 +624,6 @@ config SIBYTE_LITTLESUR
select BOOT_ELF32 select BOOT_ELF32
select DMA_COHERENT select DMA_COHERENT
select HAVE_PATA_PLATFORM select HAVE_PATA_PLATFORM
select NR_CPUS_DEFAULT_2
select SIBYTE_SB1250 select SIBYTE_SB1250
select SWAP_IO_SPACE select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1 select SYS_HAS_CPU_SB1
...@@ -635,7 +635,6 @@ config SIBYTE_SENTOSA ...@@ -635,7 +635,6 @@ config SIBYTE_SENTOSA
bool "Sibyte BCM91250E-Sentosa" bool "Sibyte BCM91250E-Sentosa"
select BOOT_ELF32 select BOOT_ELF32
select DMA_COHERENT select DMA_COHERENT
select NR_CPUS_DEFAULT_2
select SIBYTE_SB1250 select SIBYTE_SB1250
select SWAP_IO_SPACE select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1 select SYS_HAS_CPU_SB1
...@@ -731,6 +730,7 @@ config CAVIUM_OCTEON_SOC ...@@ -731,6 +730,7 @@ config CAVIUM_OCTEON_SOC
select USB_ARCH_HAS_OHCI select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI select USB_ARCH_HAS_EHCI
select HOLES_IN_ZONE select HOLES_IN_ZONE
select ARCH_REQUIRE_GPIOLIB
help help
This option supports all of the Octeon reference boards from Cavium This option supports all of the Octeon reference boards from Cavium
Networks. It builds a kernel that dynamically determines the Octeon Networks. It builds a kernel that dynamically determines the Octeon
...@@ -1860,7 +1860,6 @@ config MIPS_MT_SMP ...@@ -1860,7 +1860,6 @@ config MIPS_MT_SMP
select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_IRQ_VI
select CPU_MIPSR2_IRQ_EI select CPU_MIPSR2_IRQ_EI
select MIPS_MT select MIPS_MT
select NR_CPUS_DEFAULT_2
select SMP select SMP
select SYS_SUPPORTS_SCHED_SMT if SMP select SYS_SUPPORTS_SCHED_SMT if SMP
select SYS_SUPPORTS_SMP select SYS_SUPPORTS_SMP
...@@ -2171,12 +2170,6 @@ config SYS_SUPPORTS_MIPS_CMP ...@@ -2171,12 +2170,6 @@ config SYS_SUPPORTS_MIPS_CMP
config SYS_SUPPORTS_SMP config SYS_SUPPORTS_SMP
bool bool
config NR_CPUS_DEFAULT_1
bool
config NR_CPUS_DEFAULT_2
bool
config NR_CPUS_DEFAULT_4 config NR_CPUS_DEFAULT_4
bool bool
...@@ -2194,10 +2187,8 @@ config NR_CPUS_DEFAULT_64 ...@@ -2194,10 +2187,8 @@ config NR_CPUS_DEFAULT_64
config NR_CPUS config NR_CPUS
int "Maximum number of CPUs (2-64)" int "Maximum number of CPUs (2-64)"
range 1 64 if NR_CPUS_DEFAULT_1 range 2 64
depends on SMP 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 "4" if NR_CPUS_DEFAULT_4
default "8" if NR_CPUS_DEFAULT_8 default "8" if NR_CPUS_DEFAULT_8
default "16" if NR_CPUS_DEFAULT_16 default "16" if NR_CPUS_DEFAULT_16
......
...@@ -194,6 +194,8 @@ include $(srctree)/arch/mips/Kbuild.platforms ...@@ -194,6 +194,8 @@ include $(srctree)/arch/mips/Kbuild.platforms
ifdef CONFIG_PHYSICAL_START ifdef CONFIG_PHYSICAL_START
load-y = $(CONFIG_PHYSICAL_START) load-y = $(CONFIG_PHYSICAL_START)
endif 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 cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
drivers-$(CONFIG_PCI) += arch/mips/pci/ drivers-$(CONFIG_PCI) += arch/mips/pci/
...@@ -225,6 +227,9 @@ KBUILD_CFLAGS += $(cflags-y) ...@@ -225,6 +227,9 @@ KBUILD_CFLAGS += $(cflags-y)
KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y) KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y)
KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0) 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) LDFLAGS += -m $(ld-emul)
ifdef CONFIG_CC_STACKPROTECTOR ifdef CONFIG_CC_STACKPROTECTOR
...@@ -254,9 +259,25 @@ drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/ ...@@ -254,9 +259,25 @@ drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/
# suspend and hibernation support # suspend and hibernation support
drivers-$(CONFIG_PM) += arch/mips/power/ 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 ifdef CONFIG_LASAT
rom.bin rom.sw: vmlinux rom.bin rom.sw: vmlinux
$(Q)$(MAKE) $(build)=arch/mips/lasat/image $@ $(Q)$(MAKE) $(build)=arch/mips/lasat/image \
$(bootvars-y) $@
endif endif
# #
...@@ -280,13 +301,14 @@ vmlinux.64: vmlinux ...@@ -280,13 +301,14 @@ vmlinux.64: vmlinux
all: $(all-y) all: $(all-y)
# boot # boot
vmlinux.bin vmlinux.ecoff vmlinux.srec: $(vmlinux-32) FORCE $(boot-y): $(vmlinux-32) FORCE
$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) arch/mips/boot/$@ $(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) \
$(bootvars-y) arch/mips/boot/$@
# boot/compressed # boot/compressed
vmlinuz vmlinuz.bin vmlinuz.ecoff vmlinuz.srec: $(vmlinux-32) FORCE $(bootz-y): $(vmlinux-32) FORCE
$(Q)$(MAKE) $(build)=arch/mips/boot/compressed \ $(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 CLEAN_FILES += vmlinux.32 vmlinux.64
...@@ -323,6 +345,8 @@ define archhelp ...@@ -323,6 +345,8 @@ define archhelp
echo ' vmlinuz.ecoff - ECOFF zboot image' echo ' vmlinuz.ecoff - ECOFF zboot image'
echo ' vmlinuz.bin - Raw binary zboot image' echo ' vmlinuz.bin - Raw binary zboot image'
echo ' vmlinuz.srec - SREC zboot image' echo ' vmlinuz.srec - SREC zboot image'
echo ' uImage - U-Boot image'
echo ' uImage.gz - U-Boot image (gzip)'
echo echo
echo ' These will be default as appropriate for a configured platform.' echo ' These will be default as appropriate for a configured platform.'
endef endef
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clkdev.h>
#include <asm/div64.h> #include <asm/div64.h>
...@@ -31,92 +32,132 @@ struct clk { ...@@ -31,92 +32,132 @@ struct clk {
unsigned long rate; unsigned long rate;
}; };
static struct clk ath79_ref_clk; static void __init ath79_add_sys_clkdev(const char *id, unsigned long rate)
static struct clk ath79_cpu_clk; {
static struct clk ath79_ddr_clk; struct clk *clk;
static struct clk ath79_ahb_clk; int err;
static struct clk ath79_wdt_clk;
static struct clk ath79_uart_clk; 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) 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 pll;
u32 freq; u32 freq;
u32 div; u32 div;
ath79_ref_clk.rate = AR71XX_BASE_FREQ; ref_rate = AR71XX_BASE_FREQ;
pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; 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; 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; 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; 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; clk_add_alias("wdt", NULL, "ahb", NULL);
ath79_uart_clk.rate = ath79_ahb_clk.rate; clk_add_alias("uart", NULL, "ahb", NULL);
} }
static void __init ar724x_clocks_init(void) 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 pll;
u32 freq; u32 freq;
u32 div; u32 div;
ath79_ref_clk.rate = AR724X_BASE_FREQ; ref_rate = AR724X_BASE_FREQ;
pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG); pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); 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); div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
freq *= div; freq *= div;
ath79_cpu_clk.rate = freq; cpu_rate = freq;
div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; 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; 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; clk_add_alias("wdt", NULL, "ahb", NULL);
ath79_uart_clk.rate = ath79_ahb_clk.rate; clk_add_alias("uart", NULL, "ahb", NULL);
} }
static void __init ar913x_clocks_init(void) 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 pll;
u32 freq; u32 freq;
u32 div; u32 div;
ath79_ref_clk.rate = AR913X_BASE_FREQ; ref_rate = AR913X_BASE_FREQ;
pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG); pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG);
div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK); 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; 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; 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_add_sys_clkdev("ref", ref_rate);
ath79_uart_clk.rate = ath79_ahb_clk.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) 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 clock_ctrl;
u32 cpu_config; u32 cpu_config;
u32 freq; u32 freq;
...@@ -124,21 +165,21 @@ static void __init ar933x_clocks_init(void) ...@@ -124,21 +165,21 @@ static void __init ar933x_clocks_init(void)
t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
if (t & AR933X_BOOTSTRAP_REF_CLK_40) if (t & AR933X_BOOTSTRAP_REF_CLK_40)
ath79_ref_clk.rate = (40 * 1000 * 1000); ref_rate = (40 * 1000 * 1000);
else else
ath79_ref_clk.rate = (25 * 1000 * 1000); ref_rate = (25 * 1000 * 1000);
clock_ctrl = ath79_pll_rr(AR933X_PLL_CLOCK_CTRL_REG); clock_ctrl = ath79_pll_rr(AR933X_PLL_CLOCK_CTRL_REG);
if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
ath79_cpu_clk.rate = ath79_ref_clk.rate; cpu_rate = ref_rate;
ath79_ahb_clk.rate = ath79_ref_clk.rate; ahb_rate = ref_rate;
ath79_ddr_clk.rate = ath79_ref_clk.rate; ddr_rate = ref_rate;
} else { } else {
cpu_config = ath79_pll_rr(AR933X_PLL_CPU_CONFIG_REG); cpu_config = ath79_pll_rr(AR933X_PLL_CPU_CONFIG_REG);
t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
AR933X_PLL_CPU_CONFIG_REFDIV_MASK; 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) & t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) &
AR933X_PLL_CPU_CONFIG_NINT_MASK; AR933X_PLL_CPU_CONFIG_NINT_MASK;
...@@ -153,19 +194,24 @@ static void __init ar933x_clocks_init(void) ...@@ -153,19 +194,24 @@ static void __init ar933x_clocks_init(void)
t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) &
AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; 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) & t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) &
AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; 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) & t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) &
AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; 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_add_sys_clkdev("ref", ref_rate);
ath79_uart_clk.rate = ath79_ref_clk.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, 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, ...@@ -174,12 +220,12 @@ static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
u64 t; u64 t;
u32 ret; u32 ret;
t = ath79_ref_clk.rate; t = ref;
t *= nint; t *= nint;
do_div(t, ref_div); do_div(t, ref_div);
ret = t; ret = t;
t = ath79_ref_clk.rate; t = ref;
t *= nfrac; t *= nfrac;
do_div(t, ref_div * frac); do_div(t, ref_div * frac);
ret += t; ret += t;
...@@ -190,6 +236,10 @@ static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, ...@@ -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) 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 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv;
u32 cpu_pll, ddr_pll; u32 cpu_pll, ddr_pll;
u32 bootstrap; u32 bootstrap;
...@@ -199,9 +249,9 @@ static void __init ar934x_clocks_init(void) ...@@ -199,9 +249,9 @@ static void __init ar934x_clocks_init(void)
bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40)
ath79_ref_clk.rate = 40 * 1000 * 1000; ref_rate = 40 * 1000 * 1000;
else else
ath79_ref_clk.rate = 25 * 1000 * 1000; ref_rate = 25 * 1000 * 1000;
pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG);
if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
...@@ -227,7 +277,7 @@ static void __init ar934x_clocks_init(void) ...@@ -227,7 +277,7 @@ static void __init ar934x_clocks_init(void)
frac = 1 << 6; 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); nfrac, frac, out_div);
pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG); pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG);
...@@ -254,7 +304,7 @@ static void __init ar934x_clocks_init(void) ...@@ -254,7 +304,7 @@ static void __init ar934x_clocks_init(void)
frac = 1 << 10; 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); nfrac, frac, out_div);
clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
...@@ -263,49 +313,58 @@ static void __init ar934x_clocks_init(void) ...@@ -263,49 +313,58 @@ static void __init ar934x_clocks_init(void)
AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK;
if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS) 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) 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 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) & postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) &
AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK; AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK;
if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS) 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) 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 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) & postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) &
AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK; AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK;
if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS) 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) 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 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; clk_add_alias("wdt", NULL, "ref", NULL);
ath79_uart_clk.rate = ath79_ref_clk.rate; clk_add_alias("uart", NULL, "ref", NULL);
iounmap(dpll_base); iounmap(dpll_base);
} }
static void __init qca955x_clocks_init(void) 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 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
u32 cpu_pll, ddr_pll; u32 cpu_pll, ddr_pll;
u32 bootstrap; u32 bootstrap;
bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP);
if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40) if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40)
ath79_ref_clk.rate = 40 * 1000 * 1000; ref_rate = 40 * 1000 * 1000;
else else
ath79_ref_clk.rate = 25 * 1000 * 1000; ref_rate = 25 * 1000 * 1000;
pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG); pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG);
out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
...@@ -317,8 +376,8 @@ static void __init qca955x_clocks_init(void) ...@@ -317,8 +376,8 @@ static void __init qca955x_clocks_init(void)
frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) & frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
QCA955X_PLL_CPU_CONFIG_NFRAC_MASK; QCA955X_PLL_CPU_CONFIG_NFRAC_MASK;
cpu_pll = nint * ath79_ref_clk.rate / ref_div; cpu_pll = nint * ref_rate / ref_div;
cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 6)); cpu_pll += frac * ref_rate / (ref_div * (1 << 6));
cpu_pll /= (1 << out_div); cpu_pll /= (1 << out_div);
pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG); pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG);
...@@ -331,8 +390,8 @@ static void __init qca955x_clocks_init(void) ...@@ -331,8 +390,8 @@ static void __init qca955x_clocks_init(void)
frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) & frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
QCA955X_PLL_DDR_CONFIG_NFRAC_MASK; QCA955X_PLL_DDR_CONFIG_NFRAC_MASK;
ddr_pll = nint * ath79_ref_clk.rate / ref_div; ddr_pll = nint * ref_rate / ref_div;
ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 10)); ddr_pll += frac * ref_rate / (ref_div * (1 << 10));
ddr_pll /= (1 << out_div); ddr_pll /= (1 << out_div);
clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG); clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG);
...@@ -341,34 +400,39 @@ static void __init qca955x_clocks_init(void) ...@@ -341,34 +400,39 @@ static void __init qca955x_clocks_init(void)
QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 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) 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 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) & postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 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) 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 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) & postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 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) 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 else
ath79_ahb_clk.rate = cpu_pll / (postdiv + 1); ahb_rate = cpu_pll / (postdiv + 1);
ath79_wdt_clk.rate = ath79_ref_clk.rate; ath79_add_sys_clkdev("ref", ref_rate);
ath79_uart_clk.rate = ath79_ref_clk.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) void __init ath79_clocks_init(void)
...@@ -387,46 +451,27 @@ void __init ath79_clocks_init(void) ...@@ -387,46 +451,27 @@ void __init ath79_clocks_init(void)
qca955x_clocks_init(); qca955x_clocks_init();
else else
BUG(); 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);
} }
/* unsigned long __init
* Linux clock API ath79_get_sys_clk_rate(const char *id)
*/
struct clk *clk_get(struct device *dev, const char *id)
{ {
if (!strcmp(id, "ref")) struct clk *clk;
return &ath79_ref_clk; unsigned long rate;
if (!strcmp(id, "cpu"))
return &ath79_cpu_clk;
if (!strcmp(id, "ddr"))
return &ath79_ddr_clk;
if (!strcmp(id, "ahb"))
return &ath79_ahb_clk;
if (!strcmp(id, "wdt")) clk = clk_get(NULL, id);
return &ath79_wdt_clk; if (IS_ERR(clk))
panic("unable to get %s clock, err=%d", id, (int) PTR_ERR(clk));
if (!strcmp(id, "uart")) rate = clk_get_rate(clk);
return &ath79_uart_clk; clk_put(clk);
return ERR_PTR(-ENOENT); return rate;
} }
EXPORT_SYMBOL(clk_get);
/*
* Linux clock API
*/
int clk_enable(struct clk *clk) int clk_enable(struct clk *clk)
{ {
return 0; return 0;
...@@ -443,8 +488,3 @@ unsigned long clk_get_rate(struct clk *clk) ...@@ -443,8 +488,3 @@ unsigned long clk_get_rate(struct clk *clk)
return clk->rate; return clk->rate;
} }
EXPORT_SYMBOL(clk_get_rate); EXPORT_SYMBOL(clk_get_rate);
void clk_put(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_put);
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#define ATH79_MEM_SIZE_MAX (128 * 1024 * 1024) #define ATH79_MEM_SIZE_MAX (128 * 1024 * 1024)
void ath79_clocks_init(void); 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_ddr_wb_flush(unsigned int reg);
void ath79_gpio_function_enable(u32 mask); void ath79_gpio_function_enable(u32 mask);
......
...@@ -81,21 +81,19 @@ static struct platform_device ar933x_uart_device = { ...@@ -81,21 +81,19 @@ static struct platform_device ar933x_uart_device = {
void __init ath79_register_uart(void) void __init ath79_register_uart(void)
{ {
struct clk *clk; unsigned long uart_clk_rate;
clk = clk_get(NULL, "uart"); uart_clk_rate = ath79_get_sys_clk_rate("uart");
if (IS_ERR(clk))
panic("unable to get UART clock, err=%ld", PTR_ERR(clk));
if (soc_is_ar71xx() || if (soc_is_ar71xx() ||
soc_is_ar724x() || soc_is_ar724x() ||
soc_is_ar913x() || soc_is_ar913x() ||
soc_is_ar934x() || soc_is_ar934x() ||
soc_is_qca955x()) { 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); platform_device_register(&ath79_uart_device);
} else if (soc_is_ar933x()) { } 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); platform_device_register(&ar933x_uart_device);
} else { } else {
BUG(); BUG();
......
...@@ -200,7 +200,6 @@ void __init plat_mem_setup(void) ...@@ -200,7 +200,6 @@ void __init plat_mem_setup(void)
ath79_detect_sys_type(); ath79_detect_sys_type();
detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX);
ath79_clocks_init();
_machine_restart = ath79_restart; _machine_restart = ath79_restart;
_machine_halt = ath79_halt; _machine_halt = ath79_halt;
...@@ -209,13 +208,25 @@ void __init plat_mem_setup(void) ...@@ -209,13 +208,25 @@ void __init plat_mem_setup(void)
void __init plat_time_init(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"); pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz",
if (IS_ERR(clk)) cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000,
panic("unable to get CPU clock, err=%ld", PTR_ERR(clk)); 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) static int __init ath79_setup(void)
......
...@@ -4,3 +4,4 @@ vmlinux.* ...@@ -4,3 +4,4 @@ vmlinux.*
zImage zImage
zImage.tmp zImage.tmp
calc_vmlinuz_load_addr calc_vmlinuz_load_addr
uImage
...@@ -40,3 +40,18 @@ quiet_cmd_srec = OBJCOPY $@ ...@@ -40,3 +40,18 @@ quiet_cmd_srec = OBJCOPY $@
cmd_srec = $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $@ cmd_srec = $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $@
$(obj)/vmlinux.srec: $(VMLINUX) FORCE $(obj)/vmlinux.srec: $(VMLINUX) FORCE
$(call if_changed,srec) $(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__ \ ...@@ -25,7 +25,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \
KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \ -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 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) ...@@ -1776,7 +1776,7 @@ asmlinkage void plat_irq_dispatch(void)
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
void fixup_irqs(void) void octeon_fixup_irqs(void)
{ {
irq_cpu_offline(); irq_cpu_offline();
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* written by Ralf Baechle <ralf@linux-mips.org> * written by Ralf Baechle <ralf@linux-mips.org>
*/ */
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/vmalloc.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/console.h> #include <linux/console.h>
...@@ -1139,3 +1140,30 @@ static int __init edac_devinit(void) ...@@ -1139,3 +1140,30 @@ static int __init edac_devinit(void)
return err; return err;
} }
device_initcall(edac_devinit); 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) ...@@ -255,8 +255,6 @@ static void octeon_cpus_done(void)
/* State of each CPU. */ /* State of each CPU. */
DEFINE_PER_CPU(int, cpu_state); DEFINE_PER_CPU(int, cpu_state);
extern void fixup_irqs(void);
static int octeon_cpu_disable(void) static int octeon_cpu_disable(void)
{ {
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
...@@ -267,7 +265,7 @@ static int octeon_cpu_disable(void) ...@@ -267,7 +265,7 @@ static int octeon_cpu_disable(void)
set_cpu_online(cpu, false); set_cpu_online(cpu, false);
cpu_clear(cpu, cpu_callin_map); cpu_clear(cpu, cpu_callin_map);
local_irq_disable(); local_irq_disable();
fixup_irqs(); octeon_fixup_irqs();
local_irq_enable(); local_irq_enable();
flush_cache_all(); 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) ...@@ -126,12 +126,13 @@ int rtc_mips_set_mmss(unsigned long nowtime)
void __init plat_time_init(void) void __init plat_time_init(void)
{ {
u32 start, end; u32 start, end;
int i = HZ / 10; int i = HZ / 8;
/* Set up the rate of periodic DS1287 interrupts. */ /* Set up the rate of periodic DS1287 interrupts. */
ds1287_set_base_clock(HZ); ds1287_set_base_clock(HZ);
if (cpu_has_counter) { if (cpu_has_counter) {
ds1287_timer_state();
while (!ds1287_timer_state()) while (!ds1287_timer_state())
; ;
...@@ -143,7 +144,7 @@ void __init plat_time_init(void) ...@@ -143,7 +144,7 @@ void __init plat_time_init(void)
end = read_c0_count(); end = read_c0_count();
mips_hpt_frequency = (end - start) * 10; mips_hpt_frequency = (end - start) * 8;
printk(KERN_INFO "MIPS counter frequency %dHz\n", printk(KERN_INFO "MIPS counter frequency %dHz\n",
mips_hpt_frequency); mips_hpt_frequency);
} else if (IOASIC) } else if (IOASIC)
......
# MIPS headers # 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 += 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) ...@@ -65,44 +65,33 @@ static inline unsigned long bmips_read_zscm_reg(unsigned int offset)
{ {
unsigned long ret; unsigned long ret;
__asm__ __volatile__( barrier();
".set push\n" cache_op(Index_Load_Tag_S, ZSCM_REG_BASE + offset);
".set noreorder\n" __sync();
"cache %1, 0(%2)\n" _ssnop();
"sync\n" _ssnop();
"_ssnop\n" _ssnop();
"_ssnop\n" _ssnop();
"_ssnop\n" _ssnop();
"_ssnop\n" _ssnop();
"_ssnop\n" _ssnop();
"_ssnop\n" ret = read_c0_ddatalo();
"_ssnop\n" _ssnop();
"mfc0 %0, $28, 3\n"
"_ssnop\n"
".set pop\n"
: "=&r" (ret)
: "i" (Index_Load_Tag_S), "r" (ZSCM_REG_BASE + offset)
: "memory");
return ret; return ret;
} }
static inline void bmips_write_zscm_reg(unsigned int offset, unsigned long data) static inline void bmips_write_zscm_reg(unsigned int offset, unsigned long data)
{ {
__asm__ __volatile__( write_c0_ddatalo(data);
".set push\n" _ssnop();
".set noreorder\n" _ssnop();
"mtc0 %0, $28, 3\n" _ssnop();
"_ssnop\n" cache_op(Index_Store_Tag_S, ZSCM_REG_BASE + offset);
"_ssnop\n" _ssnop();
"_ssnop\n" _ssnop();
"cache %1, 0(%2)\n" _ssnop();
"_ssnop\n" barrier();
"_ssnop\n"
"_ssnop\n"
: /* no outputs */
: "r" (data),
"i" (Index_Store_Tag_S), "r" (ZSCM_REG_BASE + offset)
: "memory");
} }
#endif /* !defined(__ASSEMBLY__) */ #endif /* !defined(__ASSEMBLY__) */
......
...@@ -141,6 +141,9 @@ ...@@ -141,6 +141,9 @@
#define PRID_IMP_CAVIUM_CN68XX 0x9100 #define PRID_IMP_CAVIUM_CN68XX 0x9100
#define PRID_IMP_CAVIUM_CN66XX 0x9200 #define PRID_IMP_CAVIUM_CN66XX 0x9200
#define PRID_IMP_CAVIUM_CN61XX 0x9300 #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 * These are the PRID's for when 23:16 == PRID_COMP_INGENIC
...@@ -176,6 +179,7 @@ ...@@ -176,6 +179,7 @@
#define PRID_IMP_NETLOGIC_XLP8XX 0x1000 #define PRID_IMP_NETLOGIC_XLP8XX 0x1000
#define PRID_IMP_NETLOGIC_XLP3XX 0x1100 #define PRID_IMP_NETLOGIC_XLP3XX 0x1100
#define PRID_IMP_NETLOGIC_XLP2XX 0x1200
/* /*
* Definitions for 7:0 on legacy processors * Definitions for 7:0 on legacy processors
...@@ -272,7 +276,7 @@ enum cpu_type_enum { ...@@ -272,7 +276,7 @@ enum cpu_type_enum {
*/ */
CPU_5KC, CPU_5KE, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2, 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_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2,
CPU_XLR, CPU_XLP, CPU_CAVIUM_OCTEON3, CPU_XLR, CPU_XLP,
CPU_LAST 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 @@ ...@@ -42,8 +42,6 @@
#define cpu_has_mips64r1 0 #define cpu_has_mips64r1 0
#define cpu_has_mips64r2 0 #define cpu_has_mips64r2 0
#define cpu_has_dsp 0
#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0 #define cpu_has_mipsmt 0
#define cpu_has_64bits 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 @@ ...@@ -20,6 +20,8 @@
#define SYSC_REG_CHIP_REV 0x0c #define SYSC_REG_CHIP_REV 0x0c
#define SYSC_REG_SYSTEM_CONFIG0 0x10 #define SYSC_REG_SYSTEM_CONFIG0 0x10
#define SYSC_REG_SYSTEM_CONFIG1 0x14 #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_CONFIG0 0x54
#define SYSC_REG_CPLL_CONFIG1 0x58 #define SYSC_REG_CPLL_CONFIG1 0x58
...@@ -29,20 +31,42 @@ ...@@ -29,20 +31,42 @@
#define MT7620A_CHIP_NAME0 0x3637544d #define MT7620A_CHIP_NAME0 0x3637544d
#define MT7620A_CHIP_NAME1 0x20203032 #define MT7620A_CHIP_NAME1 0x20203032
#define SYSCFG0_XTAL_FREQ_SEL BIT(6)
#define CHIP_REV_PKG_MASK 0x1 #define CHIP_REV_PKG_MASK 0x1
#define CHIP_REV_PKG_SHIFT 16 #define CHIP_REV_PKG_SHIFT 16
#define CHIP_REV_VER_MASK 0xf #define CHIP_REV_VER_MASK 0xf
#define CHIP_REV_VER_SHIFT 8 #define CHIP_REV_VER_SHIFT 8
#define CHIP_REV_ECO_MASK 0xf #define CHIP_REV_ECO_MASK 0xf
#define CPLL_SW_CONFIG_SHIFT 31 #define CLKCFG0_PERI_CLK_SEL BIT(4)
#define CPLL_SW_CONFIG_MASK 0x1
#define CPLL_CPU_CLK_SHIFT 24 #define CPU_SYS_CLKCFG_OCP_RATIO_SHIFT 16
#define CPLL_CPU_CLK_MASK 0x1 #define CPU_SYS_CLKCFG_OCP_RATIO_MASK 0xf
#define CPLL_MULT_RATIO_SHIFT 16 #define CPU_SYS_CLKCFG_OCP_RATIO_1 0 /* 1:1 (Reserved) */
#define CPLL_MULT_RATIO 0x7 #define CPU_SYS_CLKCFG_OCP_RATIO_1_5 1 /* 1:1.5 (Reserved) */
#define CPLL_DIV_RATIO_SHIFT 10 #define CPU_SYS_CLKCFG_OCP_RATIO_2 2 /* 1:2 */
#define CPLL_DIV_RATIO 0x3 #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_MASK 0x3
#define SYSCFG0_DRAM_TYPE_SHIFT 4 #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 @@ ...@@ -88,6 +88,7 @@
#define BRIDGE_DRAM_LIMIT6 0x22 #define BRIDGE_DRAM_LIMIT6 0x22
#define BRIDGE_DRAM_LIMIT7 0x23 #define BRIDGE_DRAM_LIMIT7 0x23
#define BRIDGE_DRAM_NODE_TRANSLN(i) (0x24 + (i))
#define BRIDGE_DRAM_NODE_TRANSLN0 0x24 #define BRIDGE_DRAM_NODE_TRANSLN0 0x24
#define BRIDGE_DRAM_NODE_TRANSLN1 0x25 #define BRIDGE_DRAM_NODE_TRANSLN1 0x25
#define BRIDGE_DRAM_NODE_TRANSLN2 0x26 #define BRIDGE_DRAM_NODE_TRANSLN2 0x26
...@@ -96,6 +97,8 @@ ...@@ -96,6 +97,8 @@
#define BRIDGE_DRAM_NODE_TRANSLN5 0x29 #define BRIDGE_DRAM_NODE_TRANSLN5 0x29
#define BRIDGE_DRAM_NODE_TRANSLN6 0x2a #define BRIDGE_DRAM_NODE_TRANSLN6 0x2a
#define BRIDGE_DRAM_NODE_TRANSLN7 0x2b #define BRIDGE_DRAM_NODE_TRANSLN7 0x2b
#define BRIDGE_DRAM_CHNL_TRANSLN(i) (0x2c + (i))
#define BRIDGE_DRAM_CHNL_TRANSLN0 0x2c #define BRIDGE_DRAM_CHNL_TRANSLN0 0x2c
#define BRIDGE_DRAM_CHNL_TRANSLN1 0x2d #define BRIDGE_DRAM_CHNL_TRANSLN1 0x2d
#define BRIDGE_DRAM_CHNL_TRANSLN2 0x2e #define BRIDGE_DRAM_CHNL_TRANSLN2 0x2e
...@@ -104,6 +107,7 @@ ...@@ -104,6 +107,7 @@
#define BRIDGE_DRAM_CHNL_TRANSLN5 0x31 #define BRIDGE_DRAM_CHNL_TRANSLN5 0x31
#define BRIDGE_DRAM_CHNL_TRANSLN6 0x32 #define BRIDGE_DRAM_CHNL_TRANSLN6 0x32
#define BRIDGE_DRAM_CHNL_TRANSLN7 0x33 #define BRIDGE_DRAM_CHNL_TRANSLN7 0x33
#define BRIDGE_PCIEMEM_BASE0 0x34 #define BRIDGE_PCIEMEM_BASE0 0x34
#define BRIDGE_PCIEMEM_BASE1 0x35 #define BRIDGE_PCIEMEM_BASE1 0x35
#define BRIDGE_PCIEMEM_BASE2 0x36 #define BRIDGE_PCIEMEM_BASE2 0x36
......
...@@ -72,6 +72,12 @@ ...@@ -72,6 +72,12 @@
#define XLP_IO_USB_OHCI2_OFFSET(node) XLP_HDR_OFFSET(node, 0, 2, 4) #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) #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_NAE_OFFSET(node) XLP_HDR_OFFSET(node, 0, 3, 0)
#define XLP_IO_POE_OFFSET(node) XLP_HDR_OFFSET(node, 0, 3, 1) #define XLP_IO_POE_OFFSET(node) XLP_HDR_OFFSET(node, 0, 3, 1)
...@@ -88,6 +94,9 @@ ...@@ -88,6 +94,9 @@
#define XLP_IO_I2C0_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 2) #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_I2C1_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 3)
#define XLP_IO_GPIO_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 4) #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 */ /* system management */
#define XLP_IO_SYS_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 5) #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) #define XLP_IO_JTAG_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 6)
...@@ -145,6 +154,7 @@ ...@@ -145,6 +154,7 @@
#define PCI_DEVICE_ID_NLM_NOR 0x1015 #define PCI_DEVICE_ID_NLM_NOR 0x1015
#define PCI_DEVICE_ID_NLM_NAND 0x1016 #define PCI_DEVICE_ID_NLM_NAND 0x1016
#define PCI_DEVICE_ID_NLM_MMC 0x1018 #define PCI_DEVICE_ID_NLM_MMC 0x1018
#define PCI_DEVICE_ID_NLM_XHCI 0x101d
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
......
...@@ -208,13 +208,14 @@ ...@@ -208,13 +208,14 @@
#define PIC_LOCAL_SCHEDULING 1 #define PIC_LOCAL_SCHEDULING 1
#define PIC_GLOBAL_SCHEDULING 0 #define PIC_GLOBAL_SCHEDULING 0
#define PIC_CLK_HZ 133333333
#define nlm_read_pic_reg(b, r) nlm_read_reg64(b, r) #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_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_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) #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 */ /* IRT and h/w interrupt routines */
static inline int static inline int
nlm_pic_read_irt(uint64_t base, int irt_index) nlm_pic_read_irt(uint64_t base, int irt_index)
......
...@@ -117,6 +117,36 @@ ...@@ -117,6 +117,36 @@
#define SYS_SCRTCH2 0x4b #define SYS_SCRTCH2 0x4b
#define SYS_SCRTCH3 0x4c #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__ #ifndef __ASSEMBLY__
#define nlm_read_sys_reg(b, r) nlm_read_reg(b, r) #define nlm_read_sys_reg(b, r) nlm_read_reg(b, r)
...@@ -124,5 +154,6 @@ ...@@ -124,5 +154,6 @@
#define nlm_get_sys_pcibase(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node)) #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) #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
#endif #endif
...@@ -41,15 +41,22 @@ ...@@ -41,15 +41,22 @@
#define PIC_PCIE_LINK_1_IRQ 20 #define PIC_PCIE_LINK_1_IRQ 20
#define PIC_PCIE_LINK_2_IRQ 21 #define PIC_PCIE_LINK_2_IRQ 21
#define PIC_PCIE_LINK_3_IRQ 22 #define PIC_PCIE_LINK_3_IRQ 22
#define PIC_EHCI_0_IRQ 23 #define PIC_EHCI_0_IRQ 23
#define PIC_EHCI_1_IRQ 24 #define PIC_EHCI_1_IRQ 24
#define PIC_OHCI_0_IRQ 25 #define PIC_OHCI_0_IRQ 25
#define PIC_OHCI_1_IRQ 26 #define PIC_OHCI_1_IRQ 26
#define PIC_OHCI_2_IRQ 27 #define PIC_OHCI_2_IRQ 27
#define PIC_OHCI_3_IRQ 28 #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_MMC_IRQ 29
#define PIC_I2C_0_IRQ 30 #define PIC_I2C_0_IRQ 30
#define PIC_I2C_1_IRQ 31 #define PIC_I2C_1_IRQ 31
#define PIC_I2C_2_IRQ 32
#define PIC_I2C_3_IRQ 33
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
...@@ -59,7 +66,17 @@ void xlp_wakeup_secondary_cpus(void); ...@@ -59,7 +66,17 @@ void xlp_wakeup_secondary_cpus(void);
void xlp_mmu_init(void); void xlp_mmu_init(void);
void nlm_hal_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); 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 /* !__ASSEMBLY__ */
#endif /* _ASM_NLM_XLP_H */ #endif /* _ASM_NLM_XLP_H */
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#define _ASM_NLM_XLR_PIC_H #define _ASM_NLM_XLR_PIC_H
#define PIC_CLK_HZ 66666666 #define PIC_CLK_HZ 66666666
#define pic_timer_freq() PIC_CLK_HZ
/* PIC hardware interrupt numbers */ /* PIC hardware interrupt numbers */
#define PIC_IRT_WD_INDEX 0 #define PIC_IRT_WD_INDEX 0
#define PIC_IRT_TIMER_0_INDEX 1 #define PIC_IRT_TIMER_0_INDEX 1
......
...@@ -251,4 +251,6 @@ extern void (*octeon_irq_setup_secondary)(void); ...@@ -251,4 +251,6 @@ extern void (*octeon_irq_setup_secondary)(void);
typedef void (*octeon_irq_ip4_handler_t)(void); typedef void (*octeon_irq_ip4_handler_t)(void);
void octeon_irq_set_ip4_handler(octeon_irq_ip4_handler_t); void octeon_irq_set_ip4_handler(octeon_irq_ip4_handler_t);
extern void octeon_fixup_irqs(void);
#endif /* __ASM_OCTEON_OCTEON_H */ #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 # UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm 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 += bitsperlong.h
header-y += break.h header-y += break.h
header-y += byteorder.h header-y += byteorder.h
...@@ -11,7 +13,6 @@ header-y += fcntl.h ...@@ -11,7 +13,6 @@ header-y += fcntl.h
header-y += inst.h header-y += inst.h
header-y += ioctl.h header-y += ioctl.h
header-y += ioctls.h header-y += ioctls.h
header-y += ipcbuf.h
header-y += kvm_para.h header-y += kvm_para.h
header-y += mman.h header-y += mman.h
header-y += msgbuf.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) ...@@ -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_CN63XX:
case PRID_IMP_CAVIUM_CN66XX: case PRID_IMP_CAVIUM_CN66XX:
case PRID_IMP_CAVIUM_CN68XX: case PRID_IMP_CAVIUM_CN68XX:
case PRID_IMP_CAVIUM_CNF71XX:
c->cputype = CPU_CAVIUM_OCTEON2; c->cputype = CPU_CAVIUM_OCTEON2;
__cpu_name[cpu] = "Cavium Octeon II"; __cpu_name[cpu] = "Cavium Octeon II";
set_elf_platform(cpu, "octeon2"); set_elf_platform(cpu, "octeon2");
break; 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: default:
printk(KERN_INFO "Unknown Octeon chip!\n"); printk(KERN_INFO "Unknown Octeon chip!\n");
c->cputype = CPU_UNKNOWN; c->cputype = CPU_UNKNOWN;
...@@ -899,6 +906,11 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu) ...@@ -899,6 +906,11 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
MIPS_CPU_LLSC); MIPS_CPU_LLSC);
switch (c->processor_id & 0xff00) { 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_XLP8XX:
case PRID_IMP_NETLOGIC_XLP3XX: case PRID_IMP_NETLOGIC_XLP3XX:
c->cputype = CPU_XLP; c->cputype = CPU_XLP;
......
...@@ -41,9 +41,9 @@ void __init dec_ioasic_clocksource_init(void) ...@@ -41,9 +41,9 @@ void __init dec_ioasic_clocksource_init(void)
{ {
unsigned int freq; unsigned int freq;
u32 start, end; u32 start, end;
int i = HZ / 10; int i = HZ / 8;
ds1287_timer_state();
while (!ds1287_timer_state()) while (!ds1287_timer_state())
; ;
...@@ -55,7 +55,7 @@ void __init dec_ioasic_clocksource_init(void) ...@@ -55,7 +55,7 @@ void __init dec_ioasic_clocksource_init(void)
end = dec_ioasic_hpt_read(&clocksource_dec); 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); printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq);
clocksource_dec.rating = 200 + freq / 10000000; clocksource_dec.rating = 200 + freq / 10000000;
......
...@@ -166,6 +166,7 @@ void __init check_wait(void) ...@@ -166,6 +166,7 @@ void __init check_wait(void)
case CPU_CAVIUM_OCTEON: case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS: case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2: case CPU_CAVIUM_OCTEON2:
case CPU_CAVIUM_OCTEON3:
case CPU_JZRISC: case CPU_JZRISC:
case CPU_LOONGSON1: case CPU_LOONGSON1:
case CPU_XLR: case CPU_XLR:
......
...@@ -83,7 +83,7 @@ _mcount: ...@@ -83,7 +83,7 @@ _mcount:
PTR_S MCOUNT_RA_ADDRESS_REG, PT_R12(sp) PTR_S MCOUNT_RA_ADDRESS_REG, PT_R12(sp)
#endif #endif
move a0, ra /* arg1: self return address */ PTR_SUBU a0, ra, 8 /* arg1: self address */
.globl ftrace_call .globl ftrace_call
ftrace_call: ftrace_call:
nop /* a placeholder for the call to a real tracing function */ nop /* a placeholder for the call to a real tracing function */
......
...@@ -26,6 +26,12 @@ process_entry: ...@@ -26,6 +26,12 @@ process_entry:
PTR_L s2, (s0) PTR_L s2, (s0)
PTR_ADD s0, s0, SZREG 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 */ /* destination page */
and s3, s2, 0x1 and s3, s2, 0x1
beq s3, zero, 1f beq s3, zero, 1f
......
...@@ -552,6 +552,52 @@ static void __init arch_mem_addpart(phys_t mem, phys_t end, int type) ...@@ -552,6 +552,52 @@ static void __init arch_mem_addpart(phys_t mem, phys_t end, int type)
add_memory_region(mem, size, 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) static void __init arch_mem_init(char **cmdline_p)
{ {
extern void plat_mem_setup(void); extern void plat_mem_setup(void);
...@@ -608,6 +654,8 @@ static void __init arch_mem_init(char **cmdline_p) ...@@ -608,6 +654,8 @@ static void __init arch_mem_init(char **cmdline_p)
BOOTMEM_DEFAULT); BOOTMEM_DEFAULT);
} }
#endif #endif
mips_parse_crashkernel();
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC
if (crashk_res.start != crashk_res.end) if (crashk_res.start != crashk_res.end)
reserve_bootmem(crashk_res.start, reserve_bootmem(crashk_res.start,
...@@ -620,52 +668,6 @@ static void __init arch_mem_init(char **cmdline_p) ...@@ -620,52 +668,6 @@ static void __init arch_mem_init(char **cmdline_p)
paging_init(); 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) static void __init resource_init(void)
{ {
int i; int i;
...@@ -678,11 +680,6 @@ static void __init resource_init(void) ...@@ -678,11 +680,6 @@ static void __init resource_init(void)
data_resource.start = __pa_symbol(&_etext); data_resource.start = __pa_symbol(&_etext);
data_resource.end = __pa_symbol(&_edata) - 1; 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++) { for (i = 0; i < boot_mem_map.nr_map; i++) {
struct resource *res; struct resource *res;
unsigned long start, end; unsigned long start, end;
......
...@@ -121,6 +121,14 @@ void __init time_init(void) ...@@ -121,6 +121,14 @@ void __init time_init(void)
{ {
plat_time_init(); 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(); init_mips_clocksource();
} }
...@@ -179,5 +179,6 @@ SECTIONS ...@@ -179,5 +179,6 @@ SECTIONS
*(.options) *(.options)
*(.pdr) *(.pdr)
*(.reginfo) *(.reginfo)
*(.eh_frame)
} }
} }
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#define CPU0CC_CPUDIV 0x0001 #define CPU0CC_CPUDIV 0x0001
/* Activation Status Register */ /* Activation Status Register */
#define ACTS_ASC0_ACT 0x00001000
#define ACTS_ASC1_ACT 0x00000800 #define ACTS_ASC1_ACT 0x00000800
#define ACTS_I2C_ACT 0x00004000 #define ACTS_I2C_ACT 0x00004000
#define ACTS_P0 0x00010000 #define ACTS_P0 0x00010000
...@@ -108,6 +109,7 @@ static void sysctl_deactivate(struct clk *clk) ...@@ -108,6 +109,7 @@ static void sysctl_deactivate(struct clk *clk)
static int sysctl_clken(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_CLKEN);
sysctl_w32(clk->module, clk->bits, SYSCTL_ACT);
sysctl_wait(clk, clk->bits, SYSCTL_CLKS); sysctl_wait(clk, clk->bits, SYSCTL_CLKS);
return 0; return 0;
} }
...@@ -256,6 +258,7 @@ void __init ltq_soc_init(void) ...@@ -256,6 +258,7 @@ void __init ltq_soc_init(void)
clkdev_add_sys("1e800400.pad", SYSCTL_SYS1, ACTS_PADCTRL1); clkdev_add_sys("1e800400.pad", SYSCTL_SYS1, ACTS_PADCTRL1);
clkdev_add_sys("1e800500.pad", SYSCTL_SYS1, ACTS_PADCTRL3); clkdev_add_sys("1e800500.pad", SYSCTL_SYS1, ACTS_PADCTRL3);
clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4); 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); 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 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 ...@@ -13,13 +13,11 @@ endif
MKLASATIMG = mklasatimg MKLASATIMG = mklasatimg
MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200 MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200
KERNEL_IMAGE = vmlinux 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 LDSCRIPT= -L$(srctree)/$(src) -Tromscript.normal
HEAD_DEFINES := -D_kernel_start=0x$(KERNEL_START) \ HEAD_DEFINES := -D_kernel_start=$(VMLINUX_LOAD_ADDRESS) \
-D_kernel_entry=0x$(KERNEL_ENTRY) \ -D_kernel_entry=$(VMLINUX_ENTRY_ADDRESS) \
-D VERSION="\"$(Version)\"" \ -D VERSION="\"$(Version)\"" \
-D TIMESTAMP=$(shell date +%s) -D TIMESTAMP=$(shell date +%s)
......
...@@ -3,8 +3,9 @@ ...@@ -3,8 +3,9 @@
# #
obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ 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_GPIOLIB) += gpio.o
obj-$(CONFIG_PCI) += pci.o
# #
# Serial port support # Serial port support
......
...@@ -436,7 +436,6 @@ static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr) ...@@ -436,7 +436,6 @@ static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr)
break; break;
default: default:
return SIGILL; return SIGILL;
break;
} }
break; break;
case mm_32f_74_op: /* c.cond.fmt */ case mm_32f_74_op: /* c.cond.fmt */
...@@ -451,12 +450,10 @@ static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr) ...@@ -451,12 +450,10 @@ static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr)
break; break;
default: default:
return SIGILL; return SIGILL;
break;
} }
break; break;
default: default:
return SIGILL; return SIGILL;
break;
} }
*insn_ptr = mips32_insn; *insn_ptr = mips32_insn;
...@@ -491,7 +488,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -491,7 +488,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
*contpc = regs->regs[insn.mm_i_format.rs]; *contpc = regs->regs[insn.mm_i_format.rs];
return 1; return 1;
break;
} }
} }
break; break;
...@@ -513,7 +509,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -513,7 +509,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc + dec_insn.pc_inc +
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
break;
case mm_bgezals_op: case mm_bgezals_op:
case mm_bgezal_op: case mm_bgezal_op:
regs->regs[31] = regs->cp0_epc + regs->regs[31] = regs->cp0_epc +
...@@ -530,7 +525,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -530,7 +525,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc + dec_insn.pc_inc +
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
break;
case mm_blez_op: case mm_blez_op:
if ((long)regs->regs[insn.mm_i_format.rs] <= 0) if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
*contpc = regs->cp0_epc + *contpc = regs->cp0_epc +
...@@ -541,7 +535,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -541,7 +535,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc + dec_insn.pc_inc +
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
break;
case mm_bgtz_op: case mm_bgtz_op:
if ((long)regs->regs[insn.mm_i_format.rs] <= 0) if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
*contpc = regs->cp0_epc + *contpc = regs->cp0_epc +
...@@ -552,7 +545,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -552,7 +545,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc + dec_insn.pc_inc +
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
break;
case mm_bc2f_op: case mm_bc2f_op:
case mm_bc1f_op: case mm_bc1f_op:
bc_false = 1; bc_false = 1;
...@@ -580,7 +572,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -580,7 +572,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
*contpc = regs->cp0_epc + *contpc = regs->cp0_epc +
dec_insn.pc_inc + dec_insn.next_pc_inc; dec_insn.pc_inc + dec_insn.next_pc_inc;
return 1; return 1;
break;
} }
break; break;
case mm_pool16c_op: case mm_pool16c_op:
...@@ -593,7 +584,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -593,7 +584,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
case mm_jr16_op: case mm_jr16_op:
*contpc = regs->regs[insn.mm_i_format.rs]; *contpc = regs->regs[insn.mm_i_format.rs];
return 1; return 1;
break;
} }
break; break;
case mm_beqz16_op: case mm_beqz16_op:
...@@ -605,7 +595,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -605,7 +595,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
*contpc = regs->cp0_epc + *contpc = regs->cp0_epc +
dec_insn.pc_inc + dec_insn.next_pc_inc; dec_insn.pc_inc + dec_insn.next_pc_inc;
return 1; return 1;
break;
case mm_bnez16_op: case mm_bnez16_op:
if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] != 0) if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] != 0)
*contpc = regs->cp0_epc + *contpc = regs->cp0_epc +
...@@ -615,12 +604,10 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -615,12 +604,10 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
*contpc = regs->cp0_epc + *contpc = regs->cp0_epc +
dec_insn.pc_inc + dec_insn.next_pc_inc; dec_insn.pc_inc + dec_insn.next_pc_inc;
return 1; return 1;
break;
case mm_b16_op: case mm_b16_op:
*contpc = regs->cp0_epc + dec_insn.pc_inc + *contpc = regs->cp0_epc + dec_insn.pc_inc +
(insn.mm_b0_format.simmediate << 1); (insn.mm_b0_format.simmediate << 1);
return 1; return 1;
break;
case mm_beq32_op: case mm_beq32_op:
if (regs->regs[insn.mm_i_format.rs] == if (regs->regs[insn.mm_i_format.rs] ==
regs->regs[insn.mm_i_format.rt]) regs->regs[insn.mm_i_format.rt])
...@@ -632,7 +619,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -632,7 +619,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc + dec_insn.pc_inc +
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
break;
case mm_bne32_op: case mm_bne32_op:
if (regs->regs[insn.mm_i_format.rs] != if (regs->regs[insn.mm_i_format.rs] !=
regs->regs[insn.mm_i_format.rt]) regs->regs[insn.mm_i_format.rt])
...@@ -643,7 +629,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -643,7 +629,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
*contpc = regs->cp0_epc + *contpc = regs->cp0_epc +
dec_insn.pc_inc + dec_insn.next_pc_inc; dec_insn.pc_inc + dec_insn.next_pc_inc;
return 1; return 1;
break;
case mm_jalx32_op: case mm_jalx32_op:
regs->regs[31] = regs->cp0_epc + regs->regs[31] = regs->cp0_epc +
dec_insn.pc_inc + dec_insn.next_pc_inc; 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, ...@@ -652,7 +637,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
*contpc <<= 28; *contpc <<= 28;
*contpc |= (insn.j_format.target << 2); *contpc |= (insn.j_format.target << 2);
return 1; return 1;
break;
case mm_jals32_op: case mm_jals32_op:
case mm_jal32_op: case mm_jal32_op:
regs->regs[31] = regs->cp0_epc + regs->regs[31] = regs->cp0_epc +
...@@ -665,7 +649,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -665,7 +649,6 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
*contpc |= (insn.j_format.target << 1); *contpc |= (insn.j_format.target << 1);
set_isa16_mode(*contpc); set_isa16_mode(*contpc);
return 1; return 1;
break;
} }
return 0; return 0;
} }
...@@ -694,7 +677,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -694,7 +677,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
case jr_op: case jr_op:
*contpc = regs->regs[insn.r_format.rs]; *contpc = regs->regs[insn.r_format.rs];
return 1; return 1;
break;
} }
break; break;
case bcond_op: case bcond_op:
...@@ -716,7 +698,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -716,7 +698,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc + dec_insn.pc_inc +
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
break;
case bgezal_op: case bgezal_op:
case bgezall_op: case bgezall_op:
regs->regs[31] = regs->cp0_epc + regs->regs[31] = regs->cp0_epc +
...@@ -734,7 +715,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -734,7 +715,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc + dec_insn.pc_inc +
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
break;
} }
break; break;
case jalx_op: case jalx_op:
...@@ -752,7 +732,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -752,7 +732,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
/* Set microMIPS mode bit: XOR for jalx. */ /* Set microMIPS mode bit: XOR for jalx. */
*contpc ^= bit; *contpc ^= bit;
return 1; return 1;
break;
case beq_op: case beq_op:
case beql_op: case beql_op:
if (regs->regs[insn.i_format.rs] == if (regs->regs[insn.i_format.rs] ==
...@@ -765,7 +744,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -765,7 +744,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc + dec_insn.pc_inc +
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
break;
case bne_op: case bne_op:
case bnel_op: case bnel_op:
if (regs->regs[insn.i_format.rs] != if (regs->regs[insn.i_format.rs] !=
...@@ -778,7 +756,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -778,7 +756,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc + dec_insn.pc_inc +
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
break;
case blez_op: case blez_op:
case blezl_op: case blezl_op:
if ((long)regs->regs[insn.i_format.rs] <= 0) 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, ...@@ -790,7 +767,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc + dec_insn.pc_inc +
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
break;
case bgtz_op: case bgtz_op:
case bgtzl_op: case bgtzl_op:
if ((long)regs->regs[insn.i_format.rs] > 0) 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, ...@@ -802,7 +778,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc + dec_insn.pc_inc +
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
break;
#ifdef CONFIG_CPU_CAVIUM_OCTEON #ifdef CONFIG_CPU_CAVIUM_OCTEON
case lwc2_op: /* This is bbit0 on Octeon */ case lwc2_op: /* This is bbit0 on Octeon */
if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt)) == 0) 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, ...@@ -856,7 +831,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc + dec_insn.pc_inc +
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
break;
case 1: /* bc1t */ case 1: /* bc1t */
case 3: /* bc1tl */ case 3: /* bc1tl */
if (fcr31 & (1 << bit)) if (fcr31 & (1 << bit))
...@@ -868,7 +842,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -868,7 +842,6 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.pc_inc + dec_insn.pc_inc +
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
break;
} }
} }
break; break;
......
...@@ -224,6 +224,20 @@ static void probe_octeon(void) ...@@ -224,6 +224,20 @@ static void probe_octeon(void)
c->options |= MIPS_CPU_PREFETCH; c->options |= MIPS_CPU_PREFETCH;
break; 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: default:
panic("Unsupported Cavium Networks CPU type"); panic("Unsupported Cavium Networks CPU type");
break; break;
......
...@@ -50,16 +50,20 @@ static inline struct page *dma_addr_to_page(struct device *dev, ...@@ -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; * Warning on the terminology - Linux calls an uncached area coherent;
* MIPS terminology calls memory areas with hardware maintained coherency * MIPS terminology calls memory areas with hardware maintained coherency
* coherent. * coherent.
*/ */
static inline int cpu_needs_post_dma_flush(struct device *dev)
static inline int cpu_is_noncoherent_r10000(struct device *dev)
{ {
return !plat_device_is_coherent(dev) && return !plat_device_is_coherent(dev) &&
(current_cpu_type() == CPU_R10000 || (boot_cpu_type() == CPU_R10000 ||
current_cpu_type() == CPU_R12000); boot_cpu_type() == CPU_R12000 ||
boot_cpu_type() == CPU_BMIPS5000);
} }
static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) 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, ...@@ -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, 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) 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_sync(dma_addr_to_page(dev, dma_addr),
dma_addr & ~PAGE_MASK, size, direction); dma_addr & ~PAGE_MASK, size, direction);
...@@ -284,7 +288,7 @@ static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg, ...@@ -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, static void mips_dma_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) 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_sync(dma_addr_to_page(dev, dma_handle),
dma_handle & ~PAGE_MASK, size, direction); dma_handle & ~PAGE_MASK, size, direction);
} }
...@@ -305,7 +309,7 @@ static void mips_dma_sync_sg_for_cpu(struct device *dev, ...@@ -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. */ /* Make sure that gcc doesn't leave the empty loop body. */
for (i = 0; i < nelems; i++, sg++) { 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, __dma_sync(sg_page(sg), sg->offset, sg->length,
direction); direction);
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/swap.h> #include <linux/swap.h>
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
#include <asm/cpu-features.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
static inline pte_t gup_get_pte(pte_t *ptep) 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, ...@@ -273,7 +274,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
len = (unsigned long) nr_pages << PAGE_SHIFT; len = (unsigned long) nr_pages << PAGE_SHIFT;
end = start + len; end = start + len;
if (end < start) if (end < start || cpu_has_dc_aliases)
goto slow_irqon; goto slow_irqon;
/* XXX: batch / limit 'nr' */ /* XXX: batch / limit 'nr' */
......
...@@ -254,6 +254,7 @@ void copy_from_user_page(struct vm_area_struct *vma, ...@@ -254,6 +254,7 @@ void copy_from_user_page(struct vm_area_struct *vma,
SetPageDcacheDirty(page); SetPageDcacheDirty(page);
} }
} }
EXPORT_SYMBOL_GPL(copy_from_user_page);
void __init fixrange_init(unsigned long start, unsigned long end, void __init fixrange_init(unsigned long start, unsigned long end,
pgd_t *pgd_base) pgd_t *pgd_base)
......
...@@ -16,10 +16,12 @@ ...@@ -16,10 +16,12 @@
#define FASTPATH_SIZE 128 #define FASTPATH_SIZE 128
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
LEAF(tlbmiss_handler_setup_pgd) LEAF(tlbmiss_handler_setup_pgd)
.space 16 * 4 .space 16 * 4
END(tlbmiss_handler_setup_pgd) END(tlbmiss_handler_setup_pgd)
EXPORT(tlbmiss_handler_setup_pgd_end) EXPORT(tlbmiss_handler_setup_pgd_end)
#endif
LEAF(handle_tlbm) LEAF(handle_tlbm)
.space FASTPATH_SIZE * 4 .space FASTPATH_SIZE * 4
......
...@@ -85,6 +85,7 @@ static int use_bbit_insns(void) ...@@ -85,6 +85,7 @@ static int use_bbit_insns(void)
case CPU_CAVIUM_OCTEON: case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS: case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2: case CPU_CAVIUM_OCTEON2:
case CPU_CAVIUM_OCTEON3:
return 1; return 1;
default: default:
return 0; return 0;
...@@ -95,6 +96,7 @@ static int use_lwx_insns(void) ...@@ -95,6 +96,7 @@ static int use_lwx_insns(void)
{ {
switch (current_cpu_type()) { switch (current_cpu_type()) {
case CPU_CAVIUM_OCTEON2: case CPU_CAVIUM_OCTEON2:
case CPU_CAVIUM_OCTEON3:
return 1; return 1;
default: default:
return 0; return 0;
......
...@@ -19,6 +19,15 @@ config DT_XLP_SVP ...@@ -19,6 +19,15 @@ config DT_XLP_SVP
pointer to the kernel. The corresponding DTS file is at pointer to the kernel. The corresponding DTS file is at
arch/mips/netlogic/dts/xlp_svp.dts 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 config NLM_MULTINODE
bool "Support for multi-chip boards" bool "Support for multi-chip boards"
depends on NLM_XLP_BOARD depends on NLM_XLP_BOARD
......
...@@ -106,9 +106,7 @@ void nlm_early_init_secondary(int cpu) ...@@ -106,9 +106,7 @@ void nlm_early_init_secondary(int cpu)
{ {
change_c0_config(CONF_CM_CMASK, 0x3); change_c0_config(CONF_CM_CMASK, 0x3);
#ifdef CONFIG_CPU_XLP #ifdef CONFIG_CPU_XLP
/* mmu init, once per core */ xlp_mmu_init();
if (cpu % NLM_THREADS_PER_CORE == 0)
xlp_mmu_init();
#endif #endif
write_c0_ebase(nlm_current_node()->ebase); write_c0_ebase(nlm_current_node()->ebase);
} }
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#if defined(CONFIG_CPU_XLP) #if defined(CONFIG_CPU_XLP)
#include <asm/netlogic/xlp-hal/iomap.h> #include <asm/netlogic/xlp-hal/iomap.h>
#include <asm/netlogic/xlp-hal/xlp.h> #include <asm/netlogic/xlp-hal/xlp.h>
#include <asm/netlogic/xlp-hal/sys.h>
#include <asm/netlogic/xlp-hal/pic.h> #include <asm/netlogic/xlp-hal/pic.h>
#elif defined(CONFIG_CPU_XLR) #elif defined(CONFIG_CPU_XLR)
#include <asm/netlogic/xlr/iomap.h> #include <asm/netlogic/xlr/iomap.h>
...@@ -91,7 +92,7 @@ static void nlm_init_pic_timer(void) ...@@ -91,7 +92,7 @@ static void nlm_init_pic_timer(void)
csrc_pic.read = nlm_get_pic_timer; csrc_pic.read = nlm_get_pic_timer;
} }
csrc_pic.rating = 1000; 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) void __init plat_time_init(void)
......
obj-$(CONFIG_DT_XLP_EVP) := xlp_evp.dtb.o obj-$(CONFIG_DT_XLP_EVP) := xlp_evp.dtb.o
obj-$(CONFIG_DT_XLP_SVP) += xlp_svp.dtb.o obj-$(CONFIG_DT_XLP_SVP) += xlp_svp.dtb.o
obj-$(CONFIG_DT_XLP_FVP) += xlp_fvp.dtb.o
...@@ -9,19 +9,12 @@ / { ...@@ -9,19 +9,12 @@ / {
#address-cells = <2>; #address-cells = <2>;
#size-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 { soc {
#address-cells = <2>; #address-cells = <2>;
#size-cells = <1>; #size-cells = <1>;
compatible = "simple-bus"; compatible = "simple-bus";
ranges = <0 0 0 0x18000000 0x04000000 // PCIe CFG 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 { serial0: serial@30000 {
device_type = "serial"; 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 @@ / { ...@@ -9,19 +9,12 @@ / {
#address-cells = <2>; #address-cells = <2>;
#size-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 { soc {
#address-cells = <2>; #address-cells = <2>;
#size-cells = <1>; #size-cells = <1>;
compatible = "simple-bus"; compatible = "simple-bus";
ranges = <0 0 0 0x18000000 0x04000000 // PCIe CFG 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 { serial0: serial@30000 {
device_type = "serial"; device_type = "serial";
......
obj-y += setup.o nlm_hal.o cop2-ex.o dt.o obj-y += setup.o nlm_hal.o cop2-ex.o dt.o
obj-$(CONFIG_SMP) += wakeup.o obj-$(CONFIG_SMP) += wakeup.o
obj-$(CONFIG_USB) += usb-init.o obj-$(CONFIG_USB) += usb-init.o
obj-$(CONFIG_USB) += usb-init-xlp2.o
...@@ -39,12 +39,18 @@ ...@@ -39,12 +39,18 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/of_device.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) void __init *xlp_dt_init(void *fdtp)
{ {
if (!fdtp) { if (!fdtp) {
switch (current_cpu_data.processor_id & 0xff00) { 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 #ifdef CONFIG_DT_XLP_SVP
case PRID_IMP_NETLOGIC_XLP3XX: case PRID_IMP_NETLOGIC_XLP3XX:
fdtp = __dtb_xlp_svp_begin; fdtp = __dtb_xlp_svp_begin;
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <asm/netlogic/haldefs.h> #include <asm/netlogic/haldefs.h>
#include <asm/netlogic/xlp-hal/iomap.h> #include <asm/netlogic/xlp-hal/iomap.h>
#include <asm/netlogic/xlp-hal/xlp.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/pic.h>
#include <asm/netlogic/xlp-hal/sys.h> #include <asm/netlogic/xlp-hal/sys.h>
...@@ -64,6 +65,7 @@ int nlm_irq_to_irt(int irq) ...@@ -64,6 +65,7 @@ int nlm_irq_to_irt(int irq)
uint64_t pcibase; uint64_t pcibase;
int devoff, irt; int devoff, irt;
devoff = 0;
switch (irq) { switch (irq) {
case PIC_UART_0_IRQ: case PIC_UART_0_IRQ:
devoff = XLP_IO_UART0_OFFSET(0); devoff = XLP_IO_UART0_OFFSET(0);
...@@ -71,44 +73,68 @@ int nlm_irq_to_irt(int irq) ...@@ -71,44 +73,68 @@ int nlm_irq_to_irt(int irq)
case PIC_UART_1_IRQ: case PIC_UART_1_IRQ:
devoff = XLP_IO_UART1_OFFSET(0); devoff = XLP_IO_UART1_OFFSET(0);
break; break;
case PIC_EHCI_0_IRQ:
devoff = XLP_IO_USB_EHCI0_OFFSET(0);
break;
case PIC_EHCI_1_IRQ:
devoff = XLP_IO_USB_EHCI1_OFFSET(0);
break;
case PIC_OHCI_0_IRQ:
devoff = XLP_IO_USB_OHCI0_OFFSET(0);
break;
case PIC_OHCI_1_IRQ:
devoff = XLP_IO_USB_OHCI1_OFFSET(0);
break;
case PIC_OHCI_2_IRQ:
devoff = XLP_IO_USB_OHCI2_OFFSET(0);
break;
case PIC_OHCI_3_IRQ:
devoff = XLP_IO_USB_OHCI3_OFFSET(0);
break;
case PIC_MMC_IRQ: case PIC_MMC_IRQ:
devoff = XLP_IO_SD_OFFSET(0); devoff = XLP_IO_SD_OFFSET(0);
break; break;
case PIC_I2C_0_IRQ: case PIC_I2C_0_IRQ: /* I2C will be fixed up */
devoff = XLP_IO_I2C0_OFFSET(0);
break;
case PIC_I2C_1_IRQ: case PIC_I2C_1_IRQ:
devoff = XLP_IO_I2C1_OFFSET(0); 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; break;
default: default:
devoff = 0; if (cpu_is_xlpii()) {
break; 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;
case PIC_EHCI_1_IRQ:
devoff = XLP_IO_USB_EHCI1_OFFSET(0);
break;
case PIC_OHCI_0_IRQ:
devoff = XLP_IO_USB_OHCI0_OFFSET(0);
break;
case PIC_OHCI_1_IRQ:
devoff = XLP_IO_USB_OHCI1_OFFSET(0);
break;
case PIC_OHCI_2_IRQ:
devoff = XLP_IO_USB_OHCI2_OFFSET(0);
break;
case PIC_OHCI_3_IRQ:
devoff = XLP_IO_USB_OHCI3_OFFSET(0);
break;
}
}
} }
if (devoff != 0) { if (devoff != 0) {
pcibase = nlm_pcicfg_base(devoff); pcibase = nlm_pcicfg_base(devoff);
irt = nlm_read_reg(pcibase, XLP_PCI_IRTINFO_REG) & 0xffff; irt = nlm_read_reg(pcibase, XLP_PCI_IRTINFO_REG) & 0xffff;
/* HW bug, I2C 1 irt entry is off by one */ /* HW weirdness, I2C IRT entry has to be fixed up */
if (irq == PIC_I2C_1_IRQ) switch (irq) {
irt = irt + 1; 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) { } 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 */ /* HW bug, PCI IRT entries are bad on early silicon, fix */
irt = PIC_IRT_PCIE_LINK_INDEX(irq - PIC_PCIE_LINK_0_IRQ); irt = PIC_IRT_PCIE_LINK_INDEX(irq - PIC_PCIE_LINK_0_IRQ);
...@@ -126,19 +152,160 @@ unsigned int nlm_get_core_frequency(int node, int core) ...@@ -126,19 +152,160 @@ unsigned int nlm_get_core_frequency(int node, int core)
sysbase = nlm_get_node(node)->sysbase; sysbase = nlm_get_node(node)->sysbase;
rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);
dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE); if (cpu_is_xlpii()) {
pll_divf = ((rstval >> 10) & 0x7f) + 1; num = 1000000ULL * (400 * 3 + 100 * (rstval >> 26));
pll_divr = ((rstval >> 8) & 0x3) + 1; denom = 3;
ext_div = ((rstval >> 30) & 0x3) + 1; } else {
dfs_div = ((dfsval >> (core * 4)) & 0xf) + 1; dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE);
pll_divf = ((rstval >> 10) & 0x7f) + 1;
num = 800000000ULL * pll_divf; pll_divr = ((rstval >> 8) & 0x3) + 1;
denom = 3 * pll_divr * ext_div * dfs_div; ext_div = ((rstval >> 30) & 0x3) + 1;
dfs_div = ((dfsval >> (core * 4)) & 0xf) + 1;
num = 800000000ULL * pll_divf;
denom = 3 * pll_divr * ext_div * dfs_div;
}
do_div(num, denom); do_div(num, denom);
return (unsigned int)num; 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) unsigned int nlm_get_cpu_frequency(void)
{ {
return nlm_get_core_frequency(0, 0); 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) ...@@ -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) void __init plat_mem_setup(void)
{ {
panic_timeout = 5; panic_timeout = 5;
...@@ -82,12 +99,23 @@ void __init plat_mem_setup(void) ...@@ -82,12 +99,23 @@ void __init plat_mem_setup(void)
/* memory and bootargs from DT */ /* memory and bootargs from DT */
early_init_devtree(initial_boot_params); 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(); nlm_fixup_mem();
} }
const char *get_system_type(void) const char *get_system_type(void)
{ {
return "Netlogic XLP Series"; 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) void __init prom_free_prom_memory(void)
...@@ -97,12 +125,20 @@ void __init prom_free_prom_memory(void) ...@@ -97,12 +125,20 @@ void __init prom_free_prom_memory(void)
void xlp_mmu_init(void) void xlp_mmu_init(void)
{ {
/* enable extended TLB and Large Fixed TLB */ u32 conf4;
write_c0_config6(read_c0_config6() | 0x24);
if (cpu_is_xlpii()) {
/* set page mask of Fixed TLB in config7 */ /* XLPII series has extended pagesize in config 4 */
write_c0_config7(PM_DEFAULT_MASK >> conf4 = read_c0_config4() & ~0x1f00u;
(13 + (ffz(PM_DEFAULT_MASK >> 13) / 2))); 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 extended Fixed TLB in config7 */
write_c0_config7(PM_DEFAULT_MASK >>
(13 + (ffz(PM_DEFAULT_MASK >> 13) / 2)));
}
} }
void nlm_percpu_init(int hwcpuid) 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) ...@@ -75,8 +75,7 @@ static void nlm_usb_intr_en(int node, int port)
port_addr = nlm_get_usb_regbase(node, port); port_addr = nlm_get_usb_regbase(node, port);
val = nlm_read_usb_reg(port_addr, USB_INT_EN); val = nlm_read_usb_reg(port_addr, USB_INT_EN);
val = USB_CTRL_INTERRUPT_EN | USB_OHCI_INTERRUPT_EN | val = USB_CTRL_INTERRUPT_EN | USB_OHCI_INTERRUPT_EN |
USB_OHCI_INTERRUPT1_EN | USB_CTRL_INTERRUPT_EN | USB_OHCI_INTERRUPT1_EN | USB_OHCI_INTERRUPT2_EN;
USB_OHCI_INTERRUPT_EN | USB_OHCI_INTERRUPT2_EN;
nlm_write_usb_reg(port_addr, USB_INT_EN, val); nlm_write_usb_reg(port_addr, USB_INT_EN, val);
} }
...@@ -100,6 +99,9 @@ static void nlm_usb_hw_reset(int node, int port) ...@@ -100,6 +99,9 @@ static void nlm_usb_hw_reset(int node, int port)
static int __init nlm_platform_usb_init(void) static int __init nlm_platform_usb_init(void)
{ {
if (cpu_is_xlpii())
return 0;
pr_info("Initializing USB Interface\n"); pr_info("Initializing USB Interface\n");
nlm_usb_hw_reset(0, 0); nlm_usb_hw_reset(0, 0);
nlm_usb_hw_reset(0, 3); nlm_usb_hw_reset(0, 3);
......
...@@ -58,10 +58,12 @@ static int xlp_wakeup_core(uint64_t sysbase, int node, int core) ...@@ -58,10 +58,12 @@ static int xlp_wakeup_core(uint64_t sysbase, int node, int core)
coremask = (1 << core); coremask = (1 << core);
/* Enable CPU clock */ /* Enable CPU clock in case of 8xx/3xx */
value = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL); if (!cpu_is_xlpii()) {
value &= ~coremask; value = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL);
nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value); value &= ~coremask;
nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value);
}
/* Remove CPU Reset */ /* Remove CPU Reset */
value = nlm_read_sys_reg(sysbase, SYS_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 ...@@ -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_SNI_RM) += fixup-sni.o ops-sni.o
obj-$(CONFIG_LANTIQ) += fixup-lantiq.o obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-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_TB0219) += fixup-tb0219.o
obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
......
...@@ -586,15 +586,16 @@ static int __init octeon_pci_setup(void) ...@@ -586,15 +586,16 @@ static int __init octeon_pci_setup(void)
else else
octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_BIG; 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()) { if (!octeon_is_pci_host()) {
pr_notice("Not in host mode, PCI Controller not initialized\n"); pr_notice("Not in host mode, PCI Controller not initialized\n");
return 0; 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", pr_notice("%s Octeon big bar support\n",
(octeon_dma_bar_type == (octeon_dma_bar_type ==
OCTEON_DMA_BAR_TYPE_BIG) ? "Enabling" : "Disabling"); 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 config BOOTLOADER_FAMILY
string "POWERTV Bootloader Family string" string "POWERTV Bootloader Family string"
default "85" default "85"
depends on POWERTV && !BOOTLOADER_DRIVER depends on POWERTV
help help
This value should be specified when the bootloader driver is disabled This value should be specified when the bootloader driver is disabled
and must be exactly two characters long. Families supported are: and must be exactly two characters long. Families supported are:
......
...@@ -147,20 +147,10 @@ static __init noinline void platform_set_family(void) ...@@ -147,20 +147,10 @@ static __init noinline void platform_set_family(void)
if (check_forcefamily(forced_family) == 0) if (check_forcefamily(forced_family) == 0)
bootldr_family = BOOTLDRFAMILY(forced_family[0], bootldr_family = BOOTLDRFAMILY(forced_family[0],
forced_family[1]); forced_family[1]);
else { else
#ifdef CONFIG_BOOTLOADER_DRIVER
bootldr_family = (unsigned short) kbldr_GetSWFamily();
#else
#if defined(CONFIG_BOOTLOADER_FAMILY)
bootldr_family = (unsigned short) BOOTLDRFAMILY( bootldr_family = (unsigned short) BOOTLDRFAMILY(
CONFIG_BOOTLOADER_FAMILY[0], CONFIG_BOOTLOADER_FAMILY[0],
CONFIG_BOOTLOADER_FAMILY[1]); CONFIG_BOOTLOADER_FAMILY[1]);
#else
#error "Unknown Bootloader Family"
#endif
#endif
}
pr_info("Bootloader Family = 0x%04X\n", bootldr_family); pr_info("Bootloader Family = 0x%04X\n", bootldr_family);
......
...@@ -87,8 +87,4 @@ void __init prom_init(void) ...@@ -87,8 +87,4 @@ void __init prom_init(void)
configure_platform(); configure_platform();
prom_meminit(); prom_meminit();
#ifndef CONFIG_BOOTLOADER_DRIVER
pr_info("\nBootloader driver isn't loaded...\n");
#endif
} }
...@@ -21,24 +21,12 @@ ...@@ -21,24 +21,12 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/reboot.h> /* Not included by linux/reboot.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 <asm/mach-powertv/asic_regs.h>
#include "reset.h" #include "reset.h"
static void mips_machine_restart(char *command) 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)); writel(0x1, asic_reg_addr(watchdog));
#endif
} }
void mips_reboot_setup(void) void mips_reboot_setup(void)
......
if RALINK if RALINK
config CLKEVT_RT3352
bool
depends on SOC_RT305X || SOC_MT7620
default y
select CLKSRC_OF
select CLKSRC_MMIO
choice choice
prompt "Ralink SoC selection" prompt "Ralink SoC selection"
default SOC_RT305X default SOC_RT305X
...@@ -19,9 +26,12 @@ choice ...@@ -19,9 +26,12 @@ choice
bool "RT3883" bool "RT3883"
select USB_ARCH_HAS_OHCI select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI select USB_ARCH_HAS_EHCI
select HW_HAS_PCI
config SOC_MT7620 config SOC_MT7620
bool "MT7620" bool "MT7620"
select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI
endchoice endchoice
......
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
# Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> # Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
# Copyright (C) 2013 John Crispin <blogic@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_RT288X) += rt288x.o
obj-$(CONFIG_SOC_RT305X) += rt305x.o obj-$(CONFIG_SOC_RT305X) += rt305x.o
......
...@@ -26,3 +26,4 @@ cflags-$(CONFIG_SOC_RT3883) += -I$(srctree)/arch/mips/include/asm/mach-ralink/rt ...@@ -26,3 +26,4 @@ cflags-$(CONFIG_SOC_RT3883) += -I$(srctree)/arch/mips/include/asm/mach-ralink/rt
# Ralink MT7620 # Ralink MT7620
# #
load-$(CONFIG_SOC_MT7620) += 0xffffffff80000000 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) ...@@ -69,4 +69,5 @@ void __init plat_time_init(void)
pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000); pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
mips_hpt_frequency = clk_get_rate(clk) / 2; mips_hpt_frequency = clk_get_rate(clk) / 2;
clk_put(clk); clk_put(clk);
clocksource_of_init();
} }
...@@ -46,6 +46,8 @@ extern void ralink_of_remap(void); ...@@ -46,6 +46,8 @@ extern void ralink_of_remap(void);
extern void ralink_clk_init(void); extern void ralink_clk_init(void);
extern void ralink_clk_add(const char *dev, unsigned long rate); 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); extern void prom_soc_init(struct ralink_soc_info *soc_info);
__iomem void *plat_of_remap_node(const char *node); __iomem void *plat_of_remap_node(const char *node);
......
...@@ -23,9 +23,6 @@ ...@@ -23,9 +23,6 @@
/* does the board have sdram or ddram */ /* does the board have sdram or ddram */
static int dram_type; static int dram_type;
/* the pll dividers */
static u32 mt7620_clk_divider[] = { 2, 3, 4, 8 };
static struct ralink_pinmux_grp mode_mux[] = { static struct ralink_pinmux_grp mode_mux[] = {
{ {
.name = "i2c", .name = "i2c",
...@@ -140,34 +137,189 @@ struct ralink_pinmux rt_gpio_pinmux = { ...@@ -140,34 +137,189 @@ struct ralink_pinmux rt_gpio_pinmux = {
.uart_mask = MT7620_GPIO_MODE_UART0_MASK, .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; u64 t;
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;
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) if (dram_type == SYSCFG0_DRAM_TYPE_SDRAM)
sys_rate = cpu_rate / 4; return pll_rate / 4;
else
sys_rate = cpu_rate / 3; 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("cpu", cpu_rate);
ralink_clk_add("10000100.timer", 40000000); ralink_clk_add("10000100.timer", periph_rate);
ralink_clk_add("10000500.uart", 40000000); ralink_clk_add("10000120.watchdog", periph_rate);
ralink_clk_add("10000c00.uartlite", 40000000); 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) void __init ralink_of_remap(void)
...@@ -214,16 +366,19 @@ void prom_soc_init(struct ralink_soc_info *soc_info) ...@@ -214,16 +366,19 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
switch (dram_type) { switch (dram_type) {
case SYSCFG0_DRAM_TYPE_SDRAM: case SYSCFG0_DRAM_TYPE_SDRAM:
pr_info("Board has SDRAM\n");
soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN; soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN;
soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX; soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX;
break; break;
case SYSCFG0_DRAM_TYPE_DDR1: case SYSCFG0_DRAM_TYPE_DDR1:
pr_info("Board has DDR1\n");
soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN; soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN;
soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX; soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX;
break; break;
case SYSCFG0_DRAM_TYPE_DDR2: case SYSCFG0_DRAM_TYPE_DDR2:
pr_info("Board has DDR2\n");
soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN; soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN;
soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX; soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX;
break; break;
......
...@@ -110,6 +110,9 @@ static int __init plat_of_setup(void) ...@@ -110,6 +110,9 @@ static int __init plat_of_setup(void)
if (of_platform_populate(NULL, of_ids, NULL, NULL)) if (of_platform_populate(NULL, of_ids, NULL, NULL))
panic("failed to populate DT\n"); panic("failed to populate DT\n");
/* make sure ithat the reset controller is setup early */
ralink_rst_init();
return 0; return 0;
} }
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h>
#include <linux/reset-controller.h>
#include <asm/reboot.h> #include <asm/reboot.h>
...@@ -19,6 +21,66 @@ ...@@ -19,6 +21,66 @@
#define SYSC_REG_RESET_CTRL 0x034 #define SYSC_REG_RESET_CTRL 0x034
#define RSTCTL_RESET_SYSTEM BIT(0) #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) static void ralink_restart(char *command)
{ {
local_irq_disable(); 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) ...@@ -350,7 +350,7 @@ static void __init select_board(void)
} }
/* select "default" board */ /* select "default" board */
#ifdef CONFIG_CPU_TX39XX #ifdef CONFIG_TOSHIBA_JMR3927
txx9_board_vec = &jmr3927_vec; txx9_board_vec = &jmr3927_vec;
#endif #endif
#ifdef CONFIG_CPU_TX49XX #ifdef CONFIG_CPU_TX49XX
......
...@@ -203,6 +203,14 @@ config GPIO_MXS ...@@ -203,6 +203,14 @@ config GPIO_MXS
select GPIO_GENERIC select GPIO_GENERIC
select GENERIC_IRQ_CHIP 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 config GPIO_PL061
bool "PrimeCell PL061 GPIO support" bool "PrimeCell PL061 GPIO support"
depends on ARM && ARM_AMBA depends on ARM && ARM_AMBA
......
...@@ -52,6 +52,7 @@ obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o ...@@ -52,6 +52,7 @@ obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o
obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o
obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o
obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o
obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o
obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.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 ...@@ -87,6 +87,27 @@ case "${ARCH}" in
[ -f "${objtree}/vmlinux.SYS" ] && cp -v -- "${objtree}/vmlinux.SYS" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.SYS" [ -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" [ -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}" [ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-kbuild-${KERNELRELEASE}"
echo "" >&2 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