forked from Minki/linux
The imx soc changes for 3.10:
* Enable anatop, well bisa and RBC for suspend to optimize the power consumption a little bit * Clock changes for TVE, LDB, PATA, SRTC support * Add System Reset Controller (SRC) support for imx5 and imx6 * Add initial imx6dl support based on imx6q code * Kconfig for cpufreq-cpu0, defconfig updates and few other changes -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAABAgAGBQJRZ/viAAoJEFBXWFqHsHzOyqUH/2t7CCwlfTVUJYDCeo6PaE9x 41cV5zG6RvX1OfkRUmJ2N2klGn4zhwg6GHsCDQmvs+IODs4E7JeB9M92FAaPng71 NnuuwCQ01iIoaTtkz8z/n3tSet3fYB+xfNCMJoWIyS0edFFkCjOgnqRsA0pHRIOp G6ey1kU80D0f4+DjAUg1mkIvJrZxbRKDwmwqfDGJzQ4VU7cv70n027YuMKbeMyCC zdeKmpKSEl9AY+O/zeMrf03zEW+kdZ4eB6cTUFlpzYwPYY9o+XHx0U0535F7/x4+ KObUZ9Qg7liP5WO3ZzkVff5HJqPs6s/q99eOsU4/okF1x0fpq2mSgIHlSw4HpK8= =TuTx -----END PGP SIGNATURE----- Merge tag 'imx-soc-3.10' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/soc2 From Shawn Guo: The imx soc changes for 3.10: * Enable anatop, well bisa and RBC for suspend to optimize the power consumption a little bit * Clock changes for TVE, LDB, PATA, SRTC support * Add System Reset Controller (SRC) support for imx5 and imx6 * Add initial imx6dl support based on imx6q code * Kconfig for cpufreq-cpu0, defconfig updates and few other changes * tag 'imx-soc-3.10' of git://git.linaro.org/people/shawnguo/linux-2.6: (275 commits) ARM i.MX53: set CLK_SET_RATE_PARENT flag on the tve_ext_sel clock ARM i.MX53: tve_di clock is not part of the CCM, but of TVE ARM i.MX53: make tve_ext_sel propagate rate change to PLL ARM i.MX53: Remove unused tve_gate clkdev entry ARM i.MX5: Remove tve_sel clock from i.MX53 clock tree ARM: i.MX5: Add PATA and SRTC clocks ARM: imx: do not bring up unavailable cores ARM: imx: add initial imx6dl support ARM: imx1: mm: add call to mxc_device_init ARM: imx_v4_v5_defconfig: Add CONFIG_GPIO_SYSFS ARM: imx_v6_v7_defconfig: Select CONFIG_PERF_EVENTS ARM: i.MX53 Add the cko1, cko2 clock outputs. staging: drm/imx: Use SRC to reset IPU ARM i.MX6q: Add GPU, VPU, IPU, and OpenVG resets to System Reset Controller (SRC) ARM: imx: do not use regmap_read for ANADIG_DIGPROG ARM i.MX6q: set the LDB serial clock parent to the video PLL ARM i.MX6q: Add audio/video PLL post dividers for i.MX6q rev 1.1 ARM i.MX6q: fix ldb di divider and selector clocks ARM i.MX53: fix ldb di divider and selector clocks ARM i.MX: Add imx_clk_divider_flags and imx_clk_mux_flags ... Signed-off-by: Olof Johansson <olof@lixom.net> Trivial change/change conflict in arch/arm/mach-imx/mach-imx6q.c resolved.
This commit is contained in:
commit
567b1b0839
@ -38,7 +38,6 @@ clocks and IDs.
|
||||
usb_phy_podf 23
|
||||
cpu_podf 24
|
||||
di_pred 25
|
||||
tve_di 26
|
||||
tve_s 27
|
||||
uart1_ipg_gate 28
|
||||
uart1_per_gate 29
|
||||
@ -172,6 +171,19 @@ clocks and IDs.
|
||||
can1_serial_gate 157
|
||||
can1_ipg_gate 158
|
||||
owire_gate 159
|
||||
gpu3d_s 160
|
||||
gpu2d_s 161
|
||||
gpu3d_gate 162
|
||||
gpu2d_gate 163
|
||||
garb_gate 164
|
||||
cko1_sel 165
|
||||
cko1_podf 166
|
||||
cko1 167
|
||||
cko2_sel 168
|
||||
cko2_podf 169
|
||||
cko2 170
|
||||
srtc_gate 171
|
||||
pata_gate 172
|
||||
|
||||
Examples (for mx53):
|
||||
|
||||
|
@ -205,6 +205,9 @@ clocks and IDs.
|
||||
enet_ref 190
|
||||
usbphy1_gate 191
|
||||
usbphy2_gate 192
|
||||
pll4_post_div 193
|
||||
pll5_post_div 194
|
||||
pll5_video_div 195
|
||||
|
||||
Examples:
|
||||
|
||||
|
49
Documentation/devicetree/bindings/reset/fsl,imx-src.txt
Normal file
49
Documentation/devicetree/bindings/reset/fsl,imx-src.txt
Normal file
@ -0,0 +1,49 @@
|
||||
Freescale i.MX System Reset Controller
|
||||
======================================
|
||||
|
||||
Please also refer to reset.txt in this directory for common reset
|
||||
controller binding usage.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "fsl,<chip>-src"
|
||||
- reg: should be register base and length as documented in the
|
||||
datasheet
|
||||
- interrupts: Should contain SRC interrupt and CPU WDOG interrupt,
|
||||
in this order.
|
||||
- #reset-cells: 1, see below
|
||||
|
||||
example:
|
||||
|
||||
src: src@020d8000 {
|
||||
compatible = "fsl,imx6q-src";
|
||||
reg = <0x020d8000 0x4000>;
|
||||
interrupts = <0 91 0x04 0 96 0x04>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
Specifying reset lines connected to IP modules
|
||||
==============================================
|
||||
|
||||
The system reset controller can be used to reset the GPU, VPU,
|
||||
IPU, and OpenVG IP modules on i.MX5 and i.MX6 ICs. Those device
|
||||
nodes should specify the reset line on the SRC in their resets
|
||||
property, containing a phandle to the SRC device node and a
|
||||
RESET_INDEX specifying which module to reset, as described in
|
||||
reset.txt
|
||||
|
||||
example:
|
||||
|
||||
ipu1: ipu@02400000 {
|
||||
resets = <&src 2>;
|
||||
};
|
||||
ipu2: ipu@02800000 {
|
||||
resets = <&src 4>;
|
||||
};
|
||||
|
||||
The following RESET_INDEX values are valid for i.MX5:
|
||||
GPU_RESET 0
|
||||
VPU_RESET 1
|
||||
IPU1_RESET 2
|
||||
OPEN_VG_RESET 3
|
||||
The following additional RESET_INDEX value is valid for i.MX6:
|
||||
IPU2_RESET 4
|
75
Documentation/devicetree/bindings/reset/reset.txt
Normal file
75
Documentation/devicetree/bindings/reset/reset.txt
Normal file
@ -0,0 +1,75 @@
|
||||
= Reset Signal Device Tree Bindings =
|
||||
|
||||
This binding is intended to represent the hardware reset signals present
|
||||
internally in most IC (SoC, FPGA, ...) designs. Reset signals for whole
|
||||
standalone chips are most likely better represented as GPIOs, although there
|
||||
are likely to be exceptions to this rule.
|
||||
|
||||
Hardware blocks typically receive a reset signal. This signal is generated by
|
||||
a reset provider (e.g. power management or clock module) and received by a
|
||||
reset consumer (the module being reset, or a module managing when a sub-
|
||||
ordinate module is reset). This binding exists to represent the provider and
|
||||
consumer, and provide a way to couple the two together.
|
||||
|
||||
A reset signal is represented by the phandle of the provider, plus a reset
|
||||
specifier - a list of DT cells that represents the reset signal within the
|
||||
provider. The length (number of cells) and semantics of the reset specifier
|
||||
are dictated by the binding of the reset provider, although common schemes
|
||||
are described below.
|
||||
|
||||
A word on where to place reset signal consumers in device tree: It is possible
|
||||
in hardware for a reset signal to affect multiple logically separate HW blocks
|
||||
at once. In this case, it would be unwise to represent this reset signal in
|
||||
the DT node of each affected HW block, since if activated, an unrelated block
|
||||
may be reset. Instead, reset signals should be represented in the DT node
|
||||
where it makes most sense to control it; this may be a bus node if all
|
||||
children of the bus are affected by the reset signal, or an individual HW
|
||||
block node for dedicated reset signals. The intent of this binding is to give
|
||||
appropriate software access to the reset signals in order to manage the HW,
|
||||
rather than to slavishly enumerate the reset signal that affects each HW
|
||||
block.
|
||||
|
||||
= Reset providers =
|
||||
|
||||
Required properties:
|
||||
#reset-cells: Number of cells in a reset specifier; Typically 0 for nodes
|
||||
with a single reset output and 1 for nodes with multiple
|
||||
reset outputs.
|
||||
|
||||
For example:
|
||||
|
||||
rst: reset-controller {
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
= Reset consumers =
|
||||
|
||||
Required properties:
|
||||
resets: List of phandle and reset specifier pairs, one pair
|
||||
for each reset signal that affects the device, or that the
|
||||
device manages. Note: if the reset provider specifies '0' for
|
||||
#reset-cells, then only the phandle portion of the pair will
|
||||
appear.
|
||||
|
||||
Optional properties:
|
||||
reset-names: List of reset signal name strings sorted in the same order as
|
||||
the resets property. Consumers drivers will use reset-names to
|
||||
match reset signal names with reset specifiers.
|
||||
|
||||
For example:
|
||||
|
||||
device {
|
||||
resets = <&rst 20>;
|
||||
reset-names = "reset";
|
||||
};
|
||||
|
||||
This represents a device with a single reset signal named "reset".
|
||||
|
||||
bus {
|
||||
resets = <&rst 10> <&rst 11> <&rst 12> <&rst 11>;
|
||||
reset-names = "i2s1", "i2s2", "dma", "mixer";
|
||||
};
|
||||
|
||||
This represents a bus that controls the reset signal of each of four sub-
|
||||
ordinate devices. Consider for example a bus that fails to operate unless no
|
||||
child device has reset asserted.
|
@ -8,6 +8,8 @@ Required properties:
|
||||
- interrupts: Should contain sync interrupt and error interrupt,
|
||||
in this order.
|
||||
- #crtc-cells: 1, See below
|
||||
- resets: phandle pointing to the system reset controller and
|
||||
reset line index, see reset/fsl,imx-src.txt for details
|
||||
|
||||
example:
|
||||
|
||||
@ -16,6 +18,7 @@ ipu: ipu@18000000 {
|
||||
compatible = "fsl,imx53-ipu";
|
||||
reg = <0x18000000 0x080000000>;
|
||||
interrupts = <11 10>;
|
||||
resets = <&src 2>;
|
||||
};
|
||||
|
||||
Parallel display support
|
||||
|
@ -890,9 +890,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
enable_msi - Enable Message Signaled Interrupt (MSI) (default = off)
|
||||
power_save - Automatic power-saving timeout (in second, 0 =
|
||||
disable)
|
||||
power_save_controller - Support runtime D3 of HD-audio controller
|
||||
(-1 = on for supported chip (default), false = off,
|
||||
true = force to on even for unsupported hardware)
|
||||
power_save_controller - Reset HD-audio controller in power-saving mode
|
||||
(default = on)
|
||||
align_buffer_size - Force rounding of buffer/period sizes to multiples
|
||||
of 128 bytes. This is more efficient in terms of memory
|
||||
access but isn't required by the HDA spec and prevents
|
||||
|
@ -5065,9 +5065,8 @@ S: Maintained
|
||||
F: drivers/net/ethernet/marvell/sk*
|
||||
|
||||
MARVELL LIBERTAS WIRELESS DRIVER
|
||||
M: Dan Williams <dcbw@redhat.com>
|
||||
L: libertas-dev@lists.infradead.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/net/wireless/libertas/
|
||||
|
||||
MARVELL MV643XX ETHERNET DRIVER
|
||||
@ -5569,6 +5568,7 @@ F: include/uapi/linux/if_*
|
||||
F: include/uapi/linux/netdevice.h
|
||||
|
||||
NETXEN (1/10) GbE SUPPORT
|
||||
M: Manish Chopra <manish.chopra@qlogic.com>
|
||||
M: Sony Chacko <sony.chacko@qlogic.com>
|
||||
M: Rajesh Borundia <rajesh.borundia@qlogic.com>
|
||||
L: netdev@vger.kernel.org
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc5
|
||||
EXTRAVERSION = -rc6
|
||||
NAME = Unicycling Gorilla
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -12,7 +12,7 @@ NM := $(NM) -B
|
||||
|
||||
LDFLAGS_vmlinux := -static -N #-relax
|
||||
CHECKFLAGS += -D__alpha__ -m64
|
||||
cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data
|
||||
cflags-y := -pipe -mno-fp-regs -ffixed-8
|
||||
cflags-y += $(call cc-option, -fno-jump-tables)
|
||||
|
||||
cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4
|
||||
|
@ -26,7 +26,7 @@
|
||||
#define fd_disable_irq() disable_irq(FLOPPY_IRQ)
|
||||
#define fd_cacheflush(addr,size) /* nothing */
|
||||
#define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt,\
|
||||
IRQF_DISABLED, "floppy", NULL)
|
||||
0, "floppy", NULL)
|
||||
#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL)
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
|
@ -117,13 +117,6 @@ handle_irq(int irq)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* From here we must proceed with IPL_MAX. Note that we do not
|
||||
* explicitly enable interrupts afterwards - some MILO PALcode
|
||||
* (namely LX164 one) seems to have severe problems with RTI
|
||||
* at IPL 0.
|
||||
*/
|
||||
local_irq_disable();
|
||||
irq_enter();
|
||||
generic_handle_irq_desc(irq, desc);
|
||||
irq_exit();
|
||||
|
@ -45,6 +45,14 @@ do_entInt(unsigned long type, unsigned long vector,
|
||||
unsigned long la_ptr, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *old_regs;
|
||||
|
||||
/*
|
||||
* Disable interrupts during IRQ handling.
|
||||
* Note that there is no matching local_irq_enable() due to
|
||||
* severe problems with RTI at IPL0 and some MILO PALcode
|
||||
* (namely LX164).
|
||||
*/
|
||||
local_irq_disable();
|
||||
switch (type) {
|
||||
case 0:
|
||||
#ifdef CONFIG_SMP
|
||||
@ -62,7 +70,6 @@ do_entInt(unsigned long type, unsigned long vector,
|
||||
{
|
||||
long cpu;
|
||||
|
||||
local_irq_disable();
|
||||
smp_percpu_timer_interrupt(regs);
|
||||
cpu = smp_processor_id();
|
||||
if (cpu != boot_cpuid) {
|
||||
@ -222,7 +229,6 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr,
|
||||
|
||||
struct irqaction timer_irqaction = {
|
||||
.handler = timer_interrupt,
|
||||
.flags = IRQF_DISABLED,
|
||||
.name = "timer",
|
||||
};
|
||||
|
||||
|
@ -188,6 +188,10 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr)
|
||||
extern void free_reserved_mem(void *, void *);
|
||||
extern void pcibios_claim_one_bus(struct pci_bus *);
|
||||
|
||||
static struct resource irongate_io = {
|
||||
.name = "Irongate PCI IO",
|
||||
.flags = IORESOURCE_IO,
|
||||
};
|
||||
static struct resource irongate_mem = {
|
||||
.name = "Irongate PCI MEM",
|
||||
.flags = IORESOURCE_MEM,
|
||||
@ -209,6 +213,7 @@ nautilus_init_pci(void)
|
||||
|
||||
irongate = pci_get_bus_and_slot(0, 0);
|
||||
bus->self = irongate;
|
||||
bus->resource[0] = &irongate_io;
|
||||
bus->resource[1] = &irongate_mem;
|
||||
|
||||
pci_bus_size_bridges(bus);
|
||||
|
@ -280,15 +280,15 @@ titan_late_init(void)
|
||||
* all reported to the kernel as machine checks, so the handler
|
||||
* is a nop so it can be called to count the individual events.
|
||||
*/
|
||||
titan_request_irq(63+16, titan_intr_nop, IRQF_DISABLED,
|
||||
titan_request_irq(63+16, titan_intr_nop, 0,
|
||||
"CChip Error", NULL);
|
||||
titan_request_irq(62+16, titan_intr_nop, IRQF_DISABLED,
|
||||
titan_request_irq(62+16, titan_intr_nop, 0,
|
||||
"PChip 0 H_Error", NULL);
|
||||
titan_request_irq(61+16, titan_intr_nop, IRQF_DISABLED,
|
||||
titan_request_irq(61+16, titan_intr_nop, 0,
|
||||
"PChip 1 H_Error", NULL);
|
||||
titan_request_irq(60+16, titan_intr_nop, IRQF_DISABLED,
|
||||
titan_request_irq(60+16, titan_intr_nop, 0,
|
||||
"PChip 0 C_Error", NULL);
|
||||
titan_request_irq(59+16, titan_intr_nop, IRQF_DISABLED,
|
||||
titan_request_irq(59+16, titan_intr_nop, 0,
|
||||
"PChip 1 C_Error", NULL);
|
||||
|
||||
/*
|
||||
@ -348,9 +348,9 @@ privateer_init_pci(void)
|
||||
* Hook a couple of extra err interrupts that the
|
||||
* common titan code won't.
|
||||
*/
|
||||
titan_request_irq(53+16, titan_intr_nop, IRQF_DISABLED,
|
||||
titan_request_irq(53+16, titan_intr_nop, 0,
|
||||
"NMI", NULL);
|
||||
titan_request_irq(50+16, titan_intr_nop, IRQF_DISABLED,
|
||||
titan_request_irq(50+16, titan_intr_nop, 0,
|
||||
"Temperature Warning", NULL);
|
||||
|
||||
/*
|
||||
|
@ -1183,9 +1183,9 @@ config ARM_NR_BANKS
|
||||
default 8
|
||||
|
||||
config IWMMXT
|
||||
bool "Enable iWMMXt support"
|
||||
bool "Enable iWMMXt support" if !CPU_PJ4
|
||||
depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4
|
||||
default y if PXA27x || PXA3xx || ARCH_MMP
|
||||
default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4
|
||||
help
|
||||
Enable support for iWMMXt context switching at run time if
|
||||
running on a CPU that supports it.
|
||||
@ -1439,6 +1439,16 @@ config ARM_ERRATA_775420
|
||||
to deadlock. This workaround puts DSB before executing ISB if
|
||||
an abort may occur on cache maintenance.
|
||||
|
||||
config ARM_ERRATA_798181
|
||||
bool "ARM errata: TLBI/DSB failure on Cortex-A15"
|
||||
depends on CPU_V7 && SMP
|
||||
help
|
||||
On Cortex-A15 (r0p0..r3p2) the TLBI*IS/DSB operations are not
|
||||
adequately shooting down all use of the old entries. This
|
||||
option enables the Linux kernel workaround for this erratum
|
||||
which sends an IPI to the CPUs that are running the same ASID
|
||||
as the one being invalidated.
|
||||
|
||||
endmenu
|
||||
|
||||
source "arch/arm/common/Kconfig"
|
||||
@ -2154,13 +2164,6 @@ if ARCH_HAS_CPUFREQ
|
||||
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
|
||||
config CPU_FREQ_IMX
|
||||
tristate "CPUfreq driver for i.MX CPUs"
|
||||
depends on ARCH_MXC && CPU_FREQ
|
||||
select CPU_FREQ_TABLE
|
||||
help
|
||||
This enables the CPUfreq driver for i.MX CPUs.
|
||||
|
||||
config CPU_FREQ_SA1100
|
||||
bool
|
||||
|
||||
|
@ -234,11 +234,11 @@ choice
|
||||
on i.MX53.
|
||||
|
||||
config DEBUG_IMX6Q_UART
|
||||
bool "i.MX6Q Debug UART"
|
||||
bool "i.MX6Q/DL Debug UART"
|
||||
depends on SOC_IMX6Q
|
||||
help
|
||||
Say Y here if you want kernel low-level debugging support
|
||||
on i.MX6Q.
|
||||
on i.MX6Q/DL.
|
||||
|
||||
config DEBUG_MMP_UART2
|
||||
bool "Kernel low-level debugging message via MMP UART2"
|
||||
|
@ -54,7 +54,7 @@
|
||||
};
|
||||
|
||||
mvsdio@d00d4000 {
|
||||
pinctrl-0 = <&sdio_pins2>;
|
||||
pinctrl-0 = <&sdio_pins3>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
/*
|
||||
|
@ -59,6 +59,12 @@
|
||||
"mpp50", "mpp51", "mpp52";
|
||||
marvell,function = "sd0";
|
||||
};
|
||||
|
||||
sdio_pins3: sdio-pins3 {
|
||||
marvell,pins = "mpp48", "mpp49", "mpp50",
|
||||
"mpp51", "mpp52", "mpp53";
|
||||
marvell,function = "sd0";
|
||||
};
|
||||
};
|
||||
|
||||
gpio0: gpio@d0018100 {
|
||||
|
@ -191,8 +191,8 @@
|
||||
|
||||
prcmu: prcmu@80157000 {
|
||||
compatible = "stericsson,db8500-prcmu";
|
||||
reg = <0x80157000 0x1000>;
|
||||
reg-names = "prcmu";
|
||||
reg = <0x80157000 0x1000>, <0x801b0000 0x8000>, <0x801b8000 0x1000>;
|
||||
reg-names = "prcmu", "prcmu-tcpm", "prcmu-tcdm";
|
||||
interrupts = <0 47 0x4>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
@ -91,6 +91,7 @@
|
||||
compatible = "arm,cortex-a9-twd-timer";
|
||||
reg = <0x00a00600 0x20>;
|
||||
interrupts = <1 13 0xf01>;
|
||||
clocks = <&clks 15>;
|
||||
};
|
||||
|
||||
L2: l2-cache@00a02000 {
|
||||
|
@ -77,6 +77,7 @@
|
||||
};
|
||||
|
||||
nand@3000000 {
|
||||
chip-delay = <40>;
|
||||
status = "okay";
|
||||
|
||||
partition@0 {
|
||||
|
@ -13,6 +13,9 @@
|
||||
compatible = "marvell,orion5x";
|
||||
interrupt-parent = <&intc>;
|
||||
|
||||
aliases {
|
||||
gpio0 = &gpio0;
|
||||
};
|
||||
intc: interrupt-controller {
|
||||
compatible = "marvell,orion-intc", "marvell,intc";
|
||||
interrupt-controller;
|
||||
@ -32,7 +35,9 @@
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
reg = <0x10100 0x40>;
|
||||
ngpio = <32>;
|
||||
ngpios = <32>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
interrupts = <6>, <7>, <8>, <9>;
|
||||
};
|
||||
|
||||
@ -91,7 +96,7 @@
|
||||
reg = <0x90000 0x10000>,
|
||||
<0xf2200000 0x800>;
|
||||
reg-names = "regs", "sram";
|
||||
interrupts = <22>;
|
||||
interrupts = <28>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
@ -109,6 +109,7 @@ CONFIG_I2C_IMX=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_IMX=y
|
||||
CONFIG_SPI_SPIDEV=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_W1=y
|
||||
CONFIG_W1_MASTER_MXC=y
|
||||
CONFIG_W1_SLAVE_THERM=y
|
||||
|
@ -9,6 +9,7 @@ CONFIG_CGROUPS=y
|
||||
CONFIG_RELAY=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_EXPERT=y
|
||||
CONFIG_PERF_EVENTS=y
|
||||
# CONFIG_SLUB_DEBUG is not set
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_MODULES=y
|
||||
|
@ -24,7 +24,7 @@ extern struct arm_delay_ops {
|
||||
void (*delay)(unsigned long);
|
||||
void (*const_udelay)(unsigned long);
|
||||
void (*udelay)(unsigned long);
|
||||
bool const_clock;
|
||||
unsigned long ticks_per_jiffy;
|
||||
} arm_delay_ops;
|
||||
|
||||
#define __delay(n) arm_delay_ops.delay(n)
|
||||
|
@ -41,6 +41,13 @@ extern void kunmap_high(struct page *page);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Needed to be able to broadcast the TLB invalidation for kmap.
|
||||
*/
|
||||
#ifdef CONFIG_ARM_ERRATA_798181
|
||||
#undef ARCH_NEEDS_KMAP_HIGH_GET
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_NEEDS_KMAP_HIGH_GET
|
||||
extern void *kmap_high_get(struct page *page);
|
||||
#else
|
||||
|
@ -27,6 +27,8 @@ void __check_vmalloc_seq(struct mm_struct *mm);
|
||||
void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
|
||||
#define init_new_context(tsk,mm) ({ atomic64_set(&mm->context.id, 0); 0; })
|
||||
|
||||
DECLARE_PER_CPU(atomic64_t, active_asids);
|
||||
|
||||
#else /* !CONFIG_CPU_HAS_ASID */
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
|
@ -450,6 +450,21 @@ static inline void local_flush_bp_all(void)
|
||||
isb();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM_ERRATA_798181
|
||||
static inline void dummy_flush_tlb_a15_erratum(void)
|
||||
{
|
||||
/*
|
||||
* Dummy TLBIMVAIS. Using the unmapped address 0 and ASID 0.
|
||||
*/
|
||||
asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0));
|
||||
dsb();
|
||||
}
|
||||
#else
|
||||
static inline void dummy_flush_tlb_a15_erratum(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* flush_pmd_entry
|
||||
*
|
||||
|
@ -276,7 +276,13 @@ ENDPROC(ftrace_graph_caller_old)
|
||||
*/
|
||||
|
||||
.macro mcount_enter
|
||||
/*
|
||||
* This pad compensates for the push {lr} at the call site. Note that we are
|
||||
* unable to unwind through a function which does not otherwise save its lr.
|
||||
*/
|
||||
UNWIND(.pad #4)
|
||||
stmdb sp!, {r0-r3, lr}
|
||||
UNWIND(.save {r0-r3, lr})
|
||||
.endm
|
||||
|
||||
.macro mcount_get_lr reg
|
||||
@ -289,6 +295,7 @@ ENDPROC(ftrace_graph_caller_old)
|
||||
.endm
|
||||
|
||||
ENTRY(__gnu_mcount_nc)
|
||||
UNWIND(.fnstart)
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
mov ip, lr
|
||||
ldmia sp!, {lr}
|
||||
@ -296,17 +303,22 @@ ENTRY(__gnu_mcount_nc)
|
||||
#else
|
||||
__mcount
|
||||
#endif
|
||||
UNWIND(.fnend)
|
||||
ENDPROC(__gnu_mcount_nc)
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
ENTRY(ftrace_caller)
|
||||
UNWIND(.fnstart)
|
||||
__ftrace_caller
|
||||
UNWIND(.fnend)
|
||||
ENDPROC(ftrace_caller)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
ENTRY(ftrace_graph_caller)
|
||||
UNWIND(.fnstart)
|
||||
__ftrace_graph_caller
|
||||
UNWIND(.fnend)
|
||||
ENDPROC(ftrace_graph_caller)
|
||||
#endif
|
||||
|
||||
|
@ -267,7 +267,7 @@ __create_page_tables:
|
||||
addne r6, r6, #1 << SECTION_SHIFT
|
||||
strne r6, [r3]
|
||||
|
||||
#if defined(CONFIG_LPAE) && defined(CONFIG_CPU_ENDIAN_BE8)
|
||||
#if defined(CONFIG_ARM_LPAE) && defined(CONFIG_CPU_ENDIAN_BE8)
|
||||
sub r4, r4, #4 @ Fixup page table pointer
|
||||
@ for 64-bit descriptors
|
||||
#endif
|
||||
|
@ -966,7 +966,7 @@ static void reset_ctrl_regs(void *unused)
|
||||
}
|
||||
|
||||
if (err) {
|
||||
pr_warning("CPU %d debug is powered down!\n", cpu);
|
||||
pr_warn_once("CPU %d debug is powered down!\n", cpu);
|
||||
cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu));
|
||||
return;
|
||||
}
|
||||
@ -987,7 +987,7 @@ clear_vcr:
|
||||
isb();
|
||||
|
||||
if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) {
|
||||
pr_warning("CPU %d failed to disable vector catch\n", cpu);
|
||||
pr_warn_once("CPU %d failed to disable vector catch\n", cpu);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1007,7 +1007,7 @@ clear_vcr:
|
||||
}
|
||||
|
||||
if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) {
|
||||
pr_warning("CPU %d failed to clear debug register pairs\n", cpu);
|
||||
pr_warn_once("CPU %d failed to clear debug register pairs\n", cpu);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -353,6 +353,23 @@ void __init early_print(const char *str, ...)
|
||||
printk("%s", buf);
|
||||
}
|
||||
|
||||
static void __init cpuid_init_hwcaps(void)
|
||||
{
|
||||
unsigned int divide_instrs;
|
||||
|
||||
if (cpu_architecture() < CPU_ARCH_ARMv7)
|
||||
return;
|
||||
|
||||
divide_instrs = (read_cpuid_ext(CPUID_EXT_ISAR0) & 0x0f000000) >> 24;
|
||||
|
||||
switch (divide_instrs) {
|
||||
case 2:
|
||||
elf_hwcap |= HWCAP_IDIVA;
|
||||
case 1:
|
||||
elf_hwcap |= HWCAP_IDIVT;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init feat_v6_fixup(void)
|
||||
{
|
||||
int id = read_cpuid_id();
|
||||
@ -483,8 +500,11 @@ static void __init setup_processor(void)
|
||||
snprintf(elf_platform, ELF_PLATFORM_SIZE, "%s%c",
|
||||
list->elf_name, ENDIANNESS);
|
||||
elf_hwcap = list->elf_hwcap;
|
||||
|
||||
cpuid_init_hwcaps();
|
||||
|
||||
#ifndef CONFIG_ARM_THUMB
|
||||
elf_hwcap &= ~HWCAP_THUMB;
|
||||
elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT);
|
||||
#endif
|
||||
|
||||
feat_v6_fixup();
|
||||
@ -524,7 +544,7 @@ int __init arm_add_memory(phys_addr_t start, phys_addr_t size)
|
||||
size -= start & ~PAGE_MASK;
|
||||
bank->start = PAGE_ALIGN(start);
|
||||
|
||||
#ifndef CONFIG_LPAE
|
||||
#ifndef CONFIG_ARM_LPAE
|
||||
if (bank->start + size < bank->start) {
|
||||
printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in "
|
||||
"32-bit physical address space\n", (long long)start);
|
||||
|
@ -673,9 +673,6 @@ static int cpufreq_callback(struct notifier_block *nb,
|
||||
if (freq->flags & CPUFREQ_CONST_LOOPS)
|
||||
return NOTIFY_OK;
|
||||
|
||||
if (arm_delay_ops.const_clock)
|
||||
return NOTIFY_OK;
|
||||
|
||||
if (!per_cpu(l_p_j_ref, cpu)) {
|
||||
per_cpu(l_p_j_ref, cpu) =
|
||||
per_cpu(cpu_data, cpu).loops_per_jiffy;
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
@ -69,12 +70,72 @@ static inline void ipi_flush_bp_all(void *ignored)
|
||||
local_flush_bp_all();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM_ERRATA_798181
|
||||
static int erratum_a15_798181(void)
|
||||
{
|
||||
unsigned int midr = read_cpuid_id();
|
||||
|
||||
/* Cortex-A15 r0p0..r3p2 affected */
|
||||
if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
static int erratum_a15_798181(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ipi_flush_tlb_a15_erratum(void *arg)
|
||||
{
|
||||
dmb();
|
||||
}
|
||||
|
||||
static void broadcast_tlb_a15_erratum(void)
|
||||
{
|
||||
if (!erratum_a15_798181())
|
||||
return;
|
||||
|
||||
dummy_flush_tlb_a15_erratum();
|
||||
smp_call_function_many(cpu_online_mask, ipi_flush_tlb_a15_erratum,
|
||||
NULL, 1);
|
||||
}
|
||||
|
||||
static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm)
|
||||
{
|
||||
int cpu;
|
||||
cpumask_t mask = { CPU_BITS_NONE };
|
||||
|
||||
if (!erratum_a15_798181())
|
||||
return;
|
||||
|
||||
dummy_flush_tlb_a15_erratum();
|
||||
for_each_online_cpu(cpu) {
|
||||
if (cpu == smp_processor_id())
|
||||
continue;
|
||||
/*
|
||||
* We only need to send an IPI if the other CPUs are running
|
||||
* the same ASID as the one being invalidated. There is no
|
||||
* need for locking around the active_asids check since the
|
||||
* switch_mm() function has at least one dmb() (as required by
|
||||
* this workaround) in case a context switch happens on
|
||||
* another CPU after the condition below.
|
||||
*/
|
||||
if (atomic64_read(&mm->context.id) ==
|
||||
atomic64_read(&per_cpu(active_asids, cpu)))
|
||||
cpumask_set_cpu(cpu, &mask);
|
||||
}
|
||||
smp_call_function_many(&mask, ipi_flush_tlb_a15_erratum, NULL, 1);
|
||||
}
|
||||
|
||||
void flush_tlb_all(void)
|
||||
{
|
||||
if (tlb_ops_need_broadcast())
|
||||
on_each_cpu(ipi_flush_tlb_all, NULL, 1);
|
||||
else
|
||||
local_flush_tlb_all();
|
||||
broadcast_tlb_a15_erratum();
|
||||
}
|
||||
|
||||
void flush_tlb_mm(struct mm_struct *mm)
|
||||
@ -83,6 +144,7 @@ void flush_tlb_mm(struct mm_struct *mm)
|
||||
on_each_cpu_mask(mm_cpumask(mm), ipi_flush_tlb_mm, mm, 1);
|
||||
else
|
||||
local_flush_tlb_mm(mm);
|
||||
broadcast_tlb_mm_a15_erratum(mm);
|
||||
}
|
||||
|
||||
void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
|
||||
@ -95,6 +157,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
|
||||
&ta, 1);
|
||||
} else
|
||||
local_flush_tlb_page(vma, uaddr);
|
||||
broadcast_tlb_mm_a15_erratum(vma->vm_mm);
|
||||
}
|
||||
|
||||
void flush_tlb_kernel_page(unsigned long kaddr)
|
||||
@ -105,6 +168,7 @@ void flush_tlb_kernel_page(unsigned long kaddr)
|
||||
on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
|
||||
} else
|
||||
local_flush_tlb_kernel_page(kaddr);
|
||||
broadcast_tlb_a15_erratum();
|
||||
}
|
||||
|
||||
void flush_tlb_range(struct vm_area_struct *vma,
|
||||
@ -119,6 +183,7 @@ void flush_tlb_range(struct vm_area_struct *vma,
|
||||
&ta, 1);
|
||||
} else
|
||||
local_flush_tlb_range(vma, start, end);
|
||||
broadcast_tlb_mm_a15_erratum(vma->vm_mm);
|
||||
}
|
||||
|
||||
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
|
||||
@ -130,6 +195,7 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end)
|
||||
on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
|
||||
} else
|
||||
local_flush_tlb_kernel_range(start, end);
|
||||
broadcast_tlb_a15_erratum();
|
||||
}
|
||||
|
||||
void flush_bp_all(void)
|
||||
|
@ -883,8 +883,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
|
||||
lr, irq, vgic_cpu->vgic_lr[lr]);
|
||||
BUG_ON(!test_bit(lr, vgic_cpu->lr_used));
|
||||
vgic_cpu->vgic_lr[lr] |= GICH_LR_PENDING_BIT;
|
||||
|
||||
goto out;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Try to use another LR for this interrupt */
|
||||
@ -898,7 +897,6 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
|
||||
vgic_cpu->vgic_irq_lr_map[irq] = lr;
|
||||
set_bit(lr, vgic_cpu->lr_used);
|
||||
|
||||
out:
|
||||
if (!vgic_irq_is_edge(vcpu, irq))
|
||||
vgic_cpu->vgic_lr[lr] |= GICH_LR_EOI;
|
||||
|
||||
@ -1018,21 +1016,6 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
|
||||
|
||||
kvm_debug("MISR = %08x\n", vgic_cpu->vgic_misr);
|
||||
|
||||
/*
|
||||
* We do not need to take the distributor lock here, since the only
|
||||
* action we perform is clearing the irq_active_bit for an EOIed
|
||||
* level interrupt. There is a potential race with
|
||||
* the queuing of an interrupt in __kvm_vgic_flush_hwstate(), where we
|
||||
* check if the interrupt is already active. Two possibilities:
|
||||
*
|
||||
* - The queuing is occurring on the same vcpu: cannot happen,
|
||||
* as we're already in the context of this vcpu, and
|
||||
* executing the handler
|
||||
* - The interrupt has been migrated to another vcpu, and we
|
||||
* ignore this interrupt for this run. Big deal. It is still
|
||||
* pending though, and will get considered when this vcpu
|
||||
* exits.
|
||||
*/
|
||||
if (vgic_cpu->vgic_misr & GICH_MISR_EOI) {
|
||||
/*
|
||||
* Some level interrupts have been EOIed. Clear their
|
||||
@ -1054,6 +1037,13 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
|
||||
} else {
|
||||
vgic_cpu_irq_clear(vcpu, irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Despite being EOIed, the LR may not have
|
||||
* been marked as empty.
|
||||
*/
|
||||
set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr);
|
||||
vgic_cpu->vgic_lr[lr] &= ~GICH_LR_ACTIVE_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1064,9 +1054,8 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
|
||||
/*
|
||||
* Sync back the VGIC state after a guest run. We do not really touch
|
||||
* the distributor here (the irq_pending_on_cpu bit is safe to set),
|
||||
* so there is no need for taking its lock.
|
||||
* Sync back the VGIC state after a guest run. The distributor lock is
|
||||
* needed so we don't get preempted in the middle of the state processing.
|
||||
*/
|
||||
static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
@ -1112,10 +1101,14 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
|
||||
|
||||
void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
|
||||
|
||||
if (!irqchip_in_kernel(vcpu->kvm))
|
||||
return;
|
||||
|
||||
spin_lock(&dist->lock);
|
||||
__kvm_vgic_sync_hwstate(vcpu);
|
||||
spin_unlock(&dist->lock);
|
||||
}
|
||||
|
||||
int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
|
||||
|
@ -58,7 +58,7 @@ static void __timer_delay(unsigned long cycles)
|
||||
static void __timer_const_udelay(unsigned long xloops)
|
||||
{
|
||||
unsigned long long loops = xloops;
|
||||
loops *= loops_per_jiffy;
|
||||
loops *= arm_delay_ops.ticks_per_jiffy;
|
||||
__timer_delay(loops >> UDELAY_SHIFT);
|
||||
}
|
||||
|
||||
@ -73,11 +73,13 @@ void __init register_current_timer_delay(const struct delay_timer *timer)
|
||||
pr_info("Switching to timer-based delay loop\n");
|
||||
delay_timer = timer;
|
||||
lpj_fine = timer->freq / HZ;
|
||||
loops_per_jiffy = lpj_fine;
|
||||
|
||||
/* cpufreq may scale loops_per_jiffy, so keep a private copy */
|
||||
arm_delay_ops.ticks_per_jiffy = lpj_fine;
|
||||
arm_delay_ops.delay = __timer_delay;
|
||||
arm_delay_ops.const_udelay = __timer_const_udelay;
|
||||
arm_delay_ops.udelay = __timer_udelay;
|
||||
arm_delay_ops.const_clock = true;
|
||||
|
||||
delay_calibrated = true;
|
||||
} else {
|
||||
pr_info("Ignoring duplicate/late registration of read_current_timer delay\n");
|
||||
|
@ -22,19 +22,9 @@
|
||||
|
||||
static struct map_desc cns3xxx_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = CNS3XXX_TC11MP_TWD_BASE_VIRT,
|
||||
.pfn = __phys_to_pfn(CNS3XXX_TC11MP_TWD_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
.virtual = CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT,
|
||||
.pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_CPU_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
.virtual = CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT,
|
||||
.pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_DIST_BASE),
|
||||
.length = SZ_4K,
|
||||
.virtual = CNS3XXX_TC11MP_SCU_BASE_VIRT,
|
||||
.pfn = __phys_to_pfn(CNS3XXX_TC11MP_SCU_BASE),
|
||||
.length = SZ_8K,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
.virtual = CNS3XXX_TIMER1_2_3_BASE_VIRT,
|
||||
|
@ -94,10 +94,10 @@
|
||||
#define RTC_INTR_STS_OFFSET 0x34
|
||||
|
||||
#define CNS3XXX_MISC_BASE 0x76000000 /* Misc Control */
|
||||
#define CNS3XXX_MISC_BASE_VIRT 0xFFF07000 /* Misc Control */
|
||||
#define CNS3XXX_MISC_BASE_VIRT 0xFB000000 /* Misc Control */
|
||||
|
||||
#define CNS3XXX_PM_BASE 0x77000000 /* Power Management Control */
|
||||
#define CNS3XXX_PM_BASE_VIRT 0xFFF08000
|
||||
#define CNS3XXX_PM_BASE_VIRT 0xFB001000
|
||||
|
||||
#define PM_CLK_GATE_OFFSET 0x00
|
||||
#define PM_SOFT_RST_OFFSET 0x04
|
||||
@ -109,7 +109,7 @@
|
||||
#define PM_PLL_HM_PD_OFFSET 0x1C
|
||||
|
||||
#define CNS3XXX_UART0_BASE 0x78000000 /* UART 0 */
|
||||
#define CNS3XXX_UART0_BASE_VIRT 0xFFF09000
|
||||
#define CNS3XXX_UART0_BASE_VIRT 0xFB002000
|
||||
|
||||
#define CNS3XXX_UART1_BASE 0x78400000 /* UART 1 */
|
||||
#define CNS3XXX_UART1_BASE_VIRT 0xFFF0A000
|
||||
@ -130,7 +130,7 @@
|
||||
#define CNS3XXX_I2S_BASE_VIRT 0xFFF10000
|
||||
|
||||
#define CNS3XXX_TIMER1_2_3_BASE 0x7C800000 /* Timer */
|
||||
#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFFF10800
|
||||
#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFB003000
|
||||
|
||||
#define TIMER1_COUNTER_OFFSET 0x00
|
||||
#define TIMER1_AUTO_RELOAD_OFFSET 0x04
|
||||
@ -227,16 +227,16 @@
|
||||
* Testchip peripheral and fpga gic regions
|
||||
*/
|
||||
#define CNS3XXX_TC11MP_SCU_BASE 0x90000000 /* IRQ, Test chip */
|
||||
#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFF000000
|
||||
#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFB004000
|
||||
|
||||
#define CNS3XXX_TC11MP_GIC_CPU_BASE 0x90000100 /* Test chip interrupt controller CPU interface */
|
||||
#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT 0xFF000100
|
||||
#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x100)
|
||||
|
||||
#define CNS3XXX_TC11MP_TWD_BASE 0x90000600
|
||||
#define CNS3XXX_TC11MP_TWD_BASE_VIRT 0xFF000600
|
||||
#define CNS3XXX_TC11MP_TWD_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x600)
|
||||
|
||||
#define CNS3XXX_TC11MP_GIC_DIST_BASE 0x90001000 /* Test chip interrupt controller distributor */
|
||||
#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT 0xFF001000
|
||||
#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x1000)
|
||||
|
||||
#define CNS3XXX_TC11MP_L220_BASE 0x92002000 /* L220 registers */
|
||||
#define CNS3XXX_TC11MP_L220_BASE_VIRT 0xFF002000
|
||||
|
@ -47,9 +47,13 @@ static void __raw_writel(unsigned int value, unsigned int ptr)
|
||||
|
||||
static inline void putc(int c)
|
||||
{
|
||||
/* Transmit fifo not full? */
|
||||
while (__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF)
|
||||
;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10000; i++) {
|
||||
/* Transmit fifo not full? */
|
||||
if (!(__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF))
|
||||
break;
|
||||
}
|
||||
|
||||
__raw_writeb(c, PHYS_UART_DATA);
|
||||
}
|
||||
|
@ -65,6 +65,9 @@ config IRAM_ALLOC
|
||||
bool
|
||||
select GENERIC_ALLOCATOR
|
||||
|
||||
config HAVE_IMX_ANATOP
|
||||
bool
|
||||
|
||||
config HAVE_IMX_GPC
|
||||
bool
|
||||
|
||||
@ -73,6 +76,7 @@ config HAVE_IMX_MMDC
|
||||
|
||||
config HAVE_IMX_SRC
|
||||
def_bool y if SMP
|
||||
select ARCH_HAS_RESET_CONTROLLER
|
||||
|
||||
config IMX_HAVE_IOMUX_V1
|
||||
bool
|
||||
@ -83,24 +87,12 @@ config ARCH_MXC_IOMUX_V3
|
||||
config ARCH_MX1
|
||||
bool
|
||||
|
||||
config MACH_MX21
|
||||
bool
|
||||
|
||||
config ARCH_MX25
|
||||
bool
|
||||
|
||||
config MACH_MX27
|
||||
bool
|
||||
|
||||
config ARCH_MX5
|
||||
bool
|
||||
|
||||
config ARCH_MX51
|
||||
bool
|
||||
|
||||
config ARCH_MX53
|
||||
bool
|
||||
|
||||
config SOC_IMX1
|
||||
bool
|
||||
select ARCH_MX1
|
||||
@ -114,7 +106,6 @@ config SOC_IMX21
|
||||
select COMMON_CLK
|
||||
select CPU_ARM926T
|
||||
select IMX_HAVE_IOMUX_V1
|
||||
select MACH_MX21
|
||||
select MXC_AVIC
|
||||
|
||||
config SOC_IMX25
|
||||
@ -128,6 +119,8 @@ config SOC_IMX25
|
||||
|
||||
config SOC_IMX27
|
||||
bool
|
||||
select ARCH_HAS_CPUFREQ
|
||||
select ARCH_HAS_OPP
|
||||
select COMMON_CLK
|
||||
select CPU_ARM926T
|
||||
select IMX_HAVE_IOMUX_V1
|
||||
@ -155,7 +148,7 @@ config SOC_IMX35
|
||||
config SOC_IMX5
|
||||
bool
|
||||
select ARCH_HAS_CPUFREQ
|
||||
select ARCH_MX5
|
||||
select ARCH_HAS_OPP
|
||||
select ARCH_MXC_IOMUX_V3
|
||||
select COMMON_CLK
|
||||
select CPU_V7
|
||||
@ -163,8 +156,6 @@ config SOC_IMX5
|
||||
|
||||
config SOC_IMX51
|
||||
bool
|
||||
select ARCH_MX5
|
||||
select ARCH_MX51
|
||||
select PINCTRL
|
||||
select PINCTRL_IMX51
|
||||
select SOC_IMX5
|
||||
@ -789,8 +780,6 @@ comment "Device tree only"
|
||||
|
||||
config SOC_IMX53
|
||||
bool "i.MX53 support"
|
||||
select ARCH_MX5
|
||||
select ARCH_MX53
|
||||
select HAVE_CAN_FLEXCAN if CAN
|
||||
select IMX_HAVE_PLATFORM_IMX2_WDT
|
||||
select PINCTRL
|
||||
@ -801,7 +790,7 @@ config SOC_IMX53
|
||||
This enables support for Freescale i.MX53 processor.
|
||||
|
||||
config SOC_IMX6Q
|
||||
bool "i.MX6 Quad support"
|
||||
bool "i.MX6 Quad/DualLite support"
|
||||
select ARCH_HAS_CPUFREQ
|
||||
select ARCH_HAS_OPP
|
||||
select ARM_CPU_SUSPEND if PM
|
||||
@ -813,6 +802,7 @@ config SOC_IMX6Q
|
||||
select CPU_V7
|
||||
select HAVE_ARM_SCU
|
||||
select HAVE_CAN_FLEXCAN if CAN
|
||||
select HAVE_IMX_ANATOP
|
||||
select HAVE_IMX_GPC
|
||||
select HAVE_IMX_MMDC
|
||||
select HAVE_IMX_SRC
|
||||
|
@ -12,7 +12,7 @@ obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-
|
||||
obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o
|
||||
|
||||
imx5-pm-$(CONFIG_PM) += pm-imx5.o
|
||||
obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o $(imx5-pm-y) cpu_op-mx51.o
|
||||
obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o $(imx5-pm-y)
|
||||
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
|
||||
clk-pfd.o clk-busy.o clk.o
|
||||
@ -27,7 +27,6 @@ obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
|
||||
obj-$(CONFIG_MXC_ULPI) += ulpi.o
|
||||
obj-$(CONFIG_MXC_USE_EPIT) += epit.o
|
||||
obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
|
||||
obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
|
||||
|
||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||
obj-y += cpuidle.o
|
||||
@ -92,6 +91,7 @@ obj-$(CONFIG_MACH_EUKREA_CPUIMX35SD) += mach-cpuimx35.o
|
||||
obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
|
||||
obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
|
||||
|
||||
obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o
|
||||
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
|
||||
obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
|
||||
obj-$(CONFIG_HAVE_IMX_SRC) += src.o
|
||||
|
@ -1,35 +0,0 @@
|
||||
zreladdr-$(CONFIG_SOC_IMX1) += 0x08008000
|
||||
params_phys-$(CONFIG_SOC_IMX1) := 0x08000100
|
||||
initrd_phys-$(CONFIG_SOC_IMX1) := 0x08800000
|
||||
|
||||
zreladdr-$(CONFIG_SOC_IMX21) += 0xC0008000
|
||||
params_phys-$(CONFIG_SOC_IMX21) := 0xC0000100
|
||||
initrd_phys-$(CONFIG_SOC_IMX21) := 0xC0800000
|
||||
|
||||
zreladdr-$(CONFIG_SOC_IMX25) += 0x80008000
|
||||
params_phys-$(CONFIG_SOC_IMX25) := 0x80000100
|
||||
initrd_phys-$(CONFIG_SOC_IMX25) := 0x80800000
|
||||
|
||||
zreladdr-$(CONFIG_SOC_IMX27) += 0xA0008000
|
||||
params_phys-$(CONFIG_SOC_IMX27) := 0xA0000100
|
||||
initrd_phys-$(CONFIG_SOC_IMX27) := 0xA0800000
|
||||
|
||||
zreladdr-$(CONFIG_SOC_IMX31) += 0x80008000
|
||||
params_phys-$(CONFIG_SOC_IMX31) := 0x80000100
|
||||
initrd_phys-$(CONFIG_SOC_IMX31) := 0x80800000
|
||||
|
||||
zreladdr-$(CONFIG_SOC_IMX35) += 0x80008000
|
||||
params_phys-$(CONFIG_SOC_IMX35) := 0x80000100
|
||||
initrd_phys-$(CONFIG_SOC_IMX35) := 0x80800000
|
||||
|
||||
zreladdr-$(CONFIG_SOC_IMX51) += 0x90008000
|
||||
params_phys-$(CONFIG_SOC_IMX51) := 0x90000100
|
||||
initrd_phys-$(CONFIG_SOC_IMX51) := 0x90800000
|
||||
|
||||
zreladdr-$(CONFIG_SOC_IMX53) += 0x70008000
|
||||
params_phys-$(CONFIG_SOC_IMX53) := 0x70000100
|
||||
initrd_phys-$(CONFIG_SOC_IMX53) := 0x70800000
|
||||
|
||||
zreladdr-$(CONFIG_SOC_IMX6Q) += 0x10008000
|
||||
params_phys-$(CONFIG_SOC_IMX6Q) := 0x10000100
|
||||
initrd_phys-$(CONFIG_SOC_IMX6Q) := 0x10800000
|
103
arch/arm/mach-imx/anatop.c
Normal file
103
arch/arm/mach-imx/anatop.c
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
#include "common.h"
|
||||
|
||||
#define REG_SET 0x4
|
||||
#define REG_CLR 0x8
|
||||
|
||||
#define ANADIG_REG_2P5 0x130
|
||||
#define ANADIG_REG_CORE 0x140
|
||||
#define ANADIG_ANA_MISC0 0x150
|
||||
#define ANADIG_USB1_CHRG_DETECT 0x1b0
|
||||
#define ANADIG_USB2_CHRG_DETECT 0x210
|
||||
#define ANADIG_DIGPROG 0x260
|
||||
|
||||
#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000
|
||||
#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000
|
||||
#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000
|
||||
#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000
|
||||
#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000
|
||||
|
||||
static struct regmap *anatop;
|
||||
|
||||
static void imx_anatop_enable_weak2p5(bool enable)
|
||||
{
|
||||
u32 reg, val;
|
||||
|
||||
regmap_read(anatop, ANADIG_ANA_MISC0, &val);
|
||||
|
||||
/* can only be enabled when stop_mode_config is clear. */
|
||||
reg = ANADIG_REG_2P5;
|
||||
reg += (enable && (val & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) ?
|
||||
REG_SET : REG_CLR;
|
||||
regmap_write(anatop, reg, BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG);
|
||||
}
|
||||
|
||||
static void imx_anatop_enable_fet_odrive(bool enable)
|
||||
{
|
||||
regmap_write(anatop, ANADIG_REG_CORE + (enable ? REG_SET : REG_CLR),
|
||||
BM_ANADIG_REG_CORE_FET_ODRIVE);
|
||||
}
|
||||
|
||||
void imx_anatop_pre_suspend(void)
|
||||
{
|
||||
imx_anatop_enable_weak2p5(true);
|
||||
imx_anatop_enable_fet_odrive(true);
|
||||
}
|
||||
|
||||
void imx_anatop_post_resume(void)
|
||||
{
|
||||
imx_anatop_enable_fet_odrive(false);
|
||||
imx_anatop_enable_weak2p5(false);
|
||||
}
|
||||
|
||||
void imx_anatop_usb_chrg_detect_disable(void)
|
||||
{
|
||||
regmap_write(anatop, ANADIG_USB1_CHRG_DETECT,
|
||||
BM_ANADIG_USB_CHRG_DETECT_EN_B
|
||||
| BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
|
||||
regmap_write(anatop, ANADIG_USB2_CHRG_DETECT,
|
||||
BM_ANADIG_USB_CHRG_DETECT_EN_B |
|
||||
BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
|
||||
}
|
||||
|
||||
u32 imx_anatop_get_digprog(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
void __iomem *anatop_base;
|
||||
static u32 digprog;
|
||||
|
||||
if (digprog)
|
||||
return digprog;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
|
||||
anatop_base = of_iomap(np, 0);
|
||||
WARN_ON(!anatop_base);
|
||||
digprog = readl_relaxed(anatop_base + ANADIG_DIGPROG);
|
||||
|
||||
return digprog;
|
||||
}
|
||||
|
||||
void __init imx_anatop_init(void)
|
||||
{
|
||||
anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
|
||||
if (IS_ERR(anatop)) {
|
||||
pr_err("%s: failed to find imx6q-anatop regmap!\n", __func__);
|
||||
return;
|
||||
}
|
||||
}
|
@ -54,8 +54,6 @@
|
||||
void __iomem *avic_base;
|
||||
static struct irq_domain *domain;
|
||||
|
||||
static u32 avic_saved_mask_reg[2];
|
||||
|
||||
#ifdef CONFIG_MXC_IRQ_PRIOR
|
||||
static int avic_irq_set_priority(unsigned char irq, unsigned char prio)
|
||||
{
|
||||
@ -113,6 +111,8 @@ static struct mxc_extra_irq avic_extra_irq = {
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static u32 avic_saved_mask_reg[2];
|
||||
|
||||
static void avic_irq_suspend(struct irq_data *d)
|
||||
{
|
||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
|
@ -278,8 +278,6 @@ int __init mx27_clocks_init(unsigned long fref)
|
||||
clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL);
|
||||
clk_register_clkdev(clk[cpu_div], "cpu", NULL);
|
||||
clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL);
|
||||
clk_register_clkdev(clk[ssi1_baud_gate], "bitrate" , "imx-ssi.0");
|
||||
clk_register_clkdev(clk[ssi2_baud_gate], "bitrate" , "imx-ssi.1");
|
||||
|
||||
mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1);
|
||||
|
||||
|
@ -257,6 +257,7 @@ int __init mx35_clocks_init(void)
|
||||
clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
|
||||
clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
|
||||
clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
|
||||
clk_register_clkdev(clk[admux_gate], "audmux", NULL);
|
||||
|
||||
clk_prepare_enable(clk[spba_gate]);
|
||||
clk_prepare_enable(clk[gpio1_gate]);
|
||||
@ -265,6 +266,7 @@ int __init mx35_clocks_init(void)
|
||||
clk_prepare_enable(clk[iim_gate]);
|
||||
clk_prepare_enable(clk[emi_gate]);
|
||||
clk_prepare_enable(clk[max_gate]);
|
||||
clk_prepare_enable(clk[iomuxc_gate]);
|
||||
|
||||
/*
|
||||
* SCC is needed to boot via mmc after a watchdog reset. The clock code
|
||||
|
@ -45,16 +45,40 @@ static const char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "
|
||||
static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", };
|
||||
static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", };
|
||||
static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", };
|
||||
static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", };
|
||||
static const char *mx51_tve_sel[] = { "tve_pred", "tve_ext_sel", };
|
||||
static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
|
||||
static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" };
|
||||
static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" };
|
||||
static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
|
||||
static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", };
|
||||
static const char *mx53_cko1_sel[] = {
|
||||
"cpu_podf", "pll1_sw", "pll2_sw", "pll3_sw",
|
||||
"emi_slow_podf", "pll4_sw", "nfc_podf", "dummy",
|
||||
"di_pred", "dummy", "dummy", "ahb",
|
||||
"ipg", "per_root", "ckil", "dummy",};
|
||||
static const char *mx53_cko2_sel[] = {
|
||||
"dummy"/* dptc_core */, "dummy"/* dptc_perich */,
|
||||
"dummy", "esdhc_a_podf",
|
||||
"usboh3_podf", "dummy"/* wrck_clk_root */,
|
||||
"ecspi_podf", "dummy"/* pll1_ref_clk */,
|
||||
"esdhc_b_podf", "dummy"/* ddr_clk_root */,
|
||||
"dummy"/* arm_axi_clk_root */, "dummy"/* usb_phy_out */,
|
||||
"vpu_sel", "ipu_sel",
|
||||
"osc", "ckih1",
|
||||
"dummy", "esdhc_c_sel",
|
||||
"ssi1_root_podf", "ssi2_root_podf",
|
||||
"dummy", "dummy",
|
||||
"dummy"/* lpsr_clk_root */, "dummy"/* pgc_clk_root */,
|
||||
"dummy"/* tve_out */, "usb_phy_sel",
|
||||
"tve_sel", "lp_apm",
|
||||
"uart_root", "dummy"/* spdif0_clk_root */,
|
||||
"dummy", "dummy", };
|
||||
|
||||
enum imx5_clks {
|
||||
dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred,
|
||||
uart_root, esdhc_a_pred, esdhc_b_pred, esdhc_c_s, esdhc_d_s,
|
||||
emi_sel, emi_slow_podf, nfc_podf, ecspi_pred, ecspi_podf, usboh3_pred,
|
||||
usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di,
|
||||
usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di_unused,
|
||||
tve_s, uart1_ipg_gate, uart1_per_gate, uart2_ipg_gate,
|
||||
uart2_per_gate, uart3_ipg_gate, uart3_per_gate, i2c1_gate, i2c2_gate,
|
||||
gpt_ipg_gate, pwm1_ipg_gate, pwm1_hf_gate, pwm2_ipg_gate, pwm2_hf_gate,
|
||||
@ -83,7 +107,10 @@ enum imx5_clks {
|
||||
ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate,
|
||||
epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate,
|
||||
can_sel, can1_serial_gate, can1_ipg_gate,
|
||||
owire_gate,
|
||||
owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate,
|
||||
cko1_sel, cko1_podf, cko1,
|
||||
cko2_sel, cko2_podf, cko2,
|
||||
srtc_gate, pata_gate,
|
||||
clk_max
|
||||
};
|
||||
|
||||
@ -160,8 +187,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
|
||||
usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
|
||||
clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3);
|
||||
clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3);
|
||||
clk[tve_di] = imx_clk_fixed("tve_di", 65000000); /* FIXME */
|
||||
clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, tve_sel, ARRAY_SIZE(tve_sel));
|
||||
clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30);
|
||||
clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6);
|
||||
clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8);
|
||||
@ -200,6 +225,11 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
|
||||
clk[nfc_gate] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20);
|
||||
clk[ipu_di0_gate] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10);
|
||||
clk[ipu_di1_gate] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12);
|
||||
clk[gpu3d_s] = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel));
|
||||
clk[gpu2d_s] = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel));
|
||||
clk[gpu3d_gate] = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2);
|
||||
clk[garb_gate] = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4);
|
||||
clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14);
|
||||
clk[vpu_s] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel));
|
||||
clk[vpu_gate] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6);
|
||||
clk[vpu_reference_gate] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8);
|
||||
@ -235,6 +265,8 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
|
||||
clk[epit2_ipg_gate] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6);
|
||||
clk[epit2_hf_gate] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8);
|
||||
clk[owire_gate] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22);
|
||||
clk[srtc_gate] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28);
|
||||
clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clk); i++)
|
||||
if (IS_ERR(clk[i]))
|
||||
@ -286,7 +318,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
|
||||
clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0");
|
||||
clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1");
|
||||
clk_register_clkdev(clk[dummy], NULL, "imx-keypad");
|
||||
clk_register_clkdev(clk[tve_gate], NULL, "imx-tve.0");
|
||||
clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0");
|
||||
clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL);
|
||||
clk_register_clkdev(clk[epit1_ipg_gate], "ipg", "imx-epit.0");
|
||||
@ -331,8 +362,10 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
|
||||
mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
|
||||
clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
|
||||
mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
|
||||
clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
|
||||
mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel));
|
||||
clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
|
||||
mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT);
|
||||
clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1,
|
||||
mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel));
|
||||
clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30);
|
||||
clk[tve_pred] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3);
|
||||
clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
|
||||
@ -423,23 +456,23 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
|
||||
clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE);
|
||||
clk[pll4_sw] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE);
|
||||
|
||||
clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
|
||||
mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel));
|
||||
clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
|
||||
clk[ldb_di1_div] = imx_clk_divider("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1);
|
||||
clk[ldb_di1_div] = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0);
|
||||
clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
|
||||
mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT);
|
||||
clk[di_pll4_podf] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3);
|
||||
clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
|
||||
mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel));
|
||||
clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
|
||||
clk[ldb_di0_div] = imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1);
|
||||
clk[ldb_di0_div] = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0);
|
||||
clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
|
||||
mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT);
|
||||
clk[ldb_di0_gate] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28);
|
||||
clk[ldb_di1_gate] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30);
|
||||
clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
|
||||
mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
|
||||
clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
|
||||
mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
|
||||
clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
|
||||
mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel));
|
||||
clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
|
||||
mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT);
|
||||
clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
|
||||
clk[tve_pred] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3);
|
||||
clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
|
||||
@ -456,6 +489,16 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
|
||||
clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6);
|
||||
clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
|
||||
|
||||
clk[cko1_sel] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
|
||||
mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
|
||||
clk[cko1_podf] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3);
|
||||
clk[cko1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7);
|
||||
|
||||
clk[cko2_sel] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5,
|
||||
mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel));
|
||||
clk[cko2_podf] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3);
|
||||
clk[cko2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clk); i++)
|
||||
if (IS_ERR(clk[i]))
|
||||
pr_err("i.MX53 clk %d: register failed with %ld\n",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 Freescale Semiconductor, Inc.
|
||||
* Copyright 2011-2013 Freescale Semiconductor, Inc.
|
||||
* Copyright 2011 Linaro Ltd.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
@ -14,6 +14,7 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
@ -22,6 +23,12 @@
|
||||
|
||||
#include "clk.h"
|
||||
#include "common.h"
|
||||
#include "hardware.h"
|
||||
|
||||
#define CCR 0x0
|
||||
#define BM_CCR_WB_COUNT (0x7 << 16)
|
||||
#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21)
|
||||
#define BM_CCR_RBC_EN (0x1 << 27)
|
||||
|
||||
#define CCGR0 0x68
|
||||
#define CCGR1 0x6c
|
||||
@ -67,6 +74,67 @@ void imx6q_set_chicken_bit(void)
|
||||
writel_relaxed(val, ccm_base + CGPR);
|
||||
}
|
||||
|
||||
static void imx6q_enable_rbc(bool enable)
|
||||
{
|
||||
u32 val;
|
||||
static bool last_rbc_mode;
|
||||
|
||||
if (last_rbc_mode == enable)
|
||||
return;
|
||||
/*
|
||||
* need to mask all interrupts in GPC before
|
||||
* operating RBC configurations
|
||||
*/
|
||||
imx_gpc_mask_all();
|
||||
|
||||
/* configure RBC enable bit */
|
||||
val = readl_relaxed(ccm_base + CCR);
|
||||
val &= ~BM_CCR_RBC_EN;
|
||||
val |= enable ? BM_CCR_RBC_EN : 0;
|
||||
writel_relaxed(val, ccm_base + CCR);
|
||||
|
||||
/* configure RBC count */
|
||||
val = readl_relaxed(ccm_base + CCR);
|
||||
val &= ~BM_CCR_RBC_BYPASS_COUNT;
|
||||
val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
|
||||
writel(val, ccm_base + CCR);
|
||||
|
||||
/*
|
||||
* need to delay at least 2 cycles of CKIL(32K)
|
||||
* due to hardware design requirement, which is
|
||||
* ~61us, here we use 65us for safe
|
||||
*/
|
||||
udelay(65);
|
||||
|
||||
/* restore GPC interrupt mask settings */
|
||||
imx_gpc_restore_all();
|
||||
|
||||
last_rbc_mode = enable;
|
||||
}
|
||||
|
||||
static void imx6q_enable_wb(bool enable)
|
||||
{
|
||||
u32 val;
|
||||
static bool last_wb_mode;
|
||||
|
||||
if (last_wb_mode == enable)
|
||||
return;
|
||||
|
||||
/* configure well bias enable bit */
|
||||
val = readl_relaxed(ccm_base + CLPCR);
|
||||
val &= ~BM_CLPCR_WB_PER_AT_LPM;
|
||||
val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
|
||||
writel_relaxed(val, ccm_base + CLPCR);
|
||||
|
||||
/* configure well bias count */
|
||||
val = readl_relaxed(ccm_base + CCR);
|
||||
val &= ~BM_CCR_WB_COUNT;
|
||||
val |= enable ? BM_CCR_WB_COUNT : 0;
|
||||
writel_relaxed(val, ccm_base + CCR);
|
||||
|
||||
last_wb_mode = enable;
|
||||
}
|
||||
|
||||
int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
|
||||
{
|
||||
u32 val = readl_relaxed(ccm_base + CLPCR);
|
||||
@ -74,6 +142,8 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
|
||||
val &= ~BM_CLPCR_LPM;
|
||||
switch (mode) {
|
||||
case WAIT_CLOCKED:
|
||||
imx6q_enable_wb(false);
|
||||
imx6q_enable_rbc(false);
|
||||
break;
|
||||
case WAIT_UNCLOCKED:
|
||||
val |= 0x1 << BP_CLPCR_LPM;
|
||||
@ -92,6 +162,8 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
|
||||
val |= 0x3 << BP_CLPCR_STBY_COUNT;
|
||||
val |= BM_CLPCR_VSTBY;
|
||||
val |= BM_CLPCR_SBYOS;
|
||||
imx6q_enable_wb(true);
|
||||
imx6q_enable_rbc(true);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@ -109,29 +181,29 @@ static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", };
|
||||
static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
|
||||
static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
|
||||
static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", };
|
||||
static const char *audio_sels[] = { "pll4_audio", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
|
||||
static const char *audio_sels[] = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
|
||||
static const char *gpu_axi_sels[] = { "axi", "ahb", };
|
||||
static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
|
||||
static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
|
||||
static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", };
|
||||
static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
|
||||
static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_pfd1_540m", };
|
||||
static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
|
||||
static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
|
||||
static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
|
||||
static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
|
||||
static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
|
||||
static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
|
||||
static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
|
||||
static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", };
|
||||
static const char *pcie_axi_sels[] = { "axi", "ahb", };
|
||||
static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio", };
|
||||
static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_post_div", };
|
||||
static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
|
||||
static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", };
|
||||
static const char *emi_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
|
||||
static const char *vdo_axi_sels[] = { "axi", "ahb", };
|
||||
static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", };
|
||||
static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video",
|
||||
static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
|
||||
"dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
|
||||
"ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", };
|
||||
"ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_post_div", };
|
||||
|
||||
enum mx6q_clks {
|
||||
dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m,
|
||||
@ -165,7 +237,7 @@ enum mx6q_clks {
|
||||
pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg,
|
||||
ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
|
||||
sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate,
|
||||
usbphy2_gate, clk_max
|
||||
usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, clk_max
|
||||
};
|
||||
|
||||
static struct clk *clk[clk_max];
|
||||
@ -182,6 +254,21 @@ static struct clk_div_table clk_enet_ref_table[] = {
|
||||
{ .val = 3, .div = 4, },
|
||||
};
|
||||
|
||||
static struct clk_div_table post_div_table[] = {
|
||||
{ .val = 2, .div = 1, },
|
||||
{ .val = 1, .div = 2, },
|
||||
{ .val = 0, .div = 4, },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_div_table video_div_table[] = {
|
||||
{ .val = 0, .div = 1, },
|
||||
{ .val = 1, .div = 2, },
|
||||
{ .val = 2, .div = 1, },
|
||||
{ .val = 3, .div = 4, },
|
||||
{ }
|
||||
};
|
||||
|
||||
int __init mx6q_clocks_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
@ -208,6 +295,14 @@ int __init mx6q_clocks_init(void)
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
|
||||
/* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
|
||||
if (cpu_is_imx6q() && imx6q_revision() == IMX_CHIP_REVISION_1_0) {
|
||||
post_div_table[1].div = 1;
|
||||
post_div_table[2].div = 1;
|
||||
video_div_table[1].div = 1;
|
||||
video_div_table[2].div = 1;
|
||||
};
|
||||
|
||||
/* type name parent_name base div_mask */
|
||||
clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
|
||||
clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
|
||||
@ -260,6 +355,10 @@ int __init mx6q_clocks_init(void)
|
||||
clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
|
||||
clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2);
|
||||
|
||||
clk[pll4_post_div] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
|
||||
clk[pll5_post_div] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
|
||||
clk[pll5_video_div] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm");
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
@ -283,8 +382,8 @@ int __init mx6q_clocks_init(void)
|
||||
clk[gpu3d_shader_sel] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
|
||||
clk[ipu1_sel] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
|
||||
clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
|
||||
clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
|
||||
clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
|
||||
clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
|
||||
clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
|
||||
clk[ipu1_di0_pre_sel] = imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
|
||||
clk[ipu1_di1_pre_sel] = imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
|
||||
clk[ipu2_di0_pre_sel] = imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
|
||||
@ -332,9 +431,9 @@ int __init mx6q_clocks_init(void)
|
||||
clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3);
|
||||
clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3);
|
||||
clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
|
||||
clk[ldb_di0_podf] = imx_clk_divider("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1);
|
||||
clk[ldb_di0_podf] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0);
|
||||
clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
|
||||
clk[ldb_di1_podf] = imx_clk_divider("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1);
|
||||
clk[ldb_di1_podf] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0);
|
||||
clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3);
|
||||
clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3);
|
||||
clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3);
|
||||
@ -443,12 +542,16 @@ int __init mx6q_clocks_init(void)
|
||||
|
||||
clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0");
|
||||
clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
|
||||
clk_register_clkdev(clk[twd], NULL, "smp_twd");
|
||||
clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL);
|
||||
clk_register_clkdev(clk[ahb], "ahb", NULL);
|
||||
clk_register_clkdev(clk[cko1], "cko1", NULL);
|
||||
clk_register_clkdev(clk[arm], NULL, "cpu0");
|
||||
|
||||
if (imx6q_revision() != IMX_CHIP_REVISION_1_0) {
|
||||
clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
|
||||
clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
|
||||
}
|
||||
|
||||
/*
|
||||
* The gpmi needs 100MHz frequency in the EDO/Sync mode,
|
||||
* We can not get the 100MHz from the pll2_pfd0_352m.
|
||||
|
@ -59,6 +59,14 @@ static inline struct clk *imx_clk_divider(const char *name, const char *parent,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_divider_flags(const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift, u8 width,
|
||||
unsigned long flags)
|
||||
{
|
||||
return clk_register_divider(NULL, name, parent, flags,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_gate(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
@ -73,6 +81,15 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
|
||||
width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_mux_flags(const char *name,
|
||||
void __iomem *reg, u8 shift, u8 width, const char **parents,
|
||||
int num_parents, unsigned long flags)
|
||||
{
|
||||
return clk_register_mux(NULL, name, parents, num_parents,
|
||||
flags, reg, shift, width, 0,
|
||||
&imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_fixed_factor(const char *name,
|
||||
const char *parent, unsigned int mult, unsigned int div)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -74,6 +74,7 @@ extern void mxc_set_cpu_type(unsigned int type);
|
||||
extern void mxc_restart(char, const char *);
|
||||
extern void mxc_arch_reset_init(void __iomem *);
|
||||
extern int mx53_revision(void);
|
||||
extern int imx6q_revision(void);
|
||||
extern int mx53_display_revision(void);
|
||||
extern void imx_set_aips(void __iomem *);
|
||||
extern int mxc_device_init(void);
|
||||
@ -110,8 +111,9 @@ void tzic_handle_irq(struct pt_regs *);
|
||||
|
||||
extern void imx_enable_cpu(int cpu, bool enable);
|
||||
extern void imx_set_cpu_jump(int cpu, void *jump_addr);
|
||||
extern u32 imx_get_cpu_arg(int cpu);
|
||||
extern void imx_set_cpu_arg(int cpu, u32 arg);
|
||||
extern void v7_cpu_resume(void);
|
||||
extern u32 *pl310_get_save_ptr(void);
|
||||
#ifdef CONFIG_SMP
|
||||
extern void v7_secondary_startup(void);
|
||||
extern void imx_scu_map_io(void);
|
||||
@ -122,13 +124,18 @@ static inline void imx_scu_map_io(void) {}
|
||||
static inline void imx_smp_prepare(void) {}
|
||||
static inline void imx_scu_standby_enable(void) {}
|
||||
#endif
|
||||
extern void imx_enable_cpu(int cpu, bool enable);
|
||||
extern void imx_set_cpu_jump(int cpu, void *jump_addr);
|
||||
extern void imx_src_init(void);
|
||||
extern void imx_src_prepare_restart(void);
|
||||
extern void imx_gpc_init(void);
|
||||
extern void imx_gpc_pre_suspend(void);
|
||||
extern void imx_gpc_post_resume(void);
|
||||
extern void imx_gpc_mask_all(void);
|
||||
extern void imx_gpc_restore_all(void);
|
||||
extern void imx_anatop_init(void);
|
||||
extern void imx_anatop_pre_suspend(void);
|
||||
extern void imx_anatop_post_resume(void);
|
||||
extern void imx_anatop_usb_chrg_detect_disable(void);
|
||||
extern u32 imx_anatop_get_digprog(void);
|
||||
extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
|
||||
extern void imx6q_set_chicken_bit(void);
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include "hardware.h"
|
||||
|
||||
static struct cpu_op mx51_cpu_op[] = {
|
||||
{
|
||||
.cpu_rate = 160000000,},
|
||||
{
|
||||
.cpu_rate = 800000000,},
|
||||
};
|
||||
|
||||
struct cpu_op *mx51_get_cpu_op(int *op)
|
||||
{
|
||||
*op = ARRAY_SIZE(mx51_cpu_op);
|
||||
return mx51_cpu_op;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
extern struct cpu_op *mx51_get_cpu_op(int *op);
|
@ -1,206 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* A driver for the Freescale Semiconductor i.MXC CPUfreq module.
|
||||
* The CPUFREQ driver is for controlling CPU frequency. It allows you to change
|
||||
* the CPU clock speed on the fly.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "hardware.h"
|
||||
|
||||
#define CLK32_FREQ 32768
|
||||
#define NANOSECOND (1000 * 1000 * 1000)
|
||||
|
||||
struct cpu_op *(*get_cpu_op)(int *op);
|
||||
|
||||
static int cpu_freq_khz_min;
|
||||
static int cpu_freq_khz_max;
|
||||
|
||||
static struct clk *cpu_clk;
|
||||
static struct cpufreq_frequency_table *imx_freq_table;
|
||||
|
||||
static int cpu_op_nr;
|
||||
static struct cpu_op *cpu_op_tbl;
|
||||
|
||||
static int set_cpu_freq(int freq)
|
||||
{
|
||||
int ret = 0;
|
||||
int org_cpu_rate;
|
||||
|
||||
org_cpu_rate = clk_get_rate(cpu_clk);
|
||||
if (org_cpu_rate == freq)
|
||||
return ret;
|
||||
|
||||
ret = clk_set_rate(cpu_clk, freq);
|
||||
if (ret != 0) {
|
||||
printk(KERN_DEBUG "cannot set CPU clock rate\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mxc_verify_speed(struct cpufreq_policy *policy)
|
||||
{
|
||||
if (policy->cpu != 0)
|
||||
return -EINVAL;
|
||||
|
||||
return cpufreq_frequency_table_verify(policy, imx_freq_table);
|
||||
}
|
||||
|
||||
static unsigned int mxc_get_speed(unsigned int cpu)
|
||||
{
|
||||
if (cpu)
|
||||
return 0;
|
||||
|
||||
return clk_get_rate(cpu_clk) / 1000;
|
||||
}
|
||||
|
||||
static int mxc_set_target(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq, unsigned int relation)
|
||||
{
|
||||
struct cpufreq_freqs freqs;
|
||||
int freq_Hz;
|
||||
int ret = 0;
|
||||
unsigned int index;
|
||||
|
||||
cpufreq_frequency_table_target(policy, imx_freq_table,
|
||||
target_freq, relation, &index);
|
||||
freq_Hz = imx_freq_table[index].frequency * 1000;
|
||||
|
||||
freqs.old = clk_get_rate(cpu_clk) / 1000;
|
||||
freqs.new = freq_Hz / 1000;
|
||||
freqs.cpu = 0;
|
||||
freqs.flags = 0;
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||
|
||||
ret = set_cpu_freq(freq_Hz);
|
||||
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mxc_cpufreq_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
printk(KERN_INFO "i.MXC CPU frequency driver\n");
|
||||
|
||||
if (policy->cpu != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!get_cpu_op)
|
||||
return -EINVAL;
|
||||
|
||||
cpu_clk = clk_get(NULL, "cpu_clk");
|
||||
if (IS_ERR(cpu_clk)) {
|
||||
printk(KERN_ERR "%s: failed to get cpu clock\n", __func__);
|
||||
return PTR_ERR(cpu_clk);
|
||||
}
|
||||
|
||||
cpu_op_tbl = get_cpu_op(&cpu_op_nr);
|
||||
|
||||
cpu_freq_khz_min = cpu_op_tbl[0].cpu_rate / 1000;
|
||||
cpu_freq_khz_max = cpu_op_tbl[0].cpu_rate / 1000;
|
||||
|
||||
imx_freq_table = kmalloc(
|
||||
sizeof(struct cpufreq_frequency_table) * (cpu_op_nr + 1),
|
||||
GFP_KERNEL);
|
||||
if (!imx_freq_table) {
|
||||
ret = -ENOMEM;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
for (i = 0; i < cpu_op_nr; i++) {
|
||||
imx_freq_table[i].index = i;
|
||||
imx_freq_table[i].frequency = cpu_op_tbl[i].cpu_rate / 1000;
|
||||
|
||||
if ((cpu_op_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min)
|
||||
cpu_freq_khz_min = cpu_op_tbl[i].cpu_rate / 1000;
|
||||
|
||||
if ((cpu_op_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max)
|
||||
cpu_freq_khz_max = cpu_op_tbl[i].cpu_rate / 1000;
|
||||
}
|
||||
|
||||
imx_freq_table[i].index = i;
|
||||
imx_freq_table[i].frequency = CPUFREQ_TABLE_END;
|
||||
|
||||
policy->cur = clk_get_rate(cpu_clk) / 1000;
|
||||
policy->min = policy->cpuinfo.min_freq = cpu_freq_khz_min;
|
||||
policy->max = policy->cpuinfo.max_freq = cpu_freq_khz_max;
|
||||
|
||||
/* Manual states, that PLL stabilizes in two CLK32 periods */
|
||||
policy->cpuinfo.transition_latency = 2 * NANOSECOND / CLK32_FREQ;
|
||||
|
||||
ret = cpufreq_frequency_table_cpuinfo(policy, imx_freq_table);
|
||||
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: failed to register i.MXC CPUfreq with error code %d\n",
|
||||
__func__, ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
cpufreq_frequency_table_get_attr(imx_freq_table, policy->cpu);
|
||||
return 0;
|
||||
err:
|
||||
kfree(imx_freq_table);
|
||||
err1:
|
||||
clk_put(cpu_clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mxc_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
cpufreq_frequency_table_put_attr(policy->cpu);
|
||||
|
||||
set_cpu_freq(cpu_freq_khz_max * 1000);
|
||||
clk_put(cpu_clk);
|
||||
kfree(imx_freq_table);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver mxc_driver = {
|
||||
.flags = CPUFREQ_STICKY,
|
||||
.verify = mxc_verify_speed,
|
||||
.target = mxc_set_target,
|
||||
.get = mxc_get_speed,
|
||||
.init = mxc_cpufreq_init,
|
||||
.exit = mxc_cpufreq_exit,
|
||||
.name = "imx",
|
||||
};
|
||||
|
||||
static int mxc_cpufreq_driver_init(void)
|
||||
{
|
||||
return cpufreq_register_driver(&mxc_driver);
|
||||
}
|
||||
|
||||
static void mxc_cpufreq_driver_exit(void)
|
||||
{
|
||||
cpufreq_unregister_driver(&mxc_driver);
|
||||
}
|
||||
|
||||
module_init(mxc_cpufreq_driver_init);
|
||||
module_exit(mxc_cpufreq_driver_exit);
|
||||
|
||||
MODULE_AUTHOR("Freescale Semiconductor Inc. Yong Shen <yong.shen@linaro.org>");
|
||||
MODULE_DESCRIPTION("CPUfreq driver for i.MX");
|
||||
MODULE_LICENSE("GPL");
|
@ -86,7 +86,3 @@ config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
|
||||
|
||||
config IMX_HAVE_PLATFORM_SPI_IMX
|
||||
bool
|
||||
|
||||
config IMX_HAVE_PLATFORM_AHCI
|
||||
bool
|
||||
default y if ARCH_MX53
|
||||
|
@ -29,5 +29,4 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RTC) += platform-mxc_rtc.o
|
||||
obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o
|
||||
obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o
|
||||
obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o
|
||||
obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) += platform-ahci-imx.o
|
||||
obj-$(CONFIG_IMX_HAVE_PLATFORM_MX2_EMMA) += platform-mx2-emma.o
|
||||
|
@ -344,13 +344,3 @@ struct platform_device *imx_add_imx_dma(char *name, resource_size_t iobase,
|
||||
int irq, int irq_err);
|
||||
struct platform_device *imx_add_imx_sdma(char *name,
|
||||
resource_size_t iobase, int irq, struct sdma_platform_data *pdata);
|
||||
|
||||
#include <linux/ahci_platform.h>
|
||||
struct imx_ahci_imx_data {
|
||||
const char *devid;
|
||||
resource_size_t iobase;
|
||||
resource_size_t irq;
|
||||
};
|
||||
struct platform_device *__init imx_add_ahci_imx(
|
||||
const struct imx_ahci_imx_data *data,
|
||||
const struct ahci_platform_data *pdata);
|
||||
|
@ -1,157 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <asm/sizes.h>
|
||||
|
||||
#include "../hardware.h"
|
||||
#include "devices-common.h"
|
||||
|
||||
#define imx_ahci_imx_data_entry_single(soc, _devid) \
|
||||
{ \
|
||||
.devid = _devid, \
|
||||
.iobase = soc ## _SATA_BASE_ADDR, \
|
||||
.irq = soc ## _INT_SATA, \
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SOC_IMX53
|
||||
const struct imx_ahci_imx_data imx53_ahci_imx_data __initconst =
|
||||
imx_ahci_imx_data_entry_single(MX53, "imx53-ahci");
|
||||
#endif
|
||||
|
||||
enum {
|
||||
HOST_CAP = 0x00,
|
||||
HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
|
||||
HOST_PORTS_IMPL = 0x0c,
|
||||
HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
|
||||
};
|
||||
|
||||
static struct clk *sata_clk, *sata_ref_clk;
|
||||
|
||||
/* AHCI module Initialization, if return 0, initialization is successful. */
|
||||
static int imx_sata_init(struct device *dev, void __iomem *addr)
|
||||
{
|
||||
u32 tmpdata;
|
||||
int ret = 0;
|
||||
struct clk *clk;
|
||||
|
||||
sata_clk = clk_get(dev, "ahci");
|
||||
if (IS_ERR(sata_clk)) {
|
||||
dev_err(dev, "no sata clock.\n");
|
||||
return PTR_ERR(sata_clk);
|
||||
}
|
||||
ret = clk_prepare_enable(sata_clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "can't prepare/enable sata clock.\n");
|
||||
goto put_sata_clk;
|
||||
}
|
||||
|
||||
/* Get the AHCI SATA PHY CLK */
|
||||
sata_ref_clk = clk_get(dev, "ahci_phy");
|
||||
if (IS_ERR(sata_ref_clk)) {
|
||||
dev_err(dev, "no sata ref clock.\n");
|
||||
ret = PTR_ERR(sata_ref_clk);
|
||||
goto release_sata_clk;
|
||||
}
|
||||
ret = clk_prepare_enable(sata_ref_clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "can't prepare/enable sata ref clock.\n");
|
||||
goto put_sata_ref_clk;
|
||||
}
|
||||
|
||||
/* Get the AHB clock rate, and configure the TIMER1MS reg later */
|
||||
clk = clk_get(dev, "ahci_dma");
|
||||
if (IS_ERR(clk)) {
|
||||
dev_err(dev, "no dma clock.\n");
|
||||
ret = PTR_ERR(clk);
|
||||
goto release_sata_ref_clk;
|
||||
}
|
||||
tmpdata = clk_get_rate(clk) / 1000;
|
||||
clk_put(clk);
|
||||
|
||||
writel(tmpdata, addr + HOST_TIMER1MS);
|
||||
|
||||
tmpdata = readl(addr + HOST_CAP);
|
||||
if (!(tmpdata & HOST_CAP_SSS)) {
|
||||
tmpdata |= HOST_CAP_SSS;
|
||||
writel(tmpdata, addr + HOST_CAP);
|
||||
}
|
||||
|
||||
if (!(readl(addr + HOST_PORTS_IMPL) & 0x1))
|
||||
writel((readl(addr + HOST_PORTS_IMPL) | 0x1),
|
||||
addr + HOST_PORTS_IMPL);
|
||||
|
||||
return 0;
|
||||
|
||||
release_sata_ref_clk:
|
||||
clk_disable_unprepare(sata_ref_clk);
|
||||
put_sata_ref_clk:
|
||||
clk_put(sata_ref_clk);
|
||||
release_sata_clk:
|
||||
clk_disable_unprepare(sata_clk);
|
||||
put_sata_clk:
|
||||
clk_put(sata_clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void imx_sata_exit(struct device *dev)
|
||||
{
|
||||
clk_disable_unprepare(sata_ref_clk);
|
||||
clk_put(sata_ref_clk);
|
||||
|
||||
clk_disable_unprepare(sata_clk);
|
||||
clk_put(sata_clk);
|
||||
|
||||
}
|
||||
struct platform_device *__init imx_add_ahci_imx(
|
||||
const struct imx_ahci_imx_data *data,
|
||||
const struct ahci_platform_data *pdata)
|
||||
{
|
||||
struct resource res[] = {
|
||||
{
|
||||
.start = data->iobase,
|
||||
.end = data->iobase + SZ_4K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.start = data->irq,
|
||||
.end = data->irq,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
return imx_add_platform_device_dmamask(data->devid, 0,
|
||||
res, ARRAY_SIZE(res),
|
||||
pdata, sizeof(*pdata), DMA_BIT_MASK(32));
|
||||
}
|
||||
|
||||
struct platform_device *__init imx53_add_ahci_imx(void)
|
||||
{
|
||||
struct ahci_platform_data pdata = {
|
||||
.init = imx_sata_init,
|
||||
.exit = imx_sata_exit,
|
||||
};
|
||||
|
||||
return imx_add_ahci_imx(&imx53_ahci_imx_data, &pdata);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 Freescale Semiconductor, Inc.
|
||||
* Copyright 2011-2013 Freescale Semiconductor, Inc.
|
||||
* Copyright 2011 Linaro Ltd.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
@ -68,6 +68,27 @@ static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void imx_gpc_mask_all(void)
|
||||
{
|
||||
void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < IMR_NUM; i++) {
|
||||
gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
|
||||
writel_relaxed(~0, reg_imr1 + i * 4);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void imx_gpc_restore_all(void)
|
||||
{
|
||||
void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < IMR_NUM; i++)
|
||||
writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
|
||||
}
|
||||
|
||||
static void imx_gpc_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
void __iomem *reg;
|
||||
|
@ -102,7 +102,6 @@
|
||||
|
||||
#include "mxc.h"
|
||||
|
||||
#include "mx6q.h"
|
||||
#include "mx51.h"
|
||||
#include "mx53.h"
|
||||
#include "mx3x.h"
|
||||
|
@ -46,11 +46,23 @@ static inline void cpu_enter_lowpower(void)
|
||||
void imx_cpu_die(unsigned int cpu)
|
||||
{
|
||||
cpu_enter_lowpower();
|
||||
/*
|
||||
* We use the cpu jumping argument register to sync with
|
||||
* imx_cpu_kill() which is running on cpu0 and waiting for
|
||||
* the register being cleared to kill the cpu.
|
||||
*/
|
||||
imx_set_cpu_arg(cpu, ~0);
|
||||
cpu_do_idle();
|
||||
}
|
||||
|
||||
int imx_cpu_kill(unsigned int cpu)
|
||||
{
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(50);
|
||||
|
||||
while (imx_get_cpu_arg(cpu) == 0)
|
||||
if (time_after(jiffies, timeout))
|
||||
return 0;
|
||||
imx_enable_cpu(cpu, false);
|
||||
imx_set_cpu_arg(cpu, 0);
|
||||
return 1;
|
||||
}
|
||||
|
@ -33,7 +33,6 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "devices-imx51.h"
|
||||
#include "cpu_op-mx51.h"
|
||||
#include "eukrea-baseboards.h"
|
||||
#include "hardware.h"
|
||||
#include "iomux-mx51.h"
|
||||
@ -285,10 +284,6 @@ static void __init eukrea_cpuimx51sd_init(void)
|
||||
mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads,
|
||||
ARRAY_SIZE(eukrea_cpuimx51sd_pads));
|
||||
|
||||
#if defined(CONFIG_CPU_FREQ_IMX)
|
||||
get_cpu_op = mx51_get_cpu_op;
|
||||
#endif
|
||||
|
||||
imx51_add_imx_uart(0, &uart_pdata);
|
||||
imx51_add_mxc_nand(&eukrea_cpuimx51sd_nand_board_info);
|
||||
imx51_add_imx2_wdt(0);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 Freescale Semiconductor, Inc.
|
||||
* Copyright 2011-2013 Freescale Semiconductor, Inc.
|
||||
* Copyright 2011 Linaro Ltd.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
@ -38,38 +38,32 @@
|
||||
#include "cpuidle.h"
|
||||
#include "hardware.h"
|
||||
|
||||
#define IMX6Q_ANALOG_DIGPROG 0x260
|
||||
static u32 chip_revision;
|
||||
|
||||
static int imx6q_revision(void)
|
||||
int imx6q_revision(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
void __iomem *base;
|
||||
static u32 rev;
|
||||
return chip_revision;
|
||||
}
|
||||
|
||||
if (!rev) {
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
|
||||
if (!np)
|
||||
return IMX_CHIP_REVISION_UNKNOWN;
|
||||
base = of_iomap(np, 0);
|
||||
if (!base) {
|
||||
of_node_put(np);
|
||||
return IMX_CHIP_REVISION_UNKNOWN;
|
||||
}
|
||||
rev = readl_relaxed(base + IMX6Q_ANALOG_DIGPROG);
|
||||
iounmap(base);
|
||||
of_node_put(np);
|
||||
}
|
||||
static void __init imx6q_init_revision(void)
|
||||
{
|
||||
u32 rev = imx_anatop_get_digprog();
|
||||
|
||||
switch (rev & 0xff) {
|
||||
case 0:
|
||||
return IMX_CHIP_REVISION_1_0;
|
||||
chip_revision = IMX_CHIP_REVISION_1_0;
|
||||
break;
|
||||
case 1:
|
||||
return IMX_CHIP_REVISION_1_1;
|
||||
chip_revision = IMX_CHIP_REVISION_1_1;
|
||||
break;
|
||||
case 2:
|
||||
return IMX_CHIP_REVISION_1_2;
|
||||
chip_revision = IMX_CHIP_REVISION_1_2;
|
||||
break;
|
||||
default:
|
||||
return IMX_CHIP_REVISION_UNKNOWN;
|
||||
chip_revision = IMX_CHIP_REVISION_UNKNOWN;
|
||||
}
|
||||
|
||||
mxc_set_cpu_type(rev >> 16 & 0xff);
|
||||
}
|
||||
|
||||
void imx6q_restart(char mode, const char *cmd)
|
||||
@ -164,29 +158,7 @@ static void __init imx6q_1588_init(void)
|
||||
}
|
||||
static void __init imx6q_usb_init(void)
|
||||
{
|
||||
struct regmap *anatop;
|
||||
|
||||
#define HW_ANADIG_USB1_CHRG_DETECT 0x000001b0
|
||||
#define HW_ANADIG_USB2_CHRG_DETECT 0x00000210
|
||||
|
||||
#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x00100000
|
||||
#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x00080000
|
||||
|
||||
anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
|
||||
if (!IS_ERR(anatop)) {
|
||||
/*
|
||||
* The external charger detector needs to be disabled,
|
||||
* or the signal at DP will be poor
|
||||
*/
|
||||
regmap_write(anatop, HW_ANADIG_USB1_CHRG_DETECT,
|
||||
BM_ANADIG_USB_CHRG_DETECT_EN_B
|
||||
| BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
|
||||
regmap_write(anatop, HW_ANADIG_USB2_CHRG_DETECT,
|
||||
BM_ANADIG_USB_CHRG_DETECT_EN_B |
|
||||
BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
|
||||
} else {
|
||||
pr_warn("failed to find fsl,imx6q-anatop regmap\n");
|
||||
}
|
||||
imx_anatop_usb_chrg_detect_disable();
|
||||
}
|
||||
|
||||
static void __init imx6q_init_machine(void)
|
||||
@ -196,6 +168,7 @@ static void __init imx6q_init_machine(void)
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
|
||||
imx_anatop_init();
|
||||
imx6q_pm_init();
|
||||
imx6q_usb_init();
|
||||
imx6q_1588_init();
|
||||
@ -282,6 +255,7 @@ static void __init imx6q_map_io(void)
|
||||
|
||||
static void __init imx6q_init_irq(void)
|
||||
{
|
||||
imx6q_init_revision();
|
||||
l2x0_of_init(0, ~0UL);
|
||||
imx_src_init();
|
||||
imx_gpc_init();
|
||||
@ -292,15 +266,17 @@ static void __init imx6q_timer_init(void)
|
||||
{
|
||||
mx6q_clocks_init();
|
||||
clocksource_of_init();
|
||||
imx_print_silicon_rev("i.MX6Q", imx6q_revision());
|
||||
imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
|
||||
imx6q_revision());
|
||||
}
|
||||
|
||||
static const char *imx6q_dt_compat[] __initdata = {
|
||||
"fsl,imx6dl",
|
||||
"fsl,imx6q",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)")
|
||||
DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
|
||||
.smp = smp_ops(imx_smp_ops),
|
||||
.map_io = imx6q_map_io,
|
||||
.init_irq = imx6q_init_irq,
|
||||
|
@ -27,7 +27,6 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "devices-imx51.h"
|
||||
#include "cpu_op-mx51.h"
|
||||
#include "hardware.h"
|
||||
#include "iomux-mx51.h"
|
||||
|
||||
@ -371,9 +370,6 @@ static void __init mx51_babbage_init(void)
|
||||
|
||||
imx51_soc_init();
|
||||
|
||||
#if defined(CONFIG_CPU_FREQ_IMX)
|
||||
get_cpu_op = mx51_get_cpu_op;
|
||||
#endif
|
||||
imx51_babbage_common_init();
|
||||
|
||||
imx51_add_imx_uart(0, &uart_pdata);
|
||||
|
@ -51,6 +51,8 @@ void __init mx1_init_irq(void)
|
||||
|
||||
void __init imx1_soc_init(void)
|
||||
{
|
||||
mxc_device_init();
|
||||
|
||||
mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256,
|
||||
MX1_GPIO_INT_PORTA, 0);
|
||||
mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256,
|
||||
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2011 Linaro Ltd.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#ifndef __MACH_MX6Q_H__
|
||||
#define __MACH_MX6Q_H__
|
||||
|
||||
#define MX6Q_IO_P2V(x) IMX_IO_P2V(x)
|
||||
#define MX6Q_IO_ADDRESS(x) IOMEM(MX6Q_IO_P2V(x))
|
||||
|
||||
/*
|
||||
* The following are the blocks that need to be statically mapped.
|
||||
* For other blocks, the base address really should be retrieved from
|
||||
* device tree.
|
||||
*/
|
||||
#define MX6Q_SCU_BASE_ADDR 0x00a00000
|
||||
#define MX6Q_SCU_SIZE 0x1000
|
||||
#define MX6Q_CCM_BASE_ADDR 0x020c4000
|
||||
#define MX6Q_CCM_SIZE 0x4000
|
||||
#define MX6Q_ANATOP_BASE_ADDR 0x020c8000
|
||||
#define MX6Q_ANATOP_SIZE 0x1000
|
||||
|
||||
#endif /* __MACH_MX6Q_H__ */
|
@ -34,6 +34,8 @@
|
||||
#define MXC_CPU_MX35 35
|
||||
#define MXC_CPU_MX51 51
|
||||
#define MXC_CPU_MX53 53
|
||||
#define MXC_CPU_IMX6DL 0x61
|
||||
#define MXC_CPU_IMX6Q 0x63
|
||||
|
||||
#define IMX_CHIP_REVISION_1_0 0x10
|
||||
#define IMX_CHIP_REVISION_1_1 0x11
|
||||
@ -150,6 +152,15 @@ extern unsigned int __mxc_cpu_type;
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
static inline bool cpu_is_imx6dl(void)
|
||||
{
|
||||
return __mxc_cpu_type == MXC_CPU_IMX6DL;
|
||||
}
|
||||
|
||||
static inline bool cpu_is_imx6q(void)
|
||||
{
|
||||
return __mxc_cpu_type == MXC_CPU_IMX6Q;
|
||||
}
|
||||
|
||||
struct cpu_op {
|
||||
u32 cpu_rate;
|
||||
|
@ -68,8 +68,8 @@ static void __init imx_smp_init_cpus(void)
|
||||
|
||||
ncores = scu_get_core_count(scu_base);
|
||||
|
||||
for (i = 0; i < ncores; i++)
|
||||
set_cpu_possible(i, true);
|
||||
for (i = ncores; i < NR_CPUS; i++)
|
||||
set_cpu_possible(i, false);
|
||||
}
|
||||
|
||||
void imx_smp_prepare(void)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 Freescale Semiconductor, Inc.
|
||||
* Copyright 2011-2013 Freescale Semiconductor, Inc.
|
||||
* Copyright 2011 Linaro Ltd.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
@ -34,10 +34,12 @@ static int imx6q_pm_enter(suspend_state_t state)
|
||||
case PM_SUSPEND_MEM:
|
||||
imx6q_set_lpm(STOP_POWER_OFF);
|
||||
imx_gpc_pre_suspend();
|
||||
imx_anatop_pre_suspend();
|
||||
imx_set_cpu_jump(0, v7_cpu_resume);
|
||||
/* Zzz ... */
|
||||
cpu_suspend(0, imx6q_suspend_finish);
|
||||
imx_smp_prepare();
|
||||
imx_anatop_post_resume();
|
||||
imx_gpc_post_resume();
|
||||
imx6q_set_lpm(WAIT_CLOCKED);
|
||||
break;
|
||||
|
@ -14,16 +14,72 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/smp_plat.h>
|
||||
|
||||
#define SRC_SCR 0x000
|
||||
#define SRC_GPR1 0x020
|
||||
#define BP_SRC_SCR_WARM_RESET_ENABLE 0
|
||||
#define BP_SRC_SCR_SW_GPU_RST 1
|
||||
#define BP_SRC_SCR_SW_VPU_RST 2
|
||||
#define BP_SRC_SCR_SW_IPU1_RST 3
|
||||
#define BP_SRC_SCR_SW_OPEN_VG_RST 4
|
||||
#define BP_SRC_SCR_SW_IPU2_RST 12
|
||||
#define BP_SRC_SCR_CORE1_RST 14
|
||||
#define BP_SRC_SCR_CORE1_ENABLE 22
|
||||
|
||||
static void __iomem *src_base;
|
||||
static DEFINE_SPINLOCK(scr_lock);
|
||||
|
||||
static const int sw_reset_bits[5] = {
|
||||
BP_SRC_SCR_SW_GPU_RST,
|
||||
BP_SRC_SCR_SW_VPU_RST,
|
||||
BP_SRC_SCR_SW_IPU1_RST,
|
||||
BP_SRC_SCR_SW_OPEN_VG_RST,
|
||||
BP_SRC_SCR_SW_IPU2_RST
|
||||
};
|
||||
|
||||
static int imx_src_reset_module(struct reset_controller_dev *rcdev,
|
||||
unsigned long sw_reset_idx)
|
||||
{
|
||||
unsigned long timeout;
|
||||
unsigned long flags;
|
||||
int bit;
|
||||
u32 val;
|
||||
|
||||
if (!src_base)
|
||||
return -ENODEV;
|
||||
|
||||
if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits))
|
||||
return -EINVAL;
|
||||
|
||||
bit = 1 << sw_reset_bits[sw_reset_idx];
|
||||
|
||||
spin_lock_irqsave(&scr_lock, flags);
|
||||
val = readl_relaxed(src_base + SRC_SCR);
|
||||
val |= bit;
|
||||
writel_relaxed(val, src_base + SRC_SCR);
|
||||
spin_unlock_irqrestore(&scr_lock, flags);
|
||||
|
||||
timeout = jiffies + msecs_to_jiffies(1000);
|
||||
while (readl(src_base + SRC_SCR) & bit) {
|
||||
if (time_after(jiffies, timeout))
|
||||
return -ETIME;
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct reset_control_ops imx_src_ops = {
|
||||
.reset = imx_src_reset_module,
|
||||
};
|
||||
|
||||
static struct reset_controller_dev imx_reset_controller = {
|
||||
.ops = &imx_src_ops,
|
||||
.nr_resets = ARRAY_SIZE(sw_reset_bits),
|
||||
};
|
||||
|
||||
void imx_enable_cpu(int cpu, bool enable)
|
||||
{
|
||||
@ -31,9 +87,11 @@ void imx_enable_cpu(int cpu, bool enable)
|
||||
|
||||
cpu = cpu_logical_map(cpu);
|
||||
mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
|
||||
spin_lock(&scr_lock);
|
||||
val = readl_relaxed(src_base + SRC_SCR);
|
||||
val = enable ? val | mask : val & ~mask;
|
||||
writel_relaxed(val, src_base + SRC_SCR);
|
||||
spin_unlock(&scr_lock);
|
||||
}
|
||||
|
||||
void imx_set_cpu_jump(int cpu, void *jump_addr)
|
||||
@ -43,14 +101,28 @@ void imx_set_cpu_jump(int cpu, void *jump_addr)
|
||||
src_base + SRC_GPR1 + cpu * 8);
|
||||
}
|
||||
|
||||
u32 imx_get_cpu_arg(int cpu)
|
||||
{
|
||||
cpu = cpu_logical_map(cpu);
|
||||
return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4);
|
||||
}
|
||||
|
||||
void imx_set_cpu_arg(int cpu, u32 arg)
|
||||
{
|
||||
cpu = cpu_logical_map(cpu);
|
||||
writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4);
|
||||
}
|
||||
|
||||
void imx_src_prepare_restart(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* clear enable bits of secondary cores */
|
||||
spin_lock(&scr_lock);
|
||||
val = readl_relaxed(src_base + SRC_SCR);
|
||||
val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE);
|
||||
writel_relaxed(val, src_base + SRC_SCR);
|
||||
spin_unlock(&scr_lock);
|
||||
|
||||
/* clear persistent entry register of primary core */
|
||||
writel_relaxed(0, src_base + SRC_GPR1);
|
||||
@ -65,11 +137,16 @@ void __init imx_src_init(void)
|
||||
src_base = of_iomap(np, 0);
|
||||
WARN_ON(!src_base);
|
||||
|
||||
imx_reset_controller.of_node = np;
|
||||
reset_controller_register(&imx_reset_controller);
|
||||
|
||||
/*
|
||||
* force warm reset sources to generate cold reset
|
||||
* for a more reliable restart
|
||||
*/
|
||||
spin_lock(&scr_lock);
|
||||
val = readl_relaxed(src_base + SRC_SCR);
|
||||
val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE);
|
||||
writel_relaxed(val, src_base + SRC_SCR);
|
||||
spin_unlock(&scr_lock);
|
||||
}
|
||||
|
@ -53,6 +53,8 @@ static struct mv_sata_platform_data guruplug_sata_data = {
|
||||
|
||||
static struct mvsdio_platform_data guruplug_mvsdio_data = {
|
||||
/* unfortunately the CD signal has not been connected */
|
||||
.gpio_card_detect = -1,
|
||||
.gpio_write_protect = -1,
|
||||
};
|
||||
|
||||
static struct gpio_led guruplug_led_pins[] = {
|
||||
|
@ -55,6 +55,7 @@ static struct mv_sata_platform_data openrd_sata_data = {
|
||||
|
||||
static struct mvsdio_platform_data openrd_mvsdio_data = {
|
||||
.gpio_card_detect = 29, /* MPP29 used as SD card detect */
|
||||
.gpio_write_protect = -1,
|
||||
};
|
||||
|
||||
static unsigned int openrd_mpp_config[] __initdata = {
|
||||
|
@ -69,6 +69,7 @@ static struct mv_sata_platform_data rd88f6281_sata_data = {
|
||||
|
||||
static struct mvsdio_platform_data rd88f6281_mvsdio_data = {
|
||||
.gpio_card_detect = 28,
|
||||
.gpio_write_protect = -1,
|
||||
};
|
||||
|
||||
static unsigned int rd88f6281_mpp_config[] __initdata = {
|
||||
|
@ -62,7 +62,10 @@ static int msm_timer_set_next_event(unsigned long cycles,
|
||||
{
|
||||
u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
|
||||
|
||||
writel_relaxed(0, event_base + TIMER_CLEAR);
|
||||
ctrl &= ~TIMER_ENABLE_EN;
|
||||
writel_relaxed(ctrl, event_base + TIMER_ENABLE);
|
||||
|
||||
writel_relaxed(ctrl, event_base + TIMER_CLEAR);
|
||||
writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
|
||||
writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
|
||||
return 0;
|
||||
|
@ -44,6 +44,8 @@
|
||||
|
||||
#define ARMADA_370_XP_MAX_PER_CPU_IRQS (28)
|
||||
|
||||
#define ARMADA_370_XP_TIMER0_PER_CPU_IRQ (5)
|
||||
|
||||
#define ACTIVE_DOORBELLS (8)
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(irq_controller_lock);
|
||||
@ -62,7 +64,7 @@ static void armada_370_xp_irq_mask(struct irq_data *d)
|
||||
#ifdef CONFIG_SMP
|
||||
irq_hw_number_t hwirq = irqd_to_hwirq(d);
|
||||
|
||||
if (hwirq > ARMADA_370_XP_MAX_PER_CPU_IRQS)
|
||||
if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ)
|
||||
writel(hwirq, main_int_base +
|
||||
ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS);
|
||||
else
|
||||
@ -79,7 +81,7 @@ static void armada_370_xp_irq_unmask(struct irq_data *d)
|
||||
#ifdef CONFIG_SMP
|
||||
irq_hw_number_t hwirq = irqd_to_hwirq(d);
|
||||
|
||||
if (hwirq > ARMADA_370_XP_MAX_PER_CPU_IRQS)
|
||||
if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ)
|
||||
writel(hwirq, main_int_base +
|
||||
ARMADA_370_XP_INT_SET_ENABLE_OFFS);
|
||||
else
|
||||
@ -147,7 +149,7 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
|
||||
writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS);
|
||||
irq_set_status_flags(virq, IRQ_LEVEL);
|
||||
|
||||
if (hw < ARMADA_370_XP_MAX_PER_CPU_IRQS) {
|
||||
if (hw == ARMADA_370_XP_TIMER0_PER_CPU_IRQ) {
|
||||
irq_set_percpu_devid(virq);
|
||||
irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip,
|
||||
handle_percpu_devid_irq);
|
||||
|
@ -538,15 +538,6 @@ static struct clk usb_hhc_ck16xx = {
|
||||
};
|
||||
|
||||
static struct clk usb_dc_ck = {
|
||||
.name = "usb_dc_ck",
|
||||
.ops = &clkops_generic,
|
||||
/* Direct from ULPD, no parent */
|
||||
.rate = 48000000,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
|
||||
.enable_bit = USB_REQ_EN_SHIFT,
|
||||
};
|
||||
|
||||
static struct clk usb_dc_ck7xx = {
|
||||
.name = "usb_dc_ck",
|
||||
.ops = &clkops_generic,
|
||||
/* Direct from ULPD, no parent */
|
||||
@ -727,8 +718,7 @@ static struct omap_clk omap_clks[] = {
|
||||
CLK(NULL, "usb_clko", &usb_clko, CK_16XX | CK_1510 | CK_310),
|
||||
CLK(NULL, "usb_hhc_ck", &usb_hhc_ck1510, CK_1510 | CK_310),
|
||||
CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx, CK_16XX),
|
||||
CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX),
|
||||
CLK(NULL, "usb_dc_ck", &usb_dc_ck7xx, CK_7XX),
|
||||
CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX | CK_7XX),
|
||||
CLK(NULL, "mclk", &mclk_1510, CK_1510 | CK_310),
|
||||
CLK(NULL, "mclk", &mclk_16xx, CK_16XX),
|
||||
CLK(NULL, "bclk", &bclk_1510, CK_1510 | CK_310),
|
||||
|
@ -52,6 +52,13 @@
|
||||
*/
|
||||
#define OMAP4_DPLL_ABE_DEFFREQ 98304000
|
||||
|
||||
/*
|
||||
* OMAP4 USB DPLL default frequency. In OMAP4430 TRM version V, section
|
||||
* "3.6.3.9.5 DPLL_USB Preferred Settings" shows that the preferred
|
||||
* locked frequency for the USB DPLL is 960MHz.
|
||||
*/
|
||||
#define OMAP4_DPLL_USB_DEFFREQ 960000000
|
||||
|
||||
/* Root clocks */
|
||||
|
||||
DEFINE_CLK_FIXED_RATE(extalt_clkin_ck, CLK_IS_ROOT, 59000000, 0x0);
|
||||
@ -1011,6 +1018,10 @@ DEFINE_CLK_OMAP_MUX(hsmmc2_fclk, "l3_init_clkdm", hsmmc1_fclk_sel,
|
||||
OMAP4430_CM_L3INIT_MMC2_CLKCTRL, OMAP4430_CLKSEL_MASK,
|
||||
hsmmc1_fclk_parents, func_dmic_abe_gfclk_ops);
|
||||
|
||||
DEFINE_CLK_GATE(ocp2scp_usb_phy_phy_48m, "func_48m_fclk", &func_48m_fclk, 0x0,
|
||||
OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
|
||||
OMAP4430_OPTFCLKEN_PHY_48M_SHIFT, 0x0, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(sha2md5_fck, "l3_div_ck", &l3_div_ck, 0x0,
|
||||
OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL,
|
||||
OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
|
||||
@ -1538,6 +1549,7 @@ static struct omap_clk omap44xx_clks[] = {
|
||||
CLK(NULL, "per_mcbsp4_gfclk", &per_mcbsp4_gfclk, CK_443X),
|
||||
CLK(NULL, "hsmmc1_fclk", &hsmmc1_fclk, CK_443X),
|
||||
CLK(NULL, "hsmmc2_fclk", &hsmmc2_fclk, CK_443X),
|
||||
CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_443X),
|
||||
CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_443X),
|
||||
CLK(NULL, "slimbus1_fclk_1", &slimbus1_fclk_1, CK_443X),
|
||||
CLK(NULL, "slimbus1_fclk_0", &slimbus1_fclk_0, CK_443X),
|
||||
@ -1705,5 +1717,13 @@ int __init omap4xxx_clk_init(void)
|
||||
if (rc)
|
||||
pr_err("%s: failed to configure ABE DPLL!\n", __func__);
|
||||
|
||||
/*
|
||||
* Lock USB DPLL on OMAP4 devices so that the L3INIT power
|
||||
* domain can transition to retention state when not in use.
|
||||
*/
|
||||
rc = clk_set_rate(&dpll_usb_ck, OMAP4_DPLL_USB_DEFFREQ);
|
||||
if (rc)
|
||||
pr_err("%s: failed to configure USB DPLL!\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -293,5 +293,8 @@ extern void omap_reserve(void);
|
||||
struct omap_hwmod;
|
||||
extern int omap_dss_reset(struct omap_hwmod *);
|
||||
|
||||
/* SoC specific clock initializer */
|
||||
extern int (*omap_clk_init)(void);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
|
||||
|
@ -54,6 +54,12 @@
|
||||
#include "prm3xxx.h"
|
||||
#include "prm44xx.h"
|
||||
|
||||
/*
|
||||
* omap_clk_init: points to a function that does the SoC-specific
|
||||
* clock initializations
|
||||
*/
|
||||
int (*omap_clk_init)(void);
|
||||
|
||||
/*
|
||||
* The machine specific code may provide the extra mapping besides the
|
||||
* default mapping provided here.
|
||||
@ -397,7 +403,7 @@ void __init omap2420_init_early(void)
|
||||
omap242x_clockdomains_init();
|
||||
omap2420_hwmod_init();
|
||||
omap_hwmod_init_postsetup();
|
||||
omap2420_clk_init();
|
||||
omap_clk_init = omap2420_clk_init;
|
||||
}
|
||||
|
||||
void __init omap2420_init_late(void)
|
||||
@ -427,7 +433,7 @@ void __init omap2430_init_early(void)
|
||||
omap243x_clockdomains_init();
|
||||
omap2430_hwmod_init();
|
||||
omap_hwmod_init_postsetup();
|
||||
omap2430_clk_init();
|
||||
omap_clk_init = omap2430_clk_init;
|
||||
}
|
||||
|
||||
void __init omap2430_init_late(void)
|
||||
@ -462,7 +468,7 @@ void __init omap3_init_early(void)
|
||||
omap3xxx_clockdomains_init();
|
||||
omap3xxx_hwmod_init();
|
||||
omap_hwmod_init_postsetup();
|
||||
omap3xxx_clk_init();
|
||||
omap_clk_init = omap3xxx_clk_init;
|
||||
}
|
||||
|
||||
void __init omap3430_init_early(void)
|
||||
@ -500,7 +506,7 @@ void __init ti81xx_init_early(void)
|
||||
omap3xxx_clockdomains_init();
|
||||
omap3xxx_hwmod_init();
|
||||
omap_hwmod_init_postsetup();
|
||||
omap3xxx_clk_init();
|
||||
omap_clk_init = omap3xxx_clk_init;
|
||||
}
|
||||
|
||||
void __init omap3_init_late(void)
|
||||
@ -568,7 +574,7 @@ void __init am33xx_init_early(void)
|
||||
am33xx_clockdomains_init();
|
||||
am33xx_hwmod_init();
|
||||
omap_hwmod_init_postsetup();
|
||||
am33xx_clk_init();
|
||||
omap_clk_init = am33xx_clk_init;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -593,7 +599,7 @@ void __init omap4430_init_early(void)
|
||||
omap44xx_clockdomains_init();
|
||||
omap44xx_hwmod_init();
|
||||
omap_hwmod_init_postsetup();
|
||||
omap4xxx_clk_init();
|
||||
omap_clk_init = omap4xxx_clk_init;
|
||||
}
|
||||
|
||||
void __init omap4430_init_late(void)
|
||||
|
@ -1368,7 +1368,9 @@ static void _enable_sysc(struct omap_hwmod *oh)
|
||||
}
|
||||
|
||||
if (sf & SYSC_HAS_MIDLEMODE) {
|
||||
if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
|
||||
if (oh->flags & HWMOD_FORCE_MSTANDBY) {
|
||||
idlemode = HWMOD_IDLEMODE_FORCE;
|
||||
} else if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
|
||||
idlemode = HWMOD_IDLEMODE_NO;
|
||||
} else {
|
||||
if (sf & SYSC_HAS_ENAWAKEUP)
|
||||
@ -1440,7 +1442,8 @@ static void _idle_sysc(struct omap_hwmod *oh)
|
||||
}
|
||||
|
||||
if (sf & SYSC_HAS_MIDLEMODE) {
|
||||
if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
|
||||
if ((oh->flags & HWMOD_SWSUP_MSTANDBY) ||
|
||||
(oh->flags & HWMOD_FORCE_MSTANDBY)) {
|
||||
idlemode = HWMOD_IDLEMODE_FORCE;
|
||||
} else {
|
||||
if (sf & SYSC_HAS_ENAWAKEUP)
|
||||
|
@ -427,8 +427,8 @@ struct omap_hwmod_omap4_prcm {
|
||||
*
|
||||
* HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out
|
||||
* of idle, rather than relying on module smart-idle
|
||||
* HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out
|
||||
* of standby, rather than relying on module smart-standby
|
||||
* HWMOD_SWSUP_MSTANDBY: omap_hwmod code should manually bring module in and
|
||||
* out of standby, rather than relying on module smart-standby
|
||||
* HWMOD_INIT_NO_RESET: don't reset this module at boot - important for
|
||||
* SDRAM controller, etc. XXX probably belongs outside the main hwmod file
|
||||
* XXX Should be HWMOD_SETUP_NO_RESET
|
||||
@ -459,6 +459,10 @@ struct omap_hwmod_omap4_prcm {
|
||||
* correctly, or this is being abused to deal with some PM latency
|
||||
* issues -- but we're currently suffering from a shortage of
|
||||
* folks who are able to track these issues down properly.
|
||||
* HWMOD_FORCE_MSTANDBY: Always keep MIDLEMODE bits cleared so that device
|
||||
* is kept in force-standby mode. Failing to do so causes PM problems
|
||||
* with musb on OMAP3630 at least. Note that musb has a dedicated register
|
||||
* to control MSTANDBY signal when MIDLEMODE is set to force-standby.
|
||||
*/
|
||||
#define HWMOD_SWSUP_SIDLE (1 << 0)
|
||||
#define HWMOD_SWSUP_MSTANDBY (1 << 1)
|
||||
@ -471,6 +475,7 @@ struct omap_hwmod_omap4_prcm {
|
||||
#define HWMOD_16BIT_REG (1 << 8)
|
||||
#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9)
|
||||
#define HWMOD_BLOCK_WFI (1 << 10)
|
||||
#define HWMOD_FORCE_MSTANDBY (1 << 11)
|
||||
|
||||
/*
|
||||
* omap_hwmod._int_flags definitions
|
||||
|
@ -1707,9 +1707,14 @@ static struct omap_hwmod omap3xxx_usbhsotg_hwmod = {
|
||||
* Erratum ID: i479 idle_req / idle_ack mechanism potentially
|
||||
* broken when autoidle is enabled
|
||||
* workaround is to disable the autoidle bit at module level.
|
||||
*
|
||||
* Enabling the device in any other MIDLEMODE setting but force-idle
|
||||
* causes core_pwrdm not enter idle states at least on OMAP3630.
|
||||
* Note that musb has OTG_FORCESTDBY register that controls MSTANDBY
|
||||
* signal when MIDLEMODE is set to force-idle.
|
||||
*/
|
||||
.flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE
|
||||
| HWMOD_SWSUP_MSTANDBY,
|
||||
| HWMOD_FORCE_MSTANDBY,
|
||||
};
|
||||
|
||||
/* usb_otg_hs */
|
||||
|
@ -2714,6 +2714,10 @@ static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct omap_hwmod_opt_clk ocp2scp_usb_phy_opt_clks[] = {
|
||||
{ .role = "48mhz", .clk = "ocp2scp_usb_phy_phy_48m" },
|
||||
};
|
||||
|
||||
/* ocp2scp_usb_phy */
|
||||
static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
|
||||
.name = "ocp2scp_usb_phy",
|
||||
@ -2728,6 +2732,8 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
|
||||
},
|
||||
},
|
||||
.dev_attr = ocp2scp_dev_attr,
|
||||
.opt_clks = ocp2scp_usb_phy_opt_clks,
|
||||
.opt_clks_cnt = ARRAY_SIZE(ocp2scp_usb_phy_opt_clks),
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -547,6 +547,8 @@ static inline void __init realtime_counter_init(void)
|
||||
clksrc_nr, clksrc_src) \
|
||||
void __init omap##name##_gptimer_timer_init(void) \
|
||||
{ \
|
||||
if (omap_clk_init) \
|
||||
omap_clk_init(); \
|
||||
omap_dmtimer_init(); \
|
||||
omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \
|
||||
omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src); \
|
||||
@ -556,6 +558,8 @@ void __init omap##name##_gptimer_timer_init(void) \
|
||||
clksrc_nr, clksrc_src) \
|
||||
void __init omap##name##_sync32k_timer_init(void) \
|
||||
{ \
|
||||
if (omap_clk_init) \
|
||||
omap_clk_init(); \
|
||||
omap_dmtimer_init(); \
|
||||
omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \
|
||||
/* Enable the use of clocksource="gp_timer" kernel parameter */ \
|
||||
|
@ -81,7 +81,6 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = {
|
||||
#endif
|
||||
|
||||
struct mmci_platform_data mop500_sdi0_data = {
|
||||
.ios_handler = mop500_sdi0_ios_handler,
|
||||
.ocr_mask = MMC_VDD_29_30,
|
||||
.f_max = 50000000,
|
||||
.capabilities = MMC_CAP_4_BIT_DATA |
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/platform_data/i2c-nomadik.h>
|
||||
@ -439,6 +440,15 @@ static void mop500_prox_deactivate(struct device *dev)
|
||||
regulator_put(prox_regulator);
|
||||
}
|
||||
|
||||
void mop500_snowball_ethernet_clock_enable(void)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
clk = clk_get_sys("fsmc", NULL);
|
||||
if (!IS_ERR(clk))
|
||||
clk_prepare_enable(clk);
|
||||
}
|
||||
|
||||
static struct cryp_platform_data u8500_cryp1_platform_data = {
|
||||
.mem_to_engine = {
|
||||
.dir = STEDMA40_MEM_TO_PERIPH,
|
||||
@ -683,6 +693,8 @@ static void __init snowball_init_machine(void)
|
||||
mop500_audio_init(parent);
|
||||
mop500_uart_init(parent);
|
||||
|
||||
mop500_snowball_ethernet_clock_enable();
|
||||
|
||||
/* This board has full regulator constraints */
|
||||
regulator_has_full_constraints();
|
||||
}
|
||||
|
@ -104,6 +104,7 @@ void __init mop500_pinmaps_init(void);
|
||||
void __init snowball_pinmaps_init(void);
|
||||
void __init hrefv60_pinmaps_init(void);
|
||||
void mop500_audio_init(struct device *parent);
|
||||
void mop500_snowball_ethernet_clock_enable(void);
|
||||
|
||||
int __init mop500_uib_init(void);
|
||||
void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info,
|
||||
|
@ -312,9 +312,10 @@ static void __init u8500_init_machine(void)
|
||||
/* Pinmaps must be in place before devices register */
|
||||
if (of_machine_is_compatible("st-ericsson,mop500"))
|
||||
mop500_pinmaps_init();
|
||||
else if (of_machine_is_compatible("calaosystems,snowball-a9500"))
|
||||
else if (of_machine_is_compatible("calaosystems,snowball-a9500")) {
|
||||
snowball_pinmaps_init();
|
||||
else if (of_machine_is_compatible("st-ericsson,hrefv60+"))
|
||||
mop500_snowball_ethernet_clock_enable();
|
||||
} else if (of_machine_is_compatible("st-ericsson,hrefv60+"))
|
||||
hrefv60_pinmaps_init();
|
||||
else if (of_machine_is_compatible("st-ericsson,ccu9540")) {}
|
||||
/* TODO: Add pinmaps for ccu9540 board. */
|
||||
|
@ -299,7 +299,7 @@ static void l2x0_unlock(u32 cache_id)
|
||||
int lockregs;
|
||||
int i;
|
||||
|
||||
switch (cache_id) {
|
||||
switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
|
||||
case L2X0_CACHE_ID_PART_L310:
|
||||
lockregs = 8;
|
||||
break;
|
||||
@ -333,15 +333,14 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
|
||||
if (cache_id_part_number_from_dt)
|
||||
cache_id = cache_id_part_number_from_dt;
|
||||
else
|
||||
cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID)
|
||||
& L2X0_CACHE_ID_PART_MASK;
|
||||
cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
|
||||
aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
|
||||
|
||||
aux &= aux_mask;
|
||||
aux |= aux_val;
|
||||
|
||||
/* Determine the number of ways */
|
||||
switch (cache_id) {
|
||||
switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
|
||||
case L2X0_CACHE_ID_PART_L310:
|
||||
if (aux & (1 << 16))
|
||||
ways = 16;
|
||||
@ -725,7 +724,6 @@ static const struct l2x0_of_data pl310_data = {
|
||||
.flush_all = l2x0_flush_all,
|
||||
.inv_all = l2x0_inv_all,
|
||||
.disable = l2x0_disable,
|
||||
.set_debug = pl310_set_debug,
|
||||
},
|
||||
};
|
||||
|
||||
@ -814,9 +812,8 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
|
||||
data->save();
|
||||
|
||||
of_init = true;
|
||||
l2x0_init(l2x0_base, aux_val, aux_mask);
|
||||
|
||||
memcpy(&outer_cache, &data->outer_cache, sizeof(outer_cache));
|
||||
l2x0_init(l2x0_base, aux_val, aux_mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ static DEFINE_RAW_SPINLOCK(cpu_asid_lock);
|
||||
static atomic64_t asid_generation = ATOMIC64_INIT(ASID_FIRST_VERSION);
|
||||
static DECLARE_BITMAP(asid_map, NUM_USER_ASIDS);
|
||||
|
||||
static DEFINE_PER_CPU(atomic64_t, active_asids);
|
||||
DEFINE_PER_CPU(atomic64_t, active_asids);
|
||||
static DEFINE_PER_CPU(u64, reserved_asids);
|
||||
static cpumask_t tlb_flush_pending;
|
||||
|
||||
@ -215,6 +215,7 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
|
||||
if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) {
|
||||
local_flush_bp_all();
|
||||
local_flush_tlb_all();
|
||||
dummy_flush_tlb_a15_erratum();
|
||||
}
|
||||
|
||||
atomic64_set(&per_cpu(active_asids, cpu), asid);
|
||||
|
@ -598,39 +598,60 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
|
||||
} while (pte++, addr += PAGE_SIZE, addr != end);
|
||||
}
|
||||
|
||||
static void __init alloc_init_section(pud_t *pud, unsigned long addr,
|
||||
static void __init map_init_section(pmd_t *pmd, unsigned long addr,
|
||||
unsigned long end, phys_addr_t phys,
|
||||
const struct mem_type *type)
|
||||
{
|
||||
#ifndef CONFIG_ARM_LPAE
|
||||
/*
|
||||
* In classic MMU format, puds and pmds are folded in to
|
||||
* the pgds. pmd_offset gives the PGD entry. PGDs refer to a
|
||||
* group of L1 entries making up one logical pointer to
|
||||
* an L2 table (2MB), where as PMDs refer to the individual
|
||||
* L1 entries (1MB). Hence increment to get the correct
|
||||
* offset for odd 1MB sections.
|
||||
* (See arch/arm/include/asm/pgtable-2level.h)
|
||||
*/
|
||||
if (addr & SECTION_SIZE)
|
||||
pmd++;
|
||||
#endif
|
||||
do {
|
||||
*pmd = __pmd(phys | type->prot_sect);
|
||||
phys += SECTION_SIZE;
|
||||
} while (pmd++, addr += SECTION_SIZE, addr != end);
|
||||
|
||||
flush_pmd_entry(pmd);
|
||||
}
|
||||
|
||||
static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
|
||||
unsigned long end, phys_addr_t phys,
|
||||
const struct mem_type *type)
|
||||
{
|
||||
pmd_t *pmd = pmd_offset(pud, addr);
|
||||
unsigned long next;
|
||||
|
||||
/*
|
||||
* Try a section mapping - end, addr and phys must all be aligned
|
||||
* to a section boundary. Note that PMDs refer to the individual
|
||||
* L1 entries, whereas PGDs refer to a group of L1 entries making
|
||||
* up one logical pointer to an L2 table.
|
||||
*/
|
||||
if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) {
|
||||
pmd_t *p = pmd;
|
||||
|
||||
#ifndef CONFIG_ARM_LPAE
|
||||
if (addr & SECTION_SIZE)
|
||||
pmd++;
|
||||
#endif
|
||||
|
||||
do {
|
||||
*pmd = __pmd(phys | type->prot_sect);
|
||||
phys += SECTION_SIZE;
|
||||
} while (pmd++, addr += SECTION_SIZE, addr != end);
|
||||
|
||||
flush_pmd_entry(p);
|
||||
} else {
|
||||
do {
|
||||
/*
|
||||
* No need to loop; pte's aren't interested in the
|
||||
* individual L1 entries.
|
||||
* With LPAE, we must loop over to map
|
||||
* all the pmds for the given range.
|
||||
*/
|
||||
alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type);
|
||||
}
|
||||
next = pmd_addr_end(addr, end);
|
||||
|
||||
/*
|
||||
* Try a section mapping - addr, next and phys must all be
|
||||
* aligned to a section boundary.
|
||||
*/
|
||||
if (type->prot_sect &&
|
||||
((addr | next | phys) & ~SECTION_MASK) == 0) {
|
||||
map_init_section(pmd, addr, next, phys, type);
|
||||
} else {
|
||||
alloc_init_pte(pmd, addr, next,
|
||||
__phys_to_pfn(phys), type);
|
||||
}
|
||||
|
||||
phys += next - addr;
|
||||
|
||||
} while (pmd++, addr = next, addr != end);
|
||||
}
|
||||
|
||||
static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
|
||||
@ -641,7 +662,7 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
|
||||
|
||||
do {
|
||||
next = pud_addr_end(addr, end);
|
||||
alloc_init_section(pud, addr, next, phys, type);
|
||||
alloc_init_pmd(pud, addr, next, phys, type);
|
||||
phys += next - addr;
|
||||
} while (pud++, addr = next, addr != end);
|
||||
}
|
||||
|
@ -420,7 +420,7 @@ __v7_pj4b_proc_info:
|
||||
__v7_ca7mp_proc_info:
|
||||
.long 0x410fc070
|
||||
.long 0xff0ffff0
|
||||
__v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV
|
||||
__v7_proc __v7_ca7mp_setup
|
||||
.size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info
|
||||
|
||||
/*
|
||||
@ -430,9 +430,24 @@ __v7_ca7mp_proc_info:
|
||||
__v7_ca15mp_proc_info:
|
||||
.long 0x410fc0f0
|
||||
.long 0xff0ffff0
|
||||
__v7_proc __v7_ca15mp_setup, hwcaps = HWCAP_IDIV
|
||||
__v7_proc __v7_ca15mp_setup
|
||||
.size __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info
|
||||
|
||||
/*
|
||||
* Qualcomm Inc. Krait processors.
|
||||
*/
|
||||
.type __krait_proc_info, #object
|
||||
__krait_proc_info:
|
||||
.long 0x510f0400 @ Required ID value
|
||||
.long 0xff0ffc00 @ Mask for ID
|
||||
/*
|
||||
* Some Krait processors don't indicate support for SDIV and UDIV
|
||||
* instructions in the ARM instruction set, even though they actually
|
||||
* do support them.
|
||||
*/
|
||||
__v7_proc __v7_setup, hwcaps = HWCAP_IDIV
|
||||
.size __krait_proc_info, . - __krait_proc_info
|
||||
|
||||
/*
|
||||
* Match any ARMv7 processor core.
|
||||
*/
|
||||
|
@ -18,7 +18,7 @@ config MIPS
|
||||
select HAVE_KRETPROBES
|
||||
select HAVE_DEBUG_KMEMLEAK
|
||||
select ARCH_BINFMT_ELF_RANDOMIZE_PIE
|
||||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE
|
||||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
|
||||
select RTC_LIB if !MACH_LOONGSON
|
||||
select GENERIC_ATOMIC64 if !64BIT
|
||||
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
|
||||
@ -657,7 +657,7 @@ config SNI_RM
|
||||
bool "SNI RM200/300/400"
|
||||
select FW_ARC if CPU_LITTLE_ENDIAN
|
||||
select FW_ARC32 if CPU_LITTLE_ENDIAN
|
||||
select SNIPROM if CPU_BIG_ENDIAN
|
||||
select FW_SNIPROM if CPU_BIG_ENDIAN
|
||||
select ARCH_MAY_HAVE_PC_FDC
|
||||
select BOOT_ELF32
|
||||
select CEVT_R4K
|
||||
@ -1144,7 +1144,7 @@ config DEFAULT_SGI_PARTITION
|
||||
config FW_ARC32
|
||||
bool
|
||||
|
||||
config SNIPROM
|
||||
config FW_SNIPROM
|
||||
bool
|
||||
|
||||
config BOOT_ELF32
|
||||
@ -1493,7 +1493,6 @@ config CPU_XLP
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
select CPU_HAS_LLSC
|
||||
select WEAK_ORDERING
|
||||
select WEAK_REORDERING_BEYOND_LLSC
|
||||
select CPU_HAS_PREFETCH
|
||||
|
@ -745,10 +745,7 @@ void __init board_prom_init(void)
|
||||
strcpy(cfe_version, "unknown");
|
||||
printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
|
||||
|
||||
if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) {
|
||||
printk(KERN_ERR PFX "invalid nvram checksum\n");
|
||||
return;
|
||||
}
|
||||
bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET);
|
||||
|
||||
board_name = bcm63xx_nvram_get_name();
|
||||
/* find board by name */
|
||||
|
@ -38,7 +38,7 @@ struct bcm963xx_nvram {
|
||||
static struct bcm963xx_nvram nvram;
|
||||
static int mac_addr_used;
|
||||
|
||||
int __init bcm63xx_nvram_init(void *addr)
|
||||
void __init bcm63xx_nvram_init(void *addr)
|
||||
{
|
||||
unsigned int check_len;
|
||||
u32 crc, expected_crc;
|
||||
@ -60,9 +60,8 @@ int __init bcm63xx_nvram_init(void *addr)
|
||||
crc = crc32_le(~0, (u8 *)&nvram, check_len);
|
||||
|
||||
if (crc != expected_crc)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n",
|
||||
expected_crc, crc);
|
||||
}
|
||||
|
||||
u8 *bcm63xx_nvram_get_name(void)
|
||||
|
@ -157,4 +157,4 @@ int __init bcm63xx_register_devices(void)
|
||||
return board_register_devices();
|
||||
}
|
||||
|
||||
device_initcall(bcm63xx_register_devices);
|
||||
arch_initcall(bcm63xx_register_devices);
|
||||
|
@ -174,7 +174,10 @@ static int octeon_kexec_prepare(struct kimage *image)
|
||||
|
||||
static void octeon_generic_shutdown(void)
|
||||
{
|
||||
int cpu, i;
|
||||
int i;
|
||||
#ifdef CONFIG_SMP
|
||||
int cpu;
|
||||
#endif
|
||||
struct cvmx_bootmem_desc *bootmem_desc;
|
||||
void *named_block_array_ptr;
|
||||
|
||||
|
@ -9,10 +9,8 @@
|
||||
*
|
||||
* Initialized the local nvram copy from the target address and checks
|
||||
* its checksum.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int __init bcm63xx_nvram_init(void *nvram);
|
||||
void bcm63xx_nvram_init(void *nvram);
|
||||
|
||||
/**
|
||||
* bcm63xx_nvram_get_name() - returns the board name according to nvram
|
||||
|
@ -28,11 +28,7 @@
|
||||
/* #define cpu_has_prefetch ? */
|
||||
#define cpu_has_mcheck 1
|
||||
/* #define cpu_has_ejtag ? */
|
||||
#ifdef CONFIG_CPU_HAS_LLSC
|
||||
#define cpu_has_llsc 1
|
||||
#else
|
||||
#define cpu_has_llsc 0
|
||||
#endif
|
||||
/* #define cpu_has_vtag_icache ? */
|
||||
/* #define cpu_has_dc_aliases ? */
|
||||
/* #define cpu_has_ic_fills_f_dc ? */
|
||||
|
@ -1166,7 +1166,10 @@ do { \
|
||||
unsigned int __dspctl; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" rddsp %0, %x1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (__dspctl) \
|
||||
: "i" (mask)); \
|
||||
__dspctl; \
|
||||
@ -1175,30 +1178,198 @@ do { \
|
||||
#define wrdsp(val, mask) \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" wrdsp %0, %x1 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (val), "i" (mask)); \
|
||||
} while (0)
|
||||
|
||||
#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;})
|
||||
#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;})
|
||||
#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;})
|
||||
#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;})
|
||||
#define mflo0() \
|
||||
({ \
|
||||
long mflo0; \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mflo %0, $ac0 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (mflo0)); \
|
||||
mflo0; \
|
||||
})
|
||||
|
||||
#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;})
|
||||
#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;})
|
||||
#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;})
|
||||
#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;})
|
||||
#define mflo1() \
|
||||
({ \
|
||||
long mflo1; \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mflo %0, $ac1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (mflo1)); \
|
||||
mflo1; \
|
||||
})
|
||||
|
||||
#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x))
|
||||
#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x))
|
||||
#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x))
|
||||
#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x))
|
||||
#define mflo2() \
|
||||
({ \
|
||||
long mflo2; \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mflo %0, $ac2 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (mflo2)); \
|
||||
mflo2; \
|
||||
})
|
||||
|
||||
#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x))
|
||||
#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x))
|
||||
#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x))
|
||||
#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x))
|
||||
#define mflo3() \
|
||||
({ \
|
||||
long mflo3; \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mflo %0, $ac3 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (mflo3)); \
|
||||
mflo3; \
|
||||
})
|
||||
|
||||
#define mfhi0() \
|
||||
({ \
|
||||
long mfhi0; \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mfhi %0, $ac0 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (mfhi0)); \
|
||||
mfhi0; \
|
||||
})
|
||||
|
||||
#define mfhi1() \
|
||||
({ \
|
||||
long mfhi1; \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mfhi %0, $ac1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (mfhi1)); \
|
||||
mfhi1; \
|
||||
})
|
||||
|
||||
#define mfhi2() \
|
||||
({ \
|
||||
long mfhi2; \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mfhi %0, $ac2 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (mfhi2)); \
|
||||
mfhi2; \
|
||||
})
|
||||
|
||||
#define mfhi3() \
|
||||
({ \
|
||||
long mfhi3; \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mfhi %0, $ac3 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (mfhi3)); \
|
||||
mfhi3; \
|
||||
})
|
||||
|
||||
|
||||
#define mtlo0(x) \
|
||||
({ \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mtlo %0, $ac0 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
})
|
||||
|
||||
#define mtlo1(x) \
|
||||
({ \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mtlo %0, $ac1 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
})
|
||||
|
||||
#define mtlo2(x) \
|
||||
({ \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mtlo %0, $ac2 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
})
|
||||
|
||||
#define mtlo3(x) \
|
||||
({ \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mtlo %0, $ac3 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
})
|
||||
|
||||
#define mthi0(x) \
|
||||
({ \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mthi %0, $ac0 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
})
|
||||
|
||||
#define mthi1(x) \
|
||||
({ \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mthi %0, $ac1 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
})
|
||||
|
||||
#define mthi2(x) \
|
||||
({ \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mthi %0, $ac2 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
})
|
||||
|
||||
#define mthi3(x) \
|
||||
({ \
|
||||
__asm__( \
|
||||
" .set push \n" \
|
||||
" .set dsp \n" \
|
||||
" mthi %0, $ac3 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (x)); \
|
||||
})
|
||||
|
||||
#else
|
||||
|
||||
|
@ -21,6 +21,6 @@
|
||||
#include <asm/sigcontext.h>
|
||||
#include <asm/siginfo.h>
|
||||
|
||||
#define __ARCH_HAS_ODD_SIGACTION
|
||||
#define __ARCH_HAS_IRIX_SIGACTION
|
||||
|
||||
#endif /* _ASM_SIGNAL_H */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user