Linux Audio

Check our new training course

Loading...
v4.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 *	Li Peng <peng.li@intel.com>
 25 */
 26
 27#include <drm/drmP.h>
 
 28#include <drm/drm.h>
 
 
 29#include "psb_intel_drv.h"
 30#include "psb_intel_reg.h"
 31#include "psb_drv.h"
 32
 33#define HDMI_READ(reg)		readl(hdmi_dev->regs + (reg))
 34#define HDMI_WRITE(reg, val)	writel(val, hdmi_dev->regs + (reg))
 35
 36#define HDMI_HCR	0x1000
 37#define HCR_ENABLE_HDCP		(1 << 5)
 38#define HCR_ENABLE_AUDIO	(1 << 2)
 39#define HCR_ENABLE_PIXEL	(1 << 1)
 40#define HCR_ENABLE_TMDS		(1 << 0)
 41
 42#define HDMI_HICR	0x1004
 43#define HDMI_HSR	0x1008
 44#define HDMI_HISR	0x100C
 45#define HDMI_DETECT_HDP		(1 << 0)
 46
 47#define HDMI_VIDEO_REG	0x3000
 48#define HDMI_UNIT_EN		(1 << 7)
 49#define HDMI_MODE_OUTPUT	(1 << 0)
 50#define HDMI_HBLANK_A	0x3100
 51
 52#define HDMI_AUDIO_CTRL	0x4000
 53#define HDMI_ENABLE_AUDIO	(1 << 0)
 54
 55#define PCH_HTOTAL_B	0x3100
 56#define PCH_HBLANK_B	0x3104
 57#define PCH_HSYNC_B	0x3108
 58#define PCH_VTOTAL_B	0x310C
 59#define PCH_VBLANK_B	0x3110
 60#define PCH_VSYNC_B	0x3114
 61#define PCH_PIPEBSRC	0x311C
 62
 63#define PCH_PIPEB_DSL	0x3800
 64#define PCH_PIPEB_SLC	0x3804
 65#define PCH_PIPEBCONF	0x3808
 66#define PCH_PIPEBSTAT	0x3824
 67
 68#define CDVO_DFT	0x5000
 69#define CDVO_SLEWRATE	0x5004
 70#define CDVO_STRENGTH	0x5008
 71#define CDVO_RCOMP	0x500C
 72
 73#define DPLL_CTRL       0x6000
 74#define DPLL_PDIV_SHIFT		16
 75#define DPLL_PDIV_MASK		(0xf << 16)
 76#define DPLL_PWRDN		(1 << 4)
 77#define DPLL_RESET		(1 << 3)
 78#define DPLL_FASTEN		(1 << 2)
 79#define DPLL_ENSTAT		(1 << 1)
 80#define DPLL_DITHEN		(1 << 0)
 81
 82#define DPLL_DIV_CTRL   0x6004
 83#define DPLL_CLKF_MASK		0xffffffc0
 84#define DPLL_CLKR_MASK		(0x3f)
 85
 86#define DPLL_CLK_ENABLE 0x6008
 87#define DPLL_EN_DISP		(1 << 31)
 88#define DPLL_SEL_HDMI		(1 << 8)
 89#define DPLL_EN_HDMI		(1 << 1)
 90#define DPLL_EN_VGA		(1 << 0)
 91
 92#define DPLL_ADJUST     0x600C
 93#define DPLL_STATUS     0x6010
 94#define DPLL_UPDATE     0x6014
 95#define DPLL_DFT        0x6020
 96
 97struct intel_range {
 98	int	min, max;
 99};
