[PATCH v2 08/12] drm: bridge/dw_hdmi: add audio config interfaces

Yang Kuankuan ykk at rock-chips.com
Mon Feb 2 04:32:05 PST 2015


On 02/02/2015 06:53 AM, Russell King - ARM Linux wrote:
> On Mon, Feb 02, 2015 at 12:02:50PM +0800, Daniel Kurtz wrote:
>> Hi ykk,
>>
>> On Sat, Jan 31, 2015 at 10:34 PM, Yang Kuankuan <ykk at rock-chips.com> wrote:
>>> On 01/31/2015 06:48 AM, Russell King - ARM Linux wrote:
>>>>> +void hdmi_audio_clk_enable(struct dw_hdmi *hdmi)
>>>>> +{
>>>>> +       if (hdmi->audio_enable)
>>>>> +               return;
>>>>> +
>>>>> +       mutex_lock(&hdmi->audio_mutex);
>>>>> +       hdmi->audio_enable = true;
>>>>> +       hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE,
>>>>> HDMI_MC_CLKDIS);
>>>>> +       mutex_unlock(&hdmi->audio_mutex);
>>>> This is racy.  The test needs to be within the mutex-protected region.
>>> This function will be called by other driver (dw-hdmi-audio), both modify
>>> the variable "hdmi->audio_enable", so i add the mutex-protected.
>> >From your comment it isn't clear whether you understand what Russell meant.
>> He is say you should do the following:
>>
>> {
>>         mutex_lock(&hdmi->audio_mutex);
>>
>>         if (hdmi->audio_enable) {
>>                mutex_unlock(&hdmi->audio_mutex);
>>                return;
>>         }
>>         hdmi->audio_enable = true;
>>         hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
>>
>>         mutex_unlock(&hdmi->audio_mutex);
>> }
> Yes, however, I prefer this kind of layout:
>
> 	mutex_lock(&hdmi->audio_mutex);
>   
> 	if (!hdmi->audio_enable) {
> 		hdmi->audio_enable = true;
> 		hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE,
> 			  HDMI_MC_CLKDIS);
>   	}
>
> 	mutex_unlock(&hdmi->audio_mutex);
>
> but that's a matter of personal opinion.  The important thing is that the
> testing and setting of the flag are both within the protected region.
>
> However, there are other bugs here: what if the audio driver is calling
> the sample rate setting function at the same time that a mode switch is
> occuring.  We actually need a mutex to protect more than just the
> audio_enable flag.

Okay, got it.

Thanks.  : )
>> By the way, it doesn't matter that the function is called from another driver.
>> What matters is that this function can be called concurrently on
>> multiple different threads of execution to change the hdmi audio
>> enable state.
>> >From DRM land, it is called with DRM lock held when enabling/disabling
>> hdmi audio (mode_set / DPMS).
>> It is also called from audio land, when enabling/disabling audio in
>> response to some audio events (userspace ioctls?).  I'm not sure
>> exactly how the audio side works, or what locks are involved, but this
>> mutex synchronizes calls from these two worlds to ensure that
>> "hdmi->audio_enable" field always matches the current (intended)
>> status of the hdmi audio clock.  This would be useful, for example, if
>> you needed to temporarily disable all HDMI clocks during a mode set,
>> and then restore the audio clock to its pre-mode_set state:
> There's some rather quirky comments in the driver right now which make
> me uneasy about changing things too much.
>
> My initial idea would be that audio should remain disabled until the
> audio driver wants it enabled, and the CTS/N values should either be
> left alone, or set to a value which disables them (there is an iMX6
> errata which says to set N=0 initially, but as seems common with iMX6
> errata, I see no code implementing the method specified in the
> documentation - I have found code implementing something similar
> though.)

I am confused with the way that audio driver realize the display 
resolution-changing.
If audio driver cannot knowing that, then audio clock may be closed 
permanently ?

>
> However, there is this in the binding function:
>
>          /*
>           * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
>           * N and cts values before enabling phy
>           */
>          hdmi_init_clk_regenerator(hdmi);
>
> which sets the N/CTS values assuming a 74.25MHz video clock and a 48kHz
> sample rate.  I've always wondered why this is necessary (I haven't
> experimented with that yet.)
>
> Then there's this in the mode set function:
>
>                  /* HDMI Initialization Step E - Configure audio */
>                  hdmi_clk_regenerator_update_pixel_clock(hdmi);
>                  hdmi_enable_audio_clk(hdmi);
>
> Where these "steps" come from, I've no idea (I can't find any documentation
> which specifies them - maybe its from the Synopsis documentation?) but
> this has always raised the question "what if audio is not enabled?"
>
static void hdmi_keep_audio_clk_status(struct dw_hdmi *hdmi)
{
     mutex_lock(&hdmi->audio_mutex);

     if (hdmi->audio_enable)
         hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE,
                             HDMI_MC_CLKDIS);
     else
         hdmi_modb(hdmi, HDMI_MC_CLKDIS_AUDCLK_DISABLE,
                             HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);

     mutex_unlock(&hdmi->audio_mutex);
}

      /* HDMI Initialization Step E - Configure audio */
     hdmi_clk_regenerator_update_pixel_clock(hdmi);
     hdmi_keep_audio_clk_status(hdmi);

keep audio status maybe suitable here.




More information about the dri-devel mailing list