1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2020 Rockchip Electronics Co. Ltd.
4 *
5 * Author: Shunqing Chen <csq@rock-chips.com>
6 */
7
8 #include <linux/delay.h>
9 #include <linux/module.h>
10 #include <linux/kernel.h>
11 #include <linux/soc/rockchip/rk_vendor_storage.h>
12 #include <linux/slab.h>
13
14 #include "rk628.h"
15 #include "rk628_combrxphy.h"
16 #include "rk628_cru.h"
17 #include "rk628_hdmirx.h"
18
19 #define INIT_FIFO_STATE 64
20
21 #define is_validfs(x) (x == 32000 || \
22 x == 44100 || \
23 x == 48000 || \
24 x == 88200 || \
25 x == 96000 || \
26 x == 176400 || \
27 x == 192000 || \
28 x == 768000)
29
30 struct rk628_audiostate {
31 u32 hdmirx_aud_clkrate;
32 u32 fs_audio;
33 u32 ctsn_flag;
34 u32 fifo_flag;
35 int init_state;
36 int pre_state;
37 bool fifo_int;
38 bool audio_enable;
39 };
40
41 struct rk628_audioinfo {
42 struct delayed_work delayed_work_audio_rate_change;
43 struct delayed_work delayed_work_audio;
44 struct mutex *confctl_mutex;
45 struct rk628 *rk628;
46 struct rk628_audiostate audio_state;
47 bool i2s_enabled_default;
48 bool i2s_enabled;
49 int debug;
50 bool fifo_ints_en;
51 bool ctsn_ints_en;
52 bool audio_present;
53 struct device *dev;
54 };
55
hdcp_load_keys_cb(struct rk628 * rk628,struct rk628_hdcp * hdcp)56 static int hdcp_load_keys_cb(struct rk628 *rk628, struct rk628_hdcp *hdcp)
57 {
58 int size;
59 u8 hdcp_vendor_data[320];
60
61 hdcp->keys = kmalloc(HDCP_KEY_SIZE, GFP_KERNEL);
62 if (!hdcp->keys)
63 return -ENOMEM;
64
65 hdcp->seeds = kmalloc(HDCP_KEY_SEED_SIZE, GFP_KERNEL);
66 if (!hdcp->seeds) {
67 kfree(hdcp->keys);
68 hdcp->keys = NULL;
69 return -ENOMEM;
70 }
71
72 size = rk_vendor_read(HDMIRX_HDCP1X_ID, hdcp_vendor_data, 314);
73 if (size < (HDCP_KEY_SIZE + HDCP_KEY_SEED_SIZE)) {
74 dev_dbg(rk628->dev, "HDCP: read size %d\n", size);
75 kfree(hdcp->keys);
76 hdcp->keys = NULL;
77 kfree(hdcp->seeds);
78 hdcp->seeds = NULL;
79 return -EINVAL;
80 }
81 memcpy(hdcp->keys, hdcp_vendor_data, HDCP_KEY_SIZE);
82 memcpy(hdcp->seeds, hdcp_vendor_data + HDCP_KEY_SIZE,
83 HDCP_KEY_SEED_SIZE);
84
85 return 0;
86 }
87
rk628_hdmi_hdcp_load_key(struct rk628 * rk628,struct rk628_hdcp * hdcp)88 static int rk628_hdmi_hdcp_load_key(struct rk628 *rk628, struct rk628_hdcp *hdcp)
89 {
90 int i;
91 int ret;
92 struct hdcp_keys *hdcp_keys;
93 u32 seeds = 0;
94
95 if (!hdcp->keys) {
96 ret = hdcp_load_keys_cb(rk628, hdcp);
97 if (ret) {
98 dev_err(rk628->dev, "HDCP: load key failed\n");
99 return ret;
100 }
101 }
102 hdcp_keys = hdcp->keys;
103
104 rk628_i2c_update_bits(rk628, HDMI_RX_HDCP_CTRL,
105 HDCP_ENABLE_MASK |
106 HDCP_ENC_EN_MASK,
107 HDCP_ENABLE(0) |
108 HDCP_ENC_EN(0));
109 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
110 SW_ADAPTER_I2CSLADR_MASK |
111 SW_EFUSE_HDCP_EN_MASK,
112 SW_ADAPTER_I2CSLADR(0) |
113 SW_EFUSE_HDCP_EN(1));
114 /* The useful data in ksv should be 5 byte */
115 for (i = 0; i < KSV_LEN; i++)
116 rk628_i2c_write(rk628, HDCP_KEY_KSV0 + i * 4,
117 hdcp_keys->KSV[i]);
118
119 for (i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++)
120 rk628_i2c_write(rk628, HDCP_KEY_DPK0 + i * 4,
121 hdcp_keys->devicekey[i]);
122
123 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
124 SW_ADAPTER_I2CSLADR_MASK |
125 SW_EFUSE_HDCP_EN_MASK,
126 SW_ADAPTER_I2CSLADR(0) |
127 SW_EFUSE_HDCP_EN(0));
128 rk628_i2c_update_bits(rk628, HDMI_RX_HDCP_CTRL,
129 HDCP_ENABLE_MASK |
130 HDCP_ENC_EN_MASK,
131 HDCP_ENABLE(1) |
132 HDCP_ENC_EN(1));
133
134 /* Enable decryption logic */
135 if (hdcp->seeds) {
136 seeds = (hdcp->seeds[0] & 0xff) << 8;
137 seeds |= (hdcp->seeds[1] & 0xff);
138 }
139 if (seeds) {
140 rk628_i2c_update_bits(rk628, HDMI_RX_HDCP_CTRL,
141 KEY_DECRIPT_ENABLE_MASK,
142 KEY_DECRIPT_ENABLE(1));
143 rk628_i2c_write(rk628, HDMI_RX_HDCP_SEED, seeds);
144 } else {
145 rk628_i2c_update_bits(rk628, HDMI_RX_HDCP_CTRL,
146 KEY_DECRIPT_ENABLE_MASK,
147 KEY_DECRIPT_ENABLE(0));
148 }
149
150 return 0;
151 }
152
rk628_hdmirx_set_hdcp(struct rk628 * rk628,struct rk628_hdcp * hdcp,bool en)153 void rk628_hdmirx_set_hdcp(struct rk628 *rk628, struct rk628_hdcp *hdcp, bool en)
154 {
155 dev_dbg(rk628->dev, "%s: %sable\n", __func__, en ? "en" : "dis");
156
157 if (en) {
158 rk628_hdmi_hdcp_load_key(rk628, hdcp);
159 } else {
160 rk628_i2c_update_bits(rk628, HDMI_RX_HDCP_CTRL,
161 HDCP_ENABLE_MASK |
162 HDCP_ENC_EN_MASK,
163 HDCP_ENABLE(0) |
164 HDCP_ENC_EN(0));
165 }
166 }
167 EXPORT_SYMBOL(rk628_hdmirx_set_hdcp);
168
rk628_hdmirx_controller_setup(struct rk628 * rk628)169 void rk628_hdmirx_controller_setup(struct rk628 *rk628)
170 {
171 rk628_i2c_write(rk628, HDMI_RX_HDMI20_CONTROL, 0x10000f10);
172 rk628_i2c_write(rk628, HDMI_RX_HDMI_MODE_RECOVER, 0x00000021);
173 rk628_i2c_write(rk628, HDMI_RX_PDEC_CTRL, 0xbfff8011);
174 rk628_i2c_write(rk628, HDMI_RX_PDEC_ASP_CTRL, 0x00000040);
175 rk628_i2c_write(rk628, HDMI_RX_HDMI_RESMPL_CTRL, 0x00000001);
176 rk628_i2c_write(rk628, HDMI_RX_HDMI_SYNC_CTRL, 0x00000014);
177 rk628_i2c_write(rk628, HDMI_RX_PDEC_ERR_FILTER, 0x00000008);
178 rk628_i2c_write(rk628, HDMI_RX_SCDC_I2CCONFIG, 0x01000000);
179 rk628_i2c_write(rk628, HDMI_RX_SCDC_CONFIG, 0x00000001);
180 rk628_i2c_write(rk628, HDMI_RX_SCDC_WRDATA0, 0xabcdef01);
181 rk628_i2c_write(rk628, HDMI_RX_CHLOCK_CONFIG, 0x0030c15c);
182 rk628_i2c_write(rk628, HDMI_RX_HDMI_ERROR_PROTECT, 0x000d0c98);
183 rk628_i2c_write(rk628, HDMI_RX_MD_HCTRL1, 0x00000010);
184 rk628_i2c_write(rk628, HDMI_RX_MD_HCTRL2, 0x00001738);
185 rk628_i2c_write(rk628, HDMI_RX_MD_VCTRL, 0x00000002);
186 rk628_i2c_write(rk628, HDMI_RX_MD_VTH, 0x0000073a);
187 rk628_i2c_write(rk628, HDMI_RX_MD_IL_POL, 0x00000004);
188 rk628_i2c_write(rk628, HDMI_RX_PDEC_ACRM_CTRL, 0x00000000);
189 rk628_i2c_write(rk628, HDMI_RX_HDMI_DCM_CTRL, 0x00040414);
190 rk628_i2c_write(rk628, HDMI_RX_HDMI_CKM_EVLTM, 0x00103e70);
191 rk628_i2c_write(rk628, HDMI_RX_HDMI_CKM_F, 0x0c1c0b54);
192 rk628_i2c_write(rk628, HDMI_RX_HDMI_RESMPL_CTRL, 0x00000001);
193
194 rk628_i2c_update_bits(rk628, HDMI_RX_HDCP_SETTINGS,
195 HDMI_RESERVED_MASK |
196 FAST_I2C_MASK |
197 ONE_DOT_ONE_MASK |
198 FAST_REAUTH_MASK,
199 HDMI_RESERVED(1) |
200 FAST_I2C(0) |
201 ONE_DOT_ONE(0) |
202 FAST_REAUTH(0));
203 }
204 EXPORT_SYMBOL(rk628_hdmirx_controller_setup);
205
rk628_hdmirx_audio_fifo_init(struct rk628_audioinfo * aif)206 static void rk628_hdmirx_audio_fifo_init(struct rk628_audioinfo *aif)
207 {
208
209 dev_dbg(aif->dev, "%s initial fifo\n", __func__);
210 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_FIFO_ICLR, 0x1f);
211 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_FIFO_CTRL, 0x10001);
212 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_FIFO_CTRL, 0x10000);
213 aif->audio_state.pre_state = aif->audio_state.init_state = INIT_FIFO_STATE*4;
214 }
215
rk628_hdmirx_audio_fifo_initd(struct rk628_audioinfo * aif)216 static void rk628_hdmirx_audio_fifo_initd(struct rk628_audioinfo *aif)
217 {
218
219 dev_dbg(aif->dev, "%s double initial fifo\n", __func__);
220 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_FIFO_ICLR, 0x1f);
221 rk628_i2c_update_bits(aif->rk628, HDMI_RX_AUD_FIFO_TH,
222 AFIF_TH_START_MASK,
223 AFIF_TH_START(192));
224 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_FIFO_CTRL, 0x10001);
225 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_FIFO_CTRL, 0x10000);
226 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_FIFO_CTRL, 0x10001);
227 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_FIFO_CTRL, 0x10000);
228 rk628_i2c_update_bits(aif->rk628, HDMI_RX_AUD_FIFO_TH,
229 AFIF_TH_START_MASK,
230 AFIF_TH_START(INIT_FIFO_STATE));
231 aif->audio_state.pre_state = aif->audio_state.init_state = INIT_FIFO_STATE*4;
232 }
233
_rk628_hdmirx_audio_fs(struct rk628_audioinfo * aif)234 static u32 _rk628_hdmirx_audio_fs(struct rk628_audioinfo *aif)
235 {
236 u64 tmdsclk = 0;
237 u32 clkrate = 0, cts_decoded = 0, n_decoded = 0, fs_audio = 0;
238
239 /* fout=128*fs=ftmds*N/CTS */
240 rk628_i2c_read(aif->rk628, HDMI_RX_HDMI_CKM_RESULT, &clkrate);
241 clkrate = clkrate & 0xffff;
242 /* tmdsclk = (clkrate/1000) * 49500000 */
243 tmdsclk = clkrate * (49500000 / 1000);
244 rk628_i2c_read(aif->rk628, HDMI_RX_PDEC_ACR_CTS, &cts_decoded);
245 rk628_i2c_read(aif->rk628, HDMI_RX_PDEC_ACR_N, &n_decoded);
246 if (cts_decoded != 0) {
247 fs_audio = div_u64((tmdsclk * n_decoded), cts_decoded);
248 fs_audio /= 128;
249 fs_audio = div_u64(fs_audio + 50, 100);
250 fs_audio *= 100;
251 }
252 dev_dbg(aif->dev,
253 "%s: clkrate:%u tmdsclk:%llu, n_decoded:%u, cts_decoded:%u, fs_audio:%u\n",
254 __func__, clkrate, tmdsclk, n_decoded, cts_decoded, fs_audio);
255 if (!is_validfs(fs_audio))
256 fs_audio = 0;
257 return fs_audio;
258 }
259
rk628_hdmirx_audio_clk_set_rate(struct rk628_audioinfo * aif,u32 rate)260 static void rk628_hdmirx_audio_clk_set_rate(struct rk628_audioinfo *aif, u32 rate)
261 {
262
263 dev_dbg(aif->dev, "%s: %u to %u\n",
264 __func__, aif->audio_state.hdmirx_aud_clkrate, rate);
265 rk628_clk_set_rate(aif->rk628, CGU_CLK_HDMIRX_AUD, rate);
266 aif->audio_state.hdmirx_aud_clkrate = rate;
267 }
268
rk628_hdmirx_audio_clk_inc_rate(struct rk628_audioinfo * aif,int dis)269 static void rk628_hdmirx_audio_clk_inc_rate(struct rk628_audioinfo *aif, int dis)
270 {
271 u32 hdmirx_aud_clkrate = aif->audio_state.hdmirx_aud_clkrate + dis;
272
273 dev_dbg(aif->dev, "%s: %u to %u\n",
274 __func__, aif->audio_state.hdmirx_aud_clkrate, hdmirx_aud_clkrate);
275 rk628_clk_set_rate(aif->rk628, CGU_CLK_HDMIRX_AUD, hdmirx_aud_clkrate);
276 aif->audio_state.hdmirx_aud_clkrate = hdmirx_aud_clkrate;
277 }
278
rk628_hdmirx_audio_set_fs(struct rk628_audioinfo * aif,u32 fs_audio)279 static void rk628_hdmirx_audio_set_fs(struct rk628_audioinfo *aif, u32 fs_audio)
280 {
281 u32 hdmirx_aud_clkrate_t = fs_audio*128;
282
283 dev_dbg(aif->dev, "%s: %u to %u with fs %u\n", __func__,
284 aif->audio_state.hdmirx_aud_clkrate, hdmirx_aud_clkrate_t,
285 fs_audio);
286 rk628_clk_set_rate(aif->rk628, CGU_CLK_HDMIRX_AUD, hdmirx_aud_clkrate_t);
287 aif->audio_state.hdmirx_aud_clkrate = hdmirx_aud_clkrate_t;
288 aif->audio_state.fs_audio = fs_audio;
289 }
290
rk628_hdmirx_audio_enable(struct rk628_audioinfo * aif)291 static void rk628_hdmirx_audio_enable(struct rk628_audioinfo *aif)
292 {
293 u32 fifo_ints;
294
295 rk628_i2c_read(aif->rk628, HDMI_RX_AUD_FIFO_ISTS, &fifo_ints);
296 dev_dbg(aif->dev, "%s fifo ints %#x\n", __func__, fifo_ints);
297 if ((fifo_ints & 0x18) == 0x18)
298 rk628_hdmirx_audio_fifo_initd(aif);
299 else if (fifo_ints & 0x18)
300 rk628_hdmirx_audio_fifo_init(aif);
301 rk628_i2c_update_bits(aif->rk628, HDMI_RX_DMI_DISABLE_IF,
302 AUD_ENABLE_MASK, AUD_ENABLE(1));
303 aif->audio_state.audio_enable = true;
304 aif->fifo_ints_en = true;
305 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_FIFO_IEN_SET,
306 AFIF_OVERFL_ISTS | AFIF_UNDERFL_ISTS);
307 }
308
rk628_csi_delayed_work_audio(struct work_struct * work)309 static void rk628_csi_delayed_work_audio(struct work_struct *work)
310 {
311 struct delayed_work *dwork = to_delayed_work(work);
312 struct rk628_audioinfo *aif = container_of(dwork, struct rk628_audioinfo,
313 delayed_work_audio);
314 struct rk628_audiostate *audio_state = &aif->audio_state;
315 u32 fs_audio;
316 int cur_state, init_state, pre_state;
317
318 init_state = audio_state->init_state;
319 pre_state = audio_state->pre_state;
320 fs_audio = _rk628_hdmirx_audio_fs(aif);
321 if (!is_validfs(fs_audio)) {
322 dev_dbg(aif->dev, "%s: no supported fs(%u)\n", __func__, fs_audio);
323 goto exit;
324 }
325 if (!audio_state->audio_enable) {
326 rk628_hdmirx_audio_set_fs(aif, fs_audio);
327 rk628_hdmirx_audio_enable(aif);
328 goto exit;
329 }
330 if (abs(fs_audio - audio_state->fs_audio) > 1000)
331 rk628_hdmirx_audio_set_fs(aif, fs_audio);
332 rk628_i2c_read(aif->rk628, HDMI_RX_AUD_FIFO_FILLSTS1, &cur_state);
333 dev_dbg(aif->dev, "%s: HDMI_RX_AUD_FIFO_FILLSTS1:%#x, single offset:%d, total offset:%d\n",
334 __func__, cur_state, cur_state - pre_state, cur_state - init_state);
335 if (cur_state != 0)
336 aif->audio_present = true;
337 else
338 aif->audio_present = false;
339
340 if ((cur_state - init_state) > 16 && (cur_state - pre_state) > 0)
341 rk628_hdmirx_audio_clk_inc_rate(aif, 10);
342 else if ((cur_state != 0) && (cur_state - init_state) < -16 && (cur_state - pre_state) < 0)
343 rk628_hdmirx_audio_clk_inc_rate(aif, -10);
344 audio_state->pre_state = cur_state;
345 exit:
346 schedule_delayed_work(&aif->delayed_work_audio, msecs_to_jiffies(1000));
347
348 }
349
rk628_csi_delayed_work_audio_rate_change(struct work_struct * work)350 static void rk628_csi_delayed_work_audio_rate_change(struct work_struct *work)
351 {
352 u32 fifo_fillsts;
353 u32 fs_audio;
354 struct delayed_work *dwork = to_delayed_work(work);
355 struct rk628_audioinfo *aif = container_of(dwork, struct rk628_audioinfo,
356 delayed_work_audio_rate_change);
357
358 mutex_lock(aif->confctl_mutex);
359 fs_audio = _rk628_hdmirx_audio_fs(aif);
360 dev_dbg(aif->dev, "%s get audio fs %u\n", __func__, fs_audio);
361 if (aif->audio_state.ctsn_flag == (ACR_N_CHG_ICLR | ACR_CTS_CHG_ICLR)) {
362 aif->audio_state.ctsn_flag = 0;
363 if (is_validfs(fs_audio)) {
364 rk628_hdmirx_audio_set_fs(aif, fs_audio);
365 /* We start audio work after recieveing cts n interrupt */
366 rk628_hdmirx_audio_enable(aif);
367 } else {
368 dev_dbg(aif->dev, "%s invalid fs when ctsn updating\n", __func__);
369 }
370 schedule_delayed_work(&aif->delayed_work_audio, msecs_to_jiffies(1000));
371 }
372 if (aif->audio_state.fifo_int) {
373 aif->audio_state.fifo_int = false;
374 if (is_validfs(fs_audio))
375 rk628_hdmirx_audio_set_fs(aif, fs_audio);
376 rk628_i2c_read(aif->rk628, HDMI_RX_AUD_FIFO_FILLSTS1, &fifo_fillsts);
377 if (!fifo_fillsts) {
378 dev_dbg(aif->dev, "%s underflow after overflow\n", __func__);
379 rk628_hdmirx_audio_fifo_initd(aif);
380 } else {
381 dev_dbg(aif->dev, "%s overflow after underflow\n", __func__);
382 rk628_hdmirx_audio_fifo_initd(aif);
383 }
384 }
385 mutex_unlock(aif->confctl_mutex);
386 }
387
rk628_hdmirx_audioinfo_alloc(struct device * dev,struct mutex * confctl_mutex,struct rk628 * rk628,bool en)388 HAUDINFO rk628_hdmirx_audioinfo_alloc(struct device *dev,
389 struct mutex *confctl_mutex,
390 struct rk628 *rk628,
391 bool en)
392 {
393 struct rk628_audioinfo *aif;
394
395 aif = devm_kzalloc(dev, sizeof(*aif), GFP_KERNEL);
396 if (!aif)
397 return NULL;
398 INIT_DELAYED_WORK(&aif->delayed_work_audio_rate_change,
399 rk628_csi_delayed_work_audio_rate_change);
400 INIT_DELAYED_WORK(&aif->delayed_work_audio,
401 rk628_csi_delayed_work_audio);
402 aif->confctl_mutex = confctl_mutex;
403 aif->rk628 = rk628;
404 aif->i2s_enabled_default = en;
405 aif->dev = dev;
406 return aif;
407 }
408 EXPORT_SYMBOL(rk628_hdmirx_audioinfo_alloc);
409
rk628_hdmirx_audio_cancel_work_audio(HAUDINFO info,bool sync)410 void rk628_hdmirx_audio_cancel_work_audio(HAUDINFO info, bool sync)
411 {
412 struct rk628_audioinfo *aif = (struct rk628_audioinfo *)info;
413
414 if (sync)
415 cancel_delayed_work_sync(&aif->delayed_work_audio);
416 else
417 cancel_delayed_work(&aif->delayed_work_audio);
418 }
419 EXPORT_SYMBOL(rk628_hdmirx_audio_cancel_work_audio);
420
rk628_hdmirx_audio_cancel_work_rate_change(HAUDINFO info,bool sync)421 void rk628_hdmirx_audio_cancel_work_rate_change(HAUDINFO info, bool sync)
422 {
423 struct rk628_audioinfo *aif = (struct rk628_audioinfo *)info;
424
425 if (sync)
426 cancel_delayed_work_sync(&aif->delayed_work_audio_rate_change);
427 else
428 cancel_delayed_work(&aif->delayed_work_audio_rate_change);
429 }
430 EXPORT_SYMBOL(rk628_hdmirx_audio_cancel_work_rate_change);
431
rk628_hdmirx_audio_destroy(HAUDINFO info)432 void rk628_hdmirx_audio_destroy(HAUDINFO info)
433 {
434 struct rk628_audioinfo *aif = (struct rk628_audioinfo *)info;
435
436 if (!aif)
437 return;
438 rk628_hdmirx_audio_cancel_work_audio(aif, true);
439 rk628_hdmirx_audio_cancel_work_rate_change(aif, true);
440 aif->confctl_mutex = NULL;
441 aif->rk628 = NULL;
442 }
443 EXPORT_SYMBOL(rk628_hdmirx_audio_destroy);
444
rk628_hdmirx_audio_present(HAUDINFO info)445 bool rk628_hdmirx_audio_present(HAUDINFO info)
446 {
447 struct rk628_audioinfo *aif = (struct rk628_audioinfo *)info;
448
449 if (!aif)
450 return false;
451 return aif->audio_present;
452 }
453 EXPORT_SYMBOL(rk628_hdmirx_audio_present);
454
rk628_hdmirx_audio_fs(HAUDINFO info)455 int rk628_hdmirx_audio_fs(HAUDINFO info)
456 {
457 struct rk628_audioinfo *aif = (struct rk628_audioinfo *)info;
458
459 if (!aif)
460 return 0;
461 return aif->audio_state.fs_audio;
462 }
463 EXPORT_SYMBOL(rk628_hdmirx_audio_fs);
464
rk628_hdmirx_audio_i2s_ctrl(HAUDINFO info,bool enable)465 void rk628_hdmirx_audio_i2s_ctrl(HAUDINFO info, bool enable)
466 {
467 struct rk628_audioinfo *aif = (struct rk628_audioinfo *)info;
468
469 if (enable == aif->i2s_enabled)
470 return;
471 if (enable) {
472 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_SAO_CTRL,
473 I2S_LPCM_BPCUV(0) |
474 I2S_32_16(1));
475 } else {
476 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_SAO_CTRL,
477 I2S_LPCM_BPCUV(0) |
478 I2S_32_16(1) |
479 I2S_ENABLE_BITS(0x3f));
480 }
481 aif->i2s_enabled = enable;
482 }
483 EXPORT_SYMBOL(rk628_hdmirx_audio_i2s_ctrl);
484
rk628_hdmirx_audio_setup(HAUDINFO info)485 void rk628_hdmirx_audio_setup(HAUDINFO info)
486 {
487 struct rk628_audioinfo *aif = (struct rk628_audioinfo *)info;
488 u32 audio_pll_n, audio_pll_cts;
489
490 dev_dbg(aif->dev, "%s: setup audio\n", __func__);
491 audio_pll_n = 5644;
492 audio_pll_cts = 148500;
493 aif->audio_state.ctsn_flag = 0;
494 aif->audio_state.fs_audio = 0;
495 aif->audio_state.pre_state = 0;
496 aif->audio_state.init_state = INIT_FIFO_STATE*4;
497 aif->audio_state.fifo_int = false;
498 aif->audio_state.audio_enable = false;
499 aif->fifo_ints_en = false;
500 aif->ctsn_ints_en = false;
501 aif->i2s_enabled = false;
502
503 rk628_hdmirx_audio_clk_set_rate(aif, 5644800);
504 /* manual aud CTS */
505 rk628_i2c_write(aif->rk628, HDMI_RX_AUDPLL_GEN_CTS, audio_pll_cts);
506 /* manual aud N */
507 rk628_i2c_write(aif->rk628, HDMI_RX_AUDPLL_GEN_N, audio_pll_n);
508
509 /* aud CTS N en manual */
510 rk628_i2c_update_bits(aif->rk628, HDMI_RX_AUD_CLK_CTRL,
511 CTS_N_REF_MASK, CTS_N_REF(1));
512 /* aud pll ctrl */
513 rk628_i2c_update_bits(aif->rk628, HDMI_RX_AUD_PLL_CTRL,
514 PLL_LOCK_TOGGLE_DIV_MASK, PLL_LOCK_TOGGLE_DIV(0));
515 rk628_i2c_update_bits(aif->rk628, HDMI_RX_AUD_FIFO_TH,
516 AFIF_TH_START_MASK |
517 AFIF_TH_MAX_MASK |
518 AFIF_TH_MIN_MASK,
519 AFIF_TH_START(64) |
520 AFIF_TH_MAX(8) |
521 AFIF_TH_MIN(8));
522
523 /* AUTO_VMUTE */
524 rk628_i2c_update_bits(aif->rk628, HDMI_RX_AUD_FIFO_CTRL,
525 AFIF_SUBPACKET_DESEL_MASK |
526 AFIF_SUBPACKETS_MASK,
527 AFIF_SUBPACKET_DESEL(0) |
528 AFIF_SUBPACKETS(1));
529 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_SAO_CTRL,
530 I2S_LPCM_BPCUV(0) |
531 I2S_32_16(1)|
532 (aif->i2s_enabled_default ? 0 : I2S_ENABLE_BITS(0x3f)));
533 aif->i2s_enabled = aif->i2s_enabled_default;
534 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_MUTE_CTRL,
535 APPLY_INT_MUTE(0) |
536 APORT_SHDW_CTRL(3) |
537 AUTO_ACLK_MUTE(2) |
538 AUD_MUTE_SPEED(1) |
539 AUD_AVMUTE_EN(1) |
540 AUD_MUTE_SEL(0) |
541 AUD_MUTE_MODE(1));
542
543 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_PAO_CTRL,
544 PAO_RATE(0));
545 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_CHEXTR_CTRL,
546 AUD_LAYOUT_CTRL(1));
547 aif->ctsn_ints_en = true;
548 rk628_i2c_write(aif->rk628, HDMI_RX_PDEC_IEN_SET, ACR_N_CHG_ICLR | ACR_CTS_CHG_ICLR);
549 /* audio detect */
550 rk628_i2c_write(aif->rk628, HDMI_RX_PDEC_AUDIODET_CTRL,
551 AUDIODET_THRESHOLD(0));
552 }
553 EXPORT_SYMBOL(rk628_hdmirx_audio_setup);
554
rk628_audio_fifoints_enabled(HAUDINFO info)555 bool rk628_audio_fifoints_enabled(HAUDINFO info)
556 {
557 return ((struct rk628_audioinfo *)info)->fifo_ints_en;
558 }
559 EXPORT_SYMBOL(rk628_audio_fifoints_enabled);
560
rk628_audio_ctsnints_enabled(HAUDINFO info)561 bool rk628_audio_ctsnints_enabled(HAUDINFO info)
562 {
563 return ((struct rk628_audioinfo *)info)->ctsn_ints_en;
564 }
565 EXPORT_SYMBOL(rk628_audio_ctsnints_enabled);
566
rk628_csi_isr_ctsn(HAUDINFO info,u32 pdec_ints)567 void rk628_csi_isr_ctsn(HAUDINFO info, u32 pdec_ints)
568 {
569 struct rk628_audioinfo *aif = (struct rk628_audioinfo *)info;
570 u32 ctsn_mask = ACR_N_CHG_ICLR | ACR_CTS_CHG_ICLR;
571
572 dev_dbg(aif->dev, "%s: pdec_ints:%#x\n", __func__, pdec_ints);
573 /* cts & n both need update but maybe come diff int */
574 if (pdec_ints & ACR_N_CHG_ICLR)
575 aif->audio_state.ctsn_flag |= ACR_N_CHG_ICLR;
576 if (pdec_ints & ACR_CTS_CHG_ICLR)
577 aif->audio_state.ctsn_flag |= ACR_CTS_CHG_ICLR;
578 if (aif->audio_state.ctsn_flag == ctsn_mask) {
579 dev_dbg(aif->dev, "%s: ctsn updated, disable ctsn int\n", __func__);
580 rk628_i2c_write(aif->rk628, HDMI_RX_PDEC_IEN_CLR, ctsn_mask);
581 aif->ctsn_ints_en = false;
582 schedule_delayed_work(&aif->delayed_work_audio_rate_change, 0);
583 }
584 rk628_i2c_write(aif->rk628, HDMI_RX_PDEC_ICLR, pdec_ints & ctsn_mask);
585 }
586 EXPORT_SYMBOL(rk628_csi_isr_ctsn);
587
rk628_csi_isr_fifoints(HAUDINFO info,u32 fifo_ints)588 void rk628_csi_isr_fifoints(HAUDINFO info, u32 fifo_ints)
589 {
590 struct rk628_audioinfo *aif = (struct rk628_audioinfo *)info;
591 u32 fifo_mask = AFIF_OVERFL_ISTS | AFIF_UNDERFL_ISTS;
592
593 dev_dbg(aif->dev, "%s: fifo_ints:%#x\n", __func__, fifo_ints);
594 /* cts & n both need update but maybe come diff int */
595 if (fifo_ints & AFIF_OVERFL_ISTS) {
596 dev_dbg(aif->dev, "%s: Audio FIFO overflow\n", __func__);
597 aif->audio_state.fifo_flag |= AFIF_OVERFL_ISTS;
598 }
599 if (fifo_ints & AFIF_UNDERFL_ISTS) {
600 dev_dbg(aif->dev, "%s: Audio FIFO underflow\n", __func__);
601 aif->audio_state.fifo_flag |= AFIF_UNDERFL_ISTS;
602 }
603 if (aif->audio_state.fifo_flag == fifo_mask) {
604 aif->audio_state.fifo_int = true;
605 aif->audio_state.fifo_flag = 0;
606 schedule_delayed_work(&aif->delayed_work_audio_rate_change, 0);
607 }
608 rk628_i2c_write(aif->rk628, HDMI_RX_AUD_FIFO_ICLR, fifo_ints & fifo_mask);
609 }
610 EXPORT_SYMBOL(rk628_csi_isr_fifoints);
611
rk628_is_avi_ready(struct rk628 * rk628,bool avi_rcv_rdy)612 int rk628_is_avi_ready(struct rk628 *rk628, bool avi_rcv_rdy)
613 {
614 u8 i;
615 u32 val, avi_pb = 0;
616 u8 cnt = 0, max_cnt = 2;
617 u32 hdcp_ctrl_val = 0;
618
619 rk628_i2c_read(rk628, HDMI_RX_HDCP_CTRL, &val);
620 if ((val & HDCP_ENABLE_MASK))
621 max_cnt = 5;
622
623 for (i = 0; i < 100; i++) {
624 rk628_i2c_read(rk628, HDMI_RX_PDEC_AVI_PB, &val);
625 dev_info(rk628->dev, "%s PDEC_AVI_PB:%#x, avi_rcv_rdy:%d\n",
626 __func__, val, avi_rcv_rdy);
627 if (i > 30 && !(hdcp_ctrl_val & 0x400)) {
628 rk628_i2c_read(rk628, HDMI_RX_HDCP_CTRL, &hdcp_ctrl_val);
629 /* force hdcp avmute */
630 hdcp_ctrl_val |= 0x400;
631 rk628_i2c_write(rk628, HDMI_RX_HDCP_CTRL, hdcp_ctrl_val);
632 }
633
634 if (val && val == avi_pb && avi_rcv_rdy) {
635 if (++cnt >= max_cnt)
636 break;
637 } else {
638 cnt = 0;
639 avi_pb = val;
640 }
641 msleep(30);
642 }
643 if (cnt < max_cnt)
644 return 0;
645
646 return 1;
647 }
648 EXPORT_SYMBOL(rk628_is_avi_ready);
649