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

Pull MIPS updates from Ralf Baechle:
 "This is the main pull request for MIPS for 4.7.  Here's the summary of
  the changes:

   - ATH79: Support for DTB passuing using the UHI boot protocol
   - ATH79: Remove support for builtin DTB.
   - ATH79: Add zboot debug serial support.
   - ATH79: Add initial support for Dragino MS14 (Dragine 2), Onion Omega
            and DPT-Module.
   - ATH79: Update devicetree clock support for AR9132 and AR9331.
   - ATH79: Cleanup the DT code.
   - ATH79: Support newer SOCs in ath79_ddr_ctrl_init.
   - ATH79: Fix regression in PCI window initialization.
   - BCM47xx: Move SPROM driver to drivers/firmware/
   - BCM63xx: Enable partition parser in defconfig.
   - BMIPS: BMIPS5000 has I cache filing from D cache
   - BMIPS: BMIPS: Add cpu-feature-overrides.h
   - BMIPS: Add Whirlwind support
   - BMIPS: Adjust mips-hpt-frequency for BCM7435
   - BMIPS: Remove maxcpus from BCM97435SVMB DTS
   - BMIPS: Add missing 7038 L1 register cells to BCM7435
   - BMIPS: Various tweaks to initialization code.
   - BMIPS: Enable partition parser in defconfig.
   - BMIPS: Cache tweaks.
   - BMIPS: Add UART, I2C and SATA devices to DT.
   - BMIPS: Add BCM6358 and BCM63268support
   - BMIPS: Add device tree example for BCM6358.
   - BMIPS: Improve Improve BCM6328 and BCM6368 device trees
   - Lantiq: Add support for device tree file from boot loader
   - Lantiq: Allow build with no built-in DT.
   - Loongson 3: Reserve 32MB for RS780E integrated GPU.
   - Loongson 3: Fix build error after ld-version.sh modification
   - Loongson 3: Move chipset ACPI code from drivers to arch.
   - Loongson 3: Speedup irq processing.
   - Loongson 3: Add basic Loongson 3A support.
   - Loongson 3: Set cache flush handlers to nop.
   - Loongson 3: Invalidate special TLBs when needed.
   - Loongson 3: Fast TLB refill handler.
   - MT7620: Fallback strategy for invalid syscfg0.
   - Netlogic: Fix CP0_EBASE redefinition warnings
   - Octeon: Initialization fixes
   - Octeon: Add DTS files for the D-Link DSR-1000N and EdgeRouter Lite
   - Octeon: Enable add Octeon-drivers in cavium_octeon_defconfig
   - Octeon: Correctly handle endian-swapped initramfs images.
   - Octeon: Support CN73xx, CN75xx and CN78xx.
   - Octeon: Remove dead code from cvmx-sysinfo.
   - Octeon: Extend number of supported CPUs past 32.
   - Octeon: Remove some code limiting NR_IRQS to 255.
   - Octeon: Simplify octeon_irq_ciu_gpio_set_type.
   - Octeon: Mark some functions __init in smp.c
   - Octeon: Octeon: Add Octeon III CN7xxx interface detection
   - PIC32: Add serial driver and bindings for it.
   - PIC32: Add PIC32 deadman timer driver and bindings.
   - PIC32: Add PIC32 clock timer driver and bindings.
   - Pistachio: Determine SoC revision during boot
   - Sibyte: Fix Kconfig dependencies of SIBYTE_BUS_WATCHER.
   - Sibyte: Strip redundant comments from bcm1480_regs.h.
   - Panic immediately if panic_on_oops is set.
   - module: fix incorrect IS_ERR_VALUE macro usage.
   - module: Make consistent use of pr_*
   - Remove no longer needed work_on_cpu() call.
   - Remove CONFIG_IPV6_PRIVACY from defconfigs.
   - Fix registers of non-crashing CPUs in dumps.
   - Handle MIPSisms in new vmcore_elf32_check_arch.
   - Select CONFIG_HANDLE_DOMAIN_IRQ and make it work.
   - Allow RIXI to be used on non-R2 or R6 cores.
   - Reserve nosave data for hibernation
   - Fix siginfo.h to use strict POSIX types.
   - Don't unwind user mode with EVA.
   - Fix watchpoint restoration
   - Ptrace watchpoints for R6.
   - Sync icache when it fills from dcache
   - I6400 I-cache fills from dcache.
   - Various MSA fixes.
   - Cleanup MIPS_CPU_* definitions.
   - Signal: Move generic copy_siginfo to signal.h
   - Signal: Fix uapi include in exported asm/siginfo.h
   - Timer fixes for sake of KVM.
   - XPA TLB refill fixes.
   - Treat perf counter feature
   - Update John Crispin's email address
   - Add PIC32 watchdog and bindings.
   - Handle R10000 LL/SC bug in set_pte()
   - cpufreq: Various fixes for Longson1.
   - R6: Fix R2 emulation.
   - mathemu: Cosmetic fix to ADDIUPC emulation, plenty of other small fixes
   - ELF: ABI and FP fixes.
   - Allow for relocatable kernel and use that to support KASLR.
   - Fix CPC_BASE_ADDR mask
   - Plenty fo smp-cps, CM, R6 and M6250 fixes.
   - Make reset_control_ops const.
   - Fix kernel command line handling of leading whitespace.
   - Cleanups to cache handling.
   - Add brcm, bcm6345-l1-intc device tree bindings.
   - Use generic clkdev.h header
   - Remove CLK_IS_ROOT usage.
   - Misc small cleanups.
   - CM: Fix compilation error when !MIPS_CM
   - oprofile: Fix a preemption issue
   - Detect DSP ASE v3 support:1"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (275 commits)
  MIPS: pic32mzda: fix getting timer clock rate.
  MIPS: ath79: fix regression in PCI window initialization
  MIPS: ath79: make ath79_ddr_ctrl_init() compatible for newer SoCs
  MIPS: Fix VZ probe gas errors with binutils <2.24
  MIPS: perf: Fix I6400 event numbers
  MIPS: DEC: Export `ioasic_ssr_lock' to modules
  MIPS: MSA: Fix a link error on `_init_msa_upper' with older GCC
  MIPS: CM: Fix compilation error when !MIPS_CM
  MIPS: Fix genvdso error on rebuild
  USB: ohci-jz4740: Remove obsolete driver
  MIPS: JZ4740: Probe OHCI platform device via DT
  MIPS: JZ4740: Qi LB60: Remove support for AVT2 variant
  MIPS: pistachio: Determine SoC revision during boot
  MIPS: BMIPS: Adjust mips-hpt-frequency for BCM7435
  mips: mt7620: fallback to SDRAM when syscfg0 does not have a valid value for the memory type
  MIPS: Prevent "restoration" of MSA context in non-MSA kernels
  MIPS: cevt-r4k: Dynamically calculate min_delta_ns
  MIPS: malta-time: Take seconds into account
  MIPS: malta-time: Start GIC count before syncing to RTC
  MIPS: Force CPUs to lose FP context during mode switches
  ...
This commit is contained in:
Linus Torvalds 2016-05-19 10:02:26 -07:00
commit 07b75260eb
358 changed files with 14041 additions and 3435 deletions

View File

@ -0,0 +1,39 @@
Microchip PIC32 Clock Controller Binding
----------------------------------------
Microchip clock controller is consists of few oscillators, PLL, multiplexer
and few divider modules.
This binding uses common clock bindings.
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible: shall be "microchip,pic32mzda-clk".
- reg: shall contain base address and length of clock registers.
- #clock-cells: shall be 1.
Optional properties:
- microchip,pic32mzda-sosc: shall be added only if platform has
secondary oscillator connected.
Example:
rootclk: clock-controller@1f801200 {
compatible = "microchip,pic32mzda-clk";
reg = <0x1f801200 0x200>;
#clock-cells = <1>;
/* optional */
microchip,pic32mzda-sosc;
};
The clock consumer shall specify the desired clock-output of the clock
controller (as defined in [2]) by specifying output-id in its "clock"
phandle cell.
[2] include/dt-bindings/clock/microchip,pic32-clock.h
For example for UART2:
uart2: serial@2 {
compatible = "microchip,pic32mzda-uart";
reg = <>;
interrupts = <>;
clocks = <&rootclk PB2CLK>;
};

View File

@ -0,0 +1,57 @@
Broadcom BCM6345-style Level 1 interrupt controller
This block is a first level interrupt controller that is typically connected
directly to one of the HW INT lines on each CPU.
Key elements of the hardware design include:
- 32, 64 or 128 incoming level IRQ lines
- Most onchip peripherals are wired directly to an L1 input
- A separate instance of the register set for each CPU, allowing individual
peripheral IRQs to be routed to any CPU
- Contains one or more enable/status word pairs per CPU
- No atomic set/clear operations
- No polarity/level/edge settings
- No FIFO or priority encoder logic; software is expected to read all
2-4 status words to determine which IRQs are pending
Required properties:
- compatible: should be "brcm,bcm<soc>-l1-intc", "brcm,bcm6345-l1-intc"
- reg: specifies the base physical address and size of the registers;
the number of supported IRQs is inferred from the size argument
- interrupt-controller: identifies the node as an interrupt controller
- #interrupt-cells: specifies the number of cells needed to encode an interrupt
source, should be 1.
- interrupt-parent: specifies the phandle to the parent interrupt controller(s)
this one is cascaded from
- interrupts: specifies the interrupt line(s) in the interrupt-parent controller
node; valid values depend on the type of parent interrupt controller
If multiple reg ranges and interrupt-parent entries are present on an SMP
system, the driver will allow IRQ SMP affinity to be set up through the
/proc/irq/ interface. In the simplest possible configuration, only one
reg range and one interrupt-parent is needed.
The driver operates in native CPU endian by default, there is no support for
specifying an alternative endianness.
Example:
periph_intc: interrupt-controller@10000000 {
compatible = "brcm,bcm63168-l1-intc", "brcm,bcm6345-l1-intc";
reg = <0x10000020 0x20>,
<0x10000040 0x20>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&cpu_intc>;
interrupts = <2>, <3>;
};

View File

@ -4,7 +4,8 @@ Required properties:
- compatible: "brcm,bcm3384", "brcm,bcm33843"
"brcm,bcm3384-viper", "brcm,bcm33843-viper"
"brcm,bcm6328", "brcm,bcm6368",
"brcm,bcm6328", "brcm,bcm6358", "brcm,bcm6368",
"brcm,bcm63168", "brcm,bcm63268",
"brcm,bcm7125", "brcm,bcm7346", "brcm,bcm7358", "brcm,bcm7360",
"brcm,bcm7362", "brcm,bcm7420", "brcm,bcm7425"

View File

@ -0,0 +1,27 @@
* Central Interrupt Unit v3
Properties:
- compatible: "cavium,octeon-7890-ciu3"
Compatibility with 78XX and 73XX SOCs.
- interrupt-controller: This is an interrupt controller.
- reg: The base address of the CIU's register bank.
- #interrupt-cells: Must be <2>. The first cell is source number.
The second cell indicates the triggering semantics, and may have a
value of either 4 for level semantics, or 1 for edge semantics.
Example:
interrupt-controller@1010000000000 {
compatible = "cavium,octeon-7890-ciu3";
interrupt-controller;
/* Interrupts are specified by two parts:
* 1) Source number (20 significant bits)
* 2) Trigger type: (4 == level, 1 == edge)
*/
#address-cells = <0>;
#interrupt-cells = <2>;
reg = <0x10100 0x00000000 0x0 0xb0000000>;
};

View File

@ -0,0 +1,29 @@
* Microchip Universal Asynchronous Receiver Transmitter (UART)
Required properties:
- compatible: Should be "microchip,pic32mzda-uart"
- reg: Should contain registers location and length
- interrupts: Should contain interrupt
- clocks: Phandle to the clock.
See: Documentation/devicetree/bindings/clock/clock-bindings.txt
- pinctrl-names: A pinctrl state names "default" must be defined.
- pinctrl-0: Phandle referencing pin configuration of the UART peripheral.
See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt
Optional properties:
- cts-gpios: CTS pin for UART
Example:
uart1: serial@1f822000 {
compatible = "microchip,pic32mzda-uart";
reg = <0x1f822000 0x50>;
interrupts = <112 IRQ_TYPE_LEVEL_HIGH>,
<113 IRQ_TYPE_LEVEL_HIGH>,
<114 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&PBCLK2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1
&pinctrl_uart1_cts
&pinctrl_uart1_rts>;
cts-gpios = <&gpio1 15 0>;
};

View File

@ -72,6 +72,8 @@ digilent Diglent, Inc.
dlg Dialog Semiconductor
dlink D-Link Corporation
dmo Data Modul AG
dptechnics DPTechnics
dragino Dragino Technology Co., Limited
ea Embedded Artists AB
ebv EBV Elektronik
edt Emerging Display Technologies
@ -176,6 +178,7 @@ nvidia NVIDIA
nxp NXP Semiconductors
okaya Okaya Electric America, Inc.
olimex OLIMEX Ltd.
onion Onion Corporation
onnn ON Semiconductor Corp.
opencores OpenCores.org
option Option NV

View File

@ -0,0 +1,19 @@
* Microchip PIC32 Deadman Timer
The deadman timer is used to reset the processor in the event of a software
malfunction. It is a free-running instruction fetch timer, which is clocked
whenever an instruction fetch occurs until a count match occurs.
Required properties:
- compatible: must be "microchip,pic32mzda-dmt".
- reg: physical base address of the controller and length of memory mapped
region.
- clocks: phandle of parent clock (should be &PBCLK7).
Example:
watchdog@1f800a00 {
compatible = "microchip,pic32mzda-dmt";
reg = <0x1f800a00 0x80>;
clocks = <&PBCLK7>;
};

View File

@ -0,0 +1,18 @@
* Microchip PIC32 Watchdog Timer
When enabled, the watchdog peripheral can be used to reset the device if the
WDT is not cleared periodically in software.
Required properties:
- compatible: must be "microchip,pic32mzda-wdt".
- reg: physical base address of the controller and length of memory mapped
region.
- clocks: phandle of source clk. should be <&LPRC> clk.
Example:
watchdog@1f800800 {
compatible = "microchip,pic32mzda-wdt";
reg = <0x1f800800 0x200>;
clocks = <&LPRC>;
};

View File

@ -6491,7 +6491,7 @@ F: net/l3mdev
F: include/net/l3mdev.h
LANTIQ MIPS ARCHITECTURE
M: John Crispin <blogic@openwrt.org>
M: John Crispin <john@phrozen.org>
L: linux-mips@linux-mips.org
S: Maintained
F: arch/mips/lantiq
@ -7332,6 +7332,15 @@ S: Supported
F: Documentation/mips/
F: arch/mips/
MIPS/LOONGSON1 ARCHITECTURE
M: Keguang Zhang <keguang.zhang@gmail.com>
L: linux-mips@linux-mips.org
S: Maintained
F: arch/mips/loongson32/
F: arch/mips/include/asm/mach-loongson32/
F: drivers/*/*loongson1*
F: drivers/*/*/*loongson1*
MIROSOUND PCM20 FM RADIO RECEIVER DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org
@ -9251,7 +9260,7 @@ S: Maintained
F: drivers/video/fbdev/aty/aty128fb.c
RALINK MIPS ARCHITECTURE
M: John Crispin <blogic@openwrt.org>
M: John Crispin <john@phrozen.org>
L: linux-mips@linux-mips.org
S: Maintained
F: arch/mips/ralink

View File

@ -62,6 +62,7 @@ config MIPS
select HAVE_IRQ_TIME_ACCOUNTING
select GENERIC_TIME_VSYSCALL
select ARCH_CLOCKSOURCE_DATA
select HANDLE_DOMAIN_IRQ
menu "Machine selection"
@ -137,7 +138,7 @@ config ATH79
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_MIPS16
select SYS_SUPPORTS_ZBOOT
select SYS_SUPPORTS_ZBOOT_UART_PROM
select USE_OF
help
Support for the Atheros AR71XX/AR724X/AR913X SoCs.
@ -194,6 +195,7 @@ config BCM47XX
select GPIOLIB
select LEDS_GPIO_REGISTER
select BCM47XX_NVRAM
select BCM47XX_SPROM
help
Support for BCM47XX based boards
@ -471,6 +473,7 @@ config MIPS_MALTA
select SYS_SUPPORTS_MULTITHREADING
select SYS_SUPPORTS_SMARTMIPS
select SYS_SUPPORTS_ZBOOT
select SYS_SUPPORTS_RELOCATABLE
select USE_OF
select ZONE_DMA32 if 64BIT
select BUILTIN_DTB
@ -505,6 +508,7 @@ config MIPS_SEAD3
select MIPS_MSC
select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_MIPS32_R2
select SYS_HAS_CPU_MIPS32_R6
select SYS_HAS_CPU_MIPS64_R1
select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_32BIT_KERNEL
@ -514,6 +518,7 @@ config MIPS_SEAD3
select SYS_SUPPORTS_SMARTMIPS
select SYS_SUPPORTS_MICROMIPS
select SYS_SUPPORTS_MIPS16
select SYS_SUPPORTS_RELOCATABLE
select USB_EHCI_BIG_ENDIAN_DESC
select USB_EHCI_BIG_ENDIAN_MMIO
select USE_OF
@ -1153,6 +1158,13 @@ config ISA_DMA_API
config HOLES_IN_ZONE
bool
config SYS_SUPPORTS_RELOCATABLE
bool
help
Selected if the platform supports relocating the kernel.
The platform must provide plat_get_fdt() if it selects CONFIG_USE_OF
to allow access to command line and entropy sources.
#
# Endianness selection. Sufficiently obscure so many users don't know what to
# answer,so we try hard to limit the available choices. Also the use of a
@ -1340,11 +1352,30 @@ config CPU_LOONGSON3
select CPU_SUPPORTS_HUGEPAGES
select WEAK_ORDERING
select WEAK_REORDERING_BEYOND_LLSC
select MIPS_PGD_C0_CONTEXT
select GPIOLIB
help
The Loongson 3 processor implements the MIPS64R2 instruction
set with many extensions.
config LOONGSON3_ENHANCEMENT
bool "New Loongson 3 CPU Enhancements"
default n
select CPU_MIPSR2
select CPU_HAS_PREFETCH
depends on CPU_LOONGSON3
help
New Loongson 3 CPU (since Loongson-3A R2, as opposed to Loongson-3A
R1, Loongson-3B R1 and Loongson-3B R2) has many enhancements, such as
FTLB, L1-VCache, EI/DI/Wait/Prefetch instruction, DSP/DSPv2 ASE, User
Local register, Read-Inhibit/Execute-Inhibit, SFB (Store Fill Buffer),
Fast TLB refill support, etc.
This option enable those enhancements which are not probed at run
time. If you want a generic kernel to run on all Loongson 3 machines,
please say 'N' here. If you want a high-performance kernel to run on
new Loongson 3 machines only, please say 'Y' here.
config CPU_LOONGSON2E
bool "Loongson 2E"
depends on SYS_HAS_CPU_LOONGSON2E
@ -1373,6 +1404,8 @@ config CPU_LOONGSON1B
bool "Loongson 1B"
depends on SYS_HAS_CPU_LOONGSON1B
select CPU_LOONGSON1
select ARCH_WANT_OPTIONAL_GPIOLIB
select LEDS_GPIO_REGISTER
help
The Loongson 1B is a 32-bit SoC, which implements the MIPS32
release 2 instruction set.
@ -1671,6 +1704,7 @@ config CPU_XLP
select CPU_HAS_PREFETCH
select CPU_MIPSR2
select CPU_SUPPORTS_HUGEPAGES
select MIPS_ASID_BITS_VARIABLE
help
Netlogic Microsystems XLP processors.
endchoice
@ -1796,6 +1830,7 @@ config CPU_BMIPS4380
select MIPS_L1_CACHE_SHIFT_6
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_HOTPLUG_CPU
select CPU_HAS_RIXI
config CPU_BMIPS5000
bool
@ -1803,10 +1838,12 @@ config CPU_BMIPS5000
select MIPS_L1_CACHE_SHIFT_7
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_HOTPLUG_CPU
select CPU_HAS_RIXI
config SYS_HAS_CPU_LOONGSON3
bool
select CPU_SUPPORTS_CPUFREQ
select CPU_HAS_RIXI
config SYS_HAS_CPU_LOONGSON2E
bool
@ -1959,11 +1996,15 @@ config CPU_MIPSR1
config CPU_MIPSR2
bool
default y if CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_CAVIUM_OCTEON
select CPU_HAS_RIXI
select MIPS_SPRAM
config CPU_MIPSR6
bool
default y if CPU_MIPS32_R6 || CPU_MIPS64_R6
select CPU_HAS_RIXI
select HAVE_ARCH_BITREVERSE
select MIPS_ASID_BITS_VARIABLE
select MIPS_SPRAM
config EVA
@ -1997,7 +2038,7 @@ config MIPS_PGD_C0_CONTEXT
#
config HARDWARE_WATCHPOINTS
bool
default y if CPU_MIPSR1 || CPU_MIPSR2
default y if CPU_MIPSR1 || CPU_MIPSR2 || CPU_MIPSR6
menu "Kernel type"
@ -2040,6 +2081,16 @@ config KVM_GUEST_TIMER_FREQ
emulation when determining guest CPU Frequency. Instead, the guest's
timer frequency is specified directly.
config MIPS_VA_BITS_48
bool "48 bits virtual memory"
depends on 64BIT
help
Support a maximum at least 48 bits of application virtual memory.
Default is 40 bits or less, depending on the CPU.
This option result in a small memory overhead for page tables.
This option is only supported with 16k and 64k page sizes.
If unsure, say N.
choice
prompt "Kernel page size"
default PAGE_SIZE_4KB
@ -2047,6 +2098,7 @@ choice
config PAGE_SIZE_4KB
bool "4kB"
depends on !CPU_LOONGSON2 && !CPU_LOONGSON3
depends on !MIPS_VA_BITS_48
help
This option select the standard 4kB Linux page size. On some
R3000-family processors this is the only available page size. Using
@ -2056,6 +2108,7 @@ config PAGE_SIZE_4KB
config PAGE_SIZE_8KB
bool "8kB"
depends on CPU_R8000 || CPU_CAVIUM_OCTEON
depends on !MIPS_VA_BITS_48
help
Using 8kB page size will result in higher performance kernel at
the price of higher memory consumption. This option is available
@ -2074,6 +2127,7 @@ config PAGE_SIZE_16KB
config PAGE_SIZE_32KB
bool "32kB"
depends on CPU_CAVIUM_OCTEON
depends on !MIPS_VA_BITS_48
help
Using 32kB page size will result in higher performance kernel at
the price of higher memory consumption. This option is available
@ -2278,7 +2332,7 @@ config MIPS_CMP
config MIPS_CPS
bool "MIPS Coherent Processing System support"
depends on SYS_SUPPORTS_MIPS_CPS && !CPU_MIPSR6
depends on SYS_SUPPORTS_MIPS_CPS
select MIPS_CM
select MIPS_CPC
select MIPS_CPS_PM if HOTPLUG_CPU
@ -2369,6 +2423,9 @@ config CPU_HAS_WB
config XKS01
bool
config CPU_HAS_RIXI
bool
#
# Vectored interrupt mode is an R2 feature
#
@ -2399,6 +2456,21 @@ config CPU_R4000_WORKAROUNDS
config CPU_R4400_WORKAROUNDS
bool
config MIPS_ASID_SHIFT
int
default 6 if CPU_R3000 || CPU_TX39XX
default 4 if CPU_R8000
default 0
config MIPS_ASID_BITS
int
default 0 if MIPS_ASID_BITS_VARIABLE
default 6 if CPU_R3000 || CPU_TX39XX
default 8
config MIPS_ASID_BITS_VARIABLE
bool
#
# - Highmem only makes sense for the 32-bit kernel.
# - The current highmem code will only work properly on physically indexed
@ -2468,6 +2540,61 @@ config NUMA
config SYS_SUPPORTS_NUMA
bool
config RELOCATABLE
bool "Relocatable kernel"
depends on SYS_SUPPORTS_RELOCATABLE && (CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_MIPS32_R6 || CPU_MIPS64_R6)
help
This builds a kernel image that retains relocation information
so it can be loaded someplace besides the default 1MB.
The relocations make the kernel binary about 15% larger,
but are discarded at runtime
config RELOCATION_TABLE_SIZE
hex "Relocation table size"
depends on RELOCATABLE
range 0x0 0x01000000
default "0x00100000"
---help---
A table of relocation data will be appended to the kernel binary
and parsed at boot to fix up the relocated kernel.
This option allows the amount of space reserved for the table to be
adjusted, although the default of 1Mb should be ok in most cases.
The build will fail and a valid size suggested if this is too small.
If unsure, leave at the default value.
config RANDOMIZE_BASE
bool "Randomize the address of the kernel image"
depends on RELOCATABLE
---help---
Randomizes the physical and virtual address at which the
kernel image is loaded, as a security feature that
deters exploit attempts relying on knowledge of the location
of kernel internals.
Entropy is generated using any coprocessor 0 registers available.
The kernel will be offset by up to RANDOMIZE_BASE_MAX_OFFSET.
If unsure, say N.
config RANDOMIZE_BASE_MAX_OFFSET
hex "Maximum kASLR offset" if EXPERT
depends on RANDOMIZE_BASE
range 0x0 0x40000000 if EVA || 64BIT
range 0x0 0x08000000
default "0x01000000"
---help---
When kASLR is active, this provides the maximum offset that will
be applied to the kernel image. It should be set according to the
amount of physical RAM available in the target system minus
PHYSICAL_START and must be a power of 2.
This is limited by the size of KSEG0, 256Mb on 32-bit or 1Gb with
EVA or 64-bit. The default is 16Mb.
config NODES_SHIFT
int
default "6"
@ -2475,7 +2602,7 @@ config NODES_SHIFT
config HW_PERF_EVENTS
bool "Enable hardware performance counter support for perf events"
depends on PERF_EVENTS && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP || CPU_LOONGSON3)
depends on PERF_EVENTS && !OPROFILE && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP || CPU_LOONGSON3)
default y
help
Enable hardware performance counter support for perf events. If
@ -2808,6 +2935,10 @@ choice
config MIPS_CMDLINE_FROM_BOOTLOADER
bool "Bootloader kernel arguments if available"
config MIPS_CMDLINE_BUILTIN_EXTEND
depends on CMDLINE_BOOL
bool "Extend builtin kernel arguments with bootloader arguments"
endchoice
endmenu

View File

@ -12,6 +12,9 @@
# for "archclean" cleaning up for this architecture.
#
archscripts: scripts_basic
$(Q)$(MAKE) $(build)=arch/mips/boot/tools relocs
KBUILD_DEFCONFIG := ip22_defconfig
#
@ -93,6 +96,10 @@ LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
KBUILD_AFLAGS_MODULE += -mlong-calls
KBUILD_CFLAGS_MODULE += -mlong-calls
ifeq ($(CONFIG_RELOCATABLE),y)
LDFLAGS_vmlinux += --emit-relocs
endif
#
# pass -msoft-float to GAS if it supports it. However on newer binutils
# (specifically newer than 2.24.51.20140728) we then also need to explicitly
@ -193,6 +200,8 @@ ifeq ($(CONFIG_CPU_HAS_MSA),y)
toolchain-msa := $(call cc-option-yn,$(mips-cflags) -mhard-float -mfp64 -Wa$(comma)-mmsa)
cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA
endif
toolchain-virt := $(call cc-option-yn,$(mips-cflags) -mvirt)
cflags-$(toolchain-virt) += -DTOOLCHAIN_SUPPORTS_VIRT
cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_NEVER) += -mcompact-branches=never
cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_OPTIMAL) += -mcompact-branches=optimal
@ -310,6 +319,10 @@ rom.bin rom.sw: vmlinux
$(bootvars-y) $@
endif
CMD_RELOCS = arch/mips/boot/tools/relocs
quiet_cmd_relocs = RELOCS $<
cmd_relocs = $(CMD_RELOCS) $<
#
# Some machines like the Indy need 32-bit ELF binaries for booting purposes.
# Other need ECOFF, so we build a 32-bit ELF binary for them which we then
@ -318,6 +331,11 @@ endif
quiet_cmd_32 = OBJCOPY $@
cmd_32 = $(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
vmlinux.32: vmlinux
ifeq ($(CONFIG_RELOCATABLE)$(CONFIG_64BIT),yy)
# Currently, objcopy fails to handle the relocations in the elf64
# So the relocs tool must be run here to remove them first
$(call cmd,relocs)
endif
$(call cmd,32)
#
@ -333,6 +351,9 @@ all: $(all-y)
# boot
$(boot-y): $(vmlinux-32) FORCE
ifeq ($(CONFIG_RELOCATABLE)$(CONFIG_32BIT),yy)
$(call cmd,relocs)
endif
$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) \
$(bootvars-y) arch/mips/boot/$@
@ -385,6 +406,7 @@ endif
archclean:
$(Q)$(MAKE) $(clean)=arch/mips/boot
$(Q)$(MAKE) $(clean)=arch/mips/boot/compressed
$(Q)$(MAKE) $(clean)=arch/mips/boot/tools
$(Q)$(MAKE) $(clean)=arch/mips/lasat
define archhelp

View File

@ -1043,8 +1043,7 @@ static int __init alchemy_clk_init(void)
/* Root of the Alchemy clock tree: external 12MHz crystal osc */
c = clk_register_fixed_rate(NULL, ALCHEMY_ROOT_CLK, NULL,
CLK_IS_ROOT,
ALCHEMY_ROOTCLK_RATE);
0, ALCHEMY_ROOTCLK_RATE);
ERRCK(c)
/* CPU core clock */

