summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h17
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c66
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_video.c64
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c33
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c10
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pipe.c28
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_rotator.c5
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);