Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3883358e authored by Beeresh Gopal's avatar Beeresh Gopal
Browse files

msm: mdss: Support cursor hotspot feature



Handle FB_CUR_SETHOT flag to enable cursor hotspot support.

The cursor hotspot is a point on the cursor image used as the active
aiming pixel for user input focused on the display.

The default cursor hotspot is at (0, 0) i.e., the upper left corner
of the cursor image. This works for a typical cursor image like a
mouse pointer with the tip of the pointer arrow at the (0, 0)
position of the cursor image. If the cursor is a cross-hair, its
hotspot would be at (31, 31) i.e., the centre of the 64x64 cursor
image. For a 64x64 cursor, the hotspot is specified from (0, 0) to
(63, 63). The cursor's hotspot pixel is displayed at the
(img->dx, img-dy) cursor position on the screen.

Change-Id: I366d3e3faea17c4fa083adaec30e9ce83f742d6f
Signed-off-by: default avatarBeeresh Gopal <gbeeresh@codeaurora.org>
Signed-off-by: default avatarMathew Karimpanal <kjmathew@codeaurora.org>
parent 078636be
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -214,6 +214,8 @@ struct mdss_mdp_mixer {
	u16 height;
	struct mdss_mdp_img_rect roi;
	u8 cursor_enabled;
	u16 cursor_hotx;
	u16 cursor_hoty;
	u8 rotator_mode;

	struct mdss_mdp_ctl *ctl;
+57 −8
Original line number Diff line number Diff line
@@ -1798,6 +1798,19 @@ static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd,
	struct fb_image *img = &cursor->image;
	u32 blendcfg;
	int ret = 0;
	u32 xres = mfd->fbi->var.xres;
	u32 yres = mfd->fbi->var.yres;
	u32 start_x = img->dx;
	u32 start_y = img->dy;
	u32 roi_x = 0;
	u32 roi_y = 0;
	int roi_w = 0;
	int roi_h = 0;
	int roi_size = 0;

	mixer = mdss_mdp_mixer_get(mdp5_data->ctl, MDSS_MDP_MIXER_MUX_DEFAULT);
	if (!mixer)
		return -ENODEV;

	if (!mfd->cursor_buf && (cursor->set & FB_CUR_SETIMAGE)) {
		mfd->cursor_buf = dma_alloc_coherent(NULL, MDSS_MDP_CURSOR_SIZE,
@@ -1820,15 +1833,14 @@ static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd,
			       ret);
			return ret;
		}
	}

	mixer = mdss_mdp_mixer_get(mdp5_data->ctl, MDSS_MDP_MIXER_MUX_DEFAULT);
	if (!mixer)
		return -ENODEV;
		mixer->cursor_hotx = 0;
		mixer->cursor_hoty = 0;
	}

	if ((img->width > MDSS_MDP_CURSOR_WIDTH) ||
		(img->height > MDSS_MDP_CURSOR_HEIGHT) ||
		(img->depth != 32))
		(img->depth != 32) || (start_x >= xres) || (start_y >= yres))
		return -EINVAL;

	pr_debug("mixer=%d enable=%x set=%x\n", mixer->num, cursor->enable,
@@ -1837,9 +1849,43 @@ static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd,
	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
	blendcfg = mdp_mixer_read(mixer, MDSS_MDP_REG_LM_CURSOR_BLEND_CONFIG);

	if (cursor->set & FB_CUR_SETPOS)
	if (cursor->set & FB_CUR_SETHOT) {
		if ((cursor->hot.x < img->width) &&
			(cursor->hot.y < img->height)) {
			mixer->cursor_hotx = cursor->hot.x;
			mixer->cursor_hoty = cursor->hot.y;
			 /* Update cursor position */
			cursor->set |= FB_CUR_SETPOS;
		} else {
			pr_err("Invalid cursor hotspot coordinates\n");
			return -EINVAL;
		}
	}

	if (start_x > mixer->cursor_hotx) {
		start_x -= mixer->cursor_hotx;
	} else {
		roi_x = mixer->cursor_hotx - start_x;
		start_x = 0;
	}
	if (start_y > mixer->cursor_hoty) {
		start_y -= mixer->cursor_hoty;
	} else {
		roi_y = mixer->cursor_hoty - start_y;
		start_y = 0;
	}

	roi_w = min(xres - start_x, img->width - roi_x);
	roi_h = min(yres - start_y, img->height - roi_y);
	roi_size = (roi_h << 16) | roi_w;

	if (cursor->set & FB_CUR_SETPOS) {
		mdp_mixer_write(mixer, MDSS_MDP_REG_LM_CURSOR_XY,
				(roi_y << 16) | roi_x);
		mdp_mixer_write(mixer, MDSS_MDP_REG_LM_CURSOR_START_XY,
				   (img->dy << 16) | img->dx);
				(start_y << 16) | start_x);
		mdp_mixer_write(mixer, MDSS_MDP_REG_LM_CURSOR_SIZE, roi_size);
	}

	if (cursor->set & FB_CUR_SETIMAGE) {
		int calpha_en, transp_en, alpha, size;
@@ -1877,7 +1923,7 @@ static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd,

		size = (img->height << 16) | img->width;
		mdp_mixer_write(mixer, MDSS_MDP_REG_LM_CURSOR_IMG_SIZE, size);
		mdp_mixer_write(mixer, MDSS_MDP_REG_LM_CURSOR_SIZE, size);
		mdp_mixer_write(mixer, MDSS_MDP_REG_LM_CURSOR_SIZE, roi_size);
		mdp_mixer_write(mixer, MDSS_MDP_REG_LM_CURSOR_STRIDE,
				   img->width * 4);
		mdp_mixer_write(mixer, MDSS_MDP_REG_LM_CURSOR_BASE_ADDR,
@@ -1910,6 +1956,9 @@ static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd,
				   MDSS_MDP_REG_LM_CURSOR_BLEND_TRANSP_HIGH1,
				   ((img->bg_color & 0xff0000) >> 16));
		}

		mixer->cursor_hotx = 0;
		mixer->cursor_hoty = 0;
	}

	if (!cursor->enable != !(blendcfg & 0x1)) {