Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6103 → Rev 6104

/drivers/video/drm/radeon/radeon_connectors.c
27,12 → 27,24
#include <drm/drm_edid.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_dp_mst_helper.h>
#include <drm/radeon_drm.h>
#include "radeon.h"
#include "radeon_audio.h"
#include "atom.h"
 
#include <linux/pm_runtime.h>
 
static int radeon_dp_handle_hpd(struct drm_connector *connector)
{
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
int ret;
 
ret = radeon_dp_mst_check_status(radeon_connector);
if (ret == -EINVAL)
return 1;
return 0;
}
void radeon_connector_hotplug(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
39,6 → 51,17
struct radeon_device *rdev = dev->dev_private;
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 
if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
struct radeon_connector_atom_dig *dig_connector =
radeon_connector->con_priv;
 
if (radeon_connector->is_mst_connector)
return;
if (dig_connector->is_mst) {
radeon_dp_handle_hpd(connector);
return;
}
}
/* bail if the connector does not have hpd pin, e.g.,
* VGA, TV, etc.
*/
72,6 → 95,11
if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
} else if (radeon_dp_needs_link_train(radeon_connector)) {
/* Don't try to start link training before we
* have the dpcd */
if (!radeon_dp_getdpcd(radeon_connector))
return;
 
/* set it to OFF so that drm_helper_connector_dpms()
* won't return immediately since the current state
* is ON at this point.
134,7 → 162,7
if (connector->display_info.bpc)
bpc = connector->display_info.bpc;
else if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
struct drm_connector_helper_funcs *connector_funcs =
const struct drm_connector_helper_funcs *connector_funcs =
connector->helper_private;
struct drm_encoder *encoder = connector_funcs->best_encoder(connector);
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
224,7 → 252,7
struct radeon_device *rdev = dev->dev_private;
struct drm_encoder *best_encoder = NULL;
struct drm_encoder *encoder = NULL;
struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
bool connected;
int i;
 
701,7 → 729,7
if (connector->encoder)
radeon_encoder = to_radeon_encoder(connector->encoder);
else {
struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector));
}
 
724,9 → 752,33
radeon_property_change_mode(&radeon_encoder->base);
}
 
if (property == rdev->mode_info.output_csc_property) {
if (connector->encoder)
radeon_encoder = to_radeon_encoder(connector->encoder);
else {
const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector));
}
 
if (radeon_encoder->output_csc == val)
return 0;
 
radeon_encoder->output_csc = val;
 
if (connector->encoder->crtc) {
struct drm_crtc *crtc = connector->encoder->crtc;
const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 
radeon_crtc->output_csc = radeon_encoder->output_csc;
 
(*crtc_funcs->load_lut)(crtc);
}
}
 
return 0;
}
 
static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
struct drm_connector *connector)
{
845,7 → 897,11
/* check if panel is valid */
if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)
ret = connector_status_connected;
 
/* don't fetch the edid from the vbios if ddc fails and runpm is
* enabled so we report disconnected.
*/
if ((rdev->flags & RADEON_IS_PX) && (radeon_runtime_pm != 0))
ret = connector_status_disconnected;
}
 
/* check for edid as well */
884,7 → 940,7
if (connector->encoder)
radeon_encoder = to_radeon_encoder(connector->encoder);
else {
struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector));
}
 
952,7 → 1008,7
struct radeon_device *rdev = dev->dev_private;
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct drm_encoder *encoder;
struct drm_encoder_helper_funcs *encoder_funcs;
const struct drm_encoder_helper_funcs *encoder_funcs;
bool dret = false;
enum drm_connector_status ret = connector_status_disconnected;
 
1074,7 → 1130,7
radeon_tv_detect(struct drm_connector *connector, bool force)
{
struct drm_encoder *encoder;
struct drm_encoder_helper_funcs *encoder_funcs;
const struct drm_encoder_helper_funcs *encoder_funcs;
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
enum drm_connector_status ret = connector_status_disconnected;
int r;
1148,7 → 1204,7
struct radeon_device *rdev = dev->dev_private;
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct drm_encoder *encoder = NULL;
struct drm_encoder_helper_funcs *encoder_funcs;
const struct drm_encoder_helper_funcs *encoder_funcs;
int i, r;
enum drm_connector_status ret = connector_status_disconnected;
bool dret = false, broken_edid = false;
1159,8 → 1215,9
goto exit;
}
 
if (radeon_connector->ddc_bus)
if (radeon_connector->ddc_bus) {
dret = radeon_ddc_probe(radeon_connector, false);
}
if (dret) {
radeon_connector->detected_by_load = false;
radeon_connector_free_edid(connector);
1304,6 → 1361,17
/* updated in get modes as well since we need to know if it's analog or digital */
radeon_connector_update_scratch_regs(connector, ret);
 
if ((radeon_audio != 0) && radeon_connector->use_digital) {
const struct drm_connector_helper_funcs *connector_funcs =
connector->helper_private;
 
encoder = connector_funcs->best_encoder(connector);
if (encoder && (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)) {
radeon_connector_get_edid(connector);
radeon_audio_detect(connector, encoder, ret);
}
}
 
exit:
return ret;
}
1550,6 → 1618,8
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
int r;
 
