Merge "drm/msm/sde: adding implementation for mdp_top in hw driver"

This commit is contained in:
Linux Build Service Account 2017-01-13 17:03:00 -08:00 committed by Gerrit - the friendly Code Review server
commit f8278058a2
8 changed files with 193 additions and 6 deletions

View file

@ -89,5 +89,6 @@ obj-$(CONFIG_DRM_MSM) += sde/sde_hw_catalog.o \
sde/sde_hw_sspp.o \
sde/sde_hw_wb.o \
sde/sde_hw_pingpong.o \
sde/sde_hw_mdp_top.o \
sde/sde_hw_interrupts.o \
sde/sde_mdp_formats.o

View file

@ -13,6 +13,7 @@
#include "sde_hwio.h"
#include "sde_hw_catalog.h"
#include "sde_hw_intf.h"
#include "sde_hw_mdp_top.h"
#define INTF_TIMING_ENGINE_EN 0x000
#define INTF_CONFIG 0x004
@ -205,10 +206,16 @@ static void sde_hw_intf_enable_timing_engine(
/* Display interface select */
if (enable) {
intf_sel = SDE_REG_READ(c, DISP_INTF_SEL);
/* top block */
struct sde_hw_mdp *mdp = sde_hw_mdptop_init(MDP_TOP,
c->base_off,
intf->mdss);
struct sde_hw_blk_reg_map *top = &mdp->hw;
intf_sel |= (intf->cap->type << ((intf->idx) * 8));
SDE_REG_WRITE(c, DISP_INTF_SEL, intf_sel);
intf_sel = SDE_REG_READ(top, DISP_INTF_SEL);
intf_sel |= (intf->cap->type << ((intf->idx - INTF_0) * 8));
SDE_REG_WRITE(top, DISP_INTF_SEL, intf_sel);
}
SDE_REG_WRITE(c, INTF_TIMING_ENGINE_EN,
@ -366,6 +373,7 @@ struct sde_hw_intf *sde_hw_intf_init(enum sde_intf idx,
*/
c->idx = idx;
c->cap = cfg;
c->mdss = m;
_setup_intf_ops(&c->ops, c->cap->features);
/*

View file

@ -85,6 +85,7 @@ struct sde_hw_intf {
/* intf */
enum sde_intf idx;
const struct sde_intf_cfg *cap;
const struct sde_mdss_cfg *mdss;
/* ops */
struct sde_hw_intf_ops ops;

View file

@ -76,7 +76,7 @@ static void sde_hw_lm_setup_out(struct sde_hw_mixer *ctx,
SDE_REG_WRITE(c, LM_OUT_SIZE, outsize);
/* SPLIT_LEFT_RIGHT */
opmode = (opmode & ~(1 << 31)) | (mixer->right_mixer & 1 << 31);
opmode = (opmode & ~(1 << 31)) | ((mixer->right_mixer) ? (1 << 31) : 0);
SDE_REG_WRITE(c, LM_OP_MODE, opmode);
}
@ -128,7 +128,7 @@ static void sde_hw_lm_setup_blendcfg(struct sde_hw_mixer *ctx,
fg->const_alpha);
SDE_REG_WRITE(c, LM_BLEND0_BG_ALPHA + stage_off,
bg->const_alpha);
SDE_REG_WRITE(c, LM_OP_MODE, blend_op);
SDE_REG_WRITE(c, LM_BLEND0_OP + stage_off, blend_op);
}
static void sde_hw_lm_setup_color3(struct sde_hw_mixer *ctx,

View file

@ -14,6 +14,7 @@
#define _SDE_HW_MDP_CTL_H
#include "sde_hw_mdss.h"
#include "sde_hw_mdp_util.h"
#include "sde_hw_catalog.h"
struct sde_hw_ctl;

View file

@ -0,0 +1,110 @@
/* Copyright (c) 2015-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
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "sde_hwio.h"
#include "sde_hw_catalog.h"
#include "sde_hw_mdp_top.h"
#define SPLIT_DISPLAY_ENABLE 0x2F4
#define LOWER_PIPE_CTRL 0x2F8
#define UPPER_PIPE_CTRL 0x3F0
#define TE_LINE_INTERVAL 0x3F4
static void sde_hw_setup_split_pipe_control(struct sde_hw_mdp *mdp,
struct split_pipe_cfg *cfg)
{
struct sde_hw_blk_reg_map *c = &mdp->hw;
u32 upper_pipe;
u32 lower_pipe;
if (cfg->en) {
upper_pipe = BIT(8);
lower_pipe = BIT(8);
if (cfg->mode == INTF_MODE_CMD) {
upper_pipe |= BIT(0);
lower_pipe |= BIT(0);
}
SDE_REG_WRITE(c, LOWER_PIPE_CTRL, lower_pipe);
SDE_REG_WRITE(c, UPPER_PIPE_CTRL, upper_pipe);
}
SDE_REG_WRITE(c, SPLIT_DISPLAY_ENABLE, cfg->en & 0x1);
}
static void _setup_mdp_ops(struct sde_hw_mdp_ops *ops,
unsigned long cap)
{
ops->setup_split_pipe = sde_hw_setup_split_pipe_control;
}
static const struct sde_mdp_cfg *_top_offset(enum sde_mdp mdp,
const struct sde_mdss_cfg *m,
void __iomem *addr,
struct sde_hw_blk_reg_map *b)
{
int i;
for (i = 0; i < m->mdp_count; i++) {
if (mdp == m->mdp[i].id) {
b->base_off = addr;
b->blk_off = m->mdp[i].base;
b->hwversion = m->hwversion;
return &m->mdp[i];
}
}
return ERR_PTR(-EINVAL);
}
struct sde_hw_mdp *sde_hw_mdptop_init(enum sde_mdp idx,
void __iomem *addr,
const struct sde_mdss_cfg *m)
{
static struct sde_hw_mdp *c;
const struct sde_mdp_cfg *cfg;
/* mdp top is singleton */
if (c) {
pr_err(" %s returning %pK", __func__, c);
return c;
}
c = kzalloc(sizeof(*c), GFP_KERNEL);
pr_err(" %s returning %pK", __func__, c);
if (!c)
return ERR_PTR(-ENOMEM);
cfg = _top_offset(idx, m, addr, &c->hw);
if (IS_ERR_OR_NULL(cfg)) {
kfree(c);
return ERR_PTR(-EINVAL);
}
/*
* Assign ops
*/
c->idx = idx;
c->cap = cfg;
_setup_mdp_ops(&c->ops, c->cap->features);
/*
* Perform any default initialization for the intf
*/
return c;
}
void sde_hw_mdp_destroy(struct sde_hw_mdp *mdp)
{
}

View file

@ -0,0 +1,66 @@
/* Copyright (c) 2015-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
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SDE_HW_MDP_TOP_H
#define _SDE_HW_MDP_TOP_H
#include "sde_hw_catalog.h"
#include "sde_hw_mdss.h"
#include "sde_hw_mdp_util.h"
struct sde_hw_mdp;
/**
* struct split_pipe_cfg - pipe configuration for dual display panels
* @en : Enable/disable dual pipe confguration
* @mode : Panel interface mode
*/
struct split_pipe_cfg {
bool en;
enum sde_intf_mode mode;
};
/**
* struct sde_hw_mdp_ops - interface to the MDP TOP Hw driver functions
* Assumption is these functions will be called after clocks are enabled.
* @setup_split_pipe : Programs the pipe control registers
*/
struct sde_hw_mdp_ops {
void (*setup_split_pipe)(struct sde_hw_mdp *mdp,
struct split_pipe_cfg *p);
};
struct sde_hw_mdp {
/* base */
struct sde_hw_blk_reg_map hw;
/* intf */
enum sde_mdp idx;
const struct sde_mdp_cfg *cap;
/* ops */
struct sde_hw_mdp_ops ops;
};
/**
* sde_hw_intf_init - initializes the intf driver for the passed interface idx
* @idx: Interface index for which driver object is required
* @addr: Mapped register io address of MDP
* @m: Pointer to mdss catalog data
*/
struct sde_hw_mdp *sde_hw_mdptop_init(enum sde_mdp idx,
void __iomem *addr,
const struct sde_mdss_cfg *m);
void sde_hw_mdp_destroy(struct sde_hw_mdp *mdp);
#endif /*_SDE_HW_MDP_TOP_H */

View file

@ -414,7 +414,7 @@ static void sde_hw_sspp_setup_sourceaddress(struct sde_hw_pipe *ctx,
return;
for (i = 0; i < cfg->src.num_planes; i++)
SDE_REG_WRITE(c, SSPP_SRC0_ADDR + idx + i*0x4,
SDE_REG_WRITE(c, SSPP_SRC0_ADDR + idx + i*0x4,
cfg->addr.plane[i]);
}