Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3242 → Rev 3243

/drivers/video/drm/i915/intel_sdvo.c
27,7 → 27,7
*/
#include <linux/i2c.h>
#include <linux/slab.h>
//#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
518,7 → 518,7
static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
void *response, int response_len)
{
u8 retry = 5;
u8 retry = 15; /* 5 quick checks, followed by 10 long checks */
u8 status;
int i;
 
531,6 → 531,15
* command to be complete.
*
* Check 5 times in case the hardware failed to read the docs.
*
* Also beware that the first response by many devices is to
* reply PENDING and stall for time. TVs are notorious for
* requiring longer than specified to complete their replies.
* Originally (in the DDX long ago), the delay was only ever 15ms
* with an additional delay of 30ms applied for TVs added later after
* many experiments. To accommodate both sets of delays, we do a
* sequence of slow checks if the device is falling behind and fails
* to reply within 5*15µs.
*/
if (!intel_sdvo_read_byte(intel_sdvo,
SDVO_I2C_CMD_STATUS,
537,8 → 546,12
&status))
goto log_fail;
 
while (status == SDVO_CMD_STATUS_PENDING && retry--) {
while (status == SDVO_CMD_STATUS_PENDING && --retry) {
if (retry < 10)
msleep(15);
else
udelay(15);
 
if (!intel_sdvo_read_byte(intel_sdvo,
SDVO_I2C_CMD_STATUS,
&status))
1237,6 → 1250,30
 
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_PIPE_B_SELECT;
I915_WRITE(intel_sdvo->sdvo_reg, temp);
POSTING_READ(intel_sdvo->sdvo_reg);
 
/* 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);
}
}
 
intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE);
}
}
1253,8 → 1290,20
u8 status;
 
temp = I915_READ(intel_sdvo->sdvo_reg);
if ((temp & SDVO_ENABLE) == 0)
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(dev)) {
struct drm_crtc *crtc = encoder->base.crtc;
int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;
 
/* Restore the transcoder select bit. */
if (pipe == PIPE_B)
temp |= SDVO_PIPE_B_SELECT;
}
 
intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE);
}
for (i = 0; i < 2; i++)
intel_wait_for_vblank(dev, intel_crtc->pipe);
 
1508,17 → 1557,11
struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
enum drm_connector_status ret;
 
if (!intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0))
if (!intel_sdvo_get_value(intel_sdvo,
SDVO_CMD_GET_ATTACHED_DISPLAYS,
&response, 2))
return connector_status_unknown;
 
/* add 30ms delay when the output type might be TV */
if (intel_sdvo->caps.output_flags & SDVO_TV_MASK)
msleep(30);
 
if (!intel_sdvo_read_response(intel_sdvo, &response, 2))
return connector_status_unknown;
 
DRM_DEBUG_KMS("SDVO response %d %d [%x]\n",
response & 0xff, response >> 8,
intel_sdvo_connector->output_flag);
1805,7 → 1848,7
intel_sdvo_destroy_enhance_property(connector);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
kfree(intel_sdvo_connector);
}
 
static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector)
1837,7 → 1880,7
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;
 
