pmaports/device/testing/linux-oppo-find-7a/0002-mdss_fb.patch
Oliver Smith 64035ac463
device/*: move to device/testing/* (!1063)
Prepare for better device categorization by moving everything to testing
subdir first.

[skip-ci]: chicken-egg problem: passing pmaports CI depends on pmbootstrap MR
				depends on this MR

Related: postmarketos#16
2020-03-14 08:35:32 +01:00

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,