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; |