ARM: OMAP5: DSS hwmod data
Subsystems (5)
PATCH 1/1 ARM: OMAP5: DSS hwmod data
Hi,
This patch adds hwmod data for omap5 display subsystem. I have tested this on omap5-uevm with a DSI panel. I cannot test omap5-uevm's hdmi output yet, as the mainline is missing omap5 HDMI driver.
I do see this when booting:
omap_hwmod: dss_dispc: cannot be enabled for reset (3)
omap_hwmod: dss_dsi1: cannot be enabled for reset (3)
omap_hwmod: dss_dsi2: cannot be enabled for reset (3)
omap_hwmod: dss_hdmi: cannot be enabled for reset (3)
omap_hwmod: dss_rfbi: cannot be enabled for reset (3)
But at least DSI works just fine.
Tomi
Archit Taneja (1):
ARM: OMAP5: Add omap5 DSS related hwmod data
arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 283 +++++++++++++++++++++++++++++ 1 file changed, 283 insertions(+)
Signature · 1 line
1.8.3.2
PATCH 1/1 ARM: OMAP5: Add omap5 DSS related hwmod data
From: Archit Taneja <[email protected]>
Add hwmod data for dss core, dispc dsi1, dsi2, rfbi and hdmi. It's more or less similar to omap4 hwmod data.
--- arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 283 +++++++++++++++++++++++++++++ 1 file changed, 283 insertions(+)
arch/arm/mach-omap2/omap_hwmod_54xx_data.c +283 -0
@@ -334,6 +334,235 @@ static struct omap_hwmod omap54xx_dmic_hwmod = { };/* +* 'dss' class +* display sub-system +*/ +static struct omap_hwmod_class_sysconfig omap54xx_dss_sysc = { + .rev_offs =0x0000 , + .syss_offs =0x0014 , + .sysc_flags =SYSS_HAS_RESET_STATUS , +}; + +static struct omap_hwmod_class omap54xx_dss_hwmod_class = { + .name ="dss" , + .sysc = &omap54xx_dss_sysc, + .reset = omap_dss_reset, +}; + +/* dss */ +static struct omap_hwmod_opt_clk dss_opt_clks[] = { + { .role ="32khz_clk" , .clk ="dss_32khz_clk" }, + { .role ="sys_clk" , .clk ="dss_sys_clk" }, + { .role ="hdmi_clk" , .clk ="dss_48mhz_clk" }, +}; + +static struct omap_hwmod omap54xx_dss_hwmod = { + .name ="dss_core" , + .class = &omap54xx_dss_hwmod_class, + .clkdm_name ="dss_clkdm" , + .flags =HWMOD_CONTROL_OPT_CLKS_IN_RESET , + .main_clk ="dss_dss_clk" , + .prcm = { + .omap4 = { + .clkctrl_offs =OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET , + .context_offs =OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET , + .modulemode =MODULEMODE_SWCTRL , + }, + }, + .opt_clks = dss_opt_clks, + .opt_clks_cnt =ARRAY_SIZE (dss_opt_clks), +}; + +/* +* 'dispc' class +* display controller +*/ + +static struct omap_hwmod_class_sysconfig omap54xx_dispc_sysc = { + .rev_offs =0x0000 , + .sysc_offs =0x0010 , + .syss_offs =0x0014 , + .sysc_flags = (SYSC_HAS_AUTOIDLE |SYSC_HAS_CLOCKACTIVITY | +SYSC_HAS_ENAWAKEUP |SYSC_HAS_MIDLEMODE | +SYSC_HAS_SIDLEMODE |SYSC_HAS_SOFTRESET | +SYSS_HAS_RESET_STATUS ), + .idlemodes = (SIDLE_FORCE |SIDLE_NO |SIDLE_SMART | +MSTANDBY_FORCE |MSTANDBY_NO |MSTANDBY_SMART ), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_dispc_hwmod_class = { + .name ="dispc" , + .sysc = &omap54xx_dispc_sysc, +}; + +/* dss_dispc */ +static struct omap_hwmod_opt_clk dss_dispc_opt_clks[] = { + { .role ="sys_clk" , .clk ="dss_sys_clk" }, +}; + +/* dss_dispc dev_attr */ +static struct omap_dss_dispc_dev_attr dss_dispc_dev_attr = { + .has_framedonetv_irq =1 , + .manager_count =4 , +}; + +static struct omap_hwmod omap54xx_dss_dispc_hwmod = { + .name ="dss_dispc" , + .class = &omap54xx_dispc_hwmod_class, + .clkdm_name ="dss_clkdm" , + .main_clk ="dss_dss_clk" , + .prcm = { + .omap4 = { + .clkctrl_offs =OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET , + .flags =HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT , + }, + }, + .opt_clks = dss_dispc_opt_clks, + .opt_clks_cnt =ARRAY_SIZE (dss_dispc_opt_clks), + .dev_attr = &dss_dispc_dev_attr, +}; + +/* +* 'dsi1' class +* display serial interface controller +*/ + +static struct omap_hwmod_class_sysconfig omap54xx_dsi1_sysc = { + .rev_offs =0x0000 , + .sysc_offs =0x0010 , + .syss_offs =0x0014 , + .sysc_flags = (SYSC_HAS_AUTOIDLE |SYSC_HAS_CLOCKACTIVITY | +SYSC_HAS_ENAWAKEUP |SYSC_HAS_SIDLEMODE | +SYSC_HAS_SOFTRESET |SYSS_HAS_RESET_STATUS ), + .idlemodes = (SIDLE_FORCE |SIDLE_NO |SIDLE_SMART ), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_dsi1_hwmod_class = { + .name ="dsi1" , + .sysc = &omap54xx_dsi1_sysc, +}; + +/* dss_dsi1_a */ +static struct omap_hwmod_opt_clk dss_dsi1_a_opt_clks[] = { + { .role ="sys_clk" , .clk ="dss_sys_clk" }, +}; + +static struct omap_hwmod omap54xx_dss_dsi1_a_hwmod = { + .name ="dss_dsi1" , + .class = &omap54xx_dsi1_hwmod_class, + .clkdm_name ="dss_clkdm" , + .main_clk ="dss_dss_clk" , + .prcm = { + .omap4 = { + .clkctrl_offs =OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET , + .flags =HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT , + }, + }, + .opt_clks = dss_dsi1_a_opt_clks, + .opt_clks_cnt =ARRAY_SIZE (dss_dsi1_a_opt_clks), +}; + +/* dss_dsi1_c */ +static struct omap_hwmod_opt_clk dss_dsi1_c_opt_clks[] = { + { .role ="sys_clk" , .clk ="dss_sys_clk" }, +}; + +static struct omap_hwmod omap54xx_dss_dsi1_c_hwmod = { + .name ="dss_dsi2" , + .class = &omap54xx_dsi1_hwmod_class, + .clkdm_name ="dss_clkdm" , + .main_clk ="dss_dss_clk" , + .prcm = { + .omap4 = { + .clkctrl_offs =OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET , + .flags =HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT , + }, + }, + .opt_clks = dss_dsi1_c_opt_clks, + .opt_clks_cnt =ARRAY_SIZE (dss_dsi1_c_opt_clks), +}; + +/* +* 'hdmi' class +* hdmi controller +*/ + +static struct omap_hwmod_class_sysconfig omap54xx_hdmi_sysc = { + .rev_offs =0x0000 , + .sysc_offs =0x0010 , + .sysc_flags = (SYSC_HAS_RESET_STATUS |SYSC_HAS_SIDLEMODE | +SYSC_HAS_SOFTRESET ), + .idlemodes = (SIDLE_FORCE |SIDLE_NO |SIDLE_SMART | +SIDLE_SMART_WKUP ), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap54xx_hdmi_hwmod_class = { + .name ="hdmi" , + .sysc = &omap54xx_hdmi_sysc, +}; + +static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = { + { .role ="sys_clk" , .clk ="dss_sys_clk" }, +}; + +static struct omap_hwmod omap54xx_dss_hdmi_hwmod = { + .name ="dss_hdmi" , + .class = &omap54xx_hdmi_hwmod_class, + .clkdm_name ="dss_clkdm" , + .main_clk ="dss_48mhz_clk" , + .prcm = { + .omap4 = { + .clkctrl_offs =OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET , + .flags =HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT , + }, + }, + .opt_clks = dss_hdmi_opt_clks, + .opt_clks_cnt =ARRAY_SIZE (dss_hdmi_opt_clks), +}; + +/* +* 'rfbi' class +* remote frame buffer interface +*/ + +static struct omap_hwmod_class_sysconfig omap54xx_rfbi_sysc = { + .rev_offs =0x0000 , + .sysc_offs =0x0010 , + .syss_offs =0x0014 , + .sysc_flags = (SYSC_HAS_AUTOIDLE |SYSC_HAS_SIDLEMODE | +SYSC_HAS_SOFTRESET |SYSS_HAS_RESET_STATUS ), + .idlemodes = (SIDLE_FORCE |SIDLE_NO |SIDLE_SMART ), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_rfbi_hwmod_class = { + .name ="rfbi" , + .sysc = &omap54xx_rfbi_sysc, +}; + +/* dss_rfbi */ +static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { + { .role ="ick" , .clk ="l3_iclk_div" }, +}; + +static struct omap_hwmod omap54xx_dss_rfbi_hwmod = { + .name ="dss_rfbi" , + .class = &omap54xx_rfbi_hwmod_class, + .clkdm_name ="dss_clkdm" , + .prcm = { + .omap4 = { + .clkctrl_offs =OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET , + .flags =HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT , + }, + }, + .opt_clks = dss_rfbi_opt_clks, + .opt_clks_cnt =ARRAY_SIZE (dss_rfbi_opt_clks), +}; + +/* * 'emif' class * external memory interface no1 (wrapper) */
@@ -1893,6 +2122,54 @@ static struct omap_hwmod_ocp_if omap54xx_l4_abe__dmic = { .user = OCP_USER_MPU, }; +/* l3_main_2 -> dss */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_dss_hwmod, + .clk ="l3_iclk_div" , + .user =OCP_USER_MPU |OCP_USER_SDMA , +}; + +/* l3_main_2 -> dss_dispc */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dispc = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_dss_dispc_hwmod, + .clk ="l3_iclk_div" , + .user =OCP_USER_MPU |OCP_USER_SDMA , +}; + +/* l3_main_2 -> dss_dsi1_a */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dsi1_a = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_dss_dsi1_a_hwmod, + .clk ="l3_iclk_div" , + .user =OCP_USER_MPU |OCP_USER_SDMA , +}; + +/* l3_main_2 -> dss_dsi1_c */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dsi1_c = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_dss_dsi1_c_hwmod, + .clk ="l3_iclk_div" , + .user =OCP_USER_MPU |OCP_USER_SDMA , +}; + +/* l3_main_2 -> dss_hdmi */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_hdmi = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_dss_hdmi_hwmod, + .clk ="l3_iclk_div" , + .user =OCP_USER_MPU |OCP_USER_SDMA , +}; + +/* l3_main_2 -> dss_rfbi */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_rfbi = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_dss_rfbi_hwmod, + .clk ="l3_iclk_div" , + .user =OCP_USER_MPU |OCP_USER_SDMA , +}; +/* mpu -> emif1 */ static struct omap_hwmod_ocp_if omap54xx_mpu__emif1 = { .master = &omap54xx_mpu_hwmod,
@@ -2345,6 +2622,12 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = { &omap54xx_l4_wkup__counter_32k, &omap54xx_l4_cfg__dma_system, &omap54xx_l4_abe__dmic, + &omap54xx_l3_main_2__dss, + &omap54xx_l3_main_2__dss_dispc, + &omap54xx_l3_main_2__dss_dsi1_a, + &omap54xx_l3_main_2__dss_dsi1_c, + &omap54xx_l3_main_2__dss_hdmi, + &omap54xx_l3_main_2__dss_rfbi, &omap54xx_mpu__emif1, &omap54xx_mpu__emif2, &omap54xx_l4_wkup__gpio1,
Signature · 1 line
1.8.3.2
PATCH 1/1 ARM: OMAP5: DSS hwmod data
In reply to Tomi ValkeinenQuoted 8 lines · Tomi Valkeinen
Hi,
This patch adds hwmod data for omap5 display subsystem. I have tested this on omap5-uevm with a DSI panel. I cannot test omap5-uevm's hdmi output yet, as the mainline is missing omap5 HDMI driver.
I do see this when booting:
Quoted 7 lines
omap_hwmod:dss_dispc: cannot be enabled for reset (3)
omap_hwmod:dss_dsi1: cannot be enabled for reset (3)
omap_hwmod:dss_dsi2: cannot be enabled for reset (3)
omap_hwmod:dss_hdmi: cannot be enabled for reset (3)
omap_hwmod:dss_rfbi: cannot be enabled for reset (3)But at least DSI works just fine.
Oh, I forgot to say that I tested this on top of the DSS DT branch, and unpublished omap5 and omap5-uevm display patches. So if applied to the current mainline, the hwmods are not used at all (except the reset at boot time, I think).
But if this gets merged for 3.15, it'll make adding omap5 DSS support easier for 3.16 as the HWMOD data is already there.
Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140312/73433334/attachment.sig>
PATCH 1/1 ARM: OMAP5: DSS hwmod data
Hi Tomi,
(resending in the text format)
Where can I get those unpublished omap5 and omap5-uevm display patches to test the video out with this patch?
I'll appreciate your assistance in additional setup (like required uEvm .dts changes and DSI panel connection short guide).
Thanks you in advance,
Dmitry Lifshitz
Quoted 27 lines · Tomi Valkeinen
Quoted 8 lines · Tomi Valkeinen
Hi,
This patch adds hwmod data for omap5 display subsystem. I have tested this on omap5-uevm with a DSI panel. I cannot test omap5-uevm's hdmi output yet, as the mainline is missing omap5 HDMI driver.
I do see this when booting:
Quoted 7 lines
omap_hwmod:dss_dispc: cannot be enabled for reset (3)
omap_hwmod:dss_dsi1: cannot be enabled for reset (3)
omap_hwmod:dss_dsi2: cannot be enabled for reset (3)
omap_hwmod:dss_hdmi: cannot be enabled for reset (3)
omap_hwmod:dss_rfbi: cannot be enabled for reset (3)But at least DSI works just fine.
Oh, I forgot to say that I tested this on top of the DSS DT branch, and unpublished omap5 and omap5-uevm display patches. So if applied to the current mainline, the hwmods are not used at all (except the reset at boot time, I think).
But if this gets merged for 3.15, it'll make adding omap5 DSS support easier for 3.16 as the HWMOD data is already there.
Tomi
PATCH 1/1 ARM: OMAP5: DSS hwmod data
Quoted 8 lines · Dmitry Lifshitz
Hi Tomi,
(resending in the text format)
Where can I get those unpublished omap5 and omap5-uevm display patches to test the video out with this patch?
I'll appreciate your assistance in additional setup (like required uEvm .dts changes and DSI panel connection short guide).
git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux.git
work/dss-dt-pyra
I've since added omap5 hdmi support, so omap5-uevm's hdmi output works on that branch.
Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140317/880b9b13/attachment.sig>
PATCH 1/1 ARM: OMAP5: DSS hwmod data
Hi Tomi,
Thank you for the feedback.
We have OMAP5 based board with no ESD & Level Translator chip. So, I made a quick hack in tpd12s015 driver to skip using un-relevant GPIOs.
I've copied DSS DT structure from uEmv board *.dts. However the HDMI output is not activate yet.
Here is some debug output:
root at cm-debian:~# dmesg | grep -i dss
[ 0.040554] omap_hwmod: dss_dispc: cannot be enabled for reset (3) [ 0.043135] omap_hwmod: dss_dsi1: cannot be enabled for reset (3) [ 0.045725] omap_hwmod: dss_dsi2: cannot be enabled for reset (3) [ 0.048311] omap_hwmod: dss_hdmi: cannot be enabled for reset (3) [ 0.050888] omap_hwmod: dss_rfbi: cannot be enabled for reset (3) [ 0.325392] DSS: set fck to 192000000 [ 0.325400] DSS: dss_runtime_get [ 0.325427] DSS: dss_restore_context [ 0.325445] OMAP DSS rev 6.1 [ 0.325450] DSS: dss_runtime_put [ 0.325456] DSS: dss_save_context [ 0.325461] DSS: context saved [ 0.325707] DSS: dss_restore_context [ 0.325711] DSS: context restored [ 0.325746] omapdss_dispc 58001000.dispc: OMAP DISPC rev 5.1 [ 0.325838] DSS: dss_save_context [ 0.325843] DSS: context saved
I do not use uEvm BSP u-Boot. I'm forking from this source:git://git.denx.de/u-boot-ti.git
Perhaps I'm missing some clocks initialization?
What are the correct bootargs for activating HDMI video output?
Thank you in advance for the assistance,
Dmitry
Quoted 18 lines · Tomi Valkeinen
Quoted 8 lines · Dmitry Lifshitz
Hi Tomi,
(resending in the text format)
Where can I get those unpublished omap5 and omap5-uevm display patches to test the video out with this patch?
I'll appreciate your assistance in additional setup (like required uEvm .dts changes and DSI panel connection short guide).
git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux.git
work/dss-dt-pyraI've since added omap5 hdmi support, so omap5-uevm's hdmi output works on that branch.
Tomi
PATCH 1/1 ARM: OMAP5: DSS hwmod data
Quoted 7 lines · Dmitry Lifshitz
Hi Tomi,
Thank you for the feedback.
We have OMAP5 based board with no ESD & Level Translator chip. So, I made a quick hack in tpd12s015 driver to skip using un-relevant GPIOs.
If you don't have tpd12s015 on your board, don't modify it. Remove it from your board's dts file totally.
Quoted 25 lines
I've copied DSS DT structure from uEmv board *.dts. However the HDMI output is not activate yet.
Here is some debug output:
root at cm-debian:~# dmesg | grep -i dss
[ 0.040554] omap_hwmod: dss_dispc: cannot be enabled for reset (3) [ 0.043135] omap_hwmod: dss_dsi1: cannot be enabled for reset (3) [ 0.045725] omap_hwmod: dss_dsi2: cannot be enabled for reset (3) [ 0.048311] omap_hwmod: dss_hdmi: cannot be enabled for reset (3) [ 0.050888] omap_hwmod: dss_rfbi: cannot be enabled for reset (3) [ 0.325392] DSS: set fck to 192000000 [ 0.325400] DSS: dss_runtime_get [ 0.325427] DSS: dss_restore_context [ 0.325445] OMAP DSS rev 6.1 [ 0.325450] DSS: dss_runtime_put [ 0.325456] DSS: dss_save_context [ 0.325461] DSS: context saved [ 0.325707] DSS: dss_restore_context [ 0.325711] DSS: context restored [ 0.325746] omapdss_dispc 58001000.dispc: OMAP DISPC rev 5.1 [ 0.325838] DSS: dss_save_context [ 0.325843] DSS: context saved
Quoted 5 lines
I do not use uEvm BSP u-Boot. I'm forking from this source:
git://git.denx.de/u-boot-ti.gitPerhaps I'm missing some clocks initialization?
What are the correct bootargs for activating HDMI video output?
HDMI is the only output on the uevm, and if your board is similar, no boot args are needed. But, of course, you need omapfb or omapdrm to manage the display.
Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140317/dcbd20db/attachment.sig>
PATCH 1/1 ARM: OMAP5: DSS hwmod data
Hi Tomi,
Unfortunately, I have a lack of experience with DT DSS stuff.
How should I define the endpoints and the connector in my case? Please, could you provide some reference.
Regarding omapfb, is it sufficient to turn it on in the Kernel config?
Thanks,
Dmitry
Quoted 48 lines · Tomi Valkeinen
Quoted 7 lines · Dmitry Lifshitz
Hi Tomi,
Thank you for the feedback.
We have OMAP5 based board with no ESD & Level Translator chip. So, I made a quick hack in tpd12s015 driver to skip using un-relevant GPIOs.
If you don't have tpd12s015 on your board, don't modify it. Remove it from your board's dts file totally.
Quoted 25 lines
I've copied DSS DT structure from uEmv board *.dts. However the HDMI output is not activate yet.
Here is some debug output:
root at cm-debian:~# dmesg | grep -i dss
[ 0.040554] omap_hwmod: dss_dispc: cannot be enabled for reset (3) [ 0.043135] omap_hwmod: dss_dsi1: cannot be enabled for reset (3) [ 0.045725] omap_hwmod: dss_dsi2: cannot be enabled for reset (3) [ 0.048311] omap_hwmod: dss_hdmi: cannot be enabled for reset (3) [ 0.050888] omap_hwmod: dss_rfbi: cannot be enabled for reset (3) [ 0.325392] DSS: set fck to 192000000 [ 0.325400] DSS: dss_runtime_get [ 0.325427] DSS: dss_restore_context [ 0.325445] OMAP DSS rev 6.1 [ 0.325450] DSS: dss_runtime_put [ 0.325456] DSS: dss_save_context [ 0.325461] DSS: context saved [ 0.325707] DSS: dss_restore_context [ 0.325711] DSS: context restored [ 0.325746] omapdss_dispc 58001000.dispc: OMAP DISPC rev 5.1 [ 0.325838] DSS: dss_save_context [ 0.325843] DSS: context savedQuoted 5 lines
I do not use uEvm BSP u-Boot. I'm forking from this source:
git://git.denx.de/u-boot-ti.gitPerhaps I'm missing some clocks initialization?
What are the correct bootargs for activating HDMI video output?HDMI is the only output on the uevm, and if your board is similar, no boot args are needed. But, of course, you need omapfb or omapdrm to manage the display.
Tomi
PATCH 1/1 ARM: OMAP5: DSS hwmod data
Quoted 6 lines · Dmitry Lifshitz
Hi Tomi,
Unfortunately, I have a lack of experience with DT DSS stuff.
How should I define the endpoints and the connector in my case? Please, could you provide some reference.
See Documentation/devicetree/bindings/media/video-interfaces.txt for a description of the ports and endpoints.
If your board is similar to uevm except you don't have the tpd12s015, then you just need to remove the tpd12s015 from the .dts file, and connect the OMAP's HDMI output directly to the connector.
Quoted 1 line
Regarding omapfb, is it sufficient to turn it on in the Kernel config?
Yes.
Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140318/1e2da321/attachment.sig>
PATCH 1/1 ARM: OMAP5: DSS hwmod data
Hi Tomi,
Thank you a lot for your assistance.
Here are my relevant DT nodes:
/ {
aliases {
display0 = &hdmi0;
};
hdmi0: connector at 0 {
compatible = "hdmi-connector";
label = "hdmi";
type = "b";
hdmi_connector_in: endpoint {
remote-endpoint = <&hdmi_out>;
};
};
};&dss {
status = "ok";
};&hdmi {
status = "ok";
vdda-supply = <&ldo4_reg>;
pinctrl-names = "default";
pinctrl-0 = <&dss_hdmi_pins>;
hdmi_out: endpoint {
remote-endpoint = <&hdmi_connector_in>;
};
};I have the following kernel crash (caused by missing .detect callback):
[ 10.885320] Unable to handle kernel NULL pointer dereference at virtual address 00000000 [ 10.893825] pgd = ed787240 [ 10.896670] [00000000] *pgd=00000000 [ 10.900427] Internal error: Oops: 80000205 [#1] SMP ARM [ 10.905883] Modules linked in: phy_omap_usb2 omapdrm(+) drm_kms_helper connector_hdmi omap4_keypad matrix_keymap omapdss fb_sys_fops omap_ocp2scp rtc_palmas spi_omap2_mcspi [ 10.922032] CPU: 1 PID: 333 Comm: modprobe Tainted: G W 3.14.0-rc4-cm-t54-test-suit+ #111 [ 10.931486] task: ece1e040 ti: ecea2000 task.ti: ecea2000 [ 10.937122] PC is at 0x0 [ 10.939771] LR is at hdmic_detect+0x14/0x18 [connector_hdmi] [ 10.945681] pc : [<00000000>] lr : [<bf1531c4>] psr: a0000013 [ 10.945681] sp : ecea3d50 ip : bf173158 fp : 00000000 [ 10.957664] r10: 00000800 r9 : 00000800 r8 : 00000004 [ 10.963118] r7 : bf17317c r6 : ecdf0400 r5 : ed6d4000 r4 : ed6d402c [ 10.969932] r3 : 00000000 r2 : bf15c7cc r1 : bf0437d0 r0 : bf059470 [ 10.976754] Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user [ 10.984207] Control: 30c5387d Table: ad787240 DAC: 55555555 [ 10.990209] Process modprobe (pid: 333, stack limit = 0xecea2248) [ 10.996574] Stack: (0xecea3d50 to 0xecea4000) [ 11.001123] 3d40: bf1531b0 bf16a134 bf16a118 bf158abc [ 11.009664] 3d60: 00000004 c0b5ae60 00000000 00000001 ece4ae00 00000000 00000800 00000800 [ 11.018203] 3d80: bf17a000 00000020 00000000 bf15b7b8 00000020 ece4ae00 ece4ae00 ecdf0400 [ 11.026751] 3da0: ed69b940 bf175978 00000000 bf16bfa4 0000081f ecdf0400 ed69b940 00000000 [ 11.035288] 3dc0: 00000000 bf167bbc 00000000 00000000 00000000 ecdf0400 00000000 00000000 [ 11.043828] 3de0: 00000000 c03afef8 c0a876a0 bf17586c ecdf0400 c03b179c c08dffd4 c01d641c [ 11.052365] 3e00: c03b1818 c0978eac c0a876b0 bf175978 c0a876b0 c03cc6c4 c03cc6ac c0b5af2c [ 11.060902] 3e20: bf175978 c03ca8cc c0a876b0 bf175978 c0a876e4 00000000 c0020f04 c03cab64 [ 11.069442] 3e40: 00000000 c0a876b0 bf175978 c03cac08 bf175978 00000000 c03cab7c c03c92dc [ 11.077983] 3e60: edcd45dc eddcb234 bf175978 ece13480 c0ab8d48 c03ca1b8 bf1740d4 c0020f04 [ 11.086524] 3e80: bf175978 bf175978 00000000 ecea2000 00000000 c03cb264 c03cbd54 c0a7e510 [ 11.095067] 3ea0: ecea2000 c0008788 000000d0 f02aefff 00000000 c0158bc0 c0003020 f02af000 [ 11.103608] 3ec0: 00000000 bf175b24 c0a93b14 00000000 00000001 bf175b24 00000000 00000000 [ 11.112156] 3ee0: 00000001 c00dc9ec c00dcdbc fffffffb 00000000 c072932c c0a92348 00000000 [ 11.120702] 3f00: c0a92348 00000000 bf175b24 c0072830 00000000 bd94362e 00000000 bf175b24 [ 11.129244] 3f20: 00400100 ecea2000 00000080 c0020f04 ecea2000 00000000 00000000 c07137b4 [ 11.137785] 3f40: 0001dfea b6d5b000 b6fa7114 0001dfea b6d5b000 c00bad0c f0290000 0001dfea [ 11.146323] 3f60: f02a29bc f02a2821 f02ab674 0000ecf0 00010510 00000000 00000000 00000000 [ 11.154860] 3f80: 00000027 00000028 0000001c 00000020 00000012 00000000 b87d23f8 00060000 [ 11.163409] 3fa0: b87d2280 c0020d80 b87d23f8 00060000 b6d5b000 0001dfea b6fa7114 b6d5b000 [ 11.171954] 3fc0: b87d23f8 00060000 b87d2280 00000080 b87d4c60 0001dfea b6fa7114 00000000 [ 11.180494] 3fe0: 00000000 bee169cc b6f9e190 b6f02e04 60000010 b6d5b000 00000000 00000000 [ 11.189071] [<bf1531c4>] (hdmic_detect [connector_hdmi]) from [<bf16a134>] (omap_connector_detect+0x1c/0x58 [omapdrm]) [ 11.200274] [<bf16a134>] (omap_connector_detect [omapdrm]) from [<bf158abc>] (drm_helper_probe_single_connector_modes+0x2b0/0x33c [drm_kms_helper]) [ 11.214089] [<bf158abc>] (drm_helper_probe_single_connector_modes [drm_kms_helper]) from [<bf15b7b8>] (drm_fb_helper_initial_config+0x5c/0xac [drm_kms_helper]) [ 11.229011] [<bf15b7b8>] (drm_fb_helper_initial_config [drm_kms_helper]) from [<bf16bfa4>] (omap_fbdev_init+0x90/0xc4 [omapdrm]) [ 11.241126] [<bf16bfa4>] (omap_fbdev_init [omapdrm]) from [<bf167bbc>] (dev_load+0xcc/0x148 [omapdrm]) [ 11.250861] [<bf167bbc>] (dev_load [omapdrm]) from [<c03afef8>] (drm_dev_register+0x78/0x138) [ 11.259776] [<c03afef8>] (drm_dev_register) from [<c03b179c>] (drm_get_platform_dev+0x50/0xa4) [ 11.268785] [<c03b179c>] (drm_get_platform_dev) from [<c03cc6c4>] (platform_drv_probe+0x18/0x48) [ 11.277968] [<c03cc6c4>] (platform_drv_probe) from [<c03ca8cc>] (really_probe+0x80/0x208) [ 11.286516] [<c03ca8cc>] (really_probe) from [<c03cab64>] (driver_probe_device+0x30/0x48) [ 11.295071] [<c03cab64>] (driver_probe_device) from [<c03cac08>] (__driver_attach+0x8c/0x90) [ 11.303881] [<c03cac08>] (__driver_attach) from [<c03c92dc>] (bus_for_each_dev+0x54/0x88) [ 11.312422] [<c03c92dc>] (bus_for_each_dev) from [<c03ca1b8>] (bus_add_driver+0xe4/0x1d8) [ 11.320957] [<c03ca1b8>] (bus_add_driver) from [<c03cb264>] (driver_register+0x78/0xf4) [ 11.329323] [<c03cb264>] (driver_register) from [<c0008788>] (do_one_initcall+0x44/0x174) [ 11.337876] [<c0008788>] (do_one_initcall) from [<c07137b4>] (do_init_module+0x48/0x17c) [ 11.346331] [<c07137b4>] (do_init_module) from [<c00bad0c>] (SyS_init_module+0x64/0x6c) [ 11.354690] [<c00bad0c>] (SyS_init_module) from [<c0020d80>]
(ret_fast_syscall+0x0/0x30)
While using FBDEV I have the following issue:
root at cm-debian:~# modprobe omapfb
[ 27.524419] ------------[ cut here ]------------ [ 27.529256] WARNING: CPU: 1 PID: 2087 at /home/lifshitz/workroot/OMAP5-eewiki/omap5-kernel/mm/page_alloc.c:2492 __alloc_pages_nodemask+0x268/0x83c() [ 27.543164] Modules linked in: omapfb(+) cfbcopyarea cfbimgblt cfbfillrect bnep rfcomm bluetooth 6lowpan_iphc phy_omap_usb2 connector_hdmi omapdss omap4_keypad matrix_keymap omap_ocp2scp rtc_palmas spi_omap2_mcspi [ 27.563113] CPU: 1 PID: 2087 Comm: modprobe Tainted: G W 3.14.0-rc4-cm-t54-test-suit+ #108 [ 27.572677] [<c00280ac>] (unwind_backtrace) from [<c0024eb0>] (show_stack+0x10/0x14) [ 27.580786] [<c0024eb0>] (show_stack) from [<c06fc434>] (dump_stack+0x70/0x88) [ 27.588341] [<c06fc434>] (dump_stack) from [<c004d8e8>] (warn_slowpath_common+0x70/0x88) [ 27.596815] [<c004d8e8>] (warn_slowpath_common) from [<c004d91c>] (warn_slowpath_null+0x1c/0x24) [ 27.606004] [<c004d91c>] (warn_slowpath_null) from [<c01135ec>] (__alloc_pages_nodemask+0x268/0x83c) [ 27.615562] [<c01135ec>] (__alloc_pages_nodemask) from [<c002cd78>] (__dma_alloc_buffer.isra.16+0x2c/0xdc) [ 27.625661] [<c002cd78>] (__dma_alloc_buffer.isra.16) from [<c002ce40>] (__alloc_remap_buffer.isra.19+0x18/0xcc) [ 27.636300] [<c002ce40>] (__alloc_remap_buffer.isra.19) from [<c002d248>] (__dma_alloc+0x110/0x138) [ 27.645757] [<c002d248>] (__dma_alloc) from [<c002d3fc>] (arm_dma_alloc+0xb0/0xd8) [ 27.653686] [<c002d3fc>] (arm_dma_alloc) from [<bf1b1f74>] (omapfb_alloc_fbmem.isra.24+0xc8/0x158 [omapfb]) [ 27.663911] [<bf1b1f74>] (omapfb_alloc_fbmem.isra.24 [omapfb]) from [<bf1b7078>] (omapfb_alloc_fbmem_display.isra.25+0xec/0xfc [omapfb]) [ 27.676759] [<bf1b7078>] (omapfb_alloc_fbmem_display.isra.25 [omapfb]) from [<bf1b21fc>] (omapfb_allocate_all_fbs+0xf4/0x174 [omapfb]) [ 27.689419] [<bf1b21fc>] (omapfb_allocate_all_fbs [omapfb]) from [<bf1b30f8>] (omapfb_create_framebuffers+0x1fc/0x524 [omapfb]) [ 27.701432] [<bf1b30f8>] (omapfb_create_framebuffers [omapfb]) from [<bf1b3fdc>] (omapfb_probe+0x28c/0x41c [omapfb]) [ 27.712446] [<bf1b3fdc>] (omapfb_probe [omapfb]) from [<c03ab844>] (platform_drv_probe+0x18/0x48) [ 27.721728] [<c03ab844>] (platform_drv_probe) from [<c03a9a4c>] (really_probe+0x80/0x208) [ 27.730284] [<c03a9a4c>] (really_probe) from [<c03a9ce4>] (driver_probe_device+0x30/0x48) [ 27.738834] [<c03a9ce4>] (driver_probe_device) from [<c03a9d88>] (__driver_attach+0x8c/0x90) [ 27.747661] [<c03a9d88>] (__driver_attach) from [<c03a845c>] (bus_for_each_dev+0x54/0x88) [ 27.756220] [<c03a845c>] (bus_for_each_dev) from [<c03a9338>] (bus_add_driver+0xe4/0x1d8) [ 27.764778] [<c03a9338>] (bus_add_driver) from [<c03aa3e4>] (driver_register+0x78/0xf4) [ 27.773148] [<c03aa3e4>] (driver_register) from [<c0008788>] (do_one_initcall+0x44/0x174) [ 27.781703] [<c0008788>] (do_one_initcall) from [<c06f2934>] (do_init_module+0x48/0x17c) [ 27.790172] [<c06f2934>] (do_init_module) from [<c00bad0c>] (SyS_init_module+0x64/0x6c) [ 27.798546] [<c00bad0c>] (SyS_init_module) from [<c0020d80>] (ret_fast_syscall+0x0/0x30) [ 27.807015] ---[ end trace 842d286115ab739d ]--- [ 27.811849] omapfb omapfb: failed to allocate framebuffer [ 27.817490] omapfb omapfb: failed to allocate fbmem [ 27.822746] omapfb omapfb: failed to setup omapfb [ 27.827710] omapfb: probe of omapfb failed with error -12
Regards,
Dmitry
Quoted 20 lines · Tomi Valkeinen
Quoted 6 lines · Dmitry Lifshitz
Hi Tomi,
Unfortunately, I have a lack of experience with DT DSS stuff.
How should I define the endpoints and the connector in my case? Please, could you provide some reference.
See
Documentation/devicetree/bindings/media/video-interfaces.txtfor a description of the ports and endpoints.If your board is similar to uevm except you don't have the tpd12s015, then you just need to remove the tpd12s015 from the .dts file, and connect the OMAP's HDMI output directly to the connector.
Quoted 1 line
Regarding omapfb, is it sufficient to turn it on in the Kernel config?
Yes.
Tomi
PATCH 1/1 ARM: OMAP5: DSS hwmod data
Quoted 27 lines · Dmitry Lifshitz
Hi Tomi,
Thank you a lot for your assistance.
Here are my relevant DT nodes:
/ { aliases { display0 = &hdmi0; }; hdmi0: connector at 0 { compatible = "hdmi-connector"; label = "hdmi"; type = "b"; hdmi_connector_in: endpoint { remote-endpoint = <&hdmi_out>; }; }; };&dss { status = "ok"; };
Quoted 11 lines
&hdmi {
status = "ok";
vdda-supply = <&ldo4_reg>;
pinctrl-names = "default";
pinctrl-0 = <&dss_hdmi_pins>;
hdmi_out: endpoint {
remote-endpoint = <&hdmi_connector_in>;
};
};The above looks fine.
Quoted 1 line
I have the following kernel crash (caused by missing .detect callback):
Yes, it seems the hdmi driver is missing detect, as there's no support in there for the detection at the moment. You can add the function to omap5.c, and return true always.
How does the HPD work on your board? On uevm, the ESD/Level shifter chip handles HPD, which is the only supported way at the moment.
Quoted 60 lines
While using FBDEV I have the following issue:
root at cm-debian:~# modprobe omapfb
[ 27.524419] ------------[ cut here ]------------ [ 27.529256] WARNING: CPU: 1 PID: 2087 at /home/lifshitz/workroot/OMAP5-eewiki/omap5-kernel/mm/page_alloc.c:2492 __alloc_pages_nodemask+0x268/0x83c() [ 27.543164] Modules linked in: omapfb(+) cfbcopyarea cfbimgblt cfbfillrect bnep rfcomm bluetooth 6lowpan_iphc phy_omap_usb2 connector_hdmi omapdss omap4_keypad matrix_keymap omap_ocp2scp rtc_palmas spi_omap2_mcspi [ 27.563113] CPU: 1 PID: 2087 Comm: modprobe Tainted: G W 3.14.0-rc4-cm-t54-test-suit+ #108 [ 27.572677] [<c00280ac>] (unwind_backtrace) from [<c0024eb0>] (show_stack+0x10/0x14) [ 27.580786] [<c0024eb0>] (show_stack) from [<c06fc434>] (dump_stack+0x70/0x88) [ 27.588341] [<c06fc434>] (dump_stack) from [<c004d8e8>] (warn_slowpath_common+0x70/0x88) [ 27.596815] [<c004d8e8>] (warn_slowpath_common) from [<c004d91c>] (warn_slowpath_null+0x1c/0x24) [ 27.606004] [<c004d91c>] (warn_slowpath_null) from [<c01135ec>] (__alloc_pages_nodemask+0x268/0x83c) [ 27.615562] [<c01135ec>] (__alloc_pages_nodemask) from [<c002cd78>] (__dma_alloc_buffer.isra.16+0x2c/0xdc) [ 27.625661] [<c002cd78>] (__dma_alloc_buffer.isra.16) from [<c002ce40>] (__alloc_remap_buffer.isra.19+0x18/0xcc) [ 27.636300] [<c002ce40>] (__alloc_remap_buffer.isra.19) from [<c002d248>] (__dma_alloc+0x110/0x138) [ 27.645757] [<c002d248>] (__dma_alloc) from [<c002d3fc>] (arm_dma_alloc+0xb0/0xd8) [ 27.653686] [<c002d3fc>] (arm_dma_alloc) from [<bf1b1f74>] (omapfb_alloc_fbmem.isra.24+0xc8/0x158 [omapfb]) [ 27.663911] [<bf1b1f74>] (omapfb_alloc_fbmem.isra.24 [omapfb]) from [<bf1b7078>] (omapfb_alloc_fbmem_display.isra.25+0xec/0xfc [omapfb]) [ 27.676759] [<bf1b7078>] (omapfb_alloc_fbmem_display.isra.25 [omapfb]) from [<bf1b21fc>] (omapfb_allocate_all_fbs+0xf4/0x174 [omapfb]) [ 27.689419] [<bf1b21fc>] (omapfb_allocate_all_fbs [omapfb]) from [<bf1b30f8>] (omapfb_create_framebuffers+0x1fc/0x524 [omapfb]) [ 27.701432] [<bf1b30f8>] (omapfb_create_framebuffers [omapfb]) from [<bf1b3fdc>] (omapfb_probe+0x28c/0x41c [omapfb]) [ 27.712446] [<bf1b3fdc>] (omapfb_probe [omapfb]) from [<c03ab844>] (platform_drv_probe+0x18/0x48) [ 27.721728] [<c03ab844>] (platform_drv_probe) from [<c03a9a4c>] (really_probe+0x80/0x208) [ 27.730284] [<c03a9a4c>] (really_probe) from [<c03a9ce4>] (driver_probe_device+0x30/0x48) [ 27.738834] [<c03a9ce4>] (driver_probe_device) from [<c03a9d88>] (__driver_attach+0x8c/0x90) [ 27.747661] [<c03a9d88>] (__driver_attach) from [<c03a845c>] (bus_for_each_dev+0x54/0x88) [ 27.756220] [<c03a845c>] (bus_for_each_dev) from [<c03a9338>] (bus_add_driver+0xe4/0x1d8) [ 27.764778] [<c03a9338>] (bus_add_driver) from [<c03aa3e4>] (driver_register+0x78/0xf4) [ 27.773148] [<c03aa3e4>] (driver_register) from [<c0008788>] (do_one_initcall+0x44/0x174) [ 27.781703] [<c0008788>] (do_one_initcall) from [<c06f2934>] (do_init_module+0x48/0x17c) [ 27.790172] [<c06f2934>] (do_init_module) from [<c00bad0c>]
Quoted 8 lines
(
SyS_init_module+0x64/0x6c)[ 27.798546] [<c00bad0c>] (SyS_init_module) from [<c0020d80>] (ret_fast_syscall+0x0/0x30) [ 27.807015] ---[ end trace 842d286115ab739d ]--- [ 27.811849] omapfb omapfb: failed to allocate framebuffer [ 27.817490] omapfb omapfb: failed to allocate fbmem [ 27.822746] omapfb omapfb: failed to setup omapfb [ 27.827710] omapfb: probe of omapfb failed with error -12
Hmm, do you have CMA enabled? Maybe something like:
CONFIG_DMA_CMA=yCONFIG_CMA_SIZE_MBYTES=32CONFIG_CMA_SIZE_SEL_MBYTES=y
And if you have omap5-uevm, you could first try that one to see if you get the branch working.
Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140318/f7e2f86c/attachment.sig>
PATCH 1/1 ARM: OMAP5: DSS hwmod data
Hi Tomi,
I've activated HDMI output with omapfb. Thank you very much !
Some minor issue are observed:
* the colors are inverted.
* DRM seems to be loaded with no failures, however there is no output.
HPD connector pin is connected to HDMI_HPD/GPIO7_193.
In addition we have DVI output (uses TFP410 encoder to convert DPI to DVI). TFP410 is not connected to I2C and its PD always on.
I tried to turn DVI support using omap4-panda-common.dtsi as the reference (with OMAP5 specific pinmux, of course), however it fails. Does it supposed to work?
Please, could you share the .config you are using with uEvm?
Thank you in advance,
Dmitry
Quoted 129 lines · Tomi Valkeinen
Quoted 27 lines · Dmitry Lifshitz
Hi Tomi,
Thank you a lot for your assistance.
Here are my relevant DT nodes:
/ { aliases { display0 = &hdmi0; }; hdmi0: connector at 0 { compatible = "hdmi-connector"; label = "hdmi"; type = "b"; hdmi_connector_in: endpoint { remote-endpoint = <&hdmi_out>; }; }; };&dss { status = "ok"; };Quoted 11 lines
&hdmi { status = "ok"; vdda-supply = <&ldo4_reg>; pinctrl-names = "default"; pinctrl-0 = <&dss_hdmi_pins>; hdmi_out: endpoint { remote-endpoint = <&hdmi_connector_in>; }; };The above looks fine.
Quoted 1 line
I have the following kernel crash (caused by missing .detect callback):
Yes, it seems the hdmi driver is missing detect, as there's no support in there for the detection at the moment. You can add the function to
omap5.c, and return true always.How does the HPD work on your board? On uevm, the ESD/Level shifter chip handles HPD, which is the only supported way at the moment.
Quoted 60 lines
While using FBDEV I have the following issue:
root at cm-debian:~# modprobe omapfb
[ 27.524419] ------------[ cut here ]------------ [ 27.529256] WARNING: CPU: 1 PID: 2087 at /home/lifshitz/workroot/OMAP5-eewiki/omap5-kernel/mm/page_alloc.c:2492 __alloc_pages_nodemask+0x268/0x83c() [ 27.543164] Modules linked in: omapfb(+) cfbcopyarea cfbimgblt cfbfillrect bnep rfcomm bluetooth 6lowpan_iphc phy_omap_usb2 connector_hdmi omapdss omap4_keypad matrix_keymap omap_ocp2scp rtc_palmas spi_omap2_mcspi [ 27.563113] CPU: 1 PID: 2087 Comm: modprobe Tainted: G W 3.14.0-rc4-cm-t54-test-suit+ #108 [ 27.572677] [<c00280ac>] (unwind_backtrace) from [<c0024eb0>] (show_stack+0x10/0x14) [ 27.580786] [<c0024eb0>] (show_stack) from [<c06fc434>] (dump_stack+0x70/0x88) [ 27.588341] [<c06fc434>] (dump_stack) from [<c004d8e8>] (warn_slowpath_common+0x70/0x88) [ 27.596815] [<c004d8e8>] (warn_slowpath_common) from [<c004d91c>] (warn_slowpath_null+0x1c/0x24) [ 27.606004] [<c004d91c>] (warn_slowpath_null) from [<c01135ec>] (__alloc_pages_nodemask+0x268/0x83c) [ 27.615562] [<c01135ec>] (__alloc_pages_nodemask) from [<c002cd78>] (__dma_alloc_buffer.isra.16+0x2c/0xdc) [ 27.625661] [<c002cd78>] (__dma_alloc_buffer.isra.16) from [<c002ce40>] (__alloc_remap_buffer.isra.19+0x18/0xcc) [ 27.636300] [<c002ce40>] (__alloc_remap_buffer.isra.19) from [<c002d248>] (__dma_alloc+0x110/0x138) [ 27.645757] [<c002d248>] (__dma_alloc) from [<c002d3fc>] (arm_dma_alloc+0xb0/0xd8) [ 27.653686] [<c002d3fc>] (arm_dma_alloc) from [<bf1b1f74>] (omapfb_alloc_fbmem.isra.24+0xc8/0x158 [omapfb]) [ 27.663911] [<bf1b1f74>] (omapfb_alloc_fbmem.isra.24 [omapfb]) from [<bf1b7078>] (omapfb_alloc_fbmem_display.isra.25+0xec/0xfc [omapfb]) [ 27.676759] [<bf1b7078>] (omapfb_alloc_fbmem_display.isra.25 [omapfb]) from [<bf1b21fc>] (omapfb_allocate_all_fbs+0xf4/0x174 [omapfb]) [ 27.689419] [<bf1b21fc>] (omapfb_allocate_all_fbs [omapfb]) from [<bf1b30f8>] (omapfb_create_framebuffers+0x1fc/0x524 [omapfb]) [ 27.701432] [<bf1b30f8>] (omapfb_create_framebuffers [omapfb]) from [<bf1b3fdc>] (omapfb_probe+0x28c/0x41c [omapfb]) [ 27.712446] [<bf1b3fdc>] (omapfb_probe [omapfb]) from [<c03ab844>] (platform_drv_probe+0x18/0x48) [ 27.721728] [<c03ab844>] (platform_drv_probe) from [<c03a9a4c>] (really_probe+0x80/0x208) [ 27.730284] [<c03a9a4c>] (really_probe) from [<c03a9ce4>] (driver_probe_device+0x30/0x48) [ 27.738834] [<c03a9ce4>] (driver_probe_device) from [<c03a9d88>] (__driver_attach+0x8c/0x90) [ 27.747661] [<c03a9d88>] (__driver_attach) from [<c03a845c>] (bus_for_each_dev+0x54/0x88) [ 27.756220] [<c03a845c>] (bus_for_each_dev) from [<c03a9338>] (bus_add_driver+0xe4/0x1d8) [ 27.764778] [<c03a9338>] (bus_add_driver) from [<c03aa3e4>] (driver_register+0x78/0xf4) [ 27.773148] [<c03aa3e4>] (driver_register) from [<c0008788>] (do_one_initcall+0x44/0x174) [ 27.781703] [<c0008788>] (do_one_initcall) from [<c06f2934>] (do_init_module+0x48/0x17c) [ 27.790172] [<c06f2934>] (do_init_module) from [<c00bad0c>]Quoted 8 lines
(
SyS_init_module+0x64/0x6c)[ 27.798546] [<c00bad0c>] (SyS_init_module) from [<c0020d80>] (ret_fast_syscall+0x0/0x30) [ 27.807015] ---[ end trace 842d286115ab739d ]--- [ 27.811849] omapfb omapfb: failed to allocate framebuffer [ 27.817490] omapfb omapfb: failed to allocate fbmem [ 27.822746] omapfb omapfb: failed to setup omapfb [ 27.827710] omapfb: probe of omapfb failed with error -12Hmm, do you have CMA enabled? Maybe something like:
CONFIG_DMA_CMA=yCONFIG_CMA_SIZE_MBYTES=32CONFIG_CMA_SIZE_SEL_MBYTES=yAnd if you have omap5-uevm, you could first try that one to see if you get the branch working.
Tomi
Paul Walmsley
maintainerPATCH 1/1 ARM: OMAP5: DSS hwmod data
In reply to Tomi ValkeinenHi,
Quoted 6 lines · Tomi Valkeinen
This patch adds hwmod data for omap5 display subsystem. I have tested this on omap5-uevm with a DSI panel. I cannot test omap5-uevm's hdmi output yet, as the mainline is missing omap5 HDMI driver.
I do see this when booting:
Quoted 7 lines
omap_hwmod:dss_dispc: cannot be enabled for reset (3)
omap_hwmod:dss_dsi1: cannot be enabled for reset (3)
omap_hwmod:dss_dsi2: cannot be enabled for reset (3)
omap_hwmod:dss_hdmi: cannot be enabled for reset (3)
omap_hwmod:dss_rfbi: cannot be enabled for reset (3)But at least DSI works just fine.
Am looking at this for v3.16. But I think someone needs to take a look at those warnings and figure out why they are happening.
Is the soc_ops.wait_target_ready() call failing in omap_hwmod.c:_enable() ?
- Paul
PATCH 1/1 ARM: OMAP5: DSS hwmod data
Hi Paul,
Quoted 16 lines · Paul Walmsley
Hi,
Quoted 12 lines · Tomi Valkeinen
This patch adds hwmod data for omap5 display subsystem. I have tested this on omap5-uevm with a DSI panel. I cannot test omap5-uevm's hdmi output yet, as the mainline is missing omap5 HDMI driver.
I do see this when booting:
omap_hwmod:dss_dispc: cannot be enabled for reset (3)
omap_hwmod:dss_dsi1: cannot be enabled for reset (3)
omap_hwmod:dss_dsi2: cannot be enabled for reset (3)
omap_hwmod:dss_hdmi: cannot be enabled for reset (3)
omap_hwmod:dss_rfbi: cannot be enabled for reset (3)
Quoted 4 lines
Quoted 1 line
But at least DSI works just fine.
Am looking at this for v3.16. But I think someone needs to take a look at those warnings and figure out why they are happening.
We associate DSS clock domain's MODULEMODE bits only with the dss_core hwmod. The rest of the dss hwmods don't touch MODULEMODE.
Therefore, these hwmods cannot be enabled independently, and reset.
We don't face this issue in the omapdss driver since the platform devices corresponding to these hwmods have their parent as the platform device corresponding to 'dss_core'. This parent child-relation ensures that 'dss_core' is enabled when the a child calls a pm_runtime_get function.
The problem is that we have multiple hwmods which use the same MODULEMODE bit. There is no use-counting done when it comes to enabling/disabling modulemode. If there was such a thing, we could have provided MODULEMODE flags even for the children hwmods.
Quoted 3 lines
Is the
soc_ops.wait_target_ready()call failing in omap_hwmod.c:_enable() ?
Yes, that's the one that fails.
We have the same DSS in OMAP4, but we don't see the issue there. That's because we have modeled the MODULEMODE bits as a fake interface clock. That lets us enable hwmods independently, but it messes up DSS PM as it breaks some rules related to the sequence in which the opt-clocks and MODULEMODE bits need to be disabled.
We would want to change OMAP4 to work the way as above too, with the cost of having these prints above.
Archit
Paul Walmsley
maintainerPATCH 1/1 ARM: OMAP5: DSS hwmod data
Hi Archit,
Quoted 36 lines · Archit Taneja
Hi Paul,
Quoted 18 lines · Paul Walmsley
Hi,
Quoted 14 lines · Tomi Valkeinen
This patch adds hwmod data for omap5 display subsystem. I have tested this on
omap5-uevm with a DSI panel. I cannot test omap5-uevm's hdmi output yet, as the
mainline is missing omap5 HDMI driver.I do see this when booting:
omap_hwmod:dss_dispc: cannot be enabled for reset (3)
omap_hwmod:dss_dsi1: cannot be enabled for reset (3)
omap_hwmod:dss_dsi2: cannot be enabled for reset (3)
omap_hwmod:dss_hdmi: cannot be enabled for reset (3)
omap_hwmod:dss_rfbi: cannot be enabled for reset (3)Quoted 4 lines
Quoted 1 line
But at least DSI works just fine.
Am looking at this for v3.16. But I think someone needs to take a look at those warnings and figure out why they are happening.
We associate DSS clock domain's MODULEMODE bits only with the
dss_corehwmod. The rest of the dss hwmods don't touch MODULEMODE.Therefore, these hwmods cannot be enabled independently, and reset.
We don't face this issue in the omapdss driver since the platform devices corresponding to these hwmods have their parent as the platform device corresponding to '
dss_core'. This parent child-relation ensures that 'dss_core' is enabled when the a child calls apm_runtime_getfunction.
Quoted 4 lines
The problem is that we have multiple hwmods which use the same MODULEMODE bit. There is no use-counting done when it comes to enabling/disabling modulemode. If there was such a thing, we could have provided MODULEMODE flags even for the children hwmods.
Thanks for the summary. This is indeed a long-overdue item for the hwmod core code. Can you please patch the hwmod core code to add this? I'd suggest making the use-counting functionality conditional on a hwmod flag that you can set for all of the DSS hwmods. (Ideally, the core code would detect that several modules share the same MODULEMODE bits, and automatically set it for those cases, but that seems a bit too complex for a first cut.)
- Paul
PATCH 1/1 ARM: OMAP5: DSS hwmod data
Hi Paul,
On Thursday 08 May 2014 09:31 PM, Paul Walmsley wrote:
<snip>
Quoted 5 lines
Quoted 4 lines
The problem is that we have multiple hwmods which use the same MODULEMODE bit. There is no use-counting done when it comes to enabling/disabling modulemode. If there was such a thing, we could have provided MODULEMODE flags even for the children hwmods.
Quoted 7 lines
Thanks for the summary. This is indeed a long-overdue item for the hwmod core code. Can you please patch the hwmod core code to add this? I'd suggest making the use-counting functionality conditional on a hwmod flag that you can set for all of the DSS hwmods. (Ideally, the core code would detect that several modules share the same MODULEMODE bits, and automatically set it for those cases, but that seems a bit too complex for a first cut.)
Sure, I can work on this.
Archit
PATCH 1/1 ARM: OMAP5: DSS hwmod data
In reply to Paul WalmsleyQuoted 45 lines · Paul Walmsley
Hi Archit,
Quoted 36 lines · Archit Taneja
Hi Paul,
Quoted 18 lines · Paul Walmsley
Hi,
Quoted 14 lines · Tomi Valkeinen
This patch adds hwmod data for omap5 display subsystem. I have tested this on
omap5-uevm with a DSI panel. I cannot test omap5-uevm's hdmi output yet, as the
mainline is missing omap5 HDMI driver.I do see this when booting:
omap_hwmod:dss_dispc: cannot be enabled for reset (3)
omap_hwmod:dss_dsi1: cannot be enabled for reset (3)
omap_hwmod:dss_dsi2: cannot be enabled for reset (3)
omap_hwmod:dss_hdmi: cannot be enabled for reset (3)
omap_hwmod:dss_rfbi: cannot be enabled for reset (3)Quoted 4 lines
Quoted 1 line
But at least DSI works just fine.
Am looking at this for v3.16. But I think someone needs to take a look at those warnings and figure out why they are happening.
We associate DSS clock domain's MODULEMODE bits only with the
dss_corehwmod. The rest of the dss hwmods don't touch MODULEMODE.Therefore, these hwmods cannot be enabled independently, and reset.
We don't face this issue in the omapdss driver since the platform devices corresponding to these hwmods have their parent as the platform device corresponding to '
dss_core'. This parent child-relation ensures that 'dss_core' is enabled when the a child calls apm_runtime_getfunction.Quoted 4 lines
The problem is that we have multiple hwmods which use the same MODULEMODE bit. There is no use-counting done when it comes to enabling/disabling modulemode. If there was such a thing, we could have provided MODULEMODE flags even for the children hwmods.
Quoted 7 lines
Thanks for the summary. This is indeed a long-overdue item for the hwmod core code. Can you please patch the hwmod core code to add this? I'd suggest making the use-counting functionality conditional on a hwmod flag that you can set for all of the DSS hwmods. (Ideally, the core code would detect that several modules share the same MODULEMODE bits, and automatically set it for those cases, but that seems a bit too complex for a first cut.)
Can we still go forward with this patch as it is? As far as I understand, the warnings are harmless (more or less), but without this patch we won't have OMAP5 display support.
Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140509/67aef498/attachment.sig>
Paul Walmsley
maintainerPATCH 1/1 ARM: OMAP5: DSS hwmod data
Quoted 54 lines · Tomi Valkeinen
Quoted 45 lines · Paul Walmsley
Hi Archit,
Quoted 36 lines · Archit Taneja
Hi Paul,
Quoted 18 lines · Paul Walmsley
Hi,
Quoted 14 lines · Tomi Valkeinen
This patch adds hwmod data for omap5 display subsystem. I have tested this on
omap5-uevm with a DSI panel. I cannot test omap5-uevm's hdmi output yet, as the
mainline is missing omap5 HDMI driver.I do see this when booting:
omap_hwmod:dss_dispc: cannot be enabled for reset (3)
omap_hwmod:dss_dsi1: cannot be enabled for reset (3)
omap_hwmod:dss_dsi2: cannot be enabled for reset (3)
omap_hwmod:dss_hdmi: cannot be enabled for reset (3)
omap_hwmod:dss_rfbi: cannot be enabled for reset (3)Quoted 4 lines
Quoted 1 line
But at least DSI works just fine.
Am looking at this for v3.16. But I think someone needs to take a look at those warnings and figure out why they are happening.
We associate DSS clock domain's MODULEMODE bits only with the
dss_corehwmod. The rest of the dss hwmods don't touch MODULEMODE.Therefore, these hwmods cannot be enabled independently, and reset.
We don't face this issue in the omapdss driver since the platform devices corresponding to these hwmods have their parent as the platform device corresponding to '
dss_core'. This parent child-relation ensures that 'dss_core' is enabled when the a child calls apm_runtime_getfunction.Quoted 4 lines
The problem is that we have multiple hwmods which use the same MODULEMODE bit. There is no use-counting done when it comes to enabling/disabling modulemode. If there was such a thing, we could have provided MODULEMODE flags even for the children hwmods.
Quoted 7 lines
Thanks for the summary. This is indeed a long-overdue item for the hwmod core code. Can you please patch the hwmod core code to add this? I'd suggest making the use-counting functionality conditional on a hwmod flag that you can set for all of the DSS hwmods. (Ideally, the core code would detect that several modules share the same MODULEMODE bits, and automatically set it for those cases, but that seems a bit too complex for a first cut.)
Quoted 3 lines
Can we still go forward with this patch as it is? As far as I understand, the warnings are harmless (more or less), but without this patch we won't have OMAP5 display support.
Generally speaking, we try to avoid queuing patches that add warnings, for a few different reasons:
1. end users don't know whether they are serious or not, and could waste time trying to determine whether those warnings are causing other, unrelated problems for them
2. once patches with warnings are merged, even if folks promise to fix them, usually people tend to deprioritize 'closing the loop' on the fixes
- so they often never make it back upstream
3. some maintainers search for warnings in their test logs and push back on patches that generate them
All that said, you and Archit are pretty good in my experience about following up on issues. And Archit has mentioned that he will be patching the hwmod core code to fix the underlying issue:
http://www.spinics.net/lists/arm-kernel/msg329614.html
So, at least speaking for myself, I'm willing to queue this patch for 3.16, with the understanding that you all will be patching the hwmod core code to fix the root cause.
- Paul
RFC v2 1/2 ARM: OMAP2+: hwmod: Add refcounting for modulemode shared by multiple hwmods
Generally, IP blocks/modules within a clock domain each have their own CM_x_CLKCTRL register, each having it's own MODULEMODE field to manage the module.
DSS clockdoain, however, has multiple modules in it, but only one register named CM_DSS_DSS_CLKCTRL, which contains one MODULEMODE register field.
Until now, we defined '.prcm.omap4.modulemode' only for the top level DSS hwmod("dss_core") and didn't define it for other DSS hwmods(like "dss_dispc", "dss_dsi1" and so on). This made the omapdss driver work as the top level DSS platform device and the rest had a parent-child relationship. This ensured that the parent hwmod("dss_core") is enabled if any of the children hwmods are enabled while using omapdss.
This method, however, doesn't work when each hwmod is enabled individually. This happens early in boot in omap_hwmod_setup_all, where each hwmod is enabled, and then reset and idled. All the 'children' DSS hwmods fail to enable and reset, since they don't enable modulemode.
The way to make such modules work both during initialization and when used by pm runtime API in the driver would be to add refcounting for enabling/disabling the modulemode field.
We add a new flag bit for the flag in omap_hwmod_omap4_prcm, which tells omap_hwmod that this hwmod uses a modulemode field shared by other hwmods.
We create a struct called 'modulemode_shared'. The hwmod data file should define a static instance of this struct. Each hwmod that uses this modulemode field should hold a pointer to this instance.
omap_hwmod's soc enable_module and disable_module ops set the MODULEMODE reigster bits only when the first module using it is enabled, or the last module using it is disabled. We serialize accesses to the struct with a spinlock.
--- arch/arm/mach-omap2/omap_hwmod.c | 123 +++++++++++++++++++++++++++++++++------ arch/arm/mach-omap2/omap_hwmod.h | 38 +++++++++--- 2 files changed, 133 insertions(+), 28 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +104 -19
@@ -973,17 +973,33 @@ static void _disable_optional_clocks(struct omap_hwmod *oh)*/ static void _omap4_enable_module (struct omap_hwmod *oh) { +unsigned long flags; +struct modulemode_shared *mmode =NULL ; +bool enable = true; +if (!oh->clkdm || !oh->prcm.omap4.modulemode)return ;pr_debug ("omap_hwmod: %s: %s: %d\n" , oh->name, __func__, oh->prcm.omap4.modulemode); -omap4_cminst_module_enable (oh->prcm.omap4.modulemode, - oh->clkdm->prcm_partition, - oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); +if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED ) { + mmode = oh->prcm.omap4.modulemode_ref; + +spin_lock_irqsave (&mmode->lock, flags); + + enable = mmode->refcnt++ ==0 ; + } + +if (enable) +omap4_cminst_module_enable (oh->prcm.omap4.modulemode, + oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + +if (mmode) +spin_unlock_irqrestore (&mmode->lock, flags); }/**
@@ -995,15 +1011,32 @@ static void _omap4_enable_module(struct omap_hwmod *oh)*/ static void _am33xx_enable_module (struct omap_hwmod *oh) { +unsigned long flags; +struct modulemode_shared *mmode =NULL ; +bool enable = true; +if (!oh->clkdm || !oh->prcm.omap4.modulemode)return ;pr_debug ("omap_hwmod: %s: %s: %d\n" , oh->name, __func__, oh->prcm.omap4.modulemode); -am33xx_cm_module_enable (oh->prcm.omap4.modulemode, oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); +if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED ) { + mmode = oh->prcm.omap4.modulemode_ref; + +spin_lock_irqsave (&mmode->lock, flags); + + enable = mmode->refcnt++ ==0 ; + } + +if (enable) +am33xx_cm_module_enable (oh->prcm.omap4.modulemode, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + +if (mmode) +spin_unlock_irqrestore (&mmode->lock, flags); }/**
@@ -1846,6 +1879,9 @@ static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh)static int _omap4_disable_module (struct omap_hwmod *oh) {int v; +unsigned long flags; +struct modulemode_shared *mmode =NULL ; +bool disable = true;if (!oh->clkdm || !oh->prcm.omap4.modulemode)return -EINVAL ;
@@ -1859,15 +1895,30 @@ static int _omap4_disable_module(struct omap_hwmod *oh)pr_debug ("omap_hwmod: %s: %s\n" , oh->name, __func__); -omap4_cminst_module_disable (oh->clkdm->prcm_partition, +if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED ) { + mmode = oh->prcm.omap4.modulemode_ref; + +spin_lock_irqsave (&mmode->lock, flags); + +WARN_ON (mmode->refcnt ==0 ); + + disable = --mmode->refcnt ==0 ; + } + +if (disable) { +omap4_cminst_module_disable (oh->clkdm->prcm_partition, oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, oh->prcm.omap4.clkctrl_offs); - v =_omap4_wait_target_disable (oh); -if (v) -pr_warn ("omap_hwmod: %s: _wait_target_disable failed\n" , - oh->name); + v =_omap4_wait_target_disable (oh); +if (v) +pr_warn ("omap_hwmod: %s: _wait_target_disable failed\n" , + oh->name); + } + +if (mmode) +spin_unlock_irqrestore (&mmode->lock, flags);return 0 ; }
@@ -1882,6 +1933,9 @@ static int _omap4_disable_module(struct omap_hwmod *oh)static int _am33xx_disable_module (struct omap_hwmod *oh) {int v; +unsigned long flags; +struct modulemode_shared *mmode =NULL ; +bool disable = true;if (!oh->clkdm || !oh->prcm.omap4.modulemode)return -EINVAL ;
@@ -1891,13 +1945,28 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)if (_are_any_hardreset_lines_asserted (oh))return 0 ; -am33xx_cm_module_disable (oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); +if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED ) { + mmode = oh->prcm.omap4.modulemode_ref; - v =_am33xx_wait_target_disable (oh); -if (v) -pr_warn ("omap_hwmod: %s: _wait_target_disable failed\n" , - oh->name); +spin_lock_irqsave (&mmode->lock, flags); + +WARN_ON (mmode->refcnt ==0 ); + + disable = --mmode->refcnt ==0 ; + } + +if (disable) { +am33xx_cm_module_disable (oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + + v =_am33xx_wait_target_disable (oh); +if (v) +pr_warn ("omap_hwmod: %s: _wait_target_disable failed\n" , + oh->name); + } + +if (mmode) +spin_unlock_irqrestore (&mmode->lock, flags);return 0 ; }
@@ -2751,6 +2820,13 @@ static int __init _register(struct omap_hwmod *oh)if (_lookup (oh->name))return -EEXIST ; +if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED && + !oh->prcm.omap4.modulemode_ref) { +pr_err ("omap_hwmod: %s shares modulemode, but doesn't hold a ref to it\n" , + oh->name); +return -EINVAL ; + } +list_add_tail (&oh->node, &omap_hwmod_list);INIT_LIST_HEAD (&oh->master_ports);
@@ -2759,6 +2835,15 @@ static int __init _register(struct omap_hwmod *oh) oh->_state = _HWMOD_STATE_REGISTERED; +if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED ) { +struct modulemode_shared *mmode = oh->prcm.omap4.modulemode_ref; + +if (!mmode->registered) { +spin_lock_init (&mmode->lock); + mmode->registered = true; + } + } +/* * XXX Rather than doing a strcmp(), this should test a flag * set in the hwmod data, inserted by the autogenerator code.
arch/arm/mach-omap2/omap_hwmod.h +29 -9
@@ -432,13 +432,31 @@ struct omap_hwmod_omap2_prcm { };/* +* struct for managing modulemode field shared accross IP blocks +* @lock: spinlock to searilze enables/disables performed by different +* hwmods sharing the same modulemode field +* @refcnt: keep a refcount of the enabled hwmods using this modulemode +* field +* @registered: a flag to track whether the struct has been registered +*/ +struct modulemode_shared { +spinlock_t lock; +unsigned refcnt; +bool registered; +}; + +/* * Possible values for struct omap_hwmod_omap4_prcm.flags * * HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT: Some IP blocks don't have a PRCM * module-level context loss register associated with them; this * flag bit should be set in those cases +* HWMOD_OMAP4_MODULEMODE_SHARED: Some IP blocks belonging to the same +* clock domain may have a shared MODULEMODE field; this flag bit +* should be set in those cases */ #define HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT (1 << 0) +#define HWMOD_OMAP4_MODULEMODE_SHARED (1 << 1)/** * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
@@ -450,6 +468,7 @@ struct omap_hwmod_omap2_prcm {* @submodule_wkdep_bit: bit shift of the WKDEP range * @flags: PRCM register capabilities for this IP block * @modulemode: allowable modulemodes +* @modulemode_ref: pointer to modulemode struct shared by multiple hwmods * @context_lost_counter: Count of module level context lost * * If @lostcontext_mask is not defined, context loss check code uses
@@ -458,15 +477,16 @@ struct omap_hwmod_omap2_prcm {* more hwmods. */ struct omap_hwmod_omap4_prcm { -u16 clkctrl_offs; -u16 rstctrl_offs; -u16 rstst_offs; -u16 context_offs; -u32 lostcontext_mask; -u8 submodule_wkdep_bit; -u8 modulemode; -u8 flags; -int context_lost_counter; +u16 clkctrl_offs; +u16 rstctrl_offs; +u16 rstst_offs; +u16 context_offs; +u32 lostcontext_mask; +u8 submodule_wkdep_bit; +u8 modulemode; +struct modulemode_shared *modulemode_ref; +u8 flags; +int context_lost_counter; };
Signature · 1 line
1.8.3.2
RFC v2 2/2 ARM: OMAP5: hwmod data: Make DSS hwmods share MODULEMODE fields
This is an example which shows how to use new 'shared modulemode' flag.
DSS hwmods share the MODULEMODE field. Add the new HWMOD_OMAP4_MODULEMODE_SHARED flag, and create a modulemode_shared struct which the DSS hwmods refer to.
This will allow the hwmods to reset properly during boot, and not break things when the DSS driver runs.
(Note: hdmi and rfbi hwmods still don't reset properly as they don't have their mainclks as dss_dss_clk, this will be fixed later).
--- arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 46 +++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 13 deletions(-)
arch/arm/mach-omap2/omap_hwmod_54xx_data.c +33 -13
@@ -337,6 +337,9 @@ static struct omap_hwmod omap54xx_dmic_hwmod = {* 'dss' class * display sub-system */ + +static struct modulemode_shared dss_modulemode_ref; +static struct omap_hwmod_class_sysconfig omap54xx_dss_sysc = { .rev_offs =0x0000 , .syss_offs =0x0014 ,
@@ -364,9 +367,11 @@ static struct omap_hwmod omap54xx_dss_hwmod = { .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .context_offs = OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET, - .modulemode = MODULEMODE_SWCTRL, + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + .flags = HWMOD_OMAP4_MODULEMODE_SHARED, + .modulemode_ref = &dss_modulemode_ref, }, }, .opt_clks = dss_opt_clks,
@@ -414,8 +419,11 @@ static struct omap_hwmod omap54xx_dss_dispc_hwmod = { .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags =HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT | + HWMOD_OMAP4_MODULEMODE_SHARED, + .modulemode = MODULEMODE_SWCTRL, + .modulemode_ref = &dss_modulemode_ref, }, }, .opt_clks = dss_dispc_opt_clks,
@@ -456,8 +464,11 @@ static struct omap_hwmod omap54xx_dss_dsi1_a_hwmod = { .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags =HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT | + HWMOD_OMAP4_MODULEMODE_SHARED, + .modulemode = MODULEMODE_SWCTRL, + .modulemode_ref = &dss_modulemode_ref, }, }, .opt_clks = dss_dsi1_a_opt_clks,
@@ -476,8 +487,11 @@ static struct omap_hwmod omap54xx_dss_dsi1_c_hwmod = { .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags =HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT | + HWMOD_OMAP4_MODULEMODE_SHARED, + .modulemode = MODULEMODE_SWCTRL, + .modulemode_ref = &dss_modulemode_ref, }, }, .opt_clks = dss_dsi1_c_opt_clks,
@@ -515,8 +529,11 @@ static struct omap_hwmod omap54xx_dss_hdmi_hwmod = { .main_clk = "dss_48mhz_clk", .prcm = { .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags =HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT | + HWMOD_OMAP4_MODULEMODE_SHARED, + .modulemode = MODULEMODE_SWCTRL, + .modulemode_ref = &dss_modulemode_ref, }, }, .opt_clks = dss_hdmi_opt_clks,
@@ -554,8 +571,11 @@ static struct omap_hwmod omap54xx_dss_rfbi_hwmod = { .clkdm_name = "dss_clkdm", .prcm = { .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags =HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT | + HWMOD_OMAP4_MODULEMODE_SHARED, + .modulemode = MODULEMODE_SWCTRL, + .modulemode_ref = &dss_modulemode_ref, }, }, .opt_clks = dss_rfbi_opt_clks,
Signature · 1 line
1.8.3.2
Re: [RFC 1/2] ARM: OMAP2+: hwmod: Add refcounting for modulemode shared by multiple hwmods
In reply to Archit TanejaQuoted 211 lines · Archit Taneja
Generally, IP blocks/modules within a clock domain each have their own
CM_x_CLKCTRLregister, each having it's own MODULEMODE field to manage the module.DSS clockdoain, however, has multiple modules in it, but only one register named
CM_DSS_DSS_CLKCTRL, which contains one MODULEMODE register field.Until now, we defined '.prcm.omap4.modulemode' only for the top level DSS
hwmod("dss_core")and didn't define it for other DSShwmods(like "dss_dispc", "dss_dsi1" and so on). This made the omapdss driver work as the top level DSS platform device and the rest had a parent-child relationship. This ensured that the parenthwmod("dss_core")is enabled if any of the children hwmods are enabled while using omapdss.This method, however, doesn't work when each hwmod is enabled individually. This happens early in boot in
omap_hwmod_setup_all, where each hwmod is enabled, and then reset and idled. All the 'children' DSS hwmods fail to enable and reset, since they don't enable modulemode.The way to make such modules work both during initialization and when used by pm runtime API in the driver would be to add refcounting for enabling/disabling the modulemode field.
We add a new flag bit for the flag in
omap_hwmod_omap4_prcm, which tellsomap_hwmodthat this hwmod uses a modulemode field shared by other hwmods.We create a struct called '
modulemode_shared'. The hwmod data file should define a static instance of this struct. Each hwmod that uses this modulemode field should hold a pointer to this instance.omap_hwmod's soc
enable_moduleanddisable_moduleops set the MODULEMODE reigster bits only when the first module using it is enabled, or the last module using it is disabled. We serialize accesses to the struct with a spinlock.Signed-off-by Archit Taneja <[email protected]>--- arch/arm/mach-omap2/omap_hwmod.c | 123 +++++++++++++++++++++++++++++++++------ arch/arm/mach-omap2/omap_hwmod.h | 38 +++++++++--- 2 files changed, 133 insertions(+), 28 deletions(-)arch/arm/mach-omap2/omap_hwmod.c +88
-19@@ -973,17 +973,33 @@ static void _disable_optional_clocks(struct omap_hwmod *oh)*/ static void _omap4_enable_module (struct omap_hwmod *oh) { +unsigned long flags; +struct modulemode_shared *mmode =NULL ; +bool enable = true; +if (!oh->clkdm || !oh->prcm.omap4.modulemode)return ;pr_debug ("omap_hwmod: %s: %s: %d\n" , oh->name, __func__, oh->prcm.omap4.modulemode); -omap4_cminst_module_enable (oh->prcm.omap4.modulemode, - oh->clkdm->prcm_partition, - oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); +if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED ) { + mmode = oh->prcm.omap4.modulemode_ref; + +spin_lock_irqsave (&mmode->lock, flags); + + enable = mmode->refcnt++ ==0 ; + } + +if (enable) +omap4_cminst_module_enable (oh->prcm.omap4.modulemode, + oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + +if (mmode) +spin_unlock_irqrestore (&mmode->lock, flags); }/** @@ -995,15 +1011,32 @@ static void _omap4_enable_module(struct omap_hwmod *oh)*/ static void _am33xx_enable_module (struct omap_hwmod *oh) { +unsigned long flags; +struct modulemode_shared *mmode =NULL ; +bool enable = true; +if (!oh->clkdm || !oh->prcm.omap4.modulemode)return ;pr_debug ("omap_hwmod: %s: %s: %d\n" , oh->name, __func__, oh->prcm.omap4.modulemode); -am33xx_cm_module_enable (oh->prcm.omap4.modulemode, oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); +if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED ) { + mmode = oh->prcm.omap4.modulemode_ref; + +spin_lock_irqsave (&mmode->lock, flags); + + enable = mmode->refcnt++ ==0 ; + } + +if (enable) +am33xx_cm_module_enable (oh->prcm.omap4.modulemode, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + +if (mmode) +spin_unlock_irqrestore (&mmode->lock, flags); }/** @@ -1846,6 +1879,9 @@ static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh)static int _omap4_disable_module (struct omap_hwmod *oh) {int v; +unsigned long flags; +struct modulemode_shared *mmode =NULL ; +bool disable = true;if (!oh->clkdm || !oh->prcm.omap4.modulemode)return -EINVAL ;@@ -1859,15 +1895,30 @@ static int _omap4_disable_module(struct omap_hwmod *oh)pr_debug ("omap_hwmod: %s: %s\n" , oh->name, __func__); -omap4_cminst_module_disable (oh->clkdm->prcm_partition, +if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED ) { + mmode = oh->prcm.omap4.modulemode_ref; + +spin_lock_irqsave (&mmode->lock, flags); + +WARN_ON (mmode->refcnt ==0 ); + + disable = --mmode->refcnt ==0 ; + } + +if (disable) { +omap4_cminst_module_disable (oh->clkdm->prcm_partition, oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, oh->prcm.omap4.clkctrl_offs); - v =_omap4_wait_target_disable (oh); -if (v) -pr_warn ("omap_hwmod: %s: _wait_target_disable failed\n" , - oh->name); + v =_omap4_wait_target_disable (oh); +if (v) +pr_warn ("omap_hwmod: %s: _wait_target_disable failed\n" , + oh->name); + } + +if (mmode) +spin_unlock_irqrestore (&mmode->lock, flags);return 0 ; }@@ -1882,6 +1933,9 @@ static int _omap4_disable_module(struct omap_hwmod *oh)static int _am33xx_disable_module (struct omap_hwmod *oh) {int v; +unsigned long flags; +struct modulemode_shared *mmode =NULL ; +bool disable = true;if (!oh->clkdm || !oh->prcm.omap4.modulemode)return -EINVAL ;@@ -1891,13 +1945,28 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)if (_are_any_hardreset_lines_asserted (oh))return 0 ; -am33xx_cm_module_disable (oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); +if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED ) { + mmode = oh->prcm.omap4.modulemode_ref; - v =_am33xx_wait_target_disable (oh); -if (v) -pr_warn ("omap_hwmod: %s: _wait_target_disable failed\n" , - oh->name); +spin_lock_irqsave (&mmode->lock, flags); + +WARN_ON (mmode->refcnt ==0 ); + + disable = --mmode->refcnt ==0 ; + } + +if (disable) { +am33xx_cm_module_disable (oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + + v =_am33xx_wait_target_disable (oh); +if (v) +pr_warn ("omap_hwmod: %s: _wait_target_disable failed\n" , + oh->name); + } + +if (mmode) +spin_unlock_irqrestore (&mmode->lock, flags);return 0 ; }
arch/arm/mach-omap2/omap_hwmod.c static int __init _register(struct omap_hwmod *oh) · line 2824
Quoted 5 lines
arch/arm/mach-omap2/omap_hwmod.c +2
-0@@ -2751,6 +2820,13 @@ static int __init _register(struct omap_hwmod *oh)if (_lookup (oh->name))return -EEXIST ; +if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED && + !oh->prcm.omap4.modulemode_ref) {
You might also want to check for someone populating a modulemode_ref but failing to populate the flag?
Alternatively, Since you expect a modulemode_ref to be always available for all modules which share modulemode, that in itself can be used to identify such modules without the need of an additional flag?
Quoted 9 lines
arch/arm/mach-omap2/omap_hwmod.c +5
-0+pr_err ("omap_hwmod: %s shares modulemode, but doesn't hold a ref to it\n" , + oh->name); +return -EINVAL ; + } +list_add_tail (&oh->node, &omap_hwmod_list);INIT_LIST_HEAD (&oh->master_ports);
arch/arm/mach-omap2/omap_hwmod.c static int __init _register(struct omap_hwmod *oh) · line 2843
Quoted 9 lines
arch/arm/mach-omap2/omap_hwmod.c +6
-0@@ -2759,6 +2835,15 @@ static int __init _register(struct omap_hwmod *oh) oh->_state = _HWMOD_STATE_REGISTERED; +if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED ) { +struct modulemode_shared *mmode = oh->prcm.omap4.modulemode_ref; + +if (!mmode->registered) { +spin_lock_init (&mmode->lock); + mmode->registered = true;
If this is only used to keep track of the spin_lock being initialized, maybe it'll be more readable if you just call it mmode->spin_lock_init = true.
Quoted 77 lines
arch/arm/mach-omap2/omap_hwmod.c +3
-0+ } + } +/* * XXX Rather than doing a strcmp(), this should test a flag * set in the hwmod data, inserted by the autogenerator code. arch/arm/mach-omap2/omap_hwmod.h +29
-9@@ -432,13 +432,31 @@ struct omap_hwmod_omap2_prcm { };/* +* struct for managing modulemode field shared accross IP blocks +* @lock: spinlock to searilze enables/disables performed by different +* hwmods sharing the same modulemode field +* @refcnt: keep a refcount of the enabled hwmods using this modulemode +* field +* @registered: a flag to track whether the struct has been registered +*/ +struct modulemode_shared { +spinlock_t lock; +unsigned refcnt; +bool registered; +}; + +/* * Possible values for struct omap_hwmod_omap4_prcm.flags * * HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT: Some IP blocks don't have a PRCM * module-level context loss register associated with them; this * flag bit should be set in those cases +* HWMOD_OMAP4_MODULEMODE_SHARED: Some IP blocks belonging to the same +* clock domain may have a shared MODULEMODE field; this flag bit +* should be set in those cases */ #define HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT (1 << 0) +#define HWMOD_OMAP4_MODULEMODE_SHARED (1 << 1)/** * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data @@ -450,6 +468,7 @@ struct omap_hwmod_omap2_prcm {* @submodule_wkdep_bit: bit shift of the WKDEP range * @flags: PRCM register capabilities for this IP block * @modulemode: allowable modulemodes +* @modulemode_ref: pointer to modulemode struct shared by multiple hwmods * @context_lost_counter: Count of module level context lost * * If @lostcontext_mask is not defined, context loss check code uses @@ -458,15 +477,16 @@ struct omap_hwmod_omap2_prcm {* more hwmods. */ struct omap_hwmod_omap4_prcm { -u16 clkctrl_offs; -u16 rstctrl_offs; -u16 rstst_offs; -u16 context_offs; -u32 lostcontext_mask; -u8 submodule_wkdep_bit; -u8 modulemode; -u8 flags; -int context_lost_counter; +u16 clkctrl_offs; +u16 rstctrl_offs; +u16 rstst_offs; +u16 context_offs; +u32 lostcontext_mask; +u8 submodule_wkdep_bit; +u8 modulemode; +struct modulemode_shared *modulemode_ref; +u8 flags; +int context_lost_counter; };
Re: [RFC 1/2] ARM: OMAP2+: hwmod: Add refcounting for modulemode shared by multiple hwmods
Hi,
Quoted 4 lines · Rajendra Nayak
Quoted 3 lines · Archit Taneja
Generally, IP blocks/modules within a clock domain each have their own
CM_x_CLKCTRLregister, each having it's own MODULEMODE field to manage the module.
<snip>
Quoted 10 lines
arch/arm/mach-omap2/omap_hwmod.c static int __init _register(struct omap_hwmod *oh) · line 2824
Quoted 6 lines
arch/arm/mach-omap2/omap_hwmod.c +2
-0@@ -2751,6 +2820,13 @@ static int __init _register(struct omap_hwmod *oh)if (_lookup (oh->name))return -EEXIST ; +if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED && + !oh->prcm.omap4.modulemode_ref) {You might also want to check for someone populating a
modulemode_refbut failing to populate the flag?
Quoted 3 lines
Alternatively, Since you expect a
modulemode_refto be always available for all modules which share modulemode, that in itself can be used to identify such modules without the need of an additional flag?
It does seem redundant to have a flag at the moment. But the flag make things more visible. 'prcm.omap4.modulemode' seems to work without a flag too, so I suppose I'll remove the flag.
Quoted 13 lines
Quoted 13 lines
arch/arm/mach-omap2/omap_hwmod.c +5
-0+pr_err ("omap_hwmod: %s shares modulemode, but doesn't hold a ref to it\n" , + oh->name); +return -EINVAL ; + } +list_add_tail (&oh->node, &omap_hwmod_list);INIT_LIST_HEAD (&oh->master_ports);@@ -2759,6 +2835,15 @@ static int __init _register(struct omap_hwmod *oh) oh->_state = _HWMOD_STATE_REGISTERED;
Quoted 9 lines
arch/arm/mach-omap2/omap_hwmod.c static int __init _register(struct omap_hwmod *oh) · line 2843
Quoted 6 lines
arch/arm/mach-omap2/omap_hwmod.c +6
-0+if (oh->prcm.omap4.flags &HWMOD_OMAP4_MODULEMODE_SHARED ) { +struct modulemode_shared *mmode = oh->prcm.omap4.modulemode_ref; + +if (!mmode->registered) { +spin_lock_init (&mmode->lock); + mmode->registered = true;If this is only used to keep track of the
spin_lockbeing initialized, maybe it'll be more readable if you just call itmmode->spin_lock_init= true.
Yes, I'll fix this.
Archit
v2 cover arm: omap2+: hwmod: Allow hwmods to share same modulemode register filed
In reply to Archit TanejaIP blocks within a clock domain generally come with their own CM_X_CLKCTRL registers, each having it's own MODULEMODE field to manage the module. This is not the case for DSS, though. DSS contains contains sub modules, each of which are represented by hwmods, but DSS itself has only one register CM_DSS_DSS_CLKCTRL.
Add a way to allow multiple hwmods to share the same MODULEMODE fiels. This means that MODULEMODE operation should be disabled only when the last hwmod using it is disabled.
Changes in v2:
- The OMAP4 PRCM hwmod flag to show that this hwmod is shared was found redundant, and therefore, removed.
- Some of the struct names are shortened, and members are named more appropriately.
Archit Taneja (2):
arm: omap2+: hwmod: Add refcounting for modulemode shared by multiple
hwmods
arm: omap5 hwmod data: Example: Make DSS hwmods share MODULEMODE
fields
arch/arm/mach-omap2/omap_hwmod.c | 145 +++++++++++++++++++++++++---- arch/arm/mach-omap2/omap_hwmod.h | 35 +++++-- arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 40 +++++--- 3 files changed, 180 insertions(+), 40 deletions(-)
Signature · 1 line
1.9.1
RFC v2 1/2 arm: omap2+: hwmod: Add refcounting for modulemode shared by multiple hwmods
Generally, IP blocks/modules within a clock domain come with their own CM_x_CLKCTRL registers, each having it's own MODULEMODE field to manage the module.
DSS clockdomain, however, has multiple modules in it, but only one register named CM_DSS_DSS_CLKCTRL, which contains one MODULEMODE register field.
Until now, we defined modulemode only for the top level DSS hwmod("dss_core") and didn't define it for other DSS hwmods(like "dss_dispc", "dss_dsi1" and so on). This made the omapdss driver work as the top level DSS platform device and the rest had a parent-child relationship, and ensured that the parent hwmod("dss_core") is enabled if any of the children hwmods are enabled.
This method, however, doesn't work when each hwmod is enabled individually. When hwmods are set up in omap_hwmod_setup_all, each hwmod is individually enabled, followed by a reset and idle. All the 'children' DSS hwmods fail to enable as they don't enable modulemode.
The way to make such modules work both during initialization and when used by pm runtime API in the driver is be to add refcounting for enabling/disabling modulemode.
We create a struct called 'mmode_shared'. The hwmod data file should define an instance of this struct. Each hwmod that uses this modulemode field should hold a pointer to this instance.
omap_hwmod's soc enable_module and disable_module ops set the MODULEMODE reigster bits only when the first module using it is enabled, or the last module using it is disabled. We serialize accesses to the struct with a spinlock.
--- arch/arm/mach-omap2/omap_hwmod.c | 145 ++++++++++++++++++++++++++++++++++----- arch/arm/mach-omap2/omap_hwmod.h | 35 +++++++--- 2 files changed, 153 insertions(+), 27 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +127 -18
@@ -1,3 +1,4 @@ +/* * omap_hwmod implementation for OMAP2/3/4 *
@@ -973,17 +974,38 @@ static void _disable_optional_clocks(struct omap_hwmod *oh)*/ static void _omap4_enable_module (struct omap_hwmod *oh) { +struct mmode_shared *mmode; +if (!oh->clkdm || !oh->prcm.omap4.modulemode)return ;pr_debug ("omap_hwmod: %s: %s: %d\n" , oh->name, __func__, oh->prcm.omap4.modulemode); -omap4_cminst_module_enable (oh->prcm.omap4.modulemode, - oh->clkdm->prcm_partition, - oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); + mmode = oh->prcm.omap4.mmode_ref; +if (mmode) { +bool enable; +unsigned long flags; + +spin_lock_irqsave (&mmode->lock, flags); + + enable = mmode->refcnt++ ==0 ; + +if (enable) +omap4_cminst_module_enable (oh->prcm.omap4.modulemode, + oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + +spin_unlock_irqrestore (&mmode->lock, flags); + }else { +omap4_cminst_module_enable (oh->prcm.omap4.modulemode, + oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + } }/**
@@ -995,15 +1017,36 @@ static void _omap4_enable_module(struct omap_hwmod *oh)*/ static void _am33xx_enable_module (struct omap_hwmod *oh) { +struct mmode_shared *mmode; +if (!oh->clkdm || !oh->prcm.omap4.modulemode)return ;pr_debug ("omap_hwmod: %s: %s: %d\n" , oh->name, __func__, oh->prcm.omap4.modulemode); -am33xx_cm_module_enable (oh->prcm.omap4.modulemode, oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); + mmode = oh->prcm.omap4.mmode_ref; +if (mmode) { +bool enable; +unsigned long flags; + +spin_lock_irqsave (&mmode->lock, flags); + + enable = mmode->refcnt++ ==0 ; + +if (enable) +am33xx_cm_module_enable (oh->prcm.omap4.modulemode, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + +spin_unlock_irqrestore (&mmode->lock, flags); + }else { +am33xx_cm_module_enable (oh->prcm.omap4.modulemode, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + } }/**
@@ -1845,7 +1888,8 @@ static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh)*/ static int _omap4_disable_module (struct omap_hwmod *oh) { -int v; +int v =0 ; +struct mmode_shared *mmode;if (!oh->clkdm || !oh->prcm.omap4.modulemode)return -EINVAL ;
@@ -1859,12 +1903,36 @@ static int _omap4_disable_module(struct omap_hwmod *oh)pr_debug ("omap_hwmod: %s: %s\n" , oh->name, __func__); -omap4_cminst_module_disable (oh->clkdm->prcm_partition, - oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); + mmode = oh->prcm.omap4.mmode_ref; +if (mmode) { +bool disable; +unsigned long flags; + +spin_lock_irqsave (&mmode->lock, flags); + +WARN_ON (mmode->refcnt ==0 ); + + disable = --mmode->refcnt ==0 ; + +if (disable) { +omap4_cminst_module_disable (oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + + v =_omap4_wait_target_disable (oh); + } + +spin_unlock_irqrestore (&mmode->lock, flags); + }else { +omap4_cminst_module_disable (oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + + v =_omap4_wait_target_disable (oh); + } - v =_omap4_wait_target_disable (oh);if (v)pr_warn ("omap_hwmod: %s: _wait_target_disable failed\n" , oh->name);
@@ -1881,7 +1949,8 @@ static int _omap4_disable_module(struct omap_hwmod *oh)*/ static int _am33xx_disable_module (struct omap_hwmod *oh) { -int v; +int v =0 ; +struct mmode_shared *mmode;if (!oh->clkdm || !oh->prcm.omap4.modulemode)return -EINVAL ;
@@ -1891,10 +1960,34 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)if (_are_any_hardreset_lines_asserted (oh))return 0 ; -am33xx_cm_module_disable (oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); + mmode = oh->prcm.omap4.mmode_ref; +if (mmode) { +bool disable; +unsigned long flags; + +spin_lock_irqsave (&mmode->lock, flags); + +WARN_ON (mmode->refcnt ==0 ); + + disable = --mmode->refcnt ==0 ; + +if (disable) { +am33xx_cm_module_disable (oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + + v =_am33xx_wait_target_disable (oh); + } + +spin_unlock_irqrestore (&mmode->lock, flags); + }else { +am33xx_cm_module_disable (oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + + v =_am33xx_wait_target_disable (oh); + } - v =_am33xx_wait_target_disable (oh);if (v)pr_warn ("omap_hwmod: %s: _wait_target_disable failed\n" , oh->name);
@@ -2751,6 +2844,12 @@ static int __init _register(struct omap_hwmod *oh)if (_lookup (oh->name))return -EEXIST ; +if (oh->prcm.omap4.mmode_ref && !oh->prcm.omap4.modulemode) { +pr_err ("omap_hwmod: %s shares modulemode, but doesn't specify any modulemode control type\n" , + oh->name); +return -EINVAL ; + } +list_add_tail (&oh->node, &omap_hwmod_list);INIT_LIST_HEAD (&oh->master_ports);
@@ -2759,6 +2858,16 @@ static int __init _register(struct omap_hwmod *oh) oh->_state = _HWMOD_STATE_REGISTERED; +if (oh->prcm.omap4.mmode_ref) { +struct mmode_shared *mmode = oh->prcm.omap4.mmode_ref; + +if (!mmode->inited) { +spin_lock_init (&mmode->lock); + mmode->refcnt =0 ; + mmode->inited = true; + } + } +/* * XXX Rather than doing a strcmp(), this should test a flag * set in the hwmod data, inserted by the autogenerator code.
arch/arm/mach-omap2/omap_hwmod.h +26 -9
@@ -432,6 +432,21 @@ struct omap_hwmod_omap2_prcm { };/* +* struct for managing modulemode field shared accross IP blocks +* @lock: spinlock to searilze enables/disables performed by different +* hwmods sharing the same modulemode field +* @refcnt: keep a refcount of the enabled hwmods using this modulemode +* field +* @inited: a flag to track whether the struct has been initialized or +* not +*/ +struct mmode_shared { +spinlock_t lock; +unsigned refcnt; +bool inited; +}; + +/* * Possible values for struct omap_hwmod_omap4_prcm.flags * * HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT: Some IP blocks don't have a PRCM
@@ -450,6 +465,7 @@ struct omap_hwmod_omap2_prcm {* @submodule_wkdep_bit: bit shift of the WKDEP range * @flags: PRCM register capabilities for this IP block * @modulemode: allowable modulemodes +* @mmode_ref: pointer to modulemode struct shared by multiple hwmods * @context_lost_counter: Count of module level context lost * * If @lostcontext_mask is not defined, context loss check code uses
@@ -458,15 +474,16 @@ struct omap_hwmod_omap2_prcm {* more hwmods. */ struct omap_hwmod_omap4_prcm { -u16 clkctrl_offs; -u16 rstctrl_offs; -u16 rstst_offs; -u16 context_offs; -u32 lostcontext_mask; -u8 submodule_wkdep_bit; -u8 modulemode; -u8 flags; -int context_lost_counter; +u16 clkctrl_offs; +u16 rstctrl_offs; +u16 rstst_offs; +u16 context_offs; +u32 lostcontext_mask; +u8 submodule_wkdep_bit; +u8 modulemode; +struct mmode_shared *mmode_ref; +u8 flags; +int context_lost_counter; };
Signature · 1 line
1.9.1
RFC v2 2/2 arm: omap5 hwmod data: Example: Make DSS hwmods share MODULEMODE fields
In reply to Archit TanejaDSS hwmods share the MODULEMODE field. Create a new 'mmode_shared' struct which the DSS hwmods refer to.
This will allow the hwmods to reset properly during boot, and not break things when the omapdss module is inserted.
(Note: hdmi and rfbi hwmods still don't reset properly as they don't have their mainclks as dss_dss_clk, this needs to be changed later).
--- arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 40 ++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 13 deletions(-)
arch/arm/mach-omap2/omap_hwmod_54xx_data.c +27 -13
@@ -337,6 +337,9 @@ static struct omap_hwmod omap54xx_dmic_hwmod = {* 'dss' class * display sub-system */ + +static struct mmode_shared dss_modulemode_ref; +static struct omap_hwmod_class_sysconfig omap54xx_dss_sysc = { .rev_offs =0x0000 , .syss_offs =0x0014 ,
@@ -364,9 +367,10 @@ static struct omap_hwmod omap54xx_dss_hwmod = { .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .context_offs = OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET, - .modulemode = MODULEMODE_SWCTRL, + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + .mmode_ref = &dss_modulemode_ref, }, }, .opt_clks = dss_opt_clks,
@@ -414,8 +418,10 @@ static struct omap_hwmod omap54xx_dss_dispc_hwmod = { .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .modulemode = MODULEMODE_SWCTRL, + .mmode_ref = &dss_modulemode_ref, }, }, .opt_clks = dss_dispc_opt_clks,
@@ -456,8 +462,10 @@ static struct omap_hwmod omap54xx_dss_dsi1_a_hwmod = { .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .modulemode = MODULEMODE_SWCTRL, + .mmode_ref = &dss_modulemode_ref, }, }, .opt_clks = dss_dsi1_a_opt_clks,
@@ -476,8 +484,10 @@ static struct omap_hwmod omap54xx_dss_dsi1_c_hwmod = { .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .modulemode = MODULEMODE_SWCTRL, + .mmode_ref = &dss_modulemode_ref, }, }, .opt_clks = dss_dsi1_c_opt_clks,
@@ -515,8 +525,10 @@ static struct omap_hwmod omap54xx_dss_hdmi_hwmod = { .main_clk = "dss_48mhz_clk", .prcm = { .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .modulemode = MODULEMODE_SWCTRL, + .mmode_ref = &dss_modulemode_ref, }, }, .opt_clks = dss_hdmi_opt_clks,
@@ -554,8 +566,10 @@ static struct omap_hwmod omap54xx_dss_rfbi_hwmod = { .clkdm_name = "dss_clkdm", .prcm = { .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + .modulemode = MODULEMODE_SWCTRL, + .mmode_ref = &dss_modulemode_ref, }, }, .opt_clks = dss_rfbi_opt_clks,
Signature · 1 line
1.9.1