diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp-i2s-audio.c index 7df74654a5e7..234549ac36ed 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp-i2s-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp-i2s-audio.c @@ -88,11 +88,22 @@ static int dw_hdmi_qp_i2s_hw_params(struct device *dev, void *data, hdmi_mod(audio, conf0, I2S_LINES_EN_MSK, AUDIO_INTERFACE_CONFIG0); - /* Enable bpcuv generated internally */ - hdmi_mod(audio, I2S_BPCUV_RCV_DIS, I2S_BPCUV_RCV_MSK, AUDIO_INTERFACE_CONFIG0); + /* + * Enable bpcuv generated internally for L-PCM, or received + * from stream for NLPCM/HBR. + */ + switch (fmt->bit_fmt) { + case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE: + conf0 = (hparms->channels == 8) ? AUD_HBR : AUD_ASP; + conf0 |= I2S_BPCUV_RCV_EN; + break; + default: + conf0 = AUD_ASP | I2S_BPCUV_RCV_DIS; + break; + } - /* Configure the audio format */ - hdmi_mod(audio, AUD_ASP, AUD_FORMAT_MSK, AUDIO_INTERFACE_CONFIG0); + hdmi_mod(audio, conf0, I2S_BPCUV_RCV_MSK | AUD_FORMAT_MSK, + AUDIO_INTERFACE_CONFIG0); /* Enable audio FIFO auto clear when overflow */ hdmi_mod(audio, AUD_FIFO_INIT_ON_OVF_EN, AUD_FIFO_INIT_ON_OVF_MSK, diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c index 7cc41314bcb1..a584c5ff2a84 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -450,6 +450,11 @@ static unsigned int hdmi_find_n(struct dw_hdmi_qp *hdmi, unsigned long pixel_clk void dw_hdmi_qp_set_channel_status(struct dw_hdmi_qp *hdmi, u8 *channel_status) { + /* Set channel status */ + hdmi_writel(hdmi, channel_status[3] | (channel_status[4] << 8), + AUDPKT_CHSTATUS_OVR1); + hdmi_modb(hdmi, AUDPKT_CHSTATUS_OVR_EN, + AUDPKT_CHSTATUS_OVR_EN_MASK, AUDPKT_CONTROL0); } EXPORT_SYMBOL_GPL(dw_hdmi_qp_set_channel_status); diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h index 0634ff8a5843..8a343df716bc 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h @@ -382,6 +382,8 @@ #define PKT5_EMP_CVTEM_CONTENTS7 0xddc /* Audio Packetizer Registers */ #define AUDPKT_CONTROL0 0xe20 +#define AUDPKT_CHSTATUS_OVR_EN_MASK BIT(0) +#define AUDPKT_CHSTATUS_OVR_EN BIT(0) #define AUDPKT_CONTROL1 0xe24 #define AUDPKT_ACR_CONTROL0 0xe40 #define AUDPKT_ACR_N_VALUE 0xfffff @@ -393,6 +395,35 @@ #define AUDPKT_ACR_STATUS0 0xe4c #define AUDPKT_CHSTATUS_OVR0 0xe60 #define AUDPKT_CHSTATUS_OVR1 0xe64 +/* IEC60958 Byte 3: Sampleing frenuency Bits 24 to 27 */ +#define AUDPKT_CHSTATUS_SR_MASK GENMASK(3, 0) +#define AUDPKT_CHSTATUS_SR_22050 0x4 +#define AUDPKT_CHSTATUS_SR_24000 0x6 +#define AUDPKT_CHSTATUS_SR_32000 0x3 +#define AUDPKT_CHSTATUS_SR_44100 0x0 +#define AUDPKT_CHSTATUS_SR_48000 0x2 +#define AUDPKT_CHSTATUS_SR_88200 0x8 +#define AUDPKT_CHSTATUS_SR_96000 0xa +#define AUDPKT_CHSTATUS_SR_176400 0xc +#define AUDPKT_CHSTATUS_SR_192000 0xe +#define AUDPKT_CHSTATUS_SR_768000 0x9 +#define AUDPKT_CHSTATUS_SR_NOT_INDICATED 0x1 +/* IEC60958 Byte 4: Original Sampleing frenuency Bits 36 to 39 */ +#define AUDPKT_CHSTATUS_0SR_MASK GENMASK(15, 12) +#define AUDPKT_CHSTATUS_OSR_8000 0x6 +#define AUDPKT_CHSTATUS_OSR_11025 0xa +#define AUDPKT_CHSTATUS_OSR_12000 0x2 +#define AUDPKT_CHSTATUS_OSR_16000 0x8 +#define AUDPKT_CHSTATUS_OSR_22050 0xb +#define AUDPKT_CHSTATUS_OSR_24000 0x9 +#define AUDPKT_CHSTATUS_OSR_32000 0xc +#define AUDPKT_CHSTATUS_OSR_44100 0xf +#define AUDPKT_CHSTATUS_OSR_48000 0xd +#define AUDPKT_CHSTATUS_OSR_88200 0x7 +#define AUDPKT_CHSTATUS_OSR_96000 0x5 +#define AUDPKT_CHSTATUS_OSR_176400 0x3 +#define AUDPKT_CHSTATUS_OSR_192000 0x1 +#define AUDPKT_CHSTATUS_OSR_NOT_INDICATED 0x0 #define AUDPKT_CHSTATUS_OVR2 0xe68 #define AUDPKT_CHSTATUS_OVR3 0xe6c #define AUDPKT_CHSTATUS_OVR4 0xe70