File Index
Files and directories
Sign in
FILE

cdn-dp-reg.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/rockchip/cdn-dp-reg.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (C) Rockchip Electronics Co., Ltd.
  4 * Author: Chris Zhong <zyw@rock-chips.com>
  5 */
  6
  7#include <linux/clk.h>
  8#include <linux/device.h>
  9#include <linux/delay.h>
 10#include <linux/io.h>
 11#include <linux/iopoll.h>
 12#include <linux/reset.h>
 13
 14#include <drm/drm_print.h>
 15
 16#include "cdn-dp-core.h"
 17#include "cdn-dp-reg.h"
 18
 19#define CDN_DP_SPDIF_CLK		200000000
 20#define FW_ALIVE_TIMEOUT_US		1000000
 21#define MAILBOX_RETRY_US		1000
 22#define MAILBOX_TIMEOUT_US		5000000
 23#define LINK_TRAINING_RETRY_MS		20
 24#define LINK_TRAINING_TIMEOUT_MS	500
 25
 26void cdn_dp_set_fw_clk(struct cdn_dp_device *dp, unsigned long clk)
 27{
 28	writel(clk / 1000000, dp->regs + SW_CLK_H);
 29}
 30
 31void cdn_dp_clock_reset(struct cdn_dp_device *dp)
 32{
 33	u32 val;
 34
 35	val = DPTX_FRMR_DATA_CLK_RSTN_EN |
 36	      DPTX_FRMR_DATA_CLK_EN |
 37	      DPTX_PHY_DATA_RSTN_EN |
 38	      DPTX_PHY_DATA_CLK_EN |
 39	      DPTX_PHY_CHAR_RSTN_EN |
 40	      DPTX_PHY_CHAR_CLK_EN |
 41	      SOURCE_AUX_SYS_CLK_RSTN_EN |
 42	      SOURCE_AUX_SYS_CLK_EN |
 43	      DPTX_SYS_CLK_RSTN_EN |
 44	      DPTX_SYS_CLK_EN |
 45	      CFG_DPTX_VIF_CLK_RSTN_EN |
 46	      CFG_DPTX_VIF_CLK_EN;
 47	writel(val, dp->regs + SOURCE_DPTX_CAR);
 48
 49	val = SOURCE_PHY_RSTN_EN | SOURCE_PHY_CLK_EN;
 50	writel(val, dp->regs + SOURCE_PHY_CAR);
 51
 52	val = SOURCE_PKT_SYS_RSTN_EN |
 53	      SOURCE_PKT_SYS_CLK_EN |
 54	      SOURCE_PKT_DATA_RSTN_EN |
 55	      SOURCE_PKT_DATA_CLK_EN;
 56	writel(val, dp->regs + SOURCE_PKT_CAR);
 57
 58	val = SPDIF_CDR_CLK_RSTN_EN |
 59	      SPDIF_CDR_CLK_EN |
 60	      SOURCE_AIF_SYS_RSTN_EN |
 61	      SOURCE_AIF_SYS_CLK_EN |
 62	      SOURCE_AIF_CLK_RSTN_EN |
 63	      SOURCE_AIF_CLK_EN;
 64	writel(val, dp->regs + SOURCE_AIF_CAR);
 65
 66	val = SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN |
 67	      SOURCE_CIPHER_SYS_CLK_EN |
 68	      SOURCE_CIPHER_CHAR_CLK_RSTN_EN |
 69	      SOURCE_CIPHER_CHAR_CLK_EN;
 70	writel(val, dp->regs + SOURCE_CIPHER_CAR);
 71
 72	val = SOURCE_CRYPTO_SYS_CLK_RSTN_EN |
 73	      SOURCE_CRYPTO_SYS_CLK_EN;
 74	writel(val, dp->regs + SOURCE_CRYPTO_CAR);
 75
 76	/* enable Mailbox and PIF interrupt */
 77	writel(0, dp->regs + APB_INT_MASK);
 78}
 79
 80static int cdn_dp_mailbox_read(struct cdn_dp_device *dp)
 81{
 82	int val, ret;
 83
 84	ret = readx_poll_timeout(readl, dp->regs + MAILBOX_EMPTY_ADDR,
 85				 val, !val, MAILBOX_RETRY_US,
 86				 MAILBOX_TIMEOUT_US);
 87	if (ret < 0)
 88		return ret;
 89
 90	return readl(dp->regs + MAILBOX0_RD_DATA) & 0xff;
 91}
 92
 93static int cdp_dp_mailbox_write(struct cdn_dp_device *dp, u8 val)
 94{
 95	int ret, full;
 96
 97	ret = readx_poll_timeout(readl, dp->regs + MAILBOX_FULL_ADDR,
 98				 full, !full, MAILBOX_RETRY_US,
 99				 MAILBOX_TIMEOUT_US);
100	if (ret < 0)
101		return ret;
102
103	writel(val, dp->regs + MAILBOX0_WR_DATA);
104
105	return 0;
106}
107
108static int cdn_dp_mailbox_validate_receive(struct cdn_dp_device *dp,
109					   u8 module_id, u8 opcode,
110					   u16 req_size)
111{
112	u32 mbox_size, i;
113	u8 header[4];
114	int ret;
115
116	/* read the header of the message */
117	for (i = 0; i < 4; i++) {
118		ret = cdn_dp_mailbox_read(dp);
119		if (ret < 0)
120			return ret;
121
122		header[i] = ret;
123	}
124
125	mbox_size = (header[2] << 8) | header[3];
126
127	if (opcode != header[0] || module_id != header[1] ||
128	    req_size != mbox_size) {
129		/*
130		 * If the message in mailbox is not what we want, we need to
131		 * clear the mailbox by reading its contents.
132		 */
133		for (i = 0; i < mbox_size; i++)
134			if (cdn_dp_mailbox_read(dp) < 0)
135				break;
136
137		return -EINVAL;
138	}
139
140	return 0;
141}
142
143static int cdn_dp_mailbox_read_receive(struct cdn_dp_device *dp,
144				       u8 *buff, u16 buff_size)
145{
146	u32 i;
147	int ret;
148
149	for (i = 0; i < buff_size; i++) {
150		ret = cdn_dp_mailbox_read(dp);
151		if (ret < 0)
152			return ret;
153
154		buff[i] = ret;
155	}
156
157	return 0;
158}
159
160static int cdn_dp_mailbox_send(struct cdn_dp_device *dp, u8 module_id,
161			       u8 opcode, u16 size, u8 *message)
162{
163	u8 header[4];
164	int ret, i;
165
166	header[0] = opcode;
167	header[1] = module_id;
168	header[2] = (size >> 8) & 0xff;
169	header[3] = size & 0xff;
170
171	for (i = 0; i < 4; i++) {
172		ret = cdp_dp_mailbox_write(dp, header[i]);
173		if (ret)
174			return ret;
175	}
176
177	for (i = 0; i < size; i++) {
178		ret = cdp_dp_mailbox_write(dp, message[i]);
179		if (ret)
180			return ret;
181	}
182
183	return 0;
184}
185
186static int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
187{
188	u8 msg[6];
189
190	msg[0] = (addr >> 8) & 0xff;
191	msg[1] = addr & 0xff;
192	msg[2] = (val >> 24) & 0xff;
193	msg[3] = (val >> 16) & 0xff;
194	msg[4] = (val >> 8) & 0xff;
195	msg[5] = val & 0xff;
196	return cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_REGISTER,
197				   sizeof(msg), msg);
198}
199
200static int cdn_dp_reg_write_bit(struct cdn_dp_device *dp, u16 addr,
201				u8 start_bit, u8 bits_no, u32 val)
202{
203	u8 field[8];
204
205	field[0] = (addr >> 8) & 0xff;
206	field[1] = addr & 0xff;
207	field[2] = start_bit;
208	field[3] = bits_no;
209	field[4] = (val >> 24) & 0xff;
210	field[5] = (val >> 16) & 0xff;
211	field[6] = (val >> 8) & 0xff;
212	field[7] = val & 0xff;
213
214	return cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_FIELD,
215				   sizeof(field), field);
216}
217
218int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
219{
220	u8 msg[5], reg[5];
221	int ret;
222
223	msg[0] = (len >> 8) & 0xff;
224	msg[1] = len & 0xff;
225	msg[2] = (addr >> 16) & 0xff;
226	msg[3] = (addr >> 8) & 0xff;
227	msg[4] = addr & 0xff;
228	ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_READ_DPCD,
229				  sizeof(msg), msg);
230	if (ret)
231		goto err_dpcd_read;
232
233	ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
234					      DPTX_READ_DPCD,
235					      sizeof(reg) + len);
236	if (ret)
237		goto err_dpcd_read;
238
239	ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
240	if (ret)
241		goto err_dpcd_read;
242
243	ret = cdn_dp_mailbox_read_receive(dp, data, len);
244
245err_dpcd_read:
246	return ret;
247}
248
249int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value)
250{
251	u8 msg[6], reg[5];
252	int ret;
253
254	msg[0] = 0;
255	msg[1] = 1;
256	msg[2] = (addr >> 16) & 0xff;
257	msg[3] = (addr >> 8) & 0xff;
258	msg[4] = addr & 0xff;
259	msg[5] = value;
260	ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_DPCD,
261				  sizeof(msg), msg);
262	if (ret)
263		goto err_dpcd_write;
264
265	ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
266					      DPTX_WRITE_DPCD, sizeof(reg));
267	if (ret)
268		goto err_dpcd_write;
269
270	ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
271	if (ret)
272		goto err_dpcd_write;
273
274	if (addr != (reg[2] << 16 | reg[3] << 8 | reg[4]))
275		ret = -EINVAL;
276
277err_dpcd_write:
278	if (ret)
279		DRM_DEV_ERROR(dp->dev, "dpcd write failed: %d\n", ret);
280	return ret;
281}
282
283int cdn_dp_load_firmware(struct cdn_dp_device *dp, const u32 *i_mem,
284			 u32 i_size, const u32 *d_mem, u32 d_size)
285{
286	u32 reg;
287	int i, ret;
288
289	/* reset ucpu before load firmware*/
290	writel(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET,
291	       dp->regs + APB_CTRL);
292
293	for (i = 0; i < i_size; i += 4)
294		writel(*i_mem++, dp->regs + ADDR_IMEM + i);
295
296	for (i = 0; i < d_size; i += 4)
297		writel(*d_mem++, dp->regs + ADDR_DMEM + i);
298
299	/* un-reset ucpu */
300	writel(0, dp->regs + APB_CTRL);
301
302	/* check the keep alive register to make sure fw working */
303	ret = readx_poll_timeout(readl, dp->regs + KEEP_ALIVE,
304				 reg, reg, 2000, FW_ALIVE_TIMEOUT_US);
305	if (ret < 0) {
306		DRM_DEV_ERROR(dp->dev, "failed to loaded the FW reg = %x\n",
307			      reg);
308		return -EINVAL;
309	}
310
311	reg = readl(dp->regs + VER_L) & 0xff;
312	dp->fw_version = reg;
313	reg = readl(dp->regs + VER_H) & 0xff;
314	dp->fw_version |= reg << 8;
315	reg = readl(dp->regs + VER_LIB_L_ADDR) & 0xff;
316	dp->fw_version |= reg << 16;
317	reg = readl(dp->regs + VER_LIB_H_ADDR) & 0xff;
318	dp->fw_version |= reg << 24;
319
320	DRM_DEV_DEBUG(dp->dev, "firmware version: %x\n", dp->fw_version);
321
322	return 0;
323}
324
325int cdn_dp_set_firmware_active(struct cdn_dp_device *dp, bool enable)
326{
327	u8 msg[5];
328	int ret, i;
329
330	msg[0] = GENERAL_MAIN_CONTROL;
331	msg[1] = MB_MODULE_ID_GENERAL;
332	msg[2] = 0;
333	msg[3] = 1;
334	msg[4] = enable ? FW_ACTIVE : FW_STANDBY;
335
336	for (i = 0; i < sizeof(msg); i++) {
337		ret = cdp_dp_mailbox_write(dp, msg[i]);
338		if (ret)
339			goto err_set_firmware_active;
340	}
341
342	/* read the firmware state */
343	for (i = 0; i < sizeof(msg); i++)  {
344		ret = cdn_dp_mailbox_read(dp);
345		if (ret < 0)
346			goto err_set_firmware_active;
347
348		msg[i] = ret;
349	}
350
351	ret = 0;
352
353err_set_firmware_active:
354	if (ret < 0)
355		DRM_DEV_ERROR(dp->dev, "set firmware active failed\n");
356	return ret;
357}
358
359int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 lanes, bool flip)
360{
361	u8 msg[8];
362	int ret;
363
364	msg[0] = CDN_DP_MAX_LINK_RATE;
365	msg[1] = lanes | SCRAMBLER_EN;
366	msg[2] = VOLTAGE_LEVEL_2;
367	msg[3] = PRE_EMPHASIS_LEVEL_3;
368	msg[4] = PTS1 | PTS2 | PTS3 | PTS4;
369	msg[5] = FAST_LT_NOT_SUPPORT;
370	msg[6] = flip ? LANE_MAPPING_FLIPPED : LANE_MAPPING_NORMAL;
371	msg[7] = ENHANCED;
372
373	ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX,
374				  DPTX_SET_HOST_CAPABILITIES,
375				  sizeof(msg), msg);
376	if (ret)
377		goto err_set_host_cap;
378
379	ret = cdn_dp_reg_write(dp, DP_AUX_SWAP_INVERSION_CONTROL,
380			       AUX_HOST_INVERT);
381
382err_set_host_cap:
383	if (ret)
384		DRM_DEV_ERROR(dp->dev, "set host cap failed: %d\n", ret);
385	return ret;
386}
387
388int cdn_dp_event_config(struct cdn_dp_device *dp)
389{
390	u8 msg[5];
391	int ret;
392
393	memset(msg, 0, sizeof(msg));
394
395	msg[0] = DPTX_EVENT_ENABLE_HPD | DPTX_EVENT_ENABLE_TRAINING;
396
397	ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_ENABLE_EVENT,
398				  sizeof(msg), msg);
399	if (ret)
400		DRM_DEV_ERROR(dp->dev, "set event config failed: %d\n", ret);
401
402	return ret;
403}
404
405u32 cdn_dp_get_event(struct cdn_dp_device *dp)
406{
407	return readl(dp->regs + SW_EVENTS0);
408}
409
410int cdn_dp_get_hpd_status(struct cdn_dp_device *dp)
411{
412	u8 status;
413	int ret;
414
415	ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_HPD_STATE,
416				  0, NULL);
417	if (ret)
418		goto err_get_hpd;
419
420	ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
421					      DPTX_HPD_STATE, sizeof(status));
422	if (ret)
423		goto err_get_hpd;
424
425	ret = cdn_dp_mailbox_read_receive(dp, &status, sizeof(status));
426	if (ret)
427		goto err_get_hpd;
428
429	return status;
430
431err_get_hpd:
432	DRM_DEV_ERROR(dp->dev, "get hpd status failed: %d\n", ret);
433	return ret;
434}
435
436int cdn_dp_get_edid_block(void *data, u8 *edid,
437			  unsigned int block, size_t length)
438{
439	struct cdn_dp_device *dp = data;
440	u8 msg[2], reg[2], i;
441	int ret;
442
443	for (i = 0; i < 4; i++) {
444		msg[0] = block / 2;
445		msg[1] = block % 2;
446
447		ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_GET_EDID,
448					  sizeof(msg), msg);
449		if (ret)
450			continue;
451
452		ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
453						      DPTX_GET_EDID,
454						      sizeof(reg) + length);
455		if (ret)
456			continue;
457
458		ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
459		if (ret)
460			continue;
461
462		ret = cdn_dp_mailbox_read_receive(dp, edid, length);
463		if (ret)
464			continue;
465
466		if (reg[0] == length && reg[1] == block / 2)
467			break;
468	}
469
470	if (ret)
471		DRM_DEV_ERROR(dp->dev, "get block[%d] edid failed: %d\n", block,
472			      ret);
473
474	return ret;
475}
476
477static int cdn_dp_training_start(struct cdn_dp_device *dp)
478{
479	unsigned long timeout;
480	u8 msg, event[2];
481	int ret;
482
483	msg = LINK_TRAINING_RUN;
484
485	/* start training */
486	ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_TRAINING_CONTROL,
487				  sizeof(msg), &msg);
488	if (ret)
489		goto err_training_start;
490
491	timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS);
492	while (time_before(jiffies, timeout)) {
493		msleep(LINK_TRAINING_RETRY_MS);
494		ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX,
495					  DPTX_READ_EVENT, 0, NULL);
496		if (ret)
497			goto err_training_start;
498
499		ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
500						      DPTX_READ_EVENT,
501						      sizeof(event));
502		if (ret)
503			goto err_training_start;
504
505		ret = cdn_dp_mailbox_read_receive(dp, event, sizeof(event));
506		if (ret)
507			goto err_training_start;
508
509		if (event[1] & EQ_PHASE_FINISHED)
510			return 0;
511	}
512
513	ret = -ETIMEDOUT;
514
515err_training_start:
516	DRM_DEV_ERROR(dp->dev, "training failed: %d\n", ret);
517	return ret;
518}
519
520static int cdn_dp_get_training_status(struct cdn_dp_device *dp)
521{
522	u8 status[10];
523	int ret;
524
525	ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_READ_LINK_STAT,
526				  0, NULL);
527	if (ret)
528		goto err_get_training_status;
529
530	ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
531					      DPTX_READ_LINK_STAT,
532					      sizeof(status));
533	if (ret)
534		goto err_get_training_status;
535
536	ret = cdn_dp_mailbox_read_receive(dp, status, sizeof(status));
537	if (ret)
538		goto err_get_training_status;
539
540	dp->max_rate = drm_dp_bw_code_to_link_rate(status[0]);
541	dp->max_lanes = status[1];
542
543err_get_training_status:
544	if (ret)
545		DRM_DEV_ERROR(dp->dev, "get training status failed: %d\n", ret);
546	return ret;
547}
548
549int cdn_dp_train_link(struct cdn_dp_device *dp)
550{
551	int ret;
552
553	ret = cdn_dp_training_start(dp);
554	if (ret) {
555		DRM_DEV_ERROR(dp->dev, "Failed to start training %d\n", ret);
556		return ret;
557	}
558
559	ret = cdn_dp_get_training_status(dp);
560	if (ret) {
561		DRM_DEV_ERROR(dp->dev, "Failed to get training stat %d\n", ret);
562		return ret;
563	}
564
565	DRM_DEV_DEBUG_KMS(dp->dev, "rate:0x%x, lanes:%d\n", dp->max_rate,
566			  dp->max_lanes);
567	return ret;
568}
569
570int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active)
571{
572	u8 msg;
573	int ret;
574
575	msg = !!active;
576
577	ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO,
578				  sizeof(msg), &msg);
579	if (ret)
580		DRM_DEV_ERROR(dp->dev, "set video status failed: %d\n", ret);
581
582	return ret;
583}
584
585static int cdn_dp_get_msa_misc(struct video_info *video,
586			       struct drm_display_mode *mode)
587{
588	u32 msa_misc;
589	u8 val[2] = {0};
590
591	switch (video->color_fmt) {
592	case PXL_RGB:
593	case Y_ONLY:
594		val[0] = 0;
595		break;
596	/* set YUV default color space conversion to BT601 */
597	case YCBCR_4_4_4:
598		val[0] = 6 + BT_601 * 8;
599		break;
600	case YCBCR_4_2_2:
601		val[0] = 5 + BT_601 * 8;
602		break;
603	case YCBCR_4_2_0:
604		val[0] = 5;
605		break;
606	}
607
608	switch (video->color_depth) {
609	case 6:
610		val[1] = 0;
611		break;
612	case 8:
613		val[1] = 1;
614		break;
615	case 10:
616		val[1] = 2;
617		break;
618	case 12:
619		val[1] = 3;
620		break;
621	case 16:
622		val[1] = 4;
623		break;
624	}
625
626	msa_misc = 2 * val[0] + 32 * val[1] +
627		   ((video->color_fmt == Y_ONLY) ? (1 << 14) : 0);
628
629	return msa_misc;
630}
631
632int cdn_dp_config_video(struct cdn_dp_device *dp)
633{
634	struct video_info *video = &dp->video_info;
635	struct drm_display_mode *mode = &dp->mode;
636	u64 symbol;
637	u32 val, link_rate, rem;
638	u8 bit_per_pix, tu_size_reg = TU_SIZE;
639	int ret;
640
641	bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ?
642		      (video->color_depth * 2) : (video->color_depth * 3);
643
644	link_rate = dp->max_rate / 1000;
645
646	ret = cdn_dp_reg_write(dp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE);
647	if (ret)
648		goto err_config_video;
649
650	ret = cdn_dp_reg_write(dp, HSYNC2VSYNC_POL_CTRL, 0);
651	if (ret)
652		goto err_config_video;
653
654	/*
655	 * get a best tu_size and valid symbol:
656	 * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32
657	 * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes)
658	 * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set
659	 *    TU += 2 and repeat 2nd step.
660	 */
661	do {
662		tu_size_reg += 2;
663		symbol = (u64)tu_size_reg * mode->clock * bit_per_pix;
664		do_div(symbol, dp->max_lanes * link_rate * 8);
665		rem = do_div(symbol, 1000);
666		if (tu_size_reg > 64) {
667			ret = -EINVAL;
668			DRM_DEV_ERROR(dp->dev,
669				      "tu error, clk:%d, lanes:%d, rate:%d\n",
670				      mode->clock, dp->max_lanes, link_rate);
671			goto err_config_video;
672		}
673	} while ((symbol <= 1) || (tu_size_reg - symbol < 4) ||
674		 (rem > 850) || (rem < 100));
675
676	val = symbol + (tu_size_reg << 8);
677	val |= TU_CNT_RST_EN;
678	ret = cdn_dp_reg_write(dp, DP_FRAMER_TU, val);
679	if (ret)
680		goto err_config_video;
681
682	/* set the FIFO Buffer size */
683	val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate;
684	val /= (dp->max_lanes * link_rate);
685	val = div_u64(8 * (symbol + 1), bit_per_pix) - val;
686	val += 2;
687	ret = cdn_dp_reg_write(dp, DP_VC_TABLE(15), val);
688
689	switch (video->color_depth) {
690	case 6:
691		val = BCS_6;
692		break;
693	case 8:
694		val = BCS_8;
695		break;
696	case 10:
697		val = BCS_10;
698		break;
699	case 12:
700		val = BCS_12;
701		break;
702	case 16:
703		val = BCS_16;
704		break;
705	}
706
707	val += video->color_fmt << 8;
708	ret = cdn_dp_reg_write(dp, DP_FRAMER_PXL_REPR, val);
709	if (ret)
710		goto err_config_video;
711
712	val = video->h_sync_polarity ? DP_FRAMER_SP_HSP : 0;
713	val |= video->v_sync_polarity ? DP_FRAMER_SP_VSP : 0;
714	ret = cdn_dp_reg_write(dp, DP_FRAMER_SP, val);
715	if (ret)
716		goto err_config_video;
717
718	val = (mode->hsync_start - mode->hdisplay) << 16;
719	val |= mode->htotal - mode->hsync_end;
720	ret = cdn_dp_reg_write(dp, DP_FRONT_BACK_PORCH, val);
721	if (ret)
722		goto err_config_video;
723
724	val = mode->hdisplay * bit_per_pix / 8;
725	ret = cdn_dp_reg_write(dp, DP_BYTE_COUNT, val);
726	if (ret)
727		goto err_config_video;
728
729	val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16);
730	ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_0, val);
731	if (ret)
732		goto err_config_video;
733
734	val = mode->hsync_end - mode->hsync_start;
735	val |= (mode->hdisplay << 16) | (video->h_sync_polarity << 15);
736	ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_1, val);
737	if (ret)
738		goto err_config_video;
739
740	val = mode->vtotal;
741	val |= (mode->vtotal - mode->vsync_start) << 16;
742	ret = cdn_dp_reg_write(dp, MSA_VERTICAL_0, val);
743	if (ret)
744		goto err_config_video;
745
746	val = mode->vsync_end - mode->vsync_start;
747	val |= (mode->vdisplay << 16) | (video->v_sync_polarity << 15);
748	ret = cdn_dp_reg_write(dp, MSA_VERTICAL_1, val);
749	if (ret)
750		goto err_config_video;
751
752	val = cdn_dp_get_msa_misc(video, mode);
753	ret = cdn_dp_reg_write(dp, MSA_MISC, val);
754	if (ret)
755		goto err_config_video;
756
757	ret = cdn_dp_reg_write(dp, STREAM_CONFIG, 1);
758	if (ret)
759		goto err_config_video;
760
761	val = mode->hsync_end - mode->hsync_start;
762	val |= mode->hdisplay << 16;
763	ret = cdn_dp_reg_write(dp, DP_HORIZONTAL, val);
764	if (ret)
765		goto err_config_video;
766
767	val = mode->vdisplay;
768	val |= (mode->vtotal - mode->vsync_start) << 16;
769	ret = cdn_dp_reg_write(dp, DP_VERTICAL_0, val);
770	if (ret)
771		goto err_config_video;
772
773	val = mode->vtotal;
774	ret = cdn_dp_reg_write(dp, DP_VERTICAL_1, val);
775	if (ret)
776		goto err_config_video;
777
778	ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 2, 1, 0);
779
780err_config_video:
781	if (ret)
782		DRM_DEV_ERROR(dp->dev, "config video failed: %d\n", ret);
783	return ret;
784}
785
786int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio)
787{
788	int ret;
789
790	ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, 0);
791	if (ret) {
792		DRM_DEV_ERROR(dp->dev, "audio stop failed: %d\n", ret);
793		return ret;
794	}
795
796	writel(0, dp->regs + SPDIF_CTRL_ADDR);
797
798	/* clearn the audio config and reset */
799	writel(0, dp->regs + AUDIO_SRC_CNTL);
800	writel(0, dp->regs + AUDIO_SRC_CNFG);
801	writel(AUDIO_SW_RST, dp->regs + AUDIO_SRC_CNTL);
802	writel(0, dp->regs + AUDIO_SRC_CNTL);
803
804	/* reset smpl2pckt component  */
805	writel(0, dp->regs + SMPL2PKT_CNTL);
806	writel(AUDIO_SW_RST, dp->regs + SMPL2PKT_CNTL);
807	writel(0, dp->regs + SMPL2PKT_CNTL);
808
809	/* reset FIFO */
810	writel(AUDIO_SW_RST, dp->regs + FIFO_CNTL);
811	writel(0, dp->regs + FIFO_CNTL);
812
813	if (audio->format == AFMT_SPDIF)
814		clk_disable_unprepare(dp->spdif_clk);
815
816	return 0;
817}
818
819int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable)
820{
821	int ret;
822
823	ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 4, 1, enable);
824	if (ret)
825		DRM_DEV_ERROR(dp->dev, "audio mute failed: %d\n", ret);
826
827	return ret;
828}
829
830static void cdn_dp_audio_config_i2s(struct cdn_dp_device *dp,
831				    struct audio_info *audio)
832{
833	int sub_pckt_num = 1, i2s_port_en_val = 0xf, i;
834	u32 val;
835
836	if (audio->channels == 2) {
837		if (dp->max_lanes == 1)
838			sub_pckt_num = 2;
839		else
840			sub_pckt_num = 4;
841
842		i2s_port_en_val = 1;
843	} else if (audio->channels == 4) {
844		i2s_port_en_val = 3;
845	}
846
847	writel(0x0, dp->regs + SPDIF_CTRL_ADDR);
848
849	writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL);
850
851	val = MAX_NUM_CH(audio->channels);
852	val |= NUM_OF_I2S_PORTS(audio->channels);
853	val |= AUDIO_TYPE_LPCM;
854	val |= CFG_SUB_PCKT_NUM(sub_pckt_num);
855	writel(val, dp->regs + SMPL2PKT_CNFG);
856
857	if (audio->sample_width == 16)
858		val = 0;
859	else if (audio->sample_width == 24)
860		val = 1 << 9;
861	else
862		val = 2 << 9;
863
864	val |= AUDIO_CH_NUM(audio->channels);
865	val |= I2S_DEC_PORT_EN(i2s_port_en_val);
866	val |= TRANS_SMPL_WIDTH_32;
867	writel(val, dp->regs + AUDIO_SRC_CNFG);
868
869	for (i = 0; i < (audio->channels + 1) / 2; i++) {
870		if (audio->sample_width == 16)
871			val = (0x02 << 8) | (0x02 << 20);
872		else if (audio->sample_width == 24)
873			val = (0x0b << 8) | (0x0b << 20);
874
875		val |= ((2 * i) << 4) | ((2 * i + 1) << 16);
876		writel(val, dp->regs + STTS_BIT_CH(i));
877	}
878
879	switch (audio->sample_rate) {
880	case 32000:
881		val = SAMPLING_FREQ(3) |
882		      ORIGINAL_SAMP_FREQ(0xc);
883		break;
884	case 44100:
885		val = SAMPLING_FREQ(0) |
886		      ORIGINAL_SAMP_FREQ(0xf);
887		break;
888	case 48000:
889		val = SAMPLING_FREQ(2) |
890		      ORIGINAL_SAMP_FREQ(0xd);
891		break;
892	case 88200:
893		val = SAMPLING_FREQ(8) |
894		      ORIGINAL_SAMP_FREQ(0x7);
895		break;
896	case 96000:
897		val = SAMPLING_FREQ(0xa) |
898		      ORIGINAL_SAMP_FREQ(5);
899		break;
900	case 176400:
901		val = SAMPLING_FREQ(0xc) |
902		      ORIGINAL_SAMP_FREQ(3);
903		break;
904	case 192000:
905		val = SAMPLING_FREQ(0xe) |
906		      ORIGINAL_SAMP_FREQ(1);
907		break;
908	}
909	val |= 4;
910	writel(val, dp->regs + COM_CH_STTS_BITS);
911
912	writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL);
913	writel(I2S_DEC_START, dp->regs + AUDIO_SRC_CNTL);
914}
915
916static void cdn_dp_audio_config_spdif(struct cdn_dp_device *dp)
917{
918	u32 val;
919
920	writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL);
921
922	val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4);
923	writel(val, dp->regs + SMPL2PKT_CNFG);
924	writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL);
925
926	val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS;
927	writel(val, dp->regs + SPDIF_CTRL_ADDR);
928
929	clk_prepare_enable(dp->spdif_clk);
930	clk_set_rate(dp->spdif_clk, CDN_DP_SPDIF_CLK);
931}
932
933int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio)
934{
935	int ret;
936
937	/* reset the spdif clk before config */
938	if (audio->format == AFMT_SPDIF) {
939		reset_control_assert(dp->spdif_rst);
940		reset_control_deassert(dp->spdif_rst);
941	}
942
943	ret = cdn_dp_reg_write(dp, CM_LANE_CTRL, LANE_REF_CYC);
944	if (ret)
945		goto err_audio_config;
946
947	ret = cdn_dp_reg_write(dp, CM_CTRL, 0);
948	if (ret)
949		goto err_audio_config;
950
951	if (audio->format == AFMT_I2S)
952		cdn_dp_audio_config_i2s(dp, audio);
953	else if (audio->format == AFMT_SPDIF)
954		cdn_dp_audio_config_spdif(dp);
955
956	ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN);
957
958err_audio_config:
959	if (ret)
960		DRM_DEV_ERROR(dp->dev, "audio config failed: %d\n", ret);
961	return ret;
962}
~/ Read-only file preview.