mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-13 20:33:15 +00:00
Main MIPS changes for v5.4:
- boot_mem_map is removed, providing a nice cleanup made possible by the recent removal of bootmem. - Some fixes to atomics, in general providing compiler barriers for smp_mb__{before,after}_atomic plus fixes specific to Loongson CPUs or MIPS32 systems using cmpxchg64(). - Conversion to the new generic VDSO infrastructure courtesy of Vincenzo Frascino. - Removal of undefined behavior in set_io_port_base(), fixing the behavior of some MIPS kernel configurations when built with recent clang versions. - Initial MIPS32 huge page support, functional on at least Ingenic SoCs. - pte_special() is now supported for some configurations, allowing among other things generic fast GUP to be used. - Miscellaneous fixes & cleanups. And platform specific changes: - Major improvements to Ingenic SoC support from Paul Cercueil, mostly enabled by the inclusion of the new TCU (timer-counter unit) drivers he's spent a very patient year or so working on. Plus some fixes for X1000 SoCs from Zhou Yanjie. - Netgear R6200 v1 systems are now supported by the bcm47xx platform. - DT updates for BMIPS, Lantiq & Microsemi Ocelot systems. -----BEGIN PGP SIGNATURE----- iIsEABYIADMWIQRgLjeFAZEXQzy86/s+p5+stXUA3QUCXYaqpRUccGF1bC5idXJ0 b25AbWlwcy5jb20ACgkQPqefrLV1AN2JUQD+PQGFIlq9bo/3vLyqsXJffm+DhwVQ 4WSCSeN5brPkO8EA/153sRJBlRtG+KK5p9f7WYKUuBfbcEawuc1uwmKuy7cG =lWlM -----END PGP SIGNATURE----- Merge tag 'mips_5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux Pull MIPS updates from Paul Burton: "Main MIPS changes: - boot_mem_map is removed, providing a nice cleanup made possible by the recent removal of bootmem. - Some fixes to atomics, in general providing compiler barriers for smp_mb__{before,after}_atomic plus fixes specific to Loongson CPUs or MIPS32 systems using cmpxchg64(). - Conversion to the new generic VDSO infrastructure courtesy of Vincenzo Frascino. - Removal of undefined behavior in set_io_port_base(), fixing the behavior of some MIPS kernel configurations when built with recent clang versions. - Initial MIPS32 huge page support, functional on at least Ingenic SoCs. - pte_special() is now supported for some configurations, allowing among other things generic fast GUP to be used. - Miscellaneous fixes & cleanups. And platform specific changes: - Major improvements to Ingenic SoC support from Paul Cercueil, mostly enabled by the inclusion of the new TCU (timer-counter unit) drivers he's spent a very patient year or so working on. Plus some fixes for X1000 SoCs from Zhou Yanjie. - Netgear R6200 v1 systems are now supported by the bcm47xx platform. - DT updates for BMIPS, Lantiq & Microsemi Ocelot systems" * tag 'mips_5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: (89 commits) MIPS: Detect bad _PFN_SHIFT values MIPS: Disable pte_special() for MIPS32 with RiXi MIPS: ralink: deactivate PCI support for SOC_MT7621 mips: compat: vdso: Use legacy syscalls as fallback MIPS: Drop Loongson _CACHE_* definitions MIPS: tlbex: Remove cpu_has_local_ebase MIPS: tlbex: Simplify r3k check MIPS: Select R3k-style TLB in Kconfig MIPS: PCI: refactor ioc3 special handling mips: remove ioremap_cachable mips/atomic: Fix smp_mb__{before,after}_atomic() mips/atomic: Fix loongson_llsc_mb() wreckage mips/atomic: Fix cmpxchg64 barriers MIPS: Octeon: remove duplicated include from dma-octeon.c firmware: bcm47xx_nvram: Allow COMPILE_TEST firmware: bcm47xx_nvram: Correct size_t printf format MIPS: Treat Loongson Extensions as ASEs MIPS: Remove dev_err() usage after platform_get_irq() MIPS: dts: mscc: describe the PTP ready interrupt MIPS: dts: mscc: describe the PTP register range ...
This commit is contained in:
commit
5c6bd5de3c
@ -1,22 +0,0 @@
|
||||
Ingenic JZ47xx PWM Controller
|
||||
=============================
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "ingenic,jz4740-pwm"
|
||||
- #pwm-cells: Should be 3. See pwm.txt in this directory for a description
|
||||
of the cells format.
|
||||
- clocks : phandle to the external clock.
|
||||
- clock-names : Should be "ext".
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
pwm: pwm@10002000 {
|
||||
compatible = "ingenic,jz4740-pwm";
|
||||
reg = <0x10002000 0x1000>;
|
||||
|
||||
#pwm-cells = <3>;
|
||||
|
||||
clocks = <&ext>;
|
||||
clock-names = "ext";
|
||||
};
|
137
Documentation/devicetree/bindings/timer/ingenic,tcu.txt
Normal file
137
Documentation/devicetree/bindings/timer/ingenic,tcu.txt
Normal file
@ -0,0 +1,137 @@
|
||||
Ingenic JZ47xx SoCs Timer/Counter Unit devicetree bindings
|
||||
==========================================================
|
||||
|
||||
For a description of the TCU hardware and drivers, have a look at
|
||||
Documentation/mips/ingenic-tcu.txt.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: Must be one of:
|
||||
* ingenic,jz4740-tcu
|
||||
* ingenic,jz4725b-tcu
|
||||
* ingenic,jz4770-tcu
|
||||
followed by "simple-mfd".
|
||||
- reg: Should be the offset/length value corresponding to the TCU registers
|
||||
- clocks: List of phandle & clock specifiers for clocks external to the TCU.
|
||||
The "pclk", "rtc" and "ext" clocks should be provided. The "tcu" clock
|
||||
should be provided if the SoC has it.
|
||||
- clock-names: List of name strings for the external clocks.
|
||||
- #clock-cells: Should be <1>;
|
||||
Clock consumers specify this argument to identify a clock. The valid values
|
||||
may be found in <dt-bindings/clock/ingenic,tcu.h>.
|
||||
- interrupt-controller : Identifies the node as an interrupt controller
|
||||
- #interrupt-cells : Specifies the number of cells needed to encode an
|
||||
interrupt source. The value should be 1.
|
||||
- interrupts : Specifies the interrupt the controller is connected to.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- ingenic,pwm-channels-mask: Bitmask of TCU channels reserved for PWM use.
|
||||
Default value is 0xfc.
|
||||
|
||||
|
||||
Children nodes
|
||||
==========================================================
|
||||
|
||||
|
||||
PWM node:
|
||||
---------
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: Must be one of:
|
||||
* ingenic,jz4740-pwm
|
||||
* ingenic,jz4725b-pwm
|
||||
- #pwm-cells: Should be 3. See ../pwm/pwm.txt for a description of the cell
|
||||
format.
|
||||
- clocks: List of phandle & clock specifiers for the TCU clocks.
|
||||
- clock-names: List of name strings for the TCU clocks.
|
||||
|
||||
|
||||
Watchdog node:
|
||||
--------------
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: Must be "ingenic,jz4740-watchdog"
|
||||
- clocks: phandle to the WDT clock
|
||||
- clock-names: should be "wdt"
|
||||
|
||||
|
||||
OS Timer node:
|
||||
---------
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: Must be one of:
|
||||
* ingenic,jz4725b-ost
|
||||
* ingenic,jz4770-ost
|
||||
- clocks: phandle to the OST clock
|
||||
- clock-names: should be "ost"
|
||||
- interrupts : Specifies the interrupt the OST is connected to.
|
||||
|
||||
|
||||
Example
|
||||
==========================================================
|
||||
|
||||
#include <dt-bindings/clock/jz4770-cgu.h>
|
||||
#include <dt-bindings/clock/ingenic,tcu.h>
|
||||
|
||||
/ {
|
||||
tcu: timer@10002000 {
|
||||
compatible = "ingenic,jz4770-tcu", "simple-mfd";
|
||||
reg = <0x10002000 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0x10002000 0x1000>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
|
||||
clocks = <&cgu JZ4770_CLK_RTC
|
||||
&cgu JZ4770_CLK_EXT
|
||||
&cgu JZ4770_CLK_PCLK>;
|
||||
clock-names = "rtc", "ext", "pclk";
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <27 26 25>;
|
||||
|
||||
watchdog: watchdog@0 {
|
||||
compatible = "ingenic,jz4740-watchdog";
|
||||
reg = <0x0 0xc>;
|
||||
|
||||
clocks = <&tcu TCU_CLK_WDT>;
|
||||
clock-names = "wdt";
|
||||
};
|
||||
|
||||
pwm: pwm@40 {
|
||||
compatible = "ingenic,jz4740-pwm";
|
||||
reg = <0x40 0x80>;
|
||||
|
||||
#pwm-cells = <3>;
|
||||
|
||||
clocks = <&tcu TCU_CLK_TIMER0
|
||||
&tcu TCU_CLK_TIMER1
|
||||
&tcu TCU_CLK_TIMER2
|
||||
&tcu TCU_CLK_TIMER3
|
||||
&tcu TCU_CLK_TIMER4
|
||||
&tcu TCU_CLK_TIMER5
|
||||
&tcu TCU_CLK_TIMER6
|
||||
&tcu TCU_CLK_TIMER7>;
|
||||
clock-names = "timer0", "timer1", "timer2", "timer3",
|
||||
"timer4", "timer5", "timer6", "timer7";
|
||||
};
|
||||
|
||||
ost: timer@e0 {
|
||||
compatible = "ingenic,jz4770-ost";
|
||||
reg = <0xe0 0x20>;
|
||||
|
||||
clocks = <&tcu TCU_CLK_OST>;
|
||||
clock-names = "ost";
|
||||
|
||||
interrupts = <15>;
|
||||
};
|
||||
};
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
Ingenic Watchdog Timer (WDT) Controller for JZ4740 & JZ4780
|
||||
|
||||
Required properties:
|
||||
compatible: "ingenic,jz4740-watchdog" or "ingenic,jz4780-watchdog"
|
||||
reg: Register address and length for watchdog registers
|
||||
clocks: phandle to the RTC clock
|
||||
clock-names: should be "rtc"
|
||||
|
||||
Example:
|
||||
|
||||
watchdog: jz4740-watchdog@10002000 {
|
||||
compatible = "ingenic,jz4740-watchdog";
|
||||
reg = <0x10002000 0x10>;
|
||||
|
||||
clocks = <&cgu JZ4740_CLK_RTC>;
|
||||
clock-names = "rtc";
|
||||
};
|
@ -144,16 +144,15 @@ implementation.
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
sh/index
|
||||
arm/index
|
||||
arm64/index
|
||||
ia64/index
|
||||
m68k/index
|
||||
powerpc/index
|
||||
mips/index
|
||||
nios2/nios2
|
||||
openrisc/index
|
||||
parisc/index
|
||||
powerpc/index
|
||||
riscv/index
|
||||
s390/index
|
||||
sh/index
|
||||
|
@ -1,11 +1,14 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=================
|
||||
MIPS architecture
|
||||
=================
|
||||
===========================
|
||||
MIPS-specific Documentation
|
||||
===========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:numbered:
|
||||
|
||||
ingenic-tcu
|
||||
|
||||
au1xxx_ide
|
||||
|
||||
|
71
Documentation/mips/ingenic-tcu.rst
Normal file
71
Documentation/mips/ingenic-tcu.rst
Normal file
@ -0,0 +1,71 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
===============================================
|
||||
Ingenic JZ47xx SoCs Timer/Counter Unit hardware
|
||||
===============================================
|
||||
|
||||
The Timer/Counter Unit (TCU) in Ingenic JZ47xx SoCs is a multi-function
|
||||
hardware block. It features up to to eight channels, that can be used as
|
||||
counters, timers, or PWM.
|
||||
|
||||
- JZ4725B, JZ4750, JZ4755 only have six TCU channels. The other SoCs all
|
||||
have eight channels.
|
||||
|
||||
- JZ4725B introduced a separate channel, called Operating System Timer
|
||||
(OST). It is a 32-bit programmable timer. On JZ4760B and above, it is
|
||||
64-bit.
|
||||
|
||||
- Each one of the TCU channels has its own clock, which can be reparented to three
|
||||
different clocks (pclk, ext, rtc), gated, and reclocked, through their TCSR register.
|
||||
|
||||
- The watchdog and OST hardware blocks also feature a TCSR register with the same
|
||||
format in their register space.
|
||||
- The TCU registers used to gate/ungate can also gate/ungate the watchdog and
|
||||
OST clocks.
|
||||
|
||||
- Each TCU channel works in one of two modes:
|
||||
|
||||
- mode TCU1: channels cannot work in sleep mode, but are easier to
|
||||
operate.
|
||||
- mode TCU2: channels can work in sleep mode, but the operation is a bit
|
||||
more complicated than with TCU1 channels.
|
||||
|
||||
- The mode of each TCU channel depends on the SoC used:
|
||||
|
||||
- On the oldest SoCs (up to JZ4740), all of the eight channels operate in
|
||||
TCU1 mode.
|
||||
- On JZ4725B, channel 5 operates as TCU2, the others operate as TCU1.
|
||||
- On newest SoCs (JZ4750 and above), channels 1-2 operate as TCU2, the
|
||||
others operate as TCU1.
|
||||
|
||||
- Each channel can generate an interrupt. Some channels share an interrupt
|
||||
line, some don't, and this changes between SoC versions:
|
||||
|
||||
- on older SoCs (JZ4740 and below), channel 0 and channel 1 have their
|
||||
own interrupt line; channels 2-7 share the last interrupt line.
|
||||
- On JZ4725B, channel 0 has its own interrupt; channels 1-5 share one
|
||||
interrupt line; the OST uses the last interrupt line.
|
||||
- on newer SoCs (JZ4750 and above), channel 5 has its own interrupt;
|
||||
channels 0-4 and (if eight channels) 6-7 all share one interrupt line;
|
||||
the OST uses the last interrupt line.
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
The functionalities of the TCU hardware are spread across multiple drivers:
|
||||
|
||||
=========== =====
|
||||
clocks drivers/clk/ingenic/tcu.c
|
||||
interrupts drivers/irqchip/irq-ingenic-tcu.c
|
||||
timers drivers/clocksource/ingenic-timer.c
|
||||
OST drivers/clocksource/ingenic-ost.c
|
||||
PWM drivers/pwm/pwm-jz4740.c
|
||||
watchdog drivers/watchdog/jz4740_wdt.c
|
||||
=========== =====
|
||||
|
||||
Because various functionalities of the TCU that belong to different drivers
|
||||
and frameworks can be controlled from the same registers, all of these
|
||||
drivers access their registers through the same regmap.
|
||||
|
||||
For more information regarding the devicetree bindings of the TCU drivers,
|
||||
have a look at Documentation/devicetree/bindings/mfd/ingenic,tcu.txt.
|
@ -22,6 +22,7 @@ config MIPS
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_CMOS_UPDATE
|
||||
select GENERIC_CPU_AUTOPROBE
|
||||
select GENERIC_GETTIMEOFDAY
|
||||
select GENERIC_IOMAP
|
||||
select GENERIC_IRQ_PROBE
|
||||
select GENERIC_IRQ_SHOW
|
||||
@ -43,7 +44,7 @@ config MIPS
|
||||
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT
|
||||
select HAVE_ARCH_SECCOMP_FILTER
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
|
||||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES
|
||||
select HAVE_ASM_MODVERSIONS
|
||||
select HAVE_EBPF_JIT if (!CPU_MICROMIPS)
|
||||
select HAVE_CONTEXT_TRACKING
|
||||
@ -75,6 +76,7 @@ config MIPS
|
||||
select HAVE_STACKPROTECTOR
|
||||
select HAVE_SYSCALL_TRACEPOINTS
|
||||
select HAVE_VIRT_CPU_ACCOUNTING_GEN if 64BIT || !SMP
|
||||
select HAVE_GENERIC_VDSO
|
||||
select IRQ_FORCED_THREADING
|
||||
select ISA if EISA
|
||||
select MODULES_USE_ELF_RELA if MODULES && 64BIT
|
||||
@ -83,6 +85,7 @@ config MIPS
|
||||
select RTC_LIB
|
||||
select SYSCTL_EXCEPTION_TRACE
|
||||
select VIRT_TO_BUS
|
||||
select ARCH_HAS_PTE_SPECIAL if !(32BIT && CPU_HAS_RIXI)
|
||||
|
||||
menu "Machine selection"
|
||||
|
||||
@ -385,6 +388,7 @@ config MACH_INGENIC
|
||||
select SYS_SUPPORTS_32BIT_KERNEL
|
||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||
select SYS_SUPPORTS_ZBOOT_UART16550
|
||||
select CPU_SUPPORTS_HUGEPAGES
|
||||
select DMA_NONCOHERENT
|
||||
select IRQ_MIPS_CPU
|
||||
select PINCTRL
|
||||
@ -1231,7 +1235,7 @@ config SYS_SUPPORTS_LITTLE_ENDIAN
|
||||
|
||||
config SYS_SUPPORTS_HUGETLBFS
|
||||
bool
|
||||
depends on CPU_SUPPORTS_HUGEPAGES && 64BIT
|
||||
depends on CPU_SUPPORTS_HUGEPAGES
|
||||
default y
|
||||
|
||||
config MIPS_HUGE_TLB_SUPPORT
|
||||
@ -1579,6 +1583,7 @@ config CPU_R3000
|
||||
depends on SYS_HAS_CPU_R3000
|
||||
select CPU_HAS_WB
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_R3K_TLB
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
help
|
||||
@ -1594,6 +1599,7 @@ config CPU_TX39XX
|
||||
depends on SYS_HAS_CPU_TX39XX
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_R3K_TLB
|
||||
|
||||
config CPU_VR41XX
|
||||
bool "R41xx"
|
||||
@ -1607,15 +1613,6 @@ config CPU_VR41XX
|
||||
kernel built with this option will not run on any other type of
|
||||
processor or vice versa.
|
||||
|
||||
config CPU_R4300
|
||||
bool "R4300"
|
||||
depends on SYS_HAS_CPU_R4300
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
help
|
||||
MIPS Technologies R4300-series processors.
|
||||
|
||||
config CPU_R4X00
|
||||
bool "R4x00"
|
||||
depends on SYS_HAS_CPU_R4X00
|
||||
@ -1646,14 +1643,6 @@ config CPU_R5000
|
||||
help
|
||||
MIPS Technologies R5000-series processors other than the Nevada.
|
||||
|
||||
config CPU_R5432
|
||||
bool "R5432"
|
||||
depends on SYS_HAS_CPU_R5432
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HUGEPAGES
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
|
||||
config CPU_R5500
|
||||
bool "R5500"
|
||||
depends on SYS_HAS_CPU_R5500
|
||||
@ -1675,16 +1664,6 @@ config CPU_NEVADA
|
||||
help
|
||||
QED / PMC-Sierra RM52xx-series ("Nevada") processors.
|
||||
|
||||
config CPU_R8000
|
||||
bool "R8000"
|
||||
depends on SYS_HAS_CPU_R8000
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
help
|
||||
MIPS Technologies R8000 processors. Note these processors are
|
||||
uncommon and the support for them is incomplete.
|
||||
|
||||
config CPU_R10000
|
||||
bool "R10000"
|
||||
depends on SYS_HAS_CPU_R10000
|
||||
@ -1977,9 +1956,6 @@ config SYS_HAS_CPU_TX39XX
|
||||
config SYS_HAS_CPU_VR41XX
|
||||
bool
|
||||
|
||||
config SYS_HAS_CPU_R4300
|
||||
bool
|
||||
|
||||
config SYS_HAS_CPU_R4X00
|
||||
bool
|
||||
|
||||
@ -1989,18 +1965,12 @@ config SYS_HAS_CPU_TX49XX
|
||||
config SYS_HAS_CPU_R5000
|
||||
bool
|
||||
|
||||
config SYS_HAS_CPU_R5432
|
||||
bool
|
||||
|
||||
config SYS_HAS_CPU_R5500
|
||||
bool
|
||||
|
||||
config SYS_HAS_CPU_NEVADA
|
||||
bool
|
||||
|
||||
config SYS_HAS_CPU_R8000
|
||||
bool
|
||||
|
||||
config SYS_HAS_CPU_R10000
|
||||
bool
|
||||
select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT
|
||||
@ -2118,6 +2088,7 @@ config CPU_SUPPORTS_ADDRWINCFG
|
||||
bool
|
||||
config CPU_SUPPORTS_HUGEPAGES
|
||||
bool
|
||||
depends on !(32BIT && (ARCH_PHYS_ADDR_T_64BIT || EVA))
|
||||
config CPU_SUPPORTS_UNCACHED_ACCELERATED
|
||||
bool
|
||||
config MIPS_PGD_C0_CONTEXT
|
||||
@ -2200,13 +2171,13 @@ config PAGE_SIZE_4KB
|
||||
|
||||
config PAGE_SIZE_8KB
|
||||
bool "8kB"
|
||||
depends on CPU_R8000 || CPU_CAVIUM_OCTEON
|
||||
depends on 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
|
||||
only on R8000 and cnMIPS processors. Note that you will need a
|
||||
suitable Linux distribution to support this.
|
||||
only on cnMIPS processors. Note that you will need a suitable Linux
|
||||
distribution to support this.
|
||||
|
||||
config PAGE_SIZE_16KB
|
||||
bool "16kB"
|
||||
@ -2297,7 +2268,7 @@ config CPU_HAS_PREFETCH
|
||||
|
||||
config CPU_GENERIC_DUMP_TLB
|
||||
bool
|
||||
default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX)
|
||||
default y if !(CPU_R3000 || CPU_TX39XX)
|
||||
|
||||
config MIPS_FP_SUPPORT
|
||||
bool "Floating Point support" if EXPERT
|
||||
@ -2319,6 +2290,9 @@ config CPU_R2300_FPU
|
||||
depends on MIPS_FP_SUPPORT
|
||||
default y if CPU_R3000 || CPU_TX39XX
|
||||
|
||||
config CPU_R3K_TLB
|
||||
bool
|
||||
|
||||
config CPU_R4K_FPU
|
||||
bool
|
||||
depends on MIPS_FP_SUPPORT
|
||||
@ -2326,7 +2300,7 @@ config CPU_R4K_FPU
|
||||
|
||||
config CPU_R4K_CACHE_TLB
|
||||
bool
|
||||
default y if !(CPU_R3000 || CPU_R8000 || CPU_SB1 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
|
||||
default y if !(CPU_R3K_TLB || CPU_SB1 || CPU_CAVIUM_OCTEON)
|
||||
|
||||
config MIPS_MT_SMP
|
||||
bool "MIPS MT SMP support (1 TC on each available VPE)"
|
||||
@ -2583,7 +2557,6 @@ config CPU_R4400_WORKAROUNDS
|
||||
config MIPS_ASID_SHIFT
|
||||
int
|
||||
default 6 if CPU_R3000 || CPU_TX39XX
|
||||
default 4 if CPU_R8000
|
||||
default 0
|
||||
|
||||
config MIPS_ASID_BITS
|
||||
@ -3077,10 +3050,6 @@ config STACKTRACE_SUPPORT
|
||||
bool
|
||||
default y
|
||||
|
||||
config HAVE_LATENCYTOP_SUPPORT
|
||||
bool
|
||||
default y
|
||||
|
||||
config PGTABLE_LEVELS
|
||||
int
|
||||
default 4 if PAGE_SIZE_4KB && MIPS_VA_BITS_48
|
||||
|
@ -163,7 +163,6 @@ cflags-y += -fno-stack-check
|
||||
#
|
||||
cflags-$(CONFIG_CPU_R3000) += -march=r3000
|
||||
cflags-$(CONFIG_CPU_TX39XX) += -march=r3900
|
||||
cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap
|
||||
cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap
|
||||
cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap
|
||||
cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap
|
||||
@ -174,8 +173,6 @@ cflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,--trap
|
||||
cflags-$(CONFIG_CPU_MIPS64_R2) += -march=mips64r2 -Wa,--trap
|
||||
cflags-$(CONFIG_CPU_MIPS64_R6) += -march=mips64r6 -Wa,--trap
|
||||
cflags-$(CONFIG_CPU_R5000) += -march=r5000 -Wa,--trap
|
||||
cflags-$(CONFIG_CPU_R5432) += $(call cc-option,-march=r5400,-march=r5000) \
|
||||
-Wa,--trap
|
||||
cflags-$(CONFIG_CPU_R5500) += $(call cc-option,-march=r5500,-march=r5000) \
|
||||
-Wa,--trap
|
||||
cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \
|
||||
@ -186,7 +183,6 @@ cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1,-march=r5000) \
|
||||
-Wa,--trap
|
||||
cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mdmx)
|
||||
cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mips3d)
|
||||
cflags-$(CONFIG_CPU_R8000) += -march=r8000 -Wa,--trap
|
||||
cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \
|
||||
-Wa,--trap
|
||||
cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += $(call cc-option,-march=octeon) -Wa,--trap
|
||||
|
@ -160,6 +160,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_board_id[] __initconst = {
|
||||
{{BCM47XX_BOARD_LUXUL_XVW_P30_V1, "Luxul XVW-P30 V1"}, "luxul_xvwp30_v1"},
|
||||
{{BCM47XX_BOARD_LUXUL_XWR_600_V1, "Luxul XWR-600 V1"}, "luxul_xwr600_v1"},
|
||||
{{BCM47XX_BOARD_LUXUL_XWR_1750_V1, "Luxul XWR-1750 V1"}, "luxul_xwr1750_v1"},
|
||||
{{BCM47XX_BOARD_NETGEAR_R6200_V1, "Netgear R6200 V1"}, "U12H192T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WGR614V8, "Netgear WGR614 V8"}, "U12H072T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WGR614V9, "Netgear WGR614 V9"}, "U12H094T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WGR614_V10, "Netgear WGR614 V10"}, "U12H139T01_NETGEAR"},
|
||||
|
@ -384,6 +384,13 @@ bcm47xx_buttons_motorola_wr850gv2v3[] __initconst = {
|
||||
|
||||
/* Netgear */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_netgear_r6200_v1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(2, KEY_RFKILL),
|
||||
BCM47XX_GPIO_KEY(3, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_netgear_wndr3400v1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_RESTART),
|
||||
@ -664,6 +671,9 @@ int __init bcm47xx_buttons_register(void)
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_wr850gv2v3);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_NETGEAR_R6200_V1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_r6200_v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_NETGEAR_WNDR3400V1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3400v1);
|
||||
break;
|
||||
|
@ -51,16 +51,22 @@
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
periph_cntl: syscon@fff8c000 {
|
||||
clkctl: clock-controller@fff8c004 {
|
||||
compatible = "brcm,bcm3368-clocks";
|
||||
reg = <0xfff8c004 0x4>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
periph_cntl: syscon@fff8c008 {
|
||||
compatible = "syscon";
|
||||
reg = <0xfff8c000 0xc>;
|
||||
reg = <0xfff8c000 0x4>;
|
||||
native-endian;
|
||||
};
|
||||
|
||||
reboot: syscon-reboot@fff8c008 {
|
||||
compatible = "syscon-reboot";
|
||||
regmap = <&periph_cntl>;
|
||||
offset = <0x8>;
|
||||
offset = <0x0>;
|
||||
mask = <0x1>;
|
||||
};
|
||||
|
||||
|
@ -51,16 +51,22 @@
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
periph_cntl: syscon@10000000 {
|
||||
clkctl: clock-controller@10000004 {
|
||||
compatible = "brcm,bcm63268-clocks";
|
||||
reg = <0x10000004 0x4>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
periph_cntl: syscon@10000008 {
|
||||
compatible = "syscon";
|
||||
reg = <0x10000000 0x14>;
|
||||
reg = <0x10000000 0xc>;
|
||||
native-endian;
|
||||
};
|
||||
|
||||
reboot: syscon-reboot@10000008 {
|
||||
compatible = "syscon-reboot";
|
||||
regmap = <&periph_cntl>;
|
||||
offset = <0x8>;
|
||||
offset = <0x0>;
|
||||
mask = <0x1>;
|
||||
};
|
||||
|
||||
|
@ -51,6 +51,12 @@
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
clkctl: clock-controller@10000004 {
|
||||
compatible = "brcm,bcm6328-clocks";
|
||||
reg = <0x10000004 0x4>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
periph_intc: interrupt-controller@10000020 {
|
||||
compatible = "brcm,bcm6345-l1-intc";
|
||||
reg = <0x10000020 0x10>,
|
||||
|
@ -51,16 +51,22 @@
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
periph_cntl: syscon@fffe0000 {
|
||||
clkctl: clock-controller@fffe0004 {
|
||||
compatible = "brcm,bcm6358-clocks";
|
||||
reg = <0xfffe0004 0x4>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
periph_cntl: syscon@fffe0008 {
|
||||
compatible = "syscon";
|
||||
reg = <0xfffe0000 0xc>;
|
||||
reg = <0xfffe0000 0x4>;
|
||||
native-endian;
|
||||
};
|
||||
|
||||
reboot: syscon-reboot@fffe0008 {
|
||||
compatible = "syscon-reboot";
|
||||
regmap = <&periph_cntl>;
|
||||
offset = <0x8>;
|
||||
offset = <0x0>;
|
||||
mask = <0x1>;
|
||||
};
|
||||
|
||||
|
@ -51,16 +51,22 @@
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
periph_cntl: syscon@10000000 {
|
||||
clkctl: clock-controller@10000004 {
|
||||
compatible = "brcm,bcm6362-clocks";
|
||||
reg = <0x10000004 0x4>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
periph_cntl: syscon@10000008 {
|
||||
compatible = "syscon";
|
||||
reg = <0x10000000 0x14>;
|
||||
reg = <0x10000000 0xc>;
|
||||
native-endian;
|
||||
};
|
||||
|
||||
reboot: syscon-reboot@10000008 {
|
||||
compatible = "syscon-reboot";
|
||||
regmap = <&periph_cntl>;
|
||||
offset = <0x8>;
|
||||
offset = <0x0>;
|
||||
mask = <0x1>;
|
||||
};
|
||||
|
||||
|
@ -51,16 +51,22 @@
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
periph_cntl: syscon@10000000 {
|
||||
clkctl: clock-controller@10000004 {
|
||||
compatible = "brcm,bcm6368-clocks";
|
||||
reg = <0x10000004 0x4>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
periph_cntl: syscon@100000008 {
|
||||
compatible = "syscon";
|
||||
reg = <0x10000000 0x14>;
|
||||
reg = <0x10000000 0xc>;
|
||||
native-endian;
|
||||
};
|
||||
|
||||
reboot: syscon-reboot@10000008 {
|
||||
compatible = "syscon-reboot";
|
||||
regmap = <&periph_cntl>;
|
||||
offset = <0x8>;
|
||||
offset = <0x0>;
|
||||
mask = <0x1>;
|
||||
};
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "jz4780.dtsi"
|
||||
#include <dt-bindings/clock/ingenic,tcu.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
/ {
|
||||
@ -238,3 +239,9 @@
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
&tcu {
|
||||
/* 3 MHz for the system timer and clocksource */
|
||||
assigned-clocks = <&tcu TCU_CLK_TIMER0>, <&tcu TCU_CLK_TIMER1>;
|
||||
assigned-clock-rates = <3000000>, <3000000>;
|
||||
};
|
||||
|
@ -2,6 +2,7 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "jz4770.dtsi"
|
||||
#include <dt-bindings/clock/ingenic,tcu.h>
|
||||
|
||||
/ {
|
||||
compatible = "gcw,zero", "ingenic,jz4770";
|
||||
@ -60,3 +61,12 @@
|
||||
/* The WiFi module is connected to the UHC. */
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&tcu {
|
||||
/* 750 kHz for the system timer and clocksource */
|
||||
assigned-clocks = <&tcu TCU_CLK_TIMER0>, <&tcu TCU_CLK_TIMER2>;
|
||||
assigned-clock-rates = <750000>, <750000>;
|
||||
|
||||
/* PWM1 is in use, so reserve channel #2 for the clocksource */
|
||||
ingenic,pwm-channels-mask = <0xfa>;
|
||||
};
|
||||
|
@ -53,6 +53,28 @@
|
||||
clock-names = "rtc";
|
||||
};
|
||||
|
||||
tcu: timer@10002000 {
|
||||
compatible = "ingenic,jz4740-tcu", "simple-mfd";
|
||||
reg = <0x10002000 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0x10002000 0x1000>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
|
||||
clocks = <&cgu JZ4740_CLK_RTC
|
||||
&cgu JZ4740_CLK_EXT
|
||||
&cgu JZ4740_CLK_PCLK
|
||||
&cgu JZ4740_CLK_TCU>;
|
||||
clock-names = "rtc", "ext", "pclk", "tcu";
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <23 22 21>;
|
||||
};
|
||||
|
||||
rtc_dev: rtc@10003000 {
|
||||
compatible = "ingenic,jz4740-rtc";
|
||||
reg = <0x10003000 0x40>;
|
||||
@ -132,6 +154,53 @@
|
||||
};
|
||||
};
|
||||
|
||||
aic: audio-controller@10020000 {
|
||||
compatible = "ingenic,jz4740-i2s";
|
||||
reg = <0x10020000 0x38>;
|
||||
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <18>;
|
||||
|
||||
clocks = <&cgu JZ4740_CLK_AIC>,
|
||||
<&cgu JZ4740_CLK_I2S>,
|
||||
<&cgu JZ4740_CLK_EXT>,
|
||||
<&cgu JZ4740_CLK_PLL_HALF>;
|
||||
clock-names = "aic", "i2s", "ext", "pll half";
|
||||
|
||||
dmas = <&dmac 25 0xffffffff>, <&dmac 24 0xffffffff>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
||||
|
||||
codec: audio-codec@100200a4 {
|
||||
compatible = "ingenic,jz4740-codec";
|
||||
reg = <0x10020080 0x8>;
|
||||
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&cgu JZ4740_CLK_AIC>;
|
||||
clock-names = "aic";
|
||||
};
|
||||
|
||||
mmc: mmc@10021000 {
|
||||
compatible = "ingenic,jz4740-mmc";
|
||||
reg = <0x10021000 0x1000>;
|
||||
|
||||
clocks = <&cgu JZ4740_CLK_MMC>;
|
||||
clock-names = "mmc";
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <14>;
|
||||
|
||||
dmas = <&dmac 27 0xffffffff>, <&dmac 26 0xffffffff>;
|
||||
dma-names = "rx", "tx";
|
||||
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
cap-sdio-irq;
|
||||
};
|
||||
|
||||
uart0: serial@10030000 {
|
||||
compatible = "ingenic,jz4740-uart";
|
||||
reg = <0x10030000 0x100>;
|
||||
@ -154,6 +223,38 @@
|
||||
clock-names = "baud", "module";
|
||||
};
|
||||
|
||||
adc: adc@10070000 {
|
||||
compatible = "ingenic,jz4740-adc";
|
||||
reg = <0x10070000 0x30>;
|
||||
#io-channel-cells = <1>;
|
||||
|
||||
clocks = <&cgu JZ4740_CLK_ADC>;
|
||||
clock-names = "adc";
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <12>;
|
||||
};
|
||||
|
||||
nemc: memory-controller@13010000 {
|
||||
compatible = "ingenic,jz4740-nemc";
|
||||
reg = <0x13010000 0x54>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
ranges = <1 0 0x18000000 0x4000000
|
||||
2 0 0x14000000 0x4000000
|
||||
3 0 0x0c000000 0x4000000
|
||||
4 0 0x08000000 0x4000000>;
|
||||
|
||||
clocks = <&cgu JZ4740_CLK_MCLK>;
|
||||
};
|
||||
|
||||
ecc: ecc-controller@13010100 {
|
||||
compatible = "ingenic,jz4740-ecc";
|
||||
reg = <0x13010100 0x2C>;
|
||||
|
||||
clocks = <&cgu JZ4740_CLK_MCLK>;
|
||||
};
|
||||
|
||||
dmac: dma-controller@13020000 {
|
||||
compatible = "ingenic,jz4740-dma";
|
||||
reg = <0x13020000 0xbc
|
||||
@ -164,9 +265,6 @@
|
||||
interrupts = <20>;
|
||||
|
||||
clocks = <&cgu JZ4740_CLK_DMA>;
|
||||
|
||||
/* Disable dmac until we have something that uses it */
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uhc: uhc@13030000 {
|
||||
@ -182,4 +280,27 @@
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
udc: usb@13040000 {
|
||||
compatible = "ingenic,jz4740-musb";
|
||||
reg = <0x13040000 0x10000>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <24>;
|
||||
interrupt-names = "mc";
|
||||
|
||||
clocks = <&cgu JZ4740_CLK_UDC>;
|
||||
clock-names = "udc";
|
||||
};
|
||||
|
||||
lcd: lcd-controller@13050000 {
|
||||
compatible = "ingenic,jz4740-lcd";
|
||||
reg = <0x13050000 0x1000>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <30>;
|
||||
|
||||
clocks = <&cgu JZ4740_CLK_LCD_PCLK>, <&cgu JZ4740_CLK_LCD>;
|
||||
clock-names = "lcd_pclk", "lcd";
|
||||
};
|
||||
};
|
||||
|
@ -46,6 +46,27 @@
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
tcu: timer@10002000 {
|
||||
compatible = "ingenic,jz4770-tcu", "simple-mfd";
|
||||
reg = <0x10002000 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0x10002000 0x1000>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
|
||||
clocks = <&cgu JZ4770_CLK_RTC
|
||||
&cgu JZ4770_CLK_EXT
|
||||
&cgu JZ4770_CLK_PCLK>;
|
||||
clock-names = "rtc", "ext", "pclk";
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <27 26 25>;
|
||||
};
|
||||
|
||||
pinctrl: pin-controller@10010000 {
|
||||
compatible = "ingenic,jz4770-pinctrl";
|
||||
reg = <0x10010000 0x600>;
|
||||
|
@ -46,6 +46,29 @@
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
tcu: timer@10002000 {
|
||||
compatible = "ingenic,jz4780-tcu",
|
||||
"ingenic,jz4770-tcu",
|
||||
"simple-mfd";
|
||||
reg = <0x10002000 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0x10002000 0x1000>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
|
||||
clocks = <&cgu JZ4780_CLK_RTCLK
|
||||
&cgu JZ4780_CLK_EXCLK
|
||||
&cgu JZ4780_CLK_PCLK>;
|
||||
clock-names = "rtc", "ext", "pclk";
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <27 26 25>;
|
||||
};
|
||||
|
||||
rtc_dev: rtc@10003000 {
|
||||
compatible = "ingenic,jz4780-rtc";
|
||||
reg = <0x10003000 0x4c>;
|
||||
|
@ -3,12 +3,231 @@
|
||||
|
||||
#include "jz4740.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/iio/adc/ingenic,adc.h>
|
||||
#include <dt-bindings/clock/ingenic,tcu.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#define KEY_QI_QI KEY_F13
|
||||
#define KEY_QI_UPRED KEY_RIGHTALT
|
||||
#define KEY_QI_VOLUP KEY_VOLUMEUP
|
||||
#define KEY_QI_VOLDOWN KEY_VOLUMEDOWN
|
||||
#define KEY_QI_FN KEY_LEFTCTRL
|
||||
|
||||
/ {
|
||||
compatible = "qi,lb60", "ingenic,jz4740";
|
||||
|
||||
chosen {
|
||||
stdout-path = &uart0;
|
||||
};
|
||||
|
||||
vcc: regulator@0 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc";
|
||||
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
mmc_power: regulator@1 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "mmc_vcc";
|
||||
gpio = <&gpd 2 0>;
|
||||
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
amp_supply: regulator@2 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "amp_supply";
|
||||
gpio = <&gpd 4 0>;
|
||||
enable-active-high;
|
||||
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
amp: analog-amplifier {
|
||||
compatible = "simple-audio-amplifier";
|
||||
enable-gpios = <&gpb 29 GPIO_ACTIVE_HIGH>;
|
||||
VCC-supply = <&_supply>;
|
||||
};
|
||||
|
||||
sound {
|
||||
compatible = "simple-audio-card";
|
||||
|
||||
simple-audio-card,name = "QI LB60";
|
||||
simple-audio-card,format = "i2s";
|
||||
|
||||
simple-audio-card,widgets =
|
||||
"Speaker", "Speaker",
|
||||
"Microphone", "Mic";
|
||||
simple-audio-card,routing =
|
||||
"MIC", "Mic",
|
||||
"Speaker", "OUTL",
|
||||
"Speaker", "OUTR",
|
||||
"INL", "LOUT",
|
||||
"INL", "ROUT";
|
||||
|
||||
simple-audio-card,aux-devs = <&>;
|
||||
|
||||
simple-audio-card,bitclock-master = <&dai_codec>;
|
||||
simple-audio-card,frame-master = <&dai_codec>;
|
||||
|
||||
dai_cpu: simple-audio-card,cpu {
|
||||
sound-dai = <&aic>;
|
||||
};
|
||||
|
||||
dai_codec: simple-audio-card,codec {
|
||||
sound-dai = <&codec>;
|
||||
};
|
||||
};
|
||||
|
||||
keys {
|
||||
compatible = "gpio-keys";
|
||||
|
||||
key {
|
||||
label = "Power";
|
||||
wakeup-source;
|
||||
linux,code = <KEY_POWER>;
|
||||
gpios = <&gpd 29 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
keyboard {
|
||||
compatible = "gpio-matrix-keypad";
|
||||
|
||||
col-scan-delay-us = <10>;
|
||||
debounce-delay-ms = <10>;
|
||||
wakeup-source;
|
||||
|
||||
row-gpios = <&gpd 18 0 &gpd 19 0 &gpd 20 0 &gpd 21 0
|
||||
&gpd 22 0 &gpd 23 0 &gpd 24 0 &gpd 26 0>;
|
||||
col-gpios = <&gpc 10 0 &gpc 11 0 &gpc 12 0 &gpc 13 0
|
||||
&gpc 14 0 &gpc 15 0 &gpc 16 0 &gpc 17 0>;
|
||||
gpio-activelow;
|
||||
|
||||
linux,keymap = <
|
||||
MATRIX_KEY(0, 0, KEY_F1) /* S2 */
|
||||
MATRIX_KEY(0, 1, KEY_F2) /* S3 */
|
||||
MATRIX_KEY(0, 2, KEY_F3) /* S4 */
|
||||
MATRIX_KEY(0, 3, KEY_F4) /* S5 */
|
||||
MATRIX_KEY(0, 4, KEY_F5) /* S6 */
|
||||
MATRIX_KEY(0, 5, KEY_F6) /* S7 */
|
||||
MATRIX_KEY(0, 6, KEY_F7) /* S8 */
|
||||
|
||||
MATRIX_KEY(1, 0, KEY_Q) /* S10 */
|
||||
MATRIX_KEY(1, 1, KEY_W) /* S11 */
|
||||
MATRIX_KEY(1, 2, KEY_E) /* S12 */
|
||||
MATRIX_KEY(1, 3, KEY_R) /* S13 */
|
||||
MATRIX_KEY(1, 4, KEY_T) /* S14 */
|
||||
MATRIX_KEY(1, 5, KEY_Y) /* S15 */
|
||||
MATRIX_KEY(1, 6, KEY_U) /* S16 */
|
||||
MATRIX_KEY(1, 7, KEY_I) /* S17 */
|
||||
MATRIX_KEY(2, 0, KEY_A) /* S18 */
|
||||
MATRIX_KEY(2, 1, KEY_S) /* S19 */
|
||||
MATRIX_KEY(2, 2, KEY_D) /* S20 */
|
||||
MATRIX_KEY(2, 3, KEY_F) /* S21 */
|
||||
MATRIX_KEY(2, 4, KEY_G) /* S22 */
|
||||
MATRIX_KEY(2, 5, KEY_H) /* S23 */
|
||||
MATRIX_KEY(2, 6, KEY_J) /* S24 */
|
||||
MATRIX_KEY(2, 7, KEY_K) /* S25 */
|
||||
MATRIX_KEY(3, 0, KEY_ESC) /* S26 */
|
||||
MATRIX_KEY(3, 1, KEY_Z) /* S27 */
|
||||
MATRIX_KEY(3, 2, KEY_X) /* S28 */
|
||||
MATRIX_KEY(3, 3, KEY_C) /* S29 */
|
||||
MATRIX_KEY(3, 4, KEY_V) /* S30 */
|
||||
MATRIX_KEY(3, 5, KEY_B) /* S31 */
|
||||
MATRIX_KEY(3, 6, KEY_N) /* S32 */
|
||||
MATRIX_KEY(3, 7, KEY_M) /* S33 */
|
||||
MATRIX_KEY(4, 0, KEY_TAB) /* S34 */
|
||||
MATRIX_KEY(4, 1, KEY_CAPSLOCK) /* S35 */
|
||||
MATRIX_KEY(4, 2, KEY_BACKSLASH) /* S36 */
|
||||
MATRIX_KEY(4, 3, KEY_APOSTROPHE) /* S37 */
|
||||
MATRIX_KEY(4, 4, KEY_COMMA) /* S38 */
|
||||
MATRIX_KEY(4, 5, KEY_DOT) /* S39 */
|
||||
MATRIX_KEY(4, 6, KEY_SLASH) /* S40 */
|
||||
MATRIX_KEY(4, 7, KEY_UP) /* S41 */
|
||||
MATRIX_KEY(5, 0, KEY_O) /* S42 */
|
||||
MATRIX_KEY(5, 1, KEY_L) /* S43 */
|
||||
MATRIX_KEY(5, 2, KEY_EQUAL) /* S44 */
|
||||
MATRIX_KEY(5, 3, KEY_QI_UPRED) /* S45 */
|
||||
MATRIX_KEY(5, 4, KEY_SPACE) /* S46 */
|
||||
MATRIX_KEY(5, 5, KEY_QI_QI) /* S47 */
|
||||
MATRIX_KEY(5, 6, KEY_RIGHTCTRL) /* S48 */
|
||||
MATRIX_KEY(5, 7, KEY_LEFT) /* S49 */
|
||||
MATRIX_KEY(6, 0, KEY_F8) /* S50 */
|
||||
MATRIX_KEY(6, 1, KEY_P) /* S51 */
|
||||
MATRIX_KEY(6, 2, KEY_BACKSPACE)/* S52 */
|
||||
MATRIX_KEY(6, 3, KEY_ENTER) /* S53 */
|
||||
MATRIX_KEY(6, 4, KEY_QI_VOLUP) /* S54 */
|
||||
MATRIX_KEY(6, 5, KEY_QI_VOLDOWN) /* S55 */
|
||||
MATRIX_KEY(6, 6, KEY_DOWN) /* S56 */
|
||||
MATRIX_KEY(6, 7, KEY_RIGHT) /* S57 */
|
||||
|
||||
MATRIX_KEY(7, 0, KEY_LEFTSHIFT) /* S58 */
|
||||
MATRIX_KEY(7, 1, KEY_LEFTALT) /* S59 */
|
||||
MATRIX_KEY(7, 2, KEY_QI_FN) /* S60 */
|
||||
>;
|
||||
};
|
||||
|
||||
spi {
|
||||
compatible = "spi-gpio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
sck-gpios = <&gpc 23 GPIO_ACTIVE_HIGH>;
|
||||
mosi-gpios = <&gpc 22 GPIO_ACTIVE_HIGH>;
|
||||
cs-gpios = <&gpc 21 GPIO_ACTIVE_LOW>;
|
||||
num-chipselects = <1>;
|
||||
};
|
||||
|
||||
usb_charger: charger {
|
||||
compatible = "gpio-charger";
|
||||
charger-type = "usb-sdp";
|
||||
gpios = <&gpd 28 GPIO_ACTIVE_LOW>;
|
||||
status-gpios = <&gpc 27 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
simple_battery: battery {
|
||||
compatible = "simple-battery";
|
||||
voltage-min-design-microvolt = <3600000>;
|
||||
voltage-max-design-microvolt = <4200000>;
|
||||
};
|
||||
|
||||
pmu {
|
||||
compatible = "ingenic,jz4740-battery";
|
||||
io-channels = <&adc INGENIC_ADC_BATTERY>;
|
||||
io-channel-names = "battery";
|
||||
power-supplies = <&usb_charger>;
|
||||
monitored-battery = <&simple_battery>;
|
||||
};
|
||||
|
||||
hwmon {
|
||||
compatible = "iio-hwmon";
|
||||
io-channels = <&adc INGENIC_ADC_AUX>;
|
||||
};
|
||||
|
||||
panel: panel {
|
||||
compatible = "giantplus,gpm940b0";
|
||||
|
||||
power-supply = <&vcc>;
|
||||
|
||||
port {
|
||||
panel_input: endpoint {
|
||||
remote-endpoint = <&panel_output>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
usb_phy: usb-phy {
|
||||
compatible = "usb-nop-xceiv";
|
||||
#phy-cells = <0>;
|
||||
|
||||
vcc-supply = <&vcc>;
|
||||
};
|
||||
};
|
||||
|
||||
&ext {
|
||||
@ -24,10 +243,116 @@
|
||||
pinctrl-0 = <&pins_uart0>;
|
||||
};
|
||||
|
||||
&uart1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&nemc {
|
||||
nandc: nand-controller@1 {
|
||||
compatible = "ingenic,jz4740-nand";
|
||||
reg = <1 0 0x4000000>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ingenic,bch-controller = <&ecc>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pins_nemc>;
|
||||
|
||||
rb-gpios = <&gpc 30 GPIO_ACTIVE_LOW>;
|
||||
|
||||
nand@1 {
|
||||
reg = <1>;
|
||||
|
||||
nand-ecc-step-size = <512>;
|
||||
nand-ecc-strength = <4>;
|
||||
nand-ecc-mode = "hw";
|
||||
nand-is-boot-medium;
|
||||
nand-on-flash-bbt;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "boot";
|
||||
reg = <0x0 0x400000>;
|
||||
};
|
||||
|
||||
partition@400000 {
|
||||
label = "kernel";
|
||||
reg = <0x400000 0x400000>;
|
||||
};
|
||||
|
||||
partition@800000 {
|
||||
label = "rootfs";
|
||||
reg = <0x800000 0x0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&lcd {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pins_lcd>;
|
||||
|
||||
port {
|
||||
panel_output: endpoint {
|
||||
remote-endpoint = <&panel_input>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&udc {
|
||||
phys = <&usb_phy>;
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
pins_lcd: lcd {
|
||||
function = "lcd";
|
||||
groups = "lcd-8bit";
|
||||
};
|
||||
|
||||
pins_nemc: nemc {
|
||||
function = "nand";
|
||||
groups = "nand-cs1";
|
||||
};
|
||||
|
||||
pins_uart0: uart0 {
|
||||
function = "uart0";
|
||||
groups = "uart0-data";
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
pins_mmc: mmc {
|
||||
mmc {
|
||||
function = "mmc";
|
||||
groups = "mmc-1bit", "mmc-4bit";
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
mmc-gpios {
|
||||
pins = "PD0", "PD2";
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&mmc {
|
||||
bus-width = <4>;
|
||||
max-frequency = <24000000>;
|
||||
cd-gpios = <&gpd 0 GPIO_ACTIVE_HIGH>;
|
||||
vmmc-supply = <&mmc_power>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pins_mmc>;
|
||||
};
|
||||
|
||||
&tcu {
|
||||
/* 750 kHz for the system timer and clocksource */
|
||||
assigned-clocks = <&tcu TCU_CLK_TIMER0>, <&tcu TCU_CLK_TIMER1>;
|
||||
assigned-clock-rates = <750000>, <750000>;
|
||||
};
|
||||
|
@ -120,6 +120,7 @@
|
||||
reg = <0x1010000 0x10000>,
|
||||
<0x1030000 0x10000>,
|
||||
<0x1080000 0x100>,
|
||||
<0x10e0000 0x10000>,
|
||||
<0x11e0000 0x100>,
|
||||
<0x11f0000 0x100>,
|
||||
<0x1200000 0x100>,
|
||||
@ -134,12 +135,12 @@
|
||||
<0x1800000 0x80000>,
|
||||
<0x1880000 0x10000>,
|
||||
<0x1060000 0x10000>;
|
||||
reg-names = "sys", "rew", "qs", "port0", "port1",
|
||||
reg-names = "sys", "rew", "qs", "ptp", "port0", "port1",
|
||||
"port2", "port3", "port4", "port5", "port6",
|
||||
"port7", "port8", "port9", "port10", "qsys",
|
||||
"ana", "s2";
|
||||
interrupts = <21 22>;
|
||||
interrupt-names = "xtr", "inj";
|
||||
interrupts = <18 21 22>;
|
||||
interrupt-names = "ptp_rdy", "xtr", "inj";
|
||||
|
||||
ethernet-ports {
|
||||
#address-cells = <1>;
|
||||
|
@ -190,7 +190,7 @@ char *octeon_swiotlb;
|
||||
|
||||
void __init plat_swiotlb_setup(void)
|
||||
{
|
||||
int i;
|
||||
struct memblock_region *mem;
|
||||
phys_addr_t max_addr;
|
||||
phys_addr_t addr_size;
|
||||
size_t swiotlbsize;
|
||||
@ -199,19 +199,15 @@ void __init plat_swiotlb_setup(void)
|
||||
max_addr = 0;
|
||||
addr_size = 0;
|
||||
|
||||
for (i = 0 ; i < boot_mem_map.nr_map; i++) {
|
||||
struct boot_mem_map_entry *e = &boot_mem_map.map[i];
|
||||
if (e->type != BOOT_MEM_RAM && e->type != BOOT_MEM_INIT_RAM)
|
||||
continue;
|
||||
|
||||
for_each_memblock(memory, mem) {
|
||||
/* These addresses map low for PCI. */
|
||||
if (e->addr > 0x410000000ull && !OCTEON_IS_OCTEON2())
|
||||
if (mem->base > 0x410000000ull && !OCTEON_IS_OCTEON2())
|
||||
continue;
|
||||
|
||||
addr_size += e->size;
|
||||
addr_size += mem->size;
|
||||
|
||||
if (max_addr < e->addr + e->size)
|
||||
max_addr = e->addr + e->size;
|
||||
if (max_addr < mem->base + mem->size)
|
||||
max_addr = mem->base + mem->size;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1007,8 +1007,7 @@ void __init plat_mem_setup(void)
|
||||
* regions next to each other.
|
||||
*/
|
||||
cvmx_bootmem_lock();
|
||||
while ((boot_mem_map.nr_map < BOOT_MEM_MAP_MAX)
|
||||
&& (total < max_memory)) {
|
||||
while (total < max_memory) {
|
||||
memory = cvmx_bootmem_phy_alloc(mem_alloc_size,
|
||||
__pa_symbol(&_end), -1,
|
||||
0x100000,
|
||||
|
@ -1,7 +1,6 @@
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
# CONFIG_CROSS_MEMORY_ATTACH is not set
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
CONFIG_SYSCTL_SYSCALL=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
@ -17,9 +16,8 @@ CONFIG_MODULE_UNLOAD=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
# CONFIG_EFI_PARTITION is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_CMA=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
@ -31,9 +29,6 @@ CONFIG_IP_ROUTE_MULTIPATH=y
|
||||
CONFIG_IP_ROUTE_VERBOSE=y
|
||||
CONFIG_IP_MROUTE=y
|
||||
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
|
||||
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
|
||||
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
|
||||
# CONFIG_INET_XFRM_MODE_BEET is not set
|
||||
# CONFIG_INET_DIAG is not set
|
||||
CONFIG_TCP_CONG_ADVANCED=y
|
||||
# CONFIG_TCP_CONG_BIC is not set
|
||||
@ -44,7 +39,8 @@ CONFIG_TCP_CONG_WESTWOOD=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
CONFIG_MTD_RAW_NAND=y
|
||||
CONFIG_MTD_NAND_JZ4740=y
|
||||
CONFIG_MTD_NAND_JZ4780=y
|
||||
CONFIG_MTD_NAND_JZ4740_ECC=y
|
||||
CONFIG_MTD_UBI=y
|
||||
CONFIG_NETDEVICES=y
|
||||
# CONFIG_WLAN is not set
|
||||
@ -66,18 +62,20 @@ CONFIG_SERIAL_8250_INGENIC=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_GPIO=y
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
CONFIG_BATTERY_JZ4740=y
|
||||
CONFIG_BATTERY_INGENIC=y
|
||||
CONFIG_CHARGER_GPIO=y
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_SENSORS_IIO_HWMON=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_JZ4740_WDT=y
|
||||
CONFIG_MFD_JZ4740_ADC=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_JZ4740=y
|
||||
CONFIG_LCD_CLASS_DEVICE=y
|
||||
# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
|
||||
CONFIG_DRM=y
|
||||
CONFIG_DRM_FBDEV_OVERALLOC=200
|
||||
CONFIG_DRM_PANEL_SIMPLE=y
|
||||
CONFIG_DRM_INGENIC=y
|
||||
# CONFIG_LCD_CLASS_DEVICE is not set
|
||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||
# CONFIG_BACKLIGHT_GENERIC is not set
|
||||
# CONFIG_VGA_CONSOLE is not set
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_LOGO=y
|
||||
@ -92,13 +90,13 @@ CONFIG_SND=y
|
||||
# CONFIG_SND_SPI is not set
|
||||
# CONFIG_SND_MIPS is not set
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_SND_JZ4740_SOC=y
|
||||
CONFIG_SND_JZ4740_SOC_QI_LB60=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_OTG_BLACKLIST_HUB=y
|
||||
CONFIG_SND_JZ4740_SOC_I2S=y
|
||||
CONFIG_SND_SOC_JZ4740_CODEC=y
|
||||
CONFIG_SND_SOC_SIMPLE_AMPLIFIER=y
|
||||
CONFIG_SND_SIMPLE_CARD=y
|
||||
CONFIG_USB_MUSB_HDRC=y
|
||||
CONFIG_USB_MUSB_GADGET=y
|
||||
CONFIG_USB_MUSB_JZ4740=y
|
||||
CONFIG_USB_INVENTRA_DMA=y
|
||||
CONFIG_NOP_USB_XCEIV=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_GADGET_DEBUG=y
|
||||
@ -109,11 +107,13 @@ CONFIG_MMC_JZ4740=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_JZ4740=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DMA_JZ4740=y
|
||||
CONFIG_DMA_JZ4780=y
|
||||
CONFIG_MEMORY=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_INGENIC_ADC=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_JZ4740=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
|
@ -27,6 +27,11 @@
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#define MAX_PROM_MEM 5
|
||||
static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
|
||||
static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
|
||||
static unsigned int nr_prom_mem __initdata;
|
||||
|
||||
/*
|
||||
* For ARC firmware memory functions the unit of meassuring memory is always
|
||||
* a 4k page of memory
|
||||
@ -129,6 +134,7 @@ void __init prom_meminit(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
nr_prom_mem = 0;
|
||||
p = PROM_NULL_MDESC;
|
||||
while ((p = ArcGetMemoryDescriptor(p))) {
|
||||
unsigned long base, size;
|
||||
@ -139,6 +145,16 @@ void __init prom_meminit(void)
|
||||
type = prom_memtype_classify(p->type);
|
||||
|
||||
add_memory_region(base, size, type);
|
||||
|
||||
if (type == BOOT_MEM_ROM_DATA) {
|
||||
if (nr_prom_mem >= 5) {
|
||||
pr_err("Too many ROM DATA regions");
|
||||
continue;
|
||||
}
|
||||
prom_mem_base[nr_prom_mem] = base;
|
||||
prom_mem_size[nr_prom_mem] = size;
|
||||
nr_prom_mem++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,12 +166,8 @@ void __init prom_free_prom_memory(void)
|
||||
if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
|
||||
return;
|
||||
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
|
||||
continue;
|
||||
|
||||
addr = boot_mem_map.map[i].addr;
|
||||
for (i = 0; i < nr_prom_mem; i++) {
|
||||
free_init_pages("prom memory",
|
||||
addr, addr + boot_mem_map.map[i].size);
|
||||
prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]);
|
||||
}
|
||||
}
|
||||
|
@ -135,18 +135,9 @@
|
||||
*/
|
||||
#define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */
|
||||
|
||||
#ifndef CONFIG_CPU_R8000
|
||||
|
||||
/*
|
||||
* The R8000 doesn't have the 32-bit compat spaces so we don't define them
|
||||
* in order to catch bugs in the source code.
|
||||
*/
|
||||
|
||||
#define COMPAT_K1BASE32 _CONST64_(0xffffffffa0000000)
|
||||
#define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
|
||||
|
||||
#endif
|
||||
|
||||
#define KDM_TO_PHYS(x) (_ACAST64_ (x) & TO_PHYS_MASK)
|
||||
#define PHYS_TO_K0(x) (_ACAST64_ (x) | CAC_BASE)
|
||||
|
||||
|
@ -68,7 +68,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v) \
|
||||
"\t" __scbeqz " %0, 1b \n" \
|
||||
" .set pop \n" \
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
: "Ir" (i) : __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
@ -98,7 +98,7 @@ static __inline__ int atomic_##op##_return_relaxed(int i, atomic_t * v) \
|
||||
" .set pop \n" \
|
||||
: "=&r" (result), "=&r" (temp), \
|
||||
"+" GCC_OFF_SMALL_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
: "Ir" (i) : __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
@ -132,7 +132,7 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v) \
|
||||
" move %0, %1 \n" \
|
||||
: "=&r" (result), "=&r" (temp), \
|
||||
"+" GCC_OFF_SMALL_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
: "Ir" (i) : __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
@ -193,6 +193,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
|
||||
if (kernel_uses_llsc) {
|
||||
int temp;
|
||||
|
||||
loongson_llsc_mb();
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set "MIPS_ISA_LEVEL" \n"
|
||||
@ -200,16 +201,16 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
|
||||
" .set pop \n"
|
||||
" subu %0, %1, %3 \n"
|
||||
" move %1, %0 \n"
|
||||
" bltz %0, 1f \n"
|
||||
" bltz %0, 2f \n"
|
||||
" .set push \n"
|
||||
" .set "MIPS_ISA_LEVEL" \n"
|
||||
" sc %1, %2 \n"
|
||||
"\t" __scbeqz " %1, 1b \n"
|
||||
"1: \n"
|
||||
"2: \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (result), "=&r" (temp),
|
||||
"+" GCC_OFF_SMALL_ASM() (v->counter)
|
||||
: "Ir" (i));
|
||||
: "Ir" (i) : __LLSC_CLOBBER);
|
||||
} else {
|
||||
unsigned long flags;
|
||||
|
||||
@ -269,7 +270,7 @@ static __inline__ void atomic64_##op(s64 i, atomic64_t * v) \
|
||||
"\t" __scbeqz " %0, 1b \n" \
|
||||
" .set pop \n" \
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
: "Ir" (i) : __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
@ -299,7 +300,7 @@ static __inline__ s64 atomic64_##op##_return_relaxed(s64 i, atomic64_t * v) \
|
||||
" .set pop \n" \
|
||||
: "=&r" (result), "=&r" (temp), \
|
||||
"+" GCC_OFF_SMALL_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
: "Ir" (i) : __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
@ -333,7 +334,7 @@ static __inline__ s64 atomic64_fetch_##op##_relaxed(s64 i, atomic64_t * v) \
|
||||
" .set pop \n" \
|
||||
: "=&r" (result), "=&r" (temp), \
|
||||
"+" GCC_OFF_SMALL_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
: "Ir" (i) : __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
|
@ -211,14 +211,22 @@
|
||||
#define __smp_wmb() barrier()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When LL/SC does imply order, it must also be a compiler barrier to avoid the
|
||||
* compiler from reordering where the CPU will not. When it does not imply
|
||||
* order, the compiler is also free to reorder across the LL/SC loop and
|
||||
* ordering will be done by smp_llsc_mb() and friends.
|
||||
*/
|
||||
#if defined(CONFIG_WEAK_REORDERING_BEYOND_LLSC) && defined(CONFIG_SMP)
|
||||
#define __WEAK_LLSC_MB " sync \n"
|
||||
#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
|
||||
#define __LLSC_CLOBBER
|
||||
#else
|
||||
#define __WEAK_LLSC_MB " \n"
|
||||
#define smp_llsc_mb() do { } while (0)
|
||||
#define __LLSC_CLOBBER "memory"
|
||||
#endif
|
||||
|
||||
#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
|
||||
|
||||
#ifdef CONFIG_CPU_CAVIUM_OCTEON
|
||||
#define smp_mb__before_llsc() smp_wmb()
|
||||
#define __smp_mb__before_llsc() __smp_wmb()
|
||||
@ -238,36 +246,40 @@
|
||||
|
||||
/*
|
||||
* Some Loongson 3 CPUs have a bug wherein execution of a memory access (load,
|
||||
* store or pref) in between an ll & sc can cause the sc instruction to
|
||||
* store or prefetch) in between an LL & SC can cause the SC instruction to
|
||||
* erroneously succeed, breaking atomicity. Whilst it's unusual to write code
|
||||
* containing such sequences, this bug bites harder than we might otherwise
|
||||
* expect due to reordering & speculation:
|
||||
*
|
||||
* 1) A memory access appearing prior to the ll in program order may actually
|
||||
* be executed after the ll - this is the reordering case.
|
||||
* 1) A memory access appearing prior to the LL in program order may actually
|
||||
* be executed after the LL - this is the reordering case.
|
||||
*
|
||||
* In order to avoid this we need to place a memory barrier (ie. a sync
|
||||
* instruction) prior to every ll instruction, in between it & any earlier
|
||||
* memory access instructions. Many of these cases are already covered by
|
||||
* smp_mb__before_llsc() but for the remaining cases, typically ones in
|
||||
* which multiple CPUs may operate on a memory location but ordering is not
|
||||
* usually guaranteed, we use loongson_llsc_mb() below.
|
||||
* In order to avoid this we need to place a memory barrier (ie. a SYNC
|
||||
* instruction) prior to every LL instruction, in between it and any earlier
|
||||
* memory access instructions.
|
||||
*
|
||||
* This reordering case is fixed by 3A R2 CPUs, ie. 3A2000 models and later.
|
||||
*
|
||||
* 2) If a conditional branch exists between an ll & sc with a target outside
|
||||
* of the ll-sc loop, for example an exit upon value mismatch in cmpxchg()
|
||||
* 2) If a conditional branch exists between an LL & SC with a target outside
|
||||
* of the LL-SC loop, for example an exit upon value mismatch in cmpxchg()
|
||||
* or similar, then misprediction of the branch may allow speculative
|
||||
* execution of memory accesses from outside of the ll-sc loop.
|
||||
* execution of memory accesses from outside of the LL-SC loop.
|
||||
*
|
||||
* In order to avoid this we need a memory barrier (ie. a sync instruction)
|
||||
* In order to avoid this we need a memory barrier (ie. a SYNC instruction)
|
||||
* at each affected branch target, for which we also use loongson_llsc_mb()
|
||||
* defined below.
|
||||
*
|
||||
* This case affects all current Loongson 3 CPUs.
|
||||
*
|
||||
* The above described cases cause an error in the cache coherence protocol;
|
||||
* such that the Invalidate of a competing LL-SC goes 'missing' and SC
|
||||
* erroneously observes its core still has Exclusive state and lets the SC
|
||||
* proceed.
|
||||
*
|
||||
* Therefore the error only occurs on SMP systems.
|
||||
*/
|
||||
#ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS /* Loongson-3's LLSC workaround */
|
||||
#define loongson_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
|
||||
#define loongson_llsc_mb() __asm__ __volatile__("sync" : : :"memory")
|
||||
#else
|
||||
#define loongson_llsc_mb() do { } while (0)
|
||||
#endif
|
||||
|
@ -66,7 +66,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" beqzl %0, 1b \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m));
|
||||
: "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m)
|
||||
: __LLSC_CLOBBER);
|
||||
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
|
||||
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
|
||||
loongson_llsc_mb();
|
||||
@ -76,7 +77,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" " __INS "%0, %3, %2, 1 \n"
|
||||
" " __SC "%0, %1 \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (bit), "r" (~0));
|
||||
: "ir" (bit), "r" (~0)
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!temp));
|
||||
#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
|
||||
} else if (kernel_uses_llsc) {
|
||||
@ -90,7 +92,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" " __SC "%0, %1 \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (1UL << bit));
|
||||
: "ir" (1UL << bit)
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!temp));
|
||||
} else
|
||||
__mips_set_bit(nr, addr);
|
||||
@ -122,7 +125,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" beqzl %0, 1b \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (~(1UL << bit)));
|
||||
: "ir" (~(1UL << bit))
|
||||
: __LLSC_CLOBBER);
|
||||
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
|
||||
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
|
||||
loongson_llsc_mb();
|
||||
@ -132,7 +136,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" " __INS "%0, $0, %2, 1 \n"
|
||||
" " __SC "%0, %1 \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (bit));
|
||||
: "ir" (bit)
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!temp));
|
||||
#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
|
||||
} else if (kernel_uses_llsc) {
|
||||
@ -146,7 +151,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" " __SC "%0, %1 \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (~(1UL << bit)));
|
||||
: "ir" (~(1UL << bit))
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!temp));
|
||||
} else
|
||||
__mips_clear_bit(nr, addr);
|
||||
@ -192,7 +198,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" beqzl %0, 1b \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (1UL << bit));
|
||||
: "ir" (1UL << bit)
|
||||
: __LLSC_CLOBBER);
|
||||
} else if (kernel_uses_llsc) {
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
|
||||
unsigned long temp;
|
||||
@ -207,7 +214,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" " __SC "%0, %1 \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (1UL << bit));
|
||||
: "ir" (1UL << bit)
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!temp));
|
||||
} else
|
||||
__mips_change_bit(nr, addr);
|
||||
@ -244,11 +252,12 @@ static inline int test_and_set_bit(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} else if (kernel_uses_llsc) {
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
|
||||
unsigned long temp;
|
||||
|
||||
loongson_llsc_mb();
|
||||
do {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
@ -259,7 +268,7 @@ static inline int test_and_set_bit(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!res));
|
||||
|
||||
res = temp & (1UL << bit);
|
||||
@ -300,11 +309,12 @@ static inline int test_and_set_bit_lock(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+m" (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} else if (kernel_uses_llsc) {
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
|
||||
unsigned long temp;
|
||||
|
||||
loongson_llsc_mb();
|
||||
do {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
@ -315,7 +325,7 @@ static inline int test_and_set_bit_lock(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!res));
|
||||
|
||||
res = temp & (1UL << bit);
|
||||
@ -358,12 +368,13 @@ static inline int test_and_clear_bit(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
|
||||
} else if (kernel_uses_llsc && __builtin_constant_p(nr)) {
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
|
||||
unsigned long temp;
|
||||
|
||||
loongson_llsc_mb();
|
||||
do {
|
||||
__asm__ __volatile__(
|
||||
" " __LL "%0, %1 # test_and_clear_bit \n"
|
||||
@ -372,13 +383,14 @@ static inline int test_and_clear_bit(unsigned long nr,
|
||||
" " __SC "%0, %1 \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "ir" (bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!temp));
|
||||
#endif
|
||||
} else if (kernel_uses_llsc) {
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
|
||||
unsigned long temp;
|
||||
|
||||
loongson_llsc_mb();
|
||||
do {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
@ -390,7 +402,7 @@ static inline int test_and_clear_bit(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!res));
|
||||
|
||||
res = temp & (1UL << bit);
|
||||
@ -433,11 +445,12 @@ static inline int test_and_change_bit(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} else if (kernel_uses_llsc) {
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
|
||||
unsigned long temp;
|
||||
|
||||
loongson_llsc_mb();
|
||||
do {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
@ -448,7 +461,7 @@ static inline int test_and_change_bit(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!res));
|
||||
|
||||
res = temp & (1UL << bit);
|
||||
|
@ -81,34 +81,19 @@ enum loongson_machine_type {
|
||||
#define MACH_INGENIC_JZ4740 1 /* JZ4740 SOC */
|
||||
#define MACH_INGENIC_JZ4770 2 /* JZ4770 SOC */
|
||||
#define MACH_INGENIC_JZ4780 3 /* JZ4780 SOC */
|
||||
#define MACH_INGENIC_X1000 4 /* X1000 SOC */
|
||||
|
||||
extern char *system_type;
|
||||
const char *get_system_type(void);
|
||||
|
||||
extern unsigned long mips_machtype;
|
||||
|
||||
#define BOOT_MEM_MAP_MAX 32
|
||||
#define BOOT_MEM_RAM 1
|
||||
#define BOOT_MEM_ROM_DATA 2
|
||||
#define BOOT_MEM_RESERVED 3
|
||||
#define BOOT_MEM_INIT_RAM 4
|
||||
#define BOOT_MEM_NOMAP 5
|
||||
|
||||
/*
|
||||
* A memory map that's built upon what was determined
|
||||
* or specified on the command line.
|
||||
*/
|
||||
struct boot_mem_map {
|
||||
int nr_map;
|
||||
struct boot_mem_map_entry {
|
||||
phys_addr_t addr; /* start of memory segment */
|
||||
phys_addr_t size; /* size of memory segment */
|
||||
long type; /* type of memory segment */
|
||||
} map[BOOT_MEM_MAP_MAX];
|
||||
};
|
||||
|
||||
extern struct boot_mem_map boot_mem_map;
|
||||
|
||||
extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type);
|
||||
extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max);
|
||||
|
||||
|
@ -46,6 +46,7 @@ extern unsigned long __xchg_called_with_bad_pointer(void)
|
||||
__typeof(*(m)) __ret; \
|
||||
\
|
||||
if (kernel_uses_llsc) { \
|
||||
loongson_llsc_mb(); \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
@ -60,7 +61,7 @@ extern unsigned long __xchg_called_with_bad_pointer(void)
|
||||
" .set pop \n" \
|
||||
: "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \
|
||||
: GCC_OFF_SMALL_ASM() (*m), "Jr" (val) \
|
||||
: "memory"); \
|
||||
: __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long __flags; \
|
||||
\
|
||||
@ -117,6 +118,7 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
|
||||
__typeof(*(m)) __ret; \
|
||||
\
|
||||
if (kernel_uses_llsc) { \
|
||||
loongson_llsc_mb(); \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
@ -132,8 +134,9 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
|
||||
" .set pop \n" \
|
||||
"2: \n" \
|
||||
: "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \
|
||||
: GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \
|
||||
: "memory"); \
|
||||
: GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \
|
||||
: __LLSC_CLOBBER); \
|
||||
loongson_llsc_mb(); \
|
||||
} else { \
|
||||
unsigned long __flags; \
|
||||
\
|
||||
@ -229,6 +232,7 @@ static inline unsigned long __cmpxchg64(volatile void *ptr,
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
|
||||
loongson_llsc_mb();
|
||||
asm volatile(
|
||||
" .set push \n"
|
||||
" .set " MIPS_ISA_ARCH_LEVEL " \n"
|
||||
@ -274,6 +278,7 @@ static inline unsigned long __cmpxchg64(volatile void *ptr,
|
||||
"r" (old),
|
||||
"r" (new)
|
||||
: "memory");
|
||||
loongson_llsc_mb();
|
||||
|
||||
local_irq_restore(flags);
|
||||
return ret;
|
||||
@ -290,10 +295,13 @@ static inline unsigned long __cmpxchg64(volatile void *ptr,
|
||||
* will cause a build error unless cpu_has_64bits is a \
|
||||
* compile-time constant 1. \
|
||||
*/ \
|
||||
if (cpu_has_64bits && kernel_uses_llsc) \
|
||||
if (cpu_has_64bits && kernel_uses_llsc) { \
|
||||
smp_mb__before_llsc(); \
|
||||
__res = __cmpxchg64((ptr), __old, __new); \
|
||||
else \
|
||||
smp_llsc_mb(); \
|
||||
} else { \
|
||||
__res = __cmpxchg64_unsupported(); \
|
||||
} \
|
||||
\
|
||||
__res; \
|
||||
})
|
||||
|
@ -243,9 +243,6 @@
|
||||
#ifndef cpu_has_pindexed_dcache
|
||||
#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
|
||||
#endif
|
||||
#ifndef cpu_has_local_ebase
|
||||
#define cpu_has_local_ebase 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I-Cache snoops remote store. This only matters on SMP. Some multiprocessors
|
||||
@ -397,6 +394,22 @@
|
||||
#define cpu_has_dsp3 __ase(MIPS_ASE_DSP3)
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_loongson_mmi
|
||||
#define cpu_has_loongson_mmi __ase(MIPS_ASE_LOONGSON_MMI)
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_loongson_cam
|
||||
#define cpu_has_loongson_cam __ase(MIPS_ASE_LOONGSON_CAM)
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_loongson_ext
|
||||
#define cpu_has_loongson_ext __ase(MIPS_ASE_LOONGSON_EXT)
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_loongson_ext2
|
||||
#define cpu_has_loongson_ext2 __ase(MIPS_ASE_LOONGSON_EXT2)
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_mipsmt
|
||||
#define cpu_has_mipsmt __isa_lt_and_ase(6, MIPS_ASE_MIPSMT)
|
||||
#endif
|
||||
|
@ -38,7 +38,7 @@ static inline int __pure __get_cpu_type(const int cpu_type)
|
||||
#if defined(CONFIG_SYS_HAS_CPU_MIPS32_R1) || \
|
||||
defined(CONFIG_SYS_HAS_CPU_MIPS32_R2)
|
||||
case CPU_4KEC:
|
||||
case CPU_JZRISC:
|
||||
case CPU_XBURST:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_MIPS32_R2
|
||||
@ -116,11 +116,6 @@ static inline int __pure __get_cpu_type(const int cpu_type)
|
||||
case CPU_VR4181A:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_R4300
|
||||
case CPU_R4300:
|
||||
case CPU_R4310:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_R4X00
|
||||
case CPU_R4000PC:
|
||||
case CPU_R4000SC:
|
||||
@ -143,10 +138,6 @@ static inline int __pure __get_cpu_type(const int cpu_type)
|
||||
case CPU_R5000:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_R5432
|
||||
case CPU_R5432:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_R5500
|
||||
case CPU_R5500:
|
||||
#endif
|
||||
@ -155,10 +146,6 @@ static inline int __pure __get_cpu_type(const int cpu_type)
|
||||
case CPU_NEVADA:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_R8000
|
||||
case CPU_R8000:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_R10000
|
||||
case CPU_R10000:
|
||||
case CPU_R12000:
|
||||
|
@ -47,7 +47,7 @@
|
||||
#define PRID_COMP_CAVIUM 0x0d0000
|
||||
#define PRID_COMP_LOONGSON 0x140000
|
||||
#define PRID_COMP_INGENIC_D0 0xd00000 /* JZ4740, JZ4750 */
|
||||
#define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775 */
|
||||
#define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775, X1000 */
|
||||
#define PRID_COMP_INGENIC_E1 0xe10000 /* JZ4780 */
|
||||
|
||||
/*
|
||||
@ -183,7 +183,7 @@
|
||||
* These are the PRID's for when 23:16 == PRID_COMP_INGENIC_*
|
||||
*/
|
||||
|
||||
#define PRID_IMP_JZRISC 0x0200
|
||||
#define PRID_IMP_XBURST 0x0200
|
||||
|
||||
/*
|
||||
* These are the PRID's for when 23:16 == PRID_COMP_NETLOGIC
|
||||
@ -293,18 +293,13 @@ enum cpu_type_enum {
|
||||
/*
|
||||
* R4000 class processors
|
||||
*/
|
||||
CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4300, CPU_R4310,
|
||||
CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200,
|
||||
CPU_R4400PC, CPU_R4400SC, CPU_R4400MC, CPU_R4600, CPU_R4640, CPU_R4650,
|
||||
CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R5432, CPU_R10000,
|
||||
CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R10000,
|
||||
CPU_R12000, CPU_R14000, CPU_R16000, CPU_VR41XX, CPU_VR4111, CPU_VR4121,
|
||||
CPU_VR4122, CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000,
|
||||
CPU_SR71000, CPU_TX49XX,
|
||||
|
||||
/*
|
||||
* R8000 class processors
|
||||
*/
|
||||
CPU_R8000,
|
||||
|
||||
/*
|
||||
* TX3900 class processors
|
||||
*/
|
||||
@ -315,7 +310,7 @@ enum cpu_type_enum {
|
||||
*/
|
||||
CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
|
||||
CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
|
||||
CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC,
|
||||
CPU_BMIPS4380, CPU_BMIPS5000, CPU_XBURST, CPU_LOONGSON1, CPU_M14KC,
|
||||
CPU_M14KEC, CPU_INTERAPTIV, CPU_P5600, CPU_PROAPTIV, CPU_1074K,
|
||||
CPU_M5150, CPU_I6400, CPU_P6600, CPU_M6250,
|
||||
|
||||
@ -433,5 +428,9 @@ enum cpu_type_enum {
|
||||
#define MIPS_ASE_MSA 0x00000100 /* MIPS SIMD Architecture */
|
||||
#define MIPS_ASE_DSP3 0x00000200 /* Signal Processing ASE Rev 3*/
|
||||
#define MIPS_ASE_MIPS16E2 0x00000400 /* MIPS16e2 */
|
||||
#define MIPS_ASE_LOONGSON_MMI 0x00000800 /* Loongson MultiMedia extensions Instructions */
|
||||
#define MIPS_ASE_LOONGSON_CAM 0x00001000 /* Loongson CAM */
|
||||
#define MIPS_ASE_LOONGSON_EXT 0x00002000 /* Loongson EXTensions */
|
||||
#define MIPS_ASE_LOONGSON_EXT2 0x00004000 /* Loongson EXTensions R2 */
|
||||
|
||||
#endif /* _ASM_CPU_H */
|
||||
|
@ -63,21 +63,11 @@
|
||||
* instruction, so the lower 16 bits must be zero. Should be true on
|
||||
* on any sane architecture; generic code does not use this assumption.
|
||||
*/
|
||||
extern const unsigned long mips_io_port_base;
|
||||
extern unsigned long mips_io_port_base;
|
||||
|
||||
/*
|
||||
* Gcc will generate code to load the value of mips_io_port_base after each
|
||||
* function call which may be fairly wasteful in some cases. So we don't
|
||||
* play quite by the book. We tell gcc mips_io_port_base is a long variable
|
||||
* which solves the code generation issue. Now we need to violate the
|
||||
* aliasing rules a little to make initialization possible and finally we
|
||||
* will need the barrier() to fight side effects of the aliasing chat.
|
||||
* This trickery will eventually collapse under gcc's optimizer. Oh well.
|
||||
*/
|
||||
static inline void set_io_port_base(unsigned long base)
|
||||
{
|
||||
* (unsigned long *) &mips_io_port_base = base;
|
||||
barrier();
|
||||
mips_io_port_base = base;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -262,11 +252,11 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset,
|
||||
#define ioremap_uc ioremap_nocache
|
||||
|
||||
/*
|
||||
* ioremap_cachable - map bus memory into CPU space
|
||||
* ioremap_cache - map bus memory into CPU space
|
||||
* @offset: bus address of the memory
|
||||
* @size: size of the resource to map
|
||||
*
|
||||
* ioremap_nocache performs a platform specific sequence of operations to
|
||||
* ioremap_cache performs a platform specific sequence of operations to
|
||||
* make bus memory CPU accessible via the readb/readw/readl/writeb/
|
||||
* writew/writel functions and the other mmio helpers. The returned
|
||||
* address is not guaranteed to be usable directly as a virtual
|
||||
@ -276,9 +266,8 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset,
|
||||
* the CPU. Also enables full write-combining. Useful for some
|
||||
* memory-like regions on I/O busses.
|
||||
*/
|
||||
#define ioremap_cachable(offset, size) \
|
||||
#define ioremap_cache(offset, size) \
|
||||
__ioremap_mode((offset), (size), _page_cachable_default)
|
||||
#define ioremap_cache ioremap_cachable
|
||||
|
||||
/*
|
||||
* ioremap_wc - map bus memory into CPU space
|
||||
|
@ -98,6 +98,7 @@ enum bcm47xx_board {
|
||||
BCM47XX_BOARD_MOTOROLA_WR850GP,
|
||||
BCM47XX_BOARD_MOTOROLA_WR850GV2V3,
|
||||
|
||||
BCM47XX_BOARD_NETGEAR_R6200_V1,
|
||||
BCM47XX_BOARD_NETGEAR_WGR614V8,
|
||||
BCM47XX_BOARD_NETGEAR_WGR614V9,
|
||||
BCM47XX_BOARD_NETGEAR_WGR614_V10,
|
||||
|
@ -45,7 +45,6 @@
|
||||
#define cpu_has_ic_fills_f_dc 0
|
||||
#define cpu_has_64bits 1
|
||||
#define cpu_has_octeon_cache 1
|
||||
#define cpu_has_saa octeon_has_saa()
|
||||
#define cpu_has_mips32r1 1
|
||||
#define cpu_has_mips32r2 1
|
||||
#define cpu_has_mips64r1 1
|
||||
@ -60,7 +59,6 @@
|
||||
|
||||
#define cpu_has_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON)
|
||||
|
||||
#define ARCH_HAS_IRQ_PER_CPU 1
|
||||
#define ARCH_HAS_SPINLOCK_PREFETCH 1
|
||||
#define spin_lock_prefetch(x) prefetch(x)
|
||||
#define PREFETCH_STRIDE 128
|
||||
@ -73,13 +71,6 @@
|
||||
#define ARCH_HAS_USABLE_BUILTIN_POPCOUNT 1
|
||||
#endif
|
||||
|
||||
static inline int octeon_has_saa(void)
|
||||
{
|
||||
int id;
|
||||
asm volatile ("mfc0 %0, $15,0" : "=r" (id));
|
||||
return id >= 0x000d0300;
|
||||
}
|
||||
|
||||
/*
|
||||
* The last 256MB are reserved for device to device mappings and the
|
||||
* BAR1 hole.
|
||||
|
@ -12,7 +12,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@ -32,7 +32,6 @@
|
||||
#define cpu_has_vtag_icache 0
|
||||
#define cpu_has_ic_fills_f_dc 0
|
||||
#define cpu_has_pindexed_dcache 0
|
||||
#define cpu_has_local_ebase 0
|
||||
#define cpu_icache_snoops_remote_store 1
|
||||
#define cpu_has_mips_4 0
|
||||
#define cpu_has_mips_5 0
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@ -15,7 +15,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 1
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 1
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 1
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@ -1,15 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
|
||||
* JZ4740 GPIO pin definitions
|
||||
*/
|
||||
|
||||
#ifndef _JZ_GPIO_H
|
||||
#define _JZ_GPIO_H
|
||||
|
||||
#define JZ_GPIO_PORTA(x) ((x) + 32 * 0)
|
||||
#define JZ_GPIO_PORTB(x) ((x) + 32 * 1)
|
||||
#define JZ_GPIO_PORTC(x) ((x) + 32 * 2)
|
||||
#define JZ_GPIO_PORTD(x) ((x) + 32 * 3)
|
||||
|
||||
#endif
|
@ -1,58 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
|
||||
*/
|
||||
|
||||
#ifndef __ASM_MACH_JZ4740_JZ4740_FB_H__
|
||||
#define __ASM_MACH_JZ4740_JZ4740_FB_H__
|
||||
|
||||
#include <linux/fb.h>
|
||||
|
||||
enum jz4740_fb_lcd_type {
|
||||
JZ_LCD_TYPE_GENERIC_16_BIT = 0,
|
||||
JZ_LCD_TYPE_GENERIC_18_BIT = 0 | (1 << 4),
|
||||
JZ_LCD_TYPE_SPECIAL_TFT_1 = 1,
|
||||
JZ_LCD_TYPE_SPECIAL_TFT_2 = 2,
|
||||
JZ_LCD_TYPE_SPECIAL_TFT_3 = 3,
|
||||
JZ_LCD_TYPE_NON_INTERLACED_CCIR656 = 5,
|
||||
JZ_LCD_TYPE_INTERLACED_CCIR656 = 7,
|
||||
JZ_LCD_TYPE_SINGLE_COLOR_STN = 8,
|
||||
JZ_LCD_TYPE_SINGLE_MONOCHROME_STN = 9,
|
||||
JZ_LCD_TYPE_DUAL_COLOR_STN = 10,
|
||||
JZ_LCD_TYPE_DUAL_MONOCHROME_STN = 11,
|
||||
JZ_LCD_TYPE_8BIT_SERIAL = 12,
|
||||
};
|
||||
|
||||
#define JZ4740_FB_SPECIAL_TFT_CONFIG(start, stop) (((start) << 16) | (stop))
|
||||
|
||||
/*
|
||||
* width: width of the lcd display in mm
|
||||
* height: height of the lcd display in mm
|
||||
* num_modes: size of modes
|
||||
* modes: list of valid video modes
|
||||
* bpp: bits per pixel for the lcd
|
||||
* lcd_type: lcd type
|
||||
*/
|
||||
|
||||
struct jz4740_fb_platform_data {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
|
||||
size_t num_modes;
|
||||
struct fb_videomode *modes;
|
||||
|
||||
unsigned int bpp;
|
||||
enum jz4740_fb_lcd_type lcd_type;
|
||||
|
||||
struct {
|
||||
uint32_t spl;
|
||||
uint32_t cls;
|
||||
uint32_t ps;
|
||||
uint32_t rev;
|
||||
} special_tft_config;
|
||||
|
||||
unsigned pixclk_falling_edge:1;
|
||||
unsigned date_enable_active_low:1;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,12 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __LINUX_MMC_JZ4740_MMC
|
||||
#define __LINUX_MMC_JZ4740_MMC
|
||||
|
||||
struct jz4740_mmc_platform_data {
|
||||
unsigned card_detect_active_low:1;
|
||||
unsigned read_only_active_low:1;
|
||||
|
||||
unsigned data_1bit:1;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,26 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
|
||||
* JZ4740 platform device definitions
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __JZ4740_PLATFORM_H
|
||||
#define __JZ4740_PLATFORM_H
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
extern struct platform_device jz4740_udc_device;
|
||||
extern struct platform_device jz4740_udc_xceiv_device;
|
||||
extern struct platform_device jz4740_mmc_device;
|
||||
extern struct platform_device jz4740_i2c_device;
|
||||
extern struct platform_device jz4740_nand_device;
|
||||
extern struct platform_device jz4740_framebuffer_device;
|
||||
extern struct platform_device jz4740_i2s_device;
|
||||
extern struct platform_device jz4740_pcm_device;
|
||||
extern struct platform_device jz4740_codec_device;
|
||||
extern struct platform_device jz4740_adc_device;
|
||||
extern struct platform_device jz4740_pwm_device;
|
||||
extern struct platform_device jz4740_dma_device;
|
||||
|
||||
#endif
|
@ -43,7 +43,6 @@
|
||||
#define cpu_has_vint 0
|
||||
#define cpu_has_vtag_icache 0
|
||||
#define cpu_has_watch 1
|
||||
#define cpu_has_local_ebase 0
|
||||
|
||||
#ifdef CONFIG_CPU_LOONGSON3
|
||||
#define cpu_has_wsbh 1
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 1
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 1
|
||||
|
@ -15,7 +15,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 1
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
|
||||
#if defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@ -689,6 +689,9 @@
|
||||
#define MIPS_CONF7_IAR (_ULCAST_(1) << 10)
|
||||
#define MIPS_CONF7_AR (_ULCAST_(1) << 16)
|
||||
|
||||
/* Ingenic Config7 bits */
|
||||
#define MIPS_CONF7_BTB_LOOP_EN (_ULCAST_(1) << 4)
|
||||
|
||||
/* Config7 Bits specific to MIPS Technologies. */
|
||||
|
||||
/* Performance counters implemented Per TC */
|
||||
@ -2813,6 +2816,7 @@ __BUILD_SET_C0(status)
|
||||
__BUILD_SET_C0(cause)
|
||||
__BUILD_SET_C0(config)
|
||||
__BUILD_SET_C0(config5)
|
||||
__BUILD_SET_C0(config7)
|
||||
__BUILD_SET_C0(intcontrol)
|
||||
__BUILD_SET_C0(intctl)
|
||||
__BUILD_SET_C0(srsmap)
|
||||
|
@ -103,22 +103,16 @@ search_module_dbetables(unsigned long addr)
|
||||
#define MODULE_PROC_FAMILY "TX39XX "
|
||||
#elif defined CONFIG_CPU_VR41XX
|
||||
#define MODULE_PROC_FAMILY "VR41XX "
|
||||
#elif defined CONFIG_CPU_R4300
|
||||
#define MODULE_PROC_FAMILY "R4300 "
|
||||
#elif defined CONFIG_CPU_R4X00
|
||||
#define MODULE_PROC_FAMILY "R4X00 "
|
||||
#elif defined CONFIG_CPU_TX49XX
|
||||
#define MODULE_PROC_FAMILY "TX49XX "
|
||||
#elif defined CONFIG_CPU_R5000
|
||||
#define MODULE_PROC_FAMILY "R5000 "
|
||||
#elif defined CONFIG_CPU_R5432
|
||||
#define MODULE_PROC_FAMILY "R5432 "
|
||||
#elif defined CONFIG_CPU_R5500
|
||||
#define MODULE_PROC_FAMILY "R5500 "
|
||||
#elif defined CONFIG_CPU_NEVADA
|
||||
#define MODULE_PROC_FAMILY "NEVADA "
|
||||
#elif defined CONFIG_CPU_R8000
|
||||
#define MODULE_PROC_FAMILY "R8000 "
|
||||
#elif defined CONFIG_CPU_R10000
|
||||
#define MODULE_PROC_FAMILY "R10000 "
|
||||
#elif defined CONFIG_CPU_RM7000
|
||||
|
@ -51,7 +51,7 @@ extern void octeon_setup_delays(void);
|
||||
extern void octeon_io_clk_delay(unsigned long);
|
||||
|
||||
#define OCTEON_ARGV_MAX_ARGS 64
|
||||
#define OCTOEN_SERIAL_LEN 20
|
||||
#define OCTEON_SERIAL_LEN 20
|
||||
|
||||
struct octeon_boot_descriptor {
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
@ -102,7 +102,7 @@ struct octeon_boot_descriptor {
|
||||
uint16_t chip_type;
|
||||
uint8_t chip_rev_major;
|
||||
uint8_t chip_rev_minor;
|
||||
char board_serial_number[OCTOEN_SERIAL_LEN];
|
||||
char board_serial_number[OCTEON_SERIAL_LEN];
|
||||
uint8_t mac_addr_base[6];
|
||||
uint8_t mac_addr_count;
|
||||
uint64_t cvmx_desc_vaddr;
|
||||
|
@ -23,6 +23,24 @@
|
||||
#include <asm/highmem.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Regarding 32-bit MIPS huge page support (and the tradeoff it entails):
|
||||
*
|
||||
* We use the same huge page sizes as 64-bit MIPS. Assuming a 4KB page size,
|
||||
* our 2-level table layout would normally have a PGD entry cover a contiguous
|
||||
* 4MB virtual address region (pointing to a 4KB PTE page of 1,024 32-bit pte_t
|
||||
* pointers, each pointing to a 4KB physical page). The problem is that 4MB,
|
||||
* spanning both halves of a TLB EntryLo0,1 pair, requires 2MB hardware page
|
||||
* support, not one of the standard supported sizes (1MB,4MB,16MB,...).
|
||||
* To correct for this, when huge pages are enabled, we halve the number of
|
||||
* pointers a PTE page holds, making its last half go to waste. Correspondingly,
|
||||
* we double the number of PGD pages. Overall, page table memory overhead
|
||||
* increases to match 64-bit MIPS, but PTE lookups remain CPU cache-friendly.
|
||||
*
|
||||
* NOTE: We don't yet support huge pages if extended-addressing is enabled
|
||||
* (i.e. EVA, XPA, 36-bit Alchemy/Netlogic).
|
||||
*/
|
||||
|
||||
extern int temp_tlb_entry;
|
||||
|
||||
/*
|
||||
@ -44,7 +62,12 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
|
||||
*/
|
||||
|
||||
/* PGDIR_SHIFT determines what a third-level page table entry can map */
|
||||
#define PGDIR_SHIFT (2 * PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2)
|
||||
#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
|
||||
# define PGDIR_SHIFT (2 * PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2 - 1)
|
||||
#else
|
||||
# define PGDIR_SHIFT (2 * PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2)
|
||||
#endif
|
||||
|
||||
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
|
||||
#define PGDIR_MASK (~(PGDIR_SIZE-1))
|
||||
|
||||
@ -52,14 +75,23 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
|
||||
* Entries per page directory level: we use two-level, so
|
||||
* we don't really have any PUD/PMD directory physically.
|
||||
*/
|
||||
#define __PGD_ORDER (32 - 3 * PAGE_SHIFT + PGD_T_LOG2 + PTE_T_LOG2)
|
||||
#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
|
||||
# define __PGD_ORDER (32 - 3 * PAGE_SHIFT + PGD_T_LOG2 + PTE_T_LOG2 + 1)
|
||||
#else
|
||||
# define __PGD_ORDER (32 - 3 * PAGE_SHIFT + PGD_T_LOG2 + PTE_T_LOG2)
|
||||
#endif
|
||||
|
||||
#define PGD_ORDER (__PGD_ORDER >= 0 ? __PGD_ORDER : 0)
|
||||
#define PUD_ORDER aieeee_attempt_to_allocate_pud
|
||||
#define PMD_ORDER 1
|
||||
#define PMD_ORDER aieeee_attempt_to_allocate_pmd
|
||||
#define PTE_ORDER 0
|
||||
|
||||
#define PTRS_PER_PGD (USER_PTRS_PER_PGD * 2)
|
||||
#define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
|
||||
#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
|
||||
# define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t) / 2)
|
||||
#else
|
||||
# define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
|
||||
#endif
|
||||
|
||||
#define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE)
|
||||
#define FIRST_USER_ADDRESS 0UL
|
||||
@ -87,7 +119,7 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
|
||||
|
||||
extern void load_pgd(unsigned long pg_dir);
|
||||
|
||||
extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
|
||||
extern pte_t invalid_pte_table[PTRS_PER_PTE];
|
||||
|
||||
/*
|
||||
* Empty pgd/pmd entries point to the invalid_pte_table.
|
||||
@ -97,7 +129,19 @@ static inline int pmd_none(pmd_t pmd)
|
||||
return pmd_val(pmd) == (unsigned long) invalid_pte_table;
|
||||
}
|
||||
|
||||
#define pmd_bad(pmd) (pmd_val(pmd) & ~PAGE_MASK)
|
||||
static inline int pmd_bad(pmd_t pmd)
|
||||
{
|
||||
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
|
||||
/* pmd_huge(pmd) but inline */
|
||||
if (unlikely(pmd_val(pmd) & _PAGE_HUGE))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if (unlikely(pmd_val(pmd) & ~PAGE_MASK))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pmd_present(pmd_t pmd)
|
||||
{
|
||||
@ -146,6 +190,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
|
||||
#else
|
||||
#define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT))
|
||||
#define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot))
|
||||
#define pfn_pmd(pfn, prot) __pmd(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot))
|
||||
#endif
|
||||
#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */
|
||||
|
||||
@ -159,6 +204,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
|
||||
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
|
||||
|
||||
#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
|
||||
#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
|
||||
|
||||
/* to find an entry in a page-table-directory */
|
||||
#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
|
||||
@ -175,7 +221,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
|
||||
((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
|
||||
#define pte_unmap(pte) ((void)(pte))
|
||||
|
||||
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
|
||||
#if defined(CONFIG_CPU_R3K_TLB)
|
||||
|
||||
/* Swap entries must have VALID bit cleared. */
|
||||
#define __swp_type(x) (((x).val >> 10) & 0x1f)
|
||||
@ -220,6 +266,6 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
|
||||
|
||||
#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */
|
||||
|
||||
#endif /* defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) */
|
||||
#endif /* defined(CONFIG_CPU_R3K_TLB) */
|
||||
|
||||
#endif /* _ASM_PGTABLE_32_H */
|
||||
|
@ -52,6 +52,9 @@ enum pgtable_bits {
|
||||
_PAGE_WRITE_SHIFT,
|
||||
_PAGE_ACCESSED_SHIFT,
|
||||
_PAGE_MODIFIED_SHIFT,
|
||||
#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL)
|
||||
_PAGE_SPECIAL_SHIFT,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@ -78,9 +81,12 @@ enum pgtable_bits {
|
||||
_PAGE_WRITE_SHIFT,
|
||||
_PAGE_ACCESSED_SHIFT,
|
||||
_PAGE_MODIFIED_SHIFT,
|
||||
#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL)
|
||||
_PAGE_SPECIAL_SHIFT,
|
||||
#endif
|
||||
};
|
||||
|
||||
#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
|
||||
#elif defined(CONFIG_CPU_R3K_TLB)
|
||||
|
||||
/* Page table bits used for r3k systems */
|
||||
enum pgtable_bits {
|
||||
@ -90,6 +96,9 @@ enum pgtable_bits {
|
||||
_PAGE_WRITE_SHIFT,
|
||||
_PAGE_ACCESSED_SHIFT,
|
||||
_PAGE_MODIFIED_SHIFT,
|
||||
#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL)
|
||||
_PAGE_SPECIAL_SHIFT,
|
||||
#endif
|
||||
|
||||
/* Used by TLB hardware (placed in EntryLo) */
|
||||
_PAGE_GLOBAL_SHIFT = 8,
|
||||
@ -110,9 +119,12 @@ enum pgtable_bits {
|
||||
_PAGE_WRITE_SHIFT,
|
||||
_PAGE_ACCESSED_SHIFT,
|
||||
_PAGE_MODIFIED_SHIFT,
|
||||
#if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT)
|
||||
#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT)
|
||||
_PAGE_HUGE_SHIFT,
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL)
|
||||
_PAGE_SPECIAL_SHIFT,
|
||||
#endif
|
||||
|
||||
/* Used by TLB hardware (placed in EntryLo*) */
|
||||
#if defined(CONFIG_CPU_HAS_RIXI)
|
||||
@ -132,9 +144,14 @@ enum pgtable_bits {
|
||||
#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
|
||||
#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
|
||||
#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
|
||||
#if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT)
|
||||
#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT)
|
||||
# define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL)
|
||||
# define _PAGE_SPECIAL (1 << _PAGE_SPECIAL_SHIFT)
|
||||
#else
|
||||
# define _PAGE_SPECIAL 0
|
||||
#endif
|
||||
|
||||
/* Used by TLB hardware (placed in EntryLo*) */
|
||||
#if defined(CONFIG_XPA)
|
||||
@ -146,7 +163,7 @@ enum pgtable_bits {
|
||||
#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
|
||||
#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT)
|
||||
#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT)
|
||||
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
|
||||
#if defined(CONFIG_CPU_R3K_TLB)
|
||||
# define _CACHE_UNCACHED (1 << _CACHE_UNCACHED_SHIFT)
|
||||
# define _CACHE_MASK _CACHE_UNCACHED
|
||||
# define _PFN_SHIFT PAGE_SHIFT
|
||||
@ -204,7 +221,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val)
|
||||
/*
|
||||
* Cache attributes
|
||||
*/
|
||||
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
|
||||
#if defined(CONFIG_CPU_R3K_TLB)
|
||||
|
||||
#define _CACHE_CACHABLE_NONCOHERENT 0
|
||||
#define _CACHE_UNCACHED_ACCELERATED _CACHE_UNCACHED
|
||||
@ -216,13 +233,6 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val)
|
||||
|
||||
#define _CACHE_CACHABLE_NONCOHERENT (5<<_CACHE_SHIFT)
|
||||
|
||||
#elif defined(CONFIG_CPU_LOONGSON3)
|
||||
|
||||
/* Using COHERENT flag for NONCOHERENT doesn't hurt. */
|
||||
|
||||
#define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT) /* LOONGSON */
|
||||
#define _CACHE_CACHABLE_COHERENT (3<<_CACHE_SHIFT) /* LOONGSON-3 */
|
||||
|
||||
#elif defined(CONFIG_MACH_INGENIC)
|
||||
|
||||
/* Ingenic uses the WA bit to achieve write-combine memory writes */
|
||||
|
@ -199,7 +199,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
|
||||
static inline void set_pte(pte_t *ptep, pte_t pteval)
|
||||
{
|
||||
*ptep = pteval;
|
||||
#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
|
||||
#if !defined(CONFIG_CPU_R3K_TLB)
|
||||
if (pte_val(pteval) & _PAGE_GLOBAL) {
|
||||
pte_t *buddy = ptep_buddy(ptep);
|
||||
/*
|
||||
@ -218,7 +218,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
|
||||
static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
htw_stop();
|
||||
#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
|
||||
#if !defined(CONFIG_CPU_R3K_TLB)
|
||||
/* Preserve global status for the pair */
|
||||
if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
|
||||
set_pte_at(mm, addr, ptep, __pte(_PAGE_GLOBAL));
|
||||
@ -277,6 +277,7 @@ extern pgd_t swapper_pg_dir[];
|
||||
static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; }
|
||||
static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; }
|
||||
static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; }
|
||||
static inline int pte_special(pte_t pte) { return pte.pte_low & _PAGE_SPECIAL; }
|
||||
|
||||
static inline pte_t pte_wrprotect(pte_t pte)
|
||||
{
|
||||
@ -337,10 +338,17 @@ static inline pte_t pte_mkyoung(pte_t pte)
|
||||
}
|
||||
return pte;
|
||||
}
|
||||
|
||||
static inline pte_t pte_mkspecial(pte_t pte)
|
||||
{
|
||||
pte.pte_low |= _PAGE_SPECIAL;
|
||||
return pte;
|
||||
}
|
||||
#else
|
||||
static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
|
||||
static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; }
|
||||
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
|
||||
static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
|
||||
|
||||
static inline pte_t pte_wrprotect(pte_t pte)
|
||||
{
|
||||
@ -384,6 +392,12 @@ static inline pte_t pte_mkyoung(pte_t pte)
|
||||
return pte;
|
||||
}
|
||||
|
||||
static inline pte_t pte_mkspecial(pte_t pte)
|
||||
{
|
||||
pte_val(pte) |= _PAGE_SPECIAL;
|
||||
return pte;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
|
||||
static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_HUGE; }
|
||||
|
||||
@ -394,8 +408,6 @@ static inline pte_t pte_mkhuge(pte_t pte)
|
||||
}
|
||||
#endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */
|
||||
#endif
|
||||
static inline int pte_special(pte_t pte) { return 0; }
|
||||
static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
|
||||
|
||||
/*
|
||||
* Macro to make mark a page protection value as "uncacheable". Note
|
||||
|
@ -54,7 +54,7 @@ static inline void mips_syscall_update_nr(struct task_struct *task,
|
||||
task_thread_info(task)->syscall = regs->regs[2];
|
||||
}
|
||||
|
||||
static inline unsigned long mips_get_syscall_arg(unsigned long *arg,
|
||||
static inline void mips_get_syscall_arg(unsigned long *arg,
|
||||
struct task_struct *task, struct pt_regs *regs, unsigned int n)
|
||||
{
|
||||
unsigned long usp __maybe_unused = regs->regs[29];
|
||||
@ -63,23 +63,24 @@ static inline unsigned long mips_get_syscall_arg(unsigned long *arg,
|
||||
case 0: case 1: case 2: case 3:
|
||||
*arg = regs->regs[4 + n];
|
||||
|
||||
return 0;
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
case 4: case 5: case 6: case 7:
|
||||
return get_user(*arg, (int *)usp + n);
|
||||
get_user(*arg, (int *)usp + n);
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
case 4: case 5: case 6: case 7:
|
||||
#ifdef CONFIG_MIPS32_O32
|
||||
if (test_tsk_thread_flag(task, TIF_32BIT_REGS))
|
||||
return get_user(*arg, (int *)usp + n);
|
||||
get_user(*arg, (int *)usp + n);
|
||||
else
|
||||
#endif
|
||||
*arg = regs->regs[4 + n];
|
||||
|
||||
return 0;
|
||||
return;
|
||||
#endif
|
||||
|
||||
default:
|
||||
@ -126,21 +127,13 @@ static inline void syscall_get_arguments(struct task_struct *task,
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int n = 6;
|
||||
int ret;
|
||||
|
||||
/* O32 ABI syscall() */
|
||||
if (mips_syscall_is_indirect(task, regs))
|
||||
i++;
|
||||
|
||||
while (n--)
|
||||
ret |= mips_get_syscall_arg(args++, task, regs, i++);
|
||||
|
||||
/*
|
||||
* No way to communicate an error because this is a void function.
|
||||
*/
|
||||
#if 0
|
||||
return ret;
|
||||
#endif
|
||||
mips_get_syscall_arg(args++, task, regs, i++);
|
||||
}
|
||||
|
||||
extern const unsigned long sys_call_table[];
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define __ASM_VDSO_H
|
||||
|
||||
#include <linux/mm_types.h>
|
||||
#include <vdso/datapage.h>
|
||||
|
||||
#include <asm/barrier.h>
|
||||
|
||||
@ -49,84 +50,9 @@ extern struct mips_vdso_image vdso_image_o32;
|
||||
extern struct mips_vdso_image vdso_image_n32;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* union mips_vdso_data - Data provided by the kernel for the VDSO.
|
||||
* @xtime_sec: Current real time (seconds part).
|
||||
* @xtime_nsec: Current real time (nanoseconds part, shifted).
|
||||
* @wall_to_mono_sec: Wall-to-monotonic offset (seconds part).
|
||||
* @wall_to_mono_nsec: Wall-to-monotonic offset (nanoseconds part).
|
||||
* @seq_count: Counter to synchronise updates (odd = updating).
|
||||
* @cs_shift: Clocksource shift value.
|
||||
* @clock_mode: Clocksource to use for time functions.
|
||||
* @cs_mult: Clocksource multiplier value.
|
||||
* @cs_cycle_last: Clock cycle value at last update.
|
||||
* @cs_mask: Clocksource mask value.
|
||||
* @tz_minuteswest: Minutes west of Greenwich (from timezone).
|
||||
* @tz_dsttime: Type of DST correction (from timezone).
|
||||
*
|
||||
* This structure contains data needed by functions within the VDSO. It is
|
||||
* populated by the kernel and mapped read-only into user memory. The time
|
||||
* fields are mirrors of internal data from the timekeeping infrastructure.
|
||||
*
|
||||
* Note: Care should be taken when modifying as the layout must remain the same
|
||||
* for both 64- and 32-bit (for 32-bit userland on 64-bit kernel).
|
||||
*/
|
||||
union mips_vdso_data {
|
||||
struct {
|
||||
u64 xtime_sec;
|
||||
u64 xtime_nsec;
|
||||
u64 wall_to_mono_sec;
|
||||
u64 wall_to_mono_nsec;
|
||||
u32 seq_count;
|
||||
u32 cs_shift;
|
||||
u8 clock_mode;
|
||||
u32 cs_mult;
|
||||
u64 cs_cycle_last;
|
||||
u64 cs_mask;
|
||||
s32 tz_minuteswest;
|
||||
s32 tz_dsttime;
|
||||
};
|
||||
|
||||
struct vdso_data data[CS_BASES];
|
||||
u8 page[PAGE_SIZE];
|
||||
};
|
||||
|
||||
static inline u32 vdso_data_read_begin(const union mips_vdso_data *data)
|
||||
{
|
||||
u32 seq;
|
||||
|
||||
while (true) {
|
||||
seq = READ_ONCE(data->seq_count);
|
||||
if (likely(!(seq & 1))) {
|
||||
/* Paired with smp_wmb() in vdso_data_write_*(). */
|
||||
smp_rmb();
|
||||
return seq;
|
||||
}
|
||||
|
||||
cpu_relax();
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool vdso_data_read_retry(const union mips_vdso_data *data,
|
||||
u32 start_seq)
|
||||
{
|
||||
/* Paired with smp_wmb() in vdso_data_write_*(). */
|
||||
smp_rmb();
|
||||
return unlikely(data->seq_count != start_seq);
|
||||
}
|
||||
|
||||
static inline void vdso_data_write_begin(union mips_vdso_data *data)
|
||||
{
|
||||
++data->seq_count;
|
||||
|
||||
/* Ensure sequence update is written before other data page values. */
|
||||
smp_wmb();
|
||||
}
|
||||
|
||||
static inline void vdso_data_write_end(union mips_vdso_data *data)
|
||||
{
|
||||
/* Ensure data values are written before updating sequence again. */
|
||||
smp_wmb();
|
||||
++data->seq_count;
|
||||
}
|
||||
|
||||
#endif /* __ASM_VDSO_H */
|
||||
|
222
arch/mips/include/asm/vdso/gettimeofday.h
Normal file
222
arch/mips/include/asm/vdso/gettimeofday.h
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (C) 2018 ARM Limited
|
||||
* Copyright (C) 2015 Imagination Technologies
|
||||
* Author: Alex Smith <alex.smith@imgtec.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#ifndef __ASM_VDSO_GETTIMEOFDAY_H
|
||||
#define __ASM_VDSO_GETTIMEOFDAY_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include <asm/vdso/vdso.h>
|
||||
#include <asm/clocksource.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/vdso.h>
|
||||
|
||||
#define VDSO_HAS_CLOCK_GETRES 1
|
||||
|
||||
#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
|
||||
|
||||
static __always_inline long gettimeofday_fallback(
|
||||
struct __kernel_old_timeval *_tv,
|
||||
struct timezone *_tz)
|
||||
{
|
||||
register struct timezone *tz asm("a1") = _tz;
|
||||
register struct __kernel_old_timeval *tv asm("a0") = _tv;
|
||||
register long ret asm("v0");
|
||||
register long nr asm("v0") = __NR_gettimeofday;
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (tv), "r" (tz), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static __always_inline long gettimeofday_fallback(
|
||||
struct __kernel_old_timeval *_tv,
|
||||
struct timezone *_tz)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static __always_inline long clock_gettime_fallback(
|
||||
clockid_t _clkid,
|
||||
struct __kernel_timespec *_ts)
|
||||
{
|
||||
register struct __kernel_timespec *ts asm("a1") = _ts;
|
||||
register clockid_t clkid asm("a0") = _clkid;
|
||||
register long ret asm("v0");
|
||||
#if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
register long nr asm("v0") = __NR_clock_gettime;
|
||||
#else
|
||||
register long nr asm("v0") = __NR_clock_gettime64;
|
||||
#endif
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (clkid), "r" (ts), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
|
||||
static __always_inline int clock_getres_fallback(
|
||||
clockid_t _clkid,
|
||||
struct __kernel_timespec *_ts)
|
||||
{
|
||||
register struct __kernel_timespec *ts asm("a1") = _ts;
|
||||
register clockid_t clkid asm("a0") = _clkid;
|
||||
register long ret asm("v0");
|
||||
#if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
register long nr asm("v0") = __NR_clock_getres;
|
||||
#else
|
||||
register long nr asm("v0") = __NR_clock_getres_time64;
|
||||
#endif
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (clkid), "r" (ts), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
|
||||
#if _MIPS_SIM != _MIPS_SIM_ABI64
|
||||
|
||||
#define VDSO_HAS_32BIT_FALLBACK 1
|
||||
|
||||
static __always_inline long clock_gettime32_fallback(
|
||||
clockid_t _clkid,
|
||||
struct old_timespec32 *_ts)
|
||||
{
|
||||
register struct old_timespec32 *ts asm("a1") = _ts;
|
||||
register clockid_t clkid asm("a0") = _clkid;
|
||||
register long ret asm("v0");
|
||||
register long nr asm("v0") = __NR_clock_gettime;
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (clkid), "r" (ts), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
|
||||
static __always_inline int clock_getres32_fallback(
|
||||
clockid_t _clkid,
|
||||
struct old_timespec32 *_ts)
|
||||
{
|
||||
register struct old_timespec32 *ts asm("a1") = _ts;
|
||||
register clockid_t clkid asm("a0") = _clkid;
|
||||
register long ret asm("v0");
|
||||
register long nr asm("v0") = __NR_clock_getres;
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (clkid), "r" (ts), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CSRC_R4K
|
||||
|
||||
static __always_inline u64 read_r4k_count(void)
|
||||
{
|
||||
unsigned int count;
|
||||
|
||||
__asm__ __volatile__(
|
||||
" .set push\n"
|
||||
" .set mips32r2\n"
|
||||
" rdhwr %0, $2\n"
|
||||
" .set pop\n"
|
||||
: "=r" (count));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CLKSRC_MIPS_GIC
|
||||
|
||||
static __always_inline u64 read_gic_count(const struct vdso_data *data)
|
||||
{
|
||||
void __iomem *gic = get_gic(data);
|
||||
u32 hi, hi2, lo;
|
||||
|
||||
do {
|
||||
hi = __raw_readl(gic + sizeof(lo));
|
||||
lo = __raw_readl(gic);
|
||||
hi2 = __raw_readl(gic + sizeof(lo));
|
||||
} while (hi2 != hi);
|
||||
|
||||
return (((u64)hi) << 32) + lo;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
|
||||
{
|
||||
#ifdef CONFIG_CLKSRC_MIPS_GIC
|
||||
const struct vdso_data *data = get_vdso_data();
|
||||
#endif
|
||||
u64 cycle_now;
|
||||
|
||||
switch (clock_mode) {
|
||||
#ifdef CONFIG_CSRC_R4K
|
||||
case VDSO_CLOCK_R4K:
|
||||
cycle_now = read_r4k_count();
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_CLKSRC_MIPS_GIC
|
||||
case VDSO_CLOCK_GIC:
|
||||
cycle_now = read_gic_count(data);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cycle_now = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return cycle_now;
|
||||
}
|
||||
|
||||
static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
|
||||
{
|
||||
return get_vdso_data();
|
||||
}
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
|
@ -6,17 +6,6 @@
|
||||
|
||||
#include <asm/sgidefs.h>
|
||||
|
||||
#if _MIPS_SIM != _MIPS_SIM_ABI64 && defined(CONFIG_64BIT)
|
||||
|
||||
/* Building 32-bit VDSO for the 64-bit kernel. Fake a 32-bit Kconfig. */
|
||||
#define BUILD_VDSO32_64
|
||||
#undef CONFIG_64BIT
|
||||
#define CONFIG_32BIT 1
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm-generic/atomic64.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <asm/asm.h>
|
||||
@ -69,14 +58,14 @@ static inline unsigned long get_vdso_base(void)
|
||||
return addr;
|
||||
}
|
||||
|
||||
static inline const union mips_vdso_data *get_vdso_data(void)
|
||||
static inline const struct vdso_data *get_vdso_data(void)
|
||||
{
|
||||
return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE);
|
||||
return (const struct vdso_data *)(get_vdso_base() - PAGE_SIZE);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CLKSRC_MIPS_GIC
|
||||
|
||||
static inline void __iomem *get_gic(const union mips_vdso_data *data)
|
||||
static inline void __iomem *get_gic(const struct vdso_data *data)
|
||||
{
|
||||
return (void __iomem *)data - PAGE_SIZE;
|
||||
}
|
43
arch/mips/include/asm/vdso/vsyscall.h
Normal file
43
arch/mips/include/asm/vdso/vsyscall.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_VDSO_VSYSCALL_H
|
||||
#define __ASM_VDSO_VSYSCALL_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/timekeeper_internal.h>
|
||||
#include <vdso/datapage.h>
|
||||
|
||||
extern struct vdso_data *vdso_data;
|
||||
|
||||
/*
|
||||
* Update the vDSO data page to keep in sync with kernel timekeeping.
|
||||
*/
|
||||
static __always_inline
|
||||
struct vdso_data *__mips_get_k_vdso_data(void)
|
||||
{
|
||||
return vdso_data;
|
||||
}
|
||||
#define __arch_get_k_vdso_data __mips_get_k_vdso_data
|
||||
|
||||
static __always_inline
|
||||
int __mips_get_clock_mode(struct timekeeper *tk)
|
||||
{
|
||||
u32 clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode;
|
||||
|
||||
return clock_mode;
|
||||
}
|
||||
#define __arch_get_clock_mode __mips_get_clock_mode
|
||||
|
||||
static __always_inline
|
||||
int __mips_use_vsyscall(struct vdso_data *vdata)
|
||||
{
|
||||
return (vdata[CS_HRES_COARSE].clock_mode != VDSO_CLOCK_NONE);
|
||||
}
|
||||
#define __arch_use_vsyscall __mips_use_vsyscall
|
||||
|
||||
/* The asm-generic header needs to be included after the definitions above */
|
||||
#include <asm-generic/vdso/vsyscall.h>
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_VDSO_VSYSCALL_H */
|
@ -128,19 +128,6 @@
|
||||
#error Check setting of R4600_V2_HIT_CACHEOP_WAR for your platform
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When an interrupt happens on a CP0 register read instruction, CPU may
|
||||
* lock up or read corrupted values of CP0 registers after it enters
|
||||
* the exception handler.
|
||||
*
|
||||
* This workaround makes sure that we read a "safe" CP0 register as the
|
||||
* first thing in the exception handler, which breaks one of the
|
||||
* pre-conditions for this problem.
|
||||
*/
|
||||
#ifndef R5432_CP0_INTERRUPT_WAR
|
||||
#error Check setting of R5432_CP0_INTERRUPT_WAR for your platform
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Workaround for the Sibyte M3 errata the text of which can be found at
|
||||
*
|
||||
|
@ -5,15 +5,10 @@
|
||||
|
||||
# Object file lists.
|
||||
|
||||
obj-y += prom.o time.o reset.o setup.o \
|
||||
platform.o timer.o
|
||||
obj-y += prom.o time.o reset.o setup.o timer.o
|
||||
|
||||
CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
|
||||
|
||||
# board specific support
|
||||
|
||||
obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
|
||||
|
||||
# PM support
|
||||
|
||||
obj-$(CONFIG_PM) += pm.o
|
||||
|
@ -1,523 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* linux/arch/mips/jz4740/board-qi_lb60.c
|
||||
*
|
||||
* QI_LB60 board support
|
||||
*
|
||||
* Copyright (c) 2009 Qi Hardware inc.,
|
||||
* Author: Xiangfu Liu <xiangfu@qi-hardware.com>
|
||||
* Copyright 2010, Lars-Peter Clausen <lars@metafoo.de>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/input/matrix_keypad.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spi_gpio.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <linux/pinctrl/pinconf-generic.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/power/jz4740-battery.h>
|
||||
#include <linux/power/gpio-charger.h>
|
||||
#include <linux/pwm.h>
|
||||
|
||||
#include <linux/platform_data/jz4740/jz4740_nand.h>
|
||||
|
||||
#include <asm/mach-jz4740/gpio.h>
|
||||
#include <asm/mach-jz4740/jz4740_fb.h>
|
||||
#include <asm/mach-jz4740/jz4740_mmc.h>
|
||||
|
||||
#include <linux/regulator/fixed.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
|
||||
#include <asm/mach-jz4740/platform.h>
|
||||
|
||||
/* GPIOs */
|
||||
#define QI_LB60_GPIO_KEYOUT(x) (JZ_GPIO_PORTC(10) + (x))
|
||||
#define QI_LB60_GPIO_KEYIN(x) (JZ_GPIO_PORTD(18) + (x))
|
||||
#define QI_LB60_GPIO_KEYIN8 JZ_GPIO_PORTD(26)
|
||||
|
||||
/* NAND */
|
||||
|
||||
/* Early prototypes of the QI LB60 had only 1GB of NAND.
|
||||
* In order to support these devices as well the partition and ecc layout is
|
||||
* initialized depending on the NAND size */
|
||||
static struct mtd_partition qi_lb60_partitions_1gb[] = {
|
||||
{
|
||||
.name = "NAND BOOT partition",
|
||||
.offset = 0 * 0x100000,
|
||||
.size = 4 * 0x100000,
|
||||
},
|
||||
{
|
||||
.name = "NAND KERNEL partition",
|
||||
.offset = 4 * 0x100000,
|
||||
.size = 4 * 0x100000,
|
||||
},
|
||||
{
|
||||
.name = "NAND ROOTFS partition",
|
||||
.offset = 8 * 0x100000,
|
||||
.size = (504 + 512) * 0x100000,
|
||||
},
|
||||
};
|
||||
|
||||
static struct mtd_partition qi_lb60_partitions_2gb[] = {
|
||||
{
|
||||
.name = "NAND BOOT partition",
|
||||
.offset = 0 * 0x100000,
|
||||
.size = 4 * 0x100000,
|
||||
},
|
||||
{
|
||||
.name = "NAND KERNEL partition",
|
||||
.offset = 4 * 0x100000,
|
||||
.size = 4 * 0x100000,
|
||||
},
|
||||
{
|
||||
.name = "NAND ROOTFS partition",
|
||||
.offset = 8 * 0x100000,
|
||||
.size = (504 + 512 + 1024) * 0x100000,
|
||||
},
|
||||
};
|
||||
|
||||
static int qi_lb60_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *oobregion)
|
||||
{
|
||||
if (section)
|
||||
return -ERANGE;
|
||||
|
||||
oobregion->length = 36;
|
||||
oobregion->offset = 6;
|
||||
|
||||
if (mtd->oobsize == 128) {
|
||||
oobregion->length *= 2;
|
||||
oobregion->offset *= 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qi_lb60_ooblayout_free(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *oobregion)
|
||||
{
|
||||
int eccbytes = 36, eccoff = 6;
|
||||
|
||||
if (section > 1)
|
||||
return -ERANGE;
|
||||
|
||||
if (mtd->oobsize == 128) {
|
||||
eccbytes *= 2;
|
||||
eccoff *= 2;
|
||||
}
|
||||
|
||||
if (!section) {
|
||||
oobregion->offset = 2;
|
||||
oobregion->length = eccoff - 2;
|
||||
} else {
|
||||
oobregion->offset = eccoff + eccbytes;
|
||||
oobregion->length = mtd->oobsize - oobregion->offset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mtd_ooblayout_ops qi_lb60_ooblayout_ops = {
|
||||
.ecc = qi_lb60_ooblayout_ecc,
|
||||
.free = qi_lb60_ooblayout_free,
|
||||
};
|
||||
|
||||
static void qi_lb60_nand_ident(struct platform_device *pdev,
|
||||
struct mtd_info *mtd, struct mtd_partition **partitions,
|
||||
int *num_partitions)
|
||||
{
|
||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
||||
|
||||
if (chip->page_shift == 12) {
|
||||
*partitions = qi_lb60_partitions_2gb;
|
||||
*num_partitions = ARRAY_SIZE(qi_lb60_partitions_2gb);
|
||||
} else {
|
||||
*partitions = qi_lb60_partitions_1gb;
|
||||
*num_partitions = ARRAY_SIZE(qi_lb60_partitions_1gb);
|
||||
}
|
||||
|
||||
mtd_set_ooblayout(mtd, &qi_lb60_ooblayout_ops);
|
||||
}
|
||||
|
||||
static struct jz_nand_platform_data qi_lb60_nand_pdata = {
|
||||
.ident_callback = qi_lb60_nand_ident,
|
||||
.banks = { 1 },
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table qi_lb60_nand_gpio_table = {
|
||||
.dev_id = "jz4740-nand.0",
|
||||
.table = {
|
||||
GPIO_LOOKUP("GPIOC", 30, "busy", 0),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/* Keyboard*/
|
||||
|
||||
#define KEY_QI_QI KEY_F13
|
||||
#define KEY_QI_UPRED KEY_RIGHTALT
|
||||
#define KEY_QI_VOLUP KEY_VOLUMEUP
|
||||
#define KEY_QI_VOLDOWN KEY_VOLUMEDOWN
|
||||
#define KEY_QI_FN KEY_LEFTCTRL
|
||||
|
||||
static const uint32_t qi_lb60_keymap[] = {
|
||||
KEY(0, 0, KEY_F1), /* S2 */
|
||||
KEY(0, 1, KEY_F2), /* S3 */
|
||||
KEY(0, 2, KEY_F3), /* S4 */
|
||||
KEY(0, 3, KEY_F4), /* S5 */
|
||||
KEY(0, 4, KEY_F5), /* S6 */
|
||||
KEY(0, 5, KEY_F6), /* S7 */
|
||||
KEY(0, 6, KEY_F7), /* S8 */
|
||||
|
||||
KEY(1, 0, KEY_Q), /* S10 */
|
||||
KEY(1, 1, KEY_W), /* S11 */
|
||||
KEY(1, 2, KEY_E), /* S12 */
|
||||
KEY(1, 3, KEY_R), /* S13 */
|
||||
KEY(1, 4, KEY_T), /* S14 */
|
||||
KEY(1, 5, KEY_Y), /* S15 */
|
||||
KEY(1, 6, KEY_U), /* S16 */
|
||||
KEY(1, 7, KEY_I), /* S17 */
|
||||
KEY(2, 0, KEY_A), /* S18 */
|
||||
KEY(2, 1, KEY_S), /* S19 */
|
||||
KEY(2, 2, KEY_D), /* S20 */
|
||||
KEY(2, 3, KEY_F), /* S21 */
|
||||
KEY(2, 4, KEY_G), /* S22 */
|
||||
KEY(2, 5, KEY_H), /* S23 */
|
||||
KEY(2, 6, KEY_J), /* S24 */
|
||||
KEY(2, 7, KEY_K), /* S25 */
|
||||
KEY(3, 0, KEY_ESC), /* S26 */
|
||||
KEY(3, 1, KEY_Z), /* S27 */
|
||||
KEY(3, 2, KEY_X), /* S28 */
|
||||
KEY(3, 3, KEY_C), /* S29 */
|
||||
KEY(3, 4, KEY_V), /* S30 */
|
||||
KEY(3, 5, KEY_B), /* S31 */
|
||||
KEY(3, 6, KEY_N), /* S32 */
|
||||
KEY(3, 7, KEY_M), /* S33 */
|
||||
KEY(4, 0, KEY_TAB), /* S34 */
|
||||
KEY(4, 1, KEY_CAPSLOCK), /* S35 */
|
||||
KEY(4, 2, KEY_BACKSLASH), /* S36 */
|
||||
KEY(4, 3, KEY_APOSTROPHE), /* S37 */
|
||||
KEY(4, 4, KEY_COMMA), /* S38 */
|
||||
KEY(4, 5, KEY_DOT), /* S39 */
|
||||
KEY(4, 6, KEY_SLASH), /* S40 */
|
||||
KEY(4, 7, KEY_UP), /* S41 */
|
||||
KEY(5, 0, KEY_O), /* S42 */
|
||||
KEY(5, 1, KEY_L), /* S43 */
|
||||
KEY(5, 2, KEY_EQUAL), /* S44 */
|
||||
KEY(5, 3, KEY_QI_UPRED), /* S45 */
|
||||
KEY(5, 4, KEY_SPACE), /* S46 */
|
||||
KEY(5, 5, KEY_QI_QI), /* S47 */
|
||||
KEY(5, 6, KEY_RIGHTCTRL), /* S48 */
|
||||
KEY(5, 7, KEY_LEFT), /* S49 */
|
||||
KEY(6, 0, KEY_F8), /* S50 */
|
||||
KEY(6, 1, KEY_P), /* S51 */
|
||||
KEY(6, 2, KEY_BACKSPACE),/* S52 */
|
||||
KEY(6, 3, KEY_ENTER), /* S53 */
|
||||
KEY(6, 4, KEY_QI_VOLUP), /* S54 */
|
||||
KEY(6, 5, KEY_QI_VOLDOWN), /* S55 */
|
||||
KEY(6, 6, KEY_DOWN), /* S56 */
|
||||
KEY(6, 7, KEY_RIGHT), /* S57 */
|
||||
|
||||
KEY(7, 0, KEY_LEFTSHIFT), /* S58 */
|
||||
KEY(7, 1, KEY_LEFTALT), /* S59 */
|
||||
KEY(7, 2, KEY_QI_FN), /* S60 */
|
||||
};
|
||||
|
||||
static const struct matrix_keymap_data qi_lb60_keymap_data = {
|
||||
.keymap = qi_lb60_keymap,
|
||||
.keymap_size = ARRAY_SIZE(qi_lb60_keymap),
|
||||
};
|
||||
|
||||
static const unsigned int qi_lb60_keypad_cols[] = {
|
||||
QI_LB60_GPIO_KEYOUT(0),
|
||||
QI_LB60_GPIO_KEYOUT(1),
|
||||
QI_LB60_GPIO_KEYOUT(2),
|
||||
QI_LB60_GPIO_KEYOUT(3),
|
||||
QI_LB60_GPIO_KEYOUT(4),
|
||||
QI_LB60_GPIO_KEYOUT(5),
|
||||
QI_LB60_GPIO_KEYOUT(6),
|
||||
QI_LB60_GPIO_KEYOUT(7),
|
||||
};
|
||||
|
||||
static const unsigned int qi_lb60_keypad_rows[] = {
|
||||
QI_LB60_GPIO_KEYIN(0),
|
||||
QI_LB60_GPIO_KEYIN(1),
|
||||
QI_LB60_GPIO_KEYIN(2),
|
||||
QI_LB60_GPIO_KEYIN(3),
|
||||
QI_LB60_GPIO_KEYIN(4),
|
||||
QI_LB60_GPIO_KEYIN(5),
|
||||
QI_LB60_GPIO_KEYIN(6),
|
||||
QI_LB60_GPIO_KEYIN8,
|
||||
};
|
||||
|
||||
static struct matrix_keypad_platform_data qi_lb60_pdata = {
|
||||
.keymap_data = &qi_lb60_keymap_data,
|
||||
.col_gpios = qi_lb60_keypad_cols,
|
||||
.row_gpios = qi_lb60_keypad_rows,
|
||||
.num_col_gpios = ARRAY_SIZE(qi_lb60_keypad_cols),
|
||||
.num_row_gpios = ARRAY_SIZE(qi_lb60_keypad_rows),
|
||||
.col_scan_delay_us = 10,
|
||||
.debounce_ms = 10,
|
||||
.wakeup = 1,
|
||||
.active_low = 1,
|
||||
};
|
||||
|
||||
static struct platform_device qi_lb60_keypad = {
|
||||
.name = "matrix-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &qi_lb60_pdata,
|
||||
},
|
||||
};
|
||||
|
||||
/* Display */
|
||||
static struct fb_videomode qi_lb60_video_modes[] = {
|
||||
{
|
||||
.name = "320x240",
|
||||
.xres = 320,
|
||||
.yres = 240,
|
||||
.refresh = 30,
|
||||
.left_margin = 140,
|
||||
.right_margin = 273,
|
||||
.upper_margin = 20,
|
||||
.lower_margin = 2,
|
||||
.hsync_len = 1,
|
||||
.vsync_len = 1,
|
||||
.sync = 0,
|
||||
.vmode = FB_VMODE_NONINTERLACED,
|
||||
},
|
||||
};
|
||||
|
||||
static struct jz4740_fb_platform_data qi_lb60_fb_pdata = {
|
||||
.width = 60,
|
||||
.height = 45,
|
||||
.num_modes = ARRAY_SIZE(qi_lb60_video_modes),
|
||||
.modes = qi_lb60_video_modes,
|
||||
.bpp = 24,
|
||||
.lcd_type = JZ_LCD_TYPE_8BIT_SERIAL,
|
||||
.pixclk_falling_edge = 1,
|
||||
};
|
||||
|
||||
struct spi_gpio_platform_data qi_lb60_spigpio_platform_data = {
|
||||
.num_chipselect = 1,
|
||||
};
|
||||
|
||||
static struct platform_device qi_lb60_spigpio_device = {
|
||||
.name = "spi_gpio",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &qi_lb60_spigpio_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table qi_lb60_spigpio_gpio_table = {
|
||||
.dev_id = "spi_gpio",
|
||||
.table = {
|
||||
GPIO_LOOKUP("GPIOC", 23,
|
||||
"sck", GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("GPIOC", 22,
|
||||
"mosi", GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("GPIOC", 21,
|
||||
"cs", GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static struct spi_board_info qi_lb60_spi_board_info[] = {
|
||||
{
|
||||
.modalias = "ili8960",
|
||||
.chip_select = 0,
|
||||
.bus_num = 1,
|
||||
.max_speed_hz = 30 * 1000,
|
||||
.mode = SPI_3WIRE,
|
||||
},
|
||||
};
|
||||
|
||||
/* Battery */
|
||||
static struct jz_battery_platform_data qi_lb60_battery_pdata = {
|
||||
.gpio_charge = JZ_GPIO_PORTC(27),
|
||||
.gpio_charge_active_low = 1,
|
||||
.info = {
|
||||
.name = "battery",
|
||||
.technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
|
||||
.voltage_max_design = 4200000,
|
||||
.voltage_min_design = 3600000,
|
||||
},
|
||||
};
|
||||
|
||||
/* GPIO Key: power */
|
||||
static struct gpio_keys_button qi_lb60_gpio_keys_buttons[] = {
|
||||
[0] = {
|
||||
.code = KEY_POWER,
|
||||
.gpio = JZ_GPIO_PORTD(29),
|
||||
.active_low = 1,
|
||||
.desc = "Power",
|
||||
.wakeup = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data qi_lb60_gpio_keys_data = {
|
||||
.nbuttons = ARRAY_SIZE(qi_lb60_gpio_keys_buttons),
|
||||
.buttons = qi_lb60_gpio_keys_buttons,
|
||||
};
|
||||
|
||||
static struct platform_device qi_lb60_gpio_keys = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &qi_lb60_gpio_keys_data,
|
||||
}
|
||||
};
|
||||
|
||||
static struct jz4740_mmc_platform_data qi_lb60_mmc_pdata = {
|
||||
/* Intentionally left blank */
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table qi_lb60_mmc_gpio_table = {
|
||||
.dev_id = "jz4740-mmc.0",
|
||||
.table = {
|
||||
GPIO_LOOKUP("GPIOD", 0, "cd", GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("GPIOD", 2, "power", GPIO_ACTIVE_LOW),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
/* beeper */
|
||||
static struct pwm_lookup qi_lb60_pwm_lookup[] = {
|
||||
PWM_LOOKUP("jz4740-pwm", 4, "pwm-beeper", NULL, 0,
|
||||
PWM_POLARITY_NORMAL),
|
||||
};
|
||||
|
||||
static struct platform_device qi_lb60_pwm_beeper = {
|
||||
.name = "pwm-beeper",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
/* charger */
|
||||
static char *qi_lb60_batteries[] = {
|
||||
"battery",
|
||||
};
|
||||
|
||||
static struct gpio_charger_platform_data qi_lb60_charger_pdata = {
|
||||
.name = "usb",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.gpio = JZ_GPIO_PORTD(28),
|
||||
.gpio_active_low = 1,
|
||||
.supplied_to = qi_lb60_batteries,
|
||||
.num_supplicants = ARRAY_SIZE(qi_lb60_batteries),
|
||||
};
|
||||
|
||||
static struct platform_device qi_lb60_charger_device = {
|
||||
.name = "gpio-charger",
|
||||
.dev = {
|
||||
.platform_data = &qi_lb60_charger_pdata,
|
||||
},
|
||||
};
|
||||
|
||||
/* audio */
|
||||
static struct platform_device qi_lb60_audio_device = {
|
||||
.name = "qi-lb60-audio",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table qi_lb60_audio_gpio_table = {
|
||||
.dev_id = "qi-lb60-audio",
|
||||
.table = {
|
||||
GPIO_LOOKUP("GPIOB", 29, "snd", 0),
|
||||
GPIO_LOOKUP("GPIOD", 4, "amp", 0),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *jz_platform_devices[] __initdata = {
|
||||
&jz4740_udc_device,
|
||||
&jz4740_udc_xceiv_device,
|
||||
&jz4740_mmc_device,
|
||||
&jz4740_nand_device,
|
||||
&qi_lb60_keypad,
|
||||
&qi_lb60_spigpio_device,
|
||||
&jz4740_framebuffer_device,
|
||||
&jz4740_pcm_device,
|
||||
&jz4740_i2s_device,
|
||||
&jz4740_codec_device,
|
||||
&jz4740_adc_device,
|
||||
&jz4740_pwm_device,
|
||||
&jz4740_dma_device,
|
||||
&qi_lb60_gpio_keys,
|
||||
&qi_lb60_pwm_beeper,
|
||||
&qi_lb60_charger_device,
|
||||
&qi_lb60_audio_device,
|
||||
};
|
||||
|
||||
static unsigned long pin_cfg_bias_disable[] = {
|
||||
PIN_CONFIG_BIAS_DISABLE,
|
||||
};
|
||||
|
||||
static struct pinctrl_map pin_map[] __initdata = {
|
||||
/* NAND pin configuration */
|
||||
PIN_MAP_MUX_GROUP_DEFAULT("jz4740-nand",
|
||||
"10010000.pin-controller", "nand-cs1", "nand"),
|
||||
|
||||
/* fbdev pin configuration */
|
||||
PIN_MAP_MUX_GROUP("jz4740-fb", PINCTRL_STATE_DEFAULT,
|
||||
"10010000.pin-controller", "lcd-8bit", "lcd"),
|
||||
PIN_MAP_MUX_GROUP("jz4740-fb", PINCTRL_STATE_SLEEP,
|
||||
"10010000.pin-controller", "lcd-no-pins", "lcd"),
|
||||
|
||||
/* MMC pin configuration */
|
||||
PIN_MAP_MUX_GROUP_DEFAULT("jz4740-mmc.0",
|
||||
"10010000.pin-controller", "mmc-1bit", "mmc"),
|
||||
PIN_MAP_MUX_GROUP_DEFAULT("jz4740-mmc.0",
|
||||
"10010000.pin-controller", "mmc-4bit", "mmc"),
|
||||
PIN_MAP_CONFIGS_PIN_DEFAULT("jz4740-mmc.0",
|
||||
"10010000.pin-controller", "PD0", pin_cfg_bias_disable),
|
||||
PIN_MAP_CONFIGS_PIN_DEFAULT("jz4740-mmc.0",
|
||||
"10010000.pin-controller", "PD2", pin_cfg_bias_disable),
|
||||
|
||||
/* PWM pin configuration */
|
||||
PIN_MAP_MUX_GROUP_DEFAULT("jz4740-pwm",
|
||||
"10010000.pin-controller", "pwm4", "pwm4"),
|
||||
};
|
||||
|
||||
|
||||
static int __init qi_lb60_init_platform_devices(void)
|
||||
{
|
||||
jz4740_framebuffer_device.dev.platform_data = &qi_lb60_fb_pdata;
|
||||
jz4740_nand_device.dev.platform_data = &qi_lb60_nand_pdata;
|
||||
jz4740_adc_device.dev.platform_data = &qi_lb60_battery_pdata;
|
||||
jz4740_mmc_device.dev.platform_data = &qi_lb60_mmc_pdata;
|
||||
|
||||
gpiod_add_lookup_table(&qi_lb60_audio_gpio_table);
|
||||
gpiod_add_lookup_table(&qi_lb60_nand_gpio_table);
|
||||
gpiod_add_lookup_table(&qi_lb60_spigpio_gpio_table);
|
||||
gpiod_add_lookup_table(&qi_lb60_mmc_gpio_table);
|
||||
|
||||
spi_register_board_info(qi_lb60_spi_board_info,
|
||||
ARRAY_SIZE(qi_lb60_spi_board_info));
|
||||
|
||||
pwm_add_table(qi_lb60_pwm_lookup, ARRAY_SIZE(qi_lb60_pwm_lookup));
|
||||
pinctrl_register_mappings(pin_map, ARRAY_SIZE(pin_map));
|
||||
|
||||
return platform_add_devices(jz_platform_devices,
|
||||
ARRAY_SIZE(jz_platform_devices));
|
||||
|
||||
}
|
||||
|
||||
static int __init qi_lb60_board_setup(void)
|
||||
{
|
||||
printk(KERN_INFO "Qi Hardware JZ4740 QI LB60 setup\n");
|
||||
|
||||
if (qi_lb60_init_platform_devices())
|
||||
panic("Failed to initialize platform devices");
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(qi_lb60_board_setup);
|
@ -1,250 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
|
||||
* JZ4740 platform devices
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/resource.h>
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <linux/usb/musb.h>
|
||||
|
||||
#include <asm/mach-jz4740/platform.h>
|
||||
#include <asm/mach-jz4740/base.h>
|
||||
#include <asm/mach-jz4740/irq.h>
|
||||
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial_8250.h>
|
||||
|
||||
/* USB Device Controller */
|
||||
struct platform_device jz4740_udc_xceiv_device = {
|
||||
.name = "usb_phy_generic",
|
||||
.id = 0,
|
||||
};
|
||||
|
||||
static struct resource jz4740_udc_resources[] = {
|
||||
[0] = {
|
||||
.start = JZ4740_UDC_BASE_ADDR,
|
||||
.end = JZ4740_UDC_BASE_ADDR + 0x10000 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = JZ4740_IRQ_UDC,
|
||||
.end = JZ4740_IRQ_UDC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
.name = "mc",
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device jz4740_udc_device = {
|
||||
.name = "musb-jz4740",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.dma_mask = &jz4740_udc_device.dev.coherent_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(jz4740_udc_resources),
|
||||
.resource = jz4740_udc_resources,
|
||||
};
|
||||
|
||||
/* MMC/SD controller */
|
||||
static struct resource jz4740_mmc_resources[] = {
|
||||
{
|
||||
.start = JZ4740_MSC_BASE_ADDR,
|
||||
.end = JZ4740_MSC_BASE_ADDR + 0x1000 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = JZ4740_IRQ_MSC,
|
||||
.end = JZ4740_IRQ_MSC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
struct platform_device jz4740_mmc_device = {
|
||||
.name = "jz4740-mmc",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.dma_mask = &jz4740_mmc_device.dev.coherent_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(jz4740_mmc_resources),
|
||||
.resource = jz4740_mmc_resources,
|
||||
};
|
||||
|
||||
/* I2C controller */
|
||||
static struct resource jz4740_i2c_resources[] = {
|
||||
{
|
||||
.start = JZ4740_I2C_BASE_ADDR,
|
||||
.end = JZ4740_I2C_BASE_ADDR + 0x1000 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = JZ4740_IRQ_I2C,
|
||||
.end = JZ4740_IRQ_I2C,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
struct platform_device jz4740_i2c_device = {
|
||||
.name = "jz4740-i2c",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(jz4740_i2c_resources),
|
||||
.resource = jz4740_i2c_resources,
|
||||
};
|
||||
|
||||
/* NAND controller */
|
||||
static struct resource jz4740_nand_resources[] = {
|
||||
{
|
||||
.name = "mmio",
|
||||
.start = JZ4740_EMC_BASE_ADDR,
|
||||
.end = JZ4740_EMC_BASE_ADDR + 0x1000 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "bank1",
|
||||
.start = 0x18000000,
|
||||
.end = 0x180C0000 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "bank2",
|
||||
.start = 0x14000000,
|
||||
.end = 0x140C0000 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "bank3",
|
||||
.start = 0x0C000000,
|
||||
.end = 0x0C0C0000 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "bank4",
|
||||
.start = 0x08000000,
|
||||
.end = 0x080C0000 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device jz4740_nand_device = {
|
||||
.name = "jz4740-nand",
|
||||
.num_resources = ARRAY_SIZE(jz4740_nand_resources),
|
||||
.resource = jz4740_nand_resources,
|
||||
};
|
||||
|
||||
/* LCD controller */
|
||||
static struct resource jz4740_framebuffer_resources[] = {
|
||||
{
|
||||
.start = JZ4740_LCD_BASE_ADDR,
|
||||
.end = JZ4740_LCD_BASE_ADDR + 0x1000 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device jz4740_framebuffer_device = {
|
||||
.name = "jz4740-fb",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(jz4740_framebuffer_resources),
|
||||
.resource = jz4740_framebuffer_resources,
|
||||
.dev = {
|
||||
.dma_mask = &jz4740_framebuffer_device.dev.coherent_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
},
|
||||
};
|
||||
|
||||
/* I2S controller */
|
||||
static struct resource jz4740_i2s_resources[] = {
|
||||
{
|
||||
.start = JZ4740_AIC_BASE_ADDR,
|
||||
.end = JZ4740_AIC_BASE_ADDR + 0x38 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device jz4740_i2s_device = {
|
||||
.name = "jz4740-i2s",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(jz4740_i2s_resources),
|
||||
.resource = jz4740_i2s_resources,
|
||||
};
|
||||
|
||||
/* PCM */
|
||||
struct platform_device jz4740_pcm_device = {
|
||||
.name = "jz4740-pcm-audio",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
/* Codec */
|
||||
static struct resource jz4740_codec_resources[] = {
|
||||
{
|
||||
.start = JZ4740_AIC_BASE_ADDR + 0x80,
|
||||
.end = JZ4740_AIC_BASE_ADDR + 0x88 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device jz4740_codec_device = {
|
||||
.name = "jz4740-codec",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(jz4740_codec_resources),
|
||||
.resource = jz4740_codec_resources,
|
||||
};
|
||||
|
||||
/* ADC controller */
|
||||
static struct resource jz4740_adc_resources[] = {
|
||||
{
|
||||
.start = JZ4740_SADC_BASE_ADDR,
|
||||
.end = JZ4740_SADC_BASE_ADDR + 0x30,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = JZ4740_IRQ_SADC,
|
||||
.end = JZ4740_IRQ_SADC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = JZ4740_IRQ_ADC_BASE,
|
||||
.end = JZ4740_IRQ_ADC_BASE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device jz4740_adc_device = {
|
||||
.name = "jz4740-adc",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(jz4740_adc_resources),
|
||||
.resource = jz4740_adc_resources,
|
||||
};
|
||||
|
||||
/* PWM */
|
||||
struct platform_device jz4740_pwm_device = {
|
||||
.name = "jz4740-pwm",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
/* DMA */
|
||||
static struct resource jz4740_dma_resources[] = {
|
||||
{
|
||||
.start = JZ4740_DMAC_BASE_ADDR,
|
||||
.end = JZ4740_DMAC_BASE_ADDR + 0x400 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = JZ4740_IRQ_DMAC,
|
||||
.end = JZ4740_IRQ_DMAC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device jz4740_dma_device = {
|
||||
.name = "jz4740-dma",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(jz4740_dma_resources),
|
||||
.resource = jz4740_dma_resources,
|
||||
};
|
@ -4,15 +4,10 @@
|
||||
* JZ4740 SoC prom code
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <linux/serial_reg.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/fw/fw.h>
|
||||
#include <asm/mach-jz4740/base.h>
|
||||
|
||||
void __init prom_init(void)
|
||||
{
|
||||
|
@ -15,10 +15,9 @@
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
#include <asm/mach-jz4740/base.h>
|
||||
|
||||
#include "reset.h"
|
||||
|
||||
#define JZ4740_EMC_BASE_ADDR 0x13010000
|
||||
|
||||
#define JZ4740_EMC_SDRAM_CTRL 0x80
|
||||
|
||||
@ -45,6 +44,8 @@ static void __init jz4740_detect_mem(void)
|
||||
|
||||
static unsigned long __init get_board_mach_type(const void *fdt)
|
||||
{
|
||||
if (!fdt_node_check_compatible(fdt, 0, "ingenic,x1000"))
|
||||
return MACH_INGENIC_X1000;
|
||||
if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4780"))
|
||||
return MACH_INGENIC_JZ4780;
|
||||
if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4770"))
|
||||
@ -85,6 +86,8 @@ void __init device_tree_init(void)
|
||||
const char *get_system_type(void)
|
||||
{
|
||||
switch (mips_machtype) {
|
||||
case MACH_INGENIC_X1000:
|
||||
return "X1000";
|
||||
case MACH_INGENIC_JZ4780:
|
||||
return "JZ4780";
|
||||
case MACH_INGENIC_JZ4770:
|
||||
|
@ -4,161 +4,14 @@
|
||||
* JZ4740 platform time support
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/clocksource.h>
|
||||
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/sched_clock.h>
|
||||
|
||||
#include <asm/mach-jz4740/irq.h>
|
||||
#include <asm/mach-jz4740/timer.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#define TIMER_CLOCKEVENT 0
|
||||
#define TIMER_CLOCKSOURCE 1
|
||||
|
||||
static uint16_t jz4740_jiffies_per_tick;
|
||||
|
||||
static u64 jz4740_clocksource_read(struct clocksource *cs)
|
||||
{
|
||||
return jz4740_timer_get_count(TIMER_CLOCKSOURCE);
|
||||
}
|
||||
|
||||
static struct clocksource jz4740_clocksource = {
|
||||
.name = "jz4740-timer",
|
||||
.rating = 200,
|
||||
.read = jz4740_clocksource_read,
|
||||
.mask = CLOCKSOURCE_MASK(16),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
static u64 notrace jz4740_read_sched_clock(void)
|
||||
{
|
||||
return jz4740_timer_get_count(TIMER_CLOCKSOURCE);
|
||||
}
|
||||
|
||||
static irqreturn_t jz4740_clockevent_irq(int irq, void *devid)
|
||||
{
|
||||
struct clock_event_device *cd = devid;
|
||||
|
||||
jz4740_timer_ack_full(TIMER_CLOCKEVENT);
|
||||
|
||||
if (!clockevent_state_periodic(cd))
|
||||
jz4740_timer_disable(TIMER_CLOCKEVENT);
|
||||
|
||||
cd->event_handler(cd);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int jz4740_clockevent_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
|
||||
jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
|
||||
jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
|
||||
jz4740_timer_enable(TIMER_CLOCKEVENT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jz4740_clockevent_resume(struct clock_event_device *evt)
|
||||
{
|
||||
jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
|
||||
jz4740_timer_enable(TIMER_CLOCKEVENT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jz4740_clockevent_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
jz4740_timer_disable(TIMER_CLOCKEVENT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jz4740_clockevent_set_next(unsigned long evt,
|
||||
struct clock_event_device *cd)
|
||||
{
|
||||
jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
|
||||
jz4740_timer_set_period(TIMER_CLOCKEVENT, evt);
|
||||
jz4740_timer_enable(TIMER_CLOCKEVENT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device jz4740_clockevent = {
|
||||
.name = "jz4740-timer",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_next_event = jz4740_clockevent_set_next,
|
||||
.set_state_shutdown = jz4740_clockevent_shutdown,
|
||||
.set_state_periodic = jz4740_clockevent_set_periodic,
|
||||
.set_state_oneshot = jz4740_clockevent_shutdown,
|
||||
.tick_resume = jz4740_clockevent_resume,
|
||||
.rating = 200,
|
||||
#ifdef CONFIG_MACH_JZ4740
|
||||
.irq = JZ4740_IRQ_TCU0,
|
||||
#endif
|
||||
#if defined(CONFIG_MACH_JZ4770) || defined(CONFIG_MACH_JZ4780)
|
||||
.irq = JZ4780_IRQ_TCU2,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct irqaction timer_irqaction = {
|
||||
.handler = jz4740_clockevent_irq,
|
||||
.flags = IRQF_PERCPU | IRQF_TIMER,
|
||||
.name = "jz4740-timerirq",
|
||||
.dev_id = &jz4740_clockevent,
|
||||
};
|
||||
|
||||
void __init plat_time_init(void)
|
||||
{
|
||||
int ret;
|
||||
uint32_t clk_rate;
|
||||
uint16_t ctrl;
|
||||
struct clk *ext_clk;
|
||||
|
||||
of_clk_init(NULL);
|
||||
jz4740_timer_init();
|
||||
|
||||
ext_clk = clk_get(NULL, "ext");
|
||||
if (IS_ERR(ext_clk))
|
||||
panic("unable to get ext clock");
|
||||
clk_rate = clk_get_rate(ext_clk) >> 4;
|
||||
clk_put(ext_clk);
|
||||
|
||||
jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ);
|
||||
|
||||
clockevent_set_clock(&jz4740_clockevent, clk_rate);
|
||||
jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent);
|
||||
jz4740_clockevent.min_delta_ticks = 100;
|
||||
jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent);
|
||||
jz4740_clockevent.max_delta_ticks = 0xffff;
|
||||
jz4740_clockevent.cpumask = cpumask_of(0);
|
||||
|
||||
clockevents_register_device(&jz4740_clockevent);
|
||||
|
||||
ret = clocksource_register_hz(&jz4740_clocksource, clk_rate);
|
||||
|
||||
if (ret)
|
||||
printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
|
||||
|
||||
sched_clock_register(jz4740_read_sched_clock, 16, clk_rate);
|
||||
|
||||
setup_irq(jz4740_clockevent.irq, &timer_irqaction);
|
||||
|
||||
ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT;
|
||||
|
||||
jz4740_timer_set_ctrl(TIMER_CLOCKEVENT, ctrl);
|
||||
jz4740_timer_set_ctrl(TIMER_CLOCKSOURCE, ctrl);
|
||||
|
||||
jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
|
||||
jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
|
||||
|
||||
jz4740_timer_set_period(TIMER_CLOCKSOURCE, 0xffff);
|
||||
|
||||
jz4740_timer_enable(TIMER_CLOCKEVENT);
|
||||
jz4740_timer_enable(TIMER_CLOCKSOURCE);
|
||||
timer_probe();
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ int __mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
|
||||
unsigned long *contpc)
|
||||
{
|
||||
union mips_instruction insn = (union mips_instruction)dec_insn.insn;
|
||||
int __maybe_unused bc_false = 0;
|
||||
|
||||
if (!cpu_has_mmips)
|
||||
return 0;
|
||||
@ -139,7 +140,6 @@ int __mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
|
||||
#ifdef CONFIG_MIPS_FP_SUPPORT
|
||||
case mm_bc2f_op:
|
||||
case mm_bc1f_op: {
|
||||
int bc_false = 0;
|
||||
unsigned int fcr31;
|
||||
unsigned int bit;
|
||||
|
||||
|
@ -1384,15 +1384,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PRID_IMP_R4300:
|
||||
c->cputype = CPU_R4300;
|
||||
__cpu_name[cpu] = "R4300";
|
||||
set_isa(c, MIPS_CPU_ISA_III);
|
||||
c->fpu_msk31 |= FPU_CSR_CONDX;
|
||||
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_LLSC;
|
||||
c->tlbsize = 32;
|
||||
break;
|
||||
case PRID_IMP_R4600:
|
||||
c->cputype = CPU_R4600;
|
||||
__cpu_name[cpu] = "R4600";
|
||||
@ -1468,14 +1459,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
MIPS_CPU_LLSC;
|
||||
c->tlbsize = 48;
|
||||
break;
|
||||
case PRID_IMP_R5432:
|
||||
c->cputype = CPU_R5432;
|
||||
__cpu_name[cpu] = "R5432";
|
||||
set_isa(c, MIPS_CPU_ISA_IV);
|
||||
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_WATCH | MIPS_CPU_LLSC;
|
||||
c->tlbsize = 48;
|
||||
break;
|
||||
case PRID_IMP_R5500:
|
||||
c->cputype = CPU_R5500;
|
||||
__cpu_name[cpu] = "R5500";
|
||||
@ -1508,15 +1491,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
*/
|
||||
c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
|
||||
break;
|
||||
case PRID_IMP_R8000:
|
||||
c->cputype = CPU_R8000;
|
||||
__cpu_name[cpu] = "RM8000";
|
||||
set_isa(c, MIPS_CPU_ISA_IV);
|
||||
c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
|
||||
MIPS_CPU_FPU | MIPS_CPU_32FPR |
|
||||
MIPS_CPU_LLSC;
|
||||
c->tlbsize = 384; /* has weird TLB: 3-way x 128 */
|
||||
break;
|
||||
case PRID_IMP_R10000:
|
||||
c->cputype = CPU_R10000;
|
||||
__cpu_name[cpu] = "R10000";
|
||||
@ -1573,6 +1547,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "ICT Loongson-3";
|
||||
set_elf_platform(cpu, "loongson3a");
|
||||
set_isa(c, MIPS_CPU_ISA_M64R1);
|
||||
c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
|
||||
MIPS_ASE_LOONGSON_EXT);
|
||||
break;
|
||||
case PRID_REV_LOONGSON3B_R1:
|
||||
case PRID_REV_LOONGSON3B_R2:
|
||||
@ -1580,6 +1556,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "ICT Loongson-3";
|
||||
set_elf_platform(cpu, "loongson3b");
|
||||
set_isa(c, MIPS_CPU_ISA_M64R1);
|
||||
c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
|
||||
MIPS_ASE_LOONGSON_EXT);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1946,6 +1924,8 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
decode_configs(c);
|
||||
c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE;
|
||||
c->writecombine = _CACHE_UNCACHED_ACCELERATED;
|
||||
c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
|
||||
MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2);
|
||||
break;
|
||||
default:
|
||||
panic("Unknown Loongson Processor ID!");
|
||||
@ -1956,14 +1936,29 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
{
|
||||
decode_configs(c);
|
||||
/* JZRISC does not implement the CP0 counter. */
|
||||
|
||||
/*
|
||||
* XBurst misses a config2 register, so config3 decode was skipped in
|
||||
* decode_configs().
|
||||
*/
|
||||
decode_config3(c);
|
||||
|
||||
/* XBurst does not implement the CP0 counter. */
|
||||
c->options &= ~MIPS_CPU_COUNTER;
|
||||
BUG_ON(!__builtin_constant_p(cpu_has_counter) || cpu_has_counter);
|
||||
|
||||
switch (c->processor_id & PRID_IMP_MASK) {
|
||||
case PRID_IMP_JZRISC:
|
||||
c->cputype = CPU_JZRISC;
|
||||
case PRID_IMP_XBURST:
|
||||
c->cputype = CPU_XBURST;
|
||||
c->writecombine = _CACHE_UNCACHED_ACCELERATED;
|
||||
__cpu_name[cpu] = "Ingenic JZRISC";
|
||||
/*
|
||||
* The XBurst core by default attempts to avoid branch target
|
||||
* buffer lookups by detecting & special casing loops. This
|
||||
* feature will cause BogoMIPS and lpj calculate in error.
|
||||
* Set cp0 config7 bit 4 to disable this feature.
|
||||
*/
|
||||
set_c0_config7(MIPS_CONF7_BTB_LOOP_EN);
|
||||
break;
|
||||
default:
|
||||
panic("Unknown Ingenic Processor ID!");
|
||||
|
@ -32,9 +32,6 @@
|
||||
NESTED(except_vec3_generic, 0, sp)
|
||||
.set push
|
||||
.set noat
|
||||
#if R5432_CP0_INTERRUPT_WAR
|
||||
mfc0 k0, CP0_INDEX
|
||||
#endif
|
||||
mfc0 k1, CP0_CAUSE
|
||||
andi k1, k1, 0x7c
|
||||
#ifdef CONFIG_64BIT
|
||||
|
@ -151,7 +151,6 @@ void __init check_wait(void)
|
||||
cpu_wait = r39xx_wait;
|
||||
break;
|
||||
case CPU_R4200:
|
||||
/* case CPU_R4300: */
|
||||
case CPU_R4600:
|
||||
case CPU_R4640:
|
||||
case CPU_R4650:
|
||||
@ -173,7 +172,7 @@ void __init check_wait(void)
|
||||
case CPU_CAVIUM_OCTEON_PLUS:
|
||||
case CPU_CAVIUM_OCTEON2:
|
||||
case CPU_CAVIUM_OCTEON3:
|
||||
case CPU_JZRISC:
|
||||
case CPU_XBURST:
|
||||
case CPU_LOONGSON1:
|
||||
case CPU_XLR:
|
||||
case CPU_XLP:
|
||||
|
@ -124,6 +124,10 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
if (cpu_has_eva) seq_printf(m, "%s", " eva");
|
||||
if (cpu_has_htw) seq_printf(m, "%s", " htw");
|
||||
if (cpu_has_xpa) seq_printf(m, "%s", " xpa");
|
||||
if (cpu_has_loongson_mmi) seq_printf(m, "%s", " loongson-mmi");
|
||||
if (cpu_has_loongson_cam) seq_printf(m, "%s", " loongson-cam");
|
||||
if (cpu_has_loongson_ext) seq_printf(m, "%s", " loongson-ext");
|
||||
if (cpu_has_loongson_ext2) seq_printf(m, "%s", " loongson-ext2");
|
||||
seq_printf(m, "\n");
|
||||
|
||||
if (cpu_has_mmips) {
|
||||
|
@ -217,7 +217,7 @@ einval: li v0, -ENOSYS
|
||||
#define sys_sched_getaffinity mipsmt_sys_sched_getaffinity
|
||||
#endif /* CONFIG_MIPS_MT_FPAFF */
|
||||
|
||||
#define __SYSCALL(nr, entry, nargs) PTR entry
|
||||
#define __SYSCALL(nr, entry) PTR entry
|
||||
.align 2
|
||||
.type sys_call_table, @object
|
||||
EXPORT(sys_call_table)
|
||||
|
@ -101,7 +101,7 @@ not_n32_scall:
|
||||
|
||||
END(handle_sysn32)
|
||||
|
||||
#define __SYSCALL(nr, entry, nargs) PTR entry
|
||||
#define __SYSCALL(nr, entry) PTR entry
|
||||
.type sysn32_call_table, @object
|
||||
EXPORT(sysn32_call_table)
|
||||
#include <asm/syscall_table_64_n32.h>
|
||||
|
@ -109,7 +109,7 @@ illegal_syscall:
|
||||
j n64_syscall_exit
|
||||
END(handle_sys64)
|
||||
|
||||
#define __SYSCALL(nr, entry, nargs) PTR entry
|
||||
#define __SYSCALL(nr, entry) PTR entry
|
||||
.align 3
|
||||
.type sys_call_table, @object
|
||||
EXPORT(sys_call_table)
|
||||
|
@ -213,7 +213,7 @@ einval: li v0, -ENOSYS
|
||||
jr ra
|
||||
END(sys32_syscall)
|
||||
|
||||
#define __SYSCALL(nr, entry, nargs) PTR entry
|
||||
#define __SYSCALL(nr, entry) PTR entry
|
||||
.align 3
|
||||
.type sys32_call_table,@object
|
||||
EXPORT(sys32_call_table)
|
||||
|
@ -63,8 +63,6 @@ unsigned long mips_machtype __read_mostly = MACH_UNKNOWN;
|
||||
|
||||
EXPORT_SYMBOL(mips_machtype);
|
||||
|
||||
struct boot_mem_map boot_mem_map;
|
||||
|
||||
static char __initdata command_line[COMMAND_LINE_SIZE];
|
||||
char __initdata arcs_cmdline[COMMAND_LINE_SIZE];
|
||||
|
||||
@ -76,7 +74,7 @@ static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
|
||||
* mips_io_port_base is the begin of the address space to which x86 style
|
||||
* I/O ports are mapped.
|
||||
*/
|
||||
const unsigned long mips_io_port_base = -1;
|
||||
unsigned long mips_io_port_base = -1;
|
||||
EXPORT_SYMBOL(mips_io_port_base);
|
||||
|
||||
static struct resource code_resource = { .name = "Kernel code", };
|
||||
@ -92,8 +90,10 @@ EXPORT_SYMBOL(ARCH_PFN_OFFSET);
|
||||
|
||||
void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
|
||||
{
|
||||
int x = boot_mem_map.nr_map;
|
||||
int i;
|
||||
/*
|
||||
* Note: This function only exists for historical reason,
|
||||
* new code should use memblock_add or memblock_add_node instead.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the region reaches the top of the physical address space, adjust
|
||||
@ -108,38 +108,20 @@ void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to merge with existing entry, if any.
|
||||
*/
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
struct boot_mem_map_entry *entry = boot_mem_map.map + i;
|
||||
unsigned long top;
|
||||
memblock_add(start, size);
|
||||
/* Reserve any memory except the ordinary RAM ranges. */
|
||||
switch (type) {
|
||||
case BOOT_MEM_RAM:
|
||||
break;
|
||||
|
||||
if (entry->type != type)
|
||||
continue;
|
||||
case BOOT_MEM_NOMAP: /* Discard the range from the system. */
|
||||
memblock_remove(start, size);
|
||||
break;
|
||||
|
||||
if (start + size < entry->addr)
|
||||
continue; /* no overlap */
|
||||
|
||||
if (entry->addr + entry->size < start)
|
||||
continue; /* no overlap */
|
||||
|
||||
top = max(entry->addr + entry->size, start + size);
|
||||
entry->addr = min(entry->addr, start);
|
||||
entry->size = top - entry->addr;
|
||||
|
||||
return;
|
||||
default: /* Reserve the rest of the memory types at boot time */
|
||||
memblock_reserve(start, size);
|
||||
break;
|
||||
}
|
||||
|
||||
if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) {
|
||||
pr_err("Ooops! Too many entries in the memory map!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
boot_mem_map.map[x].addr = start;
|
||||
boot_mem_map.map[x].size = size;
|
||||
boot_mem_map.map[x].type = type;
|
||||
boot_mem_map.nr_map++;
|
||||
}
|
||||
|
||||
void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max)
|
||||
@ -161,70 +143,6 @@ void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_add
|
||||
add_memory_region(start, size, BOOT_MEM_RAM);
|
||||
}
|
||||
|
||||
static bool __init __maybe_unused memory_region_available(phys_addr_t start,
|
||||
phys_addr_t size)
|
||||
{
|
||||
int i;
|
||||
bool in_ram = false, free = true;
|
||||
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
phys_addr_t start_, end_;
|
||||
|
||||
start_ = boot_mem_map.map[i].addr;
|
||||
end_ = boot_mem_map.map[i].addr + boot_mem_map.map[i].size;
|
||||
|
||||
switch (boot_mem_map.map[i].type) {
|
||||
case BOOT_MEM_RAM:
|
||||
if (start >= start_ && start + size <= end_)
|
||||
in_ram = true;
|
||||
break;
|
||||
case BOOT_MEM_RESERVED:
|
||||
case BOOT_MEM_NOMAP:
|
||||
if ((start >= start_ && start < end_) ||
|
||||
(start < start_ && start + size >= start_))
|
||||
free = false;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return in_ram && free;
|
||||
}
|
||||
|
||||
static void __init print_memory_map(void)
|
||||
{
|
||||
int i;
|
||||
const int field = 2 * sizeof(unsigned long);
|
||||
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
printk(KERN_INFO " memory: %0*Lx @ %0*Lx ",
|
||||
field, (unsigned long long) boot_mem_map.map[i].size,
|
||||
field, (unsigned long long) boot_mem_map.map[i].addr);
|
||||
|
||||
switch (boot_mem_map.map[i].type) {
|
||||
case BOOT_MEM_RAM:
|
||||
printk(KERN_CONT "(usable)\n");
|
||||
break;
|
||||
case BOOT_MEM_INIT_RAM:
|
||||
printk(KERN_CONT "(usable after init)\n");
|
||||
break;
|
||||
case BOOT_MEM_ROM_DATA:
|
||||
printk(KERN_CONT "(ROM data)\n");
|
||||
break;
|
||||
case BOOT_MEM_RESERVED:
|
||||
printk(KERN_CONT "(reserved)\n");
|
||||
break;
|
||||
case BOOT_MEM_NOMAP:
|
||||
printk(KERN_CONT "(nomap)\n");
|
||||
break;
|
||||
default:
|
||||
printk(KERN_CONT "type %lu\n", boot_mem_map.map[i].type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Manage initrd
|
||||
*/
|
||||
@ -376,8 +294,11 @@ static void __init bootmem_init(void)
|
||||
|
||||
static void __init bootmem_init(void)
|
||||
{
|
||||
phys_addr_t ramstart = PHYS_ADDR_MAX;
|
||||
int i;
|
||||
struct memblock_region *mem;
|
||||
phys_addr_t ramstart, ramend;
|
||||
|
||||
ramstart = memblock_start_of_DRAM();
|
||||
ramend = memblock_end_of_DRAM();
|
||||
|
||||
/*
|
||||
* Sanity check any INITRD first. We don't take it into account
|
||||
@ -391,47 +312,7 @@ static void __init bootmem_init(void)
|
||||
memblock_reserve(__pa_symbol(&_text),
|
||||
__pa_symbol(&_end) - __pa_symbol(&_text));
|
||||
|
||||
/*
|
||||
* max_low_pfn is not a number of pages. The number of pages
|
||||
* of the system is given by 'max_low_pfn - min_low_pfn'.
|
||||
*/
|
||||
min_low_pfn = ~0UL;
|
||||
max_low_pfn = 0;
|
||||
|
||||
/* Find the highest and lowest page frame numbers we have available. */
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
unsigned long start, end;
|
||||
|
||||
if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
|
||||
continue;
|
||||
|
||||
start = PFN_UP(boot_mem_map.map[i].addr);
|
||||
end = PFN_DOWN(boot_mem_map.map[i].addr
|
||||
+ boot_mem_map.map[i].size);
|
||||
|
||||
ramstart = min(ramstart, boot_mem_map.map[i].addr);
|
||||
|
||||
#ifndef CONFIG_HIGHMEM
|
||||
/*
|
||||
* Skip highmem here so we get an accurate max_low_pfn if low
|
||||
* memory stops short of high memory.
|
||||
* If the region overlaps HIGHMEM_START, end is clipped so
|
||||
* max_pfn excludes the highmem portion.
|
||||
*/
|
||||
if (start >= PFN_DOWN(HIGHMEM_START))
|
||||
continue;
|
||||
if (end > PFN_DOWN(HIGHMEM_START))
|
||||
end = PFN_DOWN(HIGHMEM_START);
|
||||
#endif
|
||||
|
||||
if (end > max_low_pfn)
|
||||
max_low_pfn = end;
|
||||
if (start < min_low_pfn)
|
||||
min_low_pfn = start;
|
||||
}
|
||||
|
||||
if (min_low_pfn >= max_low_pfn)
|
||||
panic("Incorrect memory mapping !!!");
|
||||
/* max_low_pfn is not a number of pages but the end pfn of low mem */
|
||||
|
||||
#ifdef CONFIG_MIPS_AUTO_PFN_OFFSET
|
||||
ARCH_PFN_OFFSET = PFN_UP(ramstart);
|
||||
@ -439,75 +320,59 @@ static void __init bootmem_init(void)
|
||||
/*
|
||||
* Reserve any memory between the start of RAM and PHYS_OFFSET
|
||||
*/
|
||||
if (ramstart > PHYS_OFFSET) {
|
||||
add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET,
|
||||
BOOT_MEM_RESERVED);
|
||||
memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET);
|
||||
}
|
||||
if (ramstart > PHYS_OFFSET)
|
||||
memblock_reserve(PHYS_OFFSET, PFN_UP(ramstart) - PHYS_OFFSET);
|
||||
|
||||
if (min_low_pfn > ARCH_PFN_OFFSET) {
|
||||
if (PFN_UP(ramstart) > ARCH_PFN_OFFSET) {
|
||||
pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
|
||||
(min_low_pfn - ARCH_PFN_OFFSET) * sizeof(struct page),
|
||||
min_low_pfn - ARCH_PFN_OFFSET);
|
||||
} else if (ARCH_PFN_OFFSET - min_low_pfn > 0UL) {
|
||||
pr_info("%lu free pages won't be used\n",
|
||||
ARCH_PFN_OFFSET - min_low_pfn);
|
||||
(unsigned long)((PFN_UP(ramstart) - ARCH_PFN_OFFSET) * sizeof(struct page)),
|
||||
(unsigned long)(PFN_UP(ramstart) - ARCH_PFN_OFFSET));
|
||||
}
|
||||
#endif
|
||||
|
||||
min_low_pfn = ARCH_PFN_OFFSET;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Determine low and high memory ranges
|
||||
*/
|
||||
max_pfn = max_low_pfn;
|
||||
if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) {
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
highstart_pfn = PFN_DOWN(HIGHMEM_START);
|
||||
highend_pfn = max_low_pfn;
|
||||
#endif
|
||||
max_low_pfn = PFN_DOWN(HIGHMEM_START);
|
||||
}
|
||||
|
||||
/* Install all valid RAM ranges to the memblock memory region */
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
unsigned long start, end;
|
||||
|
||||
start = PFN_UP(boot_mem_map.map[i].addr);
|
||||
end = PFN_DOWN(boot_mem_map.map[i].addr
|
||||
+ boot_mem_map.map[i].size);
|
||||
|
||||
if (start < min_low_pfn)
|
||||
start = min_low_pfn;
|
||||
#ifndef CONFIG_HIGHMEM
|
||||
/* Ignore highmem regions if highmem is unsupported */
|
||||
if (end > max_low_pfn)
|
||||
end = max_low_pfn;
|
||||
#endif
|
||||
if (end <= start)
|
||||
continue;
|
||||
|
||||
memblock_add_node(PFN_PHYS(start), PFN_PHYS(end - start), 0);
|
||||
|
||||
/* Reserve any memory except the ordinary RAM ranges. */
|
||||
switch (boot_mem_map.map[i].type) {
|
||||
case BOOT_MEM_RAM:
|
||||
break;
|
||||
case BOOT_MEM_NOMAP: /* Discard the range from the system. */
|
||||
memblock_remove(PFN_PHYS(start), PFN_PHYS(end - start));
|
||||
continue;
|
||||
default: /* Reserve the rest of the memory types at boot time */
|
||||
memblock_reserve(PFN_PHYS(start), PFN_PHYS(end - start));
|
||||
break;
|
||||
}
|
||||
max_pfn = PFN_DOWN(ramend);
|
||||
for_each_memblock(memory, mem) {
|
||||
unsigned long start = memblock_region_memory_base_pfn(mem);
|
||||
unsigned long end = memblock_region_memory_end_pfn(mem);
|
||||
|
||||
/*
|
||||
* In any case the added to the memblock memory regions
|
||||
* (highmem/lowmem, available/reserved, etc) are considered
|
||||
* as present, so inform sparsemem about them.
|
||||
* Skip highmem here so we get an accurate max_low_pfn if low
|
||||
* memory stops short of high memory.
|
||||
* If the region overlaps HIGHMEM_START, end is clipped so
|
||||
* max_pfn excludes the highmem portion.
|
||||
*/
|
||||
memory_present(0, start, end);
|
||||
if (memblock_is_nomap(mem))
|
||||
continue;
|
||||
if (start >= PFN_DOWN(HIGHMEM_START))
|
||||
continue;
|
||||
if (end > PFN_DOWN(HIGHMEM_START))
|
||||
end = PFN_DOWN(HIGHMEM_START);
|
||||
if (end > max_low_pfn)
|
||||
max_low_pfn = end;
|
||||
}
|
||||
|
||||
if (min_low_pfn >= max_low_pfn)
|
||||
panic("Incorrect memory mapping !!!");
|
||||
|
||||
if (max_pfn > PFN_DOWN(HIGHMEM_START)) {
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
highstart_pfn = PFN_DOWN(HIGHMEM_START);
|
||||
highend_pfn = max_pfn;
|
||||
#else
|
||||
max_low_pfn = PFN_DOWN(HIGHMEM_START);
|
||||
max_pfn = max_low_pfn;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* In any case the added to the memblock memory regions
|
||||
* (highmem/lowmem, available/reserved, etc) are considered
|
||||
* as present, so inform sparsemem about them.
|
||||
*/
|
||||
memblocks_present();
|
||||
|
||||
/*
|
||||
* Reserve initrd memory if needed.
|
||||
*/
|
||||
@ -528,8 +393,9 @@ static int __init early_parse_mem(char *p)
|
||||
* size.
|
||||
*/
|
||||
if (usermem == 0) {
|
||||
boot_mem_map.nr_map = 0;
|
||||
usermem = 1;
|
||||
memblock_remove(memblock_start_of_DRAM(),
|
||||
memblock_end_of_DRAM() - memblock_start_of_DRAM());
|
||||
}
|
||||
start = 0;
|
||||
size = memparse(p, &p);
|
||||
@ -586,14 +452,13 @@ early_param("memmap", early_parse_memmap);
|
||||
unsigned long setup_elfcorehdr, setup_elfcorehdr_size;
|
||||
static int __init early_parse_elfcorehdr(char *p)
|
||||
{
|
||||
int i;
|
||||
struct memblock_region *mem;
|
||||
|
||||
setup_elfcorehdr = memparse(p, &p);
|
||||
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
unsigned long start = boot_mem_map.map[i].addr;
|
||||
unsigned long end = (boot_mem_map.map[i].addr +
|
||||
boot_mem_map.map[i].size);
|
||||
for_each_memblock(memory, mem) {
|
||||
unsigned long start = mem->base;
|
||||
unsigned long end = start + mem->size;
|
||||
if (setup_elfcorehdr >= start && setup_elfcorehdr < end) {
|
||||
/*
|
||||
* Reserve from the elf core header to the end of
|
||||
@ -613,47 +478,20 @@ static int __init early_parse_elfcorehdr(char *p)
|
||||
early_param("elfcorehdr", early_parse_elfcorehdr);
|
||||
#endif
|
||||
|
||||
static void __init arch_mem_addpart(phys_addr_t mem, phys_addr_t end, int type)
|
||||
{
|
||||
phys_addr_t size;
|
||||
int i;
|
||||
|
||||
size = end - mem;
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
/* Make sure it is in the boot_mem_map */
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
if (mem >= boot_mem_map.map[i].addr &&
|
||||
mem < (boot_mem_map.map[i].addr +
|
||||
boot_mem_map.map[i].size))
|
||||
return;
|
||||
}
|
||||
add_memory_region(mem, size, type);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KEXEC
|
||||
static inline unsigned long long get_total_mem(void)
|
||||
{
|
||||
unsigned long long total;
|
||||
|
||||
total = max_pfn - min_low_pfn;
|
||||
return total << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
static void __init mips_parse_crashkernel(void)
|
||||
{
|
||||
unsigned long long total_mem;
|
||||
unsigned long long crash_size, crash_base;
|
||||
int ret;
|
||||
|
||||
total_mem = get_total_mem();
|
||||
total_mem = memblock_phys_mem_size();
|
||||
ret = parse_crashkernel(boot_command_line, total_mem,
|
||||
&crash_size, &crash_base);
|
||||
if (ret != 0 || crash_size <= 0)
|
||||
return;
|
||||
|
||||
if (!memory_region_available(crash_base, crash_size)) {
|
||||
if (!memblock_find_in_range(crash_base, crash_base + crash_size, crash_size, 0)) {
|
||||
pr_warn("Invalid memory region reserved for crash kernel\n");
|
||||
return;
|
||||
}
|
||||
@ -686,6 +524,17 @@ static void __init request_crashkernel(struct resource *res)
|
||||
}
|
||||
#endif /* !defined(CONFIG_KEXEC) */
|
||||
|
||||
static void __init check_kernel_sections_mem(void)
|
||||
{
|
||||
phys_addr_t start = PFN_PHYS(PFN_DOWN(__pa_symbol(&_text)));
|
||||
phys_addr_t size = PFN_PHYS(PFN_UP(__pa_symbol(&_end))) - start;
|
||||
|
||||
if (!memblock_is_region_memory(start, size)) {
|
||||
pr_info("Kernel sections are not in the memory maps\n");
|
||||
memblock_add(start, size);
|
||||
}
|
||||
}
|
||||
|
||||
#define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
|
||||
#define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
|
||||
#define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
|
||||
@ -731,25 +580,6 @@ static void __init arch_mem_init(char **cmdline_p)
|
||||
plat_mem_setup();
|
||||
memblock_set_bottom_up(true);
|
||||
|
||||
/*
|
||||
* Make sure all kernel memory is in the maps. The "UP" and
|
||||
* "DOWN" are opposite for initdata since if it crosses over
|
||||
* into another memory section you don't want that to be
|
||||
* freed when the initdata is freed.
|
||||
*/
|
||||
arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT,
|
||||
PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT,
|
||||
BOOT_MEM_RAM);
|
||||
arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT,
|
||||
PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT,
|
||||
BOOT_MEM_INIT_RAM);
|
||||
arch_mem_addpart(PFN_DOWN(__pa_symbol(&__bss_start)) << PAGE_SHIFT,
|
||||
PFN_UP(__pa_symbol(&__bss_stop)) << PAGE_SHIFT,
|
||||
BOOT_MEM_RAM);
|
||||
|
||||
pr_info("Determined physical RAM map:\n");
|
||||
print_memory_map();
|
||||
|
||||
#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
|
||||
strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
|
||||
#else
|
||||
@ -783,14 +613,17 @@ static void __init arch_mem_init(char **cmdline_p)
|
||||
|
||||
parse_early_param();
|
||||
|
||||
if (usermem) {
|
||||
pr_info("User-defined physical RAM map:\n");
|
||||
print_memory_map();
|
||||
}
|
||||
if (usermem)
|
||||
pr_info("User-defined physical RAM map overwrite\n");
|
||||
|
||||
check_kernel_sections_mem();
|
||||
|
||||
early_init_fdt_reserve_self();
|
||||
early_init_fdt_scan_reserved_mem();
|
||||
|
||||
#ifndef CONFIG_NUMA
|
||||
memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
|
||||
#endif
|
||||
bootmem_init();
|
||||
|
||||
/*
|
||||
@ -830,12 +663,12 @@ static void __init arch_mem_init(char **cmdline_p)
|
||||
|
||||
memblock_dump_all();
|
||||
|
||||
early_memtest(PFN_PHYS(min_low_pfn), PFN_PHYS(max_low_pfn));
|
||||
early_memtest(PFN_PHYS(ARCH_PFN_OFFSET), PFN_PHYS(max_low_pfn));
|
||||
}
|
||||
|
||||
static void __init resource_init(void)
|
||||
{
|
||||
int i;
|
||||
struct memblock_region *region;
|
||||
|
||||
if (UNCAC_BASE != IO_BASE)
|
||||
return;
|
||||
@ -847,16 +680,10 @@ static void __init resource_init(void)
|
||||
bss_resource.start = __pa_symbol(&__bss_start);
|
||||
bss_resource.end = __pa_symbol(&__bss_stop) - 1;
|
||||
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
for_each_memblock(memory, region) {
|
||||
phys_addr_t start = PFN_PHYS(memblock_region_memory_base_pfn(region));
|
||||
phys_addr_t end = PFN_PHYS(memblock_region_memory_end_pfn(region)) - 1;
|
||||
struct resource *res;
|
||||
unsigned long start, end;
|
||||
|
||||
start = boot_mem_map.map[i].addr;
|
||||
end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1;
|
||||
if (start >= HIGHMEM_START)
|
||||
continue;
|
||||
if (end >= HIGHMEM_START)
|
||||
end = HIGHMEM_START - 1;
|
||||
|
||||
res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES);
|
||||
if (!res)
|
||||
@ -865,20 +692,8 @@ static void __init resource_init(void)
|
||||
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
|
||||
|
||||
switch (boot_mem_map.map[i].type) {
|
||||
case BOOT_MEM_RAM:
|
||||
case BOOT_MEM_INIT_RAM:
|
||||
case BOOT_MEM_ROM_DATA:
|
||||
res->name = "System RAM";
|
||||
res->flags |= IORESOURCE_SYSRAM;
|
||||
break;
|
||||
case BOOT_MEM_RESERVED:
|
||||
case BOOT_MEM_NOMAP:
|
||||
default:
|
||||
res->name = "reserved";
|
||||
}
|
||||
res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
|
||||
res->name = "System RAM";
|
||||
|
||||
request_resource(&iomem_resource, res);
|
||||
|
||||
|
@ -132,6 +132,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new)
|
||||
[efault] "i" (-EFAULT)
|
||||
: "memory");
|
||||
} else if (cpu_has_llsc) {
|
||||
loongson_llsc_mb();
|
||||
__asm__ __volatile__ (
|
||||
" .set push \n"
|
||||
" .set "MIPS_ISA_ARCH_LEVEL" \n"
|
||||
|
@ -13,10 +13,10 @@ emit() {
|
||||
t_entry="$3"
|
||||
|
||||
while [ $t_nxt -lt $t_nr ]; do
|
||||
printf "__SYSCALL(%s, sys_ni_syscall, )\n" "${t_nxt}"
|
||||
printf "__SYSCALL(%s,sys_ni_syscall)\n" "${t_nxt}"
|
||||
t_nxt=$((t_nxt+1))
|
||||
done
|
||||
printf "__SYSCALL(%s, %s, )\n" "${t_nxt}" "${t_entry}"
|
||||
printf "__SYSCALL(%s,%s)\n" "${t_nxt}" "${t_entry}"
|
||||
}
|
||||
|
||||
grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
|
||||
|
@ -20,9 +20,12 @@
|
||||
#include <asm/mips-cps.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/vdso.h>
|
||||
#include <vdso/helpers.h>
|
||||
#include <vdso/vsyscall.h>
|
||||
|
||||
/* Kernel-provided data used by the VDSO. */
|
||||
static union mips_vdso_data vdso_data __page_aligned_data;
|
||||
static union mips_vdso_data mips_vdso_data __page_aligned_data;
|
||||
struct vdso_data *vdso_data = mips_vdso_data.data;
|
||||
|
||||
/*
|
||||
* Mapping for the VDSO data/GIC pages. The real pages are mapped manually, as
|
||||
@ -66,34 +69,6 @@ static int __init init_vdso(void)
|
||||
}
|
||||
subsys_initcall(init_vdso);
|
||||
|
||||
void update_vsyscall(struct timekeeper *tk)
|
||||
{
|
||||
vdso_data_write_begin(&vdso_data);
|
||||
|
||||
vdso_data.xtime_sec = tk->xtime_sec;
|
||||
vdso_data.xtime_nsec = tk->tkr_mono.xtime_nsec;
|
||||
vdso_data.wall_to_mono_sec = tk->wall_to_monotonic.tv_sec;
|
||||
vdso_data.wall_to_mono_nsec = tk->wall_to_monotonic.tv_nsec;
|
||||
vdso_data.cs_shift = tk->tkr_mono.shift;
|
||||
|
||||
vdso_data.clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode;
|
||||
if (vdso_data.clock_mode != VDSO_CLOCK_NONE) {
|
||||
vdso_data.cs_mult = tk->tkr_mono.mult;
|
||||
vdso_data.cs_cycle_last = tk->tkr_mono.cycle_last;
|
||||
vdso_data.cs_mask = tk->tkr_mono.mask;
|
||||
}
|
||||
|
||||
vdso_data_write_end(&vdso_data);
|
||||
}
|
||||
|
||||
void update_vsyscall_tz(void)
|
||||
{
|
||||
if (vdso_data.clock_mode != VDSO_CLOCK_NONE) {
|
||||
vdso_data.tz_minuteswest = sys_tz.tz_minuteswest;
|
||||
vdso_data.tz_dsttime = sys_tz.tz_dsttime;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long vdso_base(void)
|
||||
{
|
||||
unsigned long base;
|
||||
@ -163,7 +138,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
||||
*/
|
||||
if (cpu_has_dc_aliases) {
|
||||
base = __ALIGN_MASK(base, shm_align_mask);
|
||||
base += ((unsigned long)&vdso_data - gic_size) & shm_align_mask;
|
||||
base += ((unsigned long)vdso_data - gic_size) & shm_align_mask;
|
||||
}
|
||||
|
||||
data_addr = base + gic_size;
|
||||
@ -189,7 +164,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
||||
|
||||
/* Map data page. */
|
||||
ret = remap_pfn_range(vma, data_addr,
|
||||
virt_to_phys(&vdso_data) >> PAGE_SHIFT,
|
||||
virt_to_phys(vdso_data) >> PAGE_SHIFT,
|
||||
PAGE_SIZE, PAGE_READONLY);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
@ -468,14 +468,14 @@ void __init ltq_soc_init(void)
|
||||
clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB0_P);
|
||||
clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB1_P);
|
||||
/* rc 0 */
|
||||
clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P);
|
||||
clkdev_add_pmu("1f106800.phy", "phy", 1, 2, PMU_ANALOG_PCIE0_P);
|
||||
clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
|
||||
clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI);
|
||||
clkdev_add_pmu("1f106800.phy", "pdi", 1, 1, PMU1_PCIE_PDI);
|
||||
clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL);
|
||||
/* rc 1 */
|
||||
clkdev_add_pmu("19000000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE1_P);
|
||||
clkdev_add_pmu("1f700400.phy", "phy", 1, 2, PMU_ANALOG_PCIE1_P);
|
||||
clkdev_add_pmu("19000000.pcie", "msi", 1, 1, PMU1_PCIE1_MSI);
|
||||
clkdev_add_pmu("19000000.pcie", "pdi", 1, 1, PMU1_PCIE1_PDI);
|
||||
clkdev_add_pmu("1f700400.phy", "pdi", 1, 1, PMU1_PCIE1_PDI);
|
||||
clkdev_add_pmu("19000000.pcie", "ctl", 1, 1, PMU1_PCIE1_CTL);
|
||||
}
|
||||
|
||||
@ -499,9 +499,9 @@ void __init ltq_soc_init(void)
|
||||
clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0);
|
||||
clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1);
|
||||
/* rc 2 */
|
||||
clkdev_add_pmu("1a800000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P);
|
||||
clkdev_add_pmu("1f106a00.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P);
|
||||
clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI);
|
||||
clkdev_add_pmu("1a800000.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI);
|
||||
clkdev_add_pmu("1f106a00.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI);
|
||||
clkdev_add_pmu("1a800000.pcie", "ctl", 1, 1, PMU1_PCIE2_CTL);
|
||||
clkdev_add_pmu("1e10b308.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP);
|
||||
clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
|
||||
@ -526,10 +526,10 @@ void __init ltq_soc_init(void)
|
||||
clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM);
|
||||
clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P);
|
||||
clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM);
|
||||
clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY);
|
||||
clkdev_add_pmu("1f106800.phy", "phy", 1, 1, PMU1_PCIE_PHY);
|
||||
clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK);
|
||||
clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
|
||||
clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI);
|
||||
clkdev_add_pmu("1f106800.phy", "pdi", 1, 1, PMU1_PCIE_PDI);
|
||||
clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL);
|
||||
clkdev_add_pmu(NULL, "ahb", 1, 0, PMU_AHBM | PMU_AHBS);
|
||||
|
||||
|
@ -28,11 +28,11 @@ obj-$(CONFIG_HIGHMEM) += highmem.o
|
||||
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
|
||||
obj-$(CONFIG_DMA_NONCOHERENT) += dma-noncoherent.o
|
||||
|
||||
obj-$(CONFIG_CPU_R3K_TLB) += tlb-r3k.o
|
||||
obj-$(CONFIG_CPU_R4K_CACHE_TLB) += c-r4k.o cex-gen.o tlb-r4k.o
|
||||
obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o
|
||||
obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o tlb-r8k.o
|
||||
obj-$(CONFIG_CPU_R3000) += c-r3k.o
|
||||
obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o tlb-r4k.o
|
||||
obj-$(CONFIG_CPU_TX39XX) += c-tx39.o tlb-r3k.o
|
||||
obj-$(CONFIG_CPU_TX39XX) += c-tx39.o
|
||||
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += c-octeon.o cex-oct.o tlb-r4k.o
|
||||
|
||||
obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
|
||||
|
@ -1098,7 +1098,6 @@ static void probe_pcache(void)
|
||||
c->options |= MIPS_CPU_CACHE_CDEX_P;
|
||||
break;
|
||||
|
||||
case CPU_R5432:
|
||||
case CPU_R5500:
|
||||
icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
|
||||
c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
|
||||
@ -1134,7 +1133,6 @@ static void probe_pcache(void)
|
||||
case CPU_R4400PC:
|
||||
case CPU_R4400SC:
|
||||
case CPU_R4400MC:
|
||||
case CPU_R4300:
|
||||
icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
|
||||
c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
|
||||
c->icache.ways = 1;
|
||||
|
@ -269,37 +269,46 @@ void __init fixrange_init(unsigned long start, unsigned long end,
|
||||
#endif
|
||||
}
|
||||
|
||||
struct maar_walk_info {
|
||||
struct maar_config cfg[16];
|
||||
unsigned int num_cfg;
|
||||
};
|
||||
|
||||
static int maar_res_walk(unsigned long start_pfn, unsigned long nr_pages,
|
||||
void *data)
|
||||
{
|
||||
struct maar_walk_info *wi = data;
|
||||
struct maar_config *cfg = &wi->cfg[wi->num_cfg];
|
||||
unsigned int maar_align;
|
||||
|
||||
/* MAAR registers hold physical addresses right shifted by 4 bits */
|
||||
maar_align = BIT(MIPS_MAAR_ADDR_SHIFT + 4);
|
||||
|
||||
/* Fill in the MAAR config entry */
|
||||
cfg->lower = ALIGN(PFN_PHYS(start_pfn), maar_align);
|
||||
cfg->upper = ALIGN_DOWN(PFN_PHYS(start_pfn + nr_pages), maar_align) - 1;
|
||||
cfg->attrs = MIPS_MAAR_S;
|
||||
|
||||
/* Ensure we don't overflow the cfg array */
|
||||
if (!WARN_ON(wi->num_cfg >= ARRAY_SIZE(wi->cfg)))
|
||||
wi->num_cfg++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned __weak platform_maar_init(unsigned num_pairs)
|
||||
{
|
||||
struct maar_config cfg[BOOT_MEM_MAP_MAX];
|
||||
unsigned i, num_configured, num_cfg = 0;
|
||||
unsigned int num_configured;
|
||||
struct maar_walk_info wi;
|
||||
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
switch (boot_mem_map.map[i].type) {
|
||||
case BOOT_MEM_RAM:
|
||||
case BOOT_MEM_INIT_RAM:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
wi.num_cfg = 0;
|
||||
walk_system_ram_range(0, max_pfn, &wi, maar_res_walk);
|
||||
|
||||
/* Round lower up */
|
||||
cfg[num_cfg].lower = boot_mem_map.map[i].addr;
|
||||
cfg[num_cfg].lower = (cfg[num_cfg].lower + 0xffff) & ~0xffff;
|
||||
|
||||
/* Round upper down */
|
||||
cfg[num_cfg].upper = boot_mem_map.map[i].addr +
|
||||
boot_mem_map.map[i].size;
|
||||
cfg[num_cfg].upper = (cfg[num_cfg].upper & ~0xffff) - 1;
|
||||
|
||||
cfg[num_cfg].attrs = MIPS_MAAR_S;
|
||||
num_cfg++;
|
||||
}
|
||||
|
||||
num_configured = maar_config(cfg, num_cfg, num_pairs);
|
||||
if (num_configured < num_cfg)
|
||||
pr_warn("Not enough MAAR pairs (%u) for all bootmem regions (%u)\n",
|
||||
num_pairs, num_cfg);
|
||||
num_configured = maar_config(wi.cfg, wi.num_cfg, num_pairs);
|
||||
if (num_configured < wi.num_cfg)
|
||||
pr_warn("Not enough MAAR pairs (%u) for all memory regions (%u)\n",
|
||||
num_pairs, wi.num_cfg);
|
||||
|
||||
return num_configured;
|
||||
}
|
||||
@ -382,33 +391,6 @@ void maar_init(void)
|
||||
}
|
||||
|
||||
#ifndef CONFIG_NEED_MULTIPLE_NODES
|
||||
int page_is_ram(unsigned long pagenr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
unsigned long addr, end;
|
||||
|
||||
switch (boot_mem_map.map[i].type) {
|
||||
case BOOT_MEM_RAM:
|
||||
case BOOT_MEM_INIT_RAM:
|
||||
break;
|
||||
default:
|
||||
/* not usable memory */
|
||||
continue;
|
||||
}
|
||||
|
||||
addr = PFN_UP(boot_mem_map.map[i].addr);
|
||||
end = PFN_DOWN(boot_mem_map.map[i].addr +
|
||||
boot_mem_map.map[i].size);
|
||||
|
||||
if (pagenr >= addr && pagenr < end)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init paging_init(void)
|
||||
{
|
||||
unsigned long max_zone_pfns[MAX_NR_ZONES];
|
||||
@ -443,7 +425,7 @@ void __init paging_init(void)
|
||||
static struct kcore_list kcore_kseg0;
|
||||
#endif
|
||||
|
||||
static inline void mem_init_free_highmem(void)
|
||||
static inline void __init mem_init_free_highmem(void)
|
||||
{
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
unsigned long tmp;
|
||||
@ -454,7 +436,7 @@ static inline void mem_init_free_highmem(void)
|
||||
for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
|
||||
struct page *page = pfn_to_page(tmp);
|
||||
|
||||
if (!page_is_ram(tmp))
|
||||
if (!memblock_is_memory(PFN_PHYS(tmp)))
|
||||
SetPageReserved(page);
|
||||
else
|
||||
free_highmem_page(page);
|
||||
@ -464,6 +446,12 @@ static inline void mem_init_free_highmem(void)
|
||||
|
||||
void __init mem_init(void)
|
||||
{
|
||||
/*
|
||||
* When _PFN_SHIFT is greater than PAGE_SHIFT we won't have enough PTE
|
||||
* bits to hold a full 32b physical address on MIPS32 systems.
|
||||
*/
|
||||
BUILD_BUG_ON(IS_ENABLED(CONFIG_32BIT) && (_PFN_SHIFT > PAGE_SHIFT));
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
#ifdef CONFIG_DISCONTIGMEM
|
||||
#error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet"
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
void pgd_init(unsigned long page)
|
||||
{
|
||||
@ -30,6 +31,25 @@ void pgd_init(unsigned long page)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_TRANSPARENT_HUGEPAGE)
|
||||
pmd_t mk_pmd(struct page *page, pgprot_t prot)
|
||||
{
|
||||
pmd_t pmd;
|
||||
|
||||
pmd_val(pmd) = (page_to_pfn(page) << _PFN_SHIFT) | pgprot_val(prot);
|
||||
|
||||
return pmd;
|
||||
}
|
||||
|
||||
|
||||
void set_pmd_at(struct mm_struct *mm, unsigned long addr,
|
||||
pmd_t *pmdp, pmd_t pmd)
|
||||
{
|
||||
*pmdp = pmd;
|
||||
flush_tlb_all();
|
||||
}
|
||||
#endif /* defined(CONFIG_TRANSPARENT_HUGEPAGE) */
|
||||
|
||||
void __init pagetable_init(void)
|
||||
{
|
||||
unsigned long vaddr;
|
||||
|
@ -221,13 +221,26 @@ static inline int __init mips_sc_probe(void)
|
||||
else
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* According to config2 it would be 5-ways, but that is contradicted
|
||||
* by all documentation.
|
||||
*/
|
||||
if (current_cpu_type() == CPU_JZRISC &&
|
||||
mips_machtype == MACH_INGENIC_JZ4770)
|
||||
c->scache.ways = 4;
|
||||
if (current_cpu_type() == CPU_XBURST) {
|
||||
switch (mips_machtype) {
|
||||
/*
|
||||
* According to config2 it would be 5-ways, but that is
|
||||
* contradicted by all documentation.
|
||||
*/
|
||||
case MACH_INGENIC_JZ4770:
|
||||
c->scache.ways = 4;
|
||||
break;
|
||||
|
||||
/*
|
||||
* According to config2 it would be 5-ways and 512-sets,
|
||||
* but that is contradicted by all documentation.
|
||||
*/
|
||||
case MACH_INGENIC_X1000:
|
||||
c->scache.sets = 256;
|
||||
c->scache.ways = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
c->scache.waysize = c->scache.sets * c->scache.linesz;
|
||||
c->scache.waybit = __ffs(c->scache.waysize);
|
||||
|
@ -1,239 +0,0 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
|
||||
* Carsten Langgaard, carstenl@mips.com
|
||||
* Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/sched.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
extern void build_tlb_refill_handler(void);
|
||||
|
||||
#define TFP_TLB_SIZE 384
|
||||
#define TFP_TLB_SET_SHIFT 7
|
||||
|
||||
/* CP0 hazard avoidance. */
|
||||
#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
|
||||
"nop; nop; nop; nop; nop; nop;\n\t" \
|
||||
".set reorder\n\t")
|
||||
|
||||
void local_flush_tlb_all(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long old_ctx;
|
||||
int entry;
|
||||
|
||||
local_irq_save(flags);
|
||||
/* Save old context and create impossible VPN2 value */
|
||||
old_ctx = read_c0_entryhi();
|
||||
write_c0_entrylo(0);
|
||||
|
||||
for (entry = 0; entry < TFP_TLB_SIZE; entry++) {
|
||||
write_c0_tlbset(entry >> TFP_TLB_SET_SHIFT);
|
||||
write_c0_vaddr(entry << PAGE_SHIFT);
|
||||
write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1)));
|
||||
mtc0_tlbw_hazard();
|
||||
tlb_write();
|
||||
}
|
||||
tlbw_use_hazard();
|
||||
write_c0_entryhi(old_ctx);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
int cpu = smp_processor_id();
|
||||
unsigned long flags;
|
||||
int oldpid, newpid, size;
|
||||
|
||||
if (!cpu_context(cpu, mm))
|
||||
return;
|
||||
|
||||
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
|
||||
size = (size + 1) >> 1;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
if (size > TFP_TLB_SIZE / 2) {
|
||||
drop_mmu_context(mm);
|
||||
goto out_restore;
|
||||
}
|
||||
|
||||
oldpid = read_c0_entryhi();
|
||||
newpid = cpu_asid(cpu, mm);
|
||||
|
||||
write_c0_entrylo(0);
|
||||
|
||||
start &= PAGE_MASK;
|
||||
end += (PAGE_SIZE - 1);
|
||||
end &= PAGE_MASK;
|
||||
while (start < end) {
|
||||
signed long idx;
|
||||
|
||||
write_c0_vaddr(start);
|
||||
write_c0_entryhi(start);
|
||||
start += PAGE_SIZE;
|
||||
tlb_probe();
|
||||
idx = read_c0_tlbset();
|
||||
if (idx < 0)
|
||||
continue;
|
||||
|
||||
write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
|
||||
tlb_write();
|
||||
}
|
||||
write_c0_entryhi(oldpid);
|
||||
|
||||
out_restore:
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/* Usable for KV1 addresses only! */
|
||||
void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
unsigned long size, flags;
|
||||
|
||||
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
|
||||
size = (size + 1) >> 1;
|
||||
|
||||
if (size > TFP_TLB_SIZE / 2) {
|
||||
local_flush_tlb_all();
|
||||
return;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
write_c0_entrylo(0);
|
||||
|
||||
start &= PAGE_MASK;
|
||||
end += (PAGE_SIZE - 1);
|
||||
end &= PAGE_MASK;
|
||||
while (start < end) {
|
||||
signed long idx;
|
||||
|
||||
write_c0_vaddr(start);
|
||||
write_c0_entryhi(start);
|
||||
start += PAGE_SIZE;
|
||||
tlb_probe();
|
||||
idx = read_c0_tlbset();
|
||||
if (idx < 0)
|
||||
continue;
|
||||
|
||||
write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
|
||||
tlb_write();
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
unsigned long flags;
|
||||
int oldpid, newpid;
|
||||
signed long idx;
|
||||
|
||||
if (!cpu_context(cpu, vma->vm_mm))
|
||||
return;
|
||||
|
||||
newpid = cpu_asid(cpu, vma->vm_mm);
|
||||
page &= PAGE_MASK;
|
||||
local_irq_save(flags);
|
||||
oldpid = read_c0_entryhi();
|
||||
write_c0_vaddr(page);
|
||||
write_c0_entryhi(newpid);
|
||||
tlb_probe();
|
||||
idx = read_c0_tlbset();
|
||||
if (idx < 0)
|
||||
goto finish;
|
||||
|
||||
write_c0_entrylo(0);
|
||||
write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
|
||||
tlb_write();
|
||||
|
||||
finish:
|
||||
write_c0_entryhi(oldpid);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* We will need multiple versions of update_mmu_cache(), one that just
|
||||
* updates the TLB with the new pte(s), and another which also checks
|
||||
* for the R4k "end of page" hardware bug and does the needy.
|
||||
*/
|
||||
void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
|
||||
{
|
||||
unsigned long flags;
|
||||
pgd_t *pgdp;
|
||||
pmd_t *pmdp;
|
||||
pte_t *ptep;
|
||||
int pid;
|
||||
|
||||
/*
|
||||
* Handle debugger faulting in for debugee.
|
||||
*/
|
||||
if (current->active_mm != vma->vm_mm)
|
||||
return;
|
||||
|
||||
pid = read_c0_entryhi() & cpu_asid_mask(¤t_cpu_data);
|
||||
|
||||
local_irq_save(flags);
|
||||
address &= PAGE_MASK;
|
||||
write_c0_vaddr(address);
|
||||
write_c0_entryhi(pid);
|
||||
pgdp = pgd_offset(vma->vm_mm, address);
|
||||
pmdp = pmd_offset(pgdp, address);
|
||||
ptep = pte_offset_map(pmdp, address);
|
||||
tlb_probe();
|
||||
|
||||
write_c0_entrylo(pte_val(*ptep++) >> 6);
|
||||
tlb_write();
|
||||
|
||||
write_c0_entryhi(pid);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static void probe_tlb(unsigned long config)
|
||||
{
|
||||
struct cpuinfo_mips *c = ¤t_cpu_data;
|
||||
|
||||
c->tlbsize = 3 * 128; /* 3 sets each 128 entries */
|
||||
}
|
||||
|
||||
void tlb_init(void)
|
||||
{
|
||||
unsigned int config = read_c0_config();
|
||||
unsigned long status;
|
||||
|
||||
probe_tlb(config);
|
||||
|
||||
status = read_c0_status();
|
||||
status &= ~(ST0_UPS | ST0_KPS);
|
||||
#ifdef CONFIG_PAGE_SIZE_4KB
|
||||
status |= (TFP_PAGESIZE_4K << 32) | (TFP_PAGESIZE_4K << 36);
|
||||
#elif defined(CONFIG_PAGE_SIZE_8KB)
|
||||
status |= (TFP_PAGESIZE_8K << 32) | (TFP_PAGESIZE_8K << 36);
|
||||
#elif defined(CONFIG_PAGE_SIZE_16KB)
|
||||
status |= (TFP_PAGESIZE_16K << 32) | (TFP_PAGESIZE_16K << 36);
|
||||
#elif defined(CONFIG_PAGE_SIZE_64KB)
|
||||
status |= (TFP_PAGESIZE_64K << 32) | (TFP_PAGESIZE_64K << 36);
|
||||
#endif
|
||||
write_c0_status(status);
|
||||
|
||||
write_c0_wired(0);
|
||||
|
||||
local_flush_tlb_all();
|
||||
|
||||
build_tlb_refill_handler();
|
||||
}
|
@ -545,7 +545,6 @@ void build_tlb_write_entry(u32 **p, struct uasm_label **l,
|
||||
tlbw(p);
|
||||
break;
|
||||
|
||||
case CPU_R4300:
|
||||
case CPU_5KC:
|
||||
case CPU_TX49XX:
|
||||
case CPU_PR4450:
|
||||
@ -604,13 +603,12 @@ void build_tlb_write_entry(u32 **p, struct uasm_label **l,
|
||||
|
||||
case CPU_VR4131:
|
||||
case CPU_VR4133:
|
||||
case CPU_R5432:
|
||||
uasm_i_nop(p);
|
||||
uasm_i_nop(p);
|
||||
tlbw(p);
|
||||
break;
|
||||
|
||||
case CPU_JZRISC:
|
||||
case CPU_XBURST:
|
||||
tlbw(p);
|
||||
uasm_i_nop(p);
|
||||
break;
|
||||
@ -631,7 +629,7 @@ static __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpu_has_rixi && _PAGE_NO_EXEC) {
|
||||
if (cpu_has_rixi && !!_PAGE_NO_EXEC) {
|
||||
if (fill_includes_sw_bits) {
|
||||
UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL));
|
||||
} else {
|
||||
@ -2609,21 +2607,11 @@ void build_tlb_refill_handler(void)
|
||||
check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
|
||||
#endif
|
||||
|
||||
switch (current_cpu_type()) {
|
||||
case CPU_R2000:
|
||||
case CPU_R3000:
|
||||
case CPU_R3000A:
|
||||
case CPU_R3081E:
|
||||
case CPU_TX3912:
|
||||
case CPU_TX3922:
|
||||
case CPU_TX3927:
|
||||
if (cpu_has_3kex) {
|
||||
#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
|
||||
if (cpu_has_local_ebase)
|
||||
build_r3000_tlb_refill_handler();
|
||||
if (!run_once) {
|
||||
if (!cpu_has_local_ebase)
|
||||
build_r3000_tlb_refill_handler();
|
||||
build_setup_pgd();
|
||||
build_r3000_tlb_refill_handler();
|
||||
build_r3000_tlb_load_handler();
|
||||
build_r3000_tlb_store_handler();
|
||||
build_r3000_tlb_modify_handler();
|
||||
@ -2633,34 +2621,27 @@ void build_tlb_refill_handler(void)
|
||||
#else
|
||||
panic("No R3000 TLB refill handler");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case CPU_R8000:
|
||||
panic("No R8000 TLB refill handler yet");
|
||||
break;
|
||||
|
||||
default:
|
||||
if (cpu_has_ldpte)
|
||||
setup_pw();
|
||||
|
||||
if (!run_once) {
|
||||
scratch_reg = allocate_kscratch();
|
||||
build_setup_pgd();
|
||||
build_r4000_tlb_load_handler();
|
||||
build_r4000_tlb_store_handler();
|
||||
build_r4000_tlb_modify_handler();
|
||||
if (cpu_has_ldpte)
|
||||
build_loongson3_tlb_refill_handler();
|
||||
else if (!cpu_has_local_ebase)
|
||||
build_r4000_tlb_refill_handler();
|
||||
flush_tlb_handlers();
|
||||
run_once++;
|
||||
}
|
||||
if (cpu_has_local_ebase)
|
||||
build_r4000_tlb_refill_handler();
|
||||
if (cpu_has_xpa)
|
||||
config_xpa_params();
|
||||
if (cpu_has_htw)
|
||||
config_htw_params();
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpu_has_ldpte)
|
||||
setup_pw();
|
||||
|
||||
if (!run_once) {
|
||||
scratch_reg = allocate_kscratch();
|
||||
build_setup_pgd();
|
||||
build_r4000_tlb_load_handler();
|
||||
build_r4000_tlb_store_handler();
|
||||
build_r4000_tlb_modify_handler();
|
||||
if (cpu_has_ldpte)
|
||||
build_loongson3_tlb_refill_handler();
|
||||
else
|
||||
build_r4000_tlb_refill_handler();
|
||||
flush_tlb_handlers();
|
||||
run_once++;
|
||||
}
|
||||
if (cpu_has_xpa)
|
||||
config_xpa_params();
|
||||
if (cpu_has_htw)
|
||||
config_htw_params();
|
||||
}
|
||||
|
@ -39,17 +39,6 @@ void __init fw_meminit(void)
|
||||
|
||||
void __init prom_free_prom_memory(void)
|
||||
{
|
||||
unsigned long addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
|
||||
continue;
|
||||
|
||||
addr = boot_mem_map.map[i].addr;
|
||||
free_init_pages("YAMON memory",
|
||||
addr, addr + boot_mem_map.map[i].size);
|
||||
}
|
||||
}
|
||||
|
||||
phys_addr_t mips_cdmm_phys_base(void)
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/memblock.h>
|
||||
|
||||
#include <asm/idle.h>
|
||||
#include <asm/reboot.h>
|
||||
@ -67,12 +68,11 @@ static void nlm_linux_exit(void)
|
||||
static void nlm_fixup_mem(void)
|
||||
{
|
||||
const int pref_backup = 512;
|
||||
int i;
|
||||
struct memblock_region *mem;
|
||||
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
|
||||
continue;
|
||||
boot_mem_map.map[i].size -= pref_backup;
|
||||
for_each_memblock(memory, mem) {
|
||||
memblock_remove(mem->base + mem->size - pref_backup,
|
||||
pref_backup);
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ void __init plat_mem_setup(void)
|
||||
/* memory and bootargs from DT */
|
||||
xlp_early_init_devtree();
|
||||
|
||||
if (boot_mem_map.nr_map == 0) {
|
||||
if (memblock_end_of_DRAM() == 0) {
|
||||
pr_info("Using DRAM BARs for memory map.\n");
|
||||
xlp_init_mem_from_bars();
|
||||
}
|
||||
|
@ -20,16 +20,50 @@
|
||||
* Most of the IOC3 PCI config register aren't present
|
||||
* we emulate what is needed for a normal PCI enumeration
|
||||
*/
|
||||
static u32 emulate_ioc3_cfg(int where, int size)
|
||||
static int ioc3_cfg_rd(void *addr, int where, int size, u32 *value)
|
||||
{
|
||||
if (size == 1 && where == 0x3d)
|
||||
return 0x01;
|
||||
else if (size == 2 && where == 0x3c)
|
||||
return 0x0100;
|
||||
else if (size == 4 && where == 0x3c)
|
||||
return 0x00000100;
|
||||
u32 cf, shift, mask;
|
||||
|
||||
return 0;
|
||||
switch (where & ~3) {
|
||||
case 0x00 ... 0x10:
|
||||
case 0x40 ... 0x44:
|
||||
if (get_dbe(cf, (u32 *)addr))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
break;
|
||||
case 0x3c:
|
||||
/* emulate sane interrupt pin value */
|
||||
cf = 0x00000100;
|
||||
break;
|
||||
default:
|
||||
cf = 0;
|
||||
break;
|
||||
}
|
||||
shift = (where & 3) << 3;
|
||||
mask = 0xffffffffU >> ((4 - size) << 3);
|
||||
*value = (cf >> shift) & mask;
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int ioc3_cfg_wr(void *addr, int where, int size, u32 value)
|
||||
{
|
||||
u32 cf, shift, mask, smask;
|
||||
|
||||
if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
|
||||
if (get_dbe(cf, (u32 *)addr))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
shift = ((where & 3) << 3);
|
||||
mask = (0xffffffffU >> ((4 - size) << 3));
|
||||
smask = mask << shift;
|
||||
|
||||
cf = (cf & ~smask) | ((value & mask) << shift);
|
||||
if (put_dbe(cf, (u32 *)addr))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static void bridge_disable_swapping(struct pci_dev *dev)
|
||||
@ -64,7 +98,7 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int slot = PCI_SLOT(devfn);
|
||||
int fn = PCI_FUNC(devfn);
|
||||
void *addr;
|
||||
u32 cf, shift, mask;
|
||||
u32 cf;
|
||||
int res;
|
||||
|
||||
addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
|
||||
@ -75,8 +109,10 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
* IOC3 is broken beyond belief ... Don't even give the
|
||||
* generic PCI code a chance to look at it for real ...
|
||||
*/
|
||||
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
|
||||
goto is_ioc3;
|
||||
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) {
|
||||
addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
|
||||
return ioc3_cfg_rd(addr, where, size, value);
|
||||
}
|
||||
|
||||
addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
|
||||
|
||||
@ -88,26 +124,6 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
res = get_dbe(*value, (u32 *)addr);
|
||||
|
||||
return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
|
||||
|
||||
is_ioc3:
|
||||
|
||||
/*
|
||||
* IOC3 special handling
|
||||
*/
|
||||
if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
|
||||
*value = emulate_ioc3_cfg(where, size);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
|
||||
if (get_dbe(cf, (u32 *)addr))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
shift = ((where & 3) << 3);
|
||||
mask = (0xffffffffU >> ((4 - size) << 3));
|
||||
*value = (cf >> shift) & mask;
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
@ -119,7 +135,7 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int slot = PCI_SLOT(devfn);
|
||||
int fn = PCI_FUNC(devfn);
|
||||
void *addr;
|
||||
u32 cf, shift, mask;
|
||||
u32 cf;
|
||||
int res;
|
||||
|
||||
bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
|
||||
@ -131,8 +147,10 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
* IOC3 is broken beyond belief ... Don't even give the
|
||||
* generic PCI code a chance to look at it for real ...
|
||||
*/
|
||||
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
|
||||
goto is_ioc3;
|
||||
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) {
|
||||
addr = &bridge->b_type1_cfg.c[(fn << 8) | (where & ~3)];
|
||||
return ioc3_cfg_rd(addr, where, size, value);
|
||||
}
|
||||
|
||||
addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
|
||||
|
||||
@ -144,26 +162,6 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
res = get_dbe(*value, (u32 *)addr);
|
||||
|
||||
return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
|
||||
|
||||
is_ioc3:
|
||||
|
||||
/*
|
||||
* IOC3 special handling
|
||||
*/
|
||||
if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
|
||||
*value = emulate_ioc3_cfg(where, size);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
addr = &bridge->b_type1_cfg.c[(fn << 8) | where];
|
||||
if (get_dbe(cf, (u32 *)addr))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
shift = ((where & 3) << 3);
|
||||
mask = (0xffffffffU >> ((4 - size) << 3));
|
||||
*value = (cf >> shift) & mask;
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int pci_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
@ -183,7 +181,7 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int slot = PCI_SLOT(devfn);
|
||||
int fn = PCI_FUNC(devfn);
|
||||
void *addr;
|
||||
u32 cf, shift, mask, smask;
|
||||
u32 cf;
|
||||
int res;
|
||||
|
||||
addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
|
||||
@ -194,8 +192,10 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
* IOC3 is broken beyond belief ... Don't even give the
|
||||
* generic PCI code a chance to look at it for real ...
|
||||
*/
|
||||
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
|
||||
goto is_ioc3;
|
||||
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) {
|
||||
addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
|
||||
return ioc3_cfg_wr(addr, where, size, value);
|
||||
}
|
||||
|
||||
addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
|
||||
|
||||
@ -210,29 +210,6 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
|
||||
is_ioc3:
|
||||
|
||||
/*
|
||||
* IOC3 special handling
|
||||
*/
|
||||
if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
|
||||
addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
|
||||
|
||||
if (get_dbe(cf, (u32 *)addr))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
shift = ((where & 3) << 3);
|
||||
mask = (0xffffffffU >> ((4 - size) << 3));
|
||||
smask = mask << shift;
|
||||
|
||||
cf = (cf & ~smask) | ((value & mask) << shift);
|
||||
if (put_dbe(cf, (u32 *)addr))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
@ -244,7 +221,7 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int fn = PCI_FUNC(devfn);
|
||||
int busno = bus->number;
|
||||
void *addr;
|
||||
u32 cf, shift, mask, smask;
|
||||
u32 cf;
|
||||
int res;
|
||||
|
||||
bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
|
||||
@ -256,8 +233,10 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
* IOC3 is broken beyond belief ... Don't even give the
|
||||
* generic PCI code a chance to look at it for real ...
|
||||
*/
|
||||
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
|
||||
goto is_ioc3;
|
||||
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) {
|
||||
addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
|
||||
return ioc3_cfg_wr(addr, where, size, value);
|
||||
}
|
||||
|
||||
addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
|
||||
|
||||
@ -272,28 +251,6 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
|
||||
is_ioc3:
|
||||
|
||||
/*
|
||||
* IOC3 special handling
|
||||
*/
|
||||
if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
|
||||
addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
|
||||
if (get_dbe(cf, (u32 *)addr))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
shift = ((where & 3) << 3);
|
||||
mask = (0xffffffffU >> ((4 - size) << 3));
|
||||
smask = mask << shift;
|
||||
|
||||
cf = (cf & ~smask) | ((value & mask) << shift);
|
||||
if (put_dbe(cf, (u32 *)addr))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
|
@ -61,6 +61,10 @@ int init_debug = 1;
|
||||
/* memory blocks */
|
||||
struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
|
||||
|
||||
static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
|
||||
static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
|
||||
static unsigned int nr_prom_mem __initdata;
|
||||
|
||||
/* default feature sets */
|
||||
static char msp_default_features[] =
|
||||
#if defined(CONFIG_PMC_MSP4200_EVAL) \
|
||||
@ -352,6 +356,16 @@ void __init prom_meminit(void)
|
||||
|
||||
add_memory_region(base, size, type);
|
||||
p++;
|
||||
|
||||
if (type == BOOT_MEM_ROM_DATA) {
|
||||
if (nr_prom_mem >= 5) {
|
||||
pr_err("Too many ROM DATA regions");
|
||||
continue;
|
||||
}
|
||||
prom_mem_base[nr_prom_mem] = base;
|
||||
prom_mem_size[nr_prom_mem] = size;
|
||||
nr_prom_mem++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -407,13 +421,9 @@ void __init prom_free_prom_memory(void)
|
||||
envp[i] = NULL; /* end array with null pointer */
|
||||
prom_envp = envp;
|
||||
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
|
||||
continue;
|
||||
|
||||
addr = boot_mem_map.map[i].addr;
|
||||
for (i = 0; i < nr_prom_mem; i++) {
|
||||
free_init_pages("prom memory",
|
||||
addr, addr + boot_mem_map.map[i].size);
|
||||
prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user