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

Commit ce71070e authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: Display splash screen during boot up"

parents 58c37704 f98a9339
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -28,7 +28,10 @@
#define MDP_CORE_CLK_RATE	100000000
#define VSYNC_EXPIRE_TICK	4

static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd);
static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd,
					struct mdp_overlay *req,
					int image_size,
					int *pipe_ndx);
static int mdp3_overlay_unset(struct msm_fb_data_type *mfd, int ndx);
static int mdp3_histogram_stop(struct mdp3_session_data *session,
					u32 block);
@@ -1066,7 +1069,10 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd,
	return 0;
}

static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd)
static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd,
					struct mdp_overlay *req,
					int image_size,
					int *pipe_ndx)
{
	struct fb_info *fbi;
	struct mdp3_session_data *mdp3_session;
+58 −1
Original line number Diff line number Diff line
@@ -147,6 +147,47 @@ static int mdss_fb_notify_update(struct msm_fb_data_type *mfd,
	return ret;
}

static int mdss_fb_splash_thread(void *data)
{
	struct msm_fb_data_type *mfd = data;
	int ret = -EINVAL;
	struct fb_info *fbi = NULL;
	int ov_index[2];

	if (!mfd || !mfd->fbi || !mfd->mdp.splash_fnc) {
		pr_err("Invalid input parameter\n");
		goto end;
	}

	fbi = mfd->fbi;

	ret = mdss_fb_open(fbi, current->tgid);
	if (ret) {
		pr_err("fb_open failed\n");
		goto end;
	}

	mfd->bl_updated = true;
	mdss_fb_set_backlight(mfd, mfd->panel_info->bl_max >> 1);

	ret = mfd->mdp.splash_fnc(mfd, ov_index, MDP_CREATE_SPLASH_OV);
	if (ret) {
		pr_err("Splash image failed\n");
		goto splash_err;
	}

	do {
		schedule_timeout_interruptible(SPLASH_THREAD_WAIT_TIMEOUT * HZ);
	} while (!kthread_should_stop());

	mfd->mdp.splash_fnc(mfd, ov_index, MDP_REMOVE_SPLASH_OV);

splash_err:
	mdss_fb_release(fbi, current->tgid);
end:
	return ret;
}

static int lcd_backlight_registered;

static void mdss_fb_set_bl_brightness(struct led_classdev *led_cdev,
@@ -407,6 +448,16 @@ static int mdss_fb_probe(struct platform_device *pdev)
	else
		mfd->mdp_sync_pt_data.threshold = 2;

	if (mfd->index == 0) {
		mfd->splash_thread = kthread_run(mdss_fb_splash_thread, mfd,
				"mdss_fb_splash");
		if (IS_ERR(mfd->splash_thread)) {
			pr_err("unable to start splash thread %d\n",
				mfd->index);
			mfd->splash_thread = NULL;
		}
	}

	return rc;
}

@@ -1214,6 +1265,12 @@ static int mdss_fb_open(struct fb_info *info, int user)
	pinfo->ref_cnt++;
	mfd->ref_cnt++;

	/* Stop the splash thread once userspace open the fb node */
	if (mfd->splash_thread && mfd->ref_cnt > 1) {
		kthread_stop(mfd->splash_thread);
		mfd->splash_thread = NULL;
	}

	return 0;

blank_error:
@@ -1593,7 +1650,7 @@ static int mdss_fb_pan_display_sub(struct fb_var_screeninfo *var,
		(var->yoffset / info->fix.ypanstep) * info->fix.ypanstep;

	if (mfd->mdp.dma_fnc)
		mfd->mdp.dma_fnc(mfd);
		mfd->mdp.dma_fnc(mfd, NULL, 0, NULL);
	else
		pr_warn("dma function not set for panel type=%d\n",
				mfd->panel.type);
+12 −1
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@
#define WAIT_DISP_OP_TIMEOUT ((WAIT_FENCE_FIRST_TIMEOUT + \
		WAIT_FENCE_FINAL_TIMEOUT) * MDP_MAX_FENCE_FD)

