• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2011 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  */
24 
25 #include <linux/delay.h>
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/platform_data/tc35876x.h>
29 
30 #include <asm/intel_scu_ipc.h>
31 
32 #include "mdfld_dsi_dpi.h"
33 #include "mdfld_dsi_pkg_sender.h"
34 #include "mdfld_output.h"
35 #include "tc35876x-dsi-lvds.h"
36 
37 static struct i2c_client *tc35876x_client;
38 static struct i2c_client *cmi_lcd_i2c_client;
39 
40 #define FLD_MASK(start, end)	(((1 << ((start) - (end) + 1)) - 1) << (end))
41 #define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
42 
43 /* DSI D-PHY Layer Registers */
44 #define D0W_DPHYCONTTX		0x0004
45 #define CLW_DPHYCONTRX		0x0020
46 #define D0W_DPHYCONTRX		0x0024
47 #define D1W_DPHYCONTRX		0x0028
48 #define D2W_DPHYCONTRX		0x002C
49 #define D3W_DPHYCONTRX		0x0030
50 #define COM_DPHYCONTRX		0x0038
51 #define CLW_CNTRL		0x0040
52 #define D0W_CNTRL		0x0044
53 #define D1W_CNTRL		0x0048
54 #define D2W_CNTRL		0x004C
55 #define D3W_CNTRL		0x0050
56 #define DFTMODE_CNTRL		0x0054
57 
58 /* DSI PPI Layer Registers */
59 #define PPI_STARTPPI		0x0104
60 #define PPI_BUSYPPI		0x0108
61 #define PPI_LINEINITCNT		0x0110
62 #define PPI_LPTXTIMECNT		0x0114
63 #define PPI_LANEENABLE		0x0134
64 #define PPI_TX_RX_TA		0x013C
65 #define PPI_CLS_ATMR		0x0140
66 #define PPI_D0S_ATMR		0x0144
67 #define PPI_D1S_ATMR		0x0148
68 #define PPI_D2S_ATMR		0x014C
69 #define PPI_D3S_ATMR		0x0150
70 #define PPI_D0S_CLRSIPOCOUNT	0x0164
71 #define PPI_D1S_CLRSIPOCOUNT	0x0168
72 #define PPI_D2S_CLRSIPOCOUNT	0x016C
73 #define PPI_D3S_CLRSIPOCOUNT	0x0170
74 #define CLS_PRE			0x0180
75 #define D0S_PRE			0x0184
76 #define D1S_PRE			0x0188
77 #define D2S_PRE			0x018C
78 #define D3S_PRE			0x0190
79 #define CLS_PREP		0x01A0
80 #define D0S_PREP		0x01A4
81 #define D1S_PREP		0x01A8
82 #define D2S_PREP		0x01AC
83 #define D3S_PREP		0x01B0
84 #define CLS_ZERO		0x01C0
85 #define D0S_ZERO		0x01C4
86 #define D1S_ZERO		0x01C8
87 #define D2S_ZERO		0x01CC
88 #define D3S_ZERO		0x01D0
89 #define PPI_CLRFLG		0x01E0
90 #define PPI_CLRSIPO		0x01E4
91 #define HSTIMEOUT		0x01F0
92 #define HSTIMEOUTENABLE		0x01F4
93 
94 /* DSI Protocol Layer Registers */
95 #define DSI_STARTDSI		0x0204
96 #define DSI_BUSYDSI		0x0208
97 #define DSI_LANEENABLE		0x0210
98 #define DSI_LANESTATUS0		0x0214
99 #define DSI_LANESTATUS1		0x0218
100 #define DSI_INTSTATUS		0x0220
101 #define DSI_INTMASK		0x0224
102 #define DSI_INTCLR		0x0228
103 #define DSI_LPTXTO		0x0230
104 
105 /* DSI General Registers */
106 #define DSIERRCNT		0x0300
107 
108 /* DSI Application Layer Registers */
109 #define APLCTRL			0x0400
110 #define RDPKTLN			0x0404
111 
112 /* Video Path Registers */
113 #define VPCTRL			0x0450
114 #define HTIM1			0x0454
115 #define HTIM2			0x0458
116 #define VTIM1			0x045C
117 #define VTIM2			0x0460
118 #define VFUEN			0x0464
119 
120 /* LVDS Registers */
121 #define LVMX0003		0x0480
122 #define LVMX0407		0x0484
123 #define LVMX0811		0x0488
124 #define LVMX1215		0x048C
125 #define LVMX1619		0x0490
126 #define LVMX2023		0x0494
127 #define LVMX2427		0x0498
128 #define LVCFG			0x049C
129 #define LVPHY0			0x04A0
130 #define LVPHY1			0x04A4
131 
132 /* System Registers */
133 #define SYSSTAT			0x0500
134 #define SYSRST			0x0504
135 
136 /* GPIO Registers */
137 /*#define GPIOC			0x0520*/
138 #define GPIOO			0x0524
139 #define GPIOI			0x0528
140 
141 /* I2C Registers */
142 #define I2CTIMCTRL		0x0540
143 #define I2CMADDR		0x0544
144 #define WDATAQ			0x0548
145 #define RDATAQ			0x054C
146 
147 /* Chip/Rev Registers */
148 #define IDREG			0x0580
149 
150 /* Debug Registers */
151 #define DEBUG00			0x05A0
152 #define DEBUG01			0x05A4
153 
154 /* Panel CABC registers */
155 #define PANEL_PWM_CONTROL	0x90
156 #define PANEL_FREQ_DIVIDER_HI	0x91
157 #define PANEL_FREQ_DIVIDER_LO	0x92
158 #define PANEL_DUTY_CONTROL	0x93
159 #define PANEL_MODIFY_RGB	0x94
160 #define PANEL_FRAMERATE_CONTROL	0x96
161 #define PANEL_PWM_MIN		0x97
162 #define PANEL_PWM_REF		0x98
163 #define PANEL_PWM_MAX		0x99
164 #define PANEL_ALLOW_DISTORT	0x9A
165 #define PANEL_BYPASS_PWMI	0x9B
166 
167 /* Panel color management registers */
168 #define PANEL_CM_ENABLE		0x700
169 #define PANEL_CM_HUE		0x701
170 #define PANEL_CM_SATURATION	0x702
171 #define PANEL_CM_INTENSITY	0x703
172 #define PANEL_CM_BRIGHTNESS	0x704
173 #define PANEL_CM_CE_ENABLE	0x705
174 #define PANEL_CM_PEAK_EN	0x710
175 #define PANEL_CM_GAIN		0x711
176 #define PANEL_CM_HUETABLE_START	0x730
177 #define PANEL_CM_HUETABLE_END	0x747 /* inclusive */
178 
179 /* Input muxing for registers LVMX0003...LVMX2427 */
180 enum {
181 	INPUT_R0,	/* 0 */
182 	INPUT_R1,
183 	INPUT_R2,
184 	INPUT_R3,
185 	INPUT_R4,
186 	INPUT_R5,
187 	INPUT_R6,
188 	INPUT_R7,
189 	INPUT_G0,	/* 8 */
190 	INPUT_G1,
191 	INPUT_G2,
192 	INPUT_G3,
193 	INPUT_G4,
194 	INPUT_G5,
195 	INPUT_G6,
196 	INPUT_G7,
197 	INPUT_B0,	/* 16 */
198 	INPUT_B1,
199 	INPUT_B2,
200 	INPUT_B3,
201 	INPUT_B4,
202 	INPUT_B5,
203 	INPUT_B6,
204 	INPUT_B7,
205 	INPUT_HSYNC,	/* 24 */
206 	INPUT_VSYNC,
207 	INPUT_DE,
208 	LOGIC_0,
209 	/* 28...31 undefined */
210 };
211 
212 #define INPUT_MUX(lvmx03, lvmx02, lvmx01, lvmx00)		\
213 	(FLD_VAL(lvmx03, 29, 24) | FLD_VAL(lvmx02, 20, 16) |	\
214 	FLD_VAL(lvmx01, 12, 8) | FLD_VAL(lvmx00, 4, 0))
215 
216 /**
217  * tc35876x_regw - Write DSI-LVDS bridge register using I2C
218  * @client: struct i2c_client to use
219  * @reg: register address
220  * @value: value to write
221  *
222  * Returns 0 on success, or a negative error value.
223  */
tc35876x_regw(struct i2c_client * client,u16 reg,u32 value)224 static int tc35876x_regw(struct i2c_client *client, u16 reg, u32 value)
225 {
226 	int r;
227 	u8 tx_data[] = {
228 		/* NOTE: Register address big-endian, data little-endian. */
229 		(reg >> 8) & 0xff,
230 		reg & 0xff,
231 		value & 0xff,
232 		(value >> 8) & 0xff,
233 		(value >> 16) & 0xff,
234 		(value >> 24) & 0xff,
235 	};
236 	struct i2c_msg msgs[] = {
237 		{
238 			.addr = client->addr,
239 			.flags = 0,
240 			.buf = tx_data,
241 			.len = ARRAY_SIZE(tx_data),
242 		},
243 	};
244 
245 	r = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
246 	if (r < 0) {
247 		dev_err(&client->dev, "%s: reg 0x%04x val 0x%08x error %d\n",
248 			__func__, reg, value, r);
249 		return r;
250 	}
251 
252 	if (r < ARRAY_SIZE(msgs)) {
253 		dev_err(&client->dev, "%s: reg 0x%04x val 0x%08x msgs %d\n",
254 			__func__, reg, value, r);
255 		return -EAGAIN;
256 	}
257 
258 	dev_dbg(&client->dev, "%s: reg 0x%04x val 0x%08x\n",
259 			__func__, reg, value);
260 
261 	return 0;
262 }
263 
264 /**
265  * tc35876x_regr - Read DSI-LVDS bridge register using I2C
266  * @client: struct i2c_client to use
267  * @reg: register address
268  * @value: pointer for storing the value
269  *
270  * Returns 0 on success, or a negative error value.
271  */
tc35876x_regr(struct i2c_client * client,u16 reg,u32 * value)272 static int tc35876x_regr(struct i2c_client *client, u16 reg, u32 *value)
273 {
274 	int r;
275 	u8 tx_data[] = {
276 		(reg >> 8) & 0xff,
277 		reg & 0xff,
278 	};
279 	u8 rx_data[4];
280 	struct i2c_msg msgs[] = {
281 		{
282 			.addr = client->addr,
283 			.flags = 0,
284 			.buf = tx_data,
285 			.len = ARRAY_SIZE(tx_data),
286 		},
287 		{
288 			.addr = client->addr,
289 			.flags = I2C_M_RD,
290 			.buf = rx_data,
291 			.len = ARRAY_SIZE(rx_data),
292 		 },
293 	};
294 
295 	r = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
296 	if (r < 0) {
297 		dev_err(&client->dev, "%s: reg 0x%04x error %d\n", __func__,
298 			reg, r);
299 		return r;
300 	}
301 
302 	if (r < ARRAY_SIZE(msgs)) {
303 		dev_err(&client->dev, "%s: reg 0x%04x msgs %d\n", __func__,
304 			reg, r);
305 		return -EAGAIN;
306 	}
307 
308 	*value = rx_data[0] << 24 | rx_data[1] << 16 |
309 		rx_data[2] << 8 | rx_data[3];
310 
311 	dev_dbg(&client->dev, "%s: reg 0x%04x value 0x%08x\n", __func__,
312 		reg, *value);
313 
314 	return 0;
315 }
316 
tc35876x_set_bridge_reset_state(struct drm_device * dev,int state)317 void tc35876x_set_bridge_reset_state(struct drm_device *dev, int state)
318 {
319 	struct tc35876x_platform_data *pdata;
320 
321 	if (WARN(!tc35876x_client, "%s called before probe", __func__))
322 		return;
323 
324 	dev_dbg(&tc35876x_client->dev, "%s: state %d\n", __func__, state);
325 
326 	pdata = dev_get_platdata(&tc35876x_client->dev);
327 
328 	if (pdata->gpio_bridge_reset == -1)
329 		return;
330 
331 	if (state) {
332 		gpio_set_value_cansleep(pdata->gpio_bridge_reset, 0);
333 		mdelay(10);
334 	} else {
335 		/* Pull MIPI Bridge reset pin to Low */
336 		gpio_set_value_cansleep(pdata->gpio_bridge_reset, 0);
337 		mdelay(20);
338 		/* Pull MIPI Bridge reset pin to High */
339 		gpio_set_value_cansleep(pdata->gpio_bridge_reset, 1);
340 		mdelay(40);
341 	}
342 }
343 
tc35876x_configure_lvds_bridge(struct drm_device * dev)344 void tc35876x_configure_lvds_bridge(struct drm_device *dev)
345 {
346 	struct i2c_client *i2c = tc35876x_client;
347 	u32 ppi_lptxtimecnt;
348 	u32 txtagocnt;
349 	u32 txtasurecnt;
350 	u32 id;
351 
352 	if (WARN(!tc35876x_client, "%s called before probe", __func__))
353 		return;
354 
355 	dev_dbg(&tc35876x_client->dev, "%s\n", __func__);
356 
357 	if (!tc35876x_regr(i2c, IDREG, &id))
358 		dev_info(&tc35876x_client->dev, "tc35876x ID 0x%08x\n", id);
359 	else
360 		dev_err(&tc35876x_client->dev, "Cannot read ID\n");
361 
362 	ppi_lptxtimecnt = 4;
363 	txtagocnt = (5 * ppi_lptxtimecnt - 3) / 4;
364 	txtasurecnt = 3 * ppi_lptxtimecnt / 2;
365 	tc35876x_regw(i2c, PPI_TX_RX_TA, FLD_VAL(txtagocnt, 26, 16) |
366 		FLD_VAL(txtasurecnt, 10, 0));
367 	tc35876x_regw(i2c, PPI_LPTXTIMECNT, FLD_VAL(ppi_lptxtimecnt, 10, 0));
368 
369 	tc35876x_regw(i2c, PPI_D0S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0));
370 	tc35876x_regw(i2c, PPI_D1S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0));
371 	tc35876x_regw(i2c, PPI_D2S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0));
372 	tc35876x_regw(i2c, PPI_D3S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0));
373 
374 	/* Enabling MIPI & PPI lanes, Enable 4 lanes */
375 	tc35876x_regw(i2c, PPI_LANEENABLE,
376 		BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0));
377 	tc35876x_regw(i2c, DSI_LANEENABLE,
378 		BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0));
379 	tc35876x_regw(i2c, PPI_STARTPPI, BIT(0));
380 	tc35876x_regw(i2c, DSI_STARTDSI, BIT(0));
381 
382 	/* Setting LVDS output frequency */
383 	tc35876x_regw(i2c, LVPHY0, FLD_VAL(1, 20, 16) |
384 		FLD_VAL(2, 15, 14) | FLD_VAL(6, 4, 0)); /* 0x00048006 */
385 
386 	/* Setting video panel control register,0x00000120 VTGen=ON ?!?!? */
387 	tc35876x_regw(i2c, VPCTRL, BIT(8) | BIT(5));
388 
389 	/* Horizontal back porch and horizontal pulse width. 0x00280028 */
390 	tc35876x_regw(i2c, HTIM1, FLD_VAL(40, 24, 16) | FLD_VAL(40, 8, 0));
391 
392 	/* Horizontal front porch and horizontal active video size. 0x00500500*/
393 	tc35876x_regw(i2c, HTIM2, FLD_VAL(80, 24, 16) | FLD_VAL(1280, 10, 0));
394 
395 	/* Vertical back porch and vertical sync pulse width. 0x000e000a */
396 	tc35876x_regw(i2c, VTIM1, FLD_VAL(14, 23, 16) | FLD_VAL(10, 7, 0));
397 
398 	/* Vertical front porch and vertical display size. 0x000e0320 */
399 	tc35876x_regw(i2c, VTIM2, FLD_VAL(14, 23, 16) | FLD_VAL(800, 10, 0));
400 
401 	/* Set above HTIM1, HTIM2, VTIM1, and VTIM2 at next VSYNC. */
402 	tc35876x_regw(i2c, VFUEN, BIT(0));
403 
404 	/* Soft reset LCD controller. */
405 	tc35876x_regw(i2c, SYSRST, BIT(2));
406 
407 	/* LVDS-TX input muxing */
408 	tc35876x_regw(i2c, LVMX0003,
409 		INPUT_MUX(INPUT_R5, INPUT_R4, INPUT_R3, INPUT_R2));
410 	tc35876x_regw(i2c, LVMX0407,
411 		INPUT_MUX(INPUT_G2, INPUT_R7, INPUT_R1, INPUT_R6));
412 	tc35876x_regw(i2c, LVMX0811,
413 		INPUT_MUX(INPUT_G1, INPUT_G0, INPUT_G4, INPUT_G3));
414 	tc35876x_regw(i2c, LVMX1215,
415 		INPUT_MUX(INPUT_B2, INPUT_G7, INPUT_G6, INPUT_G5));
416 	tc35876x_regw(i2c, LVMX1619,
417 		INPUT_MUX(INPUT_B4, INPUT_B3, INPUT_B1, INPUT_B0));
418 	tc35876x_regw(i2c, LVMX2023,
419 		INPUT_MUX(LOGIC_0,  INPUT_B7, INPUT_B6, INPUT_B5));
420 	tc35876x_regw(i2c, LVMX2427,
421 		INPUT_MUX(INPUT_R0, INPUT_DE, INPUT_VSYNC, INPUT_HSYNC));
422 
423 	/* Enable LVDS transmitter. */
424 	tc35876x_regw(i2c, LVCFG, BIT(0));
425 
426 	/* Clear notifications. Don't write reserved bits. Was write 0xffffffff
427 	 * to 0x0288, must be in error?! */
428 	tc35876x_regw(i2c, DSI_INTCLR, FLD_MASK(31, 30) | FLD_MASK(22, 0));
429 }
430 
431 #define GPIOPWMCTRL	0x38F
432 #define PWM0CLKDIV0	0x62 /* low byte */
433 #define PWM0CLKDIV1	0x61 /* high byte */
434 
435 #define SYSTEMCLK	19200000UL /* 19.2 MHz */
436 #define PWM_FREQUENCY	9600 /* Hz */
437 
438 /* f = baseclk / (clkdiv + 1) => clkdiv = (baseclk - f) / f */
calc_clkdiv(unsigned long baseclk,unsigned int f)439 static inline u16 calc_clkdiv(unsigned long baseclk, unsigned int f)
440 {
441 	return (baseclk - f) / f;
442 }
443 
tc35876x_brightness_init(struct drm_device * dev)444 static void tc35876x_brightness_init(struct drm_device *dev)
445 {
446 	int ret;
447 	u8 pwmctrl;
448 	u16 clkdiv;
449 
450 	/* Make sure the PWM reference is the 19.2 MHz system clock. Read first
451 	 * instead of setting directly to catch potential conflicts between PWM
452 	 * users. */
453 	ret = intel_scu_ipc_ioread8(GPIOPWMCTRL, &pwmctrl);
454 	if (ret || pwmctrl != 0x01) {
455 		if (ret)
456 			dev_err(&dev->pdev->dev, "GPIOPWMCTRL read failed\n");
457 		else
458 			dev_warn(&dev->pdev->dev, "GPIOPWMCTRL was not set to system clock (pwmctrl = 0x%02x)\n", pwmctrl);
459 
460 		ret = intel_scu_ipc_iowrite8(GPIOPWMCTRL, 0x01);
461 		if (ret)
462 			dev_err(&dev->pdev->dev, "GPIOPWMCTRL set failed\n");
463 	}
464 
465 	clkdiv = calc_clkdiv(SYSTEMCLK, PWM_FREQUENCY);
466 
467 	ret = intel_scu_ipc_iowrite8(PWM0CLKDIV1, (clkdiv >> 8) & 0xff);
468 	if (!ret)
469 		ret = intel_scu_ipc_iowrite8(PWM0CLKDIV0, clkdiv & 0xff);
470 
471 	if (ret)
472 		dev_err(&dev->pdev->dev, "PWM0CLKDIV set failed\n");
473 	else
474 		dev_dbg(&dev->pdev->dev, "PWM0CLKDIV set to 0x%04x (%d Hz)\n",
475 			clkdiv, PWM_FREQUENCY);
476 }
477 
478 #define PWM0DUTYCYCLE			0x67
479 
tc35876x_brightness_control(struct drm_device * dev,int level)480 void tc35876x_brightness_control(struct drm_device *dev, int level)
481 {
482 	int ret;
483 	u8 duty_val;
484 	u8 panel_duty_val;
485 
486 	level = clamp(level, 0, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL);
487 
488 	/* PWM duty cycle 0x00...0x63 corresponds to 0...99% */
489 	duty_val = level * 0x63 / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL;
490 
491 	/* I won't pretend to understand this formula. The panel spec is quite
492 	 * bad engrish.
493 	 */
494 	panel_duty_val = (2 * level - 100) * 0xA9 /
495 			 MDFLD_DSI_BRIGHTNESS_MAX_LEVEL + 0x56;
496 
497 	ret = intel_scu_ipc_iowrite8(PWM0DUTYCYCLE, duty_val);
498 	if (ret)
499 		dev_err(&tc35876x_client->dev, "%s: ipc write fail\n",
500 			__func__);
501 
502 	if (cmi_lcd_i2c_client) {
503 		ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client,
504 						PANEL_PWM_MAX, panel_duty_val);
505 		if (ret < 0)
506 			dev_err(&cmi_lcd_i2c_client->dev, "%s: i2c write failed\n",
507 				__func__);
508 	}
509 }
510 
tc35876x_toshiba_bridge_panel_off(struct drm_device * dev)511 void tc35876x_toshiba_bridge_panel_off(struct drm_device *dev)
512 {
513 	struct tc35876x_platform_data *pdata;
514 
515 	if (WARN(!tc35876x_client, "%s called before probe", __func__))
516 		return;
517 
518 	dev_dbg(&tc35876x_client->dev, "%s\n", __func__);
519 
520 	pdata = dev_get_platdata(&tc35876x_client->dev);
521 
522 	if (pdata->gpio_panel_bl_en != -1)
523 		gpio_set_value_cansleep(pdata->gpio_panel_bl_en, 0);
524 
525 	if (pdata->gpio_panel_vadd != -1)
526 		gpio_set_value_cansleep(pdata->gpio_panel_vadd, 0);
527 }
528 
tc35876x_toshiba_bridge_panel_on(struct drm_device * dev)529 void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev)
530 {
531 	struct tc35876x_platform_data *pdata;
532 	struct drm_psb_private *dev_priv = dev->dev_private;
533 
534 	if (WARN(!tc35876x_client, "%s called before probe", __func__))
535 		return;
536 
537 	dev_dbg(&tc35876x_client->dev, "%s\n", __func__);
538 
539 	pdata = dev_get_platdata(&tc35876x_client->dev);
540 
541 	if (pdata->gpio_panel_vadd != -1) {
542 		gpio_set_value_cansleep(pdata->gpio_panel_vadd, 1);
543 		msleep(260);
544 	}
545 
546 	if (cmi_lcd_i2c_client) {
547 		int ret;
548 		dev_dbg(&cmi_lcd_i2c_client->dev, "setting TCON\n");
549 		/* Bit 4 is average_saving. Setting it to 1, the brightness is
550 		 * referenced to the average of the frame content. 0 means
551 		 * reference to the maximum of frame contents. Bits 3:0 are
552 		 * allow_distort. When set to a nonzero value, all color values
553 		 * between 255-allow_distort*2 and 255 are mapped to the
554 		 * 255-allow_distort*2 value.
555 		 */
556 		ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client,
557 						PANEL_ALLOW_DISTORT, 0x10);
558 		if (ret < 0)
559 			dev_err(&cmi_lcd_i2c_client->dev,
560 				"i2c write failed (%d)\n", ret);
561 		ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client,
562 						PANEL_BYPASS_PWMI, 0);
563 		if (ret < 0)
564 			dev_err(&cmi_lcd_i2c_client->dev,
565 				"i2c write failed (%d)\n", ret);
566 		/* Set minimum brightness value - this is tunable */
567 		ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client,
568 						PANEL_PWM_MIN, 0x35);
569 		if (ret < 0)
570 			dev_err(&cmi_lcd_i2c_client->dev,
571 				"i2c write failed (%d)\n", ret);
572 	}
573 
574 	if (pdata->gpio_panel_bl_en != -1)
575 		gpio_set_value_cansleep(pdata->gpio_panel_bl_en, 1);
576 
577 	tc35876x_brightness_control(dev, dev_priv->brightness_adjusted);
578 }
579 
tc35876x_get_config_mode(struct drm_device * dev)580 static struct drm_display_mode *tc35876x_get_config_mode(struct drm_device *dev)
581 {
582 	struct drm_display_mode *mode;
583 
584 	dev_dbg(&dev->pdev->dev, "%s\n", __func__);
585 
586 	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
587 	if (!mode)
588 		return NULL;
589 
590 	/* FIXME: do this properly. */
591 	mode->hdisplay = 1280;
592 	mode->vdisplay = 800;
593 	mode->hsync_start = 1360;
594 	mode->hsync_end = 1400;
595 	mode->htotal = 1440;
596 	mode->vsync_start = 814;
597 	mode->vsync_end = 824;
598 	mode->vtotal = 838;
599 	mode->clock = 33324 << 1;
600 
601 	dev_info(&dev->pdev->dev, "hdisplay(w) = %d\n", mode->hdisplay);
602 	dev_info(&dev->pdev->dev, "vdisplay(h) = %d\n", mode->vdisplay);
603 	dev_info(&dev->pdev->dev, "HSS = %d\n", mode->hsync_start);
604 	dev_info(&dev->pdev->dev, "HSE = %d\n", mode->hsync_end);
605 	dev_info(&dev->pdev->dev, "htotal = %d\n", mode->htotal);
606 	dev_info(&dev->pdev->dev, "VSS = %d\n", mode->vsync_start);
607 	dev_info(&dev->pdev->dev, "VSE = %d\n", mode->vsync_end);
608 	dev_info(&dev->pdev->dev, "vtotal = %d\n", mode->vtotal);
609 	dev_info(&dev->pdev->dev, "clock = %d\n", mode->clock);
610 
611 	drm_mode_set_name(mode);
612 	drm_mode_set_crtcinfo(mode, 0);
613 
614 	mode->type |= DRM_MODE_TYPE_PREFERRED;
615 
616 	return mode;
617 }
618 
619 /* DV1 Active area 216.96 x 135.6 mm */
620 #define DV1_PANEL_WIDTH 217
621 #define DV1_PANEL_HEIGHT 136
622 
tc35876x_get_panel_info(struct drm_device * dev,int pipe,struct panel_info * pi)623 static int tc35876x_get_panel_info(struct drm_device *dev, int pipe,
624 				struct panel_info *pi)
625 {
626 	if (!dev || !pi)
627 		return -EINVAL;
628 
629 	pi->width_mm = DV1_PANEL_WIDTH;
630 	pi->height_mm = DV1_PANEL_HEIGHT;
631 
632 	return 0;
633 }
634 
tc35876x_bridge_probe(struct i2c_client * client,const struct i2c_device_id * id)635 static int tc35876x_bridge_probe(struct i2c_client *client,
636 				const struct i2c_device_id *id)
637 {
638 	struct tc35876x_platform_data *pdata;
639 
640 	dev_info(&client->dev, "%s\n", __func__);
641 
642 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
643 		dev_err(&client->dev, "%s: i2c_check_functionality() failed\n",
644 			__func__);
645 		return -ENODEV;
646 	}
647 
648 	pdata = dev_get_platdata(&client->dev);
649 	if (!pdata) {
650 		dev_err(&client->dev, "%s: no platform data\n", __func__);
651 		return -ENODEV;
652 	}
653 
654 	if (pdata->gpio_bridge_reset != -1) {
655 		gpio_request(pdata->gpio_bridge_reset, "tc35876x bridge reset");
656 		gpio_direction_output(pdata->gpio_bridge_reset, 0);
657 	}
658 
659 	if (pdata->gpio_panel_bl_en != -1) {
660 		gpio_request(pdata->gpio_panel_bl_en, "tc35876x panel bl en");
661 		gpio_direction_output(pdata->gpio_panel_bl_en, 0);
662 	}
663 
664 	if (pdata->gpio_panel_vadd != -1) {
665 		gpio_request(pdata->gpio_panel_vadd, "tc35876x panel vadd");
666 		gpio_direction_output(pdata->gpio_panel_vadd, 0);
667 	}
668 
669 	tc35876x_client = client;
670 
671 	return 0;
672 }
673 
tc35876x_bridge_remove(struct i2c_client * client)674 static int tc35876x_bridge_remove(struct i2c_client *client)
675 {
676 	struct tc35876x_platform_data *pdata = dev_get_platdata(&client->dev);
677 
678 	dev_dbg(&client->dev, "%s\n", __func__);
679 
680 	if (pdata->gpio_bridge_reset != -1)
681 		gpio_free(pdata->gpio_bridge_reset);
682 
683 	if (pdata->gpio_panel_bl_en != -1)
684 		gpio_free(pdata->gpio_panel_bl_en);
685 
686 	if (pdata->gpio_panel_vadd != -1)
687 		gpio_free(pdata->gpio_panel_vadd);
688 
689 	tc35876x_client = NULL;
690 
691 	return 0;
692 }
693 
694 static const struct i2c_device_id tc35876x_bridge_id[] = {
695 	{ "i2c_disp_brig", 0 },
696 	{ }
697 };
698 MODULE_DEVICE_TABLE(i2c, tc35876x_bridge_id);
699 
700 static struct i2c_driver tc35876x_bridge_i2c_driver = {
701 	.driver = {
702 		.name = "i2c_disp_brig",
703 	},
704 	.id_table = tc35876x_bridge_id,
705 	.probe = tc35876x_bridge_probe,
706 	.remove = tc35876x_bridge_remove,
707 };
708 
709 /* LCD panel I2C */
cmi_lcd_i2c_probe(struct i2c_client * client,const struct i2c_device_id * id)710 static int cmi_lcd_i2c_probe(struct i2c_client *client,
711 			     const struct i2c_device_id *id)
712 {
713 	dev_info(&client->dev, "%s\n", __func__);
714 
715 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
716 		dev_err(&client->dev, "%s: i2c_check_functionality() failed\n",
717 			__func__);
718 		return -ENODEV;
719 	}
720 
721 	cmi_lcd_i2c_client = client;
722 
723 	return 0;
724 }
725 
cmi_lcd_i2c_remove(struct i2c_client * client)726 static int cmi_lcd_i2c_remove(struct i2c_client *client)
727 {
728 	dev_dbg(&client->dev, "%s\n", __func__);
729 
730 	cmi_lcd_i2c_client = NULL;
731 
732 	return 0;
733 }
734 
735 static const struct i2c_device_id cmi_lcd_i2c_id[] = {
736 	{ "cmi-lcd", 0 },
737 	{ }
738 };
739 MODULE_DEVICE_TABLE(i2c, cmi_lcd_i2c_id);
740 
741 static struct i2c_driver cmi_lcd_i2c_driver = {
742 	.driver = {
743 		.name = "cmi-lcd",
744 	},
745 	.id_table = cmi_lcd_i2c_id,
746 	.probe = cmi_lcd_i2c_probe,
747 	.remove = cmi_lcd_i2c_remove,
748 };
749 
750 /* HACK to create I2C device while it's not created by platform code */
751 #define CMI_LCD_I2C_ADAPTER	2
752 #define CMI_LCD_I2C_ADDR	0x60
753 
cmi_lcd_hack_create_device(void)754 static int cmi_lcd_hack_create_device(void)
755 {
756 	struct i2c_adapter *adapter;
757 	struct i2c_client *client;
758 	struct i2c_board_info info = {
759 		.type = "cmi-lcd",
760 		.addr = CMI_LCD_I2C_ADDR,
761 	};
762 
763 	pr_debug("%s\n", __func__);
764 
765 	adapter = i2c_get_adapter(CMI_LCD_I2C_ADAPTER);
766 	if (!adapter) {
767 		pr_err("%s: i2c_get_adapter(%d) failed\n", __func__,
768 			CMI_LCD_I2C_ADAPTER);
769 		return -EINVAL;
770 	}
771 
772 	client = i2c_new_device(adapter, &info);
773 	if (!client) {
774 		pr_err("%s: i2c_new_device() failed\n", __func__);
775 		i2c_put_adapter(adapter);
776 		return -EINVAL;
777 	}
778 
779 	return 0;
780 }
781 
782 static const struct drm_encoder_helper_funcs tc35876x_encoder_helper_funcs = {
783 	.dpms = mdfld_dsi_dpi_dpms,
784 	.mode_fixup = mdfld_dsi_dpi_mode_fixup,
785 	.prepare = mdfld_dsi_dpi_prepare,
786 	.mode_set = mdfld_dsi_dpi_mode_set,
787 	.commit = mdfld_dsi_dpi_commit,
788 };
789 
790 static const struct drm_encoder_funcs tc35876x_encoder_funcs = {
791 	.destroy = drm_encoder_cleanup,
792 };
793 
794 const struct panel_funcs mdfld_tc35876x_funcs = {
795 	.encoder_funcs = &tc35876x_encoder_funcs,
796 	.encoder_helper_funcs = &tc35876x_encoder_helper_funcs,
797 	.get_config_mode = tc35876x_get_config_mode,
798 	.get_panel_info = tc35876x_get_panel_info,
799 };
800 
tc35876x_init(struct drm_device * dev)801 void tc35876x_init(struct drm_device *dev)
802 {
803 	int r;
804 
805 	dev_dbg(&dev->pdev->dev, "%s\n", __func__);
806 
807 	cmi_lcd_hack_create_device();
808 
809 	r = i2c_add_driver(&cmi_lcd_i2c_driver);
810 	if (r < 0)
811 		dev_err(&dev->pdev->dev,
812 			"%s: i2c_add_driver() for %s failed (%d)\n",
813 			__func__, cmi_lcd_i2c_driver.driver.name, r);
814 
815 	r = i2c_add_driver(&tc35876x_bridge_i2c_driver);
816 	if (r < 0)
817 		dev_err(&dev->pdev->dev,
818 			"%s: i2c_add_driver() for %s failed (%d)\n",
819 			__func__, tc35876x_bridge_i2c_driver.driver.name, r);
820 
821 	tc35876x_brightness_init(dev);
822 }
823 
tc35876x_exit(void)824 void tc35876x_exit(void)
825 {
826 	pr_debug("%s\n", __func__);
827 
828 	i2c_del_driver(&tc35876x_bridge_i2c_driver);
829 
830 	if (cmi_lcd_i2c_client)
831 		i2c_del_driver(&cmi_lcd_i2c_driver);
832 }
833