100
101struct oaktrail_hdmi_limit {
102	struct intel_range vco, np, nr, nf;
103};
104
105struct oaktrail_hdmi_clock {
106	int np;
107	int nr;
108	int nf;
109	int dot;
110};
111
112#define VCO_MIN		320000
113#define VCO_MAX		1650000
114#define	NP_MIN		1
115#define	NP_MAX		15
116#define	NR_MIN		1
117#define	NR_MAX		64
118#define NF_MIN		2
119#define NF_MAX		4095
120
121static const struct oaktrail_hdmi_limit oaktrail_hdmi_limit = {
122	.vco = { .min = VCO_MIN,		.max = VCO_MAX },
123	.np  = { .min = NP_MIN,			.max = NP_MAX  },
124	.nr  = { .min = NR_MIN,			.max = NR_MAX  },
125	.nf  = { .min = NF_MIN,			.max = NF_MAX  },
126};
127
128static void oaktrail_hdmi_audio_enable(struct drm_device *dev)
129{
130	struct drm_psb_private *dev_priv = dev->dev_private;
131	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
132
133	HDMI_WRITE(HDMI_HCR, 0x67);
134	HDMI_READ(HDMI_HCR);
135
136	HDMI_WRITE(0x51a8, 0x10);
137	HDMI_READ(0x51a8);
138
139	HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1);
140	HDMI_READ(HDMI_AUDIO_CTRL);
141}
142
143static void oaktrail_hdmi_audio_disable(struct drm_device *dev)
144{
145	struct drm_psb_private *dev_priv = dev->dev_private;
146	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
147
148	HDMI_WRITE(0x51a8, 0x0);
149	HDMI_READ(0x51a8);
150
151	HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0);
152	HDMI_READ(HDMI_AUDIO_CTRL);
153
154	HDMI_WRITE(HDMI_HCR, 0x47);
155	HDMI_READ(HDMI_HCR);
156}
157
158static unsigned int htotal_calculate(struct drm_display_mode *mode)
159{
160	u32 htotal, new_crtc_htotal;
161
162	htotal = (mode->crtc_hdisplay - 1) | ((mode->crtc_htotal - 1) << 16);
163
164	/*
165	 * 1024 x 768  new_crtc_htotal = 0x1024;
166	 * 1280 x 1024 new_crtc_htotal = 0x0c34;
167	 */
168	new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock;
169
170	DRM_DEBUG_KMS("new crtc htotal 0x%4x\n", new_crtc_htotal);
171	return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16);
172}
173
174static void oaktrail_hdmi_find_dpll(struct drm_crtc *crtc, int target,
175				int refclk, struct oaktrail_hdmi_clock *best_clock)
176{
177	int np_min, np_max, nr_min, nr_max;
178	int np, nr, nf;
179
180	np_min = DIV_ROUND_UP(oaktrail_hdmi_limit.vco.min, target * 10);
181	np_max = oaktrail_hdmi_limit.vco.max / (target * 10);
182	if (np_min < oaktrail_hdmi_limit.np.min)
183		np_min = oaktrail_hdmi_limit.np.min;
184	if (np_max > oaktrail_hdmi_limit.np.max)
185		np_max = oaktrail_hdmi_limit.np.max;
186
187	nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max));
188	nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min));
189	if (nr_min < oaktrail_hdmi_limit.nr.min)
190		nr_min = oaktrail_hdmi_limit.nr.min;
191	if (nr_max > oaktrail_hdmi_limit.nr.max)
192		nr_max = oaktrail_hdmi_limit.nr.max;
193
194	np = DIV_ROUND_UP((refclk * 1000), (target * 10 * nr_max));
195	nr = DIV_ROUND_UP((refclk * 1000), (target * 10 * np));
196	nf = DIV_ROUND_CLOSEST((target * 10 * np * nr), refclk);
197	DRM_DEBUG_KMS("np, nr, nf %d %d %d\n", np, nr, nf);
198
199	/*
200	 * 1024 x 768  np = 1; nr = 0x26; nf = 0x0fd8000;
201	 * 1280 x 1024 np = 1; nr = 0x17; nf = 0x1034000;
202	 */
203	best_clock->np = np;
204	best_clock->nr = nr - 1;
205	best_clock->nf = (nf << 14);
206}
207
208static void scu_busy_loop(void __iomem *scu_base)
209{
210	u32 status = 0;
211	u32 loop_count = 0;
212
213	status = readl(scu_base + 0x04);
214	while (status & 1) {
215		udelay(1); /* scu processing time is in few u secods */
216		status = readl(scu_base + 0x04);
217		loop_count++;
218		/* break if scu doesn't reset busy bit after huge retry */
219		if (loop_count > 1000) {
220			DRM_DEBUG_KMS("SCU IPC timed out");
221			return;
222		}
223	}
224}
225
226/*
227 *	You don't want to know, you really really don't want to know....
228 *
229 *	This is magic. However it's safe magic because of the way the platform
230 *	works and it is necessary magic.
231 */
232static void oaktrail_hdmi_reset(struct drm_device *dev)
233{
234	void __iomem *base;
235	unsigned long scu_ipc_mmio = 0xff11c000UL;
236	int scu_len = 1024;
237
238	base = ioremap((resource_size_t)scu_ipc_mmio, scu_len);
239	if (base == NULL) {
240		DRM_ERROR("failed to map scu mmio\n");
241		return;
242	}
243
244	/* scu ipc: assert hdmi controller reset */
245	writel(0xff11d118, base + 0x0c);
246	writel(0x7fffffdf, base + 0x80);
247	writel(0x42005, base + 0x0);
248	scu_busy_loop(base);
249
250	/* scu ipc: de-assert hdmi controller reset */
251	writel(0xff11d118, base + 0x0c);
252	writel(0x7fffffff, base + 0x80);
253	writel(0x42005, base + 0x0);
254	scu_busy_loop(base);
255
256	iounmap(base);
257}
258
259int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc,
260			    struct drm_display_mode *mode,
261			    struct drm_display_mode *adjusted_mode,
262			    int x, int y,
263			    struct drm_framebuffer *old_fb)
264{
265	struct drm_device *dev = crtc->dev;
266	struct drm_psb_private *dev_priv = dev->dev_private;
267	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
268	int pipe = 1;
269	int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
270	int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
271	int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
272	int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
273	int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
274	int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
275	int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
276	int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
277	int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
278	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
279	int refclk;
280	struct oaktrail_hdmi_clock clock;
281	u32 dspcntr, pipeconf, dpll, temp;
282	int dspcntr_reg = DSPBCNTR;
283
284	if (!gma_power_begin(dev, true))
285		return 0;
286
287	/* Disable the VGA plane that we never use */
288	REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
289
290	/* Disable dpll if necessary */
291	dpll = REG_READ(DPLL_CTRL);
292	if ((dpll & DPLL_PWRDN) == 0) {
293		REG_WRITE(DPLL_CTRL, dpll | (DPLL_PWRDN | DPLL_RESET));
294		REG_WRITE(DPLL_DIV_CTRL, 0x00000000);
295		REG_WRITE(DPLL_STATUS, 0x1);
296	}
297	udelay(150);
298
299	/* Reset controller */
300	oaktrail_hdmi_reset(dev);
301
302	/* program and enable dpll */
303	refclk = 25000;
304	oaktrail_hdmi_find_dpll(crtc, adjusted_mode->clock, refclk, &clock);
305
306	/* Set the DPLL */
307	dpll = REG_READ(DPLL_CTRL);
308	dpll &= ~DPLL_PDIV_MASK;
309	dpll &= ~(DPLL_PWRDN | DPLL_RESET);
310	REG_WRITE(DPLL_CTRL, 0x00000008);
311	REG_WRITE(DPLL_DIV_CTRL, ((clock.nf << 6) | clock.nr));
312	REG_WRITE(DPLL_ADJUST, ((clock.nf >> 14) - 1));
313	REG_WRITE(DPLL_CTRL, (dpll | (clock.np << DPLL_PDIV_SHIFT) | DPLL_ENSTAT | DPLL_DITHEN));
314	REG_WRITE(DPLL_UPDATE, 0x80000000);
315	REG_WRITE(DPLL_CLK_ENABLE, 0x80050102);
316	udelay(150);
317
318	/* configure HDMI */
319	HDMI_WRITE(0x1004, 0x1fd);
320	HDMI_WRITE(0x2000, 0x1);
321	HDMI_WRITE(0x2008, 0x0);
322	HDMI_WRITE(0x3130, 0x8);
323	HDMI_WRITE(0x101c, 0x1800810);
324
325	temp = htotal_calculate(adjusted_mode);
326	REG_WRITE(htot_reg, temp);
327	REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
328	REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
329	REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
330	REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
331	REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
332	REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
333
334	REG_WRITE(PCH_HTOTAL_B, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16));
335	REG_WRITE(PCH_HBLANK_B, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
336	REG_WRITE(PCH_HSYNC_B, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
337	REG_WRITE(PCH_VTOTAL_B, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
338	REG_WRITE(PCH_VBLANK_B, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
339	REG_WRITE(PCH_VSYNC_B, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
340	REG_WRITE(PCH_PIPEBSRC, ((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
341
342	temp = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
343	HDMI_WRITE(HDMI_HBLANK_A, ((adjusted_mode->crtc_hdisplay - 1) << 16) |  temp);
344
345	REG_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
346	REG_WRITE(dsppos_reg, 0);
347
348	/* Flush the plane changes */
349	{
350		const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
351		crtc_funcs->mode_set_base(crtc, x, y, old_fb);
352	}
353
354	/* Set up the display plane register */
355	dspcntr = REG_READ(dspcntr_reg);
356	dspcntr |= DISPPLANE_GAMMA_ENABLE;
357	dspcntr |= DISPPLANE_SEL_PIPE_B;
358	dspcntr |= DISPLAY_PLANE_ENABLE;
359
360	/* setup pipeconf */
361	pipeconf = REG_READ(pipeconf_reg);
362	pipeconf |= PIPEACONF_ENABLE;
363
364	REG_WRITE(pipeconf_reg, pipeconf);
365	REG_READ(pipeconf_reg);
366
367	REG_WRITE(PCH_PIPEBCONF, pipeconf);
368	REG_READ(PCH_PIPEBCONF);
369	gma_wait_for_vblank(dev);
370
371	REG_WRITE(dspcntr_reg, dspcntr);
372	gma_wait_for_vblank(dev);
373
374	gma_power_end(dev);
375
376	return 0;
377}
378
379void oaktrail_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode)
380{
381	struct drm_device *dev = crtc->dev;
382	u32 temp;
383
384	DRM_DEBUG_KMS("%s %d\n", __func__, mode);
385
386	switch (mode) {
387	case DRM_MODE_DPMS_OFF:
388		REG_WRITE(VGACNTRL, 0x80000000);
389
390		/* Disable plane */
391		temp = REG_READ(DSPBCNTR);
392		if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
393			REG_WRITE(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
394			REG_READ(DSPBCNTR);
395			/* Flush the plane changes */
396			REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
397			REG_READ(DSPBSURF);
398		}
399
400		/* Disable pipe B */
401		temp = REG_READ(PIPEBCONF);
402		if ((temp & PIPEACONF_ENABLE) != 0) {
403			REG_WRITE(PIPEBCONF, temp & ~PIPEACONF_ENABLE);
404			REG_READ(PIPEBCONF);
405		}
406
407		/* Disable LNW Pipes, etc */
408		temp = REG_READ(PCH_PIPEBCONF);
409		if ((temp & PIPEACONF_ENABLE) != 0) {
410			REG_WRITE(PCH_PIPEBCONF, temp & ~PIPEACONF_ENABLE);
411			REG_READ(PCH_PIPEBCONF);
412		}
413
414		/* wait for pipe off */
415		udelay(150);
416
417		/* Disable dpll */
418		temp = REG_READ(DPLL_CTRL);
419		if ((temp & DPLL_PWRDN) == 0) {
420			REG_WRITE(DPLL_CTRL, temp | (DPLL_PWRDN | DPLL_RESET));
421			REG_WRITE(DPLL_STATUS, 0x1);
422		}
423
424		/* wait for dpll off */
425		udelay(150);
426
427		break;
428	case DRM_MODE_DPMS_ON:
429	case DRM_MODE_DPMS_STANDBY:
430	case DRM_MODE_DPMS_SUSPEND:
431		/* Enable dpll */
432		temp = REG_READ(DPLL_CTRL);
433		if ((temp & DPLL_PWRDN) != 0) {
434			REG_WRITE(DPLL_CTRL, temp & ~(DPLL_PWRDN | DPLL_RESET));
435			temp = REG_READ(DPLL_CLK_ENABLE);
436			REG_WRITE(DPLL_CLK_ENABLE, temp | DPLL_EN_DISP | DPLL_SEL_HDMI | DPLL_EN_HDMI);
437			REG_READ(DPLL_CLK_ENABLE);
438		}
439		/* wait for dpll warm up */
440		udelay(150);
441
442		/* Enable pipe B */
443		temp = REG_READ(PIPEBCONF);
444		if ((temp & PIPEACONF_ENABLE) == 0) {
445			REG_WRITE(PIPEBCONF, temp | PIPEACONF_ENABLE);
446			REG_READ(PIPEBCONF);
447		}
448
449		/* Enable LNW Pipe B */
450		temp = REG_READ(PCH_PIPEBCONF);
451		if ((temp & PIPEACONF_ENABLE) == 0) {
452			REG_WRITE(PCH_PIPEBCONF, temp | PIPEACONF_ENABLE);
453			REG_READ(PCH_PIPEBCONF);
454		}
455
456		gma_wait_for_vblank(dev);
457
458		/* Enable plane */
459		temp = REG_READ(DSPBCNTR);
460		if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
461			REG_WRITE(DSPBCNTR, temp | DISPLAY_PLANE_ENABLE);
462			/* Flush the plane changes */
463			REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
464			REG_READ(DSPBSURF);
465		}
466
467		gma_crtc_load_lut(crtc);
468	}
469
470	/* DSPARB */
471	REG_WRITE(DSPARB, 0x00003fbf);
472
473	/* FW1 */
474	REG_WRITE(0x70034, 0x3f880a0a);
475
476	/* FW2 */
477	REG_WRITE(0x70038, 0x0b060808);
478
479	/* FW4 */
480	REG_WRITE(0x70050, 0x08030404);
481
482	/* FW5 */
483	REG_WRITE(0x70054, 0x04040404);
484
485	/* LNC Chicken Bits - Squawk! */
486	REG_WRITE(0x70400, 0x4000);
487
488	return;
489}
490
491static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode)
492{
493	static int dpms_mode = -1;
494
495	struct drm_device *dev = encoder->dev;
496	struct drm_psb_private *dev_priv = dev->dev_private;
497	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
498	u32 temp;
499
500	if (dpms_mode == mode)
501		return;
502
503	if (mode != DRM_MODE_DPMS_ON)
504		temp = 0x0;
505	else
506		temp = 0x99;
507
508	dpms_mode = mode;
509	HDMI_WRITE(HDMI_VIDEO_REG, temp);
510}
511
512static int oaktrail_hdmi_mode_valid(struct drm_connector *connector,
513				struct drm_display_mode *mode)
514{
515	if (mode->clock > 165000)
516		return MODE_CLOCK_HIGH;
517	if (mode->clock < 20000)
518		return MODE_CLOCK_LOW;
519
520	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
521		return MODE_NO_DBLESCAN;
522
523	return MODE_OK;
524}
525
526static enum drm_connector_status
527oaktrail_hdmi_detect(struct drm_connector *connector, bool force)
528{
529	enum drm_connector_status status;
530	struct drm_device *dev = connector->dev;
531	struct drm_psb_private *dev_priv = dev->dev_private;
532	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
533	u32 temp;
534
535	temp = HDMI_READ(HDMI_HSR);
536	DRM_DEBUG_KMS("HDMI_HSR %x\n", temp);
537
538	if ((temp & HDMI_DETECT_HDP) != 0)
539		status = connector_status_connected;
540	else
541		status = connector_status_disconnected;
542
543	return status;
544}
545
546static const unsigned char raw_edid[] = {
547	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0,
548	0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78,
549	0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5,
550	0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01,
551	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
552	0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a,
553	0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35,
554	0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44,
555	0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20,
556	0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a,
557	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d
558};
559
560static int oaktrail_hdmi_get_modes(struct drm_connector *connector)
561{
562	struct i2c_adapter *i2c_adap;
563	struct edid *edid;
564	int ret = 0;
565
566	/*
567	 *	FIXME: We need to figure this lot out. In theory we can
568	 *	read the EDID somehow but I've yet to find working reference
569	 *	code.
570	 */
571	i2c_adap = i2c_get_adapter(3);
572	if (i2c_adap == NULL) {
573		DRM_ERROR("No ddc adapter available!\n");
574		edid = (struct edid *)raw_edid;
575	} else {
576		edid = (struct edid *)raw_edid;
577		/* FIXME ? edid = drm_get_edid(connector, i2c_adap); */
578	}
579
580	if (edid) {
581		drm_mode_connector_update_edid_property(connector, edid);
582		ret = drm_add_edid_modes(connector, edid);
583	}
584	return ret;
585}
586
587static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder,
588			       struct drm_display_mode *mode,
589			       struct drm_display_mode *adjusted_mode)
590{
591	struct drm_device *dev = encoder->dev;
592
593	oaktrail_hdmi_audio_enable(dev);
594	return;
595}
596
597static void oaktrail_hdmi_destroy(struct drm_connector *connector)
598{
599	return;
600}
601
602static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = {
603	.dpms = oaktrail_hdmi_dpms,
604	.prepare = gma_encoder_prepare,
605	.mode_set = oaktrail_hdmi_mode_set,
606	.commit = gma_encoder_commit,
607};
608
609static const struct drm_connector_helper_funcs
610					oaktrail_hdmi_connector_helper_funcs = {
611	.get_modes = oaktrail_hdmi_get_modes,
612	.mode_valid = oaktrail_hdmi_mode_valid,
613	.best_encoder = gma_best_encoder,
614};
615
616static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = {
617	.dpms = drm_helper_connector_dpms,
618	.detect = oaktrail_hdmi_detect,
619	.fill_modes = drm_helper_probe_single_connector_modes,
620	.destroy = oaktrail_hdmi_destroy,
621};
622
623static void oaktrail_hdmi_enc_destroy(struct drm_encoder *encoder)
624{
625	drm_encoder_cleanup(encoder);
626}
627
628static const struct drm_encoder_funcs oaktrail_hdmi_enc_funcs = {
629	.destroy = oaktrail_hdmi_enc_destroy,
630};
631
632void oaktrail_hdmi_init(struct drm_device *dev,
633					struct psb_intel_mode_device *mode_dev)
634{
635	struct gma_encoder *gma_encoder;
636	struct gma_connector *gma_connector;
637	struct drm_connector *connector;
638	struct drm_encoder *encoder;
639
640	gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL);
641	if (!gma_encoder)
642		return;
643
644	gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL);
645	if (!gma_connector)
646		goto failed_connector;
647
648	connector = &gma_connector->base;
649	encoder = &gma_encoder->base;
650	drm_connector_init(dev, connector,
651			   &oaktrail_hdmi_connector_funcs,
652			   DRM_MODE_CONNECTOR_DVID);
653
654	drm_encoder_init(dev, encoder,
655			 &oaktrail_hdmi_enc_funcs,
656			 DRM_MODE_ENCODER_TMDS, NULL);
657
658	gma_connector_attach_encoder(gma_connector, gma_encoder);
659
660	gma_encoder->type = INTEL_OUTPUT_HDMI;
661	drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs);
662	drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs);
663
664	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
665	connector->interlace_allowed = false;
666	connector->doublescan_allowed = false;
667	drm_connector_register(connector);
668	dev_info(dev->dev, "HDMI initialised.\n");
669
670	return;
671
672failed_connector:
673	kfree(gma_encoder);
674}
675
676static const struct pci_device_id hdmi_ids[] = {
677	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) },
678	{ 0 }
679};
680
681void oaktrail_hdmi_setup(struct drm_device *dev)
682{
683	struct drm_psb_private *dev_priv = dev->dev_private;
684	struct pci_dev *pdev;
685	struct oaktrail_hdmi_dev *hdmi_dev;
686	int ret;
687
688	pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
689	if (!pdev)
690		return;
691
692	hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL);
693	if (!hdmi_dev) {
694		dev_err(dev->dev, "failed to allocate memory\n");
695		goto out;
696	}
697
698
699	ret = pci_enable_device(pdev);
700	if (ret) {
701		dev_err(dev->dev, "failed to enable hdmi controller\n");
702		goto free;
703	}
704
705	hdmi_dev->mmio = pci_resource_start(pdev, 0);
706	hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
707	hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
708	if (!hdmi_dev->regs) {
709		dev_err(dev->dev, "failed to map hdmi mmio\n");
710		goto free;
711	}
712
713	hdmi_dev->dev = pdev;
714	pci_set_drvdata(pdev, hdmi_dev);
715
716	/* Initialize i2c controller */
717	ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev);
718	if (ret)
719		dev_err(dev->dev, "HDMI I2C initialization failed\n");
720
721	dev_priv->hdmi_priv = hdmi_dev;
722	oaktrail_hdmi_audio_disable(dev);
723
724	dev_info(dev->dev, "HDMI hardware present.\n");
725
726	return;
727
728free:
729	kfree(hdmi_dev);
730out:
731	return;
732}
733
734void oaktrail_hdmi_teardown(struct drm_device *dev)
735{
736	struct drm_psb_private *dev_priv = dev->dev_private;
737	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
738	struct pci_dev *pdev;
739
740	if (hdmi_dev) {
741		pdev = hdmi_dev->dev;
742		pci_set_drvdata(pdev, NULL);
743		oaktrail_hdmi_i2c_exit(pdev);
744		iounmap(hdmi_dev->regs);
745		kfree(hdmi_dev);
746		pci_dev_put(pdev);
747	}
748}
749
750/* save HDMI register state */
751void oaktrail_hdmi_save(struct drm_device *dev)
752{
753	struct drm_psb_private *dev_priv = dev->dev_private;
754	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
755	struct psb_state *regs = &dev_priv->regs.psb;
756	struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
757	int i;
758
759	/* dpll */
760	hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
761	hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL);
762	hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST);
763	hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE);
764	hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE);
765
766	/* pipe B */
767	pipeb->conf = PSB_RVDC32(PIPEBCONF);
768	pipeb->src = PSB_RVDC32(PIPEBSRC);
769	pipeb->htotal = PSB_RVDC32(HTOTAL_B);
770	pipeb->hblank = PSB_RVDC32(HBLANK_B);
771	pipeb->hsync = PSB_RVDC32(HSYNC_B);
772	pipeb->vtotal = PSB_RVDC32(VTOTAL_B);
773	pipeb->vblank = PSB_RVDC32(VBLANK_B);
774	pipeb->vsync = PSB_RVDC32(VSYNC_B);
775
776	hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF);
777	hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC);
778	hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B);
779	hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B);
780	hdmi_dev->savePCH_HSYNC_B  = PSB_RVDC32(PCH_HSYNC_B);
781	hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B);
782	hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B);
783	hdmi_dev->savePCH_VSYNC_B  = PSB_RVDC32(PCH_VSYNC_B);
784
785	/* plane */
786	pipeb->cntr = PSB_RVDC32(DSPBCNTR);
787	pipeb->stride = PSB_RVDC32(DSPBSTRIDE);
788	pipeb->addr = PSB_RVDC32(DSPBBASE);
789	pipeb->surf = PSB_RVDC32(DSPBSURF);
790	pipeb->linoff = PSB_RVDC32(DSPBLINOFF);
791	pipeb->tileoff = PSB_RVDC32(DSPBTILEOFF);
792
793	/* cursor B */
794	regs->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
795	regs->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
796	regs->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
797
798	/* save palette */
799	for (i = 0; i < 256; i++)
800		pipeb->palette[i] = PSB_RVDC32(PALETTE_B + (i << 2));
801}
802
803/* restore HDMI register state */
804void oaktrail_hdmi_restore(struct drm_device *dev)
805{
806	struct drm_psb_private *dev_priv = dev->dev_private;
807	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
808	struct psb_state *regs = &dev_priv->regs.psb;
809	struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
810	int i;
811
812	/* dpll */
813	PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
814	PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL);
815	PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
816	PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
817	PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
818	DRM_UDELAY(150);
819
820	/* pipe */
821	PSB_WVDC32(pipeb->src, PIPEBSRC);
822	PSB_WVDC32(pipeb->htotal, HTOTAL_B);
823	PSB_WVDC32(pipeb->hblank, HBLANK_B);
824	PSB_WVDC32(pipeb->hsync,  HSYNC_B);
825	PSB_WVDC32(pipeb->vtotal, VTOTAL_B);
826	PSB_WVDC32(pipeb->vblank, VBLANK_B);
827	PSB_WVDC32(pipeb->vsync,  VSYNC_B);
828
829	PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC);
830	PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B);
831	PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B);
832	PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B,  PCH_HSYNC_B);
833	PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B);
834	PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B);
835	PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B,  PCH_VSYNC_B);
836
837	PSB_WVDC32(pipeb->conf, PIPEBCONF);
838	PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
839
840	/* plane */
841	PSB_WVDC32(pipeb->linoff, DSPBLINOFF);
842	PSB_WVDC32(pipeb->stride, DSPBSTRIDE);
843	PSB_WVDC32(pipeb->tileoff, DSPBTILEOFF);
844	PSB_WVDC32(pipeb->cntr, DSPBCNTR);
845	PSB_WVDC32(pipeb->surf, DSPBSURF);
846
847	/* cursor B */
848	PSB_WVDC32(regs->saveDSPBCURSOR_CTRL, CURBCNTR);
849	PSB_WVDC32(regs->saveDSPBCURSOR_POS, CURBPOS);
850	PSB_WVDC32(regs->saveDSPBCURSOR_BASE, CURBBASE);
851
852	/* restore palette */
853	for (i = 0; i < 256; i++)
854		PSB_WVDC32(pipeb->palette[i], PALETTE_B + (i << 2));
855}
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 *	Li Peng <peng.li@intel.com>
 25 */
 26
 27#include <linux/delay.h>
 28
 29#include <drm/drm.h>
 30
 31#include "psb_drv.h"
 32#include "psb_intel_drv.h"
 33#include "psb_intel_reg.h"
 
 34
 35#define HDMI_READ(reg)		readl(hdmi_dev->regs + (reg))
 36#define HDMI_WRITE(reg, val)	writel(val, hdmi_dev->regs + (reg))
 37
 38#define HDMI_HCR	0x1000
 39#define HCR_ENABLE_HDCP		(1 << 5)
 40#define HCR_ENABLE_AUDIO	(1 << 2)
 41#define HCR_ENABLE_PIXEL	(1 << 1)
 42#define HCR_ENABLE_TMDS		(1 << 0)
 43
 44#define HDMI_HICR	0x1004
 45#define HDMI_HSR	0x1008
 46#define HDMI_HISR	0x100C
 47#define HDMI_DETECT_HDP		(1 << 0)
 48
 49#define HDMI_VIDEO_REG	0x3000
 50#define HDMI_UNIT_EN		(1 << 7)
 51#define HDMI_MODE_OUTPUT	(1 << 0)
 52#define HDMI_HBLANK_A	0x3100
 53
 54#define HDMI_AUDIO_CTRL	0x4000
 55#define HDMI_ENABLE_AUDIO	(1 << 0)
 56
 57#define PCH_HTOTAL_B	0x3100
 58#define PCH_HBLANK_B	0x3104
 59#define PCH_HSYNC_B	0x3108
 60#define PCH_VTOTAL_B	0x310C
 61#define PCH_VBLANK_B	0x3110
 62#define PCH_VSYNC_B	0x3114
 63#define PCH_PIPEBSRC	0x311C
 64
 65#define PCH_PIPEB_DSL	0x3800
 66#define PCH_PIPEB_SLC	0x3804
 67#define PCH_PIPEBCONF	0x3808
 68#define PCH_PIPEBSTAT	0x3824
 69
 70#define CDVO_DFT	0x5000
 71#define CDVO_SLEWRATE	0x5004
 72#define CDVO_STRENGTH	0x5008
 73#define CDVO_RCOMP	0x500C
 74
 75#define DPLL_CTRL       0x6000
 76#define DPLL_PDIV_SHIFT		16
 77#define DPLL_PDIV_MASK		(0xf << 16)
 78#define DPLL_PWRDN		(1 << 4)
 79#define DPLL_RESET		(1 << 3)
 80#define DPLL_FASTEN		(1 << 2)
 81#define DPLL_ENSTAT		(1 << 1)
 82#define DPLL_DITHEN		(1 << 0)
 83
 84#define DPLL_DIV_CTRL   0x6004
 85#define DPLL_CLKF_MASK		0xffffffc0
 86#define DPLL_CLKR_MASK		(0x3f)
 87
 88#define DPLL_CLK_ENABLE 0x6008
 89#define DPLL_EN_DISP		(1 << 31)
 90#define DPLL_SEL_HDMI		(1 << 8)
 91#define DPLL_EN_HDMI		(1 << 1)
 92#define DPLL_EN_VGA		(1 << 0)
 93
 94#define DPLL_ADJUST     0x600C
 95#define DPLL_STATUS     0x6010
 96#define DPLL_UPDATE     0x6014
 97#define DPLL_DFT        0x6020
 98
 99struct intel_range {
100	int	min, max;
101};
102
103struct oaktrail_hdmi_limit {
104	struct intel_range vco, np, nr, nf;
105};
106
107struct oaktrail_hdmi_clock {
108	int np;
109	int nr;
110	int nf;
111	int dot;
112};
113
114#define VCO_MIN		320000
115#define VCO_MAX		1650000
116#define	NP_MIN		1
117#define	NP_MAX		15
118#define	NR_MIN		1
119#define	NR_MAX		64
120#define NF_MIN		2
121#define NF_MAX		4095
122
123static const struct oaktrail_hdmi_limit oaktrail_hdmi_limit = {
124	.vco = { .min = VCO_MIN,		.max = VCO_MAX },
125	.np  = { .min = NP_MIN,			.max = NP_MAX  },
126	.nr  = { .min = NR_MIN,			.max = NR_MAX  },
127	.nf  = { .min = NF_MIN,			.max = NF_MAX  },
128};
129
130static void oaktrail_hdmi_audio_enable(struct drm_device *dev)
131{
132	struct drm_psb_private *dev_priv = dev->dev_private;
133	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
134
135	HDMI_WRITE(HDMI_HCR, 0x67);
136	HDMI_READ(HDMI_HCR);
137
138	HDMI_WRITE(0x51a8, 0x10);
139	HDMI_READ(0x51a8);
140
141	HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1);
142	HDMI_READ(HDMI_AUDIO_CTRL);
143}
144
145static void oaktrail_hdmi_audio_disable(struct drm_device *dev)
146{
147	struct drm_psb_private *dev_priv = dev->dev_private;
148	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
149
150	HDMI_WRITE(0x51a8, 0x0);
151	HDMI_READ(0x51a8);
152
153	HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0);
154	HDMI_READ(HDMI_AUDIO_CTRL);
155
156	HDMI_WRITE(HDMI_HCR, 0x47);
157	HDMI_READ(HDMI_HCR);
158}
159
160static unsigned int htotal_calculate(struct drm_display_mode *mode)
161{
162	u32 htotal, new_crtc_htotal;
163
164	htotal = (mode->crtc_hdisplay - 1) | ((mode->crtc_htotal - 1) << 16);
165
166	/*
167	 * 1024 x 768  new_crtc_htotal = 0x1024;
168	 * 1280 x 1024 new_crtc_htotal = 0x0c34;
169	 */
170	new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock;
171
172	DRM_DEBUG_KMS("new crtc htotal 0x%4x\n", new_crtc_htotal);
173	return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16);
174}
175
176static void oaktrail_hdmi_find_dpll(struct drm_crtc *crtc, int target,
177				int refclk, struct oaktrail_hdmi_clock *best_clock)
178{
179	int np_min, np_max, nr_min, nr_max;
180	int np, nr, nf;
181
182	np_min = DIV_ROUND_UP(oaktrail_hdmi_limit.vco.min, target * 10);
183	np_max = oaktrail_hdmi_limit.vco.max / (target * 10);
184	if (np_min < oaktrail_hdmi_limit.np.min)
185		np_min = oaktrail_hdmi_limit.np.min;
186	if (np_max > oaktrail_hdmi_limit.np.max)
187		np_max = oaktrail_hdmi_limit.np.max;
188
189	nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max));
190	nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min));
191	if (nr_min < oaktrail_hdmi_limit.nr.min)
192		nr_min = oaktrail_hdmi_limit.nr.min;
193	if (nr_max > oaktrail_hdmi_limit.nr.max)
194		nr_max = oaktrail_hdmi_limit.nr.max;
195
196	np = DIV_ROUND_UP((refclk * 1000), (target * 10 * nr_max));
197	nr = DIV_ROUND_UP((refclk * 1000), (target * 10 * np));
198	nf = DIV_ROUND_CLOSEST((target * 10 * np * nr), refclk);
199	DRM_DEBUG_KMS("np, nr, nf %d %d %d\n", np, nr, nf);
200
201	/*
202	 * 1024 x 768  np = 1; nr = 0x26; nf = 0x0fd8000;
203	 * 1280 x 1024 np = 1; nr = 0x17; nf = 0x1034000;
204	 */
205	best_clock->np = np;
206	best_clock->nr = nr - 1;
207	best_clock->nf = (nf << 14);
208}
209
210static void scu_busy_loop(void __iomem *scu_base)
211{
212	u32 status = 0;
213	u32 loop_count = 0;
214
215	status = readl(scu_base + 0x04);
216	while (status & 1) {
217		udelay(1); /* scu processing time is in few u secods */
218		status = readl(scu_base + 0x04);
219		loop_count++;
220		/* break if scu doesn't reset busy bit after huge retry */
221		if (loop_count > 1000) {
222			DRM_DEBUG_KMS("SCU IPC timed out");
223			return;
224		}
225	}
226}
227
228/*
229 *	You don't want to know, you really really don't want to know....
230 *
231 *	This is magic. However it's safe magic because of the way the platform
232 *	works and it is necessary magic.
233 */
234static void oaktrail_hdmi_reset(struct drm_device *dev)
235{
236	void __iomem *base;
237	unsigned long scu_ipc_mmio = 0xff11c000UL;
238	int scu_len = 1024;
239
240	base = ioremap((resource_size_t)scu_ipc_mmio, scu_len);
241	if (base == NULL) {
242		DRM_ERROR("failed to map scu mmio\n");
243		return;
244	}
245
246	/* scu ipc: assert hdmi controller reset */
247	writel(0xff11d118, base + 0x0c);
248	writel(0x7fffffdf, base + 0x80);
249	writel(0x42005, base + 0x0);
250	scu_busy_loop(base);
251
252	/* scu ipc: de-assert hdmi controller reset */
253	writel(0xff11d118, base + 0x0c);
254	writel(0x7fffffff, base + 0x80);
255	writel(0x42005, base + 0x0);
256	scu_busy_loop(base);
257
258	iounmap(base);
259}
260
261int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc,
262			    struct drm_display_mode *mode,
263			    struct drm_display_mode *adjusted_mode,
264			    int x, int y,
265			    struct drm_framebuffer *old_fb)
266{
267	struct drm_device *dev = crtc->dev;
268	struct drm_psb_private *dev_priv = dev->dev_private;
269	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
270	int pipe = 1;
271	int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
272	int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
273	int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
274	int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
275	int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
276	int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
277	int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
278	int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
279	int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
280	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
281	int refclk;
282	struct oaktrail_hdmi_clock clock;
283	u32 dspcntr, pipeconf, dpll, temp;
284	int dspcntr_reg = DSPBCNTR;
285
286	if (!gma_power_begin(dev, true))
287		return 0;
288
289	/* Disable the VGA plane that we never use */
290	REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
291
292	/* Disable dpll if necessary */
293	dpll = REG_READ(DPLL_CTRL);
294	if ((dpll & DPLL_PWRDN) == 0) {
295		REG_WRITE(DPLL_CTRL, dpll | (DPLL_PWRDN | DPLL_RESET));
296		REG_WRITE(DPLL_DIV_CTRL, 0x00000000);
297		REG_WRITE(DPLL_STATUS, 0x1);
298	}
299	udelay(150);
300
301	/* Reset controller */
302	oaktrail_hdmi_reset(dev);
303
304	/* program and enable dpll */
305	refclk = 25000;
306	oaktrail_hdmi_find_dpll(crtc, adjusted_mode->clock, refclk, &clock);
307
308	/* Set the DPLL */
309	dpll = REG_READ(DPLL_CTRL);
310	dpll &= ~DPLL_PDIV_MASK;
311	dpll &= ~(DPLL_PWRDN | DPLL_RESET);
312	REG_WRITE(DPLL_CTRL, 0x00000008);
313	REG_WRITE(DPLL_DIV_CTRL, ((clock.nf << 6) | clock.nr));
314	REG_WRITE(DPLL_ADJUST, ((clock.nf >> 14) - 1));
315	REG_WRITE(DPLL_CTRL, (dpll | (clock.np << DPLL_PDIV_SHIFT) | DPLL_ENSTAT | DPLL_DITHEN));
316	REG_WRITE(DPLL_UPDATE, 0x80000000);
317	REG_WRITE(DPLL_CLK_ENABLE, 0x80050102);
318	udelay(150);
319
320	/* configure HDMI */
321	HDMI_WRITE(0x1004, 0x1fd);
322	HDMI_WRITE(0x2000, 0x1);
323	HDMI_WRITE(0x2008, 0x0);
324	HDMI_WRITE(0x3130, 0x8);
325	HDMI_WRITE(0x101c, 0x1800810);
326
327	temp = htotal_calculate(adjusted_mode);
328	REG_WRITE(htot_reg, temp);
329	REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
330	REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
331	REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
332	REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
333	REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
334	REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
335
336	REG_WRITE(PCH_HTOTAL_B, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16));
337	REG_WRITE(PCH_HBLANK_B, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
338	REG_WRITE(PCH_HSYNC_B, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
339	REG_WRITE(PCH_VTOTAL_B, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
340	REG_WRITE(PCH_VBLANK_B, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
341	REG_WRITE(PCH_VSYNC_B, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
342	REG_WRITE(PCH_PIPEBSRC, ((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
343
344	temp = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
345	HDMI_WRITE(HDMI_HBLANK_A, ((adjusted_mode->crtc_hdisplay - 1) << 16) |  temp);
346
347	REG_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
348	REG_WRITE(dsppos_reg, 0);
349
350	/* Flush the plane changes */
351	{
352		const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
353		crtc_funcs->mode_set_base(crtc, x, y, old_fb);
354	}
355
356	/* Set up the display plane register */
357	dspcntr = REG_READ(dspcntr_reg);
358	dspcntr |= DISPPLANE_GAMMA_ENABLE;
359	dspcntr |= DISPPLANE_SEL_PIPE_B;
360	dspcntr |= DISPLAY_PLANE_ENABLE;
361
362	/* setup pipeconf */
363	pipeconf = REG_READ(pipeconf_reg);
364	pipeconf |= PIPEACONF_ENABLE;
365
366	REG_WRITE(pipeconf_reg, pipeconf);
367	REG_READ(pipeconf_reg);
368
369	REG_WRITE(PCH_PIPEBCONF, pipeconf);
370	REG_READ(PCH_PIPEBCONF);
371	gma_wait_for_vblank(dev);
372
373	REG_WRITE(dspcntr_reg, dspcntr);
374	gma_wait_for_vblank(dev);
375
376	gma_power_end(dev);
377
378	return 0;
379}
380
381void oaktrail_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode)
382{
383	struct drm_device *dev = crtc->dev;
384	u32 temp;
385
386	DRM_DEBUG_KMS("%s %d\n", __func__, mode);
387
388	switch (mode) {
389	case DRM_MODE_DPMS_OFF:
390		REG_WRITE(VGACNTRL, 0x80000000);
391
392		/* Disable plane */
393		temp = REG_READ(DSPBCNTR);
394		if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
395			REG_WRITE(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
396			REG_READ(DSPBCNTR);
397			/* Flush the plane changes */
398			REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
399			REG_READ(DSPBSURF);
400		}
401
402		/* Disable pipe B */
403		temp = REG_READ(PIPEBCONF);
404		if ((temp & PIPEACONF_ENABLE) != 0) {
405			REG_WRITE(PIPEBCONF, temp & ~PIPEACONF_ENABLE);
406			REG_READ(PIPEBCONF);
407		}
408
409		/* Disable LNW Pipes, etc */
410		temp = REG_READ(PCH_PIPEBCONF);
411		if ((temp & PIPEACONF_ENABLE) != 0) {
412			REG_WRITE(PCH_PIPEBCONF, temp & ~PIPEACONF_ENABLE);
413			REG_READ(PCH_PIPEBCONF);
414		}
415
416		/* wait for pipe off */
417		udelay(150);
418
419		/* Disable dpll */
420		temp = REG_READ(DPLL_CTRL);
421		if ((temp & DPLL_PWRDN) == 0) {
422			REG_WRITE(DPLL_CTRL, temp | (DPLL_PWRDN | DPLL_RESET));
423			REG_WRITE(DPLL_STATUS, 0x1);
424		}
425
426		/* wait for dpll off */
427		udelay(150);
428
429		break;
430	case DRM_MODE_DPMS_ON:
431	case DRM_MODE_DPMS_STANDBY:
432	case DRM_MODE_DPMS_SUSPEND:
433		/* Enable dpll */
434		temp = REG_READ(DPLL_CTRL);
435		if ((temp & DPLL_PWRDN) != 0) {
436			REG_WRITE(DPLL_CTRL, temp & ~(DPLL_PWRDN | DPLL_RESET));
437			temp = REG_READ(DPLL_CLK_ENABLE);
438			REG_WRITE(DPLL_CLK_ENABLE, temp | DPLL_EN_DISP | DPLL_SEL_HDMI | DPLL_EN_HDMI);
439			REG_READ(DPLL_CLK_ENABLE);
440		}
441		/* wait for dpll warm up */
442		udelay(150);
443
444		/* Enable pipe B */
445		temp = REG_READ(PIPEBCONF);
446		if ((temp & PIPEACONF_ENABLE) == 0) {
447			REG_WRITE(PIPEBCONF, temp | PIPEACONF_ENABLE);
448			REG_READ(PIPEBCONF);
449		}
450
451		/* Enable LNW Pipe B */
452		temp = REG_READ(PCH_PIPEBCONF);
453		if ((temp & PIPEACONF_ENABLE) == 0) {
454			REG_WRITE(PCH_PIPEBCONF, temp | PIPEACONF_ENABLE);
455			REG_READ(PCH_PIPEBCONF);
456		}
457
458		gma_wait_for_vblank(dev);
459
460		/* Enable plane */
461		temp = REG_READ(DSPBCNTR);
462		if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
463			REG_WRITE(DSPBCNTR, temp | DISPLAY_PLANE_ENABLE);
464			/* Flush the plane changes */
465			REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
466			REG_READ(DSPBSURF);
467		}
468
469		gma_crtc_load_lut(crtc);
470	}
471
472	/* DSPARB */
473	REG_WRITE(DSPARB, 0x00003fbf);
474
475	/* FW1 */
476	REG_WRITE(0x70034, 0x3f880a0a);
477
478	/* FW2 */
479	REG_WRITE(0x70038, 0x0b060808);
480
481	/* FW4 */
482	REG_WRITE(0x70050, 0x08030404);
483
484	/* FW5 */
485	REG_WRITE(0x70054, 0x04040404);
486
487	/* LNC Chicken Bits - Squawk! */
488	REG_WRITE(0x70400, 0x4000);
489
490	return;
491}
492
493static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode)
494{
495	static int dpms_mode = -1;
496
497	struct drm_device *dev = encoder->dev;
498	struct drm_psb_private *dev_priv = dev->dev_private;
499	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
500	u32 temp;
501
502	if (dpms_mode == mode)
503		return;
504
505	if (mode != DRM_MODE_DPMS_ON)
506		temp = 0x0;
507	else
508		temp = 0x99;
509
510	dpms_mode = mode;
511	HDMI_WRITE(HDMI_VIDEO_REG, temp);
512}
513
514static enum drm_mode_status oaktrail_hdmi_mode_valid(struct drm_connector *connector,
515				struct drm_display_mode *mode)
516{
517	if (mode->clock > 165000)
518		return MODE_CLOCK_HIGH;
519	if (mode->clock < 20000)
520		return MODE_CLOCK_LOW;
521
522	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
523		return MODE_NO_DBLESCAN;
524
525	return MODE_OK;
526}
527
528static enum drm_connector_status
529oaktrail_hdmi_detect(struct drm_connector *connector, bool force)
530{
531	enum drm_connector_status status;
532	struct drm_device *dev = connector->dev;
533	struct drm_psb_private *dev_priv = dev->dev_private;
534	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
535	u32 temp;
536
537	temp = HDMI_READ(HDMI_HSR);
538	DRM_DEBUG_KMS("HDMI_HSR %x\n", temp);
539
540	if ((temp & HDMI_DETECT_HDP) != 0)
541		status = connector_status_connected;
542	else
543		status = connector_status_disconnected;
544
545	return status;
546}
547
548static const unsigned char raw_edid[] = {
549	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0,
550	0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78,
551	0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5,
552	0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01,
553	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
554	0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a,
555	0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35,
556	0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44,
557	0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20,
558	0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a,
559	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d
560};
561
562static int oaktrail_hdmi_get_modes(struct drm_connector *connector)
563{
564	struct i2c_adapter *i2c_adap;
565	struct edid *edid;
566	int ret = 0;
567
568	/*
569	 *	FIXME: We need to figure this lot out. In theory we can
570	 *	read the EDID somehow but I've yet to find working reference
571	 *	code.
572	 */
573	i2c_adap = i2c_get_adapter(3);
574	if (i2c_adap == NULL) {
575		DRM_ERROR("No ddc adapter available!\n");
576		edid = (struct edid *)raw_edid;
577	} else {
578		edid = (struct edid *)raw_edid;
579		/* FIXME ? edid = drm_get_edid(connector, i2c_adap); */
580	}
581
582	if (edid) {
583		drm_connector_update_edid_property(connector, edid);
584		ret = drm_add_edid_modes(connector, edid);
585	}
586	return ret;
587}
588
589static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder,
590			       struct drm_display_mode *mode,
591			       struct drm_display_mode *adjusted_mode)
592{
593	struct drm_device *dev = encoder->dev;
594
595	oaktrail_hdmi_audio_enable(dev);
596	return;
597}
598
599static void oaktrail_hdmi_destroy(struct drm_connector *connector)
600{
601	return;
602}
603
604static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = {
605	.dpms = oaktrail_hdmi_dpms,
606	.prepare = gma_encoder_prepare,
607	.mode_set = oaktrail_hdmi_mode_set,
608	.commit = gma_encoder_commit,
609};
610
611static const struct drm_connector_helper_funcs
612					oaktrail_hdmi_connector_helper_funcs = {
613	.get_modes = oaktrail_hdmi_get_modes,
614	.mode_valid = oaktrail_hdmi_mode_valid,
615	.best_encoder = gma_best_encoder,
616};
617
618static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = {
619	.dpms = drm_helper_connector_dpms,
620	.detect = oaktrail_hdmi_detect,
621	.fill_modes = drm_helper_probe_single_connector_modes,
622	.destroy = oaktrail_hdmi_destroy,
623};
624
625static void oaktrail_hdmi_enc_destroy(struct drm_encoder *encoder)
626{
627	drm_encoder_cleanup(encoder);
628}
629
630static const struct drm_encoder_funcs oaktrail_hdmi_enc_funcs = {
631	.destroy = oaktrail_hdmi_enc_destroy,
632};
633
634void oaktrail_hdmi_init(struct drm_device *dev,
635					struct psb_intel_mode_device *mode_dev)
636{
637	struct gma_encoder *gma_encoder;
638	struct gma_connector *gma_connector;
639	struct drm_connector *connector;
640	struct drm_encoder *encoder;
641
642	gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL);
643	if (!gma_encoder)
644		return;
645
646	gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL);
647	if (!gma_connector)
648		goto failed_connector;
649
650	connector = &gma_connector->base;
651	encoder = &gma_encoder->base;
652	drm_connector_init(dev, connector,
653			   &oaktrail_hdmi_connector_funcs,
654			   DRM_MODE_CONNECTOR_DVID);
655
656	drm_encoder_init(dev, encoder,
657			 &oaktrail_hdmi_enc_funcs,
658			 DRM_MODE_ENCODER_TMDS, NULL);
659
660	gma_connector_attach_encoder(gma_connector, gma_encoder);
661
662	gma_encoder->type = INTEL_OUTPUT_HDMI;
663	drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs);
664	drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs);
665
666	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
667	connector->interlace_allowed = false;
668	connector->doublescan_allowed = false;
669	drm_connector_register(connector);
670	dev_info(dev->dev, "HDMI initialised.\n");
671
672	return;
673
674failed_connector:
675	kfree(gma_encoder);
676}
677
678static const struct pci_device_id hdmi_ids[] = {
679	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) },
680	{ 0 }
681};
682
683void oaktrail_hdmi_setup(struct drm_device *dev)
684{
685	struct drm_psb_private *dev_priv = dev->dev_private;
686	struct pci_dev *pdev;
687	struct oaktrail_hdmi_dev *hdmi_dev;
688	int ret;
689
690	pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
691	if (!pdev)
692		return;
693
694	hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL);
695	if (!hdmi_dev) {
696		dev_err(dev->dev, "failed to allocate memory\n");
697		goto out;
698	}
699
700
701	ret = pci_enable_device(pdev);
702	if (ret) {
703		dev_err(dev->dev, "failed to enable hdmi controller\n");
704		goto free;
705	}
706
707	hdmi_dev->mmio = pci_resource_start(pdev, 0);
708	hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
709	hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
710	if (!hdmi_dev->regs) {
711		dev_err(dev->dev, "failed to map hdmi mmio\n");
712		goto free;
713	}
714
715	hdmi_dev->dev = pdev;
716	pci_set_drvdata(pdev, hdmi_dev);
717
718	/* Initialize i2c controller */
719	ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev);
720	if (ret)
721		dev_err(dev->dev, "HDMI I2C initialization failed\n");
722
723	dev_priv->hdmi_priv = hdmi_dev;
724	oaktrail_hdmi_audio_disable(dev);
725
726	dev_info(dev->dev, "HDMI hardware present.\n");
727
728	return;
729
730free:
731	kfree(hdmi_dev);
732out:
733	return;
734}
735
736void oaktrail_hdmi_teardown(struct drm_device *dev)
737{
738	struct drm_psb_private *dev_priv = dev->dev_private;
739	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
740	struct pci_dev *pdev;
741
742	if (hdmi_dev) {
743		pdev = hdmi_dev->dev;
744		pci_set_drvdata(pdev, NULL);
745		oaktrail_hdmi_i2c_exit(pdev);
746		iounmap(hdmi_dev->regs);
747		kfree(hdmi_dev);
748		pci_dev_put(pdev);
749	}
750}
751
752/* save HDMI register state */
753void oaktrail_hdmi_save(struct drm_device *dev)
754{
755	struct drm_psb_private *dev_priv = dev->dev_private;
756	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
757	struct psb_state *regs = &dev_priv->regs.psb;
758	struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
759	int i;
760
761	/* dpll */
762	hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
763	hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL);
764	hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST);
765	hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE);
766	hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE);
767
768	/* pipe B */
769	pipeb->conf = PSB_RVDC32(PIPEBCONF);
770	pipeb->src = PSB_RVDC32(PIPEBSRC);
771	pipeb->htotal = PSB_RVDC32(HTOTAL_B);
772	pipeb->hblank = PSB_RVDC32(HBLANK_B);
773	pipeb->hsync = PSB_RVDC32(HSYNC_B);
774	pipeb->vtotal = PSB_RVDC32(VTOTAL_B);
775	pipeb->vblank = PSB_RVDC32(VBLANK_B);
776	pipeb->vsync = PSB_RVDC32(VSYNC_B);
777
778	hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF);
779	hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC);
780	hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B);
781	hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B);
782	hdmi_dev->savePCH_HSYNC_B  = PSB_RVDC32(PCH_HSYNC_B);
783	hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B);
784	hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B);
785	hdmi_dev->savePCH_VSYNC_B  = PSB_RVDC32(PCH_VSYNC_B);
786
787	/* plane */
788	pipeb->cntr = PSB_RVDC32(DSPBCNTR);
789	pipeb->stride = PSB_RVDC32(DSPBSTRIDE);
790	pipeb->addr = PSB_RVDC32(DSPBBASE);
791	pipeb->surf = PSB_RVDC32(DSPBSURF);
792	pipeb->linoff = PSB_RVDC32(DSPBLINOFF);
793	pipeb->tileoff = PSB_RVDC32(DSPBTILEOFF);
794
795	/* cursor B */
796	regs->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
797	regs->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
798	regs->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
799
800	/* save palette */
801	for (i = 0; i < 256; i++)
802		pipeb->palette[i] = PSB_RVDC32(PALETTE_B + (i << 2));
803}
804
805/* restore HDMI register state */
806void oaktrail_hdmi_restore(struct drm_device *dev)
807{
808	struct drm_psb_private *dev_priv = dev->dev_private;
809	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
810	struct psb_state *regs = &dev_priv->regs.psb;
811	struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
812	int i;
813
814	/* dpll */
815	PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
816	PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL);
817	PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
818	PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
819	PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
820	udelay(150);
821
822	/* pipe */
823	PSB_WVDC32(pipeb->src, PIPEBSRC);
824	PSB_WVDC32(pipeb->htotal, HTOTAL_B);
825	PSB_WVDC32(pipeb->hblank, HBLANK_B);
826	PSB_WVDC32(pipeb->hsync,  HSYNC_B);
827	PSB_WVDC32(pipeb->vtotal, VTOTAL_B);
828	PSB_WVDC32(pipeb->vblank, VBLANK_B);
829	PSB_WVDC32(pipeb->vsync,  VSYNC_B);
830
831	PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC);
832	PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B);
833	PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B);
834	PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B,  PCH_HSYNC_B);
835	PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B);
836	PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B);
837	PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B,  PCH_VSYNC_B);
838
839	PSB_WVDC32(pipeb->conf, PIPEBCONF);
840	PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
841
842	/* plane */
843	PSB_WVDC32(pipeb->linoff, DSPBLINOFF);
844	PSB_WVDC32(pipeb->stride, DSPBSTRIDE);
845	PSB_WVDC32(pipeb->tileoff, DSPBTILEOFF);
846	PSB_WVDC32(pipeb->cntr, DSPBCNTR);
847	PSB_WVDC32(pipeb->surf, DSPBSURF);
848
849	/* cursor B */
850	PSB_WVDC32(regs->saveDSPBCURSOR_CTRL, CURBCNTR);
851	PSB_WVDC32(regs->saveDSPBCURSOR_POS, CURBPOS);
852	PSB_WVDC32(regs->saveDSPBCURSOR_BASE, CURBBASE);
853
854	/* restore palette */
855	for (i = 0; i < 256; i++)
856		PSB_WVDC32(pipeb->palette[i], PALETTE_B + (i << 2));
857}