30,6 → 30,18 |
#include "radeon.h" |
#include "atom.h" |
|
static void radeon_overscan_setup(struct drm_crtc *crtc, |
struct drm_display_mode *mode) |
{ |
struct drm_device *dev = crtc->dev; |
struct radeon_device *rdev = dev->dev_private; |
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
|
WREG32(RADEON_OVR_CLR + radeon_crtc->crtc_offset, 0); |
WREG32(RADEON_OVR_WID_LEFT_RIGHT + radeon_crtc->crtc_offset, 0); |
WREG32(RADEON_OVR_WID_TOP_BOTTOM + radeon_crtc->crtc_offset, 0); |
} |
|
static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, |
struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode) |
292,8 → 304,7 |
uint32_t mask; |
|
if (radeon_crtc->crtc_id) |
mask = (RADEON_CRTC2_EN | |
RADEON_CRTC2_DISP_DIS | |
mask = (RADEON_CRTC2_DISP_DIS | |
RADEON_CRTC2_VSYNC_DIS | |
RADEON_CRTC2_HSYNC_DIS | |
RADEON_CRTC2_DISP_REQ_EN_B); |
305,7 → 316,7 |
switch (mode) { |
case DRM_MODE_DPMS_ON: |
if (radeon_crtc->crtc_id) |
WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~mask); |
WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask)); |
else { |
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | |
RADEON_CRTC_DISP_REQ_EN_B)); |
319,7 → 330,7 |
case DRM_MODE_DPMS_OFF: |
// drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); |
if (radeon_crtc->crtc_id) |
WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask); |
WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask)); |
else { |
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | |
RADEON_CRTC_DISP_REQ_EN_B)); |
400,6 → 411,7 |
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
struct radeon_framebuffer *radeon_fb; |
struct drm_gem_object *obj; |
struct radeon_bo *rbo; |
uint64_t base; |
uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0; |
uint32_t crtc_pitch, pitch_pixels; |
406,8 → 418,14 |
uint32_t tiling_flags; |
int format; |
uint32_t gen_cntl_reg, gen_cntl_val; |
int r; |
|
DRM_DEBUG("\n"); |
/* no fb bound */ |
if (!crtc->fb) { |
DRM_DEBUG("No FB bound\n"); |
return 0; |
} |
|
radeon_fb = to_radeon_framebuffer(crtc->fb); |
|
431,11 → 449,21 |
return false; |
} |
|
/* Pin framebuffer & get tilling informations */ |
obj = radeon_fb->obj; |
// if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &base)) { |
// return -EINVAL; |
// } |
base = rdev->mc.vram_location; |
rbo = obj->driver_private; |
r = radeon_bo_reserve(rbo, false); |
if (unlikely(r != 0)) |
return r; |
r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &base); |
if (unlikely(r != 0)) { |
radeon_bo_unreserve(rbo); |
return -EINVAL; |
} |
radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); |
radeon_bo_unreserve(rbo); |
if (tiling_flags & RADEON_TILING_MICRO) |
DRM_ERROR("trying to scanout microtiled buffer\n"); |
|
/* if scanout was in GTT this really wouldn't work */ |
/* crtc offset is from display base addr not FB location */ |
451,13 → 479,7 |
(crtc->fb->bits_per_pixel * 8)); |
crtc_pitch |= crtc_pitch << 16; |
|
// radeon_object_get_tiling_flags(obj->driver_private, |
// &tiling_flags, NULL); |
tiling_flags = 0; |
|
if (tiling_flags & RADEON_TILING_MICRO) |
DRM_ERROR("trying to scanout microtiled buffer\n"); |
|
if (tiling_flags & RADEON_TILING_MACRO) { |
if (ASIC_IS_R300(rdev)) |
crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN | |
532,10 → 554,15 |
WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset); |
WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch); |
|
// if (old_fb && old_fb != crtc->fb) { |
// radeon_fb = to_radeon_framebuffer(old_fb); |
// radeon_gem_object_unpin(radeon_fb->obj); |
// } |
if (old_fb && old_fb != crtc->fb) { |
radeon_fb = to_radeon_framebuffer(old_fb); |
rbo = radeon_fb->obj->driver_private; |
r = radeon_bo_reserve(rbo, false); |
if (unlikely(r != 0)) |
return r; |
radeon_bo_unpin(rbo); |
radeon_bo_unreserve(rbo); |
} |
|
/* Bytes per pixel may have changed */ |
radeon_bandwidth_update(rdev); |
646,12 → 673,8 |
uint32_t crtc2_gen_cntl; |
uint32_t disp2_merge_cntl; |
|
/* check to see if TV DAC is enabled for another crtc and keep it enabled */ |
if (RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_CRT2_ON) |
crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON; |
else |
crtc2_gen_cntl = 0; |
|
/* if TV DAC is enabled for another crtc and keep it enabled */ |
crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL) & 0x00718080; |
crtc2_gen_cntl |= ((format << 8) |
| RADEON_CRTC2_VSYNC_DIS |
| RADEON_CRTC2_HSYNC_DIS |
680,7 → 703,8 |
uint32_t crtc_ext_cntl; |
uint32_t disp_merge_cntl; |
|
crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN |
crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL) & 0x00718000; |
crtc_gen_cntl |= (RADEON_CRTC_EXT_DISP_EN |
| (format << 8) |
| RADEON_CRTC_DISP_REQ_EN_B |
| ((mode->flags & DRM_MODE_FLAG_DBLSCAN) |
783,6 → 807,7 |
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) |
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; |
if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { |
if (!rdev->is_atom_bios) { |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; |
if (lvds) { |
794,6 → 819,7 |
use_bios_divs = true; |
} |
} |
} |
pll_flags |= RADEON_PLL_USE_REF_DIV; |
} |
} |
1031,6 → 1057,7 |
radeon_crtc_set_base(crtc, x, y, old_fb); |
radeon_set_crtc_timing(crtc, adjusted_mode); |
radeon_set_pll(crtc, adjusted_mode); |
radeon_overscan_setup(crtc, adjusted_mode); |
if (radeon_crtc->crtc_id == 0) { |
radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode); |
} else { |
1046,13 → 1073,30 |
|
static void radeon_crtc_prepare(struct drm_crtc *crtc) |
{ |
radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
struct drm_device *dev = crtc->dev; |
struct drm_crtc *crtci; |
|
/* |
* The hardware wedges sometimes if you reconfigure one CRTC |
* whilst another is running (see fdo bug #24611). |
*/ |
list_for_each_entry(crtci, &dev->mode_config.crtc_list, head) |
radeon_crtc_dpms(crtci, DRM_MODE_DPMS_OFF); |
} |
|
static void radeon_crtc_commit(struct drm_crtc *crtc) |
{ |
radeon_crtc_dpms(crtc, DRM_MODE_DPMS_ON); |
struct drm_device *dev = crtc->dev; |
struct drm_crtc *crtci; |
|
/* |
* Reenable the CRTCs that should be running. |
*/ |
list_for_each_entry(crtci, &dev->mode_config.crtc_list, head) { |
if (crtci->enabled) |
radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); |
} |
} |
|
static const struct drm_crtc_helper_funcs legacy_helper_funcs = { |
.dpms = radeon_crtc_dpms, |