View File

@ -71,18 +71,6 @@ config ATH79_MACH_UBNT_XM
Say 'Y' here if you want your kernel to support the
Ubiquiti Networks XM (rev 1.0) board.
choice
prompt "Build a DTB in the kernel"
optional
help
Select a devicetree that should be built into the kernel.
config DTB_TL_WR1043ND_V1
bool "TL-WR1043ND Version 1"
select BUILTIN_DTB
select SOC_AR913X
endchoice
endmenu
config SOC_AR71XX

View File

@ -18,17 +18,21 @@
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <dt-bindings/clock/ath79-clk.h>
#include <asm/div64.h>
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
#include "common.h"
#include "machtypes.h"
#define AR71XX_BASE_FREQ 40000000
#define AR724X_BASE_FREQ 40000000
static struct clk *clks[3];
static struct clk *clks[ATH79_CLK_END];
static struct clk_onecell_data clk_data = {
.clks = clks,
.clk_num = ARRAY_SIZE(clks),
@ -40,7 +44,7 @@ static struct clk *__init ath79_add_sys_clkdev(
struct clk *clk;
int err;
clk = clk_register_fixed_rate(NULL, id, NULL, CLK_IS_ROOT, rate);
clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate);
if (!clk)
panic("failed to allocate %s clock structure", id);
@ -78,59 +82,123 @@ static void __init ar71xx_clocks_init(void)
ahb_rate = cpu_rate / div;
ath79_add_sys_clkdev("ref", ref_rate);
clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate);
clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate);
clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate);
clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate);
clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate);
clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate);
clk_add_alias("wdt", NULL, "ahb", NULL);
clk_add_alias("uart", NULL, "ahb", NULL);
}
static struct clk * __init ath79_reg_ffclk(const char *name,
const char *parent_name, unsigned int mult, unsigned int div)
{
struct clk *clk;
clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div);
if (!clk)
panic("failed to allocate %s clock structure", name);
return clk;
}
static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base)
{
u32 pll;
u32 mult, div, ddr_div, ahb_div;
pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG);
mult = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK);
div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2;
ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", mult, div);
clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", mult, div * ddr_div);
clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", mult, div * ahb_div);
}
static void __init ar724x_clocks_init(void)
{
unsigned long ref_rate;
unsigned long cpu_rate;
unsigned long ddr_rate;
unsigned long ahb_rate;
u32 pll;
u32 freq;
u32 div;
struct clk *ref_clk;
ref_rate = AR724X_BASE_FREQ;
pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
ref_clk = ath79_add_sys_clkdev("ref", AR724X_BASE_FREQ);
div = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK);
freq = div * ref_rate;
ar724x_clk_init(ref_clk, ath79_pll_base);
div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2;
freq /= div;
cpu_rate = freq;
div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
ddr_rate = freq / div;
div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
ahb_rate = cpu_rate / div;
ath79_add_sys_clkdev("ref", ref_rate);
clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate);
clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate);
clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate);
/* just make happy plat_time_init() from arch/mips/ath79/setup.c */
clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL);
clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL);
clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL);
clk_add_alias("wdt", NULL, "ahb", NULL);
clk_add_alias("uart", NULL, "ahb", NULL);
}
static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base)
{
u32 clock_ctrl;
u32 ref_div;
u32 ninit_mul;
u32 out_div;
u32 cpu_div;
u32 ddr_div;
u32 ahb_div;
clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG);
if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
ref_div = 1;
ninit_mul = 1;
out_div = 1;
cpu_div = 1;
ddr_div = 1;
ahb_div = 1;
} else {
u32 cpu_config;
u32 t;
cpu_config = __raw_readl(pll_base + AR933X_PLL_CPU_CONFIG_REG);
t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
ref_div = t;
ninit_mul = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) &
AR933X_PLL_CPU_CONFIG_NINT_MASK;
t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
AR933X_PLL_CPU_CONFIG_OUTDIV_MASK;
if (t == 0)
t = 1;
out_div = (1 << t);
cpu_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) &
AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1;
ddr_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) &
AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1;
ahb_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) &
AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1;
}
clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref",
ninit_mul, ref_div * out_div * cpu_div);
clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref",
ninit_mul, ref_div * out_div * ddr_div);
clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref",
ninit_mul, ref_div * out_div * ahb_div);
}
static void __init ar933x_clocks_init(void)
{
struct clk *ref_clk;
unsigned long ref_rate;
unsigned long cpu_rate;
unsigned long ddr_rate;
unsigned long ahb_rate;
u32 clock_ctrl;
u32 cpu_config;
u32 freq;
u32 t;
t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
@ -139,46 +207,14 @@ static void __init ar933x_clocks_init(void)
else
ref_rate = (25 * 1000 * 1000);
clock_ctrl = ath79_pll_rr(AR933X_PLL_CLOCK_CTRL_REG);
if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
cpu_rate = ref_rate;
ahb_rate = ref_rate;
ddr_rate = ref_rate;
} else {
cpu_config = ath79_pll_rr(AR933X_PLL_CPU_CONFIG_REG);
ref_clk = ath79_add_sys_clkdev("ref", ref_rate);
t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
freq = ref_rate / t;
ar9330_clk_init(ref_clk, ath79_pll_base);
t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) &
AR933X_PLL_CPU_CONFIG_NINT_MASK;
freq *= t;
t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
AR933X_PLL_CPU_CONFIG_OUTDIV_MASK;
if (t == 0)
t = 1;
freq >>= t;
t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) &
AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1;
cpu_rate = freq / t;
t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) &
AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1;
ddr_rate = freq / t;
t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) &
AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1;
ahb_rate = freq / t;
}
ath79_add_sys_clkdev("ref", ref_rate);
clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate);
clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate);
clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate);
/* just make happy plat_time_init() from arch/mips/ath79/setup.c */
clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL);
clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL);
clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL);
clk_add_alias("wdt", NULL, "ahb", NULL);
clk_add_alias("uart", NULL, "ref", NULL);
@ -310,9 +346,9 @@ static void __init ar934x_clocks_init(void)
ahb_rate = cpu_pll / (postdiv + 1);
ath79_add_sys_clkdev("ref", ref_rate);
clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate);
clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate);
clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate);
clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate);
clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate);
clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate);
clk_add_alias("wdt", NULL, "ref", NULL);
clk_add_alias("uart", NULL, "ref", NULL);
@ -397,9 +433,9 @@ static void __init qca955x_clocks_init(void)
ahb_rate = cpu_pll / (postdiv + 1);
ath79_add_sys_clkdev("ref", ref_rate);
clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate);
clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate);
clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate);
clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate);
clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate);
clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate);
clk_add_alias("wdt", NULL, "ref", NULL);
clk_add_alias("uart", NULL, "ref", NULL);
@ -419,8 +455,6 @@ void __init ath79_clocks_init(void)
qca955x_clocks_init();
else
BUG();
of_clk_init(NULL);
}
unsigned long __init
@ -447,8 +481,49 @@ static void __init ath79_clocks_init_dt(struct device_node *np)
CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt);
CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt);
CLK_OF_DECLARE(ar9130, "qca,ar9130-pll", ath79_clocks_init_dt);
CLK_OF_DECLARE(ar9330, "qca,ar9330-pll", ath79_clocks_init_dt);
CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt);
CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt);
static void __init ath79_clocks_init_dt_ng(struct device_node *np)
{
struct clk *ref_clk;
void __iomem *pll_base;
const char *dnfn = of_node_full_name(np);
ref_clk = of_clk_get(np, 0);
if (IS_ERR(ref_clk)) {
pr_err("%s: of_clk_get failed\n", dnfn);
goto err;
}
pll_base = of_iomap(np, 0);
if (!pll_base) {
pr_err("%s: can't map pll registers\n", dnfn);
goto err_clk;
}
if (of_device_is_compatible(np, "qca,ar9130-pll"))
ar724x_clk_init(ref_clk, pll_base);
else if (of_device_is_compatible(np, "qca,ar9330-pll"))
ar9330_clk_init(ref_clk, pll_base);
else {
pr_err("%s: could not find any appropriate clk_init()\n", dnfn);
goto err_clk;
}
if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) {
pr_err("%s: could not register clk provider\n", dnfn);
goto err_clk;
}
return;
err_clk:
clk_put(ref_clk);
err:
return;
}
CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt_ng);
CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt_ng);
#endif

View File

@ -46,12 +46,12 @@ void ath79_ddr_ctrl_init(void)
{
ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
AR71XX_DDR_CTRL_SIZE);
if (soc_is_ar71xx() || soc_is_ar934x()) {
ath79_ddr_wb_flush_base = ath79_ddr_base + 0x9c;
ath79_ddr_pci_win_base = ath79_ddr_base + 0x7c;
} else {
if (soc_is_ar913x() || soc_is_ar724x() || soc_is_ar933x()) {
ath79_ddr_wb_flush_base = ath79_ddr_base + 0x7c;
ath79_ddr_pci_win_base = 0;
} else {
ath79_ddr_wb_flush_base = ath79_ddr_base + 0x9c;
ath79_ddr_pci_win_base = ath79_ddr_base + 0x7c;
}
}
EXPORT_SYMBOL_GPL(ath79_ddr_ctrl_init);
@ -76,14 +76,14 @@ void ath79_ddr_set_pci_windows(void)
{
BUG_ON(!ath79_ddr_pci_win_base);
__raw_writel(AR71XX_PCI_WIN0_OFFS, ath79_ddr_pci_win_base + 0);
__raw_writel(AR71XX_PCI_WIN1_OFFS, ath79_ddr_pci_win_base + 1);
__raw_writel(AR71XX_PCI_WIN2_OFFS, ath79_ddr_pci_win_base + 2);
__raw_writel(AR71XX_PCI_WIN3_OFFS, ath79_ddr_pci_win_base + 3);
__raw_writel(AR71XX_PCI_WIN4_OFFS, ath79_ddr_pci_win_base + 4);
__raw_writel(AR71XX_PCI_WIN5_OFFS, ath79_ddr_pci_win_base + 5);
__raw_writel(AR71XX_PCI_WIN6_OFFS, ath79_ddr_pci_win_base + 6);
__raw_writel(AR71XX_PCI_WIN7_OFFS, ath79_ddr_pci_win_base + 7);
__raw_writel(AR71XX_PCI_WIN0_OFFS, ath79_ddr_pci_win_base + 0x0);
__raw_writel(AR71XX_PCI_WIN1_OFFS, ath79_ddr_pci_win_base + 0x4);
__raw_writel(AR71XX_PCI_WIN2_OFFS, ath79_ddr_pci_win_base + 0x8);
__raw_writel(AR71XX_PCI_WIN3_OFFS, ath79_ddr_pci_win_base + 0xc);
__raw_writel(AR71XX_PCI_WIN4_OFFS, ath79_ddr_pci_win_base + 0x10);
__raw_writel(AR71XX_PCI_WIN5_OFFS, ath79_ddr_pci_win_base + 0x14);
__raw_writel(AR71XX_PCI_WIN6_OFFS, ath79_ddr_pci_win_base + 0x18);
__raw_writel(AR71XX_PCI_WIN7_OFFS, ath79_ddr_pci_win_base + 0x1c);
}
EXPORT_SYMBOL_GPL(ath79_ddr_set_pci_windows);

View File

@ -17,6 +17,7 @@
#include <linux/bootmem.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/of_platform.h>
#include <linux/of_fdt.h>
@ -203,26 +204,57 @@ void __init plat_mem_setup(void)
fdt_start = fw_getenvl("fdt_start");
if (fdt_start)
__dt_setup_arch((void *)KSEG0ADDR(fdt_start));
#ifdef CONFIG_BUILTIN_DTB
else
__dt_setup_arch(__dtb_start);
#endif
else if (fw_arg0 == -2)
__dt_setup_arch((void *)KSEG0ADDR(fw_arg1));
ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
AR71XX_RESET_SIZE);
ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
AR71XX_PLL_SIZE);
ath79_detect_sys_type();
ath79_ddr_ctrl_init();
if (mips_machtype != ATH79_MACH_GENERIC_OF) {
ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
AR71XX_RESET_SIZE);
ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
AR71XX_PLL_SIZE);
ath79_detect_sys_type();
ath79_ddr_ctrl_init();
if (mips_machtype != ATH79_MACH_GENERIC_OF)
detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX);
_machine_restart = ath79_restart;
/* OF machines should use the reset driver */
_machine_restart = ath79_restart;
}
_machine_halt = ath79_halt;
pm_power_off = ath79_halt;
}
static void __init ath79_of_plat_time_init(void)
{
struct device_node *np;
struct clk *clk;
unsigned long cpu_clk_rate;
of_clk_init(NULL);
np = of_get_cpu_node(0, NULL);
if (!np) {
pr_err("Failed to get CPU node\n");
return;
}
clk = of_clk_get(np, 0);
if (IS_ERR(clk)) {
pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk));
return;
}
cpu_clk_rate = clk_get_rate(clk);
pr_info("CPU clock: %lu.%03lu MHz\n",
cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000);
mips_hpt_frequency = cpu_clk_rate / 2;
clk_put(clk);
}
void __init plat_time_init(void)
{
unsigned long cpu_clk_rate;
@ -230,6 +262,11 @@ void __init plat_time_init(void)
unsigned long ddr_clk_rate;
unsigned long ref_clk_rate;
if (IS_ENABLED(CONFIG_OF) && mips_machtype == ATH79_MACH_GENERIC_OF) {
ath79_of_plat_time_init();
return;
}
ath79_clocks_init();
cpu_clk_rate = ath79_get_sys_clk_rate("cpu");

View File

@ -3,5 +3,5 @@
# under Linux.
#
obj-y += irq.o prom.o serial.o setup.o time.o sprom.o
obj-y += irq.o prom.o serial.o setup.o time.o
obj-y += board.o buttons.o leds.o workarounds.o

View File

@ -10,9 +10,6 @@
/* 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);

View File

@ -28,6 +28,7 @@
#include "bcm47xx_private.h"
#include <linux/bcm47xx_sprom.h>
#include <linux/export.h>
#include <linux/types.h>
#include <linux/ethtool.h>
@ -151,7 +152,6 @@ void __init plat_mem_setup(void)
pr_info("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

View File

@ -21,6 +21,10 @@ config DT_BCM93384WVG_VIPER
bool "BCM93384WVG Viper CPU (EXPERIMENTAL)"
select BUILTIN_DTB
config DT_BCM96358NB4SER
bool "BCM96358NB4SER"
select BUILTIN_DTB
config DT_BCM96368MVWG
bool "BCM96368MVWG"
select BUILTIN_DTB

View File

@ -95,6 +95,15 @@ static void bcm6328_quirks(void)
bcm63xx_fixup_cpu1();
}
static void bcm6358_quirks(void)
{
/*
* BCM6358 needs special handling for its shared TLB, so
* disable SMP for now
*/
bmips_smp_enabled = 0;
}
static void bcm6368_quirks(void)
{
bcm63xx_fixup_cpu1();
@ -104,13 +113,16 @@ static const struct bmips_quirk bmips_quirk_list[] = {
{ "brcm,bcm3384-viper", &bcm3384_viper_quirks },
{ "brcm,bcm33843-viper", &bcm3384_viper_quirks },
{ "brcm,bcm6328", &bcm6328_quirks },
{ "brcm,bcm6358", &bcm6358_quirks },
{ "brcm,bcm6368", &bcm6368_quirks },
{ "brcm,bcm63168", &bcm6368_quirks },
{ "brcm,bcm63268", &bcm6368_quirks },
{ },
};
void __init prom_init(void)
{
bmips_cpu_setup();
register_bmips_smp_ops();
}

View File

@ -37,8 +37,13 @@ vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT) += $(obj)/dbg.o
vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM) += $(obj)/uart-prom.o
vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o
vmlinuzobjs-$(CONFIG_ATH79) += $(obj)/uart-ath79.o
endif
extra-y += uart-ath79.c
$(obj)/uart-ath79.c: $(srctree)/arch/mips/ath79/early_printk.c
$(call cmd,shipped)
vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o $(obj)/bswapsi.o
extra-y += ashldi3.c bswapsi.c

View File

@ -1,5 +1,6 @@
dtb-$(CONFIG_DT_BCM93384WVG) += bcm93384wvg.dtb
dtb-$(CONFIG_DT_BCM93384WVG_VIPER) += bcm93384wvg_viper.dtb
dtb-$(CONFIG_DT_BCM96358NB4SER) += bcm96358nb4ser.dtb
dtb-$(CONFIG_DT_BCM96368MVWG) += bcm96368mvwg.dtb
dtb-$(CONFIG_DT_BCM9EJTAGPRB) += bcm9ejtagprb.dtb
dtb-$(CONFIG_DT_BCM97125CBMB) += bcm97125cbmb.dtb
@ -14,6 +15,7 @@ dtb-$(CONFIG_DT_BCM97435SVMB) += bcm97435svmb.dtb
dtb-$(CONFIG_DT_NONE) += \
bcm93384wvg.dtb \
bcm93384wvg_viper.dtb \
bcm96358nb4ser.dtb \
bcm96368mvwg.dtb \
bcm9ejtagprb.dtb \
bcm97125cbmb.dtb \

View File

