[go: nahoru, domu]

1/*
2 * Copyright © 2006-2007 Intel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Authors:
18 *	Eric Anholt <eric@anholt.net>
19 */
20
21#include <linux/i2c.h>
22#include <linux/pm_runtime.h>
23
24#include <drm/drmP.h>
25#include "psb_intel_reg.h"
26#include "gma_display.h"
27#include "framebuffer.h"
28#include "mdfld_output.h"
29#include "mdfld_dsi_output.h"
30
31/* Hardcoded currently */
32static int ksel = KSEL_CRYSTAL_19;
33
34struct psb_intel_range_t {
35	int min, max;
36};
37
38struct mrst_limit_t {
39	struct psb_intel_range_t dot, m, p1;
40};
41
42struct mrst_clock_t {
43	/* derived values */
44	int dot;
45	int m;
46	int p1;
47};
48
49#define COUNT_MAX 0x10000000
50
51void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe)
52{
53	struct drm_psb_private *dev_priv = dev->dev_private;
54	const struct psb_offset *map = &dev_priv->regmap[pipe];
55	int count, temp;
56
57	switch (pipe) {
58	case 0:
59	case 1:
60	case 2:
61		break;
62	default:
63		DRM_ERROR("Illegal Pipe Number.\n");
64		return;
65	}
66
67	/* FIXME JLIU7_PO */
68	gma_wait_for_vblank(dev);
69	return;
70
71	/* Wait for for the pipe disable to take effect. */
72	for (count = 0; count < COUNT_MAX; count++) {
73		temp = REG_READ(map->conf);
74		if ((temp & PIPEACONF_PIPE_STATE) == 0)
75			break;
76	}
77}
78
79void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe)
80{
81	struct drm_psb_private *dev_priv = dev->dev_private;
82	const struct psb_offset *map = &dev_priv->regmap[pipe];
83	int count, temp;
84
85	switch (pipe) {
86	case 0:
87	case 1:
88	case 2:
89		break;
90	default:
91		DRM_ERROR("Illegal Pipe Number.\n");
92		return;
93	}
94
95	/* FIXME JLIU7_PO */
96	gma_wait_for_vblank(dev);
97	return;
98
99	/* Wait for for the pipe enable to take effect. */
100	for (count = 0; count < COUNT_MAX; count++) {
101		temp = REG_READ(map->conf);
102		if ((temp & PIPEACONF_PIPE_STATE) == 1)
103			break;
104	}
105}
106
107/**
108 * Return the pipe currently connected to the panel fitter,
109 * or -1 if the panel fitter is not present or not in use
110 */
111static int psb_intel_panel_fitter_pipe(struct drm_device *dev)
112{
113	u32 pfit_control;
114
115	pfit_control = REG_READ(PFIT_CONTROL);
116
117	/* See if the panel fitter is in use */
118	if ((pfit_control & PFIT_ENABLE) == 0)
119		return -1;
120
121	/* 965 can place panel fitter on either pipe */
122	return (pfit_control >> 29) & 0x3;
123}
124
125static struct drm_device globle_dev;
126
127void mdfld__intel_plane_set_alpha(int enable)
128{
129	struct drm_device *dev = &globle_dev;
130	int dspcntr_reg = DSPACNTR;
131	u32 dspcntr;
132
133	dspcntr = REG_READ(dspcntr_reg);
134
135	if (enable) {
136		dspcntr &= ~DISPPLANE_32BPP_NO_ALPHA;
137		dspcntr |= DISPPLANE_32BPP;
138	} else {
139		dspcntr &= ~DISPPLANE_32BPP;
140		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
141	}
142
143	REG_WRITE(dspcntr_reg, dspcntr);
144}
145
146static int check_fb(struct drm_framebuffer *fb)
147{
148	if (!fb)
149		return 0;
150
151	switch (fb->bits_per_pixel) {
152	case 8:
153	case 16:
154	case 24:
155	case 32:
156		return 0;
157	default:
158		DRM_ERROR("Unknown color depth\n");
159		return -EINVAL;
160	}
161}
162
163static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
164				struct drm_framebuffer *old_fb)
165{
166	struct drm_device *dev = crtc->dev;
167	struct drm_psb_private *dev_priv = dev->dev_private;
168	struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
169	struct psb_framebuffer *psbfb = to_psb_fb(crtc->primary->fb);
170	int pipe = gma_crtc->pipe;
171	const struct psb_offset *map = &dev_priv->regmap[pipe];
172	unsigned long start, offset;
173	u32 dspcntr;
174	int ret;
175
176	memcpy(&globle_dev, dev, sizeof(struct drm_device));
177
178	dev_dbg(dev->dev, "pipe = 0x%x.\n", pipe);
179
180	/* no fb bound */
181	if (!crtc->primary->fb) {
182		dev_dbg(dev->dev, "No FB bound\n");
183		return 0;
184	}
185
186	ret = check_fb(crtc->primary->fb);
187	if (ret)
188		return ret;
189
190	if (pipe > 2) {
191		DRM_ERROR("Illegal Pipe Number.\n");
192		return -EINVAL;
193	}
194
195	if (!gma_power_begin(dev, true))
196		return 0;
197
198	start = psbfb->gtt->offset;
199	offset = y * crtc->primary->fb->pitches[0] + x * (crtc->primary->fb->bits_per_pixel / 8);
200
201	REG_WRITE(map->stride, crtc->primary->fb->pitches[0]);
202	dspcntr = REG_READ(map->cntr);
203	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
204
205	switch (crtc->primary->fb->bits_per_pixel) {
206	case 8:
207		dspcntr |= DISPPLANE_8BPP;
208		break;
209	case 16:
210		if (crtc->primary->fb->depth == 15)
211			dspcntr |= DISPPLANE_15_16BPP;
212		else
213			dspcntr |= DISPPLANE_16BPP;
214		break;
215	case 24:
216	case 32:
217		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
218		break;
219	}
220	REG_WRITE(map->cntr, dspcntr);
221
222	dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n",
223						start, offset, x, y);
224	REG_WRITE(map->linoff, offset);
225	REG_READ(map->linoff);
226	REG_WRITE(map->surf, start);
227	REG_READ(map->surf);
228
229	gma_power_end(dev);
230
231	return 0;
232}
233
234/*
235 * Disable the pipe, plane and pll.
236 *
237 */
238void mdfld_disable_crtc(struct drm_device *dev, int pipe)
239{
240	struct drm_psb_private *dev_priv = dev->dev_private;
241	const struct psb_offset *map = &dev_priv->regmap[pipe];
242	u32 temp;
243
244	dev_dbg(dev->dev, "pipe = %d\n", pipe);
245
246
247	if (pipe != 1)
248		mdfld_dsi_gen_fifo_ready(dev, MIPI_GEN_FIFO_STAT_REG(pipe),
249				HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
250
251	/* Disable display plane */
252	temp = REG_READ(map->cntr);
253	if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
254		REG_WRITE(map->cntr,
255			  temp & ~DISPLAY_PLANE_ENABLE);
256		/* Flush the plane changes */
257		REG_WRITE(map->base, REG_READ(map->base));
258		REG_READ(map->base);
259	}
260
261	/* FIXME_JLIU7 MDFLD_PO revisit */
262
263	/* Next, disable display pipes */
264	temp = REG_READ(map->conf);
265	if ((temp & PIPEACONF_ENABLE) != 0) {
266		temp &= ~PIPEACONF_ENABLE;
267		temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
268		REG_WRITE(map->conf, temp);
269		REG_READ(map->conf);
270
271		/* Wait for for the pipe disable to take effect. */
272		mdfldWaitForPipeDisable(dev, pipe);
273	}
274
275	temp = REG_READ(map->dpll);
276	if (temp & DPLL_VCO_ENABLE) {
277		if ((pipe != 1 &&
278			!((REG_READ(PIPEACONF) | REG_READ(PIPECCONF))
279				& PIPEACONF_ENABLE)) || pipe == 1) {
280			temp &= ~(DPLL_VCO_ENABLE);
281			REG_WRITE(map->dpll, temp);
282			REG_READ(map->dpll);
283			/* Wait for the clocks to turn off. */
284			/* FIXME_MDFLD PO may need more delay */
285			udelay(500);
286
287			if (!(temp & MDFLD_PWR_GATE_EN)) {
288				/* gating power of DPLL */
289				REG_WRITE(map->dpll, temp | MDFLD_PWR_GATE_EN);
290				/* FIXME_MDFLD PO - change 500 to 1 after PO */
291				udelay(5000);
292			}
293		}
294	}
295
296}
297
298/**
299 * Sets the power management mode of the pipe and plane.
300 *
301 * This code should probably grow support for turning the cursor off and back
302 * on appropriately at the same time as we're turning the pipe off/on.
303 */
304static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode)
305{
306	struct drm_device *dev = crtc->dev;
307	struct drm_psb_private *dev_priv = dev->dev_private;
308	struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
309	int pipe = gma_crtc->pipe;
310	const struct psb_offset *map = &dev_priv->regmap[pipe];
311	u32 pipeconf = dev_priv->pipeconf[pipe];
312	u32 temp;
313	int timeout = 0;
314
315	dev_dbg(dev->dev, "mode = %d, pipe = %d\n", mode, pipe);
316
317	/* Note: Old code uses pipe a stat for pipe b but that appears
318	   to be a bug */
319
320	if (!gma_power_begin(dev, true))
321		return;
322
323	/* XXX: When our outputs are all unaware of DPMS modes other than off
324	 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
325	 */
326	switch (mode) {
327	case DRM_MODE_DPMS_ON:
328	case DRM_MODE_DPMS_STANDBY:
329	case DRM_MODE_DPMS_SUSPEND:
330		/* Enable the DPLL */
331		temp = REG_READ(map->dpll);
332
333		if ((temp & DPLL_VCO_ENABLE) == 0) {
334			/* When ungating power of DPLL, needs to wait 0.5us
335			   before enable the VCO */
336			if (temp & MDFLD_PWR_GATE_EN) {
337				temp &= ~MDFLD_PWR_GATE_EN;
338				REG_WRITE(map->dpll, temp);
339				/* FIXME_MDFLD PO - change 500 to 1 after PO */
340				udelay(500);
341			}
342
343			REG_WRITE(map->dpll, temp);
344			REG_READ(map->dpll);
345			/* FIXME_MDFLD PO - change 500 to 1 after PO */
346			udelay(500);
347
348			REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE);
349			REG_READ(map->dpll);
350
351			/**
352			 * wait for DSI PLL to lock
353			 * NOTE: only need to poll status of pipe 0 and pipe 1,
354			 * since both MIPI pipes share the same PLL.
355			 */
356			while ((pipe != 2) && (timeout < 20000) &&
357			  !(REG_READ(map->conf) & PIPECONF_DSIPLL_LOCK)) {
358				udelay(150);
359				timeout++;
360			}
361		}
362
363		/* Enable the plane */
364		temp = REG_READ(map->cntr);
365		if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
366			REG_WRITE(map->cntr,
367				temp | DISPLAY_PLANE_ENABLE);
368			/* Flush the plane changes */
369			REG_WRITE(map->base, REG_READ(map->base));
370		}
371
372		/* Enable the pipe */
373		temp = REG_READ(map->conf);
374		if ((temp & PIPEACONF_ENABLE) == 0) {
375			REG_WRITE(map->conf, pipeconf);
376
377			/* Wait for for the pipe enable to take effect. */
378			mdfldWaitForPipeEnable(dev, pipe);
379		}
380
381		/*workaround for sighting 3741701 Random X blank display*/
382		/*perform w/a in video mode only on pipe A or C*/
383		if (pipe == 0 || pipe == 2) {
384			REG_WRITE(map->status, REG_READ(map->status));
385			msleep(100);
386			if (PIPE_VBLANK_STATUS & REG_READ(map->status))
387				dev_dbg(dev->dev, "OK");
388			else {
389				dev_dbg(dev->dev, "STUCK!!!!");
390				/*shutdown controller*/
391				temp = REG_READ(map->cntr);
392				REG_WRITE(map->cntr,
393						temp & ~DISPLAY_PLANE_ENABLE);
394				REG_WRITE(map->base, REG_READ(map->base));
395				/*mdfld_dsi_dpi_shut_down(dev, pipe);*/
396				REG_WRITE(0xb048, 1);
397				msleep(100);
398				temp = REG_READ(map->conf);
399				temp &= ~PIPEACONF_ENABLE;
400				REG_WRITE(map->conf, temp);
401				msleep(100); /*wait for pipe disable*/
402				REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 0);
403				msleep(100);
404				REG_WRITE(0xb004, REG_READ(0xb004));
405				/* try to bring the controller back up again*/
406				REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 1);
407				temp = REG_READ(map->cntr);
408				REG_WRITE(map->cntr,
409						temp | DISPLAY_PLANE_ENABLE);
410				REG_WRITE(map->base, REG_READ(map->base));
411				/*mdfld_dsi_dpi_turn_on(dev, pipe);*/
412				REG_WRITE(0xb048, 2);
413				msleep(100);
414				temp = REG_READ(map->conf);
415				temp |= PIPEACONF_ENABLE;
416				REG_WRITE(map->conf, temp);
417			}
418		}
419
420		gma_crtc_load_lut(crtc);
421
422		/* Give the overlay scaler a chance to enable
423		   if it's on this pipe */
424		/* psb_intel_crtc_dpms_video(crtc, true); TODO */
425
426		break;
427	case DRM_MODE_DPMS_OFF:
428		/* Give the overlay scaler a chance to disable
429		 * if it's on this pipe */
430		/* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
431		if (pipe != 1)
432			mdfld_dsi_gen_fifo_ready(dev,
433				MIPI_GEN_FIFO_STAT_REG(pipe),
434				HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
435
436		/* Disable the VGA plane that we never use */
437		REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
438
439		/* Disable display plane */
440		temp = REG_READ(map->cntr);
441		if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
442			REG_WRITE(map->cntr,
443				  temp & ~DISPLAY_PLANE_ENABLE);
444			/* Flush the plane changes */
445			REG_WRITE(map->base, REG_READ(map->base));
446			REG_READ(map->base);
447		}
448
449		/* Next, disable display pipes */
450		temp = REG_READ(map->conf);
451		if ((temp & PIPEACONF_ENABLE) != 0) {
452			temp &= ~PIPEACONF_ENABLE;
453			temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
454			REG_WRITE(map->conf, temp);
455			REG_READ(map->conf);
456
457			/* Wait for for the pipe disable to take effect. */
458			mdfldWaitForPipeDisable(dev, pipe);
459		}
460
461		temp = REG_READ(map->dpll);
462		if (temp & DPLL_VCO_ENABLE) {
463			if ((pipe != 1 && !((REG_READ(PIPEACONF)
464				| REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
465					|| pipe == 1) {
466				temp &= ~(DPLL_VCO_ENABLE);
467				REG_WRITE(map->dpll, temp);
468				REG_READ(map->dpll);
469				/* Wait for the clocks to turn off. */
470				/* FIXME_MDFLD PO may need more delay */
471				udelay(500);
472			}
473		}
474		break;
475	}
476	gma_power_end(dev);
477}
478
479
480#define MDFLD_LIMT_DPLL_19	    0
481#define MDFLD_LIMT_DPLL_25	    1
482#define MDFLD_LIMT_DPLL_83	    2
483#define MDFLD_LIMT_DPLL_100	    3
484#define MDFLD_LIMT_DSIPLL_19	    4
485#define MDFLD_LIMT_DSIPLL_25	    5
486#define MDFLD_LIMT_DSIPLL_83	    6
487#define MDFLD_LIMT_DSIPLL_100	    7
488
489#define MDFLD_DOT_MIN		  19750
490#define MDFLD_DOT_MAX		  120000
491#define MDFLD_DPLL_M_MIN_19	    113
492#define MDFLD_DPLL_M_MAX_19	    155
493#define MDFLD_DPLL_P1_MIN_19	    2
494#define MDFLD_DPLL_P1_MAX_19	    10
495#define MDFLD_DPLL_M_MIN_25	    101
496#define MDFLD_DPLL_M_MAX_25	    130
497#define MDFLD_DPLL_P1_MIN_25	    2
498#define MDFLD_DPLL_P1_MAX_25	    10
499#define MDFLD_DPLL_M_MIN_83	    64
500#define MDFLD_DPLL_M_MAX_83	    64
501#define MDFLD_DPLL_P1_MIN_83	    2
502#define MDFLD_DPLL_P1_MAX_83	    2
503#define MDFLD_DPLL_M_MIN_100	    64
504#define MDFLD_DPLL_M_MAX_100	    64
505#define MDFLD_DPLL_P1_MIN_100	    2
506#define MDFLD_DPLL_P1_MAX_100	    2
507#define MDFLD_DSIPLL_M_MIN_19	    131
508#define MDFLD_DSIPLL_M_MAX_19	    175
509#define MDFLD_DSIPLL_P1_MIN_19	    3
510#define MDFLD_DSIPLL_P1_MAX_19	    8
511#define MDFLD_DSIPLL_M_MIN_25	    97
512#define MDFLD_DSIPLL_M_MAX_25	    140
513#define MDFLD_DSIPLL_P1_MIN_25	    3
514#define MDFLD_DSIPLL_P1_MAX_25	    9
515#define MDFLD_DSIPLL_M_MIN_83	    33
516#define MDFLD_DSIPLL_M_MAX_83	    92
517#define MDFLD_DSIPLL_P1_MIN_83	    2
518#define MDFLD_DSIPLL_P1_MAX_83	    3
519#define MDFLD_DSIPLL_M_MIN_100	    97
520#define MDFLD_DSIPLL_M_MAX_100	    140
521#define MDFLD_DSIPLL_P1_MIN_100	    3
522#define MDFLD_DSIPLL_P1_MAX_100	    9
523
524static const struct mrst_limit_t mdfld_limits[] = {
525	{			/* MDFLD_LIMT_DPLL_19 */
526	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
527	 .m = {.min = MDFLD_DPLL_M_MIN_19, .max = MDFLD_DPLL_M_MAX_19},
528	 .p1 = {.min = MDFLD_DPLL_P1_MIN_19, .max = MDFLD_DPLL_P1_MAX_19},
529	 },
530	{			/* MDFLD_LIMT_DPLL_25 */
531	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
532	 .m = {.min = MDFLD_DPLL_M_MIN_25, .max = MDFLD_DPLL_M_MAX_25},
533	 .p1 = {.min = MDFLD_DPLL_P1_MIN_25, .max = MDFLD_DPLL_P1_MAX_25},
534	 },
535	{			/* MDFLD_LIMT_DPLL_83 */
536	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
537	 .m = {.min = MDFLD_DPLL_M_MIN_83, .max = MDFLD_DPLL_M_MAX_83},
538	 .p1 = {.min = MDFLD_DPLL_P1_MIN_83, .max = MDFLD_DPLL_P1_MAX_83},
539	 },
540	{			/* MDFLD_LIMT_DPLL_100 */
541	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
542	 .m = {.min = MDFLD_DPLL_M_MIN_100, .max = MDFLD_DPLL_M_MAX_100},
543	 .p1 = {.min = MDFLD_DPLL_P1_MIN_100, .max = MDFLD_DPLL_P1_MAX_100},
544	 },
545	{			/* MDFLD_LIMT_DSIPLL_19 */
546	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
547	 .m = {.min = MDFLD_DSIPLL_M_MIN_19, .max = MDFLD_DSIPLL_M_MAX_19},
548	 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_19, .max = MDFLD_DSIPLL_P1_MAX_19},
549	 },
550	{			/* MDFLD_LIMT_DSIPLL_25 */
551	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
552	 .m = {.min = MDFLD_DSIPLL_M_MIN_25, .max = MDFLD_DSIPLL_M_MAX_25},
553	 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_25, .max = MDFLD_DSIPLL_P1_MAX_25},
554	 },
555	{			/* MDFLD_LIMT_DSIPLL_83 */
556	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
557	 .m = {.min = MDFLD_DSIPLL_M_MIN_83, .max = MDFLD_DSIPLL_M_MAX_83},
558	 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_83, .max = MDFLD_DSIPLL_P1_MAX_83},
559	 },
560	{			/* MDFLD_LIMT_DSIPLL_100 */
561	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
562	 .m = {.min = MDFLD_DSIPLL_M_MIN_100, .max = MDFLD_DSIPLL_M_MAX_100},
563	 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_100, .max = MDFLD_DSIPLL_P1_MAX_100},
564	 },
565};
566
567#define MDFLD_M_MIN	    21
568#define MDFLD_M_MAX	    180
569static const u32 mdfld_m_converts[] = {
570/* M configuration table from 9-bit LFSR table */
571	224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */
572	173, 342, 171, 85, 298, 149, 74, 37, 18, 265,   /* 31 - 40 */
573	388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */
574	83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */
575	341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */
576	461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */
577	106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */
578	71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */
579	253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */
580	478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */
581	477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */
582	210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */
583	145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */
584	380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */
585	103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */
586	396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */
587};
588
589static const struct mrst_limit_t *mdfld_limit(struct drm_crtc *crtc)
590{
591	const struct mrst_limit_t *limit = NULL;
592	struct drm_device *dev = crtc->dev;
593	struct drm_psb_private *dev_priv = dev->dev_private;
594
595	if (gma_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)
596	    || gma_pipe_has_type(crtc, INTEL_OUTPUT_MIPI2)) {
597		if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
598			limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_19];
599		else if (ksel == KSEL_BYPASS_25)
600			limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_25];
601		else if ((ksel == KSEL_BYPASS_83_100) &&
602				(dev_priv->core_freq == 166))
603			limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_83];
604		else if ((ksel == KSEL_BYPASS_83_100) &&
605			 (dev_priv->core_freq == 100 ||
606				dev_priv->core_freq == 200))
607			limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_100];
608	} else if (gma_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
609		if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
610			limit = &mdfld_limits[MDFLD_LIMT_DPLL_19];
611		else if (ksel == KSEL_BYPASS_25)
612			limit = &mdfld_limits[MDFLD_LIMT_DPLL_25];
613		else if ((ksel == KSEL_BYPASS_83_100) &&
614				(dev_priv->core_freq == 166))
615			limit = &mdfld_limits[MDFLD_LIMT_DPLL_83];
616		else if ((ksel == KSEL_BYPASS_83_100) &&
617				 (dev_priv->core_freq == 100 ||
618				 dev_priv->core_freq == 200))
619			limit = &mdfld_limits[MDFLD_LIMT_DPLL_100];
620	} else {
621		limit = NULL;
622		dev_dbg(dev->dev, "mdfld_limit Wrong display type.\n");
623	}
624
625	return limit;
626}
627
628/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
629static void mdfld_clock(int refclk, struct mrst_clock_t *clock)
630{
631	clock->dot = (refclk * clock->m) / clock->p1;
632}
633
634/**
635 * Returns a set of divisors for the desired target clock with the given refclk,
636 * or FALSE.  Divisor values are the actual divisors for
637 */
638static bool
639mdfldFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
640		struct mrst_clock_t *best_clock)
641{
642	struct mrst_clock_t clock;
643	const struct mrst_limit_t *limit = mdfld_limit(crtc);
644	int err = target;
645
646	memset(best_clock, 0, sizeof(*best_clock));
647
648	for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
649		for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
650		     clock.p1++) {
651			int this_err;
652
653			mdfld_clock(refclk, &clock);
654
655			this_err = abs(clock.dot - target);
656			if (this_err < err) {
657				*best_clock = clock;
658				err = this_err;
659			}
660		}
661	}
662	return err != target;
663}
664
665static int mdfld_crtc_mode_set(struct drm_crtc *crtc,
666			      struct drm_display_mode *mode,
667			      struct drm_display_mode *adjusted_mode,
668			      int x, int y,
669			      struct drm_framebuffer *old_fb)
670{
671	struct drm_device *dev = crtc->dev;
672	struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
673	struct drm_psb_private *dev_priv = dev->dev_private;
674	int pipe = gma_crtc->pipe;
675	const struct psb_offset *map = &dev_priv->regmap[pipe];
676	int refclk = 0;
677	int clk_n = 0, clk_p2 = 0, clk_byte = 1, clk = 0, m_conv = 0,
678								clk_tmp = 0;
679	struct mrst_clock_t clock;
680	bool ok;
681	u32 dpll = 0, fp = 0;
682	bool is_mipi = false, is_mipi2 = false, is_hdmi = false;
683	struct drm_mode_config *mode_config = &dev->mode_config;
684	struct gma_encoder *gma_encoder = NULL;
685	uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
686	struct drm_encoder *encoder;
687	struct drm_connector *connector;
688	int timeout = 0;
689	int ret;
690
691	dev_dbg(dev->dev, "pipe = 0x%x\n", pipe);
692
693#if 0
694	if (pipe == 1) {
695		if (!gma_power_begin(dev, true))
696			return 0;
697		android_hdmi_crtc_mode_set(crtc, mode, adjusted_mode,
698			x, y, old_fb);
699		goto mrst_crtc_mode_set_exit;
700	}
701#endif
702
703	ret = check_fb(crtc->primary->fb);
704	if (ret)
705		return ret;
706
707	dev_dbg(dev->dev, "adjusted_hdisplay = %d\n",
708		 adjusted_mode->hdisplay);
709	dev_dbg(dev->dev, "adjusted_vdisplay = %d\n",
710		 adjusted_mode->vdisplay);
711	dev_dbg(dev->dev, "adjusted_hsync_start = %d\n",
712		 adjusted_mode->hsync_start);
713	dev_dbg(dev->dev, "adjusted_hsync_end = %d\n",
714		 adjusted_mode->hsync_end);
715	dev_dbg(dev->dev, "adjusted_htotal = %d\n",
716		 adjusted_mode->htotal);
717	dev_dbg(dev->dev, "adjusted_vsync_start = %d\n",
718		 adjusted_mode->vsync_start);
719	dev_dbg(dev->dev, "adjusted_vsync_end = %d\n",
720		 adjusted_mode->vsync_end);
721	dev_dbg(dev->dev, "adjusted_vtotal = %d\n",
722		 adjusted_mode->vtotal);
723	dev_dbg(dev->dev, "adjusted_clock = %d\n",
724		 adjusted_mode->clock);
725	dev_dbg(dev->dev, "hdisplay = %d\n",
726		 mode->hdisplay);
727	dev_dbg(dev->dev, "vdisplay = %d\n",
728		 mode->vdisplay);
729
730	if (!gma_power_begin(dev, true))
731		return 0;
732
733	memcpy(&gma_crtc->saved_mode, mode,
734					sizeof(struct drm_display_mode));
735	memcpy(&gma_crtc->saved_adjusted_mode, adjusted_mode,
736					sizeof(struct drm_display_mode));
737
738	list_for_each_entry(connector, &mode_config->connector_list, head) {
739		if (!connector)
740			continue;
741
742		encoder = connector->encoder;
743
744		if (!encoder)
745			continue;
746
747		if (encoder->crtc != crtc)
748			continue;
749
750		gma_encoder = gma_attached_encoder(connector);
751
752		switch (gma_encoder->type) {
753		case INTEL_OUTPUT_MIPI:
754			is_mipi = true;
755			break;
756		case INTEL_OUTPUT_MIPI2:
757			is_mipi2 = true;
758			break;
759		case INTEL_OUTPUT_HDMI:
760			is_hdmi = true;
761			break;
762		}
763	}
764
765	/* Disable the VGA plane that we never use */
766	REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
767
768	/* Disable the panel fitter if it was on our pipe */
769	if (psb_intel_panel_fitter_pipe(dev) == pipe)
770		REG_WRITE(PFIT_CONTROL, 0);
771
772	/* pipesrc and dspsize control the size that is scaled from,
773	 * which should always be the user's requested size.
774	 */
775	if (pipe == 1) {
776		/* FIXME: To make HDMI display with 864x480 (TPO), 480x864
777		 * (PYR) or 480x854 (TMD), set the sprite width/height and
778		 * souce image size registers with the adjusted mode for
779		 * pipe B.
780		 */
781
782		/*
783		 * The defined sprite rectangle must always be completely
784		 * contained within the displayable area of the screen image
785		 * (frame buffer).
786		 */
787		REG_WRITE(map->size, ((min(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16)
788				| (min(mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay) - 1));
789		/* Set the CRTC with encoder mode. */
790		REG_WRITE(map->src, ((mode->crtc_hdisplay - 1) << 16)
791				 | (mode->crtc_vdisplay - 1));
792	} else {
793		REG_WRITE(map->size,
794				((mode->crtc_vdisplay - 1) << 16) |
795						(mode->crtc_hdisplay - 1));
796		REG_WRITE(map->src,
797				((mode->crtc_hdisplay - 1) << 16) |
798						(mode->crtc_vdisplay - 1));
799	}
800
801	REG_WRITE(map->pos, 0);
802
803	if (gma_encoder)
804		drm_object_property_get_value(&connector->base,
805			dev->mode_config.scaling_mode_property, &scalingType);
806
807	if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
808		/* Medfield doesn't have register support for centering so we
809		 * need to mess with the h/vblank and h/vsync start and ends
810		 * to get centering
811		 */
812		int offsetX = 0, offsetY = 0;
813
814		offsetX = (adjusted_mode->crtc_hdisplay -
815					mode->crtc_hdisplay) / 2;
816		offsetY = (adjusted_mode->crtc_vdisplay -
817					mode->crtc_vdisplay) / 2;
818
819		REG_WRITE(map->htotal, (mode->crtc_hdisplay - 1) |
820			((adjusted_mode->crtc_htotal - 1) << 16));
821		REG_WRITE(map->vtotal, (mode->crtc_vdisplay - 1) |
822			((adjusted_mode->crtc_vtotal - 1) << 16));
823		REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start -
824								offsetX - 1) |
825			((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
826		REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start -
827								offsetX - 1) |
828			((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
829		REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start -
830								offsetY - 1) |
831			((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
832		REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start -
833								offsetY - 1) |
834			((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
835	} else {
836		REG_WRITE(map->htotal, (adjusted_mode->crtc_hdisplay - 1) |
837			((adjusted_mode->crtc_htotal - 1) << 16));
838		REG_WRITE(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) |
839			((adjusted_mode->crtc_vtotal - 1) << 16));
840		REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start - 1) |
841			((adjusted_mode->crtc_hblank_end - 1) << 16));
842		REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start - 1) |
843			((adjusted_mode->crtc_hsync_end - 1) << 16));
844		REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start - 1) |
845			((adjusted_mode->crtc_vblank_end - 1) << 16));
846		REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start - 1) |
847			((adjusted_mode->crtc_vsync_end - 1) << 16));
848	}
849
850	/* Flush the plane changes */
851	{
852		struct drm_crtc_helper_funcs *crtc_funcs =
853		    crtc->helper_private;
854		crtc_funcs->mode_set_base(crtc, x, y, old_fb);
855	}
856
857	/* setup pipeconf */
858	dev_priv->pipeconf[pipe] = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */
859
860	/* Set up the display plane register */
861	dev_priv->dspcntr[pipe] = REG_READ(map->cntr);
862	dev_priv->dspcntr[pipe] |= pipe << DISPPLANE_SEL_PIPE_POS;
863	dev_priv->dspcntr[pipe] |= DISPLAY_PLANE_ENABLE;
864
865	if (is_mipi2)
866		goto mrst_crtc_mode_set_exit;
867	clk = adjusted_mode->clock;
868
869	if (is_hdmi) {
870		if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) {
871			refclk = 19200;
872
873			if (is_mipi || is_mipi2)
874				clk_n = 1, clk_p2 = 8;
875			else if (is_hdmi)
876				clk_n = 1, clk_p2 = 10;
877		} else if (ksel == KSEL_BYPASS_25) {
878			refclk = 25000;
879
880			if (is_mipi || is_mipi2)
881				clk_n = 1, clk_p2 = 8;
882			else if (is_hdmi)
883				clk_n = 1, clk_p2 = 10;
884		} else if ((ksel == KSEL_BYPASS_83_100) &&
885					dev_priv->core_freq == 166) {
886			refclk = 83000;
887
888			if (is_mipi || is_mipi2)
889				clk_n = 4, clk_p2 = 8;
890			else if (is_hdmi)
891				clk_n = 4, clk_p2 = 10;
892		} else if ((ksel == KSEL_BYPASS_83_100) &&
893					(dev_priv->core_freq == 100 ||
894					dev_priv->core_freq == 200)) {
895			refclk = 100000;
896			if (is_mipi || is_mipi2)
897				clk_n = 4, clk_p2 = 8;
898			else if (is_hdmi)
899				clk_n = 4, clk_p2 = 10;
900		}
901
902		if (is_mipi)
903			clk_byte = dev_priv->bpp / 8;
904		else if (is_mipi2)
905			clk_byte = dev_priv->bpp2 / 8;
906
907		clk_tmp = clk * clk_n * clk_p2 * clk_byte;
908
909		dev_dbg(dev->dev, "clk = %d, clk_n = %d, clk_p2 = %d.\n",
910					clk, clk_n, clk_p2);
911		dev_dbg(dev->dev, "adjusted_mode->clock = %d, clk_tmp = %d.\n",
912					adjusted_mode->clock, clk_tmp);
913
914		ok = mdfldFindBestPLL(crtc, clk_tmp, refclk, &clock);
915
916		if (!ok) {
917			DRM_ERROR
918			    ("mdfldFindBestPLL fail in mdfld_crtc_mode_set.\n");
919		} else {
920			m_conv = mdfld_m_converts[(clock.m - MDFLD_M_MIN)];
921
922			dev_dbg(dev->dev, "dot clock = %d,"
923				 "m = %d, p1 = %d, m_conv = %d.\n",
924					clock.dot, clock.m,
925					clock.p1, m_conv);
926		}
927
928		dpll = REG_READ(map->dpll);
929
930		if (dpll & DPLL_VCO_ENABLE) {
931			dpll &= ~DPLL_VCO_ENABLE;
932			REG_WRITE(map->dpll, dpll);
933			REG_READ(map->dpll);
934
935			/* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */
936			/* FIXME_MDFLD PO - change 500 to 1 after PO */
937			udelay(500);
938
939			/* reset M1, N1 & P1 */
940			REG_WRITE(map->fp0, 0);
941			dpll &= ~MDFLD_P1_MASK;
942			REG_WRITE(map->dpll, dpll);
943			/* FIXME_MDFLD PO - change 500 to 1 after PO */
944			udelay(500);
945		}
946
947		/* When ungating power of DPLL, needs to wait 0.5us before
948		 * enable the VCO */
949		if (dpll & MDFLD_PWR_GATE_EN) {
950			dpll &= ~MDFLD_PWR_GATE_EN;
951			REG_WRITE(map->dpll, dpll);
952			/* FIXME_MDFLD PO - change 500 to 1 after PO */
953			udelay(500);
954		}
955		dpll = 0;
956
957#if 0 /* FIXME revisit later */
958		if (ksel == KSEL_CRYSTAL_19 || ksel == KSEL_BYPASS_19 ||
959						ksel == KSEL_BYPASS_25)
960			dpll &= ~MDFLD_INPUT_REF_SEL;
961		else if (ksel == KSEL_BYPASS_83_100)
962			dpll |= MDFLD_INPUT_REF_SEL;
963#endif /* FIXME revisit later */
964
965		if (is_hdmi)
966			dpll |= MDFLD_VCO_SEL;
967
968		fp = (clk_n / 2) << 16;
969		fp |= m_conv;
970
971		/* compute bitmask from p1 value */
972		dpll |= (1 << (clock.p1 - 2)) << 17;
973
974#if 0 /* 1080p30 & 720p */
975		dpll = 0x00050000;
976		fp = 0x000001be;
977#endif
978#if 0 /* 480p */
979		dpll = 0x02010000;
980		fp = 0x000000d2;
981#endif
982	} else {
983#if 0 /*DBI_TPO_480x864*/
984		dpll = 0x00020000;
985		fp = 0x00000156;
986#endif /* DBI_TPO_480x864 */ /* get from spec. */
987
988		dpll = 0x00800000;
989		fp = 0x000000c1;
990	}
991
992	REG_WRITE(map->fp0, fp);
993	REG_WRITE(map->dpll, dpll);
994	/* FIXME_MDFLD PO - change 500 to 1 after PO */
995	udelay(500);
996
997	dpll |= DPLL_VCO_ENABLE;
998	REG_WRITE(map->dpll, dpll);
999	REG_READ(map->dpll);
1000
1001	/* wait for DSI PLL to lock */
1002	while (timeout < 20000 &&
1003			!(REG_READ(map->conf) & PIPECONF_DSIPLL_LOCK)) {
1004		udelay(150);
1005		timeout++;
1006	}
1007
1008	if (is_mipi)
1009		goto mrst_crtc_mode_set_exit;
1010
1011	dev_dbg(dev->dev, "is_mipi = 0x%x\n", is_mipi);
1012
1013	REG_WRITE(map->conf, dev_priv->pipeconf[pipe]);
1014	REG_READ(map->conf);
1015
1016	/* Wait for for the pipe enable to take effect. */
1017	REG_WRITE(map->cntr, dev_priv->dspcntr[pipe]);
1018	gma_wait_for_vblank(dev);
1019
1020mrst_crtc_mode_set_exit:
1021
1022	gma_power_end(dev);
1023
1024	return 0;
1025}
1026
1027const struct drm_crtc_helper_funcs mdfld_helper_funcs = {
1028	.dpms = mdfld_crtc_dpms,
1029	.mode_fixup = gma_crtc_mode_fixup,
1030	.mode_set = mdfld_crtc_mode_set,
1031	.mode_set_base = mdfld__intel_pipe_set_base,
1032	.prepare = gma_crtc_prepare,
1033	.commit = gma_crtc_commit,
1034};
1035
1036