#define SPLASH_THREAD_WAIT_TIMEOUT 3

#ifndef MAX
#define  MAX(x, y) (((x) > (y)) ? (x) : (y))
#endif
@@ -70,6 +72,11 @@ enum mdp_notify_event {
	MDP_NOTIFY_FRAME_TIMEOUT,
};

enum mdp_splash_event {
	MDP_CREATE_SPLASH_OV = 0,
	MDP_REMOVE_SPLASH_OV,
};

struct disp_info_type_suspend {
	int op_enable;
	int panel_power_on;
@@ -113,7 +120,8 @@ struct msm_mdp_interface {
	int (*kickoff_fnc)(struct msm_fb_data_type *mfd,
					struct mdp_display_commit *data);
	int (*ioctl_handler)(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
	void (*dma_fnc)(struct msm_fb_data_type *mfd);
	void (*dma_fnc)(struct msm_fb_data_type *mfd, struct mdp_overlay *req,
				int image_len, int *pipe_ndx);
	int (*cursor_update)(struct msm_fb_data_type *mfd,
				struct fb_cursor *cursor);
	int (*lut_update)(struct msm_fb_data_type *mfd, struct fb_cmap *cmap);
@@ -122,6 +130,7 @@ struct msm_mdp_interface {
	int (*update_ad_input)(struct msm_fb_data_type *mfd);
	int (*panel_register_done)(struct mdss_panel_data *pdata);
	u32 (*fb_stride)(u32 fb_index, u32 xres, int bpp);
	int (*splash_fnc) (struct msm_fb_data_type *mfd, int *index, int req);
	struct msm_sync_pt_data *(*get_sync_fnc)(struct msm_fb_data_type *mfd,
				const struct mdp_buf_sync *buf_sync);
	void *private1;
@@ -204,6 +213,8 @@ struct msm_fb_data_type {
	wait_queue_head_t idle_wait_q;
	bool shutdown_pending;

	struct task_struct *splash_thread;

	struct msm_fb_backup_type msm_fb_backup;
	struct completion power_set_comp;
	u32 is_power_setting;
+142 −42
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@
#include "mdss_mdp.h"
#include "mdss_mdp_rotator.h"

#include "splash.h"

#define VSYNC_PERIOD 16
#define BORDERFILL_NDX	0x0BF000BF
#define CHECK_BOUNDS(offset, size, max_size) \
@@ -44,6 +46,8 @@

#define MEM_PROTECT_SD_CTRL 0xF

#define INVALID_PIPE_INDEX 0xFFFF

struct sd_ctrl_req {
	unsigned int enable;
} __attribute__ ((__packed__));
@@ -1382,18 +1386,18 @@ static int mdss_mdp_overlay_free_fb_pipe(struct msm_fb_data_type *mfd)

static int mdss_mdp_overlay_get_fb_pipe(struct msm_fb_data_type *mfd,
					struct mdss_mdp_pipe **ppipe,
					int mixer_mux)
					int mixer_mux,
					struct mdp_overlay *req_ov)
{
	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
	struct mdss_mdp_pipe *pipe;
	int ret;

	pipe = mdss_mdp_mixer_stage_pipe(mdp5_data->ctl, mixer_mux,
					 MDSS_MDP_STAGE_BASE);

	if (pipe == NULL) {
		struct mdp_overlay req;
		struct fb_info *fbi = mfd->fbi;
		struct mdss_mdp_mixer *mixer;
		int ret, bpp;

		mixer = mdss_mdp_mixer_get(mdp5_data->ctl,
					MDSS_MDP_MIXER_MUX_LEFT);
@@ -1402,6 +1406,11 @@ static int mdss_mdp_overlay_get_fb_pipe(struct msm_fb_data_type *mfd,
			return -ENODEV;
		}

		if (req_ov == NULL) {
			struct mdp_overlay req;
			struct fb_info *fbi = mfd->fbi;
			int bpp;

			memset(&req, 0, sizeof(req));

			bpp = fbi->var.bits_per_pixel / 8;
@@ -1420,7 +1429,8 @@ static int mdss_mdp_overlay_get_fb_pipe(struct msm_fb_data_type *mfd,
				req.src_rect.w = fbi->var.xres - mixer->width;
			} else {
				req.src_rect.x = 0;
			req.src_rect.w = MIN(fbi->var.xres, mixer->width);
				req.src_rect.w = MIN(fbi->var.xres,
								mixer->width);
			}

			req.src_rect.y = 0;
@@ -1436,15 +1446,33 @@ static int mdss_mdp_overlay_get_fb_pipe(struct msm_fb_data_type *mfd,
			ret = mdss_mdp_overlay_pipe_setup(mfd, &req, &pipe);
			if (ret)
				return ret;
		} else {
			if (mixer_mux == MDSS_MDP_MIXER_MUX_RIGHT) {
				req_ov->id = MSMFB_NEW_REQUEST;
				req_ov->flags |= MDSS_MDP_RIGHT_MIXER;
				req_ov->src_rect.w = MIN(mixer->width,
						req_ov->src_rect.w >> 1);
				req_ov->dst_rect.w = req_ov->src_rect.w;
				req_ov->src_rect.x = req_ov->src_rect.w;
				req_ov->dst_rect.x = 0;
			}

		pr_debug("ctl=%d pnum=%d\n", mdp5_data->ctl->num, pipe->num);
			ret = mdss_mdp_overlay_pipe_setup(mfd, req_ov, &pipe);
			if (ret)
				return ret;
		}
	}

	pr_debug("ctl=%d pnum=%d\n", mdp5_data->ctl->num, pipe->num);

	*ppipe = pipe;
	return 0;
}

static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd)
static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd,
					struct mdp_overlay *req,
					int image_size,
					int *pipe_ndx)
{
	struct mdss_mdp_data *buf;
	struct mdss_mdp_pipe *pipe;
@@ -1492,8 +1520,8 @@ static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd)
		goto pan_display_error;
	}


	ret = mdss_mdp_overlay_get_fb_pipe(mfd, &pipe, MDSS_MDP_MIXER_MUX_LEFT);
	ret = mdss_mdp_overlay_get_fb_pipe(mfd, &pipe,
					MDSS_MDP_MIXER_MUX_LEFT, req);
	if (ret) {
		pr_err("unable to allocate base pipe\n");
		goto pan_display_error;
@@ -1503,12 +1531,14 @@ static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd)
		pr_err("unable to map base pipe\n");
		goto pan_display_error;
	}
	if (pipe_ndx)
		pipe_ndx[0] = pipe->ndx;

