root/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _lm_offset
  2. _stage_offset
  3. dpu_hw_lm_setup_out
  4. dpu_hw_lm_setup_border_color
  5. dpu_hw_lm_setup_blend_config_sdm845
  6. dpu_hw_lm_setup_blend_config
  7. dpu_hw_lm_setup_color3
  8. _setup_mixer_ops
  9. dpu_hw_lm_init
  10. dpu_hw_lm_destroy

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
   3  */
   4 
   5 #include "dpu_kms.h"
   6 #include "dpu_hw_catalog.h"
   7 #include "dpu_hwio.h"
   8 #include "dpu_hw_lm.h"
   9 #include "dpu_hw_mdss.h"
  10 
  11 #define LM_OP_MODE                        0x00
  12 #define LM_OUT_SIZE                       0x04
  13 #define LM_BORDER_COLOR_0                 0x08
  14 #define LM_BORDER_COLOR_1                 0x010
  15 
  16 /* These register are offset to mixer base + stage base */
  17 #define LM_BLEND0_OP                     0x00
  18 #define LM_BLEND0_CONST_ALPHA            0x04
  19 #define LM_FG_COLOR_FILL_COLOR_0         0x08
  20 #define LM_FG_COLOR_FILL_COLOR_1         0x0C
  21 #define LM_FG_COLOR_FILL_SIZE            0x10
  22 #define LM_FG_COLOR_FILL_XY              0x14
  23 
  24 #define LM_BLEND0_FG_ALPHA               0x04
  25 #define LM_BLEND0_BG_ALPHA               0x08
  26 
  27 static struct dpu_lm_cfg *_lm_offset(enum dpu_lm mixer,
  28                 struct dpu_mdss_cfg *m,
  29                 void __iomem *addr,
  30                 struct dpu_hw_blk_reg_map *b)
  31 {
  32         int i;
  33 
  34         for (i = 0; i < m->mixer_count; i++) {
  35                 if (mixer == m->mixer[i].id) {
  36                         b->base_off = addr;
  37                         b->blk_off = m->mixer[i].base;
  38                         b->length = m->mixer[i].len;
  39                         b->hwversion = m->hwversion;
  40                         b->log_mask = DPU_DBG_MASK_LM;
  41                         return &m->mixer[i];
  42                 }
  43         }
  44 
  45         return ERR_PTR(-ENOMEM);
  46 }
  47 
  48 /**
  49  * _stage_offset(): returns the relative offset of the blend registers
  50  * for the stage to be setup
  51  * @c:     mixer ctx contains the mixer to be programmed
  52  * @stage: stage index to setup
  53  */
  54 static inline int _stage_offset(struct dpu_hw_mixer *ctx, enum dpu_stage stage)
  55 {
  56         const struct dpu_lm_sub_blks *sblk = ctx->cap->sblk;
  57         if (stage != DPU_STAGE_BASE && stage <= sblk->maxblendstages)
  58                 return sblk->blendstage_base[stage - DPU_STAGE_0];
  59 
  60         return -EINVAL;
  61 }
  62 
  63 static void dpu_hw_lm_setup_out(struct dpu_hw_mixer *ctx,
  64                 struct dpu_hw_mixer_cfg *mixer)
  65 {
  66         struct dpu_hw_blk_reg_map *c = &ctx->hw;
  67         u32 outsize;
  68         u32 op_mode;
  69 
  70         op_mode = DPU_REG_READ(c, LM_OP_MODE);
  71 
  72         outsize = mixer->out_height << 16 | mixer->out_width;
  73         DPU_REG_WRITE(c, LM_OUT_SIZE, outsize);
  74 
  75         /* SPLIT_LEFT_RIGHT */
  76         if (mixer->right_mixer)
  77                 op_mode |= BIT(31);
  78         else
  79                 op_mode &= ~BIT(31);
  80         DPU_REG_WRITE(c, LM_OP_MODE, op_mode);
  81 }
  82 
  83 static void dpu_hw_lm_setup_border_color(struct dpu_hw_mixer *ctx,
  84                 struct dpu_mdss_color *color,
  85                 u8 border_en)
  86 {
  87         struct dpu_hw_blk_reg_map *c = &ctx->hw;
  88 
  89         if (border_en) {
  90                 DPU_REG_WRITE(c, LM_BORDER_COLOR_0,
  91                         (color->color_0 & 0xFFF) |
  92                         ((color->color_1 & 0xFFF) << 0x10));
  93                 DPU_REG_WRITE(c, LM_BORDER_COLOR_1,
  94                         (color->color_2 & 0xFFF) |
  95                         ((color->color_3 & 0xFFF) << 0x10));
  96         }
  97 }
  98 
  99 static void dpu_hw_lm_setup_blend_config_sdm845(struct dpu_hw_mixer *ctx,
 100         u32 stage, u32 fg_alpha, u32 bg_alpha, u32 blend_op)
 101 {
 102         struct dpu_hw_blk_reg_map *c = &ctx->hw;
 103         int stage_off;
 104         u32 const_alpha;
 105 
 106         if (stage == DPU_STAGE_BASE)
 107                 return;
 108 
 109         stage_off = _stage_offset(ctx, stage);
 110         if (WARN_ON(stage_off < 0))
 111                 return;
 112 
 113         const_alpha = (bg_alpha & 0xFF) | ((fg_alpha & 0xFF) << 16);
 114         DPU_REG_WRITE(c, LM_BLEND0_CONST_ALPHA + stage_off, const_alpha);
 115         DPU_REG_WRITE(c, LM_BLEND0_OP + stage_off, blend_op);
 116 }
 117 
 118 static void dpu_hw_lm_setup_blend_config(struct dpu_hw_mixer *ctx,
 119         u32 stage, u32 fg_alpha, u32 bg_alpha, u32 blend_op)
 120 {
 121         struct dpu_hw_blk_reg_map *c = &ctx->hw;
 122         int stage_off;
 123 
 124         if (stage == DPU_STAGE_BASE)
 125                 return;
 126 
 127         stage_off = _stage_offset(ctx, stage);
 128         if (WARN_ON(stage_off < 0))
 129                 return;
 130 
 131         DPU_REG_WRITE(c, LM_BLEND0_FG_ALPHA + stage_off, fg_alpha);
 132         DPU_REG_WRITE(c, LM_BLEND0_BG_ALPHA + stage_off, bg_alpha);
 133         DPU_REG_WRITE(c, LM_BLEND0_OP + stage_off, blend_op);
 134 }
 135 
 136 static void dpu_hw_lm_setup_color3(struct dpu_hw_mixer *ctx,
 137         uint32_t mixer_op_mode)
 138 {
 139         struct dpu_hw_blk_reg_map *c = &ctx->hw;
 140         int op_mode;
 141 
 142         /* read the existing op_mode configuration */
 143         op_mode = DPU_REG_READ(c, LM_OP_MODE);
 144 
 145         op_mode = (op_mode & (BIT(31) | BIT(30))) | mixer_op_mode;
 146 
 147         DPU_REG_WRITE(c, LM_OP_MODE, op_mode);
 148 }
 149 
 150 static void _setup_mixer_ops(struct dpu_mdss_cfg *m,
 151                 struct dpu_hw_lm_ops *ops,
 152                 unsigned long features)
 153 {
 154         ops->setup_mixer_out = dpu_hw_lm_setup_out;
 155         if (IS_SDM845_TARGET(m->hwversion) || IS_SDM670_TARGET(m->hwversion))
 156                 ops->setup_blend_config = dpu_hw_lm_setup_blend_config_sdm845;
 157         else
 158                 ops->setup_blend_config = dpu_hw_lm_setup_blend_config;
 159         ops->setup_alpha_out = dpu_hw_lm_setup_color3;
 160         ops->setup_border_color = dpu_hw_lm_setup_border_color;
 161 };
 162 
 163 static struct dpu_hw_blk_ops dpu_hw_ops;
 164 
 165 struct dpu_hw_mixer *dpu_hw_lm_init(enum dpu_lm idx,
 166                 void __iomem *addr,
 167                 struct dpu_mdss_cfg *m)
 168 {
 169         struct dpu_hw_mixer *c;
 170         struct dpu_lm_cfg *cfg;
 171 
 172         c = kzalloc(sizeof(*c), GFP_KERNEL);
 173         if (!c)
 174                 return ERR_PTR(-ENOMEM);
 175 
 176         cfg = _lm_offset(idx, m, addr, &c->hw);
 177         if (IS_ERR_OR_NULL(cfg)) {
 178                 kfree(c);
 179                 return ERR_PTR(-EINVAL);
 180         }
 181 
 182         /* Assign ops */
 183         c->idx = idx;
 184         c->cap = cfg;
 185         _setup_mixer_ops(m, &c->ops, c->cap->features);
 186 
 187         dpu_hw_blk_init(&c->base, DPU_HW_BLK_LM, idx, &dpu_hw_ops);
 188 
 189         return c;
 190 }
 191 
 192 void dpu_hw_lm_destroy(struct dpu_hw_mixer *lm)
 193 {
 194         if (lm)
 195                 dpu_hw_blk_destroy(&lm->base);
 196         kfree(lm);
 197 }

/* [<][>][^][v][top][bottom][index][help] */