@ -23,7 +23,7 @@ cpu@1 {
};
clocks {
periph_clk: periph_clk {
periph_clk: periph-clk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <50000000>;
@ -31,11 +31,11 @@ periph_clk: periph_clk {
};
aliases {
leds0 = &leds0;
uart0 = &uart0;
serial0 = &uart0;
serial1 = &uart1;
};
cpu_intc: cpu_intc {
cpu_intc: interrupt-controller {
#address-cells = <0>;
compatible = "mti,cpu-interrupt-controller";
@ -50,16 +50,16 @@ ubus {
compatible = "simple-bus";
ranges;
periph_intc: periph_intc@10000020 {
compatible = "brcm,bcm3380-l2-intc";
reg = <0x10000024 0x4 0x1000002c 0x4>,
<0x10000020 0x4 0x10000028 0x4>;
periph_intc: interrupt-controller@10000020 {
compatible = "brcm,bcm6345-l1-intc";
reg = <0x10000020 0x10>,
<0x10000030 0x10>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&cpu_intc>;
interrupts = <2>;
interrupts = <2>, <3>;
};
uart0: serial@10000100 {
@ -71,13 +71,22 @@ uart0: serial@10000100 {
status = "disabled";
};
timer: timer@10000040 {
uart1: serial@10000120 {
compatible = "brcm,bcm6345-uart";
reg = <0x10000120 0x18>;
interrupt-parent = <&periph_intc>;
interrupts = <39>;
clocks = <&periph_clk>;
status = "disabled";
};
timer: syscon@10000040 {
compatible = "syscon";
reg = <0x10000040 0x2c>;
native-endian;
};
reboot {
reboot: syscon-reboot@10000068 {
compatible = "syscon-reboot";
regmap = <&timer>;
offset = <0x28>;
@ -91,5 +100,24 @@ leds0: led-controller@10000800 {
reg = <0x10000800 0x24>;
status = "disabled";
};
ehci: usb@10002500 {
compatible = "brcm,bcm6328-ehci", "generic-ehci";
reg = <0x10002500 0x100>;
big-endian;
interrupt-parent = <&periph_intc>;
interrupts = <42>;
status = "disabled";
};
ohci: usb@10002600 {
compatible = "brcm,bcm6328-ohci", "generic-ohci";
reg = <0x10002600 0x100>;
big-endian;
no-big-frame-no;
interrupt-parent = <&periph_intc>;
interrupts = <41>;
status = "disabled";
};
};
};

View File

@ -0,0 +1,130 @@
/ {
#address-cells = <1>;
#size-cells = <1>;
compatible = "brcm,bcm6358";
cpus {
#address-cells = <1>;
#size-cells = <0>;
mips-hpt-frequency = <150000000>;
cpu@0 {
compatible = "brcm,bmips4350";
device_type = "cpu";
reg = <0>;
};
cpu@1 {
compatible = "brcm,bmips4350";
device_type = "cpu";
reg = <1>;
};
};
clocks {
periph_clk: periph-clk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <50000000>;
};
};
aliases {
serial0 = &uart0;
serial1 = &uart1;
};
cpu_intc: interrupt-controller {
#address-cells = <0>;
compatible = "mti,cpu-interrupt-controller";
interrupt-controller;
#interrupt-cells = <1>;
};
ubus {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges;
periph_cntl: syscon@fffe0000 {
compatible = "syscon";
reg = <0xfffe0000 0xc>;
native-endian;
};
reboot: syscon-reboot@fffe0008 {
compatible = "syscon-reboot";
regmap = <&periph_cntl>;
offset = <0x8>;
mask = <0x1>;
};
periph_intc: interrupt-controller@fffe000c {
compatible = "brcm,bcm6345-l1-intc";
reg = <0xfffe000c 0x8>,
<0xfffe0038 0x8>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&cpu_intc>;
interrupts = <2>, <3>;
};
leds0: led-controller@fffe00d0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,bcm6358-leds";
reg = <0xfffe00d0 0x8>;
status = "disabled";
};
uart0: serial@fffe0100 {
compatible = "brcm,bcm6345-uart";
reg = <0xfffe0100 0x18>;
interrupt-parent = <&periph_intc>;
interrupts = <2>;
clocks = <&periph_clk>;
status = "disabled";
};
uart1: serial@fffe0120 {
compatible = "brcm,bcm6345-uart";
reg = <0xfffe0120 0x18>;
interrupt-parent = <&periph_intc>;
interrupts = <3>;
clocks = <&periph_clk>;
status = "disabled";
};
ehci: usb@fffe1300 {
compatible = "brcm,bcm6358-ehci", "generic-ehci";
reg = <0xfffe1300 0x100>;
big-endian;
interrupt-parent = <&periph_intc>;
interrupts = <10>;
status = "disabled";
};
ohci: usb@fffe1400 {
compatible = "brcm,bcm6358-ohci", "generic-ohci";
reg = <0xfffe1400 0x100>;
big-endian;
no-big-frame-no;
interrupt-parent = <&periph_intc>;
interrupts = <5>;
status = "disabled";
};
};
};

View File

@ -20,11 +20,10 @@ cpu@1 {
device_type = "cpu";
reg = <1>;
};
};
clocks {
periph_clk: periph_clk {
periph_clk: periph-clk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <50000000>;
@ -32,11 +31,11 @@ periph_clk: periph_clk {
};
aliases {
leds0 = &leds0;
uart0 = &uart0;
serial0 = &uart0;
serial1 = &uart1;
};
cpu_intc: cpu_intc {
cpu_intc: interrupt-controller {
#address-cells = <0>;
compatible = "mti,cpu-interrupt-controller";
@ -64,16 +63,16 @@ reboot: syscon-reboot@10000008 {
mask = <0x1>;
};
periph_intc: periph_intc@10000020 {
compatible = "brcm,bcm3380-l2-intc";
reg = <0x10000024 0x4 0x1000002c 0x4>,
<0x10000020 0x4 0x10000028 0x4>;
periph_intc: interrupt-controller@10000020 {
compatible = "brcm,bcm6345-l1-intc";
reg = <0x10000020 0x10>,
<0x10000030 0x10>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&cpu_intc>;
interrupts = <2>;
interrupts = <2>, <3>;
};
leds0: led-controller@100000d0 {
@ -93,7 +92,16 @@ uart0: serial@10000100 {
status = "disabled";
};
ehci0: usb@10001500 {
uart1: serial@10000120 {
compatible = "brcm,bcm6345-uart";
reg = <0x10000120 0x18>;
interrupt-parent = <&periph_intc>;
interrupts = <3>;
clocks = <&periph_clk>;
status = "disabled";
};
ehci: usb@10001500 {
compatible = "brcm,bcm6368-ehci", "generic-ehci";
reg = <0x10001500 0x100>;
big-endian;
@ -102,7 +110,7 @@ ehci0: usb@10001500 {
status = "disabled";
};
ohci0: usb@10001600 {
ohci: usb@10001600 {
compatible = "brcm,bcm6368-ohci", "generic-ohci";
reg = <0x10001600 0x100>;
big-endian;

View File

@ -85,14 +85,15 @@ upg_irq0_intc: upg_irq0_intc@406780 {
compatible = "brcm,bcm7120-l2-intc";
reg = <0x406780 0x8>;
brcm,int-map-mask = <0x44>;
brcm,int-map-mask = <0x44>, <0xf000000>;
brcm,int-fwd-mask = <0x70000>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&periph_intc>;
interrupts = <18>;
interrupts = <18>, <19>;
interrupt-names = "upg_main", "upg_bsc";
};
sun_top_ctrl: syscon@404000 {
@ -118,6 +119,70 @@ uart0: serial@406b00 {
status = "disabled";
};
uart1: serial@406b40 {
compatible = "ns16550a";
reg = <0x406b40 0x20>;
reg-io-width = <0x4>;
reg-shift = <0x2>;
native-endian;
interrupt-parent = <&periph_intc>;
interrupts = <64>;
clocks = <&uart_clk>;
status = "disabled";
};
uart2: serial@406b80 {
compatible = "ns16550a";
reg = <0x406b80 0x20>;
reg-io-width = <0x4>;
reg-shift = <0x2>;
native-endian;
interrupt-parent = <&periph_intc>;
interrupts = <65>;
clocks = <&uart_clk>;
status = "disabled";
};
bsca: i2c@406200 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406200 0x58>;
interrupts = <24>;
interrupt-names = "upg_bsca";
status = "disabled";
};
bscb: i2c@406280 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406280 0x58>;
interrupts = <25>;
interrupt-names = "upg_bscb";
status = "disabled";
};
bscc: i2c@406300 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406300 0x58>;
interrupts = <26>;
interrupt-names = "upg_bscc";
status = "disabled";
};
bscd: i2c@406380 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406380 0x58>;
interrupts = <27>;
interrupt-names = "upg_bscd";
status = "disabled";
};
ehci0: usb@488300 {
compatible = "brcm,bcm7125-ehci", "generic-ehci";
reg = <0x488300 0x100>;

View File

@ -24,8 +24,6 @@ cpu@1 {
aliases {
uart0 = &uart0;
uart1 = &uart1;
uart2 = &uart2;
};
cpu_intc: cpu_intc {
@ -323,8 +321,6 @@ sata: sata@181000 {
interrupts = <40>;
#address-cells = <1>;
#size-cells = <0>;
brcm,broken-ncq;
brcm,broken-phy;
status = "disabled";
sata0: sata-port@0 {
@ -338,7 +334,7 @@ sata1: sata-port@1 {
};
};
sata_phy: sata-phy@1800000 {
sata_phy: sata-phy@180100 {
compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3";
reg = <0x180100 0x0eff>;
reg-names = "phy";

View File

@ -18,8 +18,6 @@ cpu@0 {
aliases {
uart0 = &uart0;
uart1 = &uart1;
uart2 = &uart2;
};
cpu_intc: cpu_intc {

View File

@ -18,8 +18,6 @@ cpu@0 {
aliases {
uart0 = &uart0;
uart1 = &uart1;
uart2 = &uart2;
};
cpu_intc: cpu_intc {
@ -241,5 +239,45 @@ ohci0: usb@480400 {
interrupts = <66>;
status = "disabled";
};
sata: sata@181000 {
compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci";
reg-names = "ahci", "top-ctrl";
reg = <0x181000 0xa9c>, <0x180020 0x1c>;
interrupt-parent = <&periph_intc>;
interrupts = <86>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
sata0: sata-port@0 {
reg = <0>;
phys = <&sata_phy0>;
};
sata1: sata-port@1 {
reg = <1>;
phys = <&sata_phy1>;
};
};
sata_phy: sata-phy@180100 {
compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3";
reg = <0x180100 0x0eff>;
reg-names = "phy";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
sata_phy0: sata-phy@0 {
reg = <0>;
#phy-cells = <0>;
};
sata_phy1: sata-phy@1 {
reg = <1>;
#phy-cells = <0>;
};
};
};
};

View File

@ -24,8 +24,6 @@ cpu@1 {
aliases {
uart0 = &uart0;
uart1 = &uart1;
uart2 = &uart2;
};
cpu_intc: cpu_intc {
@ -246,8 +244,6 @@ sata: sata@181000 {
interrupts = <86>;
#address-cells = <1>;
#size-cells = <0>;
brcm,broken-ncq;
brcm,broken-phy;
status = "disabled";
sata0: sata-port@0 {
@ -261,7 +257,7 @@ sata1: sata-port@1 {
};
};
sata_phy: sata-phy@1800000 {
sata_phy: sata-phy@180100 {
compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3";
reg = <0x180100 0x0eff>;
reg-names = "phy";

View File

@ -86,14 +86,15 @@ upg_irq0_intc: upg_irq0_intc@406780 {
compatible = "brcm,bcm7120-l2-intc";
reg = <0x406780 0x8>;
brcm,int-map-mask = <0x44>;
brcm,int-map-mask = <0x44>, <0x1f000000>;
brcm,int-fwd-mask = <0x70000>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&periph_intc>;
interrupts = <18>;
interrupts = <18>, <19>;
interrupt-names = "upg_main", "upg_bsc";
};
sun_top_ctrl: syscon@404000 {
@ -118,6 +119,78 @@ uart0: serial@406b00 {
status = "disabled";
};
uart1: serial@406b40 {
compatible = "ns16550a";
reg = <0x406b40 0x20>;
reg-io-width = <0x4>;
reg-shift = <0x2>;
interrupt-parent = <&periph_intc>;
interrupts = <64>;
clocks = <&uart_clk>;
status = "disabled";
};
uart2: serial@406b80 {
compatible = "ns16550a";
reg = <0x406b80 0x20>;
reg-io-width = <0x4>;
reg-shift = <0x2>;
interrupt-parent = <&periph_intc>;
interrupts = <65>;
clocks = <&uart_clk>;
status = "disabled";
};
bsca: i2c@406200 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406200 0x58>;
interrupts = <24>;
interrupt-names = "upg_bsca";
status = "disabled";
};
bscb: i2c@406280 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406280 0x58>;
interrupts = <25>;
interrupt-names = "upg_bscb";
status = "disabled";
};
bscc: i2c@406300 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406300 0x58>;
interrupts = <26>;
interrupt-names = "upg_bscc";
status = "disabled";
};
bscd: i2c@406380 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406380 0x58>;
interrupts = <27>;
interrupt-names = "upg_bscd";
status = "disabled";
};
bsce: i2c@406800 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406800 0x58>;
interrupts = <28>;
interrupt-names = "upg_bsce";
status = "disabled";
};
enet0: ethernet@468000 {
phy-mode = "internal";
phy-handle = <&phy1>;

View File

@ -87,14 +87,32 @@ upg_irq0_intc: upg_irq0_intc@406780 {
compatible = "brcm,bcm7120-l2-intc";
reg = <0x406780 0x8>;
brcm,int-map-mask = <0x44>;
brcm,int-map-mask = <0x44>, <0x7000000>;
brcm,int-fwd-mask = <0x70000>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&periph_intc>;
interrupts = <55>;
interrupts = <55>, <53>;
interrupt-names = "upg_main", "upg_bsc";
};
upg_aon_irq0_intc: upg_aon_irq0_intc@409480 {
compatible = "brcm,bcm7120-l2-intc";
reg = <0x409480 0x8>;
brcm,int-map-mask = <0x40>, <0x18000000>, <0x100000>;
brcm,int-fwd-mask = <0>;
brcm,irq-can-wake;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&periph_intc>;
interrupts = <56>, <54>, <59>;
interrupt-names = "upg_main_aon", "upg_bsc_aon",
"upg_spi";
};
sun_top_ctrl: syscon@404000 {
@ -119,6 +137,78 @@ uart0: serial@406b00 {
status = "disabled";
};
uart1: serial@406b40 {
compatible = "ns16550a";
reg = <0x406b40 0x20>;
reg-io-width = <0x4>;
reg-shift = <0x2>;
interrupt-parent = <&periph_intc>;
interrupts = <62>;
clocks = <&uart_clk>;
status = "disabled";
};
uart2: serial@406b80 {
compatible = "ns16550a";
reg = <0x406b80 0x20>;
reg-io-width = <0x4>;
reg-shift = <0x2>;
interrupt-parent = <&periph_intc>;
interrupts = <63>;
clocks = <&uart_clk>;
status = "disabled";
};
bsca: i2c@409180 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_aon_irq0_intc>;
reg = <0x409180 0x58>;
interrupts = <27>;
interrupt-names = "upg_bsca";
status = "disabled";
};
bscb: i2c@409400 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_aon_irq0_intc>;
reg = <0x409400 0x58>;
interrupts = <28>;
interrupt-names = "upg_bscb";
status = "disabled";
};
bscc: i2c@406200 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406200 0x58>;
interrupts = <24>;
interrupt-names = "upg_bscc";
status = "disabled";
};
bscd: i2c@406280 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406280 0x58>;
interrupts = <25>;
interrupt-names = "upg_bscd";
status = "disabled";
};
bsce: i2c@406300 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406300 0x58>;
interrupts = <26>;
interrupt-names = "upg_bsce";
status = "disabled";
};
enet0: ethernet@b80000 {
phy-mode = "internal";
phy-handle = <&phy1>;
@ -227,11 +317,9 @@ sata: sata@181000 {
reg-names = "ahci", "top-ctrl";
reg = <0x181000 0xa9c>, <0x180020 0x1c>;
interrupt-parent = <&periph_intc>;
interrupts = <40>;
interrupts = <41>;
#address-cells = <1>;
#size-cells = <0>;
brcm,broken-ncq;
brcm,broken-phy;
status = "disabled";
sata0: sata-port@0 {
@ -245,7 +333,7 @@ sata1: sata-port@1 {
};
};
sata_phy: sata-phy@1800000 {
sata_phy: sata-phy@180100 {
compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3";
reg = <0x180100 0x0eff>;
reg-names = "phy";

View File

@ -7,7 +7,7 @@ cpus {
#address-cells = <1>;
#size-cells = <0>;
mips-hpt-frequency = <163125000>;
mips-hpt-frequency = <175625000>;
cpu@0 {
compatible = "brcm,bmips5200";
@ -63,13 +63,14 @@ rdb {
periph_intc: periph_intc@41b500 {
compatible = "brcm,bcm7038-l1-intc";
reg = <0x41b500 0x40>, <0x41b600 0x40>;
reg = <0x41b500 0x40>, <0x41b600 0x40>,
<0x41b700 0x40>, <0x41b800 0x40>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&cpu_intc>;
interrupts = <2>, <3>;
interrupts = <2>, <3>, <2>, <3>;
};
sun_l2_intc: sun_l2_intc@403000 {
@ -101,14 +102,32 @@ upg_irq0_intc: upg_irq0_intc@406780 {
compatible = "brcm,bcm7120-l2-intc";
reg = <0x406780 0x8>;
brcm,int-map-mask = <0x44>;
brcm,int-map-mask = <0x44>, <0x7000000>;
brcm,int-fwd-mask = <0x70000>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&periph_intc>;
interrupts = <60>;
interrupts = <60>, <58>;
interrupt-names = "upg_main", "upg_bsc";
};
upg_aon_irq0_intc: upg_aon_irq0_intc@409480 {
compatible = "brcm,bcm7120-l2-intc";
reg = <0x409480 0x8>;
brcm,int-map-mask = <0x40>, <0x18000000>, <0x100000>;
brcm,int-fwd-mask = <0>;
brcm,irq-can-wake;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&periph_intc>;
interrupts = <61>, <59>, <64>;
interrupt-names = "upg_main_aon", "upg_bsc_aon",
"upg_spi";
};
sun_top_ctrl: syscon@404000 {
@ -133,6 +152,78 @@ uart0: serial@406b00 {
status = "disabled";
};
uart1: serial@406b40 {
compatible = "ns16550a";
reg = <0x406b40 0x20>;
reg-io-width = <0x4>;
reg-shift = <0x2>;
interrupt-parent = <&periph_intc>;
interrupts = <67>;
clocks = <&uart_clk>;
status = "disabled";
};
uart2: serial@406b80 {
compatible = "ns16550a";
reg = <0x406b80 0x20>;
reg-io-width = <0x4>;
reg-shift = <0x2>;
interrupt-parent = <&periph_intc>;
interrupts = <68>;
clocks = <&uart_clk>;
status = "disabled";
};
bsca: i2c@406300 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406300 0x58>;
interrupts = <26>;
interrupt-names = "upg_bsca";
status = "disabled";
};
bscb: i2c@409400 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_aon_irq0_intc>;
reg = <0x409400 0x58>;
interrupts = <28>;
interrupt-names = "upg_bscb";
status = "disabled";
};
bscc: i2c@406200 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406200 0x58>;
interrupts = <24>;
interrupt-names = "upg_bscc";
status = "disabled";
};
bscd: i2c@406280 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_irq0_intc>;
reg = <0x406280 0x58>;
interrupts = <25>;
interrupt-names = "upg_bscd";
status = "disabled";
};
bsce: i2c@409180 {
clock-frequency = <390000>;
compatible = "brcm,brcmstb-i2c";
interrupt-parent = <&upg_aon_irq0_intc>;
reg = <0x409180 0x58>;
interrupts = <27>;
interrupt-names = "upg_bsce";
status = "disabled";
};
enet0: ethernet@b80000 {
phy-mode = "internal";
phy-handle = <&phy1>;
@ -235,5 +326,45 @@ ohci3: usb@490600 {
interrupts = <78>;
status = "disabled";
};
sata: sata@181000 {
compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci";
reg-names = "ahci", "top-ctrl";
reg = <0x181000 0xa9c>, <0x180020 0x1c>;
interrupt-parent = <&periph_intc>;
interrupts = <45>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
sata0: sata-port@0 {
reg = <0>;
phys = <&sata_phy0>;
};
sata1: sata-port@1 {
reg = <1>;
phys = <&sata_phy1>;
};
};
sata_phy: sata-phy@180100 {
compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3";
reg = <0x180100 0x0eff>;
reg-names = "phy";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
sata_phy0: sata-phy@0 {
reg = <0>;
#phy-cells = <0>;
};
sata_phy1: sata-phy@1 {
reg = <1>;
#phy-cells = <0>;
};
};
};
};

View File

@ -0,0 +1,46 @@
/dts-v1/;
/include/ "bcm6358.dtsi"
/ {
compatible = "sfr,nb4-ser", "brcm,bcm6358";
model = "SFR Neufbox 4 (Sercomm)";
memory@0 {
device_type = "memory";
reg = <0x00000000 0x02000000>;
};
chosen {
stdout-path = &uart0;
};
};
&leds0 {
status = "ok";
led@0 {
reg = <0>;
active-low;
label = "nb4-ser:white:alarm";
};
led@2 {
reg = <2>;
active-low;
label = "nb4-ser:white:tv";
};
led@3 {
reg = <3>;
active-low;
label = "nb4-ser:white:tel";
};
led@4 {
reg = <4>;
active-low;
label = "nb4-ser:white:adsl";
};
};
&uart0 {
status = "okay";
};

View File

@ -22,10 +22,10 @@ &uart0 {
};
/* FIXME: need to set up USB_CTRL registers first */
&ehci0 {
&ehci {
status = "disabled";
};
&ohci0 {
&ohci {
status = "disabled";
};

View File

@ -21,6 +21,30 @@ &uart0 {
status = "okay";
};
&uart1 {
status = "okay";
};
&uart2 {
status = "okay";
};
&bsca {
status = "okay";
};
&bscb {
status = "okay";
};
&bscc {
status = "okay";
};
&bscd {
status = "okay";
};
/* FIXME: USB is wonky; disable it for now */
&ehci0 {
status = "disabled";

View File

@ -56,3 +56,11 @@ &ehci0 {
&ohci0 {
status = "okay";
};
&sata {
status = "okay";
};
&sata_phy {
status = "okay";
};

View File

@ -23,6 +23,34 @@ &uart0 {
status = "okay";
};
&uart1 {
status = "okay";
};
&uart2 {
status = "okay";
};
&bsca {
status = "okay";
};
&bscb {
status = "okay";
};
&bscc {
status = "okay";
};
&bscd {
status = "okay";
};
&bsce {
status = "okay";
};
/* FIXME: MAC driver comes up but cannot attach to PHY */
&enet0 {
status = "disabled";

View File

@ -23,6 +23,34 @@ &uart0 {
status = "okay";
};
&uart1 {
status = "okay";
};
&uart2 {
status = "okay";
};
&bsca {
status = "okay";
};
&bscb {
status = "okay";
};
&bscc {
status = "okay";
};
&bscd {
status = "okay";
};
&bsce {
status = "okay";
};
&enet0 {
status = "okay";
};

View File

@ -14,7 +14,7 @@ memory@0 {
};
chosen {
bootargs = "console=ttyS0,115200 maxcpus=1";
bootargs = "console=ttyS0,115200";
stdout-path = &uart0;
};
};
@ -23,6 +23,34 @@ &uart0 {
status = "okay";
};
&uart1 {
status = "okay";
};
&uart2 {
status = "okay";
};
&bsca {
status = "okay";
};
&bscb {
status = "okay";
};
&bscc {
status = "okay";
};
&bscd {
status = "okay";
};
&bsce {
status = "okay";
};
&enet0 {
status = "okay";
};
@ -58,3 +86,11 @@ &ehci3 {
&ohci3 {
status = "okay";
};
&sata {
status = "okay";
};
&sata_phy {
status = "okay";
};

View File

@ -0,0 +1,78 @@
/*
* Device tree source for D-Link DSR-1000N.
*
* Written by: Aaro Koskinen <aaro.koskinen@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/include/ "octeon_3xxx.dtsi"
/ {
model = "dlink,dsr-1000n";
soc@0 {
smi0: mdio@1180000001800 {
phy8: ethernet-phy@8 {
reg = <8>;
compatible = "ethernet-phy-ieee802.3-c22";
};
};
pip: pip@11800a0000000 {
interface@0 {
ethernet@0 {
fixed-link {
speed = <1000>;
full-duplex;
};
};
ethernet@1 {
fixed-link {
speed = <1000>;
full-duplex;
};
};
ethernet@2 {
phy-handle = <&phy8>;
};
};
};
twsi0: i2c@1180000001000 {
rtc@68 {
compatible = "dallas,ds1337";
reg = <0x68>;
};
};
uart0: serial@1180000000800 {
clock-frequency = <500000000>;
};
usbn: usbn@1180068000000 {
refclk-frequency = <12000000>;
refclk-type = "crystal";
};
};
leds {
compatible = "gpio-leds";
usb1 {
label = "usb1";
gpios = <&gpio 9 1>; /* Active low */
};
usb2 {
label = "usb2";
gpios = <&gpio 10 1>; /* Active low */
};
};
aliases {
pip = &pip;
};
};

View File

@ -1,4 +1,3 @@
/dts-v1/;
/*
* OCTEON 3XXX, 5XXX, 63XX device tree skeleton.
*
@ -6,56 +5,12 @@
* use. Because of this, it contains a super-set of the available
* devices and properties.
*/
/include/ "octeon_3xxx.dtsi"
/ {
compatible = "cavium,octeon-3860";
#address-cells = <2>;
#size-cells = <2>;
interrupt-parent = <&ciu>;
soc@0 {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges; /* Direct mapping */
ciu: interrupt-controller@1070000000000 {
compatible = "cavium,octeon-3860-ciu";
interrupt-controller;
/* Interrupts are specified by two parts:
* 1) Controller register (0 or 1)
* 2) Bit within the register (0..63)
*/
#interrupt-cells = <2>;
reg = <0x10700 0x00000000 0x0 0x7000>;
};
gpio: gpio-controller@1070000000800 {
#gpio-cells = <2>;
compatible = "cavium,octeon-3860-gpio";
reg = <0x10700 0x00000800 0x0 0x100>;
gpio-controller;
/* Interrupts are specified by two parts:
* 1) GPIO pin number (0..15)
* 2) Triggering (1 - edge rising
* 2 - edge falling
* 4 - level active high
* 8 - level active low)
*/
interrupt-controller;
#interrupt-cells = <2>;
/* The GPIO pin connect to 16 consecutive CUI bits */
interrupts = <0 16>, <0 17>, <0 18>, <0 19>,
<0 20>, <0 21>, <0 22>, <0 23>,
<0 24>, <0 25>, <0 26>, <0 27>,
<0 28>, <0 29>, <0 30>, <0 31>;
};
smi0: mdio@1180000001800 {
compatible = "cavium,octeon-3860-mdio";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x11800 0x00001800 0x0 0x40>;
phy0: ethernet-phy@0 {
compatible = "marvell,88e1118";
marvell,reg-init =
@ -220,35 +175,16 @@ mix1: ethernet@1070000100800 {
};
pip: pip@11800a0000000 {
compatible = "cavium,octeon-3860-pip";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x11800 0xa0000000 0x0 0x2000>;
interface@0 {
compatible = "cavium,octeon-3860-pip-interface";
#address-cells = <1>;
#size-cells = <0>;
reg = <0>; /* interface */
ethernet@0 {
compatible = "cavium,octeon-3860-pip-port";
reg = <0x0>; /* Port */
local-mac-address = [ 00 00 00 00 00 00 ];
phy-handle = <&phy2>;
cavium,alt-phy-handle = <&phy100>;
};
ethernet@1 {
compatible = "cavium,octeon-3860-pip-port";
reg = <0x1>; /* Port */
local-mac-address = [ 00 00 00 00 00 00 ];
phy-handle = <&phy3>;
cavium,alt-phy-handle = <&phy101>;
};
ethernet@2 {
compatible = "cavium,octeon-3860-pip-port";
reg = <0x2>; /* Port */
local-mac-address = [ 00 00 00 00 00 00 ];
phy-handle = <&phy4>;
cavium,alt-phy-handle = <&phy102>;
};
@ -322,11 +258,6 @@ ethernet@f {
};
interface@1 {
compatible = "cavium,octeon-3860-pip-interface";
#address-cells = <1>;
#size-cells = <0>;
reg = <1>; /* interface */
ethernet@0 {
compatible = "cavium,octeon-3860-pip-port";
reg = <0x0>; /* Port */
@ -355,13 +286,6 @@ ethernet@3 {
};
twsi0: i2c@1180000001000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "cavium,octeon-3860-twsi";
reg = <0x11800 0x00001000 0x0 0x200>;
interrupts = <0 45>;
clock-frequency = <100000>;
rtc@68 {
compatible = "dallas,ds1337";
reg = <0x68>;
@ -381,15 +305,6 @@ twsi1: i2c@1180000001200 {
clock-frequency = <100000>;
};
uart0: serial@1180000000800 {
compatible = "cavium,octeon-3860-uart","ns16550";
reg = <0x11800 0x00000800 0x0 0x400>;
clock-frequency = <0>;
current-speed = <115200>;
reg-shift = <3>;
interrupts = <0 34>;
};
uart1: serial@1180000000c00 {
compatible = "cavium,octeon-3860-uart","ns16550";
reg = <0x11800 0x00000c00 0x0 0x400>;
@ -409,98 +324,6 @@ uart2: serial@1180000000400 {
};
bootbus: bootbus@1180000000000 {
compatible = "cavium,octeon-3860-bootbus";
reg = <0x11800 0x00000000 0x0 0x200>;
/* The chip select number and offset */
#address-cells = <2>;
/* The size of the chip select region */
#size-cells = <1>;
ranges = <0 0 0x0 0x1f400000 0xc00000>,
<1 0 0x10000 0x30000000 0>,
<2 0 0x10000 0x40000000 0>,
<3 0 0x10000 0x50000000 0>,
<4 0 0x0 0x1d020000 0x10000>,
<5 0 0x0 0x1d040000 0x10000>,
<6 0 0x0 0x1d050000 0x10000>,
<7 0 0x10000 0x90000000 0>;
cavium,cs-config@0 {
compatible = "cavium,octeon-3860-bootbus-config";
cavium,cs-index = <0>;
cavium,t-adr = <20>;
cavium,t-ce = <60>;
cavium,t-oe = <60>;
cavium,t-we = <45>;
cavium,t-rd-hld = <35>;
cavium,t-wr-hld = <45>;
cavium,t-pause = <0>;
cavium,t-wait = <0>;
cavium,t-page = <35>;
cavium,t-rd-dly = <0>;
cavium,pages = <0>;
cavium,bus-width = <8>;
};
cavium,cs-config@4 {
compatible = "cavium,octeon-3860-bootbus-config";
cavium,cs-index = <4>;
cavium,t-adr = <320>;
cavium,t-ce = <320>;
cavium,t-oe = <320>;
cavium,t-we = <320>;
cavium,t-rd-hld = <320>;
cavium,t-wr-hld = <320>;
cavium,t-pause = <320>;
cavium,t-wait = <320>;
cavium,t-page = <320>;
cavium,t-rd-dly = <0>;
cavium,pages = <0>;
cavium,bus-width = <8>;
};
cavium,cs-config@5 {
compatible = "cavium,octeon-3860-bootbus-config";
cavium,cs-index = <5>;
cavium,t-adr = <5>;
cavium,t-ce = <300>;
cavium,t-oe = <125>;
cavium,t-we = <150>;
cavium,t-rd-hld = <100>;
cavium,t-wr-hld = <30>;
cavium,t-pause = <0>;
cavium,t-wait = <30>;
cavium,t-page = <320>;
cavium,t-rd-dly = <0>;
cavium,pages = <0>;
cavium,bus-width = <16>;
};
cavium,cs-config@6 {
compatible = "cavium,octeon-3860-bootbus-config";
cavium,cs-index = <6>;
cavium,t-adr = <5>;
cavium,t-ce = <300>;
cavium,t-oe = <270>;
cavium,t-we = <150>;
cavium,t-rd-hld = <100>;
cavium,t-wr-hld = <70>;
cavium,t-pause = <0>;
cavium,t-wait = <0>;
cavium,t-page = <320>;
cavium,t-rd-dly = <0>;
cavium,pages = <0>;
cavium,wait-mode;
cavium,bus-width = <16>;
};
flash0: nor@0,0 {
compatible = "cfi-flash";
reg = <0 0 0x800000>;
#address-cells = <1>;
#size-cells = <1>;
};
led0: led-display@4,0 {
compatible = "avago,hdsp-253x";
reg = <4 0x20 0x20>, <4 0 0x20>;
@ -515,17 +338,6 @@ cf0: compact-flash@5,0 {
};
};
dma0: dma-engine@1180000000100 {
compatible = "cavium,octeon-5750-bootbus-dma";
reg = <0x11800 0x00000100 0x0 0x8>;
interrupts = <0 63>;
};
dma1: dma-engine@1180000000108 {
compatible = "cavium,octeon-5750-bootbus-dma";
reg = <0x11800 0x00000108 0x0 0x8>;
interrupts = <0 63>;
};
uctl: uctl@118006f000000 {
compatible = "cavium,octeon-6335-uctl";
reg = <0x11800 0x6f000000 0x0 0x100>;
@ -552,21 +364,10 @@ ohci@16f0000000400 {
};
usbn: usbn@1180068000000 {
compatible = "cavium,octeon-5750-usbn";
reg = <0x11800 0x68000000 0x0 0x1000>;
ranges; /* Direct mapping */
#address-cells = <2>;
#size-cells = <2>;
/* 12MHz, 24MHz and 48MHz allowed */
refclk-frequency = <12000000>;
/* Either "crystal" or "external" */
refclk-type = "crystal";
usbc@16f0010000000 {
compatible = "cavium,octeon-5750-usbc";
reg = <0x16f00 0x10000000 0x0 0x80000>;
interrupts = <0 56>;
};
};
};

View File

@ -0,0 +1,231 @@
/* OCTEON 3XXX DTS common parts. */
/dts-v1/;
/ {
compatible = "cavium,octeon-3860";
#address-cells = <2>;
#size-cells = <2>;
interrupt-parent = <&ciu>;
soc@0 {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges; /* Direct mapping */
ciu: interrupt-controller@1070000000000 {
compatible = "cavium,octeon-3860-ciu";
interrupt-controller;
/* Interrupts are specified by two parts:
* 1) Controller register (0 or 1)
* 2) Bit within the register (0..63)
*/
#interrupt-cells = <2>;
reg = <0x10700 0x00000000 0x0 0x7000>;
};
gpio: gpio-controller@1070000000800 {
#gpio-cells = <2>;
compatible = "cavium,octeon-3860-gpio";
reg = <0x10700 0x00000800 0x0 0x100>;
gpio-controller;
/* Interrupts are specified by two parts:
* 1) GPIO pin number (0..15)
* 2) Triggering (1 - edge rising
* 2 - edge falling
* 4 - level active high
* 8 - level active low)
*/
interrupt-controller;
#interrupt-cells = <2>;
/* The GPIO pin connect to 16 consecutive CUI bits */
interrupts = <0 16>, <0 17>, <0 18>, <0 19>,
<0 20>, <0 21>, <0 22>, <0 23>,
<0 24>, <0 25>, <0 26>, <0 27>,
<0 28>, <0 29>, <0 30>, <0 31>;
};
smi0: mdio@1180000001800 {
compatible = "cavium,octeon-3860-mdio";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x11800 0x00001800 0x0 0x40>;
};
pip: pip@11800a0000000 {
compatible = "cavium,octeon-3860-pip";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x11800 0xa0000000 0x0 0x2000>;
interface@0 {
compatible = "cavium,octeon-3860-pip-interface";
#address-cells = <1>;
#size-cells = <0>;
reg = <0>; /* interface */
ethernet@0 {
compatible = "cavium,octeon-3860-pip-port";
reg = <0x0>; /* Port */
local-mac-address = [ 00 00 00 00 00 00 ];
};
ethernet@1 {
compatible = "cavium,octeon-3860-pip-port";
reg = <0x1>; /* Port */
local-mac-address = [ 00 00 00 00 00 00 ];
};
ethernet@2 {
compatible = "cavium,octeon-3860-pip-port";
reg = <0x2>; /* Port */
local-mac-address = [ 00 00 00 00 00 00 ];
};
};
interface@1 {
compatible = "cavium,octeon-3860-pip-interface";
#address-cells = <1>;
#size-cells = <0>;
reg = <1>; /* interface */
};
};
twsi0: i2c@1180000001000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "cavium,octeon-3860-twsi";
reg = <0x11800 0x00001000 0x0 0x200>;
interrupts = <0 45>;
clock-frequency = <100000>;
};
uart0: serial@1180000000800 {
compatible = "cavium,octeon-3860-uart","ns16550";
reg = <0x11800 0x00000800 0x0 0x400>;
clock-frequency = <0>;
current-speed = <115200>;
reg-shift = <3>;
interrupts = <0 34>;
};
bootbus: bootbus@1180000000000 {
compatible = "cavium,octeon-3860-bootbus";
reg = <0x11800 0x00000000 0x0 0x200>;
/* The chip select number and offset */
#address-cells = <2>;
/* The size of the chip select region */
#size-cells = <1>;
ranges = <0 0 0x0 0x1f400000 0xc00000>,
<1 0 0x10000 0x30000000 0>,
<2 0 0x10000 0x40000000 0>,
<3 0 0x10000 0x50000000 0>,
<4 0 0x0 0x1d020000 0x10000>,
<5 0 0x0 0x1d040000 0x10000>,
<6 0 0x0 0x1d050000 0x10000>,
<7 0 0x10000 0x90000000 0>;
cavium,cs-config@0 {
compatible = "cavium,octeon-3860-bootbus-config";
cavium,cs-index = <0>;
cavium,t-adr = <20>;
cavium,t-ce = <60>;
cavium,t-oe = <60>;
cavium,t-we = <45>;
cavium,t-rd-hld = <35>;
cavium,t-wr-hld = <45>;
cavium,t-pause = <0>;
cavium,t-wait = <0>;
cavium,t-page = <35>;
cavium,t-rd-dly = <0>;
cavium,pages = <0>;
cavium,bus-width = <8>;
};
cavium,cs-config@4 {
compatible = "cavium,octeon-3860-bootbus-config";
cavium,cs-index = <4>;
cavium,t-adr = <320>;
cavium,t-ce = <320>;
cavium,t-oe = <320>;
cavium,t-we = <320>;
cavium,t-rd-hld = <320>;
cavium,t-wr-hld = <320>;
cavium,t-pause = <320>;
cavium,t-wait = <320>;
cavium,t-page = <320>;
cavium,t-rd-dly = <0>;
cavium,pages = <0>;
cavium,bus-width = <8>;
};
cavium,cs-config@5 {
compatible = "cavium,octeon-3860-bootbus-config";
cavium,cs-index = <5>;
cavium,t-adr = <5>;
cavium,t-ce = <300>;
cavium,t-oe = <125>;
cavium,t-we = <150>;
cavium,t-rd-hld = <100>;
cavium,t-wr-hld = <30>;
cavium,t-pause = <0>;
cavium,t-wait = <30>;
cavium,t-page = <320>;
cavium,t-rd-dly = <0>;
cavium,pages = <0>;
cavium,bus-width = <16>;
};
cavium,cs-config@6 {
compatible = "cavium,octeon-3860-bootbus-config";
cavium,cs-index = <6>;
cavium,t-adr = <5>;
cavium,t-ce = <300>;
cavium,t-oe = <270>;
cavium,t-we = <150>;
cavium,t-rd-hld = <100>;
cavium,t-wr-hld = <70>;
cavium,t-pause = <0>;
cavium,t-wait = <0>;
cavium,t-page = <320>;
cavium,t-rd-dly = <0>;
cavium,pages = <0>;
cavium,wait-mode;
cavium,bus-width = <16>;
};
flash0: nor@0,0 {
compatible = "cfi-flash";
reg = <0 0 0x800000>;
#address-cells = <1>;
#size-cells = <1>;
};
};
dma0: dma-engine@1180000000100 {
compatible = "cavium,octeon-5750-bootbus-dma";
reg = <0x11800 0x00000100 0x0 0x8>;
interrupts = <0 63>;
};
dma1: dma-engine@1180000000108 {
compatible = "cavium,octeon-5750-bootbus-dma";
reg = <0x11800 0x00000108 0x0 0x8>;
interrupts = <0 63>;
};
usbn: usbn@1180068000000 {
compatible = "cavium,octeon-5750-usbn";
reg = <0x11800 0x68000000 0x0 0x1000>;
ranges; /* Direct mapping */
#address-cells = <2>;
#size-cells = <2>;
usbc@16f0010000000 {
compatible = "cavium,octeon-5750-usbc";
reg = <0x16f00 0x10000000 0x0 0x80000>;
interrupts = <0 56>;
};
};
};
};

View File

@ -0,0 +1,59 @@
/*
* Device tree source for EdgeRouter Lite.
*
* Written by: Aaro Koskinen <aaro.koskinen@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/include/ "octeon_3xxx.dtsi"
/ {
model = "ubnt,e100";
soc@0 {
smi0: mdio@1180000001800 {
phy5: ethernet-phy@5 {
reg = <5>;
compatible = "ethernet-phy-ieee802.3-c22";
};
phy6: ethernet-phy@6 {
reg = <6>;
compatible = "ethernet-phy-ieee802.3-c22";
};
phy7: ethernet-phy@7 {
reg = <7>;
compatible = "ethernet-phy-ieee802.3-c22";
};
};
pip: pip@11800a0000000 {
interface@0 {
ethernet@0 {
phy-handle = <&phy7>;
};
ethernet@1 {
phy-handle = <&phy6>;
};
ethernet@2 {
phy-handle = <&phy5>;
};
};
};
uart0: serial@1180000000800 {
clock-frequency = <500000000>;
};
usbn: usbn@1180068000000 {
refclk-frequency = <12000000>;
refclk-type = "crystal";
};
};
aliases {
pip = &pip;
};
};

View File

@ -65,4 +65,18 @@ uart1: serial@10031000 {
clocks = <&ext>, <&cgu JZ4740_CLK_UART1>;
clock-names = "baud", "module";
};
uhc: uhc@13030000 {
compatible = "ingenic,jz4740-ohci", "generic-ohci";
reg = <0x13030000 0x1000>;
clocks = <&cgu JZ4740_CLK_UHC>;
assigned-clocks = <&cgu JZ4740_CLK_UHC>;
assigned-clock-rates = <48000000>;
interrupt-parent = <&intc>;
interrupts = <3>;
status = "disabled";
};
};

View File

@ -52,7 +52,7 @@ partition@400000 {
};
gpio: pinmux@E100B10 {
compatible = "lantiq,pinctrl-xway";
compatible = "lantiq,danube-pinctrl";
pinctrl-names = "default";
pinctrl-0 = <&state_default>;

View File

@ -1,236 +0,0 @@
/*
* Device Tree Source for PIC32MZDA clock data
*
* Purna Chandra Mandal <purna.mandal@microchip.com>
* Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
*
* Licensed under GPLv2 or later.
*/
/* all fixed rate clocks */
/ {
POSC:posc_clk { /* On-chip primary oscillator */
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
};
FRC:frc_clk { /* internal FRC oscillator */
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <8000000>;
};
BFRC:bfrc_clk { /* internal backup FRC oscillator */
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <8000000>;
};
LPRC:lprc_clk { /* internal low-power FRC oscillator */
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32000>;
};
/* UPLL provides clock to USBCORE */
UPLL:usb_phy_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "usbphy_clk";
};
TxCKI:txcki_clk { /* external clock input on TxCLKI pin */
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <4000000>;
status = "disabled";
};
/* external clock input on REFCLKIx pin */
REFIx:refix_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
status = "disabled";
};
/* PIC32 specific clks */
pic32_clktree {
#address-cells = <1>;
#size-cells = <1>;
reg = <0x1f801200 0x200>;
compatible = "microchip,pic32mzda-clk";
ranges = <0 0x1f801200 0x200>;
/* secondary oscillator; external input on SOSCI pin */
SOSC:sosc_clk@0 {
#clock-cells = <0>;
compatible = "microchip,pic32mzda-sosc";
clock-frequency = <32768>;
reg = <0x000 0x10>, /* enable reg */
<0x1d0 0x10>; /* status reg */
microchip,bit-mask = <0x02>; /* enable mask */
microchip,status-bit-mask = <0x10>; /* status-mask*/
};
FRCDIV:frcdiv_clk {
#clock-cells = <0>;
compatible = "microchip,pic32mzda-frcdivclk";
clocks = <&FRC>;
clock-output-names = "frcdiv_clk";
};
/* System PLL clock */
SYSPLL:spll_clk@020 {
#clock-cells = <0>;
compatible = "microchip,pic32mzda-syspll";
reg = <0x020 0x10>, /* SPLL register */
<0x1d0 0x10>; /* CLKSTAT register */
clocks = <&POSC>, <&FRC>;
clock-output-names = "sys_pll";
microchip,status-bit-mask = <0x80>; /* SPLLRDY */
};
/* system clock; mux with postdiv & slew */
SYSCLK:sys_clk@1c0 {
#clock-cells = <0>;
compatible = "microchip,pic32mzda-sysclk-v2";
reg = <0x1c0 0x04>; /* SLEWCON */
clocks = <&FRCDIV>, <&SYSPLL>, <&POSC>, <&SOSC>,
<&LPRC>, <&FRCDIV>;
microchip,clock-indices = <0>, <1>, <2>, <4>,
<5>, <7>;
clock-output-names = "sys_clk";
};
/* Peripheral bus1 clock */
PBCLK1:pb1_clk@140 {
reg = <0x140 0x10>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-pbclk";
clocks = <&SYSCLK>;
clock-output-names = "pb1_clk";
/* used by system modules, not gateable */
microchip,ignore-unused;
};
/* Peripheral bus2 clock */
PBCLK2:pb2_clk@150 {
reg = <0x150 0x10>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-pbclk";
clocks = <&SYSCLK>;
clock-output-names = "pb2_clk";
/* avoid gating even if unused */
microchip,ignore-unused;
};
/* Peripheral bus3 clock */
PBCLK3:pb3_clk@160 {
reg = <0x160 0x10>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-pbclk";
clocks = <&SYSCLK>;
clock-output-names = "pb3_clk";
};
/* Peripheral bus4 clock(I/O ports, GPIO) */
PBCLK4:pb4_clk@170 {
reg = <0x170 0x10>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-pbclk";
clocks = <&SYSCLK>;
clock-output-names = "pb4_clk";
};
/* Peripheral bus clock */
PBCLK5:pb5_clk@180 {
reg = <0x180 0x10>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-pbclk";
clocks = <&SYSCLK>;
clock-output-names = "pb5_clk";
};
/* Peripheral Bus6 clock; */
PBCLK6:pb6_clk@190 {
reg = <0x190 0x10>;
compatible = "microchip,pic32mzda-pbclk";
clocks = <&SYSCLK>;
#clock-cells = <0>;
};
/* Peripheral bus7 clock */
PBCLK7:pb7_clk@1a0 {
reg = <0x1a0 0x10>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-pbclk";
/* CPU is driven by this clock; so named */
clock-output-names = "cpu_clk";
clocks = <&SYSCLK>;
};
/* Reference Oscillator clock for SPI/I2S */
REFCLKO1:refo1_clk@80 {
reg = <0x080 0x20>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-refoclk";
clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
<&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
<5>, <7>, <8>, <9>;
clock-output-names = "refo1_clk";
};
/* Reference Oscillator clock for SQI */
REFCLKO2:refo2_clk@a0 {
reg = <0x0a0 0x20>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-refoclk";
clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
<&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
<5>, <7>, <8>, <9>;
clock-output-names = "refo2_clk";
};
/* Reference Oscillator clock, ADC */
REFCLKO3:refo3_clk@c0 {
reg = <0x0c0 0x20>;
compatible = "microchip,pic32mzda-refoclk";
clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
<&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
<5>, <7>, <8>, <9>;
#clock-cells = <0>;
clock-output-names = "refo3_clk";
};
/* Reference Oscillator clock */
REFCLKO4:refo4_clk@e0 {
reg = <0x0e0 0x20>;
compatible = "microchip,pic32mzda-refoclk";
clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
<&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
<5>, <7>, <8>, <9>;
#clock-cells = <0>;
clock-output-names = "refo4_clk";
};
/* Reference Oscillator clock, LCD */
REFCLKO5:refo5_clk@100 {
reg = <0x100 0x20>;
compatible = "microchip,pic32mzda-refoclk";
clocks = <&SYSCLK>,<&PBCLK1>,<&POSC>,<&FRC>,<&LPRC>,
<&SOSC>,<&SYSPLL>,<&REFIx>,<&BFRC>;
microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
<5>, <7>, <8>, <9>;
#clock-cells = <0>;
clock-output-names = "refo5_clk";
};
};
};

View File

@ -6,11 +6,9 @@
* published by the Free Software Foundation.
*
*/
#include <dt-bindings/clock/microchip,pic32-clock.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include "pic32mzda-clk.dtsi"
/ {
#address-cells = <1>;
#size-cells = <1>;
@ -50,6 +48,29 @@ soc {
interrupts = <0 IRQ_TYPE_EDGE_RISING>;
};
/* external clock input on TxCLKI pin */
txcki: txcki_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <4000000>;
status = "disabled";
};
/* external input on REFCLKIx pin */
refix: refix_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
status = "disabled";
};
rootclk: clock-controller@1f801200 {
compatible = "microchip,pic32mzda-clk";
reg = <0x1f801200 0x200>;
#clock-cells = <1>;
microchip,pic32mzda-sosc;
};
evic: interrupt-controller@1f810000 {
compatible = "microchip,pic32mzda-evic";
interrupt-controller;
@ -63,7 +84,7 @@ pic32_pinctrl: pinctrl@1f801400{
#size-cells = <1>;
compatible = "microchip,pic32mzda-pinctrl";
reg = <0x1f801400 0x400>;
clocks = <&PBCLK1>;
clocks = <&rootclk PB1CLK>;
};
/* PORTA */
@ -75,7 +96,7 @@ gpio0: gpio0@1f860000 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
clocks = <&rootclk PB4CLK>;
microchip,gpio-bank = <0>;
gpio-ranges = <&pic32_pinctrl 0 0 16>;
};
@ -89,7 +110,7 @@ gpio1: gpio1@1f860100 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
clocks = <&rootclk PB4CLK>;
microchip,gpio-bank = <1>;
gpio-ranges = <&pic32_pinctrl 0 16 16>;
};
@ -103,7 +124,7 @@ gpio2: gpio2@1f860200 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
clocks = <&rootclk PB4CLK>;
microchip,gpio-bank = <2>;
gpio-ranges = <&pic32_pinctrl 0 32 16>;
};
@ -117,7 +138,7 @@ gpio3: gpio3@1f860300 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
clocks = <&rootclk PB4CLK>;
microchip,gpio-bank = <3>;
gpio-ranges = <&pic32_pinctrl 0 48 16>;
};
@ -131,7 +152,7 @@ gpio4: gpio4@1f860400 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
clocks = <&rootclk PB4CLK>;
microchip,gpio-bank = <4>;
gpio-ranges = <&pic32_pinctrl 0 64 16>;
};
@ -145,7 +166,7 @@ gpio5: gpio5@1f860500 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
clocks = <&rootclk PB4CLK>;
microchip,gpio-bank = <5>;
gpio-ranges = <&pic32_pinctrl 0 80 16>;
};
@ -159,7 +180,7 @@ gpio6: gpio6@1f860600 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
clocks = <&rootclk PB4CLK>;
microchip,gpio-bank = <6>;
gpio-ranges = <&pic32_pinctrl 0 96 16>;
};
@ -173,7 +194,7 @@ gpio7: gpio7@1f860700 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
clocks = <&rootclk PB4CLK>;
microchip,gpio-bank = <7>;
gpio-ranges = <&pic32_pinctrl 0 112 16>;
};
@ -189,7 +210,7 @@ gpio8: gpio8@1f860800 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
clocks = <&rootclk PB4CLK>;
microchip,gpio-bank = <8>;
gpio-ranges = <&pic32_pinctrl 0 128 16>;
};
@ -203,7 +224,7 @@ gpio9: gpio9@1f860900 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
clocks = <&rootclk PB4CLK>;
microchip,gpio-bank = <9>;
gpio-ranges = <&pic32_pinctrl 0 144 16>;
};
@ -212,7 +233,7 @@ sdhci: sdhci@1f8ec000 {
compatible = "microchip,pic32mzda-sdhci";
reg = <0x1f8ec000 0x100>;
interrupts = <191 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&REFCLKO4>, <&PBCLK5>;
clocks = <&rootclk REF4CLK>, <&rootclk PB5CLK>;
clock-names = "base_clk", "sys_clk";
bus-width = <4>;
cap-sd-highspeed;
@ -225,7 +246,7 @@ uart1: serial@1f822000 {
interrupts = <112 IRQ_TYPE_LEVEL_HIGH>,
<113 IRQ_TYPE_LEVEL_HIGH>,
<114 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&PBCLK2>;
clocks = <&rootclk PB2CLK>;
status = "disabled";
};
@ -235,7 +256,7 @@ uart2: serial@1f822200 {
interrupts = <145 IRQ_TYPE_LEVEL_HIGH>,
<146 IRQ_TYPE_LEVEL_HIGH>,
<147 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&PBCLK2>;
clocks = <&rootclk PB2CLK>;
status = "disabled";
};
@ -245,7 +266,7 @@ uart3: serial@1f822400 {
interrupts = <157 IRQ_TYPE_LEVEL_HIGH>,
<158 IRQ_TYPE_LEVEL_HIGH>,
<159 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&PBCLK2>;
clocks = <&rootclk PB2CLK>;
status = "disabled";
};
@ -255,7 +276,7 @@ uart4: serial@1f822600 {
interrupts = <170 IRQ_TYPE_LEVEL_HIGH>,
<171 IRQ_TYPE_LEVEL_HIGH>,
<172 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&PBCLK2>;
clocks = <&rootclk PB2CLK>;
status = "disabled";
};
@ -265,7 +286,7 @@ uart5: serial@1f822800 {
interrupts = <179 IRQ_TYPE_LEVEL_HIGH>,
<180 IRQ_TYPE_LEVEL_HIGH>,
<181 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&PBCLK2>;
clocks = <&rootclk PB2CLK>;
status = "disabled";
};
@ -275,7 +296,7 @@ uart6: serial@1f822A00 {
interrupts = <188 IRQ_TYPE_LEVEL_HIGH>,
<189 IRQ_TYPE_LEVEL_HIGH>,
<190 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&PBCLK2>;
clocks = <&rootclk PB2CLK>;
status = "disabled";
};
};

View File

@ -95,8 +95,9 @@ &sdhci {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sdhc1>;
status = "okay";
assigned-clocks = <&REFCLKO2>,<&REFCLKO4>,<&REFCLKO5>;
assigned-clock-rates = <50000000>,<25000000>,<40000000>;
assigned-clocks = <&rootclk REF2CLK>, <&rootclk REF4CLK>,
<&rootclk REF5CLK>;
assigned-clock-rates = <50000000>, <25000000>, <40000000>;
};
&pic32_pinctrl {

View File

@ -1,8 +1,9 @@
# All DTBs
dtb-$(CONFIG_ATH79) += ar9132_tl_wr1043nd_v1.dtb
# Select a DTB to build in the kernel
obj-$(CONFIG_DTB_TL_WR1043ND_V1) += ar9132_tl_wr1043nd_v1.dtb.o
dtb-$(CONFIG_ATH79) += ar9331_dpt_module.dtb
dtb-$(CONFIG_ATH79) += ar9331_dragino_ms14.dtb
dtb-$(CONFIG_ATH79) += ar9331_omega.dtb
dtb-$(CONFIG_ATH79) += ar9331_tl_mr3020.dtb
# Force kbuild to make empty built-in.o if necessary
obj- += dummy.o

View File

@ -1,3 +1,5 @@
#include <dt-bindings/clock/ath79-clk.h>
/ {
compatible = "qca,ar9132";
@ -11,6 +13,7 @@ cpus {
cpu@0 {
device_type = "cpu";
compatible = "mips,mips24Kc";
clocks = <&pll ATH79_CLK_CPU>;
reg = <0>;
};
};
@ -52,12 +55,12 @@ ddr_ctrl: memory-controller@18000000 {
#qca,ddr-wb-channel-cells = <1>;
};
uart@18020000 {
uart: uart@18020000 {
compatible = "ns8250";
reg = <0x18020000 0x20>;
interrupts = <3>;
clocks = <&pll 2>;
clocks = <&pll ATH79_CLK_AHB>;
clock-names = "uart";
reg-io-width = <4>;
@ -94,13 +97,13 @@ pll: pll-controller@18050000 {
clock-output-names = "cpu", "ddr", "ahb";
};
wdt@18060008 {
wdt: wdt@18060008 {
compatible = "qca,ar7130-wdt";
reg = <0x18060008 0x8>;
interrupts = <4>;
clocks = <&pll 2>;
clocks = <&pll ATH79_CLK_AHB>;
clock-names = "wdt";
};
@ -125,7 +128,7 @@ rst: reset-controller@1806001c {
};
};
usb@1b000100 {
usb: usb@1b000100 {
compatible = "qca,ar7100-ehci", "generic-ehci";
reg = <0x1b000100 0x100>;
@ -140,11 +143,11 @@ usb@1b000100 {
status = "disabled";
};
spi@1f000000 {
spi: spi@1f000000 {
compatible = "qca,ar9132-spi", "qca,ar7100-spi";
reg = <0x1f000000 0x10>;
clocks = <&pll 2>;
clocks = <&pll ATH79_CLK_AHB>;
clock-names = "ahb";
status = "disabled";

View File

@ -9,10 +9,6 @@ / {
compatible = "tplink,tl-wr1043nd-v1", "qca,ar9132";
model = "TP-Link TL-WR1043ND Version 1";
alias {
serial0 = "/ahb/apb/uart@18020000";
};
memory@0 {
device_type = "memory";
reg = <0x0 0x2000000>;
@ -24,55 +20,6 @@ extosc: ref {
clock-frequency = <40000000>;
};
ahb {
apb {
uart@18020000 {
status = "okay";
};
pll-controller@18050000 {
clocks = <&extosc>;
};
};
usb@1b000100 {
status = "okay";
};
spi@1f000000 {
status = "okay";
num-cs = <1>;
flash@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "s25sl064a";
reg = <0>;
spi-max-frequency = <25000000>;
partition@0 {
label = "u-boot";
reg = <0x000000 0x020000>;
};
partition@1 {
label = "firmware";
reg = <0x020000 0x7D0000>;
};
partition@2 {
label = "art";
reg = <0x7F0000 0x010000>;
read-only;
};
};
};
};
usb-phy {
status = "okay";
};
gpio-keys {
compatible = "gpio-keys-polled";
#address-cells = <1>;
@ -118,3 +65,48 @@ led@3 {
};
};
};
&uart {
status = "okay";
};
&pll {
clocks = <&extosc>;
};
&usb {
status = "okay";
};
&usb_phy {
status = "okay";
};
&spi {
status = "okay";
num-cs = <1>;
flash@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "s25sl064a";
reg = <0>;
spi-max-frequency = <25000000>;
partition@0 {
label = "u-boot";
reg = <0x000000 0x020000>;
};
partition@1 {
label = "firmware";
reg = <0x020000 0x7D0000>;
};
partition@2 {
label = "art";
reg = <0x7F0000 0x010000>;
read-only;
};
};
};

View File

@ -0,0 +1,155 @@
#include <dt-bindings/clock/ath79-clk.h>
/ {
compatible = "qca,ar9331";
#address-cells = <1>;
#size-cells = <1>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
device_type = "cpu";
compatible = "mips,mips24Kc";
clocks = <&pll ATH79_CLK_CPU>;
reg = <0>;
};
};
cpuintc: interrupt-controller {
compatible = "qca,ar7100-cpu-intc";
interrupt-controller;
#interrupt-cells = <1>;
qca,ddr-wb-channel-interrupts = <2>, <3>;
qca,ddr-wb-channels = <&ddr_ctrl 3>, <&ddr_ctrl 2>;
};
ref: ref {
compatible = "fixed-clock";
#clock-cells = <0>;
};
ahb {
compatible = "simple-bus";
ranges;
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&cpuintc>;
apb {
compatible = "simple-bus";
ranges;
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&miscintc>;
ddr_ctrl: memory-controller@18000000 {
compatible = "qca,ar7240-ddr-controller";
reg = <0x18000000 0x100>;
#qca,ddr-wb-channel-cells = <1>;
};
uart: uart@18020000 {
compatible = "qca,ar9330-uart";
reg = <0x18020000 0x14>;
interrupts = <3>;
clocks = <&ref>;
clock-names = "uart";
status = "disabled";
};
gpio: gpio@18040000 {
compatible = "qca,ar7100-gpio";
reg = <0x18040000 0x34>;
interrupts = <2>;
ngpios = <30>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
status = "disabled";
};
pll: pll-controller@18050000 {
compatible = "qca,ar9330-pll";
reg = <0x18050000 0x100>;
clocks = <&ref>;
clock-names = "ref";
#clock-cells = <1>;
};
miscintc: interrupt-controller@18060010 {
compatible = "qca,ar7240-misc-intc";
reg = <0x18060010 0x4>;
interrupt-parent = <&cpuintc>;
interrupts = <6>;
interrupt-controller;
#interrupt-cells = <1>;
};
rst: reset-controller@1806001c {
compatible = "qca,ar7100-reset";
reg = <0x1806001c 0x4>;
#reset-cells = <1>;
};
};
usb: usb@1b000100 {
compatible = "chipidea,usb2";
reg = <0x1b000000 0x200>;
interrupts = <3>;
resets = <&rst 5>;
phy-names = "usb-phy";
phys = <&usb_phy>;
status = "disabled";
};
spi: spi@1f000000 {
compatible = "qca,ar7100-spi";
reg = <0x1f000000 0x10>;
clocks = <&pll ATH79_CLK_AHB>;
clock-names = "ahb";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
};
usb_phy: usb-phy {
compatible = "qca,ar7100-usb-phy";
reset-names = "usb-phy", "usb-suspend-override";
resets = <&rst 4>, <&rst 3>;
#phy-cells = <0>;
status = "disabled";
};
};

View File

@ -0,0 +1,78 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "ar9331.dtsi"
/ {
model = "DPTechnics DPT-Module";
compatible = "dptechnics,dpt-module";
aliases {
serial0 = &uart;
};
memory@0 {
device_type = "memory";
reg = <0x0 0x4000000>;
};
leds {
compatible = "gpio-leds";
system {
label = "dpt-module:green:system";
gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
default-state = "off";
};
};
gpio-keys-polled {
compatible = "gpio-keys-polled";
#address-cells = <1>;
#size-cells = <0>;
poll-interval = <100>;
button@0 {
label = "reset";
linux,code = <KEY_RESTART>;
gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
};
};
};
&ref {
clock-frequency = <25000000>;
};
&uart {
status = "okay";
};
&gpio {
status = "okay";
};
&usb {
dr_mode = "host";
status = "okay";
};
&usb_phy {
status = "okay";
};
&spi {
num-chipselects = <1>;
status = "okay";
/* Winbond 25Q128FVSG SPI flash */
spiflash: w25q128@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "winbond,w25q128", "jedec,spi-nor";
spi-max-frequency = <104000000>;
reg = <0>;
};
};

View File

@ -0,0 +1,102 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "ar9331.dtsi"
/ {
model = "Dragino MS14 (Dragino 2)";
compatible = "dragino,ms14";
aliases {
serial0 = &uart;
};
memory@0 {
device_type = "memory";
reg = <0x0 0x4000000>;
};
leds {
compatible = "gpio-leds";
wlan {
label = "dragino2:red:wlan";
gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
lan {
label = "dragino2:red:lan";
gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
default-state = "off";
};
wan {
label = "dragino2:red:wan";
gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
default-state = "off";
};
system {
label = "dragino2:red:system";
gpios = <&gpio 28 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
};
gpio-keys-polled {
compatible = "gpio-keys-polled";
#address-cells = <1>;
#size-cells = <0>;
poll-interval = <100>;
button@0 {
label = "jumpstart";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
};
button@1 {
label = "reset";
linux,code = <KEY_RESTART>;
gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
};
};
};
&ref {
clock-frequency = <25000000>;
};
&uart {
status = "okay";
};
&gpio {
status = "okay";
};
&usb {
dr_mode = "host";
status = "okay";
};
&usb_phy {
status = "okay";
};
&spi {
num-chipselects = <1>;
status = "okay";
/* Winbond 25Q128BVFG SPI flash */
spiflash: w25q128@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "winbond,w25q128", "jedec,spi-nor";
spi-max-frequency = <104000000>;
reg = <0>;
};
};

View File

@ -0,0 +1,78 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "ar9331.dtsi"
/ {
model = "Onion Omega";
compatible = "onion,omega";
aliases {
serial0 = &uart;
};
memory@0 {
device_type = "memory";
reg = <0x0 0x4000000>;
};
leds {
compatible = "gpio-leds";
system {
label = "onion:amber:system";
gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
default-state = "off";
};
};
gpio-keys-polled {
compatible = "gpio-keys-polled";
#address-cells = <1>;
#size-cells = <0>;
poll-interval = <100>;
button@0 {
label = "reset";
linux,code = <KEY_RESTART>;
gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
};
};
};
&ref {
clock-frequency = <25000000>;
};
&uart {
status = "okay";
};
&gpio {
status = "okay";
};
&usb {
dr_mode = "host";
status = "okay";
};
&usb_phy {
status = "okay";
};
&spi {
num-chipselects = <1>;
status = "okay";
/* Winbond 25Q128FVSG SPI flash */
spiflash: w25q128@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "winbond,w25q128", "jedec,spi-nor";
spi-max-frequency = <104000000>;
reg = <0>;
};
};

View File

@ -0,0 +1,118 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "ar9331.dtsi"
/ {
model = "TP-Link TL-MR3020";
compatible = "tplink,tl-mr3020";
aliases {
serial0 = &uart;
};
memory@0 {
device_type = "memory";
reg = <0x0 0x2000000>;
};
leds {
compatible = "gpio-leds";
wlan {
label = "tp-link:green:wlan";
gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
lan {
label = "tp-link:green:lan";
gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
default-state = "off";
};
wps {
label = "tp-link:green:wps";
gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
default-state = "off";
};
led3g {
label = "tp-link:green:3g";
gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
default-state = "off";
};
};
gpio-keys-polled {
compatible = "gpio-keys-polled";
#address-cells = <1>;
#size-cells = <0>;
poll-interval = <100>;
button@0 {
label = "wps";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
};
button@1 {
label = "sw1";
linux,code = <BTN_0>;
gpios = <&gpio 18 GPIO_ACTIVE_HIGH>;
};
button@2 {
label = "sw2";
linux,code = <BTN_1>;
gpios = <&gpio 20 GPIO_ACTIVE_HIGH>;
};
};
reg_usb_vbus: reg_usb_vbus {
compatible = "regulator-fixed";
regulator-name = "usb_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&gpio 8 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
};
&ref {
clock-frequency = <25000000>;
};
&uart {
status = "okay";
};
&gpio {
status = "okay";
};
&usb {
dr_mode = "host";
vbus-supply = <&reg_usb_vbus>;
status = "okay";
};
&usb_phy {
status = "okay";
};
&spi {
num-chipselects = <1>;
status = "okay";
/* Spansion S25FL032PIF SPI flash */
spiflash: s25sl032p@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "spansion,s25sl032p", "jedec,spi-nor";
spi-max-frequency = <104000000>;
reg = <0>;
};
};

1
arch/mips/boot/tools/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
relocs

View File

@ -0,0 +1,8 @@
hostprogs-y += relocs
relocs-objs += relocs_32.o
relocs-objs += relocs_64.o
relocs-objs += relocs_main.o
PHONY += relocs
relocs: $(obj)/relocs
@:

View File

@ -0,0 +1,680 @@
/* This is included from relocs_32/64.c */
#define ElfW(type) _ElfW(ELF_BITS, type)
#define _ElfW(bits, type) __ElfW(bits, type)
#define __ElfW(bits, type) Elf##bits##_##type
#define Elf_Addr ElfW(Addr)
#define Elf_Ehdr ElfW(Ehdr)
#define Elf_Phdr ElfW(Phdr)
#define Elf_Shdr ElfW(Shdr)
#define Elf_Sym ElfW(Sym)
static Elf_Ehdr ehdr;
struct relocs {
uint32_t *offset;
unsigned long count;
unsigned long size;
};
static struct relocs relocs;
struct section {
Elf_Shdr shdr;
struct section *link;
Elf_Sym *symtab;
Elf_Rel *reltab;
char *strtab;
long shdr_offset;
};
static struct section *secs;
static const char * const regex_sym_kernel = {
/* Symbols matching these regex's should never be relocated */
"^(__crc_)",
};
static regex_t sym_regex_c;
static int regex_skip_reloc(const char *sym_name)
{
return !regexec(&sym_regex_c, sym_name, 0, NULL, 0);
}
static void regex_init(void)
{
char errbuf[128];
int err;
err = regcomp(&sym_regex_c, regex_sym_kernel,
REG_EXTENDED|REG_NOSUB);
if (err) {
regerror(err, &sym_regex_c, errbuf, sizeof(errbuf));
die("%s", errbuf);
}
}
static const char *rel_type(unsigned type)
{
static const char * const type_name[] = {
#define REL_TYPE(X)[X] = #X
REL_TYPE(R_MIPS_NONE),
REL_TYPE(R_MIPS_16),
REL_TYPE(R_MIPS_32),
REL_TYPE(R_MIPS_REL32),
REL_TYPE(R_MIPS_26),
REL_TYPE(R_MIPS_HI16),
REL_TYPE(R_MIPS_LO16),
REL_TYPE(R_MIPS_GPREL16),
REL_TYPE(R_MIPS_LITERAL),
REL_TYPE(R_MIPS_GOT16),
REL_TYPE(R_MIPS_PC16),
REL_TYPE(R_MIPS_CALL16),
REL_TYPE(R_MIPS_GPREL32),
REL_TYPE(R_MIPS_64),
REL_TYPE(R_MIPS_HIGHER),
REL_TYPE(R_MIPS_HIGHEST),
REL_TYPE(R_MIPS_PC21_S2),
REL_TYPE(R_MIPS_PC26_S2),
#undef REL_TYPE
};
const char *name = "unknown type rel type name";
if (type < ARRAY_SIZE(type_name) && type_name[type])
name = type_name[type];
return name;
}
static const char *sec_name(unsigned shndx)
{
const char *sec_strtab;
const char *name;
sec_strtab = secs[ehdr.e_shstrndx].strtab;
if (shndx < ehdr.e_shnum)
name = sec_strtab + secs[shndx].shdr.sh_name;
else if (shndx == SHN_ABS)
name = "ABSOLUTE";
else if (shndx == SHN_COMMON)
name = "COMMON";
else
name = "<noname>";
return name;
}
static struct section *sec_lookup(const char *secname)
{
int i;
for (i = 0; i < ehdr.e_shnum; i++)
if (strcmp(secname, sec_name(i)) == 0)
return &secs[i];
return NULL;
}
static const char *sym_name(const char *sym_strtab, Elf_Sym *sym)
{
const char *name;
if (sym->st_name)
name = sym_strtab + sym->st_name;
else
name = sec_name(sym->st_shndx);
return name;
}
#if BYTE_ORDER == LITTLE_ENDIAN
#define le16_to_cpu(val) (val)
#define le32_to_cpu(val) (val)
#define le64_to_cpu(val) (val)
#define be16_to_cpu(val) bswap_16(val)
#define be32_to_cpu(val) bswap_32(val)
#define be64_to_cpu(val) bswap_64(val)
#define cpu_to_le16(val) (val)
#define cpu_to_le32(val) (val)
#define cpu_to_le64(val) (val)
#define cpu_to_be16(val) bswap_16(val)
#define cpu_to_be32(val) bswap_32(val)
#define cpu_to_be64(val) bswap_64(val)
#endif
#if BYTE_ORDER == BIG_ENDIAN
#define le16_to_cpu(val) bswap_16(val)
#define le32_to_cpu(val) bswap_32(val)
#define le64_to_cpu(val) bswap_64(val)
#define be16_to_cpu(val) (val)
#define be32_to_cpu(val) (val)
#define be64_to_cpu(val) (val)
#define cpu_to_le16(val) bswap_16(val)
#define cpu_to_le32(val) bswap_32(val)
#define cpu_to_le64(val) bswap_64(val)
#define cpu_to_be16(val) (val)
#define cpu_to_be32(val) (val)
#define cpu_to_be64(val) (val)
#endif
static uint16_t elf16_to_cpu(uint16_t val)
{
if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
return le16_to_cpu(val);
else
return be16_to_cpu(val);
}
static uint32_t elf32_to_cpu(uint32_t val)
{
if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
return le32_to_cpu(val);
else
return be32_to_cpu(val);
}
static uint32_t cpu_to_elf32(uint32_t val)
{
if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
return cpu_to_le32(val);
else
return cpu_to_be32(val);
}
#define elf_half_to_cpu(x) elf16_to_cpu(x)
#define elf_word_to_cpu(x) elf32_to_cpu(x)
#if ELF_BITS == 64
static uint64_t elf64_to_cpu(uint64_t val)
{
if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
return le64_to_cpu(val);
else
return be64_to_cpu(val);
}
#define elf_addr_to_cpu(x) elf64_to_cpu(x)
#define elf_off_to_cpu(x) elf64_to_cpu(x)
#define elf_xword_to_cpu(x) elf64_to_cpu(x)
#else
#define elf_addr_to_cpu(x) elf32_to_cpu(x)
#define elf_off_to_cpu(x) elf32_to_cpu(x)
#define elf_xword_to_cpu(x) elf32_to_cpu(x)
#endif
static void read_ehdr(FILE *fp)
{
if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
die("Cannot read ELF header: %s\n", strerror(errno));
if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0)
die("No ELF magic\n");
if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
die("Not a %d bit executable\n", ELF_BITS);
if ((ehdr.e_ident[EI_DATA] != ELFDATA2LSB) &&
(ehdr.e_ident[EI_DATA] != ELFDATA2MSB))
die("Unknown ELF Endianness\n");
if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
die("Unknown ELF version\n");
/* Convert the fields to native endian */
ehdr.e_type = elf_half_to_cpu(ehdr.e_type);
ehdr.e_machine = elf_half_to_cpu(ehdr.e_machine);
ehdr.e_version = elf_word_to_cpu(ehdr.e_version);
ehdr.e_entry = elf_addr_to_cpu(ehdr.e_entry);
ehdr.e_phoff = elf_off_to_cpu(ehdr.e_phoff);
ehdr.e_shoff = elf_off_to_cpu(ehdr.e_shoff);
ehdr.e_flags = elf_word_to_cpu(ehdr.e_flags);
ehdr.e_ehsize = elf_half_to_cpu(ehdr.e_ehsize);
ehdr.e_phentsize = elf_half_to_cpu(ehdr.e_phentsize);
ehdr.e_phnum = elf_half_to_cpu(ehdr.e_phnum);
ehdr.e_shentsize = elf_half_to_cpu(ehdr.e_shentsize);
ehdr.e_shnum = elf_half_to_cpu(ehdr.e_shnum);
ehdr.e_shstrndx = elf_half_to_cpu(ehdr.e_shstrndx);
if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN))
die("Unsupported ELF header type\n");
if (ehdr.e_machine != ELF_MACHINE)
die("Not for %s\n", ELF_MACHINE_NAME);
if (ehdr.e_version != EV_CURRENT)
die("Unknown ELF version\n");
if (ehdr.e_ehsize != sizeof(Elf_Ehdr))
die("Bad Elf header size\n");
if (ehdr.e_phentsize != sizeof(Elf_Phdr))
die("Bad program header entry\n");
if (ehdr.e_shentsize != sizeof(Elf_Shdr))
die("Bad section header entry\n");
if (ehdr.e_shstrndx >= ehdr.e_shnum)
die("String table index out of bounds\n");
}
static void read_shdrs(FILE *fp)
{
int i;
Elf_Shdr shdr;
secs = calloc(ehdr.e_shnum, sizeof(struct section));
if (!secs)
die("Unable to allocate %d section headers\n", ehdr.e_shnum);
if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0)
die("Seek to %d failed: %s\n", ehdr.e_shoff, strerror(errno));
for (i = 0; i < ehdr.e_shnum; i++) {
struct section *sec = &secs[i];
sec->shdr_offset = ftell(fp);
if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
die("Cannot read ELF section headers %d/%d: %s\n",
i, ehdr.e_shnum, strerror(errno));
sec->shdr.sh_name = elf_word_to_cpu(shdr.sh_name);
sec->shdr.sh_type = elf_word_to_cpu(shdr.sh_type);
sec->shdr.sh_flags = elf_xword_to_cpu(shdr.sh_flags);
sec->shdr.sh_addr = elf_addr_to_cpu(shdr.sh_addr);
sec->shdr.sh_offset = elf_off_to_cpu(shdr.sh_offset);
sec->shdr.sh_size = elf_xword_to_cpu(shdr.sh_size);
sec->shdr.sh_link = elf_word_to_cpu(shdr.sh_link);
sec->shdr.sh_info = elf_word_to_cpu(shdr.sh_info);
sec->shdr.sh_addralign = elf_xword_to_cpu(shdr.sh_addralign);
sec->shdr.sh_entsize = elf_xword_to_cpu(shdr.sh_entsize);
if (sec->shdr.sh_link < ehdr.e_shnum)
sec->link = &secs[sec->shdr.sh_link];
}
}
static void read_strtabs(FILE *fp)
{
int i;
for (i = 0; i < ehdr.e_shnum; i++) {
struct section *sec = &secs[i];
if (sec->shdr.sh_type != SHT_STRTAB)
continue;
sec->strtab = malloc(sec->shdr.sh_size);
if (!sec->strtab)
die("malloc of %d bytes for strtab failed\n",
sec->shdr.sh_size);
if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
die("Seek to %d failed: %s\n",
sec->shdr.sh_offset, strerror(errno));
if (fread(sec->strtab, 1, sec->shdr.sh_size, fp) !=
sec->shdr.sh_size)
die("Cannot read symbol table: %s\n", strerror(errno));
}
}
static void read_symtabs(FILE *fp)
{
int i, j;
for (i = 0; i < ehdr.e_shnum; i++) {
struct section *sec = &secs[i];
if (sec->shdr.sh_type != SHT_SYMTAB)
continue;
sec->symtab = malloc(sec->shdr.sh_size);
if (!sec->symtab)
die("malloc of %d bytes for symtab failed\n",
sec->shdr.sh_size);
if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
die("Seek to %d failed: %s\n",
sec->shdr.sh_offset, strerror(errno));
if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) !=
sec->shdr.sh_size)
die("Cannot read symbol table: %s\n", strerror(errno));
for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Sym); j++) {
Elf_Sym *sym = &sec->symtab[j];
sym->st_name = elf_word_to_cpu(sym->st_name);
sym->st_value = elf_addr_to_cpu(sym->st_value);
sym->st_size = elf_xword_to_cpu(sym->st_size);
sym->st_shndx = elf_half_to_cpu(sym->st_shndx);
}
}
}
static void read_relocs(FILE *fp)
{
static unsigned long base = 0;
int i, j;
if (!base) {
struct section *sec = sec_lookup(".text");
if (!sec)
die("Could not find .text section\n");
base = sec->shdr.sh_addr;
}
for (i = 0; i < ehdr.e_shnum; i++) {
struct section *sec = &secs[i];
if (sec->shdr.sh_type != SHT_REL_TYPE)
continue;
sec->reltab = malloc(sec->shdr.sh_size);
if (!sec->reltab)
die("malloc of %d bytes for relocs failed\n",
sec->shdr.sh_size);
if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
die("Seek to %d failed: %s\n",
sec->shdr.sh_offset, strerror(errno));
if (fread(sec->reltab, 1, sec->shdr.sh_size, fp) !=
sec->shdr.sh_size)
die("Cannot read symbol table: %s\n", strerror(errno));
for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
Elf_Rel *rel = &sec->reltab[j];
rel->r_offset = elf_addr_to_cpu(rel->r_offset);
/* Set offset into kernel image */
rel->r_offset -= base;
#if (ELF_BITS == 32)
rel->r_info = elf_xword_to_cpu(rel->r_info);
#else
/* Convert MIPS64 RELA format - only the symbol
* index needs converting to native endianness
*/
rel->r_info = rel->r_info;
ELF_R_SYM(rel->r_info) = elf32_to_cpu(ELF_R_SYM(rel->r_info));
#endif
#if (SHT_REL_TYPE == SHT_RELA)
rel->r_addend = elf_xword_to_cpu(rel->r_addend);
#endif
}
}
}
static void remove_relocs(FILE *fp)
{
int i;
Elf_Shdr shdr;
for (i = 0; i < ehdr.e_shnum; i++) {
struct section *sec = &secs[i];
if (sec->shdr.sh_type != SHT_REL_TYPE)
continue;
if (fseek(fp, sec->shdr_offset, SEEK_SET) < 0)
die("Seek to %d failed: %s\n",
sec->shdr_offset, strerror(errno));
if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
die("Cannot read ELF section headers %d/%d: %s\n",
i, ehdr.e_shnum, strerror(errno));
/* Set relocation section size to 0, effectively removing it.
* This is necessary due to lack of support for relocations
* in objcopy when creating 32bit elf from 64bit elf.
*/
shdr.sh_size = 0;
if (fseek(fp, sec->shdr_offset, SEEK_SET) < 0)
die("Seek to %d failed: %s\n",
sec->shdr_offset, strerror(errno));
if (fwrite(&shdr, sizeof(shdr), 1, fp) != 1)
die("Cannot write ELF section headers %d/%d: %s\n",
i, ehdr.e_shnum, strerror(errno));
}
}
static void add_reloc(struct relocs *r, uint32_t offset, unsigned type)
{
/* Relocation representation in binary table:
* |76543210|76543210|76543210|76543210|
* | Type | offset from _text >> 2 |
*/
offset >>= 2;
if (offset > 0x00FFFFFF)
die("Kernel image exceeds maximum size for relocation!\n");
offset = (offset & 0x00FFFFFF) | ((type & 0xFF) << 24);
if (r->count == r->size) {
unsigned long newsize = r->size + 50000;
void *mem = realloc(r->offset, newsize * sizeof(r->offset[0]));
if (!mem)
die("realloc failed\n");
r->offset = mem;
r->size = newsize;
}
r->offset[r->count++] = offset;
}
static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel,
Elf_Sym *sym, const char *symname))
{
int i;
/* Walk through the relocations */
for (i = 0; i < ehdr.e_shnum; i++) {
char *sym_strtab;
Elf_Sym *sh_symtab;
struct section *sec_applies, *sec_symtab;
int j;
struct section *sec = &secs[i];
if (sec->shdr.sh_type != SHT_REL_TYPE)
continue;
sec_symtab = sec->link;
sec_applies = &secs[sec->shdr.sh_info];
if (!(sec_applies->shdr.sh_flags & SHF_ALLOC))
continue;
sh_symtab = sec_symtab->symtab;
sym_strtab = sec_symtab->link->strtab;
for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
Elf_Rel *rel = &sec->reltab[j];
Elf_Sym *sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
const char *symname = sym_name(sym_strtab, sym);
process(sec, rel, sym, symname);
}
}
}
static int do_reloc(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
const char *symname)
{
unsigned r_type = ELF_R_TYPE(rel->r_info);
unsigned bind = ELF_ST_BIND(sym->st_info);
if ((bind == STB_WEAK) && (sym->st_value == 0)) {
/* Don't relocate weak symbols without a target */
return 0;
}
if (regex_skip_reloc(symname))
return 0;
switch (r_type) {
case R_MIPS_NONE:
case R_MIPS_REL32:
case R_MIPS_PC16:
case R_MIPS_PC21_S2:
case R_MIPS_PC26_S2:
/*
* NONE can be ignored and PC relative relocations don't
* need to be adjusted.
*/
case R_MIPS_HIGHEST:
case R_MIPS_HIGHER:
/* We support relocating within the same 4Gb segment only,
* thus leaving the top 32bits unchanged
*/
case R_MIPS_LO16:
/* We support relocating by 64k jumps only
* thus leaving the bottom 16bits unchanged
*/
break;
case R_MIPS_64:
case R_MIPS_32:
case R_MIPS_26:
case R_MIPS_HI16:
add_reloc(&relocs, rel->r_offset, r_type);
break;
default:
die("Unsupported relocation type: %s (%d)\n",
rel_type(r_type), r_type);
break;
}
return 0;
}
static int write_reloc_as_bin(uint32_t v, FILE *f)
{
unsigned char buf[4];
v = cpu_to_elf32(v);
memcpy(buf, &v, sizeof(uint32_t));
return fwrite(buf, 1, 4, f);
}
static int write_reloc_as_text(uint32_t v, FILE *f)
{
int res;
res = fprintf(f, "\t.long 0x%08"PRIx32"\n", v);
if (res < 0)
return res;
else
return sizeof(uint32_t);
}
static void emit_relocs(int as_text, int as_bin, FILE *outf)
{
int i;
int (*write_reloc)(uint32_t, FILE *) = write_reloc_as_bin;
int size = 0;
int size_reserved;
struct section *sec_reloc;
sec_reloc = sec_lookup(".data.reloc");
if (!sec_reloc)
die("Could not find relocation section\n");
size_reserved = sec_reloc->shdr.sh_size;
/* Collect up the relocations */
walk_relocs(do_reloc);
/* Print the relocations */
if (as_text) {
/* Print the relocations in a form suitable that
* gas will like.
*/
printf(".section \".data.reloc\",\"a\"\n");
printf(".balign 4\n");
/* Output text to stdout */
write_reloc = write_reloc_as_text;
outf = stdout;
} else if (as_bin) {
/* Output raw binary to stdout */
outf = stdout;
} else {
/* Seek to offset of the relocation section.
* Each relocation is then written into the
* vmlinux kernel image.
*/
if (fseek(outf, sec_reloc->shdr.sh_offset, SEEK_SET) < 0) {
die("Seek to %d failed: %s\n",
sec_reloc->shdr.sh_offset, strerror(errno));
}
}
for (i = 0; i < relocs.count; i++)
size += write_reloc(relocs.offset[i], outf);
/* Print a stop, but only if we've actually written some relocs */
if (size)
size += write_reloc(0, outf);
if (size > size_reserved)
/* Die, but suggest a value for CONFIG_RELOCATION_TABLE_SIZE
* which will fix this problem and allow a bit of headroom
* if more kernel features are enabled
*/
die("Relocations overflow available space!\n" \
"Please adjust CONFIG_RELOCATION_TABLE_SIZE " \
"to at least 0x%08x\n", (size + 0x1000) & ~0xFFF);
}
/*
* As an aid to debugging problems with different linkers
* print summary information about the relocs.
* Since different linkers tend to emit the sections in
* different orders we use the section names in the output.
*/
static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
const char *symname)
{
printf("%16s 0x%08x %16s %40s %16s\n",
sec_name(sec->shdr.sh_info),
(unsigned int)rel->r_offset,
rel_type(ELF_R_TYPE(rel->r_info)),
symname,
sec_name(sym->st_shndx));
return 0;
}
static void print_reloc_info(void)
{
printf("%16s %10s %16s %40s %16s\n",
"reloc section",
"offset",
"reloc type",
"symbol",
"symbol section");
walk_relocs(do_reloc_info);
}
#if ELF_BITS == 64
# define process process_64
#else
# define process process_32
#endif
void process(FILE *fp, int as_text, int as_bin,
int show_reloc_info, int keep_relocs)
{
regex_init();
read_ehdr(fp);
read_shdrs(fp);
read_strtabs(fp);
read_symtabs(fp);
read_relocs(fp);
if (show_reloc_info) {
print_reloc_info();
return;
}
emit_relocs(as_text, as_bin, fp);
if (!keep_relocs)
remove_relocs(fp);
}

View File

@ -0,0 +1,45 @@
#ifndef RELOCS_H
#define RELOCS_H
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <elf.h>
#include <byteswap.h>
#define USE_BSD
#include <endian.h>
#include <regex.h>
void die(char *fmt, ...);
/*
* Introduced for MIPSr6
*/
#ifndef R_MIPS_PC21_S2
#define R_MIPS_PC21_S2 60
#endif
#ifndef R_MIPS_PC26_S2
#define R_MIPS_PC26_S2 61
#endif
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
enum symtype {
S_ABS,
S_REL,
S_SEG,
S_LIN,
S_NSYMTYPES
};
void process_32(FILE *fp, int as_text, int as_bin,
int show_reloc_info, int keep_relocs);
void process_64(FILE *fp, int as_text, int as_bin,
int show_reloc_info, int keep_relocs);
#endif /* RELOCS_H */

View File

@ -0,0 +1,17 @@
#include "relocs.h"
#define ELF_BITS 32
#define ELF_MACHINE EM_MIPS
#define ELF_MACHINE_NAME "MIPS"
#define SHT_REL_TYPE SHT_REL
#define Elf_Rel ElfW(Rel)
#define ELF_CLASS ELFCLASS32
#define ELF_R_SYM(val) ELF32_R_SYM(val)
#define ELF_R_TYPE(val) ELF32_R_TYPE(val)
#define ELF_ST_TYPE(o) ELF32_ST_TYPE(o)
#define ELF_ST_BIND(o) ELF32_ST_BIND(o)
#define ELF_ST_VISIBILITY(o) ELF32_ST_VISIBILITY(o)
#include "relocs.c"

View File

@ -0,0 +1,27 @@
#include "relocs.h"
#define ELF_BITS 64
#define ELF_MACHINE EM_MIPS
#define ELF_MACHINE_NAME "MIPS64"
#define SHT_REL_TYPE SHT_RELA
#define Elf_Rel Elf64_Rela
typedef uint8_t Elf64_Byte;
typedef struct {
Elf64_Word r_sym; /* Symbol index. */
Elf64_Byte r_ssym; /* Special symbol. */
Elf64_Byte r_type3; /* Third relocation. */
Elf64_Byte r_type2; /* Second relocation. */
Elf64_Byte r_type; /* First relocation. */
} Elf64_Mips_Rela;
#define ELF_CLASS ELFCLASS64
#define ELF_R_SYM(val) (((Elf64_Mips_Rela *)(&val))->r_sym)
#define ELF_R_TYPE(val) (((Elf64_Mips_Rela *)(&val))->r_type)
#define ELF_ST_TYPE(o) ELF64_ST_TYPE(o)
#define ELF_ST_BIND(o) ELF64_ST_BIND(o)
#define ELF_ST_VISIBILITY(o) ELF64_ST_VISIBILITY(o)
#include "relocs.c"

View File

@ -0,0 +1,84 @@
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <endian.h>
#include <elf.h>
#include "relocs.h"
void die(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
exit(1);
}
static void usage(void)
{
die("relocs [--reloc-info|--text|--bin|--keep] vmlinux\n");
}
int main(int argc, char **argv)
{
int show_reloc_info, as_text, as_bin, keep_relocs;
const char *fname;
FILE *fp;
int i;
unsigned char e_ident[EI_NIDENT];
show_reloc_info = 0;
as_text = 0;
as_bin = 0;
keep_relocs = 0;
fname = NULL;
for (i = 1; i < argc; i++) {
char *arg = argv[i];
if (*arg == '-') {
if (strcmp(arg, "--reloc-info") == 0) {
show_reloc_info = 1;
continue;
}
if (strcmp(arg, "--text") == 0) {
as_text = 1;
continue;
}
if (strcmp(arg, "--bin") == 0) {
as_bin = 1;
continue;
}
if (strcmp(arg, "--keep") == 0) {
keep_relocs = 1;
continue;
}
} else if (!fname) {
fname = arg;
continue;
}
usage();
}
if (!fname)
usage();
fp = fopen(fname, "r+");
if (!fp)
die("Cannot open %s: %s\n", fname, strerror(errno));
if (fread(&e_ident, 1, EI_NIDENT, fp) != EI_NIDENT)
die("Cannot read %s: %s", fname, strerror(errno));
rewind(fp);
if (e_ident[EI_CLASS] == ELFCLASS64)
process_64(fp, as_text, as_bin, show_reloc_info, keep_relocs);
else
process_32(fp, as_text, as_bin, show_reloc_info, keep_relocs);
fclose(fp);
return 0;
}

View File

@ -19,6 +19,7 @@
#include <asm/octeon/cvmx-ipd-defs.h>
#include <asm/octeon/cvmx-mio-defs.h>
#include <asm/octeon/cvmx-rst-defs.h>
#include <asm/octeon/cvmx-fpa-defs.h>
static u64 f;
static u64 rdiv;
@ -65,9 +66,13 @@ void __init octeon_setup_delays(void)
*/
void octeon_init_cvmcount(void)
{
u64 clk_reg;
unsigned long flags;
unsigned loops = 2;
clk_reg = octeon_has_feature(OCTEON_FEATURE_FPA3) ?
CVMX_FPA_CLK_COUNT : CVMX_IPD_CLK_COUNT;
/* Clobber loops so GCC will not unroll the following while loop. */
asm("" : "+r" (loops));
@ -77,18 +82,18 @@ void octeon_init_cvmcount(void)
* which should give more deterministic timing.
*/
while (loops--) {
u64 ipd_clk_count = cvmx_read_csr(CVMX_IPD_CLK_COUNT);
u64 clk_count = cvmx_read_csr(clk_reg);
if (rdiv != 0) {
ipd_clk_count *= rdiv;
clk_count *= rdiv;
if (f != 0) {
asm("dmultu\t%[cnt],%[f]\n\t"
"mfhi\t%[cnt]"
: [cnt] "+r" (ipd_clk_count)
: [cnt] "+r" (clk_count)
: [f] "r" (f)
: "hi", "lo");
}
}
write_c0_cvmcount(ipd_clk_count);
write_c0_cvmcount(clk_count);
}
local_irq_restore(flags);
}

View File

@ -87,6 +87,8 @@ int cvmx_helper_get_number_of_interfaces(void)
return 9;
if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
return 4;
if (OCTEON_IS_MODEL(OCTEON_CN7XXX))
return 5;
else
return 3;
}
@ -259,6 +261,41 @@ static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface)
}
}
/**
* @INTERNAL
* Return interface mode for CN7XXX.
*/
static cvmx_helper_interface_mode_t __cvmx_get_mode_cn7xxx(int interface)
{
union cvmx_gmxx_inf_mode mode;
mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
switch (interface) {
case 0:
case 1:
switch (mode.cn68xx.mode) {
case 0:
return CVMX_HELPER_INTERFACE_MODE_DISABLED;
case 1:
case 2:
return CVMX_HELPER_INTERFACE_MODE_SGMII;
case 3:
return CVMX_HELPER_INTERFACE_MODE_XAUI;
default:
return CVMX_HELPER_INTERFACE_MODE_SGMII;
}
case 2:
return CVMX_HELPER_INTERFACE_MODE_NPI;
case 3:
return CVMX_HELPER_INTERFACE_MODE_LOOP;
case 4:
return CVMX_HELPER_INTERFACE_MODE_RGMII;
default:
return CVMX_HELPER_INTERFACE_MODE_DISABLED;
}
}
/**
* Get the operating mode of an interface. Depending on the Octeon
* chip and configuration, this function returns an enumeration
@ -277,6 +314,12 @@ cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
interface >= cvmx_helper_get_number_of_interfaces())
return CVMX_HELPER_INTERFACE_MODE_DISABLED;
/*
* OCTEON III models
*/
if (OCTEON_IS_MODEL(OCTEON_CN7XXX))
return __cvmx_get_mode_cn7xxx(interface);
/*
* Octeon II models
*/

View File

@ -32,86 +32,22 @@
#include <linux/module.h>
#include <asm/octeon/cvmx.h>
#include <asm/octeon/cvmx-spinlock.h>
#include <asm/octeon/cvmx-sysinfo.h>
/**
/*
* This structure defines the private state maintained by sysinfo module.
*
*/
static struct {
struct cvmx_sysinfo sysinfo; /* system information */
cvmx_spinlock_t lock; /* mutex spinlock */
} state = {
.lock = CVMX_SPINLOCK_UNLOCKED_INITIALIZER
};
static struct cvmx_sysinfo sysinfo; /* system information */
/*
* Global variables that define the min/max of the memory region set
* up for 32 bit userspace access.
*/
uint64_t linux_mem32_min;
uint64_t linux_mem32_max;
uint64_t linux_mem32_wired;
uint64_t linux_mem32_offset;
/**
* This function returns the application information as obtained
* Returns the application information as obtained
* by the bootloader. This provides the core mask of the cores
* running the same application image, as well as the physical
* memory regions available to the core.
*
* Returns Pointer to the boot information structure
*
*/
struct cvmx_sysinfo *cvmx_sysinfo_get(void)
{
return &(state.sysinfo);
return &sysinfo;
}
EXPORT_SYMBOL(cvmx_sysinfo_get);
/**
* This function is used in non-simple executive environments (such as
* Linux kernel, u-boot, etc.) to configure the minimal fields that
* are required to use simple executive files directly.
*
* Locking (if required) must be handled outside of this
* function
*
* @phy_mem_desc_ptr:
* Pointer to global physical memory descriptor
* (bootmem descriptor) @board_type: Octeon board
* type enumeration
*
* @board_rev_major:
* Board major revision
* @board_rev_minor:
* Board minor revision
* @cpu_clock_hz:
* CPU clock freqency in hertz
*
* Returns 0: Failure
* 1: success
*/
int cvmx_sysinfo_minimal_initialize(void *phy_mem_desc_ptr,
uint16_t board_type,
uint8_t board_rev_major,
uint8_t board_rev_minor,
uint32_t cpu_clock_hz)
{
/* The sysinfo structure was already initialized */
if (state.sysinfo.board_type)
return 0;
memset(&(state.sysinfo), 0x0, sizeof(state.sysinfo));
state.sysinfo.phy_mem_desc_ptr = phy_mem_desc_ptr;
state.sysinfo.board_type = board_type;
state.sysinfo.board_rev_major = board_rev_major;
state.sysinfo.board_rev_minor = board_rev_minor;
state.sysinfo.cpu_clock_hz = cpu_clock_hz;
return 1;
}

View File

@ -71,11 +71,11 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
uint32_t fuse_data = 0;
fus3.u64 = 0;
if (!OCTEON_IS_MODEL(OCTEON_CN6XXX))
if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN5XXX))
fus3.u64 = cvmx_read_csr(CVMX_L2D_FUS3);
fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);
num_cores = cvmx_pop(cvmx_read_csr(CVMX_CIU_FUSE));
num_cores = cvmx_octeon_num_cores();
/* Make sure the non existent devices look disabled */
switch ((chip_id >> 8) & 0xff) {
@ -121,6 +121,15 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
* later.
*/
switch (num_cores) {
case 48:
core_model = "90";
break;
case 44:
core_model = "88";
break;
case 40:
core_model = "85";
break;
case 32:
core_model = "80";
break;
@ -297,7 +306,7 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
if (fus_dat3.s.nozip)
suffix = "SCP";
if (fus_dat3.s.bar2_en)
if (fus_dat3.cn56xx.bar2_en)
suffix = "NSPB2";
}
if (fus3.cn56xx.crip_1024k)
@ -369,6 +378,73 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
else
suffix = "AAP";
break;
case 0x94: /* CNF71XX */
family = "F71";
if (fus_dat3.cnf71xx.nozip)
suffix = "SCP";
else
suffix = "AAP";
break;
case 0x95: /* CN78XX */
if (num_cores == 6) /* Other core counts match generic */
core_model = "35";
if (OCTEON_IS_MODEL(OCTEON_CN76XX))
family = "76";
else
family = "78";
if (fus_dat3.cn78xx.l2c_crip == 2)
family = "77";
if (fus_dat3.cn78xx.nozip
&& fus_dat3.cn78xx.nodfa_dte
&& fus_dat3.cn78xx.nohna_dte) {
if (fus_dat3.cn78xx.nozip &&
!fus_dat2.cn78xx.raid_en &&
fus_dat3.cn78xx.nohna_dte) {
suffix = "CP";
} else {
suffix = "SCP";
}
} else if (fus_dat2.cn78xx.raid_en == 0)
suffix = "HCP";
else
suffix = "AAP";
break;
case 0x96: /* CN70XX */
family = "70";
if (cvmx_read_csr(CVMX_MIO_FUS_PDF) & (0x1ULL << 32))
family = "71";
if (fus_dat2.cn70xx.nocrypto)
suffix = "CP";
else if (fus_dat3.cn70xx.nodfa_dte)
suffix = "SCP";
else
suffix = "AAP";
break;
case 0x97: /* CN73XX */
if (num_cores == 6) /* Other core counts match generic */
core_model = "35";
family = "73";
if (fus_dat3.cn73xx.l2c_crip == 2)
family = "72";
if (fus_dat3.cn73xx.nozip
&& fus_dat3.cn73xx.nodfa_dte
&& fus_dat3.cn73xx.nohna_dte) {
if (!fus_dat2.cn73xx.raid_en)
suffix = "CP";
else
suffix = "SCP";
} else
suffix = "AAP";
break;
case 0x98: /* CN75XX */
family = "F75";
if (fus_dat3.cn78xx.nozip
&& fus_dat3.cn78xx.nodfa_dte
&& fus_dat3.cn78xx.nohna_dte)
suffix = "SCP";
else
suffix = "AAP";
break;
default:
family = "XX";
core_model = "XX";

View File

@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2004-2014 Cavium, Inc.
* Copyright (C) 2004-2016 Cavium, Inc.
*/
#include <linux/of_address.h>
@ -19,16 +19,53 @@
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-ciu2-defs.h>
#include <asm/octeon/cvmx-ciu3-defs.h>
static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu0_en_mirror);
static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu1_en_mirror);
static DEFINE_PER_CPU(raw_spinlock_t, octeon_irq_ciu_spinlock);
static DEFINE_PER_CPU(unsigned int, octeon_irq_ciu3_idt_ip2);
static DEFINE_PER_CPU(unsigned int, octeon_irq_ciu3_idt_ip3);
static DEFINE_PER_CPU(struct octeon_ciu3_info *, octeon_ciu3_info);
#define CIU3_MBOX_PER_CORE 10
/*
* The 8 most significant bits of the intsn identify the interrupt major block.
* Each major block might use its own interrupt domain. Thus 256 domains are
* needed.
*/
#define MAX_CIU3_DOMAINS 256
typedef irq_hw_number_t (*octeon_ciu3_intsn2hw_t)(struct irq_domain *, unsigned int);
/* Information for each ciu3 in the system */
struct octeon_ciu3_info {
u64 ciu3_addr;
int node;
struct irq_domain *domain[MAX_CIU3_DOMAINS];
octeon_ciu3_intsn2hw_t intsn2hw[MAX_CIU3_DOMAINS];
};
/* Each ciu3 in the system uses its own data (one ciu3 per node) */
static struct octeon_ciu3_info *octeon_ciu3_info_per_node[4];
struct octeon_irq_ciu_domain_data {
int num_sum; /* number of sum registers (2 or 3). */
};
static __read_mostly u8 octeon_irq_ciu_to_irq[8][64];
/* Register offsets from ciu3_addr */
#define CIU3_CONST 0x220
#define CIU3_IDT_CTL(_idt) ((_idt) * 8 + 0x110000)
#define CIU3_IDT_PP(_idt, _idx) ((_idt) * 32 + (_idx) * 8 + 0x120000)
#define CIU3_IDT_IO(_idt) ((_idt) * 8 + 0x130000)
#define CIU3_DEST_PP_INT(_pp_ip) ((_pp_ip) * 8 + 0x200000)
#define CIU3_DEST_IO_INT(_io) ((_io) * 8 + 0x210000)
#define CIU3_ISC_CTL(_intsn) ((_intsn) * 8 + 0x80000000)
#define CIU3_ISC_W1C(_intsn) ((_intsn) * 8 + 0x90000000)
#define CIU3_ISC_W1S(_intsn) ((_intsn) * 8 + 0xa0000000)
static __read_mostly int octeon_irq_ciu_to_irq[8][64];
struct octeon_ciu_chip_data {
union {
@ -39,10 +76,11 @@ struct octeon_ciu_chip_data {
struct { /* only used for ciu/ciu2 */
u8 line;
u8 bit;
u8 gpio_line;
};
};
int gpio_line;
int current_cpu; /* Next CPU expected to take this irq */
int ciu_node; /* NUMA node number of the CIU */
};
struct octeon_core_chip_data {
@ -626,6 +664,18 @@ static void octeon_irq_ciu_enable_all_v2(struct irq_data *data)
}
}
static int octeon_irq_ciu_set_type(struct irq_data *data, unsigned int t)
{
irqd_set_trigger_type(data, t);
if (t & IRQ_TYPE_EDGE_BOTH)
irq_set_handler_locked(data, handle_edge_irq);
else
irq_set_handler_locked(data, handle_level_irq);
return IRQ_SET_MASK_OK;
}
static void octeon_irq_gpio_setup(struct irq_data *data)
{
union cvmx_gpio_bit_cfgx cfg;
@ -663,7 +713,7 @@ static int octeon_irq_ciu_gpio_set_type(struct irq_data *data, unsigned int t)
irqd_set_trigger_type(data, t);
octeon_irq_gpio_setup(data);
if (irqd_get_trigger_type(data) & IRQ_TYPE_EDGE_BOTH)
if (t & IRQ_TYPE_EDGE_BOTH)
irq_set_handler_locked(data, handle_edge_irq);
else
irq_set_handler_locked(data, handle_level_irq);
@ -863,6 +913,16 @@ static int octeon_irq_ciu_set_affinity_sum2(struct irq_data *data,
}
#endif
static unsigned int edge_startup(struct irq_data *data)
{
/* ack any pending edge-irq at startup, so there is
* an _edge_ to fire on when the event reappears.
*/
data->chip->irq_ack(data);
data->chip->irq_enable(data);
return 0;
}
/*
* Newer octeon chips have support for lockless CIU operation.
*/
@ -1158,16 +1218,6 @@ static struct irq_chip *octeon_irq_ciu_chip;
static struct irq_chip *octeon_irq_ciu_chip_edge;
static struct irq_chip *octeon_irq_gpio_chip;
static bool octeon_irq_virq_in_range(unsigned int virq)
{
/* We cannot let it overflow the mapping array. */
if (virq < (1ul << 8 * sizeof(octeon_irq_ciu_to_irq[0][0])))
return true;
WARN_ONCE(true, "virq out of range %u.\n", virq);
return false;
}
static int octeon_irq_ciu_map(struct irq_domain *d,
unsigned int virq, irq_hw_number_t hw)
{
@ -1176,13 +1226,6 @@ static int octeon_irq_ciu_map(struct irq_domain *d,
unsigned int bit = hw & 63;
struct octeon_irq_ciu_domain_data *dd = d->host_data;
if (!octeon_irq_virq_in_range(virq))
return -EINVAL;
/* Don't map irq if it is reserved for GPIO. */
if (line == 0 && bit >= 16 && bit <32)
return 0;
if (line >= dd->num_sum || octeon_irq_ciu_to_irq[line][bit] != 0)
return -EINVAL;
@ -1215,9 +1258,6 @@ static int octeon_irq_gpio_map(struct irq_domain *d,
unsigned int line, bit;
int r;
if (!octeon_irq_virq_in_range(virq))
return -EINVAL;
line = (hw + gpiod->base_hwirq) >> 6;
bit = (hw + gpiod->base_hwirq) & 63;
if (line > ARRAY_SIZE(octeon_irq_ciu_to_irq) ||
@ -1899,9 +1939,6 @@ static int octeon_irq_ciu2_map(struct irq_domain *d,
unsigned int line = hw >> 6;
unsigned int bit = hw & 63;
if (!octeon_irq_virq_in_range(virq))
return -EINVAL;
/*
* Don't map irq if it is reserved for GPIO.
* (Line 7 are the GPIO lines.)
@ -2294,10 +2331,598 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
return 0;
}
int octeon_irq_ciu3_xlat(struct irq_domain *d,
struct device_node *node,
const u32 *intspec,
unsigned int intsize,
unsigned long *out_hwirq,
unsigned int *out_type)
{
struct octeon_ciu3_info *ciu3_info = d->host_data;
unsigned int hwirq, type, intsn_major;
union cvmx_ciu3_iscx_ctl isc;
if (intsize < 2)
return -EINVAL;
hwirq = intspec[0];
type = intspec[1];
if (hwirq >= (1 << 20))
return -EINVAL;
intsn_major = hwirq >> 12;
switch (intsn_major) {
case 0x04: /* Software handled separately. */
return -EINVAL;
default:
break;
}
isc.u64 = cvmx_read_csr(ciu3_info->ciu3_addr + CIU3_ISC_CTL(hwirq));
if (!isc.s.imp)
return -EINVAL;
switch (type) {
case 4: /* official value for level triggering. */
*out_type = IRQ_TYPE_LEVEL_HIGH;
break;
case 0: /* unofficial value, but we might as well let it work. */
case 1: /* official value for edge triggering. */
*out_type = IRQ_TYPE_EDGE_RISING;
break;
default: /* Nothing else is acceptable. */
return -EINVAL;
}
*out_hwirq = hwirq;
return 0;
}
void octeon_irq_ciu3_enable(struct irq_data *data)
{
int cpu;
union cvmx_ciu3_iscx_ctl isc_ctl;
union cvmx_ciu3_iscx_w1c isc_w1c;
u64 isc_ctl_addr;
struct octeon_ciu_chip_data *cd;
cpu = next_cpu_for_irq(data);
cd = irq_data_get_irq_chip_data(data);
isc_w1c.u64 = 0;
isc_w1c.s.en = 1;
cvmx_write_csr(cd->ciu3_addr + CIU3_ISC_W1C(cd->intsn), isc_w1c.u64);
isc_ctl_addr = cd->ciu3_addr + CIU3_ISC_CTL(cd->intsn);
isc_ctl.u64 = 0;
isc_ctl.s.en = 1;
isc_ctl.s.idt = per_cpu(octeon_irq_ciu3_idt_ip2, cpu);
cvmx_write_csr(isc_ctl_addr, isc_ctl.u64);
cvmx_read_csr(isc_ctl_addr);
}
void octeon_irq_ciu3_disable(struct irq_data *data)
{
u64 isc_ctl_addr;
union cvmx_ciu3_iscx_w1c isc_w1c;
struct octeon_ciu_chip_data *cd;
cd = irq_data_get_irq_chip_data(data);
isc_w1c.u64 = 0;
isc_w1c.s.en = 1;
isc_ctl_addr = cd->ciu3_addr + CIU3_ISC_CTL(cd->intsn);
cvmx_write_csr(cd->ciu3_addr + CIU3_ISC_W1C(cd->intsn), isc_w1c.u64);
cvmx_write_csr(isc_ctl_addr, 0);
cvmx_read_csr(isc_ctl_addr);
}
void octeon_irq_ciu3_ack(struct irq_data *data)
{
u64 isc_w1c_addr;
union cvmx_ciu3_iscx_w1c isc_w1c;
struct octeon_ciu_chip_data *cd;
u32 trigger_type = irqd_get_trigger_type(data);
/*
* We use a single irq_chip, so we have to do nothing to ack a
* level interrupt.
*/
if (!(trigger_type & IRQ_TYPE_EDGE_BOTH))
return;
cd = irq_data_get_irq_chip_data(data);
isc_w1c.u64 = 0;
isc_w1c.s.raw = 1;
isc_w1c_addr = cd->ciu3_addr + CIU3_ISC_W1C(cd->intsn);
cvmx_write_csr(isc_w1c_addr, isc_w1c.u64);
cvmx_read_csr(isc_w1c_addr);
}
void octeon_irq_ciu3_mask(struct irq_data *data)
{
union cvmx_ciu3_iscx_w1c isc_w1c;
u64 isc_w1c_addr;
struct octeon_ciu_chip_data *cd;
cd = irq_data_get_irq_chip_data(data);
isc_w1c.u64 = 0;
isc_w1c.s.en = 1;
isc_w1c_addr = cd->ciu3_addr + CIU3_ISC_W1C(cd->intsn);
cvmx_write_csr(isc_w1c_addr, isc_w1c.u64);
cvmx_read_csr(isc_w1c_addr);
}
void octeon_irq_ciu3_mask_ack(struct irq_data *data)
{
union cvmx_ciu3_iscx_w1c isc_w1c;
u64 isc_w1c_addr;
struct octeon_ciu_chip_data *cd;
u32 trigger_type = irqd_get_trigger_type(data);
cd = irq_data_get_irq_chip_data(data);
isc_w1c.u64 = 0;
isc_w1c.s.en = 1;
/*
* We use a single irq_chip, so only ack an edge (!level)
* interrupt.
*/
if (trigger_type & IRQ_TYPE_EDGE_BOTH)
isc_w1c.s.raw = 1;
isc_w1c_addr = cd->ciu3_addr + CIU3_ISC_W1C(cd->intsn);
cvmx_write_csr(isc_w1c_addr, isc_w1c.u64);
cvmx_read_csr(isc_w1c_addr);
}
#ifdef CONFIG_SMP
int octeon_irq_ciu3_set_affinity(struct irq_data *data,
const struct cpumask *dest, bool force)
{
union cvmx_ciu3_iscx_ctl isc_ctl;
union cvmx_ciu3_iscx_w1c isc_w1c;
u64 isc_ctl_addr;
int cpu;
bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data);
struct octeon_ciu_chip_data *cd = irq_data_get_irq_chip_data(data);
if (!cpumask_subset(dest, cpumask_of_node(cd->ciu_node)))
return -EINVAL;
if (!enable_one)
return IRQ_SET_MASK_OK;
cd = irq_data_get_irq_chip_data(data);
cpu = cpumask_first(dest);
if (cpu >= nr_cpu_ids)
cpu = smp_processor_id();
cd->current_cpu = cpu;
isc_w1c.u64 = 0;
isc_w1c.s.en = 1;
cvmx_write_csr(cd->ciu3_addr + CIU3_ISC_W1C(cd->intsn), isc_w1c.u64);
isc_ctl_addr = cd->ciu3_addr + CIU3_ISC_CTL(cd->intsn);
isc_ctl.u64 = 0;
isc_ctl.s.en = 1;
isc_ctl.s.idt = per_cpu(octeon_irq_ciu3_idt_ip2, cpu);
cvmx_write_csr(isc_ctl_addr, isc_ctl.u64);
cvmx_read_csr(isc_ctl_addr);
return IRQ_SET_MASK_OK;
}
#endif
static struct irq_chip octeon_irq_chip_ciu3 = {
.name = "CIU3",
.irq_startup = edge_startup,
.irq_enable = octeon_irq_ciu3_enable,
.irq_disable = octeon_irq_ciu3_disable,
.irq_ack = octeon_irq_ciu3_ack,
.irq_mask = octeon_irq_ciu3_mask,
.irq_mask_ack = octeon_irq_ciu3_mask_ack,
.irq_unmask = octeon_irq_ciu3_enable,
.irq_set_type = octeon_irq_ciu_set_type,
#ifdef CONFIG_SMP
.irq_set_affinity = octeon_irq_ciu3_set_affinity,
.irq_cpu_offline = octeon_irq_cpu_offline_ciu,
#endif
};
int octeon_irq_ciu3_mapx(struct irq_domain *d, unsigned int virq,
irq_hw_number_t hw, struct irq_chip *chip)
{
struct octeon_ciu3_info *ciu3_info = d->host_data;
struct octeon_ciu_chip_data *cd = kzalloc_node(sizeof(*cd), GFP_KERNEL,
ciu3_info->node);
if (!cd)
return -ENOMEM;
cd->intsn = hw;
cd->current_cpu = -1;
cd->ciu3_addr = ciu3_info->ciu3_addr;
cd->ciu_node = ciu3_info->node;
irq_set_chip_and_handler(virq, chip, handle_edge_irq);
irq_set_chip_data(virq, cd);
return 0;
}
static int octeon_irq_ciu3_map(struct irq_domain *d,
unsigned int virq, irq_hw_number_t hw)
{
return octeon_irq_ciu3_mapx(d, virq, hw, &octeon_irq_chip_ciu3);
}
static struct irq_domain_ops octeon_dflt_domain_ciu3_ops = {
.map = octeon_irq_ciu3_map,
.unmap = octeon_irq_free_cd,
.xlate = octeon_irq_ciu3_xlat,
};
static void octeon_irq_ciu3_ip2(void)
{
union cvmx_ciu3_destx_pp_int dest_pp_int;
struct octeon_ciu3_info *ciu3_info;
u64 ciu3_addr;
ciu3_info = __this_cpu_read(octeon_ciu3_info);
ciu3_addr = ciu3_info->ciu3_addr;
dest_pp_int.u64 = cvmx_read_csr(ciu3_addr + CIU3_DEST_PP_INT(3 * cvmx_get_local_core_num()));
if (likely(dest_pp_int.s.intr)) {
irq_hw_number_t intsn = dest_pp_int.s.intsn;
irq_hw_number_t hw;
struct irq_domain *domain;
/* Get the domain to use from the major block */
int block = intsn >> 12;
int ret;
domain = ciu3_info->domain[block];
if (ciu3_info->intsn2hw[block])
hw = ciu3_info->intsn2hw[block](domain, intsn);
else
hw = intsn;
ret = handle_domain_irq(domain, hw, NULL);
if (ret < 0) {
union cvmx_ciu3_iscx_w1c isc_w1c;
u64 isc_w1c_addr = ciu3_addr + CIU3_ISC_W1C(intsn);
isc_w1c.u64 = 0;
isc_w1c.s.en = 1;
cvmx_write_csr(isc_w1c_addr, isc_w1c.u64);
cvmx_read_csr(isc_w1c_addr);
spurious_interrupt();
}
} else {
spurious_interrupt();
}
}
/*
* 10 mbox per core starting from zero.
* Base mbox is core * 10
*/
static unsigned int octeon_irq_ciu3_base_mbox_intsn(int core)
{
/* SW (mbox) are 0x04 in bits 12..19 */
return 0x04000 + CIU3_MBOX_PER_CORE * core;
}
static unsigned int octeon_irq_ciu3_mbox_intsn_for_core(int core, unsigned int mbox)
{
return octeon_irq_ciu3_base_mbox_intsn(core) + mbox;
}
static unsigned int octeon_irq_ciu3_mbox_intsn_for_cpu(int cpu, unsigned int mbox)
{
int local_core = octeon_coreid_for_cpu(cpu) & 0x3f;
return octeon_irq_ciu3_mbox_intsn_for_core(local_core, mbox);
}
static void octeon_irq_ciu3_mbox(void)
{
union cvmx_ciu3_destx_pp_int dest_pp_int;
struct octeon_ciu3_info *ciu3_info;
u64 ciu3_addr;
int core = cvmx_get_local_core_num();
ciu3_info = __this_cpu_read(octeon_ciu3_info);
ciu3_addr = ciu3_info->ciu3_addr;
dest_pp_int.u64 = cvmx_read_csr(ciu3_addr + CIU3_DEST_PP_INT(1 + 3 * core));
if (likely(dest_pp_int.s.intr)) {
irq_hw_number_t intsn = dest_pp_int.s.intsn;
int mbox = intsn - octeon_irq_ciu3_base_mbox_intsn(core);
if (likely(mbox >= 0 && mbox < CIU3_MBOX_PER_CORE)) {
do_IRQ(mbox + OCTEON_IRQ_MBOX0);
} else {
union cvmx_ciu3_iscx_w1c isc_w1c;
u64 isc_w1c_addr = ciu3_addr + CIU3_ISC_W1C(intsn);
isc_w1c.u64 = 0;
isc_w1c.s.en = 1;
cvmx_write_csr(isc_w1c_addr, isc_w1c.u64);
cvmx_read_csr(isc_w1c_addr);
spurious_interrupt();
}
} else {
spurious_interrupt();
}
}
void octeon_ciu3_mbox_send(int cpu, unsigned int mbox)
{
struct octeon_ciu3_info *ciu3_info;
unsigned int intsn;
union cvmx_ciu3_iscx_w1s isc_w1s;
u64 isc_w1s_addr;
if (WARN_ON_ONCE(mbox >= CIU3_MBOX_PER_CORE))
return;
intsn = octeon_irq_ciu3_mbox_intsn_for_cpu(cpu, mbox);
ciu3_info = per_cpu(octeon_ciu3_info, cpu);
isc_w1s_addr = ciu3_info->ciu3_addr + CIU3_ISC_W1S(intsn);
isc_w1s.u64 = 0;
isc_w1s.s.raw = 1;
cvmx_write_csr(isc_w1s_addr, isc_w1s.u64);
cvmx_read_csr(isc_w1s_addr);
}
static void octeon_irq_ciu3_mbox_set_enable(struct irq_data *data, int cpu, bool en)
{
struct octeon_ciu3_info *ciu3_info;
unsigned int intsn;
u64 isc_ctl_addr, isc_w1c_addr;
union cvmx_ciu3_iscx_ctl isc_ctl;
unsigned int mbox = data->irq - OCTEON_IRQ_MBOX0;
intsn = octeon_irq_ciu3_mbox_intsn_for_cpu(cpu, mbox);
ciu3_info = per_cpu(octeon_ciu3_info, cpu);
isc_w1c_addr = ciu3_info->ciu3_addr + CIU3_ISC_W1C(intsn);
isc_ctl_addr = ciu3_info->ciu3_addr + CIU3_ISC_CTL(intsn);
isc_ctl.u64 = 0;
isc_ctl.s.en = 1;
cvmx_write_csr(isc_w1c_addr, isc_ctl.u64);
cvmx_write_csr(isc_ctl_addr, 0);
if (en) {
unsigned int idt = per_cpu(octeon_irq_ciu3_idt_ip3, cpu);
isc_ctl.u64 = 0;
isc_ctl.s.en = 1;
isc_ctl.s.idt = idt;
cvmx_write_csr(isc_ctl_addr, isc_ctl.u64);
}
cvmx_read_csr(isc_ctl_addr);
}
static void octeon_irq_ciu3_mbox_enable(struct irq_data *data)
{
int cpu;
unsigned int mbox = data->irq - OCTEON_IRQ_MBOX0;
WARN_ON(mbox >= CIU3_MBOX_PER_CORE);
for_each_online_cpu(cpu)
octeon_irq_ciu3_mbox_set_enable(data, cpu, true);
}
static void octeon_irq_ciu3_mbox_disable(struct irq_data *data)
{
int cpu;
unsigned int mbox = data->irq - OCTEON_IRQ_MBOX0;
WARN_ON(mbox >= CIU3_MBOX_PER_CORE);
for_each_online_cpu(cpu)
octeon_irq_ciu3_mbox_set_enable(data, cpu, false);
}
static void octeon_irq_ciu3_mbox_ack(struct irq_data *data)
{
struct octeon_ciu3_info *ciu3_info;
unsigned int intsn;
u64 isc_w1c_addr;
union cvmx_ciu3_iscx_w1c isc_w1c;
unsigned int mbox = data->irq - OCTEON_IRQ_MBOX0;
intsn = octeon_irq_ciu3_mbox_intsn_for_core(cvmx_get_local_core_num(), mbox);
isc_w1c.u64 = 0;
isc_w1c.s.raw = 1;
ciu3_info = __this_cpu_read(octeon_ciu3_info);
isc_w1c_addr = ciu3_info->ciu3_addr + CIU3_ISC_W1C(intsn);
cvmx_write_csr(isc_w1c_addr, isc_w1c.u64);
cvmx_read_csr(isc_w1c_addr);
}
static void octeon_irq_ciu3_mbox_cpu_online(struct irq_data *data)
{
octeon_irq_ciu3_mbox_set_enable(data, smp_processor_id(), true);
}
static void octeon_irq_ciu3_mbox_cpu_offline(struct irq_data *data)
{
octeon_irq_ciu3_mbox_set_enable(data, smp_processor_id(), false);
}
static int octeon_irq_ciu3_alloc_resources(struct octeon_ciu3_info *ciu3_info)
{
u64 b = ciu3_info->ciu3_addr;
int idt_ip2, idt_ip3, idt_ip4;
int unused_idt2;
int core = cvmx_get_local_core_num();
int i;
__this_cpu_write(octeon_ciu3_info, ciu3_info);
/*
* 4 idt per core starting from 1 because zero is reserved.
* Base idt per core is 4 * core + 1
*/
idt_ip2 = core * 4 + 1;
idt_ip3 = core * 4 + 2;
idt_ip4 = core * 4 + 3;
unused_idt2 = core * 4 + 4;
__this_cpu_write(octeon_irq_ciu3_idt_ip2, idt_ip2);
__this_cpu_write(octeon_irq_ciu3_idt_ip3, idt_ip3);
/* ip2 interrupts for this CPU */
cvmx_write_csr(b + CIU3_IDT_CTL(idt_ip2), 0);
cvmx_write_csr(b + CIU3_IDT_PP(idt_ip2, 0), 1ull << core);
cvmx_write_csr(b + CIU3_IDT_IO(idt_ip2), 0);
/* ip3 interrupts for this CPU */
cvmx_write_csr(b + CIU3_IDT_CTL(idt_ip3), 1);
cvmx_write_csr(b + CIU3_IDT_PP(idt_ip3, 0), 1ull << core);
cvmx_write_csr(b + CIU3_IDT_IO(idt_ip3), 0);
/* ip4 interrupts for this CPU */
cvmx_write_csr(b + CIU3_IDT_CTL(idt_ip4), 2);
cvmx_write_csr(b + CIU3_IDT_PP(idt_ip4, 0), 0);
cvmx_write_csr(b + CIU3_IDT_IO(idt_ip4), 0);
cvmx_write_csr(b + CIU3_IDT_CTL(unused_idt2), 0);
cvmx_write_csr(b + CIU3_IDT_PP(unused_idt2, 0), 0);
cvmx_write_csr(b + CIU3_IDT_IO(unused_idt2), 0);
for (i = 0; i < CIU3_MBOX_PER_CORE; i++) {
unsigned int intsn = octeon_irq_ciu3_mbox_intsn_for_core(core, i);
cvmx_write_csr(b + CIU3_ISC_W1C(intsn), 2);
cvmx_write_csr(b + CIU3_ISC_CTL(intsn), 0);
}
return 0;
}
static void octeon_irq_setup_secondary_ciu3(void)
{
struct octeon_ciu3_info *ciu3_info;
ciu3_info = octeon_ciu3_info_per_node[cvmx_get_node_num()];
octeon_irq_ciu3_alloc_resources(ciu3_info);
irq_cpu_online();
/* Enable the CIU lines */
set_c0_status(STATUSF_IP3 | STATUSF_IP2);
if (octeon_irq_use_ip4)
set_c0_status(STATUSF_IP4);
else
clear_c0_status(STATUSF_IP4);
}
static struct irq_chip octeon_irq_chip_ciu3_mbox = {
.name = "CIU3-M",
.irq_enable = octeon_irq_ciu3_mbox_enable,
.irq_disable = octeon_irq_ciu3_mbox_disable,
.irq_ack = octeon_irq_ciu3_mbox_ack,
.irq_cpu_online = octeon_irq_ciu3_mbox_cpu_online,
.irq_cpu_offline = octeon_irq_ciu3_mbox_cpu_offline,
.flags = IRQCHIP_ONOFFLINE_ENABLED,
};
static int __init octeon_irq_init_ciu3(struct device_node *ciu_node,
struct device_node *parent)
{
int i;
int node;
struct irq_domain *domain;
struct octeon_ciu3_info *ciu3_info;
const __be32 *zero_addr;
u64 base_addr;
union cvmx_ciu3_const consts;
node = 0; /* of_node_to_nid(ciu_node); */
ciu3_info = kzalloc_node(sizeof(*ciu3_info), GFP_KERNEL, node);
if (!ciu3_info)
return -ENOMEM;
zero_addr = of_get_address(ciu_node, 0, NULL, NULL);
if (WARN_ON(!zero_addr))
return -EINVAL;
base_addr = of_translate_address(ciu_node, zero_addr);
base_addr = (u64)phys_to_virt(base_addr);
ciu3_info->ciu3_addr = base_addr;
ciu3_info->node = node;
consts.u64 = cvmx_read_csr(base_addr + CIU3_CONST);
octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu3;
octeon_irq_ip2 = octeon_irq_ciu3_ip2;
octeon_irq_ip3 = octeon_irq_ciu3_mbox;
octeon_irq_ip4 = octeon_irq_ip4_mask;
if (node == cvmx_get_node_num()) {
/* Mips internal */
octeon_irq_init_core();
/* Only do per CPU things if it is the CIU of the boot node. */
i = irq_alloc_descs_from(OCTEON_IRQ_MBOX0, 8, node);
WARN_ON(i < 0);
for (i = 0; i < 8; i++)
irq_set_chip_and_handler(i + OCTEON_IRQ_MBOX0,
&octeon_irq_chip_ciu3_mbox, handle_percpu_irq);
}
/*
* Initialize all domains to use the default domain. Specific major
* blocks will overwrite the default domain as needed.
*/
domain = irq_domain_add_tree(ciu_node, &octeon_dflt_domain_ciu3_ops,
ciu3_info);
for (i = 0; i < MAX_CIU3_DOMAINS; i++)
ciu3_info->domain[i] = domain;
octeon_ciu3_info_per_node[node] = ciu3_info;
if (node == cvmx_get_node_num()) {
/* Only do per CPU things if it is the CIU of the boot node. */
octeon_irq_ciu3_alloc_resources(ciu3_info);
if (node == 0)
irq_set_default_host(domain);
octeon_irq_use_ip4 = false;
/* Enable the CIU lines */
set_c0_status(STATUSF_IP2 | STATUSF_IP3);
clear_c0_status(STATUSF_IP4);
}
return 0;
}
static struct of_device_id ciu_types[] __initdata = {
{.compatible = "cavium,octeon-3860-ciu", .data = octeon_irq_init_ciu},
{.compatible = "cavium,octeon-3860-gpio", .data = octeon_irq_init_gpio},
{.compatible = "cavium,octeon-6880-ciu2", .data = octeon_irq_init_ciu2},
{.compatible = "cavium,octeon-7890-ciu3", .data = octeon_irq_init_ciu3},
{.compatible = "cavium,octeon-7130-cib", .data = octeon_irq_init_cib},
{}
};

View File

@ -13,6 +13,7 @@
#include <linux/i2c.h>
#include <linux/usb.h>
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
@ -525,10 +526,17 @@ static void __init octeon_fdt_set_phy(int eth, int phy_addr)
static void __init octeon_fdt_set_mac_addr(int n, u64 *pmac)
{
const u8 *old_mac;
int old_len;
u8 new_mac[6];
u64 mac = *pmac;
int r;
old_mac = fdt_getprop(initial_boot_params, n, "local-mac-address",
&old_len);
if (!old_mac || old_len != 6 || is_valid_ether_addr(old_mac))
return;
new_mac[0] = (mac >> 40) & 0xff;
new_mac[1] = (mac >> 32) & 0xff;
new_mac[2] = (mac >> 24) & 0xff;
@ -560,7 +568,7 @@ static void __init octeon_fdt_rm_ethernet(int node)
fdt_nop_node(initial_boot_params, node);
}
static void __init octeon_fdt_pip_port(int iface, int i, int p, int max, u64 *pmac)
static void __init octeon_fdt_pip_port(int iface, int i, int p, int max)
{
char name_buffer[20];
int eth;
@ -583,10 +591,9 @@ static void __init octeon_fdt_pip_port(int iface, int i, int p, int max, u64 *pm
phy_addr = cvmx_helper_board_get_mii_address(ipd_port);
octeon_fdt_set_phy(eth, phy_addr);
octeon_fdt_set_mac_addr(eth, pmac);
}
static void __init octeon_fdt_pip_iface(int pip, int idx, u64 *pmac)
static void __init octeon_fdt_pip_iface(int pip, int idx)
{
char name_buffer[20];
int iface;
@ -602,7 +609,73 @@ static void __init octeon_fdt_pip_iface(int pip, int idx, u64 *pmac)
count = cvmx_helper_ports_on_interface(idx);
for (p = 0; p < 16; p++)
octeon_fdt_pip_port(iface, idx, p, count - 1, pmac);
octeon_fdt_pip_port(iface, idx, p, count - 1);
}
void __init octeon_fill_mac_addresses(void)
{
const char *alias_prop;
char name_buffer[20];
u64 mac_addr_base;
int aliases;
int pip;
int i;
aliases = fdt_path_offset(initial_boot_params, "/aliases");
if (aliases < 0)
return;
mac_addr_base =
((octeon_bootinfo->mac_addr_base[0] & 0xffull)) << 40 |
((octeon_bootinfo->mac_addr_base[1] & 0xffull)) << 32 |
((octeon_bootinfo->mac_addr_base[2] & 0xffull)) << 24 |
((octeon_bootinfo->mac_addr_base[3] & 0xffull)) << 16 |
((octeon_bootinfo->mac_addr_base[4] & 0xffull)) << 8 |
(octeon_bootinfo->mac_addr_base[5] & 0xffull);
for (i = 0; i < 2; i++) {
int mgmt;
snprintf(name_buffer, sizeof(name_buffer), "mix%d", i);
alias_prop = fdt_getprop(initial_boot_params, aliases,
name_buffer, NULL);
if (!alias_prop)
continue;
mgmt = fdt_path_offset(initial_boot_params, alias_prop);
if (mgmt < 0)
continue;
octeon_fdt_set_mac_addr(mgmt, &mac_addr_base);
}
alias_prop = fdt_getprop(initial_boot_params, aliases, "pip", NULL);
if (!alias_prop)
return;
pip = fdt_path_offset(initial_boot_params, alias_prop);
if (pip < 0)
return;
for (i = 0; i <= 4; i++) {
int iface;
int p;
snprintf(name_buffer, sizeof(name_buffer), "interface@%d", i);
iface = fdt_subnode_offset(initial_boot_params, pip,
name_buffer);
if (iface < 0)
continue;
for (p = 0; p < 16; p++) {
int eth;
snprintf(name_buffer, sizeof(name_buffer),
"ethernet@%x", p);
eth = fdt_subnode_offset(initial_boot_params, iface,
name_buffer);
if (eth < 0)
continue;
octeon_fdt_set_mac_addr(eth, &mac_addr_base);
}
}
}
int __init octeon_prune_device_tree(void)
@ -612,7 +685,6 @@ int __init octeon_prune_device_tree(void)
const char *alias_prop;
char name_buffer[20];
int aliases;
u64 mac_addr_base;
if (fdt_check_header(initial_boot_params))
panic("Corrupt Device Tree.");
@ -623,15 +695,6 @@ int __init octeon_prune_device_tree(void)
return -EINVAL;
}
mac_addr_base =
((octeon_bootinfo->mac_addr_base[0] & 0xffull)) << 40 |
((octeon_bootinfo->mac_addr_base[1] & 0xffull)) << 32 |
((octeon_bootinfo->mac_addr_base[2] & 0xffull)) << 24 |
((octeon_bootinfo->mac_addr_base[3] & 0xffull)) << 16 |
((octeon_bootinfo->mac_addr_base[4] & 0xffull)) << 8 |
(octeon_bootinfo->mac_addr_base[5] & 0xffull);
if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN63XX))
max_port = 2;
else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN68XX))
@ -660,7 +723,6 @@ int __init octeon_prune_device_tree(void)
} else {
int phy_addr = cvmx_helper_board_get_mii_address(CVMX_HELPER_BOARD_MGMT_IPD_PORT + i);
octeon_fdt_set_phy(mgmt, phy_addr);
octeon_fdt_set_mac_addr(mgmt, &mac_addr_base);
}
}
}
@ -670,7 +732,7 @@ int __init octeon_prune_device_tree(void)
int pip = fdt_path_offset(initial_boot_params, pip_path);
if (pip >= 0)
for (i = 0; i <= 4; i++)
octeon_fdt_pip_iface(pip, i, &mac_addr_base);
octeon_fdt_pip_iface(pip, i);
}
/* I2C */

View File

@ -43,8 +43,6 @@
#include <asm/octeon/cvmx-mio-defs.h>
#include <asm/octeon/cvmx-rst-defs.h>
extern struct plat_smp_ops octeon_smp_ops;
#ifdef CONFIG_PCI
extern void pci_console_init(const char *arg);
#endif
@ -466,15 +464,25 @@ static void octeon_halt(void)
static char __read_mostly octeon_system_type[80];
static int __init init_octeon_system_type(void)
static void __init init_octeon_system_type(void)
{
snprintf(octeon_system_type, sizeof(octeon_system_type), "%s (%s)",
cvmx_board_type_to_string(octeon_bootinfo->board_type),
octeon_model_get_string(read_c0_prid()));
char const *board_type;
return 0;
board_type = cvmx_board_type_to_string(octeon_bootinfo->board_type);
if (board_type == NULL) {
struct device_node *root;
int ret;
root = of_find_node_by_path("/");
ret = of_property_read_string(root, "model", &board_type);
of_node_put(root);
if (ret)
board_type = "Unsupported Board";
}
snprintf(octeon_system_type, sizeof(octeon_system_type), "%s (%s)",
board_type, octeon_model_get_string(read_c0_prid()));
}
early_initcall(init_octeon_system_type);
/**
* Return a string representing the system type
@ -492,8 +500,6 @@ const char *get_system_type(void)
void octeon_user_io_init(void)
{
union octeon_cvmemctl cvmmemctl;
union cvmx_iob_fau_timeout fau_timeout;
union cvmx_pow_nw_tim nm_tim;
/* Get the current settings for CP0_CVMMEMCTL_REG */
cvmmemctl.u64 = read_c0_cvmmemctl();
@ -595,17 +601,27 @@ void octeon_user_io_init(void)
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE,
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128);
/* Set a default for the hardware timeouts */
fau_timeout.u64 = 0;
fau_timeout.s.tout_val = 0xfff;
/* Disable tagwait FAU timeout */
fau_timeout.s.tout_enb = 0;
cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_timeout.u64);
if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
union cvmx_iob_fau_timeout fau_timeout;
nm_tim.u64 = 0;
/* 4096 cycles */
nm_tim.s.nw_tim = 3;
cvmx_write_csr(CVMX_POW_NW_TIM, nm_tim.u64);
/* Set a default for the hardware timeouts */
fau_timeout.u64 = 0;
fau_timeout.s.tout_val = 0xfff;
/* Disable tagwait FAU timeout */
fau_timeout.s.tout_enb = 0;
cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_timeout.u64);
}
if ((!OCTEON_IS_MODEL(OCTEON_CN68XX) &&
!OCTEON_IS_MODEL(OCTEON_CN7XXX)) ||
OCTEON_IS_MODEL(OCTEON_CN70XX)) {
union cvmx_pow_nw_tim nm_tim;
nm_tim.u64 = 0;
/* 4096 cycles */
nm_tim.s.nw_tim = 3;
cvmx_write_csr(CVMX_POW_NW_TIM, nm_tim.u64);
}
write_octeon_c0_icacheerr(0);
write_c0_derraddr1(0);
@ -637,9 +653,22 @@ void __init prom_init(void)
sysinfo = cvmx_sysinfo_get();
memset(sysinfo, 0, sizeof(*sysinfo));
sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
sysinfo->phy_mem_desc_ptr =
cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr);
sysinfo->core_mask = octeon_bootinfo->core_mask;
sysinfo->phy_mem_desc_addr = (u64)phys_to_virt(octeon_bootinfo->phy_mem_desc_addr);
if ((octeon_bootinfo->major_version > 1) ||
(octeon_bootinfo->major_version == 1 &&
octeon_bootinfo->minor_version >= 4))
cvmx_coremask_copy(&sysinfo->core_mask,
&octeon_bootinfo->ext_core_mask);
else
cvmx_coremask_set64(&sysinfo->core_mask,
octeon_bootinfo->core_mask);
/* Some broken u-boot pass garbage in upper bits, clear them out */
if (!OCTEON_IS_MODEL(OCTEON_CN78XX))
for (i = 512; i < 1024; i++)
cvmx_coremask_clear_core(&sysinfo->core_mask, i);
sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
@ -867,7 +896,7 @@ void __init prom_init(void)
#endif
octeon_user_io_init();
register_smp_ops(&octeon_smp_ops);
octeon_setup_smp();
}
/* Exclude a single page from the regions obtained in plat_mem_setup. */
@ -1079,6 +1108,7 @@ void __init prom_free_prom_memory(void)
}
}
void __init octeon_fill_mac_addresses(void);
int octeon_prune_device_tree(void);
extern const char __appended_dtb;
@ -1088,11 +1118,13 @@ void __init device_tree_init(void)
{
const void *fdt;
bool do_prune;
bool fill_mac;
#ifdef CONFIG_MIPS_ELF_APPENDED_DTB
if (!fdt_check_header(&__appended_dtb)) {
fdt = &__appended_dtb;
do_prune = false;
fill_mac = true;
pr_info("Using appended Device Tree.\n");
} else
#endif
@ -1101,13 +1133,16 @@ void __init device_tree_init(void)
if (fdt_check_header(fdt))
panic("Corrupt Device Tree passed to kernel.");
do_prune = false;
fill_mac = false;
pr_info("Using passed Device Tree.\n");
} else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
fdt = &__dtb_octeon_68xx_begin;
do_prune = true;
fill_mac = true;
} else {
fdt = &__dtb_octeon_3xxx_begin;
do_prune = true;
fill_mac = true;
}
initial_boot_params = (void *)fdt;
@ -1116,7 +1151,10 @@ void __init device_tree_init(void)
octeon_prune_device_tree();
pr_info("Using internal Device Tree.\n");
}
if (fill_mac)
octeon_fill_mac_addresses();
unflatten_and_copy_device_tree();
init_octeon_system_type();
}
static int __initdata disable_octeon_edac_p;

