diff options
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_fb.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 17 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_ctl.c | 66 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_video.c | 64 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c | 33 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_overlay.c | 10 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pipe.c | 28 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_rotator.c | 5 |
8 files changed, 123 insertions, 101 deletions
diff --git a/drivers/video/fbdev/msm/mdss_fb.h b/drivers/video/fbdev/msm/mdss_fb.h index 8ad8665fdcfb..193b6b723295 100644 --- a/drivers/video/fbdev/msm/mdss_fb.h +++ b/drivers/video/fbdev/msm/mdss_fb.h @@ -110,6 +110,7 @@ struct msm_fb_data_type { u32 mdp_fb_page_protection; + struct mdss_data_type *mdata; struct mdss_mdp_ctl *ctl; struct mdss_mdp_wb *wb; struct list_head overlay_list; diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 4a2bec98d07c..d87ab8e240c5 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -131,6 +131,8 @@ struct mdss_mdp_ctl { u32 bus_ib_quota; u32 clk_rate; + char __iomem *base; + struct mdss_data_type *mdata; struct msm_fb_data_type *mfd; struct mdss_mdp_mixer *mixer_left; struct mdss_mdp_mixer *mixer_right; @@ -150,6 +152,7 @@ struct mdss_mdp_ctl { struct mdss_mdp_mixer { u32 num; u32 ref_cnt; + char __iomem *base; u8 type; u8 params_changed; @@ -213,6 +216,7 @@ struct mdss_mdp_pipe { u32 num; u32 type; u32 ndx; + char __iomem *base; atomic_t ref_cnt; u32 play_cnt; @@ -260,14 +264,12 @@ struct mdss_mdp_writeback_arg { static inline void mdss_mdp_ctl_write(struct mdss_mdp_ctl *ctl, u32 reg, u32 val) { - int offset = MDSS_MDP_REG_CTL_OFFSET(ctl->num); - MDSS_MDP_REG_WRITE(offset + reg, val); + writel_relaxed(val, ctl->base + reg); } static inline u32 mdss_mdp_ctl_read(struct mdss_mdp_ctl *ctl, u32 reg) { - int offset = MDSS_MDP_REG_CTL_OFFSET(ctl->num); - return MDSS_MDP_REG_READ(offset + reg); + return readl_relaxed(ctl->base + reg); } irqreturn_t mdss_mdp_isr(int irq, void *ptr); @@ -333,9 +335,10 @@ int mdss_mdp_hist_collect(struct fb_info *info, struct mdp_histogram_data *hist, u32 *hist_data_addr); void mdss_mdp_hist_intr_done(u32 isr); - -struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum(u32 pnum); -struct mdss_mdp_pipe *mdss_mdp_pipe_alloc(u32 type); +struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum( + struct mdss_mdp_mixer *mixer, u32 pnum); +struct mdss_mdp_pipe *mdss_mdp_pipe_alloc( + struct mdss_mdp_mixer *mixer, u32 type); struct mdss_mdp_pipe *mdss_mdp_pipe_get(u32 ndx); int mdss_mdp_pipe_map(struct mdss_mdp_pipe *pipe); void mdss_mdp_pipe_unmap(struct mdss_mdp_pipe *pipe); diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index e17c8dc878e2..2ecd4b6ffb3d 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -41,6 +41,12 @@ static DEFINE_MUTEX(mdss_mdp_ctl_lock); static struct mdss_mdp_ctl mdss_mdp_ctl_list[MDSS_MDP_MAX_CTL]; static struct mdss_mdp_mixer mdss_mdp_mixer_list[MDSS_MDP_MAX_LAYERMIXER]; +static inline void mdp_mixer_write(struct mdss_mdp_mixer *mixer, + u32 reg, u32 val) +{ + writel_relaxed(val, mixer->base + reg); +} + static int mdss_mdp_ctl_perf_commit(u32 flags) { struct mdss_mdp_ctl *ctl; @@ -227,7 +233,7 @@ static int mdss_mdp_ctl_perf_update(struct mdss_mdp_ctl *ctl, u32 *flags) return ret; } -static struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(void) +static struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(struct mdss_data_type *mdata) { struct mdss_mdp_ctl *ctl = NULL; int cnum; @@ -238,6 +244,9 @@ static struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(void) ctl = &mdss_mdp_ctl_list[cnum]; ctl->num = cnum; ctl->ref_cnt++; + ctl->mdata = mdata; + ctl->base = mdata->mdp_base + + MDSS_MDP_REG_CTL_OFFSET(cnum); mutex_init(&ctl->lock); pr_debug("alloc ctl_num=%d\n", ctl->num); @@ -269,20 +278,27 @@ static int mdss_mdp_ctl_free(struct mdss_mdp_ctl *ctl) return 0; } -static struct mdss_mdp_mixer *mdss_mdp_mixer_alloc(u32 type) +static struct mdss_mdp_mixer *mdss_mdp_mixer_alloc( + struct mdss_mdp_ctl *ctl, u32 type) { struct mdss_mdp_mixer *mixer = NULL; int mnum; + if (!ctl || !ctl->mdata) + return NULL; + mutex_lock(&mdss_mdp_ctl_lock); for (mnum = 0; mnum < MDSS_MDP_MAX_LAYERMIXER; mnum++) { - if (type == mdss_res->mixer_type_map[mnum] && + if (type == ctl->mdata->mixer_type_map[mnum] && mdss_mdp_mixer_list[mnum].ref_cnt == 0) { mixer = &mdss_mdp_mixer_list[mnum]; mixer->num = mnum; mixer->ref_cnt++; mixer->params_changed++; mixer->type = type; + mixer->base = ctl->mdata->mdp_base + + MDSS_MDP_REG_LM_OFFSET(mnum); + mixer->ctl = ctl; pr_debug("mixer_num=%d\n", mixer->num); break; @@ -318,12 +334,11 @@ struct mdss_mdp_mixer *mdss_mdp_wb_mixer_alloc(int rotator) struct mdss_mdp_ctl *ctl = NULL; struct mdss_mdp_mixer *mixer = NULL; - ctl = mdss_mdp_ctl_alloc(); - + ctl = mdss_mdp_ctl_alloc(mdss_res); if (!ctl) return NULL; - mixer = mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_WRITEBACK); + mixer = mdss_mdp_mixer_alloc(ctl, MDSS_MDP_MIXER_TYPE_WRITEBACK); if (!mixer) goto error; @@ -344,7 +359,6 @@ struct mdss_mdp_mixer *mdss_mdp_wb_mixer_alloc(int rotator) } ctl->mixer_left = mixer; - mixer->ctl = ctl; ctl->start_fnc = mdss_mdp_writeback_start; ctl->power_on = true; @@ -429,7 +443,7 @@ static int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl) if (!ctl->mixer_left) { ctl->mixer_left = - mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_INTF); + mdss_mdp_mixer_alloc(ctl, MDSS_MDP_MIXER_TYPE_INTF); if (!ctl->mixer_left) { pr_err("unable to allocate layer mixer\n"); return -ENOMEM; @@ -441,7 +455,6 @@ static int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl) ctl->mixer_left->width = width; ctl->mixer_left->height = height; - ctl->mixer_left->ctl = ctl; if (split_ctl) { pr_debug("split display detected\n"); @@ -450,8 +463,8 @@ static int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl) if (width < ctl->width) { if (ctl->mixer_right == NULL) { - ctl->mixer_right = - mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_INTF); + ctl->mixer_right = mdss_mdp_mixer_alloc(ctl, + MDSS_MDP_MIXER_TYPE_INTF); if (!ctl->mixer_right) { pr_err("unable to allocate right mixer\n"); if (ctl->mixer_left) @@ -461,7 +474,6 @@ static int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl) } ctl->mixer_right->width = width; ctl->mixer_right->height = height; - ctl->mixer_right->ctl = ctl; } else if (ctl->mixer_right) { mdss_mdp_mixer_free(ctl->mixer_right); } @@ -483,7 +495,7 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata, struct mdss_mdp_ctl *ctl; int ret = 0; - ctl = mdss_mdp_ctl_alloc(); + ctl = mdss_mdp_ctl_alloc(mfd->mdata); if (!ctl) { pr_err("unable to allocate ctl\n"); return ERR_PTR(-ENOMEM); @@ -586,15 +598,14 @@ int mdss_mdp_ctl_split_display_setup(struct mdss_mdp_ctl *ctl, sctl->width = pdata->panel_info.xres; sctl->height = pdata->panel_info.yres; - ctl->mixer_left = mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_INTF); + ctl->mixer_left = mdss_mdp_mixer_alloc(ctl, MDSS_MDP_MIXER_TYPE_INTF); if (!ctl->mixer_left) { pr_err("unable to allocate layer mixer\n"); mdss_mdp_ctl_destroy(sctl); return -ENOMEM; } - ctl->mixer_left->ctl = ctl; - mixer = mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_INTF); + mixer = mdss_mdp_mixer_alloc(sctl, MDSS_MDP_MIXER_TYPE_INTF); if (!mixer) { pr_err("unable to allocate layer mixer\n"); mdss_mdp_ctl_destroy(sctl); @@ -603,7 +614,6 @@ int mdss_mdp_ctl_split_display_setup(struct mdss_mdp_ctl *ctl, mixer->width = sctl->width; mixer->height = sctl->height; - mixer->ctl = sctl; sctl->mixer_left = mixer; return mdss_mdp_set_split_ctl(ctl, sctl); @@ -689,7 +699,7 @@ int mdss_mdp_ctl_intf_event(struct mdss_mdp_ctl *ctl, int event, void *arg) static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl) { struct mdss_mdp_mixer *mixer; - u32 outsize, temp, off; + u32 outsize, temp; int ret = 0; if (ctl->start_fnc) @@ -713,15 +723,8 @@ static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl) temp |= (ctl->intf_type << ((ctl->intf_num - MDSS_MDP_INTF0) * 8)); MDSS_MDP_REG_WRITE(MDSS_MDP_REG_DISP_INTF_SEL, temp); - if (ctl->intf_num != MDSS_MDP_NO_INTF) { - off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_PANEL_FORMAT, - ctl->dst_format); - } - outsize = (mixer->height << 16) | mixer->width; - off = MDSS_MDP_REG_LM_OFFSET(mixer->num); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_OUT_SIZE, outsize); + mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OUT_SIZE, outsize); return ret; } @@ -868,8 +871,7 @@ static int mdss_mdp_mixer_setup(struct mdss_mdp_ctl *ctl, } blend_stage = stage - MDSS_MDP_STAGE_0; - off = MDSS_MDP_REG_LM_OFFSET(mixer->num) + - MDSS_MDP_REG_LM_BLEND_OFFSET(blend_stage); + off = MDSS_MDP_REG_LM_BLEND_OFFSET(blend_stage); if (pipe->is_fg) { bgalpha = 0; @@ -915,10 +917,10 @@ static int mdss_mdp_mixer_setup(struct mdss_mdp_ctl *ctl, mixercfg |= stage << (3 * pipe->num); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_OP_MODE, blend_op); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_BLEND_FG_ALPHA, + mdp_mixer_write(mixer, off + MDSS_MDP_REG_LM_OP_MODE, blend_op); + mdp_mixer_write(mixer, off + MDSS_MDP_REG_LM_BLEND_FG_ALPHA, pipe->alpha); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_BLEND_BG_ALPHA, + mdp_mixer_write(mixer, off + MDSS_MDP_REG_LM_BLEND_BG_ALPHA, 0xFF - pipe->alpha); } @@ -930,7 +932,7 @@ static int mdss_mdp_mixer_setup(struct mdss_mdp_ctl *ctl, ctl->flush_bits |= BIT(6) << mixer->num; /* LAYER_MIXER */ off = MDSS_MDP_REG_LM_OFFSET(mixer->num); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_OP_MODE, blend_color_out); + mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OP_MODE, blend_color_out); mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(mixer->num), mixercfg); return 0; diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c index a6a6d59b07da..0cba9c3540dd 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c @@ -41,6 +41,8 @@ struct intf_timing_params { #define MAX_SESSIONS 3 struct mdss_mdp_video_ctx { u32 pp_num; + char __iomem *base; + u32 intf_type; u8 ref_cnt; u8 timegen_en; @@ -53,7 +55,13 @@ struct mdss_mdp_video_ctx { struct mdss_mdp_video_ctx mdss_mdp_video_ctx_list[MAX_SESSIONS]; -static int mdss_mdp_video_timegen_setup(struct mdss_mdp_ctl *ctl, +static inline void mdp_video_write(struct mdss_mdp_video_ctx *ctx, + u32 reg, u32 val) +{ + writel_relaxed(val, ctx->base + reg); +} + +static int mdss_mdp_video_timegen_setup(struct mdss_mdp_video_ctx *ctx, struct intf_timing_params *p) { u32 hsync_period, vsync_period; @@ -61,9 +69,6 @@ static int mdss_mdp_video_timegen_setup(struct mdss_mdp_ctl *ctl, u32 active_h_start, active_h_end, active_v_start, active_v_end; u32 den_polarity, hsync_polarity, vsync_polarity; u32 display_hctl, active_hctl, hsync_ctl, polarity_ctl; - int off; - - off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num); hsync_period = p->hsync_pulse_width + p->h_back_porch + p->width + p->h_front_porch; @@ -75,7 +80,7 @@ static int mdss_mdp_video_timegen_setup(struct mdss_mdp_ctl *ctl, display_v_end = ((vsync_period - p->v_front_porch) * hsync_period) + p->hsync_skew - 1; - if (ctl->intf_type == MDSS_INTF_EDP) { + if (ctx->intf_type == MDSS_INTF_EDP) { display_v_start += p->hsync_pulse_width + p->h_back_porch; display_v_end -= p->h_front_porch; } @@ -114,7 +119,7 @@ static int mdss_mdp_video_timegen_setup(struct mdss_mdp_ctl *ctl, display_hctl = (hsync_end_x << 16) | hsync_start_x; den_polarity = 0; - if (MDSS_INTF_HDMI == ctl->intf_type) { + if (MDSS_INTF_HDMI == ctx->intf_type) { hsync_polarity = p->yres >= 720 ? 0 : 1; vsync_polarity = p->yres >= 720 ? 0 : 1; } else { @@ -125,31 +130,25 @@ static int mdss_mdp_video_timegen_setup(struct mdss_mdp_ctl *ctl, (vsync_polarity << 1) | /* VSYNC Polarity */ (hsync_polarity << 0); /* HSYNC Polarity */ - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_HSYNC_CTL, hsync_ctl); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_VSYNC_PERIOD_F0, + mdp_video_write(ctx, MDSS_MDP_REG_INTF_HSYNC_CTL, hsync_ctl); + mdp_video_write(ctx, MDSS_MDP_REG_INTF_VSYNC_PERIOD_F0, vsync_period * hsync_period); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_VSYNC_PULSE_WIDTH_F0, + mdp_video_write(ctx, MDSS_MDP_REG_INTF_VSYNC_PULSE_WIDTH_F0, p->vsync_pulse_width * hsync_period); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_DISPLAY_HCTL, - display_hctl); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_DISPLAY_V_START_F0, + mdp_video_write(ctx, MDSS_MDP_REG_INTF_DISPLAY_HCTL, display_hctl); + mdp_video_write(ctx, MDSS_MDP_REG_INTF_DISPLAY_V_START_F0, display_v_start); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_DISPLAY_V_END_F0, - display_v_end); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_ACTIVE_HCTL, active_hctl); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_ACTIVE_V_START_F0, + mdp_video_write(ctx, MDSS_MDP_REG_INTF_DISPLAY_V_END_F0, display_v_end); + mdp_video_write(ctx, MDSS_MDP_REG_INTF_ACTIVE_HCTL, active_hctl); + mdp_video_write(ctx, MDSS_MDP_REG_INTF_ACTIVE_V_START_F0, active_v_start); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_ACTIVE_V_END_F0, - active_v_end); + mdp_video_write(ctx, MDSS_MDP_REG_INTF_ACTIVE_V_END_F0, active_v_end); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_BORDER_COLOR, - p->border_clr); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_UNDERFLOW_COLOR, + mdp_video_write(ctx, MDSS_MDP_REG_INTF_BORDER_COLOR, p->border_clr); + mdp_video_write(ctx, MDSS_MDP_REG_INTF_UNDERFLOW_COLOR, p->underflow_clr); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_HSYNC_SKEW, - p->hsync_skew); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_POLARITY_CTL, - polarity_ctl); + mdp_video_write(ctx, MDSS_MDP_REG_INTF_HSYNC_SKEW, p->hsync_skew); + mdp_video_write(ctx, MDSS_MDP_REG_INTF_POLARITY_CTL, polarity_ctl); return 0; } @@ -198,7 +197,7 @@ static int mdss_mdp_video_set_vsync_handler(struct mdss_mdp_ctl *ctl, static int mdss_mdp_video_stop(struct mdss_mdp_ctl *ctl) { struct mdss_mdp_video_ctx *ctx; - int rc, off; + int rc; pr_debug("stop ctl=%d\n", ctl->num); @@ -217,8 +216,7 @@ static int mdss_mdp_video_stop(struct mdss_mdp_ctl *ctl) } WARN(rc, "intf %d blank error (%d)\n", ctl->intf_num, rc); - off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 0); + mdp_video_write(ctx, MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 0); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); ctx->timegen_en = false; @@ -276,15 +274,13 @@ static int mdss_mdp_video_display(struct mdss_mdp_ctl *ctl, void *arg) video_vsync_irq_enable(ctl); if (!ctx->timegen_en) { - int off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num); - rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_UNBLANK, NULL); WARN(rc, "intf %d unblank error (%d)\n", ctl->intf_num, rc); pr_debug("enabling timing gen for intf=%d\n", ctl->intf_num); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 1); + mdp_video_write(ctx, MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 1); wmb(); } @@ -333,7 +329,10 @@ int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl) return -ENOMEM; } ctl->priv_data = ctx; + ctx->base = ctl->mdata->mdp_base + + MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num); ctx->pp_num = mixer->num; + ctx->intf_type = ctl->intf_type; init_completion(&ctx->vsync_comp); spin_lock_init(&ctx->vsync_lock); atomic_set(&ctx->vsync_ref, 0); @@ -356,10 +355,11 @@ int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl) itp.hsync_pulse_width = pinfo->lcdc.h_pulse_width; itp.vsync_pulse_width = pinfo->lcdc.v_pulse_width; - if (mdss_mdp_video_timegen_setup(ctl, &itp)) { + if (mdss_mdp_video_timegen_setup(ctx, &itp)) { pr_err("unable to get timing parameters\n"); return -EINVAL; } + mdp_video_write(ctx, MDSS_MDP_REG_INTF_PANEL_FORMAT, ctl->dst_format); ctl->stop_fnc = mdss_mdp_video_stop; ctl->display_fnc = mdss_mdp_video_display; diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c index 2c0dddaaf9b8..ee953969cbae 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c @@ -27,6 +27,7 @@ enum mdss_mdp_writeback_type { struct mdss_mdp_writeback_ctx { u32 wb_num; + char __iomem *base; u8 ref_cnt; u8 type; @@ -75,10 +76,16 @@ static struct mdss_mdp_writeback_ctx wb_ctx_list[MDSS_MDP_MAX_WRITEBACK] = { }, }; +static inline void mdp_wb_write(struct mdss_mdp_writeback_ctx *ctx, + u32 reg, u32 val) +{ + writel_relaxed(val, ctx->base + reg); +} + static int mdss_mdp_writeback_addr_setup(struct mdss_mdp_writeback_ctx *ctx, struct mdss_mdp_data *data) { - int off, ret; + int ret; if (!data) return -EINVAL; @@ -89,11 +96,10 @@ static int mdss_mdp_writeback_addr_setup(struct mdss_mdp_writeback_ctx *ctx, if (ret) return ret; - off = MDSS_MDP_REG_WB_OFFSET(ctx->wb_num); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST0_ADDR, data->p[0].addr); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST1_ADDR, data->p[1].addr); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST2_ADDR, data->p[2].addr); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST3_ADDR, data->p[3].addr); + mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST0_ADDR, data->p[0].addr); + mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST1_ADDR, data->p[1].addr); + mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST2_ADDR, data->p[2].addr); + mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST3_ADDR, data->p[3].addr); return 0; } @@ -102,7 +108,6 @@ static int mdss_mdp_writeback_format_setup(struct mdss_mdp_writeback_ctx *ctx) { struct mdss_mdp_format_params *fmt; u32 dst_format, pattern, ystride0, ystride1, outsize, chroma_samp; - int off; u32 opmode = ctx->opmode; pr_debug("wb_num=%d format=%d\n", ctx->wb_num, ctx->format); @@ -173,13 +178,12 @@ static int mdss_mdp_writeback_format_setup(struct mdss_mdp_writeback_ctx *ctx) (ctx->dst_planes.ystride[3] << 16); outsize = (ctx->height << 16) | ctx->width; - off = MDSS_MDP_REG_WB_OFFSET(ctx->wb_num); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST_FORMAT, dst_format); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST_OP_MODE, opmode); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST_PACK_PATTERN, pattern); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST_YSTRIDE0, ystride0); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST_YSTRIDE1, ystride1); - MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_OUT_SIZE, outsize); + mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST_FORMAT, dst_format); + mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST_OP_MODE, opmode); + mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST_PACK_PATTERN, pattern); + mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST_YSTRIDE0, ystride0); + mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST_YSTRIDE1, ystride1); + mdp_wb_write(ctx, MDSS_MDP_REG_WB_OUT_SIZE, outsize); return 0; } @@ -352,6 +356,7 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl) } ctl->priv_data = ctx; ctx->wb_num = ctl->num; /* wb num should match ctl num */ + ctx->base = ctl->mdata->mdp_base + MDSS_MDP_REG_WB_OFFSET(ctx->wb_num); ctx->initialized = false; mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num, diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index 8e113f2d87ec..0bc506b756e2 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -280,12 +280,12 @@ static int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd, else pipe_type = MDSS_MDP_PIPE_TYPE_RGB; - pipe = mdss_mdp_pipe_alloc(pipe_type); + pipe = mdss_mdp_pipe_alloc(mixer, pipe_type); /* VIG pipes can also support RGB format */ if (!pipe && pipe_type == MDSS_MDP_PIPE_TYPE_RGB) { pipe_type = MDSS_MDP_PIPE_TYPE_VIG; - pipe = mdss_mdp_pipe_alloc(pipe_type); + pipe = mdss_mdp_pipe_alloc(mixer, pipe_type); } if (pipe == NULL) { @@ -1326,6 +1326,12 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd) struct device *dev = mfd->fbi->dev; int rc; + mfd->mdata = dev_get_drvdata(mfd->pdev->dev.parent); + if (!mfd->mdata) { + pr_err("unable to initialize overlay for fb%d\n", mfd->index); + return -ENODEV; + } + mfd->on_fnc = mdss_mdp_overlay_on; mfd->off_fnc = mdss_mdp_overlay_off; mfd->hw_refresh = true; diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c index 4ece15da50fa..1f381e173f00 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c @@ -179,16 +179,24 @@ int mdss_mdp_pipe_map(struct mdss_mdp_pipe *pipe) return 0; } -static struct mdss_mdp_pipe *mdss_mdp_pipe_init(u32 pnum) +static struct mdss_mdp_pipe *mdss_mdp_pipe_init( + struct mdss_mdp_mixer *mixer, u32 pnum) { - struct mdss_mdp_pipe *pipe; + struct mdss_mdp_pipe *pipe = NULL; + struct mdss_data_type *mdata; + + if (!mixer || !mixer->ctl || !mixer->ctl->mdata) + return NULL; + mdata = mixer->ctl->mdata; pipe = &mdss_mdp_pipe_list[pnum]; if (atomic_cmpxchg(&pipe->ref_cnt, 0, 1) == 0) { pipe->num = pnum; pipe->type = mdss_res->pipe_type_map[pnum]; pipe->ndx = BIT(pnum); + pipe->base = mdata->mdp_base + MDSS_MDP_REG_SSPP_OFFSET(pnum); + pipe->mixer = mixer; pr_debug("ndx=%x pnum=%d\n", pipe->ndx, pipe->num); @@ -198,17 +206,19 @@ static struct mdss_mdp_pipe *mdss_mdp_pipe_init(u32 pnum) return NULL; } -struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum(u32 pnum) +struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum( + struct mdss_mdp_mixer *mixer, u32 pnum) { struct mdss_mdp_pipe *pipe = NULL; mutex_lock(&mdss_mdp_sspp_lock); if (mdss_res->pipe_type_map[pnum] != MDSS_MDP_PIPE_TYPE_UNUSED) - pipe = mdss_mdp_pipe_init(pnum); + pipe = mdss_mdp_pipe_init(mixer, pnum); mutex_unlock(&mdss_mdp_sspp_lock); return pipe; } -struct mdss_mdp_pipe *mdss_mdp_pipe_alloc(u32 type) +struct mdss_mdp_pipe *mdss_mdp_pipe_alloc( + struct mdss_mdp_mixer *mixer, u32 type) { struct mdss_mdp_pipe *pipe = NULL; int pnum; @@ -216,7 +226,7 @@ struct mdss_mdp_pipe *mdss_mdp_pipe_alloc(u32 type) mutex_lock(&mdss_mdp_sspp_lock); for (pnum = 0; pnum < MDSS_MDP_MAX_SSPP; pnum++) { if (type == mdss_res->pipe_type_map[pnum]) { - pipe = mdss_mdp_pipe_init(pnum); + pipe = mdss_mdp_pipe_init(mixer, pnum); if (pipe) break; } @@ -283,14 +293,12 @@ int mdss_mdp_pipe_destroy(struct mdss_mdp_pipe *pipe) static inline void mdss_mdp_pipe_write(struct mdss_mdp_pipe *pipe, u32 reg, u32 val) { - int offset = MDSS_MDP_REG_SSPP_OFFSET(pipe->num); - MDSS_MDP_REG_WRITE(offset + reg, val); + writel_relaxed(val, pipe->base + reg); } static inline u32 mdss_mdp_pipe_read(struct mdss_mdp_pipe *pipe, u32 reg) { - int offset = MDSS_MDP_REG_SSPP_OFFSET(pipe->num); - return MDSS_MDP_REG_READ(offset + reg); + return readl_relaxed(pipe->base + reg); } static int mdss_mdp_leading_zero(u32 num) diff --git a/drivers/video/fbdev/msm/mdss_mdp_rotator.c b/drivers/video/fbdev/msm/mdss_mdp_rotator.c index 8c13931af9e5..0ee336a110e7 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_rotator.c +++ b/drivers/video/fbdev/msm/mdss_mdp_rotator.c @@ -87,10 +87,7 @@ static struct mdss_mdp_pipe *mdss_mdp_rotator_pipe_alloc(void) goto done; } - pipe = mdss_mdp_pipe_alloc_pnum(pnum); - - if (!IS_ERR_OR_NULL(pipe)) - pipe->mixer = mixer; + pipe = mdss_mdp_pipe_alloc_pnum(mixer, pnum); done: if (!pipe) mdss_mdp_wb_mixer_destroy(mixer); |
