summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/radeon/atombios_crtc.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2014-06-08 10:24:07 +0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-06-08 10:24:07 +0400
commita292241cccb7e20e8b997a9a44177e7c98141859 (patch)
treea0b0bb95e7dce3233a2d8b203f9e326cdec7a00e /drivers/gpu/drm/radeon/atombios_crtc.c
parentd49cb7aeebb974713f9f7ab2991352d3050b095b (diff)
parent68807a0c2015cb40df4869e16651f0ce5cc14d52 (diff)
downloadlinux-a292241cccb7e20e8b997a9a44177e7c98141859.tar.xz
Merge branch 'next' into for-linus
Prepare input updates for 3.16.
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_crtc.c')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c90
1 files changed, 62 insertions, 28 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 0d19f4f94d5a..c31c12b4e666 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1106,7 +1106,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
int r;
/* no fb bound */
- if (!atomic && !crtc->fb) {
+ if (!atomic && !crtc->primary->fb) {
DRM_DEBUG_KMS("No FB bound\n");
return 0;
}
@@ -1116,8 +1116,8 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
target_fb = fb;
}
else {
- radeon_fb = to_radeon_framebuffer(crtc->fb);
- target_fb = crtc->fb;
+ radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
+ target_fb = crtc->primary->fb;
}
/* If atomic, assume fb object is pinned & idle & fenced and
@@ -1177,27 +1177,43 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
/* Set NUM_BANKS. */
if (rdev->family >= CHIP_TAHITI) {
- unsigned tileb, index, num_banks, tile_split_bytes;
+ unsigned index, num_banks;
- /* Calculate the macrotile mode index. */
- tile_split_bytes = 64 << tile_split;
- tileb = 8 * 8 * target_fb->bits_per_pixel / 8;
- tileb = min(tile_split_bytes, tileb);
+ if (rdev->family >= CHIP_BONAIRE) {
+ unsigned tileb, tile_split_bytes;
- for (index = 0; tileb > 64; index++) {
- tileb >>= 1;
- }
+ /* Calculate the macrotile mode index. */
+ tile_split_bytes = 64 << tile_split;
+ tileb = 8 * 8 * target_fb->bits_per_pixel / 8;
+ tileb = min(tile_split_bytes, tileb);
- if (index >= 16) {
- DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n",
- target_fb->bits_per_pixel, tile_split);
- return -EINVAL;
- }
+ for (index = 0; tileb > 64; index++)
+ tileb >>= 1;
+
+ if (index >= 16) {
+ DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n",
+ target_fb->bits_per_pixel, tile_split);
+ return -EINVAL;
+ }
- if (rdev->family >= CHIP_BONAIRE)
num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3;
- else
+ } else {
+ switch (target_fb->bits_per_pixel) {
+ case 8:
+ index = 10;
+ break;
+ case 16:
+ index = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
+ break;
+ default:
+ case 32:
+ index = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
+ break;
+ }
+
num_banks = (rdev->config.si.tile_mode_array[index] >> 20) & 0x3;
+ }
+
fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks);
} else {
/* NI and older. */
@@ -1316,7 +1332,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
/* set pageflip to happen anywhere in vblank interval */
WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
- if (!atomic && fb && fb != crtc->fb) {
+ if (!atomic && fb && fb != crtc->primary->fb) {
radeon_fb = to_radeon_framebuffer(fb);
rbo = gem_to_radeon_bo(radeon_fb->obj);
r = radeon_bo_reserve(rbo, false);
@@ -1350,7 +1366,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
int r;
/* no fb bound */
- if (!atomic && !crtc->fb) {
+ if (!atomic && !crtc->primary->fb) {
DRM_DEBUG_KMS("No FB bound\n");
return 0;
}
@@ -1360,8 +1376,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
target_fb = fb;
}
else {
- radeon_fb = to_radeon_framebuffer(crtc->fb);
- target_fb = crtc->fb;
+ radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
+ target_fb = crtc->primary->fb;
}
obj = radeon_fb->obj;
@@ -1485,7 +1501,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
/* set pageflip to happen anywhere in vblank interval */
WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
- if (!atomic && fb && fb != crtc->fb) {
+ if (!atomic && fb && fb != crtc->primary->fb) {
radeon_fb = to_radeon_framebuffer(fb);
rbo = gem_to_radeon_bo(radeon_fb->obj);
r = radeon_bo_reserve(rbo, false);
@@ -1720,8 +1736,9 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
}
/* otherwise, pick one of the plls */
if ((rdev->family == CHIP_KAVERI) ||
- (rdev->family == CHIP_KABINI)) {
- /* KB/KV has PPLL1 and PPLL2 */
+ (rdev->family == CHIP_KABINI) ||
+ (rdev->family == CHIP_MULLINS)) {
+ /* KB/KV/ML has PPLL1 and PPLL2 */
pll_in_use = radeon_get_pll_use_mask(crtc);
if (!(pll_in_use & (1 << ATOM_PPLL2)))
return ATOM_PPLL2;
@@ -1774,6 +1791,20 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
return ATOM_PPLL1;
DRM_ERROR("unable to allocate a PPLL\n");
return ATOM_PPLL_INVALID;
+ } else if (ASIC_IS_DCE41(rdev)) {
+ /* Don't share PLLs on DCE4.1 chips */
+ if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
+ if (rdev->clock.dp_extclk)
+ /* skip PPLL programming if using ext clock */
+ return ATOM_PPLL_INVALID;
+ }
+ pll_in_use = radeon_get_pll_use_mask(crtc);
+ if (!(pll_in_use & (1 << ATOM_PPLL1)))
+ return ATOM_PPLL1;
+ if (!(pll_in_use & (1 << ATOM_PPLL2)))
+ return ATOM_PPLL2;
+ DRM_ERROR("unable to allocate a PPLL\n");
+ return ATOM_PPLL_INVALID;
} else if (ASIC_IS_DCE4(rdev)) {
/* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
* depending on the asic:
@@ -1801,7 +1832,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
if (pll != ATOM_PPLL_INVALID)
return pll;
}
- } else if (!ASIC_IS_DCE41(rdev)) { /* Don't share PLLs on DCE4.1 chips */
+ } else {
/* use the same PPLL for all monitors with the same clock */
pll = radeon_get_shared_nondp_ppll(crtc);
if (pll != ATOM_PPLL_INVALID)
@@ -1871,6 +1902,9 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
(ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
is_tvcv = true;
+ if (!radeon_crtc->adjusted_clock)
+ return -EINVAL;
+
atombios_crtc_set_pll(crtc, adjusted_mode);
if (ASIC_IS_DCE4(rdev))
@@ -1958,12 +1992,12 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
int i;
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
- if (crtc->fb) {
+ if (crtc->primary->fb) {
int r;
struct radeon_framebuffer *radeon_fb;
struct radeon_bo *rbo;
- radeon_fb = to_radeon_framebuffer(crtc->fb);
+ radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
rbo = gem_to_radeon_bo(radeon_fb->obj);
r = radeon_bo_reserve(rbo, false);
if (unlikely(r))