if (radeon_dig_connector->is_mst)
return connector_status_disconnected;
 
if (!force && radeon_check_hpd_status_unchanged(connector)) {
ret = connector->status;
1567,6 → 1637,11
/* check if panel is valid */
if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)
ret = connector_status_connected;
/* don't fetch the edid from the vbios if ddc fails and runpm is
* enabled so we report disconnected.
*/
if ((rdev->flags & RADEON_IS_PX) && (radeon_runtime_pm != 0))
ret = connector_status_disconnected;
}
/* eDP is always DP */
radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
1592,7 → 1667,7
if (radeon_ddc_probe(radeon_connector, true)) /* try DDC */
ret = connector_status_connected;
else if (radeon_connector->dac_load_detect) { /* try load detection */
struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
ret = encoder_funcs->detect(encoder, connector);
}
}
1600,12 → 1675,21
radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
ret = connector_status_connected;
if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
radeon_dp_getdpcd(radeon_connector);
r = radeon_dp_mst_probe(radeon_connector);
if (r == 1)
ret = connector_status_disconnected;
}
} else {
if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
if (radeon_dp_getdpcd(radeon_connector))
if (radeon_dp_getdpcd(radeon_connector)) {
r = radeon_dp_mst_probe(radeon_connector);
if (r == 1)
ret = connector_status_disconnected;
else
ret = connector_status_connected;
}
} else {
/* try non-aux ddc (DP to DVI/HDMI/etc. adapter) */
if (radeon_ddc_probe(radeon_connector, false))
1615,6 → 1699,12
}
 
radeon_connector_update_scratch_regs(connector, ret);
 
if ((radeon_audio != 0) && encoder) {
radeon_connector_get_edid(connector);
radeon_audio_detect(connector, encoder, ret);
}
 
out:
return ret;
}
1822,6 → 1912,10
drm_object_attach_property(&radeon_connector->base.base,
dev->mode_config.scaling_mode_property,
DRM_MODE_SCALE_NONE);
if (ASIC_IS_DCE5(rdev))
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.output_csc_property,
RADEON_OUTPUT_CSC_BYPASS);
break;
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_DVID:
1854,6 → 1948,10
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
RADEON_AUDIO_AUTO);
if (ASIC_IS_DCE5(rdev))
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.output_csc_property,
RADEON_OUTPUT_CSC_BYPASS);
 
subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = true;
1900,6 → 1998,10
drm_object_attach_property(&radeon_connector->base.base,
dev->mode_config.scaling_mode_property,
DRM_MODE_SCALE_NONE);
if (ASIC_IS_DCE5(rdev))
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.output_csc_property,
RADEON_OUTPUT_CSC_BYPASS);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1922,6 → 2024,10
drm_object_attach_property(&radeon_connector->base.base,
dev->mode_config.scaling_mode_property,
DRM_MODE_SCALE_NONE);
if (ASIC_IS_DCE5(rdev))
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.output_csc_property,
RADEON_OUTPUT_CSC_BYPASS);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
connector->interlace_allowed = true;
1973,6 → 2079,10
rdev->mode_info.load_detect_property,
1);
}
if (ASIC_IS_DCE5(rdev))
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.output_csc_property,
RADEON_OUTPUT_CSC_BYPASS);
connector->interlace_allowed = true;
if (connector_type == DRM_MODE_CONNECTOR_DVII)
connector->doublescan_allowed = true;
2018,6 → 2128,10
rdev->mode_info.audio_property,
RADEON_AUDIO_AUTO);
}
if (ASIC_IS_DCE5(rdev))
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.output_csc_property,
RADEON_OUTPUT_CSC_BYPASS);
subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = true;
if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
2066,6 → 2180,10
rdev->mode_info.audio_property,
RADEON_AUDIO_AUTO);
}
if (ASIC_IS_DCE5(rdev))
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.output_csc_property,
RADEON_OUTPUT_CSC_BYPASS);
connector->interlace_allowed = true;
/* in theory with a DP to VGA converter... */
connector->doublescan_allowed = false;
2302,3 → 2420,27
connector->display_info.subpixel_order = subpixel_order;
drm_connector_register(connector);
}
 
void radeon_setup_mst_connector(struct drm_device *dev)
{
struct radeon_device *rdev = dev->dev_private;
struct drm_connector *connector;
struct radeon_connector *radeon_connector;
 
if (!ASIC_IS_DCE5(rdev))
return;
 
if (radeon_mst == 0)
return;
 
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
int ret;
 
radeon_connector = to_radeon_connector(connector);
 
if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
continue;
 
ret = radeon_dp_mst_init(radeon_connector);
}
}