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

Commit e4048697 authored by Veera Sundaram Sankaran's avatar Veera Sundaram Sankaran Committed by Sandeep Panda
Browse files

msm: mdss: add support to change panel resolution dynamically



Helpful in changing the panel resolution on the fly with the help of
debugfs nodes and when used along with simulated panels, it allows to
test different panel configurations dynamically.

Change-Id: I9cdf82e4fffd3dd618ee97601f169d72ab76a473
Signed-off-by: default avatarVeera Sundaram Sankaran <veeras@codeaurora.org>
Signed-off-by: default avatarSandeep Panda <spanda@codeaurora.org>
parent 3394d3c9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ mdss-dsi-objs := mdss_dsi.o mdss_dsi_host.o mdss_dsi_cmd.o mdss_dsi_status.o
mdss-dsi-objs += mdss_dsi_panel.o
mdss-dsi-objs += msm_mdss_io_8974.o
obj-$(CONFIG_FB_MSM_MDSS) += mdss-dsi.o
obj-$(CONFIG_FB_MSM_MDSS) += mdss_panel.o
obj-$(CONFIG_FB_MSM_MDSS_EDP_PANEL) += mdss_edp.o
obj-$(CONFIG_FB_MSM_MDSS_EDP_PANEL) += mdss_edp_aux.o

+30 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -1182,6 +1182,28 @@ int mdss_dsi_register_recovery_handler(struct mdss_dsi_ctrl_pdata *ctrl,
	return 0;
}

static int mdss_dsi_clk_refresh(struct mdss_panel_data *pdata)
{
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
	int rc = 0;

	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
							panel_data);
	rc = mdss_dsi_clk_div_config(&pdata->panel_info,
			pdata->panel_info.mipi.frame_rate);
	if (rc) {
		pr_err("%s: unable to initialize the clk dividers\n",
								__func__);
		return rc;
	}
	ctrl_pdata->refresh_clk_rate = false;
	ctrl_pdata->pclk_rate = pdata->panel_info.mipi.dsi_pclk_rate;
	ctrl_pdata->byte_clk_rate = pdata->panel_info.clk_rate / 8;
	pr_debug("%s ctrl_pdata->byte_clk_rate=%d ctrl_pdata->pclk_rate=%d\n",
		__func__, ctrl_pdata->byte_clk_rate, ctrl_pdata->pclk_rate);
	return rc;
}