View File

@ -30,25 +30,55 @@ uint64_t octeon_bootloader_entry_addr;
EXPORT_SYMBOL(octeon_bootloader_entry_addr);
#endif
static void octeon_icache_flush(void)
{
asm volatile ("synci 0($0)\n");
}
static void (*octeon_message_functions[8])(void) = {
scheduler_ipi,
generic_smp_call_function_interrupt,
octeon_icache_flush,
};
static irqreturn_t mailbox_interrupt(int irq, void *dev_id)
{
const int coreid = cvmx_get_core_num();
uint64_t action;
u64 mbox_clrx = CVMX_CIU_MBOX_CLRX(cvmx_get_core_num());
u64 action;
int i;
/* Load the mailbox register to figure out what we're supposed to do */
action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid)) & 0xffff;
/*
* Make sure the function array initialization remains
* correct.
*/
BUILD_BUG_ON(SMP_RESCHEDULE_YOURSELF != (1 << 0));
BUILD_BUG_ON(SMP_CALL_FUNCTION != (1 << 1));
BUILD_BUG_ON(SMP_ICACHE_FLUSH != (1 << 2));
/*
* Load the mailbox register to figure out what we're supposed
* to do.
*/
action = cvmx_read_csr(mbox_clrx);
if (OCTEON_IS_MODEL(OCTEON_CN68XX))
action &= 0xff;
else
action &= 0xffff;
/* Clear the mailbox to clear the interrupt */
cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), action);
cvmx_write_csr(mbox_clrx, action);
if (action & SMP_CALL_FUNCTION)
generic_smp_call_function_interrupt();
if (action & SMP_RESCHEDULE_YOURSELF)
scheduler_ipi();
for (i = 0; i < ARRAY_SIZE(octeon_message_functions) && action;) {
if (action & 1) {
void (*fn)(void) = octeon_message_functions[i];
/* Check if we've been told to flush the icache */
if (action & SMP_ICACHE_FLUSH)
asm volatile ("synci 0($0)\n");
if (fn)
fn();
}
action >>= 1;
i++;
}
return IRQ_HANDLED;
}
@ -97,13 +127,15 @@ static void octeon_smp_hotplug_setup(void)
#endif
}
static void octeon_smp_setup(void)
static void __init octeon_smp_setup(void)
{
const int coreid = cvmx_get_core_num();
int cpus;
int id;
int core_mask = octeon_get_boot_coremask();
struct cvmx_sysinfo *sysinfo = cvmx_sysinfo_get();
#ifdef CONFIG_HOTPLUG_CPU
int core_mask = octeon_get_boot_coremask();
unsigned int num_cores = cvmx_octeon_num_cores();
#endif
@ -119,7 +151,7 @@ static void octeon_smp_setup(void)
/* The present CPUs get the lowest CPU numbers. */
cpus = 1;
for (id = 0; id < NR_CPUS; id++) {
if ((id != coreid) && (core_mask & (1 << id))) {
if ((id != coreid) && cvmx_coremask_is_core_set(&sysinfo->core_mask, id)) {
set_cpu_possible(cpus, true);
set_cpu_present(cpus, true);
__cpu_number_map[id] = cpus;
@ -196,7 +228,7 @@ static void octeon_init_secondary(void)
* Callout to firmware before smp_init
*
*/
void octeon_prepare_cpus(unsigned int max_cpus)
static void __init octeon_prepare_cpus(unsigned int max_cpus)
{
/*
* Only the low order mailbox bits are used for IPIs, leave
@ -242,7 +274,7 @@ static int octeon_cpu_disable(void)
cpumask_clear_cpu(cpu, &cpu_callin_map);
octeon_fixup_irqs();
flush_cache_all();
__flush_cache_all();
local_flush_tlb_all();
return 0;
@ -388,3 +420,92 @@ struct plat_smp_ops octeon_smp_ops = {
.cpu_die = octeon_cpu_die,
#endif
};
static irqreturn_t octeon_78xx_reched_interrupt(int irq, void *dev_id)
{
scheduler_ipi();
return IRQ_HANDLED;
}
static irqreturn_t octeon_78xx_call_function_interrupt(int irq, void *dev_id)
{
generic_smp_call_function_interrupt();
return IRQ_HANDLED;
}
static irqreturn_t octeon_78xx_icache_flush_interrupt(int irq, void *dev_id)
{
octeon_icache_flush();
return IRQ_HANDLED;
}
/*
* Callout to firmware before smp_init
*/
static void octeon_78xx_prepare_cpus(unsigned int max_cpus)
{
if (request_irq(OCTEON_IRQ_MBOX0 + 0,
octeon_78xx_reched_interrupt,
IRQF_PERCPU | IRQF_NO_THREAD, "Scheduler",
octeon_78xx_reched_interrupt)) {
panic("Cannot request_irq for SchedulerIPI");
}
if (request_irq(OCTEON_IRQ_MBOX0 + 1,
octeon_78xx_call_function_interrupt,
IRQF_PERCPU | IRQF_NO_THREAD, "SMP-Call",
octeon_78xx_call_function_interrupt)) {
panic("Cannot request_irq for SMP-Call");
}
if (request_irq(OCTEON_IRQ_MBOX0 + 2,
octeon_78xx_icache_flush_interrupt,
IRQF_PERCPU | IRQF_NO_THREAD, "ICache-Flush",
octeon_78xx_icache_flush_interrupt)) {
panic("Cannot request_irq for ICache-Flush");
}
}
static void octeon_78xx_send_ipi_single(int cpu, unsigned int action)
{
int i;
for (i = 0; i < 8; i++) {
if (action & 1)
octeon_ciu3_mbox_send(cpu, i);
action >>= 1;
}
}
static void octeon_78xx_send_ipi_mask(const struct cpumask *mask,
unsigned int action)
{
unsigned int cpu;
for_each_cpu(cpu, mask)
octeon_78xx_send_ipi_single(cpu, action);
}
static struct plat_smp_ops octeon_78xx_smp_ops = {
.send_ipi_single = octeon_78xx_send_ipi_single,
.send_ipi_mask = octeon_78xx_send_ipi_mask,
.init_secondary = octeon_init_secondary,
.smp_finish = octeon_smp_finish,
.boot_secondary = octeon_boot_secondary,
.smp_setup = octeon_smp_setup,
.prepare_cpus = octeon_78xx_prepare_cpus,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_disable = octeon_cpu_disable,
.cpu_die = octeon_cpu_die,
#endif
};
void __init octeon_setup_smp(void)
{
struct plat_smp_ops *ops;
if (octeon_has_feature(OCTEON_FEATURE_CIU3))
ops = &octeon_78xx_smp_ops;
else
ops = &octeon_smp_ops;
register_smp_ops(ops);
}

View File

@ -23,7 +23,6 @@ CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
CONFIG_SYN_COOKIES=y
CONFIG_TCP_CONG_ADVANCED=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_IPV6_MROUTE=y

View File

@ -44,6 +44,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_MTD=y
CONFIG_MTD_BCM63XX_PARTS=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y

View File

@ -62,7 +62,6 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=m
CONFIG_INET_XFRM_MODE_TUNNEL=m
# CONFIG_INET_LRO is not set
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_IPV6_OPTIMISTIC_DAD=y

View File

@ -36,6 +36,7 @@ CONFIG_DEVTMPFS_MOUNT=y
CONFIG_PRINTK_TIME=y
CONFIG_BRCMSTB_GISB_ARB=y
CONFIG_MTD=y
CONFIG_MTD_BCM63XX_PARTS=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y

View File

@ -119,14 +119,16 @@ CONFIG_SPI=y
CONFIG_SPI_OCTEON=y
# CONFIG_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_USB_SUPPORT is not set
CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB=m
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_EHCI_HCD_PLATFORM=m
CONFIG_USB_OHCI_HCD=m
CONFIG_USB_OHCI_HCD_PLATFORM=m
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_DS1307=y
CONFIG_STAGING=y
CONFIG_OCTEON_ETHERNET=y
CONFIG_OCTEON_USB=m
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
@ -152,6 +154,9 @@ CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MD5_OCTEON=y
CONFIG_CRYPTO_SHA1_OCTEON=m
CONFIG_CRYPTO_SHA256_OCTEON=m
CONFIG_CRYPTO_SHA512_OCTEON=m
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set

View File

@ -30,7 +30,6 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=m
CONFIG_INET_XFRM_MODE_TUNNEL=m
CONFIG_INET_XFRM_MODE_BEET=m
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_INET6_AH=m

View File

@ -48,7 +48,6 @@ CONFIG_INET_XFRM_MODE_TUNNEL=m
CONFIG_INET_XFRM_MODE_BEET=m
# CONFIG_INET_LRO is not set
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_IPV6_OPTIMISTIC_DAD=y

View File

@ -43,7 +43,6 @@ CONFIG_INET_XFRM_MODE_TUNNEL=m
CONFIG_INET_XFRM_MODE_BEET=m
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_IPV6_OPTIMISTIC_DAD=y

View File

@ -34,7 +34,6 @@ CONFIG_IP_PIMSM_V2=y
CONFIG_INET_XFRM_MODE_TRANSPORT=m
CONFIG_INET_XFRM_MODE_TUNNEL=m
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_INET6_AH=m

View File

@ -71,7 +71,6 @@ CONFIG_TCP_CONG_ADVANCED=y
CONFIG_TCP_CONG_BIC=y
CONFIG_DEFAULT_BIC=y
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_TUNNEL=m
CONFIG_IPV6_MULTIPLE_TABLES=y

View File

@ -1,19 +1,17 @@
CONFIG_MACH_LOONGSON32=y
CONFIG_PREEMPT=y
# CONFIG_SECCOMP is not set
CONFIG_EXPERIMENTAL=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_KERNEL_XZ=y
CONFIG_SYSVIPC=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
CONFIG_NAMESPACES=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_EXPERT=y
CONFIG_PERF_EVENTS=y
# CONFIG_COMPAT_BRK is not set
@ -41,6 +39,12 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_STANDALONE is not set
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_LOONGSON1=y
CONFIG_MTD_UBI=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_SCSI=m
# CONFIG_SCSI_PROC_FS is not set
@ -48,7 +52,6 @@ CONFIG_BLK_DEV_SD=m
# CONFIG_SCSI_LOWLEVEL is not set
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_BROADCOM is not set
# CONFIG_NET_VENDOR_CHELSIO is not set
# CONFIG_NET_VENDOR_INTEL is not set
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
@ -56,7 +59,6 @@ CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_SEEQ is not set
# CONFIG_NET_VENDOR_SMSC is not set
CONFIG_STMMAC_ETH=y
CONFIG_STMMAC_DA=y
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_WLAN is not set
CONFIG_INPUT_EVDEV=y
@ -69,18 +71,25 @@ CONFIG_LEGACY_PTY_COUNT=8
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
# CONFIG_HW_RANDOM is not set
CONFIG_GPIOLIB=y
CONFIG_GPIO_LOONGSON1=y
# CONFIG_HWMON is not set
# CONFIG_VGA_CONSOLE is not set
CONFIG_USB_HID=m
CONFIG_HID_GENERIC=m
CONFIG_USB_HID=m
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_STORAGE=m
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_PL2303=m
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_LOONGSON1=y
# CONFIG_IOMMU_SUPPORT is not set
@ -96,15 +105,21 @@ CONFIG_VFAT_FS=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_UBIFS_FS=y
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
CONFIG_UBIFS_ATIME_SUPPORT=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_ISO8859_1=m
CONFIG_DYNAMIC_DEBUG=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_FTRACE is not set
# CONFIG_EARLY_PRINTK is not set
# CONFIG_CRYPTO_ECHAINIV is not set
# CONFIG_CRYPTO_HW is not set

View File

@ -51,7 +51,6 @@ CONFIG_INET_IPCOMP=m
CONFIG_INET_XFRM_MODE_TRANSPORT=m
CONFIG_INET_XFRM_MODE_TUNNEL=m
CONFIG_INET_XFRM_MODE_BEET=m
CONFIG_IPV6_PRIVACY=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m

View File

@ -95,7 +95,6 @@ CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m

View File

@ -75,7 +75,6 @@ CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m

View File

@ -37,7 +37,6 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=m
CONFIG_INET_XFRM_MODE_TUNNEL=m
CONFIG_INET_XFRM_MODE_BEET=m
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_INET6_AH=m

View File

@ -60,6 +60,7 @@ EXPORT_SYMBOL(dec_kn_slot_size);
int dec_tc_bus;
DEFINE_SPINLOCK(ioasic_ssr_lock);
EXPORT_SYMBOL(ioasic_ssr_lock);
volatile u32 *ioasic_base;

View File

@ -1,5 +1,6 @@
# MIPS headers
generic-(CONFIG_GENERIC_CSUM) += checksum.h
generic-y += clkdev.h
generic-y += cputime.h
generic-y += current.h
generic-y += dma-contiguous.h

View File

@ -235,6 +235,7 @@
.macro ld_b wd, off, base
.set push
.set mips32r2
.set fp=64
.set msa
ld.b $w\wd, \off(\base)
.set pop
@ -243,6 +244,7 @@
.macro ld_h wd, off, base
.set push
.set mips32r2
.set fp=64
.set msa
ld.h $w\wd, \off(\base)
.set pop
@ -251,6 +253,7 @@
.macro ld_w wd, off, base
.set push
.set mips32r2
.set fp=64
.set msa
ld.w $w\wd, \off(\base)
.set pop
@ -268,6 +271,7 @@
.macro st_b wd, off, base
.set push
.set mips32r2
.set fp=64
.set msa
st.b $w\wd, \off(\base)
.set pop
@ -276,6 +280,7 @@
.macro st_h wd, off, base
.set push
.set mips32r2
.set fp=64
.set msa
st.h $w\wd, \off(\base)
.set pop
@ -284,6 +289,7 @@
.macro st_w wd, off, base
.set push
.set mips32r2
.set fp=64
.set msa
st.w $w\wd, \off(\base)
.set pop
@ -298,21 +304,21 @@
.set pop
.endm
.macro copy_u_w ws, n
.macro copy_s_w ws, n
.set push
.set mips32r2
.set fp=64
.set msa
copy_u.w $1, $w\ws[\n]
copy_s.w $1, $w\ws[\n]
.set pop
.endm
.macro copy_u_d ws, n
.macro copy_s_d ws, n
.set push
.set mips64r2
.set fp=64
.set msa
copy_u.d $1, $w\ws[\n]
copy_s.d $1, $w\ws[\n]
.set pop
.endm
@ -346,8 +352,8 @@
#define STH_MSA_INSN 0x5800081f
#define STW_MSA_INSN 0x5800082f
#define STD_MSA_INSN 0x5800083f
#define COPY_UW_MSA_INSN 0x58f00056
#define COPY_UD_MSA_INSN 0x58f80056
#define COPY_SW_MSA_INSN 0x58b00056
#define COPY_SD_MSA_INSN 0x58b80056
#define INSERT_W_MSA_INSN 0x59300816
#define INSERT_D_MSA_INSN 0x59380816
#else
@ -361,8 +367,8 @@
#define STH_MSA_INSN 0x78000825
#define STW_MSA_INSN 0x78000826
#define STD_MSA_INSN 0x78000827
#define COPY_UW_MSA_INSN 0x78f00059
#define COPY_UD_MSA_INSN 0x78f80059
#define COPY_SW_MSA_INSN 0x78b00059
#define COPY_SD_MSA_INSN 0x78b80059
#define INSERT_W_MSA_INSN 0x79300819
#define INSERT_D_MSA_INSN 0x79380819
#endif
@ -393,7 +399,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word LDB_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -402,7 +408,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word LDH_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -411,7 +417,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word LDW_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -420,7 +426,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word LDD_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -429,7 +435,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word STB_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -438,7 +444,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word STH_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -447,7 +453,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word STW_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -456,26 +462,26 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word STD_MSA_INSN | (\wd << 6)
.set pop
.endm
.macro copy_u_w ws, n
.macro copy_s_w ws, n
.set push
.set noat
SET_HARDFLOAT
.insn
.word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
.word COPY_SW_MSA_INSN | (\n << 16) | (\ws << 11)
.set pop
.endm
.macro copy_u_d ws, n
.macro copy_s_d ws, n
.set push
.set noat
SET_HARDFLOAT
.insn
.word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
.word COPY_SD_MSA_INSN | (\n << 16) | (\ws << 11)
.set pop
.endm
@ -496,41 +502,52 @@
.endm
#endif
#ifdef TOOLCHAIN_SUPPORTS_MSA
#define FPR_BASE_OFFS THREAD_FPR0
#define FPR_BASE $1
#else
#define FPR_BASE_OFFS 0
#define FPR_BASE \thread
#endif
.macro msa_save_all thread
st_d 0, THREAD_FPR0, \thread
st_d 1, THREAD_FPR1, \thread
st_d 2, THREAD_FPR2, \thread
st_d 3, THREAD_FPR3, \thread
st_d 4, THREAD_FPR4, \thread
st_d 5, THREAD_FPR5, \thread
st_d 6, THREAD_FPR6, \thread
st_d 7, THREAD_FPR7, \thread
st_d 8, THREAD_FPR8, \thread
st_d 9, THREAD_FPR9, \thread
st_d 10, THREAD_FPR10, \thread
st_d 11, THREAD_FPR11, \thread
st_d 12, THREAD_FPR12, \thread
st_d 13, THREAD_FPR13, \thread
st_d 14, THREAD_FPR14, \thread
st_d 15, THREAD_FPR15, \thread
st_d 16, THREAD_FPR16, \thread
st_d 17, THREAD_FPR17, \thread
st_d 18, THREAD_FPR18, \thread
st_d 19, THREAD_FPR19, \thread
st_d 20, THREAD_FPR20, \thread
st_d 21, THREAD_FPR21, \thread
st_d 22, THREAD_FPR22, \thread
st_d 23, THREAD_FPR23, \thread
st_d 24, THREAD_FPR24, \thread
st_d 25, THREAD_FPR25, \thread
st_d 26, THREAD_FPR26, \thread
st_d 27, THREAD_FPR27, \thread
st_d 28, THREAD_FPR28, \thread
st_d 29, THREAD_FPR29, \thread
st_d 30, THREAD_FPR30, \thread
st_d 31, THREAD_FPR31, \thread
.set push
.set noat
#ifdef TOOLCHAIN_SUPPORTS_MSA
PTR_ADDU FPR_BASE, \thread, FPR_BASE_OFFS
#endif
st_d 0, THREAD_FPR0 - FPR_BASE_OFFS, FPR_BASE
st_d 1, THREAD_FPR1 - FPR_BASE_OFFS, FPR_BASE
st_d 2, THREAD_FPR2 - FPR_BASE_OFFS, FPR_BASE
st_d 3, THREAD_FPR3 - FPR_BASE_OFFS, FPR_BASE
st_d 4, THREAD_FPR4 - FPR_BASE_OFFS, FPR_BASE
st_d 5, THREAD_FPR5 - FPR_BASE_OFFS, FPR_BASE
st_d 6, THREAD_FPR6 - FPR_BASE_OFFS, FPR_BASE
st_d 7, THREAD_FPR7 - FPR_BASE_OFFS, FPR_BASE
st_d 8, THREAD_FPR8 - FPR_BASE_OFFS, FPR_BASE
st_d 9, THREAD_FPR9 - FPR_BASE_OFFS, FPR_BASE
st_d 10, THREAD_FPR10 - FPR_BASE_OFFS, FPR_BASE
st_d 11, THREAD_FPR11 - FPR_BASE_OFFS, FPR_BASE
st_d 12, THREAD_FPR12 - FPR_BASE_OFFS, FPR_BASE
st_d 13, THREAD_FPR13 - FPR_BASE_OFFS, FPR_BASE
st_d 14, THREAD_FPR14 - FPR_BASE_OFFS, FPR_BASE
st_d 15, THREAD_FPR15 - FPR_BASE_OFFS, FPR_BASE
st_d 16, THREAD_FPR16 - FPR_BASE_OFFS, FPR_BASE
st_d 17, THREAD_FPR17 - FPR_BASE_OFFS, FPR_BASE
st_d 18, THREAD_FPR18 - FPR_BASE_OFFS, FPR_BASE
st_d 19, THREAD_FPR19 - FPR_BASE_OFFS, FPR_BASE
st_d 20, THREAD_FPR20 - FPR_BASE_OFFS, FPR_BASE
st_d 21, THREAD_FPR21 - FPR_BASE_OFFS, FPR_BASE
st_d 22, THREAD_FPR22 - FPR_BASE_OFFS, FPR_BASE
st_d 23, THREAD_FPR23 - FPR_BASE_OFFS, FPR_BASE
st_d 24, THREAD_FPR24 - FPR_BASE_OFFS, FPR_BASE
st_d 25, THREAD_FPR25 - FPR_BASE_OFFS, FPR_BASE
st_d 26, THREAD_FPR26 - FPR_BASE_OFFS, FPR_BASE
st_d 27, THREAD_FPR27 - FPR_BASE_OFFS, FPR_BASE
st_d 28, THREAD_FPR28 - FPR_BASE_OFFS, FPR_BASE
st_d 29, THREAD_FPR29 - FPR_BASE_OFFS, FPR_BASE
st_d 30, THREAD_FPR30 - FPR_BASE_OFFS, FPR_BASE
st_d 31, THREAD_FPR31 - FPR_BASE_OFFS, FPR_BASE
SET_HARDFLOAT
_cfcmsa $1, MSA_CSR
sw $1, THREAD_MSA_CSR(\thread)
@ -543,41 +560,47 @@
SET_HARDFLOAT
lw $1, THREAD_MSA_CSR(\thread)
_ctcmsa MSA_CSR, $1
.set pop
ld_d 0, THREAD_FPR0, \thread
ld_d 1, THREAD_FPR1, \thread
ld_d 2, THREAD_FPR2, \thread
ld_d 3, THREAD_FPR3, \thread
ld_d 4, THREAD_FPR4, \thread
ld_d 5, THREAD_FPR5, \thread
ld_d 6, THREAD_FPR6, \thread
ld_d 7, THREAD_FPR7, \thread
ld_d 8, THREAD_FPR8, \thread
ld_d 9, THREAD_FPR9, \thread
ld_d 10, THREAD_FPR10, \thread
ld_d 11, THREAD_FPR11, \thread
ld_d 12, THREAD_FPR12, \thread
ld_d 13, THREAD_FPR13, \thread
ld_d 14, THREAD_FPR14, \thread
ld_d 15, THREAD_FPR15, \thread
ld_d 16, THREAD_FPR16, \thread
ld_d 17, THREAD_FPR17, \thread
ld_d 18, THREAD_FPR18, \thread
ld_d 19, THREAD_FPR19, \thread
ld_d 20, THREAD_FPR20, \thread
ld_d 21, THREAD_FPR21, \thread
ld_d 22, THREAD_FPR22, \thread
ld_d 23, THREAD_FPR23, \thread
ld_d 24, THREAD_FPR24, \thread
ld_d 25, THREAD_FPR25, \thread
ld_d 26, THREAD_FPR26, \thread
ld_d 27, THREAD_FPR27, \thread
ld_d 28, THREAD_FPR28, \thread
ld_d 29, THREAD_FPR29, \thread
ld_d 30, THREAD_FPR30, \thread
ld_d 31, THREAD_FPR31, \thread
#ifdef TOOLCHAIN_SUPPORTS_MSA
PTR_ADDU FPR_BASE, \thread, FPR_BASE_OFFS
#endif
ld_d 0, THREAD_FPR0 - FPR_BASE_OFFS, FPR_BASE
ld_d 1, THREAD_FPR1 - FPR_BASE_OFFS, FPR_BASE
ld_d 2, THREAD_FPR2 - FPR_BASE_OFFS, FPR_BASE
ld_d 3, THREAD_FPR3 - FPR_BASE_OFFS, FPR_BASE
ld_d 4, THREAD_FPR4 - FPR_BASE_OFFS, FPR_BASE
ld_d 5, THREAD_FPR5 - FPR_BASE_OFFS, FPR_BASE
ld_d 6, THREAD_FPR6 - FPR_BASE_OFFS, FPR_BASE
ld_d 7, THREAD_FPR7 - FPR_BASE_OFFS, FPR_BASE
ld_d 8, THREAD_FPR8 - FPR_BASE_OFFS, FPR_BASE
ld_d 9, THREAD_FPR9 - FPR_BASE_OFFS, FPR_BASE
ld_d 10, THREAD_FPR10 - FPR_BASE_OFFS, FPR_BASE
ld_d 11, THREAD_FPR11 - FPR_BASE_OFFS, FPR_BASE
ld_d 12, THREAD_FPR12 - FPR_BASE_OFFS, FPR_BASE
ld_d 13, THREAD_FPR13 - FPR_BASE_OFFS, FPR_BASE
ld_d 14, THREAD_FPR14 - FPR_BASE_OFFS, FPR_BASE
ld_d 15, THREAD_FPR15 - FPR_BASE_OFFS, FPR_BASE
ld_d 16, THREAD_FPR16 - FPR_BASE_OFFS, FPR_BASE
ld_d 17, THREAD_FPR17 - FPR_BASE_OFFS, FPR_BASE
ld_d 18, THREAD_FPR18 - FPR_BASE_OFFS, FPR_BASE
ld_d 19, THREAD_FPR19 - FPR_BASE_OFFS, FPR_BASE
ld_d 20, THREAD_FPR20 - FPR_BASE_OFFS, FPR_BASE
ld_d 21, THREAD_FPR21 - FPR_BASE_OFFS, FPR_BASE
ld_d 22, THREAD_FPR22 - FPR_BASE_OFFS, FPR_BASE
ld_d 23, THREAD_FPR23 - FPR_BASE_OFFS, FPR_BASE
ld_d 24, THREAD_FPR24 - FPR_BASE_OFFS, FPR_BASE
ld_d 25, THREAD_FPR25 - FPR_BASE_OFFS, FPR_BASE
ld_d 26, THREAD_FPR26 - FPR_BASE_OFFS, FPR_BASE
ld_d 27, THREAD_FPR27 - FPR_BASE_OFFS, FPR_BASE
ld_d 28, THREAD_FPR28 - FPR_BASE_OFFS, FPR_BASE
ld_d 29, THREAD_FPR29 - FPR_BASE_OFFS, FPR_BASE
ld_d 30, THREAD_FPR30 - FPR_BASE_OFFS, FPR_BASE
ld_d 31, THREAD_FPR31 - FPR_BASE_OFFS, FPR_BASE
.set pop
.endm
#undef FPR_BASE_OFFS
#undef FPR_BASE
.macro msa_init_upper wd
#ifdef CONFIG_64BIT
insert_d \wd, 1

View File

@ -19,25 +19,10 @@
#include <asm/byteorder.h> /* sigh ... */
#include <asm/compiler.h>
#include <asm/cpu-features.h>
#include <asm/llsc.h>
#include <asm/sgidefs.h>
#include <asm/war.h>
#if _MIPS_SZLONG == 32
#define SZLONG_LOG 5
#define SZLONG_MASK 31UL
#define __LL "ll "
#define __SC "sc "
#define __INS "ins "
#define __EXT "ext "
#elif _MIPS_SZLONG == 64
#define SZLONG_LOG 6
#define SZLONG_MASK 63UL
#define __LL "lld "
#define __SC "scd "
#define __INS "dins "
#define __EXT "dext "
#endif
/*
* These are the "slower" versions of the functions and are in bitops.c.
* These functions call raw_local_irq_{save,restore}().

View File

@ -0,0 +1,30 @@
#ifndef __MIPS_ASM_BITREV_H__
#define __MIPS_ASM_BITREV_H__
#include <linux/swab.h>
static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
{
u32 ret;
asm("bitswap %0, %1" : "=r"(ret) : "r"(__swab32(x)));
return ret;
}
static __always_inline __attribute_const__ u16 __arch_bitrev16(u16 x)
{
u16 ret;
asm("bitswap %0, %1" : "=r"(ret) : "r"(__swab16(x)));
return ret;
}
static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x)
{
u8 ret;
asm("bitswap %0, %1" : "=r"(ret) : "r"(x));
return ret;
}
#endif /* __MIPS_ASM_BITREV_H__ */

View File

@ -88,6 +88,7 @@ extern unsigned long bmips_tp1_irqs;
extern void bmips_ebase_setup(void);
extern asmlinkage void plat_wired_tlb_setup(void);
extern void bmips_cpu_setup(void);
static inline unsigned long bmips_read_zscm_reg(unsigned int offset)
{

View File

@ -144,4 +144,22 @@ static inline void plat_swiotlb_setup(void) {}
#endif /* CONFIG_SWIOTLB */
#ifdef CONFIG_USE_OF
/**
* plat_get_fdt() - Return a pointer to the platform's device tree blob
*
* This function provides a platform independent API to get a pointer to the
* flattened device tree blob. The interface between bootloader and kernel
* is not consistent across platforms so it is necessary to provide this
* API such that common startup code can locate the FDT.
*
* This is used by the KASLR code to get command line arguments and random
* seed from the device tree. Any platform wishing to use KASLR should
* provide this API and select SYS_SUPPORTS_RELOCATABLE.
*
* Return: Pointer to the flattened device tree blob.
*/
extern void *plat_get_fdt(void);
#endif /* CONFIG_USE_OF */
#endif /* _ASM_BOOTINFO_H */

View File

@ -51,7 +51,6 @@ extern void (*flush_cache_range)(struct vm_area_struct *vma,
unsigned long start, unsigned long end);
extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
extern void __flush_dcache_page(struct page *page);
extern void __flush_icache_page(struct vm_area_struct *vma, struct page *page);
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
static inline void flush_dcache_page(struct page *page)
@ -77,11 +76,6 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
static inline void flush_icache_page(struct vm_area_struct *vma,
struct page *page)
{
if (!cpu_has_ic_fills_f_dc && (vma->vm_flags & VM_EXEC) &&
Page_dcache_dirty(page)) {
__flush_icache_page(vma, page);
ClearPageDcacheDirty(page);
}
}
extern void (*flush_icache_range)(unsigned long start, unsigned long end);
@ -132,6 +126,7 @@ static inline void kunmap_noncoherent(void)
static inline void flush_kernel_dcache_page(struct page *page)
{
BUG_ON(cpu_has_dc_aliases && PageHighMem(page));
flush_dcache_page(page);
}
/*

View File

@ -21,6 +21,7 @@
#define Cache_I 0x00
#define Cache_D 0x01
#define Cache_T 0x02
#define Cache_V 0x02 /* Loongson-3 */
#define Cache_S 0x03
#define Index_Writeback_Inv 0x00
@ -107,4 +108,9 @@
*/
#define Hit_Invalidate_I_Loongson2 (Cache_I | 0x00)
/*
* Loongson3-specific cacheops
*/
#define Index_Writeback_Inv_V (Cache_V | Index_Writeback_Inv)
#endif /* __ASM_CACHEOPS_H */

View File

@ -1,27 +0,0 @@
/*
* based on arch/arm/include/asm/clkdev.h
*
* Copyright (C) 2008 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Helper for the clk API to assist looking up a struct clk.
*/
#ifndef __ASM_CLKDEV_H
#define __ASM_CLKDEV_H
#include <linux/slab.h>
#ifndef CONFIG_COMMON_CLK
#define __clk_get(clk) ({ 1; })
#define __clk_put(clk) do { } while (0)
#endif
static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
{
return kzalloc(size, GFP_KERNEL);
}
#endif

View File

@ -35,6 +35,9 @@
#ifndef cpu_has_htw
#define cpu_has_htw (cpu_data[0].options & MIPS_CPU_HTW)
#endif
#ifndef cpu_has_ldpte
#define cpu_has_ldpte (cpu_data[0].options & MIPS_CPU_LDPTE)
#endif
#ifndef cpu_has_rixiex
#define cpu_has_rixiex (cpu_data[0].options & MIPS_CPU_RIXIEX)
#endif
@ -117,6 +120,21 @@
#ifndef kernel_uses_llsc
#define kernel_uses_llsc cpu_has_llsc
#endif
#ifndef cpu_has_guestctl0ext
#define cpu_has_guestctl0ext (cpu_data[0].options & MIPS_CPU_GUESTCTL0EXT)
#endif
#ifndef cpu_has_guestctl1
#define cpu_has_guestctl1 (cpu_data[0].options & MIPS_CPU_GUESTCTL1)
#endif
#ifndef cpu_has_guestctl2
#define cpu_has_guestctl2 (cpu_data[0].options & MIPS_CPU_GUESTCTL2)
#endif
#ifndef cpu_has_guestid
#define cpu_has_guestid (cpu_data[0].options & MIPS_CPU_GUESTID)
#endif
#ifndef cpu_has_drg
#define cpu_has_drg (cpu_data[0].options & MIPS_CPU_DRG)
#endif
#ifndef cpu_has_mips16
#define cpu_has_mips16 (cpu_data[0].ases & MIPS_ASE_MIPS16)
#endif
@ -142,8 +160,14 @@
# endif
#endif
#ifndef cpu_has_lpa
#define cpu_has_lpa (cpu_data[0].options & MIPS_CPU_LPA)
#endif
#ifndef cpu_has_mvh
#define cpu_has_mvh (cpu_data[0].options & MIPS_CPU_MVH)
#endif
#ifndef cpu_has_xpa
#define cpu_has_xpa (cpu_data[0].options & MIPS_CPU_XPA)
#define cpu_has_xpa (cpu_has_lpa && cpu_has_mvh)
#endif
#ifndef cpu_has_vtag_icache
#define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
@ -307,10 +331,18 @@
#define cpu_has_dsp2 (cpu_data[0].ases & MIPS_ASE_DSP2P)
#endif
#ifndef cpu_has_dsp3
#define cpu_has_dsp3 (cpu_data[0].ases & MIPS_ASE_DSP3)
#endif
#ifndef cpu_has_mipsmt
#define cpu_has_mipsmt (cpu_data[0].ases & MIPS_ASE_MIPSMT)
#endif
#ifndef cpu_has_vp
#define cpu_has_vp (cpu_data[0].options & MIPS_CPU_VP)
#endif
#ifndef cpu_has_userlocal
#define cpu_has_userlocal (cpu_data[0].options & MIPS_CPU_ULRI)
#endif
@ -421,4 +453,107 @@
#define cpu_has_nan_2008 (cpu_data[0].options & MIPS_CPU_NAN_2008)
#endif
#ifndef cpu_has_ebase_wg
# define cpu_has_ebase_wg (cpu_data[0].options & MIPS_CPU_EBASE_WG)
#endif
#ifndef cpu_has_badinstr
# define cpu_has_badinstr (cpu_data[0].options & MIPS_CPU_BADINSTR)
#endif
#ifndef cpu_has_badinstrp
# define cpu_has_badinstrp (cpu_data[0].options & MIPS_CPU_BADINSTRP)
#endif
#ifndef cpu_has_contextconfig
# define cpu_has_contextconfig (cpu_data[0].options & MIPS_CPU_CTXTC)
#endif
#ifndef cpu_has_perf
# define cpu_has_perf (cpu_data[0].options & MIPS_CPU_PERF)
#endif
/*
* Guest capabilities
*/
#ifndef cpu_guest_has_conf1
#define cpu_guest_has_conf1 (cpu_data[0].guest.conf & (1 << 1))
#endif
#ifndef cpu_guest_has_conf2
#define cpu_guest_has_conf2 (cpu_data[0].guest.conf & (1 << 2))
#endif
#ifndef cpu_guest_has_conf3
#define cpu_guest_has_conf3 (cpu_data[0].guest.conf & (1 << 3))
#endif
#ifndef cpu_guest_has_conf4
#define cpu_guest_has_conf4 (cpu_data[0].guest.conf & (1 << 4))
#endif
#ifndef cpu_guest_has_conf5
#define cpu_guest_has_conf5 (cpu_data[0].guest.conf & (1 << 5))
#endif
#ifndef cpu_guest_has_conf6
#define cpu_guest_has_conf6 (cpu_data[0].guest.conf & (1 << 6))
#endif
#ifndef cpu_guest_has_conf7
#define cpu_guest_has_conf7 (cpu_data[0].guest.conf & (1 << 7))
#endif
#ifndef cpu_guest_has_fpu
#define cpu_guest_has_fpu (cpu_data[0].guest.options & MIPS_CPU_FPU)
#endif
#ifndef cpu_guest_has_watch
#define cpu_guest_has_watch (cpu_data[0].guest.options & MIPS_CPU_WATCH)
#endif
#ifndef cpu_guest_has_contextconfig
#define cpu_guest_has_contextconfig (cpu_data[0].guest.options & MIPS_CPU_CTXTC)
#endif
#ifndef cpu_guest_has_segments
#define cpu_guest_has_segments (cpu_data[0].guest.options & MIPS_CPU_SEGMENTS)
#endif
#ifndef cpu_guest_has_badinstr
#define cpu_guest_has_badinstr (cpu_data[0].guest.options & MIPS_CPU_BADINSTR)
#endif
#ifndef cpu_guest_has_badinstrp
#define cpu_guest_has_badinstrp (cpu_data[0].guest.options & MIPS_CPU_BADINSTRP)
#endif
#ifndef cpu_guest_has_htw
#define cpu_guest_has_htw (cpu_data[0].guest.options & MIPS_CPU_HTW)
#endif
#ifndef cpu_guest_has_msa
#define cpu_guest_has_msa (cpu_data[0].guest.ases & MIPS_ASE_MSA)
#endif
#ifndef cpu_guest_has_kscr
#define cpu_guest_has_kscr(n) (cpu_data[0].guest.kscratch_mask & (1u << (n)))
#endif
#ifndef cpu_guest_has_rw_llb
#define cpu_guest_has_rw_llb (cpu_has_mips_r6 || (cpu_data[0].guest.options & MIPS_CPU_RW_LLB))
#endif
#ifndef cpu_guest_has_perf
#define cpu_guest_has_perf (cpu_data[0].guest.options & MIPS_CPU_PERF)
#endif
#ifndef cpu_guest_has_maar
#define cpu_guest_has_maar (cpu_data[0].guest.options & MIPS_CPU_MAAR)
#endif
/*
* Guest dynamic capabilities
*/
#ifndef cpu_guest_has_dyn_fpu
#define cpu_guest_has_dyn_fpu (cpu_data[0].guest.options_dyn & MIPS_CPU_FPU)
#endif
#ifndef cpu_guest_has_dyn_watch
#define cpu_guest_has_dyn_watch (cpu_data[0].guest.options_dyn & MIPS_CPU_WATCH)
#endif
#ifndef cpu_guest_has_dyn_contextconfig
#define cpu_guest_has_dyn_contextconfig (cpu_data[0].guest.options_dyn & MIPS_CPU_CTXTC)
#endif
#ifndef cpu_guest_has_dyn_perf
#define cpu_guest_has_dyn_perf (cpu_data[0].guest.options_dyn & MIPS_CPU_PERF)
#endif
#ifndef cpu_guest_has_dyn_msa
#define cpu_guest_has_dyn_msa (cpu_data[0].guest.ases_dyn & MIPS_ASE_MSA)
#endif
#ifndef cpu_guest_has_dyn_maar
#define cpu_guest_has_dyn_maar (cpu_data[0].guest.options_dyn & MIPS_CPU_MAAR)
#endif
#endif /* __ASM_CPU_FEATURES_H */

View File

@ -28,6 +28,15 @@ struct cache_desc {
unsigned char flags; /* Flags describing cache properties */
};
struct guest_info {
unsigned long ases;
unsigned long ases_dyn;
unsigned long long options;
unsigned long long options_dyn;
u8 conf;
u8 kscratch_mask;
};
/*
* Flag definitions
*/
@ -40,6 +49,9 @@ struct cache_desc {
struct cpuinfo_mips {
unsigned long asid_cache;
#ifdef CONFIG_MIPS_ASID_BITS_VARIABLE
unsigned long asid_mask;
#endif
/*
* Capability and feature descriptor structure for MIPS CPU
@ -60,6 +72,7 @@ struct cpuinfo_mips {
int tlbsizeftlbways;
struct cache_desc icache; /* Primary I-cache */
struct cache_desc dcache; /* Primary D or combined I/D cache */
struct cache_desc vcache; /* Victim cache, between pcache and scache */
struct cache_desc scache; /* Secondary cache */
struct cache_desc tcache; /* Tertiary/split secondary cache */
int srsets; /* Shadow register sets */
@ -68,7 +81,7 @@ struct cpuinfo_mips {
#ifdef CONFIG_64BIT
int vmbits; /* Virtual memory size in bits */
#endif
#ifdef CONFIG_MIPS_MT_SMP
#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
/*
* There is not necessarily a 1:1 mapping of VPE num to CPU number
* in particular on multi-core systems.
@ -91,6 +104,11 @@ struct cpuinfo_mips {
* htw_start/htw_stop calls
*/
unsigned int htw_seq;
/* VZ & Guest features */
struct guest_info guest;
unsigned int gtoffset_mask;
unsigned int guestid_mask;
} __attribute__((aligned(SMP_CACHE_BYTES)));
extern struct cpuinfo_mips cpu_data[];
@ -125,10 +143,31 @@ struct proc_cpuinfo_notifier_args {
unsigned long n;
};
#ifdef CONFIG_MIPS_MT_SMP
#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
# define cpu_vpe_id(cpuinfo) ((cpuinfo)->vpe_id)
#else
# define cpu_vpe_id(cpuinfo) ({ (void)cpuinfo; 0; })
#endif
static inline unsigned long cpu_asid_inc(void)
{
return 1 << CONFIG_MIPS_ASID_SHIFT;
}
static inline unsigned long cpu_asid_mask(struct cpuinfo_mips *cpuinfo)
{
#ifdef CONFIG_MIPS_ASID_BITS_VARIABLE
return cpuinfo->asid_mask;
#endif
return ((1 << CONFIG_MIPS_ASID_BITS) - 1) << CONFIG_MIPS_ASID_SHIFT;
}
static inline void set_cpu_asid_mask(struct cpuinfo_mips *cpuinfo,
unsigned long asid_mask)
{
#ifdef CONFIG_MIPS_ASID_BITS_VARIABLE
cpuinfo->asid_mask = asid_mask;
#endif
}
#endif /* __ASM_CPU_INFO_H */

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