Skip to content

Commit

Permalink
Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/airlied/drm-2.6

* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm/radeon/kms: use helper functions for fence read/write
  drm/radeon/kms: set DP link config properly for DP bridges
  drm/radeon/kms/atom: AdjustPixelClock fixes for DP bridges
  drm/radeon/kms: fix handling of DP to LVDS bridges
  drm/radeon/kms: issue blank/unblank commands for ext encoders
  drm/radeon/kms: fix support for DDC on dp bridges
  drm/radeon/kms: add support for load detection on dp bridges
  drm/radeon/kms: add missing external encoder action
  drm/radeon/kms: rework atombios_get_encoder_mode()
  drm/radeon/kms: fix num crtcs for Cedar and Caicos
  Revert "drm/i915: Enable GMBUS for post-gen2 chipsets"
  drivers/gpu/drm: use printk_ratelimited instead of printk_ratelimit
  drm/radeon: workaround a hw bug on some radeon chipsets with all-0 EDIDs.
  drm: make debug levels match in edid failure code.
  drm/radeon/kms: clear wb memory by default
  drm/radeon/kms: be more pedantic about the g5 quirk (v2)
  drm/radeon/kms: signed fix for evergreen thermal
  drm: populate irq_by_busid-member for pci
  • Loading branch information
torvalds committed Jun 17, 2011
2 parents 8b97b21 + b81157d commit eb96c92
Show file tree
Hide file tree
Showing 15 changed files with 237 additions and 75 deletions.
19 changes: 17 additions & 2 deletions drivers/gpu/drm/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,9 @@ drm_edid_block_valid(u8 *raw_edid)

bad:
if (raw_edid) {
DRM_ERROR("Raw EDID:\n");
printk(KERN_ERR "Raw EDID:\n");
print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH);
printk("\n");
printk(KERN_ERR "\n");
}
return 0;
}
Expand Down Expand Up @@ -258,6 +258,17 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
return ret == 2 ? 0 : -1;
}

static bool drm_edid_is_zero(u8 *in_edid, int length)
{
int i;
u32 *raw_edid = (u32 *)in_edid;

for (i = 0; i < length / 4; i++)
if (*(raw_edid + i) != 0)
return false;
return true;
}

static u8 *
drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
{
Expand All @@ -273,6 +284,10 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
goto out;
if (drm_edid_block_valid(block))
break;
if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
connector->null_edid_counter++;
goto carp;
}
}
if (i == 4)
goto carp;
Expand Down
9 changes: 5 additions & 4 deletions drivers/gpu/drm/drm_ioc32.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* IN THE SOFTWARE.
*/
#include <linux/compat.h>
#include <linux/ratelimit.h>

#include "drmP.h"
#include "drm_core.h"
Expand Down Expand Up @@ -253,10 +254,10 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd,
return -EFAULT;

m32.handle = (unsigned long)handle;
if (m32.handle != (unsigned long)handle && printk_ratelimit())
printk(KERN_ERR "compat_drm_addmap truncated handle"
" %p for type %d offset %x\n",
handle, m32.type, m32.offset);
if (m32.handle != (unsigned long)handle)
printk_ratelimited(KERN_ERR "compat_drm_addmap truncated handle"
" %p for type %d offset %x\n",
handle, m32.type, m32.offset);

if (copy_to_user(argp, &m32, sizeof(m32)))
return -EFAULT;
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/drm_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ int drm_pci_set_unique(struct drm_device *dev,
}


int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
{
if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
(p->busnum & 0xff) != dev->pdev->bus->number ||
Expand Down Expand Up @@ -292,6 +292,7 @@ static struct drm_bus drm_pci_bus = {
.get_name = drm_pci_get_name,
.set_busid = drm_pci_set_busid,
.set_unique = drm_pci_set_unique,
.irq_by_busid = drm_pci_irq_by_busid,
.agp_init = drm_pci_agp_init,
};

Expand Down
3 changes: 1 addition & 2 deletions drivers/gpu/drm/i915/intel_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,7 @@ int intel_setup_gmbus(struct drm_device *dev)
bus->reg0 = i | GMBUS_RATE_100KHZ;

/* XXX force bit banging until GMBUS is fully debugged */
if (IS_GEN2(dev))
bus->force_bit = intel_gpio_create(dev_priv, i);
bus->force_bit = intel_gpio_create(dev_priv, i);
}

intel_i2c_reset(dev_priv->dev);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/radeon/atombios.h
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,7 @@ typedef struct _EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3
#define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF 0x10
#define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING 0x11
#define EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION 0x12
#define EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP 0x14

