The imx/mxs soc changes for 3.13:
* Low-level debug support for Vybrid * Support soc bus/device for imx6 * Suspend support for imx6dl and imx6sl * The imx6q clock updates for PCIe and audio PLL support * IOMUXC GPR update for fec support * Some random cleanup * A few defconfig updates -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAABAgAGBQJSZI9RAAoJEFBXWFqHsHzOhgkH/RpZ6cvXFFaRdTWQu/SZCXTN m3Ul0VpuaUp9gsbDNbu//OmqCAsayXaKI7PuJhs885zDKw6R3yMH7hbwXY7z0Qrq jl9hP1Wzj7oU4CHTQbSDdcO3glUk+jl58a2MrsMsUaXPJTF8iMb8RkatwnReYhiZ uCBXPwaet7SJTuVQOL1uJmq35LmiROwyAkGsDKnDmphg3ZDUiI9mhqlyOyrS522w TjmCXrzZQiHkTp12Xo42fIEvE6BF5wCLDlJbq9HRDAlT82CnV62uQC/9os45Hott H1pJbwdbcdv3+6gUdnWbraukrbhCxT8Yk0As4ljP6YBCxC7Sau+oMh3ii4pvuI0= =VUrE -----END PGP SIGNATURE----- Merge tag 'imx-soc-3.13' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/soc From Shawn Guo: The imx/mxs soc changes for 3.13: * Low-level debug support for Vybrid * Support soc bus/device for imx6 * Suspend support for imx6dl and imx6sl * The imx6q clock updates for PCIe and audio PLL support * IOMUXC GPR update for fec support * Some random cleanup * A few defconfig updates * tag 'imx-soc-3.13' of git://git.linaro.org/people/shawnguo/linux-2.6: (31 commits) ARM: imx: enable suspend for imx6sl ARM: imx: ensure dsm_request signal is not asserted when setting LPM ARM: imx6q: call WB and RBC configuration from imx6q_pm_enter() ARM: imx6q: move low-power code out of clock driver ARM: imx: drop extern with function prototypes in common.h ARM: imx: reset core along with enable/disable operation ARM: imx: do not return from imx_cpu_die() call ARM: imx_v6_v7_defconfig: Select CONFIG_PROVE_LOCKING ARM: imx_v6_v7_defconfig: Enable LEDS_GPIO related options ARM: mxs_defconfig: Turn off CONFIG_DEBUG_GPIO ARM: imx: replace imx6q_restart() with mxc_restart() ARM: mach-imx: mm-imx5: Retrieve iomuxc base address from dt ARM: mach-imx: mm-imx5: Retrieve tzic base address from dt ARM: mach-imx: clk-imx51-imx53: Retrieve base address and irq from dt ARM: mxs_defconfig: Add CHIPIDEA_UDC support ARM: imx: Include linux/err.h ARM: imx_v6_v7_defconfig: Add CHIPIDEA_UDC support ARM: imx_v6_v7_defconfig: Add SPDIF support ARM: imx6q: clock and Kconfig update for PCIe support ARM: imx: Add LVDS general-purpose clocks to i.MX6Q ... Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
Коммит
b6fb5474af
|
@ -215,6 +215,11 @@ clocks and IDs.
|
|||
cko2 200
|
||||
cko 201
|
||||
vdoa 202
|
||||
pll4_audio_div 203
|
||||
lvds1_sel 204
|
||||
lvds2_sel 205
|
||||
lvds1_gate 206
|
||||
lvds2_gate 207
|
||||
|
||||
Examples:
|
||||
|
||||
|
|
|
@ -386,6 +386,13 @@ choice
|
|||
when u-boot hands over to the kernel, the system
|
||||
silently crashes, with no serial output at all.
|
||||
|
||||
config DEBUG_VF_UART
|
||||
bool "Vybrid UART"
|
||||
depends on SOC_VF610
|
||||
help
|
||||
Say Y here if you want kernel low-level debugging support
|
||||
on Vybrid based platforms.
|
||||
|
||||
config DEBUG_NOMADIK_UART
|
||||
bool "Kernel low-level debugging messages via NOMADIK UART"
|
||||
depends on ARCH_NOMADIK
|
||||
|
@ -906,6 +913,7 @@ config DEBUG_LL_INCLUDE
|
|||
default "debug/tegra.S" if DEBUG_TEGRA_UART
|
||||
default "debug/ux500.S" if DEBUG_UX500_UART
|
||||
default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT
|
||||
default "debug/vf.S" if DEBUG_VF_UART
|
||||
default "debug/vt8500.S" if DEBUG_VT8500_UART0
|
||||
default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1
|
||||
default "mach/debug-macro.S"
|
||||
|
|
|
@ -380,7 +380,9 @@
|
|||
};
|
||||
|
||||
anatop: anatop@020c8000 {
|
||||
compatible = "fsl,imx6sl-anatop", "syscon", "simple-bus";
|
||||
compatible = "fsl,imx6sl-anatop",
|
||||
"fsl,imx6q-anatop",
|
||||
"syscon", "simple-bus";
|
||||
reg = <0x020c8000 0x1000>;
|
||||
interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
|
||||
|
||||
|
|
|
@ -132,7 +132,6 @@ CONFIG_TOUCHSCREEN_MC13783=y
|
|||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_MMA8450=y
|
||||
CONFIG_SERIO_SERPORT=m
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_DEVKMEM is not set
|
||||
CONFIG_SERIAL_IMX=y
|
||||
|
@ -188,22 +187,33 @@ CONFIG_SND_SOC_PHYCORE_AC97=y
|
|||
CONFIG_SND_SOC_EUKREA_TLV320=y
|
||||
CONFIG_SND_SOC_IMX_WM8962=y
|
||||
CONFIG_SND_SOC_IMX_SGTL5000=y
|
||||
CONFIG_SND_SOC_IMX_SPDIF=y
|
||||
CONFIG_SND_SOC_IMX_MC13783=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_MXC=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_CHIPIDEA=y
|
||||
CONFIG_USB_CHIPIDEA_UDC=y
|
||||
CONFIG_USB_CHIPIDEA_HOST=y
|
||||
CONFIG_USB_PHY=y
|
||||
CONFIG_NOP_USB_XCEIV=y
|
||||
CONFIG_USB_MXS_PHY=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_ETH=m
|
||||
CONFIG_USB_MASS_STORAGE=m
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SDHCI_ESDHC_IMX=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_GPIO=y
|
||||
CONFIG_LEDS_TRIGGERS=y
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_LEDS_TRIGGER_ONESHOT=y
|
||||
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
||||
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
|
||||
CONFIG_LEDS_TRIGGER_GPIO=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_INTF_DEV_UIE_EMUL=y
|
||||
CONFIG_RTC_DRV_MC13XXX=y
|
||||
|
@ -246,7 +256,6 @@ CONFIG_UDF_FS=m
|
|||
CONFIG_MSDOS_FS=m
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_CONFIGFS_FS=m
|
||||
CONFIG_JFFS2_FS=y
|
||||
CONFIG_UBIFS_FS=y
|
||||
CONFIG_NFS_FS=y
|
||||
|
@ -261,6 +270,7 @@ CONFIG_NLS_ISO8859_15=m
|
|||
CONFIG_NLS_UTF8=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
CONFIG_PROVE_LOCKING=y
|
||||
# CONFIG_DEBUG_BUGVERBOSE is not set
|
||||
# CONFIG_FTRACE is not set
|
||||
# CONFIG_ARM_UNWIND is not set
|
||||
|
|
|
@ -76,7 +76,6 @@ CONFIG_INPUT_EVDEV=y
|
|||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_TOUCHSCREEN_TSC2007=m
|
||||
# CONFIG_SERIO is not set
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_DEVKMEM is not set
|
||||
|
@ -91,7 +90,6 @@ CONFIG_I2C_MXS=y
|
|||
CONFIG_SPI=y
|
||||
CONFIG_SPI_GPIO=m
|
||||
CONFIG_SPI_MXS=y
|
||||
CONFIG_DEBUG_GPIO=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_WATCHDOG=y
|
||||
|
@ -115,9 +113,12 @@ CONFIG_USB=y
|
|||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_CHIPIDEA=y
|
||||
CONFIG_USB_CHIPIDEA_UDC=y
|
||||
CONFIG_USB_CHIPIDEA_HOST=y
|
||||
CONFIG_USB_PHY=y
|
||||
CONFIG_USB_MXS_PHY=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_ETH=m
|
||||
CONFIG_USB_MASS_STORAGE=m
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_UNSAFE_RESUME=y
|
||||
CONFIG_MMC_MXS=y
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
.macro addruart, rp, rv, tmp
|
||||
ldr \rp, =0x40028000 @ physical
|
||||
ldr \rv, =0xfe028000 @ virtual
|
||||
.endm
|
||||
|
||||
.macro senduart, rd, rx
|
||||
strb \rd, [\rx, #0x7] @ Data Register
|
||||
.endm
|
||||
|
||||
.macro busyuart, rd, rx
|
||||
1001: ldrb \rd, [\rx, #0x4] @ Status Register 1
|
||||
tst \rd, #1 << 6 @ TC
|
||||
beq 1001b @ wait until transmit done
|
||||
.endm
|
||||
|
||||
.macro waituart,rd,rx
|
||||
.endm
|
|
@ -11,6 +11,7 @@ config ARCH_MXC
|
|||
select GENERIC_IRQ_CHIP
|
||||
select MIGHT_HAVE_CACHE_L2X0 if ARCH_MULTI_V6_V7
|
||||
select MULTI_IRQ_HANDLER
|
||||
select SOC_BUS
|
||||
select SPARSE_IRQ
|
||||
select USE_OF
|
||||
help
|
||||
|
@ -24,7 +25,7 @@ config MXC_IRQ_PRIOR
|
|||
help
|
||||
Select this if you want to use prioritized IRQ handling.
|
||||
This feature prevents higher priority ISR to be interrupted
|
||||
by lower priority IRQ even IRQF_DISABLED flag is not set.
|
||||
by lower priority IRQ.
|
||||
This may be useful in embedded applications, where are strong
|
||||
requirements for timing.
|
||||
Say N here, unless you have a specialized requirement.
|
||||
|
@ -801,6 +802,8 @@ config SOC_IMX6Q
|
|||
select HAVE_IMX_SRC
|
||||
select HAVE_SMP
|
||||
select MFD_SYSCON
|
||||
select MIGHT_HAVE_PCI
|
||||
select PCI_DOMAINS if PCI
|
||||
select PINCTRL
|
||||
select PINCTRL_IMX6Q
|
||||
select PL310_ERRATA_588369 if CACHE_PL310
|
||||
|
|
|
@ -102,6 +102,8 @@ obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
|
|||
|
||||
ifeq ($(CONFIG_PM),y)
|
||||
obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
|
||||
# i.MX6SL reuses pm-imx6q.c
|
||||
obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o
|
||||
endif
|
||||
|
||||
# i.MX5 based machines
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
#include "common.h"
|
||||
#include "hardware.h"
|
||||
|
||||
#define REG_SET 0x4
|
||||
#define REG_CLR 0x8
|
||||
|
@ -26,6 +27,7 @@
|
|||
#define ANADIG_USB1_CHRG_DETECT 0x1b0
|
||||
#define ANADIG_USB2_CHRG_DETECT 0x210
|
||||
#define ANADIG_DIGPROG 0x260
|
||||
#define ANADIG_DIGPROG_IMX6SL 0x280
|
||||
|
||||
#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000
|
||||
#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000
|
||||
|
@ -76,21 +78,38 @@ static void imx_anatop_usb_chrg_detect_disable(void)
|
|||
BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
|
||||
}
|
||||
|
||||
u32 imx_anatop_get_digprog(void)
|
||||
void __init imx_init_revision_from_anatop(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
void __iomem *anatop_base;
|
||||
static u32 digprog;
|
||||
|
||||
if (digprog)
|
||||
return digprog;
|
||||
unsigned int revision;
|
||||
u32 digprog;
|
||||
u16 offset = ANADIG_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);
|
||||
if (of_device_is_compatible(np, "fsl,imx6sl-anatop"))
|
||||
offset = ANADIG_DIGPROG_IMX6SL;
|
||||
digprog = readl_relaxed(anatop_base + offset);
|
||||
iounmap(anatop_base);
|
||||
|
||||
return digprog;
|
||||
switch (digprog & 0xff) {
|
||||
case 0:
|
||||
revision = IMX_CHIP_REVISION_1_0;
|
||||
break;
|
||||
case 1:
|
||||
revision = IMX_CHIP_REVISION_1_1;
|
||||
break;
|
||||
case 2:
|
||||
revision = IMX_CHIP_REVISION_1_2;
|
||||
break;
|
||||
default:
|
||||
revision = IMX_CHIP_REVISION_UNKNOWN;
|
||||
}
|
||||
|
||||
mxc_set_cpu_type(digprog >> 16 & 0xff);
|
||||
imx_set_soc_revision(revision);
|
||||
}
|
||||
|
||||
void __init imx_anatop_init(void)
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#include "crm-regs-imx5.h"
|
||||
#include "clk.h"
|
||||
|
@ -472,8 +475,9 @@ CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init_dt);
|
|||
|
||||
static void __init mx53_clocks_init(struct device_node *np)
|
||||
{
|
||||
int i;
|
||||
int i, irq;
|
||||
unsigned long r;
|
||||
void __iomem *base;
|
||||
|
||||
clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE);
|
||||
clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE);
|
||||
|
@ -559,14 +563,17 @@ static void __init mx53_clocks_init(struct device_node *np)
|
|||
clk_set_rate(clk[esdhc_a_podf], 200000000);
|
||||
clk_set_rate(clk[esdhc_b_podf], 200000000);
|
||||
|
||||
/* System timer */
|
||||
mxc_timer_init(MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), MX53_INT_GPT);
|
||||
|
||||
clk_prepare_enable(clk[iim_gate]);
|
||||
imx_print_silicon_rev("i.MX53", mx53_revision());
|
||||
clk_disable_unprepare(clk[iim_gate]);
|
||||
|
||||
r = clk_round_rate(clk[usboh3_per_gate], 54000000);
|
||||
clk_set_rate(clk[usboh3_per_gate], r);
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx53-gpt");
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
irq = irq_of_parse_and_map(np, 0);
|
||||
mxc_timer_init(base, irq);
|
||||
}
|
||||
CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init);
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#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>
|
||||
|
@ -25,155 +24,6 @@
|
|||
#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
|
||||
#define CCGR2 0x70
|
||||
#define CCGR3 0x74
|
||||
#define CCGR4 0x78
|
||||
#define CCGR5 0x7c
|
||||
#define CCGR6 0x80
|
||||
#define CCGR7 0x84
|
||||
|
||||
#define CLPCR 0x54
|
||||
#define BP_CLPCR_LPM 0
|
||||
#define BM_CLPCR_LPM (0x3 << 0)
|
||||
#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
|
||||
#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
|
||||
#define BM_CLPCR_SBYOS (0x1 << 6)
|
||||
#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
|
||||
#define BM_CLPCR_VSTBY (0x1 << 8)
|
||||
#define BP_CLPCR_STBY_COUNT 9
|
||||
#define BM_CLPCR_STBY_COUNT (0x3 << 9)
|
||||
#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
|
||||
#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
|
||||
#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
|
||||
#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
|
||||
#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
|
||||
#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
|
||||
#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
|
||||
#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
|
||||
#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
|
||||
#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
|
||||
#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
|
||||
|
||||
#define CGPR 0x64
|
||||
#define BM_CGPR_CHICKEN_BIT (0x1 << 17)
|
||||
|
||||
static void __iomem *ccm_base;
|
||||
|
||||
void imx6q_set_chicken_bit(void)
|
||||
{
|
||||
u32 val = readl_relaxed(ccm_base + CGPR);
|
||||
|
||||
val |= BM_CGPR_CHICKEN_BIT;
|
||||
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);
|
||||
|
||||
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;
|
||||
val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
|
||||
break;
|
||||
case STOP_POWER_ON:
|
||||
val |= 0x2 << BP_CLPCR_LPM;
|
||||
break;
|
||||
case WAIT_UNCLOCKED_POWER_OFF:
|
||||
val |= 0x1 << BP_CLPCR_LPM;
|
||||
val &= ~BM_CLPCR_VSTBY;
|
||||
val &= ~BM_CLPCR_SBYOS;
|
||||
break;
|
||||
case STOP_POWER_OFF:
|
||||
val |= 0x2 << BP_CLPCR_LPM;
|
||||
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;
|
||||
}
|
||||
|
||||
writel_relaxed(val, ccm_base + CLPCR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
|
||||
static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
|
||||
static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
|
||||
|
@ -182,7 +32,7 @@ static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
|
|||
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", "periph", "pll3_pfd1_540m", };
|
||||
static const char *audio_sels[] = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
|
||||
static const char *audio_sels[] = { "pll4_audio_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", };
|
||||
|
@ -196,7 +46,7 @@ static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di
|
|||
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_post_div", };
|
||||
static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_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[] = { "pll2_pfd2_396m", "pll3_usb_otg", "axi", "pll2_pfd0_352m", };
|
||||
|
@ -205,7 +55,7 @@ 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_div",
|
||||
"dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
|
||||
"ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_post_div", };
|
||||
"ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio_div", };
|
||||
static const char *cko2_sels[] = {
|
||||
"mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1",
|
||||
"gpu2d_axi", "dummy", "ecspi_root", "gpu3d_axi",
|
||||
|
@ -217,6 +67,11 @@ static const char *cko2_sels[] = {
|
|||
"uart_serial", "spdif", "asrc", "hsi_tx",
|
||||
};
|
||||
static const char *cko_sels[] = { "cko1", "cko2", };
|
||||
static const char *lvds_sels[] = {
|
||||
"dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
|
||||
"pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
|
||||
"pcie_ref", "sata_ref",
|
||||
};
|
||||
|
||||
enum mx6q_clks {
|
||||
dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m,
|
||||
|
@ -251,7 +106,8 @@ enum mx6q_clks {
|
|||
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, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow,
|
||||
spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, clk_max
|
||||
spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, pll4_audio_div,
|
||||
lvds1_sel, lvds2_sel, lvds1_gate, lvds2_gate, clk_max
|
||||
};
|
||||
|
||||
static struct clk *clk[clk_max];
|
||||
|
@ -300,7 +156,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
|||
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) {
|
||||
if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) {
|
||||
post_div_table[1].div = 1;
|
||||
post_div_table[2].div = 1;
|
||||
video_div_table[1].div = 1;
|
||||
|
@ -342,6 +198,18 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
|||
base + 0xe0, 0, 2, 0, clk_enet_ref_table,
|
||||
&imx_ccm_lock);
|
||||
|
||||
clk[lvds1_sel] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
|
||||
clk[lvds2_sel] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
|
||||
|
||||
/*
|
||||
* lvds1_gate and lvds2_gate are pseudo-gates. Both can be
|
||||
* independently configured as clock inputs or outputs. We treat
|
||||
* the "output_enable" bit as a gate, even though it's really just
|
||||
* enabling clock output.
|
||||
*/
|
||||
clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "dummy", base + 0x160, 10);
|
||||
clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "dummy", base + 0x160, 11);
|
||||
|
||||
/* name parent_name reg idx */
|
||||
clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
|
||||
clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
|
||||
|
@ -359,13 +227,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
|||
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[pll4_audio_div] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &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 = ccm_node;
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
ccm_base = base;
|
||||
|
||||
imx6q_pm_set_ccm_base(base);
|
||||
|
||||
/* name reg shift width parent_names num_parents */
|
||||
clk[step] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
|
||||
|
@ -573,7 +443,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
|||
clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL);
|
||||
clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL);
|
||||
|
||||
if ((imx6q_revision() != IMX_CHIP_REVISION_1_0) || cpu_is_imx6dl()) {
|
||||
if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
|
||||
cpu_is_imx6dl()) {
|
||||
clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
|
||||
clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
|
||||
}
|
||||
|
@ -603,8 +474,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
|||
if (ret)
|
||||
pr_warn("failed to set up CLKO: %d\n", ret);
|
||||
|
||||
/* Set initial power mode */
|
||||
imx6q_set_lpm(WAIT_CLOCKED);
|
||||
/* All existing boards with PCIe use LVDS1 */
|
||||
if (IS_ENABLED(CONFIG_PCI_IMX6))
|
||||
clk_set_parent(clk[lvds1_sel], clk[sata_ref]);
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
|
||||
base = of_iomap(np, 0);
|
||||
|
|
|
@ -127,6 +127,9 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
|
|||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
|
||||
/* Reuse imx6q pm code */
|
||||
imx6q_pm_set_ccm_base(base);
|
||||
|
||||
/* name reg shift width parent_names num_parents */
|
||||
clks[IMX6SL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
|
||||
clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
|
||||
|
|
|
@ -13,70 +13,73 @@
|
|||
|
||||
#include <linux/reboot.h>
|
||||
|
||||
struct irq_data;
|
||||
struct platform_device;
|
||||
struct pt_regs;
|
||||
struct clk;
|
||||
enum mxc_cpu_pwr_mode;
|
||||
|
||||
extern void mx1_map_io(void);
|
||||
extern void mx21_map_io(void);
|
||||
extern void mx25_map_io(void);
|
||||
extern void mx27_map_io(void);
|
||||
extern void mx31_map_io(void);
|
||||
extern void mx35_map_io(void);
|
||||
extern void mx51_map_io(void);
|
||||
extern void mx53_map_io(void);
|
||||
extern void imx1_init_early(void);
|
||||
extern void imx21_init_early(void);
|
||||
extern void imx25_init_early(void);
|
||||
extern void imx27_init_early(void);
|
||||
extern void imx31_init_early(void);
|
||||
extern void imx35_init_early(void);
|
||||
extern void imx51_init_early(void);
|
||||
extern void imx53_init_early(void);
|
||||
extern void mxc_init_irq(void __iomem *);
|
||||
extern void tzic_init_irq(void __iomem *);
|
||||
extern void mx1_init_irq(void);
|
||||
extern void mx21_init_irq(void);
|
||||
extern void mx25_init_irq(void);
|
||||
extern void mx27_init_irq(void);
|
||||
extern void mx31_init_irq(void);
|
||||
extern void mx35_init_irq(void);
|
||||
extern void mx51_init_irq(void);
|
||||
extern void mx53_init_irq(void);
|
||||
extern void imx1_soc_init(void);
|
||||
extern void imx21_soc_init(void);
|
||||
extern void imx25_soc_init(void);
|
||||
extern void imx27_soc_init(void);
|
||||
extern void imx31_soc_init(void);
|
||||
extern void imx35_soc_init(void);
|
||||
extern void imx51_soc_init(void);
|
||||
extern void imx51_init_late(void);
|
||||
extern void imx53_init_late(void);
|
||||
extern void epit_timer_init(void __iomem *base, int irq);
|
||||
extern void mxc_timer_init(void __iomem *, int);
|
||||
extern int mx1_clocks_init(unsigned long fref);
|
||||
extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
|
||||
extern int mx25_clocks_init(void);
|
||||
extern int mx27_clocks_init(unsigned long fref);
|
||||
extern int mx31_clocks_init(unsigned long fref);
|
||||
extern int mx35_clocks_init(void);
|
||||
extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
|
||||
void mx1_map_io(void);
|
||||
void mx21_map_io(void);
|
||||
void mx25_map_io(void);
|
||||
void mx27_map_io(void);
|
||||
void mx31_map_io(void);
|
||||
void mx35_map_io(void);
|
||||
void mx51_map_io(void);
|
||||
void mx53_map_io(void);
|
||||
void imx1_init_early(void);
|
||||
void imx21_init_early(void);
|
||||
void imx25_init_early(void);
|
||||
void imx27_init_early(void);
|
||||
void imx31_init_early(void);
|
||||
void imx35_init_early(void);
|
||||
void imx51_init_early(void);
|
||||
void imx53_init_early(void);
|
||||
void mxc_init_irq(void __iomem *);
|
||||
void tzic_init_irq(void __iomem *);
|
||||
void mx1_init_irq(void);
|
||||
void mx21_init_irq(void);
|
||||
void mx25_init_irq(void);
|
||||
void mx27_init_irq(void);
|
||||
void mx31_init_irq(void);
|
||||
void mx35_init_irq(void);
|
||||
void mx51_init_irq(void);
|
||||
void mx53_init_irq(void);
|
||||
void imx1_soc_init(void);
|
||||
void imx21_soc_init(void);
|
||||
void imx25_soc_init(void);
|
||||
void imx27_soc_init(void);
|
||||
void imx31_soc_init(void);
|
||||
void imx35_soc_init(void);
|
||||
void imx51_soc_init(void);
|
||||
void imx51_init_late(void);
|
||||
void imx53_init_late(void);
|
||||
void epit_timer_init(void __iomem *base, int irq);
|
||||
void mxc_timer_init(void __iomem *, int);
|
||||
int mx1_clocks_init(unsigned long fref);
|
||||
int mx21_clocks_init(unsigned long lref, unsigned long fref);
|
||||
int mx25_clocks_init(void);
|
||||
int mx27_clocks_init(unsigned long fref);
|
||||
int mx31_clocks_init(unsigned long fref);
|
||||
int mx35_clocks_init(void);
|
||||
int mx51_clocks_init(unsigned long ckil, unsigned long osc,
|
||||
unsigned long ckih1, unsigned long ckih2);
|
||||
extern int mx25_clocks_init_dt(void);
|
||||
extern int mx27_clocks_init_dt(void);
|
||||
extern int mx31_clocks_init_dt(void);
|
||||
extern struct platform_device *mxc_register_gpio(char *name, int id,
|
||||
int mx25_clocks_init_dt(void);
|
||||
int mx27_clocks_init_dt(void);
|
||||
int mx31_clocks_init_dt(void);
|
||||
struct platform_device *mxc_register_gpio(char *name, int id,
|
||||
resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
|
||||
extern void mxc_set_cpu_type(unsigned int type);
|
||||
extern void mxc_restart(enum reboot_mode, const char *);
|
||||
extern void mxc_arch_reset_init(void __iomem *);
|
||||
extern void mxc_arch_reset_init_dt(void);
|
||||
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);
|
||||
void mxc_set_cpu_type(unsigned int type);
|
||||
void mxc_restart(enum reboot_mode, const char *);
|
||||
void mxc_arch_reset_init(void __iomem *);
|
||||
void mxc_arch_reset_init_dt(void);
|
||||
int mx53_revision(void);
|
||||
void imx_set_aips(void __iomem *);
|
||||
int mxc_device_init(void);
|
||||
void imx_set_soc_revision(unsigned int rev);
|
||||
unsigned int imx_get_soc_revision(void);
|
||||
void imx_init_revision_from_anatop(void);
|
||||
struct device *imx_soc_device_init(void);
|
||||
|
||||
enum mxc_cpu_pwr_mode {
|
||||
WAIT_CLOCKED, /* wfi only */
|
||||
|
@ -93,8 +96,8 @@ enum mx3_cpu_pwr_mode {
|
|||
MX3_SLEEP,
|
||||
};
|
||||
|
||||
extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
|
||||
extern void imx_print_silicon_rev(const char *cpu, int srev);
|
||||
void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
|
||||
void imx_print_silicon_rev(const char *cpu, int srev);
|
||||
|
||||
void avic_handle_irq(struct pt_regs *);
|
||||
void tzic_handle_irq(struct pt_regs *);
|
||||
|
@ -108,54 +111,61 @@ void tzic_handle_irq(struct pt_regs *);
|
|||
#define imx51_handle_irq tzic_handle_irq
|
||||
#define imx53_handle_irq tzic_handle_irq
|
||||
|
||||
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);
|
||||
void imx_enable_cpu(int cpu, bool enable);
|
||||
void imx_set_cpu_jump(int cpu, void *jump_addr);
|
||||
u32 imx_get_cpu_arg(int cpu);
|
||||
void imx_set_cpu_arg(int cpu, u32 arg);
|
||||
void v7_cpu_resume(void);
|
||||
#ifdef CONFIG_SMP
|
||||
extern void v7_secondary_startup(void);
|
||||
extern void imx_scu_map_io(void);
|
||||
extern void imx_smp_prepare(void);
|
||||
extern void imx_scu_standby_enable(void);
|
||||
void v7_secondary_startup(void);
|
||||
void imx_scu_map_io(void);
|
||||
void imx_smp_prepare(void);
|
||||
void imx_scu_standby_enable(void);
|
||||
#else
|
||||
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_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 u32 imx_anatop_get_digprog(void);
|
||||
extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
|
||||
extern void imx6q_set_chicken_bit(void);
|
||||
void imx_src_init(void);
|
||||
#ifdef CONFIG_HAVE_IMX_SRC
|
||||
void imx_src_prepare_restart(void);
|
||||
#else
|
||||
static inline void imx_src_prepare_restart(void) {}
|
||||
#endif
|
||||
void imx_gpc_init(void);
|
||||
void imx_gpc_pre_suspend(void);
|
||||
void imx_gpc_post_resume(void);
|
||||
void imx_gpc_mask_all(void);
|
||||
void imx_gpc_restore_all(void);
|
||||
void imx_gpc_irq_mask(struct irq_data *d);
|
||||
void imx_gpc_irq_unmask(struct irq_data *d);
|
||||
void imx_anatop_init(void);
|
||||
void imx_anatop_pre_suspend(void);
|
||||
void imx_anatop_post_resume(void);
|
||||
int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
|
||||
void imx6q_set_chicken_bit(void);
|
||||
|
||||
extern void imx_cpu_die(unsigned int cpu);
|
||||
extern int imx_cpu_kill(unsigned int cpu);
|
||||
void imx_cpu_die(unsigned int cpu);
|
||||
int imx_cpu_kill(unsigned int cpu);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
extern void imx6q_pm_init(void);
|
||||
extern void imx5_pm_init(void);
|
||||
void imx6q_pm_init(void);
|
||||
void imx6q_pm_set_ccm_base(void __iomem *base);
|
||||
void imx5_pm_init(void);
|
||||
#else
|
||||
static inline void imx6q_pm_init(void) {}
|
||||
static inline void imx6q_pm_set_ccm_base(void __iomem *base) {}
|
||||
static inline void imx5_pm_init(void) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NEON
|
||||
extern int mx51_neon_fixup(void);
|
||||
int mx51_neon_fixup(void);
|
||||
#else
|
||||
static inline int mx51_neon_fixup(void) { return 0; }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CACHE_L2X0
|
||||
extern void imx_init_l2cache(void);
|
||||
void imx_init_l2cache(void);
|
||||
#else
|
||||
static inline void imx_init_l2cache(void) {}
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sys_soc.h>
|
||||
|
||||
#include "hardware.h"
|
||||
#include "common.h"
|
||||
|
@ -8,11 +11,23 @@
|
|||
unsigned int __mxc_cpu_type;
|
||||
EXPORT_SYMBOL(__mxc_cpu_type);
|
||||
|
||||
static unsigned int imx_soc_revision;
|
||||
|
||||
void mxc_set_cpu_type(unsigned int type)
|
||||
{
|
||||
__mxc_cpu_type = type;
|
||||
}
|
||||
|
||||
void imx_set_soc_revision(unsigned int rev)
|
||||
{
|
||||
imx_soc_revision = rev;
|
||||
}
|
||||
|
||||
unsigned int imx_get_soc_revision(void)
|
||||
{
|
||||
return imx_soc_revision;
|
||||
}
|
||||
|
||||
void imx_print_silicon_rev(const char *cpu, int srev)
|
||||
{
|
||||
if (srev == IMX_CHIP_REVISION_UNKNOWN)
|
||||
|
@ -44,3 +59,81 @@ void __init imx_set_aips(void __iomem *base)
|
|||
reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
|
||||
__raw_writel(reg, base + 0x50);
|
||||
}
|
||||
|
||||
struct device * __init imx_soc_device_init(void)
|
||||
{
|
||||
struct soc_device_attribute *soc_dev_attr;
|
||||
struct soc_device *soc_dev;
|
||||
struct device_node *root;
|
||||
const char *soc_id;
|
||||
int ret;
|
||||
|
||||
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
|
||||
if (!soc_dev_attr)
|
||||
return NULL;
|
||||
|
||||
soc_dev_attr->family = "Freescale i.MX";
|
||||
|
||||
root = of_find_node_by_path("/");
|
||||
ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
|
||||
of_node_put(root);
|
||||
if (ret)
|
||||
goto free_soc;
|
||||
|
||||
switch (__mxc_cpu_type) {
|
||||
case MXC_CPU_MX1:
|
||||
soc_id = "i.MX1";
|
||||
break;
|
||||
case MXC_CPU_MX21:
|
||||
soc_id = "i.MX21";
|
||||
break;
|
||||
case MXC_CPU_MX25:
|
||||
soc_id = "i.MX25";
|
||||
break;
|
||||
case MXC_CPU_MX27:
|
||||
soc_id = "i.MX27";
|
||||
break;
|
||||
case MXC_CPU_MX31:
|
||||
soc_id = "i.MX31";
|
||||
break;
|
||||
case MXC_CPU_MX35:
|
||||
soc_id = "i.MX35";
|
||||
break;
|
||||
case MXC_CPU_MX51:
|
||||
soc_id = "i.MX51";
|
||||
break;
|
||||
case MXC_CPU_MX53:
|
||||
soc_id = "i.MX53";
|
||||
break;
|
||||
case MXC_CPU_IMX6SL:
|
||||
soc_id = "i.MX6SL";
|
||||
break;
|
||||
case MXC_CPU_IMX6DL:
|
||||
soc_id = "i.MX6DL";
|
||||
break;
|
||||
case MXC_CPU_IMX6Q:
|
||||
soc_id = "i.MX6Q";
|
||||
break;
|
||||
default:
|
||||
soc_id = "Unknown";
|
||||
}
|
||||
soc_dev_attr->soc_id = soc_id;
|
||||
|
||||
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d.%d",
|
||||
(imx_soc_revision >> 4) & 0xf,
|
||||
imx_soc_revision & 0xf);
|
||||
if (!soc_dev_attr->revision)
|
||||
goto free_soc;
|
||||
|
||||
soc_dev = soc_device_register(soc_dev_attr);
|
||||
if (IS_ERR(soc_dev))
|
||||
goto free_rev;
|
||||
|
||||
return soc_device_to_device(soc_dev);
|
||||
|
||||
free_rev:
|
||||
kfree(soc_dev_attr->revision);
|
||||
free_soc:
|
||||
kfree(soc_dev_attr);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
|
|||
|
||||
static struct irqaction epit_timer_irq = {
|
||||
.name = "i.MX EPIT Timer Tick",
|
||||
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.handler = epit_timer_interrupt,
|
||||
};
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ void imx_gpc_restore_all(void)
|
|||
writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
|
||||
}
|
||||
|
||||
static void imx_gpc_irq_unmask(struct irq_data *d)
|
||||
void imx_gpc_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
|
@ -105,7 +105,7 @@ static void imx_gpc_irq_unmask(struct irq_data *d)
|
|||
writel_relaxed(val, reg);
|
||||
}
|
||||
|
||||
static void imx_gpc_irq_mask(struct irq_data *d)
|
||||
void imx_gpc_irq_mask(struct irq_data *d)
|
||||
{
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
|
|
|
@ -52,7 +52,9 @@ void imx_cpu_die(unsigned int cpu)
|
|||
* the register being cleared to kill the cpu.
|
||||
*/
|
||||
imx_set_cpu_arg(cpu, ~0);
|
||||
cpu_do_idle();
|
||||
|
||||
while (1)
|
||||
cpu_do_idle();
|
||||
}
|
||||
|
||||
int imx_cpu_kill(unsigned int cpu)
|
||||
|
|
|
@ -404,8 +404,7 @@ static int armadillo5x0_sdhc1_init(struct device *dev,
|
|||
|
||||
/* When supported the trigger type have to be BOTH */
|
||||
ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK)),
|
||||
detect_irq,
|
||||
IRQF_DISABLED | IRQF_TRIGGER_FALLING,
|
||||
detect_irq, IRQF_TRIGGER_FALLING,
|
||||
"sdhc-detect", data);
|
||||
|
||||
if (ret)
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -38,64 +37,6 @@
|
|||
#include "cpuidle.h"
|
||||
#include "hardware.h"
|
||||
|
||||
static u32 chip_revision;
|
||||
|
||||
int imx6q_revision(void)
|
||||
{
|
||||
return chip_revision;
|
||||
}
|
||||
|
||||
static void __init imx6q_init_revision(void)
|
||||
{
|
||||
u32 rev = imx_anatop_get_digprog();
|
||||
|
||||
switch (rev & 0xff) {
|
||||
case 0:
|
||||
chip_revision = IMX_CHIP_REVISION_1_0;
|
||||
break;
|
||||
case 1:
|
||||
chip_revision = IMX_CHIP_REVISION_1_1;
|
||||
break;
|
||||
case 2:
|
||||
chip_revision = IMX_CHIP_REVISION_1_2;
|
||||
break;
|
||||
default:
|
||||
chip_revision = IMX_CHIP_REVISION_UNKNOWN;
|
||||
}
|
||||
|
||||
mxc_set_cpu_type(rev >> 16 & 0xff);
|
||||
}
|
||||
|
||||
static void imx6q_restart(enum reboot_mode mode, const char *cmd)
|
||||
{
|
||||
struct device_node *np;
|
||||
void __iomem *wdog_base;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-wdt");
|
||||
wdog_base = of_iomap(np, 0);
|
||||
if (!wdog_base)
|
||||
goto soft;
|
||||
|
||||
imx_src_prepare_restart();
|
||||
|
||||
/* enable wdog */
|
||||
writew_relaxed(1 << 2, wdog_base);
|
||||
/* write twice to ensure the request will not get ignored */
|
||||
writew_relaxed(1 << 2, wdog_base);
|
||||
|
||||
/* wait for reset to assert ... */
|
||||
mdelay(500);
|
||||
|
||||
pr_err("Watchdog reset failed to assert reset\n");
|
||||
|
||||
/* delay to allow the serial port to show the message */
|
||||
mdelay(50);
|
||||
|
||||
soft:
|
||||
/* we'll take a jump through zero as a poor second */
|
||||
soft_restart(0);
|
||||
}
|
||||
|
||||
/* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */
|
||||
static int ksz9021rn_phy_fixup(struct phy_device *phydev)
|
||||
{
|
||||
|
@ -190,12 +131,20 @@ static void __init imx6q_1588_init(void)
|
|||
|
||||
static void __init imx6q_init_machine(void)
|
||||
{
|
||||
struct device *parent;
|
||||
|
||||
imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
|
||||
imx6q_revision());
|
||||
imx_get_soc_revision());
|
||||
|
||||
mxc_arch_reset_init_dt();
|
||||
|
||||
parent = imx_soc_device_init();
|
||||
if (parent == NULL)
|
||||
pr_warn("failed to initialize soc device\n");
|
||||
|
||||
imx6q_enet_phy_init();
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
|
||||
|
||||
imx_anatop_init();
|
||||
imx6q_pm_init();
|
||||
|
@ -270,7 +219,7 @@ static void __init imx6q_init_late(void)
|
|||
* WAIT mode is broken on TO 1.0 and 1.1, so there is no point
|
||||
* to run cpuidle on them.
|
||||
*/
|
||||
if (imx6q_revision() > IMX_CHIP_REVISION_1_1)
|
||||
if (imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
|
||||
imx6q_cpuidle_init();
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
|
||||
|
@ -287,7 +236,7 @@ static void __init imx6q_map_io(void)
|
|||
|
||||
static void __init imx6q_init_irq(void)
|
||||
{
|
||||
imx6q_init_revision();
|
||||
imx_init_revision_from_anatop();
|
||||
imx_init_l2cache();
|
||||
imx_src_init();
|
||||
imx_gpc_init();
|
||||
|
@ -307,5 +256,5 @@ DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
|
|||
.init_machine = imx6q_init_machine,
|
||||
.init_late = imx6q_init_late,
|
||||
.dt_compat = imx6q_dt_compat,
|
||||
.restart = imx6q_restart,
|
||||
.restart = mxc_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -10,20 +10,51 @@
|
|||
#include <linux/irqchip.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static void __init imx6sl_fec_init(void)
|
||||
{
|
||||
struct regmap *gpr;
|
||||
|
||||
/* set FEC clock from internal PLL clock source */
|
||||
gpr = syscon_regmap_lookup_by_compatible("fsl,imx6sl-iomuxc-gpr");
|
||||
if (!IS_ERR(gpr)) {
|
||||
regmap_update_bits(gpr, IOMUXC_GPR1,
|
||||
IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK, 0);
|
||||
regmap_update_bits(gpr, IOMUXC_GPR1,
|
||||
IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK, 0);
|
||||
} else {
|
||||
pr_err("failed to find fsl,imx6sl-iomux-gpr regmap\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void __init imx6sl_init_machine(void)
|
||||
{
|
||||
struct device *parent;
|
||||
|
||||
mxc_arch_reset_init_dt();
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
parent = imx_soc_device_init();
|
||||
if (parent == NULL)
|
||||
pr_warn("failed to initialize soc device\n");
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
|
||||
|
||||
imx6sl_fec_init();
|
||||
imx_anatop_init();
|
||||
/* Reuse imx6q pm code */
|
||||
imx6q_pm_init();
|
||||
}
|
||||
|
||||
static void __init imx6sl_init_irq(void)
|
||||
{
|
||||
imx_init_revision_from_anatop();
|
||||
imx_init_l2cache();
|
||||
imx_src_init();
|
||||
imx_gpc_init();
|
||||
|
|
|
@ -311,7 +311,7 @@ static int mx31_3ds_sdhc1_init(struct device *dev,
|
|||
}
|
||||
|
||||
ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)),
|
||||
detect_irq, IRQF_DISABLED |
|
||||
detect_irq,
|
||||
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
|
||||
"sdhc1-detect", data);
|
||||
if (ret) {
|
||||
|
|
|
@ -371,8 +371,7 @@ static int pcm970_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
|
|||
#endif
|
||||
|
||||
ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SCK6)), detect_irq,
|
||||
IRQF_DISABLED | IRQF_TRIGGER_FALLING,
|
||||
"sdhc-detect", data);
|
||||
IRQF_TRIGGER_FALLING, "sdhc-detect", data);
|
||||
if (ret)
|
||||
goto err_gpio_free_2;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
|
@ -88,8 +89,15 @@ void __init imx51_init_early(void)
|
|||
|
||||
void __init imx53_init_early(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
void __iomem *base;
|
||||
|
||||
mxc_set_cpu_type(MXC_CPU_MX53);
|
||||
mxc_iomux_v3_init(MX53_IO_ADDRESS(MX53_IOMUXC_BASE_ADDR));
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx53-iomuxc");
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
mxc_iomux_v3_init(base);
|
||||
imx_src_init();
|
||||
}
|
||||
|
||||
|
@ -100,7 +108,14 @@ void __init mx51_init_irq(void)
|
|||
|
||||
void __init mx53_init_irq(void)
|
||||
{
|
||||
tzic_init_irq(MX53_IO_ADDRESS(MX53_TZIC_BASE_ADDR));
|
||||
struct device_node *np;
|
||||
void __iomem *base;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx53-tzic");
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
|
||||
tzic_init_irq(base);
|
||||
}
|
||||
|
||||
static struct sdma_platform_data imx51_sdma_pdata __initdata = {
|
||||
|
|
|
@ -130,8 +130,7 @@ static int mxc_mmc1_init(struct device *dev,
|
|||
gpio_direction_input(gpio_wp);
|
||||
|
||||
ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)),
|
||||
detect_irq,
|
||||
IRQF_DISABLED | IRQF_TRIGGER_FALLING,
|
||||
detect_irq, IRQF_TRIGGER_FALLING,
|
||||
"MMC detect", data);
|
||||
if (ret)
|
||||
goto exit_free_wp;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#define MXC_CPU_MX35 35
|
||||
#define MXC_CPU_MX51 51
|
||||
#define MXC_CPU_MX53 53
|
||||
#define MXC_CPU_IMX6SL 0x60
|
||||
#define MXC_CPU_IMX6DL 0x61
|
||||
#define MXC_CPU_IMX6Q 0x63
|
||||
|
||||
|
@ -152,6 +153,11 @@ extern unsigned int __mxc_cpu_type;
|
|||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
static inline bool cpu_is_imx6sl(void)
|
||||
{
|
||||
return __mxc_cpu_type == MXC_CPU_IMX6SL;
|
||||
}
|
||||
|
||||
static inline bool cpu_is_imx6dl(void)
|
||||
{
|
||||
return __mxc_cpu_type == MXC_CPU_IMX6DL;
|
||||
|
|
|
@ -10,9 +10,15 @@
|
|||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/proc-fns.h>
|
||||
|
@ -22,6 +28,147 @@
|
|||
#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 CLPCR 0x54
|
||||
#define BP_CLPCR_LPM 0
|
||||
#define BM_CLPCR_LPM (0x3 << 0)
|
||||
#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
|
||||
#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
|
||||
#define BM_CLPCR_SBYOS (0x1 << 6)
|
||||
#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
|
||||
#define BM_CLPCR_VSTBY (0x1 << 8)
|
||||
#define BP_CLPCR_STBY_COUNT 9
|
||||
#define BM_CLPCR_STBY_COUNT (0x3 << 9)
|
||||
#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
|
||||
#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
|
||||
#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
|
||||
#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
|
||||
#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
|
||||
#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
|
||||
#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
|
||||
#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
|
||||
#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
|
||||
#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
|
||||
#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
|
||||
|
||||
#define CGPR 0x64
|
||||
#define BM_CGPR_CHICKEN_BIT (0x1 << 17)
|
||||
|
||||
static void __iomem *ccm_base;
|
||||
|
||||
void imx6q_set_chicken_bit(void)
|
||||
{
|
||||
u32 val = readl_relaxed(ccm_base + CGPR);
|
||||
|
||||
val |= BM_CGPR_CHICKEN_BIT;
|
||||
writel_relaxed(val, ccm_base + CGPR);
|
||||
}
|
||||
|
||||
static void imx6q_enable_rbc(bool enable)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
|
||||
static void imx6q_enable_wb(bool enable)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
|
||||
{
|
||||
struct irq_desc *iomuxc_irq_desc;
|
||||
u32 val = readl_relaxed(ccm_base + CLPCR);
|
||||
|
||||
val &= ~BM_CLPCR_LPM;
|
||||
switch (mode) {
|
||||
case WAIT_CLOCKED:
|
||||
break;
|
||||
case WAIT_UNCLOCKED:
|
||||
val |= 0x1 << BP_CLPCR_LPM;
|
||||
val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
|
||||
break;
|
||||
case STOP_POWER_ON:
|
||||
val |= 0x2 << BP_CLPCR_LPM;
|
||||
break;
|
||||
case WAIT_UNCLOCKED_POWER_OFF:
|
||||
val |= 0x1 << BP_CLPCR_LPM;
|
||||
val &= ~BM_CLPCR_VSTBY;
|
||||
val &= ~BM_CLPCR_SBYOS;
|
||||
break;
|
||||
case STOP_POWER_OFF:
|
||||
val |= 0x2 << BP_CLPCR_LPM;
|
||||
val |= 0x3 << BP_CLPCR_STBY_COUNT;
|
||||
val |= BM_CLPCR_VSTBY;
|
||||
val |= BM_CLPCR_SBYOS;
|
||||
if (cpu_is_imx6sl()) {
|
||||
val |= BM_CLPCR_BYPASS_PMIC_READY;
|
||||
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
|
||||
} else {
|
||||
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unmask the always pending IOMUXC interrupt #32 as wakeup source to
|
||||
* deassert dsm_request signal, so that we can ensure dsm_request
|
||||
* is not asserted when we're going to write CLPCR register to set LPM.
|
||||
* After setting up LPM bits, we need to mask this wakeup source.
|
||||
*/
|
||||
iomuxc_irq_desc = irq_to_desc(32);
|
||||
imx_gpc_irq_unmask(&iomuxc_irq_desc->irq_data);
|
||||
writel_relaxed(val, ccm_base + CLPCR);
|
||||
imx_gpc_irq_mask(&iomuxc_irq_desc->irq_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx6q_suspend_finish(unsigned long val)
|
||||
{
|
||||
cpu_do_idle();
|
||||
|
@ -33,14 +180,19 @@ static int imx6q_pm_enter(suspend_state_t state)
|
|||
switch (state) {
|
||||
case PM_SUSPEND_MEM:
|
||||
imx6q_set_lpm(STOP_POWER_OFF);
|
||||
imx6q_enable_wb(true);
|
||||
imx6q_enable_rbc(true);
|
||||
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();
|
||||
if (cpu_is_imx6q() || cpu_is_imx6dl())
|
||||
imx_smp_prepare();
|
||||
imx_anatop_post_resume();
|
||||
imx_gpc_post_resume();
|
||||
imx6q_enable_rbc(false);
|
||||
imx6q_enable_wb(false);
|
||||
imx6q_set_lpm(WAIT_CLOCKED);
|
||||
break;
|
||||
default:
|
||||
|
@ -55,7 +207,29 @@ static const struct platform_suspend_ops imx6q_pm_ops = {
|
|||
.valid = suspend_valid_only_mem,
|
||||
};
|
||||
|
||||
void __init imx6q_pm_set_ccm_base(void __iomem *base)
|
||||
{
|
||||
ccm_base = base;
|
||||
}
|
||||
|
||||
void __init imx6q_pm_init(void)
|
||||
{
|
||||
struct regmap *gpr;
|
||||
|
||||
WARN_ON(!ccm_base);
|
||||
|
||||
/*
|
||||
* Force IOMUXC irq pending, so that the interrupt to GPC can be
|
||||
* used to deassert dsm_request signal when the signal gets
|
||||
* asserted unexpectedly.
|
||||
*/
|
||||
gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
|
||||
if (!IS_ERR(gpr))
|
||||
regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT,
|
||||
IMX6Q_GPR1_GINT);
|
||||
|
||||
/* Set initial power mode */
|
||||
imx6q_set_lpm(WAIT_CLOCKED);
|
||||
|
||||
suspend_set_ops(&imx6q_pm_ops);
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ void imx_enable_cpu(int cpu, bool enable)
|
|||
spin_lock(&scr_lock);
|
||||
val = readl_relaxed(src_base + SRC_SCR);
|
||||
val = enable ? val | mask : val & ~mask;
|
||||
val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1);
|
||||
writel_relaxed(val, src_base + SRC_SCR);
|
||||
spin_unlock(&scr_lock);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,9 @@ void mxc_restart(enum reboot_mode mode, const char *cmd)
|
|||
{
|
||||
unsigned int wcr_enable;
|
||||
|
||||
if (cpu_is_imx6q() || cpu_is_imx6dl())
|
||||
imx_src_prepare_restart();
|
||||
|
||||
if (wdog_clk)
|
||||
clk_enable(wdog_clk);
|
||||
|
||||
|
@ -52,6 +55,8 @@ void mxc_restart(enum reboot_mode mode, const char *cmd)
|
|||
|
||||
/* Assert SRS signal */
|
||||
__raw_writew(wcr_enable, wdog_base);
|
||||
/* write twice to ensure the request will not get ignored */
|
||||
__raw_writew(wcr_enable, wdog_base);
|
||||
|
||||
/* wait for reset to assert... */
|
||||
mdelay(500);
|
||||
|
|
|
@ -250,7 +250,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
|
|||
|
||||
static struct irqaction mxc_timer_irq = {
|
||||
.name = "i.MX Timer Tick",
|
||||
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.handler = mxc_timer_interrupt,
|
||||
};
|
||||
|
||||
|
|
|
@ -363,4 +363,9 @@
|
|||
#define IMX6Q_GPR13_SATA_TX_LVL_1_240_V (0x1f << 2)
|
||||
#define IMX6Q_GPR13_SATA_MPLL_CLK_EN BIT(1)
|
||||
#define IMX6Q_GPR13_SATA_TX_EDGE_RATE BIT(0)
|
||||
|
||||
/* For imx6sl iomux gpr register field define */
|
||||
#define IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK (0x3 << 17)
|
||||
#define IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK (0x1 << 14)
|
||||
|
||||
#endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */
|
||||
|
|
Загрузка…
Ссылка в новой задаче