diff options
author | Tony Lindgren <tony@atomide.com> | 2016-03-30 10:36:06 -0700 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2016-03-30 10:36:06 -0700 |
commit | 1809de7e7d37c585e01a1bcc583ea92b78fc759d (patch) | |
tree | 76c5b35c2b04eafce86a1a729c02ab705eba44bc /arch/arm/mach-omap2/omap_hwmod_7xx_data.c | |
parent | ebf24414809200915b9ddf7f109bba7c278c8210 (diff) | |
parent | 3ca4a238106dedc285193ee47f494a6584b6fd2f (diff) | |
download | linux-stable-1809de7e7d37c585e01a1bcc583ea92b78fc759d.tar.gz linux-stable-1809de7e7d37c585e01a1bcc583ea92b78fc759d.tar.bz2 linux-stable-1809de7e7d37c585e01a1bcc583ea92b78fc759d.zip |
Merge tag 'for-v4.6-rc/omap-fixes-a' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into omap-for-v4.6/fixes
ARM: OMAP2+: first hwmod fix for v4.6-rc
Fix a longstanding bug in the hwmod code that could cause
hardware SYSCONFIG register values to not match the kernel's
idea of what they should be, and that could result in lower
performance during IP block idle entry.
Basic build, boot, and PM test logs are available here:
http://www.pwsan.com/omap/testlogs/omap-hwmod-fixes-a-for-v4.6-rc/20160326231727/
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod_7xx_data.c')
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index b61355e2a771..9442d89bd229 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -430,6 +430,67 @@ static struct omap_hwmod dra7xx_dma_system_hwmod = { }; /* + * 'tpcc' class + * + */ +static struct omap_hwmod_class dra7xx_tpcc_hwmod_class = { + .name = "tpcc", +}; + +static struct omap_hwmod dra7xx_tpcc_hwmod = { + .name = "tpcc", + .class = &dra7xx_tpcc_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3MAIN1_TPCC_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3MAIN1_TPCC_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'tptc' class + * + */ +static struct omap_hwmod_class dra7xx_tptc_hwmod_class = { + .name = "tptc", +}; + +/* tptc0 */ +static struct omap_hwmod dra7xx_tptc0_hwmod = { + .name = "tptc0", + .class = &dra7xx_tptc_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3MAIN1_TPTC1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3MAIN1_TPTC1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* tptc1 */ +static struct omap_hwmod dra7xx_tptc1_hwmod = { + .name = "tptc1", + .class = &dra7xx_tptc_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3MAIN1_TPTC2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3MAIN1_TPTC2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* * 'dss' class * */ @@ -1526,8 +1587,31 @@ static struct omap_hwmod dra7xx_ocp2scp3_hwmod = { * */ +/* + * As noted in documentation for _reset() in omap_hwmod.c, the stock reset + * functionality of OMAP HWMOD layer does not deassert the hardreset lines + * associated with an IP automatically leaving the driver to handle that + * by itself. This does not work for PCIeSS which needs the reset lines + * deasserted for the driver to start accessing registers. + * + * We use a PCIeSS HWMOD class specific reset handler to deassert the hardreset + * lines after asserting them. + */ +static int dra7xx_pciess_reset(struct omap_hwmod *oh) +{ + int i; + + for (i = 0; i < oh->rst_lines_cnt; i++) { + omap_hwmod_assert_hardreset(oh, oh->rst_lines[i].name); + omap_hwmod_deassert_hardreset(oh, oh->rst_lines[i].name); + } + + return 0; +} + static struct omap_hwmod_class dra7xx_pciess_hwmod_class = { .name = "pcie", + .reset = dra7xx_pciess_reset, }; /* pcie1 */ @@ -2563,6 +2647,30 @@ static struct omap_hwmod_ocp_if dra7xx_l4_cfg__dma_system = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* l3_main_1 -> tpcc */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tpcc = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_tpcc_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + +/* l3_main_1 -> tptc0 */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tptc0 = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_tptc0_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + +/* l3_main_1 -> tptc1 */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tptc1 = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_tptc1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + static struct omap_hwmod_addr_space dra7xx_dss_addrs[] = { { .name = "family", @@ -3380,6 +3488,9 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { &dra7xx_l3_main_1__mcasp3, &dra7xx_gmac__mdio, &dra7xx_l4_cfg__dma_system, + &dra7xx_l3_main_1__tpcc, + &dra7xx_l3_main_1__tptc0, + &dra7xx_l3_main_1__tptc1, &dra7xx_l3_main_1__dss, &dra7xx_l3_main_1__dispc, &dra7xx_l3_main_1__hdmi, |