Commit 5c6bd5de authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents f7c3bf8f 05d013a0
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";
};
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>;
};
};
};
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
......
.. SPDX-License-Identifier: GPL-2.0
=================
MIPS architecture
=================
===========================
MIPS-specific Documentation
===========================
.. toctree::
:maxdepth: 2
:numbered:
ingenic-tcu
au1xxx_ide
......
.. 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 @@ ubus {
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 @@ ubus {
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 @@ ubus {
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 @@ ubus {
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 @@ ubus {
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 @@ ubus {
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 @@ pins_mmc1: mmc1 {
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 @@ &uhc {
/* 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 @@ watchdog: watchdog@10002000 {
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 @@ gpd: gpio@3 {
};
};
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 @@ uart1: serial@10031000 {
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 @@ dmac: dma-controller@13020000 {
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 @@ uhc: uhc@13030000 {
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 @@ cgu: jz4770-cgu@10000000 {
#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 @@ cgu: jz4780-cgu@10000000 {
#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 = <&amp_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 = <&amp>;
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 @@ &uart0 {
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 @@ switch@1010000 {
reg = <0x1010000 0x10000>,
<0x1030000 0x10000>,
<0x1080000 0x100>,
<0x10e0000 0x10000>,
<0x11e0000 0x100>,
<0x11f0000 0x100>,
<0x1200000 0x100>,
......@@ -134,12 +135,12 @@ switch@1010000 {
<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,
......
# 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" \
......@@ -133,7 +135,8 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
"2: \n" \
: "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \
: GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \
: "memory"); \
: __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
......
/* 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
/* 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
/* 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
/* 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 */
/*
* 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;
}
......
/* 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
This diff is collapsed.
// 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)
......
This diff is collapsed.
......@@ -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;
......
This diff is collapsed.
......@@ -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;
if (current_cpu_type() == CPU_XBURST) {
switch (mips_machtype) {
/*
* According to config2 it would be 5-ways, but that is contradicted
* by all documentation.
* 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)
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);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment