Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6083 → Rev 6084

/drivers/video/drm/i915/intel_sdvo.c
30,6 → 30,7
#include <linux/delay.h>
#include <linux/export.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"
52,7 → 53,7
#define IS_DIGITAL(c) (c->output_flag & (SDVO_TMDS_MASK | SDVO_LVDS_MASK))
 
 
static const char *tv_format_names[] = {
static const char * const tv_format_names[] = {
"NTSC_M" , "NTSC_J" , "NTSC_443",
"PAL_B" , "PAL_D" , "PAL_G" ,
"PAL_H" , "PAL_I" , "PAL_M" ,
62,7 → 63,7
"SECAM_60"
};
 
#define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names))
#define TV_FORMAT_NUM ARRAY_SIZE(tv_format_names)
 
struct intel_sdvo {
struct intel_encoder base;
106,6 → 107,11
bool color_range_auto;
 
/**
* HDMI user specified aspect ratio
*/
enum hdmi_picture_aspect aspect_ratio;
 
/**
* This is set if we're going to treat the device as TV-out.
*
* While we have these nice friendly flags for output types that ought
241,7 → 247,15
 
if (intel_sdvo->sdvo_reg == PCH_SDVOB) {
I915_WRITE(intel_sdvo->sdvo_reg, val);
I915_READ(intel_sdvo->sdvo_reg);
POSTING_READ(intel_sdvo->sdvo_reg);
/*
* HW workaround, need to write this twice for issue
* that may result in first write getting masked.
*/
if (HAS_PCH_IBX(dev)) {
I915_WRITE(intel_sdvo->sdvo_reg, val);
POSTING_READ(intel_sdvo->sdvo_reg);
}
return;
}
 
258,9 → 272,9
for (i = 0; i < 2; i++)
{
I915_WRITE(GEN3_SDVOB, bval);
I915_READ(GEN3_SDVOB);
POSTING_READ(GEN3_SDVOB);
I915_WRITE(GEN3_SDVOC, cval);
I915_READ(GEN3_SDVOC);
POSTING_READ(GEN3_SDVOC);
}
}
 
443,7 → 457,7
DRM_DEBUG_KMS("%s: W: %02X %s\n", SDVO_NAME(intel_sdvo), cmd, buffer);
}
 
static const char *cmd_status_names[] = {
static const char * const cmd_status_names[] = {
"Power on",
"Success",
"Not supported",
594,11 → 608,11
return false;
}
 
static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
static int intel_sdvo_get_pixel_multiplier(const struct drm_display_mode *adjusted_mode)
{
if (mode->clock >= 100000)
if (adjusted_mode->crtc_clock >= 100000)
return 1;
else if (mode->clock >= 50000)
else if (adjusted_mode->crtc_clock >= 50000)
return 2;
else
return 4;
1007,7 → 1021,7
}
 
if (intel_sdvo->rgb_quant_range_selectable) {
if (intel_crtc->config.limited_color_range)
if (intel_crtc->config->limited_color_range)
frame.avi.quantization_range =
HDMI_QUANTIZATION_RANGE_LIMITED;
else
1085,7 → 1099,7
return true;
}
 
static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_config *pipe_config)
static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config)
{
unsigned dotclock = pipe_config->port_clock;
struct dpll *clock = &pipe_config->dpll;
1112,11 → 1126,11
}
 
static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
struct intel_crtc_state *pipe_config)
{
struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
struct drm_display_mode *mode = &pipe_config->requested_mode;
struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
struct drm_display_mode *mode = &pipe_config->base.mode;
 
DRM_DEBUG_KMS("forcing bpc to 8 for SDVO\n");
pipe_config->pipe_bpp = 8*3;
1172,6 → 1186,10
if (intel_sdvo->is_tv)
i9xx_adjust_sdvo_tv_clock(pipe_config);
 
/* Set user selected PAR to incoming mode's member */
if (intel_sdvo->is_hdmi)
adjusted_mode->picture_aspect_ratio = intel_sdvo->aspect_ratio;
 
return true;
}
 
