diff mbox

[01/11,RESEND] ARM: OMAP: DRA7: hwmod: Add data for McASP3

Message ID 1442326206-30192-1-git-send-email-peter.ujfalusi@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Peter Ujfalusi Sept. 15, 2015, 2:10 p.m. UTC
McASP3 is used by default on DRA7x based boards for audio.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
Hi Paul,

this patch is part of my earlier series and as Tony suggested I'll resend the
hwmod patch for you to review since I missed you from the TO in the series.

The original series:
https://www.mail-archive.com/linux-omap@vger.kernel.org/msg119319.html

Regards,
Peter

 arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 41 +++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

Comments

Peter Ujfalusi Sept. 25, 2015, 7:02 a.m. UTC | #1
Paul,

On 09/15/2015 05:10 PM, Peter Ujfalusi wrote:
> McASP3 is used by default on DRA7x based boards for audio.

Can you take a look at this patch? It would be great to have this one reviewed
so the audio support for the dra7 family could be applied by Tony.

Thanks,
Péter

> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
> Hi Paul,
> 
> this patch is part of my earlier series and as Tony suggested I'll resend the
> hwmod patch for you to review since I missed you from the TO in the series.
> 
> The original series:
> https://www.mail-archive.com/linux-omap@vger.kernel.org/msg119319.html
> 
> Regards,
> Peter
> 
>  arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 41 +++++++++++++++++++++++++++++++
>  1 file changed, 41 insertions(+)
> 
> diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> index 562247bced49..c38b7fa30c27 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> @@ -1298,6 +1298,38 @@ static struct omap_hwmod dra7xx_mcspi4_hwmod = {
>  };
>  
>  /*
> + * 'mcasp' class
> + *
> + */
> +static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
> +	.sysc_offs	= 0x0004,
> +	.sysc_flags	= SYSC_HAS_SIDLEMODE,
> +	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
> +	.sysc_fields	= &omap_hwmod_sysc_type3,
> +};
> +
> +static struct omap_hwmod_class dra7xx_mcasp_hwmod_class = {
> +	.name	= "mcasp",
> +	.sysc	= &dra7xx_mcasp_sysc,
> +};
> +
> +/* mcasp3 */
> +static struct omap_hwmod dra7xx_mcasp3_hwmod = {
> +	.name		= "mcasp3",
> +	.class		= &dra7xx_mcasp_hwmod_class,
> +	.clkdm_name	= "l4per2_clkdm",
> +	.main_clk	= "mcasp3_ahclkx_mux",
> +	.flags		= HWMOD_SWSUP_SIDLE,
> +	.prcm = {
> +		.omap4 = {
> +			.clkctrl_offs = DRA7XX_CM_L4PER2_MCASP3_CLKCTRL_OFFSET,
> +			.context_offs = DRA7XX_RM_L4PER2_MCASP3_CONTEXT_OFFSET,
> +			.modulemode   = MODULEMODE_SWCTRL,
> +		},
> +	},
> +};
> +
> +/*
>   * 'mmc' class
>   *
>   */
> @@ -2566,6 +2598,14 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = {
>  	.user		= OCP_USER_MPU | OCP_USER_SDMA,
>  };
>  
> +/* l4_per2 -> mcasp3 */
> +static struct omap_hwmod_ocp_if dra7xx_l4_per2__mcasp3 = {
> +	.master		= &dra7xx_l4_per2_hwmod,
> +	.slave		= &dra7xx_mcasp3_hwmod,
> +	.clk		= "l3_iclk_div",
> +	.user		= OCP_USER_MPU | OCP_USER_SDMA,
> +};
> +
>  static struct omap_hwmod_addr_space dra7xx_elm_addrs[] = {
>  	{
>  		.pa_start	= 0x48078000,
> @@ -3338,6 +3378,7 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
>  	&dra7xx_l4_wkup__dcan1,
>  	&dra7xx_l4_per2__dcan2,
>  	&dra7xx_l4_per2__cpgmac0,
> +	&dra7xx_l4_per2__mcasp3,
>  	&dra7xx_gmac__mdio,
>  	&dra7xx_l4_cfg__dma_system,
>  	&dra7xx_l3_main_1__dss,
>
Paul Walmsley Sept. 27, 2015, 7:02 a.m. UTC | #2
Hi Péter,

a few comments:

On Tue, 15 Sep 2015, Peter Ujfalusi wrote:

> McASP3 is used by default on DRA7x based boards for audio.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
> Hi Paul,
> 
> this patch is part of my earlier series and as Tony suggested I'll resend the
> hwmod patch for you to review since I missed you from the TO in the series.
> 
> The original series:
> https://www.mail-archive.com/linux-omap@vger.kernel.org/msg119319.html
> 
> Regards,
> Peter
> 
>  arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 41 +++++++++++++++++++++++++++++++
>  1 file changed, 41 insertions(+)
> 
> diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> index 562247bced49..c38b7fa30c27 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> @@ -1298,6 +1298,38 @@ static struct omap_hwmod dra7xx_mcspi4_hwmod = {
>  };
>  
>  /*
> + * 'mcasp' class
> + *
> + */
> +static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
> +	.sysc_offs	= 0x0004,
> +	.sysc_flags	= SYSC_HAS_SIDLEMODE,
> +	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
> +	.sysc_fields	= &omap_hwmod_sysc_type3,
> +};
> +
> +static struct omap_hwmod_class dra7xx_mcasp_hwmod_class = {
> +	.name	= "mcasp",
> +	.sysc	= &dra7xx_mcasp_sysc,
> +};
> +
> +/* mcasp3 */
> +static struct omap_hwmod dra7xx_mcasp3_hwmod = {
> +	.name		= "mcasp3",
> +	.class		= &dra7xx_mcasp_hwmod_class,
> +	.clkdm_name	= "l4per2_clkdm",
> +	.main_clk	= "mcasp3_ahclkx_mux",

I'd expect this clock to be something derived from mcasp3_aux_gfclk, 
according to Table 24-408 "Clocks and Resets" of SPRUHZ6.  Could you 
please doublecheck this?

> +	.flags		= HWMOD_SWSUP_SIDLE,

Is this needed?  If it is, please add a brief comment describing the issue 
or bug that it's working around.

> +	.prcm = {
> +		.omap4 = {
> +			.clkctrl_offs = DRA7XX_CM_L4PER2_MCASP3_CLKCTRL_OFFSET,
> +			.context_offs = DRA7XX_RM_L4PER2_MCASP3_CONTEXT_OFFSET,
> +			.modulemode   = MODULEMODE_SWCTRL,
> +		},
> +	},
> +};
> +
> +/*
>   * 'mmc' class
>   *
>   */
> @@ -2566,6 +2598,14 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = {
>  	.user		= OCP_USER_MPU | OCP_USER_SDMA,
>  };
>  
> +/* l4_per2 -> mcasp3 */
> +static struct omap_hwmod_ocp_if dra7xx_l4_per2__mcasp3 = {
> +	.master		= &dra7xx_l4_per2_hwmod,
> +	.slave		= &dra7xx_mcasp3_hwmod,

So this is the low-speed control/register access port, where the MPU 
writes to the McASP3 config registers...

> +	.clk		= "l3_iclk_div",

... and thus this interface clock doesn't look right for this port, since 
it's most likely generated from the L4PER2, where this port is connected.  
So it should probably be "l4_iclk_div".
 
> +	.user		= OCP_USER_MPU | OCP_USER_SDMA,
> +};

There's another struct omap_hwmod_ocp_if record missing: the high-speed 
bus-master port that the McASP3 uses to DMA audio data.  This port should 
most likely be clocked with "l3_iclk_div" per Table 24-408 "Clocks and 
Resets".  This port is also where the registers described in Table 24-555 
"MCASP_DAT Register Summary 3" L3_MAIN column are exposed.  You've got 
that address map range blocked out in your DT data reg property, and 
associated with this device, right? 0x46000000?

> +
>  static struct omap_hwmod_addr_space dra7xx_elm_addrs[] = {
>  	{
>  		.pa_start	= 0x48078000,
> @@ -3338,6 +3378,7 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
>  	&dra7xx_l4_wkup__dcan1,
>  	&dra7xx_l4_per2__dcan2,
>  	&dra7xx_l4_per2__cpgmac0,
> +	&dra7xx_l4_per2__mcasp3,
>  	&dra7xx_gmac__mdio,
>  	&dra7xx_l4_cfg__dma_system,
>  	&dra7xx_l3_main_1__dss,
> -- 
> 2.5.0
> 


- Paul
Peter Ujfalusi Sept. 30, 2015, 10:06 a.m. UTC | #3
Paul,

On 09/27/2015 10:02 AM, Paul Walmsley wrote:
>>  /*
>> + * 'mcasp' class
>> + *
>> + */
>> +static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
>> +	.sysc_offs	= 0x0004,
>> +	.sysc_flags	= SYSC_HAS_SIDLEMODE,
>> +	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
>> +	.sysc_fields	= &omap_hwmod_sysc_type3,
>> +};
>> +
>> +static struct omap_hwmod_class dra7xx_mcasp_hwmod_class = {
>> +	.name	= "mcasp",
>> +	.sysc	= &dra7xx_mcasp_sysc,
>> +};
>> +
>> +/* mcasp3 */
>> +static struct omap_hwmod dra7xx_mcasp3_hwmod = {
>> +	.name		= "mcasp3",
>> +	.class		= &dra7xx_mcasp_hwmod_class,
>> +	.clkdm_name	= "l4per2_clkdm",
>> +	.main_clk	= "mcasp3_ahclkx_mux",
> 
> I'd expect this clock to be something derived from mcasp3_aux_gfclk, 
> according to Table 24-408 "Clocks and Resets" of SPRUHZ6.  Could you 
> please doublecheck this?

I can not explain this. If I change the main_clk to "mcasp3_aux_gfclk_mux"
then I can not access to McASP3 register at all.
I don't see anything popping out in the clock data, nor in other places.

>> +	.flags		= HWMOD_SWSUP_SIDLE,

Not sure why this has been added, I can not find any pointers regarding to
this and everything is working w/o this flag. Will remove it in v2.


> Is this needed?  If it is, please add a brief comment describing the issue 
> or bug that it's working around.
> 
>> +	.prcm = {
>> +		.omap4 = {
>> +			.clkctrl_offs = DRA7XX_CM_L4PER2_MCASP3_CLKCTRL_OFFSET,
>> +			.context_offs = DRA7XX_RM_L4PER2_MCASP3_CONTEXT_OFFSET,
>> +			.modulemode   = MODULEMODE_SWCTRL,
>> +		},
>> +	},
>> +};
>> +
>> +/*
>>   * 'mmc' class
>>   *
>>   */
>> @@ -2566,6 +2598,14 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = {
>>  	.user		= OCP_USER_MPU | OCP_USER_SDMA,
>>  };
>>  
>> +/* l4_per2 -> mcasp3 */
>> +static struct omap_hwmod_ocp_if dra7xx_l4_per2__mcasp3 = {
>> +	.master		= &dra7xx_l4_per2_hwmod,
>> +	.slave		= &dra7xx_mcasp3_hwmod,
> 
> So this is the low-speed control/register access port, where the MPU 
> writes to the McASP3 config registers...
> 
>> +	.clk		= "l3_iclk_div",
> 
> ... and thus this interface clock doesn't look right for this port, since 
> it's most likely generated from the L4PER2, where this port is connected.  
> So it should probably be "l4_iclk_div".

There is no "l4_iclk_div" for dra7xx. Looking around the file all other script
generated data uses "l3_iclk_div" for IPs under dra7xx_l4_per2_hwmod.

Tero: do you know the reason for this?

>  
>> +	.user		= OCP_USER_MPU | OCP_USER_SDMA,
>> +};
> 
> There's another struct omap_hwmod_ocp_if record missing: the high-speed 
> bus-master port that the McASP3 uses to DMA audio data.  This port should 
> most likely be clocked with "l3_iclk_div" per Table 24-408 "Clocks and 
> Resets".  This port is also where the registers described in Table 24-555 
> "MCASP_DAT Register Summary 3" L3_MAIN column are exposed.  You've got 
> that address map range blocked out in your DT data reg property, and 
> associated with this device, right? 0x46000000?

Yes, the McASP3-dat port is not used ATM. This is over the L3 interconnect and
due to a feature we can not use it with sDMA (constant addressing is not
supported through L3 interconnect for DMAs).
We could use eDMA, but there are complications regarding to that.
At the moment we are using the sDMA through the L4 interconnect address space.

> 
>> +
>>  static struct omap_hwmod_addr_space dra7xx_elm_addrs[] = {
>>  	{
>>  		.pa_start	= 0x48078000,
>> @@ -3338,6 +3378,7 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
>>  	&dra7xx_l4_wkup__dcan1,
>>  	&dra7xx_l4_per2__dcan2,
>>  	&dra7xx_l4_per2__cpgmac0,
>> +	&dra7xx_l4_per2__mcasp3,
>>  	&dra7xx_gmac__mdio,
>>  	&dra7xx_l4_cfg__dma_system,
>>  	&dra7xx_l3_main_1__dss,
>> -- 
>> 2.5.0
>>
> 
> 
> - Paul
>
Tero Kristo Sept. 30, 2015, 1 p.m. UTC | #4
On 09/30/2015 01:06 PM, Peter Ujfalusi wrote:
> Paul,
>
> On 09/27/2015 10:02 AM, Paul Walmsley wrote:
>>>   /*
>>> + * 'mcasp' class
>>> + *
>>> + */
>>> +static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
>>> +	.sysc_offs	= 0x0004,
>>> +	.sysc_flags	= SYSC_HAS_SIDLEMODE,
>>> +	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
>>> +	.sysc_fields	= &omap_hwmod_sysc_type3,
>>> +};
>>> +
>>> +static struct omap_hwmod_class dra7xx_mcasp_hwmod_class = {
>>> +	.name	= "mcasp",
>>> +	.sysc	= &dra7xx_mcasp_sysc,
>>> +};
>>> +
>>> +/* mcasp3 */
>>> +static struct omap_hwmod dra7xx_mcasp3_hwmod = {
>>> +	.name		= "mcasp3",
>>> +	.class		= &dra7xx_mcasp_hwmod_class,
>>> +	.clkdm_name	= "l4per2_clkdm",
>>> +	.main_clk	= "mcasp3_ahclkx_mux",
>>
>> I'd expect this clock to be something derived from mcasp3_aux_gfclk,
>> according to Table 24-408 "Clocks and Resets" of SPRUHZ6.  Could you
>> please doublecheck this?
>
> I can not explain this. If I change the main_clk to "mcasp3_aux_gfclk_mux"
> then I can not access to McASP3 register at all.
> I don't see anything popping out in the clock data, nor in other places.
>
>>> +	.flags		= HWMOD_SWSUP_SIDLE,
>
> Not sure why this has been added, I can not find any pointers regarding to
> this and everything is working w/o this flag. Will remove it in v2.
>
>
>> Is this needed?  If it is, please add a brief comment describing the issue
>> or bug that it's working around.
>>
>>> +	.prcm = {
>>> +		.omap4 = {
>>> +			.clkctrl_offs = DRA7XX_CM_L4PER2_MCASP3_CLKCTRL_OFFSET,
>>> +			.context_offs = DRA7XX_RM_L4PER2_MCASP3_CONTEXT_OFFSET,
>>> +			.modulemode   = MODULEMODE_SWCTRL,
>>> +		},
>>> +	},
>>> +};
>>> +
>>> +/*
>>>    * 'mmc' class
>>>    *
>>>    */
>>> @@ -2566,6 +2598,14 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = {
>>>   	.user		= OCP_USER_MPU | OCP_USER_SDMA,
>>>   };
>>>
>>> +/* l4_per2 -> mcasp3 */
>>> +static struct omap_hwmod_ocp_if dra7xx_l4_per2__mcasp3 = {
>>> +	.master		= &dra7xx_l4_per2_hwmod,
>>> +	.slave		= &dra7xx_mcasp3_hwmod,
>>
>> So this is the low-speed control/register access port, where the MPU
>> writes to the McASP3 config registers...
>>
>>> +	.clk		= "l3_iclk_div",
>>
>> ... and thus this interface clock doesn't look right for this port, since
>> it's most likely generated from the L4PER2, where this port is connected.
>> So it should probably be "l4_iclk_div".
>
> There is no "l4_iclk_div" for dra7xx. Looking around the file all other script
> generated data uses "l3_iclk_div" for IPs under dra7xx_l4_per2_hwmod.
>
> Tero: do you know the reason for this?

This comes from the autogen generated data. Looking at the hwdb data for 
dra7, it seems l3 clock is defined as the OCP input clock for most of 
the modules.

Looking at TRM, we also have L3 ICK defined as the interface clock for 
GPIO modules for example, and also mcasp modules.

I think this is just a documentation issue and we are missing a divide 
by 2 from all interface clocks, the interface clocks are coming from l4 
interconnects and the interconnect chapter still clearly states that the 
l4 clock is l3 clock / 2.

-Tero

>
>>
>>> +	.user		= OCP_USER_MPU | OCP_USER_SDMA,
>>> +};
>>
>> There's another struct omap_hwmod_ocp_if record missing: the high-speed
>> bus-master port that the McASP3 uses to DMA audio data.  This port should
>> most likely be clocked with "l3_iclk_div" per Table 24-408 "Clocks and
>> Resets".  This port is also where the registers described in Table 24-555
>> "MCASP_DAT Register Summary 3" L3_MAIN column are exposed.  You've got
>> that address map range blocked out in your DT data reg property, and
>> associated with this device, right? 0x46000000?
>
> Yes, the McASP3-dat port is not used ATM. This is over the L3 interconnect and
> due to a feature we can not use it with sDMA (constant addressing is not
> supported through L3 interconnect for DMAs).
> We could use eDMA, but there are complications regarding to that.
> At the moment we are using the sDMA through the L4 interconnect address space.
>
>>
>>> +
>>>   static struct omap_hwmod_addr_space dra7xx_elm_addrs[] = {
>>>   	{
>>>   		.pa_start	= 0x48078000,
>>> @@ -3338,6 +3378,7 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
>>>   	&dra7xx_l4_wkup__dcan1,
>>>   	&dra7xx_l4_per2__dcan2,
>>>   	&dra7xx_l4_per2__cpgmac0,
>>> +	&dra7xx_l4_per2__mcasp3,
>>>   	&dra7xx_gmac__mdio,
>>>   	&dra7xx_l4_cfg__dma_system,
>>>   	&dra7xx_l3_main_1__dss,
>>> --
>>> 2.5.0
>>>
>>
>>
>> - Paul
>>
>
>
Peter Ujfalusi Oct. 1, 2015, 5:57 a.m. UTC | #5
On 09/30/2015 04:00 PM, Tero Kristo wrote:
>>>> +/* l4_per2 -> mcasp3 */
>>>> +static struct omap_hwmod_ocp_if dra7xx_l4_per2__mcasp3 = {
>>>> +    .master        = &dra7xx_l4_per2_hwmod,
>>>> +    .slave        = &dra7xx_mcasp3_hwmod,
>>>
>>> So this is the low-speed control/register access port, where the MPU
>>> writes to the McASP3 config registers...
>>>
>>>> +    .clk        = "l3_iclk_div",
>>>
>>> ... and thus this interface clock doesn't look right for this port, since
>>> it's most likely generated from the L4PER2, where this port is connected.
>>> So it should probably be "l4_iclk_div".
>>
>> There is no "l4_iclk_div" for dra7xx. Looking around the file all other script
>> generated data uses "l3_iclk_div" for IPs under dra7xx_l4_per2_hwmod.
>>
>> Tero: do you know the reason for this?
> 
> This comes from the autogen generated data. Looking at the hwdb data for dra7,
> it seems l3 clock is defined as the OCP input clock for most of the modules.
> 
> Looking at TRM, we also have L3 ICK defined as the interface clock for GPIO
> modules for example, and also mcasp modules.
> 
> I think this is just a documentation issue and we are missing a divide by 2
> from all interface clocks, the interface clocks are coming from l4
> interconnects and the interconnect chapter still clearly states that the l4
> clock is l3 clock / 2.

It seams that we have the clock node for the l4_iclk_div, but it is called as
l4_root_clk_div.

I will use this in the mcasp3 hwmod patch.
Paul Walmsley Oct. 2, 2015, 9:07 a.m. UTC | #6
Hello Péter,

On Wed, 30 Sep 2015, Peter Ujfalusi wrote:

> On 09/27/2015 10:02 AM, Paul Walmsley wrote:
> >>  /*
> >> + * 'mcasp' class
> >> + *
> >> + */
> >> +static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
> >> +	.sysc_offs	= 0x0004,
> >> +	.sysc_flags	= SYSC_HAS_SIDLEMODE,
> >> +	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
> >> +	.sysc_fields	= &omap_hwmod_sysc_type3,
> >> +};
> >> +
> >> +static struct omap_hwmod_class dra7xx_mcasp_hwmod_class = {
> >> +	.name	= "mcasp",
> >> +	.sysc	= &dra7xx_mcasp_sysc,
> >> +};
> >> +
> >> +/* mcasp3 */
> >> +static struct omap_hwmod dra7xx_mcasp3_hwmod = {
> >> +	.name		= "mcasp3",
> >> +	.class		= &dra7xx_mcasp_hwmod_class,
> >> +	.clkdm_name	= "l4per2_clkdm",
> >> +	.main_clk	= "mcasp3_ahclkx_mux",
> > 
> > I'd expect this clock to be something derived from mcasp3_aux_gfclk, 
> > according to Table 24-408 "Clocks and Resets" of SPRUHZ6.  Could you 
> > please doublecheck this?
> 
> I can not explain this. If I change the main_clk to "mcasp3_aux_gfclk_mux"
> then I can not access to McASP3 register at all.
> I don't see anything popping out in the clock data, nor in other places.

OK thank you for testing that.  Maybe just add a brief comment along those 
lines in the hwmod data, above the structure record declaration?

> >> +	.flags		= HWMOD_SWSUP_SIDLE,
> 
> Not sure why this has been added, I can not find any pointers regarding to
> this and everything is working w/o this flag. Will remove it in v2.

OK thanks.  

> >> @@ -2566,6 +2598,14 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = {
> >>  	.user		= OCP_USER_MPU | OCP_USER_SDMA,
> >>  };
> >>  
> >> +/* l4_per2 -> mcasp3 */
> >> +static struct omap_hwmod_ocp_if dra7xx_l4_per2__mcasp3 = {
> >> +	.master		= &dra7xx_l4_per2_hwmod,
> >> +	.slave		= &dra7xx_mcasp3_hwmod,
> > 
> > So this is the low-speed control/register access port, where the MPU 
> > writes to the McASP3 config registers...
> > 
> >> +	.clk		= "l3_iclk_div",
> > 
> > ... and thus this interface clock doesn't look right for this port, since 
> > it's most likely generated from the L4PER2, where this port is connected.  
> > So it should probably be "l4_iclk_div".
> 
> There is no "l4_iclk_div" for dra7xx. Looking around the file all other script
> generated data uses "l3_iclk_div" for IPs under dra7xx_l4_per2_hwmod.
> 
> Tero: do you know the reason for this?

Sounds like from your followup E-mail that the clock name to use in the 
kernel is "l4_root_clk_div", which sounds fine to me.  (Haven't looked 
closely at the clock data, though.)

> >> +	.user		= OCP_USER_MPU | OCP_USER_SDMA,
> >> +};
> > 
> > There's another struct omap_hwmod_ocp_if record missing: the high-speed 
> > bus-master port that the McASP3 uses to DMA audio data.  This port should 
> > most likely be clocked with "l3_iclk_div" per Table 24-408 "Clocks and 
> > Resets".  This port is also where the registers described in Table 24-555 
> > "MCASP_DAT Register Summary 3" L3_MAIN column are exposed.  You've got 
> > that address map range blocked out in your DT data reg property, and 
> > associated with this device, right? 0x46000000?
> 
> Yes, the McASP3-dat port is not used ATM. This is over the L3 interconnect and
> due to a feature we can not use it with sDMA (constant addressing is not
> supported through L3 interconnect for DMAs).
> We could use eDMA, but there are complications regarding to that.
> At the moment we are using the sDMA through the L4 interconnect address space.

OK thanks for the explanation.  The hwmod code prevents links from being 
registered if no initiator 'users' are listed, so sounds like we should 
leave it out for now.  Could you add a brief comment, similar to your 
paragraph above, in the data, in case others wonder about the L3 link?

After those changes are made, feel free to add my ack.


Köszönöm,

- Paul
Peter Ujfalusi Oct. 2, 2015, 11:22 a.m. UTC | #7
Paul,

On 10/02/2015 12:07 PM, Paul Walmsley wrote:
> Hello Péter,
> 
> On Wed, 30 Sep 2015, Peter Ujfalusi wrote:
> 
>> On 09/27/2015 10:02 AM, Paul Walmsley wrote:
>>>>  /*
>>>> + * 'mcasp' class
>>>> + *
>>>> + */
>>>> +static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
>>>> +	.sysc_offs	= 0x0004,
>>>> +	.sysc_flags	= SYSC_HAS_SIDLEMODE,
>>>> +	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
>>>> +	.sysc_fields	= &omap_hwmod_sysc_type3,
>>>> +};
>>>> +
>>>> +static struct omap_hwmod_class dra7xx_mcasp_hwmod_class = {
>>>> +	.name	= "mcasp",
>>>> +	.sysc	= &dra7xx_mcasp_sysc,
>>>> +};
>>>> +
>>>> +/* mcasp3 */
>>>> +static struct omap_hwmod dra7xx_mcasp3_hwmod = {
>>>> +	.name		= "mcasp3",
>>>> +	.class		= &dra7xx_mcasp_hwmod_class,
>>>> +	.clkdm_name	= "l4per2_clkdm",
>>>> +	.main_clk	= "mcasp3_ahclkx_mux",
>>>
>>> I'd expect this clock to be something derived from mcasp3_aux_gfclk, 
>>> according to Table 24-408 "Clocks and Resets" of SPRUHZ6.  Could you 
>>> please doublecheck this?
>>
>> I can not explain this. If I change the main_clk to "mcasp3_aux_gfclk_mux"
>> then I can not access to McASP3 register at all.
>> I don't see anything popping out in the clock data, nor in other places.
> 
> OK thank you for testing that.  Maybe just add a brief comment along those 
> lines in the hwmod data, above the structure record declaration?

Now I more or less figured out the root of the issue. According to the
documentations the McASP in dra7xx family has following clocks:
ICLK - interface clock
GFCLK - functional clock
AHCLKX - Transmit high-frequency master clock
AHCLKR - Receive high-frequency master clock (on selected instances)

In order to access registers all of these clock lines must have valid clock
signal. No other SoC with McASP has this setup.
As for why things seams to work when mcasp3_ahclkx_mux is set as main_clk and
mcasp3_aux_gfclk_mux is not handled at all?
The mcasp3_aux_gfclk_mux by default is from PER_ABE_X1GFCLK we never change
this. On dra7/72 evm the AHCLKX is reparented to ATL2 clock.
When with pm_runtime we enable the device, the mcasp3_ahclkx_mux will be
enabled by the SW (and ATL as well) _and_ the mcasp3_aux_gfclk_mux path will
be enabled by HW w/o SW.
The reason why I have had crash when I switched the main_clk to
mcasp3_aux_gfclk_mux is that even the path for the mcasp3_ahclkx_mux is
enabled by the HW, the ATL itself was not enabled, so it was not generating
the needed clocks. Same goes backwards for the gfclk: if I reparent it to
let's say HDMI clock - which is not present, and handle the ahclkx clock I
have similar crash.
All in all: the McASP3 needs ICLK and both FCLK and AHCLKX to be running in
order to be able to access registers.

This current setup works fine, the only issue I see is that the refcounts for
the mcasp3_aux_gfclk_mux path is not reflecting the reality.

With Tero we looked at different angles of this and how to solve it w/o
considering it as a hack.
Either we go with the hwmod data with main_clk set to mcasp3_ahclkx_mux and
document it in a comment, or:
Add new flag HWMOD_OPT_CLKS_NEEDED to hwmods to use to tell that the optional
clocks are not really optional as they are needed to be enabled in order to
access to the IP. In omap_hwmod.c's _enable_clocks() and _disable_clocks() we
call _enable_optional_clocks()/_disable_optional_clocks() if the flag is set
for the hwmod and add the ahclkx_mux as optional clock for McASP3.

>>>> +	.user		= OCP_USER_MPU | OCP_USER_SDMA,
>>>> +};
>>>
>>> There's another struct omap_hwmod_ocp_if record missing: the high-speed 
>>> bus-master port that the McASP3 uses to DMA audio data.  This port should 
>>> most likely be clocked with "l3_iclk_div" per Table 24-408 "Clocks and 
>>> Resets".  This port is also where the registers described in Table 24-555 
>>> "MCASP_DAT Register Summary 3" L3_MAIN column are exposed.  You've got 
>>> that address map range blocked out in your DT data reg property, and 
>>> associated with this device, right? 0x46000000?
>>
>> Yes, the McASP3-dat port is not used ATM. This is over the L3 interconnect and
>> due to a feature we can not use it with sDMA (constant addressing is not
>> supported through L3 interconnect for DMAs).
>> We could use eDMA, but there are complications regarding to that.
>> At the moment we are using the sDMA through the L4 interconnect address space.
> 
> OK thanks for the explanation.  The hwmod code prevents links from being 
> registered if no initiator 'users' are listed, so sounds like we should 
> leave it out for now.  Could you add a brief comment, similar to your 
> paragraph above, in the data, in case others wonder about the L3 link?

Sure, I'll do that.

> 
> After those changes are made, feel free to add my ack.

I'll wait for your comment regarding to the multiple main_clk need for the
McASP3 before I'll send the next version.

> Köszönöm,

:D

> 
> - Paul
>
Peter Ujfalusi Oct. 2, 2015, 11:55 a.m. UTC | #8
On 10/02/2015 02:22 PM, Peter Ujfalusi wrote:
> Paul,
> 
> On 10/02/2015 12:07 PM, Paul Walmsley wrote:
>> Hello Péter,
>>
>> On Wed, 30 Sep 2015, Peter Ujfalusi wrote:
>>
>>> On 09/27/2015 10:02 AM, Paul Walmsley wrote:
>>>>>  /*
>>>>> + * 'mcasp' class
>>>>> + *
>>>>> + */
>>>>> +static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
>>>>> +	.sysc_offs	= 0x0004,
>>>>> +	.sysc_flags	= SYSC_HAS_SIDLEMODE,
>>>>> +	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
>>>>> +	.sysc_fields	= &omap_hwmod_sysc_type3,
>>>>> +};
>>>>> +
>>>>> +static struct omap_hwmod_class dra7xx_mcasp_hwmod_class = {
>>>>> +	.name	= "mcasp",
>>>>> +	.sysc	= &dra7xx_mcasp_sysc,
>>>>> +};
>>>>> +
>>>>> +/* mcasp3 */
>>>>> +static struct omap_hwmod dra7xx_mcasp3_hwmod = {
>>>>> +	.name		= "mcasp3",
>>>>> +	.class		= &dra7xx_mcasp_hwmod_class,
>>>>> +	.clkdm_name	= "l4per2_clkdm",
>>>>> +	.main_clk	= "mcasp3_ahclkx_mux",
>>>>
>>>> I'd expect this clock to be something derived from mcasp3_aux_gfclk, 
>>>> according to Table 24-408 "Clocks and Resets" of SPRUHZ6.  Could you 
>>>> please doublecheck this?
>>>
>>> I can not explain this. If I change the main_clk to "mcasp3_aux_gfclk_mux"
>>> then I can not access to McASP3 register at all.
>>> I don't see anything popping out in the clock data, nor in other places.
>>
>> OK thank you for testing that.  Maybe just add a brief comment along those 
>> lines in the hwmod data, above the structure record declaration?
> 
> Now I more or less figured out the root of the issue. According to the
> documentations the McASP in dra7xx family has following clocks:
> ICLK - interface clock
> GFCLK - functional clock
> AHCLKX - Transmit high-frequency master clock
> AHCLKR - Receive high-frequency master clock (on selected instances)
> 
> In order to access registers all of these clock lines must have valid clock
> signal. No other SoC with McASP has this setup.
> As for why things seams to work when mcasp3_ahclkx_mux is set as main_clk and
> mcasp3_aux_gfclk_mux is not handled at all?
> The mcasp3_aux_gfclk_mux by default is from PER_ABE_X1GFCLK we never change
> this. On dra7/72 evm the AHCLKX is reparented to ATL2 clock.
> When with pm_runtime we enable the device, the mcasp3_ahclkx_mux will be
> enabled by the SW (and ATL as well) _and_ the mcasp3_aux_gfclk_mux path will
> be enabled by HW w/o SW.
> The reason why I have had crash when I switched the main_clk to
> mcasp3_aux_gfclk_mux is that even the path for the mcasp3_ahclkx_mux is
> enabled by the HW, the ATL itself was not enabled, so it was not generating
> the needed clocks. Same goes backwards for the gfclk: if I reparent it to
> let's say HDMI clock - which is not present, and handle the ahclkx clock I
> have similar crash.
> All in all: the McASP3 needs ICLK and both FCLK and AHCLKX to be running in
> order to be able to access registers.
> 
> This current setup works fine, the only issue I see is that the refcounts for
> the mcasp3_aux_gfclk_mux path is not reflecting the reality.
> 
> With Tero we looked at different angles of this and how to solve it w/o
> considering it as a hack.
> Either we go with the hwmod data with main_clk set to mcasp3_ahclkx_mux and
> document it in a comment, or:
> Add new flag HWMOD_OPT_CLKS_NEEDED to hwmods to use to tell that the optional
> clocks are not really optional as they are needed to be enabled in order to
> access to the IP. In omap_hwmod.c's _enable_clocks() and _disable_clocks() we
> call _enable_optional_clocks()/_disable_optional_clocks() if the flag is set
> for the hwmod and add the ahclkx_mux as optional clock for McASP3.

This might be awkward to say that the optional clocks are not optional,
probably would be better to add:
struct omap_hwmod {
	...
	struct omap_hwmod_opt_clk	*needed_clks;
	...
	u8				needed_clks_cnt;
	...
};

and use the needed_clks in _init_main_clk()/_enable_clocks()/_disable_clocks() ?
Peter Ujfalusi Oct. 2, 2015, 12:48 p.m. UTC | #9
On 10/02/2015 02:55 PM, Peter Ujfalusi wrote:
> On 10/02/2015 02:22 PM, Peter Ujfalusi wrote:
>> Paul,
>>
>> On 10/02/2015 12:07 PM, Paul Walmsley wrote:
>>> Hello Péter,
>>>
>>> On Wed, 30 Sep 2015, Peter Ujfalusi wrote:
>>>
>>>> On 09/27/2015 10:02 AM, Paul Walmsley wrote:
>>>>>>  /*
>>>>>> + * 'mcasp' class
>>>>>> + *
>>>>>> + */
>>>>>> +static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
>>>>>> +	.sysc_offs	= 0x0004,
>>>>>> +	.sysc_flags	= SYSC_HAS_SIDLEMODE,
>>>>>> +	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
>>>>>> +	.sysc_fields	= &omap_hwmod_sysc_type3,
>>>>>> +};
>>>>>> +
>>>>>> +static struct omap_hwmod_class dra7xx_mcasp_hwmod_class = {
>>>>>> +	.name	= "mcasp",
>>>>>> +	.sysc	= &dra7xx_mcasp_sysc,
>>>>>> +};
>>>>>> +
>>>>>> +/* mcasp3 */
>>>>>> +static struct omap_hwmod dra7xx_mcasp3_hwmod = {
>>>>>> +	.name		= "mcasp3",
>>>>>> +	.class		= &dra7xx_mcasp_hwmod_class,
>>>>>> +	.clkdm_name	= "l4per2_clkdm",
>>>>>> +	.main_clk	= "mcasp3_ahclkx_mux",
>>>>>
>>>>> I'd expect this clock to be something derived from mcasp3_aux_gfclk, 
>>>>> according to Table 24-408 "Clocks and Resets" of SPRUHZ6.  Could you 
>>>>> please doublecheck this?
>>>>
>>>> I can not explain this. If I change the main_clk to "mcasp3_aux_gfclk_mux"
>>>> then I can not access to McASP3 register at all.
>>>> I don't see anything popping out in the clock data, nor in other places.
>>>
>>> OK thank you for testing that.  Maybe just add a brief comment along those 
>>> lines in the hwmod data, above the structure record declaration?
>>
>> Now I more or less figured out the root of the issue. According to the
>> documentations the McASP in dra7xx family has following clocks:
>> ICLK - interface clock
>> GFCLK - functional clock
>> AHCLKX - Transmit high-frequency master clock
>> AHCLKR - Receive high-frequency master clock (on selected instances)
>>
>> In order to access registers all of these clock lines must have valid clock
>> signal. No other SoC with McASP has this setup.
>> As for why things seams to work when mcasp3_ahclkx_mux is set as main_clk and
>> mcasp3_aux_gfclk_mux is not handled at all?
>> The mcasp3_aux_gfclk_mux by default is from PER_ABE_X1GFCLK we never change
>> this. On dra7/72 evm the AHCLKX is reparented to ATL2 clock.
>> When with pm_runtime we enable the device, the mcasp3_ahclkx_mux will be
>> enabled by the SW (and ATL as well) _and_ the mcasp3_aux_gfclk_mux path will
>> be enabled by HW w/o SW.
>> The reason why I have had crash when I switched the main_clk to
>> mcasp3_aux_gfclk_mux is that even the path for the mcasp3_ahclkx_mux is
>> enabled by the HW, the ATL itself was not enabled, so it was not generating
>> the needed clocks. Same goes backwards for the gfclk: if I reparent it to
>> let's say HDMI clock - which is not present, and handle the ahclkx clock I
>> have similar crash.
>> All in all: the McASP3 needs ICLK and both FCLK and AHCLKX to be running in
>> order to be able to access registers.
>>
>> This current setup works fine, the only issue I see is that the refcounts for
>> the mcasp3_aux_gfclk_mux path is not reflecting the reality.
>>
>> With Tero we looked at different angles of this and how to solve it w/o
>> considering it as a hack.
>> Either we go with the hwmod data with main_clk set to mcasp3_ahclkx_mux and
>> document it in a comment, or:
>> Add new flag HWMOD_OPT_CLKS_NEEDED to hwmods to use to tell that the optional
>> clocks are not really optional as they are needed to be enabled in order to
>> access to the IP. In omap_hwmod.c's _enable_clocks() and _disable_clocks() we
>> call _enable_optional_clocks()/_disable_optional_clocks() if the flag is set
>> for the hwmod and add the ahclkx_mux as optional clock for McASP3.
> 
> This might be awkward to say that the optional clocks are not optional,
> probably would be better to add:
> struct omap_hwmod {
> 	...
> 	struct omap_hwmod_opt_clk	*needed_clks;
> 	...
> 	u8				needed_clks_cnt;
> 	...
> };
> 
> and use the needed_clks in _init_main_clk()/_enable_clocks()/_disable_clocks() ?

Arrgh, but how to deal with this via DT bindings? It will be better to mark
the optional clocks as needed.
diff mbox

Patch

diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index 562247bced49..c38b7fa30c27 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -1298,6 +1298,38 @@  static struct omap_hwmod dra7xx_mcspi4_hwmod = {
 };
 
 /*
+ * 'mcasp' class
+ *
+ */
+static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
+	.sysc_offs	= 0x0004,
+	.sysc_flags	= SYSC_HAS_SIDLEMODE,
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type3,
+};
+
+static struct omap_hwmod_class dra7xx_mcasp_hwmod_class = {
+	.name	= "mcasp",
+	.sysc	= &dra7xx_mcasp_sysc,
+};
+
+/* mcasp3 */
+static struct omap_hwmod dra7xx_mcasp3_hwmod = {
+	.name		= "mcasp3",
+	.class		= &dra7xx_mcasp_hwmod_class,
+	.clkdm_name	= "l4per2_clkdm",
+	.main_clk	= "mcasp3_ahclkx_mux",
+	.flags		= HWMOD_SWSUP_SIDLE,
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = DRA7XX_CM_L4PER2_MCASP3_CLKCTRL_OFFSET,
+			.context_offs = DRA7XX_RM_L4PER2_MCASP3_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/*
  * 'mmc' class
  *
  */
@@ -2566,6 +2598,14 @@  static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = {
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/* l4_per2 -> mcasp3 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per2__mcasp3 = {
+	.master		= &dra7xx_l4_per2_hwmod,
+	.slave		= &dra7xx_mcasp3_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_addr_space dra7xx_elm_addrs[] = {
 	{
 		.pa_start	= 0x48078000,
@@ -3338,6 +3378,7 @@  static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
 	&dra7xx_l4_wkup__dcan1,
 	&dra7xx_l4_per2__dcan2,
 	&dra7xx_l4_per2__cpgmac0,
+	&dra7xx_l4_per2__mcasp3,
 	&dra7xx_gmac__mdio,
 	&dra7xx_l4_cfg__dma_system,
 	&dra7xx_l3_main_1__dss,