aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-02 19:15:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-02 19:15:12 -0400
commit825f4e0271b0de3f7f31d963dcdaa0056fe9b73a (patch)
treeaef1f198da011a96fefbe9851137ca17afd929a4 /arch/arm/mach-omap2
parent0a58471541cc823ef8056d23945c39fec154481c (diff)
parentb5b9324a6296bd0176fe1f8e06a1220207bd1bd3 (diff)
Merge tag 'soc-for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc into next
Pull part one of ARM SoC updates from Olof Johansson: "A quite large set of SoC updates this cycle. In no particular order: - Multi-cluster power management for Samsung Exynos, adding support for big.LITTLE CPU switching on EXYNOS5 - SMP support for Marvell Armada 375 and 38x - SMP rework on Allwinner A31 - Xilinx Zynq support for SOC_BUS, big endian - Marvell orion5x platform cleanup, modernizing the implementation and moving to DT. - _Finally_ moving Samsung Exynos over to support MULTIPLATFORM, so that their platform can be enabled in the same kernel binary as most of the other v7 platforms in the tree. \o/ The work isn't quite complete, there's some driver fixes still needed, but the basics now work. New SoC support added: - Freescale i.MX6SX - LSI Axxia AXM55xx SoCs - Samsung EXYNOS 3250, 5260, 5410, 5420 and 5800 - STi STIH407 plus a large set of various smaller updates for different platforms. I'm probably missing some important one here" * tag 'soc-for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (281 commits) ARM: exynos: don't run exynos4 l2x0 setup on other platforms ARM: exynos: Fix "allmodconfig" build errors in mcpm and hotplug ARM: EXYNOS: mcpm rename the power_down_finish ARM: EXYNOS: Enable mcpm for dual-cluster exynos5800 SoC ARM: EXYNOS: Enable multi-platform build support ARM: EXYNOS: Consolidate Kconfig entries ARM: EXYNOS: Add support for EXYNOS5410 SoC ARM: EXYNOS: Support secondary CPU boot of Exynos3250 ARM: EXYNOS: Add Exynos3250 SoC ID ARM: EXYNOS: Add 5800 SoC support ARM: EXYNOS: initial board support for exynos5260 SoC clk: exynos5410: register clocks using common clock framework ARM: debug: qcom: add UART addresses to Kconfig help for APQ8084 ARM: sunxi: allow building without reset controller Documentation: devicetree: arm: sort enable-method entries ARM: rockchip: convert smp bringup to CPU_METHOD_OF_DECLARE clk: exynos5250: Add missing sysmmu clocks for DISP and ISP blocks ARM: dts: axxia: Add reset controller power: reset: Add Axxia system reset driver ARM: axxia: Adding defconfig for AXM55xx ...
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/id.c37
-rw-r--r--arch/arm/mach-omap2/io.c1
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c99
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_54xx_data.c283
-rw-r--r--arch/arm/mach-omap2/omap_twl.c60
-rw-r--r--arch/arm/mach-omap2/pm.c45
-rw-r--r--arch/arm/mach-omap2/pm.h8
-rw-r--r--arch/arm/mach-omap2/pm24xx.c4
-rw-r--r--arch/arm/mach-omap2/pm34xx.c11
-rw-r--r--arch/arm/mach-omap2/pm44xx.c6
-rw-r--r--arch/arm/mach-omap2/prm-regbits-34xx.h11
-rw-r--r--arch/arm/mach-omap2/soc.h5
-rw-r--r--arch/arm/mach-omap2/vc.c232
-rw-r--r--arch/arm/mach-omap2/vc.h3
14 files changed, 545 insertions, 260 deletions
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index f61f1bf68df4..43969da5d50b 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -628,6 +628,41 @@ void __init omap5xxx_check_revision(void)
628 pr_info("%s %s\n", soc_name, soc_rev); 628 pr_info("%s %s\n", soc_name, soc_rev);
629} 629}
630 630
631void __init dra7xxx_check_revision(void)
632{
633 u32 idcode;
634 u16 hawkeye;
635 u8 rev;
636
637 idcode = read_tap_reg(OMAP_TAP_IDCODE);
638 hawkeye = (idcode >> 12) & 0xffff;
639 rev = (idcode >> 28) & 0xff;
640 switch (hawkeye) {
641 case 0xb990:
642 switch (rev) {
643 case 0:
644 omap_revision = DRA752_REV_ES1_0;
645 break;
646 case 1:
647 default:
648 omap_revision = DRA752_REV_ES1_1;
649 }
650 break;
651
652 default:
653 /* Unknown default to latest silicon rev as default*/
654 pr_warn("%s: unknown idcode=0x%08x (hawkeye=0x%08x,rev=0x%d)\n",
655 __func__, idcode, hawkeye, rev);
656 omap_revision = DRA752_REV_ES1_1;
657 }
658
659 sprintf(soc_name, "DRA%03x", omap_rev() >> 16);
660 sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
661 (omap_rev() >> 8) & 0xf);
662
663 pr_info("%s %s\n", soc_name, soc_rev);
664}
665
631/* 666/*
632 * Set up things for map_io and processor detection later on. Gets called 667 * Set up things for map_io and processor detection later on. Gets called
633 * pretty much first thing from board init. For multi-omap, this gets 668 * pretty much first thing from board init. For multi-omap, this gets
@@ -669,6 +704,8 @@ static const char * __init omap_get_family(void)
669 return kasprintf(GFP_KERNEL, "OMAP5"); 704 return kasprintf(GFP_KERNEL, "OMAP5");
670 else if (soc_is_am43xx()) 705 else if (soc_is_am43xx())
671 return kasprintf(GFP_KERNEL, "AM43xx"); 706 return kasprintf(GFP_KERNEL, "AM43xx");
707 else if (soc_is_dra7xx())
708 return kasprintf(GFP_KERNEL, "DRA7");
672 else 709 else
673 return kasprintf(GFP_KERNEL, "Unknown"); 710 return kasprintf(GFP_KERNEL, "Unknown");
674} 711}
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index f14f9ac2dca1..4ec3b4a93843 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -693,6 +693,7 @@ void __init dra7xx_init_early(void)
693 omap_prm_base_init(); 693 omap_prm_base_init();
694 omap_cm_base_init(); 694 omap_cm_base_init();
695 omap44xx_prm_init(); 695 omap44xx_prm_init();
696 dra7xxx_check_revision();
696 dra7xx_powerdomains_init(); 697 dra7xx_powerdomains_init();
697 dra7xx_clockdomains_init(); 698 dra7xx_clockdomains_init();
698 dra7xx_hwmod_init(); 699 dra7xx_hwmod_init();
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 1219280bb976..41e54f759934 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -3635,15 +3635,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic = {
3635 .master = &omap44xx_l4_abe_hwmod, 3635 .master = &omap44xx_l4_abe_hwmod,
3636 .slave = &omap44xx_dmic_hwmod, 3636 .slave = &omap44xx_dmic_hwmod,
3637 .clk = "ocp_abe_iclk", 3637 .clk = "ocp_abe_iclk",
3638 .user = OCP_USER_MPU, 3638 .user = OCP_USER_MPU | OCP_USER_SDMA,
3639};
3640
3641/* l4_abe -> dmic (dma) */
3642static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic_dma = {
3643 .master = &omap44xx_l4_abe_hwmod,
3644 .slave = &omap44xx_dmic_hwmod,
3645 .clk = "ocp_abe_iclk",
3646 .user = OCP_USER_SDMA,
3647}; 3639};
3648 3640
3649/* dsp -> iva */ 3641/* dsp -> iva */
@@ -4209,15 +4201,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1 = {
4209 .master = &omap44xx_l4_abe_hwmod, 4201 .master = &omap44xx_l4_abe_hwmod,
4210 .slave = &omap44xx_mcbsp1_hwmod, 4202 .slave = &omap44xx_mcbsp1_hwmod,
4211 .clk = "ocp_abe_iclk", 4203 .clk = "ocp_abe_iclk",
4212 .user = OCP_USER_MPU, 4204 .user = OCP_USER_MPU | OCP_USER_SDMA,
4213};
4214
4215/* l4_abe -> mcbsp1 (dma) */
4216static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1_dma = {
4217 .master = &omap44xx_l4_abe_hwmod,
4218 .slave = &omap44xx_mcbsp1_hwmod,
4219 .clk = "ocp_abe_iclk",
4220 .user = OCP_USER_SDMA,
4221}; 4205};
4222 4206
4223/* l4_abe -> mcbsp2 */ 4207/* l4_abe -> mcbsp2 */
@@ -4225,15 +4209,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2 = {
4225 .master = &omap44xx_l4_abe_hwmod, 4209 .master = &omap44xx_l4_abe_hwmod,
4226 .slave = &omap44xx_mcbsp2_hwmod, 4210 .slave = &omap44xx_mcbsp2_hwmod,
4227 .clk = "ocp_abe_iclk", 4211 .clk = "ocp_abe_iclk",
4228 .user = OCP_USER_MPU, 4212 .user = OCP_USER_MPU | OCP_USER_SDMA,
4229};
4230
4231/* l4_abe -> mcbsp2 (dma) */
4232static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2_dma = {
4233 .master = &omap44xx_l4_abe_hwmod,
4234 .slave = &omap44xx_mcbsp2_hwmod,
4235 .clk = "ocp_abe_iclk",
4236 .user = OCP_USER_SDMA,
4237}; 4213};
4238 4214
4239/* l4_abe -> mcbsp3 */ 4215/* l4_abe -> mcbsp3 */
@@ -4241,15 +4217,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3 = {
4241 .master = &omap44xx_l4_abe_hwmod, 4217 .master = &omap44xx_l4_abe_hwmod,
4242 .slave = &omap44xx_mcbsp3_hwmod, 4218 .slave = &omap44xx_mcbsp3_hwmod,
4243 .clk = "ocp_abe_iclk", 4219 .clk = "ocp_abe_iclk",
4244 .user = OCP_USER_MPU, 4220 .user = OCP_USER_MPU | OCP_USER_SDMA,
4245};
4246
4247/* l4_abe -> mcbsp3 (dma) */
4248static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3_dma = {
4249 .master = &omap44xx_l4_abe_hwmod,
4250 .slave = &omap44xx_mcbsp3_hwmod,
4251 .clk = "ocp_abe_iclk",
4252 .user = OCP_USER_SDMA,
4253}; 4221};
4254 4222
4255/* l4_per -> mcbsp4 */ 4223/* l4_per -> mcbsp4 */
@@ -4265,15 +4233,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcpdm = {
4265 .master = &omap44xx_l4_abe_hwmod, 4233 .master = &omap44xx_l4_abe_hwmod,
4266 .slave = &omap44xx_mcpdm_hwmod, 4234 .slave = &omap44xx_mcpdm_hwmod,
4267 .clk = "ocp_abe_iclk", 4235 .clk = "ocp_abe_iclk",
4268 .user = OCP_USER_MPU, 4236 .user = OCP_USER_MPU | OCP_USER_SDMA,
4269};
4270
4271/* l4_abe -> mcpdm (dma) */
4272static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcpdm_dma = {
4273 .master = &omap44xx_l4_abe_hwmod,
4274 .slave = &omap44xx_mcpdm_hwmod,
4275 .clk = "ocp_abe_iclk",
4276 .user = OCP_USER_SDMA,
4277}; 4237};
4278 4238
4279/* l4_per -> mcspi1 */ 4239/* l4_per -> mcspi1 */
@@ -4575,15 +4535,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer5 = {
4575 .master = &omap44xx_l4_abe_hwmod, 4535 .master = &omap44xx_l4_abe_hwmod,
4576 .slave = &omap44xx_timer5_hwmod, 4536 .slave = &omap44xx_timer5_hwmod,
4577 .clk = "ocp_abe_iclk", 4537 .clk = "ocp_abe_iclk",
4578 .user = OCP_USER_MPU, 4538 .user = OCP_USER_MPU | OCP_USER_SDMA,
4579};
4580
4581/* l4_abe -> timer5 (dma) */
4582static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer5_dma = {
4583 .master = &omap44xx_l4_abe_hwmod,
4584 .slave = &omap44xx_timer5_hwmod,
4585 .clk = "ocp_abe_iclk",
4586 .user = OCP_USER_SDMA,
4587}; 4539};
4588 4540
4589/* l4_abe -> timer6 */ 4541/* l4_abe -> timer6 */
@@ -4591,15 +4543,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer6 = {
4591 .master = &omap44xx_l4_abe_hwmod, 4543 .master = &omap44xx_l4_abe_hwmod,
4592 .slave = &omap44xx_timer6_hwmod, 4544 .slave = &omap44xx_timer6_hwmod,
4593 .clk = "ocp_abe_iclk", 4545 .clk = "ocp_abe_iclk",
4594 .user = OCP_USER_MPU, 4546 .user = OCP_USER_MPU | OCP_USER_SDMA,
4595};
4596
4597/* l4_abe -> timer6 (dma) */
4598static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer6_dma = {
4599 .master = &omap44xx_l4_abe_hwmod,
4600 .slave = &omap44xx_timer6_hwmod,
4601 .clk = "ocp_abe_iclk",
4602 .user = OCP_USER_SDMA,
4603}; 4547};
4604 4548
4605/* l4_abe -> timer7 */ 4549/* l4_abe -> timer7 */
@@ -4607,15 +4551,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer7 = {
4607 .master = &omap44xx_l4_abe_hwmod, 4551 .master = &omap44xx_l4_abe_hwmod,
4608 .slave = &omap44xx_timer7_hwmod, 4552 .slave = &omap44xx_timer7_hwmod,
4609 .clk = "ocp_abe_iclk", 4553 .clk = "ocp_abe_iclk",
4610 .user = OCP_USER_MPU, 4554 .user = OCP_USER_MPU | OCP_USER_SDMA,
4611};
4612
4613/* l4_abe -> timer7 (dma) */
4614static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer7_dma = {
4615 .master = &omap44xx_l4_abe_hwmod,
4616 .slave = &omap44xx_timer7_hwmod,
4617 .clk = "ocp_abe_iclk",
4618 .user = OCP_USER_SDMA,
4619}; 4555};
4620 4556
4621/* l4_abe -> timer8 */ 4557/* l4_abe -> timer8 */
@@ -4623,15 +4559,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer8 = {
4623 .master = &omap44xx_l4_abe_hwmod, 4559 .master = &omap44xx_l4_abe_hwmod,
4624 .slave = &omap44xx_timer8_hwmod, 4560 .slave = &omap44xx_timer8_hwmod,
4625 .clk = "ocp_abe_iclk", 4561 .clk = "ocp_abe_iclk",
4626 .user = OCP_USER_MPU, 4562 .user = OCP_USER_MPU | OCP_USER_SDMA,
4627};
4628
4629/* l4_abe -> timer8 (dma) */
4630static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer8_dma = {
4631 .master = &omap44xx_l4_abe_hwmod,
4632 .slave = &omap44xx_timer8_hwmod,
4633 .clk = "ocp_abe_iclk",
4634 .user = OCP_USER_SDMA,
4635}; 4563};
4636 4564
4637/* l4_per -> timer9 */ 4565/* l4_per -> timer9 */
@@ -4831,7 +4759,6 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
4831 &omap44xx_l3_instr__debugss, 4759 &omap44xx_l3_instr__debugss,
4832 &omap44xx_l4_cfg__dma_system, 4760 &omap44xx_l4_cfg__dma_system,
4833 &omap44xx_l4_abe__dmic, 4761 &omap44xx_l4_abe__dmic,
4834 &omap44xx_l4_abe__dmic_dma,
4835 &omap44xx_dsp__iva, 4762 &omap44xx_dsp__iva,
4836 /* &omap44xx_dsp__sl2if, */ 4763 /* &omap44xx_dsp__sl2if, */
4837 &omap44xx_l4_cfg__dsp, 4764 &omap44xx_l4_cfg__dsp,
@@ -4874,14 +4801,10 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
4874 &omap44xx_l4_abe__mcasp, 4801 &omap44xx_l4_abe__mcasp,
4875 &omap44xx_l4_abe__mcasp_dma, 4802 &omap44xx_l4_abe__mcasp_dma,
4876 &omap44xx_l4_abe__mcbsp1, 4803 &omap44xx_l4_abe__mcbsp1,
4877 &omap44xx_l4_abe__mcbsp1_dma,
4878 &omap44xx_l4_abe__mcbsp2, 4804 &omap44xx_l4_abe__mcbsp2,
4879 &omap44xx_l4_abe__mcbsp2_dma,
4880 &omap44xx_l4_abe__mcbsp3, 4805 &omap44xx_l4_abe__mcbsp3,
4881 &omap44xx_l4_abe__mcbsp3_dma,
4882 &omap44xx_l4_per__mcbsp4, 4806 &omap44xx_l4_per__mcbsp4,
4883 &omap44xx_l4_abe__mcpdm, 4807 &omap44xx_l4_abe__mcpdm,
4884 &omap44xx_l4_abe__mcpdm_dma,
4885 &omap44xx_l4_per__mcspi1, 4808 &omap44xx_l4_per__mcspi1,
4886 &omap44xx_l4_per__mcspi2, 4809 &omap44xx_l4_per__mcspi2,
4887 &omap44xx_l4_per__mcspi3, 4810 &omap44xx_l4_per__mcspi3,
@@ -4913,13 +4836,9 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
4913 &omap44xx_l4_per__timer3, 4836 &omap44xx_l4_per__timer3,
4914 &omap44xx_l4_per__timer4, 4837 &omap44xx_l4_per__timer4,
4915 &omap44xx_l4_abe__timer5, 4838 &omap44xx_l4_abe__timer5,
4916 &omap44xx_l4_abe__timer5_dma,
4917 &omap44xx_l4_abe__timer6, 4839 &omap44xx_l4_abe__timer6,
4918 &omap44xx_l4_abe__timer6_dma,
4919 &omap44xx_l4_abe__timer7, 4840 &omap44xx_l4_abe__timer7,
4920 &omap44xx_l4_abe__timer7_dma,
4921 &omap44xx_l4_abe__timer8, 4841 &omap44xx_l4_abe__timer8,
4922 &omap44xx_l4_abe__timer8_dma,
4923 &omap44xx_l4_per__timer9, 4842 &omap44xx_l4_per__timer9,
4924 &omap44xx_l4_per__timer10, 4843 &omap44xx_l4_per__timer10,
4925 &omap44xx_l4_per__timer11, 4844 &omap44xx_l4_per__timer11,
diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
index e829664e6a6c..290213f2cbe3 100644
--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -334,6 +334,235 @@ static struct omap_hwmod omap54xx_dmic_hwmod = {
334}; 334};
335 335
336/* 336/*
337 * 'dss' class
338 * display sub-system
339 */
340static struct omap_hwmod_class_sysconfig omap54xx_dss_sysc = {
341 .rev_offs = 0x0000,
342 .syss_offs = 0x0014,
343 .sysc_flags = SYSS_HAS_RESET_STATUS,
344};
345
346static struct omap_hwmod_class omap54xx_dss_hwmod_class = {
347 .name = "dss",
348 .sysc = &omap54xx_dss_sysc,
349 .reset = omap_dss_reset,
350};
351
352/* dss */
353static struct omap_hwmod_opt_clk dss_opt_clks[] = {
354 { .role = "32khz_clk", .clk = "dss_32khz_clk" },
355 { .role = "sys_clk", .clk = "dss_sys_clk" },
356 { .role = "hdmi_clk", .clk = "dss_48mhz_clk" },
357};
358
359static struct omap_hwmod omap54xx_dss_hwmod = {
360 .name = "dss_core",
361 .class = &omap54xx_dss_hwmod_class,
362 .clkdm_name = "dss_clkdm",
363 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
364 .main_clk = "dss_dss_clk",
365 .prcm = {
366 .omap4 = {
367 .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
368 .context_offs = OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET,
369 .modulemode = MODULEMODE_SWCTRL,
370 },
371 },
372 .opt_clks = dss_opt_clks,
373 .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
374};
375
376/*
377 * 'dispc' class
378 * display controller
379 */
380
381static struct omap_hwmod_class_sysconfig omap54xx_dispc_sysc = {
382 .rev_offs = 0x0000,
383 .sysc_offs = 0x0010,
384 .syss_offs = 0x0014,
385 .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
386 SYSC_HAS_ENAWAKEUP | SYSC_HAS_MIDLEMODE |
387 SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
388 SYSS_HAS_RESET_STATUS),
389 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
390 MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
391 .sysc_fields = &omap_hwmod_sysc_type1,
392};
393
394static struct omap_hwmod_class omap54xx_dispc_hwmod_class = {
395 .name = "dispc",
396 .sysc = &omap54xx_dispc_sysc,
397};
398
399/* dss_dispc */
400static struct omap_hwmod_opt_clk dss_dispc_opt_clks[] = {
401 { .role = "sys_clk", .clk = "dss_sys_clk" },
402};
403
404/* dss_dispc dev_attr */
405static struct omap_dss_dispc_dev_attr dss_dispc_dev_attr = {
406 .has_framedonetv_irq = 1,
407 .manager_count = 4,
408};
409
410static struct omap_hwmod omap54xx_dss_dispc_hwmod = {
411 .name = "dss_dispc",
412 .class = &omap54xx_dispc_hwmod_class,
413 .clkdm_name = "dss_clkdm",
414 .main_clk = "dss_dss_clk",
415 .prcm = {
416 .omap4 = {
417 .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
418 .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
419 },
420 },
421 .opt_clks = dss_dispc_opt_clks,
422 .opt_clks_cnt = ARRAY_SIZE(dss_dispc_opt_clks),
423 .dev_attr = &dss_dispc_dev_attr,
424};
425
426/*
427 * 'dsi1' class
428 * display serial interface controller
429 */
430
431static struct omap_hwmod_class_sysconfig omap54xx_dsi1_sysc = {
432 .rev_offs = 0x0000,
433 .sysc_offs = 0x0010,
434 .syss_offs = 0x0014,
435 .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
436 SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
437 SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
438 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
439 .sysc_fields = &omap_hwmod_sysc_type1,
440};
441
442static struct omap_hwmod_class omap54xx_dsi1_hwmod_class = {
443 .name = "dsi1",
444 .sysc = &omap54xx_dsi1_sysc,
445};
446
447/* dss_dsi1_a */
448static struct omap_hwmod_opt_clk dss_dsi1_a_opt_clks[] = {
449 { .role = "sys_clk", .clk = "dss_sys_clk" },
450};
451
452static struct omap_hwmod omap54xx_dss_dsi1_a_hwmod = {
453 .name = "dss_dsi1",
454 .class = &omap54xx_dsi1_hwmod_class,
455 .clkdm_name = "dss_clkdm",
456 .main_clk = "dss_dss_clk",
457 .prcm = {
458 .omap4 = {
459 .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
460 .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
461 },
462 },
463 .opt_clks = dss_dsi1_a_opt_clks,
464 .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_a_opt_clks),
465};
466
467/* dss_dsi1_c */
468static struct omap_hwmod_opt_clk dss_dsi1_c_opt_clks[] = {
469 { .role = "sys_clk", .clk = "dss_sys_clk" },
470};
471
472static struct omap_hwmod omap54xx_dss_dsi1_c_hwmod = {
473 .name = "dss_dsi2",
474 .class = &omap54xx_dsi1_hwmod_class,
475 .clkdm_name = "dss_clkdm",
476 .main_clk = "dss_dss_clk",
477 .prcm = {
478 .omap4 = {
479 .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
480 .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
481 },
482 },
483 .opt_clks = dss_dsi1_c_opt_clks,
484 .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_c_opt_clks),
485};
486
487/*
488 * 'hdmi' class
489 * hdmi controller
490 */
491
492static struct omap_hwmod_class_sysconfig omap54xx_hdmi_sysc = {
493 .rev_offs = 0x0000,
494 .sysc_offs = 0x0010,
495 .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE |
496 SYSC_HAS_SOFTRESET),
497 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
498 SIDLE_SMART_WKUP),
499 .sysc_fields = &omap_hwmod_sysc_type2,
500};
501
502static struct omap_hwmod_class omap54xx_hdmi_hwmod_class = {
503 .name = "hdmi",
504 .sysc = &omap54xx_hdmi_sysc,
505};
506
507static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = {
508 { .role = "sys_clk", .clk = "dss_sys_clk" },
509};
510
511static struct omap_hwmod omap54xx_dss_hdmi_hwmod = {
512 .name = "dss_hdmi",
513 .class = &omap54xx_hdmi_hwmod_class,
514 .clkdm_name = "dss_clkdm",
515 .main_clk = "dss_48mhz_clk",
516 .prcm = {
517 .omap4 = {
518 .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
519 .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
520 },
521 },
522 .opt_clks = dss_hdmi_opt_clks,
523 .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks),
524};
525
526/*
527 * 'rfbi' class
528 * remote frame buffer interface
529 */
530
531static struct omap_hwmod_class_sysconfig omap54xx_rfbi_sysc = {
532 .rev_offs = 0x0000,
533 .sysc_offs = 0x0010,
534 .syss_offs = 0x0014,
535 .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
536 SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
537 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
538 .sysc_fields = &omap_hwmod_sysc_type1,
539};
540
541static struct omap_hwmod_class omap54xx_rfbi_hwmod_class = {
542 .name = "rfbi",
543 .sysc = &omap54xx_rfbi_sysc,
544};
545
546/* dss_rfbi */
547static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = {
548 { .role = "ick", .clk = "l3_iclk_div" },
549};
550
551static struct omap_hwmod omap54xx_dss_rfbi_hwmod = {
552 .name = "dss_rfbi",
553 .class = &omap54xx_rfbi_hwmod_class,
554 .clkdm_name = "dss_clkdm",
555 .prcm = {
556 .omap4 = {
557 .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
558 .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
559 },
560 },
561 .opt_clks = dss_rfbi_opt_clks,
562 .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks),
563};
564
565/*
337 * 'emif' class 566 * 'emif' class
338 * external memory interface no1 (wrapper) 567 * external memory interface no1 (wrapper)
339 */ 568 */
@@ -1974,6 +2203,54 @@ static struct omap_hwmod_ocp_if omap54xx_l4_abe__dmic = {
1974 .user = OCP_USER_MPU, 2203 .user = OCP_USER_MPU,
1975}; 2204};
1976 2205
2206/* l3_main_2 -> dss */
2207static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss = {
2208 .master = &omap54xx_l3_main_2_hwmod,
2209 .slave = &omap54xx_dss_hwmod,
2210 .clk = "l3_iclk_div",
2211 .user = OCP_USER_MPU | OCP_USER_SDMA,
2212};
2213
2214/* l3_main_2 -> dss_dispc */
2215static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dispc = {
2216 .master = &omap54xx_l3_main_2_hwmod,
2217 .slave = &omap54xx_dss_dispc_hwmod,
2218 .clk = "l3_iclk_div",
2219 .user = OCP_USER_MPU | OCP_USER_SDMA,
2220};
2221
2222/* l3_main_2 -> dss_dsi1_a */
2223static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dsi1_a = {
2224 .master = &omap54xx_l3_main_2_hwmod,
2225 .slave = &omap54xx_dss_dsi1_a_hwmod,
2226 .clk = "l3_iclk_div",
2227 .user = OCP_USER_MPU | OCP_USER_SDMA,
2228};
2229
2230/* l3_main_2 -> dss_dsi1_c */
2231static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dsi1_c = {
2232 .master = &omap54xx_l3_main_2_hwmod,
2233 .slave = &omap54xx_dss_dsi1_c_hwmod,
2234 .clk = "l3_iclk_div",
2235 .user = OCP_USER_MPU | OCP_USER_SDMA,
2236};
2237
2238/* l3_main_2 -> dss_hdmi */
2239static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_hdmi = {
2240 .master = &omap54xx_l3_main_2_hwmod,
2241 .slave = &omap54xx_dss_hdmi_hwmod,
2242 .clk = "l3_iclk_div",
2243 .user = OCP_USER_MPU | OCP_USER_SDMA,
2244};
2245
2246/* l3_main_2 -> dss_rfbi */
2247static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_rfbi = {
2248 .master = &omap54xx_l3_main_2_hwmod,
2249 .slave = &omap54xx_dss_rfbi_hwmod,
2250 .clk = "l3_iclk_div",
2251 .user = OCP_USER_MPU | OCP_USER_SDMA,
2252};
2253
1977/* mpu -> emif1 */ 2254/* mpu -> emif1 */
1978static struct omap_hwmod_ocp_if omap54xx_mpu__emif1 = { 2255static struct omap_hwmod_ocp_if omap54xx_mpu__emif1 = {
1979 .master = &omap54xx_mpu_hwmod, 2256 .master = &omap54xx_mpu_hwmod,
@@ -2427,6 +2704,12 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = {
2427 &omap54xx_l4_cfg__dma_system, 2704 &omap54xx_l4_cfg__dma_system,
2428 &omap54xx_l4_abe__dmic, 2705 &omap54xx_l4_abe__dmic,
2429 &omap54xx_l4_cfg__mmu_dsp, 2706 &omap54xx_l4_cfg__mmu_dsp,
2707 &omap54xx_l3_main_2__dss,
2708 &omap54xx_l3_main_2__dss_dispc,
2709 &omap54xx_l3_main_2__dss_dsi1_a,
2710 &omap54xx_l3_main_2__dss_dsi1_c,
2711 &omap54xx_l3_main_2__dss_hdmi,
2712 &omap54xx_l3_main_2__dss_rfbi,
2430 &omap54xx_mpu__emif1, 2713 &omap54xx_mpu__emif1,
2431 &omap54xx_mpu__emif2, 2714 &omap54xx_mpu__emif2,
2432 &omap54xx_l4_wkup__gpio1, 2715 &omap54xx_l4_wkup__gpio1,
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 615e5b1fb025..6bf626700557 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -46,15 +46,8 @@
46 46
47static bool is_offset_valid; 47static bool is_offset_valid;
48static u8 smps_offset; 48static u8 smps_offset;
49/*
50 * Flag to ensure Smartreflex bit in TWL
51 * being cleared in board file is not overwritten.
52 */
53static bool __initdata twl_sr_enable_autoinit;
54 49
55#define TWL4030_DCDC_GLOBAL_CFG 0x06
56#define REG_SMPS_OFFSET 0xE0 50#define REG_SMPS_OFFSET 0xE0
57#define SMARTREFLEX_ENABLE BIT(3)
58 51
59static unsigned long twl4030_vsel_to_uv(const u8 vsel) 52static unsigned long twl4030_vsel_to_uv(const u8 vsel)
60{ 53{
@@ -251,18 +244,6 @@ int __init omap3_twl_init(void)
251 if (!cpu_is_omap34xx()) 244 if (!cpu_is_omap34xx())
252 return -ENODEV; 245 return -ENODEV;
253 246
254 /*
255 * The smartreflex bit on twl4030 specifies if the setting of voltage
256 * is done over the I2C_SR path. Since this setting is independent of
257 * the actual usage of smartreflex AVS module, we enable TWL SR bit
258 * by default irrespective of whether smartreflex AVS module is enabled
259 * on the OMAP side or not. This is because without this bit enabled,
260 * the voltage scaling through vp forceupdate/bypass mechanism of
261 * voltage scaling will not function on TWL over I2C_SR.
262 */
263 if (!twl_sr_enable_autoinit)
264 omap3_twl_set_sr_bit(true);
265
266 voltdm = voltdm_lookup("mpu_iva"); 247 voltdm = voltdm_lookup("mpu_iva");
267 omap_voltage_register_pmic(voltdm, &omap3_mpu_pmic); 248 omap_voltage_register_pmic(voltdm, &omap3_mpu_pmic);
268 249
@@ -271,44 +252,3 @@ int __init omap3_twl_init(void)
271 252
272 return 0; 253 return 0;
273} 254}
274
275/**
276 * omap3_twl_set_sr_bit() - Set/Clear SR bit on TWL
277 * @enable: enable SR mode in twl or not
278 *
279 * If 'enable' is true, enables Smartreflex bit on TWL 4030 to make sure
280 * voltage scaling through OMAP SR works. Else, the smartreflex bit
281 * on twl4030 is cleared as there are platforms which use OMAP3 and T2 but
282 * use Synchronized Scaling Hardware Strategy (ENABLE_VMODE=1) and Direct
283 * Strategy Software Scaling Mode (ENABLE_VMODE=0), for setting the voltages,
284 * in those scenarios this bit is to be cleared (enable = false).
285 *
286 * Returns 0 on success, error is returned if I2C read/write fails.
287 */
288int __init omap3_twl_set_sr_bit(bool enable)
289{
290 u8 temp;
291 int ret;
292 if (twl_sr_enable_autoinit)
293 pr_warning("%s: unexpected multiple calls\n", __func__);
294
295 ret = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &temp,
296 TWL4030_DCDC_GLOBAL_CFG);
297 if (ret)
298 goto err;
299
300 if (enable)
301 temp |= SMARTREFLEX_ENABLE;
302 else
303 temp &= ~SMARTREFLEX_ENABLE;
304
305 ret = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, temp,
306 TWL4030_DCDC_GLOBAL_CFG);
307 if (!ret) {
308 twl_sr_enable_autoinit = true;
309 return 0;
310 }
311err:
312 pr_err("%s: Error access to TWL4030 (%d)\n", __func__, ret);
313 return ret;
314}
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index e1b41416fbf1..828aee9ea6a8 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -32,11 +32,13 @@
32#include "pm.h" 32#include "pm.h"
33#include "twl-common.h" 33#include "twl-common.h"
34 34
35#ifdef CONFIG_SUSPEND
35/* 36/*
36 * omap_pm_suspend: points to a function that does the SoC-specific 37 * omap_pm_suspend: points to a function that does the SoC-specific
37 * suspend work 38 * suspend work
38 */ 39 */
39int (*omap_pm_suspend)(void); 40static int (*omap_pm_suspend)(void);
41#endif
40 42
41#ifdef CONFIG_PM 43#ifdef CONFIG_PM
42/** 44/**
@@ -243,6 +245,15 @@ static const struct platform_suspend_ops omap_pm_ops = {
243 .valid = suspend_valid_only_mem, 245 .valid = suspend_valid_only_mem,
244}; 246};
245 247
248/**
249 * omap_common_suspend_init - Set common suspend routines for OMAP SoCs
250 * @pm_suspend: function pointer to SoC specific suspend function
251 */
252void omap_common_suspend_init(void *pm_suspend)
253{
254 omap_pm_suspend = pm_suspend;
255 suspend_set_ops(&omap_pm_ops);
256}
246#endif /* CONFIG_SUSPEND */ 257#endif /* CONFIG_SUSPEND */
247 258
248static void __init omap3_init_voltages(void) 259static void __init omap3_init_voltages(void)
@@ -287,32 +298,24 @@ omap_postcore_initcall(omap2_common_pm_init);
287 298
288int __init omap2_common_pm_late_init(void) 299int __init omap2_common_pm_late_init(void)
289{ 300{
290 /* 301 if (of_have_populated_dt()) {
291 * In the case of DT, the PMIC and SR initialization will be done using 302 omap3_twl_init();
292 * a completely different mechanism. 303 omap4_twl_init();
293 * Disable this part if a DT blob is available. 304 }
294 */
295 if (!of_have_populated_dt()) {
296
297 /* Init the voltage layer */
298 omap_pmic_late_init();
299 omap_voltage_late_init();
300 305
301 /* Initialize the voltages */ 306 /* Init the voltage layer */
302 omap3_init_voltages(); 307 omap_pmic_late_init();
303 omap4_init_voltages(); 308 omap_voltage_late_init();
304 309
305 /* Smartreflex device init */ 310 /* Initialize the voltages */
306 omap_devinit_smartreflex(); 311 omap3_init_voltages();
312 omap4_init_voltages();
307 313
308 } 314 /* Smartreflex device init */
315 omap_devinit_smartreflex();
309 316
310 /* cpufreq dummy device instantiation */ 317 /* cpufreq dummy device instantiation */
311 omap_init_cpufreq(); 318 omap_init_cpufreq();
312 319
313#ifdef CONFIG_SUSPEND
314 suspend_set_ops(&omap_pm_ops);
315#endif
316
317 return 0; 320 return 0;
318} 321}
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index d4d0fce325c7..e150102d6c06 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -34,7 +34,6 @@ extern void *omap3_secure_ram_storage;
34extern void omap3_pm_off_mode_enable(int); 34extern void omap3_pm_off_mode_enable(int);
35extern void omap_sram_idle(void); 35extern void omap_sram_idle(void);
36extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused); 36extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused);
37extern int (*omap_pm_suspend)(void);
38 37
39#if defined(CONFIG_PM_OPP) 38#if defined(CONFIG_PM_OPP)
40extern int omap3_opp_init(void); 39extern int omap3_opp_init(void);
@@ -147,4 +146,11 @@ static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { *tstart = *
147static inline void omap_pm_setup_sr_i2c_pcb_length(u32 mm) { } 146static inline void omap_pm_setup_sr_i2c_pcb_length(u32 mm) { }
148#endif 147#endif
149 148
149#ifdef CONFIG_SUSPEND
150void omap_common_suspend_init(void *pm_suspend);
151#else
152static inline void omap_common_suspend_init(void *pm_suspend)
153{
154}
155#endif /* CONFIG_SUSPEND */
150#endif 156#endif
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 8c0759496c8d..a5ea988ff340 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -229,9 +229,7 @@ static void __init prcm_setup_regs(void)
229 clkdm_for_each(omap_pm_clkdms_setup, NULL); 229 clkdm_for_each(omap_pm_clkdms_setup, NULL);
230 clkdm_add_wkdep(mpu_clkdm, wkup_clkdm); 230 clkdm_add_wkdep(mpu_clkdm, wkup_clkdm);
231 231
232#ifdef CONFIG_SUSPEND 232 omap_common_suspend_init(omap2_enter_full_retention);
233 omap_pm_suspend = omap2_enter_full_retention;
234#endif
235 233
236 /* REVISIT: Configure number of 32 kHz clock cycles for sys_clk 234 /* REVISIT: Configure number of 32 kHz clock cycles for sys_clk
237 * stabilisation */ 235 * stabilisation */
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 87099bb6de69..507d8eeaab95 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -50,6 +50,7 @@
50#include "sdrc.h" 50#include "sdrc.h"
51#include "sram.h" 51#include "sram.h"
52#include "control.h" 52#include "control.h"
53#include "vc.h"
53 54
54/* pm34xx errata defined in pm.h */ 55/* pm34xx errata defined in pm.h */
55u16 pm34xx_errata; 56u16 pm34xx_errata;
@@ -288,6 +289,9 @@ void omap_sram_idle(void)
288 } 289 }
289 } 290 }
290 291
292 /* Configure PMIC signaling for I2C4 or sys_off_mode */
293 omap3_vc_set_pmic_signaling(core_next_state);
294
291 omap3_intc_prepare_idle(); 295 omap3_intc_prepare_idle();
292 296
293 /* 297 /*
@@ -391,7 +395,8 @@ restore:
391 395
392 return ret; 396 return ret;
393} 397}
394 398#else
399#define omap3_pm_suspend NULL
395#endif /* CONFIG_SUSPEND */ 400#endif /* CONFIG_SUSPEND */
396 401
397 402
@@ -705,9 +710,7 @@ int __init omap3_pm_init(void)
705 per_clkdm = clkdm_lookup("per_clkdm"); 710 per_clkdm = clkdm_lookup("per_clkdm");
706 wkup_clkdm = clkdm_lookup("wkup_clkdm"); 711 wkup_clkdm = clkdm_lookup("wkup_clkdm");
707 712
708#ifdef CONFIG_SUSPEND 713 omap_common_suspend_init(omap3_pm_suspend);
709 omap_pm_suspend = omap3_pm_suspend;
710#endif
711 714
712 arm_pm_idle = omap3_pm_idle; 715 arm_pm_idle = omap3_pm_idle;
713 omap3_idle_init(); 716 omap3_idle_init();
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index eefb30cfcabd..0dda6cf8b855 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -96,6 +96,8 @@ static int omap4_pm_suspend(void)
96 96
97 return 0; 97 return 0;
98} 98}
99#else
100#define omap4_pm_suspend NULL
99#endif /* CONFIG_SUSPEND */ 101#endif /* CONFIG_SUSPEND */
100 102
101static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) 103static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
@@ -251,9 +253,7 @@ int __init omap4_pm_init(void)
251 253
252 (void) clkdm_for_each(omap_pm_clkdms_setup, NULL); 254 (void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
253 255
254#ifdef CONFIG_SUSPEND 256 omap_common_suspend_init(omap4_pm_suspend);
255 omap_pm_suspend = omap4_pm_suspend;
256#endif
257 257
258 /* Overwrite the default cpu_do_idle() */ 258 /* Overwrite the default cpu_do_idle() */
259 arm_pm_idle = omap_default_idle; 259 arm_pm_idle = omap_default_idle;
diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
index cebad565ed37..106132db532b 100644
--- a/arch/arm/mach-omap2/prm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
@@ -123,8 +123,15 @@
123#define OMAP3430_GLOBAL_SW_RST_SHIFT 1 123#define OMAP3430_GLOBAL_SW_RST_SHIFT 1
124#define OMAP3430_GLOBAL_COLD_RST_SHIFT 0 124#define OMAP3430_GLOBAL_COLD_RST_SHIFT 0
125#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0) 125#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0)
126#define OMAP3430_SEL_OFF_MASK (1 << 3) 126#define OMAP3430_PRM_VOLTCTRL_SEL_VMODE (1 << 4)
127#define OMAP3430_AUTO_OFF_MASK (1 << 2) 127#define OMAP3430_PRM_VOLTCTRL_SEL_OFF (1 << 3)
128#define OMAP3430_PRM_VOLTCTRL_AUTO_OFF (1 << 2)
129#define OMAP3430_PRM_VOLTCTRL_AUTO_RET (1 << 1)
130#define OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP (1 << 0)
128#define OMAP3430_SETUP_TIME2_MASK (0xffff << 16) 131#define OMAP3430_SETUP_TIME2_MASK (0xffff << 16)
129#define OMAP3430_SETUP_TIME1_MASK (0xffff << 0) 132#define OMAP3430_SETUP_TIME1_MASK (0xffff << 0)
133#define OMAP3430_PRM_POLCTRL_OFFMODE_POL (1 << 3)
134#define OMAP3430_PRM_POLCTRL_CLKOUT_POL (1 << 2)
135#define OMAP3430_PRM_POLCTRL_CLKREQ_POL (1 << 1)
136#define OMAP3430_PRM_POLCTRL_EXTVOL_POL (1 << 0)
130#endif 137#endif
diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h
index 30abcc8b20e0..de2a34c423a7 100644
--- a/arch/arm/mach-omap2/soc.h
+++ b/arch/arm/mach-omap2/soc.h
@@ -459,10 +459,15 @@ IS_OMAP_TYPE(3430, 0x3430)
459#define OMAP5430_REV_ES2_0 (OMAP54XX_CLASS | (0x30 << 16) | (0x20 << 8)) 459#define OMAP5430_REV_ES2_0 (OMAP54XX_CLASS | (0x30 << 16) | (0x20 << 8))
460#define OMAP5432_REV_ES2_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x20 << 8)) 460#define OMAP5432_REV_ES2_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x20 << 8))
461 461
462#define DRA7XX_CLASS 0x07000000
463#define DRA752_REV_ES1_0 (DRA7XX_CLASS | (0x52 << 16) | (0x10 << 8))
464#define DRA752_REV_ES1_1 (DRA7XX_CLASS | (0x52 << 16) | (0x11 << 8))
465
462void omap2xxx_check_revision(void); 466void omap2xxx_check_revision(void);
463void omap3xxx_check_revision(void); 467void omap3xxx_check_revision(void);
464void omap4xxx_check_revision(void); 468void omap4xxx_check_revision(void);
465void omap5xxx_check_revision(void); 469void omap5xxx_check_revision(void);
470void dra7xxx_check_revision(void);
466void omap3xxx_check_features(void); 471void omap3xxx_check_features(void);
467void ti81xx_check_features(void); 472void ti81xx_check_features(void);
468void am33xx_check_features(void); 473void am33xx_check_features(void);
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 267f204559c3..a4628a9e760c 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -220,10 +220,126 @@ static inline u32 omap_usec_to_32k(u32 usec)
220 return DIV_ROUND_UP_ULL(32768ULL * (u64)usec, 1000000ULL); 220 return DIV_ROUND_UP_ULL(32768ULL * (u64)usec, 1000000ULL);
221} 221}
222 222
223/* Set oscillator setup time for omap3 */ 223struct omap3_vc_timings {
224static void omap3_set_clksetup(u32 usec, struct voltagedomain *voltdm) 224 u32 voltsetup1;
225 u32 voltsetup2;
226};
227
228struct omap3_vc {
229 struct voltagedomain *vd;
230 u32 voltctrl;
231 u32 voltsetup1;
232 u32 voltsetup2;
233 struct omap3_vc_timings timings[2];
234};
235static struct omap3_vc vc;
236
237void omap3_vc_set_pmic_signaling(int core_next_state)
238{
239 struct voltagedomain *vd = vc.vd;
240 struct omap3_vc_timings *c = vc.timings;
241 u32 voltctrl, voltsetup1, voltsetup2;
242
243 voltctrl = vc.voltctrl;
244 voltsetup1 = vc.voltsetup1;
245 voltsetup2 = vc.voltsetup2;
246
247 switch (core_next_state) {
248 case PWRDM_POWER_OFF:
249 voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_RET |
250 OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP);
251 voltctrl |= OMAP3430_PRM_VOLTCTRL_AUTO_OFF;
252 if (voltctrl & OMAP3430_PRM_VOLTCTRL_SEL_OFF)
253 voltsetup2 = c->voltsetup2;
254 else
255 voltsetup1 = c->voltsetup1;
256 break;
257 case PWRDM_POWER_RET:
258 default:
259 c++;
260 voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_OFF |
261 OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP);
262 voltctrl |= OMAP3430_PRM_VOLTCTRL_AUTO_RET;
263 voltsetup1 = c->voltsetup1;
264 break;
265 }
266
267 if (voltctrl != vc.voltctrl) {
268 vd->write(voltctrl, OMAP3_PRM_VOLTCTRL_OFFSET);
269 vc.voltctrl = voltctrl;
270 }
271 if (voltsetup1 != vc.voltsetup1) {
272 vd->write(c->voltsetup1,
273 OMAP3_PRM_VOLTSETUP1_OFFSET);
274 vc.voltsetup1 = voltsetup1;
275 }
276 if (voltsetup2 != vc.voltsetup2) {
277 vd->write(c->voltsetup2,
278 OMAP3_PRM_VOLTSETUP2_OFFSET);
279 vc.voltsetup2 = voltsetup2;
280 }
281}
282
283#define PRM_POLCTRL_TWL_MASK (OMAP3430_PRM_POLCTRL_CLKREQ_POL | \
284 OMAP3430_PRM_POLCTRL_CLKREQ_POL)
285#define PRM_POLCTRL_TWL_VAL OMAP3430_PRM_POLCTRL_CLKREQ_POL
286
287/*
288 * Configure signal polarity for sys_clkreq and sys_off_mode pins
289 * as the default values are wrong and can cause the system to hang
290 * if any twl4030 scripts are loaded.
291 */
292static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm)
293{
294 u32 val;
295
296 if (vc.vd)
297 return;
298
299 vc.vd = voltdm;
300
301 val = voltdm->read(OMAP3_PRM_POLCTRL_OFFSET);
302 if (!(val & OMAP3430_PRM_POLCTRL_CLKREQ_POL) ||
303 (val & OMAP3430_PRM_POLCTRL_CLKREQ_POL)) {
304 val |= OMAP3430_PRM_POLCTRL_CLKREQ_POL;
305 val &= ~OMAP3430_PRM_POLCTRL_OFFMODE_POL;
306 pr_debug("PM: fixing sys_clkreq and sys_off_mode polarity to 0x%x\n",
307 val);
308 voltdm->write(val, OMAP3_PRM_POLCTRL_OFFSET);
309 }
310
311 /*
312 * By default let's use I2C4 signaling for retention idle
313 * and sys_off_mode pin signaling for off idle. This way we
314 * have sys_clk_req pin go down for retention and both
315 * sys_clk_req and sys_off_mode pins will go down for off
316 * idle. And we can also scale voltages to zero for off-idle.
317 * Note that no actual voltage scaling during off-idle will
318 * happen unless the board specific twl4030 PMIC scripts are
319 * loaded.
320 */
321 val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
322 if (!(val & OMAP3430_PRM_VOLTCTRL_SEL_OFF)) {
323 val |= OMAP3430_PRM_VOLTCTRL_SEL_OFF;
324 pr_debug("PM: setting voltctrl sys_off_mode signaling to 0x%x\n",
325 val);
326 voltdm->write(val, OMAP3_PRM_VOLTCTRL_OFFSET);
327 }
328 vc.voltctrl = val;
329
330 omap3_vc_set_pmic_signaling(PWRDM_POWER_ON);
331}
332
333static void omap3_init_voltsetup1(struct voltagedomain *voltdm,
334 struct omap3_vc_timings *c, u32 idle)
225{ 335{
226 voltdm->write(omap_usec_to_32k(usec), OMAP3_PRM_CLKSETUP_OFFSET); 336 unsigned long val;
337
338 val = (voltdm->vc_param->on - idle) / voltdm->pmic->slew_rate;
339 val *= voltdm->sys_clk.rate / 8 / 1000000 + 1;
340 val <<= __ffs(voltdm->vfsm->voltsetup_mask);
341 c->voltsetup1 &= ~voltdm->vfsm->voltsetup_mask;
342 c->voltsetup1 |= val;
227} 343}
228 344
229/** 345/**
@@ -236,37 +352,21 @@ static void omap3_set_clksetup(u32 usec, struct voltagedomain *voltdm)
236 * or retention. Off mode has additionally an option to use sys_off_mode 352 * or retention. Off mode has additionally an option to use sys_off_mode
237 * pad, which uses a global signal to program the whole power IC to 353 * pad, which uses a global signal to program the whole power IC to
238 * off-mode. 354 * off-mode.
355 *
356 * Note that pmic is not controlling the voltage scaling during
357 * retention signaled over I2C4, so we can keep voltsetup2 as 0.
358 * And the oscillator is not shut off over I2C4, so no need to
359 * set clksetup.
239 */ 360 */
240static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode) 361static void omap3_set_i2c_timings(struct voltagedomain *voltdm)
241{ 362{
242 unsigned long voltsetup1; 363 struct omap3_vc_timings *c = vc.timings;
243 u32 tgt_volt;
244
245 /*
246 * Oscillator is shut down only if we are using sys_off_mode pad,
247 * thus we set a minimal setup time here
248 */
249 omap3_set_clksetup(1, voltdm);
250 364
251 if (off_mode) 365 /* Configure PRWDM_POWER_OFF over I2C4 */
252 tgt_volt = voltdm->vc_param->off; 366 omap3_init_voltsetup1(voltdm, c, voltdm->vc_param->off);
253 else 367 c++;
254 tgt_volt = voltdm->vc_param->ret; 368 /* Configure PRWDM_POWER_RET over I2C4 */
255 369 omap3_init_voltsetup1(voltdm, c, voltdm->vc_param->ret);
256 voltsetup1 = (voltdm->vc_param->on - tgt_volt) /
257 voltdm->pmic->slew_rate;
258
259 voltsetup1 = voltsetup1 * voltdm->sys_clk.rate / 8 / 1000000 + 1;
260
261 voltdm->rmw(voltdm->vfsm->voltsetup_mask,
262 voltsetup1 << __ffs(voltdm->vfsm->voltsetup_mask),
263 voltdm->vfsm->voltsetup_reg);
264
265 /*
266 * pmic is not controlling the voltage scaling during retention,
267 * thus set voltsetup2 to 0
268 */
269 voltdm->write(0, OMAP3_PRM_VOLTSETUP2_OFFSET);
270} 370}
271 371
272/** 372/**
@@ -275,69 +375,49 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)
275 * 375 *
276 * Calculates and sets up off-mode timings for a channel. Off-mode 376 * Calculates and sets up off-mode timings for a channel. Off-mode
277 * can use either I2C based voltage scaling, or alternatively 377 * can use either I2C based voltage scaling, or alternatively
278 * sys_off_mode pad can be used to send a global command to power IC. 378 * sys_off_mode pad can be used to send a global command to power IC.n,
279 * This function first checks which mode is being used, and calls
280 * omap3_set_i2c_timings() if the system is using I2C control mode.
281 * sys_off_mode has the additional benefit that voltages can be 379 * sys_off_mode has the additional benefit that voltages can be
282 * scaled to zero volt level with TWL4030 / TWL5030, I2C can only 380 * scaled to zero volt level with TWL4030 / TWL5030, I2C can only
283 * scale to 600mV. 381 * scale to 600mV.
382 *
383 * Note that omap is not controlling the voltage scaling during
384 * off idle signaled by sys_off_mode, so we can keep voltsetup1
385 * as 0.
284 */ 386 */
285static void omap3_set_off_timings(struct voltagedomain *voltdm) 387static void omap3_set_off_timings(struct voltagedomain *voltdm)
286{ 388{
287 unsigned long clksetup; 389 struct omap3_vc_timings *c = vc.timings;
288 unsigned long voltsetup2; 390 u32 tstart, tshut, clksetup, voltoffset;
289 unsigned long voltsetup2_old;
290 u32 val;
291 u32 tstart, tshut;
292 391
293 /* check if sys_off_mode is used to control off-mode voltages */ 392 if (c->voltsetup2)
294 val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
295 if (!(val & OMAP3430_SEL_OFF_MASK)) {
296 /* No, omap is controlling them over I2C */
297 omap3_set_i2c_timings(voltdm, true);
298 return; 393 return;
299 }
300 394
301 omap_pm_get_oscillator(&tstart, &tshut); 395 omap_pm_get_oscillator(&tstart, &tshut);
302 omap3_set_clksetup(tstart, voltdm); 396 if (tstart == ULONG_MAX) {
303 397 pr_debug("PM: oscillator start-up time not initialized, using 10ms\n");
304 clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET); 398 clksetup = omap_usec_to_32k(10000);
305 399 } else {
306 /* voltsetup 2 in us */ 400 clksetup = omap_usec_to_32k(tstart);
307 voltsetup2 = voltdm->vc_param->on / voltdm->pmic->slew_rate; 401 }
308
309 /* convert to 32k clk cycles */
310 voltsetup2 = DIV_ROUND_UP(voltsetup2 * 32768, 1000000);
311
312 voltsetup2_old = voltdm->read(OMAP3_PRM_VOLTSETUP2_OFFSET);
313
314 /*
315 * Update voltsetup2 if higher than current value (needed because
316 * we have multiple channels with different ramp times), also
317 * update voltoffset always to value recommended by TRM
318 */
319 if (voltsetup2 > voltsetup2_old) {
320 voltdm->write(voltsetup2, OMAP3_PRM_VOLTSETUP2_OFFSET);
321 voltdm->write(clksetup - voltsetup2,
322 OMAP3_PRM_VOLTOFFSET_OFFSET);
323 } else
324 voltdm->write(clksetup - voltsetup2_old,
325 OMAP3_PRM_VOLTOFFSET_OFFSET);
326 402
327 /* 403 /*
328 * omap is not controlling voltage scaling during off-mode, 404 * For twl4030 errata 27, we need to allow minimum ~488.32 us wait to
329 * thus set voltsetup1 to 0 405 * switch from HFCLKIN to internal oscillator. That means timings
406 * have voltoffset fixed to 0xa in rounded up 32 KiHz cycles. And
407 * that means we can calculate the value based on the oscillator
408 * start-up time since voltoffset2 = clksetup - voltoffset.
330 */ 409 */
331 voltdm->rmw(voltdm->vfsm->voltsetup_mask, 0, 410 voltoffset = omap_usec_to_32k(488);
332 voltdm->vfsm->voltsetup_reg); 411 c->voltsetup2 = clksetup - voltoffset;
333 412 voltdm->write(clksetup, OMAP3_PRM_CLKSETUP_OFFSET);
334 /* voltoffset must be clksetup minus voltsetup2 according to TRM */ 413 voltdm->write(voltoffset, OMAP3_PRM_VOLTOFFSET_OFFSET);
335 voltdm->write(clksetup - voltsetup2, OMAP3_PRM_VOLTOFFSET_OFFSET);
336} 414}
337 415
338static void __init omap3_vc_init_channel(struct voltagedomain *voltdm) 416static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
339{ 417{
418 omap3_vc_init_pmic_signaling(voltdm);
340 omap3_set_off_timings(voltdm); 419 omap3_set_off_timings(voltdm);
420 omap3_set_i2c_timings(voltdm);
341} 421}
342 422
343/** 423/**
diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h
index 91c8d75bf2ea..cdbdd78e755e 100644
--- a/arch/arm/mach-omap2/vc.h
+++ b/arch/arm/mach-omap2/vc.h
@@ -117,6 +117,9 @@ extern struct omap_vc_param omap4_mpu_vc_data;
117extern struct omap_vc_param omap4_iva_vc_data; 117extern struct omap_vc_param omap4_iva_vc_data;
118extern struct omap_vc_param omap4_core_vc_data; 118extern struct omap_vc_param omap4_core_vc_data;
119 119
120void omap3_vc_set_pmic_signaling(int core_next_state);
121
122
120void omap_vc_init_channel(struct voltagedomain *voltdm); 123void omap_vc_init_channel(struct voltagedomain *voltdm);
121int omap_vc_pre_scale(struct voltagedomain *voltdm, 124int omap_vc_pre_scale(struct voltagedomain *voltdm,
122 unsigned long target_volt, 125 unsigned long target_volt,