Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle: "This is an unusually large pull request for MIPS - in parts because lots of patches missed the 3.18 deadline but primarily because some folks opened the flood gates. - Retire the MIPS-specific phys_t with the generic phys_addr_t. - Improvments for the backtrace code used by oprofile. - Better backtraces on SMP systems. - Cleanups for the Octeon platform code. - Cleanups and fixes for the Loongson platform code. - Cleanups and fixes to the firmware library. - Switch ATH79 platform to use the firmware library. - Grand overhault to the SEAD3 and Malta interrupt code. - Move the GIC interrupt code to drivers/irqchip - Lots of GIC cleanups and updates to the GIC code to use modern IRQ infrastructures and features of the kernel. - OF documentation updates for the GIC bindings - Move GIC clocksource driver to drivers/clocksource - Merge GIC clocksource driver with clockevent driver. - Further updates to bring the GIC clocksource driver up to date. - R3000 TLB code cleanups - Improvments to the Loongson 3 platform code. - Convert pr_warning to pr_warn. - Merge a bunch of small lantiq and ralink fixes that have been staged/lingering inside the openwrt tree for a while. - Update archhelp for IP22/IP32 - Fix a number of issues for Loongson 1B. - New clocksource and clockevent driver for Loongson 1B. - Further work on clk handling for Loongson 1B. - Platform work for Broadcom BMIPS. - Error handling cleanups for TurboChannel. - Fixes and optimization to the microMIPS support. - Option to disable the FTLB. - Dump more relevant information on machine check exception - Change binfmt to allow arch to examine PT_*PROC headers - Support for new style FPU register model in O32 - VDSO randomization. - BCM47xx cleanups - BCM47xx reimplement the way the kernel accesses NVRAM information. - Random cleanups - Add support for ATH25 platforms - Remove pointless locking code in some PCI platforms. - Some improvments to EVA support - Minor Alchemy cleanup" * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (185 commits) MIPS: Add MFHC0 and MTHC0 instructions to uasm. MIPS: Cosmetic cleanups of page table headers. MIPS: Add CP0 macros for extended EntryLo registers MIPS: Remove now unused definition of phys_t. MIPS: Replace use of phys_t with phys_addr_t. MIPS: Replace MIPS-specific 64BIT_PHYS_ADDR with generic PHYS_ADDR_T_64BIT PCMCIA: Alchemy Don't select 64BIT_PHYS_ADDR in Kconfig. MIPS: lib: memset: Clean up some MIPS{EL,EB} ifdefery MIPS: iomap: Use __mem_{read,write}{b,w,l} for MMIO MIPS: <asm/types.h> fix indentation. MAINTAINERS: Add entry for BMIPS multiplatform kernel MIPS: Enable VDSO randomization MIPS: Remove a temporary hack for debugging cache flushes in SMTC configuration MIPS: Remove declaration of obsolete arch_init_clk_ops() MIPS: atomic.h: Reformat to fit in 79 columns MIPS: Apply `.insn' to fixup labels throughout MIPS: Fix microMIPS LL/SC immediate offsets MIPS: Kconfig: Only allow 32-bit microMIPS builds MIPS: signal.c: Fix an invalid cast in ISA mode bit handling MIPS: mm: Only build one microassembler that is suitable ...
This commit is contained in:
commit
c0222ac086
|
@ -0,0 +1,55 @@
|
|||
MIPS Global Interrupt Controller (GIC)
|
||||
|
||||
The MIPS GIC routes external interrupts to individual VPEs and IRQ pins.
|
||||
It also supports local (per-processor) interrupts and software-generated
|
||||
interrupts which can be used as IPIs. The GIC also includes a free-running
|
||||
global timer, per-CPU count/compare timers, and a watchdog.
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "mti,gic".
|
||||
- interrupt-controller : Identifies the node as an interrupt controller
|
||||
- #interrupt-cells : Specifies the number of cells needed to encode an
|
||||
interrupt specifier. Should be 3.
|
||||
- The first cell is the type of interrupt, local or shared.
|
||||
See <include/dt-bindings/interrupt-controller/mips-gic.h>.
|
||||
- The second cell is the GIC interrupt number.
|
||||
- The third cell encodes the interrupt flags.
|
||||
See <include/dt-bindings/interrupt-controller/irq.h> for a list of valid
|
||||
flags.
|
||||
|
||||
Optional properties:
|
||||
- reg : Base address and length of the GIC registers. If not present,
|
||||
the base address reported by the hardware GCR_GIC_BASE will be used.
|
||||
- mti,reserved-cpu-vectors : Specifies the list of CPU interrupt vectors
|
||||
to which the GIC may not route interrupts. Valid values are 2 - 7.
|
||||
This property is ignored if the CPU is started in EIC mode.
|
||||
|
||||
Required properties for timer sub-node:
|
||||
- compatible : Should be "mti,gic-timer".
|
||||
- interrupts : Interrupt for the GIC local timer.
|
||||
- clock-frequency : Clock frequency at which the GIC timers operate.
|
||||
|
||||
Example:
|
||||
|
||||
gic: interrupt-controller@1bdc0000 {
|
||||
compatible = "mti,gic";
|
||||
reg = <0x1bdc0000 0x20000>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
|
||||
mti,reserved-cpu-vectors = <7>;
|
||||
|
||||
timer {
|
||||
compatible = "mti,gic-timer";
|
||||
interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
|
||||
clock-frequency = <50000000>;
|
||||
};
|
||||
};
|
||||
|
||||
uart@18101400 {
|
||||
...
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
...
|
||||
};
|
|
@ -0,0 +1,37 @@
|
|||
* Interrupt Controller
|
||||
|
||||
Properties:
|
||||
- compatible: "brcm,bcm3384-intc"
|
||||
|
||||
Compatibility with BCM3384 and possibly other BCM33xx/BCM63xx SoCs.
|
||||
|
||||
- reg: Address/length pairs for each mask/status register set. Length must
|
||||
be 8. If multiple register sets are specified, the first set will
|
||||
handle IRQ offsets 0..31, the second set 32..63, and so on.
|
||||
|
||||
- interrupt-controller: This is an interrupt controller.
|
||||
|
||||
- #interrupt-cells: Must be <1>. Just a simple IRQ offset; no level/edge
|
||||
or polarity configuration is possible with this controller.
|
||||
|
||||
- interrupt-parent: This controller is cascaded from a MIPS CPU HW IRQ, or
|
||||
from another INTC.
|
||||
|
||||
- interrupts: The IRQ on the parent controller.
|
||||
|
||||
Example:
|
||||
periph_intc: periph_intc@14e00038 {
|
||||
compatible = "brcm,bcm3384-intc";
|
||||
|
||||
/*
|
||||
* IRQs 0..31: mask reg 0x14e00038, status reg 0x14e0003c
|
||||
* IRQs 32..63: mask reg 0x14e00340, status reg 0x14e00344
|
||||
*/
|
||||
reg = <0x14e00038 0x8 0x14e00340 0x8>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interrupt-parent = <&cpu_intc>;
|
||||
interrupts = <4>;
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
* Broadcom MIPS (BMIPS) CPUs
|
||||
|
||||
Required properties:
|
||||
- compatible: "brcm,bmips3300", "brcm,bmips4350", "brcm,bmips4380",
|
||||
"brcm,bmips5000"
|
||||
|
||||
- mips-hpt-frequency: This is common to all CPUs in the system so it lives
|
||||
under the "cpus" node.
|
|
@ -0,0 +1,11 @@
|
|||
* Broadcom cable/DSL platforms
|
||||
|
||||
SoCs:
|
||||
|
||||
Required properties:
|
||||
- compatible: "brcm,bcm3384", "brcm,bcm33843"
|
||||
|
||||
Boards:
|
||||
|
||||
Required properties:
|
||||
- compatible: "brcm,bcm93384wvg"
|
|
@ -0,0 +1,11 @@
|
|||
* Broadcom USB controllers
|
||||
|
||||
Required properties:
|
||||
- compatible: "brcm,bcm3384-ohci", "brcm,bcm3384-ehci"
|
||||
|
||||
These currently use the generic-ohci and generic-ehci drivers. On some
|
||||
systems, special handling may be needed in the following cases:
|
||||
|
||||
- Restoring state after systemwide power save modes
|
||||
- Sharing PHYs with the USBD (UDC) hardware
|
||||
- Figuring out which controllers are disabled on ASIC bondout variants
|
|
@ -1,6 +1,6 @@
|
|||
MIPS CPU interrupt controller
|
||||
|
||||
On MIPS the mips_cpu_intc_init() helper can be used to initialize the 8 CPU
|
||||
On MIPS the mips_cpu_irq_of_init() helper can be used to initialize the 8 CPU
|
||||
IRQs from a devicetree file and create a irq_domain for IRQ controller.
|
||||
|
||||
With the irq_domain in place we can describe how the 8 IRQs are wired to the
|
||||
|
@ -36,7 +36,7 @@ Example devicetree:
|
|||
|
||||
Example platform irq.c:
|
||||
static struct of_device_id __initdata of_irq_ids[] = {
|
||||
{ .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init },
|
||||
{ .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init },
|
||||
{ .compatible = "ralink,rt2880-intc", .data = intc_of_init },
|
||||
{},
|
||||
};
|
||||
|
|
|
@ -101,6 +101,7 @@ mitsubishi Mitsubishi Electric Corporation
|
|||
mosaixtech Mosaix Technologies, Inc.
|
||||
moxa Moxa
|
||||
mpl MPL AG
|
||||
mti Imagination Technologies Ltd. (formerly MIPS Technologies Inc.)
|
||||
mundoreader Mundo Reader S.L.
|
||||
murata Murata Manufacturing Co., Ltd.
|
||||
mxicy Macronix International Co., Ltd.
|
||||
|
|
26
MAINTAINERS
26
MAINTAINERS
|
@ -2085,6 +2085,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git
|
|||
S: Maintained
|
||||
N: bcm2835
|
||||
|
||||
BROADCOM BCM33XX MIPS ARCHITECTURE
|
||||
M: Kevin Cernekee <cernekee@gmail.com>
|
||||
L: linux-mips@linux-mips.org
|
||||
S: Maintained
|
||||
F: arch/mips/bcm3384/*
|
||||
F: arch/mips/include/asm/mach-bcm3384/*
|
||||
F: arch/mips/kernel/*bmips*
|
||||
|
||||
BROADCOM BCM5301X ARM ARCHITECTURE
|
||||
M: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
L: linux-arm-kernel@lists.infradead.org
|
||||
|
@ -2101,6 +2109,12 @@ S: Maintained
|
|||
F: arch/arm/mach-bcm/bcm63xx.c
|
||||
F: arch/arm/include/debug/bcm63xx.S
|
||||
|
||||
BROADCOM BCM63XX/BCM33XX UDC DRIVER
|
||||
M: Kevin Cernekee <cernekee@gmail.com>
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/usb/gadget/udc/bcm63xx_udc.*
|
||||
|
||||
BROADCOM BCM7XXX ARM ARCHITECTURE
|
||||
M: Marc Carino <marc.ceeeee@gmail.com>
|
||||
M: Brian Norris <computersforpeace@gmail.com>
|
||||
|
@ -2112,6 +2126,18 @@ F: arch/arm/mach-bcm/*brcmstb*
|
|||
F: arch/arm/boot/dts/bcm7*.dts*
|
||||
F: drivers/bus/brcmstb_gisb.c
|
||||
|
||||
BROADCOM BMIPS MIPS ARCHITECTURE
|
||||
M: Kevin Cernekee <cernekee@gmail.com>
|
||||
M: Florian Fainelli <f.fainelli@gmail.com>
|
||||
L: linux-mips@linux-mips.org
|
||||
S: Maintained
|
||||
F: arch/mips/bmips/*
|
||||
F: arch/mips/include/asm/mach-bmips/*
|
||||
F: arch/mips/kernel/*bmips*
|
||||
F: arch/mips/boot/dts/bcm*.dts*
|
||||
F: drivers/irqchip/irq-bcm7*
|
||||
F: drivers/irqchip/irq-brcmstb*
|
||||
|
||||
BROADCOM TG3 GIGABIT ETHERNET DRIVER
|
||||
M: Prashant Sreedharan <prashant@broadcom.com>
|
||||
M: Michael Chan <mchan@broadcom.com>
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
platforms += alchemy
|
||||
platforms += ar7
|
||||
platforms += ath25
|
||||
platforms += ath79
|
||||
platforms += bcm3384
|
||||
platforms += bcm47xx
|
||||
platforms += bcm63xx
|
||||
platforms += cavium-octeon
|
||||
|
|
|
@ -53,6 +53,7 @@ config MIPS
|
|||
select HAVE_CC_STACKPROTECTOR
|
||||
select CPU_PM if CPU_IDLE
|
||||
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
|
||||
select ARCH_BINFMT_ELF_STATE
|
||||
|
||||
menu "Machine selection"
|
||||
|
||||
|
@ -62,7 +63,7 @@ choice
|
|||
|
||||
config MIPS_ALCHEMY
|
||||
bool "Alchemy processor based machines"
|
||||
select 64BIT_PHYS_ADDR
|
||||
select ARCH_PHYS_ADDR_T_64BIT
|
||||
select CEVT_R4K
|
||||
select CSRC_R4K
|
||||
select IRQ_CPU
|
||||
|
@ -96,6 +97,20 @@ config AR7
|
|||
Support for the Texas Instruments AR7 System-on-a-Chip
|
||||
family: TNETD7100, 7200 and 7300.
|
||||
|
||||
config ATH25
|
||||
bool "Atheros AR231x/AR531x SoC support"
|
||||
select CEVT_R4K
|
||||
select CSRC_R4K
|
||||
select DMA_NONCOHERENT
|
||||
select IRQ_CPU
|
||||
select IRQ_DOMAIN
|
||||
select SYS_HAS_CPU_MIPS32_R1
|
||||
select SYS_SUPPORTS_BIG_ENDIAN
|
||||
select SYS_SUPPORTS_32BIT_KERNEL
|
||||
select SYS_HAS_EARLY_PRINTK
|
||||
help
|
||||
Support for Atheros AR231x and Atheros AR531x based boards
|
||||
|
||||
config ATH79
|
||||
bool "Atheros AR71XX/AR724X/AR913X based boards"
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
|
@ -115,6 +130,32 @@ config ATH79
|
|||
help
|
||||
Support for the Atheros AR71XX/AR724X/AR913X SoCs.
|
||||
|
||||
config BCM3384
|
||||
bool "Broadcom BCM3384 based boards"
|
||||
select BOOT_RAW
|
||||
select NO_EXCEPT_FILL
|
||||
select USE_OF
|
||||
select CEVT_R4K
|
||||
select CSRC_R4K
|
||||
select SYNC_R4K
|
||||
select COMMON_CLK
|
||||
select DMA_NONCOHERENT
|
||||
select IRQ_CPU
|
||||
select SYS_SUPPORTS_32BIT_KERNEL
|
||||
select SYS_SUPPORTS_BIG_ENDIAN
|
||||
select SYS_SUPPORTS_HIGHMEM
|
||||
select SYS_HAS_CPU_BMIPS5000
|
||||
select SWAP_IO_SPACE
|
||||
select USB_EHCI_BIG_ENDIAN_DESC
|
||||
select USB_EHCI_BIG_ENDIAN_MMIO
|
||||
select USB_OHCI_BIG_ENDIAN_DESC
|
||||
select USB_OHCI_BIG_ENDIAN_MMIO
|
||||
help
|
||||
Support for BCM3384 based boards. BCM3384/BCM33843 is a cable modem
|
||||
chipset with a Linux application processor that is often used to
|
||||
provide Samba services, a CUPS print server, and/or advanced routing
|
||||
features.
|
||||
|
||||
config BCM47XX
|
||||
bool "Broadcom BCM47XX based boards"
|
||||
select ARCH_WANT_OPTIONAL_GPIOLIB
|
||||
|
@ -269,6 +310,8 @@ config LANTIQ
|
|||
select USE_OF
|
||||
select PINCTRL
|
||||
select PINCTRL_LANTIQ
|
||||
select ARCH_HAS_RESET_CONTROLLER
|
||||
select RESET_CONTROLLER
|
||||
|
||||
config LASAT
|
||||
bool "LASAT Networks platforms"
|
||||
|
@ -315,17 +358,18 @@ config MIPS_MALTA
|
|||
select BOOT_RAW
|
||||
select CEVT_R4K
|
||||
select CSRC_R4K
|
||||
select CSRC_GIC
|
||||
select CLKSRC_MIPS_GIC
|
||||
select DMA_MAYBE_COHERENT
|
||||
select GENERIC_ISA_DMA
|
||||
select HAVE_PCSPKR_PLATFORM
|
||||
select IRQ_CPU
|
||||
select IRQ_GIC
|
||||
select MIPS_GIC
|
||||
select HW_HAS_PCI
|
||||
select I8253
|
||||
select I8259
|
||||
select MIPS_BONITO64
|
||||
select MIPS_CPU_SCACHE
|
||||
select MIPS_L1_CACHE_SHIFT_6
|
||||
select PCI_GT64XXX_PCI0
|
||||
select MIPS_MSC
|
||||
select SWAP_IO_SPACE
|
||||
|
@ -340,6 +384,7 @@ config MIPS_MALTA
|
|||
select SYS_SUPPORTS_64BIT_KERNEL
|
||||
select SYS_SUPPORTS_BIG_ENDIAN
|
||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||
select SYS_SUPPORTS_MICROMIPS
|
||||
select SYS_SUPPORTS_MIPS_CMP
|
||||
select SYS_SUPPORTS_MIPS_CPS
|
||||
select SYS_SUPPORTS_MIPS16
|
||||
|
@ -357,12 +402,12 @@ config MIPS_SEAD3
|
|||
select BUILTIN_DTB
|
||||
select CEVT_R4K
|
||||
select CSRC_R4K
|
||||
select CSRC_GIC
|
||||
select CLKSRC_MIPS_GIC
|
||||
select CPU_MIPSR2_IRQ_VI
|
||||
select CPU_MIPSR2_IRQ_EI
|
||||
select DMA_NONCOHERENT
|
||||
select IRQ_CPU
|
||||
select IRQ_GIC
|
||||
select MIPS_GIC
|
||||
select LIBFDT
|
||||
select MIPS_MSC
|
||||
select SYS_HAS_CPU_MIPS32_R1
|
||||
|
@ -726,7 +771,7 @@ config MIKROTIK_RB532
|
|||
config CAVIUM_OCTEON_SOC
|
||||
bool "Cavium Networks Octeon SoC based boards"
|
||||
select CEVT_R4K
|
||||
select 64BIT_PHYS_ADDR
|
||||
select ARCH_PHYS_ADDR_T_64BIT
|
||||
select DMA_COHERENT
|
||||
select SYS_SUPPORTS_64BIT_KERNEL
|
||||
select SYS_SUPPORTS_BIG_ENDIAN
|
||||
|
@ -768,7 +813,7 @@ config NLM_XLR_BOARD
|
|||
select SWAP_IO_SPACE
|
||||
select SYS_SUPPORTS_32BIT_KERNEL
|
||||
select SYS_SUPPORTS_64BIT_KERNEL
|
||||
select 64BIT_PHYS_ADDR
|
||||
select ARCH_PHYS_ADDR_T_64BIT
|
||||
select SYS_SUPPORTS_BIG_ENDIAN
|
||||
select SYS_SUPPORTS_HIGHMEM
|
||||
select DMA_COHERENT
|
||||
|
@ -794,7 +839,7 @@ config NLM_XLP_BOARD
|
|||
select HW_HAS_PCI
|
||||
select SYS_SUPPORTS_32BIT_KERNEL
|
||||
select SYS_SUPPORTS_64BIT_KERNEL
|
||||
select 64BIT_PHYS_ADDR
|
||||
select ARCH_PHYS_ADDR_T_64BIT
|
||||
select SYS_SUPPORTS_BIG_ENDIAN
|
||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||
select SYS_SUPPORTS_HIGHMEM
|
||||
|
@ -835,6 +880,7 @@ config MIPS_PARAVIRT
|
|||
endchoice
|
||||
|
||||
source "arch/mips/alchemy/Kconfig"
|
||||
source "arch/mips/ath25/Kconfig"
|
||||
source "arch/mips/ath79/Kconfig"
|
||||
source "arch/mips/bcm47xx/Kconfig"
|
||||
source "arch/mips/bcm63xx/Kconfig"
|
||||
|
@ -907,10 +953,6 @@ config CEVT_GT641XX
|
|||
config CEVT_R4K
|
||||
bool
|
||||
|
||||
config CEVT_GIC
|
||||
select MIPS_CM
|
||||
bool
|
||||
|
||||
config CEVT_SB1250
|
||||
bool
|
||||
|
||||
|
@ -926,10 +968,6 @@ config CSRC_IOASIC
|
|||
config CSRC_R4K
|
||||
bool
|
||||
|
||||
config CSRC_GIC
|
||||
select MIPS_CM
|
||||
bool
|
||||
|
||||
config CSRC_SB1250
|
||||
bool
|
||||
|
||||
|
@ -941,7 +979,7 @@ config FW_CFE
|
|||
bool
|
||||
|
||||
config ARCH_DMA_ADDR_T_64BIT
|
||||
def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT
|
||||
def_bool (HIGHMEM && ARCH_PHYS_ADDR_T_64BIT) || 64BIT
|
||||
|
||||
config DMA_MAYBE_COHERENT
|
||||
select DMA_NONCOHERENT
|
||||
|
@ -975,6 +1013,7 @@ config SYS_SUPPORTS_HOTPLUG_CPU
|
|||
|
||||
config I8259
|
||||
bool
|
||||
select IRQ_DOMAIN
|
||||
|
||||
config MIPS_BONITO64
|
||||
bool
|
||||
|
@ -1055,6 +1094,7 @@ config MIPS_HUGE_TLB_SUPPORT
|
|||
|
||||
config IRQ_CPU
|
||||
bool
|
||||
select IRQ_DOMAIN
|
||||
|
||||
config IRQ_CPU_RM7K
|
||||
bool
|
||||
|
@ -1071,10 +1111,6 @@ config IRQ_TXX9
|
|||
config IRQ_GT641XX
|
||||
bool
|
||||
|
||||
config IRQ_GIC
|
||||
select MIPS_CM
|
||||
bool
|
||||
|
||||
config PCI_GT64XXX_PCI0
|
||||
bool
|
||||
|
||||
|
@ -1574,6 +1610,7 @@ config CPU_LOONGSON1
|
|||
select CPU_HAS_PREFETCH
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
select CPU_SUPPORTS_CPUFREQ
|
||||
|
||||
config CPU_BMIPS32_3300
|
||||
select SMP_UP if SMP
|
||||
|
@ -1586,12 +1623,14 @@ config CPU_BMIPS4350
|
|||
|
||||
config CPU_BMIPS4380
|
||||
bool
|
||||
select MIPS_L1_CACHE_SHIFT_6
|
||||
select SYS_SUPPORTS_SMP
|
||||
select SYS_SUPPORTS_HOTPLUG_CPU
|
||||
|
||||
config CPU_BMIPS5000
|
||||
bool
|
||||
select MIPS_CPU_SCACHE
|
||||
select MIPS_L1_CACHE_SHIFT_7
|
||||
select SYS_SUPPORTS_SMP
|
||||
select SYS_SUPPORTS_HOTPLUG_CPU
|
||||
|
||||
|
@ -1886,15 +1925,6 @@ config FORCE_MAX_ZONEORDER
|
|||
The page size is not necessarily 4KB. Keep this in mind
|
||||
when choosing a value for this option.
|
||||
|
||||
config CEVT_GIC
|
||||
bool "Use GIC global counter for clock events"
|
||||
depends on IRQ_GIC && !MIPS_SEAD3
|
||||
help
|
||||
Use the GIC global counter for the clock events. The R4K clock
|
||||
event driver is always present, so if the platform ends up not
|
||||
detecting a GIC, it will fall back to the R4K timer for the
|
||||
generation of clock events.
|
||||
|
||||
config BOARD_SCACHE
|
||||
bool
|
||||
|
||||
|
@ -1908,7 +1938,6 @@ config IP22_CPU_SCACHE
|
|||
config MIPS_CPU_SCACHE
|
||||
bool
|
||||
select BOARD_SCACHE
|
||||
select MIPS_L1_CACHE_SHIFT_6
|
||||
|
||||
config R5000_CPU_SCACHE
|
||||
bool
|
||||
|
@ -2095,11 +2124,8 @@ config SB1_PASS_2_1_WORKAROUNDS
|
|||
default y
|
||||
|
||||
|
||||
config 64BIT_PHYS_ADDR
|
||||
bool
|
||||
|
||||
config ARCH_PHYS_ADDR_T_64BIT
|
||||
def_bool 64BIT_PHYS_ADDR
|
||||
bool
|
||||
|
||||
choice
|
||||
prompt "SmartMIPS or microMIPS ASE support"
|
||||
|
@ -2122,7 +2148,7 @@ config CPU_HAS_SMARTMIPS
|
|||
here.
|
||||
|
||||
config CPU_MICROMIPS
|
||||
depends on SYS_SUPPORTS_MICROMIPS
|
||||
depends on 32BIT && SYS_SUPPORTS_MICROMIPS
|
||||
bool "microMIPS"
|
||||
help
|
||||
When this option is enabled the kernel will be built using the
|
||||
|
|
|
@ -122,4 +122,17 @@ config SPINLOCK_TEST
|
|||
help
|
||||
Add several files to the debugfs to test spinlock speed.
|
||||
|
||||
config FP32XX_HYBRID_FPRS
|
||||
bool "Run FP32 & FPXX code with hybrid FPRs"
|
||||
depends on MIPS_O32_FP64_SUPPORT
|
||||
help
|
||||
The hybrid FPR scheme is normally used only when a program needs to
|
||||
execute a mix of FP32 & FP64A code, since the trapping & emulation
|
||||
that it entails is expensive. When enabled, this option will lead
|
||||
to the kernel running programs which use the FP32 & FPXX FP ABIs
|
||||
using the hybrid FPR scheme, which can be useful for debugging
|
||||
purposes.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -380,6 +380,7 @@ define archhelp
|
|||
echo ' vmlinux.ecoff - ECOFF boot image'
|
||||
echo ' vmlinux.bin - Raw binary boot image'
|
||||
echo ' vmlinux.srec - SREC boot image'
|
||||
echo ' vmlinux.32 - 64-bit boot image wrapped in 32bits (IP22/IP32)'
|
||||
echo ' vmlinuz - Compressed boot(zboot) image'
|
||||
echo ' vmlinuz.ecoff - ECOFF zboot image'
|
||||
echo ' vmlinuz.bin - Raw binary zboot image'
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk-private.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/types.h>
|
||||
|
@ -397,10 +396,10 @@ static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate,
|
|||
break;
|
||||
|
||||
/* if this parent is currently unused, remember it.
|
||||
* XXX: I know it's a layering violation, but it works
|
||||
* so well.. (if (!clk_has_active_children(pc)) )
|
||||
* XXX: we would actually want clk_has_active_children()
|
||||
* but this is a good-enough approximation for now.
|
||||
*/
|
||||
if (pc->prepare_count == 0) {
|
||||
if (!__clk_is_prepared(pc)) {
|
||||
if (!free)
|
||||
free = pc;
|
||||
}
|
||||
|
|
|
@ -70,9 +70,9 @@ void __init plat_mem_setup(void)
|
|||
iomem_resource.end = IOMEM_RESOURCE_END;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI)
|
||||
#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI)
|
||||
/* This routine should be valid for all Au1x based boards */
|
||||
phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
|
||||
phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
|
||||
{
|
||||
unsigned long start = ALCHEMY_PCI_MEMWIN_START;
|
||||
unsigned long end = ALCHEMY_PCI_MEMWIN_END;
|
||||
|
@ -83,7 +83,7 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
|
|||
|
||||
/* Check for PCI memory window */
|
||||
if (phys_addr >= start && (phys_addr + size - 1) <= end)
|
||||
return (phys_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr);
|
||||
return (phys_addr_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr);
|
||||
|
||||
/* default nop */
|
||||
return phys_addr;
|
||||
|
|
|
@ -311,8 +311,7 @@ static void __init cpmac_get_mac(int instance, unsigned char *dev_addr)
|
|||
&dev_addr[0], &dev_addr[1],
|
||||
&dev_addr[2], &dev_addr[3],
|
||||
&dev_addr[4], &dev_addr[5]) != 6) {
|
||||
pr_warning("cannot parse mac address, "
|
||||
"using random address\n");
|
||||
pr_warn("cannot parse mac address, using random address\n");
|
||||
eth_random_addr(dev_addr);
|
||||
}
|
||||
} else
|
||||
|
@ -665,7 +664,7 @@ static int __init ar7_register_devices(void)
|
|||
|
||||
res = platform_device_register(&physmap_flash);
|
||||
if (res)
|
||||
pr_warning("unable to register physmap-flash: %d\n", res);
|
||||
pr_warn("unable to register physmap-flash: %d\n", res);
|
||||
|
||||
if (ar7_is_titan())
|
||||
titan_fixup_devices();
|
||||
|
@ -673,13 +672,13 @@ static int __init ar7_register_devices(void)
|
|||
ar7_device_disable(vlynq_low_data.reset_bit);
|
||||
res = platform_device_register(&vlynq_low);
|
||||
if (res)
|
||||
pr_warning("unable to register vlynq-low: %d\n", res);
|
||||
pr_warn("unable to register vlynq-low: %d\n", res);
|
||||
|
||||
if (ar7_has_high_vlynq()) {
|
||||
ar7_device_disable(vlynq_high_data.reset_bit);
|
||||
res = platform_device_register(&vlynq_high);
|
||||
if (res)
|
||||
pr_warning("unable to register vlynq-high: %d\n", res);
|
||||
pr_warn("unable to register vlynq-high: %d\n", res);
|
||||
}
|
||||
|
||||
if (ar7_has_high_cpmac()) {
|
||||
|
@ -689,9 +688,10 @@ static int __init ar7_register_devices(void)
|
|||
|
||||
res = platform_device_register(&cpmac_high);
|
||||
if (res)
|
||||
pr_warning("unable to register cpmac-high: %d\n", res);
|
||||
pr_warn("unable to register cpmac-high: %d\n",
|
||||
res);
|
||||
} else
|
||||
pr_warning("unable to add cpmac-high phy: %d\n", res);
|
||||
pr_warn("unable to add cpmac-high phy: %d\n", res);
|
||||
} else
|
||||
cpmac_low_data.phy_mask = 0xffffffff;
|
||||
|
||||
|
@ -700,18 +700,18 @@ static int __init ar7_register_devices(void)
|
|||
cpmac_get_mac(0, cpmac_low_data.dev_addr);
|
||||
res = platform_device_register(&cpmac_low);
|
||||
if (res)
|
||||
pr_warning("unable to register cpmac-low: %d\n", res);
|
||||
pr_warn("unable to register cpmac-low: %d\n", res);
|
||||
} else
|
||||
pr_warning("unable to add cpmac-low phy: %d\n", res);
|
||||
pr_warn("unable to add cpmac-low phy: %d\n", res);
|
||||
|
||||
detect_leds();
|
||||
res = platform_device_register(&ar7_gpio_leds);
|
||||
if (res)
|
||||
pr_warning("unable to register leds: %d\n", res);
|
||||
pr_warn("unable to register leds: %d\n", res);
|
||||
|
||||
res = platform_device_register(&ar7_udc);
|
||||
if (res)
|
||||
pr_warning("unable to register usb slave: %d\n", res);
|
||||
pr_warn("unable to register usb slave: %d\n", res);
|
||||
|
||||
/* Register watchdog only if enabled in hardware */
|
||||
bootcr = ioremap_nocache(AR7_REGS_DCL, 4);
|
||||
|
@ -726,7 +726,7 @@ static int __init ar7_register_devices(void)
|
|||
ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
|
||||
res = platform_device_register(&ar7_wdt);
|
||||
if (res)
|
||||
pr_warning("unable to register watchdog: %d\n", res);
|
||||
pr_warn("unable to register watchdog: %d\n", res);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
config SOC_AR5312
|
||||
bool "Atheros AR5312/AR2312+ SoC support"
|
||||
depends on ATH25
|
||||
default y
|
||||
|
||||
config SOC_AR2315
|
||||
bool "Atheros AR2315+ SoC support"
|
||||
depends on ATH25
|
||||
default y
|
||||
|
||||
config PCI_AR2315
|
||||
bool "Atheros AR2315 PCI controller support"
|
||||
depends on SOC_AR2315
|
||||
select HW_HAS_PCI
|
||||
select PCI
|
||||
default y
|
|
@ -0,0 +1,16 @@
|
|||
#
|
||||
# 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) 2006 FON Technology, SL.
|
||||
# Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
|
||||
# Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
|
||||
#
|
||||
|
||||
obj-y += board.o prom.o devices.o
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
|
||||
obj-$(CONFIG_SOC_AR5312) += ar5312.o
|
||||
obj-$(CONFIG_SOC_AR2315) += ar2315.o
|
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# Atheros AR531X/AR231X WiSoC
|
||||
#
|
||||
platform-$(CONFIG_ATH25) += ath25/
|
||||
cflags-$(CONFIG_ATH25) += -I$(srctree)/arch/mips/include/asm/mach-ath25
|
||||
load-$(CONFIG_ATH25) += 0xffffffff80041000
|
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
* 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) 2003 Atheros Communications, Inc., All Rights Reserved.
|
||||
* Copyright (C) 2006 FON Technology, SL.
|
||||
* Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
|
||||
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
|
||||
* Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Platform devices for Atheros AR2315 SoCs
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#include <ath25_platform.h>
|
||||
|
||||
#include "devices.h"
|
||||
#include "ar2315.h"
|
||||
#include "ar2315_regs.h"
|
||||
|
||||
static void __iomem *ar2315_rst_base;
|
||||
static struct irq_domain *ar2315_misc_irq_domain;
|
||||
|
||||
static inline u32 ar2315_rst_reg_read(u32 reg)
|
||||
{
|
||||
return __raw_readl(ar2315_rst_base + reg);
|
||||
}
|
||||
|
||||
static inline void ar2315_rst_reg_write(u32 reg, u32 val)
|
||||
{
|
||||
__raw_writel(val, ar2315_rst_base + reg);
|
||||
}
|
||||
|
||||
static inline void ar2315_rst_reg_mask(u32 reg, u32 mask, u32 val)
|
||||
{
|
||||
u32 ret = ar2315_rst_reg_read(reg);
|
||||
|
||||
ret &= ~mask;
|
||||
ret |= val;
|
||||
ar2315_rst_reg_write(reg, ret);
|
||||
}
|
||||
|
||||
static irqreturn_t ar2315_ahb_err_handler(int cpl, void *dev_id)
|
||||
{
|
||||
ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET);
|
||||
ar2315_rst_reg_read(AR2315_AHB_ERR1);
|
||||
|
||||
pr_emerg("AHB fatal error\n");
|
||||
machine_restart("AHB error"); /* Catastrophic failure */
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction ar2315_ahb_err_interrupt = {
|
||||
.handler = ar2315_ahb_err_handler,
|
||||
.name = "ar2315-ahb-error",
|
||||
};
|
||||
|
||||
static void ar2315_misc_irq_handler(unsigned irq, struct irq_desc *desc)
|
||||
{
|
||||
u32 pending = ar2315_rst_reg_read(AR2315_ISR) &
|
||||
ar2315_rst_reg_read(AR2315_IMR);
|
||||
unsigned nr, misc_irq = 0;
|
||||
|
||||
if (pending) {
|
||||
struct irq_domain *domain = irq_get_handler_data(irq);
|
||||
|
||||
nr = __ffs(pending);
|
||||
misc_irq = irq_find_mapping(domain, nr);
|
||||
}
|
||||
|
||||
if (misc_irq) {
|
||||
if (nr == AR2315_MISC_IRQ_GPIO)
|
||||
ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_GPIO);
|
||||
else if (nr == AR2315_MISC_IRQ_WATCHDOG)
|
||||
ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_WD);
|
||||
generic_handle_irq(misc_irq);
|
||||
} else {
|
||||
spurious_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
static void ar2315_misc_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
ar2315_rst_reg_mask(AR2315_IMR, 0, BIT(d->hwirq));
|
||||
}
|
||||
|
||||
static void ar2315_misc_irq_mask(struct irq_data *d)
|
||||
{
|
||||
ar2315_rst_reg_mask(AR2315_IMR, BIT(d->hwirq), 0);
|
||||
}
|
||||
|
||||
static struct irq_chip ar2315_misc_irq_chip = {
|
||||
.name = "ar2315-misc",
|
||||
.irq_unmask = ar2315_misc_irq_unmask,
|
||||
.irq_mask = ar2315_misc_irq_mask,
|
||||
};
|
||||
|
||||
static int ar2315_misc_irq_map(struct irq_domain *d, unsigned irq,
|
||||
irq_hw_number_t hw)
|
||||
{
|
||||
irq_set_chip_and_handler(irq, &ar2315_misc_irq_chip, handle_level_irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_domain_ops ar2315_misc_irq_domain_ops = {
|
||||
.map = ar2315_misc_irq_map,
|
||||
};
|
||||
|
||||
/*
|
||||
* Called when an interrupt is received, this function
|
||||
* determines exactly which interrupt it was, and it
|
||||
* invokes the appropriate handler.
|
||||
*
|
||||
* Implicitly, we also define interrupt priority by
|
||||
* choosing which to dispatch first.
|
||||
*/
|
||||
static void ar2315_irq_dispatch(void)
|
||||
{
|
||||
u32 pending = read_c0_status() & read_c0_cause();
|
||||
|
||||
if (pending & CAUSEF_IP3)
|
||||
do_IRQ(AR2315_IRQ_WLAN0);
|
||||
#ifdef CONFIG_PCI_AR2315
|
||||
else if (pending & CAUSEF_IP5)
|
||||
do_IRQ(AR2315_IRQ_LCBUS_PCI);
|
||||
#endif
|
||||
else if (pending & CAUSEF_IP2)
|
||||
do_IRQ(AR2315_IRQ_MISC);
|
||||
else if (pending & CAUSEF_IP7)
|
||||
do_IRQ(ATH25_IRQ_CPU_CLOCK);
|
||||
else
|
||||
spurious_interrupt();
|
||||
}
|
||||
|
||||
void __init ar2315_arch_init_irq(void)
|
||||
{
|
||||
struct irq_domain *domain;
|
||||
unsigned irq;
|
||||
|
||||
ath25_irq_dispatch = ar2315_irq_dispatch;
|
||||
|
||||
domain = irq_domain_add_linear(NULL, AR2315_MISC_IRQ_COUNT,
|
||||
&ar2315_misc_irq_domain_ops, NULL);
|
||||
if (!domain)
|
||||
panic("Failed to add IRQ domain");
|
||||
|
||||
irq = irq_create_mapping(domain, AR2315_MISC_IRQ_AHB);
|
||||
setup_irq(irq, &ar2315_ahb_err_interrupt);
|
||||
|
||||
irq_set_chained_handler(AR2315_IRQ_MISC, ar2315_misc_irq_handler);
|
||||
irq_set_handler_data(AR2315_IRQ_MISC, domain);
|
||||
|
||||
ar2315_misc_irq_domain = domain;
|
||||
}
|
||||
|
||||
void __init ar2315_init_devices(void)
|
||||
{
|
||||
/* Find board configuration */
|
||||
ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE);
|
||||
|
||||
ath25_add_wmac(0, AR2315_WLAN0_BASE, AR2315_IRQ_WLAN0);
|
||||
}
|
||||
|
||||
static void ar2315_restart(char *command)
|
||||
{
|
||||
void (*mips_reset_vec)(void) = (void *)0xbfc00000;
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
/* try reset the system via reset control */
|
||||
ar2315_rst_reg_write(AR2315_COLD_RESET, AR2317_RESET_SYSTEM);
|
||||
|
||||
/* Cold reset does not work on the AR2315/6, use the GPIO reset bits
|
||||
* a workaround. Give it some time to attempt a gpio based hardware
|
||||
* reset (atheros reference design workaround) */
|
||||
|
||||
/* TODO: implement the GPIO reset workaround */
|
||||
|
||||
/* Some boards (e.g. Senao EOC-2610) don't implement the reset logic
|
||||
* workaround. Attempt to jump to the mips reset location -
|
||||
* the boot loader itself might be able to recover the system */
|
||||
mips_reset_vec();
|
||||
}
|
||||
|
||||
/*
|
||||
* This table is indexed by bits 5..4 of the CLOCKCTL1 register
|
||||
* to determine the predevisor value.
|
||||
*/
|
||||
static int clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 };
|
||||
static int pllc_divide_table[5] __initdata = { 2, 3, 4, 6, 3 };
|
||||
|
||||
static unsigned __init ar2315_sys_clk(u32 clock_ctl)
|
||||
{
|
||||
unsigned int pllc_ctrl, cpu_div;
|
||||
unsigned int pllc_out, refdiv, fdiv, divby2;
|
||||
unsigned int clk_div;
|
||||
|
||||
pllc_ctrl = ar2315_rst_reg_read(AR2315_PLLC_CTL);
|
||||
refdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_REF_DIV);
|
||||
refdiv = clockctl1_predivide_table[refdiv];
|
||||
fdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_FDBACK_DIV);
|
||||
divby2 = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_ADD_FDBACK_DIV) + 1;
|
||||
pllc_out = (40000000 / refdiv) * (2 * divby2) * fdiv;
|
||||
|
||||
/* clkm input selected */
|
||||
switch (clock_ctl & AR2315_CPUCLK_CLK_SEL_M) {
|
||||
case 0:
|
||||
case 1:
|
||||
clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKM_DIV);
|
||||
clk_div = pllc_divide_table[clk_div];
|
||||
break;
|
||||
case 2:
|
||||
clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKC_DIV);
|
||||
clk_div = pllc_divide_table[clk_div];
|
||||
break;
|
||||
default:
|
||||
pllc_out = 40000000;
|
||||
clk_div = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
cpu_div = ATH25_REG_MS(clock_ctl, AR2315_CPUCLK_CLK_DIV);
|
||||
cpu_div = cpu_div * 2 ?: 1;
|
||||
|
||||
return pllc_out / (clk_div * cpu_div);
|
||||
}
|
||||
|
||||
static inline unsigned ar2315_cpu_frequency(void)
|
||||
{
|
||||
return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_CPUCLK));
|
||||
}
|
||||
|
||||
static inline unsigned ar2315_apb_frequency(void)
|
||||
{
|
||||
return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_AMBACLK));
|
||||
}
|
||||
|
||||
void __init ar2315_plat_time_init(void)
|
||||
{
|
||||
mips_hpt_frequency = ar2315_cpu_frequency() / 2;
|
||||
}
|
||||
|
||||
void __init ar2315_plat_mem_setup(void)
|
||||
{
|
||||
void __iomem *sdram_base;
|
||||
u32 memsize, memcfg;
|
||||
u32 devid;
|
||||
u32 config;
|
||||
|
||||
/* Detect memory size */
|
||||
sdram_base = ioremap_nocache(AR2315_SDRAMCTL_BASE,
|
||||
AR2315_SDRAMCTL_SIZE);
|
||||
memcfg = __raw_readl(sdram_base + AR2315_MEM_CFG);
|
||||
memsize = 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_DATA_WIDTH);
|
||||
memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_COL_WIDTH);
|
||||
memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_ROW_WIDTH);
|
||||
memsize <<= 3;
|
||||
add_memory_region(0, memsize, BOOT_MEM_RAM);
|
||||
iounmap(sdram_base);
|
||||
|
||||
ar2315_rst_base = ioremap_nocache(AR2315_RST_BASE, AR2315_RST_SIZE);
|
||||
|
||||
/* Detect the hardware based on the device ID */
|
||||
devid = ar2315_rst_reg_read(AR2315_SREV) & AR2315_REV_CHIP;
|
||||
switch (devid) {
|
||||
case 0x91: /* Need to check */
|
||||
ath25_soc = ATH25_SOC_AR2318;
|
||||
break;
|
||||
case 0x90:
|
||||
ath25_soc = ATH25_SOC_AR2317;
|
||||
break;
|
||||
case 0x87:
|
||||
ath25_soc = ATH25_SOC_AR2316;
|
||||
break;
|
||||
case 0x86:
|
||||
default:
|
||||
ath25_soc = ATH25_SOC_AR2315;
|
||||
break;
|
||||
}
|
||||
ath25_board.devid = devid;
|
||||
|
||||
/* Clear any lingering AHB errors */
|
||||
config = read_c0_config();
|
||||
write_c0_config(config & ~0x3);
|
||||
ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET);
|
||||
ar2315_rst_reg_read(AR2315_AHB_ERR1);
|
||||
ar2315_rst_reg_write(AR2315_WDT_CTRL, AR2315_WDT_CTRL_IGNORE);
|
||||
|
||||
_machine_restart = ar2315_restart;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_AR2315
|
||||
static struct resource ar2315_pci_res[] = {
|
||||
{
|
||||
.name = "ar2315-pci-ctrl",
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = AR2315_PCI_BASE,
|
||||
.end = AR2315_PCI_BASE + AR2315_PCI_SIZE - 1,
|
||||
},
|
||||
{
|
||||
.name = "ar2315-pci-ext",
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = AR2315_PCI_EXT_BASE,
|
||||
.end = AR2315_PCI_EXT_BASE + AR2315_PCI_EXT_SIZE - 1,
|
||||
},
|
||||
{
|
||||
.name = "ar2315-pci",
|
||||
.flags = IORESOURCE_IRQ,
|
||||
.start = AR2315_IRQ_LCBUS_PCI,
|
||||
.end = AR2315_IRQ_LCBUS_PCI,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
void __init ar2315_arch_init(void)
|
||||
{
|
||||
unsigned irq = irq_create_mapping(ar2315_misc_irq_domain,
|
||||
AR2315_MISC_IRQ_UART0);
|
||||
|
||||
ath25_serial_setup(AR2315_UART0_BASE, irq, ar2315_apb_frequency());
|
||||
|
||||
#ifdef CONFIG_PCI_AR2315
|
||||
if (ath25_soc == ATH25_SOC_AR2315) {
|
||||
/* Reset PCI DMA logic */
|
||||
ar2315_rst_reg_mask(AR2315_RESET, 0, AR2315_RESET_PCIDMA);
|
||||
msleep(20);
|
||||
ar2315_rst_reg_mask(AR2315_RESET, AR2315_RESET_PCIDMA, 0);
|
||||
msleep(20);
|
||||
|
||||
/* Configure endians */
|
||||
ar2315_rst_reg_mask(AR2315_ENDIAN_CTL, 0, AR2315_CONFIG_PCIAHB |
|
||||
AR2315_CONFIG_PCIAHB_BRIDGE);
|
||||
|
||||
/* Configure as PCI host with DMA */
|
||||
ar2315_rst_reg_write(AR2315_PCICLK, AR2315_PCICLK_PLLC_CLKM |
|
||||
(AR2315_PCICLK_IN_FREQ_DIV_6 <<
|
||||
AR2315_PCICLK_DIV_S));
|
||||
ar2315_rst_reg_mask(AR2315_AHB_ARB_CTL, 0, AR2315_ARB_PCI);
|
||||
ar2315_rst_reg_mask(AR2315_IF_CTL, AR2315_IF_PCI_CLK_MASK |
|
||||
AR2315_IF_MASK, AR2315_IF_PCI |
|
||||
AR2315_IF_PCI_HOST | AR2315_IF_PCI_INTR |
|
||||
(AR2315_IF_PCI_CLK_OUTPUT_CLK <<
|
||||
AR2315_IF_PCI_CLK_SHIFT));
|
||||
|
||||
platform_device_register_simple("ar2315-pci", -1,
|
||||
ar2315_pci_res,
|
||||
ARRAY_SIZE(ar2315_pci_res));
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef __AR2315_H
|
||||
#define __AR2315_H
|
||||
|
||||
#ifdef CONFIG_SOC_AR2315
|
||||
|
||||
void ar2315_arch_init_irq(void);
|
||||
void ar2315_init_devices(void);
|
||||
void ar2315_plat_time_init(void);
|
||||
void ar2315_plat_mem_setup(void);
|
||||
void ar2315_arch_init(void);
|
||||
|
||||
#else
|
||||
|
||||
static inline void ar2315_arch_init_irq(void) {}
|
||||
static inline void ar2315_init_devices(void) {}
|
||||
static inline void ar2315_plat_time_init(void) {}
|
||||
static inline void ar2315_plat_mem_setup(void) {}
|
||||
static inline void ar2315_arch_init(void) {}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __AR2315_H */
|
|
@ -0,0 +1,410 @@
|
|||
/*
|
||||
* Register definitions for AR2315+
|
||||
*
|
||||
* 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) 2003 Atheros Communications, Inc., All Rights Reserved.
|
||||
* Copyright (C) 2006 FON Technology, SL.
|
||||
* Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
|
||||
* Copyright (C) 2006-2008 Felix Fietkau <nbd@openwrt.org>
|
||||
*/
|
||||
|
||||
#ifndef __ASM_MACH_ATH25_AR2315_REGS_H
|
||||
#define __ASM_MACH_ATH25_AR2315_REGS_H
|
||||
|
||||
/*
|
||||
* IRQs
|
||||
*/
|
||||
#define AR2315_IRQ_MISC (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */
|
||||
#define AR2315_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */
|
||||
#define AR2315_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */
|
||||
#define AR2315_IRQ_LCBUS_PCI (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */
|
||||
#define AR2315_IRQ_WLAN0_POLL (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */
|
||||
|
||||
/*
|
||||
* Miscellaneous interrupts, which share IP2.
|
||||
*/
|
||||
#define AR2315_MISC_IRQ_UART0 0
|
||||
#define AR2315_MISC_IRQ_I2C_RSVD 1
|
||||
#define AR2315_MISC_IRQ_SPI 2
|
||||
#define AR2315_MISC_IRQ_AHB 3
|
||||
#define AR2315_MISC_IRQ_APB 4
|
||||
#define AR2315_MISC_IRQ_TIMER 5
|
||||
#define AR2315_MISC_IRQ_GPIO 6
|
||||
#define AR2315_MISC_IRQ_WATCHDOG 7
|
||||
#define AR2315_MISC_IRQ_IR_RSVD 8
|
||||
#define AR2315_MISC_IRQ_COUNT 9
|
||||
|
||||
/*
|
||||
* Address map
|
||||
*/
|
||||
#define AR2315_SPI_READ_BASE 0x08000000 /* SPI flash */
|
||||
#define AR2315_SPI_READ_SIZE 0x01000000
|
||||
#define AR2315_WLAN0_BASE 0x10000000 /* Wireless MMR */
|
||||
#define AR2315_PCI_BASE 0x10100000 /* PCI MMR */
|
||||
#define AR2315_PCI_SIZE 0x00001000
|
||||
#define AR2315_SDRAMCTL_BASE 0x10300000 /* SDRAM MMR */
|
||||
#define AR2315_SDRAMCTL_SIZE 0x00000020
|
||||
#define AR2315_LOCAL_BASE 0x10400000 /* Local bus MMR */
|
||||
#define AR2315_ENET0_BASE 0x10500000 /* Ethernet MMR */
|
||||
#define AR2315_RST_BASE 0x11000000 /* Reset control MMR */
|
||||
#define AR2315_RST_SIZE 0x00000100
|
||||
#define AR2315_UART0_BASE 0x11100000 /* UART MMR */
|
||||
#define AR2315_SPI_MMR_BASE 0x11300000 /* SPI flash MMR */
|
||||
#define AR2315_SPI_MMR_SIZE 0x00000010
|
||||
#define AR2315_PCI_EXT_BASE 0x80000000 /* PCI external */
|
||||
#define AR2315_PCI_EXT_SIZE 0x40000000
|
||||
|
||||
/*
|
||||
* Configuration registers
|
||||
*/
|
||||
|
||||
/* Cold reset register */
|
||||
#define AR2315_COLD_RESET 0x0000
|
||||
|
||||
#define AR2315_RESET_COLD_AHB 0x00000001
|
||||
#define AR2315_RESET_COLD_APB 0x00000002
|
||||
#define AR2315_RESET_COLD_CPU 0x00000004
|
||||
#define AR2315_RESET_COLD_CPUWARM 0x00000008
|
||||
#define AR2315_RESET_SYSTEM (RESET_COLD_CPU |\
|
||||
RESET_COLD_APB |\
|
||||
RESET_COLD_AHB) /* full system */
|
||||
#define AR2317_RESET_SYSTEM 0x00000010
|
||||
|
||||
/* Reset register */
|
||||
#define AR2315_RESET 0x0004
|
||||
|
||||
#define AR2315_RESET_WARM_WLAN0_MAC 0x00000001 /* warm reset WLAN0 MAC */
|
||||
#define AR2315_RESET_WARM_WLAN0_BB 0x00000002 /* warm reset WLAN0 BB */
|
||||
#define AR2315_RESET_MPEGTS_RSVD 0x00000004 /* warm reset MPEG-TS */
|
||||
#define AR2315_RESET_PCIDMA 0x00000008 /* warm reset PCI ahb/dma */
|
||||
#define AR2315_RESET_MEMCTL 0x00000010 /* warm reset mem control */
|
||||
#define AR2315_RESET_LOCAL 0x00000020 /* warm reset local bus */
|
||||
#define AR2315_RESET_I2C_RSVD 0x00000040 /* warm reset I2C bus */
|
||||
#define AR2315_RESET_SPI 0x00000080 /* warm reset SPI iface */
|
||||
#define AR2315_RESET_UART0 0x00000100 /* warm reset UART0 */
|
||||
#define AR2315_RESET_IR_RSVD 0x00000200 /* warm reset IR iface */
|
||||
#define AR2315_RESET_EPHY0 0x00000400 /* cold reset ENET0 phy */
|
||||
#define AR2315_RESET_ENET0 0x00000800 /* cold reset ENET0 MAC */
|
||||
|
||||
/* AHB master arbitration control */
|
||||
#define AR2315_AHB_ARB_CTL 0x0008
|
||||
|
||||
#define AR2315_ARB_CPU 0x00000001 /* CPU, default */
|
||||
#define AR2315_ARB_WLAN 0x00000002 /* WLAN */
|
||||
#define AR2315_ARB_MPEGTS_RSVD 0x00000004 /* MPEG-TS */
|
||||
#define AR2315_ARB_LOCAL 0x00000008 /* Local bus */
|
||||
#define AR2315_ARB_PCI 0x00000010 /* PCI bus */
|
||||
#define AR2315_ARB_ETHERNET 0x00000020 /* Ethernet */
|
||||
#define AR2315_ARB_RETRY 0x00000100 /* Retry policy (debug) */
|
||||
|
||||
/* Config Register */
|
||||
#define AR2315_ENDIAN_CTL 0x000c
|
||||
|
||||
#define AR2315_CONFIG_AHB 0x00000001 /* EC-AHB bridge endian */
|
||||
#define AR2315_CONFIG_WLAN 0x00000002 /* WLAN byteswap */
|
||||
#define AR2315_CONFIG_MPEGTS_RSVD 0x00000004 /* MPEG-TS byteswap */
|
||||
#define AR2315_CONFIG_PCI 0x00000008 /* PCI byteswap */
|
||||
#define AR2315_CONFIG_MEMCTL 0x00000010 /* Mem controller endian */
|
||||
#define AR2315_CONFIG_LOCAL 0x00000020 /* Local bus byteswap */
|
||||
#define AR2315_CONFIG_ETHERNET 0x00000040 /* Ethernet byteswap */
|
||||
#define AR2315_CONFIG_MERGE 0x00000200 /* CPU write buffer merge */
|
||||
#define AR2315_CONFIG_CPU 0x00000400 /* CPU big endian */
|
||||
#define AR2315_CONFIG_BIG 0x00000400
|
||||
#define AR2315_CONFIG_PCIAHB 0x00000800
|
||||
#define AR2315_CONFIG_PCIAHB_BRIDGE 0x00001000
|
||||
#define AR2315_CONFIG_SPI 0x00008000 /* SPI byteswap */
|
||||
#define AR2315_CONFIG_CPU_DRAM 0x00010000
|
||||
#define AR2315_CONFIG_CPU_PCI 0x00020000
|
||||
#define AR2315_CONFIG_CPU_MMR 0x00040000
|
||||
|
||||
/* NMI control */
|
||||
#define AR2315_NMI_CTL 0x0010
|
||||
|
||||
#define AR2315_NMI_EN 1
|
||||
|
||||
/* Revision Register - Initial value is 0x3010 (WMAC 3.0, AR231X 1.0). */
|
||||
#define AR2315_SREV 0x0014
|
||||
|
||||
#define AR2315_REV_MAJ 0x000000f0
|
||||
#define AR2315_REV_MAJ_S 4
|
||||
#define AR2315_REV_MIN 0x0000000f
|
||||
#define AR2315_REV_MIN_S 0
|
||||
#define AR2315_REV_CHIP (AR2315_REV_MAJ | AR2315_REV_MIN)
|
||||
|
||||
/* Interface Enable */
|
||||
#define AR2315_IF_CTL 0x0018
|
||||
|
||||
#define AR2315_IF_MASK 0x00000007
|
||||
#define AR2315_IF_DISABLED 0 /* Disable all */
|
||||
#define AR2315_IF_PCI 1 /* PCI */
|
||||
#define AR2315_IF_TS_LOCAL 2 /* Local bus */
|
||||
#define AR2315_IF_ALL 3 /* Emulation only */
|
||||
#define AR2315_IF_LOCAL_HOST 0x00000008
|
||||
#define AR2315_IF_PCI_HOST 0x00000010
|
||||
#define AR2315_IF_PCI_INTR 0x00000020
|
||||
#define AR2315_IF_PCI_CLK_MASK 0x00030000
|
||||
#define AR2315_IF_PCI_CLK_INPUT 0
|
||||
#define AR2315_IF_PCI_CLK_OUTPUT_LOW 1
|
||||
#define AR2315_IF_PCI_CLK_OUTPUT_CLK 2
|
||||
#define AR2315_IF_PCI_CLK_OUTPUT_HIGH 3
|
||||
#define AR2315_IF_PCI_CLK_SHIFT 16
|
||||
|
||||
/* APB Interrupt control */
|
||||
#define AR2315_ISR 0x0020
|
||||
#define AR2315_IMR 0x0024
|
||||
#define AR2315_GISR 0x0028
|
||||
|
||||
#define AR2315_ISR_UART0 0x00000001 /* high speed UART */
|
||||
#define AR2315_ISR_I2C_RSVD 0x00000002 /* I2C bus */
|
||||
#define AR2315_ISR_SPI 0x00000004 /* SPI bus */
|
||||
#define AR2315_ISR_AHB 0x00000008 /* AHB error */
|
||||
#define AR2315_ISR_APB 0x00000010 /* APB error */
|
||||
#define AR2315_ISR_TIMER 0x00000020 /* Timer */
|
||||
#define AR2315_ISR_GPIO 0x00000040 /* GPIO */
|
||||
#define AR2315_ISR_WD 0x00000080 /* Watchdog */
|
||||
#define AR2315_ISR_IR_RSVD 0x00000100 /* IR */
|
||||
|
||||
#define AR2315_GISR_MISC 0x00000001 /* Misc */
|
||||
#define AR2315_GISR_WLAN0 0x00000002 /* WLAN0 */
|
||||
#define AR2315_GISR_MPEGTS_RSVD 0x00000004 /* MPEG-TS */
|
||||
#define AR2315_GISR_LOCALPCI 0x00000008 /* Local/PCI bus */
|
||||
#define AR2315_GISR_WMACPOLL 0x00000010
|
||||
#define AR2315_GISR_TIMER 0x00000020
|
||||
#define AR2315_GISR_ETHERNET 0x00000040 /* Ethernet */
|
||||
|
||||
/* Generic timer */
|
||||
#define AR2315_TIMER 0x0030
|
||||
#define AR2315_RELOAD 0x0034
|
||||
|
||||
/* Watchdog timer */
|
||||
#define AR2315_WDT_TIMER 0x0038
|
||||
#define AR2315_WDT_CTRL 0x003c
|
||||
|
||||
#define AR2315_WDT_CTRL_IGNORE 0x00000000 /* ignore expiration */
|
||||
#define AR2315_WDT_CTRL_NMI 0x00000001 /* NMI on watchdog */
|
||||
#define AR2315_WDT_CTRL_RESET 0x00000002 /* reset on watchdog */
|
||||
|
||||
/* CPU Performance Counters */
|
||||
#define AR2315_PERFCNT0 0x0048
|
||||
#define AR2315_PERFCNT1 0x004c
|
||||
|
||||
#define AR2315_PERF0_DATAHIT 0x00000001 /* Count Data Cache Hits */
|
||||
#define AR2315_PERF0_DATAMISS 0x00000002 /* Count Data Cache Misses */
|
||||
#define AR2315_PERF0_INSTHIT 0x00000004 /* Count Instruction Cache Hits */
|
||||
#define AR2315_PERF0_INSTMISS 0x00000008 /* Count Instruction Cache Misses */
|
||||
#define AR2315_PERF0_ACTIVE 0x00000010 /* Count Active Processor Cycles */
|
||||
#define AR2315_PERF0_WBHIT 0x00000020 /* Count CPU Write Buffer Hits */
|
||||
#define AR2315_PERF0_WBMISS 0x00000040 /* Count CPU Write Buffer Misses */
|
||||
|
||||
#define AR2315_PERF1_EB_ARDY 0x00000001 /* Count EB_ARdy signal */
|
||||
#define AR2315_PERF1_EB_AVALID 0x00000002 /* Count EB_AValid signal */
|
||||
#define AR2315_PERF1_EB_WDRDY 0x00000004 /* Count EB_WDRdy signal */
|
||||
#define AR2315_PERF1_EB_RDVAL 0x00000008 /* Count EB_RdVal signal */
|
||||
#define AR2315_PERF1_VRADDR 0x00000010 /* Count valid read address cycles*/
|
||||
#define AR2315_PERF1_VWADDR 0x00000020 /* Count valid write address cycl.*/
|
||||
#define AR2315_PERF1_VWDATA 0x00000040 /* Count valid write data cycles */
|
||||
|
||||
/* AHB Error Reporting */
|
||||
#define AR2315_AHB_ERR0 0x0050 /* error */
|
||||
#define AR2315_AHB_ERR1 0x0054 /* haddr */
|
||||
#define AR2315_AHB_ERR2 0x0058 /* hwdata */
|
||||
#define AR2315_AHB_ERR3 0x005c /* hrdata */
|
||||
#define AR2315_AHB_ERR4 0x0060 /* status */
|
||||
|
||||
#define AR2315_AHB_ERROR_DET 1 /* AHB Error has been detected, */
|
||||
/* write 1 to clear all bits in ERR0 */
|
||||
#define AR2315_AHB_ERROR_OVR 2 /* AHB Error overflow has been detected */
|
||||
#define AR2315_AHB_ERROR_WDT 4 /* AHB Error due to wdt instead of hresp */
|
||||
|
||||
#define AR2315_PROCERR_HMAST 0x0000000f
|
||||
#define AR2315_PROCERR_HMAST_DFLT 0
|
||||
#define AR2315_PROCERR_HMAST_WMAC 1
|
||||
#define AR2315_PROCERR_HMAST_ENET 2
|
||||
#define AR2315_PROCERR_HMAST_PCIENDPT 3
|
||||
#define AR2315_PROCERR_HMAST_LOCAL 4
|
||||
#define AR2315_PROCERR_HMAST_CPU 5
|
||||
#define AR2315_PROCERR_HMAST_PCITGT 6
|
||||
#define AR2315_PROCERR_HMAST_S 0
|
||||
#define AR2315_PROCERR_HWRITE 0x00000010
|
||||
#define AR2315_PROCERR_HSIZE 0x00000060
|
||||
#define AR2315_PROCERR_HSIZE_S 5
|
||||
#define AR2315_PROCERR_HTRANS 0x00000180
|
||||
#define AR2315_PROCERR_HTRANS_S 7
|
||||
#define AR2315_PROCERR_HBURST 0x00000e00
|
||||
#define AR2315_PROCERR_HBURST_S 9
|
||||
|
||||
/* Clock Control */
|
||||
#define AR2315_PLLC_CTL 0x0064
|
||||
#define AR2315_PLLV_CTL 0x0068
|
||||
#define AR2315_CPUCLK 0x006c
|
||||
#define AR2315_AMBACLK 0x0070
|
||||
#define AR2315_SYNCCLK 0x0074
|
||||
#define AR2315_DSL_SLEEP_CTL 0x0080
|
||||
#define AR2315_DSL_SLEEP_DUR 0x0084
|
||||
|
||||
/* PLLc Control fields */
|
||||
#define AR2315_PLLC_REF_DIV_M 0x00000003
|
||||
#define AR2315_PLLC_REF_DIV_S 0
|
||||
#define AR2315_PLLC_FDBACK_DIV_M 0x0000007c
|
||||
#define AR2315_PLLC_FDBACK_DIV_S 2
|
||||
#define AR2315_PLLC_ADD_FDBACK_DIV_M 0x00000080
|
||||
#define AR2315_PLLC_ADD_FDBACK_DIV_S 7
|
||||
#define AR2315_PLLC_CLKC_DIV_M 0x0001c000
|
||||
#define AR2315_PLLC_CLKC_DIV_S 14
|
||||
#define AR2315_PLLC_CLKM_DIV_M 0x00700000
|
||||
#define AR2315_PLLC_CLKM_DIV_S 20
|
||||
|
||||
/* CPU CLK Control fields */
|
||||
#define AR2315_CPUCLK_CLK_SEL_M 0x00000003
|
||||
#define AR2315_CPUCLK_CLK_SEL_S 0
|
||||
#define AR2315_CPUCLK_CLK_DIV_M 0x0000000c
|
||||
#define AR2315_CPUCLK_CLK_DIV_S 2
|
||||
|
||||
/* AMBA CLK Control fields */
|
||||
#define AR2315_AMBACLK_CLK_SEL_M 0x00000003
|
||||
#define AR2315_AMBACLK_CLK_SEL_S 0
|
||||
#define AR2315_AMBACLK_CLK_DIV_M 0x0000000c
|
||||
#define AR2315_AMBACLK_CLK_DIV_S 2
|
||||
|
||||
/* PCI Clock Control */
|
||||
#define AR2315_PCICLK 0x00a4
|
||||
|
||||
#define AR2315_PCICLK_INPUT_M 0x00000003
|
||||
#define AR2315_PCICLK_INPUT_S 0
|
||||
#define AR2315_PCICLK_PLLC_CLKM 0
|
||||
#define AR2315_PCICLK_PLLC_CLKM1 1
|
||||
#define AR2315_PCICLK_PLLC_CLKC 2
|
||||
#define AR2315_PCICLK_REF_CLK 3
|
||||
#define AR2315_PCICLK_DIV_M 0x0000000c
|
||||
#define AR2315_PCICLK_DIV_S 2
|
||||
#define AR2315_PCICLK_IN_FREQ 0
|
||||
#define AR2315_PCICLK_IN_FREQ_DIV_6 1
|
||||
#define AR2315_PCICLK_IN_FREQ_DIV_8 2
|
||||
#define AR2315_PCICLK_IN_FREQ_DIV_10 3
|
||||
|
||||
/* Observation Control Register */
|
||||
#define AR2315_OCR 0x00b0
|
||||
|
||||
#define AR2315_OCR_GPIO0_IRIN 0x00000040
|
||||
#define AR2315_OCR_GPIO1_IROUT 0x00000080
|
||||
#define AR2315_OCR_GPIO3_RXCLR 0x00000200
|
||||
|
||||
/* General Clock Control */
|
||||
#define AR2315_MISCCLK 0x00b4
|
||||
|
||||
#define AR2315_MISCCLK_PLLBYPASS_EN 0x00000001
|
||||
#define AR2315_MISCCLK_PROCREFCLK 0x00000002
|
||||
|
||||
/*
|
||||
* SDRAM Controller
|
||||
* - No read or write buffers are included.
|
||||
*/
|
||||
#define AR2315_MEM_CFG 0x0000
|
||||
#define AR2315_MEM_CTRL 0x000c
|
||||
#define AR2315_MEM_REF 0x0010
|
||||
|
||||
#define AR2315_MEM_CFG_DATA_WIDTH_M 0x00006000
|
||||
#define AR2315_MEM_CFG_DATA_WIDTH_S 13
|
||||
#define AR2315_MEM_CFG_COL_WIDTH_M 0x00001e00
|
||||
#define AR2315_MEM_CFG_COL_WIDTH_S 9
|
||||
#define AR2315_MEM_CFG_ROW_WIDTH_M 0x000001e0
|
||||
#define AR2315_MEM_CFG_ROW_WIDTH_S 5
|
||||
#define AR2315_MEM_CFG_BANKADDR_BITS_M 0x00000018
|
||||
#define AR2315_MEM_CFG_BANKADDR_BITS_S 3
|
||||
|
||||
/*
|
||||
* Local Bus Interface Registers
|
||||
*/
|
||||
#define AR2315_LB_CONFIG 0x0000
|
||||
|
||||
#define AR2315_LBCONF_OE 0x00000001 /* =1 OE is low-true */
|
||||
#define AR2315_LBCONF_CS0 0x00000002 /* =1 first CS is low-true */
|
||||
#define AR2315_LBCONF_CS1 0x00000004 /* =1 2nd CS is low-true */
|
||||
#define AR2315_LBCONF_RDY 0x00000008 /* =1 RDY is low-true */
|
||||
#define AR2315_LBCONF_WE 0x00000010 /* =1 Write En is low-true */
|
||||
#define AR2315_LBCONF_WAIT 0x00000020 /* =1 WAIT is low-true */
|
||||
#define AR2315_LBCONF_ADS 0x00000040 /* =1 Adr Strobe is low-true */
|
||||
#define AR2315_LBCONF_MOT 0x00000080 /* =0 Intel, =1 Motorola */
|
||||
#define AR2315_LBCONF_8CS 0x00000100 /* =1 8 bits CS, 0= 16bits */
|
||||
#define AR2315_LBCONF_8DS 0x00000200 /* =1 8 bits Data S, 0=16bits */
|
||||
#define AR2315_LBCONF_ADS_EN 0x00000400 /* =1 Enable ADS */
|
||||
#define AR2315_LBCONF_ADR_OE 0x00000800 /* =1 Adr cap on OE, WE or DS */
|
||||
#define AR2315_LBCONF_ADDT_MUX 0x00001000 /* =1 Adr and Data share bus */
|
||||
#define AR2315_LBCONF_DATA_OE 0x00002000 /* =1 Data cap on OE, WE, DS */
|
||||
#define AR2315_LBCONF_16DATA 0x00004000 /* =1 Data is 16 bits wide */
|
||||
#define AR2315_LBCONF_SWAPDT 0x00008000 /* =1 Byte swap data */
|
||||
#define AR2315_LBCONF_SYNC 0x00010000 /* =1 Bus synchronous to clk */
|
||||
#define AR2315_LBCONF_INT 0x00020000 /* =1 Intr is low true */
|
||||
#define AR2315_LBCONF_INT_CTR0 0x00000000 /* GND high-Z, Vdd is high-Z */
|
||||
#define AR2315_LBCONF_INT_CTR1 0x00040000 /* GND drive, Vdd is high-Z */
|
||||
#define AR2315_LBCONF_INT_CTR2 0x00080000 /* GND high-Z, Vdd drive */
|
||||
#define AR2315_LBCONF_INT_CTR3 0x000c0000 /* GND drive, Vdd drive */
|
||||
#define AR2315_LBCONF_RDY_WAIT 0x00100000 /* =1 RDY is negative of WAIT */
|
||||
#define AR2315_LBCONF_INT_PULSE 0x00200000 /* =1 Interrupt is a pulse */
|
||||
#define AR2315_LBCONF_ENABLE 0x00400000 /* =1 Falcon respond to LB */
|
||||
|
||||
#define AR2315_LB_CLKSEL 0x0004
|
||||
|
||||
#define AR2315_LBCLK_EXT 0x00000001 /* use external clk for lb */
|
||||
|
||||
#define AR2315_LB_1MS 0x0008
|
||||
|
||||
#define AR2315_LB1MS_MASK 0x0003ffff /* # of AHB clk cycles in 1ms */
|
||||
|
||||
#define AR2315_LB_MISCCFG 0x000c
|
||||
|
||||
#define AR2315_LBM_TXD_EN 0x00000001 /* Enable TXD for fragments */
|
||||
#define AR2315_LBM_RX_INTEN 0x00000002 /* Enable LB ints on RX ready */
|
||||
#define AR2315_LBM_MBOXWR_INTEN 0x00000004 /* Enable LB ints on mbox wr */
|
||||
#define AR2315_LBM_MBOXRD_INTEN 0x00000008 /* Enable LB ints on mbox rd */
|
||||
#define AR2315_LMB_DESCSWAP_EN 0x00000010 /* Byte swap desc enable */
|
||||
#define AR2315_LBM_TIMEOUT_M 0x00ffff80
|
||||
#define AR2315_LBM_TIMEOUT_S 7
|
||||
#define AR2315_LBM_PORTMUX 0x07000000
|
||||
|
||||
#define AR2315_LB_RXTSOFF 0x0010
|
||||
|
||||
#define AR2315_LB_TX_CHAIN_EN 0x0100
|
||||
|
||||
#define AR2315_LB_TXEN_0 0x00000001
|
||||
#define AR2315_LB_TXEN_1 0x00000002
|
||||
#define AR2315_LB_TXEN_2 0x00000004
|
||||
#define AR2315_LB_TXEN_3 0x00000008
|
||||
|
||||
#define AR2315_LB_TX_CHAIN_DIS 0x0104
|
||||
#define AR2315_LB_TX_DESC_PTR 0x0200
|
||||
|
||||
#define AR2315_LB_RX_CHAIN_EN 0x0400
|
||||
|
||||
#define AR2315_LB_RXEN 0x00000001
|
||||
|
||||
#define AR2315_LB_RX_CHAIN_DIS 0x0404
|
||||
#define AR2315_LB_RX_DESC_PTR 0x0408
|
||||
|
||||
#define AR2315_LB_INT_STATUS 0x0500
|
||||
|
||||
#define AR2315_LB_INT_TX_DESC 0x00000001
|
||||
#define AR2315_LB_INT_TX_OK 0x00000002
|
||||
#define AR2315_LB_INT_TX_ERR 0x00000004
|
||||
#define AR2315_LB_INT_TX_EOF 0x00000008
|
||||
#define AR2315_LB_INT_RX_DESC 0x00000010
|
||||
#define AR2315_LB_INT_RX_OK 0x00000020
|
||||
#define AR2315_LB_INT_RX_ERR 0x00000040
|
||||
#define AR2315_LB_INT_RX_EOF 0x00000080
|
||||
#define AR2315_LB_INT_TX_TRUNC 0x00000100
|
||||
#define AR2315_LB_INT_TX_STARVE 0x00000200
|
||||
#define AR2315_LB_INT_LB_TIMEOUT 0x00000400
|
||||
#define AR2315_LB_INT_LB_ERR 0x00000800
|
||||
#define AR2315_LB_INT_MBOX_WR 0x00001000
|
||||
#define AR2315_LB_INT_MBOX_RD 0x00002000
|
||||
|
||||
/* Bit definitions for INT MASK are the same as INT_STATUS */
|
||||
#define AR2315_LB_INT_MASK 0x0504
|
||||
|
||||
#define AR2315_LB_INT_EN 0x0508
|
||||
#define AR2315_LB_MBOX 0x0600
|
||||
|
||||
#endif /* __ASM_MACH_ATH25_AR2315_REGS_H */
|
|
@ -0,0 +1,393 @@
|
|||
/*
|
||||
* 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) 2003 Atheros Communications, Inc., All Rights Reserved.
|
||||
* Copyright (C) 2006 FON Technology, SL.
|
||||
* Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
|
||||
* Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
|
||||
* Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Platform devices for Atheros AR5312 SoCs
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#include <ath25_platform.h>
|
||||
|
||||
#include "devices.h"
|
||||
#include "ar5312.h"
|
||||
#include "ar5312_regs.h"
|
||||
|
||||
static void __iomem *ar5312_rst_base;
|
||||
static struct irq_domain *ar5312_misc_irq_domain;
|
||||
|
||||
static inline u32 ar5312_rst_reg_read(u32 reg)
|
||||
{
|
||||
return __raw_readl(ar5312_rst_base + reg);
|
||||
}
|
||||
|
||||
static inline void ar5312_rst_reg_write(u32 reg, u32 val)
|
||||
{
|
||||
__raw_writel(val, ar5312_rst_base + reg);
|
||||
}
|
||||
|
||||
static inline void ar5312_rst_reg_mask(u32 reg, u32 mask, u32 val)
|
||||
{
|
||||
u32 ret = ar5312_rst_reg_read(reg);
|
||||
|
||||
ret &= ~mask;
|
||||
ret |= val;
|
||||
ar5312_rst_reg_write(reg, ret);
|
||||
}
|
||||
|
||||
static irqreturn_t ar5312_ahb_err_handler(int cpl, void *dev_id)
|
||||
{
|
||||
u32 proc1 = ar5312_rst_reg_read(AR5312_PROC1);
|
||||
u32 proc_addr = ar5312_rst_reg_read(AR5312_PROCADDR); /* clears error */
|
||||
u32 dma1 = ar5312_rst_reg_read(AR5312_DMA1);
|
||||
u32 dma_addr = ar5312_rst_reg_read(AR5312_DMAADDR); /* clears error */
|
||||
|
||||
pr_emerg("AHB interrupt: PROCADDR=0x%8.8x PROC1=0x%8.8x DMAADDR=0x%8.8x DMA1=0x%8.8x\n",
|
||||
proc_addr, proc1, dma_addr, dma1);
|
||||
|
||||
machine_restart("AHB error"); /* Catastrophic failure */
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction ar5312_ahb_err_interrupt = {
|
||||
.handler = ar5312_ahb_err_handler,
|
||||
.name = "ar5312-ahb-error",
|
||||
};
|
||||
|
||||
static void ar5312_misc_irq_handler(unsigned irq, struct irq_desc *desc)
|
||||
{
|
||||
u32 pending = ar5312_rst_reg_read(AR5312_ISR) &
|
||||
ar5312_rst_reg_read(AR5312_IMR);
|
||||
unsigned nr, misc_irq = 0;
|
||||
|
||||
if (pending) {
|
||||
struct irq_domain *domain = irq_get_handler_data(irq);
|
||||
|
||||
nr = __ffs(pending);
|
||||
misc_irq = irq_find_mapping(domain, nr);
|
||||
}
|
||||
|
||||
if (misc_irq) {
|
||||
generic_handle_irq(misc_irq);
|
||||
if (nr == AR5312_MISC_IRQ_TIMER)
|
||||
ar5312_rst_reg_read(AR5312_TIMER);
|
||||
} else {
|
||||
spurious_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable the specified AR5312_MISC_IRQ interrupt */
|
||||
static void ar5312_misc_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
ar5312_rst_reg_mask(AR5312_IMR, 0, BIT(d->hwirq));
|
||||
}
|
||||
|
||||
/* Disable the specified AR5312_MISC_IRQ interrupt */
|
||||
static void ar5312_misc_irq_mask(struct irq_data *d)
|
||||
{
|
||||
ar5312_rst_reg_mask(AR5312_IMR, BIT(d->hwirq), 0);
|
||||
ar5312_rst_reg_read(AR5312_IMR); /* flush write buffer */
|
||||
}
|
||||
|
||||
static struct irq_chip ar5312_misc_irq_chip = {
|
||||
.name = "ar5312-misc",
|
||||
.irq_unmask = ar5312_misc_irq_unmask,
|
||||
.irq_mask = ar5312_misc_irq_mask,
|
||||
};
|
||||
|
||||
static int ar5312_misc_irq_map(struct irq_domain *d, unsigned irq,
|
||||
irq_hw_number_t hw)
|
||||
{
|
||||
irq_set_chip_and_handler(irq, &ar5312_misc_irq_chip, handle_level_irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_domain_ops ar5312_misc_irq_domain_ops = {
|
||||
.map = ar5312_misc_irq_map,
|
||||
};
|
||||
|
||||
static void ar5312_irq_dispatch(void)
|
||||
{
|
||||
u32 pending = read_c0_status() & read_c0_cause();
|
||||
|
||||
if (pending & CAUSEF_IP2)
|
||||
do_IRQ(AR5312_IRQ_WLAN0);
|
||||
else if (pending & CAUSEF_IP5)
|
||||
do_IRQ(AR5312_IRQ_WLAN1);
|
||||
else if (pending & CAUSEF_IP6)
|
||||
do_IRQ(AR5312_IRQ_MISC);
|
||||
else if (pending & CAUSEF_IP7)
|
||||
do_IRQ(ATH25_IRQ_CPU_CLOCK);
|
||||
else
|
||||
spurious_interrupt();
|
||||
}
|
||||
|
||||
void __init ar5312_arch_init_irq(void)
|
||||
{
|
||||
struct irq_domain *domain;
|
||||
unsigned irq;
|
||||
|
||||
ath25_irq_dispatch = ar5312_irq_dispatch;
|
||||
|
||||
domain = irq_domain_add_linear(NULL, AR5312_MISC_IRQ_COUNT,
|
||||
&ar5312_misc_irq_domain_ops, NULL);
|
||||
if (!domain)
|
||||
panic("Failed to add IRQ domain");
|
||||
|
||||
irq = irq_create_mapping(domain, AR5312_MISC_IRQ_AHB_PROC);
|
||||
setup_irq(irq, &ar5312_ahb_err_interrupt);
|
||||
|
||||
irq_set_chained_handler(AR5312_IRQ_MISC, ar5312_misc_irq_handler);
|
||||
irq_set_handler_data(AR5312_IRQ_MISC, domain);
|
||||
|
||||
ar5312_misc_irq_domain = domain;
|
||||
}
|
||||
|
||||
static struct physmap_flash_data ar5312_flash_data = {
|
||||
.width = 2,
|
||||
};
|
||||
|
||||
static struct resource ar5312_flash_resource = {
|
||||
.start = AR5312_FLASH_BASE,
|
||||
.end = AR5312_FLASH_BASE + AR5312_FLASH_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device ar5312_physmap_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev.platform_data = &ar5312_flash_data,
|
||||
.resource = &ar5312_flash_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
static void __init ar5312_flash_init(void)
|
||||
{
|
||||
void __iomem *flashctl_base;
|
||||
u32 ctl;
|
||||
|
||||
flashctl_base = ioremap_nocache(AR5312_FLASHCTL_BASE,
|
||||
AR5312_FLASHCTL_SIZE);
|
||||
|
||||
ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL0);
|
||||
ctl &= AR5312_FLASHCTL_MW;
|
||||
|
||||
/* fixup flash width */
|
||||
switch (ctl) {
|
||||
case AR5312_FLASHCTL_MW16:
|
||||
ar5312_flash_data.width = 2;
|
||||
break;
|
||||
case AR5312_FLASHCTL_MW8:
|
||||
default:
|
||||
ar5312_flash_data.width = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure flash bank 0.
|
||||
* Assume 8M window size. Flash will be aliased if it's smaller
|
||||
*/
|
||||
ctl |= AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC_8M | AR5312_FLASHCTL_RBLE;
|
||||
ctl |= 0x01 << AR5312_FLASHCTL_IDCY_S;
|
||||
ctl |= 0x07 << AR5312_FLASHCTL_WST1_S;
|
||||
ctl |= 0x07 << AR5312_FLASHCTL_WST2_S;
|
||||
__raw_writel(ctl, flashctl_base + AR5312_FLASHCTL0);
|
||||
|
||||
/* Disable other flash banks */
|
||||
ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL1);
|
||||
ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC);
|
||||
__raw_writel(ctl, flashctl_base + AR5312_FLASHCTL1);
|
||||
ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL2);
|
||||
ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC);
|
||||
__raw_writel(ctl, flashctl_base + AR5312_FLASHCTL2);
|
||||
|
||||
iounmap(flashctl_base);
|
||||
}
|
||||
|
||||
void __init ar5312_init_devices(void)
|
||||
{
|
||||
struct ath25_boarddata *config;
|
||||
|
||||
ar5312_flash_init();
|
||||
|
||||
/* Locate board/radio config data */
|
||||
ath25_find_config(AR5312_FLASH_BASE, AR5312_FLASH_SIZE);
|
||||
config = ath25_board.config;
|
||||
|
||||
/* AR2313 has CPU minor rev. 10 */
|
||||
if ((current_cpu_data.processor_id & 0xff) == 0x0a)
|
||||
ath25_soc = ATH25_SOC_AR2313;
|
||||
|
||||
/* AR2312 shares the same Silicon ID as AR5312 */
|
||||
else if (config->flags & BD_ISCASPER)
|
||||
ath25_soc = ATH25_SOC_AR2312;
|
||||
|
||||
/* Everything else is probably AR5312 or compatible */
|
||||
else
|
||||
ath25_soc = ATH25_SOC_AR5312;
|
||||
|
||||
platform_device_register(&ar5312_physmap_flash);
|
||||
|
||||
switch (ath25_soc) {
|
||||
case ATH25_SOC_AR5312:
|
||||
if (!ath25_board.radio)
|
||||
return;
|
||||
|
||||
if (!(config->flags & BD_WLAN0))
|
||||
break;
|
||||
|
||||
ath25_add_wmac(0, AR5312_WLAN0_BASE, AR5312_IRQ_WLAN0);
|
||||
break;
|
||||
case ATH25_SOC_AR2312:
|
||||
case ATH25_SOC_AR2313:
|
||||
if (!ath25_board.radio)
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (config->flags & BD_WLAN1)
|
||||
ath25_add_wmac(1, AR5312_WLAN1_BASE, AR5312_IRQ_WLAN1);
|
||||
}
|
||||
|
||||
static void ar5312_restart(char *command)
|
||||
{
|
||||
/* reset the system */
|
||||
local_irq_disable();
|
||||
while (1)
|
||||
ar5312_rst_reg_write(AR5312_RESET, AR5312_RESET_SYSTEM);
|
||||
}
|
||||
|
||||
/*
|
||||
* This table is indexed by bits 5..4 of the CLOCKCTL1 register
|
||||
* to determine the predevisor value.
|
||||
*/
|
||||
static unsigned clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 };
|
||||
|
||||
static unsigned __init ar5312_cpu_frequency(void)
|
||||
{
|
||||
u32 scratch, devid, clock_ctl1;
|
||||
u32 predivide_mask, multiplier_mask, doubler_mask;
|
||||
unsigned predivide_shift, multiplier_shift;
|
||||
unsigned predivide_select, predivisor, multiplier;
|
||||
|
||||
/* Trust the bootrom's idea of cpu frequency. */
|
||||
scratch = ar5312_rst_reg_read(AR5312_SCRATCH);
|
||||
if (scratch)
|
||||
return scratch;
|
||||
|
||||
devid = ar5312_rst_reg_read(AR5312_REV);
|
||||
devid = (devid & AR5312_REV_MAJ) >> AR5312_REV_MAJ_S;
|
||||
if (devid == AR5312_REV_MAJ_AR2313) {
|
||||
predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK;
|
||||
predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT;
|
||||
multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK;
|
||||
multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT;
|
||||
doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK;
|
||||
} else { /* AR5312 and AR2312 */
|
||||
predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK;
|
||||
predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT;
|
||||
multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK;
|
||||
multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT;
|
||||
doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clocking is derived from a fixed 40MHz input clock.
|
||||
*
|
||||
* cpu_freq = input_clock * MULT (where MULT is PLL multiplier)
|
||||
* sys_freq = cpu_freq / 4 (used for APB clock, serial,
|
||||
* flash, Timer, Watchdog Timer)
|
||||
*
|
||||
* cnt_freq = cpu_freq / 2 (use for CPU count/compare)
|
||||
*
|
||||
* So, for example, with a PLL multiplier of 5, we have
|
||||
*
|
||||
* cpu_freq = 200MHz
|
||||
* sys_freq = 50MHz
|
||||
* cnt_freq = 100MHz
|
||||
*
|
||||
* We compute the CPU frequency, based on PLL settings.
|
||||
*/
|
||||
|
||||
clock_ctl1 = ar5312_rst_reg_read(AR5312_CLOCKCTL1);
|
||||
predivide_select = (clock_ctl1 & predivide_mask) >> predivide_shift;
|
||||
predivisor = clockctl1_predivide_table[predivide_select];
|
||||
multiplier = (clock_ctl1 & multiplier_mask) >> multiplier_shift;
|
||||
|
||||
if (clock_ctl1 & doubler_mask)
|
||||
multiplier <<= 1;
|
||||
|
||||
return (40000000 / predivisor) * multiplier;
|
||||
}
|
||||
|
||||
static inline unsigned ar5312_sys_frequency(void)
|
||||
{
|
||||
return ar5312_cpu_frequency() / 4;
|
||||
}
|
||||
|
||||
void __init ar5312_plat_time_init(void)
|
||||
{
|
||||
mips_hpt_frequency = ar5312_cpu_frequency() / 2;
|
||||
}
|
||||
|
||||
void __init ar5312_plat_mem_setup(void)
|
||||
{
|
||||
void __iomem *sdram_base;
|
||||
u32 memsize, memcfg, bank0_ac, bank1_ac;
|
||||
u32 devid;
|
||||
|
||||
/* Detect memory size */
|
||||
sdram_base = ioremap_nocache(AR5312_SDRAMCTL_BASE,
|
||||
AR5312_SDRAMCTL_SIZE);
|
||||
memcfg = __raw_readl(sdram_base + AR5312_MEM_CFG1);
|
||||
bank0_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC0);
|
||||
bank1_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC1);
|
||||
memsize = (bank0_ac ? (1 << (bank0_ac + 1)) : 0) +
|
||||
(bank1_ac ? (1 << (bank1_ac + 1)) : 0);
|
||||
memsize <<= 20;
|
||||
add_memory_region(0, memsize, BOOT_MEM_RAM);
|
||||
iounmap(sdram_base);
|
||||
|
||||
ar5312_rst_base = ioremap_nocache(AR5312_RST_BASE, AR5312_RST_SIZE);
|
||||
|
||||
devid = ar5312_rst_reg_read(AR5312_REV);
|
||||
devid >>= AR5312_REV_WMAC_MIN_S;
|
||||
devid &= AR5312_REV_CHIP;
|
||||
ath25_board.devid = (u16)devid;
|
||||
|
||||
/* Clear any lingering AHB errors */
|
||||
ar5312_rst_reg_read(AR5312_PROCADDR);
|
||||
ar5312_rst_reg_read(AR5312_DMAADDR);
|
||||
ar5312_rst_reg_write(AR5312_WDT_CTRL, AR5312_WDT_CTRL_IGNORE);
|
||||
|
||||
_machine_restart = ar5312_restart;
|
||||
}
|
||||
|
||||
void __init ar5312_arch_init(void)
|
||||
{
|
||||
unsigned irq = irq_create_mapping(ar5312_misc_irq_domain,
|
||||
AR5312_MISC_IRQ_UART0);
|
||||
|
||||
ath25_serial_setup(AR5312_UART0_BASE, irq, ar5312_sys_frequency());
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef __AR5312_H
|
||||
#define __AR5312_H
|
||||
|
||||
#ifdef CONFIG_SOC_AR5312
|
||||
|
||||
void ar5312_arch_init_irq(void);
|
||||
void ar5312_init_devices(void);
|
||||
void ar5312_plat_time_init(void);
|
||||
void ar5312_plat_mem_setup(void);
|
||||
void ar5312_arch_init(void);
|
||||
|
||||
#else
|
||||
|
||||
static inline void ar5312_arch_init_irq(void) {}
|
||||
static inline void ar5312_init_devices(void) {}
|
||||
static inline void ar5312_plat_time_init(void) {}
|
||||
static inline void ar5312_plat_mem_setup(void) {}
|
||||
static inline void ar5312_arch_init(void) {}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __AR5312_H */
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* 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) 2003 Atheros Communications, Inc., All Rights Reserved.
|
||||
* Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
|
||||
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
|
||||
*/
|
||||
|
||||
#ifndef __ASM_MACH_ATH25_AR5312_REGS_H
|
||||
#define __ASM_MACH_ATH25_AR5312_REGS_H
|
||||
|
||||
/*
|
||||
* IRQs
|
||||
*/
|
||||
#define AR5312_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */
|
||||
#define AR5312_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */
|
||||
#define AR5312_IRQ_ENET1 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */
|
||||
#define AR5312_IRQ_WLAN1 (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */
|
||||
#define AR5312_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */
|
||||
|
||||
/*
|
||||
* Miscellaneous interrupts, which share IP6.
|
||||
*/
|
||||
#define AR5312_MISC_IRQ_TIMER 0
|
||||
#define AR5312_MISC_IRQ_AHB_PROC 1
|
||||
#define AR5312_MISC_IRQ_AHB_DMA 2
|
||||
#define AR5312_MISC_IRQ_GPIO 3
|
||||
#define AR5312_MISC_IRQ_UART0 4
|
||||
#define AR5312_MISC_IRQ_UART0_DMA 5
|
||||
#define AR5312_MISC_IRQ_WATCHDOG 6
|
||||
#define AR5312_MISC_IRQ_LOCAL 7
|
||||
#define AR5312_MISC_IRQ_SPI 8
|
||||
#define AR5312_MISC_IRQ_COUNT 9
|
||||
|
||||
/*
|
||||
* Address Map
|
||||
*
|
||||
* The AR5312 supports 2 enet MACS, even though many reference boards only
|
||||
* actually use 1 of them (i.e. Only MAC 0 is actually connected to an enet
|
||||
* PHY or PHY switch. The AR2312 supports 1 enet MAC.
|
||||
*/
|
||||
#define AR5312_WLAN0_BASE 0x18000000
|
||||
#define AR5312_ENET0_BASE 0x18100000
|
||||
#define AR5312_ENET1_BASE 0x18200000
|
||||
#define AR5312_SDRAMCTL_BASE 0x18300000
|
||||
#define AR5312_SDRAMCTL_SIZE 0x00000010
|
||||
#define AR5312_FLASHCTL_BASE 0x18400000
|
||||
#define AR5312_FLASHCTL_SIZE 0x00000010
|
||||
#define AR5312_WLAN1_BASE 0x18500000
|
||||
#define AR5312_UART0_BASE 0x1c000000 /* UART MMR */
|
||||
#define AR5312_GPIO_BASE 0x1c002000
|
||||
#define AR5312_GPIO_SIZE 0x00000010
|
||||
#define AR5312_RST_BASE 0x1c003000
|
||||
#define AR5312_RST_SIZE 0x00000100
|
||||
#define AR5312_FLASH_BASE 0x1e000000
|
||||
#define AR5312_FLASH_SIZE 0x00800000
|
||||
|
||||
/*
|
||||
* Need these defines to determine true number of ethernet MACs
|
||||
*/
|
||||
#define AR5312_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */
|
||||
#define AR5312_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */
|
||||
#define AR5312_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */
|
||||
|
||||
/* Reset/Timer Block Address Map */
|
||||
#define AR5312_TIMER 0x0000 /* countdown timer */
|
||||
#define AR5312_RELOAD 0x0004 /* timer reload value */
|
||||
#define AR5312_WDT_CTRL 0x0008 /* watchdog cntrl */
|
||||
#define AR5312_WDT_TIMER 0x000c /* watchdog timer */
|
||||
#define AR5312_ISR 0x0010 /* Intr Status Reg */
|
||||
#define AR5312_IMR 0x0014 /* Intr Mask Reg */
|
||||
#define AR5312_RESET 0x0020
|
||||
#define AR5312_CLOCKCTL1 0x0064
|
||||
#define AR5312_SCRATCH 0x006c
|
||||
#define AR5312_PROCADDR 0x0070
|
||||
#define AR5312_PROC1 0x0074
|
||||
#define AR5312_DMAADDR 0x0078
|
||||
#define AR5312_DMA1 0x007c
|
||||
#define AR5312_ENABLE 0x0080 /* interface enb */
|
||||
#define AR5312_REV 0x0090 /* revision */
|
||||
|
||||
/* AR5312_WDT_CTRL register bit field definitions */
|
||||
#define AR5312_WDT_CTRL_IGNORE 0x00000000 /* ignore expiration */
|
||||
#define AR5312_WDT_CTRL_NMI 0x00000001
|
||||
#define AR5312_WDT_CTRL_RESET 0x00000002
|
||||
|
||||
/* AR5312_ISR register bit field definitions */
|
||||
#define AR5312_ISR_TIMER 0x00000001
|
||||
#define AR5312_ISR_AHBPROC 0x00000002
|
||||
#define AR5312_ISR_AHBDMA 0x00000004
|
||||
#define AR5312_ISR_GPIO 0x00000008
|
||||
#define AR5312_ISR_UART0 0x00000010
|
||||
#define AR5312_ISR_UART0DMA 0x00000020
|
||||
#define AR5312_ISR_WD 0x00000040
|
||||
#define AR5312_ISR_LOCAL 0x00000080
|
||||
|
||||
/* AR5312_RESET register bit field definitions */
|
||||
#define AR5312_RESET_SYSTEM 0x00000001 /* cold reset full system */
|
||||
#define AR5312_RESET_PROC 0x00000002 /* cold reset MIPS core */
|
||||
#define AR5312_RESET_WLAN0 0x00000004 /* cold reset WLAN MAC/BB */
|
||||
#define AR5312_RESET_EPHY0 0x00000008 /* cold reset ENET0 phy */
|
||||
#define AR5312_RESET_EPHY1 0x00000010 /* cold reset ENET1 phy */
|
||||
#define AR5312_RESET_ENET0 0x00000020 /* cold reset ENET0 MAC */
|
||||
#define AR5312_RESET_ENET1 0x00000040 /* cold reset ENET1 MAC */
|
||||
#define AR5312_RESET_UART0 0x00000100 /* cold reset UART0 */
|
||||
#define AR5312_RESET_WLAN1 0x00000200 /* cold reset WLAN MAC/BB */
|
||||
#define AR5312_RESET_APB 0x00000400 /* cold reset APB ar5312 */
|
||||
#define AR5312_RESET_WARM_PROC 0x00001000 /* warm reset MIPS core */
|
||||
#define AR5312_RESET_WARM_WLAN0_MAC 0x00002000 /* warm reset WLAN0 MAC */
|
||||
#define AR5312_RESET_WARM_WLAN0_BB 0x00004000 /* warm reset WLAN0 BB */
|
||||
#define AR5312_RESET_NMI 0x00010000 /* send an NMI to the CPU */
|
||||
#define AR5312_RESET_WARM_WLAN1_MAC 0x00020000 /* warm reset WLAN1 MAC */
|
||||
#define AR5312_RESET_WARM_WLAN1_BB 0x00040000 /* warm reset WLAN1 BB */
|
||||
#define AR5312_RESET_LOCAL_BUS 0x00080000 /* reset local bus */
|
||||
#define AR5312_RESET_WDOG 0x00100000 /* last reset was a wdt */
|
||||
|
||||
#define AR5312_RESET_WMAC0_BITS (AR5312_RESET_WLAN0 |\
|
||||
AR5312_RESET_WARM_WLAN0_MAC |\
|
||||
AR5312_RESET_WARM_WLAN0_BB)
|
||||
|
||||
#define AR5312_RESET_WMAC1_BITS (AR5312_RESET_WLAN1 |\
|
||||
AR5312_RESET_WARM_WLAN1_MAC |\
|
||||
AR5312_RESET_WARM_WLAN1_BB)
|
||||
|
||||
/* AR5312_CLOCKCTL1 register bit field definitions */
|
||||
#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030
|
||||
#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4
|
||||
#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00
|
||||
#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8
|
||||
#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000
|
||||
|
||||
/* Valid for AR5312 and AR2312 */
|
||||
#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030
|
||||
#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4
|
||||
#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00
|
||||
#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8
|
||||
#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000
|
||||
|
||||
/* Valid for AR2313 */
|
||||
#define AR2313_CLOCKCTL1_PREDIVIDE_MASK 0x00003000
|
||||
#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT 12
|
||||
#define AR2313_CLOCKCTL1_MULTIPLIER_MASK 0x001f0000
|
||||
#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT 16
|
||||
#define AR2313_CLOCKCTL1_DOUBLER_MASK 0x00000000
|
||||
|
||||
/* AR5312_ENABLE register bit field definitions */
|
||||
#define AR5312_ENABLE_WLAN0 0x00000001
|
||||
#define AR5312_ENABLE_ENET0 0x00000002
|
||||
#define AR5312_ENABLE_ENET1 0x00000004
|
||||
#define AR5312_ENABLE_UART_AND_WLAN1_PIO 0x00000008/* UART & WLAN1 PIO */
|
||||
#define AR5312_ENABLE_WLAN1_DMA 0x00000010/* WLAN1 DMAs */
|
||||
#define AR5312_ENABLE_WLAN1 (AR5312_ENABLE_UART_AND_WLAN1_PIO |\
|
||||
AR5312_ENABLE_WLAN1_DMA)
|
||||
|
||||
/* AR5312_REV register bit field definitions */
|
||||
#define AR5312_REV_WMAC_MAJ 0x0000f000
|
||||
#define AR5312_REV_WMAC_MAJ_S 12
|
||||
#define AR5312_REV_WMAC_MIN 0x00000f00
|
||||
#define AR5312_REV_WMAC_MIN_S 8
|
||||
#define AR5312_REV_MAJ 0x000000f0
|
||||
#define AR5312_REV_MAJ_S 4
|
||||
#define AR5312_REV_MIN 0x0000000f
|
||||
#define AR5312_REV_MIN_S 0
|
||||
#define AR5312_REV_CHIP (AR5312_REV_MAJ|AR5312_REV_MIN)
|
||||
|
||||
/* Major revision numbers, bits 7..4 of Revision ID register */
|
||||
#define AR5312_REV_MAJ_AR5312 0x4
|
||||
#define AR5312_REV_MAJ_AR2313 0x5
|
||||
|
||||
/* Minor revision numbers, bits 3..0 of Revision ID register */
|
||||
#define AR5312_REV_MIN_DUAL 0x0 /* Dual WLAN version */
|
||||
#define AR5312_REV_MIN_SINGLE 0x1 /* Single WLAN version */
|
||||
|
||||
/*
|
||||
* ARM Flash Controller -- 3 flash banks with either x8 or x16 devices
|
||||
*/
|
||||
#define AR5312_FLASHCTL0 0x0000
|
||||
#define AR5312_FLASHCTL1 0x0004
|
||||
#define AR5312_FLASHCTL2 0x0008
|
||||
|
||||
/* AR5312_FLASHCTL register bit field definitions */
|
||||
#define AR5312_FLASHCTL_IDCY 0x0000000f /* Idle cycle turnaround time */
|
||||
#define AR5312_FLASHCTL_IDCY_S 0
|
||||
#define AR5312_FLASHCTL_WST1 0x000003e0 /* Wait state 1 */
|
||||
#define AR5312_FLASHCTL_WST1_S 5
|
||||
#define AR5312_FLASHCTL_RBLE 0x00000400 /* Read byte lane enable */
|
||||
#define AR5312_FLASHCTL_WST2 0x0000f800 /* Wait state 2 */
|
||||
#define AR5312_FLASHCTL_WST2_S 11
|
||||
#define AR5312_FLASHCTL_AC 0x00070000 /* Flash addr check (added) */
|
||||
#define AR5312_FLASHCTL_AC_S 16
|
||||
#define AR5312_FLASHCTL_AC_128K 0x00000000
|
||||
#define AR5312_FLASHCTL_AC_256K 0x00010000
|
||||
#define AR5312_FLASHCTL_AC_512K 0x00020000
|
||||
#define AR5312_FLASHCTL_AC_1M 0x00030000
|
||||
#define AR5312_FLASHCTL_AC_2M 0x00040000
|
||||
#define AR5312_FLASHCTL_AC_4M 0x00050000
|
||||
#define AR5312_FLASHCTL_AC_8M 0x00060000
|
||||
#define AR5312_FLASHCTL_AC_RES 0x00070000 /* 16MB is not supported */
|
||||
#define AR5312_FLASHCTL_E 0x00080000 /* Flash bank enable (added) */
|
||||
#define AR5312_FLASHCTL_BUSERR 0x01000000 /* Bus transfer error flag */
|
||||
#define AR5312_FLASHCTL_WPERR 0x02000000 /* Write protect error flag */
|
||||
#define AR5312_FLASHCTL_WP 0x04000000 /* Write protect */
|
||||
#define AR5312_FLASHCTL_BM 0x08000000 /* Burst mode */
|
||||
#define AR5312_FLASHCTL_MW 0x30000000 /* Mem width */
|
||||
#define AR5312_FLASHCTL_MW8 0x00000000 /* Mem width x8 */
|
||||
#define AR5312_FLASHCTL_MW16 0x10000000 /* Mem width x16 */
|
||||
#define AR5312_FLASHCTL_MW32 0x20000000 /* Mem width x32 (not supp) */
|
||||
#define AR5312_FLASHCTL_ATNR 0x00000000 /* Access == no retry */
|
||||
#define AR5312_FLASHCTL_ATR 0x80000000 /* Access == retry every */
|
||||
#define AR5312_FLASHCTL_ATR4 0xc0000000 /* Access == retry every 4 */
|
||||
|
||||
/*
|
||||
* ARM SDRAM Controller -- just enough to determine memory size
|
||||
*/
|
||||
#define AR5312_MEM_CFG1 0x0004
|
||||
|
||||
#define AR5312_MEM_CFG1_AC0_M 0x00000700 /* bank 0: SDRAM addr check */
|
||||
#define AR5312_MEM_CFG1_AC0_S 8
|
||||
#define AR5312_MEM_CFG1_AC1_M 0x00007000 /* bank 1: SDRAM addr check */
|
||||
#define AR5312_MEM_CFG1_AC1_S 12
|
||||
|
||||
#endif /* __ASM_MACH_ATH25_AR5312_REGS_H */
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* 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) 2003 Atheros Communications, Inc., All Rights Reserved.
|
||||
* Copyright (C) 2006 FON Technology, SL.
|
||||
* Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
|
||||
* Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <asm/irq_cpu.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#include <ath25_platform.h>
|
||||
#include "devices.h"
|
||||
#include "ar5312.h"
|
||||
#include "ar2315.h"
|
||||
|
||||
void (*ath25_irq_dispatch)(void);
|
||||
|
||||
static inline bool check_radio_magic(const void __iomem *addr)
|
||||
{
|
||||
addr += 0x7a; /* offset for flash magic */
|
||||
return (__raw_readb(addr) == 0x5a) && (__raw_readb(addr + 1) == 0xa5);
|
||||
}
|
||||
|
||||
static inline bool check_notempty(const void __iomem *addr)
|
||||
{
|
||||
return __raw_readl(addr) != 0xffffffff;
|
||||
}
|
||||
|
||||
static inline bool check_board_data(const void __iomem *addr, bool broken)
|
||||
{
|
||||
/* config magic found */
|
||||
if (__raw_readl(addr) == ATH25_BD_MAGIC)
|
||||
return true;
|
||||
|
||||
if (!broken)
|
||||
return false;
|
||||
|
||||
/* broken board data detected, use radio data to find the
|
||||
* offset, user will fix this */
|
||||
|
||||
if (check_radio_magic(addr + 0x1000))
|
||||
return true;
|
||||
if (check_radio_magic(addr + 0xf8))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const void __iomem * __init find_board_config(const void __iomem *limit,
|
||||
const bool broken)
|
||||
{
|
||||
const void __iomem *addr;
|
||||
const void __iomem *begin = limit - 0x1000;
|
||||
const void __iomem *end = limit - 0x30000;
|
||||
|
||||
for (addr = begin; addr >= end; addr -= 0x1000)
|
||||
if (check_board_data(addr, broken))
|
||||
return addr;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const void __iomem * __init find_radio_config(const void __iomem *limit,
|
||||
const void __iomem *bcfg)
|
||||
{
|
||||
const void __iomem *rcfg, *begin, *end;
|
||||
|
||||
/*
|
||||
* Now find the start of Radio Configuration data, using heuristics:
|
||||
* Search forward from Board Configuration data by 0x1000 bytes
|
||||
* at a time until we find non-0xffffffff.
|
||||
*/
|
||||
begin = bcfg + 0x1000;
|
||||
end = limit;
|
||||
for (rcfg = begin; rcfg < end; rcfg += 0x1000)
|
||||
if (check_notempty(rcfg) && check_radio_magic(rcfg))
|
||||
return rcfg;
|
||||
|
||||
/* AR2316 relocates radio config to new location */
|
||||
begin = bcfg + 0xf8;
|
||||
end = limit - 0x1000 + 0xf8;
|
||||
for (rcfg = begin; rcfg < end; rcfg += 0x1000)
|
||||
if (check_notempty(rcfg) && check_radio_magic(rcfg))
|
||||
return rcfg;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* NB: Search region size could be larger than the actual flash size,
|
||||
* but this shouldn't be a problem here, because the flash
|
||||
* will simply be mapped multiple times.
|
||||
*/
|
||||
int __init ath25_find_config(phys_addr_t base, unsigned long size)
|
||||
{
|
||||
const void __iomem *flash_base, *flash_limit;
|
||||
struct ath25_boarddata *config;
|
||||
unsigned int rcfg_size;
|
||||
int broken_boarddata = 0;
|
||||
const void __iomem *bcfg, *rcfg;
|
||||
u8 *board_data;
|
||||
u8 *radio_data;
|
||||
u8 *mac_addr;
|
||||
u32 offset;
|
||||
|
||||
flash_base = ioremap_nocache(base, size);
|
||||
flash_limit = flash_base + size;
|
||||
|
||||
ath25_board.config = NULL;
|
||||
ath25_board.radio = NULL;
|
||||
|
||||
/* Copy the board and radio data to RAM, because accessing the mapped
|
||||
* memory of the flash directly after booting is not safe */
|
||||
|
||||
/* Try to find valid board and radio data */
|
||||
bcfg = find_board_config(flash_limit, false);
|
||||
|
||||
/* If that fails, try to at least find valid radio data */
|
||||
if (!bcfg) {
|
||||
bcfg = find_board_config(flash_limit, true);
|
||||
broken_boarddata = 1;
|
||||
}
|
||||
|
||||
if (!bcfg) {
|
||||
pr_warn("WARNING: No board configuration data found!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
board_data = kzalloc(BOARD_CONFIG_BUFSZ, GFP_KERNEL);
|
||||
ath25_board.config = (struct ath25_boarddata *)board_data;
|
||||
memcpy_fromio(board_data, bcfg, 0x100);
|
||||
if (broken_boarddata) {
|
||||
pr_warn("WARNING: broken board data detected\n");
|
||||
config = ath25_board.config;
|
||||
if (is_zero_ether_addr(config->enet0_mac)) {
|
||||
pr_info("Fixing up empty mac addresses\n");
|
||||
config->reset_config_gpio = 0xffff;
|
||||
config->sys_led_gpio = 0xffff;
|
||||
random_ether_addr(config->wlan0_mac);
|
||||
config->wlan0_mac[0] &= ~0x06;
|
||||
random_ether_addr(config->enet0_mac);
|
||||
random_ether_addr(config->enet1_mac);
|
||||
}
|
||||
}
|
||||
|
||||
/* Radio config starts 0x100 bytes after board config, regardless
|
||||
* of what the physical layout on the flash chip looks like */
|
||||
|
||||
rcfg = find_radio_config(flash_limit, bcfg);
|
||||
if (!rcfg) {
|
||||
pr_warn("WARNING: Could not find Radio Configuration data\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
radio_data = board_data + 0x100 + ((rcfg - bcfg) & 0xfff);
|
||||
ath25_board.radio = radio_data;
|
||||
offset = radio_data - board_data;
|
||||
pr_info("Radio config found at offset 0x%x (0x%x)\n", rcfg - bcfg,
|
||||
offset);
|
||||
rcfg_size = BOARD_CONFIG_BUFSZ - offset;
|
||||
memcpy_fromio(radio_data, rcfg, rcfg_size);
|
||||
|
||||
mac_addr = &radio_data[0x1d * 2];
|
||||
if (is_broadcast_ether_addr(mac_addr)) {
|
||||
pr_info("Radio MAC is blank; using board-data\n");
|
||||
ether_addr_copy(mac_addr, ath25_board.config->wlan0_mac);
|
||||
}
|
||||
|
||||
iounmap(flash_base);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
iounmap(flash_base);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void ath25_halt(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
unreachable();
|
||||
}
|
||||
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
_machine_halt = ath25_halt;
|
||||
pm_power_off = ath25_halt;
|
||||
|
||||
if (is_ar5312())
|
||||
ar5312_plat_mem_setup();
|
||||
else
|
||||
ar2315_plat_mem_setup();
|
||||
|
||||
/* Disable data watchpoints */
|
||||
write_c0_watchlo0(0);
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(void)
|
||||
{
|
||||
ath25_irq_dispatch();
|
||||
}
|
||||
|
||||
void __init plat_time_init(void)
|
||||
{
|
||||
if (is_ar5312())
|
||||
ar5312_plat_time_init();
|
||||
else
|
||||
ar2315_plat_time_init();
|
||||
}
|
||||
|
||||
unsigned int __cpuinit get_c0_compare_int(void)
|
||||
{
|
||||
return CP0_LEGACY_COMPARE_IRQ;
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
clear_c0_status(ST0_IM);
|
||||
mips_cpu_irq_init();
|
||||
|
||||
/* Initialize interrupt controllers */
|
||||
if (is_ar5312())
|
||||
ar5312_arch_init_irq();
|
||||
else
|
||||
ar2315_arch_init_irq();
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/bootinfo.h>
|
||||
|
||||
#include <ath25_platform.h>
|
||||
#include "devices.h"
|
||||
#include "ar5312.h"
|
||||
#include "ar2315.h"
|
||||
|
||||
struct ar231x_board_config ath25_board;
|
||||
enum ath25_soc_type ath25_soc = ATH25_SOC_UNKNOWN;
|
||||
|
||||
static struct resource ath25_wmac0_res[] = {
|
||||
{
|
||||
.name = "wmac0_membase",
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "wmac0_irq",
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
static struct resource ath25_wmac1_res[] = {
|
||||
{
|
||||
.name = "wmac1_membase",
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "wmac1_irq",
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device ath25_wmac[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.name = "ar231x-wmac",
|
||||
.resource = ath25_wmac0_res,
|
||||
.num_resources = ARRAY_SIZE(ath25_wmac0_res),
|
||||
.dev.platform_data = &ath25_board,
|
||||
},
|
||||
{
|
||||
.id = 1,
|
||||
.name = "ar231x-wmac",
|
||||
.resource = ath25_wmac1_res,
|
||||
.num_resources = ARRAY_SIZE(ath25_wmac1_res),
|
||||
.dev.platform_data = &ath25_board,
|
||||
},
|
||||
};
|
||||
|
||||
static const char * const soc_type_strings[] = {
|
||||
[ATH25_SOC_AR5312] = "Atheros AR5312",
|
||||
[ATH25_SOC_AR2312] = "Atheros AR2312",
|
||||
[ATH25_SOC_AR2313] = "Atheros AR2313",
|
||||
[ATH25_SOC_AR2315] = "Atheros AR2315",
|
||||
[ATH25_SOC_AR2316] = "Atheros AR2316",
|
||||
[ATH25_SOC_AR2317] = "Atheros AR2317",
|
||||
[ATH25_SOC_AR2318] = "Atheros AR2318",
|
||||
[ATH25_SOC_UNKNOWN] = "Atheros (unknown)",
|
||||
};
|
||||
|
||||
const char *get_system_type(void)
|
||||
{
|
||||
if ((ath25_soc >= ARRAY_SIZE(soc_type_strings)) ||
|
||||
!soc_type_strings[ath25_soc])
|
||||
return soc_type_strings[ATH25_SOC_UNKNOWN];
|
||||
return soc_type_strings[ath25_soc];
|
||||
}
|
||||
|
||||
void __init ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk)
|
||||
{
|
||||
struct uart_port s;
|
||||
|
||||
memset(&s, 0, sizeof(s));
|
||||
|
||||
s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP;
|
||||
s.iotype = UPIO_MEM32;
|
||||
s.irq = irq;
|
||||
s.regshift = 2;
|
||||
s.mapbase = mapbase;
|
||||
s.uartclk = uartclk;
|
||||
|
||||
early_serial_setup(&s);
|
||||
}
|
||||
|
||||
int __init ath25_add_wmac(int nr, u32 base, int irq)
|
||||
{
|
||||
struct resource *res;
|
||||
|
||||
ath25_wmac[nr].dev.platform_data = &ath25_board;
|
||||
res = &ath25_wmac[nr].resource[0];
|
||||
res->start = base;
|
||||
res->end = base + 0x10000 - 1;
|
||||
res++;
|
||||
res->start = irq;
|
||||
res->end = irq;
|
||||
return platform_device_register(&ath25_wmac[nr]);
|
||||
}
|
||||
|
||||
static int __init ath25_register_devices(void)
|
||||
{
|
||||
if (is_ar5312())
|
||||
ar5312_init_devices();
|
||||
else
|
||||
ar2315_init_devices();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(ath25_register_devices);
|
||||
|
||||
static int __init ath25_arch_init(void)
|
||||
{
|
||||
if (is_ar5312())
|
||||
ar5312_arch_init();
|
||||
else
|
||||
ar2315_arch_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(ath25_arch_init);
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef __ATH25_DEVICES_H
|
||||
#define __ATH25_DEVICES_H
|
||||
|
||||
#include <linux/cpu.h>
|
||||
|
||||
#define ATH25_REG_MS(_val, _field) (((_val) & _field##_M) >> _field##_S)
|
||||
|
||||
#define ATH25_IRQ_CPU_CLOCK (MIPS_CPU_IRQ_BASE + 7) /* C0_CAUSE: 0x8000 */
|
||||
|
||||
enum ath25_soc_type {
|
||||
/* handled by ar5312.c */
|
||||
ATH25_SOC_AR2312,
|
||||
ATH25_SOC_AR2313,
|
||||
ATH25_SOC_AR5312,
|
||||
|
||||
/* handled by ar2315.c */
|
||||
ATH25_SOC_AR2315,
|
||||
ATH25_SOC_AR2316,
|
||||
ATH25_SOC_AR2317,
|
||||
ATH25_SOC_AR2318,
|
||||
|
||||
ATH25_SOC_UNKNOWN
|
||||
};
|
||||
|
||||
extern enum ath25_soc_type ath25_soc;
|
||||
extern struct ar231x_board_config ath25_board;
|
||||
extern void (*ath25_irq_dispatch)(void);
|
||||
|
||||
int ath25_find_config(phys_addr_t offset, unsigned long size);
|
||||
void ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk);
|
||||
int ath25_add_wmac(int nr, u32 base, int irq);
|
||||
|
||||
static inline bool is_ar2315(void)
|
||||
{
|
||||
return (current_cpu_data.cputype == CPU_4KEC);
|
||||
}
|
||||
|
||||
static inline bool is_ar5312(void)
|
||||
{
|
||||
return !is_ar2315();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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) 2010 Gabor Juhos <juhosg@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/serial_reg.h>
|
||||
|
||||
#include "devices.h"
|
||||
#include "ar2315_regs.h"
|
||||
#include "ar5312_regs.h"
|
||||
|
||||
static inline void prom_uart_wr(void __iomem *base, unsigned reg,
|
||||
unsigned char ch)
|
||||
{
|
||||
__raw_writel(ch, base + 4 * reg);
|
||||
}
|
||||
|
||||
static inline unsigned char prom_uart_rr(void __iomem *base, unsigned reg)
|
||||
{
|
||||
return __raw_readl(base + 4 * reg);
|
||||
}
|
||||
|
||||
void prom_putchar(unsigned char ch)
|
||||
{
|
||||
static void __iomem *base;
|
||||
|
||||
if (unlikely(base == NULL)) {
|
||||
if (is_ar2315())
|
||||
base = (void __iomem *)(KSEG1ADDR(AR2315_UART0_BASE));
|
||||
else
|
||||
base = (void __iomem *)(KSEG1ADDR(AR5312_UART0_BASE));
|
||||
}
|
||||
|
||||
while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0)
|
||||
;
|
||||
prom_uart_wr(base, UART_TX, ch);
|
||||
while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0)
|
||||
;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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 MontaVista Software Inc
|
||||
* Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
|
||||
* Copyright (C) 2006 FON Technology, SL.
|
||||
* Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
|
||||
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Prom setup file for AR5312/AR231x SoCs
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <asm/bootinfo.h>
|
||||
|
||||
void __init prom_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void __init prom_free_prom_memory(void)
|
||||
{
|
||||
}
|
|
@ -359,7 +359,6 @@ void __init arch_init_irq(void)
|
|||
BUG();
|
||||
}
|
||||
|
||||
cp0_perfcount_irq = ATH79_MISC_IRQ(5);
|
||||
mips_cpu_irq_init();
|
||||
ath79_misc_irq_init();
|
||||
|
||||
|
|
|
@ -13,42 +13,24 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/initrd.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/fw/fw.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static inline int is_valid_ram_addr(void *addr)
|
||||
{
|
||||
if (((u32) addr > KSEG0) &&
|
||||
((u32) addr < (KSEG0 + ATH79_MEM_SIZE_MAX)))
|
||||
return 1;
|
||||
|
||||
if (((u32) addr > KSEG1) &&
|
||||
((u32) addr < (KSEG1 + ATH79_MEM_SIZE_MAX)))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __init void ath79_prom_init_cmdline(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!is_valid_ram_addr(argv))
|
||||
return;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
if (is_valid_ram_addr(argv[i])) {
|
||||
strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
|
||||
strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline));
|
||||
}
|
||||
}
|
||||
|
||||
void __init prom_init(void)
|
||||
{
|
||||
ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1);
|
||||
fw_init_cmdline();
|
||||
|
||||
/* Read the initrd address from the firmware environment */
|
||||
initrd_start = fw_getenvl("initrd_start");
|
||||
if (initrd_start) {
|
||||
initrd_start = KSEG0ADDR(initrd_start);
|
||||
initrd_end = initrd_start + fw_getenvl("initrd_size");
|
||||
}
|
||||
}
|
||||
|
||||
void __init prom_free_prom_memory(void)
|
||||
|
|
|
@ -182,6 +182,11 @@ const char *get_system_type(void)
|
|||
return ath79_sys_type;
|
||||
}
|
||||
|
||||
int get_c0_perfcount_int(void)
|
||||
{
|
||||
return ATH79_MISC_IRQ(5);
|
||||
}
|
||||
|
||||
unsigned int get_c0_compare_int(void)
|
||||
{
|
||||
return CP0_LEGACY_COMPARE_IRQ;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
obj-y += setup.o irq.o dma.o
|
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Broadcom BCM3384 boards
|
||||
#
|
||||
platform-$(CONFIG_BCM3384) += bcm3384/
|
||||
cflags-$(CONFIG_BCM3384) += \
|
||||
-I$(srctree)/arch/mips/include/asm/mach-bcm3384/
|
||||
load-$(CONFIG_BCM3384) := 0xffffffff80010000
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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) 2014 Kevin Cernekee <cernekee@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-direction.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/types.h>
|
||||
#include <dma-coherence.h>
|
||||
|
||||
/*
|
||||
* BCM3384 has configurable address translation windows which allow the
|
||||
* peripherals' DMA addresses to be different from the Zephyr-visible
|
||||
* physical addresses. e.g. usb_dma_addr = zephyr_pa ^ 0x08000000
|
||||
*
|
||||
* If our DT "memory" node has a "dma-xor-mask" property we will enable this
|
||||
* translation using the provided offset.
|
||||
*/
|
||||
static u32 bcm3384_dma_xor_mask;
|
||||
static u32 bcm3384_dma_xor_limit = 0xffffffff;
|
||||
|
||||
/*
|
||||
* PCI collapses the memory hole at 0x10000000 - 0x1fffffff.
|
||||
* On systems with a dma-xor-mask, this range is guaranteed to live above
|
||||
* the dma-xor-limit.
|
||||
*/
|
||||
#define BCM3384_MEM_HOLE_PA 0x10000000
|
||||
#define BCM3384_MEM_HOLE_SIZE 0x10000000
|
||||
|
||||
static dma_addr_t bcm3384_phys_to_dma(struct device *dev, phys_addr_t pa)
|
||||
{
|
||||
if (dev && dev_is_pci(dev) &&
|
||||
pa >= (BCM3384_MEM_HOLE_PA + BCM3384_MEM_HOLE_SIZE))
|
||||
return pa - BCM3384_MEM_HOLE_SIZE;
|
||||
if (pa <= bcm3384_dma_xor_limit)
|
||||
return pa ^ bcm3384_dma_xor_mask;
|
||||
return pa;
|
||||
}
|
||||
|
||||
dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
|
||||
{
|
||||
return bcm3384_phys_to_dma(dev, virt_to_phys(addr));
|
||||
}
|
||||
|
||||
dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
|
||||
{
|
||||
return bcm3384_phys_to_dma(dev, page_to_phys(page));
|
||||
}
|
||||
|
||||
unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr)
|
||||
{
|
||||
if (dev && dev_is_pci(dev) &&
|
||||
dma_addr >= BCM3384_MEM_HOLE_PA)
|
||||
return dma_addr + BCM3384_MEM_HOLE_SIZE;
|
||||
if ((dma_addr ^ bcm3384_dma_xor_mask) <= bcm3384_dma_xor_limit)
|
||||
return dma_addr ^ bcm3384_dma_xor_mask;
|
||||
return dma_addr;
|
||||
}
|
||||
|
||||
static int __init bcm3384_init_dma_xor(void)
|
||||
{
|
||||
struct device_node *np = of_find_node_by_type(NULL, "memory");
|
||||
|
||||
if (!np)
|
||||
return 0;
|
||||
|
||||
of_property_read_u32(np, "dma-xor-mask", &bcm3384_dma_xor_mask);
|
||||
of_property_read_u32(np, "dma-xor-limit", &bcm3384_dma_xor_limit);
|
||||
|
||||
of_node_put(np);
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(bcm3384_init_dma_xor);
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* Partially based on arch/mips/ralink/irq.c
|
||||
*
|
||||
* Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/bmips.h>
|
||||
#include <asm/irq_cpu.h>
|
||||
#include <asm/mipsregs.h>
|
||||
|
||||
/* INTC register offsets */
|
||||
#define INTC_REG_ENABLE 0x00
|
||||
#define INTC_REG_STATUS 0x04
|
||||
|
||||
#define MAX_WORDS 2
|
||||
#define IRQS_PER_WORD 32
|
||||
|
||||
struct bcm3384_intc {
|
||||
int n_words;
|
||||
void __iomem *reg[MAX_WORDS];
|
||||
u32 enable[MAX_WORDS];
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
static void bcm3384_intc_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct bcm3384_intc *priv = d->domain->host_data;
|
||||
unsigned long flags;
|
||||
int idx = d->hwirq / IRQS_PER_WORD;
|
||||
int bit = d->hwirq % IRQS_PER_WORD;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
priv->enable[idx] |= BIT(bit);
|
||||
__raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
static void bcm3384_intc_irq_mask(struct irq_data *d)
|
||||
{
|
||||
struct bcm3384_intc *priv = d->domain->host_data;
|
||||
unsigned long flags;
|
||||
int idx = d->hwirq / IRQS_PER_WORD;
|
||||
int bit = d->hwirq % IRQS_PER_WORD;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
priv->enable[idx] &= ~BIT(bit);
|
||||
__raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
static struct irq_chip bcm3384_intc_irq_chip = {
|
||||
.name = "INTC",
|
||||
.irq_unmask = bcm3384_intc_irq_unmask,
|
||||
.irq_mask = bcm3384_intc_irq_mask,
|
||||
.irq_mask_ack = bcm3384_intc_irq_mask,
|
||||
};
|
||||
|
||||
unsigned int get_c0_compare_int(void)
|
||||
{
|
||||
return CP0_LEGACY_COMPARE_IRQ;
|
||||
}
|
||||
|
||||
static void bcm3384_intc_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct irq_domain *domain = irq_get_handler_data(irq);
|
||||
struct bcm3384_intc *priv = domain->host_data;
|
||||
unsigned long flags;
|
||||
unsigned int idx;
|
||||
|
||||
for (idx = 0; idx < priv->n_words; idx++) {
|
||||
unsigned long pending;
|
||||
int hwirq;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
pending = __raw_readl(priv->reg[idx] + INTC_REG_STATUS) &
|
||||
priv->enable[idx];
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) {
|
||||
generic_handle_irq(irq_find_mapping(domain,
|
||||
hwirq + idx * IRQS_PER_WORD));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(void)
|
||||
{
|
||||
unsigned long pending =
|
||||
(read_c0_status() & read_c0_cause() & ST0_IM) >> STATUSB_IP0;
|
||||
int bit;
|
||||
|
||||
for_each_set_bit(bit, &pending, 8)
|
||||
do_IRQ(MIPS_CPU_IRQ_BASE + bit);
|
||||
}
|
||||
|
||||
static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
|
||||
{
|
||||
irq_set_chip_and_handler(irq, &bcm3384_intc_irq_chip, handle_level_irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops irq_domain_ops = {
|
||||
.xlate = irq_domain_xlate_onecell,
|
||||
.map = intc_map,
|
||||
};
|
||||
|
||||
static int __init ioremap_one_pair(struct bcm3384_intc *priv,
|
||||
struct device_node *node,
|
||||
int idx)
|
||||
{
|
||||
struct resource res;
|
||||
|
||||
if (of_address_to_resource(node, idx, &res))
|
||||
return 0;
|
||||
|
||||
if (request_mem_region(res.start, resource_size(&res),
|
||||
res.name) < 0)
|
||||
pr_err("Failed to request INTC register region\n");
|
||||
|
||||
priv->reg[idx] = ioremap_nocache(res.start, resource_size(&res));
|
||||
if (!priv->reg[idx])
|
||||
panic("Failed to ioremap INTC register range");
|
||||
|
||||
/* start up with everything masked before we hook the parent IRQ */
|
||||
__raw_writel(0, priv->reg[idx] + INTC_REG_ENABLE);
|
||||
priv->enable[idx] = 0;
|
||||
|
||||
return IRQS_PER_WORD;
|
||||
}
|
||||
|
||||
static int __init intc_of_init(struct device_node *node,
|
||||
struct device_node *parent)
|
||||
{
|
||||
struct irq_domain *domain;
|
||||
unsigned int parent_irq, n_irqs = 0;
|
||||
struct bcm3384_intc *priv;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
panic("Failed to allocate bcm3384_intc struct");
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
|
||||
parent_irq = irq_of_parse_and_map(node, 0);
|
||||
if (!parent_irq)
|
||||
panic("Failed to get INTC IRQ");
|
||||
|
||||
n_irqs += ioremap_one_pair(priv, node, 0);
|
||||
n_irqs += ioremap_one_pair(priv, node, 1);
|
||||
|
||||
if (!n_irqs)
|
||||
panic("Failed to map INTC registers");
|
||||
|
||||
priv->n_words = n_irqs / IRQS_PER_WORD;
|
||||
domain = irq_domain_add_linear(node, n_irqs, &irq_domain_ops, priv);
|
||||
if (!domain)
|
||||
panic("Failed to add irqdomain");
|
||||
|
||||
irq_set_chained_handler(parent_irq, bcm3384_intc_irq_handler);
|
||||
irq_set_handler_data(parent_irq, domain);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id of_irq_ids[] __initdata = {
|
||||
{ .compatible = "mti,cpu-interrupt-controller",
|
||||
.data = mips_cpu_intc_init },
|
||||
{ .compatible = "brcm,bcm3384-intc",
|
||||
.data = intc_of_init },
|
||||
{},
|
||||
};
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
bmips_tp1_irqs = 0;
|
||||
of_irq_init(of_irq_ids);
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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) 2008 Maxime Bizon <mbizon@freebox.fr>
|
||||
* Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/bmips.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/smp-ops.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
void __init prom_init(void)
|
||||
{
|
||||
register_bmips_smp_ops();
|
||||
}
|
||||
|
||||
void __init prom_free_prom_memory(void)
|
||||
{
|
||||
}
|
||||
|
||||
const char *get_system_type(void)
|
||||
{
|
||||
return "BCM3384";
|
||||
}
|
||||
|
||||
void __init plat_time_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
u32 freq;
|
||||
|
||||
np = of_find_node_by_name(NULL, "cpus");
|
||||
if (!np)
|
||||
panic("missing 'cpus' DT node");
|
||||
if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
|
||||
panic("missing 'mips-hpt-frequency' property");
|
||||
of_node_put(np);
|
||||
|
||||
mips_hpt_frequency = freq;
|
||||
}
|
||||
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
void *dtb = __dtb_start;
|
||||
|
||||
set_io_port_base(0);
|
||||
ioport_resource.start = 0;
|
||||
ioport_resource.end = ~0;
|
||||
|
||||
/* intended to somewhat resemble ARM; see Documentation/arm/Booting */
|
||||
if (fw_arg0 == 0 && fw_arg1 == 0xffffffff)
|
||||
dtb = phys_to_virt(fw_arg2);
|
||||
|
||||
__dt_setup_arch(dtb);
|
||||
|
||||
strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
|
||||
}
|
||||
|
||||
void __init device_tree_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
unflatten_and_copy_device_tree();
|
||||
|
||||
/* Disable SMP boot unless both CPUs are listed in DT and !disabled */
|
||||
np = of_find_node_by_name(NULL, "cpus");
|
||||
if (np && of_get_available_child_count(np) <= 1)
|
||||
bmips_smp_enabled = 0;
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
int __init plat_of_setup(void)
|
||||
{
|
||||
return __dt_register_buses("brcm,bcm3384", "simple-bus");
|
||||
}
|
||||
|
||||
arch_initcall(plat_of_setup);
|
||||
|
||||
static int __init plat_dev_init(void)
|
||||
{
|
||||
of_clk_init(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(plat_dev_init);
|
|
@ -6,12 +6,18 @@
|
|||
/* prom.c */
|
||||
void __init bcm47xx_prom_highmem_init(void);
|
||||
|
||||
/* sprom.c */
|
||||
void bcm47xx_sprom_register_fallbacks(void);
|
||||
|
||||
/* buttons.c */
|
||||
int __init bcm47xx_buttons_register(void);
|
||||
|
||||
/* leds.c */
|
||||
void __init bcm47xx_leds_register(void);
|
||||
|
||||
/* setup.c */
|
||||
void __init bcm47xx_bus_setup(void);
|
||||
|
||||
/* workarounds.c */
|
||||
void __init bcm47xx_workarounds(void);
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "bcm47xx_private.h"
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
|
@ -65,6 +67,12 @@ DEFINE_HWx_IRQDISPATCH(7)
|
|||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
/*
|
||||
* This is the first arch callback after mm_init (we can use kmalloc),
|
||||
* so let's finish bus initialization now.
|
||||
*/
|
||||
bcm47xx_bus_setup();
|
||||
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) {
|
||||
bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core,
|
||||
|
|
|
@ -13,24 +13,35 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ssb/ssb.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <bcm47xx_nvram.h>
|
||||
#include <asm/mach-bcm47xx/bcm47xx.h>
|
||||
|
||||
#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */
|
||||
#define NVRAM_SPACE 0x8000
|
||||
|
||||
#define FLASH_MIN 0x00020000 /* Minimum flash size */
|
||||
|
||||
struct nvram_header {
|
||||
u32 magic;
|
||||
u32 len;
|
||||
u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
|
||||
u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
|
||||
u32 config_ncdl; /* ncdl values for memc */
|
||||
};
|
||||
|
||||
static char nvram_buf[NVRAM_SPACE];
|
||||
static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000};
|
||||
|
||||
static u32 find_nvram_size(u32 end)
|
||||
static u32 find_nvram_size(void __iomem *end)
|
||||
{
|
||||
struct nvram_header *header;
|
||||
struct nvram_header __iomem *header;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
|
||||
header = (struct nvram_header *)KSEG1ADDR(end - nvram_sizes[i]);
|
||||
if (header->magic == NVRAM_HEADER)
|
||||
header = (struct nvram_header *)(end - nvram_sizes[i]);
|
||||
if (header->magic == NVRAM_MAGIC)
|
||||
return nvram_sizes[i];
|
||||
}
|
||||
|
||||
|
@ -38,36 +49,40 @@ static u32 find_nvram_size(u32 end)
|
|||
}
|
||||
|
||||
/* Probe for NVRAM header */
|
||||
static int nvram_find_and_copy(u32 base, u32 lim)
|
||||
static int nvram_find_and_copy(void __iomem *iobase, u32 lim)
|
||||
{
|
||||
struct nvram_header *header;
|
||||
struct nvram_header __iomem *header;
|
||||
int i;
|
||||
u32 off;
|
||||
u32 *src, *dst;
|
||||
u32 size;
|
||||
|
||||
if (nvram_buf[0]) {
|
||||
pr_warn("nvram already initialized\n");
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
/* TODO: when nvram is on nand flash check for bad blocks first. */
|
||||
off = FLASH_MIN;
|
||||
while (off <= lim) {
|
||||
/* Windowed flash access */
|
||||
size = find_nvram_size(base + off);
|
||||
size = find_nvram_size(iobase + off);
|
||||
if (size) {
|
||||
header = (struct nvram_header *)KSEG1ADDR(base + off -
|
||||
size);
|
||||
header = (struct nvram_header *)(iobase + off - size);
|
||||
goto found;
|
||||
}
|
||||
off <<= 1;
|
||||
}
|
||||
|
||||
/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
|
||||
header = (struct nvram_header *) KSEG1ADDR(base + 4096);
|
||||
if (header->magic == NVRAM_HEADER) {
|
||||
header = (struct nvram_header *)(iobase + 4096);
|
||||
if (header->magic == NVRAM_MAGIC) {
|
||||
size = NVRAM_SPACE;
|
||||
goto found;
|
||||
}
|
||||
|
||||
header = (struct nvram_header *) KSEG1ADDR(base + 1024);
|
||||
if (header->magic == NVRAM_HEADER) {
|
||||
header = (struct nvram_header *)(iobase + 1024);
|
||||
if (header->magic == NVRAM_MAGIC) {
|
||||
size = NVRAM_SPACE;
|
||||
goto found;
|
||||
}
|
||||
|
@ -94,71 +109,73 @@ found:
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
static int nvram_init_ssb(void)
|
||||
/*
|
||||
* On bcm47xx we need access to the NVRAM very early, so we can't use mtd
|
||||
* subsystem to access flash. We can't even use platform device / driver to
|
||||
* store memory offset.
|
||||
* To handle this we provide following symbol. It's supposed to be called as
|
||||
* soon as we get info about flash device, before any NVRAM entry is needed.
|
||||
*/
|
||||
int bcm47xx_nvram_init_from_mem(u32 base, u32 lim)
|
||||
{
|
||||
struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore;
|
||||
u32 base;
|
||||
u32 lim;
|
||||
void __iomem *iobase;
|
||||
int err;
|
||||
|
||||
if (mcore->pflash.present) {
|
||||
base = mcore->pflash.window;
|
||||
lim = mcore->pflash.window_size;
|
||||
} else {
|
||||
pr_err("Couldn't find supported flash memory\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
iobase = ioremap_nocache(base, lim);
|
||||
if (!iobase)
|
||||
return -ENOMEM;
|
||||
|
||||
return nvram_find_and_copy(base, lim);
|
||||
err = nvram_find_and_copy(iobase, lim);
|
||||
|
||||
iounmap(iobase);
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
static int nvram_init_bcma(void)
|
||||
{
|
||||
struct bcma_drv_cc *cc = &bcm47xx_bus.bcma.bus.drv_cc;
|
||||
u32 base;
|
||||
u32 lim;
|
||||
|
||||
#ifdef CONFIG_BCMA_NFLASH
|
||||
if (cc->nflash.boot) {
|
||||
base = BCMA_SOC_FLASH1;
|
||||
lim = BCMA_SOC_FLASH1_SZ;
|
||||
} else
|
||||
#endif
|
||||
if (cc->pflash.present) {
|
||||
base = cc->pflash.window;
|
||||
lim = cc->pflash.window_size;
|
||||
#ifdef CONFIG_BCMA_SFLASH
|
||||
} else if (cc->sflash.present) {
|
||||
base = cc->sflash.window;
|
||||
lim = cc->sflash.size;
|
||||
#endif
|
||||
} else {
|
||||
pr_err("Couldn't find supported flash memory\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return nvram_find_and_copy(base, lim);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int nvram_init(void)
|
||||
{
|
||||
switch (bcm47xx_bus_type) {
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
case BCM47XX_BUS_TYPE_SSB:
|
||||
return nvram_init_ssb();
|
||||
#endif
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
case BCM47XX_BUS_TYPE_BCMA:
|
||||
return nvram_init_bcma();
|
||||
#endif
|
||||
#ifdef CONFIG_MTD
|
||||
struct mtd_info *mtd;
|
||||
struct nvram_header header;
|
||||
size_t bytes_read;
|
||||
int err, i;
|
||||
|
||||
mtd = get_mtd_device_nm("nvram");
|
||||
if (IS_ERR(mtd))
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
|
||||
loff_t from = mtd->size - nvram_sizes[i];
|
||||
|
||||
if (from < 0)
|
||||
continue;
|
||||
|
||||
err = mtd_read(mtd, from, sizeof(header), &bytes_read,
|
||||
(uint8_t *)&header);
|
||||
if (!err && header.magic == NVRAM_MAGIC) {
|
||||
u8 *dst = (uint8_t *)nvram_buf;
|
||||
size_t len = header.len;
|
||||
|
||||
if (header.len > NVRAM_SPACE) {
|
||||
pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
|
||||
header.len, NVRAM_SPACE);
|
||||
len = NVRAM_SPACE;
|
||||
}
|
||||
|
||||
err = mtd_read(mtd, from, len, &bytes_read, dst);
|
||||
if (err)
|
||||
return err;
|
||||
memset(dst + bytes_read, 0x0, NVRAM_SPACE - bytes_read);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len)
|
||||
int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len)
|
||||
{
|
||||
char *var, *value, *end, *eq;
|
||||
int err;
|
||||
|
|
|
@ -102,23 +102,6 @@ static void bcm47xx_machine_halt(void)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
|
||||
{
|
||||
char prefix[10];
|
||||
|
||||
if (bus->bustype == SSB_BUSTYPE_PCI) {
|
||||
memset(out, 0, sizeof(struct ssb_sprom));
|
||||
snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
|
||||
bus->host_pci->bus->number + 1,
|
||||
PCI_SLOT(bus->host_pci->devfn));
|
||||
bcm47xx_fill_sprom(out, prefix, false);
|
||||
return 0;
|
||||
} else {
|
||||
printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int bcm47xx_get_invariants(struct ssb_bus *bus,
|
||||
struct ssb_init_invariants *iv)
|
||||
{
|
||||
|
@ -144,11 +127,6 @@ static void __init bcm47xx_register_ssb(void)
|
|||
char buf[100];
|
||||
struct ssb_mipscore *mcore;
|
||||
|
||||
err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb);
|
||||
if (err)
|
||||
printk(KERN_WARNING "bcm47xx: someone else already registered"
|
||||
" a ssb SPROM callback handler (err %d)\n", err);
|
||||
|
||||
err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE,
|
||||
bcm47xx_get_invariants);
|
||||
if (err)
|
||||
|
@ -171,56 +149,21 @@ static void __init bcm47xx_register_ssb(void)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
|
||||
{
|
||||
char prefix[10];
|
||||
struct bcma_device *core;
|
||||
|
||||
switch (bus->hosttype) {
|
||||
case BCMA_HOSTTYPE_PCI:
|
||||
memset(out, 0, sizeof(struct ssb_sprom));
|
||||
snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
|
||||
bus->host_pci->bus->number + 1,
|
||||
PCI_SLOT(bus->host_pci->devfn));
|
||||
bcm47xx_fill_sprom(out, prefix, false);
|
||||
return 0;
|
||||
case BCMA_HOSTTYPE_SOC:
|
||||
memset(out, 0, sizeof(struct ssb_sprom));
|
||||
core = bcma_find_core(bus, BCMA_CORE_80211);
|
||||
if (core) {
|
||||
snprintf(prefix, sizeof(prefix), "sb/%u/",
|
||||
core->core_index);
|
||||
bcm47xx_fill_sprom(out, prefix, true);
|
||||
} else {
|
||||
bcm47xx_fill_sprom(out, NULL, false);
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init bcm47xx_register_bcma(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma);
|
||||
if (err)
|
||||
pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err);
|
||||
|
||||
err = bcma_host_soc_register(&bcm47xx_bus.bcma);
|
||||
if (err)
|
||||
panic("Failed to register BCMA bus (err %d)", err);
|
||||
|
||||
err = bcma_host_soc_init(&bcm47xx_bus.bcma);
|
||||
if (err)
|
||||
panic("Failed to initialize BCMA bus (err %d)", err);
|
||||
|
||||
bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Memory setup is done in the early part of MIPS's arch_mem_init. It's supposed
|
||||
* to detect memory and record it with add_memory_region.
|
||||
* Any extra initializaion performed here must not use kmalloc or bootmem.
|
||||
*/
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
struct cpuinfo_mips *c = ¤t_cpu_data;
|
||||
|
@ -229,6 +172,7 @@ void __init plat_mem_setup(void)
|
|||
printk(KERN_INFO "bcm47xx: using bcma bus\n");
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
|
||||
bcm47xx_sprom_register_fallbacks();
|
||||
bcm47xx_register_bcma();
|
||||
bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
|
@ -239,6 +183,7 @@ void __init plat_mem_setup(void)
|
|||
printk(KERN_INFO "bcm47xx: using ssb bus\n");
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
|
||||
bcm47xx_sprom_register_fallbacks();
|
||||
bcm47xx_register_ssb();
|
||||
bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id);
|
||||
#endif
|
||||
|
@ -247,6 +192,28 @@ void __init plat_mem_setup(void)
|
|||
_machine_restart = bcm47xx_machine_restart;
|
||||
_machine_halt = bcm47xx_machine_halt;
|
||||
pm_power_off = bcm47xx_machine_halt;
|
||||
}
|
||||
|
||||
/*
|
||||
* This finishes bus initialization doing things that were not possible without
|
||||
* kmalloc. Make sure to call it late enough (after mm_init).
|
||||
*/
|
||||
void __init bcm47xx_bus_setup(void)
|
||||
{
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) {
|
||||
int err;
|
||||
|
||||
err = bcma_host_soc_init(&bcm47xx_bus.bcma);
|
||||
if (err)
|
||||
panic("Failed to initialize BCMA bus (err %d)", err);
|
||||
|
||||
bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo,
|
||||
NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* With bus initialized we can access NVRAM and detect the board */
|
||||
bcm47xx_board_detect();
|
||||
mips_set_machine_name(bcm47xx_board_get_name());
|
||||
}
|
||||
|
|
|
@ -136,6 +136,20 @@ static void nvram_read_leddc(const char *prefix, const char *name,
|
|||
*leddc_off_time = (val >> 16) & 0xff;
|
||||
}
|
||||
|
||||
static void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6])
|
||||
{
|
||||
if (strchr(buf, ':'))
|
||||
sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
|
||||
&macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
|
||||
&macaddr[5]);
|
||||
else if (strchr(buf, '-'))
|
||||
sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0],
|
||||
&macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
|
||||
&macaddr[5]);
|
||||
else
|
||||
pr_warn("Can not parse mac address: %s\n", buf);
|
||||
}
|
||||
|
||||
static void nvram_read_macaddr(const char *prefix, const char *name,
|
||||
u8 val[6], bool fallback)
|
||||
{
|
||||
|
@ -801,3 +815,71 @@ void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo,
|
|||
nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BCM47XX_SSB)
|
||||
static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
|
||||
{
|
||||
char prefix[10];
|
||||
|
||||
if (bus->bustype == SSB_BUSTYPE_PCI) {
|
||||
memset(out, 0, sizeof(struct ssb_sprom));
|
||||
snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
|
||||
bus->host_pci->bus->number + 1,
|
||||
PCI_SLOT(bus->host_pci->devfn));
|
||||
bcm47xx_fill_sprom(out, prefix, false);
|
||||
return 0;
|
||||
} else {
|
||||
pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BCM47XX_BCMA)
|
||||
static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
|
||||
{
|
||||
char prefix[10];
|
||||
struct bcma_device *core;
|
||||
|
||||
switch (bus->hosttype) {
|
||||
case BCMA_HOSTTYPE_PCI:
|
||||
memset(out, 0, sizeof(struct ssb_sprom));
|
||||
snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
|
||||
bus->host_pci->bus->number + 1,
|
||||
PCI_SLOT(bus->host_pci->devfn));
|
||||
bcm47xx_fill_sprom(out, prefix, false);
|
||||
return 0;
|
||||
case BCMA_HOSTTYPE_SOC:
|
||||
memset(out, 0, sizeof(struct ssb_sprom));
|
||||
core = bcma_find_core(bus, BCMA_CORE_80211);
|
||||
if (core) {
|
||||
snprintf(prefix, sizeof(prefix), "sb/%u/",
|
||||
core->core_index);
|
||||
bcm47xx_fill_sprom(out, prefix, true);
|
||||
} else {
|
||||
bcm47xx_fill_sprom(out, NULL, false);
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On bcm47xx we need to register SPROM fallback handler very early, so we can't
|
||||
* use anything like platform device / driver for this.
|
||||
*/
|
||||
void bcm47xx_sprom_register_fallbacks(void)
|
||||
{
|
||||
#if defined(CONFIG_BCM47XX_SSB)
|
||||
if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb))
|
||||
pr_warn("Failed to registered ssb SPROM handler\n");
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BCM47XX_BCMA)
|
||||
if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma))
|
||||
pr_warn("Failed to registered bcma SPROM handler\n");
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -263,7 +263,7 @@ static unsigned int detect_memory_size(void)
|
|||
|
||||
if (BCMCPU_IS_6345()) {
|
||||
val = bcm_sdram_readl(SDRAM_MBASE_REG);
|
||||
return (val * 8 * 1024 * 1024);
|
||||
return val * 8 * 1024 * 1024;
|
||||
}
|
||||
|
||||
if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
dtb-$(CONFIG_BCM3384) += bcm93384wvg.dtb
|
||||
dtb-$(CONFIG_CAVIUM_OCTEON_SOC) += octeon_3xxx.dtb octeon_68xx.dtb
|
||||
dtb-$(CONFIG_DT_EASY50712) += easy50712.dtb
|
||||
dtb-$(CONFIG_DT_XLP_EVP) += xlp_evp.dtb
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "brcm,bcm3384", "brcm,bcm33843";
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/* On BMIPS5000 this is 1/8th of the CPU core clock */
|
||||
mips-hpt-frequency = <100000000>;
|
||||
|
||||
cpu@0 {
|
||||
compatible = "brcm,bmips5000";
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
compatible = "brcm,bmips5000";
|
||||
device_type = "cpu";
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
clocks {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
periph_clk: periph_clk@0 {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <54000000>;
|
||||
};
|
||||
};
|
||||
|
||||
aliases {
|
||||
uart0 = &uart0;
|
||||
};
|
||||
|
||||
cpu_intc: cpu_intc@0 {
|
||||
#address-cells = <0>;
|
||||
compatible = "mti,cpu-interrupt-controller";
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
};
|
||||
|
||||
periph_intc: periph_intc@14e00038 {
|
||||
compatible = "brcm,bcm3384-intc";
|
||||
reg = <0x14e00038 0x8 0x14e00340 0x8>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interrupt-parent = <&cpu_intc>;
|
||||
interrupts = <4>;
|
||||
};
|
||||
|
||||
zmips_intc: zmips_intc@104b0060 {
|
||||
compatible = "brcm,bcm3384-intc";
|
||||
reg = <0x104b0060 0x8>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <29>;
|
||||
};
|
||||
|
||||
iop_intc: iop_intc@14e00058 {
|
||||
compatible = "brcm,bcm3384-intc";
|
||||
reg = <0x14e00058 0x8>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interrupt-parent = <&cpu_intc>;
|
||||
interrupts = <6>;
|
||||
};
|
||||
|
||||
uart0: serial@14e00520 {
|
||||
compatible = "brcm,bcm6345-uart";
|
||||
reg = <0x14e00520 0x18>;
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <2>;
|
||||
clocks = <&periph_clk>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ehci0: usb@15400300 {
|
||||
compatible = "brcm,bcm3384-ehci", "generic-ehci";
|
||||
reg = <0x15400300 0x100>;
|
||||
big-endian;
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <41>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ohci0: usb@15400400 {
|
||||
compatible = "brcm,bcm3384-ohci", "generic-ohci";
|
||||
reg = <0x15400400 0x100>;
|
||||
big-endian;
|
||||
no-big-frame-no;
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <40>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
/dts-v1/;
|
||||
|
||||
/include/ "bcm3384.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "brcm,bcm93384wvg", "brcm,bcm3384";
|
||||
model = "Broadcom BCM93384WVG";
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttyS0,115200";
|
||||
stdout-path = &uart0;
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x04000000>;
|
||||
dma-xor-mask = <0x08000000>;
|
||||
dma-xor-limit = <0x0fffffff>;
|
||||
};
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ehci0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ohci0 {
|
||||
status = "okay";
|
||||
};
|
|
@ -262,8 +262,8 @@ char *octeon_swiotlb;
|
|||
void __init plat_swiotlb_setup(void)
|
||||
{
|
||||
int i;
|
||||
phys_t max_addr;
|
||||
phys_t addr_size;
|
||||
phys_addr_t max_addr;
|
||||
phys_addr_t addr_size;
|
||||
size_t swiotlbsize;
|
||||
unsigned long swiotlb_nslabs;
|
||||
|
||||
|
|
|
@ -28,22 +28,23 @@
|
|||
#include <asm/octeon/octeon.h>
|
||||
|
||||
/**
|
||||
* Given the chip processor ID from COP0, this function returns a
|
||||
* string representing the chip model number. The string is of the
|
||||
* form CNXXXXpX.X-FREQ-SUFFIX.
|
||||
* - XXXX = The chip model number
|
||||
* - X.X = Chip pass number
|
||||
* - FREQ = Current frequency in Mhz
|
||||
* - SUFFIX = NSP, EXP, SCP, SSP, or CP
|
||||
* Read a byte of fuse data
|
||||
* @byte_addr: address to read
|
||||
*
|
||||
* @chip_id: Chip ID
|
||||
*
|
||||
* Returns Model string
|
||||
* Returns fuse value: 0 or 1
|
||||
*/
|
||||
const char *octeon_model_get_string(uint32_t chip_id)
|
||||
static uint8_t __init cvmx_fuse_read_byte(int byte_addr)
|
||||
{
|
||||
static char buffer[32];
|
||||
return octeon_model_get_string_buffer(chip_id, buffer);
|
||||
union cvmx_mio_fus_rcmd read_cmd;
|
||||
|
||||
read_cmd.u64 = 0;
|
||||
read_cmd.s.addr = byte_addr;
|
||||
read_cmd.s.pend = 1;
|
||||
cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64);
|
||||
while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD))
|
||||
&& read_cmd.s.pend)
|
||||
;
|
||||
return read_cmd.s.dat;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -51,7 +52,8 @@ const char *octeon_model_get_string(uint32_t chip_id)
|
|||
* as running early in u-boot static/global variables don't work when
|
||||
* running from flash.
|
||||
*/
|
||||
const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
|
||||
static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
|
||||
char *buffer)
|
||||
{
|
||||
const char *family;
|
||||
const char *core_model;
|
||||
|
@ -407,3 +409,22 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
|
|||
sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the chip processor ID from COP0, this function returns a
|
||||
* string representing the chip model number. The string is of the
|
||||
* form CNXXXXpX.X-FREQ-SUFFIX.
|
||||
* - XXXX = The chip model number
|
||||
* - X.X = Chip pass number
|
||||
* - FREQ = Current frequency in Mhz
|
||||
* - SUFFIX = NSP, EXP, SCP, SSP, or CP
|
||||
*
|
||||
* @chip_id: Chip ID
|
||||
*
|
||||
* Returns Model string
|
||||
*/
|
||||
const char *__init octeon_model_get_string(uint32_t chip_id)
|
||||
{
|
||||
static char buffer[32];
|
||||
return octeon_model_get_string_buffer(chip_id, buffer);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
CONFIG_BCM3384=y
|
||||
CONFIG_HIGHMEM=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_NR_CPUS=4
|
||||
# CONFIG_SECCOMP is not set
|
||||
CONFIG_MIPS_O32_FP64_SUPPORT=y
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
# CONFIG_SWAP is not set
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_RD_GZIP is not set
|
||||
CONFIG_EXPERT=y
|
||||
# CONFIG_VM_EVENT_COUNTERS is not set
|
||||
# CONFIG_SLUB_DEBUG is not set
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_PACKET_DIAG=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=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_CFG80211=y
|
||||
CONFIG_NL80211_TESTMODE=y
|
||||
CONFIG_MAC80211=y
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
# CONFIG_STANDALONE is not set
|
||||
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_CFI=y
|
||||
CONFIG_MTD_CFI_INTELEXT=y
|
||||
CONFIG_MTD_CFI_AMDSTD=y
|
||||
CONFIG_MTD_PHYSMAP=y
|
||||
# CONFIG_BLK_DEV is not set
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
# CONFIG_SCSI_LOWLEVEL is not set
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_USB_USBNET=y
|
||||
# CONFIG_INPUT is not set
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_DEVKMEM is not set
|
||||
CONFIG_SERIAL_EARLYCON_FORCE=y
|
||||
CONFIG_SERIAL_BCM63XX=y
|
||||
CONFIG_SERIAL_BCM63XX_CONSOLE=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_CIFS=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ASCII=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
# CONFIG_CRYPTO_HW is not set
|
|
@ -68,7 +68,7 @@ char *fw_getenv(char *envname)
|
|||
result = fw_envp(index + 1);
|
||||
break;
|
||||
} else if (fw_envp(index)[i] == '=') {
|
||||
result = (fw_envp(index + 1) + i);
|
||||
result = fw_envp(index) + i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -88,13 +88,13 @@ unsigned long fw_getenvl(char *envname)
|
|||
{
|
||||
unsigned long envl = 0UL;
|
||||
char *str;
|
||||
long val;
|
||||
int tmp;
|
||||
|
||||
str = fw_getenv(envname);
|
||||
if (str) {
|
||||
tmp = kstrtol(str, 0, &val);
|
||||
envl = (unsigned long)val;
|
||||
tmp = kstrtoul(str, 0, &envl);
|
||||
if (tmp)
|
||||
envl = 0;
|
||||
}
|
||||
|
||||
return envl;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/irqflags.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/compiler.h>
|
||||
#include <asm/cpu-features.h>
|
||||
#include <asm/cmpxchg.h>
|
||||
#include <asm/war.h>
|
||||
|
@ -40,95 +41,97 @@
|
|||
*/
|
||||
#define atomic_set(v, i) ((v)->counter = (i))
|
||||
|
||||
#define ATOMIC_OP(op, c_op, asm_op) \
|
||||
static __inline__ void atomic_##op(int i, atomic_t * v) \
|
||||
{ \
|
||||
if (kernel_uses_llsc && R10000_LLSC_WAR) { \
|
||||
int temp; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
"1: ll %0, %1 # atomic_" #op " \n" \
|
||||
" " #asm_op " %0, %2 \n" \
|
||||
" sc %0, %1 \n" \
|
||||
" beqzl %0, 1b \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (temp), "+m" (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} else if (kernel_uses_llsc) { \
|
||||
int temp; \
|
||||
\
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
" ll %0, %1 # atomic_" #op "\n" \
|
||||
" " #asm_op " %0, %2 \n" \
|
||||
" sc %0, %1 \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (temp), "+m" (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} while (unlikely(!temp)); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
raw_local_irq_save(flags); \
|
||||
v->counter c_op i; \
|
||||
raw_local_irq_restore(flags); \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
|
||||
static __inline__ int atomic_##op##_return(int i, atomic_t * v) \
|
||||
{ \
|
||||
int result; \
|
||||
\
|
||||
smp_mb__before_llsc(); \
|
||||
\
|
||||
if (kernel_uses_llsc && R10000_LLSC_WAR) { \
|
||||
int temp; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
"1: ll %1, %2 # atomic_" #op "_return \n" \
|
||||
" " #asm_op " %0, %1, %3 \n" \
|
||||
" sc %0, %2 \n" \
|
||||
" beqzl %0, 1b \n" \
|
||||
" " #asm_op " %0, %1, %3 \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (result), "=&r" (temp), "+m" (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} else if (kernel_uses_llsc) { \
|
||||
int temp; \
|
||||
\
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
" ll %1, %2 # atomic_" #op "_return \n" \
|
||||
" " #asm_op " %0, %1, %3 \n" \
|
||||
" sc %0, %2 \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (result), "=&r" (temp), "+m" (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} while (unlikely(!result)); \
|
||||
\
|
||||
result = temp; result c_op i; \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
raw_local_irq_save(flags); \
|
||||
result = v->counter; \
|
||||
result c_op i; \
|
||||
v->counter = result; \
|
||||
raw_local_irq_restore(flags); \
|
||||
} \
|
||||
\
|
||||
smp_llsc_mb(); \
|
||||
\
|
||||
return result; \
|
||||
#define ATOMIC_OP(op, c_op, asm_op) \
|
||||
static __inline__ void atomic_##op(int i, atomic_t * v) \
|
||||
{ \
|
||||
if (kernel_uses_llsc && R10000_LLSC_WAR) { \
|
||||
int temp; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
"1: ll %0, %1 # atomic_" #op " \n" \
|
||||
" " #asm_op " %0, %2 \n" \
|
||||
" sc %0, %1 \n" \
|
||||
" beqzl %0, 1b \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} else if (kernel_uses_llsc) { \
|
||||
int temp; \
|
||||
\
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
" ll %0, %1 # atomic_" #op "\n" \
|
||||
" " #asm_op " %0, %2 \n" \
|
||||
" sc %0, %1 \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} while (unlikely(!temp)); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
raw_local_irq_save(flags); \
|
||||
v->counter c_op i; \
|
||||
raw_local_irq_restore(flags); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ATOMIC_OPS(op, c_op, asm_op) \
|
||||
ATOMIC_OP(op, c_op, asm_op) \
|
||||
#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
|
||||
static __inline__ int atomic_##op##_return(int i, atomic_t * v) \
|
||||
{ \
|
||||
int result; \
|
||||
\
|
||||
smp_mb__before_llsc(); \
|
||||
\
|
||||
if (kernel_uses_llsc && R10000_LLSC_WAR) { \
|
||||
int temp; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
"1: ll %1, %2 # atomic_" #op "_return \n" \
|
||||
" " #asm_op " %0, %1, %3 \n" \
|
||||
" sc %0, %2 \n" \
|
||||
" beqzl %0, 1b \n" \
|
||||
" " #asm_op " %0, %1, %3 \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (result), "=&r" (temp), \
|
||||
"+" GCC_OFF12_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} else if (kernel_uses_llsc) { \
|
||||
int temp; \
|
||||
\
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
" ll %1, %2 # atomic_" #op "_return \n" \
|
||||
" " #asm_op " %0, %1, %3 \n" \
|
||||
" sc %0, %2 \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (result), "=&r" (temp), \
|
||||
"+" GCC_OFF12_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} while (unlikely(!result)); \
|
||||
\
|
||||
result = temp; result c_op i; \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
raw_local_irq_save(flags); \
|
||||
result = v->counter; \
|
||||
result c_op i; \
|
||||
v->counter = result; \
|
||||
raw_local_irq_restore(flags); \
|
||||
} \
|
||||
\
|
||||
smp_llsc_mb(); \
|
||||
\
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define ATOMIC_OPS(op, c_op, asm_op) \
|
||||
ATOMIC_OP(op, c_op, asm_op) \
|
||||
ATOMIC_OP_RETURN(op, c_op, asm_op)
|
||||
|
||||
ATOMIC_OPS(add, +=, addu)
|
||||
|
@ -167,8 +170,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
|
|||
" .set reorder \n"
|
||||
"1: \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (result), "=&r" (temp), "+m" (v->counter)
|
||||
: "Ir" (i), "m" (v->counter)
|
||||
: "=&r" (result), "=&r" (temp),
|
||||
"+" GCC_OFF12_ASM() (v->counter)
|
||||
: "Ir" (i), GCC_OFF12_ASM() (v->counter)
|
||||
: "memory");
|
||||
} else if (kernel_uses_llsc) {
|
||||
int temp;
|
||||
|
@ -185,7 +189,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
|
|||
" .set reorder \n"
|
||||
"1: \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (result), "=&r" (temp), "+m" (v->counter)
|
||||
: "=&r" (result), "=&r" (temp),
|
||||
"+" GCC_OFF12_ASM() (v->counter)
|
||||
: "Ir" (i));
|
||||
} else {
|
||||
unsigned long flags;
|
||||
|
@ -315,96 +320,98 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
|
|||
*/
|
||||
#define atomic64_set(v, i) ((v)->counter = (i))
|
||||
|
||||
#define ATOMIC64_OP(op, c_op, asm_op) \
|
||||
static __inline__ void atomic64_##op(long i, atomic64_t * v) \
|
||||
{ \
|
||||
if (kernel_uses_llsc && R10000_LLSC_WAR) { \
|
||||
long temp; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
"1: lld %0, %1 # atomic64_" #op " \n" \
|
||||
" " #asm_op " %0, %2 \n" \
|
||||
" scd %0, %1 \n" \
|
||||
" beqzl %0, 1b \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (temp), "+m" (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} else if (kernel_uses_llsc) { \
|
||||
long temp; \
|
||||
\
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
" lld %0, %1 # atomic64_" #op "\n" \
|
||||
" " #asm_op " %0, %2 \n" \
|
||||
" scd %0, %1 \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (temp), "+m" (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} while (unlikely(!temp)); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
raw_local_irq_save(flags); \
|
||||
v->counter c_op i; \
|
||||
raw_local_irq_restore(flags); \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define ATOMIC64_OP_RETURN(op, c_op, asm_op) \
|
||||
static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \
|
||||
{ \
|
||||
long result; \
|
||||
\
|
||||
smp_mb__before_llsc(); \
|
||||
\
|
||||
if (kernel_uses_llsc && R10000_LLSC_WAR) { \
|
||||
long temp; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
"1: lld %1, %2 # atomic64_" #op "_return\n" \
|
||||
" " #asm_op " %0, %1, %3 \n" \
|
||||
" scd %0, %2 \n" \
|
||||
" beqzl %0, 1b \n" \
|
||||
" " #asm_op " %0, %1, %3 \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (result), "=&r" (temp), "+m" (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} else if (kernel_uses_llsc) { \
|
||||
long temp; \
|
||||
\
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
" lld %1, %2 # atomic64_" #op "_return\n" \
|
||||
" " #asm_op " %0, %1, %3 \n" \
|
||||
" scd %0, %2 \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter) \
|
||||
: "Ir" (i), "m" (v->counter) \
|
||||
: "memory"); \
|
||||
} while (unlikely(!result)); \
|
||||
\
|
||||
result = temp; result c_op i; \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
raw_local_irq_save(flags); \
|
||||
result = v->counter; \
|
||||
result c_op i; \
|
||||
v->counter = result; \
|
||||
raw_local_irq_restore(flags); \
|
||||
} \
|
||||
\
|
||||
smp_llsc_mb(); \
|
||||
\
|
||||
return result; \
|
||||
#define ATOMIC64_OP(op, c_op, asm_op) \
|
||||
static __inline__ void atomic64_##op(long i, atomic64_t * v) \
|
||||
{ \
|
||||
if (kernel_uses_llsc && R10000_LLSC_WAR) { \
|
||||
long temp; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
"1: lld %0, %1 # atomic64_" #op " \n" \
|
||||
" " #asm_op " %0, %2 \n" \
|
||||
" scd %0, %1 \n" \
|
||||
" beqzl %0, 1b \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} else if (kernel_uses_llsc) { \
|
||||
long temp; \
|
||||
\
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
" lld %0, %1 # atomic64_" #op "\n" \
|
||||
" " #asm_op " %0, %2 \n" \
|
||||
" scd %0, %1 \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} while (unlikely(!temp)); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
raw_local_irq_save(flags); \
|
||||
v->counter c_op i; \
|
||||
raw_local_irq_restore(flags); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ATOMIC64_OPS(op, c_op, asm_op) \
|
||||
ATOMIC64_OP(op, c_op, asm_op) \
|
||||
#define ATOMIC64_OP_RETURN(op, c_op, asm_op) \
|
||||
static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \
|
||||
{ \
|
||||
long result; \
|
||||
\
|
||||
smp_mb__before_llsc(); \
|
||||
\
|
||||
if (kernel_uses_llsc && R10000_LLSC_WAR) { \
|
||||
long temp; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
"1: lld %1, %2 # atomic64_" #op "_return\n" \
|
||||
" " #asm_op " %0, %1, %3 \n" \
|
||||
" scd %0, %2 \n" \
|
||||
" beqzl %0, 1b \n" \
|
||||
" " #asm_op " %0, %1, %3 \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (result), "=&r" (temp), \
|
||||
"+" GCC_OFF12_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
} else if (kernel_uses_llsc) { \
|
||||
long temp; \
|
||||
\
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set arch=r4000 \n" \
|
||||
" lld %1, %2 # atomic64_" #op "_return\n" \
|
||||
" " #asm_op " %0, %1, %3 \n" \
|
||||
" scd %0, %2 \n" \
|
||||
" .set mips0 \n" \
|
||||
: "=&r" (result), "=&r" (temp), \
|
||||
"=" GCC_OFF12_ASM() (v->counter) \
|
||||
: "Ir" (i), GCC_OFF12_ASM() (v->counter) \
|
||||
: "memory"); \
|
||||
} while (unlikely(!result)); \
|
||||
\
|
||||
result = temp; result c_op i; \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
raw_local_irq_save(flags); \
|
||||
result = v->counter; \
|
||||
result c_op i; \
|
||||
v->counter = result; \
|
||||
raw_local_irq_restore(flags); \
|
||||
} \
|
||||
\
|
||||
smp_llsc_mb(); \
|
||||
\
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define ATOMIC64_OPS(op, c_op, asm_op) \
|
||||
ATOMIC64_OP(op, c_op, asm_op) \
|
||||
ATOMIC64_OP_RETURN(op, c_op, asm_op)
|
||||
|
||||
ATOMIC64_OPS(add, +=, daddu)
|
||||
|
@ -415,7 +422,8 @@ ATOMIC64_OPS(sub, -=, dsubu)
|
|||
#undef ATOMIC64_OP
|
||||
|
||||
/*
|
||||
* atomic64_sub_if_positive - conditionally subtract integer from atomic variable
|
||||
* atomic64_sub_if_positive - conditionally subtract integer from atomic
|
||||
* variable
|
||||
* @i: integer value to subtract
|
||||
* @v: pointer of type atomic64_t
|
||||
*
|
||||
|
@ -443,8 +451,9 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
|
|||
" .set reorder \n"
|
||||
"1: \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||
: "Ir" (i), "m" (v->counter)
|
||||
: "=&r" (result), "=&r" (temp),
|
||||
"=" GCC_OFF12_ASM() (v->counter)
|
||||
: "Ir" (i), GCC_OFF12_ASM() (v->counter)
|
||||
: "memory");
|
||||
} else if (kernel_uses_llsc) {
|
||||
long temp;
|
||||
|
@ -461,7 +470,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
|
|||
" .set reorder \n"
|
||||
"1: \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (result), "=&r" (temp), "+m" (v->counter)
|
||||
: "=&r" (result), "=&r" (temp),
|
||||
"+" GCC_OFF12_ASM() (v->counter)
|
||||
: "Ir" (i));
|
||||
} else {
|
||||
unsigned long flags;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/byteorder.h> /* sigh ... */
|
||||
#include <asm/compiler.h>
|
||||
#include <asm/cpu-features.h>
|
||||
#include <asm/sgidefs.h>
|
||||
#include <asm/war.h>
|
||||
|
@ -78,8 +79,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
|
|||
" " __SC "%0, %1 \n"
|
||||
" beqzl %0, 1b \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "=m" (*m)
|
||||
: "ir" (1UL << bit), "m" (*m));
|
||||
: "=&r" (temp), "=" GCC_OFF12_ASM() (*m)
|
||||
: "ir" (1UL << bit), GCC_OFF12_ASM() (*m));
|
||||
#ifdef CONFIG_CPU_MIPSR2
|
||||
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
|
||||
do {
|
||||
|
@ -87,7 +88,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
|
|||
" " __LL "%0, %1 # set_bit \n"
|
||||
" " __INS "%0, %3, %2, 1 \n"
|
||||
" " __SC "%0, %1 \n"
|
||||
: "=&r" (temp), "+m" (*m)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
|
||||
: "ir" (bit), "r" (~0));
|
||||
} while (unlikely(!temp));
|
||||
#endif /* CONFIG_CPU_MIPSR2 */
|
||||
|
@ -99,7 +100,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
|
|||
" or %0, %2 \n"
|
||||
" " __SC "%0, %1 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "+m" (*m)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
|
||||
: "ir" (1UL << bit));
|
||||
} while (unlikely(!temp));
|
||||
} else
|
||||
|
@ -130,7 +131,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
|
|||
" " __SC "%0, %1 \n"
|
||||
" beqzl %0, 1b \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "+m" (*m)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
|
||||
: "ir" (~(1UL << bit)));
|
||||
#ifdef CONFIG_CPU_MIPSR2
|
||||
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
|
||||
|
@ -139,7 +140,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
|
|||
" " __LL "%0, %1 # clear_bit \n"
|
||||
" " __INS "%0, $0, %2, 1 \n"
|
||||
" " __SC "%0, %1 \n"
|
||||
: "=&r" (temp), "+m" (*m)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
|
||||
: "ir" (bit));
|
||||
} while (unlikely(!temp));
|
||||
#endif /* CONFIG_CPU_MIPSR2 */
|
||||
|
@ -151,7 +152,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
|
|||
" and %0, %2 \n"
|
||||
" " __SC "%0, %1 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "+m" (*m)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
|
||||
: "ir" (~(1UL << bit)));
|
||||
} while (unlikely(!temp));
|
||||
} else
|
||||
|
@ -196,7 +197,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
|
|||
" " __SC "%0, %1 \n"
|
||||
" beqzl %0, 1b \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "+m" (*m)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
|
||||
: "ir" (1UL << bit));
|
||||
} else if (kernel_uses_llsc) {
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
|
||||
|
@ -209,7 +210,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
|
|||
" xor %0, %2 \n"
|
||||
" " __SC "%0, %1 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "+m" (*m)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
|
||||
: "ir" (1UL << bit));
|
||||
} while (unlikely(!temp));
|
||||
} else
|
||||
|
@ -244,7 +245,7 @@ static inline int test_and_set_bit(unsigned long nr,
|
|||
" beqzl %2, 1b \n"
|
||||
" and %2, %0, %3 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "+m" (*m), "=&r" (res)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
} else if (kernel_uses_llsc) {
|
||||
|
@ -258,7 +259,7 @@ static inline int test_and_set_bit(unsigned long nr,
|
|||
" or %2, %0, %3 \n"
|
||||
" " __SC "%2, %1 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "+m" (*m), "=&r" (res)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
} while (unlikely(!res));
|
||||
|
@ -312,7 +313,7 @@ static inline int test_and_set_bit_lock(unsigned long nr,
|
|||
" or %2, %0, %3 \n"
|
||||
" " __SC "%2, %1 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "+m" (*m), "=&r" (res)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
} while (unlikely(!res));
|
||||
|
@ -354,7 +355,7 @@ static inline int test_and_clear_bit(unsigned long nr,
|
|||
" beqzl %2, 1b \n"
|
||||
" and %2, %0, %3 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "+m" (*m), "=&r" (res)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
#ifdef CONFIG_CPU_MIPSR2
|
||||
|
@ -368,7 +369,7 @@ static inline int test_and_clear_bit(unsigned long nr,
|
|||
" " __EXT "%2, %0, %3, 1 \n"
|
||||
" " __INS "%0, $0, %3, 1 \n"
|
||||
" " __SC "%0, %1 \n"
|
||||
: "=&r" (temp), "+m" (*m), "=&r" (res)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
|
||||
: "ir" (bit)
|
||||
: "memory");
|
||||
} while (unlikely(!temp));
|
||||
|
@ -385,7 +386,7 @@ static inline int test_and_clear_bit(unsigned long nr,
|
|||
" xor %2, %3 \n"
|
||||
" " __SC "%2, %1 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "+m" (*m), "=&r" (res)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
} while (unlikely(!res));
|
||||
|
@ -427,7 +428,7 @@ static inline int test_and_change_bit(unsigned long nr,
|
|||
" beqzl %2, 1b \n"
|
||||
" and %2, %0, %3 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "+m" (*m), "=&r" (res)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
} else if (kernel_uses_llsc) {
|
||||
|
@ -441,7 +442,7 @@ static inline int test_and_change_bit(unsigned long nr,
|
|||
" xor %2, %0, %3 \n"
|
||||
" " __SC "\t%2, %1 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "+m" (*m), "=&r" (res)
|
||||
: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
} while (unlikely(!res));
|
||||
|
|
|
@ -84,6 +84,7 @@ extern char bmips_smp_int_vec_end;
|
|||
extern int bmips_smp_enabled;
|
||||
extern int bmips_cpu_offset;
|
||||
extern cpumask_t bmips_booted_mask;
|
||||
extern unsigned long bmips_tp1_irqs;
|
||||
|
||||
extern void bmips_ebase_setup(void);
|
||||
extern asmlinkage void plat_wired_tlb_setup(void);
|
||||
|
|
|
@ -70,10 +70,7 @@ enum loongson_machine_type {
|
|||
MACH_DEXXON_GDIUM2F10,
|
||||
MACH_LEMOTE_NAS,
|
||||
MACH_LEMOTE_LL2F,
|
||||
MACH_LEMOTE_A1004,
|
||||
MACH_LEMOTE_A1101,
|
||||
MACH_LEMOTE_A1201,
|
||||
MACH_LEMOTE_A1205,
|
||||
MACH_LOONGSON_GENERIC,
|
||||
MACH_LOONGSON_END
|
||||
};
|
||||
|
||||
|
@ -101,16 +98,16 @@ extern unsigned long mips_machtype;
|
|||
struct boot_mem_map {
|
||||
int nr_map;
|
||||
struct boot_mem_map_entry {
|
||||
phys_t addr; /* start of memory segment */
|
||||
phys_t size; /* size of memory segment */
|
||||
phys_addr_t addr; /* start of memory segment */
|
||||
phys_addr_t size; /* size of memory segment */
|
||||
long type; /* type of memory segment */
|
||||
} map[BOOT_MEM_MAP_MAX];
|
||||
};
|
||||
|
||||
extern struct boot_mem_map boot_mem_map;
|
||||
|
||||
extern void add_memory_region(phys_t start, phys_t size, long type);
|
||||
extern void detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max);
|
||||
extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type);
|
||||
extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max);
|
||||
|
||||
extern void prom_init(void);
|
||||
extern void prom_free_prom_memory(void);
|
||||
|
|
|
@ -35,9 +35,6 @@ struct clk {
|
|||
#define CLK_ALWAYS_ENABLED (1 << 0)
|
||||
#define CLK_RATE_PROPAGATES (1 << 1)
|
||||
|
||||
/* Should be defined by processor-specific code */
|
||||
void arch_init_clk_ops(struct clk_ops **, int type);
|
||||
|
||||
int clk_init(void);
|
||||
|
||||
int __clk_enable(struct clk *);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/irqflags.h>
|
||||
#include <asm/compiler.h>
|
||||
#include <asm/war.h>
|
||||
|
||||
static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
|
||||
|
@ -30,8 +31,8 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
|
|||
" sc %2, %1 \n"
|
||||
" beqzl %2, 1b \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
|
||||
: "R" (*m), "Jr" (val)
|
||||
: "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy)
|
||||
: GCC_OFF12_ASM() (*m), "Jr" (val)
|
||||
: "memory");
|
||||
} else if (kernel_uses_llsc) {
|
||||
unsigned long dummy;
|
||||
|
@ -45,8 +46,9 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
|
|||
" .set arch=r4000 \n"
|
||||
" sc %2, %1 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
|
||||
: "R" (*m), "Jr" (val)
|
||||
: "=&r" (retval), "=" GCC_OFF12_ASM() (*m),
|
||||
"=&r" (dummy)
|
||||
: GCC_OFF12_ASM() (*m), "Jr" (val)
|
||||
: "memory");
|
||||
} while (unlikely(!dummy));
|
||||
} else {
|
||||
|
@ -80,8 +82,8 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
|
|||
" scd %2, %1 \n"
|
||||
" beqzl %2, 1b \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
|
||||
: "R" (*m), "Jr" (val)
|
||||
: "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy)
|
||||
: GCC_OFF12_ASM() (*m), "Jr" (val)
|
||||
: "memory");
|
||||
} else if (kernel_uses_llsc) {
|
||||
unsigned long dummy;
|
||||
|
@ -93,8 +95,9 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
|
|||
" move %2, %z4 \n"
|
||||
" scd %2, %1 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
|
||||
: "R" (*m), "Jr" (val)
|
||||
: "=&r" (retval), "=" GCC_OFF12_ASM() (*m),
|
||||
"=&r" (dummy)
|
||||
: GCC_OFF12_ASM() (*m), "Jr" (val)
|
||||
: "memory");
|
||||
} while (unlikely(!dummy));
|
||||
} else {
|
||||
|
@ -155,8 +158,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
|
|||
" beqzl $1, 1b \n" \
|
||||
"2: \n" \
|
||||
" .set pop \n" \
|
||||
: "=&r" (__ret), "=R" (*m) \
|
||||
: "R" (*m), "Jr" (old), "Jr" (new) \
|
||||
: "=&r" (__ret), "=" GCC_OFF12_ASM() (*m) \
|
||||
: GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new) \
|
||||
: "memory"); \
|
||||
} else if (kernel_uses_llsc) { \
|
||||
__asm__ __volatile__( \
|
||||
|
@ -172,8 +175,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
|
|||
" beqz $1, 1b \n" \
|
||||
" .set pop \n" \
|
||||
"2: \n" \
|
||||
: "=&r" (__ret), "=R" (*m) \
|
||||
: "R" (*m), "Jr" (old), "Jr" (new) \
|
||||
: "=&r" (__ret), "=" GCC_OFF12_ASM() (*m) \
|
||||
: GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new) \
|
||||
: "memory"); \
|
||||
} else { \
|
||||
unsigned long __flags; \
|
||||
|
|
|
@ -16,4 +16,12 @@
|
|||
#define GCC_REG_ACCUM "accum"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_CPU_MICROMIPS
|
||||
#define GCC_OFF12_ASM() "R"
|
||||
#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
|
||||
#define GCC_OFF12_ASM() "ZC"
|
||||
#else
|
||||
#error "microMIPS compilation unsupported with GCC older than 4.9"
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_COMPILER_H */
|
||||
|
|
|
@ -344,4 +344,8 @@
|
|||
# define cpu_has_msa 0
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_fre
|
||||
# define cpu_has_fre (cpu_data[0].options & MIPS_CPU_FRE)
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_CPU_FEATURES_H */
|
||||
|
|
|
@ -142,6 +142,7 @@
|
|||
#define PRID_IMP_BMIPS3300_BUG 0x0000
|
||||
#define PRID_IMP_BMIPS43XX 0xa000
|
||||
#define PRID_IMP_BMIPS5000 0x5a00
|
||||
#define PRID_IMP_BMIPS5200 0x5b00
|
||||
|
||||
#define PRID_REV_BMIPS4380_LO 0x0040
|
||||
#define PRID_REV_BMIPS4380_HI 0x006f
|
||||
|
@ -368,6 +369,7 @@ enum cpu_type_enum {
|
|||
#define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */
|
||||
#define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */
|
||||
#define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */
|
||||
#define MIPS_CPU_FRE 0x800000000ull /* FRE & UFE bits implemented */
|
||||
|
||||
/*
|
||||
* CPU ASE encodings
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef ASM_EDAC_H
|
||||
#define ASM_EDAC_H
|
||||
|
||||
#include <asm/compiler.h>
|
||||
|
||||
/* ECC atomic, DMA, SMP and interrupt safe scrub function */
|
||||
|
||||
static inline void atomic_scrub(void *va, u32 size)
|
||||
|
@ -24,8 +26,8 @@ static inline void atomic_scrub(void *va, u32 size)
|
|||
" sc %0, %1 \n"
|
||||
" beqz %0, 1b \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (temp), "=m" (*virt_addr)
|
||||
: "m" (*virt_addr));
|
||||
: "=&r" (temp), "=" GCC_OFF12_ASM() (*virt_addr)
|
||||
: GCC_OFF12_ASM() (*virt_addr));
|
||||
|
||||
virt_addr++;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#ifndef _ASM_ELF_H
|
||||
#define _ASM_ELF_H
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <uapi/linux/elf.h>
|
||||
|
||||
/* ELF header e_flags defines. */
|
||||
/* MIPS architecture level. */
|
||||
|
@ -28,6 +30,7 @@
|
|||
#define PT_MIPS_REGINFO 0x70000000
|
||||
#define PT_MIPS_RTPROC 0x70000001
|
||||
#define PT_MIPS_OPTIONS 0x70000002
|
||||
#define PT_MIPS_ABIFLAGS 0x70000003
|
||||
|
||||
/* Flags in the e_flags field of the header */
|
||||
#define EF_MIPS_NOREORDER 0x00000001
|
||||
|
@ -174,6 +177,30 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
|||
typedef double elf_fpreg_t;
|
||||
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
|
||||
|
||||
struct mips_elf_abiflags_v0 {
|
||||
uint16_t version; /* Version of flags structure */
|
||||
uint8_t isa_level; /* The level of the ISA: 1-5, 32, 64 */
|
||||
uint8_t isa_rev; /* The revision of ISA: 0 for MIPS V and below,
|
||||
1-n otherwise */
|
||||
uint8_t gpr_size; /* The size of general purpose registers */
|
||||
uint8_t cpr1_size; /* The size of co-processor 1 registers */
|
||||
uint8_t cpr2_size; /* The size of co-processor 2 registers */
|
||||
uint8_t fp_abi; /* The floating-point ABI */
|
||||
uint32_t isa_ext; /* Mask of processor-specific extensions */
|
||||
uint32_t ases; /* Mask of ASEs used */
|
||||
uint32_t flags1; /* Mask of general flags */
|
||||
uint32_t flags2;
|
||||
};
|
||||
|
||||
#define MIPS_ABI_FP_ANY 0 /* FP ABI doesn't matter */
|
||||
#define MIPS_ABI_FP_DOUBLE 1 /* -mdouble-float */
|
||||
#define MIPS_ABI_FP_SINGLE 2 /* -msingle-float */
|
||||
#define MIPS_ABI_FP_SOFT 3 /* -msoft-float */
|
||||
#define MIPS_ABI_FP_OLD_64 4 /* -mips32r2 -mfp64 */
|
||||
#define MIPS_ABI_FP_XX 5 /* -mfpxx */
|
||||
#define MIPS_ABI_FP_64 6 /* -mips32r2 -mfp64 */
|
||||
#define MIPS_ABI_FP_64A 7 /* -mips32r2 -mfp64 -mno-odd-spreg */
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
|
||||
/*
|
||||
|
@ -262,16 +289,13 @@ extern struct mips_abi mips_abi_n32;
|
|||
|
||||
#ifdef CONFIG_32BIT
|
||||
|
||||
#define SET_PERSONALITY(ex) \
|
||||
#define SET_PERSONALITY2(ex, state) \
|
||||
do { \
|
||||
if ((ex).e_flags & EF_MIPS_FP64) \
|
||||
clear_thread_flag(TIF_32BIT_FPREGS); \
|
||||
else \
|
||||
set_thread_flag(TIF_32BIT_FPREGS); \
|
||||
\
|
||||
if (personality(current->personality) != PER_LINUX) \
|
||||
set_personality(PER_LINUX); \
|
||||
\
|
||||
mips_set_personality_fp(state); \
|
||||
\
|
||||
current->thread.abi = &mips_abi; \
|
||||
} while (0)
|
||||
|
||||
|
@ -291,44 +315,44 @@ do { \
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS32_O32
|
||||
#define __SET_PERSONALITY32_O32(ex) \
|
||||
#define __SET_PERSONALITY32_O32(ex, state) \
|
||||
do { \
|
||||
set_thread_flag(TIF_32BIT_REGS); \
|
||||
set_thread_flag(TIF_32BIT_ADDR); \
|
||||
\
|
||||
if (!((ex).e_flags & EF_MIPS_FP64)) \
|
||||
set_thread_flag(TIF_32BIT_FPREGS); \
|
||||
mips_set_personality_fp(state); \
|
||||
\
|
||||
current->thread.abi = &mips_abi_32; \
|
||||
} while (0)
|
||||
#else
|
||||
#define __SET_PERSONALITY32_O32(ex) \
|
||||
#define __SET_PERSONALITY32_O32(ex, state) \
|
||||
do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS32_COMPAT
|
||||
#define __SET_PERSONALITY32(ex) \
|
||||
#define __SET_PERSONALITY32(ex, state) \
|
||||
do { \
|
||||
if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \
|
||||
((ex).e_flags & EF_MIPS_ABI) == 0) \
|
||||
__SET_PERSONALITY32_N32(); \
|
||||
else \
|
||||
__SET_PERSONALITY32_O32(ex); \
|
||||
__SET_PERSONALITY32_O32(ex, state); \
|
||||
} while (0)
|
||||
#else
|
||||
#define __SET_PERSONALITY32(ex) do { } while (0)
|
||||
#define __SET_PERSONALITY32(ex, state) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define SET_PERSONALITY(ex) \
|
||||
#define SET_PERSONALITY2(ex, state) \
|
||||
do { \
|
||||
unsigned int p; \
|
||||
\
|
||||
clear_thread_flag(TIF_32BIT_REGS); \
|
||||
clear_thread_flag(TIF_32BIT_FPREGS); \
|
||||
clear_thread_flag(TIF_HYBRID_FPREGS); \
|
||||
clear_thread_flag(TIF_32BIT_ADDR); \
|
||||
\
|
||||
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
|
||||
__SET_PERSONALITY32(ex); \
|
||||
__SET_PERSONALITY32(ex, state); \
|
||||
else \
|
||||
current->thread.abi = &mips_abi; \
|
||||
\
|
||||
|
@ -390,4 +414,24 @@ struct mm_struct;
|
|||
extern unsigned long arch_randomize_brk(struct mm_struct *mm);
|
||||
#define arch_randomize_brk arch_randomize_brk
|
||||
|
||||
struct arch_elf_state {
|
||||
int fp_abi;
|
||||
int interp_fp_abi;
|
||||
int overall_abi;
|
||||
};
|
||||
|
||||
#define INIT_ARCH_ELF_STATE { \
|
||||
.fp_abi = -1, \
|
||||
.interp_fp_abi = -1, \
|
||||
.overall_abi = -1, \
|
||||
}
|
||||
|
||||
extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf,
|
||||
bool is_interp, struct arch_elf_state *state);
|
||||
|
||||
extern int arch_check_elf(void *ehdr, bool has_interpreter,
|
||||
struct arch_elf_state *state);
|
||||
|
||||
extern void mips_set_personality_fp(struct arch_elf_state *state);
|
||||
|
||||
#endif /* _ASM_ELF_H */
|
||||
|
|
|
@ -36,14 +36,16 @@ extern void _restore_fp(struct task_struct *);
|
|||
|
||||
/*
|
||||
* This enum specifies a mode in which we want the FPU to operate, for cores
|
||||
* which implement the Status.FR bit. Note that FPU_32BIT & FPU_64BIT
|
||||
* purposefully have the values 0 & 1 respectively, so that an integer value
|
||||
* of Status.FR can be trivially casted to the corresponding enum fpu_mode.
|
||||
* which implement the Status.FR bit. Note that the bottom bit of the value
|
||||
* purposefully matches the desired value of the Status.FR bit.
|
||||
*/
|
||||
enum fpu_mode {
|
||||
FPU_32BIT = 0, /* FR = 0 */
|
||||
FPU_64BIT, /* FR = 1 */
|
||||
FPU_64BIT, /* FR = 1, FRE = 0 */
|
||||
FPU_AS_IS,
|
||||
FPU_HYBRID, /* FR = 1, FRE = 1 */
|
||||
|
||||
#define FPU_FR_MASK 0x1
|
||||
};
|
||||
|
||||
static inline int __enable_fpu(enum fpu_mode mode)
|
||||
|
@ -57,6 +59,14 @@ static inline int __enable_fpu(enum fpu_mode mode)
|
|||
enable_fpu_hazard();
|
||||
return 0;
|
||||
|
||||
case FPU_HYBRID:
|
||||
if (!cpu_has_fre)
|
||||
return SIGFPE;
|
||||
|
||||
/* set FRE */
|
||||
write_c0_config5(read_c0_config5() | MIPS_CONF5_FRE);
|
||||
goto fr_common;
|
||||
|
||||
case FPU_64BIT:
|
||||
#if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_64BIT))
|
||||
/* we only have a 32-bit FPU */
|
||||
|
@ -64,8 +74,11 @@ static inline int __enable_fpu(enum fpu_mode mode)
|
|||
#endif
|
||||
/* fall through */
|
||||
case FPU_32BIT:
|
||||
/* clear FRE */
|
||||
write_c0_config5(read_c0_config5() & ~MIPS_CONF5_FRE);
|
||||
fr_common:
|
||||
/* set CU1 & change FR appropriately */
|
||||
fr = (int)mode;
|
||||
fr = (int)mode & FPU_FR_MASK;
|
||||
change_c0_status(ST0_CU1 | ST0_FR, ST0_CU1 | (fr ? ST0_FR : 0));
|
||||
enable_fpu_hazard();
|
||||
|
||||
|
@ -102,13 +115,17 @@ static inline int __own_fpu(void)
|
|||
enum fpu_mode mode;
|
||||
int ret;
|
||||
|
||||
mode = !test_thread_flag(TIF_32BIT_FPREGS);
|
||||
if (test_thread_flag(TIF_HYBRID_FPREGS))
|
||||
mode = FPU_HYBRID;
|
||||
else
|
||||
mode = !test_thread_flag(TIF_32BIT_FPREGS);
|
||||
|
||||
ret = __enable_fpu(mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
KSTK_STATUS(current) |= ST0_CU1;
|
||||
if (mode == FPU_64BIT)
|
||||
if (mode == FPU_64BIT || mode == FPU_HYBRID)
|
||||
KSTK_STATUS(current) |= ST0_FR;
|
||||
else /* mode == FPU_32BIT */
|
||||
KSTK_STATUS(current) &= ~ST0_FR;
|
||||
|
@ -166,8 +183,24 @@ static inline int init_fpu(void)
|
|||
|
||||
if (cpu_has_fpu) {
|
||||
ret = __own_fpu();
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
unsigned int config5 = read_c0_config5();
|
||||
|
||||
/*
|
||||
* Ensure FRE is clear whilst running _init_fpu, since
|
||||
* single precision FP instructions are used. If FRE
|
||||
* was set then we'll just end up initialising all 32
|
||||
* 64b registers.
|
||||
*/
|
||||
write_c0_config5(config5 & ~MIPS_CONF5_FRE);
|
||||
enable_fpu_hazard();
|
||||
|
||||
_init_fpu();
|
||||
|
||||
/* Restore FRE */
|
||||
write_c0_config5(config5);
|
||||
enable_fpu_hazard();
|
||||
}
|
||||
} else
|
||||
fpu_emulator_init_fpu();
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/uaccess.h>
|
||||
#include <asm/asm-eva.h>
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/compiler.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/war.h>
|
||||
|
||||
|
@ -32,6 +33,7 @@
|
|||
" beqzl $1, 1b \n" \
|
||||
__WEAK_LLSC_MB \
|
||||
"3: \n" \
|
||||
" .insn \n" \
|
||||
" .set pop \n" \
|
||||
" .set mips0 \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
|
@ -42,8 +44,10 @@
|
|||
" "__UA_ADDR "\t1b, 4b \n" \
|
||||
" "__UA_ADDR "\t2b, 4b \n" \
|
||||
" .previous \n" \
|
||||
: "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \
|
||||
: "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \
|
||||
: "=r" (ret), "=&r" (oldval), \
|
||||
"=" GCC_OFF12_ASM() (*uaddr) \
|
||||
: "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg), \
|
||||
"i" (-EFAULT) \
|
||||
: "memory"); \
|
||||
} else if (cpu_has_llsc) { \
|
||||
__asm__ __volatile__( \
|
||||
|
@ -58,6 +62,7 @@
|
|||
" beqz $1, 1b \n" \
|
||||
__WEAK_LLSC_MB \
|
||||
"3: \n" \
|
||||
" .insn \n" \
|
||||
" .set pop \n" \
|
||||
" .set mips0 \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
|
@ -68,8 +73,10 @@
|
|||
" "__UA_ADDR "\t1b, 4b \n" \
|
||||
" "__UA_ADDR "\t2b, 4b \n" \
|
||||
" .previous \n" \
|
||||
: "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \
|
||||
: "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \
|
||||
: "=r" (ret), "=&r" (oldval), \
|
||||
"=" GCC_OFF12_ASM() (*uaddr) \
|
||||
: "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg), \
|
||||
"i" (-EFAULT) \
|
||||
: "memory"); \
|
||||
} else \
|
||||
ret = -ENOSYS; \
|
||||
|
@ -157,6 +164,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
|||
" beqzl $1, 1b \n"
|
||||
__WEAK_LLSC_MB
|
||||
"3: \n"
|
||||
" .insn \n"
|
||||
" .set pop \n"
|
||||
" .section .fixup,\"ax\" \n"
|
||||
"4: li %0, %6 \n"
|
||||
|
@ -166,8 +174,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
|||
" "__UA_ADDR "\t1b, 4b \n"
|
||||
" "__UA_ADDR "\t2b, 4b \n"
|
||||
" .previous \n"
|
||||
: "+r" (ret), "=&r" (val), "=R" (*uaddr)
|
||||
: "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT)
|
||||
: "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr)
|
||||
: GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
|
||||
"i" (-EFAULT)
|
||||
: "memory");
|
||||
} else if (cpu_has_llsc) {
|
||||
__asm__ __volatile__(
|
||||
|
@ -184,6 +193,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
|||
" beqz $1, 1b \n"
|
||||
__WEAK_LLSC_MB
|
||||
"3: \n"
|
||||
" .insn \n"
|
||||
" .set pop \n"
|
||||
" .section .fixup,\"ax\" \n"
|
||||
"4: li %0, %6 \n"
|
||||
|
@ -193,8 +203,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
|||
" "__UA_ADDR "\t1b, 4b \n"
|
||||
" "__UA_ADDR "\t2b, 4b \n"
|
||||
" .previous \n"
|
||||
: "+r" (ret), "=&r" (val), "=R" (*uaddr)
|
||||
: "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT)
|
||||
: "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr)
|
||||
: GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
|
||||
"i" (-EFAULT)
|
||||
: "memory");
|
||||
} else
|
||||
return -ENOSYS;
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef _ASM_HPET_H
|
||||
#define _ASM_HPET_H
|
||||
|
||||
#ifdef CONFIG_RS780_HPET
|
||||
|
||||
#define HPET_MMAP_SIZE 1024
|
||||
|
||||
#define HPET_ID 0x000
|
||||
#define HPET_PERIOD 0x004
|
||||
#define HPET_CFG 0x010
|
||||
#define HPET_STATUS 0x020
|
||||
#define HPET_COUNTER 0x0f0
|
||||
|
||||
#define HPET_Tn_CFG(n) (0x100 + 0x20 * n)
|
||||
#define HPET_Tn_CMP(n) (0x108 + 0x20 * n)
|
||||
#define HPET_Tn_ROUTE(n) (0x110 + 0x20 * n)
|
||||
|
||||
#define HPET_T0_IRS 0x001
|
||||
#define HPET_T1_IRS 0x002
|
||||
#define HPET_T3_IRS 0x004
|
||||
|
||||
#define HPET_T0_CFG 0x100
|
||||
#define HPET_T0_CMP 0x108
|
||||
#define HPET_T0_ROUTE 0x110
|
||||
#define HPET_T1_CFG 0x120
|
||||
#define HPET_T1_CMP 0x128
|
||||
#define HPET_T1_ROUTE 0x130
|
||||
#define HPET_T2_CFG 0x140
|
||||
#define HPET_T2_CMP 0x148
|
||||
#define HPET_T2_ROUTE 0x150
|
||||
|
||||
#define HPET_ID_REV 0x000000ff
|
||||
#define HPET_ID_NUMBER 0x00001f00
|
||||
#define HPET_ID_64BIT 0x00002000
|
||||
#define HPET_ID_LEGSUP 0x00008000
|
||||
#define HPET_ID_VENDOR 0xffff0000
|
||||
#define HPET_ID_NUMBER_SHIFT 8
|
||||
#define HPET_ID_VENDOR_SHIFT 16
|
||||
|
||||
#define HPET_CFG_ENABLE 0x001
|
||||
#define HPET_CFG_LEGACY 0x002
|
||||
#define HPET_LEGACY_8254 2
|
||||
#define HPET_LEGACY_RTC 8
|
||||
|
||||
#define HPET_TN_LEVEL 0x0002
|
||||
#define HPET_TN_ENABLE 0x0004
|
||||
#define HPET_TN_PERIODIC 0x0008
|
||||
#define HPET_TN_PERIODIC_CAP 0x0010
|
||||
#define HPET_TN_64BIT_CAP 0x0020
|
||||
#define HPET_TN_SETVAL 0x0040
|
||||
#define HPET_TN_32BIT 0x0100
|
||||
#define HPET_TN_ROUTE 0x3e00
|
||||
#define HPET_TN_FSB 0x4000
|
||||
#define HPET_TN_FSB_CAP 0x8000
|
||||
#define HPET_TN_ROUTE_SHIFT 9
|
||||
|
||||
/* Max HPET Period is 10^8 femto sec as in HPET spec */
|
||||
#define HPET_MAX_PERIOD 100000000UL
|
||||
/*
|
||||
* Min HPET period is 10^5 femto sec just for safety. If it is less than this,
|
||||
* then 32 bit HPET counter wrapsaround in less than 0.5 sec.
|
||||
*/
|
||||
#define HPET_MIN_PERIOD 100000UL
|
||||
|
||||
#define HPET_ADDR 0x20000
|
||||
#define HPET_MMIO_ADDR 0x90000e0000020000
|
||||
#define HPET_FREQ 14318780
|
||||
#define HPET_COMPARE_VAL ((HPET_FREQ + HZ / 2) / HZ)
|
||||
#define HPET_T0_IRQ 0
|
||||
|
||||
extern void __init setup_hpet_timer(void);
|
||||
#endif /* CONFIG_RS780_HPET */
|
||||
#endif /* _ASM_HPET_H */
|
|
@ -167,7 +167,7 @@ static inline void * isa_bus_to_virt(unsigned long address)
|
|||
*/
|
||||
#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
|
||||
|
||||
extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags);
|
||||
extern void __iomem * __ioremap(phys_addr_t offset, phys_addr_t size, unsigned long flags);
|
||||
extern void __iounmap(const volatile void __iomem *addr);
|
||||
|
||||
#ifndef CONFIG_PCI
|
||||
|
@ -175,7 +175,7 @@ struct pci_dev;
|
|||
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
|
||||
#endif
|
||||
|
||||
static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
|
||||
static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long size,
|
||||
unsigned long flags)
|
||||
{
|
||||
void __iomem *addr = plat_ioremap(offset, size, flags);
|
||||
|
@ -183,7 +183,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
|
|||
if (addr)
|
||||
return addr;
|
||||
|
||||
#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
|
||||
#define __IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL))
|
||||
|
||||
if (cpu_has_64bit_addresses) {
|
||||
u64 base = UNCAC_BASE;
|
||||
|
@ -197,7 +197,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
|
|||
return (void __iomem *) (unsigned long) (base + offset);
|
||||
} else if (__builtin_constant_p(offset) &&
|
||||
__builtin_constant_p(size) && __builtin_constant_p(flags)) {
|
||||
phys_t phys_addr, last_addr;
|
||||
phys_addr_t phys_addr, last_addr;
|
||||
|
||||
phys_addr = fixup_bigphys_addr(offset, size);
|
||||
|
||||
|
|
|
@ -48,4 +48,7 @@ extern int cp0_compare_irq;
|
|||
extern int cp0_compare_irq_shift;
|
||||
extern int cp0_perfcount_irq;
|
||||
|
||||
void arch_trigger_all_cpu_backtrace(bool);
|
||||
#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
|
||||
|
||||
#endif /* _ASM_IRQ_H */
|
||||
|
|
|
@ -19,8 +19,8 @@ extern void rm9k_cpu_irq_init(void);
|
|||
|
||||
#ifdef CONFIG_IRQ_DOMAIN
|
||||
struct device_node;
|
||||
extern int mips_cpu_intc_init(struct device_node *of_node,
|
||||
struct device_node *parent);
|
||||
extern int mips_cpu_irq_of_init(struct device_node *of_node,
|
||||
struct device_node *parent);
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_IRQ_CPU_H */
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef __ASM_MACH_ATH25_PLATFORM_H
|
||||
#define __ASM_MACH_ATH25_PLATFORM_H
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
/*
|
||||
* This is board-specific data that is stored in a "fixed" location in flash.
|
||||
* It is shared across operating systems, so it should not be changed lightly.
|
||||
* The main reason we need it is in order to extract the ethernet MAC
|
||||
* address(es).
|
||||
*/
|
||||
struct ath25_boarddata {
|
||||
u32 magic; /* board data is valid */
|
||||
#define ATH25_BD_MAGIC 0x35333131 /* "5311", for all 531x/231x platforms */
|
||||
u16 cksum; /* checksum (starting with BD_REV 2) */
|
||||
u16 rev; /* revision of this struct */
|
||||
#define BD_REV 4
|
||||
char board_name[64]; /* Name of board */
|
||||
u16 major; /* Board major number */
|
||||
u16 minor; /* Board minor number */
|
||||
u32 flags; /* Board configuration */
|
||||
#define BD_ENET0 0x00000001 /* ENET0 is stuffed */
|
||||
#define BD_ENET1 0x00000002 /* ENET1 is stuffed */
|
||||
#define BD_UART1 0x00000004 /* UART1 is stuffed */
|
||||
#define BD_UART0 0x00000008 /* UART0 is stuffed (dma) */
|
||||
#define BD_RSTFACTORY 0x00000010 /* Reset factory defaults stuffed */
|
||||
#define BD_SYSLED 0x00000020 /* System LED stuffed */
|
||||
#define BD_EXTUARTCLK 0x00000040 /* External UART clock */
|
||||
#define BD_CPUFREQ 0x00000080 /* cpu freq is valid in nvram */
|
||||
#define BD_SYSFREQ 0x00000100 /* sys freq is set in nvram */
|
||||
#define BD_WLAN0 0x00000200 /* Enable WLAN0 */
|
||||
#define BD_MEMCAP 0x00000400 /* CAP SDRAM @ mem_cap for testing */
|
||||
#define BD_DISWATCHDOG 0x00000800 /* disable system watchdog */
|
||||
#define BD_WLAN1 0x00001000 /* Enable WLAN1 (ar5212) */
|
||||
#define BD_ISCASPER 0x00002000 /* FLAG for AR2312 */
|
||||
#define BD_WLAN0_2G_EN 0x00004000 /* FLAG for radio0_2G */
|
||||
#define BD_WLAN0_5G_EN 0x00008000 /* FLAG for radio0_2G */
|
||||
#define BD_WLAN1_2G_EN 0x00020000 /* FLAG for radio0_2G */
|
||||
#define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */
|
||||
u16 reset_config_gpio; /* Reset factory GPIO pin */
|
||||
u16 sys_led_gpio; /* System LED GPIO pin */
|
||||
|
||||
u32 cpu_freq; /* CPU core frequency in Hz */
|
||||
u32 sys_freq; /* System frequency in Hz */
|
||||
u32 cnt_freq; /* Calculated C0_COUNT frequency */
|
||||
|
||||
u8 wlan0_mac[ETH_ALEN];
|
||||
u8 enet0_mac[ETH_ALEN];
|
||||
u8 enet1_mac[ETH_ALEN];
|
||||
|
||||
u16 pci_id; /* Pseudo PCIID for common code */
|
||||
u16 mem_cap; /* cap bank1 in MB */
|
||||
|
||||
/* version 3 */
|
||||
u8 wlan1_mac[ETH_ALEN]; /* (ar5212) */
|
||||
};
|
||||
|
||||
#define BOARD_CONFIG_BUFSZ 0x1000
|
||||
|
||||
/*
|
||||
* Platform device information for the Wireless MAC
|
||||
*/
|
||||
struct ar231x_board_config {
|
||||
u16 devid;
|
||||
|
||||
/* board config data */
|
||||
struct ath25_boarddata *config;
|
||||
|
||||
/* radio calibration data */
|
||||
const char *radio;
|
||||
};
|
||||
|
||||
#endif /* __ASM_MACH_ATH25_PLATFORM_H */
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Atheros AR231x/AR531x SoC specific CPU feature overrides
|
||||
*
|
||||
* Copyright (C) 2008 Gabor Juhos <juhosg@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 __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H
|
||||
#define __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H
|
||||
|
||||
/*
|
||||
* The Atheros AR531x/AR231x SoCs have MIPS 4Kc/4KEc core.
|
||||
*/
|
||||
#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_ejtag 1
|
||||
|
||||
#if !defined(CONFIG_SOC_AR5312)
|
||||
# define cpu_has_llsc 1
|
||||
#else
|
||||
/*
|
||||
* The MIPS 4Kc V0.9 core in the AR5312/AR2312 have problems with the
|
||||
* ll/sc instructions.
|
||||
*/
|
||||
# define cpu_has_llsc 0
|
||||
#endif
|
||||
|
||||
#define cpu_has_mips16 0
|
||||
#define cpu_has_mdmx 0
|
||||
#define cpu_has_mips3d 0
|
||||
#define cpu_has_smartmips 0
|
||||
|
||||
#define cpu_has_mips32r1 1
|
||||
|
||||
#if !defined(CONFIG_SOC_AR5312)
|
||||
# define cpu_has_mips32r2 1
|
||||
#endif
|
||||
|
||||
#define cpu_has_mips64r1 0
|
||||
#define cpu_has_mips64r2 0
|
||||
|
||||
#define cpu_has_dsp 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
|
||||
|
||||
#endif /* __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H */
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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) 2006 Ralf Baechle <ralf@linux-mips.org>
|
||||
* Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
|
||||
*
|
||||
*/
|
||||
#ifndef __ASM_MACH_ATH25_DMA_COHERENCE_H
|
||||
#define __ASM_MACH_ATH25_DMA_COHERENCE_H
|
||||
|
||||
#include <linux/device.h>
|
||||
|
||||
/*
|
||||
* We need some arbitrary non-zero value to be programmed to the BAR1 register
|
||||
* of PCI host controller to enable DMA. The same value should be used as the
|
||||
* offset to calculate the physical address of DMA buffer for PCI devices.
|
||||
*/
|
||||
#define AR2315_PCI_HOST_SDRAM_BASEADDR 0x20000000
|
||||
|
||||
static inline dma_addr_t ath25_dev_offset(struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_PCI
|
||||
extern struct bus_type pci_bus_type;
|
||||
|
||||
if (dev && dev->bus == &pci_bus_type)
|
||||
return AR2315_PCI_HOST_SDRAM_BASEADDR;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline dma_addr_t
|
||||
plat_map_dma_mem(struct device *dev, void *addr, size_t size)
|
||||
{
|
||||
return virt_to_phys(addr) + ath25_dev_offset(dev);
|
||||
}
|
||||
|
||||
static inline dma_addr_t
|
||||
plat_map_dma_mem_page(struct device *dev, struct page *page)
|
||||
{
|
||||
return page_to_phys(page) + ath25_dev_offset(dev);
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr)
|
||||
{
|
||||
return dma_addr - ath25_dev_offset(dev);
|
||||
}
|
||||
|
||||
static inline void
|
||||
plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int plat_dma_supported(struct device *dev, u64 mask)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void plat_extra_sync_for_device(struct device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int plat_dma_mapping_error(struct device *dev,
|
||||
dma_addr_t dma_addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int plat_device_is_coherent(struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_DMA_COHERENT
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef CONFIG_DMA_NONCOHERENT
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* __ASM_MACH_ATH25_DMA_COHERENCE_H */
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef __ASM_MACH_ATH25_GPIO_H
|
||||
#define __ASM_MACH_ATH25_GPIO_H
|
||||
|
||||
#include <asm-generic/gpio.h>
|
||||
|
||||
#define gpio_get_value __gpio_get_value
|
||||
#define gpio_set_value __gpio_set_value
|
||||
#define gpio_cansleep __gpio_cansleep
|
||||
#define gpio_to_irq __gpio_to_irq
|
||||
|
||||
static inline int irq_to_gpio(unsigned irq)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#endif /* __ASM_MACH_ATH25_GPIO_H */
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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) 2008 Felix Fietkau <nbd@openwrt.org>
|
||||
*/
|
||||
#ifndef __ASM_MACH_ATH25_WAR_H
|
||||
#define __ASM_MACH_ATH25_WAR_H
|
||||
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
#define MIPS_CACHE_SYNC_WAR 0
|
||||
#define TX49XX_ICACHE_INDEX_INV_WAR 0
|
||||
#define RM9000_CDEX_SMP_WAR 0
|
||||
#define ICACHE_REFILLS_WORKAROUND_WAR 0
|
||||
#define R10000_LLSC_WAR 0
|
||||
#define MIPS34K_MISSED_ITLB_WAR 0
|
||||
|
||||
#endif /* __ASM_MACH_ATH25_WAR_H */
|
|
@ -11,10 +11,10 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
|
||||
#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI)
|
||||
extern phys_t __fixup_bigphys_addr(phys_t, phys_t);
|
||||
#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI)
|
||||
extern phys_addr_t __fixup_bigphys_addr(phys_addr_t, phys_addr_t);
|
||||
#else
|
||||
static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
|
||||
static inline phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
|
||||
{
|
||||
return phys_addr;
|
||||
}
|
||||
|
@ -23,12 +23,12 @@ static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
|
|||
/*
|
||||
* Allow physical addresses to be fixed up to help 36-bit peripherals.
|
||||
*/
|
||||
static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
|
||||
static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
|
||||
{
|
||||
return __fixup_bigphys_addr(phys_addr, size);
|
||||
}
|
||||
|
||||
static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
|
||||
static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
|
||||
unsigned long flags)
|
||||
{
|
||||
return NULL;
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
|
||||
* Copyright (C) 2009 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_MACH_BCM3384_DMA_COHERENCE_H
|
||||
#define __ASM_MACH_BCM3384_DMA_COHERENCE_H
|
||||
|
||||
struct device;
|
||||
|
||||
extern dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size);
|
||||
extern dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page);
|
||||
extern unsigned long plat_dma_addr_to_phys(struct device *dev,
|
||||
dma_addr_t dma_addr);
|
||||
|
||||
static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
|
||||
size_t size, enum dma_data_direction direction)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int plat_dma_supported(struct device *dev, u64 mask)
|
||||
{
|
||||
/*
|
||||
* we fall back to GFP_DMA when the mask isn't all 1s,
|
||||
* so we can't guarantee allocations that must be
|
||||
* within a tighter range than GFP_DMA..
|
||||
*/
|
||||
if (mask < DMA_BIT_MASK(24))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int plat_device_is_coherent(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __ASM_MACH_BCM3384_DMA_COHERENCE_H */
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
|
||||
*/
|
||||
#ifndef __ASM_MIPS_MACH_BCM3384_WAR_H
|
||||
#define __ASM_MIPS_MACH_BCM3384_WAR_H
|
||||
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
#define MIPS_CACHE_SYNC_WAR 0
|
||||
#define TX49XX_ICACHE_INDEX_INV_WAR 0
|
||||
#define ICACHE_REFILLS_WORKAROUND_WAR 0
|
||||
#define R10000_LLSC_WAR 0
|
||||
#define MIPS34K_MISSED_ITLB_WAR 0
|
||||
|
||||
#endif /* __ASM_MIPS_MACH_BCM3384_WAR_H */
|
|
@ -14,40 +14,8 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
struct nvram_header {
|
||||
u32 magic;
|
||||
u32 len;
|
||||
u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
|
||||
u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
|
||||
u32 config_ncdl; /* ncdl values for memc */
|
||||
};
|
||||
|
||||
#define NVRAM_HEADER 0x48534C46 /* 'FLSH' */
|
||||
#define NVRAM_VERSION 1
|
||||
#define NVRAM_HEADER_SIZE 20
|
||||
#define NVRAM_SPACE 0x8000
|
||||
|
||||
#define FLASH_MIN 0x00020000 /* Minimum flash size */
|
||||
|
||||
#define NVRAM_MAX_VALUE_LEN 255
|
||||
#define NVRAM_MAX_PARAM_LEN 64
|
||||
|
||||
extern int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len);
|
||||
|
||||
static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6])
|
||||
{
|
||||
if (strchr(buf, ':'))
|
||||
sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
|
||||
&macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
|
||||
&macaddr[5]);
|
||||
else if (strchr(buf, '-'))
|
||||
sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0],
|
||||
&macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
|
||||
&macaddr[5]);
|
||||
else
|
||||
printk(KERN_WARNING "Can not parse mac address: %s\n", buf);
|
||||
}
|
||||
|
||||
int bcm47xx_nvram_init_from_mem(u32 base, u32 lim);
|
||||
int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len);
|
||||
int bcm47xx_nvram_gpio_pin(const char *name);
|
||||
|
||||
#endif /* __BCM47XX_NVRAM_H */
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
|
||||
#include <bcm63xx_cpu.h>
|
||||
|
||||
static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
|
||||
static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
|
||||
{
|
||||
return phys_addr;
|
||||
}
|
||||
|
||||
static inline int is_bcm63xx_internal_registers(phys_t offset)
|
||||
static inline int is_bcm63xx_internal_registers(phys_addr_t offset)
|
||||
{
|
||||
switch (bcm63xx_get_cpu_id()) {
|
||||
case BCM3368_CPU_ID:
|
||||
|
@ -32,7 +32,7 @@ static inline int is_bcm63xx_internal_registers(phys_t offset)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
|
||||
static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
|
||||
unsigned long flags)
|
||||
{
|
||||
if (is_bcm63xx_internal_registers(offset))
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
* Allow physical addresses to be fixed up to help peripherals located
|
||||
* outside the low 32-bit range -- generic pass-through version.
|
||||
*/
|
||||
static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
|
||||
static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
|
||||
{
|
||||
return phys_addr;
|
||||
}
|
||||
|
||||
static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
|
||||
static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
|
||||
unsigned long flags)
|
||||
{
|
||||
return NULL;
|
||||
|
|
|
@ -36,4 +36,10 @@
|
|||
|
||||
#endif /* CONFIG_IRQ_CPU */
|
||||
|
||||
#ifdef CONFIG_MIPS_GIC
|
||||
#ifndef MIPS_GIC_IRQ_BASE
|
||||
#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
|
||||
#endif
|
||||
#endif /* CONFIG_MIPS_GIC */
|
||||
|
||||
#endif /* __ASM_MACH_GENERIC_IRQ_H */
|
||||
|
|
|
@ -48,6 +48,8 @@ extern struct clk *clk_get_ppe(void);
|
|||
extern unsigned char ltq_boot_select(void);
|
||||
/* find out what caused the last cpu reset */
|
||||
extern int ltq_reset_cause(void);
|
||||
/* find out the soc type */
|
||||
extern int ltq_soc_type(void);
|
||||
|
||||
#define IOPORT_RESOURCE_START 0x10000000
|
||||
#define IOPORT_RESOURCE_END 0xffffffff
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
#define VIDEO_ROM 7
|
||||
#define ADAPTER_ROM 8
|
||||
#define ACPI_TABLE 9
|
||||
#define MAX_MEMORY_TYPE 10
|
||||
#define SMBIOS_TABLE 10
|
||||
#define MAX_MEMORY_TYPE 11
|
||||
|
||||
#define LOONGSON3_BOOT_MEM_MAP_MAX 128
|
||||
struct efi_memory_map_loongson {
|
||||
|
@ -42,15 +43,49 @@ struct efi_cpuinfo_loongson {
|
|||
u32 processor_id; /* PRID, e.g. 6305, 6306 */
|
||||
u32 cputype; /* Loongson_3A/3B, etc. */
|
||||
u32 total_node; /* num of total numa nodes */
|
||||
u32 cpu_startup_core_id; /* Core id */
|
||||
u16 cpu_startup_core_id; /* Boot core id */
|
||||
u16 reserved_cores_mask;
|
||||
u32 cpu_clock_freq; /* cpu_clock */
|
||||
u32 nr_cpus;
|
||||
} __packed;
|
||||
|
||||
#define MAX_UARTS 64
|
||||
struct uart_device {
|
||||
u32 iotype; /* see include/linux/serial_core.h */
|
||||
u32 uartclk;
|
||||
u32 int_offset;
|
||||
u64 uart_base;
|
||||
} __packed;
|
||||
|
||||
#define MAX_SENSORS 64
|
||||
#define SENSOR_TEMPER 0x00000001
|
||||
#define SENSOR_VOLTAGE 0x00000002
|
||||
#define SENSOR_FAN 0x00000004
|
||||
struct sensor_device {
|
||||
char name[32]; /* a formal name */
|
||||
char label[64]; /* a flexible description */
|
||||
u32 type; /* SENSOR_* */
|
||||
u32 id; /* instance id of a sensor-class */
|
||||
u32 fan_policy; /* see loongson_hwmon.h */
|
||||
u32 fan_percent;/* only for constant speed policy */
|
||||
u64 base_addr; /* base address of device registers */
|
||||
} __packed;
|
||||
|
||||
struct system_loongson {
|
||||
u16 vers; /* version of system_loongson */
|
||||
u32 ccnuma_smp; /* 0: no numa; 1: has numa */
|
||||
u32 sing_double_channel; /* 1:single; 2:double */
|
||||
u32 nr_uarts;
|
||||
struct uart_device uarts[MAX_UARTS];
|
||||
u32 nr_sensors;
|
||||
struct sensor_device sensors[MAX_SENSORS];
|
||||
char has_ec;
|
||||
char ec_name[32];
|
||||
u64 ec_base_addr;
|
||||
char has_tcm;
|
||||
char tcm_name[32];
|
||||
u64 tcm_base_addr;
|
||||
u64 workarounds; /* see workarounds.h */
|
||||
} __packed;
|
||||
|
||||
struct irq_source_routing_table {
|
||||
|
@ -149,6 +184,8 @@ struct loongson_system_configuration {
|
|||
u32 nr_nodes;
|
||||
int cores_per_node;
|
||||
int cores_per_package;
|
||||
u16 boot_cpu_id;
|
||||
u16 reserved_cpus_mask;
|
||||
enum loongson_cpu_type cputype;
|
||||
u64 ht_control_base;
|
||||
u64 pci_mem_start_addr;
|
||||
|
@ -159,9 +196,15 @@ struct loongson_system_configuration {
|
|||
u64 suspend_addr;
|
||||
u64 vgabios_addr;
|
||||
u32 dma_mask_bits;
|
||||
char ecname[32];
|
||||
u32 nr_uarts;
|
||||
struct uart_device uarts[MAX_UARTS];
|
||||
u32 nr_sensors;
|
||||
struct sensor_device sensors[MAX_SENSORS];
|
||||
u64 workarounds;
|
||||
};
|
||||
|
||||
extern struct efi_memory_map_loongson *loongson_memmap;
|
||||
extern struct loongson_system_configuration loongson_sysconf;
|
||||
extern int cpuhotplug_workaround;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,7 +23,7 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
|
|||
size_t size)
|
||||
{
|
||||
#ifdef CONFIG_CPU_LOONGSON3
|
||||
return virt_to_phys(addr);
|
||||
return phys_to_dma(dev, virt_to_phys(addr));
|
||||
#else
|
||||
return virt_to_phys(addr) | 0x80000000;
|
||||
#endif
|
||||
|
@ -33,7 +33,7 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
|
|||
struct page *page)
|
||||
{
|
||||
#ifdef CONFIG_CPU_LOONGSON3
|
||||
return page_to_phys(page);
|
||||
return phys_to_dma(dev, page_to_phys(page));
|
||||
#else
|
||||
return page_to_phys(page) | 0x80000000;
|
||||
#endif
|
||||
|
@ -43,7 +43,7 @@ static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
|
|||
dma_addr_t dma_addr)
|
||||
{
|
||||
#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT)
|
||||
return dma_addr;
|
||||
return dma_to_phys(dev, dma_addr);
|
||||
#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
|
||||
return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff);
|
||||
#else
|
||||
|
|
|
@ -32,8 +32,7 @@
|
|||
#define LOONGSON_INT_ROUTER_LPC LOONGSON_INT_ROUTER_ENTRY(0x0a)
|
||||
#define LOONGSON_INT_ROUTER_HT1(n) LOONGSON_INT_ROUTER_ENTRY(n + 0x18)
|
||||
|
||||
#define LOONGSON_INT_CORE0_INT0 0x11 /* route to int 0 of core 0 */
|
||||
#define LOONGSON_INT_CORE0_INT1 0x21 /* route to int 1 of core 0 */
|
||||
#define LOONGSON_INT_COREx_INTy(x, y) (1<<(x) | 1<<(y+4)) /* route to int y of core x */
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ extern void __init prom_init_cmdline(void);
|
|||
extern void __init prom_init_machtype(void);
|
||||
extern void __init prom_init_env(void);
|
||||
#ifdef CONFIG_LOONGSON_UART_BASE
|
||||
extern unsigned long _loongson_uart_base, loongson_uart_base;
|
||||
extern unsigned long _loongson_uart_base[], loongson_uart_base[];
|
||||
extern void prom_init_loongson_uart_base(void);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef __LOONGSON_HWMON_H_
|
||||
#define __LOONGSON_HWMON_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define MIN_TEMP 0
|
||||
#define MAX_TEMP 255
|
||||
#define NOT_VALID_TEMP 999
|
||||
|
||||
typedef int (*get_temp_fun)(int);
|
||||
extern int loongson3_cpu_temp(int);
|
||||
|
||||
/* 0:Max speed, 1:Manual, 2:Auto */
|
||||
enum fan_control_mode {
|
||||
FAN_FULL_MODE = 0,
|
||||
FAN_MANUAL_MODE = 1,
|
||||
FAN_AUTO_MODE = 2,
|
||||
FAN_MODE_END
|
||||
};
|
||||
|
||||
struct temp_range {
|
||||
u8 low;
|
||||
u8 high;
|
||||
u8 level;
|
||||
};
|
||||
|
||||
#define CONSTANT_SPEED_POLICY 0 /* at constent speed */
|
||||
#define STEP_SPEED_POLICY 1 /* use up/down arrays to describe policy */
|
||||
#define KERNEL_HELPER_POLICY 2 /* kernel as a helper to fan control */
|
||||
|
||||
#define MAX_STEP_NUM 16
|
||||
#define MAX_FAN_LEVEL 255
|
||||
|
||||
/* loongson_fan_policy works when fan work at FAN_AUTO_MODE */
|
||||
struct loongson_fan_policy {
|
||||
u8 type;
|
||||
|
||||
/* percent only used when type is CONSTANT_SPEED_POLICY */
|
||||
u8 percent;
|
||||
|
||||
/* period between two check. (Unit: S) */
|
||||
u8 adjust_period;
|
||||
|
||||
/* fan adjust usually depend on a temprature input */
|
||||
get_temp_fun depend_temp;
|
||||
|
||||
/* up_step/down_step used when type is STEP_SPEED_POLICY */
|
||||
u8 up_step_num;
|
||||
u8 down_step_num;
|
||||
struct temp_range up_step[MAX_STEP_NUM];
|
||||
struct temp_range down_step[MAX_STEP_NUM];
|
||||
struct delayed_work work;
|
||||
};
|
||||
|
||||
#endif /* __LOONGSON_HWMON_H_*/
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#ifdef CONFIG_LOONGSON_MACH3X
|
||||
|
||||
#define LOONGSON_MACHTYPE MACH_LEMOTE_A1101
|
||||
#define LOONGSON_MACHTYPE MACH_LOONGSON_GENERIC
|
||||
|
||||
#endif /* CONFIG_LOONGSON_MACH3X */
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#ifdef CONFIG_NUMA
|
||||
|
||||
#define cpu_to_node(cpu) ((cpu) >> 2)
|
||||
#define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2)
|
||||
#define parent_node(node) (node)
|
||||
#define cpumask_of_node(node) (&__node_data[(node)]->cpumask)
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef __ASM_MACH_LOONGSON_WORKAROUNDS_H_
|
||||
#define __ASM_MACH_LOONGSON_WORKAROUNDS_H_
|
||||
|
||||
#define WORKAROUND_CPUFREQ 0x00000001
|
||||
#define WORKAROUND_CPUHOTPLUG 0x00000002
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com>
|
||||
*
|
||||
* Loongson 1 CPUFreq platform support.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __ASM_MACH_LOONGSON1_CPUFREQ_H
|
||||
#define __ASM_MACH_LOONGSON1_CPUFREQ_H
|
||||
|
||||
struct plat_ls1x_cpufreq {
|
||||
const char *clk_name; /* CPU clk */
|
||||
const char *osc_clk_name; /* OSC clk */
|
||||
unsigned int max_freq; /* in kHz */
|
||||
unsigned int min_freq; /* in kHz */
|
||||
};
|
||||
|
||||
#endif /* __ASM_MACH_LOONGSON1_CPUFREQ_H */
|
|
@ -16,6 +16,7 @@
|
|||
#define DEFAULT_MEMSIZE 256 /* If no memsize provided */
|
||||
|
||||
/* Loongson 1 Register Bases */
|
||||
#define LS1X_MUX_BASE 0x1fd00420
|
||||
#define LS1X_INTC_BASE 0x1fd01040
|
||||
#define LS1X_EHCI_BASE 0x1fe00000
|
||||
#define LS1X_OHCI_BASE 0x1fe08000
|
||||
|
@ -31,7 +32,10 @@
|
|||
#define LS1X_I2C0_BASE 0x1fe58000
|
||||
#define LS1X_I2C1_BASE 0x1fe68000
|
||||
#define LS1X_I2C2_BASE 0x1fe70000
|
||||
#define LS1X_PWM_BASE 0x1fe5c000
|
||||
#define LS1X_PWM0_BASE 0x1fe5c000
|
||||
#define LS1X_PWM1_BASE 0x1fe5c010
|
||||
#define LS1X_PWM2_BASE 0x1fe5c020
|
||||
#define LS1X_PWM3_BASE 0x1fe5c030
|
||||
#define LS1X_WDT_BASE 0x1fe5c060
|
||||
#define LS1X_RTC_BASE 0x1fe64000
|
||||
#define LS1X_AC97_BASE 0x1fe74000
|
||||
|
@ -39,6 +43,8 @@
|
|||
#define LS1X_CLK_BASE 0x1fe78030
|
||||
|
||||
#include <regs-clk.h>
|
||||
#include <regs-mux.h>
|
||||
#include <regs-pwm.h>
|
||||
#include <regs-wdt.h>
|
||||
|
||||
#endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */
|
||||
|
|
|
@ -13,10 +13,12 @@
|
|||
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
extern struct platform_device ls1x_uart_device;
|
||||
extern struct platform_device ls1x_eth0_device;
|
||||
extern struct platform_device ls1x_ehci_device;
|
||||
extern struct platform_device ls1x_rtc_device;
|
||||
extern struct platform_device ls1x_uart_pdev;
|
||||
extern struct platform_device ls1x_cpufreq_pdev;
|
||||
extern struct platform_device ls1x_eth0_pdev;
|
||||
extern struct platform_device ls1x_eth1_pdev;
|
||||
extern struct platform_device ls1x_ehci_pdev;
|
||||
extern struct platform_device ls1x_rtc_pdev;
|
||||
|
||||
extern void __init ls1x_clk_init(void);
|
||||
extern void __init ls1x_serial_setup(struct platform_device *pdev);
|
||||
|
|
|
@ -20,15 +20,32 @@
|
|||
|
||||
/* Clock PLL Divisor Register Bits */
|
||||
#define DIV_DC_EN (0x1 << 31)
|
||||
#define DIV_DC_RST (0x1 << 30)
|
||||
#define DIV_CPU_EN (0x1 << 25)
|
||||
#define DIV_CPU_RST (0x1 << 24)
|
||||
#define DIV_DDR_EN (0x1 << 19)
|
||||
#define DIV_DDR_RST (0x1 << 18)
|
||||
#define RST_DC_EN (0x1 << 5)
|
||||
#define RST_DC (0x1 << 4)
|
||||
#define RST_DDR_EN (0x1 << 3)
|
||||
#define RST_DDR (0x1 << 2)
|
||||
#define RST_CPU_EN (0x1 << 1)
|
||||
#define RST_CPU 0x1
|
||||
|
||||
#define DIV_DC_SHIFT 26
|
||||
#define DIV_CPU_SHIFT 20
|
||||
#define DIV_DDR_SHIFT 14
|
||||
|
||||
#define DIV_DC_WIDTH 5
|
||||
#define DIV_CPU_WIDTH 5
|
||||
#define DIV_DDR_WIDTH 5
|
||||
#define DIV_DC_WIDTH 4
|
||||
#define DIV_CPU_WIDTH 4
|
||||
#define DIV_DDR_WIDTH 4
|
||||
|
||||
#define BYPASS_DC_SHIFT 12
|
||||
#define BYPASS_DDR_SHIFT 10
|
||||
#define BYPASS_CPU_SHIFT 8
|
||||
|
||||
#define BYPASS_DC_WIDTH 1
|
||||
#define BYPASS_DDR_WIDTH 1
|
||||
#define BYPASS_CPU_WIDTH 1
|
||||
|
||||
#endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com>
|
||||
*
|
||||
* Loongson 1 MUX Register Definitions.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_MACH_LOONGSON1_REGS_MUX_H
|
||||
#define __ASM_MACH_LOONGSON1_REGS_MUX_H
|
||||
|
||||
#define LS1X_MUX_REG(x) \
|
||||
((void __iomem *)KSEG1ADDR(LS1X_MUX_BASE + (x)))
|
||||
|
||||
#define LS1X_MUX_CTRL0 LS1X_MUX_REG(0x0)
|
||||
#define LS1X_MUX_CTRL1 LS1X_MUX_REG(0x4)
|
||||
|
||||
/* MUX CTRL0 Register Bits */
|
||||
#define UART0_USE_PWM23 (0x1 << 28)
|
||||
#define UART0_USE_PWM01 (0x1 << 27)
|
||||
#define UART1_USE_LCD0_5_6_11 (0x1 << 26)
|
||||
#define I2C2_USE_CAN1 (0x1 << 25)
|
||||
#define I2C1_USE_CAN0 (0x1 << 24)
|
||||
#define NAND3_USE_UART5 (0x1 << 23)
|
||||
#define NAND3_USE_UART4 (0x1 << 22)
|
||||
#define NAND3_USE_UART1_DAT (0x1 << 21)
|
||||
#define NAND3_USE_UART1_CTS (0x1 << 20)
|
||||
#define NAND3_USE_PWM23 (0x1 << 19)
|
||||
#define NAND3_USE_PWM01 (0x1 << 18)
|
||||
#define NAND2_USE_UART5 (0x1 << 17)
|
||||
#define NAND2_USE_UART4 (0x1 << 16)
|
||||
#define NAND2_USE_UART1_DAT (0x1 << 15)
|
||||
#define NAND2_USE_UART1_CTS (0x1 << 14)
|
||||
#define NAND2_USE_PWM23 (0x1 << 13)
|
||||
#define NAND2_USE_PWM01 (0x1 << 12)
|
||||
#define NAND1_USE_UART5 (0x1 << 11)
|
||||
#define NAND1_USE_UART4 (0x1 << 10)
|
||||
#define NAND1_USE_UART1_DAT (0x1 << 9)
|
||||
#define NAND1_USE_UART1_CTS (0x1 << 8)
|
||||
#define NAND1_USE_PWM23 (0x1 << 7)
|
||||
#define NAND1_USE_PWM01 (0x1 << 6)
|
||||
#define GMAC1_USE_UART1 (0x1 << 4)
|
||||
#define GMAC1_USE_UART0 (0x1 << 3)
|
||||
#define LCD_USE_UART0_DAT (0x1 << 2)
|
||||
#define LCD_USE_UART15 (0x1 << 1)
|
||||
#define LCD_USE_UART0 0x1
|
||||
|
||||
/* MUX CTRL1 Register Bits */
|
||||
#define USB_RESET (0x1 << 31)
|
||||
#define SPI1_CS_USE_PWM01 (0x1 << 24)
|
||||
#define SPI1_USE_CAN (0x1 << 23)
|
||||
#define DISABLE_DDR_CONFSPACE (0x1 << 20)
|
||||
#define DDR32TO16EN (0x1 << 16)
|
||||
#define GMAC1_SHUT (0x1 << 13)
|
||||
#define GMAC0_SHUT (0x1 << 12)
|
||||
#define USB_SHUT (0x1 << 11)
|
||||
#define UART1_3_USE_CAN1 (0x1 << 5)
|
||||
#define UART1_2_USE_CAN0 (0x1 << 4)
|
||||
#define GMAC1_USE_TXCLK (0x1 << 3)
|
||||
#define GMAC0_USE_TXCLK (0x1 << 2)
|
||||
#define GMAC1_USE_PWM23 (0x1 << 1)
|
||||
#define GMAC0_USE_PWM01 0x1
|
||||
|
||||
#endif /* __ASM_MACH_LOONGSON1_REGS_MUX_H */
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com>
|
||||
*
|
||||
* Loongson 1 PWM Register Definitions.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_MACH_LOONGSON1_REGS_PWM_H
|
||||
#define __ASM_MACH_LOONGSON1_REGS_PWM_H
|
||||
|
||||
/* Loongson 1 PWM Timer Register Definitions */
|
||||
#define PWM_CNT 0x0
|
||||
#define PWM_HRC 0x4
|
||||
#define PWM_LRC 0x8
|
||||
#define PWM_CTRL 0xc
|
||||
|
||||
/* PWM Control Register Bits */
|
||||
#define CNT_RST (0x1 << 7)
|
||||
#define INT_SR (0x1 << 6)
|
||||
#define INT_EN (0x1 << 5)
|
||||
#define PWM_SINGLE (0x1 << 4)
|
||||
#define PWM_OE (0x1 << 3)
|
||||
#define CNT_EN 0x1
|
||||
|
||||
#endif /* __ASM_MACH_LOONGSON1_REGS_PWM_H */
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
|
||||
*
|
||||
* Loongson 1 watchdog register definitions.
|
||||
* Loongson 1 Watchdog Register Definitions.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
|
@ -12,11 +12,8 @@
|
|||
#ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H
|
||||
#define __ASM_MACH_LOONGSON1_REGS_WDT_H
|
||||
|
||||
#define LS1X_WDT_REG(x) \
|
||||
((void __iomem *)KSEG1ADDR(LS1X_WDT_BASE + (x)))
|
||||
|
||||
#define LS1X_WDT_EN LS1X_WDT_REG(0x0)
|
||||
#define LS1X_WDT_SET LS1X_WDT_REG(0x4)
|
||||
#define LS1X_WDT_TIMER LS1X_WDT_REG(0x8)
|
||||
#define WDT_EN 0x0
|
||||
#define WDT_TIMER 0x4
|
||||
#define WDT_SET 0x8
|
||||
|
||||
#endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define __ASM_MACH_MIPS_IRQ_H
|
||||
|
||||
|
||||
#define GIC_NUM_INTRS (24 + NR_CPUS * 2)
|
||||
#define NR_IRQS 256
|
||||
|
||||
#include_next <irq.h>
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/compiler.h>
|
||||
#include <asm/war.h>
|
||||
|
||||
#ifndef R10000_LLSC_WAR
|
||||
|
@ -84,8 +85,8 @@ static inline void set_value_reg32(volatile u32 *const addr,
|
|||
" "__beqz"%0, 1b \n"
|
||||
" nop \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "=m" (*addr)
|
||||
: "ir" (~mask), "ir" (value), "m" (*addr));
|
||||
: "=&r" (temp), "=" GCC_OFF12_ASM() (*addr)
|
||||
: "ir" (~mask), "ir" (value), GCC_OFF12_ASM() (*addr));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -105,8 +106,8 @@ static inline void set_reg32(volatile u32 *const addr,
|
|||
" "__beqz"%0, 1b \n"
|
||||
" nop \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "=m" (*addr)
|
||||
: "ir" (mask), "m" (*addr));
|
||||
: "=&r" (temp), "=" GCC_OFF12_ASM() (*addr)
|
||||
: "ir" (mask), GCC_OFF12_ASM() (*addr));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -126,8 +127,8 @@ static inline void clear_reg32(volatile u32 *const addr,
|
|||
" "__beqz"%0, 1b \n"
|
||||
" nop \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "=m" (*addr)
|
||||
: "ir" (~mask), "m" (*addr));
|
||||
: "=&r" (temp), "=" GCC_OFF12_ASM() (*addr)
|
||||
: "ir" (~mask), GCC_OFF12_ASM() (*addr));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -147,8 +148,8 @@ static inline void toggle_reg32(volatile u32 *const addr,
|
|||
" "__beqz"%0, 1b \n"
|
||||
" nop \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "=m" (*addr)
|
||||
: "ir" (mask), "m" (*addr));
|
||||
: "=&r" (temp), "=" GCC_OFF12_ASM() (*addr)
|
||||
: "ir" (mask), GCC_OFF12_ASM() (*addr));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -219,8 +220,8 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr)
|
|||
" .set arch=r4000 \n" \
|
||||
"1: ll %0, %1 #custom_read_reg32 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (tmp), "=m" (*address) \
|
||||
: "m" (*address))
|
||||
: "=r" (tmp), "=" GCC_OFF12_ASM() (*address) \
|
||||
: GCC_OFF12_ASM() (*address))
|
||||
|
||||
#define custom_write_reg32(address, tmp) \
|
||||
__asm__ __volatile__( \
|
||||
|
@ -230,7 +231,7 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr)
|
|||
" "__beqz"%0, 1b \n" \
|
||||
" nop \n" \
|
||||
" .set pop \n" \
|
||||
: "=&r" (tmp), "=m" (*address) \
|
||||
: "0" (tmp), "m" (*address))
|
||||
: "=&r" (tmp), "=" GCC_OFF12_ASM() (*address) \
|
||||
: "0" (tmp), GCC_OFF12_ASM() (*address))
|
||||
|
||||
#endif /* __ASM_REGOPS_H__ */
|
||||
|
|
|
@ -13,6 +13,13 @@
|
|||
#ifndef _MT7620_REGS_H_
|
||||
#define _MT7620_REGS_H_
|
||||
|
||||
enum mt762x_soc_type {
|
||||
MT762X_SOC_UNKNOWN = 0,
|
||||
MT762X_SOC_MT7620A,
|
||||
MT762X_SOC_MT7620N,
|
||||
MT762X_SOC_MT7628AN,
|
||||
};
|
||||
|
||||
#define MT7620_SYSC_BASE 0x10000000
|
||||
|
||||
#define SYSC_REG_CHIP_NAME0 0x00
|
||||
|
@ -25,11 +32,9 @@
|
|||
#define SYSC_REG_CPLL_CONFIG0 0x54
|
||||
#define SYSC_REG_CPLL_CONFIG1 0x58
|
||||
|
||||
#define MT7620N_CHIP_NAME0 0x33365452
|
||||
#define MT7620N_CHIP_NAME1 0x20203235
|
||||
|
||||
#define MT7620A_CHIP_NAME0 0x3637544d
|
||||
#define MT7620A_CHIP_NAME1 0x20203032
|
||||
#define MT7620_CHIP_NAME0 0x3637544d
|
||||
#define MT7620_CHIP_NAME1 0x20203032
|
||||
#define MT7628_CHIP_NAME1 0x20203832
|
||||
|
||||
#define SYSCFG0_XTAL_FREQ_SEL BIT(6)
|
||||
|
||||
|
@ -74,6 +79,9 @@
|
|||
#define SYSCFG0_DRAM_TYPE_DDR1 1
|
||||
#define SYSCFG0_DRAM_TYPE_DDR2 2
|
||||
|
||||
#define SYSCFG0_DRAM_TYPE_DDR2_MT7628 0
|
||||
#define SYSCFG0_DRAM_TYPE_DDR1_MT7628 1
|
||||
|
||||
#define MT7620_DRAM_BASE 0x0
|
||||
#define MT7620_SDRAM_SIZE_MIN 2
|
||||
#define MT7620_SDRAM_SIZE_MAX 64
|
||||
|
@ -82,7 +90,6 @@
|
|||
#define MT7620_DDR2_SIZE_MIN 32
|
||||
#define MT7620_DDR2_SIZE_MAX 256
|
||||
|
||||
#define MT7620_GPIO_MODE_I2C BIT(0)
|
||||
#define MT7620_GPIO_MODE_UART0_SHIFT 2
|
||||
#define MT7620_GPIO_MODE_UART0_MASK 0x7
|
||||
#define MT7620_GPIO_MODE_UART0(x) ((x) << MT7620_GPIO_MODE_UART0_SHIFT)
|
||||
|
@ -94,15 +101,40 @@
|
|||
#define MT7620_GPIO_MODE_GPIO_UARTF 0x5
|
||||
#define MT7620_GPIO_MODE_GPIO_I2S 0x6
|
||||
#define MT7620_GPIO_MODE_GPIO 0x7
|
||||
#define MT7620_GPIO_MODE_UART1 BIT(5)
|
||||
#define MT7620_GPIO_MODE_MDIO BIT(8)
|
||||
#define MT7620_GPIO_MODE_RGMII1 BIT(9)
|
||||
#define MT7620_GPIO_MODE_RGMII2 BIT(10)
|
||||
#define MT7620_GPIO_MODE_SPI BIT(11)
|
||||
#define MT7620_GPIO_MODE_SPI_REF_CLK BIT(12)
|
||||
#define MT7620_GPIO_MODE_WLED BIT(13)
|
||||
#define MT7620_GPIO_MODE_JTAG BIT(15)
|
||||
#define MT7620_GPIO_MODE_EPHY BIT(15)
|
||||
#define MT7620_GPIO_MODE_WDT BIT(22)
|
||||
|
||||
#define MT7620_GPIO_MODE_NAND 0
|
||||
#define MT7620_GPIO_MODE_SD 1
|
||||
#define MT7620_GPIO_MODE_ND_SD_GPIO 2
|
||||
#define MT7620_GPIO_MODE_ND_SD_MASK 0x3
|
||||
#define MT7620_GPIO_MODE_ND_SD_SHIFT 18
|
||||
|
||||
#define MT7620_GPIO_MODE_PCIE_RST 0
|
||||
#define MT7620_GPIO_MODE_PCIE_REF 1
|
||||
#define MT7620_GPIO_MODE_PCIE_GPIO 2
|
||||
#define MT7620_GPIO_MODE_PCIE_MASK 0x3
|
||||
#define MT7620_GPIO_MODE_PCIE_SHIFT 16
|
||||
|
||||
#define MT7620_GPIO_MODE_WDT_RST 0
|
||||
#define MT7620_GPIO_MODE_WDT_REF 1
|
||||
#define MT7620_GPIO_MODE_WDT_GPIO 2
|
||||
#define MT7620_GPIO_MODE_WDT_MASK 0x3
|
||||
#define MT7620_GPIO_MODE_WDT_SHIFT 21
|
||||
|
||||
#define MT7620_GPIO_MODE_I2C 0
|
||||
#define MT7620_GPIO_MODE_UART1 5
|
||||
#define MT7620_GPIO_MODE_MDIO 8
|
||||
#define MT7620_GPIO_MODE_RGMII1 9
|
||||
#define MT7620_GPIO_MODE_RGMII2 10
|
||||
#define MT7620_GPIO_MODE_SPI 11
|
||||
#define MT7620_GPIO_MODE_SPI_REF_CLK 12
|
||||
#define MT7620_GPIO_MODE_WLED 13
|
||||
#define MT7620_GPIO_MODE_JTAG 15
|
||||
#define MT7620_GPIO_MODE_EPHY 15
|
||||
#define MT7620_GPIO_MODE_PA 20
|
||||
|
||||
static inline int mt7620_get_eco(void)
|
||||
{
|
||||
return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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
|
||||
* publishhed by the Free Software Foundation.
|
||||
*
|
||||
* Copyright (C) 2012 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#ifndef _RT288X_PINMUX_H__
|
||||
#define _RT288X_PINMUX_H__
|
||||
|
||||
#define FUNC(name, value, pin_first, pin_count) \
|
||||
{ name, value, pin_first, pin_count }
|
||||
|
||||
#define GRP(_name, _func, _mask, _shift) \
|
||||
{ .name = _name, .mask = _mask, .shift = _shift, \
|
||||
.func = _func, .gpio = _mask, \
|
||||
.func_count = ARRAY_SIZE(_func) }
|
||||
|
||||
#define GRP_G(_name, _func, _mask, _gpio, _shift) \
|
||||
{ .name = _name, .mask = _mask, .shift = _shift, \
|
||||
.func = _func, .gpio = _gpio, \
|
||||
.func_count = ARRAY_SIZE(_func) }
|
||||
|
||||
struct rt2880_pmx_group;
|
||||
|
||||
struct rt2880_pmx_func {
|
||||
const char *name;
|
||||
const char value;
|
||||
|
||||
int pin_first;
|
||||
int pin_count;
|
||||
int *pins;
|
||||
|
||||
int *groups;
|
||||
int group_count;
|
||||
|
||||
int enabled;
|
||||
};
|
||||
|
||||
struct rt2880_pmx_group {
|
||||
const char *name;
|
||||
int enabled;
|
||||
|
||||
const u32 shift;
|
||||
const char mask;
|
||||
const char gpio;
|
||||
|
||||
struct rt2880_pmx_func *func;
|
||||
int func_count;
|
||||
};
|
||||
|
||||
extern struct rt2880_pmx_group *rt2880_pinmux_data;
|
||||
|
||||
#endif
|
|
@ -26,6 +26,13 @@ static inline u32 rt_sysc_r32(unsigned reg)
|
|||
return __raw_readl(rt_sysc_membase + reg);
|
||||
}
|
||||
|
||||
static inline void rt_sysc_m32(u32 clr, u32 set, unsigned reg)
|
||||
{
|
||||
u32 val = rt_sysc_r32(reg) & ~clr;
|
||||
|
||||
__raw_writel(val | set, rt_sysc_membase + reg);
|
||||
}
|
||||
|
||||
static inline void rt_memc_w32(u32 val, unsigned reg)
|
||||
{
|
||||
__raw_writel(val, rt_memc_membase + reg);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue