diff options
Diffstat (limited to 'drivers/gpu/drm/gma500')
-rw-r--r-- | drivers/gpu/drm/gma500/cdv_device.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/cdv_intel_dp.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/cdv_intel_hdmi.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/cdv_intel_lvds.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/mdfld_dsi_output.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/mdfld_intel_display.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/oaktrail.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/oaktrail_crtc.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/oaktrail_device.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/oaktrail_hdmi.c | 365 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/oaktrail_lvds.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_intel_lvds.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_intel_sdvo.c | 24 |
13 files changed, 405 insertions, 56 deletions
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c index 1ceca3d13b6..23e14e93991 100644 --- a/drivers/gpu/drm/gma500/cdv_device.c +++ b/drivers/gpu/drm/gma500/cdv_device.c @@ -523,7 +523,7 @@ void cdv_intel_attach_force_audio_property(struct drm_connector *connector) dev_priv->force_audio_property = prop; } - drm_connector_attach_property(connector, prop, 0); + drm_object_attach_property(&connector->base, prop, 0); } @@ -553,7 +553,7 @@ void cdv_intel_attach_broadcast_rgb_property(struct drm_connector *connector) dev_priv->broadcast_rgb_property = prop; } - drm_connector_attach_property(connector, prop, 0); + drm_object_attach_property(&connector->base, prop, 0); } /* Cedarview */ diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c index e3a3978cf32..51044cc55cf 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c @@ -1650,7 +1650,7 @@ cdv_intel_dp_set_property(struct drm_connector *connector, struct cdv_intel_dp *intel_dp = encoder->dev_priv; int ret; - ret = drm_connector_property_set_value(connector, property, val); + ret = drm_object_property_set_value(&connector->base, property, val); if (ret) return ret; diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c index 7272a461edf..e223b500022 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c +++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c @@ -185,14 +185,14 @@ static int cdv_hdmi_set_property(struct drm_connector *connector, return -1; } - if (drm_connector_property_get_value(connector, + if (drm_object_property_get_value(&connector->base, property, &curValue)) return -1; if (curValue == value) return 0; - if (drm_connector_property_set_value(connector, + if (drm_object_property_set_value(&connector->base, property, value)) return -1; @@ -341,7 +341,7 @@ void cdv_hdmi_init(struct drm_device *dev, connector->interlace_allowed = false; connector->doublescan_allowed = false; - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN); diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c index b362dd39bf5..d81dbc3368f 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c @@ -479,7 +479,7 @@ static int cdv_intel_lvds_set_property(struct drm_connector *connector, return -1; } - if (drm_connector_property_get_value(connector, + if (drm_object_property_get_value(&connector->base, property, &curValue)) return -1; @@ -487,7 +487,7 @@ static int cdv_intel_lvds_set_property(struct drm_connector *connector, if (curValue == value) return 0; - if (drm_connector_property_set_value(connector, + if (drm_object_property_set_value(&connector->base, property, value)) return -1; @@ -502,7 +502,7 @@ static int cdv_intel_lvds_set_property(struct drm_connector *connector, return -1; } } else if (!strcmp(property->name, "backlight") && encoder) { - if (drm_connector_property_set_value(connector, + if (drm_object_property_set_value(&connector->base, property, value)) return -1; @@ -671,10 +671,10 @@ void cdv_intel_lvds_init(struct drm_device *dev, connector->doublescan_allowed = false; /*Attach connector properties*/ - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN); - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, dev_priv->backlight_property, BRIGHTNESS_MAX_LEVEL); diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c index 32dba2ab53e..2d4ab48f07a 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c @@ -265,13 +265,13 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector, goto set_prop_error; } - if (drm_connector_property_get_value(connector, property, &val)) + if (drm_object_property_get_value(&connector->base, property, &val)) goto set_prop_error; if (val == value) goto set_prop_done; - if (drm_connector_property_set_value(connector, + if (drm_object_property_set_value(&connector->base, property, value)) goto set_prop_error; @@ -296,7 +296,7 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector, } } } else if (!strcmp(property->name, "backlight") && encoder) { - if (drm_connector_property_set_value(connector, property, + if (drm_object_property_set_value(&connector->base, property, value)) goto set_prop_error; else @@ -506,7 +506,7 @@ void mdfld_dsi_output_init(struct drm_device *dev, dev_dbg(dev->dev, "init DSI output on pipe %d\n", pipe); - if (!dev || ((pipe != 0) && (pipe != 2))) { + if (pipe != 0 && pipe != 2) { DRM_ERROR("Invalid parameter\n"); return; } @@ -572,10 +572,10 @@ void mdfld_dsi_output_init(struct drm_device *dev, connector->doublescan_allowed = false; /*attach properties*/ - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN); - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, dev_priv->backlight_property, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL); diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c index dec6a9aea3c..74485dc4394 100644 --- a/drivers/gpu/drm/gma500/mdfld_intel_display.c +++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c @@ -820,7 +820,7 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, REG_WRITE(map->pos, 0); if (psb_intel_encoder) - drm_connector_property_get_value(connector, + drm_object_property_get_value(&connector->base, dev->mode_config.scaling_mode_property, &scalingType); if (scalingType == DRM_MODE_SCALE_NO_SCALE) { diff --git a/drivers/gpu/drm/gma500/oaktrail.h b/drivers/gpu/drm/gma500/oaktrail.h index f2f9f38a536..30adbbe2302 100644 --- a/drivers/gpu/drm/gma500/oaktrail.h +++ b/drivers/gpu/drm/gma500/oaktrail.h @@ -249,3 +249,9 @@ extern void oaktrail_hdmi_i2c_exit(struct pci_dev *dev); extern void oaktrail_hdmi_save(struct drm_device *dev); extern void oaktrail_hdmi_restore(struct drm_device *dev); extern void oaktrail_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev); +extern int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, int x, int y, + struct drm_framebuffer *old_fb); +extern void oaktrail_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode); + + diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c index cdafd2acc72..3071526bc3c 100644 --- a/drivers/gpu/drm/gma500/oaktrail_crtc.c +++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c @@ -168,6 +168,11 @@ static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode) const struct psb_offset *map = &dev_priv->regmap[pipe]; u32 temp; + if (pipe == 1) { + oaktrail_crtc_hdmi_dpms(crtc, mode); + return; + } + if (!gma_power_begin(dev, true)) return; @@ -302,6 +307,9 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN; struct drm_connector *connector; + if (pipe == 1) + return oaktrail_crtc_hdmi_mode_set(crtc, mode, adjusted_mode, x, y, old_fb); + if (!gma_power_begin(dev, true)) return 0; @@ -343,7 +351,7 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, (mode->crtc_vdisplay - 1)); if (psb_intel_encoder) - drm_connector_property_get_value(connector, + drm_object_property_get_value(&connector->base, dev->mode_config.scaling_mode_property, &scalingType); if (scalingType == DRM_MODE_SCALE_NO_SCALE) { diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c index 010b820744a..08747fd7105 100644 --- a/drivers/gpu/drm/gma500/oaktrail_device.c +++ b/drivers/gpu/drm/gma500/oaktrail_device.c @@ -544,7 +544,7 @@ const struct psb_ops oaktrail_chip_ops = { .accel_2d = 1, .pipes = 2, .crtcs = 2, - .hdmi_mask = (1 << 0), + .hdmi_mask = (1 << 1), .lvds_mask = (1 << 0), .cursor_needs_phys = 0, .sgx_offset = MRST_SGX_OFFSET, diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c index 69e51e903f3..f036f1fc161 100644 --- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c +++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c @@ -155,6 +155,345 @@ static void oaktrail_hdmi_audio_disable(struct drm_device *dev) HDMI_READ(HDMI_HCR); } +static void wait_for_vblank(struct drm_device *dev) +{ + /* Wait for 20ms, i.e. one cycle at 50hz. */ + mdelay(20); +} + +static unsigned int htotal_calculate(struct drm_display_mode *mode) +{ + u32 htotal, new_crtc_htotal; + + htotal = (mode->crtc_hdisplay - 1) | ((mode->crtc_htotal - 1) << 16); + + /* + * 1024 x 768 new_crtc_htotal = 0x1024; + * 1280 x 1024 new_crtc_htotal = 0x0c34; + */ + new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock; + + DRM_DEBUG_KMS("new crtc htotal 0x%4x\n", new_crtc_htotal); + return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16); +} + +static void oaktrail_hdmi_find_dpll(struct drm_crtc *crtc, int target, + int refclk, struct oaktrail_hdmi_clock *best_clock) +{ + int np_min, np_max, nr_min, nr_max; + int np, nr, nf; + + np_min = DIV_ROUND_UP(oaktrail_hdmi_limit.vco.min, target * 10); + np_max = oaktrail_hdmi_limit.vco.max / (target * 10); + if (np_min < oaktrail_hdmi_limit.np.min) + np_min = oaktrail_hdmi_limit.np.min; + if (np_max > oaktrail_hdmi_limit.np.max) + np_max = oaktrail_hdmi_limit.np.max; + + nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max)); + nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min)); + if (nr_min < oaktrail_hdmi_limit.nr.min) + nr_min = oaktrail_hdmi_limit.nr.min; + if (nr_max > oaktrail_hdmi_limit.nr.max) + nr_max = oaktrail_hdmi_limit.nr.max; + + np = DIV_ROUND_UP((refclk * 1000), (target * 10 * nr_max)); + nr = DIV_ROUND_UP((refclk * 1000), (target * 10 * np)); + nf = DIV_ROUND_CLOSEST((target * 10 * np * nr), refclk); + DRM_DEBUG_KMS("np, nr, nf %d %d %d\n", np, nr, nf); + + /* + * 1024 x 768 np = 1; nr = 0x26; nf = 0x0fd8000; + * 1280 x 1024 np = 1; nr = 0x17; nf = 0x1034000; + */ + best_clock->np = np; + best_clock->nr = nr - 1; + best_clock->nf = (nf << 14); +} + +static void scu_busy_loop(void __iomem *scu_base) +{ + u32 status = 0; + u32 loop_count = 0; + + status = readl(scu_base + 0x04); + while (status & 1) { + udelay(1); /* scu processing time is in few u secods */ + status = readl(scu_base + 0x04); + loop_count++; + /* break if scu doesn't reset busy bit after huge retry */ + if (loop_count > 1000) { + DRM_DEBUG_KMS("SCU IPC timed out"); + return; + } + } +} + +/* + * You don't want to know, you really really don't want to know.... + * + * This is magic. However it's safe magic because of the way the platform + * works and it is necessary magic. + */ +static void oaktrail_hdmi_reset(struct drm_device *dev) +{ + void __iomem *base; + unsigned long scu_ipc_mmio = 0xff11c000UL; + int scu_len = 1024; + + base = ioremap((resource_size_t)scu_ipc_mmio, scu_len); + if (base == NULL) { + DRM_ERROR("failed to map scu mmio\n"); + return; + } + + /* scu ipc: assert hdmi controller reset */ + writel(0xff11d118, base + 0x0c); + writel(0x7fffffdf, base + 0x80); + writel(0x42005, base + 0x0); + scu_busy_loop(base); + + /* scu ipc: de-assert hdmi controller reset */ + writel(0xff11d118, base + 0x0c); + writel(0x7fffffff, base + 0x80); + writel(0x42005, base + 0x0); + scu_busy_loop(base); + + iounmap(base); +} + +int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, + int x, int y, + struct drm_framebuffer *old_fb) +{ + struct drm_device *dev = crtc->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; + int pipe = 1; + int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; + int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; + int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; + int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; + int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; + int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; + int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; + int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; + int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + int refclk; + struct oaktrail_hdmi_clock clock; + u32 dspcntr, pipeconf, dpll, temp; + int dspcntr_reg = DSPBCNTR; + + if (!gma_power_begin(dev, true)) + return 0; + + /* Disable the VGA plane that we never use */ + REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); + + /* Disable dpll if necessary */ + dpll = REG_READ(DPLL_CTRL); + if ((dpll & DPLL_PWRDN) == 0) { + REG_WRITE(DPLL_CTRL, dpll | (DPLL_PWRDN | DPLL_RESET)); + REG_WRITE(DPLL_DIV_CTRL, 0x00000000); + REG_WRITE(DPLL_STATUS, 0x1); + } + udelay(150); + + /* Reset controller */ + oaktrail_hdmi_reset(dev); + + /* program and enable dpll */ + refclk = 25000; + oaktrail_hdmi_find_dpll(crtc, adjusted_mode->clock, refclk, &clock); + + /* Set the DPLL */ + dpll = REG_READ(DPLL_CTRL); + dpll &= ~DPLL_PDIV_MASK; + dpll &= ~(DPLL_PWRDN | DPLL_RESET); + REG_WRITE(DPLL_CTRL, 0x00000008); + REG_WRITE(DPLL_DIV_CTRL, ((clock.nf << 6) | clock.nr)); + REG_WRITE(DPLL_ADJUST, ((clock.nf >> 14) - 1)); + REG_WRITE(DPLL_CTRL, (dpll | (clock.np << DPLL_PDIV_SHIFT) | DPLL_ENSTAT | DPLL_DITHEN)); + REG_WRITE(DPLL_UPDATE, 0x80000000); + REG_WRITE(DPLL_CLK_ENABLE, 0x80050102); + udelay(150); + + /* configure HDMI */ + HDMI_WRITE(0x1004, 0x1fd); + HDMI_WRITE(0x2000, 0x1); + HDMI_WRITE(0x2008, 0x0); + HDMI_WRITE(0x3130, 0x8); + HDMI_WRITE(0x101c, 0x1800810); + + temp = htotal_calculate(adjusted_mode); + REG_WRITE(htot_reg, temp); + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16)); + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16)); + REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16)); + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16)); + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16)); + REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); + + REG_WRITE(PCH_HTOTAL_B, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16)); + REG_WRITE(PCH_HBLANK_B, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16)); + REG_WRITE(PCH_HSYNC_B, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16)); + REG_WRITE(PCH_VTOTAL_B, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16)); + REG_WRITE(PCH_VBLANK_B, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16)); + REG_WRITE(PCH_VSYNC_B, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16)); + REG_WRITE(PCH_PIPEBSRC, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); + + temp = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start; + HDMI_WRITE(HDMI_HBLANK_A, ((adjusted_mode->crtc_hdisplay - 1) << 16) | temp); + + REG_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); + REG_WRITE(dsppos_reg, 0); + + /* Flush the plane changes */ + { + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + crtc_funcs->mode_set_base(crtc, x, y, old_fb); + } + + /* Set up the display plane register */ + dspcntr = REG_READ(dspcntr_reg); + dspcntr |= DISPPLANE_GAMMA_ENABLE; + dspcntr |= DISPPLANE_SEL_PIPE_B; + dspcntr |= DISPLAY_PLANE_ENABLE; + + /* setup pipeconf */ + pipeconf = REG_READ(pipeconf_reg); + pipeconf |= PIPEACONF_ENABLE; + + REG_WRITE(pipeconf_reg, pipeconf); + REG_READ(pipeconf_reg); + + REG_WRITE(PCH_PIPEBCONF, pipeconf); + REG_READ(PCH_PIPEBCONF); + wait_for_vblank(dev); + + REG_WRITE(dspcntr_reg, dspcntr); + wait_for_vblank(dev); + + gma_power_end(dev); + + return 0; +} + +void oaktrail_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode) +{ + struct drm_device *dev = crtc->dev; + u32 temp; + + DRM_DEBUG_KMS("%s %d\n", __func__, mode); + + switch (mode) { + case DRM_MODE_DPMS_OFF: + REG_WRITE(VGACNTRL, 0x80000000); + + /* Disable plane */ + temp = REG_READ(DSPBCNTR); + if ((temp & DISPLAY_PLANE_ENABLE) != 0) { + REG_WRITE(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE); + REG_READ(DSPBCNTR); + /* Flush the plane changes */ + REG_WRITE(DSPBSURF, REG_READ(DSPBSURF)); + REG_READ(DSPBSURF); + } + + /* Disable pipe B */ + temp = REG_READ(PIPEBCONF); + if ((temp & PIPEACONF_ENABLE) != 0) { + REG_WRITE(PIPEBCONF, temp & ~PIPEACONF_ENABLE); + REG_READ(PIPEBCONF); + } + + /* Disable LNW Pipes, etc */ + temp = REG_READ(PCH_PIPEBCONF); + if ((temp & PIPEACONF_ENABLE) != 0) { + REG_WRITE(PCH_PIPEBCONF, temp & ~PIPEACONF_ENABLE); + REG_READ(PCH_PIPEBCONF); + } + + /* wait for pipe off */ + udelay(150); + + /* Disable dpll */ + temp = REG_READ(DPLL_CTRL); + if ((temp & DPLL_PWRDN) == 0) { + REG_WRITE(DPLL_CTRL, temp | (DPLL_PWRDN | DPLL_RESET)); + REG_WRITE(DPLL_STATUS, 0x1); + } + + /* wait for dpll off */ + udelay(150); + + break; + case DRM_MODE_DPMS_ON: + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + /* Enable dpll */ + temp = REG_READ(DPLL_CTRL); + if ((temp & DPLL_PWRDN) != 0) { + REG_WRITE(DPLL_CTRL, temp & ~(DPLL_PWRDN | DPLL_RESET)); + temp = REG_READ(DPLL_CLK_ENABLE); + REG_WRITE(DPLL_CLK_ENABLE, temp | DPLL_EN_DISP | DPLL_SEL_HDMI | DPLL_EN_HDMI); + REG_READ(DPLL_CLK_ENABLE); + } + /* wait for dpll warm up */ + udelay(150); + + /* Enable pipe B */ + temp = REG_READ(PIPEBCONF); + if ((temp & PIPEACONF_ENABLE) == 0) { + REG_WRITE(PIPEBCONF, temp | PIPEACONF_ENABLE); + REG_READ(PIPEBCONF); + } + + /* Enable LNW Pipe B */ + temp = REG_READ(PCH_PIPEBCONF); + if ((temp & PIPEACONF_ENABLE) == 0) { + REG_WRITE(PCH_PIPEBCONF, temp | PIPEACONF_ENABLE); + REG_READ(PCH_PIPEBCONF); + } + + wait_for_vblank(dev); + + /* Enable plane */ + temp = REG_READ(DSPBCNTR); + if ((temp & DISPLAY_PLANE_ENABLE) == 0) { + REG_WRITE(DSPBCNTR, temp | DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + REG_WRITE(DSPBSURF, REG_READ(DSPBSURF)); + REG_READ(DSPBSURF); + } + + psb_intel_crtc_load_lut(crtc); + } + + /* DSPARB */ + REG_WRITE(DSPARB, 0x00003fbf); + + /* FW1 */ + REG_WRITE(0x70034, 0x3f880a0a); + + /* FW2 */ + REG_WRITE(0x70038, 0x0b060808); + + /* FW4 */ + REG_WRITE(0x70050, 0x08030404); + + /* FW5 */ + REG_WRITE(0x70054, 0x04040404); + + /* LNC Chicken Bits - Squawk! */ + REG_WRITE(0x70400, 0x4000); + + return; +} + static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode) { static int dpms_mode = -1; @@ -233,13 +572,15 @@ static const unsigned char raw_edid[] = { static int oaktrail_hdmi_get_modes(struct drm_connector *connector) { - struct drm_device *dev = connector->dev; - struct drm_psb_private *dev_priv = dev->dev_private; struct i2c_adapter *i2c_adap; struct edid *edid; - struct drm_display_mode *mode, *t; - int i = 0, ret = 0; + int ret = 0; + /* + * FIXME: We need to figure this lot out. In theory we can + * read the EDID somehow but I've yet to find working reference + * code. + */ i2c_adap = i2c_get_adapter(3); if (i2c_adap == NULL) { DRM_ERROR("No ddc adapter available!\n"); @@ -253,17 +594,7 @@ static int oaktrail_hdmi_get_modes(struct drm_connector *connector) drm_mode_connector_update_edid_property(connector, edid); ret = drm_add_edid_modes(connector, edid); } - - /* - * prune modes that require frame buffer bigger than stolen mem - */ - list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { - if ((mode->hdisplay * mode->vdisplay * 4) >= dev_priv->vram_stolen_size) { - i++; - drm_mode_remove(connector, mode); - } - } - return ret - i; + return ret; } static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder, @@ -349,6 +680,7 @@ void oaktrail_hdmi_init(struct drm_device *dev, connector->interlace_allowed = false; connector->doublescan_allowed = false; drm_sysfs_connector_add(connector); + dev_info(dev->dev, "HDMI initialised.\n"); return; @@ -403,6 +735,9 @@ void oaktrail_hdmi_setup(struct drm_device *dev) dev_priv->hdmi_priv = hdmi_dev; oaktrail_hdmi_audio_disable(dev); + + dev_info(dev->dev, "HDMI hardware present.\n"); + return; free: diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c index 558c77fb55e..325013a9c48 100644 --- a/drivers/gpu/drm/gma500/oaktrail_lvds.c +++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c @@ -133,8 +133,8 @@ static void oaktrail_lvds_mode_set(struct drm_encoder *encoder, return; } - drm_connector_property_get_value( - connector, + drm_object_property_get_value( + &connector->base, dev->mode_config.scaling_mode_property, &v); @@ -363,10 +363,10 @@ void oaktrail_lvds_init(struct drm_device *dev, connector->interlace_allowed = false; connector->doublescan_allowed = false; - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN); - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, dev_priv->backlight_property, BRIGHTNESS_MAX_LEVEL); diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c index 2a4c3a9e33e..9fa5fa2e619 100644 --- a/drivers/gpu/drm/gma500/psb_intel_lvds.c +++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c @@ -603,7 +603,7 @@ int psb_intel_lvds_set_property(struct drm_connector *connector, goto set_prop_error; } - if (drm_connector_property_get_value(connector, + if (drm_object_property_get_value(&connector->base, property, &curval)) goto set_prop_error; @@ -611,7 +611,7 @@ int psb_intel_lvds_set_property(struct drm_connector *connector, if (curval == value) goto set_prop_done; - if (drm_connector_property_set_value(connector, + if (drm_object_property_set_value(&connector->base, property, value)) goto set_prop_error; @@ -626,7 +626,7 @@ int psb_intel_lvds_set_property(struct drm_connector *connector, goto set_prop_error; } } else if (!strcmp(property->name, "backlight")) { - if (drm_connector_property_set_value(connector, + if (drm_object_property_set_value(&connector->base, property, value)) goto set_prop_error; @@ -746,10 +746,10 @@ void psb_intel_lvds_init(struct drm_device *dev, connector->doublescan_allowed = false; /*Attach connector properties*/ - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN); - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, dev_priv->backlight_property, BRIGHTNESS_MAX_LEVEL); diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index fc9292705db..a4cc777ab7a 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c @@ -1694,7 +1694,7 @@ psb_intel_sdvo_set_property(struct drm_connector *connector, uint8_t cmd; int ret; - ret = drm_connector_property_set_value(connector, property, val); + ret = drm_object_property_set_value(&connector->base, property, val); if (ret) return ret; @@ -1749,7 +1749,7 @@ psb_intel_sdvo_set_property(struct drm_connector *connector, } else if (IS_TV_OR_LVDS(psb_intel_sdvo_connector)) { temp_value = val; if (psb_intel_sdvo_connector->left == property) { - drm_connector_property_set_value(connector, + drm_object_property_set_value(&connector->base, psb_intel_sdvo_connector->right, val); if (psb_intel_sdvo_connector->left_margin == temp_value) return 0; @@ -1761,7 +1761,7 @@ psb_intel_sdvo_set_property(struct drm_connector *connector, cmd = SDVO_CMD_SET_OVERSCAN_H; goto set_value; } else if (psb_intel_sdvo_connector->right == property) { - drm_connector_property_set_value(connector, + drm_object_property_set_value(&connector->base, psb_intel_sdvo_connector->left, val); if (psb_intel_sdvo_connector->right_margin == temp_value) return 0; @@ -1773,7 +1773,7 @@ psb_intel_sdvo_set_property(struct drm_connector *connector, cmd = SDVO_CMD_SET_OVERSCAN_H; goto set_value; } else if (psb_intel_sdvo_connector->top == property) { - drm_connector_property_set_value(connector, + drm_object_property_set_value(&connector->base, psb_intel_sdvo_connector->bottom, val); if (psb_intel_sdvo_connector->top_margin == temp_value) return 0; @@ -1785,7 +1785,7 @@ psb_intel_sdvo_set_property(struct drm_connector *connector, cmd = SDVO_CMD_SET_OVERSCAN_V; goto set_value; } else if (psb_intel_sdvo_connector->bottom == property) { - drm_connector_property_set_value(connector, + drm_object_property_set_value(&connector->base, psb_intel_sdvo_connector->top, val); if (psb_intel_sdvo_connector->bottom_margin == temp_value) return 0; @@ -2286,7 +2286,7 @@ static bool psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_s i, tv_format_names[psb_intel_sdvo_connector->tv_format_supported[i]]); psb_intel_sdvo->tv_format_index = psb_intel_sdvo_connector->tv_format_supported[0]; - drm_connector_attach_property(&psb_intel_sdvo_connector->base.base, + drm_object_attach_property(&psb_intel_sdvo_connector->base.base.base, psb_intel_sdvo_connector->tv_format, 0); return true; @@ -2302,7 +2302,7 @@ static bool psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_s psb_intel_sdvo_connector->name = \ drm_property_create_range(dev, 0, #name, 0, data_value[0]); \ if (!psb_intel_sdvo_connector->name) return false; \ - drm_connector_attach_property(connector, \ + drm_object_attach_property(&connector->base, \ psb_intel_sdvo_connector->name, \ psb_intel_sdvo_connector->cur_##name); \ DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \ @@ -2339,7 +2339,7 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo, if (!psb_intel_sdvo_connector->left) return false; - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, psb_intel_sdvo_connector->left, psb_intel_sdvo_connector->left_margin); @@ -2348,7 +2348,7 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo, if (!psb_intel_sdvo_connector->right) return false; - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, psb_intel_sdvo_connector->right, psb_intel_sdvo_connector->right_margin); DRM_DEBUG_KMS("h_overscan: max %d, " @@ -2375,7 +2375,7 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo, if (!psb_intel_sdvo_connector->top) return false; - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, psb_intel_sdvo_connector->top, psb_intel_sdvo_connector->top_margin); @@ -2384,7 +2384,7 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo, if (!psb_intel_sdvo_connector->bottom) return false; - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, psb_intel_sdvo_connector->bottom, psb_intel_sdvo_connector->bottom_margin); DRM_DEBUG_KMS("v_overscan: max %d, " @@ -2416,7 +2416,7 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo, if (!psb_intel_sdvo_connector->dot_crawl) return false; - drm_connector_attach_property(connector, + drm_object_attach_property(&connector->base, psb_intel_sdvo_connector->dot_crawl, psb_intel_sdvo_connector->cur_dot_crawl); DRM_DEBUG_KMS("dot crawl: current %d\n", response); |