	buf = &pipe->back_buf;
	if (is_mdss_iommu_attached()) {
		if (!mfd->iova) {
			pr_err("mfd iova is zero\n");
			goto pan_display_error;
			goto attach_err;
		}
		buf->p[0].addr = mfd->iova;
	} else {
@@ -1516,21 +1546,27 @@ static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd)
	}

	buf->p[0].addr += offset;
	if (image_size)
		buf->p[0].len = image_size;
	else
		buf->p[0].len = fbi->fix.smem_len - offset;
	buf->num_planes = 1;
	mdss_mdp_pipe_unmap(pipe);

	if (fbi->var.xres > MAX_MIXER_WIDTH || mfd->split_display) {
		ret = mdss_mdp_overlay_get_fb_pipe(mfd, &pipe,
						   MDSS_MDP_MIXER_MUX_RIGHT);
					   MDSS_MDP_MIXER_MUX_RIGHT, req);
		if (ret) {
			pr_err("unable to allocate right base pipe\n");
			goto pan_display_error;
			goto attach_err;
		}
		if (mdss_mdp_pipe_map(pipe)) {
			pr_err("unable to map right base pipe\n");
			goto pan_display_error;
			goto attach_err;
		}
		if (pipe_ndx)
			pipe_ndx[1] = pipe->ndx;

		pipe->back_buf = *buf;
		mdss_mdp_pipe_unmap(pipe);
	}