1894,7 → 1937,7
} else if (IS_TV_OR_LVDS(intel_sdvo_connector)) {
temp_value = val;
if (intel_sdvo_connector->left == property) {
drm_connector_property_set_value(connector,
drm_object_property_set_value(&connector->base,
intel_sdvo_connector->right, val);
if (intel_sdvo_connector->left_margin == temp_value)
return 0;
1906,7 → 1949,7
cmd = SDVO_CMD_SET_OVERSCAN_H;
goto set_value;
} else if (intel_sdvo_connector->right == property) {
drm_connector_property_set_value(connector,
drm_object_property_set_value(&connector->base,
intel_sdvo_connector->left, val);
if (intel_sdvo_connector->right_margin == temp_value)
return 0;
1918,7 → 1961,7
cmd = SDVO_CMD_SET_OVERSCAN_H;
goto set_value;
} else if (intel_sdvo_connector->top == property) {
drm_connector_property_set_value(connector,
drm_object_property_set_value(&connector->base,
intel_sdvo_connector->bottom, val);
if (intel_sdvo_connector->top_margin == temp_value)
return 0;
1930,7 → 1973,7
cmd = SDVO_CMD_SET_OVERSCAN_V;
goto set_value;
} else if (intel_sdvo_connector->bottom == property) {
drm_connector_property_set_value(connector,
drm_object_property_set_value(&connector->base,
intel_sdvo_connector->top, val);
if (intel_sdvo_connector->bottom_margin == temp_value)
return 0;
2003,7 → 2046,7
drm_mode_destroy(encoder->dev,
intel_sdvo->sdvo_lvds_fixed_mode);
 
// i2c_del_adapter(&intel_sdvo->ddc);
i2c_del_adapter(&intel_sdvo->ddc);
intel_encoder_destroy(encoder);
}
 
2083,17 → 2126,24
else
mapping = &dev_priv->sdvo_mappings[1];
 
if (mapping->initialized && intel_gmbus_is_port_valid(mapping->i2c_pin))
pin = mapping->i2c_pin;
else
pin = GMBUS_PORT_DPB;
if (mapping->initialized)
pin = mapping->i2c_pin;
 
if (intel_gmbus_is_port_valid(pin)) {
sdvo->i2c = intel_gmbus_get_adapter(dev_priv, pin);
intel_gmbus_set_speed(sdvo->i2c, GMBUS_RATE_1MHZ);
 
/* With gmbus we should be able to drive sdvo i2c at 2MHz, but somehow
* our code totally fails once we start using gmbus. Hence fall back to
* bit banging for now. */
intel_gmbus_force_bit(sdvo->i2c, true);
} else {
sdvo->i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB);
}
 
/* undo any changes intel_sdvo_select_i2c_bus() did to sdvo->i2c */
static void
intel_sdvo_unselect_i2c_bus(struct intel_sdvo *sdvo)
{
intel_gmbus_force_bit(sdvo->i2c, false);
}
 
static bool
2438,7 → 2488,7
i, tv_format_names[intel_sdvo_connector->tv_format_supported[i]]);
 
intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[0];
drm_connector_attach_property(&intel_sdvo_connector->base.base,
drm_object_attach_property(&intel_sdvo_connector->base.base.base,
intel_sdvo_connector->tv_format, 0);
return true;
 
2454,7 → 2504,7
intel_sdvo_connector->name = \
drm_property_create_range(dev, 0, #name, 0, data_value[0]); \
if (!intel_sdvo_connector->name) return false; \
drm_connector_attach_property(connector, \
drm_object_attach_property(&connector->base, \
intel_sdvo_connector->name, \
intel_sdvo_connector->cur_##name); \
DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \
2491,7 → 2541,7
if (!intel_sdvo_connector->left)
return false;
 
drm_connector_attach_property(connector,
drm_object_attach_property(&connector->base,
intel_sdvo_connector->left,
intel_sdvo_connector->left_margin);
 
2500,7 → 2550,7
if (!intel_sdvo_connector->right)
return false;
 
drm_connector_attach_property(connector,
drm_object_attach_property(&connector->base,
intel_sdvo_connector->right,
intel_sdvo_connector->right_margin);
DRM_DEBUG_KMS("h_overscan: max %d, "
2528,7 → 2578,7
if (!intel_sdvo_connector->top)
return false;
 
drm_connector_attach_property(connector,
drm_object_attach_property(&connector->base,
intel_sdvo_connector->top,
intel_sdvo_connector->top_margin);
 
2538,7 → 2588,7
if (!intel_sdvo_connector->bottom)
return false;
 
drm_connector_attach_property(connector,
drm_object_attach_property(&connector->base,
intel_sdvo_connector->bottom,
intel_sdvo_connector->bottom_margin);
DRM_DEBUG_KMS("v_overscan: max %d, "
2570,7 → 2620,7
if (!intel_sdvo_connector->dot_crawl)
return false;
 
drm_connector_attach_property(connector,
drm_object_attach_property(&connector->base,
intel_sdvo_connector->dot_crawl,
intel_sdvo_connector->cur_dot_crawl);
DRM_DEBUG_KMS("dot crawl: current %d\n", response);
2655,7 → 2705,7
sdvo->ddc.algo_data = sdvo;
sdvo->ddc.algo = &intel_sdvo_ddc_proxy;
 
return 1; //i2c_add_adapter(&sdvo->ddc) == 0;
return i2c_add_adapter(&sdvo->ddc) == 0;
}
 
bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
2674,10 → 2724,8
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);
if (!intel_sdvo_init_ddc_proxy(intel_sdvo, dev)) {
kfree(intel_sdvo);
return false;
}
if (!intel_sdvo_init_ddc_proxy(intel_sdvo, dev))
goto err_i2c_bus;
 
/* encoder type will be decided later */
intel_encoder = &intel_sdvo->base;
2775,7 → 2823,9
 
err:
drm_encoder_cleanup(&intel_encoder->base);
// i2c_del_adapter(&intel_sdvo->ddc);
i2c_del_adapter(&intel_sdvo->ddc);
err_i2c_bus:
intel_sdvo_unselect_i2c_bus(intel_sdvo);
kfree(intel_sdvo);
 
return false;