Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6083 → Rev 6084

/drivers/video/drm/i915/intel_lvds.c
32,6 → 32,7
#include <linux/i2c.h>
#include <linux/slab.h>
#include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include "intel_drv.h"
93,19 → 94,15
}
 
static void intel_lvds_get_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 lvds_reg, tmp, flags = 0;
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
u32 tmp, flags = 0;
int dotclock;
 
if (HAS_PCH_SPLIT(dev))
lvds_reg = PCH_LVDS;
else
lvds_reg = LVDS;
 
tmp = I915_READ(lvds_reg);
tmp = I915_READ(lvds_encoder->reg);
if (tmp & LVDS_HSYNC_POLARITY)
flags |= DRM_MODE_FLAG_NHSYNC;
else
115,7 → 112,7
else
flags |= DRM_MODE_FLAG_PVSYNC;
 
pipe_config->adjusted_mode.flags |= flags;
pipe_config->base.adjusted_mode.flags |= flags;
 
/* gen2/3 store dither state in pfit control, needs to match */
if (INTEL_INFO(dev)->gen < 4) {
129,7 → 126,7
if (HAS_PCH_SPLIT(dev_priv->dev))
ironlake_check_encoder_dotclock(pipe_config, dotclock);
 
pipe_config->adjusted_mode.crtc_clock = dotclock;
pipe_config->base.adjusted_mode.crtc_clock = dotclock;
}
 
static void intel_pre_enable_lvds(struct intel_encoder *encoder)
138,8 → 135,7
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
const struct drm_display_mode *adjusted_mode =
&crtc->config.adjusted_mode;
const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
int pipe = crtc->pipe;
u32 temp;
 
167,7 → 163,7
 
/* set the corresponsding LVDS_BORDER bit */
temp &= ~LVDS_BORDER_ENABLE;
temp |= crtc->config.gmch_pfit.lvds_border_bits;
temp |= crtc->config->gmch_pfit.lvds_border_bits;
/* Set the B0-B3 data pairs corresponding to whether we're going to
* set the DPLLs for dual-channel mode or not.
*/
190,7 → 186,7
if (INTEL_INFO(dev)->gen == 4) {
/* Bspec wording suggests that LVDS port dithering only exists
* for 18bpp panels. */
if (crtc->config.dither && crtc->config.pipe_bpp == 18)
if (crtc->config->dither && crtc->config->pipe_bpp == 18)
temp |= LVDS_ENABLE_DITHER;
else
temp &= ~LVDS_ENABLE_DITHER;
238,8 → 234,6
{
struct drm_device *dev = encoder->base.dev;
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
struct intel_connector *intel_connector =
&lvds_encoder->attached_connector->base;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 ctl_reg, stat_reg;
 
251,8 → 245,6
stat_reg = PP_STATUS;
}
 
intel_panel_disable_backlight(intel_connector);
 
I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000))
DRM_ERROR("timed out waiting for panel to power off\n");
261,6 → 253,31
POSTING_READ(lvds_encoder->reg);
}
 
static void gmch_disable_lvds(struct intel_encoder *encoder)
{
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
struct intel_connector *intel_connector =
&lvds_encoder->attached_connector->base;
 
intel_panel_disable_backlight(intel_connector);
 
intel_disable_lvds(encoder);
}
 
static void pch_disable_lvds(struct intel_encoder *encoder)
{
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
struct intel_connector *intel_connector =
&lvds_encoder->attached_connector->base;
 
intel_panel_disable_backlight(intel_connector);
}
 
static void pch_post_disable_lvds(struct intel_encoder *encoder)
{
intel_disable_lvds(encoder);
}
 
static enum drm_mode_status
intel_lvds_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
267,17 → 284,20
{
struct intel_connector *intel_connector = to_intel_connector(connector);
struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
int max_pixclk = to_i915(connector->dev)->max_dotclk_freq;
 
if (mode->hdisplay > fixed_mode->hdisplay)
return MODE_PANEL;
if (mode->vdisplay > fixed_mode->vdisplay)
return MODE_PANEL;
if (fixed_mode->clock > max_pixclk)
return MODE_CLOCK_HIGH;
 
return MODE_OK;
}
 
