drm/bridge: synopsys: dw-hdmi-qp: Make audio path always on

Keep ACR, AUDI, AUDS packet always on to make SINK device
active for better compatibility and user experience.

This also fix POP sound on some SINK devices which wakeup
from suspend to active.

Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
Change-Id: I6bb80a85a7ce0ba7046b4ac7bb7d75c38fcd95f3
This commit is contained in:
Sugar Zhang
2022-07-29 17:36:45 +08:00
parent 60d1573824
commit b68072194c
2 changed files with 49 additions and 5 deletions

View File

@@ -69,6 +69,11 @@ static int dw_hdmi_qp_i2s_hw_params(struct device *dev, void *data,
/* Reset the audio data path of the AVP */
hdmi_write(audio, AVP_DATAPATH_PACKET_AUDIO_SWINIT_P, GLOBAL_SWRESET_REQUEST);
/* Disable AUDS, ACR, AUDI */
hdmi_mod(audio, 0,
PKTSCHED_ACR_TX_EN | PKTSCHED_AUDS_TX_EN | PKTSCHED_AUDI_TX_EN,
PKTSCHED_PKT_EN);
/* Clear the audio FIFO */
hdmi_write(audio, AUDIO_FIFO_CLR_P, AUDIO_INTERFACE_CONTROL0);
@@ -141,12 +146,22 @@ static int dw_hdmi_qp_i2s_audio_startup(struct device *dev, void *data)
static void dw_hdmi_qp_i2s_audio_shutdown(struct device *dev, void *data)
{
struct dw_hdmi_qp_i2s_audio_data *audio = data;
struct dw_hdmi_qp *hdmi = audio->hdmi;
if (is_dw_hdmi_qp_clk_off(audio))
return;
dw_hdmi_qp_audio_disable(hdmi);
/*
* Keep ACR, AUDI, AUDS packet always on to make SINK device
* active for better compatibility and user experience.
*
* This also fix POP sound on some SINK devices which wakeup
* from suspend to active.
*/
hdmi_mod(audio, I2S_BPCUV_RCV_DIS, I2S_BPCUV_RCV_MSK,
AUDIO_INTERFACE_CONFIG0);
hdmi_mod(audio, AUDPKT_PBIT_FORCE_EN | AUDPKT_CHSTATUS_OVR_EN,
AUDPKT_PBIT_FORCE_EN_MASK | AUDPKT_CHSTATUS_OVR_EN_MASK,
AUDPKT_CONTROL0);
}
static int dw_hdmi_qp_i2s_get_eld(struct device *dev, void *data, uint8_t *buf,

View File

@@ -471,9 +471,38 @@ void dw_hdmi_qp_set_channel_status(struct dw_hdmi_qp *hdmi,
return;
}
/* Set channel status */
hdmi_writel(hdmi, channel_status[3] | (channel_status[4] << 8),
AUDPKT_CHSTATUS_OVR1);
/*
* AUDPKT_CHSTATUS_OVR0: { RSV, RSV, CS1, CS0 }
* AUDPKT_CHSTATUS_OVR1: { CS6, CS5, CS4, CS3 }
*
* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
* CS0: | Mode | d | c | b | a |
* CS1: | Category Code |
* CS2: | Channel Number | Source Number |
* CS3: | Clock Accuracy | Sample Freq |
* CS4: | Ori Sample Freq | Word Length |
* CS5: | | CGMS-A |
* CS6~CS23: Reserved
*
* a: use of channel status block
* b: linear PCM identification: 0 for lpcm, 1 for nlpcm
* c: copyright information
* d: additional format information
*/
if (ref2stream)
channel_status[0] |= IEC958_AES0_NONAUDIO;
if ((hdmi_readl(hdmi, AUDIO_INTERFACE_CONFIG0) & GENMASK(25, 24)) == AUD_HBR) {
/* fixup cs for HBR */
channel_status[3] = (channel_status[3] & 0xf0) | IEC958_AES3_CON_FS_768000;
channel_status[4] = (channel_status[4] & 0x0f) | IEC958_AES4_CON_ORIGFS_NOTID;
}
hdmi_writel(hdmi, channel_status[0] | (channel_status[1] << 8),
AUDPKT_CHSTATUS_OVR0);
regmap_bulk_write(hdmi->regm, AUDPKT_CHSTATUS_OVR1, &channel_status[3], 1);
if (ref2stream)
hdmi_modb(hdmi, 0,