3209440946
[ci:skip-build]: already built successfully in CI
393 lines
13 KiB
Diff
393 lines
13 KiB
Diff
--- a/drivers/video/msm/mdss/mdss_fb.c.orig 2019-06-08 13:45:24.053712000 +0200
|
|
+++ b/drivers/video/msm/mdss/mdss_fb.c 2019-06-10 22:37:30.194743429 +0200
|
|
@@ -310,6 +310,20 @@ static ssize_t mdss_fb_get_type(struct d
|
|
return ret;
|
|
}
|
|
|
|
+static int mdss_fb_get_panel_xres(struct mdss_panel_info *pinfo)
|
|
+{
|
|
+ struct mdss_panel_data *pdata;
|
|
+ int xres;
|
|
+
|
|
+ pdata = container_of(pinfo, struct mdss_panel_data, panel_info);
|
|
+
|
|
+ xres = pinfo->xres;
|
|
+ if (pdata->next && pdata->next->active)
|
|
+ xres += mdss_fb_get_panel_xres(&pdata->next->panel_info);
|
|
+
|
|
+ return xres;
|
|
+}
|
|
+
|
|
static void mdss_fb_parse_dt(struct msm_fb_data_type *mfd)
|
|
{
|
|
u32 data[2] = {0};
|
|
@@ -1156,6 +1170,8 @@ static int mdss_fb_blank_unblank(struct
|
|
}
|
|
|
|
if (mfd->mdp.on_fnc) {
|
|
+ struct mdss_panel_info *panel_info = mfd->panel_info;
|
|
+ struct fb_var_screeninfo *var = &mfd->fbi->var;
|
|
ret = mfd->mdp.on_fnc(mfd);
|
|
if (ret) {
|
|
mdss_fb_stop_disp_thread(mfd);
|
|
@@ -1168,6 +1184,12 @@ static int mdss_fb_blank_unblank(struct
|
|
mfd->update.type = NOTIFY_TYPE_UPDATE;
|
|
mfd->update.is_suspend = 0;
|
|
mutex_unlock(&mfd->update.lock);
|
|
+ /*
|
|
+ * Panel info can change depending in the information
|
|
+ * programmed in the controller.
|
|
+ * Update this info in the upstream structs.
|
|
+ */
|
|
+ mdss_panelinfo_to_fb_var(panel_info, var);
|
|
|
|
/* Start the work thread to signal idle time */
|
|
if (mfd->idle_time)
|
|
@@ -1687,6 +1709,7 @@ static int mdss_fb_register(struct msm_f
|
|
{
|
|
int ret = -ENODEV;
|
|
int bpp;
|
|
+ char panel_name[20];
|
|
struct mdss_panel_info *panel_info = mfd->panel_info;
|
|
struct fb_info *fbi = mfd->fbi;
|
|
struct fb_fix_screeninfo *fix;
|
|
@@ -1827,9 +1850,7 @@ static int mdss_fb_register(struct msm_f
|
|
return ret;
|
|
}
|
|
|
|
- var->xres = panel_info->xres;
|
|
- if (mfd->split_display)
|
|
- var->xres *= 2;
|
|
+ mdss_panelinfo_to_fb_var(panel_info, var);
|
|
|
|
fix->type = panel_info->is_3d_panel;
|
|
if (mfd->mdp.fb_stride)
|
|
@@ -1838,21 +1859,9 @@ static int mdss_fb_register(struct msm_f
|
|
else
|
|
fix->line_length = var->xres * bpp;
|
|
|
|
- var->yres = panel_info->yres;
|
|
- if (panel_info->physical_width)
|
|
- var->width = panel_info->physical_width;
|
|
- if (panel_info->physical_height)
|
|
- var->height = panel_info->physical_height;
|
|
var->xres_virtual = var->xres;
|
|
var->yres_virtual = panel_info->yres * mfd->fb_page;
|
|
var->bits_per_pixel = bpp * 8; /* FrameBuffer color depth */
|
|
- var->upper_margin = panel_info->lcdc.v_back_porch;
|
|
- var->lower_margin = panel_info->lcdc.v_front_porch;
|
|
- var->vsync_len = panel_info->lcdc.v_pulse_width;
|
|
- var->left_margin = panel_info->lcdc.h_back_porch;
|
|
- var->right_margin = panel_info->lcdc.h_front_porch;
|
|
- var->hsync_len = panel_info->lcdc.h_pulse_width;
|
|
- var->pixclock = panel_info->clk_rate / 1000;
|
|
|
|
/*
|
|
* Populate smem length here for uspace to get the
|
|
@@ -1915,6 +1924,8 @@ static int mdss_fb_register(struct msm_f
|
|
return -EPERM;
|
|
}
|
|
|
|
+ snprintf(panel_name, ARRAY_SIZE(panel_name), "mdss_panel_fb%d",
|
|
+ mfd->index);
|
|
pr_info("FrameBuffer[%d] %dx%d registered successfully!\n", mfd->index,
|
|
fbi->var.xres, fbi->var.yres);
|
|
|
|
@@ -2598,9 +2609,59 @@ static void mdss_fb_var_to_panelinfo(str
|
|
pinfo->lcdc.h_front_porch = var->right_margin;
|
|
pinfo->lcdc.h_back_porch = var->left_margin;
|
|
pinfo->lcdc.h_pulse_width = var->hsync_len;
|
|
- pinfo->clk_rate = var->pixclock;
|
|
+ /*
|
|
+ * if greater than 1M, then rate would fall below 1mhz which is not
|
|
+ * even supported. In this case it means clock rate is actually
|
|
+ * passed directly in hz.
|
|
+ */
|
|
+ if (var->pixclock > SZ_1M)
|
|
+ pinfo->clk_rate = var->pixclock;
|
|
+ else
|
|
+ pinfo->clk_rate = PICOS2KHZ(var->pixclock) * 1000;
|
|
}
|
|
|
|
+void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo,
|
|
+ struct fb_var_screeninfo *var)
|
|
+{
|
|
+ u32 frame_rate;
|
|
+
|
|
+ var->xres = mdss_fb_get_panel_xres(pinfo);
|
|
+ var->yres = pinfo->yres;
|
|
+ var->lower_margin = pinfo->lcdc.v_front_porch -
|
|
+ pinfo->prg_fet;
|
|
+ var->upper_margin = pinfo->lcdc.v_back_porch +
|
|
+ pinfo->prg_fet;
|
|
+ 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;
|
|
+
|
|
+ frame_rate = mdss_panel_get_framerate(pinfo,
|
|
+ FPS_RESOLUTION_HZ);
|
|
+ if (frame_rate) {
|
|
+ unsigned long clk_rate, h_total, v_total;
|
|
+
|
|
+ h_total = var->xres + var->left_margin
|
|
+ + var->right_margin + var->hsync_len;
|
|
+ v_total = var->yres + var->lower_margin
|
|
+ + var->upper_margin + var->vsync_len;
|
|
+ clk_rate = h_total * v_total * frame_rate;
|
|
+ var->pixclock = KHZ2PICOS(clk_rate / 1000);
|
|
+ } else if (pinfo->clk_rate) {
|
|
+ var->pixclock = KHZ2PICOS(
|
|
+ (unsigned long int) pinfo->clk_rate / 1000);
|
|
+ }
|
|
+
|
|
+ if (pinfo->physical_width)
|
|
+ var->width = pinfo->physical_width;
|
|
+ if (pinfo->physical_height)
|
|
+ var->height = pinfo->physical_height;
|
|
+
|
|
+ pr_debug("ScreenInfo: res=%dx%d [%d, %d] [%d, %d]\n",
|
|
+ var->xres, var->yres, var->left_margin,
|
|
+ var->right_margin, var->upper_margin,
|
|
+ var->lower_margin);
|
|
+}
|
|
/**
|
|
* __mdss_fb_perform_commit() - process a frame to display
|
|
* @mfd: Framebuffer data structure for display
|
|
@@ -3329,6 +3390,7 @@ int mdss_register_panel(struct platform_
|
|
goto mdss_notfound;
|
|
}
|
|
|
|
+ pdata->active = true;
|
|
fb_pdev = of_find_device_by_node(node);
|
|
if (fb_pdev) {
|
|
rc = mdss_fb_register_extra_panel(fb_pdev, pdata);
|
|
--- a/drivers/video/msm/mdss/mdss_fb.h.orig 2019-06-08 13:45:24.053712000 +0200
|
|
+++ b/drivers/video/msm/mdss/mdss_fb.h 2019-06-09 23:22:43.940850298 +0200
|
|
@@ -309,4 +309,6 @@ struct sync_fence *mdss_fb_sync_get_fenc
|
|
int mdss_fb_register_mdp_instance(struct msm_mdp_interface *mdp);
|
|
int mdss_fb_dcm(struct msm_fb_data_type *mfd, int req_state);
|
|
int mdss_fb_suspres_panel(struct device *dev, void *data);
|
|
+void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo,
|
|
+ struct fb_var_screeninfo *var);
|
|
#endif /* MDSS_FB_H */
|
|
--- a/drivers/video/msm/mdss/mdss_panel.h.orig 2019-06-08 13:45:24.061712000 +0200
|
|
+++ b/drivers/video/msm/mdss/mdss_panel.h 2019-06-10 15:44:12.295557101 +0200
|
|
@@ -18,12 +18,20 @@
|
|
#include <linux/types.h>
|
|
#include <linux/of_device.h>
|
|
|
|
+#define KHZ_TO_HZ 1000
|
|
+
|
|
/* panel id type */
|
|
struct panel_id {
|
|
u16 id;
|
|
u16 type;
|
|
};
|
|
|
|
+enum fps_resolution {
|
|
+ FPS_RESOLUTION_DEFAULT,
|
|
+ FPS_RESOLUTION_HZ,
|
|
+ FPS_RESOLUTION_KHZ,
|
|
+};
|
|
+
|
|
#define DEFAULT_FRAME_RATE 60
|
|
#define MDSS_DSI_RST_SEQ_LEN 10
|
|
|
|
@@ -352,7 +360,7 @@ struct mdss_panel_info {
|
|
u32 min_height;
|
|
u32 min_fps;
|
|
u32 max_fps;
|
|
-
|
|
+ u32 prg_fet;
|
|
u32 cont_splash_enabled;
|
|
u32 partial_update_enabled;
|
|
struct ion_handle *splash_ihdl;
|
|
@@ -393,7 +401,7 @@ struct mdss_panel_data {
|
|
* and teardown.
|
|
*/
|
|
int (*event_handler) (struct mdss_panel_data *pdata, int e, void *arg);
|
|
-
|
|
+ bool active;
|
|
struct mdss_panel_data *next;
|
|
};
|
|
|
|
@@ -401,12 +409,17 @@ struct mdss_panel_data {
|
|
* mdss_get_panel_framerate() - get panel frame rate based on panel information
|
|
* @panel_info: Pointer to panel info containing all panel information
|
|
*/
|
|
-static inline u32 mdss_panel_get_framerate(struct mdss_panel_info *panel_info)
|
|
+static inline u32 mdss_panel_get_framerate(struct mdss_panel_info *panel_info,
|
|
+ u32 flags)
|
|
{
|
|
u32 frame_rate, pixel_total;
|
|
+ u64 rate;
|
|
|
|
- if (panel_info == NULL)
|
|
+ if (panel_info == NULL) {
|
|
return DEFAULT_FRAME_RATE;
|
|
+ goto end;
|
|
+ }
|
|
+
|
|
|
|
switch (panel_info->type) {
|
|
case MIPI_VIDEO_PANEL:
|
|
@@ -428,13 +441,25 @@ static inline u32 mdss_panel_get_framera
|
|
panel_info->lcdc.v_front_porch +
|
|
panel_info->lcdc.v_pulse_width +
|
|
panel_info->yres);
|
|
- if (pixel_total)
|
|
- frame_rate = panel_info->clk_rate / pixel_total;
|
|
- else
|
|
+ if (pixel_total) {
|
|
+ rate = panel_info->clk_rate * KHZ_TO_HZ;
|
|
+ do_div(rate, pixel_total);
|
|
+ frame_rate = (u32)rate;
|
|
+ } else {
|
|
frame_rate = DEFAULT_FRAME_RATE;
|
|
-
|
|
+ }
|
|
break;
|
|
}
|
|
+
|
|
+end:
|
|
+ if (flags == FPS_RESOLUTION_KHZ) {
|
|
+ if (!(frame_rate / KHZ_TO_HZ))
|
|
+ frame_rate *= KHZ_TO_HZ;
|
|
+ } else if (flags == FPS_RESOLUTION_HZ) {
|
|
+ if (frame_rate / KHZ_TO_HZ)
|
|
+ frame_rate /= KHZ_TO_HZ;
|
|
+ }
|
|
+
|
|
return frame_rate;
|
|
}
|
|
|
|
--- a/drivers/video/msm/mdss/mdss_dsi.c.orig 2019-06-08 13:45:24.049712000 +0200
|
|
+++ b/drivers/video/msm/mdss/mdss_dsi.c 2019-06-10 00:49:41.148334433 +0200
|
|
@@ -1582,7 +1582,8 @@ int dsi_panel_device_register(struct dev
|
|
ctrl_pdata->shared_pdata.broadcast_enable = of_property_read_bool(
|
|
pan_node, "qcom,mdss-dsi-panel-broadcast-mode");
|
|
|
|
- pinfo->panel_max_fps = mdss_panel_get_framerate(pinfo);
|
|
+ pinfo->panel_max_fps = mdss_panel_get_framerate(pinfo,
|
|
+ FPS_RESOLUTION_HZ);
|
|
pinfo->panel_max_vtotal = mdss_panel_get_vtotal(pinfo);
|
|
ctrl_pdata->disp_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,
|
|
"qcom,platform-enable-gpio", 0);
|
|
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c.orig 2019-06-08 13:45:24.057712000 +0200
|
|
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c 2019-06-10 22:41:26.524149757 +0200
|
|
@@ -344,7 +344,8 @@ int mdss_mdp_perf_calc_pipe(struct mdss_
|
|
fps = pinfo->panel_max_fps;
|
|
v_total = pinfo->panel_max_vtotal;
|
|
} else {
|
|
- fps = mdss_panel_get_framerate(pinfo);
|
|
+ fps = mdss_panel_get_framerate(pinfo,
|
|
+ FPS_RESOLUTION_HZ);
|
|
v_total = mdss_panel_get_vtotal(pinfo);
|
|
}
|
|
xres = pinfo->xres;
|
|
@@ -470,7 +471,8 @@ static void mdss_mdp_perf_calc_mixer(str
|
|
fps = pinfo->panel_max_fps;
|
|
v_total = pinfo->panel_max_vtotal;
|
|
} else {
|
|
- fps = mdss_panel_get_framerate(pinfo);
|
|
+ fps = mdss_panel_get_framerate(pinfo,
|
|
+ FPS_RESOLUTION_HZ);
|
|
v_total = mdss_panel_get_vtotal(pinfo);
|
|
}
|
|
|
|
@@ -595,9 +597,12 @@ static u32 mdss_mdp_get_vbp_factor(struc
|
|
return 0;
|
|
|
|
pinfo = &ctl->panel_data->panel_info;
|
|
- fps = mdss_panel_get_framerate(pinfo);
|
|
+ fps = mdss_panel_get_framerate(pinfo,
|
|
+ FPS_RESOLUTION_HZ);
|
|
v_total = mdss_panel_get_vtotal(pinfo);
|
|
vbp = pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width;
|
|
+ vbp += pinfo->prg_fet;
|
|
+
|
|
vbp_fac = (vbp) ? fps * v_total / vbp : 0;
|
|
pr_debug("vbp_fac=%d vbp=%d v_total=%d\n", vbp_fac, vbp, v_total);
|
|
|
|
@@ -1740,7 +1745,7 @@ int mdss_mdp_ctl_intf_event(struct mdss_
|
|
if (pdata->event_handler)
|
|
rc = pdata->event_handler(pdata, event, arg);
|
|
pdata = pdata->next;
|
|
- } while (rc == 0 && pdata);
|
|
+ } while (rc == 0 && pdata && pdata->active);
|
|
|
|
return rc;
|
|
}
|
|
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c.orig 2019-06-08 13:45:24.057712000 +0200
|
|
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c 2019-06-10 22:10:05.072953787 +0200
|
|
@@ -2266,6 +2266,7 @@ static ssize_t dynamic_fps_sysfs_wta_dfp
|
|
mutex_unlock(&mdp5_data->dfps_lock);
|
|
return rc;
|
|
}
|
|
+ pdata->panel_info.prg_fet = 0;
|
|
pdata->panel_info.new_fps = dfps;
|
|
mutex_unlock(&mdp5_data->dfps_lock);
|
|
return count;
|
|
@@ -2790,7 +2791,8 @@ static int mdss_fb_get_metadata(struct m
|
|
switch (metadata->op) {
|
|
case metadata_op_frame_rate:
|
|
metadata->data.panel_frame_rate =
|
|
- mdss_panel_get_framerate(mfd->panel_info);
|
|
+ mdss_panel_get_framerate(mfd->panel_info,
|
|
+ FPS_RESOLUTION_DEFAULT);
|
|
break;
|
|
case metadata_op_get_caps:
|
|
ret = mdss_fb_get_hw_caps(mfd, &metadata->data.caps);
|
|
@@ -3325,7 +3327,8 @@ static int mdss_mdp_overlay_off(struct m
|
|
* As a last resort signal the timeline if vsync doesn't arrive.
|
|
*/
|
|
if (mdp5_data->retire_cnt) {
|
|
- u32 fps = mdss_panel_get_framerate(mfd->panel_info);
|
|
+ u32 fps = mdss_panel_get_framerate(mfd->panel_info,
|
|
+ FPS_RESOLUTION_HZ);
|
|
u32 vsync_time = 1000 / (fps ? : DEFAULT_FRAME_RATE);
|
|
|
|
msleep(vsync_time);
|
|
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c.orig 2019-06-08 13:45:24.057712000 +0200
|
|
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c 2019-06-10 21:53:02.826870697 +0200
|
|
@@ -329,7 +329,7 @@ static int mdss_mdp_video_stop(struct md
|
|
/* wait for at least one VSYNC on HDMI intf for proper TG OFF */
|
|
if (MDSS_INTF_HDMI == ctx->intf_type) {
|
|
frame_rate = mdss_panel_get_framerate
|
|
- (&(ctl->panel_data->panel_info));
|
|
+ (&(ctl->panel_data->panel_info), FPS_RESOLUTION_HZ);
|
|
if (!(frame_rate >= 24 && frame_rate <= 240))
|
|
frame_rate = 24;
|
|
msleep((1000/frame_rate) + 1);
|
|
@@ -531,7 +531,7 @@ static int mdss_mdp_video_vfp_fps_update
|
|
|
|
vsync_period = mdss_panel_get_vtotal(&pdata->panel_info);
|
|
hsync_period = mdss_panel_get_htotal(&pdata->panel_info, true);
|
|
- curr_fps = mdss_panel_get_framerate(&pdata->panel_info);
|
|
+ curr_fps = mdss_panel_get_framerate(&pdata->panel_info, FPS_RESOLUTION_HZ);
|
|
|
|
if (curr_fps > new_fps) {
|
|
add_v_lines = mult_frac(vsync_period,
|
|
@@ -887,6 +887,9 @@ int mdss_mdp_video_start(struct mdss_mdp
|
|
pinfo->bpp);
|
|
itp.vsync_pulse_width = pinfo->lcdc.v_pulse_width;
|
|
|
|
+ pinfo->prg_fet = 0;
|
|
+ pr_debug("programmable fetch is not supported\n");
|
|
+
|
|
if (mdss_mdp_video_timegen_setup(ctl, &itp)) {
|
|
pr_err("unable to get timing parameters\n");
|
|
return -EINVAL;
|
|
--- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c.orig 2019-06-08 13:45:24.057712000 +0200
|
|
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c 2019-06-10 15:10:56.025186537 +0200
|
|
@@ -836,7 +836,8 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ct
|
|
}
|
|
spin_unlock_irqrestore(&ctx->clk_lock, flags);
|
|
|
|
- hz = mdss_panel_get_framerate(&ctl->panel_data->panel_info);
|
|
+ hz = mdss_panel_get_framerate(&ctl->panel_data->panel_info,
|
|
+ FPS_RESOLUTION_HZ);
|
|
|
|
if (need_wait) {
|
|
if (wait_for_completion_timeout(&ctx->stop_comp,
|