0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include <linux/delay.h>
0028
0029 #include <drm/drm.h>
0030 #include <drm/drm_edid.h>
0031 #include <drm/drm_simple_kms_helper.h>
0032
0033 #include "psb_drv.h"
0034 #include "psb_intel_drv.h"
0035 #include "psb_intel_reg.h"
0036
0037 #define HDMI_READ(reg) readl(hdmi_dev->regs + (reg))
0038 #define HDMI_WRITE(reg, val) writel(val, hdmi_dev->regs + (reg))
0039
0040 #define HDMI_HCR 0x1000
0041 #define HCR_ENABLE_HDCP (1 << 5)
0042 #define HCR_ENABLE_AUDIO (1 << 2)
0043 #define HCR_ENABLE_PIXEL (1 << 1)
0044 #define HCR_ENABLE_TMDS (1 << 0)
0045
0046 #define HDMI_HICR 0x1004
0047 #define HDMI_HSR 0x1008
0048 #define HDMI_HISR 0x100C
0049 #define HDMI_DETECT_HDP (1 << 0)
0050
0051 #define HDMI_VIDEO_REG 0x3000
0052 #define HDMI_UNIT_EN (1 << 7)
0053 #define HDMI_MODE_OUTPUT (1 << 0)
0054 #define HDMI_HBLANK_A 0x3100
0055
0056 #define HDMI_AUDIO_CTRL 0x4000
0057 #define HDMI_ENABLE_AUDIO (1 << 0)
0058
0059 #define PCH_HTOTAL_B 0x3100
0060 #define PCH_HBLANK_B 0x3104
0061 #define PCH_HSYNC_B 0x3108
0062 #define PCH_VTOTAL_B 0x310C
0063 #define PCH_VBLANK_B 0x3110
0064 #define PCH_VSYNC_B 0x3114
0065 #define PCH_PIPEBSRC 0x311C
0066
0067 #define PCH_PIPEB_DSL 0x3800
0068 #define PCH_PIPEB_SLC 0x3804
0069 #define PCH_PIPEBCONF 0x3808
0070 #define PCH_PIPEBSTAT 0x3824
0071
0072 #define CDVO_DFT 0x5000
0073 #define CDVO_SLEWRATE 0x5004
0074 #define CDVO_STRENGTH 0x5008
0075 #define CDVO_RCOMP 0x500C
0076
0077 #define DPLL_CTRL 0x6000
0078 #define DPLL_PDIV_SHIFT 16
0079 #define DPLL_PDIV_MASK (0xf << 16)
0080 #define DPLL_PWRDN (1 << 4)
0081 #define DPLL_RESET (1 << 3)
0082 #define DPLL_FASTEN (1 << 2)
0083 #define DPLL_ENSTAT (1 << 1)
0084 #define DPLL_DITHEN (1 << 0)
0085
0086 #define DPLL_DIV_CTRL 0x6004
0087 #define DPLL_CLKF_MASK 0xffffffc0
0088 #define DPLL_CLKR_MASK (0x3f)
0089
0090 #define DPLL_CLK_ENABLE 0x6008
0091 #define DPLL_EN_DISP (1 << 31)
0092 #define DPLL_SEL_HDMI (1 << 8)
0093 #define DPLL_EN_HDMI (1 << 1)
0094 #define DPLL_EN_VGA (1 << 0)
0095
0096 #define DPLL_ADJUST 0x600C
0097 #define DPLL_STATUS 0x6010
0098 #define DPLL_UPDATE 0x6014
0099 #define DPLL_DFT 0x6020
0100
0101 struct intel_range {
0102 int min, max;
0103 };
0104
0105 struct oaktrail_hdmi_limit {
0106 struct intel_range vco, np, nr, nf;
0107 };
0108
0109 struct oaktrail_hdmi_clock {
0110 int np;
0111 int nr;
0112 int nf;
0113 int dot;
0114 };
0115
0116 #define VCO_MIN 320000
0117 #define VCO_MAX 1650000
0118 #define NP_MIN 1
0119 #define NP_MAX 15
0120 #define NR_MIN 1
0121 #define NR_MAX 64
0122 #define NF_MIN 2
0123 #define NF_MAX 4095
0124
0125 static const struct oaktrail_hdmi_limit oaktrail_hdmi_limit = {
0126 .vco = { .min = VCO_MIN, .max = VCO_MAX },
0127 .np = { .min = NP_MIN, .max = NP_MAX },
0128 .nr = { .min = NR_MIN, .max = NR_MAX },
0129 .nf = { .min = NF_MIN, .max = NF_MAX },
0130 };
0131
0132 static void oaktrail_hdmi_audio_enable(struct drm_device *dev)
0133 {
0134 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0135 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0136
0137 HDMI_WRITE(HDMI_HCR, 0x67);
0138 HDMI_READ(HDMI_HCR);
0139
0140 HDMI_WRITE(0x51a8, 0x10);
0141 HDMI_READ(0x51a8);
0142
0143 HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1);
0144 HDMI_READ(HDMI_AUDIO_CTRL);
0145 }
0146
0147 static void oaktrail_hdmi_audio_disable(struct drm_device *dev)
0148 {
0149 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0150 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0151
0152 HDMI_WRITE(0x51a8, 0x0);
0153 HDMI_READ(0x51a8);
0154
0155 HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0);
0156 HDMI_READ(HDMI_AUDIO_CTRL);
0157
0158 HDMI_WRITE(HDMI_HCR, 0x47);
0159 HDMI_READ(HDMI_HCR);
0160 }
0161
0162 static unsigned int htotal_calculate(struct drm_display_mode *mode)
0163 {
0164 u32 new_crtc_htotal;
0165
0166
0167
0168
0169
0170 new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock;
0171
0172 DRM_DEBUG_KMS("new crtc htotal 0x%4x\n", new_crtc_htotal);
0173 return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16);
0174 }
0175
0176 static void oaktrail_hdmi_find_dpll(struct drm_crtc *crtc, int target,
0177 int refclk, struct oaktrail_hdmi_clock *best_clock)
0178 {
0179 int np_min, np_max, nr_min, nr_max;
0180 int np, nr, nf;
0181
0182 np_min = DIV_ROUND_UP(oaktrail_hdmi_limit.vco.min, target * 10);
0183 np_max = oaktrail_hdmi_limit.vco.max / (target * 10);
0184 if (np_min < oaktrail_hdmi_limit.np.min)
0185 np_min = oaktrail_hdmi_limit.np.min;
0186 if (np_max > oaktrail_hdmi_limit.np.max)
0187 np_max = oaktrail_hdmi_limit.np.max;
0188
0189 nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max));
0190 nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min));
0191 if (nr_min < oaktrail_hdmi_limit.nr.min)
0192 nr_min = oaktrail_hdmi_limit.nr.min;
0193 if (nr_max > oaktrail_hdmi_limit.nr.max)
0194 nr_max = oaktrail_hdmi_limit.nr.max;
0195
0196 np = DIV_ROUND_UP((refclk * 1000), (target * 10 * nr_max));
0197 nr = DIV_ROUND_UP((refclk * 1000), (target * 10 * np));
0198 nf = DIV_ROUND_CLOSEST((target * 10 * np * nr), refclk);
0199 DRM_DEBUG_KMS("np, nr, nf %d %d %d\n", np, nr, nf);
0200
0201
0202
0203
0204
0205 best_clock->np = np;
0206 best_clock->nr = nr - 1;
0207 best_clock->nf = (nf << 14);
0208 }
0209
0210 static void scu_busy_loop(void __iomem *scu_base)
0211 {
0212 u32 status = 0;
0213 u32 loop_count = 0;
0214
0215 status = readl(scu_base + 0x04);
0216 while (status & 1) {
0217 udelay(1);
0218 status = readl(scu_base + 0x04);
0219 loop_count++;
0220
0221 if (loop_count > 1000) {
0222 DRM_DEBUG_KMS("SCU IPC timed out");
0223 return;
0224 }
0225 }
0226 }
0227
0228
0229
0230
0231
0232
0233
0234 static void oaktrail_hdmi_reset(struct drm_device *dev)
0235 {
0236 void __iomem *base;
0237 unsigned long scu_ipc_mmio = 0xff11c000UL;
0238 int scu_len = 1024;
0239
0240 base = ioremap((resource_size_t)scu_ipc_mmio, scu_len);
0241 if (base == NULL) {
0242 DRM_ERROR("failed to map scu mmio\n");
0243 return;
0244 }
0245
0246
0247 writel(0xff11d118, base + 0x0c);
0248 writel(0x7fffffdf, base + 0x80);
0249 writel(0x42005, base + 0x0);
0250 scu_busy_loop(base);
0251
0252
0253 writel(0xff11d118, base + 0x0c);
0254 writel(0x7fffffff, base + 0x80);
0255 writel(0x42005, base + 0x0);
0256 scu_busy_loop(base);
0257
0258 iounmap(base);
0259 }
0260
0261 int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc,
0262 struct drm_display_mode *mode,
0263 struct drm_display_mode *adjusted_mode,
0264 int x, int y,
0265 struct drm_framebuffer *old_fb)
0266 {
0267 struct drm_device *dev = crtc->dev;
0268 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0269 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0270 int pipe = 1;
0271 int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
0272 int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
0273 int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
0274 int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
0275 int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
0276 int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
0277 int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
0278 int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
0279 int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
0280 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
0281 int refclk;
0282 struct oaktrail_hdmi_clock clock;
0283 u32 dspcntr, pipeconf, dpll, temp;
0284 int dspcntr_reg = DSPBCNTR;
0285
0286 if (!gma_power_begin(dev, true))
0287 return 0;
0288
0289
0290 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
0291
0292
0293 dpll = REG_READ(DPLL_CTRL);
0294 if ((dpll & DPLL_PWRDN) == 0) {
0295 REG_WRITE(DPLL_CTRL, dpll | (DPLL_PWRDN | DPLL_RESET));
0296 REG_WRITE(DPLL_DIV_CTRL, 0x00000000);
0297 REG_WRITE(DPLL_STATUS, 0x1);
0298 }
0299 udelay(150);
0300
0301
0302 oaktrail_hdmi_reset(dev);
0303
0304
0305 refclk = 25000;
0306 oaktrail_hdmi_find_dpll(crtc, adjusted_mode->clock, refclk, &clock);
0307
0308
0309 dpll = REG_READ(DPLL_CTRL);
0310 dpll &= ~DPLL_PDIV_MASK;
0311 dpll &= ~(DPLL_PWRDN | DPLL_RESET);
0312 REG_WRITE(DPLL_CTRL, 0x00000008);
0313 REG_WRITE(DPLL_DIV_CTRL, ((clock.nf << 6) | clock.nr));
0314 REG_WRITE(DPLL_ADJUST, ((clock.nf >> 14) - 1));
0315 REG_WRITE(DPLL_CTRL, (dpll | (clock.np << DPLL_PDIV_SHIFT) | DPLL_ENSTAT | DPLL_DITHEN));
0316 REG_WRITE(DPLL_UPDATE, 0x80000000);
0317 REG_WRITE(DPLL_CLK_ENABLE, 0x80050102);
0318 udelay(150);
0319
0320
0321 HDMI_WRITE(0x1004, 0x1fd);
0322 HDMI_WRITE(0x2000, 0x1);
0323 HDMI_WRITE(0x2008, 0x0);
0324 HDMI_WRITE(0x3130, 0x8);
0325 HDMI_WRITE(0x101c, 0x1800810);
0326
0327 temp = htotal_calculate(adjusted_mode);
0328 REG_WRITE(htot_reg, temp);
0329 REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
0330 REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
0331 REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
0332 REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
0333 REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
0334 REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1));
0335
0336 REG_WRITE(PCH_HTOTAL_B, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16));
0337 REG_WRITE(PCH_HBLANK_B, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
0338 REG_WRITE(PCH_HSYNC_B, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
0339 REG_WRITE(PCH_VTOTAL_B, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
0340 REG_WRITE(PCH_VBLANK_B, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
0341 REG_WRITE(PCH_VSYNC_B, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
0342 REG_WRITE(PCH_PIPEBSRC, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1));
0343
0344 temp = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
0345 HDMI_WRITE(HDMI_HBLANK_A, ((adjusted_mode->crtc_hdisplay - 1) << 16) | temp);
0346
0347 REG_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
0348 REG_WRITE(dsppos_reg, 0);
0349
0350
0351 {
0352 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
0353 crtc_funcs->mode_set_base(crtc, x, y, old_fb);
0354 }
0355
0356
0357 dspcntr = REG_READ(dspcntr_reg);
0358 dspcntr |= DISPPLANE_GAMMA_ENABLE;
0359 dspcntr |= DISPPLANE_SEL_PIPE_B;
0360 dspcntr |= DISPLAY_PLANE_ENABLE;
0361
0362
0363 pipeconf = REG_READ(pipeconf_reg);
0364 pipeconf |= PIPEACONF_ENABLE;
0365
0366 REG_WRITE(pipeconf_reg, pipeconf);
0367 REG_READ(pipeconf_reg);
0368
0369 REG_WRITE(PCH_PIPEBCONF, pipeconf);
0370 REG_READ(PCH_PIPEBCONF);
0371 gma_wait_for_vblank(dev);
0372
0373 REG_WRITE(dspcntr_reg, dspcntr);
0374 gma_wait_for_vblank(dev);
0375
0376 gma_power_end(dev);
0377
0378 return 0;
0379 }
0380
0381 void oaktrail_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode)
0382 {
0383 struct drm_device *dev = crtc->dev;
0384 u32 temp;
0385
0386 DRM_DEBUG_KMS("%s %d\n", __func__, mode);
0387
0388 switch (mode) {
0389 case DRM_MODE_DPMS_OFF:
0390 REG_WRITE(VGACNTRL, 0x80000000);
0391
0392
0393 temp = REG_READ(DSPBCNTR);
0394 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
0395 REG_WRITE(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
0396 REG_READ(DSPBCNTR);
0397
0398 REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
0399 REG_READ(DSPBSURF);
0400 }
0401
0402
0403 temp = REG_READ(PIPEBCONF);
0404 if ((temp & PIPEACONF_ENABLE) != 0) {
0405 REG_WRITE(PIPEBCONF, temp & ~PIPEACONF_ENABLE);
0406 REG_READ(PIPEBCONF);
0407 }
0408
0409
0410 temp = REG_READ(PCH_PIPEBCONF);
0411 if ((temp & PIPEACONF_ENABLE) != 0) {
0412 REG_WRITE(PCH_PIPEBCONF, temp & ~PIPEACONF_ENABLE);
0413 REG_READ(PCH_PIPEBCONF);
0414 }
0415
0416
0417 udelay(150);
0418
0419
0420 temp = REG_READ(DPLL_CTRL);
0421 if ((temp & DPLL_PWRDN) == 0) {
0422 REG_WRITE(DPLL_CTRL, temp | (DPLL_PWRDN | DPLL_RESET));
0423 REG_WRITE(DPLL_STATUS, 0x1);
0424 }
0425
0426
0427 udelay(150);
0428
0429 break;
0430 case DRM_MODE_DPMS_ON:
0431 case DRM_MODE_DPMS_STANDBY:
0432 case DRM_MODE_DPMS_SUSPEND:
0433
0434 temp = REG_READ(DPLL_CTRL);
0435 if ((temp & DPLL_PWRDN) != 0) {
0436 REG_WRITE(DPLL_CTRL, temp & ~(DPLL_PWRDN | DPLL_RESET));
0437 temp = REG_READ(DPLL_CLK_ENABLE);
0438 REG_WRITE(DPLL_CLK_ENABLE, temp | DPLL_EN_DISP | DPLL_SEL_HDMI | DPLL_EN_HDMI);
0439 REG_READ(DPLL_CLK_ENABLE);
0440 }
0441
0442 udelay(150);
0443
0444
0445 temp = REG_READ(PIPEBCONF);
0446 if ((temp & PIPEACONF_ENABLE) == 0) {
0447 REG_WRITE(PIPEBCONF, temp | PIPEACONF_ENABLE);
0448 REG_READ(PIPEBCONF);
0449 }
0450
0451
0452 temp = REG_READ(PCH_PIPEBCONF);
0453 if ((temp & PIPEACONF_ENABLE) == 0) {
0454 REG_WRITE(PCH_PIPEBCONF, temp | PIPEACONF_ENABLE);
0455 REG_READ(PCH_PIPEBCONF);
0456 }
0457
0458 gma_wait_for_vblank(dev);
0459
0460
0461 temp = REG_READ(DSPBCNTR);
0462 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
0463 REG_WRITE(DSPBCNTR, temp | DISPLAY_PLANE_ENABLE);
0464
0465 REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
0466 REG_READ(DSPBSURF);
0467 }
0468
0469 gma_crtc_load_lut(crtc);
0470 }
0471
0472
0473 REG_WRITE(DSPARB, 0x00003fbf);
0474
0475
0476 REG_WRITE(0x70034, 0x3f880a0a);
0477
0478
0479 REG_WRITE(0x70038, 0x0b060808);
0480
0481
0482 REG_WRITE(0x70050, 0x08030404);
0483
0484
0485 REG_WRITE(0x70054, 0x04040404);
0486
0487
0488 REG_WRITE(0x70400, 0x4000);
0489
0490 return;
0491 }
0492
0493 static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode)
0494 {
0495 static int dpms_mode = -1;
0496
0497 struct drm_device *dev = encoder->dev;
0498 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0499 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0500 u32 temp;
0501
0502 if (dpms_mode == mode)
0503 return;
0504
0505 if (mode != DRM_MODE_DPMS_ON)
0506 temp = 0x0;
0507 else
0508 temp = 0x99;
0509
0510 dpms_mode = mode;
0511 HDMI_WRITE(HDMI_VIDEO_REG, temp);
0512 }
0513
0514 static enum drm_mode_status oaktrail_hdmi_mode_valid(struct drm_connector *connector,
0515 struct drm_display_mode *mode)
0516 {
0517 if (mode->clock > 165000)
0518 return MODE_CLOCK_HIGH;
0519 if (mode->clock < 20000)
0520 return MODE_CLOCK_LOW;
0521
0522 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
0523 return MODE_NO_DBLESCAN;
0524
0525 return MODE_OK;
0526 }
0527
0528 static enum drm_connector_status
0529 oaktrail_hdmi_detect(struct drm_connector *connector, bool force)
0530 {
0531 enum drm_connector_status status;
0532 struct drm_device *dev = connector->dev;
0533 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0534 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0535 u32 temp;
0536
0537 temp = HDMI_READ(HDMI_HSR);
0538 DRM_DEBUG_KMS("HDMI_HSR %x\n", temp);
0539
0540 if ((temp & HDMI_DETECT_HDP) != 0)
0541 status = connector_status_connected;
0542 else
0543 status = connector_status_disconnected;
0544
0545 return status;
0546 }
0547
0548 static const unsigned char raw_edid[] = {
0549 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0,
0550 0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78,
0551 0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5,
0552 0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01,
0553 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
0554 0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a,
0555 0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35,
0556 0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44,
0557 0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20,
0558 0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a,
0559 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d
0560 };
0561
0562 static int oaktrail_hdmi_get_modes(struct drm_connector *connector)
0563 {
0564 struct i2c_adapter *i2c_adap;
0565 struct edid *edid;
0566 int ret = 0;
0567
0568
0569
0570
0571
0572
0573 i2c_adap = i2c_get_adapter(3);
0574 if (i2c_adap == NULL) {
0575 DRM_ERROR("No ddc adapter available!\n");
0576 edid = (struct edid *)raw_edid;
0577 } else {
0578 edid = (struct edid *)raw_edid;
0579
0580 }
0581
0582 if (edid) {
0583 drm_connector_update_edid_property(connector, edid);
0584 ret = drm_add_edid_modes(connector, edid);
0585 }
0586 return ret;
0587 }
0588
0589 static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder,
0590 struct drm_display_mode *mode,
0591 struct drm_display_mode *adjusted_mode)
0592 {
0593 struct drm_device *dev = encoder->dev;
0594
0595 oaktrail_hdmi_audio_enable(dev);
0596 return;
0597 }
0598
0599 static void oaktrail_hdmi_destroy(struct drm_connector *connector)
0600 {
0601 return;
0602 }
0603
0604 static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = {
0605 .dpms = oaktrail_hdmi_dpms,
0606 .prepare = gma_encoder_prepare,
0607 .mode_set = oaktrail_hdmi_mode_set,
0608 .commit = gma_encoder_commit,
0609 };
0610
0611 static const struct drm_connector_helper_funcs
0612 oaktrail_hdmi_connector_helper_funcs = {
0613 .get_modes = oaktrail_hdmi_get_modes,
0614 .mode_valid = oaktrail_hdmi_mode_valid,
0615 .best_encoder = gma_best_encoder,
0616 };
0617
0618 static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = {
0619 .dpms = drm_helper_connector_dpms,
0620 .detect = oaktrail_hdmi_detect,
0621 .fill_modes = drm_helper_probe_single_connector_modes,
0622 .destroy = oaktrail_hdmi_destroy,
0623 };
0624
0625 void oaktrail_hdmi_init(struct drm_device *dev,
0626 struct psb_intel_mode_device *mode_dev)
0627 {
0628 struct gma_encoder *gma_encoder;
0629 struct gma_connector *gma_connector;
0630 struct drm_connector *connector;
0631 struct drm_encoder *encoder;
0632
0633 gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL);
0634 if (!gma_encoder)
0635 return;
0636
0637 gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL);
0638 if (!gma_connector)
0639 goto failed_connector;
0640
0641 connector = &gma_connector->base;
0642 encoder = &gma_encoder->base;
0643 drm_connector_init(dev, connector,
0644 &oaktrail_hdmi_connector_funcs,
0645 DRM_MODE_CONNECTOR_DVID);
0646
0647 drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
0648
0649 gma_connector_attach_encoder(gma_connector, gma_encoder);
0650
0651 gma_encoder->type = INTEL_OUTPUT_HDMI;
0652 drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs);
0653 drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs);
0654
0655 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
0656 connector->interlace_allowed = false;
0657 connector->doublescan_allowed = false;
0658 dev_info(dev->dev, "HDMI initialised.\n");
0659
0660 return;
0661
0662 failed_connector:
0663 kfree(gma_encoder);
0664 }
0665
0666 void oaktrail_hdmi_setup(struct drm_device *dev)
0667 {
0668 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0669 struct pci_dev *pdev;
0670 struct oaktrail_hdmi_dev *hdmi_dev;
0671 int ret;
0672
0673 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
0674 if (!pdev)
0675 return;
0676
0677 hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL);
0678 if (!hdmi_dev) {
0679 dev_err(dev->dev, "failed to allocate memory\n");
0680 goto out;
0681 }
0682
0683
0684 ret = pci_enable_device(pdev);
0685 if (ret) {
0686 dev_err(dev->dev, "failed to enable hdmi controller\n");
0687 goto free;
0688 }
0689
0690 hdmi_dev->mmio = pci_resource_start(pdev, 0);
0691 hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
0692 hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
0693 if (!hdmi_dev->regs) {
0694 dev_err(dev->dev, "failed to map hdmi mmio\n");
0695 goto free;
0696 }
0697
0698 hdmi_dev->dev = pdev;
0699 pci_set_drvdata(pdev, hdmi_dev);
0700
0701
0702 ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev);
0703 if (ret)
0704 dev_err(dev->dev, "HDMI I2C initialization failed\n");
0705
0706 dev_priv->hdmi_priv = hdmi_dev;
0707 oaktrail_hdmi_audio_disable(dev);
0708
0709 dev_info(dev->dev, "HDMI hardware present.\n");
0710
0711 return;
0712
0713 free:
0714 kfree(hdmi_dev);
0715 out:
0716 return;
0717 }
0718
0719 void oaktrail_hdmi_teardown(struct drm_device *dev)
0720 {
0721 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0722 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0723 struct pci_dev *pdev;
0724
0725 if (hdmi_dev) {
0726 pdev = hdmi_dev->dev;
0727 pci_set_drvdata(pdev, NULL);
0728 oaktrail_hdmi_i2c_exit(pdev);
0729 iounmap(hdmi_dev->regs);
0730 kfree(hdmi_dev);
0731 pci_dev_put(pdev);
0732 }
0733 }
0734
0735
0736 void oaktrail_hdmi_save(struct drm_device *dev)
0737 {
0738 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0739 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0740 struct psb_state *regs = &dev_priv->regs.psb;
0741 struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
0742 int i;
0743
0744
0745 hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
0746 hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL);
0747 hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST);
0748 hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE);
0749 hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE);
0750
0751
0752 pipeb->conf = PSB_RVDC32(PIPEBCONF);
0753 pipeb->src = PSB_RVDC32(PIPEBSRC);
0754 pipeb->htotal = PSB_RVDC32(HTOTAL_B);
0755 pipeb->hblank = PSB_RVDC32(HBLANK_B);
0756 pipeb->hsync = PSB_RVDC32(HSYNC_B);
0757 pipeb->vtotal = PSB_RVDC32(VTOTAL_B);
0758 pipeb->vblank = PSB_RVDC32(VBLANK_B);
0759 pipeb->vsync = PSB_RVDC32(VSYNC_B);
0760
0761 hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF);
0762 hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC);
0763 hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B);
0764 hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B);
0765 hdmi_dev->savePCH_HSYNC_B = PSB_RVDC32(PCH_HSYNC_B);
0766 hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B);
0767 hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B);
0768 hdmi_dev->savePCH_VSYNC_B = PSB_RVDC32(PCH_VSYNC_B);
0769
0770
0771 pipeb->cntr = PSB_RVDC32(DSPBCNTR);
0772 pipeb->stride = PSB_RVDC32(DSPBSTRIDE);
0773 pipeb->addr = PSB_RVDC32(DSPBBASE);
0774 pipeb->surf = PSB_RVDC32(DSPBSURF);
0775 pipeb->linoff = PSB_RVDC32(DSPBLINOFF);
0776 pipeb->tileoff = PSB_RVDC32(DSPBTILEOFF);
0777
0778
0779 regs->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
0780 regs->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
0781 regs->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
0782
0783
0784 for (i = 0; i < 256; i++)
0785 pipeb->palette[i] = PSB_RVDC32(PALETTE_B + (i << 2));
0786 }
0787
0788
0789 void oaktrail_hdmi_restore(struct drm_device *dev)
0790 {
0791 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0792 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0793 struct psb_state *regs = &dev_priv->regs.psb;
0794 struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
0795 int i;
0796
0797
0798 PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
0799 PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL);
0800 PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
0801 PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
0802 PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
0803 udelay(150);
0804
0805
0806 PSB_WVDC32(pipeb->src, PIPEBSRC);
0807 PSB_WVDC32(pipeb->htotal, HTOTAL_B);
0808 PSB_WVDC32(pipeb->hblank, HBLANK_B);
0809 PSB_WVDC32(pipeb->hsync, HSYNC_B);
0810 PSB_WVDC32(pipeb->vtotal, VTOTAL_B);
0811 PSB_WVDC32(pipeb->vblank, VBLANK_B);
0812 PSB_WVDC32(pipeb->vsync, VSYNC_B);
0813
0814 PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC);
0815 PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B);
0816 PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B);
0817 PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B, PCH_HSYNC_B);
0818 PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B);
0819 PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B);
0820 PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B, PCH_VSYNC_B);
0821
0822 PSB_WVDC32(pipeb->conf, PIPEBCONF);
0823 PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
0824
0825
0826 PSB_WVDC32(pipeb->linoff, DSPBLINOFF);
0827 PSB_WVDC32(pipeb->stride, DSPBSTRIDE);
0828 PSB_WVDC32(pipeb->tileoff, DSPBTILEOFF);
0829 PSB_WVDC32(pipeb->cntr, DSPBCNTR);
0830 PSB_WVDC32(pipeb->surf, DSPBSURF);
0831
0832
0833 PSB_WVDC32(regs->saveDSPBCURSOR_CTRL, CURBCNTR);
0834 PSB_WVDC32(regs->saveDSPBCURSOR_POS, CURBPOS);
0835 PSB_WVDC32(regs->saveDSPBCURSOR_BASE, CURBBASE);
0836
0837
0838 for (i = 0; i < 256; i++)
0839 PSB_WVDC32(pipeb->palette[i], PALETTE_B + (i << 2));
0840 }