// ucConfig
#define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_MASK 0x03
Expand Down
7 changes: 7 additions & 0 deletions drivers/gpu/drm/radeon/atombios_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,13 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
DISPPLL_CONFIG_DUAL_LINK;
}
}
if (radeon_encoder_is_dp_bridge(encoder)) {
struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder);
args.v3.sInput.ucExtTransmitterID = ext_radeon_encoder->encoder_id;
} else
args.v3.sInput.ucExtTransmitterID = 0;

atom_execute_table(rdev->mode_info.atom_context,
index, (uint32_t *)&args);
adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/radeon/evergreen.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
/* get temperature in millidegrees */
int evergreen_get_temp(struct radeon_device *rdev)
{
u32 temp, toffset, actual_temp = 0;
u32 temp, toffset;
int actual_temp = 0;

if (rdev->family == CHIP_JUNIPER) {
toffset = (RREG32(CG_THERMAL_CTRL) & TOFFSET_MASK) >>
Expand Down
31 changes: 19 additions & 12 deletions drivers/gpu/drm/radeon/radeon_asic.c
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,13 @@ static struct radeon_asic cayman_asic = {
int radeon_asic_init(struct radeon_device *rdev)
{
radeon_register_accessor_init(rdev);

/* set the number of crtcs */
if (rdev->flags & RADEON_SINGLE_CRTC)
rdev->num_crtc = 1;
else
rdev->num_crtc = 2;

switch (rdev->family) {
case CHIP_R100:
case CHIP_RV100:
Expand Down Expand Up @@ -1017,6 +1024,11 @@ int radeon_asic_init(struct radeon_device *rdev)
case CHIP_JUNIPER:
case CHIP_CYPRESS:
case CHIP_HEMLOCK:
/* set num crtcs */
if (rdev->family == CHIP_CEDAR)
rdev->num_crtc = 4;
else
rdev->num_crtc = 6;
rdev->asic = &evergreen_asic;
break;
case CHIP_PALM:
Expand All @@ -1027,10 +1039,17 @@ int radeon_asic_init(struct radeon_device *rdev)
case CHIP_BARTS:
case CHIP_TURKS:
case CHIP_CAICOS:
/* set num crtcs */
if (rdev->family == CHIP_CAICOS)
rdev->num_crtc = 4;
else
rdev->num_crtc = 6;
rdev->asic = &btc_asic;
break;
case CHIP_CAYMAN:
rdev->asic = &cayman_asic;
/* set num crtcs */
rdev->num_crtc = 6;
break;
default:
/* FIXME: not supported yet */
Expand All @@ -1042,18 +1061,6 @@ int radeon_asic_init(struct radeon_device *rdev)
rdev->asic->set_memory_clock = NULL;
}

/* set the number of crtcs */
if (rdev->flags & RADEON_SINGLE_CRTC)
rdev->num_crtc = 1;
else {
if (ASIC_IS_DCE41(rdev))
rdev->num_crtc = 2;
else if (ASIC_IS_DCE4(rdev))
rdev->num_crtc = 6;
else
rdev->num_crtc = 2;
}

return 0;
}

9 changes: 6 additions & 3 deletions drivers/gpu/drm/radeon/radeon_combios.c
Original file line number Diff line number Diff line change
Expand Up @@ -1553,9 +1553,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
(rdev->pdev->subsystem_device == 0x4a48)) {
/* Mac X800 */
rdev->mode_info.connector_table = CT_MAC_X800;
} else if (of_machine_is_compatible("PowerMac7,2") ||
of_machine_is_compatible("PowerMac7,3")) {
/* Mac G5 9600 */
} else if ((of_machine_is_compatible("PowerMac7,2") ||
of_machine_is_compatible("PowerMac7,3")) &&
(rdev->pdev->device == 0x4150) &&
(rdev->pdev->subsystem_vendor == 0x1002) &&
(rdev->pdev->subsystem_device == 0x4150)) {
/* Mac G5 tower 9600 */
rdev->mode_info.connector_table = CT_MAC_G5_9600;
} else
#endif /* CONFIG_PPC_PMAC */
Expand Down
58 changes: 50 additions & 8 deletions drivers/gpu/drm/radeon/radeon_connectors.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ extern void
radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
struct drm_connector *drm_connector);

bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector);

