Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
oaktrail_hdmi.c
Go to the documentation of this file.
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 <[email protected]>
25  */
26 
27 #include <drm/drmP.h>
28 #include <drm/drm.h>
29 #include "psb_intel_drv.h"
30 #include "psb_intel_reg.h"
31 #include "psb_drv.h"
32 
33 #define HDMI_READ(reg) readl(hdmi_dev->regs + (reg))
34 #define HDMI_WRITE(reg, val) writel(val, hdmi_dev->regs + (reg))
35 
36 #define HDMI_HCR 0x1000
37 #define HCR_ENABLE_HDCP (1 << 5)
38 #define HCR_ENABLE_AUDIO (1 << 2)
39 #define HCR_ENABLE_PIXEL (1 << 1)
40 #define HCR_ENABLE_TMDS (1 << 0)
41 
42 #define HDMI_HICR 0x1004
43 #define HDMI_HSR 0x1008
44 #define HDMI_HISR 0x100C
45 #define HDMI_DETECT_HDP (1 << 0)
46 
47 #define HDMI_VIDEO_REG 0x3000
48 #define HDMI_UNIT_EN (1 << 7)
49 #define HDMI_MODE_OUTPUT (1 << 0)
50 #define HDMI_HBLANK_A 0x3100
51 
52 #define HDMI_AUDIO_CTRL 0x4000
53 #define HDMI_ENABLE_AUDIO (1 << 0)
54 
55 #define PCH_HTOTAL_B 0x3100
56 #define PCH_HBLANK_B 0x3104
57 #define PCH_HSYNC_B 0x3108
58 #define PCH_VTOTAL_B 0x310C
59 #define PCH_VBLANK_B 0x3110
60 #define PCH_VSYNC_B 0x3114
61 #define PCH_PIPEBSRC 0x311C
62 
63 #define PCH_PIPEB_DSL 0x3800
64 #define PCH_PIPEB_SLC 0x3804
65 #define PCH_PIPEBCONF 0x3808
66 #define PCH_PIPEBSTAT 0x3824
67 
68 #define CDVO_DFT 0x5000
69 #define CDVO_SLEWRATE 0x5004
70 #define CDVO_STRENGTH 0x5008
71 #define CDVO_RCOMP 0x500C
72 
73 #define DPLL_CTRL 0x6000
74 #define DPLL_PDIV_SHIFT 16
75 #define DPLL_PDIV_MASK (0xf << 16)
76 #define DPLL_PWRDN (1 << 4)
77 #define DPLL_RESET (1 << 3)
78 #define DPLL_FASTEN (1 << 2)
79 #define DPLL_ENSTAT (1 << 1)
80 #define DPLL_DITHEN (1 << 0)
81 
82 #define DPLL_DIV_CTRL 0x6004
83 #define DPLL_CLKF_MASK 0xffffffc0
84 #define DPLL_CLKR_MASK (0x3f)
85 
86 #define DPLL_CLK_ENABLE 0x6008
87 #define DPLL_EN_DISP (1 << 31)
88 #define DPLL_SEL_HDMI (1 << 8)
89 #define DPLL_EN_HDMI (1 << 1)
90 #define DPLL_EN_VGA (1 << 0)
91 
92 #define DPLL_ADJUST 0x600C
93 #define DPLL_STATUS 0x6010
94 #define DPLL_UPDATE 0x6014
95 #define DPLL_DFT 0x6020
96 
97 struct intel_range {
98  int min, max;
99 };
100 
102  struct intel_range vco, np, nr, nf;
103 };
104 
106  int np;
107  int nr;
108  int nf;
109  int dot;
110 };
111 
112 #define VCO_MIN 320000
113 #define VCO_MAX 1650000
114 #define NP_MIN 1
115 #define NP_MAX 15
116 #define NR_MIN 1
117 #define NR_MAX 64
118 #define NF_MIN 2
119 #define NF_MAX 4095
120 
121 static const struct oaktrail_hdmi_limit oaktrail_hdmi_limit = {
122  .vco = { .min = VCO_MIN, .max = VCO_MAX },
123  .np = { .min = NP_MIN, .max = NP_MAX },
124  .nr = { .min = NR_MIN, .max = NR_MAX },
125  .nf = { .min = NF_MIN, .max = NF_MAX },
126 };
127 
128 static void oaktrail_hdmi_audio_enable(struct drm_device *dev)
129 {
130  struct drm_psb_private *dev_priv = dev->dev_private;
131  struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
132 
133  HDMI_WRITE(HDMI_HCR, 0x67);
135 
136  HDMI_WRITE(0x51a8, 0x10);
137  HDMI_READ(0x51a8);
138 
141 }
142 
143 static void oaktrail_hdmi_audio_disable(struct drm_device *dev)
144 {
145  struct drm_psb_private *dev_priv = dev->dev_private;
146  struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
147 
148  HDMI_WRITE(0x51a8, 0x0);
149  HDMI_READ(0x51a8);
150 
153 
154  HDMI_WRITE(HDMI_HCR, 0x47);
156 }
157 
158 static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode)
159 {
160  static int dpms_mode = -1;
161 
162  struct drm_device *dev = encoder->dev;
163  struct drm_psb_private *dev_priv = dev->dev_private;
164  struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
165  u32 temp;
166 
167  if (dpms_mode == mode)
168  return;
169 
170  if (mode != DRM_MODE_DPMS_ON)
171  temp = 0x0;
172  else
173  temp = 0x99;
174 
175  dpms_mode = mode;
176  HDMI_WRITE(HDMI_VIDEO_REG, temp);
177 }
178 
179 static int oaktrail_hdmi_mode_valid(struct drm_connector *connector,
180  struct drm_display_mode *mode)
181 {
182  if (mode->clock > 165000)
183  return MODE_CLOCK_HIGH;
184  if (mode->clock < 20000)
185  return MODE_CLOCK_LOW;
186 
187  if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
188  return MODE_NO_DBLESCAN;
189 
190  return MODE_OK;
191 }
192 
193 static bool oaktrail_hdmi_mode_fixup(struct drm_encoder *encoder,
194  const struct drm_display_mode *mode,
195  struct drm_display_mode *adjusted_mode)
196 {
197  return true;
198 }
199 
200 static enum drm_connector_status
201 oaktrail_hdmi_detect(struct drm_connector *connector, bool force)
202 {
204  struct drm_device *dev = connector->dev;
205  struct drm_psb_private *dev_priv = dev->dev_private;
206  struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
207  u32 temp;
208 
209  temp = HDMI_READ(HDMI_HSR);
210  DRM_DEBUG_KMS("HDMI_HSR %x\n", temp);
211 
212  if ((temp & HDMI_DETECT_HDP) != 0)
214  else
216 
217  return status;
218 }
219 
220 static const unsigned char raw_edid[] = {
221  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0,
222  0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78,
223  0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5,
224  0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01,
225  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
226  0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a,
227  0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35,
228  0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44,
229  0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20,
230  0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a,
231  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d
232 };
233 
234 static int oaktrail_hdmi_get_modes(struct drm_connector *connector)
235 {
236  struct drm_device *dev = connector->dev;
237  struct drm_psb_private *dev_priv = dev->dev_private;
238  struct i2c_adapter *i2c_adap;
239  struct edid *edid;
240  struct drm_display_mode *mode, *t;
241  int i = 0, ret = 0;
242 
243  i2c_adap = i2c_get_adapter(3);
244  if (i2c_adap == NULL) {
245  DRM_ERROR("No ddc adapter available!\n");
246  edid = (struct edid *)raw_edid;
247  } else {
248  edid = (struct edid *)raw_edid;
249  /* FIXME ? edid = drm_get_edid(connector, i2c_adap); */
250  }
251 
252  if (edid) {
254  ret = drm_add_edid_modes(connector, edid);
255  }
256 
257  /*
258  * prune modes that require frame buffer bigger than stolen mem
259  */
260  list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
261  if ((mode->hdisplay * mode->vdisplay * 4) >= dev_priv->vram_stolen_size) {
262  i++;
263  drm_mode_remove(connector, mode);
264  }
265  }
266  return ret - i;
267 }
268 
269 static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder,
270  struct drm_display_mode *mode,
271  struct drm_display_mode *adjusted_mode)
272 {
273  struct drm_device *dev = encoder->dev;
274 
275  oaktrail_hdmi_audio_enable(dev);
276  return;
277 }
278 
279 static void oaktrail_hdmi_destroy(struct drm_connector *connector)
280 {
281  return;
282 }
283 
284 static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = {
285  .dpms = oaktrail_hdmi_dpms,
286  .mode_fixup = oaktrail_hdmi_mode_fixup,
287  .prepare = psb_intel_encoder_prepare,
288  .mode_set = oaktrail_hdmi_mode_set,
289  .commit = psb_intel_encoder_commit,
290 };
291 
292 static const struct drm_connector_helper_funcs
293  oaktrail_hdmi_connector_helper_funcs = {
294  .get_modes = oaktrail_hdmi_get_modes,
295  .mode_valid = oaktrail_hdmi_mode_valid,
296  .best_encoder = psb_intel_best_encoder,
297 };
298 
299 static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = {
301  .detect = oaktrail_hdmi_detect,
303  .destroy = oaktrail_hdmi_destroy,
304 };
305 
306 static void oaktrail_hdmi_enc_destroy(struct drm_encoder *encoder)
307 {
308  drm_encoder_cleanup(encoder);
309 }
310 
311 static const struct drm_encoder_funcs oaktrail_hdmi_enc_funcs = {
312  .destroy = oaktrail_hdmi_enc_destroy,
313 };
314 
316  struct psb_intel_mode_device *mode_dev)
317 {
320  struct drm_connector *connector;
321  struct drm_encoder *encoder;
322 
323  psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL);
324  if (!psb_intel_encoder)
325  return;
326 
327  psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL);
328  if (!psb_intel_connector)
329  goto failed_connector;
330 
331  connector = &psb_intel_connector->base;
332  encoder = &psb_intel_encoder->base;
333  drm_connector_init(dev, connector,
334  &oaktrail_hdmi_connector_funcs,
336 
337  drm_encoder_init(dev, encoder,
338  &oaktrail_hdmi_enc_funcs,
340 
341  psb_intel_connector_attach_encoder(psb_intel_connector,
342  psb_intel_encoder);
343 
344  psb_intel_encoder->type = INTEL_OUTPUT_HDMI;
345  drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs);
346  drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs);
347 
348  connector->display_info.subpixel_order = SubPixelHorizontalRGB;
349  connector->interlace_allowed = false;
350  connector->doublescan_allowed = false;
351  drm_sysfs_connector_add(connector);
352 
353  return;
354 
355 failed_connector:
356  kfree(psb_intel_encoder);
357 }
358 
359 static DEFINE_PCI_DEVICE_TABLE(hdmi_ids) = {
360  { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) },
361  { 0 }
362 };
363 
365 {
366  struct drm_psb_private *dev_priv = dev->dev_private;
367  struct pci_dev *pdev;
368  struct oaktrail_hdmi_dev *hdmi_dev;
369  int ret;
370 
371  pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
372  if (!pdev)
373  return;
374 
375  hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL);
376  if (!hdmi_dev) {
377  dev_err(dev->dev, "failed to allocate memory\n");
378  goto out;
379  }
380 
381 
382  ret = pci_enable_device(pdev);
383  if (ret) {
384  dev_err(dev->dev, "failed to enable hdmi controller\n");
385  goto free;
386  }
387 
388  hdmi_dev->mmio = pci_resource_start(pdev, 0);
389  hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
390  hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
391  if (!hdmi_dev->regs) {
392  dev_err(dev->dev, "failed to map hdmi mmio\n");
393  goto free;
394  }
395 
396  hdmi_dev->dev = pdev;
397  pci_set_drvdata(pdev, hdmi_dev);
398 
399  /* Initialize i2c controller */
400  ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev);
401  if (ret)
402  dev_err(dev->dev, "HDMI I2C initialization failed\n");
403 
404  dev_priv->hdmi_priv = hdmi_dev;
405  oaktrail_hdmi_audio_disable(dev);
406  return;
407 
408 free:
409  kfree(hdmi_dev);
410 out:
411  return;
412 }
413 
415 {
416  struct drm_psb_private *dev_priv = dev->dev_private;
417  struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
418  struct pci_dev *pdev;
419 
420  if (hdmi_dev) {
421  pdev = hdmi_dev->dev;
422  pci_set_drvdata(pdev, NULL);
424  iounmap(hdmi_dev->regs);
425  kfree(hdmi_dev);
426  pci_dev_put(pdev);
427  }
428 }
429 
430 /* save HDMI register state */
432 {
433  struct drm_psb_private *dev_priv = dev->dev_private;
434  struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
435  struct psb_state *regs = &dev_priv->regs.psb;
436  struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
437  int i;
438 
439  /* dpll */
440  hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
445 
446  /* pipe B */
447  pipeb->conf = PSB_RVDC32(PIPEBCONF);
448  pipeb->src = PSB_RVDC32(PIPEBSRC);
449  pipeb->htotal = PSB_RVDC32(HTOTAL_B);
450  pipeb->hblank = PSB_RVDC32(HBLANK_B);
451  pipeb->hsync = PSB_RVDC32(HSYNC_B);
452  pipeb->vtotal = PSB_RVDC32(VTOTAL_B);
453  pipeb->vblank = PSB_RVDC32(VBLANK_B);
454  pipeb->vsync = PSB_RVDC32(VSYNC_B);
455 
464 
465  /* plane */
466  pipeb->cntr = PSB_RVDC32(DSPBCNTR);
467  pipeb->stride = PSB_RVDC32(DSPBSTRIDE);
468  pipeb->addr = PSB_RVDC32(DSPBBASE);
469  pipeb->surf = PSB_RVDC32(DSPBSURF);
470  pipeb->linoff = PSB_RVDC32(DSPBLINOFF);
471  pipeb->tileoff = PSB_RVDC32(DSPBTILEOFF);
472 
473  /* cursor B */
477 
478  /* save palette */
479  for (i = 0; i < 256; i++)
480  pipeb->palette[i] = PSB_RVDC32(PALETTE_B + (i << 2));
481 }
482 
483 /* restore HDMI register state */
485 {
486  struct drm_psb_private *dev_priv = dev->dev_private;
487  struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
488  struct psb_state *regs = &dev_priv->regs.psb;
489  struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
490  int i;
491 
492  /* dpll */
493  PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
498  DRM_UDELAY(150);
499 
500  /* pipe */
501  PSB_WVDC32(pipeb->src, PIPEBSRC);
502  PSB_WVDC32(pipeb->htotal, HTOTAL_B);
503  PSB_WVDC32(pipeb->hblank, HBLANK_B);
504  PSB_WVDC32(pipeb->hsync, HSYNC_B);
505  PSB_WVDC32(pipeb->vtotal, VTOTAL_B);
506  PSB_WVDC32(pipeb->vblank, VBLANK_B);
507  PSB_WVDC32(pipeb->vsync, VSYNC_B);
508 
516 
517  PSB_WVDC32(pipeb->conf, PIPEBCONF);
519 
520  /* plane */
521  PSB_WVDC32(pipeb->linoff, DSPBLINOFF);
522  PSB_WVDC32(pipeb->stride, DSPBSTRIDE);
523  PSB_WVDC32(pipeb->tileoff, DSPBTILEOFF);
524  PSB_WVDC32(pipeb->cntr, DSPBCNTR);
525  PSB_WVDC32(pipeb->surf, DSPBSURF);
526 
527  /* cursor B */
531 
532  /* restore palette */
533  for (i = 0; i < 256; i++)
534  PSB_WVDC32(pipeb->palette[i], PALETTE_B + (i << 2));
535 }