Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "Scattered selection of fixes: - radeon: load detect fixes from SuSE/AMD - intel: misc i830, sdvo regression, vesafb kickoff ums fix - exynos: maintainers entry update + fixes - udl: fix stride scanout issue it's slightly bigger than I'd probably like, but nothing looked dangerous enough to hold off on." * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/udl: fix stride issues scanning out stride != width*bpp drm/radeon: add load detection support for ext DAC on R200 (v2) DRM/radeon: For single CRTC GPUs move handling of CRTC_CRT_ON to crtc_dpms(). DRM/Radeon: Fix TV DAC Load Detection for single CRTC chips. DRM/Radeon: Clean up code in TV DAC load detection. drm/radeon: fix ATPX function documentation drivers/gpu/drm/radeon/evergreen_cs.c: Remove unnecessary semicolon DRM/Radeon: On DVI-I use Load Detection when EDID is bogus. DRM/Radeon: Fix primary DAC Load Detection for RV100 chips. DRM/Radeon: Fix Load Detection on legacy primary DAC. drm: exynos: removed warning due to missing typecast for mixer driver data drm/exynos: add support for ARCH_MULTIPLATFORM MAINTAINERS: Add git repository for Exynos DRM drm/exynos: fix display on issue drm/i915: Only kick out vesafb if we takeover the fbcon with KMS drm/i915: be less verbose about inability to provide vendor backlight drm/i915: clear the entire sdvo infoframe buffer drm/i915: VGA needs to be on pipe A on i830M drm/i915: fix overlay on i830M
This commit is contained in:
commit
53f9313f5c
@ -2507,6 +2507,7 @@ M: Joonyoung Shim <jy0922.shim@samsung.com>
|
|||||||
M: Seung-Woo Kim <sw0312.kim@samsung.com>
|
M: Seung-Woo Kim <sw0312.kim@samsung.com>
|
||||||
M: Kyungmin Park <kyungmin.park@samsung.com>
|
M: Kyungmin Park <kyungmin.park@samsung.com>
|
||||||
L: dri-devel@lists.freedesktop.org
|
L: dri-devel@lists.freedesktop.org
|
||||||
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/gpu/drm/exynos
|
F: drivers/gpu/drm/exynos
|
||||||
F: include/drm/exynos*
|
F: include/drm/exynos*
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
config DRM_EXYNOS
|
config DRM_EXYNOS
|
||||||
tristate "DRM Support for Samsung SoC EXYNOS Series"
|
tristate "DRM Support for Samsung SoC EXYNOS Series"
|
||||||
depends on DRM && PLAT_SAMSUNG
|
depends on DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM)
|
||||||
select DRM_KMS_HELPER
|
select DRM_KMS_HELPER
|
||||||
select FB_CFB_FILLRECT
|
select FB_CFB_FILLRECT
|
||||||
select FB_CFB_COPYAREA
|
select FB_CFB_COPYAREA
|
||||||
|
@ -374,6 +374,7 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
|
|||||||
exynos_connector->encoder_id = encoder->base.id;
|
exynos_connector->encoder_id = encoder->base.id;
|
||||||
exynos_connector->manager = manager;
|
exynos_connector->manager = manager;
|
||||||
exynos_connector->dpms = DRM_MODE_DPMS_OFF;
|
exynos_connector->dpms = DRM_MODE_DPMS_OFF;
|
||||||
|
connector->dpms = DRM_MODE_DPMS_OFF;
|
||||||
connector->encoder = encoder;
|
connector->encoder = encoder;
|
||||||
|
|
||||||
err = drm_mode_connector_attach_encoder(connector, encoder);
|
err = drm_mode_connector_attach_encoder(connector, encoder);
|
||||||
|
@ -43,12 +43,14 @@
|
|||||||
* @manager: specific encoder has its own manager to control a hardware
|
* @manager: specific encoder has its own manager to control a hardware
|
||||||
* appropriately and we can access a hardware drawing on this manager.
|
* appropriately and we can access a hardware drawing on this manager.
|
||||||
* @dpms: store the encoder dpms value.
|
* @dpms: store the encoder dpms value.
|
||||||
|
* @updated: indicate whether overlay data updating is needed or not.
|
||||||
*/
|
*/
|
||||||
struct exynos_drm_encoder {
|
struct exynos_drm_encoder {
|
||||||
struct drm_crtc *old_crtc;
|
struct drm_crtc *old_crtc;
|
||||||
struct drm_encoder drm_encoder;
|
struct drm_encoder drm_encoder;
|
||||||
struct exynos_drm_manager *manager;
|
struct exynos_drm_manager *manager;
|
||||||
int dpms;
|
int dpms;
|
||||||
|
bool updated;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode)
|
static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode)
|
||||||
@ -85,7 +87,9 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
|
|||||||
switch (mode) {
|
switch (mode) {
|
||||||
case DRM_MODE_DPMS_ON:
|
case DRM_MODE_DPMS_ON:
|
||||||
if (manager_ops && manager_ops->apply)
|
if (manager_ops && manager_ops->apply)
|
||||||
manager_ops->apply(manager->dev);
|
if (!exynos_encoder->updated)
|
||||||
|
manager_ops->apply(manager->dev);
|
||||||
|
|
||||||
exynos_drm_connector_power(encoder, mode);
|
exynos_drm_connector_power(encoder, mode);
|
||||||
exynos_encoder->dpms = mode;
|
exynos_encoder->dpms = mode;
|
||||||
break;
|
break;
|
||||||
@ -94,6 +98,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
|
|||||||
case DRM_MODE_DPMS_OFF:
|
case DRM_MODE_DPMS_OFF:
|
||||||
exynos_drm_connector_power(encoder, mode);
|
exynos_drm_connector_power(encoder, mode);
|
||||||
exynos_encoder->dpms = mode;
|
exynos_encoder->dpms = mode;
|
||||||
|
exynos_encoder->updated = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DRM_ERROR("unspecified mode %d\n", mode);
|
DRM_ERROR("unspecified mode %d\n", mode);
|
||||||
@ -205,13 +210,22 @@ static void exynos_drm_encoder_prepare(struct drm_encoder *encoder)
|
|||||||
|
|
||||||
static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
|
static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
|
||||||
{
|
{
|
||||||
struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
|
struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
|
||||||
|
struct exynos_drm_manager *manager = exynos_encoder->manager;
|
||||||
struct exynos_drm_manager_ops *manager_ops = manager->ops;
|
struct exynos_drm_manager_ops *manager_ops = manager->ops;
|
||||||
|
|
||||||
DRM_DEBUG_KMS("%s\n", __FILE__);
|
DRM_DEBUG_KMS("%s\n", __FILE__);
|
||||||
|
|
||||||
if (manager_ops && manager_ops->commit)
|
if (manager_ops && manager_ops->commit)
|
||||||
manager_ops->commit(manager->dev);
|
manager_ops->commit(manager->dev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this will avoid one issue that overlay data is updated to
|
||||||
|
* real hardware two times.
|
||||||
|
* And this variable will be used to check if the data was
|
||||||
|
* already updated or not by exynos_drm_encoder_dpms function.
|
||||||
|
*/
|
||||||
|
exynos_encoder->updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
|
static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
|
||||||
@ -400,19 +414,6 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data)
|
|||||||
if (manager_ops && manager_ops->dpms)
|
if (manager_ops && manager_ops->dpms)
|
||||||
manager_ops->dpms(manager->dev, mode);
|
manager_ops->dpms(manager->dev, mode);
|
||||||
|
|
||||||
/*
|
|
||||||
* set current mode to new one so that data aren't updated into
|
|
||||||
* registers by drm_helper_connector_dpms two times.
|
|
||||||
*
|
|
||||||
* in case that drm_crtc_helper_set_mode() is called,
|
|
||||||
* overlay_ops->commit() and manager_ops->commit() callbacks
|
|
||||||
* can be called two times, first at drm_crtc_helper_set_mode()
|
|
||||||
* and second at drm_helper_connector_dpms().
|
|
||||||
* so with this setting, when drm_helper_connector_dpms() is called
|
|
||||||
* encoder->funcs->dpms() will be ignored.
|
|
||||||
*/
|
|
||||||
exynos_encoder->dpms = mode;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if this condition is ok then it means that the crtc is already
|
* if this condition is ok then it means that the crtc is already
|
||||||
* detached from encoder and last function for detaching is properly
|
* detached from encoder and last function for detaching is properly
|
||||||
|
@ -1142,7 +1142,7 @@ static int __devinit mixer_probe(struct platform_device *pdev)
|
|||||||
const struct of_device_id *match;
|
const struct of_device_id *match;
|
||||||
match = of_match_node(of_match_ptr(mixer_match_types),
|
match = of_match_node(of_match_ptr(mixer_match_types),
|
||||||
pdev->dev.of_node);
|
pdev->dev.of_node);
|
||||||
drv = match->data;
|
drv = (struct mixer_drv_data *)match->data;
|
||||||
} else {
|
} else {
|
||||||
drv = (struct mixer_drv_data *)
|
drv = (struct mixer_drv_data *)
|
||||||
platform_get_device_id(pdev)->driver_data;
|
platform_get_device_id(pdev)->driver_data;
|
||||||
|
@ -1505,7 +1505,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
|||||||
goto put_gmch;
|
goto put_gmch;
|
||||||
}
|
}
|
||||||
|
|
||||||
i915_kick_out_firmware_fb(dev_priv);
|
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
|
i915_kick_out_firmware_fb(dev_priv);
|
||||||
|
|
||||||
pci_set_master(dev->pdev);
|
pci_set_master(dev->pdev);
|
||||||
|
|
||||||
|
@ -729,7 +729,7 @@ void intel_crt_init(struct drm_device *dev)
|
|||||||
|
|
||||||
crt->base.type = INTEL_OUTPUT_ANALOG;
|
crt->base.type = INTEL_OUTPUT_ANALOG;
|
||||||
crt->base.cloneable = true;
|
crt->base.cloneable = true;
|
||||||
if (IS_HASWELL(dev))
|
if (IS_HASWELL(dev) || IS_I830(dev))
|
||||||
crt->base.crtc_mask = (1 << 0);
|
crt->base.crtc_mask = (1 << 0);
|
||||||
else
|
else
|
||||||
crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
|
crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
|
||||||
|
@ -341,9 +341,17 @@ static int intel_overlay_off(struct intel_overlay *overlay)
|
|||||||
intel_ring_emit(ring, flip_addr);
|
intel_ring_emit(ring, flip_addr);
|
||||||
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
||||||
/* turn overlay off */
|
/* turn overlay off */
|
||||||
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
|
if (IS_I830(dev)) {
|
||||||
intel_ring_emit(ring, flip_addr);
|
/* Workaround: Don't disable the overlay fully, since otherwise
|
||||||
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
* it dies on the next OVERLAY_ON cmd. */
|
||||||
|
intel_ring_emit(ring, MI_NOOP);
|
||||||
|
intel_ring_emit(ring, MI_NOOP);
|
||||||
|
intel_ring_emit(ring, MI_NOOP);
|
||||||
|
} else {
|
||||||
|
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
|
||||||
|
intel_ring_emit(ring, flip_addr);
|
||||||
|
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
||||||
|
}
|
||||||
intel_ring_advance(ring);
|
intel_ring_advance(ring);
|
||||||
|
|
||||||
return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
|
return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
|
||||||
|
@ -435,7 +435,7 @@ int intel_panel_setup_backlight(struct drm_device *dev)
|
|||||||
props.type = BACKLIGHT_RAW;
|
props.type = BACKLIGHT_RAW;
|
||||||
props.max_brightness = _intel_panel_get_max_backlight(dev);
|
props.max_brightness = _intel_panel_get_max_backlight(dev);
|
||||||
if (props.max_brightness == 0) {
|
if (props.max_brightness == 0) {
|
||||||
DRM_ERROR("Failed to get maximum backlight value\n");
|
DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
dev_priv->backlight =
|
dev_priv->backlight =
|
||||||
|
@ -894,6 +894,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo,
|
||||||
|
unsigned if_index, uint8_t tx_rate,
|
||||||
|
uint8_t *data, unsigned length)
|
||||||
|
{
|
||||||
|
uint8_t set_buf_index[2] = { if_index, 0 };
|
||||||
|
uint8_t hbuf_size, tmp[8];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!intel_sdvo_set_value(intel_sdvo,
|
||||||
|
SDVO_CMD_SET_HBUF_INDEX,
|
||||||
|
set_buf_index, 2))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO,
|
||||||
|
&hbuf_size, 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Buffer size is 0 based, hooray! */
|
||||||
|
hbuf_size++;
|
||||||
|
|
||||||
|
DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n",
|
||||||
|
if_index, length, hbuf_size);
|
||||||
|
|
||||||
|
for (i = 0; i < hbuf_size; i += 8) {
|
||||||
|
memset(tmp, 0, 8);
|
||||||
|
if (i < length)
|
||||||
|
memcpy(tmp, data + i, min_t(unsigned, 8, length - i));
|
||||||
|
|
||||||
|
if (!intel_sdvo_set_value(intel_sdvo,
|
||||||
|
SDVO_CMD_SET_HBUF_DATA,
|
||||||
|
tmp, 8))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return intel_sdvo_set_value(intel_sdvo,
|
||||||
|
SDVO_CMD_SET_HBUF_TXRATE,
|
||||||
|
&tx_rate, 1);
|
||||||
|
}
|
||||||
|
|
||||||
static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
|
static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
|
||||||
{
|
{
|
||||||
struct dip_infoframe avi_if = {
|
struct dip_infoframe avi_if = {
|
||||||
@ -901,11 +940,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
|
|||||||
.ver = DIP_VERSION_AVI,
|
.ver = DIP_VERSION_AVI,
|
||||||
.len = DIP_LEN_AVI,
|
.len = DIP_LEN_AVI,
|
||||||
};
|
};
|
||||||
uint8_t tx_rate = SDVO_HBUF_TX_VSYNC;
|
|
||||||
uint8_t set_buf_index[2] = { 1, 0 };
|
|
||||||
uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)];
|
uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)];
|
||||||
uint64_t *data = (uint64_t *)sdvo_data;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
intel_dip_infoframe_csum(&avi_if);
|
intel_dip_infoframe_csum(&avi_if);
|
||||||
|
|
||||||
@ -915,22 +950,9 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
|
|||||||
sdvo_data[3] = avi_if.checksum;
|
sdvo_data[3] = avi_if.checksum;
|
||||||
memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi));
|
memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi));
|
||||||
|
|
||||||
if (!intel_sdvo_set_value(intel_sdvo,
|
return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF,
|
||||||
SDVO_CMD_SET_HBUF_INDEX,
|
SDVO_HBUF_TX_VSYNC,
|
||||||
set_buf_index, 2))
|
sdvo_data, sizeof(sdvo_data));
|
||||||
return false;
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(sdvo_data); i += 8) {
|
|
||||||
if (!intel_sdvo_set_value(intel_sdvo,
|
|
||||||
SDVO_CMD_SET_HBUF_DATA,
|
|
||||||
data, 8))
|
|
||||||
return false;
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return intel_sdvo_set_value(intel_sdvo,
|
|
||||||
SDVO_CMD_SET_HBUF_TXRATE,
|
|
||||||
&tx_rate, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo)
|
static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo)
|
||||||
|
@ -708,6 +708,8 @@ struct intel_sdvo_enhancements_arg {
|
|||||||
#define SDVO_CMD_SET_AUDIO_STAT 0x91
|
#define SDVO_CMD_SET_AUDIO_STAT 0x91
|
||||||
#define SDVO_CMD_GET_AUDIO_STAT 0x92
|
#define SDVO_CMD_GET_AUDIO_STAT 0x92
|
||||||
#define SDVO_CMD_SET_HBUF_INDEX 0x93
|
#define SDVO_CMD_SET_HBUF_INDEX 0x93
|
||||||
|
#define SDVO_HBUF_INDEX_ELD 0
|
||||||
|
#define SDVO_HBUF_INDEX_AVI_IF 1
|
||||||
#define SDVO_CMD_GET_HBUF_INDEX 0x94
|
#define SDVO_CMD_GET_HBUF_INDEX 0x94
|
||||||
#define SDVO_CMD_GET_HBUF_INFO 0x95
|
#define SDVO_CMD_GET_HBUF_INFO 0x95
|
||||||
#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96
|
#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96
|
||||||
|
@ -264,7 +264,7 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p,
|
|||||||
/* macro tile width & height */
|
/* macro tile width & height */
|
||||||
palign = (8 * surf->bankw * track->npipes) * surf->mtilea;
|
palign = (8 * surf->bankw * track->npipes) * surf->mtilea;
|
||||||
halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea;
|
halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea;
|
||||||
mtileb = (palign / 8) * (halign / 8) * tileb;;
|
mtileb = (palign / 8) * (halign / 8) * tileb;
|
||||||
mtile_pr = surf->nbx / palign;
|
mtile_pr = surf->nbx / palign;
|
||||||
mtile_ps = (mtile_pr * surf->nby) / halign;
|
mtile_ps = (mtile_pr * surf->nby) / halign;
|
||||||
surf->layer_size = mtile_ps * mtileb * slice_pt;
|
surf->layer_size = mtile_ps * mtileb * slice_pt;
|
||||||
|
@ -352,9 +352,9 @@ static int radeon_atpx_switchto(enum vga_switcheroo_client_id id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* radeon_atpx_switchto - switch to the requested GPU
|
* radeon_atpx_power_state - power down/up the requested GPU
|
||||||
*
|
*
|
||||||
* @id: GPU to switch to
|
* @id: GPU to power down/up
|
||||||
* @state: requested power state (0 = off, 1 = on)
|
* @state: requested power state (0 = off, 1 = on)
|
||||||
*
|
*
|
||||||
* Execute the necessary ATPX function to power down/up the discrete GPU
|
* Execute the necessary ATPX function to power down/up the discrete GPU
|
||||||
|
@ -941,7 +941,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
|
|||||||
struct drm_mode_object *obj;
|
struct drm_mode_object *obj;
|
||||||
int i;
|
int i;
|
||||||
enum drm_connector_status ret = connector_status_disconnected;
|
enum drm_connector_status ret = connector_status_disconnected;
|
||||||
bool dret = false;
|
bool dret = false, broken_edid = false;
|
||||||
|
|
||||||
if (!force && radeon_check_hpd_status_unchanged(connector))
|
if (!force && radeon_check_hpd_status_unchanged(connector))
|
||||||
return connector->status;
|
return connector->status;
|
||||||
@ -965,6 +965,9 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
|
|||||||
ret = connector_status_disconnected;
|
ret = connector_status_disconnected;
|
||||||
DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector));
|
DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector));
|
||||||
radeon_connector->ddc_bus = NULL;
|
radeon_connector->ddc_bus = NULL;
|
||||||
|
} else {
|
||||||
|
ret = connector_status_connected;
|
||||||
|
broken_edid = true; /* defer use_digital to later */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
|
radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
|
||||||
@ -1047,13 +1050,24 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
|
|||||||
|
|
||||||
encoder_funcs = encoder->helper_private;
|
encoder_funcs = encoder->helper_private;
|
||||||
if (encoder_funcs->detect) {
|
if (encoder_funcs->detect) {
|
||||||
if (ret != connector_status_connected) {
|
if (!broken_edid) {
|
||||||
ret = encoder_funcs->detect(encoder, connector);
|
if (ret != connector_status_connected) {
|
||||||
if (ret == connector_status_connected) {
|
/* deal with analog monitors without DDC */
|
||||||
radeon_connector->use_digital = false;
|
ret = encoder_funcs->detect(encoder, connector);
|
||||||
|
if (ret == connector_status_connected) {
|
||||||
|
radeon_connector->use_digital = false;
|
||||||
|
}
|
||||||
|
if (ret != connector_status_disconnected)
|
||||||
|
radeon_connector->detected_by_load = true;
|
||||||
}
|
}
|
||||||
if (ret != connector_status_disconnected)
|
} else {
|
||||||
radeon_connector->detected_by_load = true;
|
enum drm_connector_status lret;
|
||||||
|
/* assume digital unless load detected otherwise */
|
||||||
|
radeon_connector->use_digital = true;
|
||||||
|
lret = encoder_funcs->detect(encoder, connector);
|
||||||
|
DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret);
|
||||||
|
if (lret == connector_status_connected)
|
||||||
|
radeon_connector->use_digital = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -295,6 +295,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||||
struct drm_device *dev = crtc->dev;
|
struct drm_device *dev = crtc->dev;
|
||||||
struct radeon_device *rdev = dev->dev_private;
|
struct radeon_device *rdev = dev->dev_private;
|
||||||
|
uint32_t crtc_ext_cntl = 0;
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
|
|
||||||
if (radeon_crtc->crtc_id)
|
if (radeon_crtc->crtc_id)
|
||||||
@ -307,6 +308,16 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||||||
RADEON_CRTC_VSYNC_DIS |
|
RADEON_CRTC_VSYNC_DIS |
|
||||||
RADEON_CRTC_HSYNC_DIS);
|
RADEON_CRTC_HSYNC_DIS);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On all dual CRTC GPUs this bit controls the CRTC of the primary DAC.
|
||||||
|
* Therefore it is set in the DAC DMPS function.
|
||||||
|
* This is different for GPU's with a single CRTC but a primary and a
|
||||||
|
* TV DAC: here it controls the single CRTC no matter where it is
|
||||||
|
* routed. Therefore we set it here.
|
||||||
|
*/
|
||||||
|
if (rdev->flags & RADEON_SINGLE_CRTC)
|
||||||
|
crtc_ext_cntl = RADEON_CRTC_CRT_ON;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case DRM_MODE_DPMS_ON:
|
case DRM_MODE_DPMS_ON:
|
||||||
radeon_crtc->enabled = true;
|
radeon_crtc->enabled = true;
|
||||||
@ -317,7 +328,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||||||
else {
|
else {
|
||||||
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN |
|
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN |
|
||||||
RADEON_CRTC_DISP_REQ_EN_B));
|
RADEON_CRTC_DISP_REQ_EN_B));
|
||||||
WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask);
|
WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl));
|
||||||
}
|
}
|
||||||
drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
|
drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
|
||||||
radeon_crtc_load_lut(crtc);
|
radeon_crtc_load_lut(crtc);
|
||||||
@ -331,7 +342,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||||||
else {
|
else {
|
||||||
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN |
|
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN |
|
||||||
RADEON_CRTC_DISP_REQ_EN_B));
|
RADEON_CRTC_DISP_REQ_EN_B));
|
||||||
WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask);
|
WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~(mask | crtc_ext_cntl));
|
||||||
}
|
}
|
||||||
radeon_crtc->enabled = false;
|
radeon_crtc->enabled = false;
|
||||||
/* adjust pm to dpms changes AFTER disabling crtcs */
|
/* adjust pm to dpms changes AFTER disabling crtcs */
|
||||||
|
@ -537,7 +537,9 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
|
/* handled in radeon_crtc_dpms() */
|
||||||
|
if (!(rdev->flags & RADEON_SINGLE_CRTC))
|
||||||
|
WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
|
||||||
WREG32(RADEON_DAC_CNTL, dac_cntl);
|
WREG32(RADEON_DAC_CNTL, dac_cntl);
|
||||||
WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
|
WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
|
||||||
|
|
||||||
@ -662,6 +664,8 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc
|
|||||||
|
|
||||||
if (ASIC_IS_R300(rdev))
|
if (ASIC_IS_R300(rdev))
|
||||||
tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
|
tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
|
||||||
|
else if (ASIC_IS_RV100(rdev))
|
||||||
|
tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT);
|
||||||
else
|
else
|
||||||
tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
|
tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
|
||||||
|
|
||||||
@ -671,6 +675,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc
|
|||||||
tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
|
tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
|
||||||
WREG32(RADEON_DAC_CNTL, tmp);
|
WREG32(RADEON_DAC_CNTL, tmp);
|
||||||
|
|
||||||
|
tmp = dac_macro_cntl;
|
||||||
tmp &= ~(RADEON_DAC_PDWN_R |
|
tmp &= ~(RADEON_DAC_PDWN_R |
|
||||||
RADEON_DAC_PDWN_G |
|
RADEON_DAC_PDWN_G |
|
||||||
RADEON_DAC_PDWN_B);
|
RADEON_DAC_PDWN_B);
|
||||||
@ -1092,7 +1097,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
|
|||||||
} else {
|
} else {
|
||||||
if (is_tv)
|
if (is_tv)
|
||||||
WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);
|
WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);
|
||||||
else
|
/* handled in radeon_crtc_dpms() */
|
||||||
|
else if (!(rdev->flags & RADEON_SINGLE_CRTC))
|
||||||
WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
|
WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
|
||||||
WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
|
WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
|
||||||
}
|
}
|
||||||
@ -1416,13 +1422,104 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder,
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder,
|
||||||
|
struct drm_connector *connector)
|
||||||
|
{
|
||||||
|
struct drm_device *dev = encoder->dev;
|
||||||
|
struct radeon_device *rdev = dev->dev_private;
|
||||||
|
uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
|
||||||
|
uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c;
|
||||||
|
uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f;
|
||||||
|
uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp;
|
||||||
|
uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
|
||||||
|
bool found = false;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* save the regs we need */
|
||||||
|
gpio_monid = RREG32(RADEON_GPIO_MONID);
|
||||||
|
fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
|
||||||
|
disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
|
||||||
|
crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
|
||||||
|
disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A);
|
||||||
|
disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B);
|
||||||
|
disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C);
|
||||||
|
disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D);
|
||||||
|
disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E);
|
||||||
|
disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F);
|
||||||
|
crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP);
|
||||||
|
crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP);
|
||||||
|
crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID);
|
||||||
|
crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID);
|
||||||
|
|
||||||
|
tmp = RREG32(RADEON_GPIO_MONID);
|
||||||
|
tmp &= ~RADEON_GPIO_A_0;
|
||||||
|
WREG32(RADEON_GPIO_MONID, tmp);
|
||||||
|
|
||||||
|
WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON |
|
||||||
|
RADEON_FP2_PANEL_FORMAT |
|
||||||
|
R200_FP2_SOURCE_SEL_TRANS_UNIT |
|
||||||
|
RADEON_FP2_DVO_EN |
|
||||||
|
R200_FP2_DVO_RATE_SEL_SDR));
|
||||||
|
|
||||||
|
WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX |
|
||||||
|
RADEON_DISP_TRANS_MATRIX_GRAPHICS));
|
||||||
|
|
||||||
|
WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN |
|
||||||
|
RADEON_CRTC2_DISP_REQ_EN_B));
|
||||||
|
|
||||||
|
WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
|
||||||
|
WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
|
||||||
|
WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
|
||||||
|
WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
|
||||||
|
WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
|
||||||
|
WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
|
||||||
|
|
||||||
|
WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
|
||||||
|
WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
|
||||||
|
WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
|
||||||
|
WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
|
||||||
|
|
||||||
|
for (i = 0; i < 200; i++) {
|
||||||
|
tmp = RREG32(RADEON_GPIO_MONID);
|
||||||
|
if (tmp & RADEON_GPIO_Y_0)
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!drm_can_sleep())
|
||||||
|
mdelay(1);
|
||||||
|
else
|
||||||
|
msleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore the regs we used */
|
||||||
|
WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
|
||||||
|
WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
|
||||||
|
WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
|
||||||
|
WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
|
||||||
|
WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
|
||||||
|
WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
|
||||||
|
WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
|
||||||
|
WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
|
||||||
|
WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
|
||||||
|
WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
|
||||||
|
WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
|
||||||
|
WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
|
||||||
|
WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
|
||||||
|
WREG32(RADEON_GPIO_MONID, gpio_monid);
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder,
|
static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder,
|
||||||
struct drm_connector *connector)
|
struct drm_connector *connector)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = encoder->dev;
|
struct drm_device *dev = encoder->dev;
|
||||||
struct radeon_device *rdev = dev->dev_private;
|
struct radeon_device *rdev = dev->dev_private;
|
||||||
uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
|
uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
|
||||||
uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
|
uint32_t gpiopad_a = 0, pixclks_cntl, tmp;
|
||||||
|
uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0;
|
||||||
enum drm_connector_status found = connector_status_disconnected;
|
enum drm_connector_status found = connector_status_disconnected;
|
||||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||||
struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
|
struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
|
||||||
@ -1459,12 +1556,27 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
|
|||||||
return connector_status_disconnected;
|
return connector_status_disconnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* R200 uses an external DAC for secondary DAC */
|
||||||
|
if (rdev->family == CHIP_R200) {
|
||||||
|
if (radeon_legacy_ext_dac_detect(encoder, connector))
|
||||||
|
found = connector_status_connected;
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
/* save the regs we need */
|
/* save the regs we need */
|
||||||
pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL);
|
pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL);
|
||||||
gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0;
|
|
||||||
disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0;
|
if (rdev->flags & RADEON_SINGLE_CRTC) {
|
||||||
disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG);
|
crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
|
||||||
crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
|
} else {
|
||||||
|
if (ASIC_IS_R300(rdev)) {
|
||||||
|
gpiopad_a = RREG32(RADEON_GPIOPAD_A);
|
||||||
|
disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
|
||||||
|
} else {
|
||||||
|
disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG);
|
||||||
|
}
|
||||||
|
crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
|
||||||
|
}
|
||||||
tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
|
tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
|
||||||
dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL);
|
dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL);
|
||||||
dac_cntl2 = RREG32(RADEON_DAC_CNTL2);
|
dac_cntl2 = RREG32(RADEON_DAC_CNTL2);
|
||||||
@ -1473,22 +1585,24 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
|
|||||||
| RADEON_PIX2CLK_DAC_ALWAYS_ONb);
|
| RADEON_PIX2CLK_DAC_ALWAYS_ONb);
|
||||||
WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
|
WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
|
||||||
|
|
||||||
if (ASIC_IS_R300(rdev))
|
if (rdev->flags & RADEON_SINGLE_CRTC) {
|
||||||
WREG32_P(RADEON_GPIOPAD_A, 1, ~1);
|
tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON;
|
||||||
|
WREG32(RADEON_CRTC_EXT_CNTL, tmp);
|
||||||
tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
|
|
||||||
tmp |= RADEON_CRTC2_CRT2_ON |
|
|
||||||
(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
|
|
||||||
|
|
||||||
WREG32(RADEON_CRTC2_GEN_CNTL, tmp);
|
|
||||||
|
|
||||||
if (ASIC_IS_R300(rdev)) {
|
|
||||||
tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
|
|
||||||
tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
|
|
||||||
WREG32(RADEON_DISP_OUTPUT_CNTL, tmp);
|
|
||||||
} else {
|
} else {
|
||||||
tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
|
tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
|
||||||
WREG32(RADEON_DISP_HW_DEBUG, tmp);
|
tmp |= RADEON_CRTC2_CRT2_ON |
|
||||||
|
(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
|
||||||
|
WREG32(RADEON_CRTC2_GEN_CNTL, tmp);
|
||||||
|
|
||||||
|
if (ASIC_IS_R300(rdev)) {
|
||||||
|
WREG32_P(RADEON_GPIOPAD_A, 1, ~1);
|
||||||
|
tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
|
||||||
|
tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
|
||||||
|
WREG32(RADEON_DISP_OUTPUT_CNTL, tmp);
|
||||||
|
} else {
|
||||||
|
tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
|
||||||
|
WREG32(RADEON_DISP_HW_DEBUG, tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = RADEON_TV_DAC_NBLANK |
|
tmp = RADEON_TV_DAC_NBLANK |
|
||||||
@ -1530,14 +1644,19 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
|
|||||||
WREG32(RADEON_DAC_CNTL2, dac_cntl2);
|
WREG32(RADEON_DAC_CNTL2, dac_cntl2);
|
||||||
WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
|
WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
|
||||||
WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
|
WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
|
||||||
WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
|
|
||||||
|
|
||||||
if (ASIC_IS_R300(rdev)) {
|
if (rdev->flags & RADEON_SINGLE_CRTC) {
|
||||||
WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
|
WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
|
||||||
WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
|
|
||||||
} else {
|
} else {
|
||||||
WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
|
WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
|
||||||
|
if (ASIC_IS_R300(rdev)) {
|
||||||
|
WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
|
||||||
|
WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
|
||||||
|
} else {
|
||||||
|
WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
|
WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
|
@ -104,7 +104,7 @@ udl_fb_user_fb_create(struct drm_device *dev,
|
|||||||
|
|
||||||
int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
|
int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
|
||||||
const char *front, char **urb_buf_ptr,
|
const char *front, char **urb_buf_ptr,
|
||||||
u32 byte_offset, u32 byte_width,
|
u32 byte_offset, u32 device_byte_offset, u32 byte_width,
|
||||||
int *ident_ptr, int *sent_ptr);
|
int *ident_ptr, int *sent_ptr);
|
||||||
|
|
||||||
int udl_dumb_create(struct drm_file *file_priv,
|
int udl_dumb_create(struct drm_file *file_priv,
|
||||||
|
@ -114,9 +114,10 @@ static void udlfb_dpy_deferred_io(struct fb_info *info,
|
|||||||
list_for_each_entry(cur, &fbdefio->pagelist, lru) {
|
list_for_each_entry(cur, &fbdefio->pagelist, lru) {
|
||||||
|
|
||||||
if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8),
|
if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8),
|
||||||
&urb, (char *) info->fix.smem_start,
|
&urb, (char *) info->fix.smem_start,
|
||||||
&cmd, cur->index << PAGE_SHIFT,
|
&cmd, cur->index << PAGE_SHIFT,
|
||||||
PAGE_SIZE, &bytes_identical, &bytes_sent))
|
cur->index << PAGE_SHIFT,
|
||||||
|
PAGE_SIZE, &bytes_identical, &bytes_sent))
|
||||||
goto error;
|
goto error;
|
||||||
bytes_rendered += PAGE_SIZE;
|
bytes_rendered += PAGE_SIZE;
|
||||||
}
|
}
|
||||||
@ -187,10 +188,11 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
|
|||||||
for (i = y; i < y + height ; i++) {
|
for (i = y; i < y + height ; i++) {
|
||||||
const int line_offset = fb->base.pitches[0] * i;
|
const int line_offset = fb->base.pitches[0] * i;
|
||||||
const int byte_offset = line_offset + (x * bpp);
|
const int byte_offset = line_offset + (x * bpp);
|
||||||
|
const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp);
|
||||||
if (udl_render_hline(dev, bpp, &urb,
|
if (udl_render_hline(dev, bpp, &urb,
|
||||||
(char *) fb->obj->vmapping,
|
(char *) fb->obj->vmapping,
|
||||||
&cmd, byte_offset, width * bpp,
|
&cmd, byte_offset, dev_byte_offset,
|
||||||
|
width * bpp,
|
||||||
&bytes_identical, &bytes_sent))
|
&bytes_identical, &bytes_sent))
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -213,11 +213,12 @@ static void udl_compress_hline16(
|
|||||||
*/
|
*/
|
||||||
int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
|
int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
|
||||||
const char *front, char **urb_buf_ptr,
|
const char *front, char **urb_buf_ptr,
|
||||||
u32 byte_offset, u32 byte_width,
|
u32 byte_offset, u32 device_byte_offset,
|
||||||
|
u32 byte_width,
|
||||||
int *ident_ptr, int *sent_ptr)
|
int *ident_ptr, int *sent_ptr)
|
||||||
{
|
{
|
||||||
const u8 *line_start, *line_end, *next_pixel;
|
const u8 *line_start, *line_end, *next_pixel;
|
||||||
u32 base16 = 0 + (byte_offset / bpp) * 2;
|
u32 base16 = 0 + (device_byte_offset / bpp) * 2;
|
||||||
struct urb *urb = *urb_ptr;
|
struct urb *urb = *urb_ptr;
|
||||||
u8 *cmd = *urb_buf_ptr;
|
u8 *cmd = *urb_buf_ptr;
|
||||||
u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;
|
u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;
|
||||||
|
Loading…
Reference in New Issue
Block a user