@@ -1542,6 +1578,12 @@ static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd)

	return;

attach_err:
	mutex_unlock(&mdp5_data->ov_lock);
	mdss_mdp_overlay_unset(mfd, pipe->ndx);
	if (pipe_ndx)
		pipe_ndx[0] = INVALID_PIPE_INDEX;
	return;
pan_display_error:
	mutex_unlock(&mdp5_data->ov_lock);
}
@@ -2669,6 +2711,63 @@ error:
	return rc;
}

static int mdss_mdp_overlay_splash_image(struct msm_fb_data_type *mfd,
						int *pipe_ndx, int splash_event)
{
	struct mdp_overlay req;
	int rc = 0;
	struct fb_info *fbi = NULL;
	int image_len = 0;

	if (!mfd || !mfd->fbi || !mfd->fbi->screen_base || !pipe_ndx) {
		pr_err("Invalid input parameter\n");
		return -EINVAL;
	}

	fbi = mfd->fbi;
	image_len = SPLASH_IMAGE_WIDTH * SPLASH_IMAGE_HEIGHT * SPLASH_IMAGE_BPP;

	if (SPLASH_IMAGE_WIDTH > fbi->var.xres ||
			SPLASH_IMAGE_HEIGHT > fbi->var.yres ||
			SPLASH_IMAGE_BPP > fbi->var.bits_per_pixel / 8 ||
			image_len > fbi->fix.smem_len) {
		pr_err("Invalid splash parameter configuration\n");
		return -EINVAL;
	}

	if (splash_event == MDP_CREATE_SPLASH_OV) {
		pipe_ndx[0] = INVALID_PIPE_INDEX;
		pipe_ndx[1] = INVALID_PIPE_INDEX;

		memset(&req, 0, sizeof(struct mdp_overlay));
		req.src.width = req.dst_rect.w = req.src_rect.w =
				SPLASH_IMAGE_WIDTH;
		req.src.height = req.dst_rect.h = req.src_rect.h =
				SPLASH_IMAGE_HEIGHT;
		req.src.format = SPLASH_IMAGE_FORMAT;
		req.id = MSMFB_NEW_REQUEST;
		req.z_order = MDSS_MDP_STAGE_0;
		req.is_fg = 1;
		req.alpha = 0xff;
		req.transp_mask = MDP_TRANSP_NOP;
		req.dst_rect.x =
			(fbi->var.xres >> 1) - (SPLASH_IMAGE_WIDTH >> 1);
		req.dst_rect.y =
			(fbi->var.yres >> 1) - (SPLASH_IMAGE_HEIGHT >> 1);

		memcpy(fbi->screen_base, splash_bgr888_image, image_len);
		mdss_mdp_overlay_pan_display(mfd, &req, image_len, pipe_ndx);

	} else if (splash_event == MDP_REMOVE_SPLASH_OV) {
		if (pipe_ndx[0] != INVALID_PIPE_INDEX)
			mdss_mdp_overlay_unset(mfd, pipe_ndx[0]);
		if (pipe_ndx[1] != INVALID_PIPE_INDEX)
			mdss_mdp_overlay_unset(mfd, pipe_ndx[1]);
	}

	return rc;
}

int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
{
	struct device *dev = mfd->fbi->dev;
@@ -2686,6 +2785,7 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
	mdp5_interface->panel_register_done = mdss_panel_register_done;
	mdp5_interface->kickoff_fnc = mdss_mdp_overlay_kickoff;
	mdp5_interface->get_sync_fnc = mdss_mdp_rotator_sync_pt_get;
	mdp5_interface->splash_fnc = mdss_mdp_overlay_splash_image;

	mdp5_data = kmalloc(sizeof(struct mdss_overlay_private), GFP_KERNEL);
	if (!mdp5_data) {
+5279 −0

File added.

Preview size limit exceeded, changes collapsed.