From 0dbe59545a8b2b86d7d0a966b28e4e7f99cef426 Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Sat, 11 Aug 2012 16:36:35 +0800 Subject: ENGR00220153 cpufreq mx6: new cpu set point and add VDDSOC/PU adjust 1.add new cpu setpoint: replace 498Mhz with 672Mhz,and remove 198Mhz. but now 498Mhz seems not stable enough, comment now, test enough to add it. Rigel kept unchange now. 2.support adjusting VDDSOC/VDDPU when cpu frequency change. Signed-off-by: Robin Gong --- arch/arm/mach-mx6/board-mx6q_arm2.c | 6 ++ arch/arm/mach-mx6/board-mx6q_sabreauto.c | 8 ++ arch/arm/mach-mx6/board-mx6q_sabrelite.c | 6 ++ arch/arm/mach-mx6/board-mx6q_sabresd.c | 6 ++ arch/arm/mach-mx6/board-mx6sl_arm2.c | 15 +++- arch/arm/mach-mx6/clock.c | 5 ++ arch/arm/mach-mx6/clock_mx6sl.c | 5 ++ arch/arm/mach-mx6/cpu_op-mx6.c | 121 ++++++++++++++++++++----------- arch/arm/mach-mx6/cpu_regulator-mx6.c | 12 ++- 9 files changed, 138 insertions(+), 46 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c index 5ed27159a842..4b0d5c26de67 100644 --- a/arch/arm/mach-mx6/board-mx6q_arm2.c +++ b/arch/arm/mach-mx6/board-mx6q_arm2.c @@ -169,6 +169,8 @@ static int disable_mipi_dsi; extern struct regulator *(*get_cpu_regulator)(void); extern void (*put_cpu_regulator)(void); extern char *gp_reg_id; +extern char *soc_reg_id; +extern char *pu_reg_id; extern int epdc_enabled; extern void mx6_cpu_regulator_init(void); static int max17135_regulator_init(struct max17135 *max17135); @@ -1881,6 +1883,8 @@ static struct mxc_mlb_platform_data mx6_arm2_mlb150_data = { static struct mxc_dvfs_platform_data arm2_dvfscore_data = { .reg_id = "cpu_vddgp", + .soc_id = "cpu_vddsoc", + .pu_id = "cpu_vddvpu", .clk1_id = "cpu_clk", .clk2_id = "gpc_dvfs_clk", .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET, @@ -2075,6 +2079,8 @@ static void __init mx6_arm2_init(void) */ gp_reg_id = arm2_dvfscore_data.reg_id; + soc_reg_id = arm2_dvfscore_data.soc_id; + pu_reg_id = arm2_dvfscore_data.pu_id; mx6_arm2_init_uart(); diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.c b/arch/arm/mach-mx6/board-mx6q_sabreauto.c index 3adf51f60c2f..eb9fb30d73af 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabreauto.c +++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c @@ -136,6 +136,10 @@ #define SABREAUTO_USB_OTG_PWR SABREAUTO_IO_EXP_GPIO3(1) #define BMCR_PDOWN 0x0800 /* PHY Powerdown */ +extern char *gp_reg_id; +extern char *soc_reg_id; +extern char *pu_reg_id; + static int mma8451_position = 3; static struct clk *sata_clk; static int mipi_sensor; @@ -1256,6 +1260,8 @@ static struct mxc_mlb_platform_data mx6_sabreauto_mlb150_data = { static struct mxc_dvfs_platform_data sabreauto_dvfscore_data = { .reg_id = "cpu_vddgp", + .soc_id = "cpu_vddsoc", + .pu_id = "cpu_vddvpu", .clk1_id = "cpu_clk", .clk2_id = "gpc_dvfs_clk", .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET, @@ -1479,6 +1485,8 @@ static void __init mx6_board_init(void) } gp_reg_id = sabreauto_dvfscore_data.reg_id; + soc_reg_id = sabreauto_dvfscore_data.soc_id; + pu_reg_id = sabreauto_dvfscore_data.pu_id; mx6q_sabreauto_init_uart(); imx6q_add_mipi_csi2(&mipi_csi2_pdata); if (cpu_is_mx6dl()) { diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c index 17a4cb1290b0..6f14aeaf6e6a 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabrelite.c +++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c @@ -101,6 +101,8 @@ void __init early_console_setup(unsigned long base, struct clk *clk); static struct clk *sata_clk; extern char *gp_reg_id; +extern char *soc_reg_id; +extern char *pu_reg_id; extern struct regulator *(*get_cpu_regulator)(void); extern void (*put_cpu_regulator)(void); @@ -1066,6 +1068,8 @@ static struct platform_pwm_backlight_data mx6_sabrelite_pwm_backlight_data = { static struct mxc_dvfs_platform_data sabrelite_dvfscore_data = { .reg_id = "cpu_vddgp", + .soc_id = "cpu_vddsoc", + .pu_id = "cpu_vddvpu", .clk1_id = "cpu_clk", .clk2_id = "gpc_dvfs_clk", .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET, @@ -1125,6 +1129,8 @@ static void __init mx6_sabrelite_board_init(void) #endif gp_reg_id = sabrelite_dvfscore_data.reg_id; + soc_reg_id = sabrelite_dvfscore_data.soc_id; + pu_reg_id = sabrelite_dvfscore_data.pu_id; mx6q_sabrelite_init_uart(); imx6q_add_mxc_hdmi_core(&hdmi_core_data); diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c index 47d0eecd58a7..480ef185c455 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabresd.c +++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c @@ -207,6 +207,8 @@ static int enable_lcd_ldb; extern char *gp_reg_id; +extern char *soc_reg_id; +extern char *pu_reg_id; extern int epdc_enabled; static int max17135_regulator_init(struct max17135 *max17135); @@ -1583,6 +1585,8 @@ static struct mxc_dvfs_platform_data sabresd_dvfscore_data = { .reg_id = "VDDCORE", #else .reg_id = "cpu_vddgp", + .soc_id = "cpu_vddsoc", + .pu_id = "cpu_vddvpu", #endif .clk1_id = "cpu_clk", .clk2_id = "gpc_dvfs_clk", @@ -1673,6 +1677,8 @@ static void __init mx6_sabresd_board_init(void) #endif gp_reg_id = sabresd_dvfscore_data.reg_id; + soc_reg_id = sabresd_dvfscore_data.soc_id; + pu_reg_id = sabresd_dvfscore_data.pu_id; mx6q_sabresd_init_uart(); /* diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c index 4e827ee97c09..0c5166627320 100755 --- a/arch/arm/mach-mx6/board-mx6sl_arm2.c +++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c @@ -133,6 +133,9 @@ static int spdc_sel; static int max17135_regulator_init(struct max17135 *max17135); struct clk *extern_audio_root; +extern char *gp_reg_id; +extern char *soc_reg_id; +extern char *pu_reg_id; extern int __init mx6sl_arm2_init_pfuze100(u32 int_gpio); enum sd_pad_mode { @@ -632,7 +635,13 @@ static struct i2c_board_info mxc_i2c2_board_info[] __initdata = { }; static struct mxc_dvfs_platform_data mx6sl_arm2_dvfscore_data = { + #ifdef CONFIG_MX6_INTER_LDO_BYPASS + .reg_id = "VDDCORE", + #else .reg_id = "cpu_vddgp", + .soc_id = "cpu_vddsoc", + .pu_id = "cpu_vddvpu", + #endif .clk1_id = "cpu_clk", .clk2_id = "gpc_dvfs_clk", .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET, @@ -1228,9 +1237,11 @@ static void __init mx6_arm2_init(void) elan_ts_init(); #ifdef CONFIG_MX6_INTER_LDO_BYPASS - gp_reg_id = "VDDCORE"; + gp_reg_id = mx6sl_arm2_dvfscore_data.reg_id; #else - gp_reg_id = "cpu_vddgp"; + gp_reg_id = mx6sl_arm2_dvfscore_data.reg_id; + soc_reg_id = mx6sl_arm2_dvfscore_data.soc_id; + pu_reg_id = mx6sl_arm2_dvfscore_data.pu_id; mx6_cpu_regulator_init(); #endif diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index 61cf37c9a4f8..5b74e2d25c01 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -1272,6 +1272,11 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) else pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk); } + if (cpu_op_tbl[i].cpu_podf) { + __raw_writel(cpu_op_tbl[i].cpu_podf, MXC_CCM_CACRR); + while (__raw_readl(MXC_CCM_CDHIPR)) + ; + } pll1_sys_main_clk.set_rate(&pll1_sys_main_clk, cpu_op_tbl[i].pll_rate); } /* Make sure pll1_sw_clk is from pll1_sys_main_clk */ diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index 887e6ad6fa96..6e0bcc479585 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -1159,6 +1159,11 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) else pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk); } + if (cpu_op_tbl[i].cpu_podf) { + __raw_writel(cpu_op_tbl[i].cpu_podf, MXC_CCM_CACRR); + while (__raw_readl(MXC_CCM_CDHIPR)) + ; + } pll1_sys_main_clk.set_rate(&pll1_sys_main_clk, cpu_op_tbl[i].pll_rate); } pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c index 6fe2fd8e7cbb..98181ceb3670 100644 --- a/arch/arm/mach-mx6/cpu_op-mx6.c +++ b/arch/arm/mach-mx6/cpu_op-mx6.c @@ -23,60 +23,68 @@ extern void (*set_num_cpu_op)(int num); extern u32 arm_max_freq; static int num_cpu_op; -/* working point(wp): 0 - 1.2GHz; 1 - 800MHz, 2 - 624MHz 3 - 400MHz, 4 - 200MHz */ +/* working point(wp): 0 - 1.2GHz; 1 - 792MHz, 2 - 498MHz 3 - 396MHz */ static struct cpu_op mx6_cpu_op_1_2G[] = { { .pll_rate = 1200000000, .cpu_rate = 1200000000, .cpu_podf = 0, + .pu_voltage = 1250000, + .soc_voltage = 1250000, .cpu_voltage = 1275000,}, { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, + .pu_voltage = 1100000, + .soc_voltage = 1100000, .cpu_voltage = 1100000,}, - { - .pll_rate = 672000000, - .cpu_rate = 672000000, - .cpu_voltage = 1050000,}, +/* { + .pll_rate = 996000000, + .cpu_rate = 498000000, + .cpu_podf = 1, + .pu_voltage = 1100000, + .soc_voltage = 1100000, + .cpu_voltage = 1050000,},*/ { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .cpu_voltage = 950000,}, - { - .pll_rate = 396000000, - .cpu_rate = 198000000, - .cpu_podf = 1, - .cpu_voltage = 850000,}, + .pu_voltage = 1100000, + .soc_voltage = 1100000, + .cpu_voltage = 925000,}, }; -/* working point(wp): 0 - 1GHz; 1 - 800MHz, 2 - 624MHz 3 - 400MHz, 4 - 200MHz */ +/* working point(wp): 0 - 1GHz; 1 - 792MHz, 2 - 498MHz 3 - 396MHz */ static struct cpu_op mx6_cpu_op_1G[] = { { .pll_rate = 996000000, .cpu_rate = 996000000, .cpu_podf = 0, + .pu_voltage = 1200000, + .soc_voltage = 1200000, .cpu_voltage = 1225000,}, { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, + .pu_voltage = 1100000, + .soc_voltage = 1100000, .cpu_voltage = 1100000,}, - { - .pll_rate = 672000000, - .cpu_rate = 672000000, - .cpu_voltage = 1050000,}, +/* { + .pll_rate = 996000000, + .cpu_rate = 498000000, + .cpu_podf = 1, + .pu_voltage = 1100000, + .soc_voltage = 1100000, + .cpu_voltage = 1050000,},*/ { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .cpu_voltage = 950000,}, - { - .pll_rate = 396000000, - .cpu_rate = 198000000, - .cpu_podf = 1, - .cpu_voltage = 850000,}, + .pu_voltage = 1100000, + .soc_voltage = 1100000, + .cpu_voltage = 925000,}, }; static struct cpu_op mx6_cpu_op[] = { @@ -84,17 +92,23 @@ static struct cpu_op mx6_cpu_op[] = { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, + .pu_voltage = 1100000, + .soc_voltage = 1100000, .cpu_voltage = 1100000,}, +/* { + .pll_rate = 996000000, + .cpu_rate = 498000000, + .cpu_podf = 1, + .pu_voltage = 1100000, + .soc_voltage = 1100000, + .cpu_voltage = 1050000,},*/ { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .cpu_voltage = 950000,}, - { - .pll_rate = 396000000, - .cpu_rate = 198000000, - .cpu_podf = 1, - .cpu_voltage = 850000,}, + .pu_voltage = 1100000, + .soc_voltage = 1100000, + .cpu_voltage = 925000,}, }; /* working point(wp): 0 - 1.2GHz; 1 - 800MHz, 2 - 400MHz, 3 - 200MHz */ @@ -103,22 +117,30 @@ static struct cpu_op mx6dl_cpu_op_1_2G[] = { .pll_rate = 1200000000, .cpu_rate = 1200000000, .cpu_podf = 0, + .pu_voltage = 1250000, + .soc_voltage = 1250000, .cpu_voltage = 1275000,}, { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, - .cpu_voltage = 1100000,}, + .pu_voltage = 1100000, + .soc_voltage = 1100000, + .cpu_voltage = 1125000,}, { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .cpu_voltage = 1000000,}, - { - .pll_rate = 396000000, - .cpu_rate = 198000000, - .cpu_podf = 1, - .cpu_voltage = 1000000,}, + .pu_voltage = 1100000, + .soc_voltage = 1100000, + .cpu_voltage = 1025000,}, + { + .pll_rate = 396000000, + .cpu_rate = 198000000, + .cpu_podf = 1, + .pu_voltage = 1100000, + .soc_voltage = 1100000, + .cpu_voltage = 1025000,}, }; /* working point(wp): 0 - 1GHz; 1 - 800MHz, 2 - 400MHz, 3 - 200MHz */ static struct cpu_op mx6dl_cpu_op_1G[] = { @@ -126,39 +148,52 @@ static struct cpu_op mx6dl_cpu_op_1G[] = { .pll_rate = 996000000, .cpu_rate = 996000000, .cpu_podf = 0, + .pu_voltage = 1200000, + .soc_voltage = 1200000, .cpu_voltage = 1225000,}, { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, + .pu_voltage = 1100000, + .soc_voltage = 1100000, .cpu_voltage = 1125000,}, - { - .pll_rate = 396000000, - .cpu_rate = 396000000, - .cpu_podf = 0, - .cpu_voltage = 1025000,}, { .pll_rate = 396000000, - .cpu_rate = 198000000, - .cpu_podf = 1, + .cpu_rate = 396000000, + .cpu_podf = 0, + .pu_voltage = 1100000, + .soc_voltage = 1100000, .cpu_voltage = 1025000,}, + { + .pll_rate = 396000000, + .cpu_rate = 198000000, + .cpu_podf = 1, + .pu_voltage = 1100000, + .soc_voltage = 1100000, + .cpu_voltage = 1025000,}, }; - static struct cpu_op mx6dl_cpu_op[] = { { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, + .pu_voltage = 1100000, + .soc_voltage = 1100000, .cpu_voltage = 1100000,}, { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, + .pu_voltage = 1100000, + .soc_voltage = 1100000, .cpu_voltage = 1000000,}, { .pll_rate = 396000000, .cpu_rate = 198000000, .cpu_podf = 1, + .pu_voltage = 1100000, + .soc_voltage = 1100000, .cpu_voltage = 1000000,}, }; diff --git a/arch/arm/mach-mx6/cpu_regulator-mx6.c b/arch/arm/mach-mx6/cpu_regulator-mx6.c index 779ed62eea53..cb08cad48204 100644 --- a/arch/arm/mach-mx6/cpu_regulator-mx6.c +++ b/arch/arm/mach-mx6/cpu_regulator-mx6.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -26,7 +26,11 @@ #include struct regulator *cpu_regulator; +struct regulator *soc_regulator; +struct regulator *pu_regulator; char *gp_reg_id; +char *soc_reg_id; +char *pu_reg_id; static struct clk *cpu_clk; static int cpu_op_nr; static struct cpu_op *cpu_op_tbl; @@ -98,5 +102,11 @@ void mx6_cpu_regulator_init(void) #endif } } + soc_regulator = regulator_get(NULL, soc_reg_id); + if (IS_ERR(soc_regulator)) + printk(KERN_ERR "%s: failed to get soc regulator\n", __func__); + pu_regulator = regulator_get(NULL, pu_reg_id); + if (IS_ERR(pu_regulator)) + printk(KERN_ERR "%s: failed to get pu regulator\n", __func__); } -- cgit v1.2.3 From 29e156d209a2618d47c640d71e166c7fb3ec8192 Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Sat, 11 Aug 2012 17:41:52 +0800 Subject: ENGR00220154 GPT mx6: move mx6_timer_rate to clock.c System will report oops as below. To fix it we will move mx6_timer_rate to clock.c, so that we can avoid use clk_get_sys which cause schedule after spin_lock. oops log: BUG: scheduling while atomic: kinteractiveup/1403/0x00000002 Modules linked in: (unwind_backtrace+0x0/0xfc) from [<804f05f0>] (__schedule+0x4b8/0x6b0) (__schedule+0x4b8/0x6b0) from [<804f12ac>] (__mutex_lock_slowpath+0x138/0x208) (__mutex_lock_slowpath+0x138/0x208) from [<804f13b4>] (mutex_lock+0x38/0x3c) mutex_lock+0x38/0x3c) from [<803b9134>] (clk_get_sys+0x1c/0xec) (clk_get_sys+0x1c/0xec) from [<8005f814>] (mx6_timer_rate+0x14/0x7c) (mx6_timer_rate+0x14/0x7c) from [<80056a20>] (_clk_gpt_get_rate+0x18/0x2c) (_clk_gpt_get_rate+0x18/0x2c) from [<8005e89c>] (clk_get_rate+0x34/0x40) (clk_get_rate+0x34/0x40) from [<80055f3c>] (_clk_pll_enable+0xa8/0x1ec) (_clk_pll_enable+0xa8/0x1ec) from [<80056088>] (_clk_pll1_enable+0x8/0x20) (_clk_pll1_enable+0x8/0x20) from [<80056998>] (_clk_arm_set_rate+0x278/0x2e8) (_clk_arm_set_rate+0x278/0x2e8) from [<8005e824>] (clk_set_rate+0x54/0x68) (clk_set_rate+0x54/0x68) from [<80061660>] (set_cpu_freq+0xb8/0x160) (set_cpu_freq+0xb8/0x160) from [<800618b4>] (mxc_set_target+0xf0/0x20c) (mxc_set_target+0xf0/0x20c) from [<80372388>](__cpufreq_driver_target+0x54/0x60) Signed-off-by: Robin Gong --- arch/arm/mach-mx6/clock.c | 28 ++++++++++++++++++++++++++++ arch/arm/mach-mx6/clock_mx6sl.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index 5b74e2d25c01..0a01c3176eb1 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -90,6 +90,11 @@ DEFINE_SPINLOCK(clk_lock); #define V2_TCN 0x24 #define V2_TSTAT 0x08 #define V2_TSTAT_ROV (1 << 5) +#define V2_TCTL_CLK_OSC_DIV8 (5 << 6) +#define MXC_TCTL 0x00 +#define MXC_TPRER 0x04 +#define V2_TPRER_PRE24M_OFFSET 12 +#define V2_TPRER_PRE24M_MASK 0xF /* We need to check the exp status again after timer expiration, * as there might be interrupt coming between the first time exp @@ -1997,6 +2002,29 @@ static struct clk vdoa_clk[] = { }, }; +static unsigned long mx6_timer_rate() +{ + u32 parent_rate = clk_get_rate(&osc_clk); + + u32 reg = __raw_readl(timer_base + MXC_TCTL); + u32 div; + + if ((reg & V2_TCTL_CLK_OSC_DIV8) == V2_TCTL_CLK_OSC_DIV8) { + if (cpu_is_mx6q()) + /* For MX6Q, only options are 24MHz or 24MHz/8*/ + return parent_rate / 8; + else { + /* For MX6DLS and MX6Solo, the rate is based on the + * divider value set in prescalar register. */ + div = __raw_readl(timer_base + MXC_TPRER); + div = (div >> V2_TPRER_PRE24M_OFFSET) & + V2_TPRER_PRE24M_MASK; + return parent_rate / (div + 1); + } + } + return 0; +} + static unsigned long _clk_gpt_get_rate(struct clk *clk) { unsigned long rate; diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index 6e0bcc479585..3b2d9e527625 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -82,6 +82,11 @@ DEFINE_SPINLOCK(mx6sl_clk_lock); #define V2_TCN 0x24 #define V2_TSTAT 0x08 #define V2_TSTAT_ROV (1 << 5) +#define V2_TCTL_CLK_OSC_DIV8 (5 << 6) +#define MXC_TCTL 0x00 +#define MXC_TPRER 0x04 +#define V2_TPRER_PRE24M_OFFSET 12 +#define V2_TPRER_PRE24M_MASK 0xF /* We need to check the exp status again after timer expiration, * as there might be interrupt coming between the first time exp @@ -1760,6 +1765,29 @@ static struct clk sdma_clk[] = { }, }; +static unsigned long mx6_timer_rate() +{ + u32 parent_rate = clk_get_rate(&osc_clk); + + u32 reg = __raw_readl(timer_base + MXC_TCTL); + u32 div; + + if ((reg & V2_TCTL_CLK_OSC_DIV8) == V2_TCTL_CLK_OSC_DIV8) { + if (cpu_is_mx6q()) + /* For MX6Q, only options are 24MHz or 24MHz/8*/ + return parent_rate / 8; + else { + /* For MX6DLS and MX6Solo, the rate is based on the + * divider value set in prescalar register. */ + div = __raw_readl(timer_base + MXC_TPRER); + div = (div >> V2_TPRER_PRE24M_OFFSET) & + V2_TPRER_PRE24M_MASK; + return parent_rate / (div + 1); + } + } + return 0; +} + static unsigned long _clk_gpt_get_rate(struct clk *clk) { unsigned long rate; -- cgit v1.2.3 From d24d1feb0d6243506696c7e5b3462b10f858d4e9 Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Fri, 10 Aug 2012 15:50:24 +0800 Subject: ENGR00217918 - mx6 cpufreq : Add on-demand governor's threshold for FEC Add on-demand governor's threshold for FEC to improves performance. i.mx6q TO1.1 tx throughput only is 64Mbps in 100Mbps mode on sabresd platform, after the change, the throughput can reach to 95Mbps for tx. Signed-off-by: Fugang Duan --- arch/arm/mach-mx6/irq.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/irq.c b/arch/arm/mach-mx6/irq.c index 2434c1b11606..22ca75cbce43 100644 --- a/arch/arm/mach-mx6/irq.c +++ b/arch/arm/mach-mx6/irq.c @@ -80,6 +80,10 @@ static struct irq_tuner mxc_irq_tuner[] = { .irq_number = 75, /* OTG */ .up_threshold = 10, .enable = 1,}, + { + .irq_number = 150, /* ENET */ + .up_threshold = 4, + .enable = 1,}, { .irq_number = 0, /* END */ .up_threshold = 0, -- cgit v1.2.3 From 88a4498cc9eec58abf4687190a79068d0a0b8fd6 Mon Sep 17 00:00:00 2001 From: Richard Liu Date: Tue, 14 Aug 2012 14:08:29 +0800 Subject: ENGR00220199 Add CPU governor trigger for GPU2D and GPUVG core Add CPU governor trigger for GPU2D and GPUVG core, without these trigger some benchmark show performance drop when enable CPU governor Signed-off-by: Richard Liu Acked-by: Lily Zhang --- arch/arm/mach-mx6/irq.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/irq.c b/arch/arm/mach-mx6/irq.c index 22ca75cbce43..197c451d5fb4 100644 --- a/arch/arm/mach-mx6/irq.c +++ b/arch/arm/mach-mx6/irq.c @@ -56,6 +56,14 @@ static struct irq_tuner mxc_irq_tuner[] = { .irq_number = 41, /* GPU 3D */ .up_threshold = 0, .enable = 1,}, + { + .irq_number = 42, /* GPU 2D */ + .up_threshold = 40, + .enable = 1,}, + { + .irq_number = 43, /* GPU VG */ + .up_threshold = 0, + .enable = 1,}, { .irq_number = 54, /* uSDHC1 */ .up_threshold = 4, -- cgit v1.2.3 From 71833bc03b14fed17dd37549d6776f5b04f49242 Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Tue, 14 Aug 2012 15:27:27 +0800 Subject: ENGR00220340 mx6sl pfuze: keep NVCC_1V8 and NVCC_1.2V always on 1. Keep the corresponding rail of pfuze:VGEN4 and VGEN1 "always on". 2. mx6sl enable LDO bypass default, which can't including adjust soc and pu regulator. To support old LDO bypass code, need check soc_regulator and pu_regulator, otherwise, system will crash. Signed-off-by: Robin Gong --- arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c index 0c3f1b20d361..eaa9721dc7d3 100644 --- a/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c +++ b/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c @@ -298,8 +298,8 @@ static struct regulator_init_data vgen1_init = { .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, .valid_modes_mask = 0, - .always_on = 0, - .boot_on = 0, + .always_on = 1, + .boot_on = 1, }, .num_consumer_supplies = ARRAY_SIZE(vgen1_consumers), .consumer_supplies = vgen1_consumers, @@ -345,6 +345,8 @@ static struct regulator_init_data vgen4_init = { .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, .valid_modes_mask = 0, + .always_on = 1, + .boot_on = 1, }, .num_consumer_supplies = ARRAY_SIZE(vgen4_consumers), .consumer_supplies = vgen4_consumers, -- cgit v1.2.3 From 4a711bb18e46d81606b804ed7d3c4f918815223f Mon Sep 17 00:00:00 2001 From: Nancy Chen Date: Tue, 14 Aug 2012 09:49:05 -0500 Subject: ENGR00220297 [MX6SL]: Fix AHB clock not correct after kernel boot 1. Fix AHB_CLK is not right after system up. ahb_clk is 49.5MHz after system up. It should be 132MHz. 2. Remove the voltage changes for VDDSOC_CAP since there are vddarm voltage changed in CPUFREQ and vddsoc voltage and vddarm voltage should meet the constraint condition: VDDSOC > VDDARM - 50mV. Therefore VDDSOC voltage changes will be implemented in CPUFREQ. Signed-off-by: Nancy Chen --- arch/arm/mach-mx6/bus_freq.c | 54 +++++------------------------------------ arch/arm/mach-mx6/clock_mx6sl.c | 4 +-- 2 files changed, 8 insertions(+), 50 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index 51e1d3b14e62..83310c436d54 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -99,14 +99,11 @@ static struct clk *pll2; static struct clk *pll3_sw_clk; static struct clk *pll2_200; static struct clk *mmdc_ch0_axi; -struct regulator *vddsoc_cap_regulator; static struct delayed_work low_bus_freq_handler; static void reduce_bus_freq_handler(struct work_struct *work) { - int ret = 0; - if (low_bus_freq_mode || !low_freq_bus_used()) return; @@ -138,17 +135,6 @@ static void reduce_bus_freq_handler(struct work_struct *work) clk_disable(pll3); } else { - /* Set VDDSOC_CAP to 1.1V */ - ret = regulator_set_voltage(vddsoc_cap_regulator, 1100000, - 1100000); - if (ret < 0) { - printk(KERN_DEBUG - "COULD NOT DECREASE VDDSOC_CAP VOLTAGE!!!!\n"); - return; - } - - udelay(150); - arm_mem_clked_in_wait = true; /* Set periph_clk to be sourced from OSC_CLK */ @@ -172,7 +158,6 @@ static void reduce_bus_freq_handler(struct work_struct *work) } high_bus_freq_mode = 0; - med_bus_freq_mode = 0; } /* Set the DDR, AHB to 24MHz. * This mode will be activated only when none of the modules that @@ -198,8 +183,6 @@ int set_low_bus_freq(void) */ int set_high_bus_freq(int high_bus_freq) { - int ret = 0; - if (busfreq_suspended) return 0; @@ -224,23 +207,6 @@ int set_high_bus_freq(int high_bus_freq) return 0; if (cpu_is_mx6sl()) { - /* Set the voltage of VDDSOC to 1.2V as in normal mode. */ - ret = regulator_set_voltage(vddsoc_cap_regulator, 1200000, - 1200000); - if (ret < 0) { - printk(KERN_DEBUG - "COULD NOT INCREASE VDDSOC_CAP VOLTAGE!!!!\n"); - return ret; - } - - /* Need to wait for the regulator to come back up */ - /* - * Delay time is based on the number of 24MHz clock cycles - * programmed in the ANA_MISC2_BASE_ADDR for each - * 25mV step. - */ - udelay(150); - /* Set periph_clk to be sourced from pll2_pfd2_400M */ /* First need to set the divider before changing the */ /* parent if parent clock is larger than previous one */ @@ -260,7 +226,6 @@ int set_high_bus_freq(int high_bus_freq) clk_round_rate(mmdc_ch0_axi, DDR_MED_CLK)); high_bus_freq_mode = 1; - med_bus_freq_mode = 0; } else { clk_enable(pll3); if (high_bus_freq) { @@ -511,13 +476,6 @@ static int __devinit busfreq_probe(struct platform_device *pdev) return PTR_ERR(mmdc_ch0_axi); } - vddsoc_cap_regulator = regulator_get(NULL, "cpu_vddsoc"); - if (IS_ERR(vddsoc_cap_regulator)) { - printk(KERN_ERR "%s: failed to get vddsoc_cap regulator\n", - __func__); - return PTR_ERR(vddsoc_cap_regulator); - } - err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr); if (err) { printk(KERN_ERR @@ -533,6 +491,11 @@ static int __devinit busfreq_probe(struct platform_device *pdev) /* To make pll2_400 use count right, as when system enter 24M, it will disable pll2_400 */ clk_enable(pll2_400); + } else if (cpu_is_mx6sl()) { + /* Set med_bus_freq_mode to 1 since med_bus_freq_mode + is not supported as yet for MX6SL */ + high_bus_freq_mode = 1; + med_bus_freq_mode = 1; } else { high_bus_freq_mode = 1; med_bus_freq_mode = 0; @@ -587,14 +550,9 @@ static int __init busfreq_init(void) if (cpu_is_mx6q()) set_high_bus_freq(1); - else + else if (cpu_is_mx6dl()) set_high_bus_freq(0); - /* Make sure system can enter low bus mode if it should be in - low bus mode */ - if (low_freq_bus_used() && !low_bus_freq_mode) - set_low_bus_freq(); - printk(KERN_INFO "Bus freq driver Enabled\n"); return 0; } diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index 3b2d9e527625..7496882feeb1 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -2908,7 +2908,7 @@ static struct clk lcdif_pix_clk = { .set_rate = _clk_lcdif_pix_set_rate, .round_rate = _clk_epdc_lcdif_pix_round_rate, .get_rate = _clk_lcdif_pix_get_rate, - .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, }; static struct clk epdc_pix_clk = { @@ -2923,7 +2923,7 @@ static struct clk epdc_pix_clk = { .set_rate = _clk_epdc_pix_set_rate, .round_rate = _clk_epdc_lcdif_pix_round_rate, .get_rate = _clk_epdc_pix_get_rate, - .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, }; static unsigned long _clk_spdif_round_rate(struct clk *clk, unsigned long rate) -- cgit v1.2.3 From d324cc15df1f1aebf6f2401218e02e4b86578098 Mon Sep 17 00:00:00 2001 From: Yuxi Sun Date: Wed, 15 Aug 2012 11:10:06 +0800 Subject: ENGR00220176 sabrelite ov5642: Fix ov5642 probe fail Add ov5642 power down function in the board initial file Signed-off-by: Yuxi Sun --- arch/arm/mach-mx6/board-mx6q_sabrelite.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c index 6f14aeaf6e6a..3abb282fd56c 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabrelite.c +++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c @@ -575,6 +575,15 @@ static struct i2c_board_info mxc_i2c0_board_info[] __initdata = { }, }; +static void mx6q_csi0_cam_powerdown(int powerdown) +{ + if (powerdown) + gpio_set_value(MX6Q_SABRELITE_CSI0_PWN, 1); + else + gpio_set_value(MX6Q_SABRELITE_CSI0_PWN, 0); + + msleep(2); +} static void mx6q_csi0_io_init(void) { @@ -615,6 +624,7 @@ static struct fsl_mxc_camera_platform_data camera_data = { .mclk_source = 0, .csi = 0, .io_init = mx6q_csi0_io_init, + .pwdn = mx6q_csi0_cam_powerdown, }; static struct i2c_board_info mxc_i2c1_board_info[] __initdata = { -- cgit v1.2.3 From 83ec55588691d188c0419b9a659bff6985239615 Mon Sep 17 00:00:00 2001 From: Xinyu Chen Date: Wed, 15 Aug 2012 13:32:06 +0800 Subject: ENGR00219856-1 mx6q sabresd: add debounce to gpio key Add a 1ms debounce to the gpio key to avoid unexpected gpio status read from gpio_key driver's workqueue. This issue happens on android's resume stage, sometimes the framework get more than one up key even user press the power key once. Signed-off-by: Xinyu Chen --- arch/arm/mach-mx6/board-mx6q_sabresd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c index 480ef185c455..429cffc6806a 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabresd.c +++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c @@ -1535,7 +1535,7 @@ static void __init imx6q_add_device_gpio_leds(void) {} #endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake) \ +#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake, debounce) \ { \ .gpio = gpio_num, \ .type = EV_KEY, \ @@ -1543,12 +1543,13 @@ static void __init imx6q_add_device_gpio_leds(void) {} .active_low = act_low, \ .desc = "btn " descr, \ .wakeup = wake, \ + .debounce_interval = debounce, \ } static struct gpio_keys_button imx6q_buttons[] = { - GPIO_BUTTON(SABRESD_VOLUME_UP, KEY_VOLUMEUP, 1, "volume-up", 0), - GPIO_BUTTON(SABRESD_VOLUME_DN, KEY_VOLUMEDOWN, 1, "volume-down", 0), - GPIO_BUTTON(SABRESD_POWER_OFF, KEY_POWER, 1, "power", 1), + GPIO_BUTTON(SABRESD_VOLUME_UP, KEY_VOLUMEUP, 1, "volume-up", 0, 1), + GPIO_BUTTON(SABRESD_VOLUME_DN, KEY_VOLUMEDOWN, 1, "volume-down", 0, 1), + GPIO_BUTTON(SABRESD_POWER_OFF, KEY_POWER, 1, "power", 1, 1), }; static struct gpio_keys_platform_data imx6q_button_data = { -- cgit v1.2.3 From d772cfee953c0702b857365b745a266490af140d Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Mon, 13 Aug 2012 16:12:31 +0800 Subject: ENGR00220161: imx6sl: Add EVK board Support - Copied the board file from ARM2, and consolidated the pinmux setting. - Added a new pmic file for EVK. - Added a new mach type. - Added board_is_mx6sl_evk() API for late use if needed. - Updated the defconfig Signed-off-by: Robby Cai --- arch/arm/mach-mx6/Kconfig | 37 + arch/arm/mach-mx6/Makefile | 3 +- arch/arm/mach-mx6/board-mx6sl_arm2.c | 472 +++++----- arch/arm/mach-mx6/board-mx6sl_arm2.h | 358 -------- arch/arm/mach-mx6/board-mx6sl_common.h | 415 +++++++++ arch/arm/mach-mx6/board-mx6sl_evk.c | 1300 +++++++++++++++++++++++++++ arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c | 440 +++++++++ 7 files changed, 2402 insertions(+), 623 deletions(-) delete mode 100755 arch/arm/mach-mx6/board-mx6sl_arm2.h create mode 100644 arch/arm/mach-mx6/board-mx6sl_common.h create mode 100644 arch/arm/mach-mx6/board-mx6sl_evk.c create mode 100644 arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/Kconfig b/arch/arm/mach-mx6/Kconfig index 08875a60a31c..45ae9eac67d2 100644 --- a/arch/arm/mach-mx6/Kconfig +++ b/arch/arm/mach-mx6/Kconfig @@ -107,6 +107,43 @@ config MACH_MX6SL_ARM2 Include support for i.MX 6Sololite Armadillo2 platform. This includes specific configurations for the board and its peripherals. +config MACH_MX6SL_EVK + bool "Support i.MX 6SoloLite EVK platform" + select ARCH_MX6Q + select SOC_IMX6SL + select IMX_HAVE_PLATFORM_IMX_UART + select IMX_HAVE_PLATFORM_DMA + select IMX_HAVE_PLATFORM_FEC + select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX + select IMX_HAVE_PLATFORM_SPI_IMX + select IMX_HAVE_PLATFORM_IMX_I2C + select IMX_HAVE_PLATFORM_VIV_GPU + select IMX_HAVE_PLATFORM_IMX_DVFS + select IMX_HAVE_PLATFORM_IMX_SSI + select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL + select IMX_HAVE_PLATFORM_FSL_USB2_UDC + select IMX_HAVE_PLATFORM_MXC_EHCI + select IMX_HAVE_PLATFORM_FSL_OTG + select IMX_HAVE_PLATFORM_FSL_USB_WAKEUP + select IMX_HAVE_PLATFORM_AHCI + select IMX_HAVE_PLATFORM_IMX_OCOTP + select IMX_HAVE_PLATFORM_IMX_VIIM + select IMX_HAVE_PLATFORM_IMX2_WDT + select IMX_HAVE_PLATFORM_IMX_SNVS_RTC + select IMX_HAVE_PLATFORM_IMX_PM + select IMX_HAVE_PLATFORM_IMX_SPDIF + select IMX_HAVE_PLATFORM_PERFMON + select IMX_HAVE_PLATFORM_IMX_EPDC + select IMX_HAVE_PLATFORM_IMX_SPDC + select IMX_HAVE_PLATFORM_IMX_PXP + select IMX_HAVE_PLATFORM_IMX_KEYPAD + select IMX_HAVE_PLATFORM_IMX_DCP + select IMX_HAVE_PLATFORM_RANDOM_RNGC + select ARCH_HAS_RNGC + help + Include support for i.MX 6Sololite EVK platform. This includes specific + configurations for the board and its peripherals. + config MACH_MX6Q_SABRELITE bool "Support i.MX 6Quad SABRE Lite platform" select ARCH_MX6Q diff --git a/arch/arm/mach-mx6/Makefile b/arch/arm/mach-mx6/Makefile index 24dae23dd089..77d809145775 100644 --- a/arch/arm/mach-mx6/Makefile +++ b/arch/arm/mach-mx6/Makefile @@ -10,10 +10,11 @@ mx6_mmdc.o mx6_ddr_freq.o obj-$(CONFIG_ARCH_MX6) += clock.o mx6_suspend.o clock_mx6sl.o obj-$(CONFIG_MACH_MX6Q_ARM2) += board-mx6q_arm2.o obj-$(CONFIG_MACH_MX6SL_ARM2) += board-mx6sl_arm2.o mx6sl_arm2_pmic_pfuze100.o +obj-$(CONFIG_MACH_MX6SL_EVK) += board-mx6sl_evk.o mx6sl_evk_pmic_pfuze100.o obj-$(CONFIG_MACH_MX6Q_SABRELITE) += board-mx6q_sabrelite.o obj-$(CONFIG_MACH_MX6Q_SABRESD) += board-mx6q_sabresd.o mx6q_sabresd_pmic_pfuze100.o obj-$(CONFIG_MACH_MX6Q_SABREAUTO) += board-mx6q_sabreauto.o mx6q_sabreauto_pmic_pfuze100.o obj-$(CONFIG_SMP) += plat_hotplug.o platsmp.o headsmp.o obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o obj-$(CONFIG_IMX_PCIE) += pcie.o -obj-$(CONFIG_USB_EHCI_ARC_H1) += usb_h1.o \ No newline at end of file +obj-$(CONFIG_USB_EHCI_ARC_H1) += usb_h1.o diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c index 0c5166627320..8f05702e74aa 100755 --- a/arch/arm/mach-mx6/board-mx6sl_arm2.c +++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -71,67 +70,11 @@ #include "devices-imx6q.h" #include "crm_regs.h" #include "cpu_op-mx6.h" -#include "board-mx6sl_arm2.h" - -#define MX6_ARM2_USBOTG1_PWR IMX_GPIO_NR(4, 0) /* KEY_COL4 */ -#define MX6_ARM2_USBOTG2_PWR IMX_GPIO_NR(4, 2) /* KEY_COL5 */ -#define MX6_ARM2_LCD_PWR_EN IMX_GPIO_NR(4, 3) /* KEY_ROW5 */ -#define MX6_ARM2_SD1_WP IMX_GPIO_NR(4, 6) /* KEY_COL7 */ -#define MX6_ARM2_SD1_CD IMX_GPIO_NR(4, 7) /* KEY_ROW7 */ -#define MX6_ARM2_ECSPI1_CS0 IMX_GPIO_NR(4, 11) /* ECSPI1_SS0 */ -#define MX6_ARM2_HEADPHONE_DET IMX_GPIO_NR(4, 19) /* FEC_RX_ER */ -#define MX6_ARM2_SD2_WP IMX_GPIO_NR(4, 29) /* SD2_DAT6 */ -#define MX6_ARM2_SD2_CD IMX_GPIO_NR(5, 0) /* SD2_DAT7 */ -#define MX6_ARM2_SD3_CD IMX_GPIO_NR(3, 22) /* REF_CLK_32K */ -#define MX6_ARM2_FEC_PWR_EN IMX_GPIO_NR(4, 21) /* FEC_TX_CLK */ - -/* EPDC GPIO pins */ -#define MX6SL_ARM2_EPDC_SDDO_0 IMX_GPIO_NR(1, 7) -#define MX6SL_ARM2_EPDC_SDDO_1 IMX_GPIO_NR(1, 8) -#define MX6SL_ARM2_EPDC_SDDO_2 IMX_GPIO_NR(1, 9) -#define MX6SL_ARM2_EPDC_SDDO_3 IMX_GPIO_NR(1, 10) -#define MX6SL_ARM2_EPDC_SDDO_4 IMX_GPIO_NR(1, 11) -#define MX6SL_ARM2_EPDC_SDDO_5 IMX_GPIO_NR(1, 12) -#define MX6SL_ARM2_EPDC_SDDO_6 IMX_GPIO_NR(1, 13) -#define MX6SL_ARM2_EPDC_SDDO_7 IMX_GPIO_NR(1, 14) -#define MX6SL_ARM2_EPDC_SDDO_8 IMX_GPIO_NR(1, 15) -#define MX6SL_ARM2_EPDC_SDDO_9 IMX_GPIO_NR(1, 16) -#define MX6SL_ARM2_EPDC_SDDO_10 IMX_GPIO_NR(1, 17) -#define MX6SL_ARM2_EPDC_SDDO_11 IMX_GPIO_NR(1, 18) -#define MX6SL_ARM2_EPDC_SDDO_12 IMX_GPIO_NR(1, 19) -#define MX6SL_ARM2_EPDC_SDDO_13 IMX_GPIO_NR(1, 20) -#define MX6SL_ARM2_EPDC_SDDO_14 IMX_GPIO_NR(1, 21) -#define MX6SL_ARM2_EPDC_SDDO_15 IMX_GPIO_NR(1, 22) -#define MX6SL_ARM2_EPDC_GDCLK IMX_GPIO_NR(1, 31) -#define MX6SL_ARM2_EPDC_GDSP IMX_GPIO_NR(2, 2) -#define MX6SL_ARM2_EPDC_GDOE IMX_GPIO_NR(2, 0) -#define MX6SL_ARM2_EPDC_GDRL IMX_GPIO_NR(2, 1) -#define MX6SL_ARM2_EPDC_SDCLK IMX_GPIO_NR(1, 23) -#define MX6SL_ARM2_EPDC_SDOE IMX_GPIO_NR(1, 25) -#define MX6SL_ARM2_EPDC_SDLE IMX_GPIO_NR(1, 24) -#define MX6SL_ARM2_EPDC_SDSHR IMX_GPIO_NR(1, 26) -#define MX6SL_ARM2_EPDC_PWRCOM IMX_GPIO_NR(2, 11) -#define MX6SL_ARM2_EPDC_PWRSTAT IMX_GPIO_NR(2, 13) -#define MX6SL_ARM2_EPDC_PWRCTRL0 IMX_GPIO_NR(2, 7) -#define MX6SL_ARM2_EPDC_PWRCTRL1 IMX_GPIO_NR(2, 8) -#define MX6SL_ARM2_EPDC_PWRCTRL2 IMX_GPIO_NR(2, 9) -#define MX6SL_ARM2_EPDC_PWRCTRL3 IMX_GPIO_NR(2, 10) -#define MX6SL_ARM2_EPDC_BDR0 IMX_GPIO_NR(2, 5) -#define MX6SL_ARM2_EPDC_BDR1 IMX_GPIO_NR(2, 6) -#define MX6SL_ARM2_EPDC_SDCE0 IMX_GPIO_NR(1, 27) -#define MX6SL_ARM2_EPDC_SDCE1 IMX_GPIO_NR(1, 28) -#define MX6SL_ARM2_EPDC_SDCE2 IMX_GPIO_NR(1, 29) -#define MX6SL_ARM2_EPDC_SDCE3 IMX_GPIO_NR(1, 30) -#define MX6SL_ARM2_EPDC_PMIC_WAKE IMX_GPIO_NR(2, 14) /* EPDC_PWRWAKEUP */ -#define MX6SL_ARM2_EPDC_PMIC_INT IMX_GPIO_NR(2, 12) /* EPDC_PWRINT */ -#define MX6SL_ARM2_EPDC_VCOM IMX_GPIO_NR(2, 3) -#define MX6SL_ARM2_ELAN_CE IMX_GPIO_NR(2, 9) -#define MX6SL_ARM2_ELAN_INT IMX_GPIO_NR(2, 10) -#define MX6SL_ARM2_ELAN_RST IMX_GPIO_NR(4, 4) +#include "board-mx6sl_common.h" static int spdc_sel; static int max17135_regulator_init(struct max17135 *max17135); -struct clk *extern_audio_root; +static struct clk *extern_audio_root; extern char *gp_reg_id; extern char *soc_reg_id; @@ -215,8 +158,8 @@ static int plt_sd_pad_change(unsigned int index, int clock) } static const struct esdhc_platform_data mx6_arm2_sd1_data __initconst = { - .cd_gpio = MX6_ARM2_SD1_CD, - .wp_gpio = MX6_ARM2_SD1_WP, + .cd_gpio = MX6_BRD_SD1_CD, + .wp_gpio = MX6_BRD_SD1_WP, .support_8bit = 1, .support_18v = 1, .keep_power_at_suspend = 1, @@ -225,8 +168,8 @@ static const struct esdhc_platform_data mx6_arm2_sd1_data __initconst = { }; static const struct esdhc_platform_data mx6_arm2_sd2_data __initconst = { - .cd_gpio = MX6_ARM2_SD2_CD, - .wp_gpio = MX6_ARM2_SD2_WP, + .cd_gpio = MX6_BRD_SD2_CD, + .wp_gpio = MX6_BRD_SD2_WP, .keep_power_at_suspend = 1, .delay_line = 0, .support_18v = 1, @@ -234,7 +177,7 @@ static const struct esdhc_platform_data mx6_arm2_sd2_data __initconst = { }; static const struct esdhc_platform_data mx6_arm2_sd3_data __initconst = { - .cd_gpio = MX6_ARM2_SD3_CD, + .cd_gpio = MX6_BRD_SD3_CD, .wp_gpio = -1, .keep_power_at_suspend = 1, .delay_line = 0, @@ -377,11 +320,11 @@ static struct max17135_platform_data max17135_pdata __initdata = { .vpos_pwrdn = 2, .gvee_pwrdn = 1, .vneg_pwrdn = 1, - .gpio_pmic_pwrgood = MX6SL_ARM2_EPDC_PWRSTAT, - .gpio_pmic_vcom_ctrl = MX6SL_ARM2_EPDC_VCOM, - .gpio_pmic_wakeup = MX6SL_ARM2_EPDC_PMIC_WAKE, - .gpio_pmic_v3p3 = MX6SL_ARM2_EPDC_PWRCTRL0, - .gpio_pmic_intr = MX6SL_ARM2_EPDC_PMIC_INT, + .gpio_pmic_pwrgood = MX6SL_BRD_EPDC_PWRSTAT, + .gpio_pmic_vcom_ctrl = MX6SL_BRD_EPDC_VCOM, + .gpio_pmic_wakeup = MX6SL_BRD_EPDC_PMIC_WAKE, + .gpio_pmic_v3p3 = MX6SL_BRD_EPDC_PWRCTRL0, + .gpio_pmic_intr = MX6SL_BRD_EPDC_PMIC_INT, .regulator_init = max17135_init_data, .init = max17135_regulator_init, }; @@ -448,7 +391,7 @@ static int __init max17135_regulator_init(struct max17135 *max17135) } static int mx6_arm2_spi_cs[] = { - MX6_ARM2_ECSPI1_CS0, + MX6_BRD_ECSPI1_CS0, }; static const struct spi_imx_master mx6_arm2_spi_data __initconst = { @@ -551,7 +494,7 @@ static struct mxc_audio_platform_data wm8962_data = { .ssi_num = 1, .src_port = 2, .ext_port = 3, - .hp_gpio = MX6_ARM2_HEADPHONE_DET, + .hp_gpio = MX6_BRD_HEADPHONE_DET, .hp_active_low = 1, .mic_gpio = -1, .mic_active_low = 1, @@ -618,7 +561,7 @@ static struct i2c_board_info mxc_i2c0_board_info[] __initdata = { .platform_data = &max17135_pdata, }, { I2C_BOARD_INFO("elan-touch", 0x10), - .irq = gpio_to_irq(MX6SL_ARM2_ELAN_INT), + .irq = gpio_to_irq(MX6SL_BRD_ELAN_INT), }, }; @@ -679,11 +622,11 @@ static int mx6sl_arm2_fec_phy_init(struct phy_device *phydev) int val; /* power on FEC phy and reset phy */ - gpio_request(MX6_ARM2_FEC_PWR_EN, "fec-pwr"); - gpio_direction_output(MX6_ARM2_FEC_PWR_EN, 0); + gpio_request(MX6_BRD_FEC_PWR_EN, "fec-pwr"); + gpio_direction_output(MX6_BRD_FEC_PWR_EN, 0); /* wait RC ms for hw reset */ msleep(1); - gpio_direction_output(MX6_ARM2_FEC_PWR_EN, 1); + gpio_direction_output(MX6_BRD_FEC_PWR_EN, 1); /* check phy power */ val = phy_read(phydev, 0x0); @@ -704,109 +647,109 @@ static int epdc_get_pins(void) int ret = 0; /* Claim GPIOs for EPDC pins - used during power up/down */ - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_0, "epdc_d0"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_1, "epdc_d1"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_2, "epdc_d2"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_3, "epdc_d3"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_4, "epdc_d4"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_5, "epdc_d5"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_6, "epdc_d6"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_7, "epdc_d7"); - ret |= gpio_request(MX6SL_ARM2_EPDC_GDCLK, "epdc_gdclk"); - ret |= gpio_request(MX6SL_ARM2_EPDC_GDSP, "epdc_gdsp"); - ret |= gpio_request(MX6SL_ARM2_EPDC_GDOE, "epdc_gdoe"); - ret |= gpio_request(MX6SL_ARM2_EPDC_GDRL, "epdc_gdrl"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDCLK, "epdc_sdclk"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDOE, "epdc_sdoe"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDLE, "epdc_sdle"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDSHR, "epdc_sdshr"); - ret |= gpio_request(MX6SL_ARM2_EPDC_BDR0, "epdc_bdr0"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDCE0, "epdc_sdce0"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDCE1, "epdc_sdce1"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDCE2, "epdc_sdce2"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "epdc_d0"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "epdc_d1"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "epdc_d2"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "epdc_d3"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "epdc_d4"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "epdc_d5"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "epdc_d6"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "epdc_d7"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "epdc_gdclk"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "epdc_gdsp"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "epdc_gdoe"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDRL, "epdc_gdrl"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "epdc_sdclk"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDOE, "epdc_sdoe"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "epdc_sdle"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "epdc_sdshr"); + ret |= gpio_request(MX6SL_BRD_EPDC_BDR0, "epdc_bdr0"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "epdc_sdce0"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "epdc_sdce1"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE2, "epdc_sdce2"); return ret; } static void epdc_put_pins(void) { - gpio_free(MX6SL_ARM2_EPDC_SDDO_0); - gpio_free(MX6SL_ARM2_EPDC_SDDO_1); - gpio_free(MX6SL_ARM2_EPDC_SDDO_2); - gpio_free(MX6SL_ARM2_EPDC_SDDO_3); - gpio_free(MX6SL_ARM2_EPDC_SDDO_4); - gpio_free(MX6SL_ARM2_EPDC_SDDO_5); - gpio_free(MX6SL_ARM2_EPDC_SDDO_6); - gpio_free(MX6SL_ARM2_EPDC_SDDO_7); - gpio_free(MX6SL_ARM2_EPDC_GDCLK); - gpio_free(MX6SL_ARM2_EPDC_GDSP); - gpio_free(MX6SL_ARM2_EPDC_GDOE); - gpio_free(MX6SL_ARM2_EPDC_GDRL); - gpio_free(MX6SL_ARM2_EPDC_SDCLK); - gpio_free(MX6SL_ARM2_EPDC_SDOE); - gpio_free(MX6SL_ARM2_EPDC_SDLE); - gpio_free(MX6SL_ARM2_EPDC_SDSHR); - gpio_free(MX6SL_ARM2_EPDC_BDR0); - gpio_free(MX6SL_ARM2_EPDC_SDCE0); - gpio_free(MX6SL_ARM2_EPDC_SDCE1); - gpio_free(MX6SL_ARM2_EPDC_SDCE2); + gpio_free(MX6SL_BRD_EPDC_SDDO_0); + gpio_free(MX6SL_BRD_EPDC_SDDO_1); + gpio_free(MX6SL_BRD_EPDC_SDDO_2); + gpio_free(MX6SL_BRD_EPDC_SDDO_3); + gpio_free(MX6SL_BRD_EPDC_SDDO_4); + gpio_free(MX6SL_BRD_EPDC_SDDO_5); + gpio_free(MX6SL_BRD_EPDC_SDDO_6); + gpio_free(MX6SL_BRD_EPDC_SDDO_7); + gpio_free(MX6SL_BRD_EPDC_GDCLK); + gpio_free(MX6SL_BRD_EPDC_GDSP); + gpio_free(MX6SL_BRD_EPDC_GDOE); + gpio_free(MX6SL_BRD_EPDC_GDRL); + gpio_free(MX6SL_BRD_EPDC_SDCLK); + gpio_free(MX6SL_BRD_EPDC_SDOE); + gpio_free(MX6SL_BRD_EPDC_SDLE); + gpio_free(MX6SL_BRD_EPDC_SDSHR); + gpio_free(MX6SL_BRD_EPDC_BDR0); + gpio_free(MX6SL_BRD_EPDC_SDCE0); + gpio_free(MX6SL_BRD_EPDC_SDCE1); + gpio_free(MX6SL_BRD_EPDC_SDCE2); } static void epdc_enable_pins(void) { /* Configure MUX settings to enable EPDC use */ - mxc_iomux_v3_setup_multiple_pads(mx6sl_arm2_epdc_enable_pads, \ - ARRAY_SIZE(mx6sl_arm2_epdc_enable_pads)); - - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_0); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_1); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_2); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_3); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_4); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_5); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_6); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_7); - gpio_direction_input(MX6SL_ARM2_EPDC_GDCLK); - gpio_direction_input(MX6SL_ARM2_EPDC_GDSP); - gpio_direction_input(MX6SL_ARM2_EPDC_GDOE); - gpio_direction_input(MX6SL_ARM2_EPDC_GDRL); - gpio_direction_input(MX6SL_ARM2_EPDC_SDCLK); - gpio_direction_input(MX6SL_ARM2_EPDC_SDOE); - gpio_direction_input(MX6SL_ARM2_EPDC_SDLE); - gpio_direction_input(MX6SL_ARM2_EPDC_SDSHR); - gpio_direction_input(MX6SL_ARM2_EPDC_BDR0); - gpio_direction_input(MX6SL_ARM2_EPDC_SDCE0); - gpio_direction_input(MX6SL_ARM2_EPDC_SDCE1); - gpio_direction_input(MX6SL_ARM2_EPDC_SDCE2); + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_enable_pads, \ + ARRAY_SIZE(mx6sl_brd_epdc_enable_pads)); + + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7); + gpio_direction_input(MX6SL_BRD_EPDC_GDCLK); + gpio_direction_input(MX6SL_BRD_EPDC_GDSP); + gpio_direction_input(MX6SL_BRD_EPDC_GDOE); + gpio_direction_input(MX6SL_BRD_EPDC_GDRL); + gpio_direction_input(MX6SL_BRD_EPDC_SDCLK); + gpio_direction_input(MX6SL_BRD_EPDC_SDOE); + gpio_direction_input(MX6SL_BRD_EPDC_SDLE); + gpio_direction_input(MX6SL_BRD_EPDC_SDSHR); + gpio_direction_input(MX6SL_BRD_EPDC_BDR0); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE0); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE1); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE2); } static void epdc_disable_pins(void) { /* Configure MUX settings for EPDC pins to * GPIO and drive to 0. */ - mxc_iomux_v3_setup_multiple_pads(mx6sl_arm2_epdc_disable_pads, \ - ARRAY_SIZE(mx6sl_arm2_epdc_disable_pads)); - - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_0, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_1, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_2, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_3, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_4, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_5, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_6, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_7, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_GDCLK, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_GDSP, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_GDOE, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_GDRL, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDCLK, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDOE, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDLE, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDSHR, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_BDR0, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDCE0, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDCE1, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDCE2, 0); + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_disable_pads, \ + ARRAY_SIZE(mx6sl_brd_epdc_disable_pads)); + + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDRL, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDOE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0); + gpio_direction_output(MX6SL_BRD_EPDC_BDR0, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE2, 0); } static struct fb_videomode e60_v110_mode = { @@ -946,108 +889,108 @@ static int spdc_get_pins(void) int ret = 0; /* Claim GPIOs for SPDC pins - used during power up/down */ - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_0, "SPDC_D0"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_1, "SPDC_D1"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_2, "SPDC_D2"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_3, "SPDC_D3"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_4, "SPDC_D4"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_5, "SPDC_D5"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_6, "SPDC_D6"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_7, "SPDC_D7"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "SPDC_D0"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "SPDC_D1"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "SPDC_D2"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "SPDC_D3"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "SPDC_D4"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "SPDC_D5"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "SPDC_D6"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "SPDC_D7"); - ret |= gpio_request(MX6SL_ARM2_EPDC_GDOE, "SIPIX_YOE"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_9, "SIPIX_PWR_RDY"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "SIPIX_YOE"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_9, "SIPIX_PWR_RDY"); - ret |= gpio_request(MX6SL_ARM2_EPDC_GDSP, "SIPIX_YDIO"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "SIPIX_YDIO"); - ret |= gpio_request(MX6SL_ARM2_EPDC_GDCLK, "SIPIX_YCLK"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDSHR, "SIPIX_XDIO"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "SIPIX_YCLK"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "SIPIX_XDIO"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDLE, "SIPIX_LD"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDCE1, "SIPIX_SOE"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "SIPIX_LD"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "SIPIX_SOE"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDCLK, "SIPIX_XCLK"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_10, "SIPIX_SHD_N"); - ret |= gpio_request(MX6SL_ARM2_EPDC_SDCE0, "SIPIX2_CE"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "SIPIX_XCLK"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_10, "SIPIX_SHD_N"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "SIPIX2_CE"); return ret; } static void spdc_put_pins(void) { - gpio_free(MX6SL_ARM2_EPDC_SDDO_0); - gpio_free(MX6SL_ARM2_EPDC_SDDO_1); - gpio_free(MX6SL_ARM2_EPDC_SDDO_2); - gpio_free(MX6SL_ARM2_EPDC_SDDO_3); - gpio_free(MX6SL_ARM2_EPDC_SDDO_4); - gpio_free(MX6SL_ARM2_EPDC_SDDO_5); - gpio_free(MX6SL_ARM2_EPDC_SDDO_6); - gpio_free(MX6SL_ARM2_EPDC_SDDO_7); - - gpio_free(MX6SL_ARM2_EPDC_GDOE); - gpio_free(MX6SL_ARM2_EPDC_SDDO_9); - gpio_free(MX6SL_ARM2_EPDC_GDSP); - gpio_free(MX6SL_ARM2_EPDC_GDCLK); - gpio_free(MX6SL_ARM2_EPDC_SDSHR); - gpio_free(MX6SL_ARM2_EPDC_SDLE); - gpio_free(MX6SL_ARM2_EPDC_SDCE1); - gpio_free(MX6SL_ARM2_EPDC_SDCLK); - gpio_free(MX6SL_ARM2_EPDC_SDDO_10); - gpio_free(MX6SL_ARM2_EPDC_SDCE0); + gpio_free(MX6SL_BRD_EPDC_SDDO_0); + gpio_free(MX6SL_BRD_EPDC_SDDO_1); + gpio_free(MX6SL_BRD_EPDC_SDDO_2); + gpio_free(MX6SL_BRD_EPDC_SDDO_3); + gpio_free(MX6SL_BRD_EPDC_SDDO_4); + gpio_free(MX6SL_BRD_EPDC_SDDO_5); + gpio_free(MX6SL_BRD_EPDC_SDDO_6); + gpio_free(MX6SL_BRD_EPDC_SDDO_7); + + gpio_free(MX6SL_BRD_EPDC_GDOE); + gpio_free(MX6SL_BRD_EPDC_SDDO_9); + gpio_free(MX6SL_BRD_EPDC_GDSP); + gpio_free(MX6SL_BRD_EPDC_GDCLK); + gpio_free(MX6SL_BRD_EPDC_SDSHR); + gpio_free(MX6SL_BRD_EPDC_SDLE); + gpio_free(MX6SL_BRD_EPDC_SDCE1); + gpio_free(MX6SL_BRD_EPDC_SDCLK); + gpio_free(MX6SL_BRD_EPDC_SDDO_10); + gpio_free(MX6SL_BRD_EPDC_SDCE0); } static void spdc_enable_pins(void) { /* Configure MUX settings to enable SPDC use */ - mxc_iomux_v3_setup_multiple_pads(mx6sl_arm2_spdc_enable_pads, \ - ARRAY_SIZE(mx6sl_arm2_spdc_enable_pads)); - - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_0); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_1); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_2); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_3); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_4); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_5); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_6); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_7); - gpio_direction_input(MX6SL_ARM2_EPDC_GDOE); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_9); - gpio_direction_input(MX6SL_ARM2_EPDC_GDSP); - gpio_direction_input(MX6SL_ARM2_EPDC_GDCLK); - gpio_direction_input(MX6SL_ARM2_EPDC_SDSHR); - gpio_direction_input(MX6SL_ARM2_EPDC_SDLE); - gpio_direction_input(MX6SL_ARM2_EPDC_SDCE1); - gpio_direction_input(MX6SL_ARM2_EPDC_SDCLK); - gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_10); - gpio_direction_input(MX6SL_ARM2_EPDC_SDCE0); + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_enable_pads, \ + ARRAY_SIZE(mx6sl_brd_spdc_enable_pads)); + + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7); + gpio_direction_input(MX6SL_BRD_EPDC_GDOE); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_9); + gpio_direction_input(MX6SL_BRD_EPDC_GDSP); + gpio_direction_input(MX6SL_BRD_EPDC_GDCLK); + gpio_direction_input(MX6SL_BRD_EPDC_SDSHR); + gpio_direction_input(MX6SL_BRD_EPDC_SDLE); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE1); + gpio_direction_input(MX6SL_BRD_EPDC_SDCLK); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_10); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE0); } static void spdc_disable_pins(void) { /* Configure MUX settings for SPDC pins to * GPIO and drive to 0. */ - mxc_iomux_v3_setup_multiple_pads(mx6sl_arm2_spdc_disable_pads, \ - ARRAY_SIZE(mx6sl_arm2_spdc_disable_pads)); - - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_0, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_1, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_2, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_3, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_4, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_5, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_6, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_7, 0); - - gpio_direction_output(MX6SL_ARM2_EPDC_GDOE, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_9, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_GDSP, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_GDCLK, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDSHR, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDLE, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDCE1, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDCLK, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_10, 0); - gpio_direction_output(MX6SL_ARM2_EPDC_SDCE0, 0); + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_disable_pads, \ + ARRAY_SIZE(mx6sl_brd_spdc_disable_pads)); + + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0); + + gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_9, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_10, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0); } static struct imx_spdc_panel_init_set spdc_init_set = { @@ -1105,9 +1048,9 @@ static void setup_spdc(void) static void imx6_arm2_usbotg_vbus(bool on) { if (on) - gpio_set_value(MX6_ARM2_USBOTG1_PWR, 1); + gpio_set_value(MX6_BRD_USBOTG1_PWR, 1); else - gpio_set_value(MX6_ARM2_USBOTG1_PWR, 0); + gpio_set_value(MX6_BRD_USBOTG1_PWR, 0); } static void __init mx6_arm2_init_usb(void) @@ -1120,19 +1063,19 @@ static void __init mx6_arm2_init_usb(void) * or it will affect signal quality at dp. */ - ret = gpio_request(MX6_ARM2_USBOTG1_PWR, "usbotg-pwr"); + ret = gpio_request(MX6_BRD_USBOTG1_PWR, "usbotg-pwr"); if (ret) { - pr_err("failed to get GPIO MX6_ARM2_USBOTG1_PWR:%d\n", ret); + pr_err("failed to get GPIO MX6_BRD_USBOTG1_PWR:%d\n", ret); return; } - gpio_direction_output(MX6_ARM2_USBOTG1_PWR, 0); + gpio_direction_output(MX6_BRD_USBOTG1_PWR, 0); - ret = gpio_request(MX6_ARM2_USBOTG2_PWR, "usbh1-pwr"); + ret = gpio_request(MX6_BRD_USBOTG2_PWR, "usbh1-pwr"); if (ret) { - pr_err("failed to get GPIO MX6_ARM2_USBOTG2_PWR:%d\n", ret); + pr_err("failed to get GPIO MX6_BRD_USBOTG2_PWR:%d\n", ret); return; } - gpio_direction_output(MX6_ARM2_USBOTG2_PWR, 1); + gpio_direction_output(MX6_BRD_USBOTG2_PWR, 1); mx6_set_otghost_vbus_func(imx6_arm2_usbotg_vbus); mx6_usb_dr_init(); @@ -1197,23 +1140,23 @@ static const struct matrix_keymap_data mx6sl_arm2_map_data __initconst = { }; static void __init elan_ts_init(void) { - mxc_iomux_v3_setup_multiple_pads(mx6sl_arm2_elan_pads, - ARRAY_SIZE(mx6sl_arm2_elan_pads)); + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_elan_pads, + ARRAY_SIZE(mx6sl_brd_elan_pads)); /* ELAN Touchscreen */ - gpio_request(MX6SL_ARM2_ELAN_INT, "elan-interrupt"); - gpio_direction_input(MX6SL_ARM2_ELAN_INT); + gpio_request(MX6SL_BRD_ELAN_INT, "elan-interrupt"); + gpio_direction_input(MX6SL_BRD_ELAN_INT); - gpio_request(MX6SL_ARM2_ELAN_CE, "elan-cs"); - gpio_direction_output(MX6SL_ARM2_ELAN_CE, 1); - gpio_direction_output(MX6SL_ARM2_ELAN_CE, 0); + gpio_request(MX6SL_BRD_ELAN_CE, "elan-cs"); + gpio_direction_output(MX6SL_BRD_ELAN_CE, 1); + gpio_direction_output(MX6SL_BRD_ELAN_CE, 0); - gpio_request(MX6SL_ARM2_ELAN_RST, "elan-rst"); - gpio_direction_output(MX6SL_ARM2_ELAN_RST, 1); - gpio_direction_output(MX6SL_ARM2_ELAN_RST, 0); + gpio_request(MX6SL_BRD_ELAN_RST, "elan-rst"); + gpio_direction_output(MX6SL_BRD_ELAN_RST, 1); + gpio_direction_output(MX6SL_BRD_ELAN_RST, 0); mdelay(1); - gpio_direction_output(MX6SL_ARM2_ELAN_RST, 1); - gpio_direction_output(MX6SL_ARM2_ELAN_CE, 1); + gpio_direction_output(MX6SL_BRD_ELAN_RST, 1); + gpio_direction_output(MX6SL_BRD_ELAN_CE, 1); } #define SNVS_LPCR 0x38 @@ -1232,7 +1175,8 @@ static void mx6_snvs_poweroff(void) */ static void __init mx6_arm2_init(void) { - mxc_iomux_v3_setup_multiple_pads(mx6sl_arm2_pads, ARRAY_SIZE(mx6sl_arm2_pads)); + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_pads, + ARRAY_SIZE(mx6sl_brd_pads)); elan_ts_init(); @@ -1285,8 +1229,8 @@ static void __init mx6_arm2_init(void) imx6q_add_mxc_pwm_backlight(0, &mx6_arm2_pwm_backlight_data); imx6dl_add_imx_elcdif(&fb_data[0]); - gpio_request(MX6_ARM2_LCD_PWR_EN, "elcdif-power-on"); - gpio_direction_output(MX6_ARM2_LCD_PWR_EN, 1); + gpio_request(MX6_BRD_LCD_PWR_EN, "elcdif-power-on"); + gpio_direction_output(MX6_BRD_LCD_PWR_EN, 1); mxc_register_device(&lcd_wvga_device, NULL); imx6dl_add_imx_pxp(); diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.h b/arch/arm/mach-mx6/board-mx6sl_arm2.h deleted file mode 100755 index 09a211690029..000000000000 --- a/arch/arm/mach-mx6/board-mx6sl_arm2.h +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -#ifndef _BOARD_MX6SL_ARM2_H -#define _BOARD_MX6SL_ARM2_H -#include - -static iomux_v3_cfg_t mx6sl_arm2_pads[] = { - - /* AUDMUX */ - MX6SL_PAD_AUD_TXC__AUDMUX_AUD3_TXC, - MX6SL_PAD_AUD_TXD__AUDMUX_AUD3_TXD, - MX6SL_PAD_AUD_TXFS__AUDMUX_AUD3_TXFS, - MX6SL_PAD_AUD_RXD__AUDMUX_AUD3_RXD, - MX6SL_PAD_AUD_MCLK__AUDMUX_AUDIO_CLK_OUT, - - /* Audio Codec */ - MX6SL_PAD_FEC_RX_ER__GPIO_4_19, /* HEADPHONE_DET */ - - /* UART1 */ - MX6SL_PAD_UART1_RXD__UART1_RXD, - MX6SL_PAD_UART1_TXD__UART1_TXD, - - /* USBOTG ID pin */ - MX6SL_PAD_EPDC_PWRCOM__ANATOP_USBOTG1_ID, - - /* USBOTG POWER GPIO */ - MX6SL_PAD_KEY_COL4__GPIO_4_0, - MX6SL_PAD_KEY_COL5__GPIO_4_2, - /* USB OC pin */ - MX6SL_PAD_KEY_ROW4__USB_USBOTG1_OC, - MX6SL_PAD_ECSPI2_SCLK__USB_USBOTG2_OC, - /* USB HSIC pin */ - MX6SL_PAD_HSIC_STROBE__USB_H_STROBE, - MX6SL_PAD_HSIC_DAT__USB_H_DATA, - - /* SD1 */ - MX6SL_PAD_SD1_CLK__USDHC1_CLK_50MHZ, - MX6SL_PAD_SD1_CMD__USDHC1_CMD_50MHZ, - MX6SL_PAD_SD1_DAT0__USDHC1_DAT0_50MHZ, - MX6SL_PAD_SD1_DAT1__USDHC1_DAT1_50MHZ, - MX6SL_PAD_SD1_DAT2__USDHC1_DAT2_50MHZ, - MX6SL_PAD_SD1_DAT3__USDHC1_DAT3_50MHZ, - MX6SL_PAD_SD1_DAT4__USDHC1_DAT4_50MHZ, - MX6SL_PAD_SD1_DAT5__USDHC1_DAT5_50MHZ, - MX6SL_PAD_SD1_DAT6__USDHC1_DAT6_50MHZ, - MX6SL_PAD_SD1_DAT7__USDHC1_DAT7_50MHZ, - /* SD1 CD & WP */ - MX6SL_PAD_KEY_ROW7__GPIO_4_7, - MX6SL_PAD_KEY_COL7__GPIO_4_6, - /* SD2 */ - MX6SL_PAD_SD2_CLK__USDHC2_CLK_50MHZ, - MX6SL_PAD_SD2_CMD__USDHC2_CMD_50MHZ, - MX6SL_PAD_SD2_DAT0__USDHC2_DAT0_50MHZ, - MX6SL_PAD_SD2_DAT1__USDHC2_DAT1_50MHZ, - MX6SL_PAD_SD2_DAT2__USDHC2_DAT2_50MHZ, - MX6SL_PAD_SD2_DAT3__USDHC2_DAT3_50MHZ, - /* SD2 CD & WP */ - MX6SL_PAD_SD2_DAT7__GPIO_5_0, - MX6SL_PAD_SD2_DAT6__GPIO_4_29, - /* SD3 */ - MX6SL_PAD_SD3_CLK__USDHC3_CLK_50MHZ, - MX6SL_PAD_SD3_CMD__USDHC3_CMD_50MHZ, - MX6SL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ, - MX6SL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ, - MX6SL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ, - MX6SL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ, - /* SD3 CD */ - MX6SL_PAD_REF_CLK_32K__GPIO_3_22, - - /* FEC */ - MX6SL_PAD_FEC_MDC__FEC_MDC, - MX6SL_PAD_FEC_MDIO__FEC_MDIO, - MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT, /* clock from anatop */ - MX6SL_PAD_FEC_RX_ER__GPIO_4_19, - MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV, - MX6SL_PAD_FEC_RXD0__FEC_RDATA_0, - MX6SL_PAD_FEC_RXD1__FEC_RDATA_1, - MX6SL_PAD_FEC_TX_EN__FEC_TX_EN, - MX6SL_PAD_FEC_TXD0__FEC_TDATA_0, - MX6SL_PAD_FEC_TXD1__FEC_TDATA_1, - MX6SL_PAD_FEC_TX_CLK__GPIO_4_21, /* Phy power enable */ - - /* I2C */ - MX6SL_PAD_I2C1_SCL__I2C1_SCL, - MX6SL_PAD_I2C1_SDA__I2C1_SDA, - MX6SL_PAD_I2C2_SCL__I2C2_SCL, - MX6SL_PAD_I2C2_SDA__I2C2_SDA, - - /* ECSPI1 */ - MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO, - MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI, - MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK, - MX6SL_PAD_ECSPI1_SS0__ECSPI1_SS0, - MX6SL_PAD_ECSPI1_SS0__GPIO_4_11, /* SS0 */ - - /* LCD */ - MX6SL_PAD_LCD_CLK__LCDIF_CLK, - MX6SL_PAD_LCD_ENABLE__LCDIF_ENABLE, - MX6SL_PAD_LCD_HSYNC__LCDIF_HSYNC, - MX6SL_PAD_LCD_VSYNC__LCDIF_VSYNC, - MX6SL_PAD_LCD_RESET__LCDIF_RESET, - MX6SL_PAD_LCD_DAT0__LCDIF_DAT_0, - MX6SL_PAD_LCD_DAT1__LCDIF_DAT_1, - MX6SL_PAD_LCD_DAT2__LCDIF_DAT_2, - MX6SL_PAD_LCD_DAT3__LCDIF_DAT_3, - MX6SL_PAD_LCD_DAT4__LCDIF_DAT_4, - MX6SL_PAD_LCD_DAT5__LCDIF_DAT_5, - MX6SL_PAD_LCD_DAT6__LCDIF_DAT_6, - MX6SL_PAD_LCD_DAT7__LCDIF_DAT_7, - MX6SL_PAD_LCD_DAT8__LCDIF_DAT_8, - MX6SL_PAD_LCD_DAT9__LCDIF_DAT_9, - MX6SL_PAD_LCD_DAT10__LCDIF_DAT_10, - MX6SL_PAD_LCD_DAT11__LCDIF_DAT_11, - MX6SL_PAD_LCD_DAT12__LCDIF_DAT_12, - MX6SL_PAD_LCD_DAT13__LCDIF_DAT_13, - MX6SL_PAD_LCD_DAT14__LCDIF_DAT_14, - MX6SL_PAD_LCD_DAT15__LCDIF_DAT_15, - MX6SL_PAD_LCD_DAT16__LCDIF_DAT_16, - MX6SL_PAD_LCD_DAT17__LCDIF_DAT_17, - MX6SL_PAD_LCD_DAT18__LCDIF_DAT_18, - MX6SL_PAD_LCD_DAT19__LCDIF_DAT_19, - MX6SL_PAD_LCD_DAT20__LCDIF_DAT_20, - MX6SL_PAD_LCD_DAT21__LCDIF_DAT_21, - MX6SL_PAD_LCD_DAT22__LCDIF_DAT_22, - MX6SL_PAD_LCD_DAT23__LCDIF_DAT_23, - /* LCD brightness */ - MX6SL_PAD_PWM1__PWM1_PWMO, - /* LCD power on */ - MX6SL_PAD_KEY_ROW5__GPIO_4_3, - - /* keypad on E-Ink add-on board */ - MX6SL_PAD_KEY_COL0__KPP_COL_0, - MX6SL_PAD_KEY_COL1__KPP_COL_1, - MX6SL_PAD_KEY_COL2__KPP_COL_2, - MX6SL_PAD_KEY_COL3__KPP_COL_3, - MX6SL_PAD_KEY_ROW0__KPP_ROW_0, - MX6SL_PAD_KEY_ROW1__KPP_ROW_1, - MX6SL_PAD_KEY_ROW2__KPP_ROW_2, - MX6SL_PAD_KEY_ROW3__KPP_ROW_3, - - /* WDOG */ - MX6SL_PAD_WDOG_B__WDOG1_WDOG_B, -}; - -static iomux_v3_cfg_t mx6sl_arm2_epdc_enable_pads[] = { - /* EPDC */ - MX6SL_PAD_EPDC_D0__EPDC_SDDO_0, - MX6SL_PAD_EPDC_D1__EPDC_SDDO_1, - MX6SL_PAD_EPDC_D2__EPDC_SDDO_2, - MX6SL_PAD_EPDC_D3__EPDC_SDDO_3, - MX6SL_PAD_EPDC_D4__EPDC_SDDO_4, - MX6SL_PAD_EPDC_D5__EPDC_SDDO_5, - MX6SL_PAD_EPDC_D6__EPDC_SDDO_6, - MX6SL_PAD_EPDC_D7__EPDC_SDDO_7, - MX6SL_PAD_EPDC_D8__EPDC_SDDO_8, - MX6SL_PAD_EPDC_D9__EPDC_SDDO_9, - MX6SL_PAD_EPDC_D10__EPDC_SDDO_10, - MX6SL_PAD_EPDC_D11__EPDC_SDDO_11, - MX6SL_PAD_EPDC_D12__EPDC_SDDO_12, - MX6SL_PAD_EPDC_D13__EPDC_SDDO_13, - MX6SL_PAD_EPDC_D14__EPDC_SDDO_14, - MX6SL_PAD_EPDC_D15__EPDC_SDDO_15, - - MX6SL_PAD_EPDC_GDCLK__EPDC_GDCLK, - MX6SL_PAD_EPDC_GDSP__EPDC_GDSP, - MX6SL_PAD_EPDC_GDOE__EPDC_GDOE, - MX6SL_PAD_EPDC_GDRL__EPDC_GDRL, - MX6SL_PAD_EPDC_SDCLK__EPDC_SDCLK, - MX6SL_PAD_EPDC_SDOE__EPDC_SDOE, - MX6SL_PAD_EPDC_SDLE__EPDC_SDLE, - MX6SL_PAD_EPDC_SDSHR__EPDC_SDSHR, - MX6SL_PAD_EPDC_BDR0__EPDC_BDR_0, - MX6SL_PAD_EPDC_SDCE0__EPDC_SDCE_0, - MX6SL_PAD_EPDC_SDCE1__EPDC_SDCE_1, - MX6SL_PAD_EPDC_SDCE2__EPDC_SDCE_2, - - /* EPD PMIC (Maxim 17135) pins */ - MX6SL_PAD_EPDC_VCOM0__GPIO_2_3, - MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13, - MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7, - MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14, -}; - -static iomux_v3_cfg_t mx6sl_arm2_epdc_disable_pads[] = { - /* EPDC */ - MX6SL_PAD_EPDC_D0__GPIO_1_7, - MX6SL_PAD_EPDC_D1__GPIO_1_8, - MX6SL_PAD_EPDC_D2__GPIO_1_9, - MX6SL_PAD_EPDC_D3__GPIO_1_10, - MX6SL_PAD_EPDC_D4__GPIO_1_11, - MX6SL_PAD_EPDC_D5__GPIO_1_12, - MX6SL_PAD_EPDC_D6__GPIO_1_13, - MX6SL_PAD_EPDC_D7__GPIO_1_14, - MX6SL_PAD_EPDC_D8__GPIO_1_15, - MX6SL_PAD_EPDC_D9__GPIO_1_16, - MX6SL_PAD_EPDC_D10__GPIO_1_17, - MX6SL_PAD_EPDC_D11__GPIO_1_18, - MX6SL_PAD_EPDC_D12__GPIO_1_19, - MX6SL_PAD_EPDC_D13__GPIO_1_20, - MX6SL_PAD_EPDC_D14__GPIO_1_21, - MX6SL_PAD_EPDC_D15__GPIO_1_22, - - MX6SL_PAD_EPDC_GDCLK__GPIO_1_31, - MX6SL_PAD_EPDC_GDSP__GPIO_2_2, - MX6SL_PAD_EPDC_GDOE__GPIO_2_0, - MX6SL_PAD_EPDC_GDRL__GPIO_2_1, - MX6SL_PAD_EPDC_SDCLK__GPIO_1_23, - MX6SL_PAD_EPDC_SDOE__GPIO_1_25, - MX6SL_PAD_EPDC_SDLE__GPIO_1_24, - MX6SL_PAD_EPDC_SDSHR__GPIO_1_26, - MX6SL_PAD_EPDC_BDR0__GPIO_2_5, - MX6SL_PAD_EPDC_SDCE0__GPIO_1_27, - MX6SL_PAD_EPDC_SDCE1__GPIO_1_28, - MX6SL_PAD_EPDC_SDCE2__GPIO_1_29, - - /* EPD PMIC (Maxim 17135) pins */ - MX6SL_PAD_EPDC_VCOM0__GPIO_2_3, - MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13, - MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7, - MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14, -}; - -static iomux_v3_cfg_t mx6sl_arm2_spdc_enable_pads[] = { - /* SPDC data*/ - MX6SL_PAD_EPDC_D0__TCON_E_DATA_0, - MX6SL_PAD_EPDC_D1__TCON_E_DATA_1, - MX6SL_PAD_EPDC_D2__TCON_E_DATA_2, - MX6SL_PAD_EPDC_D3__TCON_E_DATA_3, - MX6SL_PAD_EPDC_D4__TCON_E_DATA_4, - MX6SL_PAD_EPDC_D5__TCON_E_DATA_5, - MX6SL_PAD_EPDC_D6__TCON_E_DATA_6, - MX6SL_PAD_EPDC_D7__TCON_E_DATA_7, - - MX6SL_PAD_EPDC_GDOE__TCON_YOEL, /* AUO panel SIPIX_YOE */ - - MX6SL_PAD_EPDC_D9__TCON_E_DATA_9, /* AUO panel SIPIX_PWR_RDY*/ - - MX6SL_PAD_EPDC_SDCE2__TCON_YDIOUR, /* AUO panel SIPIX_YDIO */ - MX6SL_PAD_EPDC_SDCE3__TCON_YDIODR, /* AUO panel SIPIX_YDIO */ - MX6SL_PAD_EPDC_GDRL__TCON_YDIOUL, /* AUO panel SIPIX_YDIO */ - MX6SL_PAD_EPDC_GDSP__TCON_YDIODL, /* SIPIX_YDIO/SIPIX2_SPV */ - - MX6SL_PAD_EPDC_GDCLK__TCON_YCKL, /* SIPIX_YCLK/SIPIX2_CKV */ - - MX6SL_PAD_EPDC_SDSHR__TCON_XDIOR, /* AUO panel SIPIX_XDIO */ - MX6SL_PAD_EPDC_SDOE__TCON_XDIOL, /* SIPIX_XDIO/SIPIX2_OE */ - - MX6SL_PAD_EPDC_SDLE__TCON_LD, /* SIPIX_LD/SIPIX2_LE */ - - MX6SL_PAD_EPDC_SDCE1__TCON_YOER, /* AUO panel SIPIX_SOE */ - MX6SL_PAD_EPDC_BDR0__TCON_RL, /* AUO panel SIPIX_SOE */ - MX6SL_PAD_EPDC_BDR1__TCON_UD, /* AUO panel SIPIX_SOE */ - - MX6SL_PAD_EPDC_SDCLK__TCON_CL, /* SIPIX_XCLK/SIPIX2_CL */ - - MX6SL_PAD_EPDC_D10__TCON_E_DATA_10, /* AUO panel SIPIX_SHD_N */ - - MX6SL_PAD_EPDC_SDCE0__TCON_YCKR, /* LG panel SIPIX2_CE */ - - /* EPD PMIC (Maxim 17135) pins */ - MX6SL_PAD_EPDC_VCOM0__GPIO_2_3, /* PMICA_CEN */ - MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13, - MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7, - MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14, -}; - -static iomux_v3_cfg_t mx6sl_arm2_spdc_disable_pads[] = { - MX6SL_PAD_EPDC_D0__GPIO_1_7, - MX6SL_PAD_EPDC_D1__GPIO_1_8, - MX6SL_PAD_EPDC_D2__GPIO_1_9, - MX6SL_PAD_EPDC_D3__GPIO_1_10, - MX6SL_PAD_EPDC_D4__GPIO_1_11, - MX6SL_PAD_EPDC_D5__GPIO_1_12, - MX6SL_PAD_EPDC_D6__GPIO_1_13, - MX6SL_PAD_EPDC_D7__GPIO_1_14, - - MX6SL_PAD_EPDC_SDCE1__GPIO_1_28, - MX6SL_PAD_EPDC_GDOE__GPIO_2_0, - MX6SL_PAD_EPDC_D9__GPIO_1_16, - MX6SL_PAD_EPDC_SDCE2__GPIO_1_29, - MX6SL_PAD_EPDC_SDCE3__GPIO_1_30, - MX6SL_PAD_EPDC_GDRL__GPIO_2_1, - MX6SL_PAD_EPDC_GDSP__GPIO_2_2, - MX6SL_PAD_EPDC_GDCLK__GPIO_1_31, - MX6SL_PAD_EPDC_SDSHR__GPIO_1_26, - MX6SL_PAD_EPDC_SDOE__GPIO_1_25, - MX6SL_PAD_EPDC_SDLE__GPIO_1_24, - MX6SL_PAD_EPDC_SDCE1__GPIO_1_28, - MX6SL_PAD_EPDC_BDR0__GPIO_2_5, - MX6SL_PAD_EPDC_BDR1__GPIO_2_6, - MX6SL_PAD_EPDC_SDCLK__GPIO_1_23, - MX6SL_PAD_EPDC_D10__GPIO_1_17, - MX6SL_PAD_EPDC_SDCE0__GPIO_1_27, - - /* EPD PMIC (Maxim 17135) pins */ - MX6SL_PAD_EPDC_VCOM0__GPIO_2_3, - MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13, - MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7, - MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14, -}; - -static iomux_v3_cfg_t mx6sl_arm2_elan_pads[] = { - MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10, /* INT */ - MX6SL_PAD_EPDC_PWRCTRL2__GPIO_2_9, /* CE */ - MX6SL_PAD_KEY_COL6__GPIO_4_4, /* RST */ -}; - -#define MX6SL_USDHC_8BIT_PAD_SETTING(id, speed) \ -mx6sl_sd##id##_##speed##mhz[] = { \ - MX6SL_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \ - MX6SL_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \ - MX6SL_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \ - MX6SL_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \ - MX6SL_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \ - MX6SL_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \ - MX6SL_PAD_SD##id##_DAT4__USDHC##id##_DAT4_##speed##MHZ, \ - MX6SL_PAD_SD##id##_DAT5__USDHC##id##_DAT5_##speed##MHZ, \ - MX6SL_PAD_SD##id##_DAT6__USDHC##id##_DAT6_##speed##MHZ, \ - MX6SL_PAD_SD##id##_DAT7__USDHC##id##_DAT7_##speed##MHZ, \ -} -#define MX6SL_USDHC_4BIT_PAD_SETTING(id, speed) \ -mx6sl_sd##id##_##speed##mhz[] = { \ - MX6SL_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \ - MX6SL_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \ - MX6SL_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \ - MX6SL_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \ - MX6SL_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \ - MX6SL_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \ -} - - -static iomux_v3_cfg_t MX6SL_USDHC_8BIT_PAD_SETTING(1, 50); -static iomux_v3_cfg_t MX6SL_USDHC_8BIT_PAD_SETTING(1, 100); -static iomux_v3_cfg_t MX6SL_USDHC_8BIT_PAD_SETTING(1, 200); -static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(2, 50); -static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(2, 100); -static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(2, 200); -static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(3, 50); -static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(3, 100); -static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(3, 200); - -#endif diff --git a/arch/arm/mach-mx6/board-mx6sl_common.h b/arch/arm/mach-mx6/board-mx6sl_common.h new file mode 100644 index 000000000000..d005e02cb6ac --- /dev/null +++ b/arch/arm/mach-mx6/board-mx6sl_common.h @@ -0,0 +1,415 @@ +/* + * Copyright (C) 2012 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. + */ + +#ifndef _BOARD_MX6SL_COMMON_H +#define _BOARD_MX6SL_COMMON_H +#include + +#define MX6_BRD_USBOTG1_PWR IMX_GPIO_NR(4, 0) /* KEY_COL4 */ +#define MX6_BRD_USBOTG2_PWR IMX_GPIO_NR(4, 2) /* KEY_COL5 */ +#define MX6_BRD_LCD_PWR_EN IMX_GPIO_NR(4, 3) /* KEY_ROW5 */ +#define MX6_BRD_SD1_WP IMX_GPIO_NR(4, 6) /* KEY_COL7 */ +#define MX6_BRD_SD1_CD IMX_GPIO_NR(4, 7) /* KEY_ROW7 */ +#define MX6_BRD_ECSPI1_CS0 IMX_GPIO_NR(4, 11) /* ECSPI1_SS0 */ +#define MX6_BRD_HEADPHONE_DET IMX_GPIO_NR(4, 19) /* FEC_RX_ER */ +#define MX6_BRD_SD2_WP IMX_GPIO_NR(4, 29) /* SD2_DAT6 */ +#define MX6_BRD_SD2_CD IMX_GPIO_NR(5, 0) /* SD2_DAT7 */ +#define MX6_BRD_SD3_CD IMX_GPIO_NR(3, 22) /* REF_CLK_32K */ +#define MX6_BRD_FEC_PWR_EN IMX_GPIO_NR(4, 21) /* FEC_TX_CLK */ + +/* EPDC GPIO pins */ +#define MX6SL_BRD_EPDC_SDDO_0 IMX_GPIO_NR(1, 7) +#define MX6SL_BRD_EPDC_SDDO_1 IMX_GPIO_NR(1, 8) +#define MX6SL_BRD_EPDC_SDDO_2 IMX_GPIO_NR(1, 9) +#define MX6SL_BRD_EPDC_SDDO_3 IMX_GPIO_NR(1, 10) +#define MX6SL_BRD_EPDC_SDDO_4 IMX_GPIO_NR(1, 11) +#define MX6SL_BRD_EPDC_SDDO_5 IMX_GPIO_NR(1, 12) +#define MX6SL_BRD_EPDC_SDDO_6 IMX_GPIO_NR(1, 13) +#define MX6SL_BRD_EPDC_SDDO_7 IMX_GPIO_NR(1, 14) +#define MX6SL_BRD_EPDC_SDDO_8 IMX_GPIO_NR(1, 15) +#define MX6SL_BRD_EPDC_SDDO_9 IMX_GPIO_NR(1, 16) +#define MX6SL_BRD_EPDC_SDDO_10 IMX_GPIO_NR(1, 17) +#define MX6SL_BRD_EPDC_SDDO_11 IMX_GPIO_NR(1, 18) +#define MX6SL_BRD_EPDC_SDDO_12 IMX_GPIO_NR(1, 19) +#define MX6SL_BRD_EPDC_SDDO_13 IMX_GPIO_NR(1, 20) +#define MX6SL_BRD_EPDC_SDDO_14 IMX_GPIO_NR(1, 21) +#define MX6SL_BRD_EPDC_SDDO_15 IMX_GPIO_NR(1, 22) +#define MX6SL_BRD_EPDC_GDCLK IMX_GPIO_NR(1, 31) +#define MX6SL_BRD_EPDC_GDSP IMX_GPIO_NR(2, 2) +#define MX6SL_BRD_EPDC_GDOE IMX_GPIO_NR(2, 0) +#define MX6SL_BRD_EPDC_GDRL IMX_GPIO_NR(2, 1) +#define MX6SL_BRD_EPDC_SDCLK IMX_GPIO_NR(1, 23) +#define MX6SL_BRD_EPDC_SDOE IMX_GPIO_NR(1, 25) +#define MX6SL_BRD_EPDC_SDLE IMX_GPIO_NR(1, 24) +#define MX6SL_BRD_EPDC_SDSHR IMX_GPIO_NR(1, 26) +#define MX6SL_BRD_EPDC_PWRCOM IMX_GPIO_NR(2, 11) +#define MX6SL_BRD_EPDC_PWRSTAT IMX_GPIO_NR(2, 13) +#define MX6SL_BRD_EPDC_PWRCTRL0 IMX_GPIO_NR(2, 7) +#define MX6SL_BRD_EPDC_PWRCTRL1 IMX_GPIO_NR(2, 8) +#define MX6SL_BRD_EPDC_PWRCTRL2 IMX_GPIO_NR(2, 9) +#define MX6SL_BRD_EPDC_PWRCTRL3 IMX_GPIO_NR(2, 10) +#define MX6SL_BRD_EPDC_BDR0 IMX_GPIO_NR(2, 5) +#define MX6SL_BRD_EPDC_BDR1 IMX_GPIO_NR(2, 6) +#define MX6SL_BRD_EPDC_SDCE0 IMX_GPIO_NR(1, 27) +#define MX6SL_BRD_EPDC_SDCE1 IMX_GPIO_NR(1, 28) +#define MX6SL_BRD_EPDC_SDCE2 IMX_GPIO_NR(1, 29) +#define MX6SL_BRD_EPDC_SDCE3 IMX_GPIO_NR(1, 30) +#define MX6SL_BRD_EPDC_PMIC_WAKE IMX_GPIO_NR(2, 14) /* EPDC_PWRWAKEUP */ +#define MX6SL_BRD_EPDC_PMIC_INT IMX_GPIO_NR(2, 12) /* EPDC_PWRINT */ +#define MX6SL_BRD_EPDC_VCOM IMX_GPIO_NR(2, 3) +/* ELAN TS */ +#define MX6SL_BRD_ELAN_CE IMX_GPIO_NR(2, 9) +#define MX6SL_BRD_ELAN_INT IMX_GPIO_NR(2, 10) +#define MX6SL_BRD_ELAN_RST IMX_GPIO_NR(4, 4) + +static iomux_v3_cfg_t mx6sl_brd_pads[] = { + + /* AUDMUX */ + MX6SL_PAD_AUD_TXC__AUDMUX_AUD3_TXC, + MX6SL_PAD_AUD_TXD__AUDMUX_AUD3_TXD, + MX6SL_PAD_AUD_TXFS__AUDMUX_AUD3_TXFS, + MX6SL_PAD_AUD_RXD__AUDMUX_AUD3_RXD, + MX6SL_PAD_AUD_MCLK__AUDMUX_AUDIO_CLK_OUT, + + /* Audio Codec */ + MX6SL_PAD_FEC_RX_ER__GPIO_4_19, /* HEADPHONE_DET */ + + /* UART1 */ + MX6SL_PAD_UART1_RXD__UART1_RXD, + MX6SL_PAD_UART1_TXD__UART1_TXD, + + /* USBOTG ID pin */ + MX6SL_PAD_EPDC_PWRCOM__ANATOP_USBOTG1_ID, + + /* USBOTG POWER GPIO */ + MX6SL_PAD_KEY_COL4__GPIO_4_0, + MX6SL_PAD_KEY_COL5__GPIO_4_2, + /* USB OC pin */ + MX6SL_PAD_KEY_ROW4__USB_USBOTG1_OC, + MX6SL_PAD_ECSPI2_SCLK__USB_USBOTG2_OC, + /* USB HSIC pin */ + MX6SL_PAD_HSIC_STROBE__USB_H_STROBE, + MX6SL_PAD_HSIC_DAT__USB_H_DATA, + + /* SD1 */ + MX6SL_PAD_SD1_CLK__USDHC1_CLK_50MHZ, + MX6SL_PAD_SD1_CMD__USDHC1_CMD_50MHZ, + MX6SL_PAD_SD1_DAT0__USDHC1_DAT0_50MHZ, + MX6SL_PAD_SD1_DAT1__USDHC1_DAT1_50MHZ, + MX6SL_PAD_SD1_DAT2__USDHC1_DAT2_50MHZ, + MX6SL_PAD_SD1_DAT3__USDHC1_DAT3_50MHZ, + MX6SL_PAD_SD1_DAT4__USDHC1_DAT4_50MHZ, + MX6SL_PAD_SD1_DAT5__USDHC1_DAT5_50MHZ, + MX6SL_PAD_SD1_DAT6__USDHC1_DAT6_50MHZ, + MX6SL_PAD_SD1_DAT7__USDHC1_DAT7_50MHZ, + /* SD1 CD & WP */ + MX6SL_PAD_KEY_ROW7__GPIO_4_7, + MX6SL_PAD_KEY_COL7__GPIO_4_6, + /* SD2 */ + MX6SL_PAD_SD2_CLK__USDHC2_CLK_50MHZ, + MX6SL_PAD_SD2_CMD__USDHC2_CMD_50MHZ, + MX6SL_PAD_SD2_DAT0__USDHC2_DAT0_50MHZ, + MX6SL_PAD_SD2_DAT1__USDHC2_DAT1_50MHZ, + MX6SL_PAD_SD2_DAT2__USDHC2_DAT2_50MHZ, + MX6SL_PAD_SD2_DAT3__USDHC2_DAT3_50MHZ, + /* SD2 CD & WP */ + MX6SL_PAD_SD2_DAT7__GPIO_5_0, + MX6SL_PAD_SD2_DAT6__GPIO_4_29, + /* SD3 */ + MX6SL_PAD_SD3_CLK__USDHC3_CLK_50MHZ, + MX6SL_PAD_SD3_CMD__USDHC3_CMD_50MHZ, + MX6SL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ, + MX6SL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ, + MX6SL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ, + MX6SL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ, + /* SD3 CD */ + MX6SL_PAD_REF_CLK_32K__GPIO_3_22, + + /* FEC */ + MX6SL_PAD_FEC_MDC__FEC_MDC, + MX6SL_PAD_FEC_MDIO__FEC_MDIO, + MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT, /* clock from anatop */ + MX6SL_PAD_FEC_RX_ER__GPIO_4_19, + MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV, + MX6SL_PAD_FEC_RXD0__FEC_RDATA_0, + MX6SL_PAD_FEC_RXD1__FEC_RDATA_1, + MX6SL_PAD_FEC_TX_EN__FEC_TX_EN, + MX6SL_PAD_FEC_TXD0__FEC_TDATA_0, + MX6SL_PAD_FEC_TXD1__FEC_TDATA_1, + MX6SL_PAD_FEC_TX_CLK__GPIO_4_21, /* Phy power enable */ + + /* I2C */ + MX6SL_PAD_I2C1_SCL__I2C1_SCL, + MX6SL_PAD_I2C1_SDA__I2C1_SDA, + MX6SL_PAD_I2C2_SCL__I2C2_SCL, + MX6SL_PAD_I2C2_SDA__I2C2_SDA, + + /* ECSPI1 */ + MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO, + MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI, + MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK, + MX6SL_PAD_ECSPI1_SS0__ECSPI1_SS0, + MX6SL_PAD_ECSPI1_SS0__GPIO_4_11, /* SS0 */ + + /* LCD */ + MX6SL_PAD_LCD_CLK__LCDIF_CLK, + MX6SL_PAD_LCD_ENABLE__LCDIF_ENABLE, + MX6SL_PAD_LCD_HSYNC__LCDIF_HSYNC, + MX6SL_PAD_LCD_VSYNC__LCDIF_VSYNC, + MX6SL_PAD_LCD_RESET__LCDIF_RESET, + MX6SL_PAD_LCD_DAT0__LCDIF_DAT_0, + MX6SL_PAD_LCD_DAT1__LCDIF_DAT_1, + MX6SL_PAD_LCD_DAT2__LCDIF_DAT_2, + MX6SL_PAD_LCD_DAT3__LCDIF_DAT_3, + MX6SL_PAD_LCD_DAT4__LCDIF_DAT_4, + MX6SL_PAD_LCD_DAT5__LCDIF_DAT_5, + MX6SL_PAD_LCD_DAT6__LCDIF_DAT_6, + MX6SL_PAD_LCD_DAT7__LCDIF_DAT_7, + MX6SL_PAD_LCD_DAT8__LCDIF_DAT_8, + MX6SL_PAD_LCD_DAT9__LCDIF_DAT_9, + MX6SL_PAD_LCD_DAT10__LCDIF_DAT_10, + MX6SL_PAD_LCD_DAT11__LCDIF_DAT_11, + MX6SL_PAD_LCD_DAT12__LCDIF_DAT_12, + MX6SL_PAD_LCD_DAT13__LCDIF_DAT_13, + MX6SL_PAD_LCD_DAT14__LCDIF_DAT_14, + MX6SL_PAD_LCD_DAT15__LCDIF_DAT_15, + MX6SL_PAD_LCD_DAT16__LCDIF_DAT_16, + MX6SL_PAD_LCD_DAT17__LCDIF_DAT_17, + MX6SL_PAD_LCD_DAT18__LCDIF_DAT_18, + MX6SL_PAD_LCD_DAT19__LCDIF_DAT_19, + MX6SL_PAD_LCD_DAT20__LCDIF_DAT_20, + MX6SL_PAD_LCD_DAT21__LCDIF_DAT_21, + MX6SL_PAD_LCD_DAT22__LCDIF_DAT_22, + MX6SL_PAD_LCD_DAT23__LCDIF_DAT_23, + /* LCD brightness */ + MX6SL_PAD_PWM1__PWM1_PWMO, + /* LCD power on */ + MX6SL_PAD_KEY_ROW5__GPIO_4_3, + + /* keypad on E-Ink add-on board */ + MX6SL_PAD_KEY_COL0__KPP_COL_0, + MX6SL_PAD_KEY_COL1__KPP_COL_1, + MX6SL_PAD_KEY_COL2__KPP_COL_2, + MX6SL_PAD_KEY_COL3__KPP_COL_3, + MX6SL_PAD_KEY_ROW0__KPP_ROW_0, + MX6SL_PAD_KEY_ROW1__KPP_ROW_1, + MX6SL_PAD_KEY_ROW2__KPP_ROW_2, + MX6SL_PAD_KEY_ROW3__KPP_ROW_3, + + /* WDOG */ + MX6SL_PAD_WDOG_B__WDOG1_WDOG_B, +}; + +static iomux_v3_cfg_t mx6sl_brd_epdc_enable_pads[] = { + /* EPDC */ + MX6SL_PAD_EPDC_D0__EPDC_SDDO_0, + MX6SL_PAD_EPDC_D1__EPDC_SDDO_1, + MX6SL_PAD_EPDC_D2__EPDC_SDDO_2, + MX6SL_PAD_EPDC_D3__EPDC_SDDO_3, + MX6SL_PAD_EPDC_D4__EPDC_SDDO_4, + MX6SL_PAD_EPDC_D5__EPDC_SDDO_5, + MX6SL_PAD_EPDC_D6__EPDC_SDDO_6, + MX6SL_PAD_EPDC_D7__EPDC_SDDO_7, + MX6SL_PAD_EPDC_D8__EPDC_SDDO_8, + MX6SL_PAD_EPDC_D9__EPDC_SDDO_9, + MX6SL_PAD_EPDC_D10__EPDC_SDDO_10, + MX6SL_PAD_EPDC_D11__EPDC_SDDO_11, + MX6SL_PAD_EPDC_D12__EPDC_SDDO_12, + MX6SL_PAD_EPDC_D13__EPDC_SDDO_13, + MX6SL_PAD_EPDC_D14__EPDC_SDDO_14, + MX6SL_PAD_EPDC_D15__EPDC_SDDO_15, + + MX6SL_PAD_EPDC_GDCLK__EPDC_GDCLK, + MX6SL_PAD_EPDC_GDSP__EPDC_GDSP, + MX6SL_PAD_EPDC_GDOE__EPDC_GDOE, + MX6SL_PAD_EPDC_GDRL__EPDC_GDRL, + MX6SL_PAD_EPDC_SDCLK__EPDC_SDCLK, + MX6SL_PAD_EPDC_SDOE__EPDC_SDOE, + MX6SL_PAD_EPDC_SDLE__EPDC_SDLE, + MX6SL_PAD_EPDC_SDSHR__EPDC_SDSHR, + MX6SL_PAD_EPDC_BDR0__EPDC_BDR_0, + MX6SL_PAD_EPDC_SDCE0__EPDC_SDCE_0, + MX6SL_PAD_EPDC_SDCE1__EPDC_SDCE_1, + MX6SL_PAD_EPDC_SDCE2__EPDC_SDCE_2, + + /* EPD PMIC (Maxim 17135) pins */ + MX6SL_PAD_EPDC_VCOM0__GPIO_2_3, + MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13, + MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7, + MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14, +}; + +static iomux_v3_cfg_t mx6sl_brd_epdc_disable_pads[] = { + /* EPDC */ + MX6SL_PAD_EPDC_D0__GPIO_1_7, + MX6SL_PAD_EPDC_D1__GPIO_1_8, + MX6SL_PAD_EPDC_D2__GPIO_1_9, + MX6SL_PAD_EPDC_D3__GPIO_1_10, + MX6SL_PAD_EPDC_D4__GPIO_1_11, + MX6SL_PAD_EPDC_D5__GPIO_1_12, + MX6SL_PAD_EPDC_D6__GPIO_1_13, + MX6SL_PAD_EPDC_D7__GPIO_1_14, + MX6SL_PAD_EPDC_D8__GPIO_1_15, + MX6SL_PAD_EPDC_D9__GPIO_1_16, + MX6SL_PAD_EPDC_D10__GPIO_1_17, + MX6SL_PAD_EPDC_D11__GPIO_1_18, + MX6SL_PAD_EPDC_D12__GPIO_1_19, + MX6SL_PAD_EPDC_D13__GPIO_1_20, + MX6SL_PAD_EPDC_D14__GPIO_1_21, + MX6SL_PAD_EPDC_D15__GPIO_1_22, + + MX6SL_PAD_EPDC_GDCLK__GPIO_1_31, + MX6SL_PAD_EPDC_GDSP__GPIO_2_2, + MX6SL_PAD_EPDC_GDOE__GPIO_2_0, + MX6SL_PAD_EPDC_GDRL__GPIO_2_1, + MX6SL_PAD_EPDC_SDCLK__GPIO_1_23, + MX6SL_PAD_EPDC_SDOE__GPIO_1_25, + MX6SL_PAD_EPDC_SDLE__GPIO_1_24, + MX6SL_PAD_EPDC_SDSHR__GPIO_1_26, + MX6SL_PAD_EPDC_BDR0__GPIO_2_5, + MX6SL_PAD_EPDC_SDCE0__GPIO_1_27, + MX6SL_PAD_EPDC_SDCE1__GPIO_1_28, + MX6SL_PAD_EPDC_SDCE2__GPIO_1_29, + + /* EPD PMIC (Maxim 17135) pins */ + MX6SL_PAD_EPDC_VCOM0__GPIO_2_3, + MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13, + MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7, + MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14, +}; + +static iomux_v3_cfg_t mx6sl_brd_spdc_enable_pads[] = { + /* SPDC data*/ + MX6SL_PAD_EPDC_D0__TCON_E_DATA_0, + MX6SL_PAD_EPDC_D1__TCON_E_DATA_1, + MX6SL_PAD_EPDC_D2__TCON_E_DATA_2, + MX6SL_PAD_EPDC_D3__TCON_E_DATA_3, + MX6SL_PAD_EPDC_D4__TCON_E_DATA_4, + MX6SL_PAD_EPDC_D5__TCON_E_DATA_5, + MX6SL_PAD_EPDC_D6__TCON_E_DATA_6, + MX6SL_PAD_EPDC_D7__TCON_E_DATA_7, + + MX6SL_PAD_EPDC_GDOE__TCON_YOEL, /* AUO panel SIPIX_YOE */ + + MX6SL_PAD_EPDC_D9__TCON_E_DATA_9, /* AUO panel SIPIX_PWR_RDY*/ + + MX6SL_PAD_EPDC_SDCE2__TCON_YDIOUR, /* AUO panel SIPIX_YDIO */ + MX6SL_PAD_EPDC_SDCE3__TCON_YDIODR, /* AUO panel SIPIX_YDIO */ + MX6SL_PAD_EPDC_GDRL__TCON_YDIOUL, /* AUO panel SIPIX_YDIO */ + MX6SL_PAD_EPDC_GDSP__TCON_YDIODL, /* SIPIX_YDIO/SIPIX2_SPV */ + + MX6SL_PAD_EPDC_GDCLK__TCON_YCKL, /* SIPIX_YCLK/SIPIX2_CKV */ + + MX6SL_PAD_EPDC_SDSHR__TCON_XDIOR, /* AUO panel SIPIX_XDIO */ + MX6SL_PAD_EPDC_SDOE__TCON_XDIOL, /* SIPIX_XDIO/SIPIX2_OE */ + + MX6SL_PAD_EPDC_SDLE__TCON_LD, /* SIPIX_LD/SIPIX2_LE */ + + MX6SL_PAD_EPDC_SDCE1__TCON_YOER, /* AUO panel SIPIX_SOE */ + MX6SL_PAD_EPDC_BDR0__TCON_RL, /* AUO panel SIPIX_SOE */ + MX6SL_PAD_EPDC_BDR1__TCON_UD, /* AUO panel SIPIX_SOE */ + + MX6SL_PAD_EPDC_SDCLK__TCON_CL, /* SIPIX_XCLK/SIPIX2_CL */ + + MX6SL_PAD_EPDC_D10__TCON_E_DATA_10, /* AUO panel SIPIX_SHD_N */ + + MX6SL_PAD_EPDC_SDCE0__TCON_YCKR, /* LG panel SIPIX2_CE */ + + /* EPD PMIC (Maxim 17135) pins */ + MX6SL_PAD_EPDC_VCOM0__GPIO_2_3, /* PMICA_CEN */ + MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13, + MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7, + MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14, +}; + +static iomux_v3_cfg_t mx6sl_brd_spdc_disable_pads[] = { + MX6SL_PAD_EPDC_D0__GPIO_1_7, + MX6SL_PAD_EPDC_D1__GPIO_1_8, + MX6SL_PAD_EPDC_D2__GPIO_1_9, + MX6SL_PAD_EPDC_D3__GPIO_1_10, + MX6SL_PAD_EPDC_D4__GPIO_1_11, + MX6SL_PAD_EPDC_D5__GPIO_1_12, + MX6SL_PAD_EPDC_D6__GPIO_1_13, + MX6SL_PAD_EPDC_D7__GPIO_1_14, + + MX6SL_PAD_EPDC_SDCE1__GPIO_1_28, + MX6SL_PAD_EPDC_GDOE__GPIO_2_0, + MX6SL_PAD_EPDC_D9__GPIO_1_16, + MX6SL_PAD_EPDC_SDCE2__GPIO_1_29, + MX6SL_PAD_EPDC_SDCE3__GPIO_1_30, + MX6SL_PAD_EPDC_GDRL__GPIO_2_1, + MX6SL_PAD_EPDC_GDSP__GPIO_2_2, + MX6SL_PAD_EPDC_GDCLK__GPIO_1_31, + MX6SL_PAD_EPDC_SDSHR__GPIO_1_26, + MX6SL_PAD_EPDC_SDOE__GPIO_1_25, + MX6SL_PAD_EPDC_SDLE__GPIO_1_24, + MX6SL_PAD_EPDC_SDCE1__GPIO_1_28, + MX6SL_PAD_EPDC_BDR0__GPIO_2_5, + MX6SL_PAD_EPDC_BDR1__GPIO_2_6, + MX6SL_PAD_EPDC_SDCLK__GPIO_1_23, + MX6SL_PAD_EPDC_D10__GPIO_1_17, + MX6SL_PAD_EPDC_SDCE0__GPIO_1_27, + + /* EPD PMIC (Maxim 17135) pins */ + MX6SL_PAD_EPDC_VCOM0__GPIO_2_3, + MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13, + MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7, + MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14, +}; + +static iomux_v3_cfg_t mx6sl_brd_elan_pads[] = { + MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10, /* INT */ + MX6SL_PAD_EPDC_PWRCTRL2__GPIO_2_9, /* CE */ + MX6SL_PAD_KEY_COL6__GPIO_4_4, /* RST */ +}; + +#define MX6SL_USDHC_8BIT_PAD_SETTING(id, speed) \ +mx6sl_sd##id##_##speed##mhz[] = { \ + MX6SL_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \ + MX6SL_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \ + MX6SL_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \ + MX6SL_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \ + MX6SL_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \ + MX6SL_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \ + MX6SL_PAD_SD##id##_DAT4__USDHC##id##_DAT4_##speed##MHZ, \ + MX6SL_PAD_SD##id##_DAT5__USDHC##id##_DAT5_##speed##MHZ, \ + MX6SL_PAD_SD##id##_DAT6__USDHC##id##_DAT6_##speed##MHZ, \ + MX6SL_PAD_SD##id##_DAT7__USDHC##id##_DAT7_##speed##MHZ, \ +} +#define MX6SL_USDHC_4BIT_PAD_SETTING(id, speed) \ +mx6sl_sd##id##_##speed##mhz[] = { \ + MX6SL_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \ + MX6SL_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \ + MX6SL_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \ + MX6SL_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \ + MX6SL_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \ + MX6SL_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \ +} + + +static iomux_v3_cfg_t MX6SL_USDHC_8BIT_PAD_SETTING(1, 50); +static iomux_v3_cfg_t MX6SL_USDHC_8BIT_PAD_SETTING(1, 100); +static iomux_v3_cfg_t MX6SL_USDHC_8BIT_PAD_SETTING(1, 200); +static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(2, 50); +static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(2, 100); +static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(2, 200); +static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(3, 50); +static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(3, 100); +static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(3, 200); + +#endif diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c new file mode 100644 index 000000000000..3f42a0eeb4df --- /dev/null +++ b/arch/arm/mach-mx6/board-mx6sl_evk.c @@ -0,0 +1,1300 @@ +/* + * Copyright (C) 2012 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "usb.h" +#include "devices-imx6q.h" +#include "crm_regs.h" +#include "cpu_op-mx6.h" +#include "board-mx6sl_common.h" + + +static int spdc_sel; +static int max17135_regulator_init(struct max17135 *max17135); +struct clk *extern_audio_root; + +extern char *gp_reg_id; +extern char *soc_reg_id; +extern char *pu_reg_id; +extern int __init mx6sl_evk_init_pfuze100(u32 int_gpio); + +enum sd_pad_mode { + SD_PAD_MODE_LOW_SPEED, + SD_PAD_MODE_MED_SPEED, + SD_PAD_MODE_HIGH_SPEED, +}; + +static int plt_sd_pad_change(unsigned int index, int clock) +{ + /* LOW speed is the default state of SD pads */ + static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED; + + iomux_v3_cfg_t *sd_pads_200mhz = NULL; + iomux_v3_cfg_t *sd_pads_100mhz = NULL; + iomux_v3_cfg_t *sd_pads_50mhz = NULL; + + u32 sd_pads_200mhz_cnt; + u32 sd_pads_100mhz_cnt; + u32 sd_pads_50mhz_cnt; + + switch (index) { + case 0: + sd_pads_200mhz = mx6sl_sd1_200mhz; + sd_pads_100mhz = mx6sl_sd1_100mhz; + sd_pads_50mhz = mx6sl_sd1_50mhz; + + sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd1_200mhz); + sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd1_100mhz); + sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd1_50mhz); + break; + case 1: + sd_pads_200mhz = mx6sl_sd2_200mhz; + sd_pads_100mhz = mx6sl_sd2_100mhz; + sd_pads_50mhz = mx6sl_sd2_50mhz; + + sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd2_200mhz); + sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd2_100mhz); + sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd2_50mhz); + break; + case 2: + sd_pads_200mhz = mx6sl_sd3_200mhz; + sd_pads_100mhz = mx6sl_sd3_100mhz; + sd_pads_50mhz = mx6sl_sd3_50mhz; + + sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd3_200mhz); + sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd3_100mhz); + sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd3_50mhz); + break; + default: + printk(KERN_ERR "no such SD host controller index %d\n", index); + return -EINVAL; + } + + if (clock > 100000000) { + if (pad_mode == SD_PAD_MODE_HIGH_SPEED) + return 0; + BUG_ON(!sd_pads_200mhz); + pad_mode = SD_PAD_MODE_HIGH_SPEED; + return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz, + sd_pads_200mhz_cnt); + } else if (clock > 52000000) { + if (pad_mode == SD_PAD_MODE_MED_SPEED) + return 0; + BUG_ON(!sd_pads_100mhz); + pad_mode = SD_PAD_MODE_MED_SPEED; + return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz, + sd_pads_100mhz_cnt); + } else { + if (pad_mode == SD_PAD_MODE_LOW_SPEED) + return 0; + BUG_ON(!sd_pads_50mhz); + pad_mode = SD_PAD_MODE_LOW_SPEED; + return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz, + sd_pads_50mhz_cnt); + } +} + +static const struct esdhc_platform_data mx6_evk_sd1_data __initconst = { + .cd_gpio = MX6_BRD_SD1_CD, + .wp_gpio = MX6_BRD_SD1_WP, + .support_8bit = 1, + .support_18v = 1, + .keep_power_at_suspend = 1, + .delay_line = 0, + .platform_pad_change = plt_sd_pad_change, +}; + +static const struct esdhc_platform_data mx6_evk_sd2_data __initconst = { + .cd_gpio = MX6_BRD_SD2_CD, + .wp_gpio = MX6_BRD_SD2_WP, + .keep_power_at_suspend = 1, + .delay_line = 0, + .support_18v = 1, + .platform_pad_change = plt_sd_pad_change, +}; + +static const struct esdhc_platform_data mx6_evk_sd3_data __initconst = { + .cd_gpio = MX6_BRD_SD3_CD, + .wp_gpio = -1, + .keep_power_at_suspend = 1, + .delay_line = 0, + .support_18v = 1, + .platform_pad_change = plt_sd_pad_change, +}; + +#define mV_to_uV(mV) (mV * 1000) +#define uV_to_mV(uV) (uV / 1000) +#define V_to_uV(V) (mV_to_uV(V * 1000)) +#define uV_to_V(uV) (uV_to_mV(uV) / 1000) + +static struct regulator_consumer_supply evk_vmmc_consumers[] = { + REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.0"), + REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"), + REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.2"), +}; + +static struct regulator_init_data evk_vmmc_init = { + .num_consumer_supplies = ARRAY_SIZE(evk_vmmc_consumers), + .consumer_supplies = evk_vmmc_consumers, +}; + +static struct fixed_voltage_config evk_vmmc_reg_config = { + .supply_name = "vmmc", + .microvolts = 3300000, + .gpio = -1, + .init_data = &evk_vmmc_init, +}; + +static struct platform_device evk_vmmc_reg_devices = { + .name = "reg-fixed-voltage", + .id = 0, + .dev = { + .platform_data = &evk_vmmc_reg_config, + }, +}; + +static struct regulator_consumer_supply display_consumers[] = { + { + /* MAX17135 */ + .supply = "DISPLAY", + }, +}; + +static struct regulator_consumer_supply vcom_consumers[] = { + { + /* MAX17135 */ + .supply = "VCOM", + }, +}; + +static struct regulator_consumer_supply v3p3_consumers[] = { + { + /* MAX17135 */ + .supply = "V3P3", + }, +}; + +static struct regulator_init_data max17135_init_data[] = { + { + .constraints = { + .name = "DISPLAY", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(display_consumers), + .consumer_supplies = display_consumers, + }, { + .constraints = { + .name = "GVDD", + .min_uV = V_to_uV(20), + .max_uV = V_to_uV(20), + }, + }, { + .constraints = { + .name = "GVEE", + .min_uV = V_to_uV(-22), + .max_uV = V_to_uV(-22), + }, + }, { + .constraints = { + .name = "HVINN", + .min_uV = V_to_uV(-22), + .max_uV = V_to_uV(-22), + }, + }, { + .constraints = { + .name = "HVINP", + .min_uV = V_to_uV(20), + .max_uV = V_to_uV(20), + }, + }, { + .constraints = { + .name = "VCOM", + .min_uV = mV_to_uV(-4325), + .max_uV = mV_to_uV(-500), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(vcom_consumers), + .consumer_supplies = vcom_consumers, + }, { + .constraints = { + .name = "VNEG", + .min_uV = V_to_uV(-15), + .max_uV = V_to_uV(-15), + }, + }, { + .constraints = { + .name = "VPOS", + .min_uV = V_to_uV(15), + .max_uV = V_to_uV(15), + }, + }, { + .constraints = { + .name = "V3P3", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(v3p3_consumers), + .consumer_supplies = v3p3_consumers, + }, +}; + +static const struct anatop_thermal_platform_data + mx6sl_anatop_thermal_data __initconst = { + .name = "anatop_thermal", + }; + +static struct platform_device max17135_sensor_device = { + .name = "max17135_sensor", + .id = 0, +}; + +static struct max17135_platform_data max17135_pdata __initdata = { + .vneg_pwrup = 1, + .gvee_pwrup = 1, + .vpos_pwrup = 2, + .gvdd_pwrup = 1, + .gvdd_pwrdn = 1, + .vpos_pwrdn = 2, + .gvee_pwrdn = 1, + .vneg_pwrdn = 1, + .gpio_pmic_pwrgood = MX6SL_BRD_EPDC_PWRSTAT, + .gpio_pmic_vcom_ctrl = MX6SL_BRD_EPDC_VCOM, + .gpio_pmic_wakeup = MX6SL_BRD_EPDC_PMIC_WAKE, + .gpio_pmic_v3p3 = MX6SL_BRD_EPDC_PWRCTRL0, + .gpio_pmic_intr = MX6SL_BRD_EPDC_PMIC_INT, + .regulator_init = max17135_init_data, + .init = max17135_regulator_init, +}; + +static int __init max17135_regulator_init(struct max17135 *max17135) +{ + struct max17135_platform_data *pdata = &max17135_pdata; + int i, ret; + + max17135->gvee_pwrup = pdata->gvee_pwrup; + max17135->vneg_pwrup = pdata->vneg_pwrup; + max17135->vpos_pwrup = pdata->vpos_pwrup; + max17135->gvdd_pwrup = pdata->gvdd_pwrup; + max17135->gvdd_pwrdn = pdata->gvdd_pwrdn; + max17135->vpos_pwrdn = pdata->vpos_pwrdn; + max17135->vneg_pwrdn = pdata->vneg_pwrdn; + max17135->gvee_pwrdn = pdata->gvee_pwrdn; + + max17135->max_wait = pdata->vpos_pwrup + pdata->vneg_pwrup + + pdata->gvdd_pwrup + pdata->gvee_pwrup; + + max17135->gpio_pmic_pwrgood = pdata->gpio_pmic_pwrgood; + max17135->gpio_pmic_vcom_ctrl = pdata->gpio_pmic_vcom_ctrl; + max17135->gpio_pmic_wakeup = pdata->gpio_pmic_wakeup; + max17135->gpio_pmic_v3p3 = pdata->gpio_pmic_v3p3; + max17135->gpio_pmic_intr = pdata->gpio_pmic_intr; + + gpio_request(max17135->gpio_pmic_wakeup, "epdc-pmic-wake"); + gpio_direction_output(max17135->gpio_pmic_wakeup, 0); + + gpio_request(max17135->gpio_pmic_vcom_ctrl, "epdc-vcom"); + gpio_direction_output(max17135->gpio_pmic_vcom_ctrl, 0); + + gpio_request(max17135->gpio_pmic_v3p3, "epdc-v3p3"); + gpio_direction_output(max17135->gpio_pmic_v3p3, 0); + + gpio_request(max17135->gpio_pmic_intr, "epdc-pmic-int"); + gpio_direction_input(max17135->gpio_pmic_intr); + + gpio_request(max17135->gpio_pmic_pwrgood, "epdc-pwrstat"); + gpio_direction_input(max17135->gpio_pmic_pwrgood); + + max17135->vcom_setup = false; + max17135->init_done = false; + + for (i = 0; i < MAX17135_NUM_REGULATORS; i++) { + ret = max17135_register_regulator(max17135, i, + &pdata->regulator_init[i]); + if (ret != 0) { + printk(KERN_ERR"max17135 regulator init failed: %d\n", + ret); + return ret; + } + } + + /* + * TODO: We cannot enable full constraints for now, since + * it results in the PFUZE regulators being disabled + * at the end of boot, which disables critical regulators. + */ + /*regulator_has_full_constraints();*/ + + return 0; +} + +static int mx6_evk_spi_cs[] = { + MX6_BRD_ECSPI1_CS0, +}; + +static const struct spi_imx_master mx6_evk_spi_data __initconst = { + .chipselect = mx6_evk_spi_cs, + .num_chipselect = ARRAY_SIZE(mx6_evk_spi_cs), +}; + +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) +static struct mtd_partition m25p32_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = 0x00100000, + }, { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct flash_platform_data m25p32_spi_flash_data = { + .name = "m25p32", + .parts = m25p32_partitions, + .nr_parts = ARRAY_SIZE(m25p32_partitions), + .type = "m25p32", +}; + +static struct spi_board_info m25p32_spi0_board_info[] __initdata = { + { + /* The modalias must be the same as spi device driver name */ + .modalias = "m25p80", + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + .platform_data = &m25p32_spi_flash_data, + }, +}; +#endif + +static void spi_device_init(void) +{ +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) + spi_register_board_info(m25p32_spi0_board_info, + ARRAY_SIZE(m25p32_spi0_board_info)); +#endif +} + +static struct imx_ssi_platform_data mx6_sabresd_ssi_pdata = { + .flags = IMX_SSI_DMA | IMX_SSI_SYN, +}; + +static struct mxc_audio_platform_data wm8962_data; + +static struct platform_device mx6_sabresd_audio_wm8962_device = { + .name = "imx-wm8962", +}; + +static struct wm8962_pdata wm8962_config_data = { + +}; + +static int wm8962_clk_enable(int enable) +{ + if (enable) + clk_enable(extern_audio_root); + else + clk_disable(extern_audio_root); + + return 0; +} + +static int mxc_wm8962_init(void) +{ + struct clk *pll4; + int rate; + + extern_audio_root = clk_get(NULL, "extern_audio_clk"); + if (IS_ERR(extern_audio_root)) { + pr_err("can't get extern_audio_root clock.\n"); + return PTR_ERR(extern_audio_root); + } + + pll4 = clk_get(NULL, "pll4"); + if (IS_ERR(pll4)) { + pr_err("can't get pll4 clock.\n"); + return PTR_ERR(pll4); + } + + clk_set_parent(extern_audio_root, pll4); + + rate = clk_round_rate(extern_audio_root, 26000000); + clk_set_rate(extern_audio_root, rate); + + wm8962_data.sysclk = rate; + + return 0; +} + +static struct mxc_audio_platform_data wm8962_data = { + .ssi_num = 1, + .src_port = 2, + .ext_port = 3, + .hp_gpio = MX6_BRD_HEADPHONE_DET, + .hp_active_low = 1, + .mic_gpio = -1, + .mic_active_low = 1, + .init = mxc_wm8962_init, + .clock_enable = wm8962_clk_enable, +}; + +static struct regulator_consumer_supply sabresd_vwm8962_consumers[] = { + REGULATOR_SUPPLY("SPKVDD1", "1-001a"), + REGULATOR_SUPPLY("SPKVDD2", "1-001a"), +}; + +static struct regulator_init_data sabresd_vwm8962_init = { + .constraints = { + .name = "SPKVDD", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(sabresd_vwm8962_consumers), + .consumer_supplies = sabresd_vwm8962_consumers, +}; + +static struct fixed_voltage_config sabresd_vwm8962_reg_config = { + .supply_name = "SPKVDD", + .microvolts = 4325000, + .gpio = -1, + .enabled_at_boot = 1, + .init_data = &sabresd_vwm8962_init, +}; + +static struct platform_device sabresd_vwm8962_reg_devices = { + .name = "reg-fixed-voltage", + .id = 4, + .dev = { + .platform_data = &sabresd_vwm8962_reg_config, + }, +}; + +static int __init imx6q_init_audio(void) +{ + platform_device_register(&sabresd_vwm8962_reg_devices); + mxc_register_device(&mx6_sabresd_audio_wm8962_device, + &wm8962_data); + imx6q_add_imx_ssi(1, &mx6_sabresd_ssi_pdata); + + return 0; +} + +static struct imxi2c_platform_data mx6_evk_i2c0_data = { + .bitrate = 100000, +}; + +static struct imxi2c_platform_data mx6_evk_i2c1_data = { + .bitrate = 100000, +}; + +static struct imxi2c_platform_data mx6_evk_i2c2_data = { + .bitrate = 400000, +}; + +static struct i2c_board_info mxc_i2c0_board_info[] __initdata = { + { + I2C_BOARD_INFO("max17135", 0x48), + .platform_data = &max17135_pdata, + }, { + I2C_BOARD_INFO("elan-touch", 0x10), + .irq = gpio_to_irq(MX6SL_BRD_ELAN_INT), + }, +}; + +static struct i2c_board_info mxc_i2c1_board_info[] __initdata = { + { + I2C_BOARD_INFO("wm8962", 0x1a), + .platform_data = &wm8962_config_data, + }, +}; + +static struct i2c_board_info mxc_i2c2_board_info[] __initdata = { + { + }, +}; + +static struct mxc_dvfs_platform_data mx6sl_evk_dvfscore_data = { + #ifdef CONFIG_MX6_INTER_LDO_BYPASS + .reg_id = "VDDCORE", + #else + .reg_id = "cpu_vddgp", + .soc_id = "cpu_vddsoc", + .pu_id = "cpu_vddvpu", + #endif + .clk1_id = "cpu_clk", + .clk2_id = "gpc_dvfs_clk", + .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET, + .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET, + .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET, + .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET, + .prediv_mask = 0x1F800, + .prediv_offset = 11, + .prediv_val = 3, + .div3ck_mask = 0xE0000000, + .div3ck_offset = 29, + .div3ck_val = 2, + .emac_val = 0x08, + .upthr_val = 25, + .dnthr_val = 9, + .pncthr_val = 33, + .upcnt_val = 10, + .dncnt_val = 10, + .delay_time = 80, +}; + +static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = { + .reserved_mem_size = SZ_128M, +}; + +void __init early_console_setup(unsigned long base, struct clk *clk); + +static inline void mx6_evk_init_uart(void) +{ + imx6q_add_imx_uart(0, NULL); /* DEBUG UART1 */ +} + +static int mx6sl_evk_fec_phy_init(struct phy_device *phydev) +{ + int val; + + /* power on FEC phy and reset phy */ + gpio_request(MX6_BRD_FEC_PWR_EN, "fec-pwr"); + gpio_direction_output(MX6_BRD_FEC_PWR_EN, 0); + /* wait RC ms for hw reset */ + msleep(1); + gpio_direction_output(MX6_BRD_FEC_PWR_EN, 1); + + /* check phy power */ + val = phy_read(phydev, 0x0); + if (val & BMCR_PDOWN) + phy_write(phydev, 0x0, (val & ~BMCR_PDOWN)); + + return 0; +} + +static struct fec_platform_data fec_data __initdata = { + .init = mx6sl_evk_fec_phy_init, + .phy = PHY_INTERFACE_MODE_RMII, +}; + +static int epdc_get_pins(void) +{ + int ret = 0; + + /* Claim GPIOs for EPDC pins - used during power up/down */ + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "epdc_d0"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "epdc_d1"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "epdc_d2"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "epdc_d3"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "epdc_d4"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "epdc_d5"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "epdc_d6"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "epdc_d7"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "epdc_gdclk"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "epdc_gdsp"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "epdc_gdoe"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDRL, "epdc_gdrl"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "epdc_sdclk"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDOE, "epdc_sdoe"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "epdc_sdle"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "epdc_sdshr"); + ret |= gpio_request(MX6SL_BRD_EPDC_BDR0, "epdc_bdr0"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "epdc_sdce0"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "epdc_sdce1"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE2, "epdc_sdce2"); + + return ret; +} + +static void epdc_put_pins(void) +{ + gpio_free(MX6SL_BRD_EPDC_SDDO_0); + gpio_free(MX6SL_BRD_EPDC_SDDO_1); + gpio_free(MX6SL_BRD_EPDC_SDDO_2); + gpio_free(MX6SL_BRD_EPDC_SDDO_3); + gpio_free(MX6SL_BRD_EPDC_SDDO_4); + gpio_free(MX6SL_BRD_EPDC_SDDO_5); + gpio_free(MX6SL_BRD_EPDC_SDDO_6); + gpio_free(MX6SL_BRD_EPDC_SDDO_7); + gpio_free(MX6SL_BRD_EPDC_GDCLK); + gpio_free(MX6SL_BRD_EPDC_GDSP); + gpio_free(MX6SL_BRD_EPDC_GDOE); + gpio_free(MX6SL_BRD_EPDC_GDRL); + gpio_free(MX6SL_BRD_EPDC_SDCLK); + gpio_free(MX6SL_BRD_EPDC_SDOE); + gpio_free(MX6SL_BRD_EPDC_SDLE); + gpio_free(MX6SL_BRD_EPDC_SDSHR); + gpio_free(MX6SL_BRD_EPDC_BDR0); + gpio_free(MX6SL_BRD_EPDC_SDCE0); + gpio_free(MX6SL_BRD_EPDC_SDCE1); + gpio_free(MX6SL_BRD_EPDC_SDCE2); +} + +static void epdc_enable_pins(void) +{ + /* Configure MUX settings to enable EPDC use */ + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_enable_pads, \ + ARRAY_SIZE(mx6sl_brd_epdc_enable_pads)); + + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7); + gpio_direction_input(MX6SL_BRD_EPDC_GDCLK); + gpio_direction_input(MX6SL_BRD_EPDC_GDSP); + gpio_direction_input(MX6SL_BRD_EPDC_GDOE); + gpio_direction_input(MX6SL_BRD_EPDC_GDRL); + gpio_direction_input(MX6SL_BRD_EPDC_SDCLK); + gpio_direction_input(MX6SL_BRD_EPDC_SDOE); + gpio_direction_input(MX6SL_BRD_EPDC_SDLE); + gpio_direction_input(MX6SL_BRD_EPDC_SDSHR); + gpio_direction_input(MX6SL_BRD_EPDC_BDR0); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE0); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE1); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE2); +} + +static void epdc_disable_pins(void) +{ + /* Configure MUX settings for EPDC pins to + * GPIO and drive to 0. */ + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_disable_pads, \ + ARRAY_SIZE(mx6sl_brd_epdc_disable_pads)); + + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDRL, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDOE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0); + gpio_direction_output(MX6SL_BRD_EPDC_BDR0, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE2, 0); +} + +static struct fb_videomode e60_v110_mode = { + .name = "E60_V110", + .refresh = 50, + .xres = 800, + .yres = 600, + .pixclock = 18604700, + .left_margin = 8, + .right_margin = 178, + .upper_margin = 4, + .lower_margin = 10, + .hsync_len = 20, + .vsync_len = 4, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, +}; +static struct fb_videomode e60_v220_mode = { + .name = "E60_V220", + .refresh = 85, + .xres = 800, + .yres = 600, + .pixclock = 30000000, + .left_margin = 8, + .right_margin = 164, + .upper_margin = 4, + .lower_margin = 8, + .hsync_len = 4, + .vsync_len = 1, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + .refresh = 85, + .xres = 800, + .yres = 600, +}; +static struct fb_videomode e060scm_mode = { + .name = "E060SCM", + .refresh = 85, + .xres = 800, + .yres = 600, + .pixclock = 26666667, + .left_margin = 8, + .right_margin = 100, + .upper_margin = 4, + .lower_margin = 8, + .hsync_len = 4, + .vsync_len = 1, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, +}; +static struct fb_videomode e97_v110_mode = { + .name = "E97_V110", + .refresh = 50, + .xres = 1200, + .yres = 825, + .pixclock = 32000000, + .left_margin = 12, + .right_margin = 128, + .upper_margin = 4, + .lower_margin = 10, + .hsync_len = 20, + .vsync_len = 4, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, +}; + +static struct imx_epdc_fb_mode panel_modes[] = { + { + &e60_v110_mode, + 4, /* vscan_holdoff */ + 10, /* sdoed_width */ + 20, /* sdoed_delay */ + 10, /* sdoez_width */ + 20, /* sdoez_delay */ + 428, /* gdclk_hp_offs */ + 20, /* gdsp_offs */ + 0, /* gdoe_offs */ + 1, /* gdclk_offs */ + 1, /* num_ce */ + }, + { + &e60_v220_mode, + 4, /* vscan_holdoff */ + 10, /* sdoed_width */ + 20, /* sdoed_delay */ + 10, /* sdoez_width */ + 20, /* sdoez_delay */ + 465, /* gdclk_hp_offs */ + 20, /* gdsp_offs */ + 0, /* gdoe_offs */ + 9, /* gdclk_offs */ + 1, /* num_ce */ + }, + { + &e060scm_mode, + 4, /* vscan_holdoff */ + 10, /* sdoed_width */ + 20, /* sdoed_delay */ + 10, /* sdoez_width */ + 20, /* sdoez_delay */ + 419, /* gdclk_hp_offs */ + 20, /* gdsp_offs */ + 0, /* gdoe_offs */ + 5, /* gdclk_offs */ + 1, /* num_ce */ + }, + { + &e97_v110_mode, + 8, /* vscan_holdoff */ + 10, /* sdoed_width */ + 20, /* sdoed_delay */ + 10, /* sdoez_width */ + 20, /* sdoez_delay */ + 632, /* gdclk_hp_offs */ + 20, /* gdsp_offs */ + 0, /* gdoe_offs */ + 1, /* gdclk_offs */ + 3, /* num_ce */ + } +}; + +static struct imx_epdc_fb_platform_data epdc_data = { + .epdc_mode = panel_modes, + .num_modes = ARRAY_SIZE(panel_modes), + .get_pins = epdc_get_pins, + .put_pins = epdc_put_pins, + .enable_pins = epdc_enable_pins, + .disable_pins = epdc_disable_pins, +}; + +static int spdc_get_pins(void) +{ + int ret = 0; + + /* Claim GPIOs for SPDC pins - used during power up/down */ + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "SPDC_D0"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "SPDC_D1"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "SPDC_D2"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "SPDC_D3"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "SPDC_D4"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "SPDC_D5"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "SPDC_D6"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "SPDC_D7"); + + ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "SIPIX_YOE"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_9, "SIPIX_PWR_RDY"); + + ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "SIPIX_YDIO"); + + ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "SIPIX_YCLK"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "SIPIX_XDIO"); + + ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "SIPIX_LD"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "SIPIX_SOE"); + + ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "SIPIX_XCLK"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_10, "SIPIX_SHD_N"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "SIPIX2_CE"); + + return ret; +} + +static void spdc_put_pins(void) +{ + gpio_free(MX6SL_BRD_EPDC_SDDO_0); + gpio_free(MX6SL_BRD_EPDC_SDDO_1); + gpio_free(MX6SL_BRD_EPDC_SDDO_2); + gpio_free(MX6SL_BRD_EPDC_SDDO_3); + gpio_free(MX6SL_BRD_EPDC_SDDO_4); + gpio_free(MX6SL_BRD_EPDC_SDDO_5); + gpio_free(MX6SL_BRD_EPDC_SDDO_6); + gpio_free(MX6SL_BRD_EPDC_SDDO_7); + + gpio_free(MX6SL_BRD_EPDC_GDOE); + gpio_free(MX6SL_BRD_EPDC_SDDO_9); + gpio_free(MX6SL_BRD_EPDC_GDSP); + gpio_free(MX6SL_BRD_EPDC_GDCLK); + gpio_free(MX6SL_BRD_EPDC_SDSHR); + gpio_free(MX6SL_BRD_EPDC_SDLE); + gpio_free(MX6SL_BRD_EPDC_SDCE1); + gpio_free(MX6SL_BRD_EPDC_SDCLK); + gpio_free(MX6SL_BRD_EPDC_SDDO_10); + gpio_free(MX6SL_BRD_EPDC_SDCE0); +} + +static void spdc_enable_pins(void) +{ + /* Configure MUX settings to enable SPDC use */ + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_enable_pads, \ + ARRAY_SIZE(mx6sl_brd_spdc_enable_pads)); + + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7); + gpio_direction_input(MX6SL_BRD_EPDC_GDOE); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_9); + gpio_direction_input(MX6SL_BRD_EPDC_GDSP); + gpio_direction_input(MX6SL_BRD_EPDC_GDCLK); + gpio_direction_input(MX6SL_BRD_EPDC_SDSHR); + gpio_direction_input(MX6SL_BRD_EPDC_SDLE); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE1); + gpio_direction_input(MX6SL_BRD_EPDC_SDCLK); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_10); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE0); +} + +static void spdc_disable_pins(void) +{ + /* Configure MUX settings for SPDC pins to + * GPIO and drive to 0. */ + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_disable_pads, \ + ARRAY_SIZE(mx6sl_brd_spdc_disable_pads)); + + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0); + + gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_9, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_10, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0); +} + +static struct imx_spdc_panel_init_set spdc_init_set = { + .yoe_pol = false, + .dual_gate = false, + .resolution = 0, + .ud = false, + .rl = false, + .data_filter_n = true, + .power_ready = true, + .rgbw_mode_enable = false, + .hburst_len_en = true, +}; + +static struct fb_videomode erk_1_4_a01 = { + .name = "ERK_1_4_A01", + .refresh = 50, + .xres = 800, + .yres = 600, + .pixclock = 40000000, + .vmode = FB_VMODE_NONINTERLACED, +}; + +static struct imx_spdc_fb_mode spdc_panel_modes[] = { + { + &erk_1_4_a01, + &spdc_init_set, + .wave_timing = "pvi" + }, +}; + +static struct imx_spdc_fb_platform_data spdc_data = { + .spdc_mode = spdc_panel_modes, + .num_modes = ARRAY_SIZE(spdc_panel_modes), + .get_pins = spdc_get_pins, + .put_pins = spdc_put_pins, + .enable_pins = spdc_enable_pins, + .disable_pins = spdc_disable_pins, +}; + +static int __init early_use_spdc_sel(char *p) +{ + spdc_sel = 1; + return 0; +} +early_param("spdc", early_use_spdc_sel); + +static void setup_spdc(void) +{ + /* GPR0[8]: 0:EPDC, 1:SPDC */ + if (spdc_sel) + mxc_iomux_set_gpr_register(0, 8, 1, 1); +} + +static void imx6_evk_usbotg_vbus(bool on) +{ + if (on) + gpio_set_value(MX6_BRD_USBOTG1_PWR, 1); + else + gpio_set_value(MX6_BRD_USBOTG1_PWR, 0); +} + +static void __init mx6_evk_init_usb(void) +{ + int ret = 0; + + imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR); + + /* disable external charger detect, + * or it will affect signal quality at dp. + */ + + ret = gpio_request(MX6_BRD_USBOTG1_PWR, "usbotg-pwr"); + if (ret) { + pr_err("failed to get GPIO MX6_BRD_USBOTG1_PWR:%d\n", ret); + return; + } + gpio_direction_output(MX6_BRD_USBOTG1_PWR, 0); + + ret = gpio_request(MX6_BRD_USBOTG2_PWR, "usbh1-pwr"); + if (ret) { + pr_err("failed to get GPIO MX6_BRD_USBOTG2_PWR:%d\n", ret); + return; + } + gpio_direction_output(MX6_BRD_USBOTG2_PWR, 1); + + mx6_set_otghost_vbus_func(imx6_evk_usbotg_vbus); + mx6_usb_dr_init(); +#ifdef CONFIG_USB_EHCI_ARC_HSIC + mx6_usb_h2_init(); +#endif +} + +static struct platform_pwm_backlight_data mx6_evk_pwm_backlight_data = { + .pwm_id = 0, + .max_brightness = 255, + .dft_brightness = 128, + .pwm_period_ns = 50000, +}; +static struct fb_videomode video_modes[] = { + { + /* 800x480 @ 57 Hz , pixel clk @ 32MHz */ + "SEIKO-WVGA", 60, 800, 480, 29850, 99, 164, 33, 10, 10, 10, + FB_SYNC_CLK_LAT_FALL, + FB_VMODE_NONINTERLACED, + 0,}, +}; + +static struct mxc_fb_platform_data fb_data[] = { + { + .interface_pix_fmt = V4L2_PIX_FMT_RGB24, + .mode_str = "SEIKO-WVGA", + .mode = video_modes, + .num_modes = ARRAY_SIZE(video_modes), + }, +}; + +static struct platform_device lcd_wvga_device = { + .name = "lcd_seiko", +}; + +static int mx6sl_evk_keymap[] = { + KEY(0, 0, KEY_SELECT), + KEY(0, 1, KEY_BACK), + KEY(0, 2, KEY_F1), + KEY(0, 3, KEY_F2), + + KEY(1, 0, KEY_F3), + KEY(1, 1, KEY_F4), + KEY(1, 2, KEY_F5), + KEY(1, 3, KEY_MENU), + + KEY(2, 0, KEY_PREVIOUS), + KEY(2, 1, KEY_NEXT), + KEY(2, 2, KEY_HOME), + KEY(2, 3, KEY_NEXT), + + KEY(3, 0, KEY_UP), + KEY(3, 1, KEY_LEFT), + KEY(3, 2, KEY_RIGHT), + KEY(3, 3, KEY_DOWN), +}; + +static const struct matrix_keymap_data mx6sl_evk_map_data __initconst = { + .keymap = mx6sl_evk_keymap, + .keymap_size = ARRAY_SIZE(mx6sl_evk_keymap), +}; +static void __init elan_ts_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_elan_pads, + ARRAY_SIZE(mx6sl_brd_elan_pads)); + + /* ELAN Touchscreen */ + gpio_request(MX6SL_BRD_ELAN_INT, "elan-interrupt"); + gpio_direction_input(MX6SL_BRD_ELAN_INT); + + gpio_request(MX6SL_BRD_ELAN_CE, "elan-cs"); + gpio_direction_output(MX6SL_BRD_ELAN_CE, 1); + gpio_direction_output(MX6SL_BRD_ELAN_CE, 0); + + gpio_request(MX6SL_BRD_ELAN_RST, "elan-rst"); + gpio_direction_output(MX6SL_BRD_ELAN_RST, 1); + gpio_direction_output(MX6SL_BRD_ELAN_RST, 0); + mdelay(1); + gpio_direction_output(MX6SL_BRD_ELAN_RST, 1); + gpio_direction_output(MX6SL_BRD_ELAN_CE, 1); +} + +#define SNVS_LPCR 0x38 +static void mx6_snvs_poweroff(void) +{ + u32 value; + void __iomem *mx6_snvs_base = MX6_IO_ADDRESS(MX6Q_SNVS_BASE_ADDR); + + value = readl(mx6_snvs_base + SNVS_LPCR); + /* set TOP and DP_EN bit */ + writel(value | 0x60, mx6_snvs_base + SNVS_LPCR); +} + +/*! + * Board specific initialization. + */ +static void __init mx6_evk_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_pads, + ARRAY_SIZE(mx6sl_brd_pads)); + + elan_ts_init(); + + #ifdef CONFIG_MX6_INTER_LDO_BYPASS + gp_reg_id = mx6sl_evk_dvfscore_data.reg_id; + #else + gp_reg_id = mx6sl_evk_dvfscore_data.reg_id; + soc_reg_id = mx6sl_evk_dvfscore_data.soc_id; + pu_reg_id = mx6sl_evk_dvfscore_data.pu_id; + mx6_cpu_regulator_init(); + #endif + + imx6q_add_imx_snvs_rtc(); + + imx6q_add_imx_i2c(0, &mx6_evk_i2c0_data); + imx6q_add_imx_i2c(1, &mx6_evk_i2c1_data); + i2c_register_board_info(0, mxc_i2c0_board_info, + ARRAY_SIZE(mxc_i2c0_board_info)); + i2c_register_board_info(1, mxc_i2c1_board_info, + ARRAY_SIZE(mxc_i2c1_board_info)); + imx6q_add_imx_i2c(2, &mx6_evk_i2c2_data); + i2c_register_board_info(2, mxc_i2c2_board_info, + ARRAY_SIZE(mxc_i2c2_board_info)); + + /* SPI */ + imx6q_add_ecspi(0, &mx6_evk_spi_data); + spi_device_init(); + + mx6sl_evk_init_pfuze100(0); + + imx6q_add_anatop_thermal_imx(1, &mx6sl_anatop_thermal_data); + + mx6_evk_init_uart(); + /* get enet tx reference clk from FEC_REF_CLK pad. + * GPR1[14] = 0, GPR1[18:17] = 00 + */ + mxc_iomux_set_gpr_register(1, 14, 1, 0); + mxc_iomux_set_gpr_register(1, 17, 2, 0); + + imx6_init_fec(fec_data); + + platform_device_register(&evk_vmmc_reg_devices); + imx6q_add_sdhci_usdhc_imx(0, &mx6_evk_sd1_data); + imx6q_add_sdhci_usdhc_imx(1, &mx6_evk_sd2_data); + imx6q_add_sdhci_usdhc_imx(2, &mx6_evk_sd3_data); + + mx6_evk_init_usb(); + imx6q_add_otp(); + imx6q_add_mxc_pwm(0); + imx6q_add_mxc_pwm_backlight(0, &mx6_evk_pwm_backlight_data); + imx6dl_add_imx_elcdif(&fb_data[0]); + + gpio_request(MX6_BRD_LCD_PWR_EN, "elcdif-power-on"); + gpio_direction_output(MX6_BRD_LCD_PWR_EN, 1); + mxc_register_device(&lcd_wvga_device, NULL); + + imx6dl_add_imx_pxp(); + imx6dl_add_imx_pxp_client(); + mxc_register_device(&max17135_sensor_device, NULL); + setup_spdc(); + if (!spdc_sel) + imx6dl_add_imx_epdc(&epdc_data); + else + imx6sl_add_imx_spdc(&spdc_data); + imx6q_add_dvfs_core(&mx6sl_evk_dvfscore_data); + + imx6q_init_audio(); + + imx6q_add_viim(); + imx6q_add_imx2_wdt(0, NULL); + + imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata); + imx6sl_add_imx_keypad(&mx6sl_evk_map_data); + imx6q_add_busfreq(); + imx6sl_add_dcp(); + imx6sl_add_rngb(); + + pm_power_off = mx6_snvs_poweroff; +} + +extern void __iomem *twd_base; +static void __init mx6_timer_init(void) +{ + struct clk *uart_clk; +#ifdef CONFIG_LOCAL_TIMERS + twd_base = ioremap(LOCAL_TWD_ADDR, SZ_256); + BUG_ON(!twd_base); +#endif + mx6sl_clocks_init(32768, 24000000, 0, 0); + + uart_clk = clk_get_sys("imx-uart.0", NULL); + early_console_setup(UART1_BASE_ADDR, uart_clk); +} + +static struct sys_timer mxc_timer = { + .init = mx6_timer_init, +}; + +static void __init mx6_evk_reserve(void) +{ +#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE) + phys_addr_t phys; + + if (imx6q_gpu_pdata.reserved_mem_size) { + phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size, + SZ_4K, MEMBLOCK_ALLOC_ACCESSIBLE); + memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size); + imx6q_gpu_pdata.reserved_mem_base = phys; + } +#endif +} + +MACHINE_START(MX6SL_EVK, "Freescale i.MX 6SoloLite EVK Board") + .boot_params = MX6SL_PHYS_OFFSET + 0x100, + .map_io = mx6_map_io, + .init_irq = mx6_init_irq, + .init_machine = mx6_evk_init, + .timer = &mxc_timer, + .reserve = mx6_evk_reserve, +MACHINE_END diff --git a/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c new file mode 100644 index 000000000000..7a74b1f34fd6 --- /dev/null +++ b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c @@ -0,0 +1,440 @@ +/* + * Copyright (C) 2012 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Convenience conversion. + * Here atm, maybe there is somewhere better for this. + */ +#define mV_to_uV(mV) (mV * 1000) +#define uV_to_mV(uV) (uV / 1000) +#define V_to_uV(V) (mV_to_uV(V * 1000)) +#define uV_to_V(uV) (uV_to_mV(uV) / 1000) + +#define PFUZE100_I2C_DEVICE_NAME "pfuze100" +/* 7-bit I2C bus slave address */ +#define PFUZE100_I2C_ADDR (0x08) + /*SWBST*/ +#define PFUZE100_SW1ASTANDBY 33 +#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x16) +#define PFUZE100_SW1ASTANDBY_STBY_M (0x3f<<0) +#define PFUZE100_SW1BSTANDBY 40 +#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x16) +#define PFUZE100_SW1BSTANDBY_STBY_M (0x3f<<0) +#define PFUZE100_SW1CSTANDBY 47 +#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x16) +#define PFUZE100_SW1CSTANDBY_STBY_M (0x3f<<0) +#define PFUZE100_SW2STANDBY 54 +#define PFUZE100_SW2STANDBY_STBY_VAL 0x0 +#define PFUZE100_SW2STANDBY_STBY_M (0x3f<<0) +#define PFUZE100_SW3ASTANDBY 61 +#define PFUZE100_SW3ASTANDBY_STBY_VAL 0x0 +#define PFUZE100_SW3ASTANDBY_STBY_M (0x3f<<0) +#define PFUZE100_SW3BSTANDBY 68 +#define PFUZE100_SW3BSTANDBY_STBY_VAL 0x0 +#define PFUZE100_SW3BSTANDBY_STBY_M (0x3f<<0) +#define PFUZE100_SW4STANDBY 75 +#define PFUZE100_SW4STANDBY_STBY_VAL 0 +#define PFUZE100_SW4STANDBY_STBY_M (0x3f<<0) +#define PFUZE100_SWBSTCON1 102 +#define PFUZE100_SWBSTCON1_SWBSTMOD_VAL (0x1<<2) +#define PFUZE100_SWBSTCON1_SWBSTMOD_M (0x3<<2) +#define PFUZE100_SW1ACON 36 +#define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */ +#define PFUZE100_SW1ACON_SPEED_M (0x3<<6) + + +#ifdef CONFIG_MX6_INTER_LDO_BYPASS +static struct regulator_consumer_supply sw1_consumers[] = { + { + .supply = "VDDCORE", + } +}; +#endif + +static struct regulator_consumer_supply sw2_consumers[] = { + { + .supply = "MICVDD", + .dev_name = "1-001a", + }, + { + .supply = "DBVDD", + .dev_name = "1-001a", + } + +}; +static struct regulator_consumer_supply sw4_consumers[] = { + { + .supply = "AUD_1V8", + } +}; +static struct regulator_consumer_supply swbst_consumers[] = { + { + .supply = "SWBST_5V", + } +}; +static struct regulator_consumer_supply vgen1_consumers[] = { + { + .supply = "VGEN1_1V5", + } +}; +static struct regulator_consumer_supply vgen2_consumers[] = { + { + .supply = "VGEN2_1V5", + } +}; +static struct regulator_consumer_supply vgen4_consumers[] = { + { + .supply = "AVDD", + .dev_name = "1-001a", + }, + { + .supply = "DCVDD", + .dev_name = "1-001a", + }, + { + .supply = "CPVDD", + .dev_name = "1-001a", + }, + { + .supply = "PLLVDD", + .dev_name = "1-001a", + } +}; +static struct regulator_consumer_supply vgen5_consumers[] = { + { + .supply = "VGEN5_2V8", + } +}; +static struct regulator_consumer_supply vgen6_consumers[] = { + { + .supply = "VGEN6_3V3", + } +}; + +static struct regulator_init_data sw1a_init = { + .constraints = { + .name = "PFUZE100_SW1A", +#ifdef PFUZE100_FIRST_VERSION + .min_uV = 650000, + .max_uV = 1437500, +#else + .min_uV = 300000, + .max_uV = 1875000, +#endif + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = 0, + .boot_on = 1, + .always_on = 1, + }, + #ifdef CONFIG_MX6_INTER_LDO_BYPASS + .num_consumer_supplies = ARRAY_SIZE(sw1_consumers), + .consumer_supplies = sw1_consumers, + #endif +}; + +static struct regulator_init_data sw1b_init = { + .constraints = { + .name = "PFUZE100_SW1B", + .min_uV = 300000, + .max_uV = 1875000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = 0, + .always_on = 1, + .boot_on = 1, + }, +}; + +static struct regulator_init_data sw1c_init = { + .constraints = { + .name = "PFUZE100_SW1C", + .min_uV = 300000, + .max_uV = 1875000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = 0, + .always_on = 1, + .boot_on = 1, + }, +}; + +static struct regulator_init_data sw2_init = { + .constraints = { + .name = "PFUZE100_SW2", +#if PFUZE100_SW2_VOL6 + .min_uV = 800000, + .max_uV = 3950000, +#else + .min_uV = 400000, + .max_uV = 1975000, +#endif + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = 0, + .always_on = 1, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(sw2_consumers), + .consumer_supplies = sw2_consumers, +}; + +static struct regulator_init_data sw3a_init = { + .constraints = { + .name = "PFUZE100_SW3A", +#if PFUZE100_SW3_VOL6 + .min_uV = 800000, + .max_uV = 3950000, +#else + .min_uV = 400000, + .max_uV = 1975000, +#endif + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = 0, + .always_on = 1, + .boot_on = 1, + }, +}; + +static struct regulator_init_data sw3b_init = { + .constraints = { + .name = "PFUZE100_SW3B", +#if PFUZE100_SW3_VOL6 + .min_uV = 800000, + .max_uV = 3950000, +#else + .min_uV = 400000, + .max_uV = 1975000, +#endif + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = 0, + .always_on = 1, + .boot_on = 1, + }, +}; + +static struct regulator_init_data sw4_init = { + .constraints = { + .name = "PFUZE100_SW4", +#if PFUZE100_SW4_VOL6 + .min_uV = 800000, + .max_uV = 3950000, +#else + .min_uV = 400000, + .max_uV = 1975000, +#endif + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = 0, + }, + .num_consumer_supplies = ARRAY_SIZE(sw4_consumers), + .consumer_supplies = sw4_consumers, +}; + +static struct regulator_init_data swbst_init = { + .constraints = { + .name = "PFUZE100_SWBST", + .min_uV = 5000000, + .max_uV = 5150000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = 0, + .always_on = 1, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(swbst_consumers), + .consumer_supplies = swbst_consumers, +}; + +static struct regulator_init_data vsnvs_init = { + .constraints = { + .name = "PFUZE100_VSNVS", + .min_uV = 1200000, + .max_uV = 3000000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = 0, + .always_on = 1, + .boot_on = 1, + }, +}; + +static struct regulator_init_data vrefddr_init = { + .constraints = { + .name = "PFUZE100_VREFDDR", + .always_on = 1, + .boot_on = 1, + }, +}; + +static struct regulator_init_data vgen1_init = { + .constraints = { + .name = "PFUZE100_VGEN1", +#ifdef PFUZE100_FIRST_VERSION + .min_uV = 1200000, + .max_uV = 1550000, +#else + .min_uV = 800000, + .max_uV = 1550000, +#endif + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .valid_modes_mask = 0, + .always_on = 0, + .boot_on = 0, + }, + .num_consumer_supplies = ARRAY_SIZE(vgen1_consumers), + .consumer_supplies = vgen1_consumers, +}; + +static struct regulator_init_data vgen2_init = { + .constraints = { + .name = "PFUZE100_VGEN2", +#ifdef PFUZE100_FIRST_VERSION + .min_uV = 1200000, + .max_uV = 1550000, +#else + .min_uV = 800000, + .max_uV = 1550000, +#endif + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .valid_modes_mask = 0, + }, + .num_consumer_supplies = ARRAY_SIZE(vgen2_consumers), + .consumer_supplies = vgen2_consumers, + +}; + +static struct regulator_init_data vgen3_init = { + .constraints = { + .name = "PFUZE100_VGEN3", + .min_uV = 1800000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .valid_modes_mask = 0, + .always_on = 0, + .boot_on = 0, + }, +}; + +static struct regulator_init_data vgen4_init = { + .constraints = { + .name = "PFUZE100_VGEN4", + .min_uV = 1800000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .valid_modes_mask = 0, + }, + .num_consumer_supplies = ARRAY_SIZE(vgen4_consumers), + .consumer_supplies = vgen4_consumers, +}; + +static struct regulator_init_data vgen5_init = { + .constraints = { + .name = "PFUZE100_VGEN5", + .min_uV = 1800000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .valid_modes_mask = 0, + }, + .num_consumer_supplies = ARRAY_SIZE(vgen5_consumers), + .consumer_supplies = vgen5_consumers, +}; + +static struct regulator_init_data vgen6_init = { + .constraints = { + .name = "PFUZE100_VGEN6", + .min_uV = 1800000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .valid_modes_mask = 0, + }, + .num_consumer_supplies = ARRAY_SIZE(vgen6_consumers), + .consumer_supplies = vgen6_consumers, +}; + +static int pfuze100_init(struct mc_pfuze *pfuze) +{ + int ret; + ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ASTANDBY, + PFUZE100_SW1ASTANDBY_STBY_M, + PFUZE100_SW1ASTANDBY_STBY_VAL); + if (ret) + goto err; + ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CSTANDBY, + PFUZE100_SW1CSTANDBY_STBY_M, + PFUZE100_SW1CSTANDBY_STBY_VAL); + if (ret) + goto err; + /*set SW1ABDVSPEED as 25mV step each 4us,quick than 16us before.*/ + ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ACON, + PFUZE100_SW1ACON_SPEED_M, + PFUZE100_SW1ACON_SPEED_VAL); + if (ret) + goto err; + return 0; +err: + printk(KERN_ERR "pfuze100 init error!\n"); + return -1; +} + +static struct pfuze_regulator_init_data mx6q_sabreauto_pfuze100_regulators[] = { + {.id = PFUZE100_SW1A, .init_data = &sw1a_init}, + {.id = PFUZE100_SW1B, .init_data = &sw1b_init}, + {.id = PFUZE100_SW1C, .init_data = &sw1c_init}, + {.id = PFUZE100_SW2, .init_data = &sw2_init}, + {.id = PFUZE100_SW3A, .init_data = &sw3a_init}, + {.id = PFUZE100_SW3B, .init_data = &sw3b_init}, + {.id = PFUZE100_SW4, .init_data = &sw4_init}, + {.id = PFUZE100_SWBST, .init_data = &swbst_init}, + {.id = PFUZE100_VSNVS, .init_data = &vsnvs_init}, + {.id = PFUZE100_VREFDDR, .init_data = &vrefddr_init}, + {.id = PFUZE100_VGEN1, .init_data = &vgen1_init}, + {.id = PFUZE100_VGEN2, .init_data = &vgen2_init}, + {.id = PFUZE100_VGEN3, .init_data = &vgen3_init}, + {.id = PFUZE100_VGEN4, .init_data = &vgen4_init}, + {.id = PFUZE100_VGEN5, .init_data = &vgen5_init}, + {.id = PFUZE100_VGEN6, .init_data = &vgen6_init}, +}; + +static struct pfuze_platform_data pfuze100_plat = { + .flags = PFUZE_USE_REGULATOR, + .num_regulators = ARRAY_SIZE(mx6q_sabreauto_pfuze100_regulators), + .regulators = mx6q_sabreauto_pfuze100_regulators, + .pfuze_init = pfuze100_init, +}; + +static struct i2c_board_info __initdata pfuze100_i2c_device = { + I2C_BOARD_INFO(PFUZE100_I2C_DEVICE_NAME, PFUZE100_I2C_ADDR), + .platform_data = &pfuze100_plat, +}; + +int __init mx6sl_evk_init_pfuze100(u32 int_gpio) +{ + if (int_gpio) + pfuze100_i2c_device.irq = gpio_to_irq(int_gpio); /*update INT gpio */ + return i2c_register_board_info(0, &pfuze100_i2c_device, 1); +} -- cgit v1.2.3 From 6198efbd51dd326018d7c0bd2a92cdd6d45d5f30 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Tue, 14 Aug 2012 18:33:45 +0800 Subject: ENGR00219872-1 MX6Q Sabresd iomux:Add LVDS CABC_EN0/1 support This patch configures NANDF_CS2/3 to be GPIO_6_15/16 to support LVDS CABC_EN0/1. Signed-off-by: Liu Ying (cherry picked from commit fdff66991738a56a7e1bc735cf452d57f1771c13) --- arch/arm/mach-mx6/board-mx6q_sabresd.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.h b/arch/arm/mach-mx6/board-mx6q_sabresd.h index 54ad3ac416b6..da26cd9e0c83 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabresd.h +++ b/arch/arm/mach-mx6/board-mx6q_sabresd.h @@ -259,6 +259,10 @@ static iomux_v3_cfg_t mx6q_sabresd_pads[] = { MX6Q_PAD_NANDF_CS0__GPIO_6_11, /* DISP_PWR_EN */ MX6Q_PAD_NANDF_CS1__GPIO_6_14, + /* CABC_EN0 */ + MX6Q_PAD_NANDF_CS2__GPIO_6_15, + /* CABC_EN1 */ + MX6Q_PAD_NANDF_CS3__GPIO_6_16, }; static iomux_v3_cfg_t mx6q_sabresd_csi0_sensor_pads[] = { -- cgit v1.2.3 From 692b4ca63b17df45af386b89ad6a31cf11fc17cb Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Tue, 14 Aug 2012 18:36:38 +0800 Subject: ENGR00219872-2 MX6Q SabreSD:Disable LVDS CABC function This patch sets CABC_EN0/1 to low to disable LVDS panel CABC function so that LVDS backlight will not be turned by the LVDS panel automatically so that we may avoid annoying unstable backlight issue. Signed-off-by: Rong Dian Signed-off-by: Liu Ying (cherry picked from commit a169940fb39216e644018304e3a3bdaca61ea88a) --- arch/arm/mach-mx6/board-mx6q_sabresd.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c index 429cffc6806a..b6b3be93196d 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabresd.c +++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c @@ -1779,6 +1779,17 @@ static void __init mx6_sabresd_board_init(void) imx_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_serial_clk"); imx6q_add_asrc(&imx_asrc_data); + /* + * Disable HannStar touch panel CABC function, + * this function turns the panel's backlight automatically + * according to the content shown on the panel which + * may cause annoying unstable backlight issue. + */ + gpio_request(SABRESD_CABC_EN0, "cabc-en0"); + gpio_direction_output(SABRESD_CABC_EN0, 0); + gpio_request(SABRESD_CABC_EN1, "cabc-en1"); + gpio_direction_output(SABRESD_CABC_EN1, 0); + imx6q_add_mxc_pwm(0); imx6q_add_mxc_pwm(1); imx6q_add_mxc_pwm(2); -- cgit v1.2.3 From 13cb1da51c62cc36e17e493b65bfac2c77fdb1cc Mon Sep 17 00:00:00 2001 From: Nancy Chen Date: Wed, 15 Aug 2012 20:53:15 -0500 Subject: ENGR00220497 [MX6Q, MX6DL]: Fix not able to set high bus freq Fix not able to set high bus frequency from low bus frequency. Signed-off-by: Nancy Chen --- arch/arm/mach-mx6/bus_freq.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index 83310c436d54..95edf0065207 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -134,6 +134,7 @@ static void reduce_bus_freq_handler(struct work_struct *work) clk_disable(pll2_400); clk_disable(pll3); + med_bus_freq_mode = 0; } else { arm_mem_clked_in_wait = true; -- cgit v1.2.3 From 33e9107f2805c515e239ce5312c5fd842b97b064 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Thu, 16 Aug 2012 02:45:11 +0800 Subject: ENGR00220388 [MX6]Adjust SOC/PU voltage according to datasheet SOC/PU voltage need to following some rules according to latest datasheet: 1. SOC/PU CAP voltage must be 1.15V <= SOC/PU <= 1.3V; 2. SOC and PU must be same as they don't have level shift; 3. Adjust previous wrong voltage setting. If SOC/PU voltage is too low, may cause system crash on some chips, we have a board that easily crash with GPU working and doing some tar operation, with this voltage adjust, this issue fixed. Signed-off-by: Anson Huang --- arch/arm/mach-mx6/cpu_op-mx6.c | 89 ++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 55 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c index 98181ceb3670..d0a7a42dfb85 100644 --- a/arch/arm/mach-mx6/cpu_op-mx6.c +++ b/arch/arm/mach-mx6/cpu_op-mx6.c @@ -36,22 +36,15 @@ static struct cpu_op mx6_cpu_op_1_2G[] = { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, - .pu_voltage = 1100000, - .soc_voltage = 1100000, + .pu_voltage = 1150000, + .soc_voltage = 1150000, .cpu_voltage = 1100000,}, -/* { - .pll_rate = 996000000, - .cpu_rate = 498000000, - .cpu_podf = 1, - .pu_voltage = 1100000, - .soc_voltage = 1100000, - .cpu_voltage = 1050000,},*/ { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1100000, - .soc_voltage = 1100000, + .pu_voltage = 1150000, + .soc_voltage = 1150000, .cpu_voltage = 925000,}, }; @@ -68,22 +61,15 @@ static struct cpu_op mx6_cpu_op_1G[] = { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, - .pu_voltage = 1100000, - .soc_voltage = 1100000, + .pu_voltage = 1150000, + .soc_voltage = 1150000, .cpu_voltage = 1100000,}, -/* { - .pll_rate = 996000000, - .cpu_rate = 498000000, - .cpu_podf = 1, - .pu_voltage = 1100000, - .soc_voltage = 1100000, - .cpu_voltage = 1050000,},*/ { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1100000, - .soc_voltage = 1100000, + .pu_voltage = 1150000, + .soc_voltage = 1150000, .cpu_voltage = 925000,}, }; @@ -92,22 +78,15 @@ static struct cpu_op mx6_cpu_op[] = { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, - .pu_voltage = 1100000, - .soc_voltage = 1100000, + .pu_voltage = 1150000, + .soc_voltage = 1150000, .cpu_voltage = 1100000,}, -/* { - .pll_rate = 996000000, - .cpu_rate = 498000000, - .cpu_podf = 1, - .pu_voltage = 1100000, - .soc_voltage = 1100000, - .cpu_voltage = 1050000,},*/ { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1100000, - .soc_voltage = 1100000, + .pu_voltage = 1150000, + .soc_voltage = 1150000, .cpu_voltage = 925000,}, }; @@ -124,22 +103,22 @@ static struct cpu_op mx6dl_cpu_op_1_2G[] = { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, - .pu_voltage = 1100000, - .soc_voltage = 1100000, - .cpu_voltage = 1125000,}, + .pu_voltage = 1150000, + .soc_voltage = 1150000, + .cpu_voltage = 1100000,}, { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1100000, - .soc_voltage = 1100000, + .pu_voltage = 1150000, + .soc_voltage = 1150000, .cpu_voltage = 1025000,}, { .pll_rate = 396000000, .cpu_rate = 198000000, .cpu_podf = 1, - .pu_voltage = 1100000, - .soc_voltage = 1100000, + .pu_voltage = 1150000, + .soc_voltage = 1150000, .cpu_voltage = 1025000,}, }; /* working point(wp): 0 - 1GHz; 1 - 800MHz, 2 - 400MHz, 3 - 200MHz */ @@ -155,22 +134,22 @@ static struct cpu_op mx6dl_cpu_op_1G[] = { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, - .pu_voltage = 1100000, - .soc_voltage = 1100000, - .cpu_voltage = 1125000,}, + .pu_voltage = 1150000, + .soc_voltage = 1150000, + .cpu_voltage = 1100000,}, { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1100000, - .soc_voltage = 1100000, + .pu_voltage = 1150000, + .soc_voltage = 1150000, .cpu_voltage = 1025000,}, { .pll_rate = 396000000, .cpu_rate = 198000000, .cpu_podf = 1, - .pu_voltage = 1100000, - .soc_voltage = 1100000, + .pu_voltage = 1150000, + .soc_voltage = 1150000, .cpu_voltage = 1025000,}, }; static struct cpu_op mx6dl_cpu_op[] = { @@ -178,23 +157,23 @@ static struct cpu_op mx6dl_cpu_op[] = { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, - .pu_voltage = 1100000, - .soc_voltage = 1100000, + .pu_voltage = 1150000, + .soc_voltage = 1150000, .cpu_voltage = 1100000,}, { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1100000, - .soc_voltage = 1100000, - .cpu_voltage = 1000000,}, + .pu_voltage = 1150000, + .soc_voltage = 1150000, + .cpu_voltage = 1025000,}, { .pll_rate = 396000000, .cpu_rate = 198000000, .cpu_podf = 1, - .pu_voltage = 1100000, - .soc_voltage = 1100000, - .cpu_voltage = 1000000,}, + .pu_voltage = 1150000, + .soc_voltage = 1150000, + .cpu_voltage = 1025000,}, }; static struct dvfs_op dvfs_core_setpoint_1_2G[] = { -- cgit v1.2.3 From c772ce534c818227910a61d1d427f93fc42b5027 Mon Sep 17 00:00:00 2001 From: Gary Zhang Date: Thu, 16 Aug 2012 14:25:39 +0800 Subject: ENGR00220512-1: mx6sl evk: change wm8962 codec 1.8V power source to VGEN3 Adjust pfuse settings for wm8962 Signed-off-by: Gary Zhang --- arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c index 7a74b1f34fd6..1ed3ebcdf7e0 100644 --- a/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c +++ b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c @@ -80,12 +80,7 @@ static struct regulator_consumer_supply sw2_consumers[] = { { .supply = "MICVDD", .dev_name = "1-001a", - }, - { - .supply = "DBVDD", - .dev_name = "1-001a", } - }; static struct regulator_consumer_supply sw4_consumers[] = { { @@ -107,7 +102,7 @@ static struct regulator_consumer_supply vgen2_consumers[] = { .supply = "VGEN2_1V5", } }; -static struct regulator_consumer_supply vgen4_consumers[] = { +static struct regulator_consumer_supply vgen3_consumers[] = { { .supply = "AVDD", .dev_name = "1-001a", @@ -123,6 +118,15 @@ static struct regulator_consumer_supply vgen4_consumers[] = { { .supply = "PLLVDD", .dev_name = "1-001a", + }, + { + .supply = "DBVDD", + .dev_name = "1-001a", + } +}; +static struct regulator_consumer_supply vgen4_consumers[] = { + { + .supply = "VGEN4_1V58", } }; static struct regulator_consumer_supply vgen5_consumers[] = { @@ -335,6 +339,8 @@ static struct regulator_init_data vgen3_init = { .always_on = 0, .boot_on = 0, }, + .num_consumer_supplies = ARRAY_SIZE(vgen3_consumers), + .consumer_supplies = vgen3_consumers, }; static struct regulator_init_data vgen4_init = { -- cgit v1.2.3 From dabdd1704ce8dc11a6476daccf739d92a45ab112 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Thu, 16 Aug 2012 15:14:19 +0800 Subject: ENGR00220512-2: mx6sl evk: keep NVCC_1V8 and NVCC_1.2V always on Keep the corresponding rail of pfuze: VGEN4 and VGEN1 "always on". It's required for any IO pad configured as this voltage. It has to be always on, even in DSM mode. Signed-off-by: Robby Cai --- arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c index 1ed3ebcdf7e0..958f8a0ab780 100644 --- a/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c +++ b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c @@ -302,8 +302,8 @@ static struct regulator_init_data vgen1_init = { .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, .valid_modes_mask = 0, - .always_on = 0, - .boot_on = 0, + .always_on = 1, + .boot_on = 1, }, .num_consumer_supplies = ARRAY_SIZE(vgen1_consumers), .consumer_supplies = vgen1_consumers, @@ -351,6 +351,8 @@ static struct regulator_init_data vgen4_init = { .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, .valid_modes_mask = 0, + .always_on = 1, + .boot_on = 1, }, .num_consumer_supplies = ARRAY_SIZE(vgen4_consumers), .consumer_supplies = vgen4_consumers, -- cgit v1.2.3 From 8ca6288db45a89a353c3b4fb51b417e91a7d4d6d Mon Sep 17 00:00:00 2001 From: Gary Zhang Date: Thu, 16 Aug 2012 16:21:25 +0800 Subject: ENGR00220027-2 mx6sl: add pad ctrl for audmux iomux setting for avoiding pop-noise adn setting audmux pad to 1.8v on evk, add pad ctrl for audmux iomux setting Signed-off-by: Gary Zhang --- arch/arm/mach-mx6/board-mx6sl_evk.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c index 3f42a0eeb4df..62daad6d867b 100644 --- a/arch/arm/mach-mx6/board-mx6sl_evk.c +++ b/arch/arm/mach-mx6/board-mx6sl_evk.c @@ -488,6 +488,17 @@ static int mxc_wm8962_init(void) clk_set_rate(extern_audio_root, rate); wm8962_data.sysclk = rate; + /* set AUDMUX pads to 1.8v */ + mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_MCLK, + PAD_CTL_LVE, PAD_CTL_LVE_MASK); + mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_RXD, + PAD_CTL_LVE, PAD_CTL_LVE_MASK); + mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXC, + PAD_CTL_LVE, PAD_CTL_LVE_MASK); + mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXD, + PAD_CTL_LVE, PAD_CTL_LVE_MASK); + mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXFS, + PAD_CTL_LVE, PAD_CTL_LVE_MASK); return 0; } -- cgit v1.2.3 From e44fdde7d6906ae163c93380670bcf91229d51f5 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Thu, 26 Jul 2012 13:53:28 -0500 Subject: ENGR00220496 MX6SL:Add low power IDLE mode optimizations. Add support for DDR freq change code in IRAM. Change PLL2 to bypass mode so that DDR is running off 24MHz OSC directly. ARM is now sourced from PLL1 (running at 800MHz) in this mode. This is required for the next step in IDLE mode optmization where all PLLs will be disabled when ARM enters WFI. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/Makefile | 4 +- arch/arm/mach-mx6/bus_freq.c | 119 ++++++++--- arch/arm/mach-mx6/clock_mx6sl.c | 39 ++-- arch/arm/mach-mx6/irq.c | 8 + arch/arm/mach-mx6/mx6_anatop_regulator.c | 4 + arch/arm/mach-mx6/mx6sl_ddr.S | 330 +++++++++++++++++++++++++++++++ 6 files changed, 464 insertions(+), 40 deletions(-) create mode 100644 arch/arm/mach-mx6/mx6sl_ddr.S (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/Makefile b/arch/arm/mach-mx6/Makefile index 77d809145775..03a104bd6628 100644 --- a/arch/arm/mach-mx6/Makefile +++ b/arch/arm/mach-mx6/Makefile @@ -9,8 +9,8 @@ mx6_mmdc.o mx6_ddr_freq.o obj-$(CONFIG_ARCH_MX6) += clock.o mx6_suspend.o clock_mx6sl.o obj-$(CONFIG_MACH_MX6Q_ARM2) += board-mx6q_arm2.o -obj-$(CONFIG_MACH_MX6SL_ARM2) += board-mx6sl_arm2.o mx6sl_arm2_pmic_pfuze100.o -obj-$(CONFIG_MACH_MX6SL_EVK) += board-mx6sl_evk.o mx6sl_evk_pmic_pfuze100.o +obj-$(CONFIG_MACH_MX6SL_ARM2) += board-mx6sl_arm2.o mx6sl_arm2_pmic_pfuze100.o mx6sl_ddr.o +obj-$(CONFIG_MACH_MX6SL_EVK) += board-mx6sl_evk.o mx6sl_evk_pmic_pfuze100.o mx6sl_ddr.o obj-$(CONFIG_MACH_MX6Q_SABRELITE) += board-mx6q_sabrelite.o obj-$(CONFIG_MACH_MX6Q_SABRESD) += board-mx6q_sabresd.o mx6q_sabresd_pmic_pfuze100.o obj-$(CONFIG_MACH_MX6Q_SABREAUTO) += board-mx6q_sabreauto.o mx6q_sabreauto_pmic_pfuze100.o diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index 95edf0065207..b1f9d80bd6d1 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -51,7 +51,7 @@ #define GPC_PGC_GPU_PGCR_OFFSET 0x260 #define GPC_CNTR_OFFSET 0x0 -DEFINE_SPINLOCK(ddr_freq_lock); +static DEFINE_SPINLOCK(freq_lock); int low_bus_freq_mode; int audio_bus_freq_mode; @@ -75,6 +75,10 @@ unsigned int ddr_normal_rate; int low_freq_bus_used(void); void set_ddr_freq(int ddr_freq); +void *mx6sl_ddr_freq_base; +void (*mx6sl_ddr_freq_change_iram)(int ddr_freq) = NULL; +extern void mx6sl_ddr_iram(int ddr_freq); + extern int init_mmdc_settings(void); extern struct cpu_op *(*get_cpu_op)(int *op); extern int update_ddr_freq(int ddr_rate); @@ -87,6 +91,7 @@ struct timeval start_time; struct timeval end_time; static int cpu_op_nr; +static u32 org_arm_podf; static struct cpu_op *cpu_op_tbl; static struct clk *pll2_400; static struct clk *axi_clk; @@ -96,6 +101,8 @@ static struct clk *osc_clk; static struct clk *cpu_clk; static struct clk *pll3; static struct clk *pll2; +static struct clk *pll1; +static struct clk *pll1_sw_clk; static struct clk *pll3_sw_clk; static struct clk *pll2_200; static struct clk *mmdc_ch0_axi; @@ -136,30 +143,46 @@ static void reduce_bus_freq_handler(struct work_struct *work) clk_disable(pll3); med_bus_freq_mode = 0; } else { + u32 reg; + u32 div; + unsigned long flags; + arm_mem_clked_in_wait = true; - /* Set periph_clk to be sourced from OSC_CLK */ - /* Set MMDC clk to 25MHz. */ - /* First need to set the divider before changing the parent */ - /* if parent clock is larger than previous one */ - clk_set_rate(mmdc_ch0_axi, clk_get_rate(mmdc_ch0_axi) / 2); - clk_set_parent(mmdc_ch0_axi, pll3_sw_clk); - clk_set_parent(mmdc_ch0_axi, pll2_200); - clk_set_rate(mmdc_ch0_axi, - clk_round_rate(mmdc_ch0_axi, LPAPM_CLK)); + spin_lock_irqsave(&freq_lock, flags); + /* Set periph_clk to be sourced from OSC_CLK */ /* Set AXI to 24MHz. */ clk_set_parent(periph_clk, osc_clk); clk_set_rate(axi_clk, clk_round_rate(axi_clk, LPAPM_CLK)); /* Set AHB to 24MHz. */ clk_set_rate(ahb_clk, clk_round_rate(ahb_clk, LPAPM_CLK)); + /* Set MMDC clk to 24MHz. */ + /* Since we are going to set PLL2 in bypass mode, + * move the CPU clock off PLL2. + */ + /* Ensure that the clock will be at lowest possible freq. */ + org_arm_podf = __raw_readl(MXC_CCM_CACRR); + div = clk_get_rate(pll1) / cpu_op_tbl[cpu_op_nr - 1].cpu_rate; + + reg = __raw_writel(div - 1, MXC_CCM_CACRR); + while (__raw_readl(MXC_CCM_CDHIPR)) + ; + clk_set_parent(pll1_sw_clk, pll1); + + /* Now change DDR freq in IRAM. */ + mx6sl_ddr_freq_change_iram(LPAPM_CLK); + low_bus_freq_mode = 1; audio_bus_freq_mode = 0; + + spin_unlock_irqrestore(&freq_lock, flags); } high_bus_freq_mode = 0; } + /* Set the DDR, AHB to 24MHz. * This mode will be activated only when none of the modules that * need a higher DDR or AHB frequency are active. @@ -208,6 +231,14 @@ int set_high_bus_freq(int high_bus_freq) return 0; if (cpu_is_mx6sl()) { + u32 reg; + unsigned long flags; + + spin_lock_irqsave(&freq_lock, flags); + + /* Change DDR freq in IRAM. */ + mx6sl_ddr_freq_change_iram(ddr_normal_rate); + /* Set periph_clk to be sourced from pll2_pfd2_400M */ /* First need to set the divider before changing the */ /* parent if parent clock is larger than previous one */ @@ -217,16 +248,19 @@ int set_high_bus_freq(int high_bus_freq) clk_round_rate(axi_clk, LPAPM_CLK / 2)); clk_set_parent(periph_clk, pll2_400); - /* Set mmdc_clk_root to be sourced */ - /* from pll2_pfd2_400M */ - clk_set_rate(mmdc_ch0_axi, - clk_round_rate(mmdc_ch0_axi, LPAPM_CLK / 2)); - clk_set_parent(mmdc_ch0_axi, pll3_sw_clk); - clk_set_parent(mmdc_ch0_axi, pll2_400); - clk_set_rate(mmdc_ch0_axi, - clk_round_rate(mmdc_ch0_axi, DDR_MED_CLK)); + /* Now move ARM to be sourced from PLL2_400 too. */ + clk_set_parent(pll1_sw_clk, pll2_400); + + /* Ensure that the clock will be at original speed. */ + reg = __raw_writel(org_arm_podf, MXC_CCM_CACRR); + while (__raw_readl(MXC_CCM_CDHIPR)) + ; high_bus_freq_mode = 1; + low_bus_freq_mode = 0; + audio_bus_freq_mode = 0; + + spin_unlock_irqrestore(&freq_lock, flags); } else { clk_enable(pll3); if (high_bus_freq) { @@ -248,14 +282,12 @@ int set_high_bus_freq(int high_bus_freq) if (audio_bus_freq_mode) clk_disable(pll2_400); + low_bus_freq_mode = 0; + audio_bus_freq_mode = 0; + clk_disable(pll3); } - low_bus_freq_mode = 0; - audio_bus_freq_mode = 0; - - /* Ensure that WAIT mode can be entered in high bus freq mode. */ - if (cpu_is_mx6sl()) arm_mem_clked_in_wait = false; @@ -394,6 +426,7 @@ static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show, * @return The function returns 0 on success * */ + static int __devinit busfreq_probe(struct platform_device *pdev) { u32 err; @@ -421,6 +454,28 @@ static int __devinit busfreq_probe(struct platform_device *pdev) return PTR_ERR(pll2); } + pll1 = clk_get(NULL, "pll1_main_clk"); + if (IS_ERR(pll1)) { + printk(KERN_DEBUG "%s: failed to get pll1\n", + __func__); + return PTR_ERR(pll1); + } + + pll1_sw_clk = clk_get(NULL, "pll1_sw_clk"); + if (IS_ERR(pll1_sw_clk)) { + printk(KERN_DEBUG "%s: failed to get pll1_sw_clk\n", + __func__); + return PTR_ERR(pll1_sw_clk); + } + + + if (IS_ERR(pll2)) { + printk(KERN_DEBUG "%s: failed to get pll2\n", + __func__); + return PTR_ERR(pll2); + } + + cpu_clk = clk_get(NULL, "cpu_clk"); if (IS_ERR(cpu_clk)) { printk(KERN_DEBUG "%s: failed to get cpu_clk\n", @@ -518,6 +573,24 @@ static int __devinit busfreq_probe(struct platform_device *pdev) if (!cpu_is_mx6sl()) init_mmdc_settings(); + else { +#if 1 + unsigned long iram_paddr; + + /* Allocate IRAM for WFI code when system is + * in low freq mode. + */ + iram_alloc(SZ_4K, &iram_paddr); + /* Need to remap the area here since we want + * the memory region to be executable. + */ + mx6sl_ddr_freq_base = __arm_ioremap(iram_paddr, + SZ_4K, MT_MEMORY_NONCACHED); + memcpy(mx6sl_ddr_freq_base, mx6sl_ddr_iram, SZ_4K); + mx6sl_ddr_freq_change_iram = (void *)mx6sl_ddr_freq_base; + +#endif + } return 0; } diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index 7496882feeb1..2abdaa5afc1d 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -100,7 +100,9 @@ DEFINE_SPINLOCK(mx6sl_clk_lock); u32 gpt_ticks; \ u32 gpt_cnt; \ u32 reg; \ + unsigned long flags; \ int result = 1; \ + spin_lock_irqsave(&mx6sl_clk_lock, flags); \ gpt_rate = clk_get_rate(&gpt_clk[0]); \ gpt_ticks = timeout / (1000000000 / gpt_rate); \ reg = __raw_readl(timer_base + V2_TSTAT);\ @@ -130,6 +132,7 @@ DEFINE_SPINLOCK(mx6sl_clk_lock); } \ } \ } \ + spin_unlock_irqrestore(&mx6sl_clk_lock, flags); \ result; \ }) @@ -445,11 +448,6 @@ static int _clk_pll_enable(struct clk *clk) SPIN_DELAY)) panic("pll enable failed\n"); - /* Enable the PLL output now*/ - reg = __raw_readl(pllbase); - reg |= ANADIG_PLL_ENABLE; - __raw_writel(reg, pllbase); - return 0; } @@ -466,7 +464,11 @@ static void _clk_pll_disable(struct clk *clk) reg = __raw_readl(pllbase); reg |= ANADIG_PLL_BYPASS; - reg &= ~ANADIG_PLL_ENABLE; + reg |= ANADIG_PLL_POWER_DOWN; + + /* The 480MHz PLLs have the opposite definition for power bit. */ + if (clk == &pll3_usb_otg_main_clk || clk == &pll7_usb_host_main_clk) + reg &= ~ANADIG_PLL_POWER_DOWN; __raw_writel(reg, pllbase); @@ -505,7 +507,7 @@ static int _clk_pll1_main_set_rate(struct clk *clk, unsigned long rate) /* Wait for PLL1 to lock */ if (!WAIT((__raw_readl(PLL1_SYS_BASE_ADDR) & ANADIG_PLL_LOCK), SPIN_DELAY)) - panic("pll1 enable failed\n"); + panic("pll1 set rate failed\n"); return 0; } @@ -531,8 +533,7 @@ static void _clk_pll1_main_disable(struct clk *clk) * requires PLL1 to be enabled. */ reg = __raw_readl(pllbase); - reg |= ANADIG_PLL_BYPASS; - + reg |= (ANADIG_PLL_BYPASS | ANADIG_PLL_POWER_DOWN); __raw_writel(reg, pllbase); } @@ -1266,7 +1267,7 @@ static int _clk_periph_set_parent(struct clk *clk, struct clk *parent) reg &= ~MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK; reg |= mux << MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET; __raw_writel(reg, MXC_CCM_CBCMR); - + udelay(5); /* Set the periph_clk_sel multiplexer. */ reg = __raw_readl(MXC_CCM_CBCDR); reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL; @@ -1433,6 +1434,7 @@ static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate) div = parent_rate / rate; if (div == 0) div++; + if (((parent_rate / div) != rate) || (div > 8)) return -EINVAL; @@ -2080,6 +2082,7 @@ static struct clk usdhc1_clk = { .round_rate = _clk_usdhc_round_rate, .set_rate = _clk_usdhc1_set_rate, .get_rate = _clk_usdhc1_get_rate, + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, }; static int _clk_usdhc2_set_parent(struct clk *clk, struct clk *parent) @@ -2137,6 +2140,7 @@ static struct clk usdhc2_clk = { .round_rate = _clk_usdhc_round_rate, .set_rate = _clk_usdhc2_set_rate, .get_rate = _clk_usdhc2_get_rate, + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, }; static int _clk_usdhc3_set_parent(struct clk *clk, struct clk *parent) @@ -2195,6 +2199,7 @@ static struct clk usdhc3_clk = { .round_rate = _clk_usdhc_round_rate, .set_rate = _clk_usdhc3_set_rate, .get_rate = _clk_usdhc3_get_rate, + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, }; static int _clk_usdhc4_set_parent(struct clk *clk, struct clk *parent) @@ -2253,6 +2258,7 @@ static struct clk usdhc4_clk = { .round_rate = _clk_usdhc_round_rate, .set_rate = _clk_usdhc4_set_rate, .get_rate = _clk_usdhc4_get_rate, + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, }; static unsigned long _clk_ssi_round_rate(struct clk *clk, @@ -3321,6 +3327,10 @@ static unsigned long _clk_uart_get_rate(struct clk *clk) div = (reg >> MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1; val = clk_get_rate(clk->parent) / div; + /* If the parent is OSC, there is an in-built divide by 6. */ + if (clk->parent == &osc_clk) + val = val / 6; + return val; } @@ -3335,7 +3345,7 @@ static int _clk_uart_set_parent(struct clk *clk, struct clk *parent) else mux = 0; /* osc */ - reg |= mux << MXC_CCM_CSCDR2_ECSPI_CLK_SEL_OFFSET; + reg |= mux << MXC_CCM_CSCDR1_UART_CLK_SEL_OFFSET; __raw_writel(reg, MXC_CCM_CSCDR1); @@ -4024,7 +4034,6 @@ int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc, 3 << MXC_CCM_CCGRx_CG0_OFFSET, MXC_CCM_CCGR0); } else { __raw_writel(1 << MXC_CCM_CCGRx_CG11_OFFSET | - 3 << MXC_CCM_CCGRx_CG2_OFFSET | 3 << MXC_CCM_CCGRx_CG1_OFFSET | 3 << MXC_CCM_CCGRx_CG0_OFFSET, MXC_CCM_CCGR0); } @@ -4032,9 +4041,9 @@ int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc, 3 << MXC_CCM_CCGRx_CG11_OFFSET, MXC_CCM_CCGR1); __raw_writel(1 << MXC_CCM_CCGRx_CG12_OFFSET | 1 << MXC_CCM_CCGRx_CG11_OFFSET | - 3 << MXC_CCM_CCGRx_CG10_OFFSET | - 3 << MXC_CCM_CCGRx_CG9_OFFSET | - 3 << MXC_CCM_CCGRx_CG8_OFFSET, MXC_CCM_CCGR2); + 1 << MXC_CCM_CCGRx_CG10_OFFSET | + 1 << MXC_CCM_CCGRx_CG9_OFFSET | + 1 << MXC_CCM_CCGRx_CG8_OFFSET, MXC_CCM_CCGR2); __raw_writel(1 << MXC_CCM_CCGRx_CG14_OFFSET | 3 << MXC_CCM_CCGRx_CG13_OFFSET | 3 << MXC_CCM_CCGRx_CG12_OFFSET | diff --git a/arch/arm/mach-mx6/irq.c b/arch/arm/mach-mx6/irq.c index 197c451d5fb4..a079c37ab9d3 100644 --- a/arch/arm/mach-mx6/irq.c +++ b/arch/arm/mach-mx6/irq.c @@ -103,6 +103,7 @@ void mx6_init_irq(void) void __iomem *gpc_base = IO_ADDRESS(GPC_BASE_ADDR); struct irq_desc *desc; unsigned int i; + u32 reg; /* start offset if private timer irq id, which is 29. * ID table: @@ -121,6 +122,13 @@ void mx6_init_irq(void) __raw_writel(0x20000000, gpc_base + 0x10); } +#ifdef CONFIG_MX6_INTER_LDO_BYPASS + /* Mask the ANATOP brown out interrupt in the GPC. */ + reg = __raw_readl(gpc_base + 0x14); + reg |= 0x80000000; + __raw_writel(reg, gpc_base + 0x14); +#endif + for (i = MXC_INT_START; i <= MXC_INT_END; i++) { desc = irq_to_desc(i); desc->irq_data.chip->irq_set_wake = mx6_gic_irq_set_wake; diff --git a/arch/arm/mach-mx6/mx6_anatop_regulator.c b/arch/arm/mach-mx6/mx6_anatop_regulator.c index 06755dc7a4ee..945adbdb759a 100644 --- a/arch/arm/mach-mx6/mx6_anatop_regulator.c +++ b/arch/arm/mach-mx6/mx6_anatop_regulator.c @@ -125,10 +125,12 @@ static int pu_enable(struct anatop_regulator *sreg) reg |= ANADIG_ANA_MISC2_REG1_BO_EN; __raw_writel(reg, ANA_MISC2_BASE_ADDR); +#ifndef CONFIG_MX6_INTER_LDO_BYPASS /* Unmask the ANATOP brown out interrupt in the GPC. */ reg = __raw_readl(gpc_base + 0x14); reg &= ~0x80000000; __raw_writel(reg, gpc_base + 0x14); +#endif return 0; } @@ -162,10 +164,12 @@ static int pu_disable(struct anatop_regulator *sreg) while (__raw_readl(gpc_base + GPC_CNTR_OFFSET) & 0x1) ; +#ifndef CONFIG_MX6_INTER_LDO_BYPASS /* Mask the ANATOP brown out interrupt in the GPC. */ reg = __raw_readl(gpc_base + 0x14); reg |= 0x80000000; __raw_writel(reg, gpc_base + 0x14); +#endif /* PU power gating. */ reg = __raw_readl(ANADIG_REG_CORE); diff --git a/arch/arm/mach-mx6/mx6sl_ddr.S b/arch/arm/mach-mx6/mx6sl_ddr.S new file mode 100644 index 000000000000..4faa294c3aa7 --- /dev/null +++ b/arch/arm/mach-mx6/mx6sl_ddr.S @@ -0,0 +1,330 @@ +/* + * Copyright (C) 2012 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 +#include + + + .macro mx6sl_switch_to_24MHz + + /* Set MMDC clock to be sourced from PLL3. */ + /* Ensure first periph2_clk2 is sourced from PLL3. */ + /* Set the PERIPH2_CLK2_PODF to divide by 2. */ + ldr r6, [r2, #0x14] + bic r6, r6, #0x7 + orr r6, r6, #0x1 + str r6, [r2, #0x14] + + /* Select PLL3 to source MMDC. */ + ldr r6, [r2, #0x18] + bic r6, r6, #0x100000 + str r6, [r2, #0x18] + + /* Swtich periph2_clk_sel to run from PLL3. */ + ldr r6, [r2, #0x14] + orr r6, r6, #0x4000000 + str r6, [r2, #0x14] + +periph2_clk_switch1: + ldr r6, [r2, #0x48] + cmp r6, #0 + bne periph2_clk_switch1 + + /* Need to clock gate the 528 PFDs before + * powering down PLL2. + * Only the PLL2_PFD2_400M should be ON + * as it feeds the MMDC + */ + ldr r6, [r3, #0x100] + orr r6, r6, #0x800000 + str r6, [r3, #0x100] + + /* Set PLL2 to bypass state. We should be here + *only if MMDC is not sourced from PLL2.*/ + ldr r6, [r3, #0x30] + orr r6, r6, #0x10000 + str r6, [r3, #0x30] + + ldr r6, [r3, #0x30] + orr r6, r6, #0x1000 + str r6, [r3, #0x30] + + /* Ensure pre_periph2_clk_mux is set to pll2 */ + ldr r6, [r2, #0x18] + bic r6, r6, #0x600000 + str r6, [r2, #0x18] + + /* Set MMDC clock to be sourced from the bypassed PLL2. */ + ldr r6, [r2, #0x14] + bic r6, r6, #0x4000000 + str r6, [r2, #0x14] + +periph2_clk_switch2: + ldr r6, [r2, #0x48] + cmp r6, #0 + bne periph2_clk_switch2 + + /* Now move MMDC back to periph2_clk2 source. + * after selecting PLL2 as the option. + */ + /* Select PLL2 as the source. */ + ldr r6, [r2, #0x18] + orr r6, r6, #0x100000 + str r6, [r2, #0x18] + + /* set periph2_clk2_podf to divide by 1. */ + ldr r6, [r2, #0x14] + bic r6, r6, #0x7 + str r6, [r2, #0x14] + + /* Now move periph2_clk to periph2_clk2 source */ + ldr r6, [r2, #0x14] + orr r6, r6, #0x4000000 + str r6, [r2, #0x14] + +periph2_clk_switch3: + ldr r6, [r2, #0x48] + cmp r6, #0 + bne periph2_clk_switch3 + + .endm + + .macro ddr_switch_400MHz + + /* Set MMDC divider first, in case PLL3 is at 480MHz. */ + ldr r6, [r3, #0x10] + and r6, r6, #0x10000 + cmp r6, #0x10000 + beq pll3_in_bypass + /* Set MMDC divder to divide by 2. */ + ldr r6, [r2, #0x14] + bic r6, r6, #0x38 + orr r6, r6, #0x8 + str r6, [r2, #0x14] + +mmdc_podf: + ldr r6, [r2, #0x48] + cmp r6, #0 + bne mmdc_podf + +pll3_in_bypass: + + /* Ensure that MMDC is sourced from PLL2 mux first. */ + ldr r6, [r2, #0x14] + bic r6, r6, #0x4000000 + str r6, [r2, #0x14] + +periph2_clk_switch4: + ldr r6, [r2, #0x48] + cmp r6, #0 + bne periph2_clk_switch4 + + /* Now ensure periph2_clk2_sel mux is set to PLL3 */ + ldr r6, [r2, #0x18] + bic r6, r6, #0x100000 + str r6, [r2, #0x18] + + /* Now switch MMDC to PLL3. */ + ldr r6, [r2, #0x14] + orr r6, r6, #0x4000000 + str r6, [r2, #0x14] + +periph2_clk_switch5: + ldr r6, [r2, #0x48] + cmp r6, #0 + bne periph2_clk_switch5 + + /* Now power up PLL2 and unbypass it. */ + ldr r6, [r3, #0x30] + bic r6, r6, #0x1000 + str r6, [r3, #0x30] + + /* Make sure PLL2 has locked.*/ +wait_for_pll_lock: + ldr r6, [r3, #0x30] + and r6, r6, #0x80000000 + cmp r6, #0x80000000 + bne wait_for_pll_lock + + ldr r6, [r3, #0x30] + bic r6, r6, #0x10000 + str r6, [r3, #0x30] + + /* Need to enable the 528 PFDs after + * powering up PLL2. + * Only the PLL2_PFD2_400M should be ON + * as it feeds the MMDC. Rest should have + * been managed by clock code. + */ + ldr r6, [r3, #0x100] + bic r6, r6, #0x800000 + str r6, [r3, #0x100] + + /* Now switch MMDC clk back to pll2_mux option. */ + /* Ensure pre_periph2_clk2 is set to pll2_pfd_400M */ + ldr r6, [r2, #0x18] + bic r6, r6, #0x600000 + orr r6, r6, #0x200000 + str r6, [r2, #0x18] + + ldr r6, [r2, #0x14] + bic r6, r6, #0x4000000 + str r6, [r2, #0x14] + +periph2_clk_switch6: + ldr r6, [r2, #0x48] + cmp r6, #0 + bne periph2_clk_switch6 + + /* Now set the MMDC PODF back to 1.*/ + + ldr r6, [r2, #0x14] + bic r6, r6, #0x38 + str r6, [r2, #0x14] + +mmdc_podf1: + ldr r6, [r2, #0x48] + cmp r6, #0 + bne mmdc_podf1 + + .endm + +/* + * mx6sl_ddr_iram + * + * Idle the processor (eg, wait for interrupt). + * Make sure DDR is in self-refresh. + * IRQs are already disabled. + * r0 : DDR freq. + */ +ENTRY(mx6sl_ddr_iram) + + push {r4, r5, r6, r7, r8, r9, r10 } + +mx6sl_ddr_freq_change: + ldr r3, =ANATOP_BASE_ADDR + add r3, r3, #PERIPBASE_VIRT + + ldr r2, =CCM_BASE_ADDR + add r2, r2, #PERIPBASE_VIRT + + ldr r8, =MMDC_P0_BASE_ADDR + add r8, r8, #PERIPBASE_VIRT + + /* Prime all TLB entries. */ + adr r7, mx6sl_ddr_freq_change @Address in this function. + + ldr r6, [r7] + ldr r6, [r8] + ldr r6, [r3] + ldr r6, [r2] + + dsb + isb + + /* Disable Automatic power savings. */ + ldr r6, [r8, #0x404] + orr r6, r6, #0x01 + str r6, [r8, #0x404] + + /* Disable MMDC power down timer. */ + /*MMDC0_MDPDC disable power down timer */ + ldr r6, [r8, #0x4] + bic r6, r6, #0xff00 + str r6, [r8, #0x4] + + /* Delay for a while */ + ldr r1, =10 +delay1: + ldr r7, =0 +cont1: + ldr r6, [r8, r7] + add r7, r7, #4 + cmp r7, #16 + bne cont1 + sub r1, r1, #1 + cmp r1, #0 + bgt delay1 + + /* Make the DDR explicitly enter self-refresh. */ + ldr r6, [r8, #0x404] + orr r6, r6, #0x200000 + str r6, [r8, #0x404] + +poll_dvfs_set_1: + ldr r6, [r8, #0x404] + and r6, r6, #0x2000000 + cmp r6, #0x2000000 + bne poll_dvfs_set_1 + + /* set SBS step-by-step mode */ + ldr r6, [r8, #0x410] + orr r6, r6, #0x100 + str r6, [r8, #0x410] + + ldr r1, =24000000 + cmp r0, r1 + beq set_to_24MHz + + ddr_switch_400MHz + b done + +set_to_24MHz: + mx6sl_switch_to_24MHz + +done: + /* clear DVFS - exit from self refresh mode */ + ldr r6, [r8, #0x404] + bic r6, r6, #0x200000 + str r6, [r8, #0x404] + +poll_dvfs_clear_1: + ldr r6, [r8, #0x404] + and r6, r6, #0x2000000 + cmp r6, #0x2000000 + beq poll_dvfs_clear_1 + + /* Enable Automatic power savings. */ + ldr r6, [r8, #0x404] + bic r6, r6, #0x01 + str r6, [r8, #0x404] + + ldr r1, =24000000 + cmp r0, r1 + beq skip_power_down + + /* Enable MMDC power down timer. */ + ldr r6, [r8, #0x4] + orr r6, r6, #0x5500 + str r6, [r8, #0x4] + +skip_power_down: + /* clear SBS - unblock DDR accesses */ + ldr r6, [r8, #0x410] + bic r6, r6, #0x100 + str r6, [r8, #0x410] + + pop {r4,r5, r6, r7, r8, r9, r10} + + /* Restore registers */ + mov pc, lr + + .type mx6sl_ddr_do_iram, #object +ENTRY(mx6sl_ddr_do_iram) + .word mx6sl_ddr_iram + .size mx6sl_ddr_iram, . - mx6sl_ddr_iram -- cgit v1.2.3 From 89338e8ab39da46aaa57a89fa4e673d30cca04f5 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Sat, 18 Aug 2012 10:07:20 -0500 Subject: ENGR00220707 MX6Q/MX6DL: Fix build break due to MX6SL LPM code Fix build break due to missing extern. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/Makefile b/arch/arm/mach-mx6/Makefile index 03a104bd6628..91fc841e9529 100644 --- a/arch/arm/mach-mx6/Makefile +++ b/arch/arm/mach-mx6/Makefile @@ -5,12 +5,12 @@ # Object file lists. obj-y := cpu.o mm.o system.o devices.o dummy_gpio.o irq.o bus_freq.o usb_dr.o usb_h2.o usb_h3.o\ pm.o cpu_op-mx6.o mx6_wfi.o mx6_fec.o mx6_anatop_regulator.o cpu_regulator-mx6.o \ -mx6_mmdc.o mx6_ddr_freq.o +mx6_mmdc.o mx6_ddr_freq.o mx6sl_ddr.o obj-$(CONFIG_ARCH_MX6) += clock.o mx6_suspend.o clock_mx6sl.o obj-$(CONFIG_MACH_MX6Q_ARM2) += board-mx6q_arm2.o -obj-$(CONFIG_MACH_MX6SL_ARM2) += board-mx6sl_arm2.o mx6sl_arm2_pmic_pfuze100.o mx6sl_ddr.o -obj-$(CONFIG_MACH_MX6SL_EVK) += board-mx6sl_evk.o mx6sl_evk_pmic_pfuze100.o mx6sl_ddr.o +obj-$(CONFIG_MACH_MX6SL_ARM2) += board-mx6sl_arm2.o mx6sl_arm2_pmic_pfuze100.o +obj-$(CONFIG_MACH_MX6SL_EVK) += board-mx6sl_evk.o mx6sl_evk_pmic_pfuze100.o obj-$(CONFIG_MACH_MX6Q_SABRELITE) += board-mx6q_sabrelite.o obj-$(CONFIG_MACH_MX6Q_SABRESD) += board-mx6q_sabresd.o mx6q_sabresd_pmic_pfuze100.o obj-$(CONFIG_MACH_MX6Q_SABREAUTO) += board-mx6q_sabreauto.o mx6q_sabreauto_pmic_pfuze100.o -- cgit v1.2.3 From 9946d67dcd92c6b2afa7ba2159b0a22eabc2082b Mon Sep 17 00:00:00 2001 From: Eric Sun Date: Mon, 20 Aug 2012 14:05:59 +0800 Subject: ENGR00220567 [MX6 SABRELite] No mxs-perfmon.0 directory The problem is caused because "mx6_sabrelite_board_init" don't add the corresponding device node. Problem resolved after add them. Signed-off-by: Eric Sun --- arch/arm/mach-mx6/board-mx6q_sabrelite.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c index 3abb282fd56c..eff81acb3208 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabrelite.c +++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c @@ -1234,6 +1234,10 @@ static void __init mx6_sabrelite_board_init(void) clk_set_rate(clko2, rate); clk_enable(clko2); imx6q_add_busfreq(); + + imx6q_add_perfmon(0); + imx6q_add_perfmon(1); + imx6q_add_perfmon(2); } extern void __iomem *twd_base; -- cgit v1.2.3 From d0f374b35141b4550538b78f6a8937fa88394cfb Mon Sep 17 00:00:00 2001 From: Eric Sun Date: Mon, 20 Aug 2012 20:51:25 +0800 Subject: ENGR00217687 [MX6SL_ARM2/EVK] Fix no perfmon directory The problem is caused because the board init routine don't add the corresponding device node. Problem resolved after add them Signed-off-by: Eric Sun --- arch/arm/mach-mx6/board-mx6sl_arm2.c | 4 ++++ arch/arm/mach-mx6/board-mx6sl_evk.c | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c index 8f05702e74aa..1d76abb8a0b1 100755 --- a/arch/arm/mach-mx6/board-mx6sl_arm2.c +++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c @@ -1254,6 +1254,10 @@ static void __init mx6_arm2_init(void) imx6sl_add_dcp(); imx6sl_add_rngb(); + imx6q_add_perfmon(0); + imx6q_add_perfmon(1); + imx6q_add_perfmon(2); + pm_power_off = mx6_snvs_poweroff; } diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c index 62daad6d867b..7ef077f91cfc 100644 --- a/arch/arm/mach-mx6/board-mx6sl_evk.c +++ b/arch/arm/mach-mx6/board-mx6sl_evk.c @@ -1266,6 +1266,10 @@ static void __init mx6_evk_init(void) imx6sl_add_dcp(); imx6sl_add_rngb(); + imx6q_add_perfmon(0); + imx6q_add_perfmon(1); + imx6q_add_perfmon(2); + pm_power_off = mx6_snvs_poweroff; } -- cgit v1.2.3 From 6564ec61a737c8ae8dad30838fafe17af6cb0cec Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Mon, 20 Aug 2012 13:35:07 -0500 Subject: ENGR00220818 [MX6SL] - Ensure the Enable bit is set for all the PLLs. The ENABLE bit is not set for all PLLs by default. Ensure that the pll_enable() function sets this bit for all PLLs. The pll_disable() function should not clear this bit for PLL1, PLL2, PLL3 and PLL7. The output of these PLLs maybe used even if they are bypassed. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/clock_mx6sl.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index 2abdaa5afc1d..8fab0f287ecd 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -448,6 +448,11 @@ static int _clk_pll_enable(struct clk *clk) SPIN_DELAY)) panic("pll enable failed\n"); + /* Enable the PLL output now*/ + reg = __raw_readl(pllbase); + reg |= ANADIG_PLL_ENABLE; + __raw_writel(reg, pllbase); + return 0; } @@ -470,6 +475,13 @@ static void _clk_pll_disable(struct clk *clk) if (clk == &pll3_usb_otg_main_clk || clk == &pll7_usb_host_main_clk) reg &= ~ANADIG_PLL_POWER_DOWN; + /* PLL1, PLL2, PLL3, PLL7 should not disable the ENABLE bit. + * The output of these PLLs maybe used even if they are bypassed. + */ + if (clk == &pll4_audio_main_clk || clk == &pll5_video_main_clk || + clk == &pll6_enet_main_clk) + reg &= ~ANADIG_PLL_ENABLE; + __raw_writel(reg, pllbase); /* -- cgit v1.2.3 From 30b0b3d67d251ebaf916b2463cc8eda479ef5758 Mon Sep 17 00:00:00 2001 From: make shi Date: Tue, 14 Aug 2012 15:02:00 +0800 Subject: ENGR00218789 mx6: clock: keep PLL3 enable and power bit all the time In order to support USB remote wake up, we should keep the PLL3 enable and power bit all the time. We use BM_ANADIG_ANA_MISC2_CONTROL0 to control the PLL3 power off PLL3's power when PLL3 is not used by other module. PLL3 power design logic as below: usb1_pll_480_ctrl_power_int=hw_anadig_usb1_pll_480_ctrl_power && ((disable_480_p ll_n && ~hw_anadig_ana_misc2_control0 )||pwrctl_otg_wakeup || utmi_otg_suspendm) There are two basic case: - If USB is active and USB remote wakeup happen , Pll3 will be turn on. - If USB is not active and no remote wakeup happen, the PLL3 will be controlled by hw_anadig_ana_misc2_control0 bit. Signed-off-by: make shi --- arch/arm/mach-mx6/clock.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index 0a01c3176eb1..d9af9f6909c1 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -505,6 +505,15 @@ static void _clk_pll_disable(struct clk *clk) if ((arm_needs_pll2_400) && (clk == &pll2_528_bus_main_clk)) return; + /* + * To support USB remote wake up, need always keep power and enable bit + * BM_ANADIG_ANA_MISC2_CONTROL0 will power off PLL3's power + * Please see TKT064178 for detail. + */ + if (clk == &pll3_usb_otg_main_clk) { + __raw_writel(BM_ANADIG_ANA_MISC2_CONTROL0, apll_base + HW_ANADIG_ANA_MISC2_SET); + return; + } pllbase = _get_pll_base(clk); @@ -514,12 +523,6 @@ static void _clk_pll_disable(struct clk *clk) __raw_writel(reg, pllbase); - /* - * It will power off PLL3's power, it is the TO1.1 fix - * Please see TKT064178 for detail. - */ - if (clk == &pll3_usb_otg_main_clk) - __raw_writel(BM_ANADIG_ANA_MISC2_CONTROL0, apll_base + HW_ANADIG_ANA_MISC2_SET); } static unsigned long _clk_pll1_main_get_rate(struct clk *clk) -- cgit v1.2.3 From 74474dc32f0404004b51b8ec26648856b940cee5 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Sun, 19 Aug 2012 01:12:59 +0800 Subject: ENGR00220370 [MX6]Fix BUS freq suspend/resume fail in low bus mode 1. BUS freq's set low bus setpoint using delat work, which didn't have mutex lock, so in some scenarios, set high bus freq function can be called at the same time, we need to move mutex lock into these two routine; 2. Using pm notify to make sure bus freq set to high setpoint before supend and restore after resume. 3. Clear build warning. Signed-off-by: Anson Huang --- arch/arm/mach-mx6/board-mx6q_sabresd.c | 5 +-- arch/arm/mach-mx6/bus_freq.c | 76 +++++++++++++++++++++++++++------- arch/arm/mach-mx6/clock.c | 7 +--- 3 files changed, 63 insertions(+), 25 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c index b6b3be93196d..1da30f10fe93 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabresd.c +++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c @@ -1505,11 +1505,10 @@ static struct gpio_led imx6q_gpio_leds[] = { /* For the latest B4 board, this GPIO_1 is connected to POR_B, which will reset the whole board if this pin's level is changed, so, for the latest board, we have to avoid using this pin as -GPIO. */ -#if 0 +GPIO. GPIO_LED(SABRESD_CHARGE_DONE, "chg_done_led", 0, 1, "charger-full"), -#endif +*/ }; static struct gpio_led_platform_data imx6q_gpio_leds_data = { diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index b1f9d80bd6d1..b85c8ec8fd7c 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -44,6 +44,7 @@ #include #include #include "crm_regs.h" +#include #define LPAPM_CLK 24000000 #define DDR_MED_CLK 400000000 @@ -111,11 +112,16 @@ static struct delayed_work low_bus_freq_handler; static void reduce_bus_freq_handler(struct work_struct *work) { - if (low_bus_freq_mode || !low_freq_bus_used()) + mutex_lock(&bus_freq_mutex); + if (low_bus_freq_mode || !low_freq_bus_used()) { + mutex_unlock(&bus_freq_mutex); return; + } - if (audio_bus_freq_mode && lp_audio_freq) + if (audio_bus_freq_mode && lp_audio_freq) { + mutex_unlock(&bus_freq_mutex); return; + } if (!cpu_is_mx6sl()) { clk_enable(pll3); @@ -181,6 +187,7 @@ static void reduce_bus_freq_handler(struct work_struct *work) } high_bus_freq_mode = 0; + mutex_unlock(&bus_freq_mutex); } /* Set the DDR, AHB to 24MHz. @@ -207,29 +214,42 @@ int set_low_bus_freq(void) */ int set_high_bus_freq(int high_bus_freq) { - if (busfreq_suspended) + if (bus_freq_scaling_initialized && bus_freq_scaling_is_active) + cancel_delayed_work_sync(&low_bus_freq_handler); + mutex_lock(&bus_freq_mutex); + if (busfreq_suspended) { + mutex_unlock(&bus_freq_mutex); return 0; + } - if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active) + if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active) { + mutex_unlock(&bus_freq_mutex); return 0; + } - if (high_bus_freq_mode && high_bus_freq) + if (high_bus_freq_mode && high_bus_freq) { + mutex_unlock(&bus_freq_mutex); return 0; + } - if (med_bus_freq_mode && !high_bus_freq) + if (med_bus_freq_mode && !high_bus_freq) { + mutex_unlock(&bus_freq_mutex); return 0; + } if (cpu_is_mx6dl() && high_bus_freq) high_bus_freq = 0; - if (cpu_is_mx6dl() && med_bus_freq_mode) + if (cpu_is_mx6dl() && med_bus_freq_mode) { + mutex_unlock(&bus_freq_mutex); return 0; - + } if ((high_bus_freq_mode && (high_bus_freq || lp_high_freq)) || (med_bus_freq_mode && !high_bus_freq && lp_med_freq && - !lp_high_freq)) + !lp_high_freq)) { + mutex_unlock(&bus_freq_mutex); return 0; - + } if (cpu_is_mx6sl()) { u32 reg; unsigned long flags; @@ -291,6 +311,7 @@ int set_high_bus_freq(int high_bus_freq) if (cpu_is_mx6sl()) arm_mem_clked_in_wait = false; + mutex_unlock(&bus_freq_mutex); return 0; } @@ -339,15 +360,21 @@ void bus_freq_update(struct clk *clk, bool flag) } } else { if ((clk->flags & AHB_MED_SET_POINT) - && !med_bus_freq_mode) + && !med_bus_freq_mode) { /* Set to Medium setpoint */ + mutex_unlock(&bus_freq_mutex); set_high_bus_freq(0); + return; + } else if ((clk->flags & AHB_HIGH_SET_POINT) - && !high_bus_freq_mode) + && !high_bus_freq_mode) { /* Currently at low or medium set point, * need to set to high setpoint */ + mutex_unlock(&bus_freq_mutex); set_high_bus_freq(1); + return; + } } } } else { @@ -363,12 +390,16 @@ void bus_freq_update(struct clk *clk, bool flag) && (clk_get_usecount(clk) == 0)) { if (low_freq_bus_used() && !low_bus_freq_mode) set_low_bus_freq(); - else + else { /* Set to either high or medium setpoint. */ + mutex_unlock(&bus_freq_mutex); set_high_bus_freq(0); + return; + } } } mutex_unlock(&bus_freq_mutex); + return; } void setup_pll(void) { @@ -404,16 +435,28 @@ static ssize_t bus_freq_scaling_enable_store(struct device *dev, static int busfreq_suspend(struct platform_device *pdev, pm_message_t message) { - set_high_bus_freq(1); - busfreq_suspended = 1; return 0; } +static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event, + void *dummy) +{ + if (event == PM_SUSPEND_PREPARE) { + set_high_bus_freq(1); + busfreq_suspended = 1; + } else if (event == PM_POST_SUSPEND) { + busfreq_suspended = 0; + } + + return NOTIFY_OK; +} static int busfreq_resume(struct platform_device *pdev) { - busfreq_suspended = 0; return 0; } +static struct notifier_block imx_bus_freq_pm_notifier = { + .notifier_call = bus_freq_pm_notify, +}; static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show, bus_freq_scaling_enable_store); @@ -570,6 +613,7 @@ static int __devinit busfreq_probe(struct platform_device *pdev) } INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler); + register_pm_notifier(&imx_bus_freq_pm_notifier); if (!cpu_is_mx6sl()) init_mmdc_settings(); diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index d9af9f6909c1..08e80dc88a2c 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -1280,11 +1280,6 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) else pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk); } - if (cpu_op_tbl[i].cpu_podf) { - __raw_writel(cpu_op_tbl[i].cpu_podf, MXC_CCM_CACRR); - while (__raw_readl(MXC_CCM_CDHIPR)) - ; - } pll1_sys_main_clk.set_rate(&pll1_sys_main_clk, cpu_op_tbl[i].pll_rate); } /* Make sure pll1_sw_clk is from pll1_sys_main_clk */ @@ -2005,7 +2000,7 @@ static struct clk vdoa_clk[] = { }, }; -static unsigned long mx6_timer_rate() +static unsigned long mx6_timer_rate(void) { u32 parent_rate = clk_get_rate(&osc_clk); -- cgit v1.2.3 From d0a8710979c4c60a06717f0e4c8ff650ddc2715d Mon Sep 17 00:00:00 2001 From: make shi Date: Tue, 21 Aug 2012 17:51:18 +0800 Subject: ENGR00220833 mx6sl: USB hsic: enable mx6sl hsic function - Set MX6SL_PAD_HSIC_DAT and MX6SL_PAD_HSIC_STROBE pad DDR attribute as DDR3 - Add imx6sl_add_fsl_ehci_hs and imx6sl_add_fsl_usb2_hs_wakeup in usb_h2.c Signed-off-by: make shi --- arch/arm/mach-mx6/board-mx6sl_arm2.c | 5 +++++ arch/arm/mach-mx6/usb_h2.c | 11 +++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c index 1d76abb8a0b1..5e3d91519c94 100755 --- a/arch/arm/mach-mx6/board-mx6sl_arm2.c +++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c @@ -1080,6 +1080,11 @@ static void __init mx6_arm2_init_usb(void) mx6_set_otghost_vbus_func(imx6_arm2_usbotg_vbus); mx6_usb_dr_init(); #ifdef CONFIG_USB_EHCI_ARC_HSIC + mxc_iomux_set_specialbits_register(MX6SL_PAD_HSIC_DAT, + PAD_CTL_DDR_SEL_DDR3, PAD_CTL_DDR_SEL_MASK); + mxc_iomux_set_specialbits_register(MX6SL_PAD_HSIC_STROBE, + PAD_CTL_DDR_SEL_DDR3, PAD_CTL_DDR_SEL_MASK); + mx6_usb_h2_init(); #endif } diff --git a/arch/arm/mach-mx6/usb_h2.c b/arch/arm/mach-mx6/usb_h2.c index 24083fd52d72..37cad034d173 100644 --- a/arch/arm/mach-mx6/usb_h2.c +++ b/arch/arm/mach-mx6/usb_h2.c @@ -227,9 +227,16 @@ void __init mx6_usb_h2_init(void) struct platform_device *pdev, *pdev_wakeup; static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); usbh2_config.wakeup_pdata = &usbh2_wakeup_config; - pdev = imx6q_add_fsl_ehci_hs(2, &usbh2_config); + if (cpu_is_mx6sl()) + pdev = imx6sl_add_fsl_ehci_hs(2, &usbh2_config); + else + pdev = imx6q_add_fsl_ehci_hs(2, &usbh2_config); + usbh2_wakeup_config.usb_pdata[0] = pdev->dev.platform_data; - pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config); + if (cpu_is_mx6sl()) + pdev_wakeup = imx6sl_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config); + else + pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config); ((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata = pdev_wakeup->dev.platform_data; /* Some phy and power's special controls for host2 -- cgit v1.2.3 From 11fc35eb6355ce57098afc68e74f0018b78ad390 Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Mon, 20 Aug 2012 19:24:28 +0800 Subject: ENGR00220776 mx6dl_arm2: ECSPI pin config overlaped by epdc ECSPI pin MX6DL_PAD_EIM_D17__ECSPI1_MISO is configured overlap by epdc MX6DL_PAD_EIM_D17__GPIO_3_17, so that SPI-NOR flash can't work normally. From schematic of ARM2 board, epdc and spi share this pin if plug epdc daughter board. But SPI-NOR is on ARM2 mother board, so it should be config well firstly. So we make sure SPI-NOR work successfully by default. But if enable epdc , SPI-NOR on ARM2 will work fail. Signed-off-by: Robin Gong --- arch/arm/mach-mx6/board-mx6dl_arm2.h | 4 +++- arch/arm/mach-mx6/board-mx6q_arm2.c | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6dl_arm2.h b/arch/arm/mach-mx6/board-mx6dl_arm2.h index 6ed3e65e68ee..429febb9813d 100644 --- a/arch/arm/mach-mx6/board-mx6dl_arm2.h +++ b/arch/arm/mach-mx6/board-mx6dl_arm2.h @@ -188,7 +188,9 @@ static iomux_v3_cfg_t mx6dl_arm2_pads[] = { MX6DL_PAD_GPIO_6__MLB_MLBSIG, MX6DL_PAD_GPIO_2__MLB_MLBDAT, - /* EPDC pins */ +}; + +static iomux_v3_cfg_t mx6dl_arm2_epdc_pads[] = { MX6DL_PAD_EIM_A17__GPIO_2_21, MX6DL_PAD_EIM_D17__GPIO_3_17, MX6DL_PAD_EIM_A18__GPIO_2_20, diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c index 4b0d5c26de67..29911a232de2 100644 --- a/arch/arm/mach-mx6/board-mx6q_arm2.c +++ b/arch/arm/mach-mx6/board-mx6q_arm2.c @@ -1993,12 +1993,14 @@ static void __init mx6_arm2_init(void) iomux_v3_cfg_t *spdif_pads = NULL; iomux_v3_cfg_t *flexcan_pads = NULL; iomux_v3_cfg_t *i2c3_pads = NULL; + iomux_v3_cfg_t *epdc_pads = NULL; int common_pads_cnt; int esai_rec_pads_cnt; int spdif_pads_cnt; int flexcan_pads_cnt; int i2c3_pads_cnt; + int epdc_pads_cnt; /* @@ -2024,12 +2026,14 @@ static void __init mx6_arm2_init(void) spdif_pads = mx6dl_arm2_spdif_pads; flexcan_pads = mx6dl_arm2_can_pads; i2c3_pads = mx6dl_arm2_i2c3_pads; + epdc_pads = mx6dl_arm2_epdc_pads; common_pads_cnt = ARRAY_SIZE(mx6dl_arm2_pads); esai_rec_pads_cnt = ARRAY_SIZE(mx6dl_arm2_esai_record_pads); spdif_pads_cnt = ARRAY_SIZE(mx6dl_arm2_spdif_pads); flexcan_pads_cnt = ARRAY_SIZE(mx6dl_arm2_can_pads); i2c3_pads_cnt = ARRAY_SIZE(mx6dl_arm2_i2c3_pads); + epdc_pads_cnt = ARRAY_SIZE(mx6dl_arm2_epdc_pads); } BUG_ON(!common_pads); @@ -2207,6 +2211,8 @@ static void __init mx6_arm2_init(void) imx6q_add_mlb150(&mx6_arm2_mlb150_data); if (cpu_is_mx6dl() && epdc_enabled) { + BUG_ON(!epdc_pads); + mxc_iomux_v3_setup_multiple_pads(epdc_pads, epdc_pads_cnt); imx6dl_add_imx_pxp(); imx6dl_add_imx_pxp_client(); mxc_register_device(&max17135_sensor_device, NULL); -- cgit v1.2.3 From 3348f4fc81bd09afa311796dfa1320fcdc7553fb Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Wed, 8 Aug 2012 14:56:15 -0500 Subject: ENGR00220696 [MX6SL]-Reduce IDLE mode power consumption. When ARM enters WFI in low power IDLE state, float the DDR IO pins to drop the power on the VDDHIGH rail. Need to run WFI code from IRAM since DDR needs to be put into self-refresh before changing the IO pins. Drop AHB to 8MHz and DDR to 1MHz when ARM is in WFI when in IDLE state. Set IPG_PERCLK to run at 3MHz, since we want to maintain a 1:2.5 ratio between PERCLK to AHB_CLK. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/Makefile | 2 +- arch/arm/mach-mx6/bus_freq.c | 24 +-- arch/arm/mach-mx6/clock_mx6sl.c | 6 + arch/arm/mach-mx6/mx6sl_wfi.S | 348 ++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-mx6/system.c | 51 +++--- 5 files changed, 401 insertions(+), 30 deletions(-) create mode 100644 arch/arm/mach-mx6/mx6sl_wfi.S (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/Makefile b/arch/arm/mach-mx6/Makefile index 91fc841e9529..49b5f86a6920 100644 --- a/arch/arm/mach-mx6/Makefile +++ b/arch/arm/mach-mx6/Makefile @@ -5,7 +5,7 @@ # Object file lists. obj-y := cpu.o mm.o system.o devices.o dummy_gpio.o irq.o bus_freq.o usb_dr.o usb_h2.o usb_h3.o\ pm.o cpu_op-mx6.o mx6_wfi.o mx6_fec.o mx6_anatop_regulator.o cpu_regulator-mx6.o \ -mx6_mmdc.o mx6_ddr_freq.o mx6sl_ddr.o +mx6_mmdc.o mx6_ddr_freq.o mx6sl_ddr.o mx6sl_wfi.o obj-$(CONFIG_ARCH_MX6) += clock.o mx6_suspend.o clock_mx6sl.o obj-$(CONFIG_MACH_MX6Q_ARM2) += board-mx6q_arm2.o diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index b85c8ec8fd7c..fa11d89e1191 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -75,6 +75,9 @@ unsigned int ddr_normal_rate; int low_freq_bus_used(void); void set_ddr_freq(int ddr_freq); +void *mx6sl_wfi_iram_base; +void (*mx6sl_wfi_iram)(int arm_podf, unsigned long wfi_iram_addr) = NULL; +extern void mx6sl_wait (int arm_podf, unsigned long wfi_iram_addr); void *mx6sl_ddr_freq_base; void (*mx6sl_ddr_freq_change_iram)(int ddr_freq) = NULL; @@ -84,7 +87,6 @@ extern int init_mmdc_settings(void); extern struct cpu_op *(*get_cpu_op)(int *op); extern int update_ddr_freq(int ddr_rate); extern int chip_rev; -extern bool arm_mem_clked_in_wait; DEFINE_MUTEX(bus_freq_mutex); @@ -153,8 +155,6 @@ static void reduce_bus_freq_handler(struct work_struct *work) u32 div; unsigned long flags; - arm_mem_clked_in_wait = true; - spin_lock_irqsave(&freq_lock, flags); /* Set periph_clk to be sourced from OSC_CLK */ @@ -177,7 +177,7 @@ static void reduce_bus_freq_handler(struct work_struct *work) ; clk_set_parent(pll1_sw_clk, pll1); - /* Now change DDR freq in IRAM. */ + /* Now change DDR freq while running from IRAM. */ mx6sl_ddr_freq_change_iram(LPAPM_CLK); low_bus_freq_mode = 1; @@ -308,9 +308,6 @@ int set_high_bus_freq(int high_bus_freq) clk_disable(pll3); } - if (cpu_is_mx6sl()) - arm_mem_clked_in_wait = false; - mutex_unlock(&bus_freq_mutex); return 0; } @@ -618,7 +615,6 @@ static int __devinit busfreq_probe(struct platform_device *pdev) if (!cpu_is_mx6sl()) init_mmdc_settings(); else { -#if 1 unsigned long iram_paddr; /* Allocate IRAM for WFI code when system is @@ -628,12 +624,22 @@ static int __devinit busfreq_probe(struct platform_device *pdev) /* Need to remap the area here since we want * the memory region to be executable. */ + mx6sl_wfi_iram_base = __arm_ioremap(iram_paddr, + SZ_4K, MT_MEMORY_NONCACHED); + memcpy(mx6sl_wfi_iram_base, mx6sl_wait, SZ_4K); + mx6sl_wfi_iram = (void *)mx6sl_wfi_iram_base; + + /* Allocate IRAM for WFI code when system is + *in low freq mode. + */ + iram_alloc(SZ_4K, &iram_paddr); + /* Need to remap the area here since we want the memory region + to be executable. */ mx6sl_ddr_freq_base = __arm_ioremap(iram_paddr, SZ_4K, MT_MEMORY_NONCACHED); memcpy(mx6sl_ddr_freq_base, mx6sl_ddr_iram, SZ_4K); mx6sl_ddr_freq_change_iram = (void *)mx6sl_ddr_freq_base; -#endif } return 0; diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index 8fab0f287ecd..33721a4e212f 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -4000,6 +4000,12 @@ int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc, * should be from OSC24M */ clk_set_parent(&ipg_perclk, &osc_clk); + /* Need to set IPG_PERCLK to 3MHz, so that we can + * satisfy the 2.5:1 AHB:IPG_PERCLK ratio. Since AHB + * can be dropped to as low as 8MHz in low power mode. + */ + clk_set_rate(&ipg_perclk, 3000000); + gpt_clk[0].parent = &ipg_perclk; gpt_clk[0].get_rate = NULL; diff --git a/arch/arm/mach-mx6/mx6sl_wfi.S b/arch/arm/mach-mx6/mx6sl_wfi.S new file mode 100644 index 000000000000..610a57f13730 --- /dev/null +++ b/arch/arm/mach-mx6/mx6sl_wfi.S @@ -0,0 +1,348 @@ +/* + * Copyright (C) 2012 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 +#include +#define IRAM_WAIT_SIZE (1 << 11) + + + .macro sl_ddr_io_save + + ldr r4, [r1, #0x30c] /* DRAM_DQM0 */ + ldr r5, [r1, #0x310] /* DRAM_DQM1 */ + ldr r6, [r1, #0x314] /* DRAM_DQM2 */ + ldr r7, [r1, #0x318] /* DRAM_DQM3 */ + stmfd r9!, {r4-r7} + + ldr r4, [r1, #0x344] /* DRAM_SDQS0 */ + ldr r5, [r1, #0x348] /* DRAM_SDQS1 */ + ldr r6, [r1, #0x34c] /* DRAM_SDQS2 */ + ldr r7, [r1, #0x350] /* DRAM_SDQS3 */ + stmfd r9!, {r4-r7} + + ldr r4, [r1, #0x5c4] /* GPR_B0DS */ + ldr r5, [r1, #0x5cc] /* GPR_B1DS */ + ldr r6, [r1, #0x5d4] /* GPR_B2DS */ + ldr r7, [r1, #0x5d8] /* GPR_B3DS */ + stmfd r9!, {r4-r7} + + ldr r4, [r1, #0x300] /* DRAM_CAS */ + ldr r5, [r1, #0x31c] /* DRAM_RAS */ + ldr r6, [r1, #0x338] /* DRAM_SDCLK_0 */ + ldr r7, [r1, #0x5ac] /* GPR_ADDS*/ + stmfd r9!, {r4-r7} + + ldr r4, [r1, #0x5b0] /* DDRMODE_CTL */ + ldr r5, [r1, #0x5c0] /* DDRMODE */ + ldr r6, [r1, #0x33c] /* DRAM_SODT0*/ + ldr r7, [r1, #0x340] /* DRAM_SODT1*/ + stmfd r9!, {r4-r7} + + ldr r4, [r1, #0x330] /* DRAM_SDCKE0 */ + ldr r5, [r1, #0x334] /* DRAM_SDCKE1 */ + ldr r6, [r1, #0x320] /* DRAM_RESET */ + ldr r7, [r1, #0x5c8] /* GPR_CTLDS */ + stmfd r9!, {r4-r7} + + .endm + + .macro sl_ddr_io_restore + + ldmea r9!, {r4-r7} + str r4, [r1, #0x30c] /* DRAM_DQM0 */ + str r5, [r1, #0x310] /* DRAM_DQM1 */ + str r6, [r1, #0x314] /* DRAM_DQM2 */ + str r7, [r1, #0x318] /* DRAM_DQM3 */ + + ldmea r9!, {r4-r7} + str r4, [r1, #0x344] /* DRAM_SDQS0 */ + str r5, [r1, #0x348] /* DRAM_SDQS1 */ + str r6, [r1, #0x34c] /* DRAM_SDQS2 */ + str r7, [r1, #0x350] /* DRAM_SDQS3 */ + + ldmea r9!, {r4-r7} + str r4, [r1, #0x5c4] /* GPR_B0DS */ + str r5, [r1, #0x5cc] /* GPR_B1DS */ + str r6, [r1, #0x5d4] /* GPR_B2DS */ + str r7, [r1, #0x5d8] /* GPR_B3DS */ + + ldmea r9!, {r4-r7} + str r4, [r1, #0x300] /* DRAM_CAS */ + str r5, [r1, #0x31c] /* DRAM_RAS */ + str r6, [r1, #0x338] /* DRAM_SDCLK_0 */ + str r7, [r1, #0x5ac] /* GPR_ADDS*/ + + ldmea r9!, {r4-r7} + str r4, [r1, #0x5b0] /* DDRMODE_CTL */ + str r5, [r1, #0x5c0] /* DDRMODE */ + str r6, [r1, #0x33c] /* DRAM_SODT0*/ + str r7, [r1, #0x340] /* DRAM_SODT1*/ + + ldmea r9!, {r4-r7} + str r4, [r1, #0x330] /* DRAM_SDCKE0 */ + str r5, [r1, #0x334] /* DRAM_SDCKE1 */ + str r6, [r1, #0x320] /* DRAM_RESET */ + str r7, [r1, #0x5c8] /* GPR_CTLDS */ + + .endm + + .macro sl_ddr_io_set_lpm + + mov r4, #0 + str r4, [r1, #0x30c] /* DRAM_DQM0 */ + str r4, [r1, #0x310] /* DRAM_DQM1 */ + str r4, [r1, #0x314] /* DRAM_DQM2 */ + str r4, [r1, #0x318] /* DRAM_DQM3 */ + + str r4, [r1, #0x344] /* DRAM_SDQS0 */ + str r4, [r1, #0x348] /* DRAM_SDQS1 */ + str r4, [r1, #0x34c] /* DRAM_SDQS2 */ + str r4, [r1, #0x350] /* DRAM_SDQS3 */ + + str r4, [r1, #0x5c4] /* GPR_B0DS */ + str r4, [r1, #0x5cc] /* GPR_B1DS */ + str r4, [r1, #0x5d4] /* GPR_B2DS */ + str r4, [r1, #0x5d8] /* GPR_B3DS */ + + str r4, [r1, #0x300] /* DRAM_CAS */ + str r4, [r1, #0x31c] /* DRAM_RAS */ + str r4, [r1, #0x338] /* DRAM_SDCLK_0 */ + str r4, [r1, #0x5ac] /* GPR_ADDS*/ + + str r4, [r1, #0x5b0] /* DDRMODE_CTL */ + str r4, [r1, #0x5c0] /* DDRMODE */ + str r4, [r1, #0x33c] /* DRAM_SODT0*/ + str r4, [r1, #0x340] /* DRAM_SODT1*/ + + str r4, [r1, #0x5c8] /* GPR_CTLDS */ + mov r4, #0x80000 + str r4, [r1, #0x320] /* DRAM_RESET */ + mov r4, #0x1000 + str r4, [r1, #0x330] /* DRAM_SDCKE0 */ + str r4, [r1, #0x334] /* DRAM_SDCKE1 */ + + .endm + +/* + * mx6sl_wait + * + * Idle the processor (eg, wait for interrupt). + * Make sure DDR is in self-refresh. + * IRQs are already disabled. + * r0 : arm_podf before WFI is entered + * r1: WFI IRAMcode base address. + */ +ENTRY(mx6sl_wait) + + push {r4, r5, r6, r7, r8, r9, r10} + +mx6sl_lpm_wfi: + /* Get the IRAM data storage address. */ + mov r10, r1 + mov r9, r1 /* get suspend_iram_base */ + add r9, r9, #IRAM_WAIT_SIZE /* 4K */ + + ldr r1, =MX6Q_IOMUXC_BASE_ADDR + add r1, r1, #PERIPBASE_VIRT + + /* Save the DDR IO state. */ + sl_ddr_io_save + + ldr r3, =ANATOP_BASE_ADDR + add r3, r3, #PERIPBASE_VIRT + + ldr r2, =CCM_BASE_ADDR + add r2, r2, #PERIPBASE_VIRT + + ldr r8, =MMDC_P0_BASE_ADDR + add r8, r8, #PERIPBASE_VIRT + + + /* Prime all TLB entries. */ + adr r7, mx6sl_lpm_wfi @Address in this function. + + ldr r6, [r7] + + ldr r6, [r8] + ldr r6, [r3] + ldr r6, [r2] + ldr r6, [r1] + + dsb + + /* Disable Automatic power savings. */ + ldr r6, [r8, #0x404] + orr r6, r6, #0x01 + str r6, [r8, #0x404] + + /* Make the DDR explicitly enter self-refresh. */ + ldr r6, [r8, #0x404] + orr r6, r6, #0x200000 + str r6, [r8, #0x404] + +poll_dvfs_set_1: + ldr r6, [r8, #0x404] + and r6, r6, #0x2000000 + cmp r6, #0x2000000 + bne poll_dvfs_set_1 + + /* Now set DDR rate to 1MHz. */ + /* DDR is from bypassed PLL2 on periph2_clk2 path. + * Set the periph2_clk2_podf to divide by 8. + */ + ldr r6, [r2, #0x14] + orr r6, r6, #0x07 + str r6, [r2, #0x14] + + /* Now set MMDC PODF to divide by 3. */ + ldr r6, [r2, #0x14] + bic r6, r6, #0x38 + orr r6, r6, #0x10 + str r6, [r2, #0x14] + + /* Set the DDR IO in LPM state. */ + sl_ddr_io_set_lpm + + /* Set AHB to 8MHz., AXI to 3MHz */ + /* We want to ensure IPG_PERCLK to AHB + * clk ratio is 1:2.5 + */ + /* Store the AXI/AHB podfs. */ + ldr r9, [r2, #0x14] + mov r6, r9 + bic r6, r6, #0x1c00 + orr r6, r6, #0x800 + orr r6, r6, #0x70000 + str r6, [r2, #0x14] + + /* Loop till podf is accepted. */ +ahb_podf: + ldr r6, [r2, #0x48] + cmp r6, #0x0 + bne podf_loop + + /* Now set ARM to 24MHz. */ + /* Move ARM to be sourced from STEP_CLK + * after setting STEP_CLK to 24MHz. + */ + ldr r6, [r2, #0xc] + bic r6, r6, #0x100 + str r6, [r2, #0x0c] + /* Now PLL1_SW_CLK to step_clk. */ + ldr r6, [r2, #0x0c] + orr r6, r6, #0x4 + str r6, [r2, #0x0c] + + /* Bypass PLL1 and power it down. */ + ldr r6, =(1 << 16) + orr r6, r6, #0x1000 + str r6, [r3, #0x04] + + /* Set the ARM PODF to divide by 8. */ + /* IPG is at 4MHz here, we need ARM to + * run at the 12:5 ratio (WAIT mode issue). + */ + ldr r6, =0x7 + str r6, [r2, #0x10] + + /* Loop till podf is accepted. */ +podf_loop: + ldr r6, [r2, #0x48] + cmp r6, #0x0 + bne podf_loop + + /* Now do WFI. */ + dsb + + wfi + + /* Set original ARM PODF back. */ + str r0, [r2, #0x10] + + /* Loop till podf is accepted. */ +podf_loop1: + ldr r6, [r2, #0x48] + cmp r6, #0x0 + bne podf_loop1 + + /* Power up PLL1 and un-bypass it. */ + ldr r6, =(1 << 12) + str r6, [r3, #0x08] + + /* Wait for PLL1 to relock. */ +wait_for_pll_lock: + ldr r6, [r3, #0x0] + and r6, r6, #0x80000000 + cmp r6, #0x80000000 + bne wait_for_pll_lock + + ldr r6, =(1 << 16) + str r6, [r3, #0x08] + + /* Set PLL1_sw_clk back to PLL1. */ + ldr r6, [r2, #0x0c] + bic r6, r6, #0x4 + str r6, [r2, #0xc] + + /* Restore AHB/AXI back. */ + str r9, [r2, #0x14] + + /* Loop till podf is accepted. */ +ahb_podf1: + ldr r6, [r2, #0x48] + cmp r6, #0x0 + bne podf_loop1 + + mov r9, r10 /* get suspend_iram_base */ + add r9, r9, #IRAM_WAIT_SIZE /* 4K */ + + /* Restore the DDR IO before exiting self-refresh. */ + sl_ddr_io_restore + + /* Set MMDC back to 24MHz. */ + /* Set periph2_clk2_podf to divide by 1. */ + /* Now set MMDC PODF to divide by 1. */ + ldr r6, [r2, #0x14] + bic r6, r6, #0x3f + str r6, [r2, #0x14] + + /* clear DVFS - exit from self refresh mode */ + ldr r6, [r8, #0x404] + bic r6, r6, #0x200000 + str r6, [r8, #0x404] + +poll_dvfs_clear_1: + ldr r6, [r8, #0x404] + and r6, r6, #0x2000000 + cmp r6, #0x2000000 + beq poll_dvfs_clear_1 + + /* Enable Automatic power savings. */ + ldr r6, [r8, #0x404] + bic r6, r6, #0x01 + str r6, [r8, #0x404] + + pop {r4,r5, r6, r7, r8, r9, r10} + + /* Restore registers */ + mov pc, lr + + .type mx6sl_do_wait, #object +ENTRY(mx6sl_do_wait) + .word mx6sl_wait + .size mx6sl_wait, . - mx6sl_wait diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c index 57dee5f4c4c0..09940ffd49aa 100644 --- a/arch/arm/mach-mx6/system.c +++ b/arch/arm/mach-mx6/system.c @@ -57,9 +57,10 @@ volatile unsigned int num_cpu_idle; volatile unsigned int num_cpu_idle_lock = 0x0; int wait_mode_arm_podf; int cur_arm_podf; -bool arm_mem_clked_in_wait; void arch_idle_with_workaround(int cpu); +extern void *mx6sl_wfi_iram_base; +extern void (*mx6sl_wfi_iram)(int arm_podf, unsigned long wfi_iram_addr); extern void mx6_wait(void *num_cpu_idle_lock, void *num_cpu_idle, \ int wait_arm_podf, int cur_arm_podf); extern bool enable_wait_mode; @@ -78,6 +79,7 @@ void gpc_set_wakeup(unsigned int irq[4]) return; } + /* set cpu low power mode before WFI instruction */ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode) { @@ -251,25 +253,34 @@ void arch_idle_single_core(void) ca9_do_idle(); } else { - /* - * Implement the 12:5 ARM:IPG_CLK ratio - * workaround for the WAIT mode issue. - * We can directly use the divider to drop the ARM - * core freq in a single core environment. - * Set the ARM_PODF to get the max freq possible - * to avoid the WAIT mode issue when IPG is at 66MHz. - */ - if (cpu_is_mx6sl()) { - reg = __raw_readl(MXC_CCM_CGPR); - reg |= MXC_CCM_CGPR_MEM_IPG_STOP_MASK; - __raw_writel(reg, MXC_CCM_CGPR); - } - __raw_writel(wait_mode_arm_podf, MXC_CCM_CACRR); - while (__raw_readl(MXC_CCM_CDHIPR)) - ; - ca9_do_idle(); + if (low_bus_freq_mode && cpu_is_mx6sl()) { + u32 org_arm_podf = __raw_readl(MXC_CCM_CACRR); - __raw_writel(cur_arm_podf - 1, MXC_CCM_CACRR); + /* Need to run WFI code from IRAM so that + * we can lower DDR freq. + */ + mx6sl_wfi_iram(org_arm_podf, + (unsigned long)mx6sl_wfi_iram_base); + + /* Clear the chicken bit to allow memories + * to be powered down + */ + } else { + /* + * Implement the 12:5 ARM:IPG_CLK ratio + * workaround for the WAIT mode issue. + * We can directly use the divider to drop the ARM + * core freq in a single core environment. + * Set the ARM_PODF to get the max freq possible + * to avoid the WAIT mode issue when IPG is at 66MHz. + */ + __raw_writel(wait_mode_arm_podf, MXC_CCM_CACRR); + while (__raw_readl(MXC_CCM_CDHIPR)) + ; + ca9_do_idle(); + + __raw_writel(cur_arm_podf - 1, MXC_CCM_CACRR); + } } } @@ -331,7 +342,7 @@ void arch_idle(void) { if (enable_wait_mode) { mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); - if ((mem_clk_on_in_wait || arm_mem_clked_in_wait)) { + if (mem_clk_on_in_wait) { u32 reg; /* * MX6SL, MX6Q (TO1.2 or later) and -- cgit v1.2.3 From d25abd9d9818575d9bdef3c6056ba384dfab54a6 Mon Sep 17 00:00:00 2001 From: Nancy Chen Date: Tue, 21 Aug 2012 16:07:49 -0500 Subject: ENGR00220989 [MX6SL]: DDR Controller measure unit workaround [MX6SL]MMDC: DDR Controller's measure unit may return an incorrect value when operating below 100 MHz Signed-off-by: Nancy Chen --- arch/arm/mach-mx6/mx6sl_ddr.S | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/mx6sl_ddr.S b/arch/arm/mach-mx6/mx6sl_ddr.S index 4faa294c3aa7..78208c192b39 100644 --- a/arch/arm/mach-mx6/mx6sl_ddr.S +++ b/arch/arm/mach-mx6/mx6sl_ddr.S @@ -204,6 +204,42 @@ mmdc_podf1: .endm + .macro mmdc_clk_lower_100MHz + + /* Prior to reducing the DDR frequency (at 528/400 MHz), + read the Measure unit count bits (MU_UNIT_DEL_NUM) */ + ldr r5, =0x8B8 + ldr r6, [r8, r5] + /* Original MU unit count */ + mov r6, r6, LSR #16 + ldr r4, =0x3FF + and r6, r6, r4 + /* Original MU unit count * 2 */ + mov r1, r6, LSL #1 + /* Bypass the automatic measure unit when below 100 MHz + by setting the Measure unit bypass enable bit (MU_BYP_EN) */ + ldr r6, [r8, r5] + orr r6, r6, #0x400 + str r6, [r8, r5] + /* Double the measure count value read in step 1 and program it in the + measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit + Register for the reduced frequency operation below 100 MHz */ + ldr r6, [r8, r5] + ldr r4, =0x3FF + bic r6, r6, r4 + orr r6, r6, r1 + str r6, [r8, r5] + .endm + + .macro mmdc_clk_above_100MHz + + /* Make sure that the PHY measurement unit is NOT in bypass mode */ + ldr r5, =0x8B8 + ldr r6, [r8, r5] + bic r6, r6, #0x400 + str r6, [r8, r5] + .endm + /* * mx6sl_ddr_iram * @@ -281,10 +317,12 @@ poll_dvfs_set_1: cmp r0, r1 beq set_to_24MHz + mmdc_clk_above_100MHz ddr_switch_400MHz b done set_to_24MHz: + mmdc_clk_lower_100MHz mx6sl_switch_to_24MHz done: -- cgit v1.2.3 From a6d5151631e09a98484a01d74feba4ad642c2b1c Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Thu, 23 Aug 2012 11:45:22 +0800 Subject: ENGR00221102-2 MX6Q: increase VPU frequence to 352Mhz Increase VPU frequency to 352Mhz for TV box, use pll2_pfd_400M.To avoid impact other code which assume ARM clock sourcing from pll2_pfd_400M, change cpu setpoint of 396M to 352M. and disable bus freq adjust. add CONFIG_MX6_VPU_352M to choose it, default is disabled. Signed-off-by: Robin Gong --- arch/arm/mach-mx6/bus_freq.c | 15 ++++++++++- arch/arm/mach-mx6/clock.c | 6 +++++ arch/arm/mach-mx6/cpu_op-mx6.c | 57 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index fa11d89e1191..1204da8368cc 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -416,7 +416,15 @@ static ssize_t bus_freq_scaling_enable_store(struct device *dev, const char *buf, size_t size) { if (strncmp(buf, "1", 1) == 0) { +#ifdef CONFIG_MX6_VPU_352M + if (cpu_is_mx6q()) + /*do not enable bus freq*/ + bus_freq_scaling_is_active = 0; + printk(KERN_WARNING "Bus frequency can't be enabled if using VPU 352M!\n"); + return size; +#else bus_freq_scaling_is_active = 1; +#endif set_high_bus_freq(0); /* Make sure system can enter low bus mode if it should be in low bus mode */ @@ -669,9 +677,14 @@ static int __init busfreq_init(void) printk(KERN_INFO "Bus freq driver module loaded\n"); +#ifdef CONFIG_MX6_VPU_352M + if (cpu_is_mx6q()) + bus_freq_scaling_is_active = 0;/*disable bus_freq*/ + +#else /* Enable busfreq by default. */ bus_freq_scaling_is_active = 1; - +#endif if (cpu_is_mx6q()) set_high_bus_freq(1); else if (cpu_is_mx6dl()) diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index 08e80dc88a2c..39e39bfe48d4 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -5339,6 +5339,12 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc, clk_tree_init(); +#ifdef CONFIG_MX6_VPU_352M + if (cpu_is_mx6q()) { + clk_set_rate(&pll2_pfd_400M, 352000000); + clk_set_parent(&vpu_clk[0], &pll2_pfd_400M); + } +#endif /* keep correct count. */ clk_enable(&cpu_clk); clk_enable(&periph_clk); diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c index d0a7a42dfb85..db0bacbfa476 100644 --- a/arch/arm/mach-mx6/cpu_op-mx6.c +++ b/arch/arm/mach-mx6/cpu_op-mx6.c @@ -36,9 +36,27 @@ static struct cpu_op mx6_cpu_op_1_2G[] = { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, +#ifdef CONFIG_MX6_VPU_352M + /*VPU 352Mhz need voltage 1.25V*/ + .pu_voltage = 1250000, + .soc_voltage = 1250000, +#else .pu_voltage = 1150000, .soc_voltage = 1150000, +#endif .cpu_voltage = 1100000,}, +#ifdef CONFIG_MX6_VPU_352M + /*pll2_pfd_400M will be fix on 352M,to avoid modify other code + which assume ARM clock sourcing from pll2_pfd_400M, change cpu + freq from 396M to 352M.*/ + { + .pll_rate = 352000000, + .cpu_rate = 352000000, + .cpu_podf = 0, + .pu_voltage = 1250000, + .soc_voltage = 1250000, + .cpu_voltage = 925000,}, +#else { .pll_rate = 396000000, .cpu_rate = 396000000, @@ -46,6 +64,7 @@ static struct cpu_op mx6_cpu_op_1_2G[] = { .pu_voltage = 1150000, .soc_voltage = 1150000, .cpu_voltage = 925000,}, +#endif }; /* working point(wp): 0 - 1GHz; 1 - 792MHz, 2 - 498MHz 3 - 396MHz */ @@ -61,9 +80,27 @@ static struct cpu_op mx6_cpu_op_1G[] = { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, +#ifdef CONFIG_MX6_VPU_352M + /*VPU 352Mhz need voltage 1.25V*/ + .pu_voltage = 1250000, + .soc_voltage = 1250000, +#else .pu_voltage = 1150000, .soc_voltage = 1150000, +#endif .cpu_voltage = 1100000,}, +#ifdef CONFIG_MX6_VPU_352M + /*pll2_pfd_400M will be fix on 352M,to avoid modify other code + which assume ARM clock sourcing from pll2_pfd_400M, change cpu + freq from 396M to 352M.*/ + { + .pll_rate = 352000000, + .cpu_rate = 352000000, + .cpu_podf = 0, + .pu_voltage = 1250000, + .soc_voltage = 1250000, + .cpu_voltage = 925000,}, +#else { .pll_rate = 396000000, .cpu_rate = 396000000, @@ -71,6 +108,7 @@ static struct cpu_op mx6_cpu_op_1G[] = { .pu_voltage = 1150000, .soc_voltage = 1150000, .cpu_voltage = 925000,}, +#endif }; static struct cpu_op mx6_cpu_op[] = { @@ -78,9 +116,27 @@ static struct cpu_op mx6_cpu_op[] = { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, +#ifdef CONFIG_MX6_VPU_352M + /*VPU 352Mhz need voltage 1.25V*/ + .pu_voltage = 1250000, + .soc_voltage = 1250000, +#else .pu_voltage = 1150000, .soc_voltage = 1150000, +#endif .cpu_voltage = 1100000,}, +#ifdef CONFIG_MX6_VPU_352M + /*pll2_pfd_400M will be fix on 352M,to avoid modify other code + which assume ARM clock sourcing from pll2_pfd_400M, change cpu + freq from 396M to 352M.*/ + { + .pll_rate = 352000000, + .cpu_rate = 352000000, + .cpu_podf = 0, + .pu_voltage = 1250000, + .soc_voltage = 1250000, + .cpu_voltage = 925000,}, +#else { .pll_rate = 396000000, .cpu_rate = 396000000, @@ -88,6 +144,7 @@ static struct cpu_op mx6_cpu_op[] = { .pu_voltage = 1150000, .soc_voltage = 1150000, .cpu_voltage = 925000,}, +#endif }; /* working point(wp): 0 - 1.2GHz; 1 - 800MHz, 2 - 400MHz, 3 - 200MHz */ -- cgit v1.2.3 From 42c0071272a9b9b2f936aa222b5c2386fc4de5b7 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Wed, 22 Aug 2012 21:47:59 +0800 Subject: ENGR00221131: imx6sl arm2/evk: add mma8450q accelerometer support mma8450q on E-INK DC3 boards, with i2c address 0x1c on I2C1. Signed-off-by: Robby Cai --- arch/arm/mach-mx6/board-mx6sl_arm2.c | 2 ++ arch/arm/mach-mx6/board-mx6sl_evk.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c index 5e3d91519c94..d1cf110f6c3b 100755 --- a/arch/arm/mach-mx6/board-mx6sl_arm2.c +++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c @@ -562,6 +562,8 @@ static struct i2c_board_info mxc_i2c0_board_info[] __initdata = { }, { I2C_BOARD_INFO("elan-touch", 0x10), .irq = gpio_to_irq(MX6SL_BRD_ELAN_INT), + }, { + I2C_BOARD_INFO("mma8450", 0x1c), }, }; diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c index 7ef077f91cfc..11623ccc68e7 100644 --- a/arch/arm/mach-mx6/board-mx6sl_evk.c +++ b/arch/arm/mach-mx6/board-mx6sl_evk.c @@ -575,6 +575,8 @@ static struct i2c_board_info mxc_i2c0_board_info[] __initdata = { }, { I2C_BOARD_INFO("elan-touch", 0x10), .irq = gpio_to_irq(MX6SL_BRD_ELAN_INT), + }, { + I2C_BOARD_INFO("mma8450", 0x1c), }, }; -- cgit v1.2.3 From 12af2814e89076095dd729cf324fc88088bd79e8 Mon Sep 17 00:00:00 2001 From: Nancy Chen Date: Thu, 23 Aug 2012 16:38:48 -0500 Subject: ENGR00221281 [MX6X] Fix BogoMIPS value is not correct [MX6X] Fix BogoMIPS value is not correct Signed-off-by: Nancy Chen --- arch/arm/mach-mx6/clock.c | 16 ++++++++++++++++ arch/arm/mach-mx6/clock_mx6sl.c | 16 ++++++++++++++++ arch/arm/mach-mx6/system.c | 1 - 3 files changed, 32 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index 39e39bfe48d4..e2d203c0a0e0 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -5304,6 +5304,8 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc, { __iomem void *base; int i, reg; + u32 parent_rate, rate; + unsigned long ipg_clk_rate, max_arm_wait_clk; external_low_reference = ckil; external_high_reference = ckih1; @@ -5510,6 +5512,20 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc, lp_med_freq = 0; lp_audio_freq = 0; + /* Get current ARM_PODF value */ + rate = clk_get_rate(&cpu_clk); + parent_rate = clk_get_rate(&pll1_sw_clk); + cur_arm_podf = parent_rate / rate; + + /* Calculate the ARM_PODF to be applied when the system + * enters WAIT state. + * The max ARM clk is decided by the ipg_clk and has to + * follow the ratio of ARM_CLK:IPG_CLK of 12:5. + */ + ipg_clk_rate = clk_get_rate(&ipg_clk); + max_arm_wait_clk = (12 * ipg_clk_rate) / 5; + wait_mode_arm_podf = parent_rate / max_arm_wait_clk; + /* Turn OFF all unnecessary PHYs. */ if (cpu_is_mx6q()) { /* Turn off SATA PHY. */ diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index 33721a4e212f..9c79f744de99 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -3982,6 +3982,8 @@ int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2) { int i; + u32 parent_rate, rate; + unsigned long ipg_clk_rate, max_arm_wait_clk; external_low_reference = ckil; external_high_reference = ckih1; @@ -4094,6 +4096,20 @@ int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc, lp_high_freq = 0; lp_med_freq = 0; + /* Get current ARM_PODF value */ + rate = clk_get_rate(&cpu_clk); + parent_rate = clk_get_rate(&pll1_sw_clk); + cur_arm_podf = parent_rate / rate; + + /* Calculate the ARM_PODF to be applied when the system + * enters WAIT state. + * The max ARM clk is decided by the ipg_clk and has to + * follow the ratio of ARM_CLK:IPG_CLK of 12:5. + */ + ipg_clk_rate = clk_get_rate(&ipg_clk); + max_arm_wait_clk = (12 * ipg_clk_rate) / 5; + wait_mode_arm_podf = parent_rate / max_arm_wait_clk; + return 0; } diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c index 09940ffd49aa..75701dc6485a 100644 --- a/arch/arm/mach-mx6/system.c +++ b/arch/arm/mach-mx6/system.c @@ -52,7 +52,6 @@ extern unsigned int gpc_wake_irq[4]; static void __iomem *gpc_base = IO_ADDRESS(GPC_BASE_ADDR); -int wait_mode_arm_podf; volatile unsigned int num_cpu_idle; volatile unsigned int num_cpu_idle_lock = 0x0; int wait_mode_arm_podf; -- cgit v1.2.3 From 804a4d36965cec49025174cf25f3f784aba41e32 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Thu, 23 Aug 2012 22:57:50 -0500 Subject: ENGR00221277 MX6DL/S - Set AXI clock to 270MHz Change AXI_CLK to be sourced from PLL3_PFD1_540MHz, so that it can run at 270MHz on MX6DL/S. This is required for improving VPU performance. Change AXI_CLK to be sourced from periph_clk just before the DDR freq is going to be dropped to 24MHz/50MHz. Change it back to PLL3_PFD1_540 when the DDR freq is back at 400MHz. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/bus_freq.c | 21 +++++++++++++++++++++ arch/arm/mach-mx6/clock.c | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index 1204da8368cc..bde499dd02a9 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -109,6 +109,7 @@ static struct clk *pll1_sw_clk; static struct clk *pll3_sw_clk; static struct clk *pll2_200; static struct clk *mmdc_ch0_axi; +static struct clk *pll3_540; static struct delayed_work low_bus_freq_handler; @@ -126,6 +127,14 @@ static void reduce_bus_freq_handler(struct work_struct *work) } if (!cpu_is_mx6sl()) { + if (cpu_is_mx6dl() && + (clk_get_parent(axi_clk) != periph_clk)) + /* Set the axi_clk to be sourced from the periph_clk. + * So that its frequency can be lowered down to 50MHz + * or 24MHz as the case may be. + */ + clk_set_parent(axi_clk, periph_clk); + clk_enable(pll3); if (lp_audio_freq) { /* Need to ensure that PLL2_PFD_400M is kept ON. */ @@ -302,6 +311,11 @@ int set_high_bus_freq(int high_bus_freq) if (audio_bus_freq_mode) clk_disable(pll2_400); + /* AXI_CLK is sourced from PLL3_PFD_540 on MX6DL */ + if (cpu_is_mx6dl() && + clk_get_parent(axi_clk) != pll3_540) + clk_set_parent(axi_clk, pll3_540); + low_bus_freq_mode = 0; audio_bus_freq_mode = 0; @@ -538,6 +552,13 @@ static int __devinit busfreq_probe(struct platform_device *pdev) return PTR_ERR(pll3); } + pll3_540 = clk_get(NULL, "pll3_pfd_540M"); + if (IS_ERR(pll3_540)) { + printk(KERN_DEBUG "%s: failed to get periph_clk\n", + __func__); + return PTR_ERR(pll3_540); + } + pll3_sw_clk = clk_get(NULL, "pll3_sw_clk"); if (IS_ERR(pll3_sw_clk)) { printk(KERN_DEBUG "%s: failed to get pll3_sw_clk\n", diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index e2d203c0a0e0..8835c20ad34b 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -5409,14 +5409,15 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc, /* pxp & epdc */ clk_set_parent(&ipu2_clk, &pll2_pfd_400M); clk_set_rate(&ipu2_clk, 200000000); + clk_set_parent(&axi_clk, &pll3_pfd_540M); } else if (cpu_is_mx6q()) { clk_set_parent(&gpu3d_core_clk[0], &mmdc_ch0_axi_clk[0]); clk_set_rate(&gpu3d_core_clk[0], 528000000); clk_set_parent(&ipu2_clk, &mmdc_ch0_axi_clk[0]); clk_set_parent(&ipu1_clk, &mmdc_ch0_axi_clk[0]); + clk_set_parent(&axi_clk, &periph_clk); } - clk_set_parent(&axi_clk, &periph_clk); /* Need to keep PLL3_PFD_540M enabled until AXI is sourced from it. */ clk_enable(&axi_clk); -- cgit v1.2.3 From cc2e51368f2620a37370746eaf35f0b70674b31e Mon Sep 17 00:00:00 2001 From: make shi Date: Fri, 24 Aug 2012 13:52:38 +0800 Subject: ENGR00221317-01 Mx6 USB host: set stop_mode_config when any USB host enabled MSL headfile part change. Signed-off-by: make shi --- arch/arm/mach-mx6/usb.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/usb.h b/arch/arm/mach-mx6/usb.h index f796e7dad87c..6914246826f6 100644 --- a/arch/arm/mach-mx6/usb.h +++ b/arch/arm/mach-mx6/usb.h @@ -30,6 +30,9 @@ extern void gpio_usbotg_utmi_inactive(void); extern void __init mx6_usb_dr_init(void); extern bool usb_icbug_swfix_need(void); +extern int usb_stop_mode_refcount(bool enable); +extern void usb_stop_mode_lock(void); +extern void usb_stop_mode_unlock(void); extern void __init mx6_usb_h2_init(void); extern void __init mx6_usb_h3_init(void); -- cgit v1.2.3 From c6f69925f9d1f39ccc8c6fcc583122fcf03c105c Mon Sep 17 00:00:00 2001 From: make shi Date: Fri, 24 Aug 2012 13:53:49 +0800 Subject: ENGR00221317-02 Mx6 USB host: set stop_mode_config when any USB host enabled The Mx6 phy sometimes work abnormally after system suspend/resume if the 1V1 is off. So we should keep the 1V1 active during the system suspend if any USB host enabled. - Add stop_mode_config to 1 with refcount - Add mutex to protect the refcount and HW_ANADIG_ANA_MISC0 register - If stop_mode_config is set as 1, the otg vbus wakeup system will be supported Signed-off-by: make shi --- arch/arm/mach-mx6/pm.c | 6 ++++++ arch/arm/mach-mx6/usb_dr.c | 18 ++++++++++++++++++ arch/arm/mach-mx6/usb_h1.c | 13 ++++++++++--- 3 files changed, 34 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c index 50df5714b2d8..dd5db57c984b 100644 --- a/arch/arm/mach-mx6/pm.c +++ b/arch/arm/mach-mx6/pm.c @@ -38,6 +38,7 @@ #endif #include "crm_regs.h" #include "src-reg.h" +#include "regs-anadig.h" #define SCU_CTRL_OFFSET 0x00 #define GPC_IMR1_OFFSET 0x08 @@ -118,6 +119,11 @@ static void usb_power_down_handler(void) { u32 temp; bool usb_oh3_clk_already_on; + if ((__raw_readl(anatop_base + HW_ANADIG_ANA_MISC0) + & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) != 0) { + usb_vbus_wakeup_enabled = false; + return; + } /* enable usb oh3 clock if needed*/ temp = __raw_readl(MXC_CCM_CCGR6); usb_oh3_clk_already_on = \ diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c index 1efac33aa7fc..8cfcb27c7594 100644 --- a/arch/arm/mach-mx6/usb_dr.c +++ b/arch/arm/mach-mx6/usb_dr.c @@ -173,6 +173,9 @@ static int usb_phy_enable(struct fsl_usb2_platform_data *pdata) static int usbotg_init_ext(struct platform_device *pdev) { struct clk *usb_clk; +#ifdef CONFIG_USB_EHCI_ARC_OTG + void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); +#endif u32 ret; /* at mx6q: this clock is AHB clock for usb core */ @@ -198,6 +201,12 @@ static int usbotg_init_ext(struct platform_device *pdev) mdelay(3); } otg_used++; +#ifdef CONFIG_USB_EHCI_ARC_OTG + usb_stop_mode_lock(); + if (usb_stop_mode_refcount(true) == 1) + __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base_addr + HW_ANADIG_ANA_MISC0_SET); + usb_stop_mode_unlock(); +#endif return ret; } @@ -205,6 +214,9 @@ static int usbotg_init_ext(struct platform_device *pdev) static void usbotg_uninit_ext(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; +#ifdef CONFIG_USB_EHCI_ARC_OTG + void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); +#endif clk_disable(usb_phy1_clk); clk_put(usb_phy1_clk); @@ -214,6 +226,12 @@ static void usbotg_uninit_ext(struct platform_device *pdev) usbotg_uninit(pdata); otg_used--; +#ifdef CONFIG_USB_EHCI_ARC_OTG + usb_stop_mode_lock(); + if (usb_stop_mode_refcount(false) == 0) + __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base_addr + HW_ANADIG_ANA_MISC0_CLR); + usb_stop_mode_unlock(); +#endif } static void usbotg_clock_gate(bool on) diff --git a/arch/arm/mach-mx6/usb_h1.c b/arch/arm/mach-mx6/usb_h1.c index 92ef0ec3c3f5..3e2f50ab6b55 100644 --- a/arch/arm/mach-mx6/usb_h1.c +++ b/arch/arm/mach-mx6/usb_h1.c @@ -134,6 +134,7 @@ static int fsl_usb_host_init_ext(struct platform_device *pdev) { int ret; struct clk *usb_clk; + void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); usb_clk = clk_get(NULL, "usboh3_clk"); clk_enable(usb_clk); usb_oh3_clk = usb_clk; @@ -145,19 +146,25 @@ static int fsl_usb_host_init_ext(struct platform_device *pdev) } usbh1_internal_phy_clock_gate(true); usb_phy_enable(pdev->dev.platform_data); - + usb_stop_mode_lock(); + if (usb_stop_mode_refcount(true) == 1) + __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base_addr + HW_ANADIG_ANA_MISC0_SET); + usb_stop_mode_unlock(); return 0; } static void fsl_usb_host_uninit_ext(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; - + void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); fsl_usb_host_uninit(pdata); clk_disable(usb_oh3_clk); clk_put(usb_oh3_clk); - + usb_stop_mode_lock(); + if (usb_stop_mode_refcount(false) == 0) + __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base_addr + HW_ANADIG_ANA_MISC0_CLR); + usb_stop_mode_unlock(); } static void usbh1_clock_gate(bool on) -- cgit v1.2.3 From 09e051a96afc77a58b51eed3841a03631321a1e4 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Tue, 21 Aug 2012 13:46:43 +0800 Subject: ENGR00220796-3: imx6sl arm2/evk: Add platform_device for V4L2 support Add platform device for V4L2 support Signed-off-by: Robby Cai --- arch/arm/mach-mx6/board-mx6sl_arm2.c | 1 + arch/arm/mach-mx6/board-mx6sl_evk.c | 1 + arch/arm/mach-mx6/devices-imx6q.h | 3 +++ 3 files changed, 5 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c index d1cf110f6c3b..45b33c9caace 100755 --- a/arch/arm/mach-mx6/board-mx6sl_arm2.c +++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c @@ -1260,6 +1260,7 @@ static void __init mx6_arm2_init(void) imx6q_add_busfreq(); imx6sl_add_dcp(); imx6sl_add_rngb(); + imx6sl_add_imx_pxp_v4l2(); imx6q_add_perfmon(0); imx6q_add_perfmon(1); diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c index 11623ccc68e7..40c05c451e7a 100644 --- a/arch/arm/mach-mx6/board-mx6sl_evk.c +++ b/arch/arm/mach-mx6/board-mx6sl_evk.c @@ -1267,6 +1267,7 @@ static void __init mx6_evk_init(void) imx6q_add_busfreq(); imx6sl_add_dcp(); imx6sl_add_rngb(); + imx6sl_add_imx_pxp_v4l2(); imx6q_add_perfmon(0); imx6q_add_perfmon(1); diff --git a/arch/arm/mach-mx6/devices-imx6q.h b/arch/arm/mach-mx6/devices-imx6q.h index c75aed86800b..f91369ffc280 100644 --- a/arch/arm/mach-mx6/devices-imx6q.h +++ b/arch/arm/mach-mx6/devices-imx6q.h @@ -220,6 +220,9 @@ extern const struct imx_pxp_data imx6dl_pxp_data __initconst; #define imx6dl_add_imx_pxp_client() \ imx_add_imx_pxp_client() +#define imx6sl_add_imx_pxp_v4l2() \ + imx_add_imx_pxp_v4l2() + extern const struct imx_epdc_data imx6dl_epdc_data __initconst; #define imx6dl_add_imx_epdc(pdata) \ imx_add_imx_epdc(&imx6dl_epdc_data, pdata) -- cgit v1.2.3 From 0b04f438957b0d93718650058a39653cdd8c1c34 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Sun, 26 Aug 2012 00:54:33 -0500 Subject: ENGR00221441 MX6SL - Update voltages based on the latest datasheet. Add a new working point table to MX6SL and set the voltages according to the latest datasheet. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/cpu_op-mx6.c | 83 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 10 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c index db0bacbfa476..3415f01f238c 100644 --- a/arch/arm/mach-mx6/cpu_op-mx6.c +++ b/arch/arm/mach-mx6/cpu_op-mx6.c @@ -24,7 +24,7 @@ extern u32 arm_max_freq; static int num_cpu_op; /* working point(wp): 0 - 1.2GHz; 1 - 792MHz, 2 - 498MHz 3 - 396MHz */ -static struct cpu_op mx6_cpu_op_1_2G[] = { +static struct cpu_op mx6q_cpu_op_1_2G[] = { { .pll_rate = 1200000000, .cpu_rate = 1200000000, @@ -68,7 +68,7 @@ static struct cpu_op mx6_cpu_op_1_2G[] = { }; /* working point(wp): 0 - 1GHz; 1 - 792MHz, 2 - 498MHz 3 - 396MHz */ -static struct cpu_op mx6_cpu_op_1G[] = { +static struct cpu_op mx6q_cpu_op_1G[] = { { .pll_rate = 996000000, .cpu_rate = 996000000, @@ -111,7 +111,7 @@ static struct cpu_op mx6_cpu_op_1G[] = { #endif }; -static struct cpu_op mx6_cpu_op[] = { +static struct cpu_op mx6q_cpu_op[] = { { .pll_rate = 792000000, .cpu_rate = 792000000, @@ -233,6 +233,61 @@ static struct cpu_op mx6dl_cpu_op[] = { .cpu_voltage = 1025000,}, }; +static struct cpu_op mx6sl_cpu_op_1G[] = { + { + .pll_rate = 996000000, + .cpu_rate = 996000000, + .cpu_podf = 0, + .pu_voltage = 1225000, + .soc_voltage = 1225000, + .cpu_voltage = 1275000,}, + { + .pll_rate = 792000000, + .cpu_rate = 792000000, + .cpu_podf = 0, + .pu_voltage = 1150000, + .soc_voltage = 1150000, + .cpu_voltage = 1200000,}, + { + .pll_rate = 396000000, + .cpu_rate = 396000000, + .cpu_podf = 0, + .pu_voltage = 1050000, + .soc_voltage = 1050000, + .cpu_voltage = 1100000,}, + { + .pll_rate = 396000000, + .cpu_rate = 198000000, + .cpu_podf = 1, + .pu_voltage = 1050000, + .soc_voltage = 1050000, + .cpu_voltage = 1050000,}, +}; + +static struct cpu_op mx6sl_cpu_op[] = { + { + .pll_rate = 792000000, + .cpu_rate = 792000000, + .cpu_podf = 0, + .pu_voltage = 1150000, + .soc_voltage = 1150000, + .cpu_voltage = 1200000,}, + { + .pll_rate = 396000000, + .cpu_rate = 396000000, + .cpu_podf = 0, + .pu_voltage = 1050000, + .soc_voltage = 1050000, + .cpu_voltage = 1100000,}, + { + .pll_rate = 396000000, + .cpu_rate = 198000000, + .cpu_podf = 1, + .pu_voltage = 1050000, + .soc_voltage = 1050000, + .cpu_voltage = 1050000,}, +}; + static struct dvfs_op dvfs_core_setpoint_1_2G[] = { {33, 14, 33, 10, 128, 0x10}, /* 1.2GHz*/ {30, 12, 33, 100, 200, 0x10}, /* 800MHz */ @@ -279,16 +334,24 @@ struct cpu_op *mx6_get_cpu_op(int *op) *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op); return mx6dl_cpu_op; } - } else { + } else if (cpu_is_mx6q()) { if (arm_max_freq == CPU_AT_1_2GHz) { - *op = num_cpu_op = ARRAY_SIZE(mx6_cpu_op_1_2G); - return mx6_cpu_op_1_2G; + *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1_2G); + return mx6q_cpu_op_1_2G; } else if (arm_max_freq == CPU_AT_1GHz) { - *op = num_cpu_op = ARRAY_SIZE(mx6_cpu_op_1G); - return mx6_cpu_op_1G; + *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1G); + return mx6q_cpu_op_1G; + } else { + *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op); + return mx6q_cpu_op; + } + } else { + if (arm_max_freq == CPU_AT_1GHz) { + *op = num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op_1G); + return mx6sl_cpu_op_1G; } else { - *op = num_cpu_op = ARRAY_SIZE(mx6_cpu_op); - return mx6_cpu_op; + *op = num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op); + return mx6sl_cpu_op; } } } -- cgit v1.2.3 From df63a57d034f77674d2fce9949f0eef6570e02f0 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Sat, 25 Aug 2012 00:14:51 -0500 Subject: ENGR00221440 MX6x-Fix race-condition in checking bus_freq variables Checking of the bus_freq variables and changing of the bus/ddr frequency should be done under one mutex. Else there is a race-condition that the variable changed just after it was checked. Also ensure that the bus freq is always increased before the cpu freq is set to anything other than the lowest setpoint. Else there is a possibility that the ARM is set to run from PLL1 at higher frequency when bus/DDR are still at 24MHz. This is dangerous since when system enters WAIT mode in low bus freq state, PLL1 is set to bypass when ARM is being sourced from it. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/bus_freq.c | 159 +++++++++++++++++++++------------------- arch/arm/mach-mx6/clock.c | 13 +++- arch/arm/mach-mx6/clock_mx6sl.c | 27 ++++--- 3 files changed, 111 insertions(+), 88 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index bde499dd02a9..53a65fb893f6 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -69,6 +69,7 @@ int bus_freq_scaling_is_active; int lp_high_freq; int lp_med_freq; int lp_audio_freq; +int high_cpu_freq; unsigned int ddr_low_rate; unsigned int ddr_med_rate; unsigned int ddr_normal_rate; @@ -194,7 +195,6 @@ static void reduce_bus_freq_handler(struct work_struct *work) spin_unlock_irqrestore(&freq_lock, flags); } - high_bus_freq_mode = 0; mutex_unlock(&bus_freq_mutex); } @@ -225,40 +225,34 @@ int set_high_bus_freq(int high_bus_freq) { if (bus_freq_scaling_initialized && bus_freq_scaling_is_active) cancel_delayed_work_sync(&low_bus_freq_handler); - mutex_lock(&bus_freq_mutex); - if (busfreq_suspended) { - mutex_unlock(&bus_freq_mutex); + + if (busfreq_suspended) return 0; - } - if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active) { - mutex_unlock(&bus_freq_mutex); + + if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active) return 0; - } - if (high_bus_freq_mode && high_bus_freq) { - mutex_unlock(&bus_freq_mutex); + + if (high_bus_freq_mode && high_bus_freq) return 0; - } - if (med_bus_freq_mode && !high_bus_freq) { - mutex_unlock(&bus_freq_mutex); + + /* medium bus freq is only supported for MX6DQ */ + if (cpu_is_mx6q() && med_bus_freq_mode && !high_bus_freq) return 0; - } if (cpu_is_mx6dl() && high_bus_freq) high_bus_freq = 0; - if (cpu_is_mx6dl() && med_bus_freq_mode) { - mutex_unlock(&bus_freq_mutex); + if (cpu_is_mx6dl() && med_bus_freq_mode) return 0; - } + if ((high_bus_freq_mode && (high_bus_freq || lp_high_freq)) || (med_bus_freq_mode && !high_bus_freq && lp_med_freq && - !lp_high_freq)) { - mutex_unlock(&bus_freq_mutex); + !lp_high_freq)) return 0; - } + if (cpu_is_mx6sl()) { u32 reg; unsigned long flags; @@ -321,8 +315,6 @@ int set_high_bus_freq(int high_bus_freq) clk_disable(pll3); } - - mutex_unlock(&bus_freq_mutex); return 0; } @@ -334,11 +326,8 @@ int low_freq_bus_used(void) /* We only go the lowest setpoint if ARM is also * at the lowest setpoint. */ - if ((clk_get_rate(cpu_clk) > - cpu_op_tbl[cpu_op_nr - 1].cpu_rate) - || (cpu_op_nr == 1)) { + if (high_cpu_freq) return 0; - } if ((lp_high_freq == 0) && (lp_med_freq == 0)) @@ -350,62 +339,80 @@ int low_freq_bus_used(void) void bus_freq_update(struct clk *clk, bool flag) { mutex_lock(&bus_freq_mutex); + if (flag) { - /* Update count */ - if (clk->flags & AHB_HIGH_SET_POINT) - lp_high_freq++; - else if (clk->flags & AHB_MED_SET_POINT) - lp_med_freq++; - else if (clk->flags & AHB_AUDIO_SET_POINT) - lp_audio_freq++; - /* Update bus freq */ - if ((clk->flags & CPU_FREQ_TRIG_UPDATE) - && (clk_get_usecount(clk) == 0)) { - if (!(clk->flags & - (AHB_HIGH_SET_POINT | AHB_MED_SET_POINT))) { - if (low_freq_bus_used()) { - if ((clk->flags & AHB_AUDIO_SET_POINT) & !audio_bus_freq_mode) - set_low_bus_freq(); - else if (!low_bus_freq_mode) - set_low_bus_freq(); - } - } else { - if ((clk->flags & AHB_MED_SET_POINT) - && !med_bus_freq_mode) { - /* Set to Medium setpoint */ - mutex_unlock(&bus_freq_mutex); + if (clk == cpu_clk) { + /* The CPU freq is being increased. + * check if we need to increase the bus freq + */ + high_cpu_freq = 1; + if (low_bus_freq_mode || audio_bus_freq_mode) set_high_bus_freq(0); - return; - } - else if ((clk->flags & AHB_HIGH_SET_POINT) - && !high_bus_freq_mode) { - /* Currently at low or medium set point, - * need to set to high setpoint - */ - mutex_unlock(&bus_freq_mutex); - set_high_bus_freq(1); - return; - } + } else { + /* Update count */ + if (clk->flags & AHB_HIGH_SET_POINT) + lp_high_freq++; + else if (clk->flags & AHB_MED_SET_POINT) + lp_med_freq++; + else if (clk->flags & AHB_AUDIO_SET_POINT) + lp_audio_freq++; + /* Update bus freq */ + if ((clk->flags & CPU_FREQ_TRIG_UPDATE) + && (clk_get_usecount(clk) == 0)) { + if (!(clk->flags & + (AHB_HIGH_SET_POINT | AHB_MED_SET_POINT))) { + if (low_freq_bus_used()) { + if ((clk->flags & AHB_AUDIO_SET_POINT) & + !audio_bus_freq_mode) + set_low_bus_freq(); + else if (!low_bus_freq_mode) + set_low_bus_freq(); + } + } else { + if ((clk->flags & AHB_MED_SET_POINT) + && !med_bus_freq_mode) { + /* Set to Medium setpoint */ + set_high_bus_freq(0); + } else if ((clk->flags & AHB_HIGH_SET_POINT) + && !high_bus_freq_mode) { + /* Currently at low or medium + * set point, need to set to + * high setpoint + */ + set_high_bus_freq(1); + } + } } } } else { - /* Update count */ - if (clk->flags & AHB_HIGH_SET_POINT) - lp_high_freq--; - else if (clk->flags & AHB_MED_SET_POINT) - lp_med_freq--; - else if (clk->flags & AHB_AUDIO_SET_POINT) - lp_audio_freq--; - /* Update bus freq */ - if ((clk->flags & CPU_FREQ_TRIG_UPDATE) - && (clk_get_usecount(clk) == 0)) { - if (low_freq_bus_used() && !low_bus_freq_mode) + if (clk == cpu_clk) { + /* CPU freq is dropped, check if we can + * lower the bus freq. + */ + high_cpu_freq = 0; + + if (low_freq_bus_used() && + !(low_bus_freq_mode || audio_bus_freq_mode)) set_low_bus_freq(); - else { - /* Set to either high or medium setpoint. */ - mutex_unlock(&bus_freq_mutex); - set_high_bus_freq(0); - return; + } else { + /* Update count */ + if (clk->flags & AHB_HIGH_SET_POINT) + lp_high_freq--; + else if (clk->flags & AHB_MED_SET_POINT) + lp_med_freq--; + else if (clk->flags & AHB_AUDIO_SET_POINT) + lp_audio_freq--; + /* Update bus freq */ + if ((clk->flags & CPU_FREQ_TRIG_UPDATE) + && (clk_get_usecount(clk) == 0)) { + if (low_freq_bus_used()) + set_low_bus_freq(); + else { + /* Set to either high or + * medium setpoint. + */ + set_high_bus_freq(0); + } } } } diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index 8835c20ad34b..e0348e4f2e33 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -472,7 +472,6 @@ static int _clk_pll_enable(struct clk *clk) pllbase = _get_pll_base(clk); reg = __raw_readl(pllbase); - reg &= ~ANADIG_PLL_BYPASS; reg &= ~ANADIG_PLL_POWER_DOWN; /* The 480MHz PLLs have the opposite definition for power bit. */ @@ -492,6 +491,7 @@ static int _clk_pll_enable(struct clk *clk) /* Enable the PLL output now*/ reg = __raw_readl(pllbase); + reg &= ~ANADIG_PLL_BYPASS; reg |= ANADIG_PLL_ENABLE; __raw_writel(reg, pllbase); @@ -1262,14 +1262,17 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) */ if (pll1_sw_clk.parent != &pll2_pfd_400M) { pll2_pfd_400M.enable(&pll2_pfd_400M); + pll2_pfd_400M.usecount++; arm_needs_pll2_400 = true; pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M); pll1_sw_clk.parent = &pll2_pfd_400M; } } else { /* Make sure PLL1 is enabled */ - if (!pll1_enabled) + if (!pll1_enabled) { pll1_sys_main_clk.enable(&pll1_sys_main_clk); + pll1_sys_main_clk.usecount = 1; + } /* Make sure PLL1 rate is what we want */ if (cpu_op_tbl[i].pll_rate != clk_get_rate(&pll1_sys_main_clk)) { /* If pll1_sw_clk is from pll1_sys_main_clk, switch it */ @@ -1285,6 +1288,8 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) /* Make sure pll1_sw_clk is from pll1_sys_main_clk */ pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); pll1_sw_clk.parent = &pll1_sys_main_clk; + if (arm_needs_pll2_400) + pll2_pfd_400M.usecount--; arm_needs_pll2_400 = false; if (pll2_pfd_400M.usecount == 0) pll2_pfd_400M.disable(&pll2_pfd_400M); @@ -1323,8 +1328,10 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) while (__raw_readl(MXC_CCM_CDHIPR)) ; - if (pll1_sys_main_clk.usecount == 1 && arm_needs_pll2_400) + if (pll1_sys_main_clk.usecount == 1 && arm_needs_pll2_400) { pll1_sys_main_clk.disable(&pll1_sys_main_clk); + pll1_sys_main_clk.usecount = 0; + } spin_unlock_irqrestore(&clk_lock, flags); diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index 9c79f744de99..d93320d59dd8 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -67,6 +67,7 @@ static struct clk pll7_usb_host_main_clk; static struct clk usdhc3_clk; static struct clk ipg_clk; static struct clk gpt_clk[]; +static struct clk ahb_clk; static struct cpu_op *cpu_op_tbl; static int cpu_op_nr; @@ -412,6 +413,7 @@ static int _clk_pfd_enable(struct clk *clk) __raw_writel((1 << (clk->enable_shift + 7)), (int)clk->enable_reg + 8); + udelay(3); return 0; } @@ -430,7 +432,6 @@ static int _clk_pll_enable(struct clk *clk) pllbase = _get_pll_base(clk); reg = __raw_readl(pllbase); - reg &= ~ANADIG_PLL_BYPASS; reg &= ~ANADIG_PLL_POWER_DOWN; /* The 480MHz PLLs have the opposite definition for power bit. */ @@ -450,6 +451,7 @@ static int _clk_pll_enable(struct clk *clk) /* Enable the PLL output now*/ reg = __raw_readl(pllbase); + reg &= ~ANADIG_PLL_BYPASS; reg |= ANADIG_PLL_ENABLE; __raw_writel(reg, pllbase); @@ -1153,6 +1155,11 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) if (i >= cpu_op_nr) return -EINVAL; + if (clk_get_rate(&ahb_clk) == 24000000) { + printk(KERN_INFO "we should not be here!!!!! AHB is at 24MHz....cpu_rate requested = %ld\n", rate); + dump_stack(); + BUG(); + } spin_lock_irqsave(&mx6sl_clk_lock, flags); if (rate <= clk_get_rate(&pll2_pfd2_400M)) { @@ -1161,14 +1168,17 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) */ if (pll1_sw_clk.parent != &pll2_pfd2_400M) { pll2_pfd2_400M.enable(&pll2_pfd2_400M); + pll2_pfd2_400M.usecount++; arm_needs_pll2_400 = true; pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd2_400M); pll1_sw_clk.parent = &pll2_pfd2_400M; } } else { /* Make sure PLL1 is enabled */ - if (!pll1_enabled) + if (!pll1_enabled) { pll1_sys_main_clk.enable(&pll1_sys_main_clk); + pll1_sys_main_clk.usecount = 1; + } if (cpu_op_tbl[i].pll_rate != clk_get_rate(&pll1_sys_main_clk)) { if (pll1_sw_clk.parent == &pll1_sys_main_clk) { /* Change the PLL1 rate. */ @@ -1177,15 +1187,13 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) else pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk); } - if (cpu_op_tbl[i].cpu_podf) { - __raw_writel(cpu_op_tbl[i].cpu_podf, MXC_CCM_CACRR); - while (__raw_readl(MXC_CCM_CDHIPR)) - ; - } pll1_sys_main_clk.set_rate(&pll1_sys_main_clk, cpu_op_tbl[i].pll_rate); } pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); pll1_sw_clk.parent = &pll1_sys_main_clk; + + if (arm_needs_pll2_400) + pll2_pfd2_400M.usecount--; arm_needs_pll2_400 = false; if (pll2_pfd2_400M.usecount == 0) pll2_pfd2_400M.disable(&pll2_pfd2_400M); @@ -1224,9 +1232,10 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) while (__raw_readl(MXC_CCM_CDHIPR)) ; - if (pll1_sys_main_clk.usecount == 1 && arm_needs_pll2_400) + if (pll1_sys_main_clk.usecount == 1 && arm_needs_pll2_400) { pll1_sys_main_clk.disable(&pll1_sys_main_clk); - + pll1_sys_main_clk.usecount = 0; + } spin_unlock_irqrestore(&mx6sl_clk_lock, flags); return 0; -- cgit v1.2.3 From d3f7f366becf5e31225dbe1aaceef84813f7ccb8 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Wed, 22 Aug 2012 13:26:11 -0500 Subject: ENGR00221161 [MX6SL]- Add audio bus freq mode support. Set DDR to 50MHz in low power audio playback. AHB/AXI are at 24MHz. Also fix correct usecount for PLL1 main clock. If not it causes issues when pll1_sw_clk's parent is changed. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/bus_freq.c | 101 ++++++++++++++++---------- arch/arm/mach-mx6/clock_mx6sl.c | 7 +- arch/arm/mach-mx6/mx6sl_ddr.S | 156 ++++++++++++++++++++++++++++------------ arch/arm/mach-mx6/mx6sl_wfi.S | 22 ++++++ arch/arm/mach-mx6/system.c | 40 ++++++++--- 5 files changed, 231 insertions(+), 95 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index 53a65fb893f6..8c04e51d8827 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -47,6 +47,7 @@ #include #define LPAPM_CLK 24000000 +#define DDR_AUDIO_CLK 50000000 #define DDR_MED_CLK 400000000 #define DDR3_NORMAL_CLK 528000000 #define GPC_PGC_GPU_PGCR_OFFSET 0x260 @@ -81,7 +82,7 @@ void (*mx6sl_wfi_iram)(int arm_podf, unsigned long wfi_iram_addr) = NULL; extern void mx6sl_wait (int arm_podf, unsigned long wfi_iram_addr); void *mx6sl_ddr_freq_base; -void (*mx6sl_ddr_freq_change_iram)(int ddr_freq) = NULL; +void (*mx6sl_ddr_freq_change_iram)(int ddr_freq, int low_bus_freq_mode) = NULL; extern void mx6sl_ddr_iram(int ddr_freq); extern int init_mmdc_settings(void); @@ -140,13 +141,13 @@ static void reduce_bus_freq_handler(struct work_struct *work) if (lp_audio_freq) { /* Need to ensure that PLL2_PFD_400M is kept ON. */ clk_enable(pll2_400); - update_ddr_freq(50000000); + update_ddr_freq(DDR_AUDIO_CLK); /* Make sure periph clk's parent also got updated */ clk_set_parent(periph_clk, pll2_200); audio_bus_freq_mode = 1; low_bus_freq_mode = 0; } else { - update_ddr_freq(24000000); + update_ddr_freq(LPAPM_CLK); /* Make sure periph clk's parent also got updated */ clk_set_parent(periph_clk, osc_clk); if (audio_bus_freq_mode) @@ -167,32 +168,61 @@ static void reduce_bus_freq_handler(struct work_struct *work) spin_lock_irqsave(&freq_lock, flags); - /* Set periph_clk to be sourced from OSC_CLK */ - /* Set AXI to 24MHz. */ - clk_set_parent(periph_clk, osc_clk); - clk_set_rate(axi_clk, clk_round_rate(axi_clk, LPAPM_CLK)); - /* Set AHB to 24MHz. */ - clk_set_rate(ahb_clk, clk_round_rate(ahb_clk, LPAPM_CLK)); - - /* Set MMDC clk to 24MHz. */ - /* Since we are going to set PLL2 in bypass mode, - * move the CPU clock off PLL2. - */ - /* Ensure that the clock will be at lowest possible freq. */ - org_arm_podf = __raw_readl(MXC_CCM_CACRR); - div = clk_get_rate(pll1) / cpu_op_tbl[cpu_op_nr - 1].cpu_rate; - - reg = __raw_writel(div - 1, MXC_CCM_CACRR); - while (__raw_readl(MXC_CCM_CDHIPR)) - ; - clk_set_parent(pll1_sw_clk, pll1); + if (high_bus_freq_mode) { + /* Set periph_clk to be sourced from OSC_CLK */ + /* Set AXI to 24MHz. */ + clk_set_parent(periph_clk, osc_clk); + clk_set_rate(axi_clk, + clk_round_rate(axi_clk, LPAPM_CLK)); + /* Set AHB to 24MHz. */ + clk_set_rate(ahb_clk, + clk_round_rate(ahb_clk, LPAPM_CLK)); + } + if (lp_audio_freq) { + /* PLL2 is on in this mode, as DDR is at 50MHz. */ + /* Now change DDR freq while running from IRAM. */ + mx6sl_ddr_freq_change_iram(DDR_AUDIO_CLK, + low_bus_freq_mode); + + if (low_bus_freq_mode) { + /* Swtich ARM to run off PLL2_PFD2_400MHz + * since DDR is anway at 50MHz. + */ + clk_set_parent(pll1_sw_clk, pll2_400); + + /* Ensure that the clock will be + * at original speed. + */ + reg = __raw_writel(org_arm_podf, MXC_CCM_CACRR); + while (__raw_readl(MXC_CCM_CDHIPR)) + ; + } + low_bus_freq_mode = 0; + audio_bus_freq_mode = 1; + } else { + /* Set MMDC clk to 24MHz. */ + /* Since we are going to set PLL2 in bypass mode, + * move the CPU clock off PLL2. + */ + /* Ensure that the clock will be at + * lowest possible freq. + */ + org_arm_podf = __raw_readl(MXC_CCM_CACRR); + div = clk_get_rate(pll1) / + cpu_op_tbl[cpu_op_nr - 1].cpu_rate; - /* Now change DDR freq while running from IRAM. */ - mx6sl_ddr_freq_change_iram(LPAPM_CLK); + reg = __raw_writel(div - 1, MXC_CCM_CACRR); + while (__raw_readl(MXC_CCM_CDHIPR)) + ; + clk_set_parent(pll1_sw_clk, pll1); - low_bus_freq_mode = 1; - audio_bus_freq_mode = 0; + /* Now change DDR freq while running from IRAM. */ + mx6sl_ddr_freq_change_iram(LPAPM_CLK, + low_bus_freq_mode); + low_bus_freq_mode = 1; + audio_bus_freq_mode = 0; + } spin_unlock_irqrestore(&freq_lock, flags); } high_bus_freq_mode = 0; @@ -258,9 +288,8 @@ int set_high_bus_freq(int high_bus_freq) unsigned long flags; spin_lock_irqsave(&freq_lock, flags); - /* Change DDR freq in IRAM. */ - mx6sl_ddr_freq_change_iram(ddr_normal_rate); + mx6sl_ddr_freq_change_iram(ddr_normal_rate, low_bus_freq_mode); /* Set periph_clk to be sourced from pll2_pfd2_400M */ /* First need to set the divider before changing the */ @@ -271,18 +300,18 @@ int set_high_bus_freq(int high_bus_freq) clk_round_rate(axi_clk, LPAPM_CLK / 2)); clk_set_parent(periph_clk, pll2_400); - /* Now move ARM to be sourced from PLL2_400 too. */ - clk_set_parent(pll1_sw_clk, pll2_400); - - /* Ensure that the clock will be at original speed. */ - reg = __raw_writel(org_arm_podf, MXC_CCM_CACRR); - while (__raw_readl(MXC_CCM_CDHIPR)) - ; + if (low_bus_freq_mode) { + /* Now move ARM to be sourced from PLL2_400 too. */ + clk_set_parent(pll1_sw_clk, pll2_400); + /* Ensure that the clock will be at original speed. */ + reg = __raw_writel(org_arm_podf, MXC_CCM_CACRR); + while (__raw_readl(MXC_CCM_CDHIPR)) + ; + } high_bus_freq_mode = 1; low_bus_freq_mode = 0; audio_bus_freq_mode = 0; - spin_unlock_irqrestore(&freq_lock, flags); } else { clk_enable(pll3); diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index d93320d59dd8..4839f1542b3a 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -1236,6 +1236,7 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) pll1_sys_main_clk.disable(&pll1_sys_main_clk); pll1_sys_main_clk.usecount = 0; } + spin_unlock_irqrestore(&mx6sl_clk_lock, flags); return 0; @@ -2451,7 +2452,7 @@ static struct clk ssi1_clk = { #else .secondary = &mmdc_ch1_axi_clk[0], #endif - .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE, }; static unsigned long _clk_ssi2_get_rate(struct clk *clk) @@ -2525,7 +2526,7 @@ static struct clk ssi2_clk = { #else .secondary = &mmdc_ch1_axi_clk[0], #endif - .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE, }; static unsigned long _clk_ssi3_get_rate(struct clk *clk) @@ -2598,7 +2599,7 @@ static struct clk ssi3_clk = { #else .secondary = &mmdc_ch1_axi_clk[0], #endif - .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE, }; static unsigned long _clk_epdc_lcdif_pix_round_rate(struct clk *clk, diff --git a/arch/arm/mach-mx6/mx6sl_ddr.S b/arch/arm/mach-mx6/mx6sl_ddr.S index 78208c192b39..3059f3aa3c8c 100644 --- a/arch/arm/mach-mx6/mx6sl_ddr.S +++ b/arch/arm/mach-mx6/mx6sl_ddr.S @@ -102,10 +102,27 @@ periph2_clk_switch3: cmp r6, #0 bne periph2_clk_switch3 + /* Now set the MMDC PODF back to 1.*/ + ldr r6, [r2, #0x14] + bic r6, r6, #0x38 + str r6, [r2, #0x14] + +mmdc_podf0: + ldr r6, [r2, #0x48] + cmp r6, #0 + bne mmdc_podf0 + .endm .macro ddr_switch_400MHz + /* Check if we are switching between + * 400Mhz <-> 50MHz. If so, we only need to + * update MMDC divider. + */ + cmp r1, #0 + beq change_divider_only + /* Set MMDC divider first, in case PLL3 is at 480MHz. */ ldr r6, [r3, #0x10] and r6, r6, #0x10000 @@ -191,10 +208,26 @@ periph2_clk_switch6: cmp r6, #0 bne periph2_clk_switch6 - /* Now set the MMDC PODF back to 1.*/ - +change_divider_only: + /* Calculate the MMDC divider + * based on the requested freq. + */ + ldr r6, =400000000 + ldr r4, =0 +Loop2: + sub r6, r6, r0 + cmp r6, r0 + blt Div_Found + add r4, r4, #1 + bgt Loop2 + + /* Shift divider into correct offset. */ + lsl r4, r4, #3 +Div_Found: + /* Set the MMDC PODF. */ ldr r6, [r2, #0x14] bic r6, r6, #0x38 + orr r6, r6, r4 str r6, [r2, #0x14] mmdc_podf1: @@ -204,41 +237,63 @@ mmdc_podf1: .endm - .macro mmdc_clk_lower_100MHz - - /* Prior to reducing the DDR frequency (at 528/400 MHz), - read the Measure unit count bits (MU_UNIT_DEL_NUM) */ - ldr r5, =0x8B8 - ldr r6, [r8, r5] - /* Original MU unit count */ - mov r6, r6, LSR #16 - ldr r4, =0x3FF - and r6, r6, r4 - /* Original MU unit count * 2 */ - mov r1, r6, LSL #1 - /* Bypass the automatic measure unit when below 100 MHz - by setting the Measure unit bypass enable bit (MU_BYP_EN) */ - ldr r6, [r8, r5] - orr r6, r6, #0x400 - str r6, [r8, r5] - /* Double the measure count value read in step 1 and program it in the - measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit - Register for the reduced frequency operation below 100 MHz */ - ldr r6, [r8, r5] - ldr r4, =0x3FF - bic r6, r6, r4 - orr r6, r6, r1 - str r6, [r8, r5] - .endm - - .macro mmdc_clk_above_100MHz - - /* Make sure that the PHY measurement unit is NOT in bypass mode */ - ldr r5, =0x8B8 - ldr r6, [r8, r5] - bic r6, r6, #0x400 - str r6, [r8, r5] - .endm + .macro mmdc_clk_lower_100MHz + + /* Prior to reducing the DDR frequency (at 528/400 MHz), + read the Measure unit count bits (MU_UNIT_DEL_NUM) */ + ldr r5, =0x8B8 + ldr r6, [r8, r5] + /* Original MU unit count */ + mov r6, r6, LSR #16 + ldr r4, =0x3FF + and r6, r6, r4 + /* Original MU unit count * 2 */ + mov r7, r6, LSL #1 + /* Bypass the automatic measure unit when below 100 MHz + by setting the Measure unit bypass enable bit (MU_BYP_EN) */ + ldr r6, [r8, r5] + orr r6, r6, #0x400 + str r6, [r8, r5] + /* Double the measure count value read in step 1 and program it in the + * measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit + * Register for the reduced frequency operation below 100 MHz + */ + ldr r6, [r8, r5] + ldr r4, =0x3FF + bic r6, r6, r4 + orr r6, r6, r7 + str r6, [r8, r5] + /* Now perform a Force Measurement. */ + ldr r6, [r8, r5] + orr r6, r6, #0x800 + str r6, [r8, r5] + /* Wait for FRC_MSR to clear. */ +force_measure: + ldr r6, [r8, r5] + and r6, r6, #0x800 + cmp r6, #0x0 + bne force_measure + + .endm + + .macro mmdc_clk_above_100MHz + + /* Make sure that the PHY measurement unit is NOT in bypass mode */ + ldr r5, =0x8B8 + ldr r6, [r8, r5] + bic r6, r6, #0x400 + str r6, [r8, r5] + /* Now perform a Force Measurement. */ + ldr r6, [r8, r5] + orr r6, r6, #0x800 + str r6, [r8, r5] + /* Wait for FRC_MSR to clear. */ +force_measure1: + ldr r6, [r8, r5] + and r6, r6, #0x800 + cmp r6, #0x0 + bne force_measure1 + .endm /* * mx6sl_ddr_iram @@ -247,6 +302,7 @@ mmdc_podf1: * Make sure DDR is in self-refresh. * IRQs are already disabled. * r0 : DDR freq. + * r1: low_bus_freq_mode flag */ ENTRY(mx6sl_ddr_iram) @@ -285,7 +341,7 @@ mx6sl_ddr_freq_change: str r6, [r8, #0x4] /* Delay for a while */ - ldr r1, =10 + ldr r10, =10 delay1: ldr r7, =0 cont1: @@ -293,8 +349,8 @@ cont1: add r7, r7, #4 cmp r7, #16 bne cont1 - sub r1, r1, #1 - cmp r1, #0 + sub r10, r10, #1 + cmp r10, #0 bgt delay1 /* Make the DDR explicitly enter self-refresh. */ @@ -313,16 +369,24 @@ poll_dvfs_set_1: orr r6, r6, #0x100 str r6, [r8, #0x410] - ldr r1, =24000000 - cmp r0, r1 + ldr r10, =100000000 + cmp r0, r10 + bgt set_ddr_mu_above_100 + mmdc_clk_lower_100MHz + +set_ddr_mu_above_100: + ldr r10, =24000000 + cmp r0, r10 beq set_to_24MHz - mmdc_clk_above_100MHz ddr_switch_400MHz + ldr r10, =100000000 + cmp r0, r10 + blt done + mmdc_clk_above_100MHz b done set_to_24MHz: - mmdc_clk_lower_100MHz mx6sl_switch_to_24MHz done: @@ -342,8 +406,8 @@ poll_dvfs_clear_1: bic r6, r6, #0x01 str r6, [r8, #0x404] - ldr r1, =24000000 - cmp r0, r1 + ldr r10, =24000000 + cmp r0, r10 beq skip_power_down /* Enable MMDC power down timer. */ diff --git a/arch/arm/mach-mx6/mx6sl_wfi.S b/arch/arm/mach-mx6/mx6sl_wfi.S index 610a57f13730..d2d910383cb7 100644 --- a/arch/arm/mach-mx6/mx6sl_wfi.S +++ b/arch/arm/mach-mx6/mx6sl_wfi.S @@ -201,6 +201,11 @@ poll_dvfs_set_1: cmp r6, #0x2000000 bne poll_dvfs_set_1 + /* set SBS step-by-step mode */ + ldr r6, [r8, #0x410] + orr r6, r6, #0x100 + str r6, [r8, #0x410] + /* Now set DDR rate to 1MHz. */ /* DDR is from bypassed PLL2 on periph2_clk2 path. * Set the periph2_clk2_podf to divide by 8. @@ -215,6 +220,12 @@ poll_dvfs_set_1: orr r6, r6, #0x10 str r6, [r2, #0x14] + /* Loop till podf is accepted. */ +mmdc_podf: + ldr r6, [r2, #0x48] + cmp r6, #0x0 + bne mmdc_podf + /* Set the DDR IO in LPM state. */ sl_ddr_io_set_lpm @@ -321,6 +332,11 @@ ahb_podf1: bic r6, r6, #0x3f str r6, [r2, #0x14] +mmdc_podf1: + ldr r6, [r2, #0x48] + cmp r6, #0x0 + bne mmdc_podf1 + /* clear DVFS - exit from self refresh mode */ ldr r6, [r8, #0x404] bic r6, r6, #0x200000 @@ -337,6 +353,12 @@ poll_dvfs_clear_1: bic r6, r6, #0x01 str r6, [r8, #0x404] + /* clear SBS - unblock DDR accesses */ + ldr r6, [r8, #0x410] + bic r6, r6, #0x100 + str r6, [r8, #0x410] + + pop {r4,r5, r6, r7, r8, r9, r10} /* Restore registers */ diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c index 75701dc6485a..686c58c1e0e5 100644 --- a/arch/arm/mach-mx6/system.c +++ b/arch/arm/mach-mx6/system.c @@ -252,18 +252,38 @@ void arch_idle_single_core(void) ca9_do_idle(); } else { - if (low_bus_freq_mode && cpu_is_mx6sl()) { - u32 org_arm_podf = __raw_readl(MXC_CCM_CACRR); + if (low_bus_freq_mode || audio_bus_freq_mode) { + if (cpu_is_mx6sl() && low_bus_freq_mode) { + /* In this mode PLL2 i already in bypass, + * ARM is sourced from PLL1. The code in IRAM + * will set ARM to be sourced from STEP_CLK + * at 24MHz. It will also set DDR to 1MHz to + * reduce power. + */ + u32 org_arm_podf = __raw_readl(MXC_CCM_CACRR); - /* Need to run WFI code from IRAM so that - * we can lower DDR freq. - */ - mx6sl_wfi_iram(org_arm_podf, - (unsigned long)mx6sl_wfi_iram_base); + /* Need to run WFI code from IRAM so that + * we can lower DDR freq. + */ + mx6sl_wfi_iram(org_arm_podf, + (unsigned long)mx6sl_wfi_iram_base); + } else { + /* Need to set ARM to run at 24MHz since IPG + * is at 12MHz. This is valid for audio mode on + * MX6SL, and all low power modes on MX6DLS. + */ + /* PLL1_SW_CLK is sourced from PLL2_PFD2400MHz + * at this point. Move it to bypassed PLL1. + */ + reg = __raw_readl(MXC_CCM_CCSR); + reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + __raw_writel(reg, MXC_CCM_CCSR); - /* Clear the chicken bit to allow memories - * to be powered down - */ + ca9_do_idle(); + + reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + __raw_writel(reg, MXC_CCM_CCSR); + } } else { /* * Implement the 12:5 ARM:IPG_CLK ratio -- cgit v1.2.3 From 45edfa15a310e20023021bc3f9e7b6305fbe630e Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 27 Aug 2012 13:53:50 +0800 Subject: ENGR00221457 MX6DL clock:Set PLL3_PFD_540M to 540MHz This patch sets PLL3_PFD_540M clock frequency to 540MHz so that IPU and VPU clock can reach 270MHz. Signed-off-by: Liu Ying (cherry picked from commit faf59e846f03b37c65996e58d045de8d64481283) --- arch/arm/mach-mx6/clock.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index e0348e4f2e33..c2bf20177909 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -5412,6 +5412,8 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc, /* on mx6dl gpu2d_axi_clk source from mmdc0 directly */ clk_set_parent(&gpu2d_axi_clk, &mmdc_ch0_axi_clk[0]); + clk_set_rate(&pll3_pfd_540M, 540000000); + clk_set_parent(&ipu1_clk, &pll3_pfd_540M); /* pxp & epdc */ clk_set_parent(&ipu2_clk, &pll2_pfd_400M); -- cgit v1.2.3 From b14b8d7f06de65bb2b494c0ced821be7af609f84 Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Mon, 27 Aug 2012 10:47:10 +0800 Subject: ENGR00221302 [MX6SL_ARM2/EVK]: VDDSOC adjust if use LDO bypass The function has been implement in LDO enable , but not in LDO bypass. Implement it on mx6sl. Signed-off-by: Robin Gong --- arch/arm/mach-mx6/board-mx6sl_arm2.c | 2 ++ arch/arm/mach-mx6/board-mx6sl_evk.c | 2 ++ arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c | 23 ++++++++++++++++++++--- arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c | 26 +++++++++++++++++++++----- 4 files changed, 45 insertions(+), 8 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c index 45b33c9caace..7ff3b3e1ceeb 100755 --- a/arch/arm/mach-mx6/board-mx6sl_arm2.c +++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c @@ -582,6 +582,7 @@ static struct i2c_board_info mxc_i2c2_board_info[] __initdata = { static struct mxc_dvfs_platform_data mx6sl_arm2_dvfscore_data = { #ifdef CONFIG_MX6_INTER_LDO_BYPASS .reg_id = "VDDCORE", + .soc_id = "VDDSOC", #else .reg_id = "cpu_vddgp", .soc_id = "cpu_vddsoc", @@ -1189,6 +1190,7 @@ static void __init mx6_arm2_init(void) #ifdef CONFIG_MX6_INTER_LDO_BYPASS gp_reg_id = mx6sl_arm2_dvfscore_data.reg_id; + soc_reg_id = mx6sl_arm2_dvfscore_data.soc_id; #else gp_reg_id = mx6sl_arm2_dvfscore_data.reg_id; soc_reg_id = mx6sl_arm2_dvfscore_data.soc_id; diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c index 40c05c451e7a..f1a1b4512b2a 100644 --- a/arch/arm/mach-mx6/board-mx6sl_evk.c +++ b/arch/arm/mach-mx6/board-mx6sl_evk.c @@ -595,6 +595,7 @@ static struct i2c_board_info mxc_i2c2_board_info[] __initdata = { static struct mxc_dvfs_platform_data mx6sl_evk_dvfscore_data = { #ifdef CONFIG_MX6_INTER_LDO_BYPASS .reg_id = "VDDCORE", + .soc_id = "VDDSOC", #else .reg_id = "cpu_vddgp", .soc_id = "cpu_vddsoc", @@ -1196,6 +1197,7 @@ static void __init mx6_evk_init(void) #ifdef CONFIG_MX6_INTER_LDO_BYPASS gp_reg_id = mx6sl_evk_dvfscore_data.reg_id; + soc_reg_id = mx6sl_evk_dvfscore_data.soc_id; #else gp_reg_id = mx6sl_evk_dvfscore_data.reg_id; soc_reg_id = mx6sl_evk_dvfscore_data.soc_id; diff --git a/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c index eaa9721dc7d3..134700a6d200 100644 --- a/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c +++ b/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c @@ -66,6 +66,9 @@ #define PFUZE100_SW1ACON 36 #define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */ #define PFUZE100_SW1ACON_SPEED_M (0x3<<6) +#define PFUZE100_SW1CCON 49 +#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */ +#define PFUZE100_SW1CCON_SPEED_M (0x3<<6) #ifdef CONFIG_MX6_INTER_LDO_BYPASS @@ -74,6 +77,11 @@ static struct regulator_consumer_supply sw1_consumers[] = { .supply = "VDDCORE", } }; +static struct regulator_consumer_supply sw1c_consumers[] = { + { + .supply = "VDDSOC", + }, +}; #endif static struct regulator_consumer_supply sw2_consumers[] = { @@ -151,10 +159,10 @@ static struct regulator_init_data sw1a_init = { .boot_on = 1, .always_on = 1, }, - #ifdef CONFIG_MX6_INTER_LDO_BYPASS +#ifdef CONFIG_MX6_INTER_LDO_BYPASS .num_consumer_supplies = ARRAY_SIZE(sw1_consumers), .consumer_supplies = sw1_consumers, - #endif +#endif }; static struct regulator_init_data sw1b_init = { @@ -179,6 +187,10 @@ static struct regulator_init_data sw1c_init = { .always_on = 1, .boot_on = 1, }, + #ifdef CONFIG_MX6_INTER_LDO_BYPASS + .num_consumer_supplies = ARRAY_SIZE(sw1c_consumers), + .consumer_supplies = sw1c_consumers, + #endif }; static struct regulator_init_data sw2_init = { @@ -391,12 +403,17 @@ static int pfuze100_init(struct mc_pfuze *pfuze) PFUZE100_SW1CSTANDBY_STBY_VAL); if (ret) goto err; - /*set SW1ABDVSPEED as 25mV step each 4us,quick than 16us before.*/ + /*set SW1AB/SW1C DVSPEED as 25mV step each 4us,quick than 16us before.*/ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ACON, PFUZE100_SW1ACON_SPEED_M, PFUZE100_SW1ACON_SPEED_VAL); if (ret) goto err; + ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CCON, + PFUZE100_SW1CCON_SPEED_M, + PFUZE100_SW1CCON_SPEED_VAL); + if (ret) + goto err; return 0; err: printk(KERN_ERR "pfuze100 init error!\n"); diff --git a/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c index 958f8a0ab780..ee66541f8bff 100644 --- a/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c +++ b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c @@ -66,7 +66,9 @@ #define PFUZE100_SW1ACON 36 #define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */ #define PFUZE100_SW1ACON_SPEED_M (0x3<<6) - +#define PFUZE100_SW1CCON 49 +#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */ +#define PFUZE100_SW1CCON_SPEED_M (0x3<<6) #ifdef CONFIG_MX6_INTER_LDO_BYPASS static struct regulator_consumer_supply sw1_consumers[] = { @@ -74,6 +76,11 @@ static struct regulator_consumer_supply sw1_consumers[] = { .supply = "VDDCORE", } }; +static struct regulator_consumer_supply sw1c_consumers[] = { + { + .supply = "VDDSOC", + }, +}; #endif static struct regulator_consumer_supply sw2_consumers[] = { @@ -126,7 +133,7 @@ static struct regulator_consumer_supply vgen3_consumers[] = { }; static struct regulator_consumer_supply vgen4_consumers[] = { { - .supply = "VGEN4_1V58", + .supply = "VGEN4_1V8", } }; static struct regulator_consumer_supply vgen5_consumers[] = { @@ -155,10 +162,10 @@ static struct regulator_init_data sw1a_init = { .boot_on = 1, .always_on = 1, }, - #ifdef CONFIG_MX6_INTER_LDO_BYPASS +#ifdef CONFIG_MX6_INTER_LDO_BYPASS .num_consumer_supplies = ARRAY_SIZE(sw1_consumers), .consumer_supplies = sw1_consumers, - #endif +#endif }; static struct regulator_init_data sw1b_init = { @@ -183,6 +190,10 @@ static struct regulator_init_data sw1c_init = { .always_on = 1, .boot_on = 1, }, +#ifdef CONFIG_MX6_INTER_LDO_BYPASS + .num_consumer_supplies = ARRAY_SIZE(sw1c_consumers), + .consumer_supplies = sw1c_consumers, +#endif }; static struct regulator_init_data sw2_init = { @@ -397,12 +408,17 @@ static int pfuze100_init(struct mc_pfuze *pfuze) PFUZE100_SW1CSTANDBY_STBY_VAL); if (ret) goto err; - /*set SW1ABDVSPEED as 25mV step each 4us,quick than 16us before.*/ + /*set SW1AB/SW1CDVSPEED as 25mV step each 4us,quick than 16us before.*/ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ACON, PFUZE100_SW1ACON_SPEED_M, PFUZE100_SW1ACON_SPEED_VAL); if (ret) goto err; + ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CCON, + PFUZE100_SW1CCON_SPEED_M, + PFUZE100_SW1CCON_SPEED_VAL); + if (ret) + goto err; return 0; err: printk(KERN_ERR "pfuze100 init error!\n"); -- cgit v1.2.3 From 8653ba355543b2c0adbfb876701aee36053a73d5 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Sat, 25 Aug 2012 16:39:06 +0800 Subject: ENGR00221438 [MX6]Adjust CPU setpoint according to datasheet 1. Adjust ARM/SOC/PU voltage according to latest datasheet; 2. Remove Rigel's 200M setpoint to align with Arik. Signed-off-by: Anson Huang --- arch/arm/mach-mx6/cpu_op-mx6.c | 123 ++++++++++------------- arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c | 6 +- arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c | 6 +- 3 files changed, 57 insertions(+), 78 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c index 3415f01f238c..80e1c1089632 100644 --- a/arch/arm/mach-mx6/cpu_op-mx6.c +++ b/arch/arm/mach-mx6/cpu_op-mx6.c @@ -29,8 +29,8 @@ static struct cpu_op mx6q_cpu_op_1_2G[] = { .pll_rate = 1200000000, .cpu_rate = 1200000000, .cpu_podf = 0, - .pu_voltage = 1250000, - .soc_voltage = 1250000, + .pu_voltage = 1275000, + .soc_voltage = 1275000, .cpu_voltage = 1275000,}, { .pll_rate = 792000000, @@ -38,13 +38,13 @@ static struct cpu_op mx6q_cpu_op_1_2G[] = { .cpu_podf = 0, #ifdef CONFIG_MX6_VPU_352M /*VPU 352Mhz need voltage 1.25V*/ - .pu_voltage = 1250000, - .soc_voltage = 1250000, + .pu_voltage = 1250000, + .soc_voltage = 1250000, #else - .pu_voltage = 1150000, - .soc_voltage = 1150000, + .pu_voltage = 1175000, + .soc_voltage = 1175000, #endif - .cpu_voltage = 1100000,}, + .cpu_voltage = 1150000,}, #ifdef CONFIG_MX6_VPU_352M /*pll2_pfd_400M will be fix on 352M,to avoid modify other code which assume ARM clock sourcing from pll2_pfd_400M, change cpu @@ -55,15 +55,15 @@ static struct cpu_op mx6q_cpu_op_1_2G[] = { .cpu_podf = 0, .pu_voltage = 1250000, .soc_voltage = 1250000, - .cpu_voltage = 925000,}, + .cpu_voltage = 950000,}, #else { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1150000, - .soc_voltage = 1150000, - .cpu_voltage = 925000,}, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 950000,}, #endif }; @@ -73,9 +73,9 @@ static struct cpu_op mx6q_cpu_op_1G[] = { .pll_rate = 996000000, .cpu_rate = 996000000, .cpu_podf = 0, - .pu_voltage = 1200000, - .soc_voltage = 1200000, - .cpu_voltage = 1225000,}, + .pu_voltage = 1250000, + .soc_voltage = 1250000, + .cpu_voltage = 1250000,}, { .pll_rate = 792000000, .cpu_rate = 792000000, @@ -85,10 +85,10 @@ static struct cpu_op mx6q_cpu_op_1G[] = { .pu_voltage = 1250000, .soc_voltage = 1250000, #else - .pu_voltage = 1150000, - .soc_voltage = 1150000, + .pu_voltage = 1175000, + .soc_voltage = 1175000, #endif - .cpu_voltage = 1100000,}, + .cpu_voltage = 1150000,}, #ifdef CONFIG_MX6_VPU_352M /*pll2_pfd_400M will be fix on 352M,to avoid modify other code which assume ARM clock sourcing from pll2_pfd_400M, change cpu @@ -99,15 +99,15 @@ static struct cpu_op mx6q_cpu_op_1G[] = { .cpu_podf = 0, .pu_voltage = 1250000, .soc_voltage = 1250000, - .cpu_voltage = 925000,}, + .cpu_voltage = 950000,}, #else { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1150000, - .soc_voltage = 1150000, - .cpu_voltage = 925000,}, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 950000,}, #endif }; @@ -121,10 +121,10 @@ static struct cpu_op mx6q_cpu_op[] = { .pu_voltage = 1250000, .soc_voltage = 1250000, #else - .pu_voltage = 1150000, - .soc_voltage = 1150000, + .pu_voltage = 1175000, + .soc_voltage = 1175000, #endif - .cpu_voltage = 1100000,}, + .cpu_voltage = 1150000,}, #ifdef CONFIG_MX6_VPU_352M /*pll2_pfd_400M will be fix on 352M,to avoid modify other code which assume ARM clock sourcing from pll2_pfd_400M, change cpu @@ -135,15 +135,15 @@ static struct cpu_op mx6q_cpu_op[] = { .cpu_podf = 0, .pu_voltage = 1250000, .soc_voltage = 1250000, - .cpu_voltage = 925000,}, + .cpu_voltage = 950000,}, #else { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1150000, - .soc_voltage = 1150000, - .cpu_voltage = 925000,}, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 950000,}, #endif }; @@ -153,30 +153,23 @@ static struct cpu_op mx6dl_cpu_op_1_2G[] = { .pll_rate = 1200000000, .cpu_rate = 1200000000, .cpu_podf = 0, - .pu_voltage = 1250000, - .soc_voltage = 1250000, + .pu_voltage = 1275000, + .soc_voltage = 1275000, .cpu_voltage = 1275000,}, { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, - .pu_voltage = 1150000, - .soc_voltage = 1150000, - .cpu_voltage = 1100000,}, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1150000,}, { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1150000, - .soc_voltage = 1150000, - .cpu_voltage = 1025000,}, - { - .pll_rate = 396000000, - .cpu_rate = 198000000, - .cpu_podf = 1, - .pu_voltage = 1150000, - .soc_voltage = 1150000, - .cpu_voltage = 1025000,}, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1075000,}, }; /* working point(wp): 0 - 1GHz; 1 - 800MHz, 2 - 400MHz, 3 - 200MHz */ static struct cpu_op mx6dl_cpu_op_1G[] = { @@ -184,53 +177,39 @@ static struct cpu_op mx6dl_cpu_op_1G[] = { .pll_rate = 996000000, .cpu_rate = 996000000, .cpu_podf = 0, - .pu_voltage = 1200000, - .soc_voltage = 1200000, - .cpu_voltage = 1225000,}, + .pu_voltage = 1250000, + .soc_voltage = 1250000, + .cpu_voltage = 1250000,}, { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, - .pu_voltage = 1150000, - .soc_voltage = 1150000, - .cpu_voltage = 1100000,}, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1150000,}, { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1150000, - .soc_voltage = 1150000, - .cpu_voltage = 1025000,}, - { - .pll_rate = 396000000, - .cpu_rate = 198000000, - .cpu_podf = 1, - .pu_voltage = 1150000, - .soc_voltage = 1150000, - .cpu_voltage = 1025000,}, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1075000,}, }; static struct cpu_op mx6dl_cpu_op[] = { { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, - .pu_voltage = 1150000, - .soc_voltage = 1150000, - .cpu_voltage = 1100000,}, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1150000,}, { .pll_rate = 396000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1150000, - .soc_voltage = 1150000, - .cpu_voltage = 1025000,}, - { - .pll_rate = 396000000, - .cpu_rate = 198000000, - .cpu_podf = 1, - .pu_voltage = 1150000, - .soc_voltage = 1150000, - .cpu_voltage = 1025000,}, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1075000,}, }; static struct cpu_op mx6sl_cpu_op_1G[] = { diff --git a/arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c index cc12a0224ab2..8cb4ffcc78fa 100644 --- a/arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c +++ b/arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c @@ -41,13 +41,13 @@ /*SWBST*/ #define PFUZE100_SW1ASTANDBY 33 -#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x18) +#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x19) #define PFUZE100_SW1ASTANDBY_STBY_M (0x3f<<0) #define PFUZE100_SW1BSTANDBY 40 -#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x18) +#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x19) #define PFUZE100_SW1BSTANDBY_STBY_M (0x3f<<0) #define PFUZE100_SW1CSTANDBY 47 -#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x18) +#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x19) #define PFUZE100_SW1CSTANDBY_STBY_M (0x3f<<0) #define PFUZE100_SW2STANDBY 54 #define PFUZE100_SW2STANDBY_STBY_VAL 0x0 diff --git a/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c index f7e7099468c1..a53036c3df03 100644 --- a/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c +++ b/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c @@ -48,13 +48,13 @@ #define PFUZE100_SW1CVOL 46 #define PFUZE100_SW1CVOL_VSEL_M (0x3f<<0) #define PFUZE100_SW1ASTANDBY 33 -#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x18) +#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x19) #define PFUZE100_SW1ASTANDBY_STBY_M (0x3f<<0) #define PFUZE100_SW1BSTANDBY 40 -#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x18) +#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x19) #define PFUZE100_SW1BSTANDBY_STBY_M (0x3f<<0) #define PFUZE100_SW1CSTANDBY 47 -#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x18) +#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x19) #define PFUZE100_SW1CSTANDBY_STBY_M (0x3f<<0) #define PFUZE100_SW2STANDBY 54 #define PFUZE100_SW2STANDBY_STBY_VAL 0x0 -- cgit v1.2.3 From 4630c97b33a135026560d4d17c6b0b8e14253ff5 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Tue, 28 Aug 2012 17:43:01 +0800 Subject: ENGR00221643 [MX6]Fix race condition of pfd 400 usecount We can't modify the usecount of pfd 400M clock when ARM freq is changed, as when the children of pfd 400M do clock enable/disable, they will also modify this usecount, these two modification is out of same lock protection. And this wrong usecount may lead to pfd 400M or pll2 disabled accidently, and it will cause system hang! Signed-off-by: Anson Huang --- arch/arm/mach-mx6/clock.c | 3 --- arch/arm/mach-mx6/clock_mx6sl.c | 3 --- 2 files changed, 6 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index c2bf20177909..81b63a55c529 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -1262,7 +1262,6 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) */ if (pll1_sw_clk.parent != &pll2_pfd_400M) { pll2_pfd_400M.enable(&pll2_pfd_400M); - pll2_pfd_400M.usecount++; arm_needs_pll2_400 = true; pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M); pll1_sw_clk.parent = &pll2_pfd_400M; @@ -1288,8 +1287,6 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) /* Make sure pll1_sw_clk is from pll1_sys_main_clk */ pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); pll1_sw_clk.parent = &pll1_sys_main_clk; - if (arm_needs_pll2_400) - pll2_pfd_400M.usecount--; arm_needs_pll2_400 = false; if (pll2_pfd_400M.usecount == 0) pll2_pfd_400M.disable(&pll2_pfd_400M); diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index 4839f1542b3a..7a66d10c3aab 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -1168,7 +1168,6 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) */ if (pll1_sw_clk.parent != &pll2_pfd2_400M) { pll2_pfd2_400M.enable(&pll2_pfd2_400M); - pll2_pfd2_400M.usecount++; arm_needs_pll2_400 = true; pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd2_400M); pll1_sw_clk.parent = &pll2_pfd2_400M; @@ -1192,8 +1191,6 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); pll1_sw_clk.parent = &pll1_sys_main_clk; - if (arm_needs_pll2_400) - pll2_pfd2_400M.usecount--; arm_needs_pll2_400 = false; if (pll2_pfd2_400M.usecount == 0) pll2_pfd2_400M.disable(&pll2_pfd2_400M); -- cgit v1.2.3 From 8f25ba9c99e012e9d72a03b4097c63c2f6d0595e Mon Sep 17 00:00:00 2001 From: make shi Date: Tue, 28 Aug 2012 17:12:07 +0800 Subject: ENGR00221716-01 Mx6 USB host: set disconnect bit should wait for resume finished For i.MX6DLTO1.1 and i.MX6DQTO1.2, the disconnection-bit can only be set after the resume finished, otherwise, the remote-wake-up may fail. Because if the device not switch to High-Speed 45ohm termination resistors mode, when the disconnection detection bit is set the disconnection detection circuit will detect a high speed disconnection by mistake. Signed-off-by: make shi --- arch/arm/mach-mx6/usb_dr.c | 25 ++++++++++++++++++++----- arch/arm/mach-mx6/usb_h1.c | 25 ++++++++++++++++++++----- 2 files changed, 40 insertions(+), 10 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c index 8cfcb27c7594..8fe9700a658f 100644 --- a/arch/arm/mach-mx6/usb_dr.c +++ b/arch/arm/mach-mx6/usb_dr.c @@ -442,18 +442,18 @@ static void _host_platform_rh_resume_swfix(struct fsl_usb2_platform_data *pdata) { u32 index = 0; - if ((UOG_PORTSC1 & (3 << 26)) != (2 << 26)) + if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH) return ; - while ((UOG_PORTSC1 & PORTSC_PORT_FORCE_RESUME) && (index < 1000)) { udelay(500); index++; } - if (index >= 1000) - printk(KERN_INFO "%s big error\n", __func__); - + printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n", + __func__, __LINE__); + /* We should add some delay to wait for the device switch to + * High-Speed 45ohm termination resistors mode. */ udelay(500); fsl_platform_otg_set_usb_phy_dis(pdata, 1); } @@ -469,9 +469,24 @@ static void _host_platform_rh_suspend(struct fsl_usb2_platform_data *pdata) static void _host_platform_rh_resume(struct fsl_usb2_platform_data *pdata) { + u32 index = 0; + /*for mx6sl ,we do not need any sw fix*/ if (cpu_is_mx6sl()) return ; + if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH) + return ; + while ((UOG_PORTSC1 & PORTSC_PORT_FORCE_RESUME) + && (index < 1000)) { + udelay(500); + index++; + } + if (index >= 1000) + printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n", + __func__, __LINE__); + /* We should add some delay to wait for the device switch to + * High-Speed 45ohm termination resistors mode. */ + udelay(500); __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL_SET); diff --git a/arch/arm/mach-mx6/usb_h1.c b/arch/arm/mach-mx6/usb_h1.c index 3e2f50ab6b55..bece29f7d44b 100644 --- a/arch/arm/mach-mx6/usb_h1.c +++ b/arch/arm/mach-mx6/usb_h1.c @@ -244,18 +244,18 @@ static void usbh1_platform_rh_resume_swfix(struct fsl_usb2_platform_data *pdata) { u32 index = 0; - if ((UH1_PORTSC1 & (3 << 26)) != (2 << 26)) + if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH) return ; - while ((UH1_PORTSC1 & PORTSC_PORT_FORCE_RESUME) && (index < 1000)) { udelay(500); index++; } - if (index >= 1000) - printk(KERN_INFO "%s big error\n", __func__); - + printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n", + __func__, __LINE__); + /* We should add some delay to wait for the device switch to + * High-Speed 45ohm termination resistors mode. */ udelay(500); fsl_platform_h1_set_usb_phy_dis(pdata, 1); } @@ -272,9 +272,24 @@ static void usbh1_platform_rh_suspend(struct fsl_usb2_platform_data *pdata) static void usbh1_platform_rh_resume(struct fsl_usb2_platform_data *pdata) { + u32 index = 0; + /*for mx6sl ,we do not need any sw fix*/ if (cpu_is_mx6sl()) return ; + if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH) + return ; + while ((UH1_PORTSC1 & PORTSC_PORT_FORCE_RESUME) + && (index < 1000)) { + udelay(500); + index++; + } + if (index >= 1000) + printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n", + __func__, __LINE__); + /* We should add some delay to wait for the device switch to + * High-Speed 45ohm termination resistors mode. */ + udelay(500); __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL_SET); -- cgit v1.2.3 From 3052b56745ce89d440c106922a7015d8bf11627c Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Wed, 29 Aug 2012 16:08:01 +0800 Subject: ENGR00221867 sabresd : support adjust VDDSOC if enable LDO bypass support adjust VDDSOC if enable LDO bypass on mx6_sabresd board Signed-off-by: Robin Gong --- arch/arm/mach-mx6/board-mx6q_sabresd.c | 11 ++++++----- arch/arm/mach-mx6/board-mx6sl_arm2.c | 12 ++++++------ arch/arm/mach-mx6/board-mx6sl_evk.c | 12 ++++++------ arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c | 23 ++++++++++++++++++++--- 4 files changed, 38 insertions(+), 20 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c index 1da30f10fe93..59ea80c9892a 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabresd.c +++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c @@ -1581,13 +1581,14 @@ static struct platform_pwm_backlight_data mx6_sabresd_pwm_backlight_data = { }; static struct mxc_dvfs_platform_data sabresd_dvfscore_data = { - #ifdef CONFIG_MX6_INTER_LDO_BYPASS +#ifdef CONFIG_MX6_INTER_LDO_BYPASS .reg_id = "VDDCORE", - #else + .soc_id = "VDDSOC", +#else .reg_id = "cpu_vddgp", .soc_id = "cpu_vddsoc", .pu_id = "cpu_vddvpu", - #endif +#endif .clk1_id = "cpu_clk", .clk2_id = "gpc_dvfs_clk", .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET, @@ -1801,9 +1802,9 @@ static void __init mx6_sabresd_board_init(void) imx6q_add_dma(); imx6q_add_dvfs_core(&sabresd_dvfscore_data); - #ifndef CONFIG_MX6_INTER_LDO_BYPASS +#ifndef CONFIG_MX6_INTER_LDO_BYPASS mx6_cpu_regulator_init(); - #endif +#endif imx6q_add_device_buttons(); /* enable sensor 3v3 and 1v8 */ diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c index 7ff3b3e1ceeb..4302b68aab95 100755 --- a/arch/arm/mach-mx6/board-mx6sl_arm2.c +++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c @@ -580,14 +580,14 @@ static struct i2c_board_info mxc_i2c2_board_info[] __initdata = { }; static struct mxc_dvfs_platform_data mx6sl_arm2_dvfscore_data = { - #ifdef CONFIG_MX6_INTER_LDO_BYPASS +#ifdef CONFIG_MX6_INTER_LDO_BYPASS .reg_id = "VDDCORE", .soc_id = "VDDSOC", - #else +#else .reg_id = "cpu_vddgp", .soc_id = "cpu_vddsoc", .pu_id = "cpu_vddvpu", - #endif +#endif .clk1_id = "cpu_clk", .clk2_id = "gpc_dvfs_clk", .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET, @@ -1188,15 +1188,15 @@ static void __init mx6_arm2_init(void) elan_ts_init(); - #ifdef CONFIG_MX6_INTER_LDO_BYPASS +#ifdef CONFIG_MX6_INTER_LDO_BYPASS gp_reg_id = mx6sl_arm2_dvfscore_data.reg_id; soc_reg_id = mx6sl_arm2_dvfscore_data.soc_id; - #else +#else gp_reg_id = mx6sl_arm2_dvfscore_data.reg_id; soc_reg_id = mx6sl_arm2_dvfscore_data.soc_id; pu_reg_id = mx6sl_arm2_dvfscore_data.pu_id; mx6_cpu_regulator_init(); - #endif +#endif imx6q_add_imx_snvs_rtc(); diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c index f1a1b4512b2a..81654a0c99fd 100644 --- a/arch/arm/mach-mx6/board-mx6sl_evk.c +++ b/arch/arm/mach-mx6/board-mx6sl_evk.c @@ -593,14 +593,14 @@ static struct i2c_board_info mxc_i2c2_board_info[] __initdata = { }; static struct mxc_dvfs_platform_data mx6sl_evk_dvfscore_data = { - #ifdef CONFIG_MX6_INTER_LDO_BYPASS +#ifdef CONFIG_MX6_INTER_LDO_BYPASS .reg_id = "VDDCORE", .soc_id = "VDDSOC", - #else +#else .reg_id = "cpu_vddgp", .soc_id = "cpu_vddsoc", .pu_id = "cpu_vddvpu", - #endif +#endif .clk1_id = "cpu_clk", .clk2_id = "gpc_dvfs_clk", .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET, @@ -1195,15 +1195,15 @@ static void __init mx6_evk_init(void) elan_ts_init(); - #ifdef CONFIG_MX6_INTER_LDO_BYPASS +#ifdef CONFIG_MX6_INTER_LDO_BYPASS gp_reg_id = mx6sl_evk_dvfscore_data.reg_id; soc_reg_id = mx6sl_evk_dvfscore_data.soc_id; - #else +#else gp_reg_id = mx6sl_evk_dvfscore_data.reg_id; soc_reg_id = mx6sl_evk_dvfscore_data.soc_id; pu_reg_id = mx6sl_evk_dvfscore_data.pu_id; mx6_cpu_regulator_init(); - #endif +#endif imx6q_add_imx_snvs_rtc(); diff --git a/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c index a53036c3df03..69daddf14000 100644 --- a/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c +++ b/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c @@ -74,6 +74,9 @@ #define PFUZE100_SW1ACON 36 #define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */ #define PFUZE100_SW1ACON_SPEED_M (0x3<<6) +#define PFUZE100_SW1CCON 49 +#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */ +#define PFUZE100_SW1CCON_SPEED_M (0x3<<6) extern u32 arm_max_freq; @@ -83,6 +86,11 @@ static struct regulator_consumer_supply sw1_consumers[] = { .supply = "VDDCORE", } }; +static struct regulator_consumer_supply sw1c_consumers[] = { + { + .supply = "VDDSOC", + }, +}; #endif static struct regulator_consumer_supply sw2_consumers[] = { @@ -160,10 +168,10 @@ static struct regulator_init_data sw1a_init = { .always_on = 1, }, - #ifdef CONFIG_MX6_INTER_LDO_BYPASS +#ifdef CONFIG_MX6_INTER_LDO_BYPASS .num_consumer_supplies = ARRAY_SIZE(sw1_consumers), .consumer_supplies = sw1_consumers, - #endif +#endif }; static struct regulator_init_data sw1b_init = { @@ -188,6 +196,10 @@ static struct regulator_init_data sw1c_init = { .always_on = 1, .boot_on = 1, }, +#ifdef CONFIG_MX6_INTER_LDO_BYPASS + .num_consumer_supplies = ARRAY_SIZE(sw1c_consumers), + .consumer_supplies = sw1c_consumers, +#endif }; static struct regulator_init_data sw2_init = { @@ -421,12 +433,17 @@ static int pfuze100_init(struct mc_pfuze *pfuze) PFUZE100_SW1CSTANDBY_STBY_VAL); if (ret) goto err; - /*set SW1ABDVSPEED as 25mV step each 4us,quick than 16us before.*/ + /*set SW1AB/1C DVSPEED as 25mV step each 4us,quick than 16us before.*/ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ACON, PFUZE100_SW1ACON_SPEED_M, PFUZE100_SW1ACON_SPEED_VAL); if (ret) goto err; + ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CCON, + PFUZE100_SW1CCON_SPEED_M, + PFUZE100_SW1CCON_SPEED_VAL); + if (ret) + goto err; return 0; err: printk(KERN_ERR "pfuze100 init error!\n"); -- cgit v1.2.3 From 9f654ff1ecd99a8171dc739e8f8474d8390a0978 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Thu, 30 Aug 2012 03:10:07 +0800 Subject: ENGR00221902 [MX6]Fix udelay inaccurate issue during suspend/resume When system enter suspend, we increase CPUFreq to the highest point without update the global loops_per_jiffy, it will lead to udelay inaccurate during the last phase of suspend/resume. WB counter and RBC counter need at least two 32K cycles to finish, here we add 80us for safe. Signed-off-by: Anson Huang --- arch/arm/mach-mx6/system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c index 686c58c1e0e5..800c7cc4e8bd 100644 --- a/arch/arm/mach-mx6/system.c +++ b/arch/arm/mach-mx6/system.c @@ -195,7 +195,7 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode) __raw_writel(__raw_readl(MXC_CCM_CCR) & (~MXC_CCM_CCR_WB_COUNT_MASK) & (~MXC_CCM_CCR_REG_BYPASS_CNT_MASK), MXC_CCM_CCR); - udelay(60); + udelay(80); /* Reconfigurate WB and RBC counter */ __raw_writel(__raw_readl(MXC_CCM_CCR) | (0x1 << MXC_CCM_CCR_WB_COUNT_OFFSET) | -- cgit v1.2.3 From d708b6efa321742bc3c67c647703326e00428b92 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Wed, 29 Aug 2012 14:38:03 -0500 Subject: ENGR00221970 MX6SL:Fix suspend/resume issue on MX6SLEVK Make sure the Pull Ups are enabled on the DQS lines of LPDDR2 memory. Without that its possible that the data latched by the memory will be incorrect when exiting from self-refresh mode. So only set the drive strengths to 0 when floating the DDR IO pads before entering suspend. Also never float the CKE pad, this pin always needs to be driven, else the DDR may incorrectly exit self-refresh. Hence remove the line that was setting CKE drive strength to zero (GRP_CTLDS). Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/mx6_suspend.S | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/mx6_suspend.S b/arch/arm/mach-mx6/mx6_suspend.S index 59b676038427..a9b7e30cd85a 100644 --- a/arch/arm/mach-mx6/mx6_suspend.S +++ b/arch/arm/mach-mx6/mx6_suspend.S @@ -85,8 +85,7 @@ r2: suspend_iram_base ldr r4, [r1, #0x330] /* DRAM_SDCKE0 */ ldr r5, [r1, #0x334] /* DRAM_SDCKE1 */ ldr r6, [r1, #0x320] /* DRAM_RESET */ - ldr r7, [r1, #0x5c8] /* GPR_CTLDS */ - stmfd r0!, {r4-r7} + stmfd r0!, {r4-r6} .endm @@ -122,11 +121,10 @@ r2: suspend_iram_base str r6, [r1, #0x33c] /* DRAM_SODT0*/ str r7, [r1, #0x340] /* DRAM_SODT1*/ - ldmea r0!, {r4-r7} + ldmea r0!, {r4-r6} str r4, [r1, #0x330] /* DRAM_SDCKE0 */ str r5, [r1, #0x334] /* DRAM_SDCKE1 */ str r6, [r1, #0x320] /* DRAM_RESET */ - str r7, [r1, #0x5c8] /* GPR_CTLDS */ .endm @@ -138,6 +136,13 @@ r2: suspend_iram_base str r0, [r1, #0x314] /* DRAM_DQM2 */ str r0, [r1, #0x318] /* DRAM_DQM3 */ + /* Make sure the Pull Ups are enabled. + * So only reduce the drive stength, but + * leave the pull-ups in the original state. + * This is required for LPDDR2. + */ + ldr r0, [r1, #0x344] + orr r0, r0, #0x3000 str r0, [r1, #0x344] /* DRAM_SDQS0 */ str r0, [r1, #0x348] /* DRAM_SDQS1 */ str r0, [r1, #0x34c] /* DRAM_SDQS2 */ @@ -158,7 +163,6 @@ r2: suspend_iram_base str r0, [r1, #0x33c] /* DRAM_SODT0*/ str r0, [r1, #0x340] /* DRAM_SODT1*/ - str r0, [r1, #0x5c8] /* GPR_CTLDS */ mov r0, #0x80000 str r0, [r1, #0x320] /* DRAM_RESET */ mov r0, #0x1000 -- cgit v1.2.3 From edd35ffe17458b98988957d7af121e2fcc494e8f Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Wed, 29 Aug 2012 14:46:02 -0500 Subject: ENGR00221974 MX6SL-Fix system hang/crash issue in low power IDLE Ensure that the pull-up is enabled when the DQS line of LPDDR2 is floated when DDR freq is dropped to 24MHz. This is required else its possible that the DDR will latch incorrect data when it exits self-refresh. CKE line should not be floated as it may cause DDR to incorrectly exit self-refresh mode. Also add 25 nops after the code that removes DDR from self-refresh. We need this to ensure that the prefetcher block in A9 does not access any instruction from DDR before the DDR exits self-refresh. The A9 prefetch depth is about 23, hence 25 nops. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/mx6sl_wfi.S | 44 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/mx6sl_wfi.S b/arch/arm/mach-mx6/mx6sl_wfi.S index d2d910383cb7..89fe4e292352 100644 --- a/arch/arm/mach-mx6/mx6sl_wfi.S +++ b/arch/arm/mach-mx6/mx6sl_wfi.S @@ -109,6 +109,13 @@ str r4, [r1, #0x314] /* DRAM_DQM2 */ str r4, [r1, #0x318] /* DRAM_DQM3 */ + /* Make sure the Pull Ups are enabled. + * So only reduce the drive stength, but + * leave the pull-ups in the original state. + * This is required for LPDDR2. + */ + ldr r4, [r1, #0x344] + orr r4, r4, #0x3000 str r4, [r1, #0x344] /* DRAM_SDQS0 */ str r4, [r1, #0x348] /* DRAM_SDQS1 */ str r4, [r1, #0x34c] /* DRAM_SDQS2 */ @@ -129,7 +136,6 @@ str r4, [r1, #0x33c] /* DRAM_SODT0*/ str r4, [r1, #0x340] /* DRAM_SODT1*/ - str r4, [r1, #0x5c8] /* GPR_CTLDS */ mov r4, #0x80000 str r4, [r1, #0x320] /* DRAM_RESET */ mov r4, #0x1000 @@ -348,6 +354,42 @@ poll_dvfs_clear_1: cmp r6, #0x2000000 beq poll_dvfs_clear_1 + /* Add these nops so that the + * prefetcher will not try to get + * any instructions from DDR. + * The prefetch depth is about 23 + * on A9, so adding 25 nops. + */ + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + /* Enable Automatic power savings. */ ldr r6, [r8, #0x404] bic r6, r6, #0x01 -- cgit v1.2.3 From 5fc5eda2ef69b50e6004ca2a377ea6f1133ba4d3 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Wed, 29 Aug 2012 17:05:11 -0500 Subject: ENGR00221975 Fix race condition in clock code. Need to ensure that check for usecount in clk_set_parent occurs within the protection of the clock mutex. Else there is a chance that the usecount can be decremented (and the clock disabled) after the check. Also add back the code to maintain the correct usecount for pll2_pfd_400. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/clock.c | 3 +++ arch/arm/mach-mx6/clock_mx6sl.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index 81b63a55c529..c2bf20177909 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -1262,6 +1262,7 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) */ if (pll1_sw_clk.parent != &pll2_pfd_400M) { pll2_pfd_400M.enable(&pll2_pfd_400M); + pll2_pfd_400M.usecount++; arm_needs_pll2_400 = true; pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M); pll1_sw_clk.parent = &pll2_pfd_400M; @@ -1287,6 +1288,8 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) /* Make sure pll1_sw_clk is from pll1_sys_main_clk */ pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); pll1_sw_clk.parent = &pll1_sys_main_clk; + if (arm_needs_pll2_400) + pll2_pfd_400M.usecount--; arm_needs_pll2_400 = false; if (pll2_pfd_400M.usecount == 0) pll2_pfd_400M.disable(&pll2_pfd_400M); diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index 7a66d10c3aab..43b2bd1baac2 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -1169,6 +1169,7 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) if (pll1_sw_clk.parent != &pll2_pfd2_400M) { pll2_pfd2_400M.enable(&pll2_pfd2_400M); arm_needs_pll2_400 = true; + pll2_pfd2_400M.usecount++; pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd2_400M); pll1_sw_clk.parent = &pll2_pfd2_400M; } @@ -1191,6 +1192,8 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); pll1_sw_clk.parent = &pll1_sys_main_clk; + if (arm_needs_pll2_400) + pll2_pfd2_400M.usecount--; arm_needs_pll2_400 = false; if (pll2_pfd2_400M.usecount == 0) pll2_pfd2_400M.disable(&pll2_pfd2_400M); -- cgit v1.2.3 From fd7e50f44f594050d9803f65b79c5a36d4c17a9c Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Fri, 24 Aug 2012 17:40:59 +0800 Subject: ENGR00221218: imx6: remove redundant spi define There're two imx6q_add_ecspi() defines, remove one. Signed-off-by: Robby Cai --- arch/arm/mach-mx6/devices-imx6q.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/devices-imx6q.h b/arch/arm/mach-mx6/devices-imx6q.h index f91369ffc280..ec724ff8de48 100644 --- a/arch/arm/mach-mx6/devices-imx6q.h +++ b/arch/arm/mach-mx6/devices-imx6q.h @@ -158,10 +158,6 @@ extern const struct imx_imx_asrc_data imx6q_imx_asrc_data[] __initconst; #define imx6q_add_asrc(pdata) \ imx_add_imx_asrc(imx6q_imx_asrc_data, pdata) -extern const struct imx_spi_imx_data imx6q_ecspi_data[] __initconst; -#define imx6q_add_ecspi(id, pdata) \ - imx_add_spi_imx(&imx6q_ecspi_data[id], pdata) - extern const struct imx_dvfs_core_data imx6q_dvfs_core_data __initconst; #define imx6q_add_dvfs_core(pdata) \ imx_add_dvfs_core(&imx6q_dvfs_core_data, pdata) -- cgit v1.2.3 From 5fd60addbbc2ca8083b15378fa460e41f5d94326 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Thu, 30 Aug 2012 14:45:10 -0500 Subject: ENGR00222133 MX6SL - Fix crashes caused by Low power IDLE support Need to ensure that the ARM_CLK rate stays exactly the same when moving ARM_CLK from PLL2_PFD_400 to PLL1 when system enters 24MHz state. Also need to ensure that PLL1 is enabled before relocking the PLL to the correct rate. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/bus_freq.c | 5 +++++ arch/arm/mach-mx6/cpu_op-mx6.c | 4 ++++ 2 files changed, 9 insertions(+) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index 8c04e51d8827..23f56d5deaf1 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -208,6 +208,10 @@ static void reduce_bus_freq_handler(struct work_struct *work) * lowest possible freq. */ org_arm_podf = __raw_readl(MXC_CCM_CACRR); + /* Need to enable PLL1 before setting its rate. */ + clk_enable(pll1); + clk_set_rate(pll1, + cpu_op_tbl[cpu_op_nr - 1].pll_lpm_rate); div = clk_get_rate(pll1) / cpu_op_tbl[cpu_op_nr - 1].cpu_rate; @@ -308,6 +312,7 @@ int set_high_bus_freq(int high_bus_freq) reg = __raw_writel(org_arm_podf, MXC_CCM_CACRR); while (__raw_readl(MXC_CCM_CDHIPR)) ; + clk_disable(pll1); } high_bus_freq_mode = 1; low_bus_freq_mode = 0; diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c index 80e1c1089632..7e054c1d743c 100644 --- a/arch/arm/mach-mx6/cpu_op-mx6.c +++ b/arch/arm/mach-mx6/cpu_op-mx6.c @@ -229,6 +229,7 @@ static struct cpu_op mx6sl_cpu_op_1G[] = { .cpu_voltage = 1200000,}, { .pll_rate = 396000000, + .pll_lpm_rate = 792000000, .cpu_rate = 396000000, .cpu_podf = 0, .pu_voltage = 1050000, @@ -236,6 +237,7 @@ static struct cpu_op mx6sl_cpu_op_1G[] = { .cpu_voltage = 1100000,}, { .pll_rate = 396000000, + .pll_lpm_rate = 792000000, .cpu_rate = 198000000, .cpu_podf = 1, .pu_voltage = 1050000, @@ -253,6 +255,7 @@ static struct cpu_op mx6sl_cpu_op[] = { .cpu_voltage = 1200000,}, { .pll_rate = 396000000, + .pll_lpm_rate = 792000000, .cpu_rate = 396000000, .cpu_podf = 0, .pu_voltage = 1050000, @@ -260,6 +263,7 @@ static struct cpu_op mx6sl_cpu_op[] = { .cpu_voltage = 1100000,}, { .pll_rate = 396000000, + .pll_lpm_rate = 792000000, .cpu_rate = 198000000, .cpu_podf = 1, .pu_voltage = 1050000, -- cgit v1.2.3 From 85a6685fb327f1eebaeea5dfc04a6750573472ef Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Thu, 30 Aug 2012 15:02:32 -0500 Subject: ENGR00222134 MX6x - Fix race-conditions in low power code. Fix couple of race-conditions associated with low power IDLE code: 1. Ensure that bus freq mutex is used in the suspend/resume function 2. Ensure that the usecount of pll2 is incremented/decremented when ARM is switched to run from PLL2_PFD_400. And PLL2 is enabled/disabled when necessary. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/bus_freq.c | 4 ++++ arch/arm/mach-mx6/clock.c | 25 +++++++++++++++++++++---- arch/arm/mach-mx6/clock_mx6sl.c | 25 +++++++++++++++++++++---- 3 files changed, 46 insertions(+), 8 deletions(-) (limited to 'arch/arm/mach-mx6') diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index 23f56d5deaf1..151b4ee27eb6 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -501,6 +501,8 @@ static int busfreq_suspend(struct platform_device *pdev, pm_message_t message) static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event, void *dummy) { + mutex_lock(&bus_freq_mutex); + if (event == PM_SUSPEND_PREPARE) { set_high_bus_freq(1); busfreq_suspended = 1; @@ -508,6 +510,8 @@ static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event, busfreq_suspended = 0; } + mutex_unlock(&bus_freq_mutex); + return NOTIFY_OK; } static int busfreq_resume(struct platform_device *pdev) diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index c2bf20177909..8b75aee78964 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -1261,7 +1261,16 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) * PLL2_PFD_400M. */ if (pll1_sw_clk.parent != &pll2_pfd_400M) { - pll2_pfd_400M.enable(&pll2_pfd_400M); + if (pll2_pfd_400M.usecount == 0) { + /* Check if PLL2 needs to be enabled also. */ + if (pll2_528_bus_main_clk.usecount == 0) + pll2_528_bus_main_clk.enable(&pll2_528_bus_main_clk); + /* Ensure parent usecount is + * also incremented. + */ + pll2_528_bus_main_clk.usecount++; + pll2_pfd_400M.enable(&pll2_pfd_400M); + } pll2_pfd_400M.usecount++; arm_needs_pll2_400 = true; pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M); @@ -1288,11 +1297,19 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) /* Make sure pll1_sw_clk is from pll1_sys_main_clk */ pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); pll1_sw_clk.parent = &pll1_sys_main_clk; - if (arm_needs_pll2_400) + if (arm_needs_pll2_400) { pll2_pfd_400M.usecount--; + if (pll2_pfd_400M.usecount == 0) { + pll2_pfd_400M.disable(&pll2_pfd_400M); + /* Ensure parent usecount is + * also decremented. + */ + pll2_528_bus_main_clk.usecount--; + if (pll2_528_bus_main_clk.usecount == 0) + pll2_528_bus_main_clk.disable(&pll2_528_bus_main_clk); + } + } arm_needs_pll2_400 = false; - if (pll2_pfd_400M.usecount == 0) - pll2_pfd_400M.disable(&pll2_pfd_400M); } parent_rate = clk_get_rate(clk->parent); div = parent_rate / rate; diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index 43b2bd1baac2..6bd818ae7139 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -1167,7 +1167,16 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) * PLL2_PFD2_400M. */ if (pll1_sw_clk.parent != &pll2_pfd2_400M) { - pll2_pfd2_400M.enable(&pll2_pfd2_400M); + if (pll2_pfd2_400M.usecount == 0) { + /* Check if PLL2 needs to be enabled also. */ + if (pll2_528_bus_main_clk.usecount == 0) + pll2_528_bus_main_clk.enable(&pll2_528_bus_main_clk); + /* Ensure parent usecount is + * also incremented. + */ + pll2_528_bus_main_clk.usecount++; + pll2_pfd2_400M.enable(&pll2_pfd2_400M); + } arm_needs_pll2_400 = true; pll2_pfd2_400M.usecount++; pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd2_400M); @@ -1192,11 +1201,19 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); pll1_sw_clk.parent = &pll1_sys_main_clk; - if (arm_needs_pll2_400) + if (arm_needs_pll2_400) { pll2_pfd2_400M.usecount--; + if (pll2_pfd2_400M.usecount == 0) { + pll2_pfd2_400M.disable(&pll2_pfd2_400M); + /* Ensure parent usecount is + * also decremented. + */ + pll2_528_bus_main_clk.usecount--; + if (pll2_528_bus_main_clk.usecount == 0) + pll2_528_bus_main_clk.disable(&pll2_528_bus_main_clk); + } + } arm_needs_pll2_400 = false; - if (pll2_pfd2_400M.usecount == 0) - pll2_pfd2_400M.disable(&pll2_pfd2_400M); } parent_rate = clk_get_rate(clk->parent); div = parent_rate / rate; -- cgit v1.2.3