static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
struct intel_crtc_config *pipe_config)
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = intel_encoder->base.dev;
struct intel_lvds_encoder *lvds_encoder =
284,8 → 304,8
to_lvds_encoder(&intel_encoder->base);
struct intel_connector *intel_connector =
&lvds_encoder->attached_connector->base;
struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc;
struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
unsigned int lvds_bpp;
 
/* Should never happen!! */
452,7 → 472,7
*/
if (!HAS_PCH_SPLIT(dev)) {
drm_modeset_lock_all(dev);
intel_modeset_setup_hw_state(dev, true);
intel_display_resume(dev);
drm_modeset_unlock_all(dev);
}
 
508,7 → 528,7
intel_connector->panel.fitting_mode = value;
 
crtc = intel_attached_encoder(connector)->base.crtc;
if (crtc && crtc->enabled) {
if (crtc && crtc->state->enable) {
/*
* If the CRTC is enabled, the display will be changed
* according to the new panel fitting mode.
527,11 → 547,14
};
 
static const struct drm_connector_funcs intel_lvds_connector_funcs = {
.dpms = intel_connector_dpms,
.dpms = drm_atomic_helper_connector_dpms,
.detect = intel_lvds_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_lvds_set_property,
.atomic_get_property = intel_connector_atomic_get_property,
.destroy = intel_lvds_destroy,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
};
 
static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
777,7 → 800,7
child->device_type != DEVICE_TYPE_LFP)
continue;
 
if (intel_gmbus_is_port_valid(child->i2c_pin))
if (intel_gmbus_is_valid_pin(dev_priv, child->i2c_pin))
*i2c_pin = child->i2c_pin;
 
/* However, we cannot trust the BIOS writers to populate
809,12 → 832,28
static const struct dmi_system_id intel_dual_link_lvds[] = {
{
.callback = intel_dual_link_lvds_callback,
.ident = "Apple MacBook Pro (Core i5/i7 Series)",
.ident = "Apple MacBook Pro 15\" (2010)",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6,2"),
},
},
{
.callback = intel_dual_link_lvds_callback,
.ident = "Apple MacBook Pro 15\" (2011)",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro8,2"),
},
},
{
.callback = intel_dual_link_lvds_callback,
.ident = "Apple MacBook Pro 15\" (2012)",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro9,1"),
},
},
{ } /* terminating entry */
};
 
844,6 → 883,11
if (i915.lvds_channel_mode > 0)
return i915.lvds_channel_mode == 2;
 
/* single channel LVDS is limited to 112 MHz */
if (lvds_encoder->attached_connector->base.panel.fixed_mode->clock
> 112999)
return true;
 
if (dmi_check_system(intel_dual_link_lvds))
return true;
 
895,6 → 939,7
struct drm_display_mode *downclock_mode = NULL;
struct edid *edid;
struct drm_crtc *crtc;
u32 lvds_reg;
u32 lvds;
int pipe;
u8 pin;
906,7 → 951,7
if (HAS_PCH_SPLIT(dev)) {
I915_WRITE(PCH_PP_CONTROL,
I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS);
} else {
} else if (INTEL_INFO(dev_priv)->gen < 5) {
I915_WRITE(PP_CONTROL,
I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS);
}
917,14 → 962,15
if (dmi_check_system(intel_no_lvds))
return;
 
pin = GMBUS_PORT_PANEL;
if (!lvds_is_present_in_vbt(dev, &pin)) {
DRM_DEBUG_KMS("LVDS is not present in VBT\n");
return;
}
if (HAS_PCH_SPLIT(dev))
lvds_reg = PCH_LVDS;
else
lvds_reg = LVDS;
 
lvds = I915_READ(lvds_reg);
 
if (HAS_PCH_SPLIT(dev)) {
if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
if ((lvds & LVDS_DETECTED) == 0)
return;
if (dev_priv->vbt.edp_support) {
DRM_DEBUG_KMS("disable LVDS for eDP support\n");
932,6 → 978,27
}
}
 
pin = GMBUS_PIN_PANEL;
if (!lvds_is_present_in_vbt(dev, &pin)) {
if ((lvds & LVDS_PORT_EN) == 0) {
DRM_DEBUG_KMS("LVDS is not present in VBT\n");
return;
}
DRM_DEBUG_KMS("LVDS is not present in VBT, but enabled anyway\n");
}
 
/* Set the Panel Power On/Off timings if uninitialized. */
if (INTEL_INFO(dev_priv)->gen < 5 &&
I915_READ(PP_ON_DELAYS) == 0 && I915_READ(PP_OFF_DELAYS) == 0) {
/* Set T2 to 40ms and T5 to 200ms */
I915_WRITE(PP_ON_DELAYS, 0x019007d0);
 
/* Set T3 to 35ms and Tx to 200ms */
I915_WRITE(PP_OFF_DELAYS, 0x015e07d0);
 
DRM_DEBUG_KMS("Panel power timings uninitialized, setting defaults\n");
}
 
lvds_encoder = kzalloc(sizeof(*lvds_encoder), GFP_KERNEL);
if (!lvds_encoder)
return;
942,6 → 1009,12
return;
}
 