void radeon_connector_hotplug(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
Expand Down Expand Up @@ -836,6 +838,13 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
if (!radeon_connector->edid) {
DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
drm_get_connector_name(connector));
/* rs690 seems to have a problem with connectors not existing and always
* return a block of 0's. If we see this just stop polling on this output */
if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) && radeon_connector->base.null_edid_counter) {
ret = connector_status_disconnected;
DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector));
radeon_connector->ddc_bus = NULL;
}
} else {
radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);

Expand Down Expand Up @@ -1063,10 +1072,11 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
{
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
int ret;

if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
struct drm_encoder *encoder;
if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
struct drm_display_mode *mode;

if (!radeon_dig_connector->edp_on)
Expand All @@ -1078,7 +1088,6 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
ATOM_TRANSMITTER_ACTION_POWER_OFF);

if (ret > 0) {
encoder = radeon_best_single_encoder(connector);
if (encoder) {
radeon_fixup_lvds_native_mode(encoder, connector);
/* add scaled modes */
Expand All @@ -1102,8 +1111,14 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
/* add scaled modes */
radeon_add_common_modes(encoder, connector);
}
} else
} else {
/* need to setup ddc on the bridge */
if (radeon_connector_encoder_is_dp_bridge(connector)) {
if (encoder)
radeon_atom_ext_encoder_setup_ddc(encoder);
}
ret = radeon_ddc_get_modes(radeon_connector);
}

return ret;
}
Expand Down Expand Up @@ -1187,14 +1202,15 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
enum drm_connector_status ret = connector_status_disconnected;
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
struct drm_encoder *encoder = radeon_best_single_encoder(connector);

if (radeon_connector->edid) {
kfree(radeon_connector->edid);
radeon_connector->edid = NULL;
}

if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
if (encoder) {
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
Expand All @@ -1214,6 +1230,11 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
atombios_set_edp_panel_power(connector,
ATOM_TRANSMITTER_ACTION_POWER_OFF);
} else {
/* need to setup ddc on the bridge */
if (radeon_connector_encoder_is_dp_bridge(connector)) {
if (encoder)
radeon_atom_ext_encoder_setup_ddc(encoder);
}
radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
ret = connector_status_connected;
Expand All @@ -1228,6 +1249,16 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
ret = connector_status_connected;
}
}

if ((ret == connector_status_disconnected) &&
radeon_connector->dac_load_detect) {
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
struct drm_encoder_helper_funcs *encoder_funcs;
if (encoder) {
encoder_funcs = encoder->helper_private;
ret = encoder_funcs->detect(encoder, connector);
}
}
}

radeon_connector_update_scratch_regs(connector, ret);
Expand All @@ -1242,7 +1273,8 @@ static int radeon_dp_mode_valid(struct drm_connector *connector,

/* XXX check mode bandwidth */

if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
struct drm_encoder *encoder = radeon_best_single_encoder(connector);

if ((mode->hdisplay < 320) || (mode->vdisplay < 240))
Expand All @@ -1252,7 +1284,7 @@ static int radeon_dp_mode_valid(struct drm_connector *connector,
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_display_mode *native_mode = &radeon_encoder->native_mode;

/* AVIVO hardware supports downscaling modes larger than the panel
/* AVIVO hardware supports downscaling modes larger than the panel
* to the panel size, but I'm not sure this is desirable.
*/
if ((mode->hdisplay > native_mode->hdisplay) ||
Expand Down Expand Up @@ -1401,6 +1433,10 @@ radeon_add_atom_connector(struct drm_device *dev,
default:
connector->interlace_allowed = true;
connector->doublescan_allowed = true;
radeon_connector->dac_load_detect = true;
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.load_detect_property,
1);
break;
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_DVID:
Expand All @@ -1422,6 +1458,12 @@ radeon_add_atom_connector(struct drm_device *dev,
connector->doublescan_allowed = true;
else
connector->doublescan_allowed = false;
if (connector_type == DRM_MODE_CONNECTOR_DVII) {
radeon_connector->dac_load_detect = true;
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.load_detect_property,
1);
}
break;
case DRM_MODE_CONNECTOR_LVDS:
case DRM_MODE_CONNECTOR_eDP:
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/radeon/radeon_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ int radeon_wb_init(struct radeon_device *rdev)
return r;
}

/* clear wb memory */
memset((char *)rdev->wb.wb, 0, RADEON_GPU_PAGE_SIZE);
/* disable event_write fences */
rdev->wb.use_event = false;
/* disabled via module param */
Expand Down
Loading

0 comments on commit eb96c92

Please sign in to comment.