From 87d1cd6a2f065666bd888ed6cd8bf8c928ec0388 Mon Sep 17 00:00:00 2001 From: Sandeep Panda Date: Thu, 9 Mar 2017 22:06:58 +0530 Subject: [PATCH] msm: mdss: handle ULPS clamp programming for sdm660 For sdm660 the ULPS clamp registers are moved from DSI PHY level to interface level. This change handles the new settings for both video mode and command mode interface. Change-Id: Ib99c605362aa25aacfa394c1a7ffe2886acf7035 Signed-off-by: Sandeep Panda --- drivers/video/fbdev/msm/mdss.h | 9 ++++ drivers/video/fbdev/msm/mdss_dsi.c | 13 +++++ drivers/video/fbdev/msm/mdss_dsi.h | 1 + drivers/video/fbdev/msm/mdss_mdp.h | 1 + drivers/video/fbdev/msm/mdss_mdp_hwio.h | 13 ++--- drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c | 50 +++++++++++++++++++ drivers/video/fbdev/msm/mdss_mdp_intf_video.c | 48 ++++++++++++++++++ drivers/video/fbdev/msm/mdss_panel.h | 8 +++ drivers/video/fbdev/msm/msm_mdss_io_8974.c | 18 ++++++- 9 files changed, 150 insertions(+), 11 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index d9a4bd91f3eb..796246a856b4 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -210,6 +210,15 @@ enum mdss_mdp_pipe_type { MDSS_MDP_PIPE_TYPE_MAX, }; +enum mdss_mdp_intf_index { + MDSS_MDP_NO_INTF, + MDSS_MDP_INTF0, + MDSS_MDP_INTF1, + MDSS_MDP_INTF2, + MDSS_MDP_INTF3, + MDSS_MDP_MAX_INTF +}; + struct reg_bus_client { char name[MAX_CLIENT_NAME_LEN]; short usecase_ndx; diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index 88eb794a5ff5..e0b980503661 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -2515,6 +2515,15 @@ static int mdss_dsi_register_mdp_callback(struct mdss_dsi_ctrl_pdata *ctrl, return 0; } +static int mdss_dsi_register_clamp_handler(struct mdss_dsi_ctrl_pdata *ctrl, + struct mdss_intf_ulp_clamp *clamp_handler) +{ + mutex_lock(&ctrl->mutex); + ctrl->clamp_handler = clamp_handler; + mutex_unlock(&ctrl->mutex); + return 0; +} + static struct device_node *mdss_dsi_get_fb_node_cb(struct platform_device *pdev) { struct device_node *fb_node; @@ -2699,6 +2708,10 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, rc = mdss_dsi_register_mdp_callback(ctrl_pdata, (struct mdss_intf_recovery *)arg); break; + case MDSS_EVENT_REGISTER_CLAMP_HANDLER: + rc = mdss_dsi_register_clamp_handler(ctrl_pdata, + (struct mdss_intf_ulp_clamp *)arg); + break; case MDSS_EVENT_DSI_DYNAMIC_SWITCH: mode = (u32)(unsigned long) arg; mdss_dsi_switch_mode(pdata, mode); diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h index bd9fd6c7d6c5..bb46b54bc8c0 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.h +++ b/drivers/video/fbdev/msm/mdss_dsi.h @@ -484,6 +484,7 @@ struct mdss_dsi_ctrl_pdata { struct mdss_hw *dsi_hw; struct mdss_intf_recovery *recovery; struct mdss_intf_recovery *mdp_callback; + struct mdss_intf_ulp_clamp *clamp_handler; struct dsi_panel_cmds on_cmds; struct dsi_panel_cmds post_dms_on_cmds; diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 3d5d046c536a..2fd047edd3e8 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -1992,6 +1992,7 @@ void mdss_mdp_disable_hw_irq(struct mdss_data_type *mdata); void mdss_mdp_set_supported_formats(struct mdss_data_type *mdata); int mdss_mdp_dest_scaler_setup_locked(struct mdss_mdp_mixer *mixer); +void *mdss_mdp_intf_get_ctx_base(struct mdss_mdp_ctl *ctl, int intf_num); #ifdef CONFIG_FB_MSM_MDP_NONE struct mdss_data_type *mdss_mdp_get_mdata(void) diff --git a/drivers/video/fbdev/msm/mdss_mdp_hwio.h b/drivers/video/fbdev/msm/mdss_mdp_hwio.h index 294e05c2fbb0..7d495232c198 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_hwio.h +++ b/drivers/video/fbdev/msm/mdss_mdp_hwio.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, 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 @@ -634,15 +634,6 @@ enum mdss_mdp_dspp_index { #define MDSS_MDP_DSPP_OP_PA_SIX_ZONE_SAT_MASK BIT(30) #define MDSS_MDP_DSPP_OP_PA_SIX_ZONE_VAL_MASK BIT(31) -enum mdss_mpd_intf_index { - MDSS_MDP_NO_INTF, - MDSS_MDP_INTF0, - MDSS_MDP_INTF1, - MDSS_MDP_INTF2, - MDSS_MDP_INTF3, - MDSS_MDP_MAX_INTF -}; - #define MDSS_MDP_REG_INTF_TIMING_ENGINE_EN 0x000 #define MDSS_MDP_REG_INTF_CONFIG 0x004 #define MDSS_MDP_REG_INTF_HSYNC_CTL 0x008 @@ -703,6 +694,8 @@ enum mdss_mpd_intf_index { #define MDSS_MDP_PANEL_FORMAT_RGB888 0x213F #define MDSS_MDP_PANEL_FORMAT_RGB666 0x212A +#define MDSS_MDP_REG_DSI_ULP_CLAMP_VALUE 0x064 + #define MDSS_MDP_PANEL_FORMAT_PACK_ALIGN_MSB BIT(7) enum mdss_mdp_pingpong_index { diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index 583cfed598cd..c9ce56fb96a4 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -103,6 +103,7 @@ struct mdss_mdp_cmd_ctx { struct mdss_intf_recovery intf_recovery; struct mdss_intf_recovery intf_mdp_callback; + struct mdss_intf_ulp_clamp intf_clamp_handler; struct mdss_mdp_cmd_ctx *sync_ctx; /* for partial update */ u32 pp_timeout_report_cnt; bool pingpong_split_slave; @@ -1281,6 +1282,32 @@ static void mdss_mdp_cmd_lineptr_done(void *arg) spin_unlock(&ctx->clk_lock); } +static int mdss_mdp_cmd_intf_clamp_ctrl(void *data, int intf_num, bool enable) +{ + struct mdss_mdp_ctl *ctl = data; + char __iomem *ctx_base = NULL; + + if (!data) { + pr_err("%s: invalid ctl\n", __func__); + return -EINVAL; + } + + ctx_base = + (char __iomem *)mdss_mdp_intf_get_ctx_base(ctl, intf_num); + if (!ctx_base) { + pr_err("%s: invalid ctx\n", __func__); + return -EINVAL; + } + + pr_debug("%s: intf num = %d, enable = %d\n", + __func__, intf_num, enable); + + writel_relaxed(enable, (ctx_base + MDSS_MDP_REG_DSI_ULP_CLAMP_VALUE)); + wmb(); /* ensure clamp is enabled */ + + return 0; +} + static int mdss_mdp_cmd_intf_recovery(void *data, int event) { struct mdss_mdp_cmd_ctx *ctx = data; @@ -3209,6 +3236,12 @@ int mdss_mdp_cmd_ctx_stop(struct mdss_mdp_ctl *ctl, memset(ctx, 0, sizeof(*ctx)); /* intf stopped, no more kickoff */ ctx->intf_stopped = 1; + /* + * Restore clamp handler as it might get called later + * when DSI panel events are handled. + */ + ctx->intf_clamp_handler.fxn = mdss_mdp_cmd_intf_clamp_ctrl; + ctx->intf_clamp_handler.data = ctl; return 0; } @@ -3349,6 +3382,11 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl, int panel_power_state) (void *)&ctx->intf_mdp_callback, CTL_INTF_EVENT_FLAG_DEFAULT); + mdss_mdp_ctl_intf_event(ctl, + MDSS_EVENT_REGISTER_CLAMP_HANDLER, + (void *)&ctx->intf_clamp_handler, + CTL_INTF_EVENT_FLAG_DEFAULT); + mdss_mdp_tearcheck_enable(ctl, true); ctx->intf_stopped = 0; @@ -3407,6 +3445,10 @@ panel_events: goto end; } + mdss_mdp_ctl_intf_event(ctl, + MDSS_EVENT_REGISTER_CLAMP_HANDLER, + NULL, CTL_INTF_EVENT_FLAG_DEFAULT); + pr_debug("%s: turn off panel\n", __func__); ctl->intf_ctx[MASTER_CTX] = NULL; ctl->intf_ctx[SLAVE_CTX] = NULL; @@ -3540,6 +3582,14 @@ static int mdss_mdp_cmd_ctx_setup(struct mdss_mdp_ctl *ctl, ctx->intf_mdp_callback.fxn = mdss_mdp_cmd_intf_callback; ctx->intf_mdp_callback.data = ctx; + ctx->intf_clamp_handler.fxn = mdss_mdp_cmd_intf_clamp_ctrl; + ctx->intf_clamp_handler.data = ctl; + + mdss_mdp_ctl_intf_event(ctl, + MDSS_EVENT_REGISTER_CLAMP_HANDLER, + (void *)&ctx->intf_clamp_handler, + CTL_INTF_EVENT_FLAG_DEFAULT); + ctx->intf_stopped = 0; pr_debug("%s: ctx=%pK num=%d aux=%d\n", __func__, ctx, diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c index 7537ca13d2c0..122fc9f1dedf 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c @@ -84,6 +84,7 @@ struct mdss_mdp_video_ctx { struct list_head vsync_handlers; struct mdss_intf_recovery intf_recovery; struct mdss_intf_recovery intf_mdp_callback; + struct mdss_intf_ulp_clamp intf_clamp_handler; struct work_struct early_wakeup_dfps_work; atomic_t lineptr_ref; @@ -150,6 +151,23 @@ static int mdss_mdp_intf_intr2index(u32 intr_type) return index; } +void *mdss_mdp_intf_get_ctx_base(struct mdss_mdp_ctl *ctl, int intf_num) +{ + struct mdss_mdp_video_ctx *head; + int i = 0; + + if (!ctl) + return NULL; + + head = ctl->mdata->video_intf; + for (i = 0; i < ctl->mdata->nintf; i++) { + if (head[i].intf_num == intf_num) + return (void *)head[i].base; + } + + return NULL; +} + int mdss_mdp_set_intf_intr_callback(struct mdss_mdp_video_ctx *ctx, u32 intr_type, void (*fnc_ptr)(void *), void *arg) { @@ -316,6 +334,29 @@ int mdss_mdp_video_addr_setup(struct mdss_data_type *mdata, return 0; } +static int mdss_mdp_video_intf_clamp_ctrl(void *data, int intf_num, bool enable) +{ + struct mdss_mdp_video_ctx *ctx = data; + + if (!data) { + pr_err("%s: invalid ctl\n", __func__); + return -EINVAL; + } + + if (intf_num != ctx->intf_num) { + pr_err("%s: invalid intf num\n", __func__); + return -EINVAL; + } + + pr_debug("%s: ctx intf num = %d, enable = %d\n", + __func__, ctx->intf_num, enable); + + mdp_video_write(ctx, MDSS_MDP_REG_DSI_ULP_CLAMP_VALUE, enable); + wmb(); /* ensure clamp is enabled */ + + return 0; +} + static int mdss_mdp_video_intf_recovery(void *data, int event) { struct mdss_mdp_video_ctx *ctx; @@ -1989,6 +2030,13 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl, MDSS_EVENT_REGISTER_MDP_CALLBACK, (void *)&ctx->intf_mdp_callback, CTL_INTF_EVENT_FLAG_DEFAULT); + + ctx->intf_clamp_handler.fxn = mdss_mdp_video_intf_clamp_ctrl; + ctx->intf_clamp_handler.data = ctx; + mdss_mdp_ctl_intf_event(ctl, + MDSS_EVENT_REGISTER_CLAMP_HANDLER, + (void *)&ctx->intf_clamp_handler, + CTL_INTF_EVENT_FLAG_DEFAULT); } else { ctx->intf_recovery.fxn = NULL; ctx->intf_recovery.data = NULL; diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index d5de8807f7a6..889019ca74a8 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -194,6 +194,11 @@ struct mdss_intf_recovery { void *data; }; +struct mdss_intf_ulp_clamp { + int (*fxn)(void *ctx, int intf_num, bool enable); + void *data; +}; + /** * enum mdss_intf_events - Different events generated by MDP core * @@ -299,6 +304,7 @@ enum mdss_intf_events { MDSS_EVENT_UPDATE_PANEL_PPM, MDSS_EVENT_DSI_TIMING_DB_CTRL, MDSS_EVENT_AVR_MODE, + MDSS_EVENT_REGISTER_CLAMP_HANDLER, MDSS_EVENT_MAX, }; @@ -355,6 +361,8 @@ static inline char *mdss_panel_intf_event_to_string(int event) return INTF_EVENT_STR(MDSS_EVENT_REGISTER_RECOVERY_HANDLER); case MDSS_EVENT_REGISTER_MDP_CALLBACK: return INTF_EVENT_STR(MDSS_EVENT_REGISTER_MDP_CALLBACK); + case MDSS_EVENT_REGISTER_CLAMP_HANDLER: + return INTF_EVENT_STR(MDSS_EVENT_REGISTER_CLAMP_HANDLER); case MDSS_EVENT_DSI_PANEL_STATUS: return INTF_EVENT_STR(MDSS_EVENT_DSI_PANEL_STATUS); case MDSS_EVENT_DSI_DYNAMIC_SWITCH: diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c index e6151b4c75a1..0e0d2621496e 100644 --- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c +++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, 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 @@ -1983,6 +1983,7 @@ static int mdss_dsi_clamp_ctrl_default(struct mdss_dsi_ctrl_pdata *ctrl, struct mipi_panel_info *mipi = NULL; u32 clamp_reg, regval = 0; u32 clamp_reg_off; + u32 intf_num = 0; if (!ctrl) { pr_err("%s: invalid input\n", __func__); @@ -1994,6 +1995,21 @@ static int mdss_dsi_clamp_ctrl_default(struct mdss_dsi_ctrl_pdata *ctrl, return -EINVAL; } + /* + * For DSI HW version 2.1.0 ULPS_CLAMP register + * is moved to interface level. + */ + if (ctrl->shared_data->hw_rev == MDSS_DSI_HW_REV_201) { + intf_num = ctrl->ndx ? MDSS_MDP_INTF2 : MDSS_MDP_INTF1; + if (ctrl->clamp_handler) { + ctrl->clamp_handler->fxn(ctrl->clamp_handler->data, + intf_num, enable); + pr_debug("%s: ndx: %d enable: %d\n", + __func__, ctrl->ndx, enable); + } + return 0; + } + clamp_reg_off = ctrl->shared_data->ulps_clamp_ctrl_off; mipi = &ctrl->panel_data.panel_info.mipi;