Commit 73bfb790 authored by Kalyan Thota's avatar Kalyan Thota Committed by Rob Clark

msm:disp:dpu1: setup display datapath for SC7180 target

Add changes to setup display datapath on SC7180 target.

Changes in v1:
 - Add changes to support ctl_active on SC7180 target.
 - While selecting the number of mixers in the topology
   consider the interface width.

Changes in v2:
 - Spawn topology mixer selection into separate patch (Rob Clark).
 - Add co-developed-by tags in the commit msg (Stephen Boyd).

Changes in v3:
 - Fix kernel checkpatch errors in v2.

This patch has dependency on the below series

https://patchwork.kernel.org/patch/11253747/Co-developed-by: default avatarShubhashree Dhar <dhar@codeaurora.org>
Signed-off-by: default avatarShubhashree Dhar <dhar@codeaurora.org>
Co-developed-by: default avatarRaviteja Tamatam <travitej@codeaurora.org>
Signed-off-by: default avatarRaviteja Tamatam <travitej@codeaurora.org>
Signed-off-by: default avatarKalyan Thota <kalyan_t@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
parent 7bdc0c4b
...@@ -280,6 +280,14 @@ static void dpu_encoder_phys_vid_setup_timing_engine( ...@@ -280,6 +280,14 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
phys_enc->hw_intf->ops.setup_timing_gen(phys_enc->hw_intf, phys_enc->hw_intf->ops.setup_timing_gen(phys_enc->hw_intf,
&timing_params, fmt); &timing_params, fmt);
phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg); phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg);
/* setup which pp blk will connect to this intf */
if (phys_enc->hw_intf->ops.bind_pingpong_blk)
phys_enc->hw_intf->ops.bind_pingpong_blk(
phys_enc->hw_intf,
true,
phys_enc->hw_pp->idx);
spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
programmable_fetch_config(phys_enc, &timing_params); programmable_fetch_config(phys_enc, &timing_params);
...@@ -435,6 +443,7 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) ...@@ -435,6 +443,7 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
{ {
struct dpu_hw_ctl *ctl; struct dpu_hw_ctl *ctl;
u32 flush_mask = 0; u32 flush_mask = 0;
u32 intf_flush_mask = 0;
ctl = phys_enc->hw_ctl; ctl = phys_enc->hw_ctl;
...@@ -459,10 +468,18 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) ...@@ -459,10 +468,18 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
ctl->ops.get_bitmask_intf(ctl, &flush_mask, phys_enc->hw_intf->idx); ctl->ops.get_bitmask_intf(ctl, &flush_mask, phys_enc->hw_intf->idx);
ctl->ops.update_pending_flush(ctl, flush_mask); ctl->ops.update_pending_flush(ctl, flush_mask);
if (ctl->ops.get_bitmask_active_intf)
ctl->ops.get_bitmask_active_intf(ctl, &intf_flush_mask,
phys_enc->hw_intf->idx);
if (ctl->ops.update_pending_intf_flush)
ctl->ops.update_pending_intf_flush(ctl, intf_flush_mask);
skip_flush: skip_flush:
DPU_DEBUG_VIDENC(phys_enc, DPU_DEBUG_VIDENC(phys_enc,
"update pending flush ctl %d flush_mask %x\n", "update pending flush ctl %d flush_mask 0%x intf_mask 0x%x\n",
ctl->idx - CTL_0, flush_mask); ctl->idx - CTL_0, flush_mask, intf_flush_mask);
/* ctl_flush & timing engine enable will be triggered by framework */ /* ctl_flush & timing engine enable will be triggered by framework */
if (phys_enc->enable_state == DPU_ENC_DISABLED) if (phys_enc->enable_state == DPU_ENC_DISABLED)
......
...@@ -374,6 +374,7 @@ static struct dpu_pingpong_cfg sc7180_pp[] = { ...@@ -374,6 +374,7 @@ static struct dpu_pingpong_cfg sc7180_pp[] = {
{\ {\
.name = _name, .id = _id, \ .name = _name, .id = _id, \
.base = _base, .len = 0x280, \ .base = _base, .len = 0x280, \
.features = BIT(DPU_CTL_ACTIVE_CFG), \
.type = _type, \ .type = _type, \
.controller_id = _ctrl_id, \ .controller_id = _ctrl_id, \
.prog_fetch_lines_worst_case = 24 \ .prog_fetch_lines_worst_case = 24 \
......
...@@ -22,11 +22,15 @@ ...@@ -22,11 +22,15 @@
#define CTL_PREPARE 0x0d0 #define CTL_PREPARE 0x0d0
#define CTL_SW_RESET 0x030 #define CTL_SW_RESET 0x030
#define CTL_LAYER_EXTN_OFFSET 0x40 #define CTL_LAYER_EXTN_OFFSET 0x40
#define CTL_INTF_ACTIVE 0x0F4
#define CTL_INTF_FLUSH 0x110
#define CTL_INTF_MASTER 0x134
#define CTL_MIXER_BORDER_OUT BIT(24) #define CTL_MIXER_BORDER_OUT BIT(24)
#define CTL_FLUSH_MASK_CTL BIT(17) #define CTL_FLUSH_MASK_CTL BIT(17)
#define DPU_REG_RESET_TIMEOUT_US 2000 #define DPU_REG_RESET_TIMEOUT_US 2000
#define INTF_IDX 31
static const struct dpu_ctl_cfg *_ctl_offset(enum dpu_ctl ctl, static const struct dpu_ctl_cfg *_ctl_offset(enum dpu_ctl ctl,
const struct dpu_mdss_cfg *m, const struct dpu_mdss_cfg *m,
...@@ -100,11 +104,27 @@ static inline void dpu_hw_ctl_update_pending_flush(struct dpu_hw_ctl *ctx, ...@@ -100,11 +104,27 @@ static inline void dpu_hw_ctl_update_pending_flush(struct dpu_hw_ctl *ctx,
ctx->pending_flush_mask |= flushbits; ctx->pending_flush_mask |= flushbits;
} }
static inline void dpu_hw_ctl_update_pending_intf_flush(struct dpu_hw_ctl *ctx,
u32 flushbits)
{
ctx->pending_intf_flush_mask |= flushbits;
}
static u32 dpu_hw_ctl_get_pending_flush(struct dpu_hw_ctl *ctx) static u32 dpu_hw_ctl_get_pending_flush(struct dpu_hw_ctl *ctx)
{ {
return ctx->pending_flush_mask; return ctx->pending_flush_mask;
} }
static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
{
if (ctx->pending_flush_mask & BIT(INTF_IDX))
DPU_REG_WRITE(&ctx->hw, CTL_INTF_FLUSH,
ctx->pending_intf_flush_mask);
DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
}
static inline void dpu_hw_ctl_trigger_flush(struct dpu_hw_ctl *ctx) static inline void dpu_hw_ctl_trigger_flush(struct dpu_hw_ctl *ctx)
{ {
trace_dpu_hw_ctl_trigger_pending_flush(ctx->pending_flush_mask, trace_dpu_hw_ctl_trigger_pending_flush(ctx->pending_flush_mask,
...@@ -222,6 +242,36 @@ static int dpu_hw_ctl_get_bitmask_intf(struct dpu_hw_ctl *ctx, ...@@ -222,6 +242,36 @@ static int dpu_hw_ctl_get_bitmask_intf(struct dpu_hw_ctl *ctx,
return 0; return 0;
} }
static int dpu_hw_ctl_get_bitmask_intf_v1(struct dpu_hw_ctl *ctx,
u32 *flushbits, enum dpu_intf intf)
{
switch (intf) {
case INTF_0:
case INTF_1:
*flushbits |= BIT(31);
break;
default:
return 0;
}
return 0;
}
static int dpu_hw_ctl_active_get_bitmask_intf(struct dpu_hw_ctl *ctx,
u32 *flushbits, enum dpu_intf intf)
{
switch (intf) {
case INTF_0:
*flushbits |= BIT(0);
break;
case INTF_1:
*flushbits |= BIT(1);
break;
default:
return 0;
}
return 0;
}
static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us) static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us)
{ {
struct dpu_hw_blk_reg_map *c = &ctx->hw; struct dpu_hw_blk_reg_map *c = &ctx->hw;
...@@ -422,6 +472,24 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx, ...@@ -422,6 +472,24 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
DPU_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg_ext3); DPU_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg_ext3);
} }
static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
struct dpu_hw_intf_cfg *cfg)
{
struct dpu_hw_blk_reg_map *c = &ctx->hw;
u32 intf_active = 0;
u32 mode_sel = 0;
if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD)
mode_sel |= BIT(17);
intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
intf_active |= BIT(cfg->intf - INTF_0);
DPU_REG_WRITE(c, CTL_TOP, mode_sel);
DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
}
static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
struct dpu_hw_intf_cfg *cfg) struct dpu_hw_intf_cfg *cfg)
{ {
...@@ -455,21 +523,31 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, ...@@ -455,21 +523,31 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
unsigned long cap) unsigned long cap)
{ {
if (cap & BIT(DPU_CTL_ACTIVE_CFG)) {
ops->trigger_flush = dpu_hw_ctl_trigger_flush_v1;
ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg_v1;
ops->get_bitmask_intf = dpu_hw_ctl_get_bitmask_intf_v1;
ops->get_bitmask_active_intf =
dpu_hw_ctl_active_get_bitmask_intf;
ops->update_pending_intf_flush =
dpu_hw_ctl_update_pending_intf_flush;
} else {
ops->trigger_flush = dpu_hw_ctl_trigger_flush;
ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg;
ops->get_bitmask_intf = dpu_hw_ctl_get_bitmask_intf;
}
ops->clear_pending_flush = dpu_hw_ctl_clear_pending_flush; ops->clear_pending_flush = dpu_hw_ctl_clear_pending_flush;
ops->update_pending_flush = dpu_hw_ctl_update_pending_flush; ops->update_pending_flush = dpu_hw_ctl_update_pending_flush;
ops->get_pending_flush = dpu_hw_ctl_get_pending_flush; ops->get_pending_flush = dpu_hw_ctl_get_pending_flush;
ops->trigger_flush = dpu_hw_ctl_trigger_flush;
ops->get_flush_register = dpu_hw_ctl_get_flush_register; ops->get_flush_register = dpu_hw_ctl_get_flush_register;
ops->trigger_start = dpu_hw_ctl_trigger_start; ops->trigger_start = dpu_hw_ctl_trigger_start;
ops->trigger_pending = dpu_hw_ctl_trigger_pending; ops->trigger_pending = dpu_hw_ctl_trigger_pending;
ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg;
ops->reset = dpu_hw_ctl_reset_control; ops->reset = dpu_hw_ctl_reset_control;
ops->wait_reset_status = dpu_hw_ctl_wait_reset_status; ops->wait_reset_status = dpu_hw_ctl_wait_reset_status;
ops->clear_all_blendstages = dpu_hw_ctl_clear_all_blendstages; ops->clear_all_blendstages = dpu_hw_ctl_clear_all_blendstages;
ops->setup_blendstage = dpu_hw_ctl_setup_blendstage; ops->setup_blendstage = dpu_hw_ctl_setup_blendstage;
ops->get_bitmask_sspp = dpu_hw_ctl_get_bitmask_sspp; ops->get_bitmask_sspp = dpu_hw_ctl_get_bitmask_sspp;
ops->get_bitmask_mixer = dpu_hw_ctl_get_bitmask_mixer; ops->get_bitmask_mixer = dpu_hw_ctl_get_bitmask_mixer;
ops->get_bitmask_intf = dpu_hw_ctl_get_bitmask_intf;
}; };
static struct dpu_hw_blk_ops dpu_hw_ops; static struct dpu_hw_blk_ops dpu_hw_ops;
......
...@@ -90,6 +90,15 @@ struct dpu_hw_ctl_ops { ...@@ -90,6 +90,15 @@ struct dpu_hw_ctl_ops {
void (*update_pending_flush)(struct dpu_hw_ctl *ctx, void (*update_pending_flush)(struct dpu_hw_ctl *ctx,
u32 flushbits); u32 flushbits);
/**
* OR in the given flushbits to the cached pending_intf_flush_mask
* No effect on hardware
* @ctx : ctl path ctx pointer
* @flushbits : module flushmask
*/
void (*update_pending_intf_flush)(struct dpu_hw_ctl *ctx,
u32 flushbits);
/** /**
* Write the value of the pending_flush_mask to hardware * Write the value of the pending_flush_mask to hardware
* @ctx : ctl path ctx pointer * @ctx : ctl path ctx pointer
...@@ -130,10 +139,23 @@ struct dpu_hw_ctl_ops { ...@@ -130,10 +139,23 @@ struct dpu_hw_ctl_ops {
uint32_t (*get_bitmask_mixer)(struct dpu_hw_ctl *ctx, uint32_t (*get_bitmask_mixer)(struct dpu_hw_ctl *ctx,
enum dpu_lm blk); enum dpu_lm blk);
/**
* Query the value of the intf flush mask
* No effect on hardware
* @ctx : ctl path ctx pointer
*/
int (*get_bitmask_intf)(struct dpu_hw_ctl *ctx, int (*get_bitmask_intf)(struct dpu_hw_ctl *ctx,
u32 *flushbits, u32 *flushbits,
enum dpu_intf blk); enum dpu_intf blk);
/**
* Query the value of the intf active flush mask
* No effect on hardware
* @ctx : ctl path ctx pointer
*/
int (*get_bitmask_active_intf)(struct dpu_hw_ctl *ctx,
u32 *flushbits, enum dpu_intf blk);
/** /**
* Set all blend stages to disabled * Set all blend stages to disabled
* @ctx : ctl path ctx pointer * @ctx : ctl path ctx pointer
...@@ -159,6 +181,7 @@ struct dpu_hw_ctl_ops { ...@@ -159,6 +181,7 @@ struct dpu_hw_ctl_ops {
* @mixer_count: number of mixers * @mixer_count: number of mixers
* @mixer_hw_caps: mixer hardware capabilities * @mixer_hw_caps: mixer hardware capabilities
* @pending_flush_mask: storage for pending ctl_flush managed via ops * @pending_flush_mask: storage for pending ctl_flush managed via ops
* @pending_intf_flush_mask: pending INTF flush
* @ops: operation list * @ops: operation list
*/ */
struct dpu_hw_ctl { struct dpu_hw_ctl {
...@@ -171,6 +194,7 @@ struct dpu_hw_ctl { ...@@ -171,6 +194,7 @@ struct dpu_hw_ctl {
int mixer_count; int mixer_count;
const struct dpu_lm_cfg *mixer_hw_caps; const struct dpu_lm_cfg *mixer_hw_caps;
u32 pending_flush_mask; u32 pending_flush_mask;
u32 pending_intf_flush_mask;
/* ops */ /* ops */
struct dpu_hw_ctl_ops ops; struct dpu_hw_ctl_ops ops;
......
...@@ -56,6 +56,8 @@ ...@@ -56,6 +56,8 @@
#define INTF_FRAME_COUNT 0x0AC #define INTF_FRAME_COUNT 0x0AC
#define INTF_LINE_COUNT 0x0B0 #define INTF_LINE_COUNT 0x0B0
#define INTF_MUX 0x25C
static const struct dpu_intf_cfg *_intf_offset(enum dpu_intf intf, static const struct dpu_intf_cfg *_intf_offset(enum dpu_intf intf,
const struct dpu_mdss_cfg *m, const struct dpu_mdss_cfg *m,
void __iomem *addr, void __iomem *addr,
...@@ -218,6 +220,30 @@ static void dpu_hw_intf_setup_prg_fetch( ...@@ -218,6 +220,30 @@ static void dpu_hw_intf_setup_prg_fetch(
DPU_REG_WRITE(c, INTF_CONFIG, fetch_enable); DPU_REG_WRITE(c, INTF_CONFIG, fetch_enable);
} }
static void dpu_hw_intf_bind_pingpong_blk(
struct dpu_hw_intf *intf,
bool enable,
const enum dpu_pingpong pp)
{
struct dpu_hw_blk_reg_map *c;
u32 mux_cfg;
if (!intf)
return;
c = &intf->hw;
mux_cfg = DPU_REG_READ(c, INTF_MUX);
mux_cfg &= ~0xf;
if (enable)
mux_cfg |= (pp - PINGPONG_0) & 0x7;
else
mux_cfg |= 0xf;
DPU_REG_WRITE(c, INTF_MUX, mux_cfg);
}
static void dpu_hw_intf_get_status( static void dpu_hw_intf_get_status(
struct dpu_hw_intf *intf, struct dpu_hw_intf *intf,
struct intf_status *s) struct intf_status *s)
...@@ -254,6 +280,8 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, ...@@ -254,6 +280,8 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops,
ops->get_status = dpu_hw_intf_get_status; ops->get_status = dpu_hw_intf_get_status;
ops->enable_timing = dpu_hw_intf_enable_timing_engine; ops->enable_timing = dpu_hw_intf_enable_timing_engine;
ops->get_line_count = dpu_hw_intf_get_line_count; ops->get_line_count = dpu_hw_intf_get_line_count;
if (cap & BIT(DPU_CTL_ACTIVE_CFG))
ops->bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk;
} }
static struct dpu_hw_blk_ops dpu_hw_ops; static struct dpu_hw_blk_ops dpu_hw_ops;
......
...@@ -52,6 +52,8 @@ struct intf_status { ...@@ -52,6 +52,8 @@ struct intf_status {
* @ enable_timing: enable/disable timing engine * @ enable_timing: enable/disable timing engine
* @ get_status: returns if timing engine is enabled or not * @ get_status: returns if timing engine is enabled or not
* @ get_line_count: reads current vertical line counter * @ get_line_count: reads current vertical line counter
* @bind_pingpong_blk: enable/disable the connection with pingpong which will
* feed pixels to this interface
*/ */
struct dpu_hw_intf_ops { struct dpu_hw_intf_ops {
void (*setup_timing_gen)(struct dpu_hw_intf *intf, void (*setup_timing_gen)(struct dpu_hw_intf *intf,
...@@ -68,6 +70,10 @@ struct dpu_hw_intf_ops { ...@@ -68,6 +70,10 @@ struct dpu_hw_intf_ops {
struct intf_status *status); struct intf_status *status);
u32 (*get_line_count)(struct dpu_hw_intf *intf); u32 (*get_line_count)(struct dpu_hw_intf *intf);
void (*bind_pingpong_blk)(struct dpu_hw_intf *intf,
bool enable,
const enum dpu_pingpong pp);
}; };
struct dpu_hw_intf { struct dpu_hw_intf {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment