Skip to content

Commit 384d2b0

Browse files
committed
drm/msm/hdmi: make use of the drm_connector_hdmi framework
Setup the HDMI connector on the MSM HDMI outputs. Make use of atomic_check hook and of the provided Infoframe infrastructure. Acked-by: Maxime Ripard <[email protected]> Reviewed-by: Abhinav Kumar <[email protected]> Signed-off-by: Dmitry Baryshkov <[email protected]> Patchwork: https://patchwork.freedesktop.org/patch/639656/ Link: https://lore.kernel.org/r/[email protected]
1 parent d309bda commit 384d2b0

File tree

5 files changed

+162
-147
lines changed

5 files changed

+162
-147
lines changed

drivers/gpu/drm/msm/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ config DRM_MSM_HDMI
170170
bool "Enable HDMI support in MSM DRM driver"
171171
depends on DRM_MSM
172172
default y
173+
select DRM_DISPLAY_HDMI_HELPER
174+
select DRM_DISPLAY_HDMI_STATE_HELPER
173175
help
174176
Compile in support for the HDMI output MSM DRM driver. It can
175177
be a primary or a secondary display on device. Note that this is used

drivers/gpu/drm/msm/hdmi/hdmi.c

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <drm/drm_bridge_connector.h>
1414
#include <drm/drm_of.h>
15+
#include <drm/display/drm_hdmi_state_helper.h>
1516

1617
#include <sound/hdmi-codec.h>
1718
#include "hdmi.h"
@@ -165,8 +166,6 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
165166
hdmi->dev = dev;
166167
hdmi->encoder = encoder;
167168

168-
hdmi_audio_infoframe_init(&hdmi->audio.infoframe);
169-
170169
ret = msm_hdmi_bridge_init(hdmi);
171170
if (ret) {
172171
DRM_DEV_ERROR(dev->dev, "failed to create HDMI bridge: %d\n", ret);
@@ -254,40 +253,12 @@ static int msm_hdmi_audio_hw_params(struct device *dev, void *data,
254253
struct hdmi_codec_params *params)
255254
{
256255
struct hdmi *hdmi = dev_get_drvdata(dev);
257-
unsigned int chan;
258-
unsigned int channel_allocation = 0;
259256
unsigned int rate;
260-
unsigned int level_shift = 0; /* 0dB */
261-
bool down_mix = false;
257+
int ret;
262258

263259
DRM_DEV_DEBUG(dev, "%u Hz, %d bit, %d channels\n", params->sample_rate,
264260
params->sample_width, params->cea.channels);
265261

266-
switch (params->cea.channels) {
267-
case 2:
268-
/* FR and FL speakers */
269-
channel_allocation = 0;
270-
chan = MSM_HDMI_AUDIO_CHANNEL_2;
271-
break;
272-
case 4:
273-
/* FC, LFE, FR and FL speakers */
274-
channel_allocation = 0x3;
275-
chan = MSM_HDMI_AUDIO_CHANNEL_4;
276-
break;
277-
case 6:
278-
/* RR, RL, FC, LFE, FR and FL speakers */
279-
channel_allocation = 0x0B;
280-
chan = MSM_HDMI_AUDIO_CHANNEL_6;
281-
break;
282-
case 8:
283-
/* FRC, FLC, RR, RL, FC, LFE, FR and FL speakers */
284-
channel_allocation = 0x1F;
285-
chan = MSM_HDMI_AUDIO_CHANNEL_8;
286-
break;
287-
default:
288-
return -EINVAL;
289-
}
290-
291262
switch (params->sample_rate) {
292263
case 32000:
293264
rate = HDMI_SAMPLE_RATE_32KHZ;
@@ -316,9 +287,12 @@ static int msm_hdmi_audio_hw_params(struct device *dev, void *data,
316287
return -EINVAL;
317288
}
318289

319-
msm_hdmi_audio_set_sample_rate(hdmi, rate);
320-
msm_hdmi_audio_info_setup(hdmi, 1, chan, channel_allocation,
321-
level_shift, down_mix);
290+
ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(hdmi->connector,
291+
&params->cea);
292+
if (ret)
293+
return ret;
294+
295+
msm_hdmi_audio_info_setup(hdmi, rate, params->cea.channels);
322296

323297
return 0;
324298
}
@@ -327,7 +301,8 @@ static void msm_hdmi_audio_shutdown(struct device *dev, void *data)
327301
{
328302
struct hdmi *hdmi = dev_get_drvdata(dev);
329303

330-
msm_hdmi_audio_info_setup(hdmi, 0, 0, 0, 0, 0);
304+
drm_atomic_helper_connector_hdmi_clear_audio_infoframe(hdmi->connector);
305+
msm_hdmi_audio_disable(hdmi);
331306
}
332307

333308
static const struct hdmi_codec_ops msm_hdmi_audio_codec_ops = {

drivers/gpu/drm/msm/hdmi/hdmi.h

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ struct hdmi_platform_config;
2424

2525
struct hdmi_audio {
2626
bool enabled;
27-
struct hdmi_audio_infoframe infoframe;
2827
int rate;
28+
int channels;
2929
};
3030

3131
struct hdmi_hdcp_ctrl;
@@ -207,12 +207,6 @@ static inline int msm_hdmi_pll_8998_init(struct platform_device *pdev)
207207
/*
208208
* audio:
209209
*/
210-
/* Supported HDMI Audio channels and rates */
211-
#define MSM_HDMI_AUDIO_CHANNEL_2 0
212-
#define MSM_HDMI_AUDIO_CHANNEL_4 1
213-
#define MSM_HDMI_AUDIO_CHANNEL_6 2
214-
#define MSM_HDMI_AUDIO_CHANNEL_8 3
215-
216210
#define HDMI_SAMPLE_RATE_32KHZ 0
217211
#define HDMI_SAMPLE_RATE_44_1KHZ 1
218212
#define HDMI_SAMPLE_RATE_48KHZ 2
@@ -222,11 +216,8 @@ static inline int msm_hdmi_pll_8998_init(struct platform_device *pdev)
222216
#define HDMI_SAMPLE_RATE_192KHZ 6
223217

224218
int msm_hdmi_audio_update(struct hdmi *hdmi);
225-
int msm_hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled,
226-
uint32_t num_of_channels, uint32_t channel_allocation,
227-
uint32_t level_shift, bool down_mix);
228-
void msm_hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate);
229-
219+
int msm_hdmi_audio_info_setup(struct hdmi *hdmi, int rate, int channels);
220+
int msm_hdmi_audio_disable(struct hdmi *hdmi);
230221

231222
/*
232223
* hdmi bridge:

drivers/gpu/drm/msm/hdmi/hdmi_audio.c

Lines changed: 19 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
#include <linux/hdmi.h>
88
#include "hdmi.h"
99

10-
/* maps MSM_HDMI_AUDIO_CHANNEL_n consts used by audio driver to # of channels: */
11-
static int nchannels[] = { 2, 4, 6, 8 };
12-
1310
/* Supported HDMI Audio sample rates */
1411
#define MSM_HDMI_SAMPLE_RATE_32KHZ 0
1512
#define MSM_HDMI_SAMPLE_RATE_44_1KHZ 1
@@ -74,16 +71,17 @@ static const struct hdmi_msm_audio_arcs *get_arcs(unsigned long int pixclock)
7471
int msm_hdmi_audio_update(struct hdmi *hdmi)
7572
{
7673
struct hdmi_audio *audio = &hdmi->audio;
77-
struct hdmi_audio_infoframe *info = &audio->infoframe;
7874
const struct hdmi_msm_audio_arcs *arcs = NULL;
7975
bool enabled = audio->enabled;
8076
uint32_t acr_pkt_ctrl, vbi_pkt_ctrl, aud_pkt_ctrl;
81-
uint32_t infofrm_ctrl, audio_config;
77+
uint32_t audio_config;
78+
79+
if (!hdmi->connector->display_info.is_hdmi)
80+
return -EINVAL;
81+
82+
DBG("audio: enabled=%d, channels=%d, rate=%d",
83+
audio->enabled, audio->channels, audio->rate);
8284

83-
DBG("audio: enabled=%d, channels=%d, channel_allocation=0x%x, "
84-
"level_shift_value=%d, downmix_inhibit=%d, rate=%d",
85-
audio->enabled, info->channels, info->channel_allocation,
86-
info->level_shift_value, info->downmix_inhibit, audio->rate);
8785
DBG("video: power_on=%d, pixclock=%lu", hdmi->power_on, hdmi->pixclock);
8886

8987
if (enabled && !(hdmi->power_on && hdmi->pixclock)) {
@@ -104,7 +102,6 @@ int msm_hdmi_audio_update(struct hdmi *hdmi)
104102
acr_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_ACR_PKT_CTRL);
105103
vbi_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_VBI_PKT_CTRL);
106104
aud_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_AUDIO_PKT_CTRL1);
107-
infofrm_ctrl = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
108105
audio_config = hdmi_read(hdmi, REG_HDMI_AUDIO_CFG);
109106

110107
/* Clear N/CTS selection bits */
@@ -113,7 +110,6 @@ int msm_hdmi_audio_update(struct hdmi *hdmi)
113110
if (enabled) {
114111
uint32_t n, cts, multiplier;
115112
enum hdmi_acr_cts select;
116-
uint8_t buf[14];
117113

118114
n = arcs->lut[audio->rate].n;
119115
cts = arcs->lut[audio->rate].cts;
@@ -155,32 +151,19 @@ int msm_hdmi_audio_update(struct hdmi *hdmi)
155151
HDMI_ACR_1_N(n));
156152

157153
hdmi_write(hdmi, REG_HDMI_AUDIO_PKT_CTRL2,
158-
COND(info->channels != 2, HDMI_AUDIO_PKT_CTRL2_LAYOUT) |
154+
COND(audio->channels != 2, HDMI_AUDIO_PKT_CTRL2_LAYOUT) |
159155
HDMI_AUDIO_PKT_CTRL2_OVERRIDE);
160156

161157
acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_CONT;
162158
acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_SEND;
163159

164-
/* configure infoframe: */
165-
hdmi_audio_infoframe_pack(info, buf, sizeof(buf));
166-
hdmi_write(hdmi, REG_HDMI_AUDIO_INFO0,
167-
(buf[3] << 0) | (buf[4] << 8) |
168-
(buf[5] << 16) | (buf[6] << 24));
169-
hdmi_write(hdmi, REG_HDMI_AUDIO_INFO1,
170-
(buf[7] << 0) | (buf[8] << 8));
171-
172160
hdmi_write(hdmi, REG_HDMI_GC, 0);
173161

174162
vbi_pkt_ctrl |= HDMI_VBI_PKT_CTRL_GC_ENABLE;
175163
vbi_pkt_ctrl |= HDMI_VBI_PKT_CTRL_GC_EVERY_FRAME;
176164

177165
aud_pkt_ctrl |= HDMI_AUDIO_PKT_CTRL1_AUDIO_SAMPLE_SEND;
178166

179-
infofrm_ctrl |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND;
180-
infofrm_ctrl |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT;
181-
infofrm_ctrl |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE;
182-
infofrm_ctrl |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE;
183-
184167
audio_config &= ~HDMI_AUDIO_CFG_FIFO_WATERMARK__MASK;
185168
audio_config |= HDMI_AUDIO_CFG_FIFO_WATERMARK(4);
186169
audio_config |= HDMI_AUDIO_CFG_ENGINE_ENABLE;
@@ -190,17 +173,12 @@ int msm_hdmi_audio_update(struct hdmi *hdmi)
190173
vbi_pkt_ctrl &= ~HDMI_VBI_PKT_CTRL_GC_ENABLE;
191174
vbi_pkt_ctrl &= ~HDMI_VBI_PKT_CTRL_GC_EVERY_FRAME;
192175
aud_pkt_ctrl &= ~HDMI_AUDIO_PKT_CTRL1_AUDIO_SAMPLE_SEND;
193-
infofrm_ctrl &= ~HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND;
194-
infofrm_ctrl &= ~HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT;
195-
infofrm_ctrl &= ~HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE;
196-
infofrm_ctrl &= ~HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE;
197176
audio_config &= ~HDMI_AUDIO_CFG_ENGINE_ENABLE;
198177
}
199178

200179
hdmi_write(hdmi, REG_HDMI_ACR_PKT_CTRL, acr_pkt_ctrl);
201180
hdmi_write(hdmi, REG_HDMI_VBI_PKT_CTRL, vbi_pkt_ctrl);
202181
hdmi_write(hdmi, REG_HDMI_AUDIO_PKT_CTRL1, aud_pkt_ctrl);
203-
hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, infofrm_ctrl);
204182

205183
hdmi_write(hdmi, REG_HDMI_AUD_INT,
206184
COND(enabled, HDMI_AUD_INT_AUD_FIFO_URUN_INT) |
@@ -214,41 +192,29 @@ int msm_hdmi_audio_update(struct hdmi *hdmi)
214192
return 0;
215193
}
216194

217-
int msm_hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled,
218-
uint32_t num_of_channels, uint32_t channel_allocation,
219-
uint32_t level_shift, bool down_mix)
195+
int msm_hdmi_audio_info_setup(struct hdmi *hdmi, int rate, int channels)
220196
{
221-
struct hdmi_audio *audio;
222-
223197
if (!hdmi)
224198
return -ENXIO;
225199

226-
audio = &hdmi->audio;
227-
228-
if (num_of_channels >= ARRAY_SIZE(nchannels))
200+
if ((rate < 0) || (rate >= MSM_HDMI_SAMPLE_RATE_MAX))
229201
return -EINVAL;
230202

231-
audio->enabled = enabled;
232-
audio->infoframe.channels = nchannels[num_of_channels];
233-
audio->infoframe.channel_allocation = channel_allocation;
234-
audio->infoframe.level_shift_value = level_shift;
235-
audio->infoframe.downmix_inhibit = down_mix;
203+
hdmi->audio.rate = rate;
204+
hdmi->audio.channels = channels;
205+
hdmi->audio.enabled = true;
236206

237207
return msm_hdmi_audio_update(hdmi);
238208
}
239209

240-
void msm_hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate)
210+
int msm_hdmi_audio_disable(struct hdmi *hdmi)
241211
{
242-
struct hdmi_audio *audio;
243-
244212
if (!hdmi)
245-
return;
246-
247-
audio = &hdmi->audio;
213+
return -ENXIO;
248214

249-
if ((rate < 0) || (rate >= MSM_HDMI_SAMPLE_RATE_MAX))
250-
return;
215+
hdmi->audio.rate = 0;
216+
hdmi->audio.channels = 2;
217+
hdmi->audio.enabled = false;
251218

252-
audio->rate = rate;
253-
msm_hdmi_audio_update(hdmi);
219+
return msm_hdmi_audio_update(hdmi);
254220
}

0 commit comments

Comments
 (0)