static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
				  int event, void *arg)
{
@@ -1200,12 +1222,19 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
	MDSS_XLOG(event, arg, ctrl_pdata->ndx, 0x3333);

	switch (event) {
	case MDSS_EVENT_CHECK_PARAMS:
		pr_debug("%s:Entered Case MDSS_EVENT_CHECK_PARAMS\n", __func__);
		ctrl_pdata->refresh_clk_rate = true;
		break;
	case MDSS_EVENT_LINK_READY:
		rc = mdss_dsi_on(pdata);
		mdss_dsi_op_mode_config(pdata->panel_info.mipi.mode,
							pdata);
		break;
	case MDSS_EVENT_UNBLANK:
		if (ctrl_pdata->refresh_clk_rate)
			rc = mdss_dsi_clk_refresh(pdata);

		if (ctrl_pdata->on_cmds.link_state == DSI_LP_MODE)
			rc = mdss_dsi_unblank(pdata);
		break;
+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -347,6 +347,7 @@ struct mdss_dsi_ctrl_pdata {
	struct dsi_drv_cm_data shared_pdata;
	u32 pclk_rate;
	u32 byte_clk_rate;
	bool refresh_clk_rate; /* flag to recalculate clk_rate */
	struct dss_module_power power_data[DSI_MAX_PM];
	u32 dsi_irq_mask;
	struct mdss_hw *dsi_hw;
+52 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 * Core MDSS framebuffer driver.
 *
 * Copyright (C) 2007 Google Incorporated
 * Copyright (c) 2008-2014, The Linux Foundation. All rights reserved.
 * Copyright (c) 2008-2015, The Linux Foundation. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
@@ -104,6 +104,8 @@ static int mdss_fb_pan_idle(struct msm_fb_data_type *mfd);
static int mdss_fb_send_panel_event(struct msm_fb_data_type *mfd,
					int event, void *arg);
static void mdss_fb_set_mdp_sync_pt_threshold(struct msm_fb_data_type *mfd);
static void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo,
					struct fb_var_screeninfo *var);
void mdss_fb_no_update_notify_timer_cb(unsigned long data)
{
	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
@@ -1185,6 +1187,34 @@ static void mdss_fb_stop_disp_thread(struct msm_fb_data_type *mfd)
	mfd->disp_thread = NULL;
}

static void mdss_panel_validate_debugfs_info(struct msm_fb_data_type *mfd)
{
	struct mdss_panel_info *panel_info = mfd->panel_info;
	struct fb_info *fbi = mfd->fbi;
	struct fb_var_screeninfo *var = &fbi->var;
	struct mdss_panel_data *pdata = container_of(panel_info,
				struct mdss_panel_data, panel_info);

	if (panel_info->debugfs_info->override_flag) {
		if (mfd->mdp.off_fnc) {
			mfd->panel_reconfig = true;
			mfd->mdp.off_fnc(mfd);
			mfd->panel_reconfig = false;
		}

		pr_debug("Overriding panel_info with debugfs_info\n");
		panel_info->debugfs_info->override_flag = 0;
		mdss_panel_debugfsinfo_to_panelinfo(panel_info);
		if (is_panel_split(mfd) && pdata->next)
			mdss_fb_validate_split(pdata->panel_info.xres,
					pdata->next->panel_info.xres, mfd);
		mdss_panelinfo_to_fb_var(panel_info, var);
		if (mdss_fb_send_panel_event(mfd, MDSS_EVENT_CHECK_PARAMS,
							panel_info))
			pr_err("Failed to send panel event CHECK_PARAMS\n");
	}
}

static int mdss_fb_unblank_sub(struct msm_fb_data_type *mfd)
{
	int ret = 0;
@@ -1193,6 +1223,9 @@ static int mdss_fb_unblank_sub(struct msm_fb_data_type *mfd)
	if (!mfd)
		return -EINVAL;

	if (mfd->panel_info->debugfs_info)
		mdss_panel_validate_debugfs_info(mfd);

	/* Start Display thread */
	if (mfd->disp_thread == NULL) {
		ret = mdss_fb_start_disp_thread(mfd);
@@ -1976,6 +2009,7 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd)
		return -EPERM;
	}

	mdss_panel_debugfs_init(panel_info);
	pr_info("FrameBuffer[%d] %dx%d registered successfully!\n", mfd->index,
					fbi->var.xres, fbi->var.yres);

@@ -2619,6 +2653,23 @@ static void mdss_fb_var_to_panelinfo(struct fb_var_screeninfo *var,
	pinfo->clk_rate = var->pixclock;
}

static void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo,
						struct fb_var_screeninfo *var)
{
	struct mdss_panel_data *pdata = container_of(pinfo,
				struct mdss_panel_data, panel_info);

	var->xres = mdss_fb_get_panel_xres(&pdata->panel_info);
	var->yres = pinfo->yres;
	var->lower_margin = pinfo->lcdc.v_front_porch;
	var->upper_margin = pinfo->lcdc.v_back_porch;
	var->vsync_len = pinfo->lcdc.v_pulse_width;
	var->right_margin = pinfo->lcdc.h_front_porch;
	var->left_margin = pinfo->lcdc.h_back_porch;
	var->hsync_len = pinfo->lcdc.h_pulse_width;
	var->pixclock = pinfo->clk_rate;
}

/**
 * __mdss_fb_perform_commit() - process a frame to display
 * @mfd:	Framebuffer data structure for display
+8 −2
Original line number Diff line number Diff line
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -3678,8 +3678,14 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
		return -ENODEV;
	}

	if (!mdss_mdp_ctl_is_power_on(mdp5_data->ctl))
	if (!mdss_mdp_ctl_is_power_on(mdp5_data->ctl)) {
		if (mfd->panel_reconfig) {
			mdp5_data->borderfill_enable = false;
			mdss_mdp_ctl_destroy(mdp5_data->ctl);
			mdp5_data->ctl = NULL;
		}
		return 0;
	}

	/*
	 * Keep a reference to the runtime pm until the overlay is turned
Loading