1180,9 → 1198,8
struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc = to_intel_crtc(intel_encoder->base.crtc);
struct drm_display_mode *adjusted_mode =
&crtc->config.adjusted_mode;
struct drm_display_mode *mode = &crtc->config.requested_mode;
const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
struct drm_display_mode *mode = &crtc->config->base.mode;
struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
u32 sdvox;
struct intel_sdvo_in_out_map in_out;
1224,7 → 1241,7
if (!intel_sdvo_set_target_input(intel_sdvo))
return;
 
if (crtc->config.has_hdmi_sink) {
if (crtc->config->has_hdmi_sink) {
intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI);
intel_sdvo_set_colorimetry(intel_sdvo,
SDVO_COLORIMETRY_RGB256);
1244,9 → 1261,9
DRM_INFO("Setting input timings on %s failed\n",
SDVO_NAME(intel_sdvo));
 
switch (crtc->config.pixel_multiplier) {
switch (crtc->config->pixel_multiplier) {
default:
WARN(1, "unknown pixel mutlipler specified\n");
WARN(1, "unknown pixel multiplier specified\n");
case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;
case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break;
case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break;
1259,7 → 1276,7
/* The real mode polarity is set by the SDVO commands, using
* struct intel_sdvo_dtd. */
sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH;
if (!HAS_PCH_SPLIT(dev) && crtc->config.limited_color_range)
if (!HAS_PCH_SPLIT(dev) && crtc->config->limited_color_range)
sdvox |= HDMI_COLOR_RANGE_16_235;
if (INTEL_INFO(dev)->gen < 5)
sdvox |= SDVO_BORDER_ENABLE;
1289,7 → 1306,7
} else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
/* done in crtc_mode_set as it lives inside the dpll register */
} else {
sdvox |= (crtc->config.pixel_multiplier - 1)
sdvox |= (crtc->config->pixel_multiplier - 1)
<< SDVO_PORT_MULTIPLY_SHIFT;
}
 
1338,7 → 1355,7
}
 
static void intel_sdvo_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;
1370,7 → 1387,7
flags |= DRM_MODE_FLAG_NVSYNC;
}
 
pipe_config->adjusted_mode.flags |= flags;
pipe_config->base.adjusted_mode.flags |= flags;
 
/*
* pixel multiplier readout is tricky: Only on i915g/gm it is stored in
1392,7 → 1409,7
if (HAS_PCH_SPLIT(dev))
ironlake_check_encoder_dotclock(pipe_config, dotclock);
 
pipe_config->adjusted_mode.crtc_clock = dotclock;
pipe_config->base.adjusted_mode.crtc_clock = dotclock;
 
/* Cross check the port pixel multiplier with the sdvo encoder state. */
if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT,
1428,6 → 1445,7
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
u32 temp;
 
intel_sdvo_set_active_outputs(intel_sdvo, 0);
1436,33 → 1454,32
DRM_MODE_DPMS_OFF);
 
temp = I915_READ(intel_sdvo->sdvo_reg);
if ((temp & SDVO_ENABLE) != 0) {
/* HW workaround for IBX, we need to move the port to
* transcoder A before disabling it. */
if (HAS_PCH_IBX(encoder->base.dev)) {
struct drm_crtc *crtc = encoder->base.crtc;
int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;
 
if (temp & SDVO_PIPE_B_SELECT) {
temp &= ~SDVO_ENABLE;
intel_sdvo_write_sdvox(intel_sdvo, temp);
 
/*
* HW workaround for IBX, we need to move the port
* to transcoder A after disabling it to allow the
* matching DP port to be enabled on transcoder A.
*/
if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) {
temp &= ~SDVO_PIPE_B_SELECT;
I915_WRITE(intel_sdvo->sdvo_reg, temp);
POSTING_READ(intel_sdvo->sdvo_reg);
temp |= SDVO_ENABLE;
intel_sdvo_write_sdvox(intel_sdvo, temp);
 
/* Again we need to write this twice. */
I915_WRITE(intel_sdvo->sdvo_reg, temp);
POSTING_READ(intel_sdvo->sdvo_reg);
 
/* Transcoder selection bits only update
* effectively on vblank. */
if (crtc)
intel_wait_for_vblank(encoder->base.dev, pipe);
else
msleep(50);
temp &= ~SDVO_ENABLE;
intel_sdvo_write_sdvox(intel_sdvo, temp);
}
}
 
intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE);
static void pch_disable_sdvo(struct intel_encoder *encoder)
{
}
 
static void pch_post_disable_sdvo(struct intel_encoder *encoder)
{
intel_disable_sdvo(encoder);
}
 
static void intel_enable_sdvo(struct intel_encoder *encoder)
1477,14 → 1494,9
bool success;
 
temp = I915_READ(intel_sdvo->sdvo_reg);
if ((temp & SDVO_ENABLE) == 0) {
/* HW workaround for IBX, we need to move the port
* to transcoder A before disabling it, so restore it here. */
if (HAS_PCH_IBX(dev))
temp |= SDVO_PIPE_SEL(intel_crtc->pipe);
temp |= SDVO_ENABLE;
intel_sdvo_write_sdvox(intel_sdvo, temp);
 
intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE);
}
for (i = 0; i < 2; i++)
intel_wait_for_vblank(dev, intel_crtc->pipe);
 
1504,51 → 1516,6
intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
}
 
/* Special dpms function to support cloning between dvo/sdvo/crt. */
static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
{
struct drm_crtc *crtc;
struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
 
/* dvo supports only 2 dpms states. */
if (mode != DRM_MODE_DPMS_ON)
mode = DRM_MODE_DPMS_OFF;
 
if (mode == connector->dpms)
return;
 
connector->dpms = mode;
 
/* Only need to change hw state when actually enabled */
crtc = intel_sdvo->base.base.crtc;
if (!crtc) {
intel_sdvo->base.connectors_active = false;
return;
}
 
/* We set active outputs manually below in case pipe dpms doesn't change
* due to cloning. */
if (mode != DRM_MODE_DPMS_ON) {
intel_sdvo_set_active_outputs(intel_sdvo, 0);
if (0)
intel_sdvo_set_encoder_power_state(intel_sdvo, mode);
 
intel_sdvo->base.connectors_active = false;
 
intel_crtc_update_dpms(crtc);
} else {
intel_sdvo->base.connectors_active = true;
 
intel_crtc_update_dpms(crtc);
 
if (0)
intel_sdvo_set_encoder_power_state(intel_sdvo, mode);
intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
}
 
intel_modeset_check_state(connector->dev);
}
 
static enum drm_mode_status
intel_sdvo_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
1617,6 → 1584,9
struct drm_device *dev = intel_sdvo->base.base.dev;
uint16_t hotplug;
 
if (!I915_HAS_HOTPLUG(dev))
return 0;
 
/* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise
* on the line. */
if (IS_I945G(dev) || IS_I945GM(dev))
2082,6 → 2052,23
goto done;
}
 
if (property == connector->dev->mode_config.aspect_ratio_property) {
switch (val) {
case DRM_MODE_PICTURE_ASPECT_NONE:
intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
break;
case DRM_MODE_PICTURE_ASPECT_4_3:
intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_4_3;
break;
case DRM_MODE_PICTURE_ASPECT_16_9:
intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_16_9;
break;
default:
return -EINVAL;
}
goto done;
}
 
#define CHECK_PROPERTY(name, NAME) \
if (intel_sdvo_connector->name == property) { \
if (intel_sdvo_connector->cur_##name == temp_value) return 0; \
2183,11 → 2170,14
}
 
static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
.dpms = intel_sdvo_dpms,
.dpms = drm_atomic_helper_connector_dpms,
.detect = intel_sdvo_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_sdvo_set_property,
.atomic_get_property = intel_connector_atomic_get_property,
.destroy = intel_sdvo_destroy,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
};
 
