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