Merge "drm/msm/sde: adding implementation for mdp_top in hw driver"
This commit is contained in:
commit
f8278058a2
8 changed files with 193 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
110
drivers/gpu/drm/msm/sde/sde_hw_mdp_top.c
Normal file
110
drivers/gpu/drm/msm/sde/sde_hw_mdp_top.c
Normal 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)
|
||||
{
|
||||
}
|
||||
|
66
drivers/gpu/drm/msm/sde/sde_hw_mdp_top.h
Normal file
66
drivers/gpu/drm/msm/sde/sde_hw_mdp_top.h
Normal 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 */
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue