Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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_edid.h>
 31#include <drm/drm_simple_kms_helper.h>
 32
 33#include "psb_drv.h"
 34#include "psb_intel_drv.h"
 35#include "psb_intel_reg.h"
 36
 37#define HDMI_READ(reg)		readl(hdmi_dev->regs + (reg))
 38#define HDMI_WRITE(reg, val)	writel(val, hdmi_dev->regs + (reg))
 39
 40#define HDMI_HCR	0x1000
 41#define HCR_ENABLE_HDCP		(1 << 5)
 42#define HCR_ENABLE_AUDIO	(1 << 2)
 43#define HCR_ENABLE_PIXEL	(1 << 1)
 44#define HCR_ENABLE_TMDS		(1 << 0)
 45
 46#define HDMI_HICR	0x1004
 47#define HDMI_HSR	0x1008
 48#define HDMI_HISR	0x100C
 49#define HDMI_DETECT_HDP		(1 << 0)
 50
 51#define HDMI_VIDEO_REG	0x3000
 52#define HDMI_UNIT_EN		(1 << 7)
 53#define HDMI_MODE_OUTPUT	(1 << 0)
 54#define HDMI_HBLANK_A	0x3100
 55
 56#define HDMI_AUDIO_CTRL	0x4000
 57#define HDMI_ENABLE_AUDIO	(1 << 0)
 58
 59#define PCH_HTOTAL_B	0x3100
 60#define PCH_HBLANK_B	0x3104
 61#define PCH_HSYNC_B	0x3108
 62#define PCH_VTOTAL_B	0x310C
 63#define PCH_VBLANK_B	0x3110
 64#define PCH_VSYNC_B	0x3114
 65#define PCH_PIPEBSRC	0x311C
 66
 67#define PCH_PIPEB_DSL	0x3800
 68#define PCH_PIPEB_SLC	0x3804
 69#define PCH_PIPEBCONF	0x3808
 70#define PCH_PIPEBSTAT	0x3824
 71
 72#define CDVO_DFT	0x5000
 73#define CDVO_SLEWRATE	0x5004
 74#define CDVO_STRENGTH	0x5008
 75#define CDVO_RCOMP	0x500C
 76
 77#define DPLL_CTRL       0x6000
 78#define DPLL_PDIV_SHIFT		16
 79#define DPLL_PDIV_MASK		(0xf << 16)
 80#define DPLL_PWRDN		(1 << 4)
 81#define DPLL_RESET		(1 << 3)
 82#define DPLL_FASTEN		(1 << 2)
 83#define DPLL_ENSTAT		(1 << 1)
 84#define DPLL_DITHEN		(1 << 0)
 85
 86#define DPLL_DIV_CTRL   0x6004
 87#define DPLL_CLKF_MASK		0xffffffc0
 88#define DPLL_CLKR_MASK		(0x3f)
 89
 90#define DPLL_CLK_ENABLE 0x6008
 91#define DPLL_EN_DISP		(1 << 31)
 92#define DPLL_SEL_HDMI		(1 << 8)
 93#define DPLL_EN_HDMI		(1 << 1)
 94#define DPLL_EN_VGA		(1 << 0)
 95
 96#define DPLL_ADJUST     0x600C
 97#define DPLL_STATUS     0x6010
 98#define DPLL_UPDATE     0x6014
 99#define DPLL_DFT        0x6020
100
101struct intel_range {
102	int	min, max;
103};
104
105struct oaktrail_hdmi_limit {
106	struct intel_range vco, np, nr, nf;
107};
108
109struct oaktrail_hdmi_clock {
110	int np;
111	int nr;
112	int nf;
113	int dot;
114};
115
116#define VCO_MIN		320000
117#define VCO_MAX		1650000
118#define	NP_MIN		1
119#define	NP_MAX		15
120#define	NR_MIN		1
121#define	NR_MAX		64
122#define NF_MIN		2
123#define NF_MAX		4095
124
125static const struct oaktrail_hdmi_limit oaktrail_hdmi_limit = {
126	.vco = { .min = VCO_MIN,		.max = VCO_MAX },
127	.np  = { .min = NP_MIN,			.max = NP_MAX  },
128	.nr  = { .min = NR_MIN,			.max = NR_MAX  },
129	.nf  = { .min = NF_MIN,			.max = NF_MAX  },
130};
131
132static void oaktrail_hdmi_audio_enable(struct drm_device *dev)
133{
134	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
135	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
136
137	HDMI_WRITE(HDMI_HCR, 0x67);
138	HDMI_READ(HDMI_HCR);
139
140	HDMI_WRITE(0x51a8, 0x10);
141	HDMI_READ(0x51a8);
142
143	HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1);
144	HDMI_READ(HDMI_AUDIO_CTRL);
145}
146
147static void oaktrail_hdmi_audio_disable(struct drm_device *dev)
148{
149	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
150	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
151
152	HDMI_WRITE(0x51a8, 0x0);
153	HDMI_READ(0x51a8);
154
155	HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0);
156	HDMI_READ(HDMI_AUDIO_CTRL);
157
158	HDMI_WRITE(HDMI_HCR, 0x47);
159	HDMI_READ(HDMI_HCR);
160}
161
162static unsigned int htotal_calculate(struct drm_display_mode *mode)
163{
164	u32 new_crtc_htotal;
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 = to_drm_psb_private(dev);
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 = to_drm_psb_private(dev);
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 = to_drm_psb_private(dev);
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
625void oaktrail_hdmi_init(struct drm_device *dev,
626					struct psb_intel_mode_device *mode_dev)
627{
628	struct gma_encoder *gma_encoder;
629	struct gma_connector *gma_connector;
630	struct drm_connector *connector;
631	struct drm_encoder *encoder;
632
633	gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL);
634	if (!gma_encoder)
635		return;
636
637	gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL);
638	if (!gma_connector)
639		goto failed_connector;
640
641	connector = &gma_connector->base;
642	encoder = &gma_encoder->base;
643	drm_connector_init(dev, connector,
644			   &oaktrail_hdmi_connector_funcs,
645			   DRM_MODE_CONNECTOR_DVID);
646
647	drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
648
649	gma_connector_attach_encoder(gma_connector, gma_encoder);
650
651	gma_encoder->type = INTEL_OUTPUT_HDMI;
652	drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs);
653	drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs);
654
655	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
656	connector->interlace_allowed = false;
657	connector->doublescan_allowed = false;
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 = to_drm_psb_private(dev);
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 = to_drm_psb_private(dev);
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 = to_drm_psb_private(dev);
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 = to_drm_psb_private(dev);
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}