1c349dbc7Sjsg /*
2c349dbc7Sjsg * Copyright © 2014 Intel Corporation
3c349dbc7Sjsg *
4c349dbc7Sjsg * Permission is hereby granted, free of charge, to any person obtaining a
5c349dbc7Sjsg * copy of this software and associated documentation files (the "Software"),
6c349dbc7Sjsg * to deal in the Software without restriction, including without limitation
7c349dbc7Sjsg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8c349dbc7Sjsg * and/or sell copies of the Software, and to permit persons to whom the
9c349dbc7Sjsg * Software is furnished to do so, subject to the following conditions:
10c349dbc7Sjsg *
11c349dbc7Sjsg * The above copyright notice and this permission notice (including the next
12c349dbc7Sjsg * paragraph) shall be included in all copies or substantial portions of the
13c349dbc7Sjsg * Software.
14c349dbc7Sjsg *
15c349dbc7Sjsg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16c349dbc7Sjsg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17c349dbc7Sjsg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18c349dbc7Sjsg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19c349dbc7Sjsg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20c349dbc7Sjsg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21c349dbc7Sjsg * DEALINGS IN THE SOFTWARE.
22c349dbc7Sjsg */
23c349dbc7Sjsg
24c349dbc7Sjsg #include <linux/component.h>
25c349dbc7Sjsg #include <linux/kernel.h>
26c349dbc7Sjsg
27c349dbc7Sjsg #include <drm/drm_edid.h>
28c349dbc7Sjsg #include <drm/i915_component.h>
29c349dbc7Sjsg
30c349dbc7Sjsg #include "i915_drv.h"
31c349dbc7Sjsg #include "intel_atomic.h"
32c349dbc7Sjsg #include "intel_audio.h"
331bb76ff1Sjsg #include "intel_audio_regs.h"
34c349dbc7Sjsg #include "intel_cdclk.h"
351bb76ff1Sjsg #include "intel_crtc.h"
365ca02815Sjsg #include "intel_de.h"
37c349dbc7Sjsg #include "intel_display_types.h"
38c349dbc7Sjsg #include "intel_lpe_audio.h"
39c349dbc7Sjsg
40c349dbc7Sjsg /**
41c349dbc7Sjsg * DOC: High Definition Audio over HDMI and Display Port
42c349dbc7Sjsg *
43c349dbc7Sjsg * The graphics and audio drivers together support High Definition Audio over
44c349dbc7Sjsg * HDMI and Display Port. The audio programming sequences are divided into audio
45c349dbc7Sjsg * codec and controller enable and disable sequences. The graphics driver
46c349dbc7Sjsg * handles the audio codec sequences, while the audio driver handles the audio
47c349dbc7Sjsg * controller sequences.
48c349dbc7Sjsg *
49c349dbc7Sjsg * The disable sequences must be performed before disabling the transcoder or
50c349dbc7Sjsg * port. The enable sequences may only be performed after enabling the
51c349dbc7Sjsg * transcoder and port, and after completed link training. Therefore the audio
52c349dbc7Sjsg * enable/disable sequences are part of the modeset sequence.
53c349dbc7Sjsg *
54c349dbc7Sjsg * The codec and controller sequences could be done either parallel or serial,
55c349dbc7Sjsg * but generally the ELDV/PD change in the codec sequence indicates to the audio
56c349dbc7Sjsg * driver that the controller sequence should start. Indeed, most of the
57c349dbc7Sjsg * co-operation between the graphics and audio drivers is handled via audio
58c349dbc7Sjsg * related registers. (The notable exception is the power management, not
59c349dbc7Sjsg * covered here.)
60c349dbc7Sjsg *
61c349dbc7Sjsg * The struct &i915_audio_component is used to interact between the graphics
62c349dbc7Sjsg * and audio drivers. The struct &i915_audio_component_ops @ops in it is
63c349dbc7Sjsg * defined in graphics driver and called in audio driver. The
64c349dbc7Sjsg * struct &i915_audio_component_audio_ops @audio_ops is called from i915 driver.
65c349dbc7Sjsg */
66c349dbc7Sjsg
671bb76ff1Sjsg struct intel_audio_funcs {
681bb76ff1Sjsg void (*audio_codec_enable)(struct intel_encoder *encoder,
691bb76ff1Sjsg const struct intel_crtc_state *crtc_state,
701bb76ff1Sjsg const struct drm_connector_state *conn_state);
711bb76ff1Sjsg void (*audio_codec_disable)(struct intel_encoder *encoder,
721bb76ff1Sjsg const struct intel_crtc_state *old_crtc_state,
731bb76ff1Sjsg const struct drm_connector_state *old_conn_state);
74f005ef32Sjsg void (*audio_codec_get_config)(struct intel_encoder *encoder,
75f005ef32Sjsg struct intel_crtc_state *crtc_state);
761bb76ff1Sjsg };
771bb76ff1Sjsg
78c349dbc7Sjsg struct hdmi_aud_ncts {
79c349dbc7Sjsg int sample_rate;
80c349dbc7Sjsg int clock;
81c349dbc7Sjsg int n;
82c349dbc7Sjsg int cts;
83c349dbc7Sjsg };
84c349dbc7Sjsg
85c349dbc7Sjsg static const struct {
86c349dbc7Sjsg int clock;
87c349dbc7Sjsg u32 config;
88c349dbc7Sjsg } hdmi_audio_clock[] = {
89c349dbc7Sjsg { 25175, AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 },
90c349dbc7Sjsg { 25200, AUD_CONFIG_PIXEL_CLOCK_HDMI_25200 }, /* default per bspec */
91c349dbc7Sjsg { 27000, AUD_CONFIG_PIXEL_CLOCK_HDMI_27000 },
92c349dbc7Sjsg { 27027, AUD_CONFIG_PIXEL_CLOCK_HDMI_27027 },
93c349dbc7Sjsg { 54000, AUD_CONFIG_PIXEL_CLOCK_HDMI_54000 },
94c349dbc7Sjsg { 54054, AUD_CONFIG_PIXEL_CLOCK_HDMI_54054 },
95c349dbc7Sjsg { 74176, AUD_CONFIG_PIXEL_CLOCK_HDMI_74176 },
96c349dbc7Sjsg { 74250, AUD_CONFIG_PIXEL_CLOCK_HDMI_74250 },
97c349dbc7Sjsg { 148352, AUD_CONFIG_PIXEL_CLOCK_HDMI_148352 },
98c349dbc7Sjsg { 148500, AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 },
99c349dbc7Sjsg { 296703, AUD_CONFIG_PIXEL_CLOCK_HDMI_296703 },
100c349dbc7Sjsg { 297000, AUD_CONFIG_PIXEL_CLOCK_HDMI_297000 },
101c349dbc7Sjsg { 593407, AUD_CONFIG_PIXEL_CLOCK_HDMI_593407 },
102c349dbc7Sjsg { 594000, AUD_CONFIG_PIXEL_CLOCK_HDMI_594000 },
103c349dbc7Sjsg };
104c349dbc7Sjsg
105c349dbc7Sjsg /* HDMI N/CTS table */
106c349dbc7Sjsg #define TMDS_297M 297000
107c349dbc7Sjsg #define TMDS_296M 296703
108c349dbc7Sjsg #define TMDS_594M 594000
109c349dbc7Sjsg #define TMDS_593M 593407
110c349dbc7Sjsg
111c349dbc7Sjsg static const struct hdmi_aud_ncts hdmi_aud_ncts_24bpp[] = {
112c349dbc7Sjsg { 32000, TMDS_296M, 5824, 421875 },
113c349dbc7Sjsg { 32000, TMDS_297M, 3072, 222750 },
114c349dbc7Sjsg { 32000, TMDS_593M, 5824, 843750 },
115c349dbc7Sjsg { 32000, TMDS_594M, 3072, 445500 },
116c349dbc7Sjsg { 44100, TMDS_296M, 4459, 234375 },
117c349dbc7Sjsg { 44100, TMDS_297M, 4704, 247500 },
118c349dbc7Sjsg { 44100, TMDS_593M, 8918, 937500 },
119c349dbc7Sjsg { 44100, TMDS_594M, 9408, 990000 },
120c349dbc7Sjsg { 88200, TMDS_296M, 8918, 234375 },
121c349dbc7Sjsg { 88200, TMDS_297M, 9408, 247500 },
122c349dbc7Sjsg { 88200, TMDS_593M, 17836, 937500 },
123c349dbc7Sjsg { 88200, TMDS_594M, 18816, 990000 },
124c349dbc7Sjsg { 176400, TMDS_296M, 17836, 234375 },
125c349dbc7Sjsg { 176400, TMDS_297M, 18816, 247500 },
126c349dbc7Sjsg { 176400, TMDS_593M, 35672, 937500 },
127c349dbc7Sjsg { 176400, TMDS_594M, 37632, 990000 },
128c349dbc7Sjsg { 48000, TMDS_296M, 5824, 281250 },
129c349dbc7Sjsg { 48000, TMDS_297M, 5120, 247500 },
130c349dbc7Sjsg { 48000, TMDS_593M, 5824, 562500 },
131c349dbc7Sjsg { 48000, TMDS_594M, 6144, 594000 },
132c349dbc7Sjsg { 96000, TMDS_296M, 11648, 281250 },
133c349dbc7Sjsg { 96000, TMDS_297M, 10240, 247500 },
134c349dbc7Sjsg { 96000, TMDS_593M, 11648, 562500 },
135c349dbc7Sjsg { 96000, TMDS_594M, 12288, 594000 },
136c349dbc7Sjsg { 192000, TMDS_296M, 23296, 281250 },
137c349dbc7Sjsg { 192000, TMDS_297M, 20480, 247500 },
138c349dbc7Sjsg { 192000, TMDS_593M, 23296, 562500 },
139c349dbc7Sjsg { 192000, TMDS_594M, 24576, 594000 },
140c349dbc7Sjsg };
141c349dbc7Sjsg
142c349dbc7Sjsg /* Appendix C - N & CTS values for deep color from HDMI 2.0 spec*/
143c349dbc7Sjsg /* HDMI N/CTS table for 10 bit deep color(30 bpp)*/
144c349dbc7Sjsg #define TMDS_371M 371250
145c349dbc7Sjsg #define TMDS_370M 370878
146c349dbc7Sjsg
147c349dbc7Sjsg static const struct hdmi_aud_ncts hdmi_aud_ncts_30bpp[] = {
148c349dbc7Sjsg { 32000, TMDS_370M, 5824, 527344 },
149c349dbc7Sjsg { 32000, TMDS_371M, 6144, 556875 },
150c349dbc7Sjsg { 44100, TMDS_370M, 8918, 585938 },
151c349dbc7Sjsg { 44100, TMDS_371M, 4704, 309375 },
152c349dbc7Sjsg { 88200, TMDS_370M, 17836, 585938 },
153c349dbc7Sjsg { 88200, TMDS_371M, 9408, 309375 },
154c349dbc7Sjsg { 176400, TMDS_370M, 35672, 585938 },
155c349dbc7Sjsg { 176400, TMDS_371M, 18816, 309375 },
156c349dbc7Sjsg { 48000, TMDS_370M, 11648, 703125 },
157c349dbc7Sjsg { 48000, TMDS_371M, 5120, 309375 },
158c349dbc7Sjsg { 96000, TMDS_370M, 23296, 703125 },
159c349dbc7Sjsg { 96000, TMDS_371M, 10240, 309375 },
160c349dbc7Sjsg { 192000, TMDS_370M, 46592, 703125 },
161c349dbc7Sjsg { 192000, TMDS_371M, 20480, 309375 },
162c349dbc7Sjsg };
163c349dbc7Sjsg
164c349dbc7Sjsg /* HDMI N/CTS table for 12 bit deep color(36 bpp)*/
165c349dbc7Sjsg #define TMDS_445_5M 445500
166c349dbc7Sjsg #define TMDS_445M 445054
167c349dbc7Sjsg
168c349dbc7Sjsg static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = {
169c349dbc7Sjsg { 32000, TMDS_445M, 5824, 632813 },
170c349dbc7Sjsg { 32000, TMDS_445_5M, 4096, 445500 },
171c349dbc7Sjsg { 44100, TMDS_445M, 8918, 703125 },
172c349dbc7Sjsg { 44100, TMDS_445_5M, 4704, 371250 },
173c349dbc7Sjsg { 88200, TMDS_445M, 17836, 703125 },
174c349dbc7Sjsg { 88200, TMDS_445_5M, 9408, 371250 },
175c349dbc7Sjsg { 176400, TMDS_445M, 35672, 703125 },
176c349dbc7Sjsg { 176400, TMDS_445_5M, 18816, 371250 },
177c349dbc7Sjsg { 48000, TMDS_445M, 5824, 421875 },
178c349dbc7Sjsg { 48000, TMDS_445_5M, 5120, 371250 },
179c349dbc7Sjsg { 96000, TMDS_445M, 11648, 421875 },
180c349dbc7Sjsg { 96000, TMDS_445_5M, 10240, 371250 },
181c349dbc7Sjsg { 192000, TMDS_445M, 23296, 421875 },
182c349dbc7Sjsg { 192000, TMDS_445_5M, 20480, 371250 },
183c349dbc7Sjsg };
184c349dbc7Sjsg
185c349dbc7Sjsg /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */
audio_config_hdmi_pixel_clock(const struct intel_crtc_state * crtc_state)186c349dbc7Sjsg static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_state)
187c349dbc7Sjsg {
188f005ef32Sjsg struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
189c349dbc7Sjsg const struct drm_display_mode *adjusted_mode =
190c349dbc7Sjsg &crtc_state->hw.adjusted_mode;
191c349dbc7Sjsg int i;
192c349dbc7Sjsg
193c349dbc7Sjsg for (i = 0; i < ARRAY_SIZE(hdmi_audio_clock); i++) {
194c349dbc7Sjsg if (adjusted_mode->crtc_clock == hdmi_audio_clock[i].clock)
195c349dbc7Sjsg break;
196c349dbc7Sjsg }
197c349dbc7Sjsg
198f005ef32Sjsg if (DISPLAY_VER(i915) < 12 && adjusted_mode->crtc_clock > 148500)
199c349dbc7Sjsg i = ARRAY_SIZE(hdmi_audio_clock);
200c349dbc7Sjsg
201c349dbc7Sjsg if (i == ARRAY_SIZE(hdmi_audio_clock)) {
202f005ef32Sjsg drm_dbg_kms(&i915->drm,
203ad8b1aafSjsg "HDMI audio pixel clock setting for %d not found, falling back to defaults\n",
204c349dbc7Sjsg adjusted_mode->crtc_clock);
205c349dbc7Sjsg i = 1;
206c349dbc7Sjsg }
207c349dbc7Sjsg
208f005ef32Sjsg drm_dbg_kms(&i915->drm,
209ad8b1aafSjsg "Configuring HDMI audio for pixel clock %d (0x%08x)\n",
210c349dbc7Sjsg hdmi_audio_clock[i].clock,
211c349dbc7Sjsg hdmi_audio_clock[i].config);
212c349dbc7Sjsg
213c349dbc7Sjsg return hdmi_audio_clock[i].config;
214c349dbc7Sjsg }
215c349dbc7Sjsg
audio_config_hdmi_get_n(const struct intel_crtc_state * crtc_state,int rate)216c349dbc7Sjsg static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state,
217c349dbc7Sjsg int rate)
218c349dbc7Sjsg {
219c349dbc7Sjsg const struct hdmi_aud_ncts *hdmi_ncts_table;
220c349dbc7Sjsg int i, size;
221c349dbc7Sjsg
222c349dbc7Sjsg if (crtc_state->pipe_bpp == 36) {
223c349dbc7Sjsg hdmi_ncts_table = hdmi_aud_ncts_36bpp;
224c349dbc7Sjsg size = ARRAY_SIZE(hdmi_aud_ncts_36bpp);
225c349dbc7Sjsg } else if (crtc_state->pipe_bpp == 30) {
226c349dbc7Sjsg hdmi_ncts_table = hdmi_aud_ncts_30bpp;
227c349dbc7Sjsg size = ARRAY_SIZE(hdmi_aud_ncts_30bpp);
228c349dbc7Sjsg } else {
229c349dbc7Sjsg hdmi_ncts_table = hdmi_aud_ncts_24bpp;
230c349dbc7Sjsg size = ARRAY_SIZE(hdmi_aud_ncts_24bpp);
231c349dbc7Sjsg }
232c349dbc7Sjsg
233c349dbc7Sjsg for (i = 0; i < size; i++) {
234c349dbc7Sjsg if (rate == hdmi_ncts_table[i].sample_rate &&
235c349dbc7Sjsg crtc_state->port_clock == hdmi_ncts_table[i].clock) {
236c349dbc7Sjsg return hdmi_ncts_table[i].n;
237c349dbc7Sjsg }
238c349dbc7Sjsg }
239c349dbc7Sjsg return 0;
240c349dbc7Sjsg }
241c349dbc7Sjsg
242f005ef32Sjsg /* ELD buffer size in dwords */
g4x_eld_buffer_size(struct drm_i915_private * i915)243f005ef32Sjsg static int g4x_eld_buffer_size(struct drm_i915_private *i915)
244c349dbc7Sjsg {
245c349dbc7Sjsg u32 tmp;
246c349dbc7Sjsg
247f005ef32Sjsg tmp = intel_de_read(i915, G4X_AUD_CNTL_ST);
248c349dbc7Sjsg
249f005ef32Sjsg return REG_FIELD_GET(G4X_ELD_BUFFER_SIZE_MASK, tmp);
250f005ef32Sjsg }
251c349dbc7Sjsg
g4x_audio_codec_get_config(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state)252f005ef32Sjsg static void g4x_audio_codec_get_config(struct intel_encoder *encoder,
253f005ef32Sjsg struct intel_crtc_state *crtc_state)
254f005ef32Sjsg {
255f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
256f005ef32Sjsg u32 *eld = (u32 *)crtc_state->eld;
257f005ef32Sjsg int eld_buffer_size, len, i;
258f005ef32Sjsg u32 tmp;
259c349dbc7Sjsg
260f005ef32Sjsg tmp = intel_de_read(i915, G4X_AUD_CNTL_ST);
261f005ef32Sjsg if ((tmp & G4X_ELD_VALID) == 0)
262f005ef32Sjsg return;
263c349dbc7Sjsg
264f005ef32Sjsg intel_de_rmw(i915, G4X_AUD_CNTL_ST, G4X_ELD_ADDRESS_MASK, 0);
265f005ef32Sjsg
266f005ef32Sjsg eld_buffer_size = g4x_eld_buffer_size(i915);
267f005ef32Sjsg len = min_t(int, sizeof(crtc_state->eld) / 4, eld_buffer_size);
268f005ef32Sjsg
269f005ef32Sjsg for (i = 0; i < len; i++)
270f005ef32Sjsg eld[i] = intel_de_read(i915, G4X_HDMIW_HDMIEDID);
271c349dbc7Sjsg }
272c349dbc7Sjsg
g4x_audio_codec_disable(struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)273c349dbc7Sjsg static void g4x_audio_codec_disable(struct intel_encoder *encoder,
274c349dbc7Sjsg const struct intel_crtc_state *old_crtc_state,
275c349dbc7Sjsg const struct drm_connector_state *old_conn_state)
276c349dbc7Sjsg {
277f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
278f005ef32Sjsg struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
279c349dbc7Sjsg
280c349dbc7Sjsg /* Invalidate ELD */
281f005ef32Sjsg intel_de_rmw(i915, G4X_AUD_CNTL_ST,
282f005ef32Sjsg G4X_ELD_VALID, 0);
283f005ef32Sjsg
284f005ef32Sjsg intel_crtc_wait_for_next_vblank(crtc);
285f005ef32Sjsg intel_crtc_wait_for_next_vblank(crtc);
286c349dbc7Sjsg }
287c349dbc7Sjsg
g4x_audio_codec_enable(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)288c349dbc7Sjsg static void g4x_audio_codec_enable(struct intel_encoder *encoder,
289c349dbc7Sjsg const struct intel_crtc_state *crtc_state,
290c349dbc7Sjsg const struct drm_connector_state *conn_state)
291c349dbc7Sjsg {
292f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
293f005ef32Sjsg struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
294f005ef32Sjsg const u32 *eld = (const u32 *)crtc_state->eld;
295f005ef32Sjsg int eld_buffer_size, len, i;
296c349dbc7Sjsg
297f005ef32Sjsg intel_crtc_wait_for_next_vblank(crtc);
298c349dbc7Sjsg
299f005ef32Sjsg intel_de_rmw(i915, G4X_AUD_CNTL_ST,
300f005ef32Sjsg G4X_ELD_VALID | G4X_ELD_ADDRESS_MASK, 0);
301c349dbc7Sjsg
302f005ef32Sjsg eld_buffer_size = g4x_eld_buffer_size(i915);
303f005ef32Sjsg len = min(drm_eld_size(crtc_state->eld) / 4, eld_buffer_size);
304c349dbc7Sjsg
305c349dbc7Sjsg for (i = 0; i < len; i++)
306f005ef32Sjsg intel_de_write(i915, G4X_HDMIW_HDMIEDID, eld[i]);
307f005ef32Sjsg for (; i < eld_buffer_size; i++)
308f005ef32Sjsg intel_de_write(i915, G4X_HDMIW_HDMIEDID, 0);
309c349dbc7Sjsg
310f005ef32Sjsg drm_WARN_ON(&i915->drm,
311f005ef32Sjsg (intel_de_read(i915, G4X_AUD_CNTL_ST) & G4X_ELD_ADDRESS_MASK) != 0);
312f005ef32Sjsg
313f005ef32Sjsg intel_de_rmw(i915, G4X_AUD_CNTL_ST,
314f005ef32Sjsg 0, G4X_ELD_VALID);
315c349dbc7Sjsg }
316c349dbc7Sjsg
317c349dbc7Sjsg static void
hsw_dp_audio_config_update(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)318c349dbc7Sjsg hsw_dp_audio_config_update(struct intel_encoder *encoder,
319c349dbc7Sjsg const struct intel_crtc_state *crtc_state)
320c349dbc7Sjsg {
321f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
322c349dbc7Sjsg enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
323c349dbc7Sjsg
324b57ef33fSjsg /* Enable time stamps. Let HW calculate Maud/Naud values */
325b57ef33fSjsg intel_de_rmw(i915, HSW_AUD_CFG(cpu_transcoder),
326b57ef33fSjsg AUD_CONFIG_N_VALUE_INDEX |
327b57ef33fSjsg AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK |
328b57ef33fSjsg AUD_CONFIG_UPPER_N_MASK |
329b57ef33fSjsg AUD_CONFIG_LOWER_N_MASK |
330b57ef33fSjsg AUD_CONFIG_N_PROG_ENABLE,
331b57ef33fSjsg AUD_CONFIG_N_VALUE_INDEX);
332c349dbc7Sjsg
333c349dbc7Sjsg }
334c349dbc7Sjsg
335c349dbc7Sjsg static void
hsw_hdmi_audio_config_update(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)336c349dbc7Sjsg hsw_hdmi_audio_config_update(struct intel_encoder *encoder,
337c349dbc7Sjsg const struct intel_crtc_state *crtc_state)
338c349dbc7Sjsg {
339f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
340f005ef32Sjsg struct i915_audio_component *acomp = i915->display.audio.component;
341c349dbc7Sjsg enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
342c349dbc7Sjsg enum port port = encoder->port;
343c349dbc7Sjsg int n, rate;
344c349dbc7Sjsg u32 tmp;
345c349dbc7Sjsg
346c349dbc7Sjsg rate = acomp ? acomp->aud_sample_rate[port] : 0;
347c349dbc7Sjsg
348f005ef32Sjsg tmp = intel_de_read(i915, HSW_AUD_CFG(cpu_transcoder));
349c349dbc7Sjsg tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
350c349dbc7Sjsg tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK;
351c349dbc7Sjsg tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
352c349dbc7Sjsg tmp |= audio_config_hdmi_pixel_clock(crtc_state);
353c349dbc7Sjsg
354c349dbc7Sjsg n = audio_config_hdmi_get_n(crtc_state, rate);
355c349dbc7Sjsg if (n != 0) {
356f005ef32Sjsg drm_dbg_kms(&i915->drm, "using N %d\n", n);
357c349dbc7Sjsg
358c349dbc7Sjsg tmp &= ~AUD_CONFIG_N_MASK;
359c349dbc7Sjsg tmp |= AUD_CONFIG_N(n);
360c349dbc7Sjsg tmp |= AUD_CONFIG_N_PROG_ENABLE;
361c349dbc7Sjsg } else {
362f005ef32Sjsg drm_dbg_kms(&i915->drm, "using automatic N\n");
363c349dbc7Sjsg }
364c349dbc7Sjsg
365f005ef32Sjsg intel_de_write(i915, HSW_AUD_CFG(cpu_transcoder), tmp);
366c349dbc7Sjsg
367c349dbc7Sjsg /*
368c349dbc7Sjsg * Let's disable "Enable CTS or M Prog bit"
369c349dbc7Sjsg * and let HW calculate the value
370c349dbc7Sjsg */
371f005ef32Sjsg tmp = intel_de_read(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder));
372c349dbc7Sjsg tmp &= ~AUD_M_CTS_M_PROG_ENABLE;
373c349dbc7Sjsg tmp &= ~AUD_M_CTS_M_VALUE_INDEX;
374f005ef32Sjsg intel_de_write(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder), tmp);
375c349dbc7Sjsg }
376c349dbc7Sjsg
377c349dbc7Sjsg static void
hsw_audio_config_update(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)378c349dbc7Sjsg hsw_audio_config_update(struct intel_encoder *encoder,
379c349dbc7Sjsg const struct intel_crtc_state *crtc_state)
380c349dbc7Sjsg {
381c349dbc7Sjsg if (intel_crtc_has_dp_encoder(crtc_state))
382c349dbc7Sjsg hsw_dp_audio_config_update(encoder, crtc_state);
383c349dbc7Sjsg else
384c349dbc7Sjsg hsw_hdmi_audio_config_update(encoder, crtc_state);
385c349dbc7Sjsg }
386c349dbc7Sjsg
hsw_audio_codec_disable(struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)387c349dbc7Sjsg static void hsw_audio_codec_disable(struct intel_encoder *encoder,
388c349dbc7Sjsg const struct intel_crtc_state *old_crtc_state,
389c349dbc7Sjsg const struct drm_connector_state *old_conn_state)
390c349dbc7Sjsg {
391f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
392f005ef32Sjsg struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
393c349dbc7Sjsg enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
394c349dbc7Sjsg
395f005ef32Sjsg mutex_lock(&i915->display.audio.mutex);
396c349dbc7Sjsg
397c349dbc7Sjsg /* Disable timestamps */
398f005ef32Sjsg intel_de_rmw(i915, HSW_AUD_CFG(cpu_transcoder),
399f005ef32Sjsg AUD_CONFIG_N_VALUE_INDEX |
400f005ef32Sjsg AUD_CONFIG_UPPER_N_MASK |
401f005ef32Sjsg AUD_CONFIG_LOWER_N_MASK,
402f005ef32Sjsg AUD_CONFIG_N_PROG_ENABLE |
403f005ef32Sjsg (intel_crtc_has_dp_encoder(old_crtc_state) ?
404f005ef32Sjsg AUD_CONFIG_N_VALUE_INDEX : 0));
405c349dbc7Sjsg
406c349dbc7Sjsg /* Invalidate ELD */
407f005ef32Sjsg intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
408f005ef32Sjsg AUDIO_ELD_VALID(cpu_transcoder), 0);
409c349dbc7Sjsg
410f005ef32Sjsg intel_crtc_wait_for_next_vblank(crtc);
411f005ef32Sjsg intel_crtc_wait_for_next_vblank(crtc);
412f005ef32Sjsg
413f005ef32Sjsg /* Disable audio presence detect */
414f005ef32Sjsg intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
415f005ef32Sjsg AUDIO_OUTPUT_ENABLE(cpu_transcoder), 0);
416f005ef32Sjsg
417f005ef32Sjsg mutex_unlock(&i915->display.audio.mutex);
418c349dbc7Sjsg }
419c349dbc7Sjsg
calc_hblank_early_prog(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)420ad8b1aafSjsg static unsigned int calc_hblank_early_prog(struct intel_encoder *encoder,
421ad8b1aafSjsg const struct intel_crtc_state *crtc_state)
422ad8b1aafSjsg {
423ad8b1aafSjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
424ad8b1aafSjsg unsigned int link_clks_available, link_clks_required;
425ad8b1aafSjsg unsigned int tu_data, tu_line, link_clks_active;
426ad8b1aafSjsg unsigned int h_active, h_total, hblank_delta, pixel_clk;
427ad8b1aafSjsg unsigned int fec_coeff, cdclk, vdsc_bpp;
428ad8b1aafSjsg unsigned int link_clk, lanes;
429ad8b1aafSjsg unsigned int hblank_rise;
430ad8b1aafSjsg
431ad8b1aafSjsg h_active = crtc_state->hw.adjusted_mode.crtc_hdisplay;
432ad8b1aafSjsg h_total = crtc_state->hw.adjusted_mode.crtc_htotal;
433ad8b1aafSjsg pixel_clk = crtc_state->hw.adjusted_mode.crtc_clock;
434ad8b1aafSjsg vdsc_bpp = crtc_state->dsc.compressed_bpp;
4351bb76ff1Sjsg cdclk = i915->display.cdclk.hw.cdclk;
436ad8b1aafSjsg /* fec= 0.972261, using rounding multiplier of 1000000 */
437ad8b1aafSjsg fec_coeff = 972261;
438ad8b1aafSjsg link_clk = crtc_state->port_clock;
439ad8b1aafSjsg lanes = crtc_state->lane_count;
440ad8b1aafSjsg
441ad8b1aafSjsg drm_dbg_kms(&i915->drm, "h_active = %u link_clk = %u :"
442ad8b1aafSjsg "lanes = %u vdsc_bpp = %u cdclk = %u\n",
443ad8b1aafSjsg h_active, link_clk, lanes, vdsc_bpp, cdclk);
444ad8b1aafSjsg
445ad8b1aafSjsg if (WARN_ON(!link_clk || !pixel_clk || !lanes || !vdsc_bpp || !cdclk))
446ad8b1aafSjsg return 0;
447ad8b1aafSjsg
448ad8b1aafSjsg link_clks_available = (h_total - h_active) * link_clk / pixel_clk - 28;
449ad8b1aafSjsg link_clks_required = DIV_ROUND_UP(192000 * h_total, 1000 * pixel_clk) * (48 / lanes + 2);
450ad8b1aafSjsg
451ad8b1aafSjsg if (link_clks_available > link_clks_required)
452ad8b1aafSjsg hblank_delta = 32;
453ad8b1aafSjsg else
454ad8b1aafSjsg hblank_delta = DIV64_U64_ROUND_UP(mul_u32_u32(5 * (link_clk + cdclk), pixel_clk),
455ad8b1aafSjsg mul_u32_u32(link_clk, cdclk));
456ad8b1aafSjsg
457ad8b1aafSjsg tu_data = div64_u64(mul_u32_u32(pixel_clk * vdsc_bpp * 8, 1000000),
458ad8b1aafSjsg mul_u32_u32(link_clk * lanes, fec_coeff));
459ad8b1aafSjsg tu_line = div64_u64(h_active * mul_u32_u32(link_clk, fec_coeff),
460ad8b1aafSjsg mul_u32_u32(64 * pixel_clk, 1000000));
461ad8b1aafSjsg link_clks_active = (tu_line - 1) * 64 + tu_data;
462ad8b1aafSjsg
463ad8b1aafSjsg hblank_rise = (link_clks_active + 6 * DIV_ROUND_UP(link_clks_active, 250) + 4) * pixel_clk / link_clk;
464ad8b1aafSjsg
465ad8b1aafSjsg return h_active - hblank_rise + hblank_delta;
466ad8b1aafSjsg }
467ad8b1aafSjsg
calc_samples_room(const struct intel_crtc_state * crtc_state)468ad8b1aafSjsg static unsigned int calc_samples_room(const struct intel_crtc_state *crtc_state)
469ad8b1aafSjsg {
470ad8b1aafSjsg unsigned int h_active, h_total, pixel_clk;
471ad8b1aafSjsg unsigned int link_clk, lanes;
472ad8b1aafSjsg
473ad8b1aafSjsg h_active = crtc_state->hw.adjusted_mode.hdisplay;
474ad8b1aafSjsg h_total = crtc_state->hw.adjusted_mode.htotal;
475ad8b1aafSjsg pixel_clk = crtc_state->hw.adjusted_mode.clock;
476ad8b1aafSjsg link_clk = crtc_state->port_clock;
477ad8b1aafSjsg lanes = crtc_state->lane_count;
478ad8b1aafSjsg
479ad8b1aafSjsg return ((h_total - h_active) * link_clk - 12 * pixel_clk) /
480ad8b1aafSjsg (pixel_clk * (48 / lanes + 2));
481ad8b1aafSjsg }
482ad8b1aafSjsg
enable_audio_dsc_wa(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)483ad8b1aafSjsg static void enable_audio_dsc_wa(struct intel_encoder *encoder,
484ad8b1aafSjsg const struct intel_crtc_state *crtc_state)
485ad8b1aafSjsg {
486ad8b1aafSjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
487f005ef32Sjsg enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
488ad8b1aafSjsg unsigned int hblank_early_prog, samples_room;
489ad8b1aafSjsg unsigned int val;
490ad8b1aafSjsg
4915ca02815Sjsg if (DISPLAY_VER(i915) < 11)
492ad8b1aafSjsg return;
493ad8b1aafSjsg
494ad8b1aafSjsg val = intel_de_read(i915, AUD_CONFIG_BE);
495ad8b1aafSjsg
4965ca02815Sjsg if (DISPLAY_VER(i915) == 11)
497f005ef32Sjsg val |= HBLANK_EARLY_ENABLE_ICL(cpu_transcoder);
4985ca02815Sjsg else if (DISPLAY_VER(i915) >= 12)
499f005ef32Sjsg val |= HBLANK_EARLY_ENABLE_TGL(cpu_transcoder);
500ad8b1aafSjsg
501ad8b1aafSjsg if (crtc_state->dsc.compression_enable &&
5025ca02815Sjsg crtc_state->hw.adjusted_mode.hdisplay >= 3840 &&
5035ca02815Sjsg crtc_state->hw.adjusted_mode.vdisplay >= 2160) {
504ad8b1aafSjsg /* Get hblank early enable value required */
505f005ef32Sjsg val &= ~HBLANK_START_COUNT_MASK(cpu_transcoder);
506ad8b1aafSjsg hblank_early_prog = calc_hblank_early_prog(encoder, crtc_state);
5075ca02815Sjsg if (hblank_early_prog < 32)
508f005ef32Sjsg val |= HBLANK_START_COUNT(cpu_transcoder, HBLANK_START_COUNT_32);
5095ca02815Sjsg else if (hblank_early_prog < 64)
510f005ef32Sjsg val |= HBLANK_START_COUNT(cpu_transcoder, HBLANK_START_COUNT_64);
5115ca02815Sjsg else if (hblank_early_prog < 96)
512f005ef32Sjsg val |= HBLANK_START_COUNT(cpu_transcoder, HBLANK_START_COUNT_96);
5135ca02815Sjsg else
514f005ef32Sjsg val |= HBLANK_START_COUNT(cpu_transcoder, HBLANK_START_COUNT_128);
515ad8b1aafSjsg
516ad8b1aafSjsg /* Get samples room value required */
517f005ef32Sjsg val &= ~NUMBER_SAMPLES_PER_LINE_MASK(cpu_transcoder);
518ad8b1aafSjsg samples_room = calc_samples_room(crtc_state);
5195ca02815Sjsg if (samples_room < 3)
520f005ef32Sjsg val |= NUMBER_SAMPLES_PER_LINE(cpu_transcoder, samples_room);
5215ca02815Sjsg else /* Program 0 i.e "All Samples available in buffer" */
522f005ef32Sjsg val |= NUMBER_SAMPLES_PER_LINE(cpu_transcoder, 0x0);
523ad8b1aafSjsg }
524ad8b1aafSjsg
525ad8b1aafSjsg intel_de_write(i915, AUD_CONFIG_BE, val);
526ad8b1aafSjsg }
527ad8b1aafSjsg
hsw_audio_codec_enable(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)528c349dbc7Sjsg static void hsw_audio_codec_enable(struct intel_encoder *encoder,
529c349dbc7Sjsg const struct intel_crtc_state *crtc_state,
530c349dbc7Sjsg const struct drm_connector_state *conn_state)
531c349dbc7Sjsg {
532f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
533f005ef32Sjsg struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
534c349dbc7Sjsg enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
535c349dbc7Sjsg
536f005ef32Sjsg mutex_lock(&i915->display.audio.mutex);
537c349dbc7Sjsg
538ad8b1aafSjsg /* Enable Audio WA for 4k DSC usecases */
539ad8b1aafSjsg if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP))
540ad8b1aafSjsg enable_audio_dsc_wa(encoder, crtc_state);
541ad8b1aafSjsg
542f005ef32Sjsg /* Enable audio presence detect */
543f005ef32Sjsg intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
544f005ef32Sjsg 0, AUDIO_OUTPUT_ENABLE(cpu_transcoder));
545f005ef32Sjsg
546f005ef32Sjsg intel_crtc_wait_for_next_vblank(crtc);
547f005ef32Sjsg
548f005ef32Sjsg /* Invalidate ELD */
549f005ef32Sjsg intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
550f005ef32Sjsg AUDIO_ELD_VALID(cpu_transcoder), 0);
551c349dbc7Sjsg
552c349dbc7Sjsg /*
553f005ef32Sjsg * The audio componenent is used to convey the ELD
554f005ef32Sjsg * instead using of the hardware ELD buffer.
555c349dbc7Sjsg */
556c349dbc7Sjsg
557c349dbc7Sjsg /* Enable timestamps */
558c349dbc7Sjsg hsw_audio_config_update(encoder, crtc_state);
559c349dbc7Sjsg
560f005ef32Sjsg mutex_unlock(&i915->display.audio.mutex);
561c349dbc7Sjsg }
562c349dbc7Sjsg
563f005ef32Sjsg struct ibx_audio_regs {
564f005ef32Sjsg i915_reg_t hdmiw_hdmiedid, aud_config, aud_cntl_st, aud_cntrl_st2;
565f005ef32Sjsg };
566f005ef32Sjsg
ibx_audio_regs_init(struct drm_i915_private * i915,enum pipe pipe,struct ibx_audio_regs * regs)567f005ef32Sjsg static void ibx_audio_regs_init(struct drm_i915_private *i915,
568f005ef32Sjsg enum pipe pipe,
569f005ef32Sjsg struct ibx_audio_regs *regs)
570f005ef32Sjsg {
571f005ef32Sjsg if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
572f005ef32Sjsg regs->hdmiw_hdmiedid = VLV_HDMIW_HDMIEDID(pipe);
573f005ef32Sjsg regs->aud_config = VLV_AUD_CFG(pipe);
574f005ef32Sjsg regs->aud_cntl_st = VLV_AUD_CNTL_ST(pipe);
575f005ef32Sjsg regs->aud_cntrl_st2 = VLV_AUD_CNTL_ST2;
576f005ef32Sjsg } else if (HAS_PCH_CPT(i915)) {
577f005ef32Sjsg regs->hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID(pipe);
578f005ef32Sjsg regs->aud_config = CPT_AUD_CFG(pipe);
579f005ef32Sjsg regs->aud_cntl_st = CPT_AUD_CNTL_ST(pipe);
580f005ef32Sjsg regs->aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
581f005ef32Sjsg } else if (HAS_PCH_IBX(i915)) {
582f005ef32Sjsg regs->hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe);
583f005ef32Sjsg regs->aud_config = IBX_AUD_CFG(pipe);
584f005ef32Sjsg regs->aud_cntl_st = IBX_AUD_CNTL_ST(pipe);
585f005ef32Sjsg regs->aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
586f005ef32Sjsg }
587f005ef32Sjsg }
588f005ef32Sjsg
ibx_audio_codec_disable(struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)589f005ef32Sjsg static void ibx_audio_codec_disable(struct intel_encoder *encoder,
590c349dbc7Sjsg const struct intel_crtc_state *old_crtc_state,
591c349dbc7Sjsg const struct drm_connector_state *old_conn_state)
592c349dbc7Sjsg {
593f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
594c349dbc7Sjsg struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
595c349dbc7Sjsg enum port port = encoder->port;
596f005ef32Sjsg enum pipe pipe = crtc->pipe;
597f005ef32Sjsg struct ibx_audio_regs regs;
598c349dbc7Sjsg
599f005ef32Sjsg if (drm_WARN_ON(&i915->drm, port == PORT_A))
600c349dbc7Sjsg return;
601c349dbc7Sjsg
602f005ef32Sjsg ibx_audio_regs_init(i915, pipe, ®s);
603f005ef32Sjsg
604f005ef32Sjsg mutex_lock(&i915->display.audio.mutex);
605c349dbc7Sjsg
606c349dbc7Sjsg /* Disable timestamps */
607f005ef32Sjsg intel_de_rmw(i915, regs.aud_config,
608f005ef32Sjsg AUD_CONFIG_N_VALUE_INDEX |
609f005ef32Sjsg AUD_CONFIG_UPPER_N_MASK |
610f005ef32Sjsg AUD_CONFIG_LOWER_N_MASK,
611f005ef32Sjsg AUD_CONFIG_N_PROG_ENABLE |
612f005ef32Sjsg (intel_crtc_has_dp_encoder(old_crtc_state) ?
613f005ef32Sjsg AUD_CONFIG_N_VALUE_INDEX : 0));
614c349dbc7Sjsg
615c349dbc7Sjsg /* Invalidate ELD */
616f005ef32Sjsg intel_de_rmw(i915, regs.aud_cntrl_st2,
617f005ef32Sjsg IBX_ELD_VALID(port), 0);
618f005ef32Sjsg
619f005ef32Sjsg mutex_unlock(&i915->display.audio.mutex);
620f005ef32Sjsg
621f005ef32Sjsg intel_crtc_wait_for_next_vblank(crtc);
622f005ef32Sjsg intel_crtc_wait_for_next_vblank(crtc);
623c349dbc7Sjsg }
624c349dbc7Sjsg
ibx_audio_codec_enable(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)625f005ef32Sjsg static void ibx_audio_codec_enable(struct intel_encoder *encoder,
626c349dbc7Sjsg const struct intel_crtc_state *crtc_state,
627c349dbc7Sjsg const struct drm_connector_state *conn_state)
628c349dbc7Sjsg {
629f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
630c349dbc7Sjsg struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
631c349dbc7Sjsg enum port port = encoder->port;
632f005ef32Sjsg enum pipe pipe = crtc->pipe;
633f005ef32Sjsg struct ibx_audio_regs regs;
634c349dbc7Sjsg
635f005ef32Sjsg if (drm_WARN_ON(&i915->drm, port == PORT_A))
636c349dbc7Sjsg return;
637c349dbc7Sjsg
638f005ef32Sjsg intel_crtc_wait_for_next_vblank(crtc);
639c349dbc7Sjsg
640f005ef32Sjsg ibx_audio_regs_init(i915, pipe, ®s);
641c349dbc7Sjsg
642f005ef32Sjsg mutex_lock(&i915->display.audio.mutex);
643c349dbc7Sjsg
644c349dbc7Sjsg /* Invalidate ELD */
645f005ef32Sjsg intel_de_rmw(i915, regs.aud_cntrl_st2,
646f005ef32Sjsg IBX_ELD_VALID(port), 0);
647c349dbc7Sjsg
648f005ef32Sjsg /*
649f005ef32Sjsg * The audio componenent is used to convey the ELD
650f005ef32Sjsg * instead using of the hardware ELD buffer.
651f005ef32Sjsg */
652c349dbc7Sjsg
653c349dbc7Sjsg /* Enable timestamps */
654f005ef32Sjsg intel_de_rmw(i915, regs.aud_config,
655f005ef32Sjsg AUD_CONFIG_N_VALUE_INDEX |
656f005ef32Sjsg AUD_CONFIG_N_PROG_ENABLE |
657f005ef32Sjsg AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK,
658f005ef32Sjsg (intel_crtc_has_dp_encoder(crtc_state) ?
659f005ef32Sjsg AUD_CONFIG_N_VALUE_INDEX :
660f005ef32Sjsg audio_config_hdmi_pixel_clock(crtc_state)));
661f005ef32Sjsg
662f005ef32Sjsg mutex_unlock(&i915->display.audio.mutex);
663f005ef32Sjsg }
664f005ef32Sjsg
intel_audio_sdp_split_update(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)665f005ef32Sjsg void intel_audio_sdp_split_update(struct intel_encoder *encoder,
666f005ef32Sjsg const struct intel_crtc_state *crtc_state)
667f005ef32Sjsg {
668f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
669f005ef32Sjsg enum transcoder trans = crtc_state->cpu_transcoder;
670f005ef32Sjsg
671f005ef32Sjsg if (HAS_DP20(i915))
672f005ef32Sjsg intel_de_rmw(i915, AUD_DP_2DOT0_CTRL(trans), AUD_ENABLE_SDP_SPLIT,
673f005ef32Sjsg crtc_state->sdp_split_enable ? AUD_ENABLE_SDP_SPLIT : 0);
674f005ef32Sjsg }
675f005ef32Sjsg
intel_audio_compute_config(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state,struct drm_connector_state * conn_state)676f005ef32Sjsg bool intel_audio_compute_config(struct intel_encoder *encoder,
677f005ef32Sjsg struct intel_crtc_state *crtc_state,
678f005ef32Sjsg struct drm_connector_state *conn_state)
679f005ef32Sjsg {
680f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
681f005ef32Sjsg struct drm_connector *connector = conn_state->connector;
682f005ef32Sjsg const struct drm_display_mode *adjusted_mode =
683f005ef32Sjsg &crtc_state->hw.adjusted_mode;
684f005ef32Sjsg
685f005ef32Sjsg if (!connector->eld[0]) {
686f005ef32Sjsg drm_dbg_kms(&i915->drm,
687f005ef32Sjsg "Bogus ELD on [CONNECTOR:%d:%s]\n",
688f005ef32Sjsg connector->base.id, connector->name);
689f005ef32Sjsg return false;
690f005ef32Sjsg }
691f005ef32Sjsg
692f005ef32Sjsg BUILD_BUG_ON(sizeof(crtc_state->eld) != sizeof(connector->eld));
693f005ef32Sjsg memcpy(crtc_state->eld, connector->eld, sizeof(crtc_state->eld));
694f005ef32Sjsg
695f005ef32Sjsg crtc_state->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2;
696f005ef32Sjsg
697f005ef32Sjsg return true;
698c349dbc7Sjsg }
699c349dbc7Sjsg
700c349dbc7Sjsg /**
701c349dbc7Sjsg * intel_audio_codec_enable - Enable the audio codec for HD audio
702c349dbc7Sjsg * @encoder: encoder on which to enable audio
703c349dbc7Sjsg * @crtc_state: pointer to the current crtc state.
704c349dbc7Sjsg * @conn_state: pointer to the current connector state.
705c349dbc7Sjsg *
706c349dbc7Sjsg * The enable sequences may only be performed after enabling the transcoder and
707c349dbc7Sjsg * port, and after completed link training.
708c349dbc7Sjsg */
intel_audio_codec_enable(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)709c349dbc7Sjsg void intel_audio_codec_enable(struct intel_encoder *encoder,
710c349dbc7Sjsg const struct intel_crtc_state *crtc_state,
711c349dbc7Sjsg const struct drm_connector_state *conn_state)
712c349dbc7Sjsg {
713f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
714f005ef32Sjsg struct i915_audio_component *acomp = i915->display.audio.component;
715c349dbc7Sjsg struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
716f005ef32Sjsg struct intel_connector *connector = to_intel_connector(conn_state->connector);
717f005ef32Sjsg enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
718f005ef32Sjsg struct intel_audio_state *audio_state;
719c349dbc7Sjsg enum port port = encoder->port;
720c349dbc7Sjsg
7211bb76ff1Sjsg if (!crtc_state->has_audio)
7221bb76ff1Sjsg return;
7231bb76ff1Sjsg
724f005ef32Sjsg drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s][ENCODER:%d:%s] Enable audio codec on [CRTC:%d:%s], %u bytes ELD\n",
725f005ef32Sjsg connector->base.base.id, connector->base.name,
7261bb76ff1Sjsg encoder->base.base.id, encoder->base.name,
727f005ef32Sjsg crtc->base.base.id, crtc->base.name,
728f005ef32Sjsg drm_eld_size(crtc_state->eld));
7291bb76ff1Sjsg
730f005ef32Sjsg if (i915->display.funcs.audio)
731f005ef32Sjsg i915->display.funcs.audio->audio_codec_enable(encoder,
732c349dbc7Sjsg crtc_state,
733c349dbc7Sjsg conn_state);
734c349dbc7Sjsg
735f005ef32Sjsg mutex_lock(&i915->display.audio.mutex);
736c349dbc7Sjsg
737f005ef32Sjsg audio_state = &i915->display.audio.state[cpu_transcoder];
738f005ef32Sjsg
739f005ef32Sjsg audio_state->encoder = encoder;
740f005ef32Sjsg BUILD_BUG_ON(sizeof(audio_state->eld) != sizeof(crtc_state->eld));
741f005ef32Sjsg memcpy(audio_state->eld, crtc_state->eld, sizeof(audio_state->eld));
742f005ef32Sjsg
743f005ef32Sjsg mutex_unlock(&i915->display.audio.mutex);
744c349dbc7Sjsg
745c349dbc7Sjsg if (acomp && acomp->base.audio_ops &&
746c349dbc7Sjsg acomp->base.audio_ops->pin_eld_notify) {
747f005ef32Sjsg /* audio drivers expect cpu_transcoder = -1 to indicate Non-MST cases */
748c349dbc7Sjsg if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))
749f005ef32Sjsg cpu_transcoder = -1;
750c349dbc7Sjsg acomp->base.audio_ops->pin_eld_notify(acomp->base.audio_ops->audio_ptr,
751f005ef32Sjsg (int)port, (int)cpu_transcoder);
752c349dbc7Sjsg }
753c349dbc7Sjsg
754f005ef32Sjsg intel_lpe_audio_notify(i915, cpu_transcoder, port, crtc_state->eld,
755c349dbc7Sjsg crtc_state->port_clock,
756c349dbc7Sjsg intel_crtc_has_dp_encoder(crtc_state));
757c349dbc7Sjsg }
758c349dbc7Sjsg
759c349dbc7Sjsg /**
760c349dbc7Sjsg * intel_audio_codec_disable - Disable the audio codec for HD audio
761c349dbc7Sjsg * @encoder: encoder on which to disable audio
762c349dbc7Sjsg * @old_crtc_state: pointer to the old crtc state.
763c349dbc7Sjsg * @old_conn_state: pointer to the old connector state.
764c349dbc7Sjsg *
765c349dbc7Sjsg * The disable sequences must be performed before disabling the transcoder or
766c349dbc7Sjsg * port.
767c349dbc7Sjsg */
intel_audio_codec_disable(struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)768c349dbc7Sjsg void intel_audio_codec_disable(struct intel_encoder *encoder,
769c349dbc7Sjsg const struct intel_crtc_state *old_crtc_state,
770c349dbc7Sjsg const struct drm_connector_state *old_conn_state)
771c349dbc7Sjsg {
772f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
773f005ef32Sjsg struct i915_audio_component *acomp = i915->display.audio.component;
774c349dbc7Sjsg struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
775f005ef32Sjsg struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
776f005ef32Sjsg enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
777f005ef32Sjsg struct intel_audio_state *audio_state;
778c349dbc7Sjsg enum port port = encoder->port;
779c349dbc7Sjsg
7801bb76ff1Sjsg if (!old_crtc_state->has_audio)
7811bb76ff1Sjsg return;
7821bb76ff1Sjsg
783f005ef32Sjsg drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s][ENCODER:%d:%s] Disable audio codec on [CRTC:%d:%s]\n",
784f005ef32Sjsg connector->base.base.id, connector->base.name,
785f005ef32Sjsg encoder->base.base.id, encoder->base.name,
786f005ef32Sjsg crtc->base.base.id, crtc->base.name);
7871bb76ff1Sjsg
788f005ef32Sjsg if (i915->display.funcs.audio)
789f005ef32Sjsg i915->display.funcs.audio->audio_codec_disable(encoder,
790c349dbc7Sjsg old_crtc_state,
791c349dbc7Sjsg old_conn_state);
792c349dbc7Sjsg
793f005ef32Sjsg mutex_lock(&i915->display.audio.mutex);
794f005ef32Sjsg
795f005ef32Sjsg audio_state = &i915->display.audio.state[cpu_transcoder];
796f005ef32Sjsg
797f005ef32Sjsg audio_state->encoder = NULL;
798f005ef32Sjsg memset(audio_state->eld, 0, sizeof(audio_state->eld));
799f005ef32Sjsg
800f005ef32Sjsg mutex_unlock(&i915->display.audio.mutex);
801c349dbc7Sjsg
802c349dbc7Sjsg if (acomp && acomp->base.audio_ops &&
803c349dbc7Sjsg acomp->base.audio_ops->pin_eld_notify) {
804f005ef32Sjsg /* audio drivers expect cpu_transcoder = -1 to indicate Non-MST cases */
805c349dbc7Sjsg if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST))
806f005ef32Sjsg cpu_transcoder = -1;
807c349dbc7Sjsg acomp->base.audio_ops->pin_eld_notify(acomp->base.audio_ops->audio_ptr,
808f005ef32Sjsg (int)port, (int)cpu_transcoder);
809c349dbc7Sjsg }
810c349dbc7Sjsg
811f005ef32Sjsg intel_lpe_audio_notify(i915, cpu_transcoder, port, NULL, 0, false);
812f005ef32Sjsg }
813f005ef32Sjsg
intel_acomp_get_config(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state)814f005ef32Sjsg static void intel_acomp_get_config(struct intel_encoder *encoder,
815f005ef32Sjsg struct intel_crtc_state *crtc_state)
816f005ef32Sjsg {
817f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
818f005ef32Sjsg enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
819f005ef32Sjsg struct intel_audio_state *audio_state;
820f005ef32Sjsg
821f005ef32Sjsg mutex_lock(&i915->display.audio.mutex);
822f005ef32Sjsg
823f005ef32Sjsg audio_state = &i915->display.audio.state[cpu_transcoder];
824f005ef32Sjsg
825f005ef32Sjsg if (audio_state->encoder)
826f005ef32Sjsg memcpy(crtc_state->eld, audio_state->eld, sizeof(audio_state->eld));
827f005ef32Sjsg
828f005ef32Sjsg mutex_unlock(&i915->display.audio.mutex);
829f005ef32Sjsg }
830f005ef32Sjsg
intel_audio_codec_get_config(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state)831f005ef32Sjsg void intel_audio_codec_get_config(struct intel_encoder *encoder,
832f005ef32Sjsg struct intel_crtc_state *crtc_state)
833f005ef32Sjsg {
834f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
835f005ef32Sjsg
836f005ef32Sjsg if (!crtc_state->has_audio)
837f005ef32Sjsg return;
838f005ef32Sjsg
839f005ef32Sjsg if (i915->display.funcs.audio)
840f005ef32Sjsg i915->display.funcs.audio->audio_codec_get_config(encoder, crtc_state);
841c349dbc7Sjsg }
842c349dbc7Sjsg
8431bb76ff1Sjsg static const struct intel_audio_funcs g4x_audio_funcs = {
8441bb76ff1Sjsg .audio_codec_enable = g4x_audio_codec_enable,
8451bb76ff1Sjsg .audio_codec_disable = g4x_audio_codec_disable,
846f005ef32Sjsg .audio_codec_get_config = g4x_audio_codec_get_config,
8471bb76ff1Sjsg };
8481bb76ff1Sjsg
849f005ef32Sjsg static const struct intel_audio_funcs ibx_audio_funcs = {
850f005ef32Sjsg .audio_codec_enable = ibx_audio_codec_enable,
851f005ef32Sjsg .audio_codec_disable = ibx_audio_codec_disable,
852f005ef32Sjsg .audio_codec_get_config = intel_acomp_get_config,
8531bb76ff1Sjsg };
8541bb76ff1Sjsg
8551bb76ff1Sjsg static const struct intel_audio_funcs hsw_audio_funcs = {
8561bb76ff1Sjsg .audio_codec_enable = hsw_audio_codec_enable,
8571bb76ff1Sjsg .audio_codec_disable = hsw_audio_codec_disable,
858f005ef32Sjsg .audio_codec_get_config = intel_acomp_get_config,
8591bb76ff1Sjsg };
8601bb76ff1Sjsg
861c349dbc7Sjsg /**
8621bb76ff1Sjsg * intel_audio_hooks_init - Set up chip specific audio hooks
863f005ef32Sjsg * @i915: device private
864c349dbc7Sjsg */
intel_audio_hooks_init(struct drm_i915_private * i915)865f005ef32Sjsg void intel_audio_hooks_init(struct drm_i915_private *i915)
866c349dbc7Sjsg {
867f005ef32Sjsg if (IS_G4X(i915))
868f005ef32Sjsg i915->display.funcs.audio = &g4x_audio_funcs;
869f005ef32Sjsg else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915) ||
870f005ef32Sjsg HAS_PCH_CPT(i915) || HAS_PCH_IBX(i915))
871f005ef32Sjsg i915->display.funcs.audio = &ibx_audio_funcs;
872f005ef32Sjsg else if (IS_HASWELL(i915) || DISPLAY_VER(i915) >= 8)
873f005ef32Sjsg i915->display.funcs.audio = &hsw_audio_funcs;
8741bb76ff1Sjsg }
8751bb76ff1Sjsg
8761bb76ff1Sjsg struct aud_ts_cdclk_m_n {
8771bb76ff1Sjsg u8 m;
8781bb76ff1Sjsg u16 n;
8791bb76ff1Sjsg };
8801bb76ff1Sjsg
intel_audio_cdclk_change_pre(struct drm_i915_private * i915)8811bb76ff1Sjsg void intel_audio_cdclk_change_pre(struct drm_i915_private *i915)
8821bb76ff1Sjsg {
8831bb76ff1Sjsg if (DISPLAY_VER(i915) >= 13)
8841bb76ff1Sjsg intel_de_rmw(i915, AUD_TS_CDCLK_M, AUD_TS_CDCLK_M_EN, 0);
8851bb76ff1Sjsg }
8861bb76ff1Sjsg
get_aud_ts_cdclk_m_n(int refclk,int cdclk,struct aud_ts_cdclk_m_n * aud_ts)8871bb76ff1Sjsg static void get_aud_ts_cdclk_m_n(int refclk, int cdclk, struct aud_ts_cdclk_m_n *aud_ts)
8881bb76ff1Sjsg {
889f005ef32Sjsg aud_ts->m = 60;
8901bb76ff1Sjsg aud_ts->n = cdclk * aud_ts->m / 24000;
8911bb76ff1Sjsg }
8921bb76ff1Sjsg
intel_audio_cdclk_change_post(struct drm_i915_private * i915)8931bb76ff1Sjsg void intel_audio_cdclk_change_post(struct drm_i915_private *i915)
8941bb76ff1Sjsg {
8951bb76ff1Sjsg struct aud_ts_cdclk_m_n aud_ts;
8961bb76ff1Sjsg
8971bb76ff1Sjsg if (DISPLAY_VER(i915) >= 13) {
8981bb76ff1Sjsg get_aud_ts_cdclk_m_n(i915->display.cdclk.hw.ref, i915->display.cdclk.hw.cdclk, &aud_ts);
8991bb76ff1Sjsg
9001bb76ff1Sjsg intel_de_write(i915, AUD_TS_CDCLK_N, aud_ts.n);
9011bb76ff1Sjsg intel_de_write(i915, AUD_TS_CDCLK_M, aud_ts.m | AUD_TS_CDCLK_M_EN);
9021bb76ff1Sjsg drm_dbg_kms(&i915->drm, "aud_ts_cdclk set to M=%u, N=%u\n", aud_ts.m, aud_ts.n);
903c349dbc7Sjsg }
904c349dbc7Sjsg }
905c349dbc7Sjsg
glk_force_audio_cdclk_commit(struct intel_atomic_state * state,struct intel_crtc * crtc,bool enable)906c349dbc7Sjsg static int glk_force_audio_cdclk_commit(struct intel_atomic_state *state,
907c349dbc7Sjsg struct intel_crtc *crtc,
908c349dbc7Sjsg bool enable)
909c349dbc7Sjsg {
910c349dbc7Sjsg struct intel_cdclk_state *cdclk_state;
911c349dbc7Sjsg int ret;
912c349dbc7Sjsg
913c349dbc7Sjsg /* need to hold at least one crtc lock for the global state */
914c349dbc7Sjsg ret = drm_modeset_lock(&crtc->base.mutex, state->base.acquire_ctx);
915c349dbc7Sjsg if (ret)
916c349dbc7Sjsg return ret;
917c349dbc7Sjsg
918c349dbc7Sjsg cdclk_state = intel_atomic_get_cdclk_state(state);
919c349dbc7Sjsg if (IS_ERR(cdclk_state))
920c349dbc7Sjsg return PTR_ERR(cdclk_state);
921c349dbc7Sjsg
922c349dbc7Sjsg cdclk_state->force_min_cdclk = enable ? 2 * 96000 : 0;
923c349dbc7Sjsg
924c349dbc7Sjsg return drm_atomic_commit(&state->base);
925c349dbc7Sjsg }
926c349dbc7Sjsg
glk_force_audio_cdclk(struct drm_i915_private * i915,bool enable)927f005ef32Sjsg static void glk_force_audio_cdclk(struct drm_i915_private *i915,
928c349dbc7Sjsg bool enable)
929c349dbc7Sjsg {
930c349dbc7Sjsg struct drm_modeset_acquire_ctx ctx;
931c349dbc7Sjsg struct drm_atomic_state *state;
932c349dbc7Sjsg struct intel_crtc *crtc;
933c349dbc7Sjsg int ret;
934c349dbc7Sjsg
935f005ef32Sjsg crtc = intel_first_crtc(i915);
936c349dbc7Sjsg if (!crtc)
937c349dbc7Sjsg return;
938c349dbc7Sjsg
939c349dbc7Sjsg drm_modeset_acquire_init(&ctx, 0);
940f005ef32Sjsg state = drm_atomic_state_alloc(&i915->drm);
941f005ef32Sjsg if (drm_WARN_ON(&i915->drm, !state))
942c349dbc7Sjsg return;
943c349dbc7Sjsg
944c349dbc7Sjsg state->acquire_ctx = &ctx;
945f005ef32Sjsg to_intel_atomic_state(state)->internal = true;
946c349dbc7Sjsg
947c349dbc7Sjsg retry:
948c349dbc7Sjsg ret = glk_force_audio_cdclk_commit(to_intel_atomic_state(state), crtc,
949c349dbc7Sjsg enable);
950c349dbc7Sjsg if (ret == -EDEADLK) {
951c349dbc7Sjsg drm_atomic_state_clear(state);
952c349dbc7Sjsg drm_modeset_backoff(&ctx);
953c349dbc7Sjsg goto retry;
954c349dbc7Sjsg }
955c349dbc7Sjsg
956f005ef32Sjsg drm_WARN_ON(&i915->drm, ret);
957c349dbc7Sjsg
958c349dbc7Sjsg drm_atomic_state_put(state);
959c349dbc7Sjsg
960c349dbc7Sjsg drm_modeset_drop_locks(&ctx);
961c349dbc7Sjsg drm_modeset_acquire_fini(&ctx);
962c349dbc7Sjsg }
963c349dbc7Sjsg
i915_audio_component_get_power(struct device * kdev)964c349dbc7Sjsg static unsigned long i915_audio_component_get_power(struct device *kdev)
965c349dbc7Sjsg {
966f005ef32Sjsg struct drm_i915_private *i915 = kdev_to_i915(kdev);
967c349dbc7Sjsg intel_wakeref_t ret;
968c349dbc7Sjsg
969c349dbc7Sjsg /* Catch potential impedance mismatches before they occur! */
970c349dbc7Sjsg BUILD_BUG_ON(sizeof(intel_wakeref_t) > sizeof(unsigned long));
971c349dbc7Sjsg
972f005ef32Sjsg ret = intel_display_power_get(i915, POWER_DOMAIN_AUDIO_PLAYBACK);
973c349dbc7Sjsg
974f005ef32Sjsg if (i915->display.audio.power_refcount++ == 0) {
975f005ef32Sjsg if (DISPLAY_VER(i915) >= 9) {
976f005ef32Sjsg intel_de_write(i915, AUD_FREQ_CNTRL,
977f005ef32Sjsg i915->display.audio.freq_cntrl);
978f005ef32Sjsg drm_dbg_kms(&i915->drm,
979c349dbc7Sjsg "restored AUD_FREQ_CNTRL to 0x%x\n",
980f005ef32Sjsg i915->display.audio.freq_cntrl);
981c349dbc7Sjsg }
982c349dbc7Sjsg
983c349dbc7Sjsg /* Force CDCLK to 2*BCLK as long as we need audio powered. */
984f005ef32Sjsg if (IS_GEMINILAKE(i915))
985f005ef32Sjsg glk_force_audio_cdclk(i915, true);
986c349dbc7Sjsg
987f005ef32Sjsg if (DISPLAY_VER(i915) >= 10)
988f005ef32Sjsg intel_de_rmw(i915, AUD_PIN_BUF_CTL,
989f005ef32Sjsg 0, AUD_PIN_BUF_ENABLE);
990c349dbc7Sjsg }
991c349dbc7Sjsg
992c349dbc7Sjsg return ret;
993c349dbc7Sjsg }
994c349dbc7Sjsg
i915_audio_component_put_power(struct device * kdev,unsigned long cookie)995c349dbc7Sjsg static void i915_audio_component_put_power(struct device *kdev,
996c349dbc7Sjsg unsigned long cookie)
997c349dbc7Sjsg {
998f005ef32Sjsg struct drm_i915_private *i915 = kdev_to_i915(kdev);
999c349dbc7Sjsg
1000c349dbc7Sjsg /* Stop forcing CDCLK to 2*BCLK if no need for audio to be powered. */
1001f005ef32Sjsg if (--i915->display.audio.power_refcount == 0)
1002f005ef32Sjsg if (IS_GEMINILAKE(i915))
1003f005ef32Sjsg glk_force_audio_cdclk(i915, false);
1004c349dbc7Sjsg
1005f005ef32Sjsg intel_display_power_put(i915, POWER_DOMAIN_AUDIO_PLAYBACK, cookie);
1006c349dbc7Sjsg }
1007c349dbc7Sjsg
i915_audio_component_codec_wake_override(struct device * kdev,bool enable)1008c349dbc7Sjsg static void i915_audio_component_codec_wake_override(struct device *kdev,
1009c349dbc7Sjsg bool enable)
1010c349dbc7Sjsg {
1011f005ef32Sjsg struct drm_i915_private *i915 = kdev_to_i915(kdev);
1012c349dbc7Sjsg unsigned long cookie;
1013c349dbc7Sjsg
1014f005ef32Sjsg if (DISPLAY_VER(i915) < 9)
1015c349dbc7Sjsg return;
1016c349dbc7Sjsg
1017c349dbc7Sjsg cookie = i915_audio_component_get_power(kdev);
1018c349dbc7Sjsg
1019c349dbc7Sjsg /*
1020c349dbc7Sjsg * Enable/disable generating the codec wake signal, overriding the
1021c349dbc7Sjsg * internal logic to generate the codec wake to controller.
1022c349dbc7Sjsg */
1023f005ef32Sjsg intel_de_rmw(i915, HSW_AUD_CHICKENBIT,
1024f005ef32Sjsg SKL_AUD_CODEC_WAKE_SIGNAL, 0);
1025c349dbc7Sjsg usleep_range(1000, 1500);
1026c349dbc7Sjsg
1027c349dbc7Sjsg if (enable) {
1028f005ef32Sjsg intel_de_rmw(i915, HSW_AUD_CHICKENBIT,
1029f005ef32Sjsg 0, SKL_AUD_CODEC_WAKE_SIGNAL);
1030c349dbc7Sjsg usleep_range(1000, 1500);
1031c349dbc7Sjsg }
1032c349dbc7Sjsg
1033c349dbc7Sjsg i915_audio_component_put_power(kdev, cookie);
1034c349dbc7Sjsg }
1035c349dbc7Sjsg
1036c349dbc7Sjsg /* Get CDCLK in kHz */
i915_audio_component_get_cdclk_freq(struct device * kdev)1037c349dbc7Sjsg static int i915_audio_component_get_cdclk_freq(struct device *kdev)
1038c349dbc7Sjsg {
1039f005ef32Sjsg struct drm_i915_private *i915 = kdev_to_i915(kdev);
1040c349dbc7Sjsg
1041f005ef32Sjsg if (drm_WARN_ON_ONCE(&i915->drm, !HAS_DDI(i915)))
1042c349dbc7Sjsg return -ENODEV;
1043c349dbc7Sjsg
1044f005ef32Sjsg return i915->display.cdclk.hw.cdclk;
1045c349dbc7Sjsg }
1046c349dbc7Sjsg
1047c349dbc7Sjsg /*
1048f005ef32Sjsg * get the intel audio state according to the parameter port and cpu_transcoder
1049f005ef32Sjsg * MST & (cpu_transcoder >= 0): return the audio.state[cpu_transcoder].encoder],
1050c349dbc7Sjsg * when port is matched
1051f005ef32Sjsg * MST & (cpu_transcoder < 0): this is invalid
1052f005ef32Sjsg * Non-MST & (cpu_transcoder >= 0): only cpu_transcoder = 0 (the first device entry)
1053c349dbc7Sjsg * will get the right intel_encoder with port matched
1054f005ef32Sjsg * Non-MST & (cpu_transcoder < 0): get the right intel_encoder with port matched
1055c349dbc7Sjsg */
find_audio_state(struct drm_i915_private * i915,int port,int cpu_transcoder)1056f005ef32Sjsg static struct intel_audio_state *find_audio_state(struct drm_i915_private *i915,
1057f005ef32Sjsg int port, int cpu_transcoder)
1058c349dbc7Sjsg {
1059f005ef32Sjsg /* MST */
1060f005ef32Sjsg if (cpu_transcoder >= 0) {
1061f005ef32Sjsg struct intel_audio_state *audio_state;
1062c349dbc7Sjsg struct intel_encoder *encoder;
1063c349dbc7Sjsg
1064f005ef32Sjsg if (drm_WARN_ON(&i915->drm,
1065f005ef32Sjsg cpu_transcoder >= ARRAY_SIZE(i915->display.audio.state)))
1066c349dbc7Sjsg return NULL;
1067c349dbc7Sjsg
1068f005ef32Sjsg audio_state = &i915->display.audio.state[cpu_transcoder];
1069f005ef32Sjsg encoder = audio_state->encoder;
1070f005ef32Sjsg
1071f005ef32Sjsg if (encoder && encoder->port == port &&
1072c349dbc7Sjsg encoder->type == INTEL_OUTPUT_DP_MST)
1073f005ef32Sjsg return audio_state;
1074c349dbc7Sjsg }
1075c349dbc7Sjsg
1076c349dbc7Sjsg /* Non-MST */
1077f005ef32Sjsg if (cpu_transcoder > 0)
1078c349dbc7Sjsg return NULL;
1079c349dbc7Sjsg
1080f005ef32Sjsg for_each_cpu_transcoder(i915, cpu_transcoder) {
1081f005ef32Sjsg struct intel_audio_state *audio_state;
1082f005ef32Sjsg struct intel_encoder *encoder;
1083c349dbc7Sjsg
1084f005ef32Sjsg audio_state = &i915->display.audio.state[cpu_transcoder];
1085f005ef32Sjsg encoder = audio_state->encoder;
1086c349dbc7Sjsg
1087f005ef32Sjsg if (encoder && encoder->port == port &&
1088f005ef32Sjsg encoder->type != INTEL_OUTPUT_DP_MST)
1089f005ef32Sjsg return audio_state;
1090c349dbc7Sjsg }
1091c349dbc7Sjsg
1092c349dbc7Sjsg return NULL;
1093c349dbc7Sjsg }
1094c349dbc7Sjsg
i915_audio_component_sync_audio_rate(struct device * kdev,int port,int cpu_transcoder,int rate)1095c349dbc7Sjsg static int i915_audio_component_sync_audio_rate(struct device *kdev, int port,
1096f005ef32Sjsg int cpu_transcoder, int rate)
1097c349dbc7Sjsg {
1098f005ef32Sjsg struct drm_i915_private *i915 = kdev_to_i915(kdev);
1099f005ef32Sjsg struct i915_audio_component *acomp = i915->display.audio.component;
1100f005ef32Sjsg const struct intel_audio_state *audio_state;
1101c349dbc7Sjsg struct intel_encoder *encoder;
1102c349dbc7Sjsg struct intel_crtc *crtc;
1103c349dbc7Sjsg unsigned long cookie;
1104c349dbc7Sjsg int err = 0;
1105c349dbc7Sjsg
1106f005ef32Sjsg if (!HAS_DDI(i915))
1107c349dbc7Sjsg return 0;
1108c349dbc7Sjsg
1109c349dbc7Sjsg cookie = i915_audio_component_get_power(kdev);
1110f005ef32Sjsg mutex_lock(&i915->display.audio.mutex);
1111c349dbc7Sjsg
1112f005ef32Sjsg audio_state = find_audio_state(i915, port, cpu_transcoder);
1113f005ef32Sjsg if (!audio_state) {
1114f005ef32Sjsg drm_dbg_kms(&i915->drm, "Not valid for port %c\n", port_name(port));
1115c349dbc7Sjsg err = -ENODEV;
1116c349dbc7Sjsg goto unlock;
1117c349dbc7Sjsg }
1118c349dbc7Sjsg
1119f005ef32Sjsg encoder = audio_state->encoder;
1120f005ef32Sjsg
1121f005ef32Sjsg /* FIXME stop using the legacy crtc pointer */
1122c349dbc7Sjsg crtc = to_intel_crtc(encoder->base.crtc);
1123c349dbc7Sjsg
1124f005ef32Sjsg /* port must be valid now, otherwise the cpu_transcoder will be invalid */
1125c349dbc7Sjsg acomp->aud_sample_rate[port] = rate;
1126c349dbc7Sjsg
1127f005ef32Sjsg /* FIXME get rid of the crtc->config stuff */
1128c349dbc7Sjsg hsw_audio_config_update(encoder, crtc->config);
1129c349dbc7Sjsg
1130c349dbc7Sjsg unlock:
1131f005ef32Sjsg mutex_unlock(&i915->display.audio.mutex);
1132c349dbc7Sjsg i915_audio_component_put_power(kdev, cookie);
1133c349dbc7Sjsg return err;
1134c349dbc7Sjsg }
1135c349dbc7Sjsg
i915_audio_component_get_eld(struct device * kdev,int port,int cpu_transcoder,bool * enabled,unsigned char * buf,int max_bytes)1136c349dbc7Sjsg static int i915_audio_component_get_eld(struct device *kdev, int port,
1137f005ef32Sjsg int cpu_transcoder, bool *enabled,
1138c349dbc7Sjsg unsigned char *buf, int max_bytes)
1139c349dbc7Sjsg {
1140f005ef32Sjsg struct drm_i915_private *i915 = kdev_to_i915(kdev);
1141f005ef32Sjsg const struct intel_audio_state *audio_state;
1142f005ef32Sjsg int ret = 0;
1143c349dbc7Sjsg
1144f005ef32Sjsg mutex_lock(&i915->display.audio.mutex);
1145c349dbc7Sjsg
1146f005ef32Sjsg audio_state = find_audio_state(i915, port, cpu_transcoder);
1147f005ef32Sjsg if (!audio_state) {
1148f005ef32Sjsg drm_dbg_kms(&i915->drm, "Not valid for port %c\n", port_name(port));
1149f005ef32Sjsg mutex_unlock(&i915->display.audio.mutex);
1150f005ef32Sjsg return -EINVAL;
1151c349dbc7Sjsg }
1152c349dbc7Sjsg
1153f005ef32Sjsg *enabled = audio_state->encoder != NULL;
1154c349dbc7Sjsg if (*enabled) {
1155f005ef32Sjsg const u8 *eld = audio_state->eld;
1156f005ef32Sjsg
1157c349dbc7Sjsg ret = drm_eld_size(eld);
1158c349dbc7Sjsg memcpy(buf, eld, min(max_bytes, ret));
1159c349dbc7Sjsg }
1160c349dbc7Sjsg
1161f005ef32Sjsg mutex_unlock(&i915->display.audio.mutex);
1162c349dbc7Sjsg return ret;
1163c349dbc7Sjsg }
1164c349dbc7Sjsg
1165c349dbc7Sjsg #ifdef notyet
1166c349dbc7Sjsg
1167c349dbc7Sjsg static const struct drm_audio_component_ops i915_audio_component_ops = {
1168c349dbc7Sjsg .owner = THIS_MODULE,
1169c349dbc7Sjsg .get_power = i915_audio_component_get_power,
1170c349dbc7Sjsg .put_power = i915_audio_component_put_power,
1171c349dbc7Sjsg .codec_wake_override = i915_audio_component_codec_wake_override,
1172c349dbc7Sjsg .get_cdclk_freq = i915_audio_component_get_cdclk_freq,
1173c349dbc7Sjsg .sync_audio_rate = i915_audio_component_sync_audio_rate,
1174c349dbc7Sjsg .get_eld = i915_audio_component_get_eld,
1175c349dbc7Sjsg };
1176c349dbc7Sjsg
i915_audio_component_bind(struct device * i915_kdev,struct device * hda_kdev,void * data)1177c349dbc7Sjsg static int i915_audio_component_bind(struct device *i915_kdev,
1178c349dbc7Sjsg struct device *hda_kdev, void *data)
1179c349dbc7Sjsg {
1180c349dbc7Sjsg struct i915_audio_component *acomp = data;
1181f005ef32Sjsg struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
1182c349dbc7Sjsg int i;
1183c349dbc7Sjsg
1184f005ef32Sjsg if (drm_WARN_ON(&i915->drm, acomp->base.ops || acomp->base.dev))
1185c349dbc7Sjsg return -EEXIST;
1186c349dbc7Sjsg
1187f005ef32Sjsg if (drm_WARN_ON(&i915->drm,
1188c349dbc7Sjsg !device_link_add(hda_kdev, i915_kdev,
1189c349dbc7Sjsg DL_FLAG_STATELESS)))
1190c349dbc7Sjsg return -ENOMEM;
1191c349dbc7Sjsg
1192f005ef32Sjsg drm_modeset_lock_all(&i915->drm);
1193c349dbc7Sjsg acomp->base.ops = &i915_audio_component_ops;
1194c349dbc7Sjsg acomp->base.dev = i915_kdev;
1195c349dbc7Sjsg BUILD_BUG_ON(MAX_PORTS != I915_MAX_PORTS);
1196c349dbc7Sjsg for (i = 0; i < ARRAY_SIZE(acomp->aud_sample_rate); i++)
1197c349dbc7Sjsg acomp->aud_sample_rate[i] = 0;
1198f005ef32Sjsg i915->display.audio.component = acomp;
1199f005ef32Sjsg drm_modeset_unlock_all(&i915->drm);
1200c349dbc7Sjsg
1201c349dbc7Sjsg return 0;
1202c349dbc7Sjsg }
1203c349dbc7Sjsg
i915_audio_component_unbind(struct device * i915_kdev,struct device * hda_kdev,void * data)1204c349dbc7Sjsg static void i915_audio_component_unbind(struct device *i915_kdev,
1205c349dbc7Sjsg struct device *hda_kdev, void *data)
1206c349dbc7Sjsg {
1207c349dbc7Sjsg struct i915_audio_component *acomp = data;
1208f005ef32Sjsg struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
1209c349dbc7Sjsg
1210f005ef32Sjsg drm_modeset_lock_all(&i915->drm);
1211c349dbc7Sjsg acomp->base.ops = NULL;
1212c349dbc7Sjsg acomp->base.dev = NULL;
1213f005ef32Sjsg i915->display.audio.component = NULL;
1214f005ef32Sjsg drm_modeset_unlock_all(&i915->drm);
1215c349dbc7Sjsg
1216c349dbc7Sjsg device_link_remove(hda_kdev, i915_kdev);
1217ad8b1aafSjsg
1218f005ef32Sjsg if (i915->display.audio.power_refcount)
1219f005ef32Sjsg drm_err(&i915->drm, "audio power refcount %d after unbind\n",
1220f005ef32Sjsg i915->display.audio.power_refcount);
1221c349dbc7Sjsg }
1222c349dbc7Sjsg
1223c349dbc7Sjsg static const struct component_ops i915_audio_component_bind_ops = {
1224c349dbc7Sjsg .bind = i915_audio_component_bind,
1225c349dbc7Sjsg .unbind = i915_audio_component_unbind,
1226c349dbc7Sjsg };
1227c349dbc7Sjsg
12285ca02815Sjsg #define AUD_FREQ_TMODE_SHIFT 14
12295ca02815Sjsg #define AUD_FREQ_4T 0
12305ca02815Sjsg #define AUD_FREQ_8T (2 << AUD_FREQ_TMODE_SHIFT)
12315ca02815Sjsg #define AUD_FREQ_PULLCLKS(x) (((x) & 0x3) << 11)
12325ca02815Sjsg #define AUD_FREQ_BCLK_96M BIT(4)
12335ca02815Sjsg
12345ca02815Sjsg #define AUD_FREQ_GEN12 (AUD_FREQ_8T | AUD_FREQ_PULLCLKS(0) | AUD_FREQ_BCLK_96M)
12355ca02815Sjsg #define AUD_FREQ_TGL_BROKEN (AUD_FREQ_8T | AUD_FREQ_PULLCLKS(2) | AUD_FREQ_BCLK_96M)
12365ca02815Sjsg
1237c349dbc7Sjsg #endif /* notyet */
1238c349dbc7Sjsg
1239c349dbc7Sjsg /**
1240c349dbc7Sjsg * i915_audio_component_init - initialize and register the audio component
1241f005ef32Sjsg * @i915: i915 device instance
1242c349dbc7Sjsg *
1243c349dbc7Sjsg * This will register with the component framework a child component which
1244c349dbc7Sjsg * will bind dynamically to the snd_hda_intel driver's corresponding master
1245c349dbc7Sjsg * component when the latter is registered. During binding the child
1246c349dbc7Sjsg * initializes an instance of struct i915_audio_component which it receives
1247c349dbc7Sjsg * from the master. The master can then start to use the interface defined by
1248c349dbc7Sjsg * this struct. Each side can break the binding at any point by deregistering
1249c349dbc7Sjsg * its own component after which each side's component unbind callback is
1250c349dbc7Sjsg * called.
1251c349dbc7Sjsg *
1252c349dbc7Sjsg * We ignore any error during registration and continue with reduced
1253c349dbc7Sjsg * functionality (i.e. without HDMI audio).
1254c349dbc7Sjsg */
i915_audio_component_init(struct drm_i915_private * i915)1255f005ef32Sjsg static void i915_audio_component_init(struct drm_i915_private *i915)
1256c349dbc7Sjsg {
1257c349dbc7Sjsg #ifdef notyet
12585ca02815Sjsg u32 aud_freq, aud_freq_init;
1259c349dbc7Sjsg
1260f005ef32Sjsg if (DISPLAY_VER(i915) >= 9) {
1261f005ef32Sjsg aud_freq_init = intel_de_read(i915, AUD_FREQ_CNTRL);
12625ca02815Sjsg
1263f005ef32Sjsg if (DISPLAY_VER(i915) >= 12)
12645ca02815Sjsg aud_freq = AUD_FREQ_GEN12;
12655ca02815Sjsg else
12665ca02815Sjsg aud_freq = aud_freq_init;
12675ca02815Sjsg
12685ca02815Sjsg /* use BIOS provided value for TGL and RKL unless it is a known bad value */
1269f005ef32Sjsg if ((IS_TIGERLAKE(i915) || IS_ROCKETLAKE(i915)) &&
12705ca02815Sjsg aud_freq_init != AUD_FREQ_TGL_BROKEN)
12715ca02815Sjsg aud_freq = aud_freq_init;
12725ca02815Sjsg
1273f005ef32Sjsg drm_dbg_kms(&i915->drm, "use AUD_FREQ_CNTRL of 0x%x (init value 0x%x)\n",
12745ca02815Sjsg aud_freq, aud_freq_init);
12755ca02815Sjsg
1276f005ef32Sjsg i915->display.audio.freq_cntrl = aud_freq;
1277c349dbc7Sjsg }
1278c349dbc7Sjsg
12791bb76ff1Sjsg /* init with current cdclk */
1280f005ef32Sjsg intel_audio_cdclk_change_post(i915);
1281*f6d48bfeSjsg #endif
1282*f6d48bfeSjsg }
1283*f6d48bfeSjsg
i915_audio_component_register(struct drm_i915_private * i915)1284*f6d48bfeSjsg static void i915_audio_component_register(struct drm_i915_private *i915)
1285*f6d48bfeSjsg {
1286*f6d48bfeSjsg #ifdef notyet
1287*f6d48bfeSjsg int ret;
1288*f6d48bfeSjsg
1289*f6d48bfeSjsg ret = component_add_typed(i915->drm.dev,
1290*f6d48bfeSjsg &i915_audio_component_bind_ops,
1291*f6d48bfeSjsg I915_COMPONENT_AUDIO);
1292*f6d48bfeSjsg if (ret < 0) {
1293*f6d48bfeSjsg drm_err(&i915->drm,
1294*f6d48bfeSjsg "failed to add audio component (%d)\n", ret);
1295*f6d48bfeSjsg /* continue with reduced functionality */
1296*f6d48bfeSjsg return;
1297*f6d48bfeSjsg }
12981bb76ff1Sjsg
1299f005ef32Sjsg i915->display.audio.component_registered = true;
1300c349dbc7Sjsg #endif
1301c349dbc7Sjsg }
1302c349dbc7Sjsg
1303c349dbc7Sjsg /**
1304c349dbc7Sjsg * i915_audio_component_cleanup - deregister the audio component
1305f005ef32Sjsg * @i915: i915 device instance
1306c349dbc7Sjsg *
1307c349dbc7Sjsg * Deregisters the audio component, breaking any existing binding to the
1308c349dbc7Sjsg * corresponding snd_hda_intel driver's master component.
1309c349dbc7Sjsg */
i915_audio_component_cleanup(struct drm_i915_private * i915)1310f005ef32Sjsg static void i915_audio_component_cleanup(struct drm_i915_private *i915)
1311c349dbc7Sjsg {
1312f005ef32Sjsg if (!i915->display.audio.component_registered)
1313c349dbc7Sjsg return;
1314c349dbc7Sjsg
1315f005ef32Sjsg component_del(i915->drm.dev, &i915_audio_component_bind_ops);
1316f005ef32Sjsg i915->display.audio.component_registered = false;
1317c349dbc7Sjsg }
1318c349dbc7Sjsg
1319c349dbc7Sjsg /**
1320c349dbc7Sjsg * intel_audio_init() - Initialize the audio driver either using
1321c349dbc7Sjsg * component framework or using lpe audio bridge
1322f005ef32Sjsg * @i915: the i915 drm device private data
1323c349dbc7Sjsg *
1324c349dbc7Sjsg */
intel_audio_init(struct drm_i915_private * i915)1325f005ef32Sjsg void intel_audio_init(struct drm_i915_private *i915)
1326c349dbc7Sjsg {
1327f005ef32Sjsg if (intel_lpe_audio_init(i915) < 0)
1328f005ef32Sjsg i915_audio_component_init(i915);
1329c349dbc7Sjsg }
1330c349dbc7Sjsg
intel_audio_register(struct drm_i915_private * i915)1331*f6d48bfeSjsg void intel_audio_register(struct drm_i915_private *i915)
1332*f6d48bfeSjsg {
1333*f6d48bfeSjsg if (!i915->display.audio.lpe.platdev)
1334*f6d48bfeSjsg i915_audio_component_register(i915);
1335*f6d48bfeSjsg }
1336*f6d48bfeSjsg
1337c349dbc7Sjsg /**
1338c349dbc7Sjsg * intel_audio_deinit() - deinitialize the audio driver
1339f005ef32Sjsg * @i915: the i915 drm device private data
1340c349dbc7Sjsg *
1341c349dbc7Sjsg */
intel_audio_deinit(struct drm_i915_private * i915)1342f005ef32Sjsg void intel_audio_deinit(struct drm_i915_private *i915)
1343c349dbc7Sjsg {
1344f005ef32Sjsg if (i915->display.audio.lpe.platdev != NULL)
1345f005ef32Sjsg intel_lpe_audio_teardown(i915);
1346c349dbc7Sjsg else
1347f005ef32Sjsg i915_audio_component_cleanup(i915);
1348c349dbc7Sjsg }
1349