drm/radeon/cik: add hw cursor support (v2)

CIK (DCE8) hw cursors are programmed the same as evergreen
(DCE4) with the following caveats:
- cursors are now 128x128 pixels
- new alpha blend enable bit

v2: rebase

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Alex Deucher 2013-01-24 10:06:33 -05:00
parent cd84a27d18
commit 9e05fa1d24
6 changed files with 94 additions and 7 deletions

View File

@ -0,0 +1,65 @@
/*
* Copyright 2012 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Alex Deucher
*/
#ifndef __CIK_REG_H__
#define __CIK_REG_H__
#define CIK_DC_GPIO_HPD_MASK 0x65b0
#define CIK_DC_GPIO_HPD_A 0x65b4
#define CIK_DC_GPIO_HPD_EN 0x65b8
#define CIK_DC_GPIO_HPD_Y 0x65bc
/* CUR blocks at 0x6998, 0x7598, 0x10198, 0x10d98, 0x11998, 0x12598 */
#define CIK_CUR_CONTROL 0x6998
# define CIK_CURSOR_EN (1 << 0)
# define CIK_CURSOR_MODE(x) (((x) & 0x3) << 8)
# define CIK_CURSOR_MONO 0
# define CIK_CURSOR_24_1 1
# define CIK_CURSOR_24_8_PRE_MULT 2
# define CIK_CURSOR_24_8_UNPRE_MULT 3
# define CIK_CURSOR_2X_MAGNIFY (1 << 16)
# define CIK_CURSOR_FORCE_MC_ON (1 << 20)
# define CIK_CURSOR_URGENT_CONTROL(x) (((x) & 0x7) << 24)
# define CIK_CURSOR_URGENT_ALWAYS 0
# define CIK_CURSOR_URGENT_1_8 1
# define CIK_CURSOR_URGENT_1_4 2
# define CIK_CURSOR_URGENT_3_8 3
# define CIK_CURSOR_URGENT_1_2 4
#define CIK_CUR_SURFACE_ADDRESS 0x699c
# define CIK_CUR_SURFACE_ADDRESS_MASK 0xfffff000
#define CIK_CUR_SIZE 0x69a0
#define CIK_CUR_SURFACE_ADDRESS_HIGH 0x69a4
#define CIK_CUR_POSITION 0x69a8
#define CIK_CUR_HOT_SPOT 0x69ac
#define CIK_CUR_COLOR1 0x69b0
#define CIK_CUR_COLOR2 0x69b4
#define CIK_CUR_UPDATE 0x69b8
# define CIK_CURSOR_UPDATE_PENDING (1 << 0)
# define CIK_CURSOR_UPDATE_TAKEN (1 << 1)
# define CIK_CURSOR_UPDATE_LOCK (1 << 16)
# define CIK_CURSOR_DISABLE_MULTIPLE_UPDATE (1 << 24)
#define CIK_ALPHA_CONTROL 0x6af0
# define CIK_CURSOR_ALPHA_BLND_ENA (1 << 1)
#endif

View File

@ -150,6 +150,13 @@ extern int radeon_fastfb;
#define RADEON_RESET_MC (1 << 10) #define RADEON_RESET_MC (1 << 10)
#define RADEON_RESET_DISPLAY (1 << 11) #define RADEON_RESET_DISPLAY (1 << 11)
/* max cursor sizes (in pixels) */
#define CURSOR_WIDTH 64
#define CURSOR_HEIGHT 64
#define CIK_CURSOR_WIDTH 128
#define CIK_CURSOR_HEIGHT 128
/* /*
* Errata workarounds. * Errata workarounds.
*/ */

View File

