.destroy = amdgpu_dm_encoder_destroy,
};
-static void dm_set_cursor(
- struct amdgpu_crtc *amdgpu_crtc,
- uint64_t gpu_addr,
- uint32_t width,
- uint32_t height)
-{
- struct dc_cursor_attributes attributes;
- struct dc_cursor_position position;
- struct drm_crtc *crtc = &amdgpu_crtc->base;
- int x, y;
- int xorigin = 0, yorigin = 0;
- struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state);
-
- amdgpu_crtc->cursor_width = width;
- amdgpu_crtc->cursor_height = height;
-
- attributes.address.high_part = upper_32_bits(gpu_addr);
- attributes.address.low_part = lower_32_bits(gpu_addr);
- attributes.width = width;
- attributes.height = height;
- attributes.color_format = CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA;
- attributes.rotation_angle = 0;
- attributes.attribute_flags.value = 0;
-
- attributes.pitch = attributes.width;
-
- x = amdgpu_crtc->cursor_x;
- y = amdgpu_crtc->cursor_y;
-
- /* avivo cursor are offset into the total surface */
- x += crtc->primary->state->src_x >> 16;
- y += crtc->primary->state->src_y >> 16;
-
- if (x < 0) {
- xorigin = min(-x, amdgpu_crtc->max_cursor_width - 1);
- x = 0;
- }
- if (y < 0) {
- yorigin = min(-y, amdgpu_crtc->max_cursor_height - 1);
- y = 0;
- }
-
- position.enable = true;
- position.x = x;
- position.y = y;
-
- position.x_hotspot = xorigin;
- position.y_hotspot = yorigin;
-
- if (!dc_stream_set_cursor_attributes(
- acrtc_state->stream,
- &attributes)) {
- DRM_ERROR("DC failed to set cursor attributes\n");
- }
-
- if (!dc_stream_set_cursor_position(
- acrtc_state->stream,
- &position)) {
- DRM_ERROR("DC failed to set cursor position\n");
- }
-}
-
-static int dm_crtc_cursor_set(
- struct drm_crtc *crtc,
- uint64_t address,
- uint32_t width,
- uint32_t height)
-{
- struct dc_cursor_position position;
- struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state);
-
- int ret;
-
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- ret = EINVAL;
-
- DRM_DEBUG_KMS("%s: crtc_id=%d with size %d to %d \n",
- __func__,
- amdgpu_crtc->crtc_id,
- width,
- height);
-
- if (!address) {
- /* turn off cursor */
- position.enable = false;
- position.x = 0;
- position.y = 0;
-
- if (acrtc_state->stream) {
- /*set cursor visible false*/
- dc_stream_set_cursor_position(
- acrtc_state->stream,
- &position);
- }
- goto release;
-
- }
-
- if ((width > amdgpu_crtc->max_cursor_width) ||
- (height > amdgpu_crtc->max_cursor_height)) {
- DRM_ERROR(
- "%s: bad cursor width or height %d x %d\n",
- __func__,
- width,
- height);
- goto release;
- }
-
- /*program new cursor bo to hardware*/
- dm_set_cursor(amdgpu_crtc, address, width, height);
-
-release:
- return ret;
-
-}
-
-static int dm_crtc_cursor_move(struct drm_crtc *crtc,
- int x, int y)
-{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- int xorigin = 0, yorigin = 0;
- struct dc_cursor_position position;
- struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state);
-
- amdgpu_crtc->cursor_x = x;
- amdgpu_crtc->cursor_y = y;
-
- /* avivo cursor are offset into the total surface */
- x += crtc->primary->state->src_x >> 16;
- y += crtc->primary->state->src_y >> 16;
-
- /*
- * TODO: for cursor debugging unguard the following
- */
-#if 0
- DRM_DEBUG_KMS(
- "%s: x %d y %d c->x %d c->y %d\n",
- __func__,
- x,
- y,
- crtc->x,
- crtc->y);
-#endif
-
- if (x < 0) {
- xorigin = min(-x, amdgpu_crtc->max_cursor_width - 1);
- x = 0;
- }
- if (y < 0) {
- yorigin = min(-y, amdgpu_crtc->max_cursor_height - 1);
- y = 0;
- }
-
- position.enable = true;
- position.x = x;
- position.y = y;
-
- position.x_hotspot = xorigin;
- position.y_hotspot = yorigin;
-
- if (acrtc_state->stream) {
- if (!dc_stream_set_cursor_position(
- acrtc_state->stream,
- &position)) {
- DRM_ERROR("DC failed to set cursor position\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
static bool fill_rects_from_plane_state(
const struct drm_plane_state *state,
struct dc_plane_state *plane_state)
acrtc->enabled = false;
}
+int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc,
+ struct dc_cursor_position *position)
+{
+ struct amdgpu_crtc *amdgpu_crtc = amdgpu_crtc = to_amdgpu_crtc(crtc);
+ int x, y;
+ int xorigin = 0, yorigin = 0;
+
+ if (!crtc || !plane->state->fb) {
+ position->enable = false;
+ position->x = 0;
+ position->y = 0;
+ return 0;
+ }
+
+ if ((plane->state->crtc_w > amdgpu_crtc->max_cursor_width) ||
+ (plane->state->crtc_h > amdgpu_crtc->max_cursor_height)) {
+ DRM_ERROR("%s: bad cursor width or height %d x %d\n",
+ __func__,
+ plane->state->crtc_w,
+ plane->state->crtc_h);
+ return -EINVAL;
+ }
+
+ x = plane->state->crtc_x;
+ y = plane->state->crtc_y;
+ /* avivo cursor are offset into the total surface */
+ x += crtc->primary->state->src_x >> 16;
+ y += crtc->primary->state->src_y >> 16;
+ if (x < 0) {
+ xorigin = min(-x, amdgpu_crtc->max_cursor_width - 1);
+ x = 0;
+ }
+ if (y < 0) {
+ yorigin = min(-y, amdgpu_crtc->max_cursor_height - 1);
+ y = 0;
+ }
+ position->enable = true;
+ position->x = x;
+ position->y = y;
+ position->x_hotspot = xorigin;
+ position->y_hotspot = yorigin;
+
+ return 0;
+}
+
static void handle_cursor_update(
struct drm_plane *plane,
struct drm_plane_state *old_plane_state)
{
+ struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(plane->state->fb);
+ struct drm_crtc *crtc = afb ? plane->state->crtc : old_plane_state->crtc;
+ struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL;
+ struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+ uint64_t address = afb ? afb->address : 0;
+ struct dc_cursor_position position;
+ struct dc_cursor_attributes attributes;
+ int ret;
+
if (!plane->state->fb && !old_plane_state->fb)
return;
- /* Check if it's a cursor on/off update or just cursor move*/
- if (plane->state->fb == old_plane_state->fb)
- dm_crtc_cursor_move(
- plane->state->crtc,
- plane->state->crtc_x,
- plane->state->crtc_y);
- else {
- struct amdgpu_framebuffer *afb =
- to_amdgpu_framebuffer(plane->state->fb);
- dm_crtc_cursor_set(
- (!!plane->state->fb) ?
- plane->state->crtc :
- old_plane_state->crtc,
- (!!plane->state->fb) ?
- afb->address :
- 0,
- plane->state->crtc_w,
- plane->state->crtc_h);
+ DRM_DEBUG_KMS("%s: crtc_id=%d with size %d to %d\n",
+ __func__,
+ amdgpu_crtc->crtc_id,
+ plane->state->crtc_w,
+ plane->state->crtc_h);
+
+ ret = get_cursor_position(plane, crtc, &position);
+ if (ret)
+ return;
+
+ if (!position.enable) {
+ /* turn off cursor */
+ if (crtc_state && crtc_state->stream)
+ dc_stream_set_cursor_position(crtc_state->stream,
+ &position);
+ return;
}
-}
+ amdgpu_crtc->cursor_width = plane->state->crtc_w;
+ amdgpu_crtc->cursor_height = plane->state->crtc_h;
+
+ attributes.address.high_part = upper_32_bits(address);
+ attributes.address.low_part = lower_32_bits(address);
+ attributes.width = plane->state->crtc_w;
+ attributes.height = plane->state->crtc_h;
+ attributes.color_format = CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA;
+ attributes.rotation_angle = 0;
+ attributes.attribute_flags.value = 0;
+
+ attributes.pitch = attributes.width;
+
+ if (!dc_stream_set_cursor_attributes(crtc_state->stream,
+ &attributes))
+ DRM_ERROR("DC failed to set cursor attributes\n");
+
+ if (crtc_state->stream)
+ if (!dc_stream_set_cursor_position(crtc_state->stream,
+ &position))
+ DRM_ERROR("DC failed to set cursor position\n");
+}
static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
{