static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
2257,7 → 2247,7
*/
static void
intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv,
struct intel_sdvo *sdvo, u32 reg)
struct intel_sdvo *sdvo)
{
struct sdvo_device_mapping *mapping;
 
2274,7 → 2264,7
 
static void
intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv,
struct intel_sdvo *sdvo, u32 reg)
struct intel_sdvo *sdvo)
{
struct sdvo_device_mapping *mapping;
u8 pin;
2284,10 → 2274,11
else
mapping = &dev_priv->sdvo_mappings[1];
 
if (mapping->initialized && intel_gmbus_is_port_valid(mapping->i2c_pin))
if (mapping->initialized &&
intel_gmbus_is_valid_pin(dev_priv, mapping->i2c_pin))
pin = mapping->i2c_pin;
else
pin = GMBUS_PORT_DPB;
pin = GMBUS_PIN_DPB;
 
sdvo->i2c = intel_gmbus_get_adapter(dev_priv, pin);
 
2409,8 → 2400,26
intel_attach_broadcast_rgb_property(&connector->base.base);
intel_sdvo->color_range_auto = true;
}
intel_attach_aspect_ratio_property(&connector->base.base);
intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
}
 
static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void)
{
struct intel_sdvo_connector *sdvo_connector;
 
sdvo_connector = kzalloc(sizeof(*sdvo_connector), GFP_KERNEL);
if (!sdvo_connector)
return NULL;
 
if (intel_connector_init(&sdvo_connector->base) < 0) {
kfree(sdvo_connector);
return NULL;
}
 
return sdvo_connector;
}
 
static bool
intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
{
2422,7 → 2431,7
 
DRM_DEBUG_KMS("initialising DVI device %d\n", device);
 
intel_sdvo_connector = kzalloc(sizeof(*intel_sdvo_connector), GFP_KERNEL);
intel_sdvo_connector = intel_sdvo_connector_alloc();
if (!intel_sdvo_connector)
return false;
 
2476,7 → 2485,7
 
DRM_DEBUG_KMS("initialising TV type %d\n", type);
 
intel_sdvo_connector = kzalloc(sizeof(*intel_sdvo_connector), GFP_KERNEL);
intel_sdvo_connector = intel_sdvo_connector_alloc();
if (!intel_sdvo_connector)
return false;
 
2519,7 → 2528,7
 
DRM_DEBUG_KMS("initialising analog device %d\n", device);
 
intel_sdvo_connector = kzalloc(sizeof(*intel_sdvo_connector), GFP_KERNEL);
intel_sdvo_connector = intel_sdvo_connector_alloc();
if (!intel_sdvo_connector)
return false;
 
2555,7 → 2564,7
 
DRM_DEBUG_KMS("initialising LVDS device %d\n", device);
 
intel_sdvo_connector = kzalloc(sizeof(*intel_sdvo_connector), GFP_KERNEL);
intel_sdvo_connector = intel_sdvo_connector_alloc();
if (!intel_sdvo_connector)
return false;
 
2935,7 → 2944,7
intel_sdvo->sdvo_reg = sdvo_reg;
intel_sdvo->is_sdvob = is_sdvob;
intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, intel_sdvo) >> 1;
intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo, sdvo_reg);
intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo);
if (!intel_sdvo_init_ddc_proxy(intel_sdvo, dev))
goto err_i2c_bus;
 
2956,7 → 2965,12
}
 
intel_encoder->compute_config = intel_sdvo_compute_config;
if (HAS_PCH_SPLIT(dev)) {
intel_encoder->disable = pch_disable_sdvo;
intel_encoder->post_disable = pch_post_disable_sdvo;
} else {
intel_encoder->disable = intel_disable_sdvo;
}
intel_encoder->pre_enable = intel_sdvo_pre_enable;
intel_encoder->enable = intel_enable_sdvo;
intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
2992,7 → 3006,7
*/
intel_sdvo->base.cloneable = 0;
 
intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg);
intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo);
 
/* Set the input timing to the screen. Assume always input 0. */
if (!intel_sdvo_set_target_input(intel_sdvo))