cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

oaktrail_hdmi.c (24347B)


      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 = to_drm_psb_private(dev);
    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 = to_drm_psb_private(dev);
    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 = to_drm_psb_private(dev);
    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 = to_drm_psb_private(dev);
    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 = to_drm_psb_private(dev);
    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	dev_info(dev->dev, "HDMI initialised.\n");
    658
    659	return;
    660
    661failed_connector:
    662	kfree(gma_encoder);
    663}
    664
    665void oaktrail_hdmi_setup(struct drm_device *dev)
    666{
    667	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
    668	struct pci_dev *pdev;
    669	struct oaktrail_hdmi_dev *hdmi_dev;
    670	int ret;
    671
    672	pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
    673	if (!pdev)
    674		return;
    675
    676	hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL);
    677	if (!hdmi_dev) {
    678		dev_err(dev->dev, "failed to allocate memory\n");
    679		goto out;
    680	}
    681
    682
    683	ret = pci_enable_device(pdev);
    684	if (ret) {
    685		dev_err(dev->dev, "failed to enable hdmi controller\n");
    686		goto free;
    687	}
    688
    689	hdmi_dev->mmio = pci_resource_start(pdev, 0);
    690	hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
    691	hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
    692	if (!hdmi_dev->regs) {
    693		dev_err(dev->dev, "failed to map hdmi mmio\n");
    694		goto free;
    695	}
    696
    697	hdmi_dev->dev = pdev;
    698	pci_set_drvdata(pdev, hdmi_dev);
    699
    700	/* Initialize i2c controller */
    701	ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev);
    702	if (ret)
    703		dev_err(dev->dev, "HDMI I2C initialization failed\n");
    704
    705	dev_priv->hdmi_priv = hdmi_dev;
    706	oaktrail_hdmi_audio_disable(dev);
    707
    708	dev_info(dev->dev, "HDMI hardware present.\n");
    709
    710	return;
    711
    712free:
    713	kfree(hdmi_dev);
    714out:
    715	return;
    716}
    717
    718void oaktrail_hdmi_teardown(struct drm_device *dev)
    719{
    720	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
    721	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
    722	struct pci_dev *pdev;
    723
    724	if (hdmi_dev) {
    725		pdev = hdmi_dev->dev;
    726		pci_set_drvdata(pdev, NULL);
    727		oaktrail_hdmi_i2c_exit(pdev);
    728		iounmap(hdmi_dev->regs);
    729		kfree(hdmi_dev);
    730		pci_dev_put(pdev);
    731	}
    732}
    733
    734/* save HDMI register state */
    735void oaktrail_hdmi_save(struct drm_device *dev)
    736{
    737	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
    738	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
    739	struct psb_state *regs = &dev_priv->regs.psb;
    740	struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
    741	int i;
    742
    743	/* dpll */
    744	hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
    745	hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL);
    746	hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST);
    747	hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE);
    748	hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE);
    749
    750	/* pipe B */
    751	pipeb->conf = PSB_RVDC32(PIPEBCONF);
    752	pipeb->src = PSB_RVDC32(PIPEBSRC);
    753	pipeb->htotal = PSB_RVDC32(HTOTAL_B);
    754	pipeb->hblank = PSB_RVDC32(HBLANK_B);
    755	pipeb->hsync = PSB_RVDC32(HSYNC_B);
    756	pipeb->vtotal = PSB_RVDC32(VTOTAL_B);
    757	pipeb->vblank = PSB_RVDC32(VBLANK_B);
    758	pipeb->vsync = PSB_RVDC32(VSYNC_B);
    759
    760	hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF);
    761	hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC);
    762	hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B);
    763	hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B);
    764	hdmi_dev->savePCH_HSYNC_B  = PSB_RVDC32(PCH_HSYNC_B);
    765	hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B);
    766	hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B);
    767	hdmi_dev->savePCH_VSYNC_B  = PSB_RVDC32(PCH_VSYNC_B);
    768
    769	/* plane */
    770	pipeb->cntr = PSB_RVDC32(DSPBCNTR);
    771	pipeb->stride = PSB_RVDC32(DSPBSTRIDE);
    772	pipeb->addr = PSB_RVDC32(DSPBBASE);
    773	pipeb->surf = PSB_RVDC32(DSPBSURF);
    774	pipeb->linoff = PSB_RVDC32(DSPBLINOFF);
    775	pipeb->tileoff = PSB_RVDC32(DSPBTILEOFF);
    776
    777	/* cursor B */
    778	regs->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
    779	regs->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
    780	regs->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
    781
    782	/* save palette */
    783	for (i = 0; i < 256; i++)
    784		pipeb->palette[i] = PSB_RVDC32(PALETTE_B + (i << 2));
    785}
    786
    787/* restore HDMI register state */
    788void oaktrail_hdmi_restore(struct drm_device *dev)
    789{
    790	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
    791	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
    792	struct psb_state *regs = &dev_priv->regs.psb;
    793	struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
    794	int i;
    795
    796	/* dpll */
    797	PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
    798	PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL);
    799	PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
    800	PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
    801	PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
    802	udelay(150);
    803
    804	/* pipe */
    805	PSB_WVDC32(pipeb->src, PIPEBSRC);
    806	PSB_WVDC32(pipeb->htotal, HTOTAL_B);
    807	PSB_WVDC32(pipeb->hblank, HBLANK_B);
    808	PSB_WVDC32(pipeb->hsync,  HSYNC_B);
    809	PSB_WVDC32(pipeb->vtotal, VTOTAL_B);
    810	PSB_WVDC32(pipeb->vblank, VBLANK_B);
    811	PSB_WVDC32(pipeb->vsync,  VSYNC_B);
    812
    813	PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC);
    814	PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B);
    815	PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B);
    816	PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B,  PCH_HSYNC_B);
    817	PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B);
    818	PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B);
    819	PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B,  PCH_VSYNC_B);
    820
    821	PSB_WVDC32(pipeb->conf, PIPEBCONF);
    822	PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
    823
    824	/* plane */
    825	PSB_WVDC32(pipeb->linoff, DSPBLINOFF);
    826	PSB_WVDC32(pipeb->stride, DSPBSTRIDE);
    827	PSB_WVDC32(pipeb->tileoff, DSPBTILEOFF);
    828	PSB_WVDC32(pipeb->cntr, DSPBCNTR);
    829	PSB_WVDC32(pipeb->surf, DSPBSURF);
    830
    831	/* cursor B */
    832	PSB_WVDC32(regs->saveDSPBCURSOR_CTRL, CURBCNTR);
    833	PSB_WVDC32(regs->saveDSPBCURSOR_POS, CURBPOS);
    834	PSB_WVDC32(regs->saveDSPBCURSOR_BASE, CURBBASE);
    835
    836	/* restore palette */
    837	for (i = 0; i < 256; i++)
    838		PSB_WVDC32(pipeb->palette[i], PALETTE_B + (i << 2));
    839}