File Index
Files and directories
Sign in
FILE

oaktrail_hdmi.c

File preview with syntax highlighting.

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