if (intel_connector_init(&lvds_connector->base) < 0) {
kfree(lvds_connector);
kfree(lvds_encoder);
return;
}
 
lvds_encoder->attached_connector = lvds_connector;
 
intel_encoder = &lvds_encoder->base;
957,7 → 1030,12
intel_encoder->enable = intel_enable_lvds;
intel_encoder->pre_enable = intel_pre_enable_lvds;
intel_encoder->compute_config = intel_lvds_compute_config;
intel_encoder->disable = intel_disable_lvds;
if (HAS_PCH_SPLIT(dev_priv)) {
intel_encoder->disable = pch_disable_lvds;
intel_encoder->post_disable = pch_post_disable_lvds;
} else {
intel_encoder->disable = gmch_disable_lvds;
}
intel_encoder->get_hw_state = intel_lvds_get_hw_state;
intel_encoder->get_config = intel_lvds_get_config;
intel_connector->get_hw_state = intel_connector_get_hw_state;
979,11 → 1057,7
connector->interlace_allowed = false;
connector->doublescan_allowed = false;
 
if (HAS_PCH_SPLIT(dev)) {
lvds_encoder->reg = PCH_LVDS;
} else {
lvds_encoder->reg = LVDS;
}
lvds_encoder->reg = lvds_reg;
 
/* create the scaling mode property */
drm_mode_create_scaling_mode_property(dev);
1037,26 → 1111,10
drm_mode_debug_printmodeline(scan);
 
fixed_mode = drm_mode_duplicate(dev, scan);
if (fixed_mode) {
downclock_mode =
intel_find_panel_downclock(dev,
fixed_mode, connector);
if (downclock_mode != NULL &&
i915.lvds_downclock) {
/* We found the downclock for LVDS. */
dev_priv->lvds_downclock_avail = true;
dev_priv->lvds_downclock =
downclock_mode->clock;
DRM_DEBUG_KMS("LVDS downclock is found"
" in EDID. Normal clock %dKhz, "
"downclock %dKhz\n",
fixed_mode->clock,
dev_priv->lvds_downclock);
}
if (fixed_mode)
goto out;
}
}
}
 
/* Failed to get EDID, what about VBT? */
if (dev_priv->vbt.lfp_lvds_vbt_mode) {
1080,7 → 1138,6
if (HAS_PCH_SPLIT(dev))
goto failed;
 
lvds = I915_READ(LVDS);
pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
crtc = intel_get_crtc_for_pipe(dev, pipe);
 
1101,6 → 1158,8
out:
mutex_unlock(&dev->mode_config.mutex);
 
intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
 
lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder);
DRM_DEBUG_KMS("detected %s-link lvds configuration\n",
lvds_encoder->is_dual_link ? "dual" : "single");
1110,7 → 1169,6
 
drm_connector_register(connector);
 
intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
intel_panel_setup_backlight(connector, INVALID_PIPE);
 
return;