Linux Audio

Check our new training course

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