@ -27,9 +27,6 @@
#include <drm/radeon_drm.h> #include <drm/radeon_drm.h>
#include "radeon.h" #include "radeon.h"
#define CURSOR_WIDTH 64
#define CURSOR_HEIGHT 64
static void radeon_lock_cursor(struct drm_crtc *crtc, bool lock) static void radeon_lock_cursor(struct drm_crtc *crtc, bool lock)
{ {
struct radeon_device *rdev = crtc->dev->dev_private; struct radeon_device *rdev = crtc->dev->dev_private;
@ -167,7 +164,8 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc,
goto unpin; goto unpin;
} }
if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) { if ((width > radeon_crtc->max_cursor_width) ||
(height > radeon_crtc->max_cursor_height)) {
DRM_ERROR("bad cursor width or height %d x %d\n", width, height); DRM_ERROR("bad cursor width or height %d x %d\n", width, height);
return -EINVAL; return -EINVAL;
} }
@ -233,11 +231,11 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc,
DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y);
if (x < 0) { if (x < 0) {
xorigin = min(-x, CURSOR_WIDTH - 1); xorigin = min(-x, radeon_crtc->max_cursor_width - 1);
x = 0; x = 0;
} }
if (y < 0) { if (y < 0) {
yorigin = min(-y, CURSOR_HEIGHT - 1); yorigin = min(-y, radeon_crtc->max_cursor_height - 1);
y = 0; y = 0;
} }

View File

@ -153,7 +153,13 @@ static void dce5_crtc_load_lut(struct drm_crtc *crtc)
NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS))); NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS)));
/* XXX match this to the depth of the crtc fmt block, move to modeset? */ /* XXX match this to the depth of the crtc fmt block, move to modeset? */
WREG32(0x6940 + radeon_crtc->crtc_offset, 0); WREG32(0x6940 + radeon_crtc->crtc_offset, 0);
if (ASIC_IS_DCE8(rdev)) {
/* XXX this only needs to be programmed once per crtc at startup,
* not sure where the best place for it is
*/
WREG32(CIK_ALPHA_CONTROL + radeon_crtc->crtc_offset,
CIK_CURSOR_ALPHA_BLND_ENA);
}
} }
static void legacy_crtc_load_lut(struct drm_crtc *crtc) static void legacy_crtc_load_lut(struct drm_crtc *crtc)
@ -512,6 +518,14 @@ static void radeon_crtc_init(struct drm_device *dev, int index)
radeon_crtc->crtc_id = index; radeon_crtc->crtc_id = index;
rdev->mode_info.crtcs[index] = radeon_crtc; rdev->mode_info.crtcs[index] = radeon_crtc;
if (rdev->family >= CHIP_BONAIRE) {
radeon_crtc->max_cursor_width = CIK_CURSOR_WIDTH;
radeon_crtc->max_cursor_height = CIK_CURSOR_HEIGHT;
} else {
radeon_crtc->max_cursor_width = CURSOR_WIDTH;
radeon_crtc->max_cursor_height = CURSOR_HEIGHT;
}
#if 0 #if 0
radeon_crtc->mode_set.crtc = &radeon_crtc->base; radeon_crtc->mode_set.crtc = &radeon_crtc->base;
radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1); radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1);

View File

@ -307,6 +307,8 @@ struct radeon_crtc {
uint64_t cursor_addr; uint64_t cursor_addr;
int cursor_width; int cursor_width;
int cursor_height; int cursor_height;
int max_cursor_width;
int max_cursor_height;
uint32_t legacy_display_base_addr; uint32_t legacy_display_base_addr;
uint32_t legacy_cursor_offset; uint32_t legacy_cursor_offset;
enum radeon_rmx_type rmx_type; enum radeon_rmx_type rmx_type;

View File

@ -57,6 +57,7 @@
#include "evergreen_reg.h" #include "evergreen_reg.h"
#include "ni_reg.h" #include "ni_reg.h"
#include "si_reg.h" #include "si_reg.h"
#include "cik_reg.h"
#define RADEON_MC_AGP_LOCATION 0x014c #define RADEON_MC_AGP_LOCATION 0x014c
#define RADEON_MC_AGP_START_MASK 0x0000FFFF #define RADEON_MC_AGP_START_MASK 0x0000FFFF