Linux Audio

Check our new training course

Loading...
v5.4
  1/*
  2 * Copyright © 2010 Intel Corporation
  3 *
  4 * Permission is hereby granted, free of charge, to any person obtaining a
  5 * copy of this software and associated documentation files (the "Software"),
  6 * to deal in the Software without restriction, including without limitation
  7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 * and/or sell copies of the Software, and to permit persons to whom the
  9 * Software is furnished to do so, subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice (including the next
 12 * paragraph) shall be included in all copies or substantial portions of the
 13 * Software.
 14 *
 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 21 * DEALINGS IN THE SOFTWARE.
 22 *
 23 * Authors:
 24 * Jackie Li<yaodong.li@intel.com>
 25 */
 26
 27#include <linux/delay.h>
 28#include <linux/freezer.h>
 29
 30#include <video/mipi_display.h>
 31
 32#include "mdfld_dsi_dpi.h"
 33#include "mdfld_dsi_output.h"
 34#include "mdfld_dsi_pkg_sender.h"
 
 35
 36#define MDFLD_DSI_READ_MAX_COUNT		5000
 37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 38enum {
 39	MDFLD_DSI_PANEL_MODE_SLEEP = 0x1,
 40};
 41
 42enum {
 43	MDFLD_DSI_PKG_SENDER_FREE = 0x0,
 44	MDFLD_DSI_PKG_SENDER_BUSY = 0x1,
 45};
 46
 47static const char *const dsi_errors[] = {
 48	"RX SOT Error",
 49	"RX SOT Sync Error",
 50	"RX EOT Sync Error",
 51	"RX Escape Mode Entry Error",
 52	"RX LP TX Sync Error",
 53	"RX HS Receive Timeout Error",
 54	"RX False Control Error",
 55	"RX ECC Single Bit Error",
 56	"RX ECC Multibit Error",
 57	"RX Checksum Error",
 58	"RX DSI Data Type Not Recognised",
 59	"RX DSI VC ID Invalid",
 60	"TX False Control Error",
 61	"TX ECC Single Bit Error",
 62	"TX ECC Multibit Error",
 63	"TX Checksum Error",
 64	"TX DSI Data Type Not Recognised",
 65	"TX DSI VC ID invalid",
 66	"High Contention",
 67	"Low contention",
 68	"DPI FIFO Under run",
 69	"HS TX Timeout",
 70	"LP RX Timeout",
 71	"Turn Around ACK Timeout",
 72	"ACK With No Error",
 73	"RX Invalid TX Length",
 74	"RX Prot Violation",
 75	"HS Generic Write FIFO Full",
 76	"LP Generic Write FIFO Full",
 77	"Generic Read Data Avail",
 78	"Special Packet Sent",
 79	"Tearing Effect",
 80};
 81
 82static inline int wait_for_gen_fifo_empty(struct mdfld_dsi_pkg_sender *sender,
 83						u32 mask)
 84{
 85	struct drm_device *dev = sender->dev;
 86	u32 gen_fifo_stat_reg = sender->mipi_gen_fifo_stat_reg;
 87	int retry = 0xffff;
 88
 89	while (retry--) {
 90		if ((mask & REG_READ(gen_fifo_stat_reg)) == mask)
 91			return 0;
 92		udelay(100);
 93	}
 94	DRM_ERROR("fifo is NOT empty 0x%08x\n", REG_READ(gen_fifo_stat_reg));
 95	return -EIO;
 96}
 97
 98static int wait_for_all_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
 99{
100	return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(10) | BIT(18) |
101						BIT(26) | BIT(27) | BIT(28)));
102}
103
104static int wait_for_lp_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
105{
106	return wait_for_gen_fifo_empty(sender, (BIT(10) | BIT(26)));
107}
108
109static int wait_for_hs_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
110{
111	return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(18)));
112}
113
114static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask)
115{
116	u32 intr_stat_reg = sender->mipi_intr_stat_reg;
117	struct drm_device *dev = sender->dev;
118
119	dev_dbg(sender->dev->dev, "Handling error 0x%08x\n", mask);
120
121	switch (mask) {
122	case BIT(0):
123	case BIT(1):
124	case BIT(2):
125	case BIT(3):
126	case BIT(4):
127	case BIT(5):
128	case BIT(6):
129	case BIT(7):
130	case BIT(8):
131	case BIT(9):
132	case BIT(10):
133	case BIT(11):
134	case BIT(12):
135	case BIT(13):
136		dev_dbg(sender->dev->dev, "No Action required\n");
137		break;
138	case BIT(14):
139		/*wait for all fifo empty*/
140		/*wait_for_all_fifos_empty(sender)*/
141		break;
142	case BIT(15):
143		dev_dbg(sender->dev->dev, "No Action required\n");
144		break;
145	case BIT(16):
146		break;
147	case BIT(17):
148		break;
149	case BIT(18):
150	case BIT(19):
151		dev_dbg(sender->dev->dev, "High/Low contention detected\n");
152		/*wait for contention recovery time*/
153		/*mdelay(10);*/
154		/*wait for all fifo empty*/
155		if (0)
156			wait_for_all_fifos_empty(sender);
157		break;
158	case BIT(20):
159		dev_dbg(sender->dev->dev, "No Action required\n");
160		break;
161	case BIT(21):
162		/*wait for all fifo empty*/
163		/*wait_for_all_fifos_empty(sender);*/
164		break;
165	case BIT(22):
166		break;
167	case BIT(23):
168	case BIT(24):
169	case BIT(25):
170	case BIT(26):
171	case BIT(27):
172		dev_dbg(sender->dev->dev, "HS Gen fifo full\n");
173		REG_WRITE(intr_stat_reg, mask);
174		wait_for_hs_fifos_empty(sender);
175		break;
176	case BIT(28):
177		dev_dbg(sender->dev->dev, "LP Gen fifo full\n");
178		REG_WRITE(intr_stat_reg, mask);
179		wait_for_lp_fifos_empty(sender);
180		break;
181	case BIT(29):
182	case BIT(30):
183	case BIT(31):
184		dev_dbg(sender->dev->dev, "No Action required\n");
185		break;
186	}
187
188	if (mask & REG_READ(intr_stat_reg))
189		dev_dbg(sender->dev->dev,
190				"Cannot clean interrupt 0x%08x\n", mask);
191	return 0;
192}
193
194static int dsi_error_handler(struct mdfld_dsi_pkg_sender *sender)
195{
196	struct drm_device *dev = sender->dev;
197	u32 intr_stat_reg = sender->mipi_intr_stat_reg;
198	u32 mask;
199	u32 intr_stat;
200	int i;
201	int err = 0;
202
203	intr_stat = REG_READ(intr_stat_reg);
204
205	for (i = 0; i < 32; i++) {
206		mask = (0x00000001UL) << i;
207		if (intr_stat & mask) {
208			dev_dbg(sender->dev->dev, "[DSI]: %s\n", dsi_errors[i]);
209			err = handle_dsi_error(sender, mask);
210			if (err)
211				DRM_ERROR("Cannot handle error\n");
212		}
213	}
214	return err;
215}
216
217static int send_short_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
218			u8 cmd, u8 param, bool hs)
219{
220	struct drm_device *dev = sender->dev;
221	u32 ctrl_reg;
222	u32 val;
223	u8 virtual_channel = 0;
224
225	if (hs) {
226		ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
227
228		/* FIXME: wait_for_hs_fifos_empty(sender); */
229	} else {
230		ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
231
232		/* FIXME: wait_for_lp_fifos_empty(sender); */
233	}
234
235	val = FLD_VAL(param, 23, 16) | FLD_VAL(cmd, 15, 8) |
236		FLD_VAL(virtual_channel, 7, 6) | FLD_VAL(data_type, 5, 0);
237
238	REG_WRITE(ctrl_reg, val);
239
240	return 0;
241}
242
243static int send_long_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
244			u8 *data, int len, bool hs)
245{
246	struct drm_device *dev = sender->dev;
247	u32 ctrl_reg;
248	u32 data_reg;
249	u32 val;
250	u8 *p;
251	u8 b1, b2, b3, b4;
252	u8 virtual_channel = 0;
253	int i;
254
255	if (hs) {
256		ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
257		data_reg = sender->mipi_hs_gen_data_reg;
258
259		/* FIXME: wait_for_hs_fifos_empty(sender); */
260	} else {
261		ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
262		data_reg = sender->mipi_lp_gen_data_reg;
263
264		/* FIXME: wait_for_lp_fifos_empty(sender); */
265	}
266
267	p = data;
268	for (i = 0; i < len / 4; i++) {
269		b1 = *p++;
270		b2 = *p++;
271		b3 = *p++;
272		b4 = *p++;
273
274		REG_WRITE(data_reg, b4 << 24 | b3 << 16 | b2 << 8 | b1);
275	}
276
277	i = len % 4;
278	if (i) {
279		b1 = 0; b2 = 0; b3 = 0;
280
281		switch (i) {
282		case 3:
283			b1 = *p++;
284			b2 = *p++;
285			b3 = *p++;
286			break;
287		case 2:
288			b1 = *p++;
289			b2 = *p++;
290			break;
291		case 1:
292			b1 = *p++;
293			break;
294		}
295
296		REG_WRITE(data_reg, b3 << 16 | b2 << 8 | b1);
297	}
298
299	val = FLD_VAL(len, 23, 8) | FLD_VAL(virtual_channel, 7, 6) |
300		FLD_VAL(data_type, 5, 0);
301
302	REG_WRITE(ctrl_reg, val);
303
304	return 0;
305}
306
307static int send_pkg_prepare(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
308			u8 *data, u16 len)
309{
310	u8 cmd;
311
312	switch (data_type) {
313	case MIPI_DSI_DCS_SHORT_WRITE:
314	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
315	case MIPI_DSI_DCS_LONG_WRITE:
316		cmd = *data;
317		break;
318	default:
319		return 0;
320	}
321
322	/*this prevents other package sending while doing msleep*/
323	sender->status = MDFLD_DSI_PKG_SENDER_BUSY;
324
325	/*wait for 120 milliseconds in case exit_sleep_mode just be sent*/
326	if (unlikely(cmd == MIPI_DCS_ENTER_SLEEP_MODE)) {
327		/*TODO: replace it with msleep later*/
328		mdelay(120);
329	}
330
331	if (unlikely(cmd == MIPI_DCS_EXIT_SLEEP_MODE)) {
332		/*TODO: replace it with msleep later*/
333		mdelay(120);
334	}
335	return 0;
336}
337
338static int send_pkg_done(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
339			u8 *data, u16 len)
340{
341	u8 cmd;
342
343	switch (data_type) {
344	case MIPI_DSI_DCS_SHORT_WRITE:
345	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
346	case MIPI_DSI_DCS_LONG_WRITE:
347		cmd = *data;
348		break;
349	default:
350		return 0;
351	}
352
353	/*update panel status*/
354	if (unlikely(cmd == MIPI_DCS_ENTER_SLEEP_MODE)) {
355		sender->panel_mode |= MDFLD_DSI_PANEL_MODE_SLEEP;
356		/*TODO: replace it with msleep later*/
357		mdelay(120);
358	} else if (unlikely(cmd == MIPI_DCS_EXIT_SLEEP_MODE)) {
359		sender->panel_mode &= ~MDFLD_DSI_PANEL_MODE_SLEEP;
360		/*TODO: replace it with msleep later*/
361		mdelay(120);
362	} else if (unlikely(cmd == MIPI_DCS_SOFT_RESET)) {
363		/*TODO: replace it with msleep later*/
364		mdelay(5);
365	}
366
367	sender->status = MDFLD_DSI_PKG_SENDER_FREE;
368
369	return 0;
370}
371
372static int send_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
373		u8 *data, u16 len, bool hs)
374{
375	int ret;
376
377	/*handle DSI error*/
378	ret = dsi_error_handler(sender);
379	if (ret) {
380		DRM_ERROR("Error handling failed\n");
381		return -EAGAIN;
382	}
383
384	/* send pkg */
385	if (sender->status == MDFLD_DSI_PKG_SENDER_BUSY) {
386		DRM_ERROR("sender is busy\n");
387		return -EAGAIN;
388	}
389
390	ret = send_pkg_prepare(sender, data_type, data, len);
391	if (ret) {
392		DRM_ERROR("send_pkg_prepare error\n");
393		return ret;
394	}
395
396	switch (data_type) {
397	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
398	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
399	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
400	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
401	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
402	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
403	case MIPI_DSI_DCS_SHORT_WRITE:
404	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
405	case MIPI_DSI_DCS_READ:
406		ret = send_short_pkg(sender, data_type, data[0], data[1], hs);
407		break;
408	case MIPI_DSI_GENERIC_LONG_WRITE:
409	case MIPI_DSI_DCS_LONG_WRITE:
410		ret = send_long_pkg(sender, data_type, data, len, hs);
411		break;
412	}
413
414	send_pkg_done(sender, data_type, data, len);
415
416	/*FIXME: should I query complete and fifo empty here?*/
417
418	return ret;
419}
420
421int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender, u8 *data,
422			u32 len, bool hs)
423{
424	unsigned long flags;
425
426	if (!sender || !data || !len) {
427		DRM_ERROR("Invalid parameters\n");
428		return -EINVAL;
429	}
430
431	spin_lock_irqsave(&sender->lock, flags);
432	send_pkg(sender, MIPI_DSI_DCS_LONG_WRITE, data, len, hs);
433	spin_unlock_irqrestore(&sender->lock, flags);
434
435	return 0;
436}
437
438int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender, u8 cmd,
439			u8 param, u8 param_num, bool hs)
440{
441	u8 data[2];
442	unsigned long flags;
443	u8 data_type;
444
445	if (!sender) {
446		DRM_ERROR("Invalid parameter\n");
447		return -EINVAL;
448	}
449
450	data[0] = cmd;
451
452	if (param_num) {
453		data_type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
454		data[1] = param;
455	} else {
456		data_type = MIPI_DSI_DCS_SHORT_WRITE;
457		data[1] = 0;
458	}
459
460	spin_lock_irqsave(&sender->lock, flags);
461	send_pkg(sender, data_type, data, sizeof(data), hs);
462	spin_unlock_irqrestore(&sender->lock, flags);
463
464	return 0;
465}
466
467int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender, u8 param0,
468			u8 param1, u8 param_num, bool hs)
469{
470	u8 data[2];
471	unsigned long flags;
472	u8 data_type;
473
474	if (!sender || param_num > 2) {
475		DRM_ERROR("Invalid parameter\n");
476		return -EINVAL;
477	}
478
479	switch (param_num) {
480	case 0:
481		data_type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM;
482		data[0] = 0;
483		data[1] = 0;
484		break;
485	case 1:
486		data_type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM;
487		data[0] = param0;
488		data[1] = 0;
489		break;
490	case 2:
491		data_type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM;
492		data[0] = param0;
493		data[1] = param1;
494		break;
495	}
496
497	spin_lock_irqsave(&sender->lock, flags);
498	send_pkg(sender, data_type, data, sizeof(data), hs);
499	spin_unlock_irqrestore(&sender->lock, flags);
500
501	return 0;
502}
503
504int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender, u8 *data,
505			u32 len, bool hs)
506{
507	unsigned long flags;
508
509	if (!sender || !data || !len) {
510		DRM_ERROR("Invalid parameters\n");
511		return -EINVAL;
512	}
513
514	spin_lock_irqsave(&sender->lock, flags);
515	send_pkg(sender, MIPI_DSI_GENERIC_LONG_WRITE, data, len, hs);
516	spin_unlock_irqrestore(&sender->lock, flags);
517
518	return 0;
519}
520
521static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
522			u8 *data, u16 len, u32 *data_out, u16 len_out, bool hs)
523{
524	unsigned long flags;
525	struct drm_device *dev;
526	int i;
527	u32 gen_data_reg;
528	int retry = MDFLD_DSI_READ_MAX_COUNT;
529
530	if (!sender || !data_out || !len_out) {
531		DRM_ERROR("Invalid parameters\n");
532		return -EINVAL;
533	}
534
535	dev = sender->dev;
536
537	/**
538	 * do reading.
539	 * 0) send out generic read request
540	 * 1) polling read data avail interrupt
541	 * 2) read data
542	 */
543	spin_lock_irqsave(&sender->lock, flags);
544
545	REG_WRITE(sender->mipi_intr_stat_reg, BIT(29));
546
547	if ((REG_READ(sender->mipi_intr_stat_reg) & BIT(29)))
548		DRM_ERROR("Can NOT clean read data valid interrupt\n");
549
550	/*send out read request*/
551	send_pkg(sender, data_type, data, len, hs);
552
553	/*polling read data avail interrupt*/
554	while (retry && !(REG_READ(sender->mipi_intr_stat_reg) & BIT(29))) {
555		udelay(100);
556		retry--;
557	}
558
559	if (!retry) {
560		spin_unlock_irqrestore(&sender->lock, flags);
561		return -ETIMEDOUT;
562	}
563
564	REG_WRITE(sender->mipi_intr_stat_reg, BIT(29));
565
566	/*read data*/
567	if (hs)
568		gen_data_reg = sender->mipi_hs_gen_data_reg;
569	else
570		gen_data_reg = sender->mipi_lp_gen_data_reg;
571
572	for (i = 0; i < len_out; i++)
573		*(data_out + i) = REG_READ(gen_data_reg);
574
575	spin_unlock_irqrestore(&sender->lock, flags);
576
577	return 0;
578}
579
580int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender, u8 cmd,
581		u32 *data, u16 len, bool hs)
582{
583	if (!sender || !data || !len) {
584		DRM_ERROR("Invalid parameters\n");
585		return -EINVAL;
586	}
587
588	return __read_panel_data(sender, MIPI_DSI_DCS_READ, &cmd, 1,
589				data, len, hs);
590}
591
592int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
593								int pipe)
594{
595	struct mdfld_dsi_pkg_sender *pkg_sender;
596	struct mdfld_dsi_config *dsi_config =
597				mdfld_dsi_get_config(dsi_connector);
598	struct drm_device *dev = dsi_config->dev;
599	struct drm_psb_private *dev_priv = dev->dev_private;
600	const struct psb_offset *map = &dev_priv->regmap[pipe];
601	u32 mipi_val = 0;
602
603	if (!dsi_connector) {
604		DRM_ERROR("Invalid parameter\n");
605		return -EINVAL;
606	}
607
608	pkg_sender = dsi_connector->pkg_sender;
609
610	if (!pkg_sender || IS_ERR(pkg_sender)) {
611		pkg_sender = kzalloc(sizeof(struct mdfld_dsi_pkg_sender),
612								GFP_KERNEL);
613		if (!pkg_sender) {
614			DRM_ERROR("Create DSI pkg sender failed\n");
615			return -ENOMEM;
616		}
617		dsi_connector->pkg_sender = (void *)pkg_sender;
618	}
619
620	pkg_sender->dev = dev;
621	pkg_sender->dsi_connector = dsi_connector;
622	pkg_sender->pipe = pipe;
623	pkg_sender->pkg_num = 0;
624	pkg_sender->panel_mode = 0;
625	pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE;
626
627	/*init regs*/
628	/* FIXME: should just copy the regmap ptr ? */
629	pkg_sender->dpll_reg = map->dpll;
630	pkg_sender->dspcntr_reg = map->cntr;
631	pkg_sender->pipeconf_reg = map->conf;
632	pkg_sender->dsplinoff_reg = map->linoff;
633	pkg_sender->dspsurf_reg = map->surf;
634	pkg_sender->pipestat_reg = map->status;
635
636	pkg_sender->mipi_intr_stat_reg = MIPI_INTR_STAT_REG(pipe);
637	pkg_sender->mipi_lp_gen_data_reg = MIPI_LP_GEN_DATA_REG(pipe);
638	pkg_sender->mipi_hs_gen_data_reg = MIPI_HS_GEN_DATA_REG(pipe);
639	pkg_sender->mipi_lp_gen_ctrl_reg = MIPI_LP_GEN_CTRL_REG(pipe);
640	pkg_sender->mipi_hs_gen_ctrl_reg = MIPI_HS_GEN_CTRL_REG(pipe);
641	pkg_sender->mipi_gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe);
642	pkg_sender->mipi_data_addr_reg = MIPI_DATA_ADD_REG(pipe);
643	pkg_sender->mipi_data_len_reg = MIPI_DATA_LEN_REG(pipe);
644	pkg_sender->mipi_cmd_addr_reg = MIPI_CMD_ADD_REG(pipe);
645	pkg_sender->mipi_cmd_len_reg = MIPI_CMD_LEN_REG(pipe);
646
647	/*init lock*/
648	spin_lock_init(&pkg_sender->lock);
649
650	if (mdfld_get_panel_type(dev, pipe) != TC35876X) {
651		/**
652		 * For video mode, don't enable DPI timing output here,
653		 * will init the DPI timing output during mode setting.
654		 */
655		mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
656
657		if (pipe == 0)
658			mipi_val |= 0x2;
659
660		REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi_val);
661		REG_READ(MIPI_PORT_CONTROL(pipe));
662
663		/* do dsi controller init */
664		mdfld_dsi_controller_init(dsi_config, pipe);
665	}
666
667	return 0;
668}
669
670void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender)
671{
672	if (!sender || IS_ERR(sender))
673		return;
674
675	/*free*/
676	kfree(sender);
677}
678
679
v3.5.6
  1/*
  2 * Copyright © 2010 Intel Corporation
  3 *
  4 * Permission is hereby granted, free of charge, to any person obtaining a
  5 * copy of this software and associated documentation files (the "Software"),
  6 * to deal in the Software without restriction, including without limitation
  7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 * and/or sell copies of the Software, and to permit persons to whom the
  9 * Software is furnished to do so, subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice (including the next
 12 * paragraph) shall be included in all copies or substantial portions of the
 13 * Software.
 14 *
 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 21 * DEALINGS IN THE SOFTWARE.
 22 *
 23 * Authors:
 24 * Jackie Li<yaodong.li@intel.com>
 25 */
 26
 
 27#include <linux/freezer.h>
 28
 
 
 
 29#include "mdfld_dsi_output.h"
 30#include "mdfld_dsi_pkg_sender.h"
 31#include "mdfld_dsi_dpi.h"
 32
 33#define MDFLD_DSI_READ_MAX_COUNT		5000
 34
 35enum data_type {
 36	DSI_DT_GENERIC_SHORT_WRITE_0	= 0x03,
 37	DSI_DT_GENERIC_SHORT_WRITE_1	= 0x13,
 38	DSI_DT_GENERIC_SHORT_WRITE_2	= 0x23,
 39	DSI_DT_GENERIC_READ_0		= 0x04,
 40	DSI_DT_GENERIC_READ_1		= 0x14,
 41	DSI_DT_GENERIC_READ_2		= 0x24,
 42	DSI_DT_GENERIC_LONG_WRITE	= 0x29,
 43	DSI_DT_DCS_SHORT_WRITE_0	= 0x05,
 44	DSI_DT_DCS_SHORT_WRITE_1	= 0x15,
 45	DSI_DT_DCS_READ			= 0x06,
 46	DSI_DT_DCS_LONG_WRITE		= 0x39,
 47};
 48
 49enum {
 50	MDFLD_DSI_PANEL_MODE_SLEEP = 0x1,
 51};
 52
 53enum {
 54	MDFLD_DSI_PKG_SENDER_FREE = 0x0,
 55	MDFLD_DSI_PKG_SENDER_BUSY = 0x1,
 56};
 57
 58static const char *const dsi_errors[] = {
 59	"RX SOT Error",
 60	"RX SOT Sync Error",
 61	"RX EOT Sync Error",
 62	"RX Escape Mode Entry Error",
 63	"RX LP TX Sync Error",
 64	"RX HS Receive Timeout Error",
 65	"RX False Control Error",
 66	"RX ECC Single Bit Error",
 67	"RX ECC Multibit Error",
 68	"RX Checksum Error",
 69	"RX DSI Data Type Not Recognised",
 70	"RX DSI VC ID Invalid",
 71	"TX False Control Error",
 72	"TX ECC Single Bit Error",
 73	"TX ECC Multibit Error",
 74	"TX Checksum Error",
 75	"TX DSI Data Type Not Recognised",
 76	"TX DSI VC ID invalid",
 77	"High Contention",
 78	"Low contention",
 79	"DPI FIFO Under run",
 80	"HS TX Timeout",
 81	"LP RX Timeout",
 82	"Turn Around ACK Timeout",
 83	"ACK With No Error",
 84	"RX Invalid TX Length",
 85	"RX Prot Violation",
 86	"HS Generic Write FIFO Full",
 87	"LP Generic Write FIFO Full",
 88	"Generic Read Data Avail"
 89	"Special Packet Sent",
 90	"Tearing Effect",
 91};
 92
 93static inline int wait_for_gen_fifo_empty(struct mdfld_dsi_pkg_sender *sender,
 94						u32 mask)
 95{
 96	struct drm_device *dev = sender->dev;
 97	u32 gen_fifo_stat_reg = sender->mipi_gen_fifo_stat_reg;
 98	int retry = 0xffff;
 99
100	while (retry--) {
101		if ((mask & REG_READ(gen_fifo_stat_reg)) == mask)
102			return 0;
103		udelay(100);
104	}
105	DRM_ERROR("fifo is NOT empty 0x%08x\n", REG_READ(gen_fifo_stat_reg));
106	return -EIO;
107}
108
109static int wait_for_all_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
110{
111	return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(10) | BIT(18) |
112						BIT(26) | BIT(27) | BIT(28)));
113}
114
115static int wait_for_lp_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
116{
117	return wait_for_gen_fifo_empty(sender, (BIT(10) | BIT(26)));
118}
119
120static int wait_for_hs_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
121{
122	return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(18)));
123}
124
125static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask)
126{
127	u32 intr_stat_reg = sender->mipi_intr_stat_reg;
128	struct drm_device *dev = sender->dev;
129
130	dev_dbg(sender->dev->dev, "Handling error 0x%08x\n", mask);
131
132	switch (mask) {
133	case BIT(0):
134	case BIT(1):
135	case BIT(2):
136	case BIT(3):
137	case BIT(4):
138	case BIT(5):
139	case BIT(6):
140	case BIT(7):
141	case BIT(8):
142	case BIT(9):
143	case BIT(10):
144	case BIT(11):
145	case BIT(12):
146	case BIT(13):
147		dev_dbg(sender->dev->dev, "No Action required\n");
148		break;
149	case BIT(14):
150		/*wait for all fifo empty*/
151		/*wait_for_all_fifos_empty(sender)*/;
152		break;
153	case BIT(15):
154		dev_dbg(sender->dev->dev, "No Action required\n");
155		break;
156	case BIT(16):
157		break;
158	case BIT(17):
159		break;
160	case BIT(18):
161	case BIT(19):
162		dev_dbg(sender->dev->dev, "High/Low contention detected\n");
163		/*wait for contention recovery time*/
164		/*mdelay(10);*/
165		/*wait for all fifo empty*/
166		if (0)
167			wait_for_all_fifos_empty(sender);
168		break;
169	case BIT(20):
170		dev_dbg(sender->dev->dev, "No Action required\n");
171		break;
172	case BIT(21):
173		/*wait for all fifo empty*/
174		/*wait_for_all_fifos_empty(sender);*/
175		break;
176	case BIT(22):
177		break;
178	case BIT(23):
179	case BIT(24):
180	case BIT(25):
181	case BIT(26):
182	case BIT(27):
183		dev_dbg(sender->dev->dev, "HS Gen fifo full\n");
184		REG_WRITE(intr_stat_reg, mask);
185		wait_for_hs_fifos_empty(sender);
186		break;
187	case BIT(28):
188		dev_dbg(sender->dev->dev, "LP Gen fifo full\n");
189		REG_WRITE(intr_stat_reg, mask);
190		wait_for_lp_fifos_empty(sender);
191		break;
192	case BIT(29):
193	case BIT(30):
194	case BIT(31):
195		dev_dbg(sender->dev->dev, "No Action required\n");
196		break;
197	}
198
199	if (mask & REG_READ(intr_stat_reg))
200		dev_dbg(sender->dev->dev,
201				"Cannot clean interrupt 0x%08x\n", mask);
202	return 0;
203}
204
205static int dsi_error_handler(struct mdfld_dsi_pkg_sender *sender)
206{
207	struct drm_device *dev = sender->dev;
208	u32 intr_stat_reg = sender->mipi_intr_stat_reg;
209	u32 mask;
210	u32 intr_stat;
211	int i;
212	int err = 0;
213
214	intr_stat = REG_READ(intr_stat_reg);
215
216	for (i = 0; i < 32; i++) {
217		mask = (0x00000001UL) << i;
218		if (intr_stat & mask) {
219			dev_dbg(sender->dev->dev, "[DSI]: %s\n", dsi_errors[i]);
220			err = handle_dsi_error(sender, mask);
221			if (err)
222				DRM_ERROR("Cannot handle error\n");
223		}
224	}
225	return err;
226}
227
228static int send_short_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
229			u8 cmd, u8 param, bool hs)
230{
231	struct drm_device *dev = sender->dev;
232	u32 ctrl_reg;
233	u32 val;
234	u8 virtual_channel = 0;
235
236	if (hs) {
237		ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
238
239		/* FIXME: wait_for_hs_fifos_empty(sender); */
240	} else {
241		ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
242
243		/* FIXME: wait_for_lp_fifos_empty(sender); */
244	}
245
246	val = FLD_VAL(param, 23, 16) | FLD_VAL(cmd, 15, 8) |
247		FLD_VAL(virtual_channel, 7, 6) | FLD_VAL(data_type, 5, 0);
248
249	REG_WRITE(ctrl_reg, val);
250
251	return 0;
252}
253
254static int send_long_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
255			u8 *data, int len, bool hs)
256{
257	struct drm_device *dev = sender->dev;
258	u32 ctrl_reg;
259	u32 data_reg;
260	u32 val;
261	u8 *p;
262	u8 b1, b2, b3, b4;
263	u8 virtual_channel = 0;
264	int i;
265
266	if (hs) {
267		ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
268		data_reg = sender->mipi_hs_gen_data_reg;
269
270		/* FIXME: wait_for_hs_fifos_empty(sender); */
271	} else {
272		ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
273		data_reg = sender->mipi_lp_gen_data_reg;
274
275		/* FIXME: wait_for_lp_fifos_empty(sender); */
276	}
277
278	p = data;
279	for (i = 0; i < len / 4; i++) {
280		b1 = *p++;
281		b2 = *p++;
282		b3 = *p++;
283		b4 = *p++;
284
285		REG_WRITE(data_reg, b4 << 24 | b3 << 16 | b2 << 8 | b1);
286	}
287
288	i = len % 4;
289	if (i) {
290		b1 = 0; b2 = 0; b3 = 0;
291
292		switch (i) {
293		case 3:
294			b1 = *p++;
295			b2 = *p++;
296			b3 = *p++;
297			break;
298		case 2:
299			b1 = *p++;
300			b2 = *p++;
301			break;
302		case 1:
303			b1 = *p++;
304			break;
305		}
306
307		REG_WRITE(data_reg, b3 << 16 | b2 << 8 | b1);
308	}
309
310	val = FLD_VAL(len, 23, 8) | FLD_VAL(virtual_channel, 7, 6) |
311		FLD_VAL(data_type, 5, 0);
312
313	REG_WRITE(ctrl_reg, val);
314
315	return 0;
316}
317
318static int send_pkg_prepare(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
319			u8 *data, u16 len)
320{
321	u8 cmd;
322
323	switch (data_type) {
324	case DSI_DT_DCS_SHORT_WRITE_0:
325	case DSI_DT_DCS_SHORT_WRITE_1:
326	case DSI_DT_DCS_LONG_WRITE:
327		cmd = *data;
328		break;
329	default:
330		return 0;
331	}
332
333	/*this prevents other package sending while doing msleep*/
334	sender->status = MDFLD_DSI_PKG_SENDER_BUSY;
335
336	/*wait for 120 milliseconds in case exit_sleep_mode just be sent*/
337	if (unlikely(cmd == DCS_ENTER_SLEEP_MODE)) {
338		/*TODO: replace it with msleep later*/
339		mdelay(120);
340	}
341
342	if (unlikely(cmd == DCS_EXIT_SLEEP_MODE)) {
343		/*TODO: replace it with msleep later*/
344		mdelay(120);
345	}
346	return 0;
347}
348
349static int send_pkg_done(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
350			u8 *data, u16 len)
351{
352	u8 cmd;
353
354	switch (data_type) {
355	case DSI_DT_DCS_SHORT_WRITE_0:
356	case DSI_DT_DCS_SHORT_WRITE_1:
357	case DSI_DT_DCS_LONG_WRITE:
358		cmd = *data;
359		break;
360	default:
361		return 0;
362	}
363
364	/*update panel status*/
365	if (unlikely(cmd == DCS_ENTER_SLEEP_MODE)) {
366		sender->panel_mode |= MDFLD_DSI_PANEL_MODE_SLEEP;
367		/*TODO: replace it with msleep later*/
368		mdelay(120);
369	} else if (unlikely(cmd == DCS_EXIT_SLEEP_MODE)) {
370		sender->panel_mode &= ~MDFLD_DSI_PANEL_MODE_SLEEP;
371		/*TODO: replace it with msleep later*/
372		mdelay(120);
373	} else if (unlikely(cmd == DCS_SOFT_RESET)) {
374		/*TODO: replace it with msleep later*/
375		mdelay(5);
376	}
377
378	sender->status = MDFLD_DSI_PKG_SENDER_FREE;
379
380	return 0;
381}
382
383static int send_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
384		u8 *data, u16 len, bool hs)
385{
386	int ret;
387
388	/*handle DSI error*/
389	ret = dsi_error_handler(sender);
390	if (ret) {
391		DRM_ERROR("Error handling failed\n");
392		return -EAGAIN;
393	}
394
395	/* send pkg */
396	if (sender->status == MDFLD_DSI_PKG_SENDER_BUSY) {
397		DRM_ERROR("sender is busy\n");
398		return -EAGAIN;
399	}
400
401	ret = send_pkg_prepare(sender, data_type, data, len);
402	if (ret) {
403		DRM_ERROR("send_pkg_prepare error\n");
404		return ret;
405	}
406
407	switch (data_type) {
408	case DSI_DT_GENERIC_SHORT_WRITE_0:
409	case DSI_DT_GENERIC_SHORT_WRITE_1:
410	case DSI_DT_GENERIC_SHORT_WRITE_2:
411	case DSI_DT_GENERIC_READ_0:
412	case DSI_DT_GENERIC_READ_1:
413	case DSI_DT_GENERIC_READ_2:
414	case DSI_DT_DCS_SHORT_WRITE_0:
415	case DSI_DT_DCS_SHORT_WRITE_1:
416	case DSI_DT_DCS_READ:
417		ret = send_short_pkg(sender, data_type, data[0], data[1], hs);
418		break;
419	case DSI_DT_GENERIC_LONG_WRITE:
420	case DSI_DT_DCS_LONG_WRITE:
421		ret = send_long_pkg(sender, data_type, data, len, hs);
422		break;
423	}
424
425	send_pkg_done(sender, data_type, data, len);
426
427	/*FIXME: should I query complete and fifo empty here?*/
428
429	return ret;
430}
431
432int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender, u8 *data,
433			u32 len, bool hs)
434{
435	unsigned long flags;
436
437	if (!sender || !data || !len) {
438		DRM_ERROR("Invalid parameters\n");
439		return -EINVAL;
440	}
441
442	spin_lock_irqsave(&sender->lock, flags);
443	send_pkg(sender, DSI_DT_DCS_LONG_WRITE, data, len, hs);
444	spin_unlock_irqrestore(&sender->lock, flags);
445
446	return 0;
447}
448
449int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender, u8 cmd,
450			u8 param, u8 param_num, bool hs)
451{
452	u8 data[2];
453	unsigned long flags;
454	u8 data_type;
455
456	if (!sender) {
457		DRM_ERROR("Invalid parameter\n");
458		return -EINVAL;
459	}
460
461	data[0] = cmd;
462
463	if (param_num) {
464		data_type = DSI_DT_DCS_SHORT_WRITE_1;
465		data[1] = param;
466	} else {
467		data_type = DSI_DT_DCS_SHORT_WRITE_0;
468		data[1] = 0;
469	}
470
471	spin_lock_irqsave(&sender->lock, flags);
472	send_pkg(sender, data_type, data, sizeof(data), hs);
473	spin_unlock_irqrestore(&sender->lock, flags);
474
475	return 0;
476}
477
478int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender, u8 param0,
479			u8 param1, u8 param_num, bool hs)
480{
481	u8 data[2];
482	unsigned long flags;
483	u8 data_type;
484
485	if (!sender || param_num > 2) {
486		DRM_ERROR("Invalid parameter\n");
487		return -EINVAL;
488	}
489
490	switch (param_num) {
491	case 0:
492		data_type = DSI_DT_GENERIC_SHORT_WRITE_0;
493		data[0] = 0;
494		data[1] = 0;
495		break;
496	case 1:
497		data_type = DSI_DT_GENERIC_SHORT_WRITE_1;
498		data[0] = param0;
499		data[1] = 0;
500		break;
501	case 2:
502		data_type = DSI_DT_GENERIC_SHORT_WRITE_2;
503		data[0] = param0;
504		data[1] = param1;
505		break;
506	}
507
508	spin_lock_irqsave(&sender->lock, flags);
509	send_pkg(sender, data_type, data, sizeof(data), hs);
510	spin_unlock_irqrestore(&sender->lock, flags);
511
512	return 0;
513}
514
515int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender, u8 *data,
516			u32 len, bool hs)
517{
518	unsigned long flags;
519
520	if (!sender || !data || !len) {
521		DRM_ERROR("Invalid parameters\n");
522		return -EINVAL;
523	}
524
525	spin_lock_irqsave(&sender->lock, flags);
526	send_pkg(sender, DSI_DT_GENERIC_LONG_WRITE, data, len, hs);
527	spin_unlock_irqrestore(&sender->lock, flags);
528
529	return 0;
530}
531
532static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
533			u8 *data, u16 len, u32 *data_out, u16 len_out, bool hs)
534{
535	unsigned long flags;
536	struct drm_device *dev = sender->dev;
537	int i;
538	u32 gen_data_reg;
539	int retry = MDFLD_DSI_READ_MAX_COUNT;
540
541	if (!sender || !data_out || !len_out) {
542		DRM_ERROR("Invalid parameters\n");
543		return -EINVAL;
544	}
545
 
 
546	/**
547	 * do reading.
548	 * 0) send out generic read request
549	 * 1) polling read data avail interrupt
550	 * 2) read data
551	 */
552	spin_lock_irqsave(&sender->lock, flags);
553
554	REG_WRITE(sender->mipi_intr_stat_reg, BIT(29));
555
556	if ((REG_READ(sender->mipi_intr_stat_reg) & BIT(29)))
557		DRM_ERROR("Can NOT clean read data valid interrupt\n");
558
559	/*send out read request*/
560	send_pkg(sender, data_type, data, len, hs);
561
562	/*polling read data avail interrupt*/
563	while (retry && !(REG_READ(sender->mipi_intr_stat_reg) & BIT(29))) {
564		udelay(100);
565		retry--;
566	}
567
568	if (!retry) {
569		spin_unlock_irqrestore(&sender->lock, flags);
570		return -ETIMEDOUT;
571	}
572
573	REG_WRITE(sender->mipi_intr_stat_reg, BIT(29));
574
575	/*read data*/
576	if (hs)
577		gen_data_reg = sender->mipi_hs_gen_data_reg;
578	else
579		gen_data_reg = sender->mipi_lp_gen_data_reg;
580
581	for (i = 0; i < len_out; i++)
582		*(data_out + i) = REG_READ(gen_data_reg);
583
584	spin_unlock_irqrestore(&sender->lock, flags);
585
586	return 0;
587}
588
589int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender, u8 cmd,
590		u32 *data, u16 len, bool hs)
591{
592	if (!sender || !data || !len) {
593		DRM_ERROR("Invalid parameters\n");
594		return -EINVAL;
595	}
596
597	return __read_panel_data(sender, DSI_DT_DCS_READ, &cmd, 1,
598				data, len, hs);
599}
600
601int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
602								int pipe)
603{
604	struct mdfld_dsi_pkg_sender *pkg_sender;
605	struct mdfld_dsi_config *dsi_config =
606				mdfld_dsi_get_config(dsi_connector);
607	struct drm_device *dev = dsi_config->dev;
608	struct drm_psb_private *dev_priv = dev->dev_private;
609	const struct psb_offset *map = &dev_priv->regmap[pipe];
610	u32 mipi_val = 0;
611
612	if (!dsi_connector) {
613		DRM_ERROR("Invalid parameter\n");
614		return -EINVAL;
615	}
616
617	pkg_sender = dsi_connector->pkg_sender;
618
619	if (!pkg_sender || IS_ERR(pkg_sender)) {
620		pkg_sender = kzalloc(sizeof(struct mdfld_dsi_pkg_sender),
621								GFP_KERNEL);
622		if (!pkg_sender) {
623			DRM_ERROR("Create DSI pkg sender failed\n");
624			return -ENOMEM;
625		}
626		dsi_connector->pkg_sender = (void *)pkg_sender;
627	}
628
629	pkg_sender->dev = dev;
630	pkg_sender->dsi_connector = dsi_connector;
631	pkg_sender->pipe = pipe;
632	pkg_sender->pkg_num = 0;
633	pkg_sender->panel_mode = 0;
634	pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE;
635
636	/*init regs*/
637	/* FIXME: should just copy the regmap ptr ? */
638	pkg_sender->dpll_reg = map->dpll;
639	pkg_sender->dspcntr_reg = map->cntr;
640	pkg_sender->pipeconf_reg = map->conf;
641	pkg_sender->dsplinoff_reg = map->linoff;
642	pkg_sender->dspsurf_reg = map->surf;
643	pkg_sender->pipestat_reg = map->status;
644
645	pkg_sender->mipi_intr_stat_reg = MIPI_INTR_STAT_REG(pipe);
646	pkg_sender->mipi_lp_gen_data_reg = MIPI_LP_GEN_DATA_REG(pipe);
647	pkg_sender->mipi_hs_gen_data_reg = MIPI_HS_GEN_DATA_REG(pipe);
648	pkg_sender->mipi_lp_gen_ctrl_reg = MIPI_LP_GEN_CTRL_REG(pipe);
649	pkg_sender->mipi_hs_gen_ctrl_reg = MIPI_HS_GEN_CTRL_REG(pipe);
650	pkg_sender->mipi_gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe);
651	pkg_sender->mipi_data_addr_reg = MIPI_DATA_ADD_REG(pipe);
652	pkg_sender->mipi_data_len_reg = MIPI_DATA_LEN_REG(pipe);
653	pkg_sender->mipi_cmd_addr_reg = MIPI_CMD_ADD_REG(pipe);
654	pkg_sender->mipi_cmd_len_reg = MIPI_CMD_LEN_REG(pipe);
655
656	/*init lock*/
657	spin_lock_init(&pkg_sender->lock);
658
659	if (mdfld_get_panel_type(dev, pipe) != TC35876X) {
660		/**
661		 * For video mode, don't enable DPI timing output here,
662		 * will init the DPI timing output during mode setting.
663		 */
664		mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
665
666		if (pipe == 0)
667			mipi_val |= 0x2;
668
669		REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi_val);
670		REG_READ(MIPI_PORT_CONTROL(pipe));
671
672		/* do dsi controller init */
673		mdfld_dsi_controller_init(dsi_config, pipe);
674	}
675
676	return 0;
677}
678
679void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender)
680{
681	if (!sender || IS_ERR(sender))
682		return;
683
684	/*free*/
685	kfree(sender);
686}
687
688