1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
6 #include "dpu_hw_catalog.h"
8 #include "dpu_hw_dspp.h"
15 #define PCC_RED_R_OFF 0x10
16 #define PCC_RED_G_OFF 0x1C
17 #define PCC_RED_B_OFF 0x28
18 #define PCC_GREEN_R_OFF 0x14
19 #define PCC_GREEN_G_OFF 0x20
20 #define PCC_GREEN_B_OFF 0x2C
21 #define PCC_BLUE_R_OFF 0x18
22 #define PCC_BLUE_G_OFF 0x24
23 #define PCC_BLUE_B_OFF 0x30
25 static void dpu_setup_dspp_pcc(struct dpu_hw_dspp
*ctx
,
26 struct dpu_hw_pcc_cfg
*cfg
)
29 u32 base
= ctx
->cap
->sblk
->pcc
.base
;
32 DRM_ERROR("invalid ctx %pK pcc base 0x%x\n", ctx
, base
);
37 DRM_DEBUG_DRIVER("disable pcc feature\n");
38 DPU_REG_WRITE(&ctx
->hw
, base
, PCC_DIS
);
42 DPU_REG_WRITE(&ctx
->hw
, base
+ PCC_RED_R_OFF
, cfg
->r
.r
);
43 DPU_REG_WRITE(&ctx
->hw
, base
+ PCC_RED_G_OFF
, cfg
->r
.g
);
44 DPU_REG_WRITE(&ctx
->hw
, base
+ PCC_RED_B_OFF
, cfg
->r
.b
);
46 DPU_REG_WRITE(&ctx
->hw
, base
+ PCC_GREEN_R_OFF
, cfg
->g
.r
);
47 DPU_REG_WRITE(&ctx
->hw
, base
+ PCC_GREEN_G_OFF
, cfg
->g
.g
);
48 DPU_REG_WRITE(&ctx
->hw
, base
+ PCC_GREEN_B_OFF
, cfg
->g
.b
);
50 DPU_REG_WRITE(&ctx
->hw
, base
+ PCC_BLUE_R_OFF
, cfg
->b
.r
);
51 DPU_REG_WRITE(&ctx
->hw
, base
+ PCC_BLUE_G_OFF
, cfg
->b
.g
);
52 DPU_REG_WRITE(&ctx
->hw
, base
+ PCC_BLUE_B_OFF
, cfg
->b
.b
);
54 DPU_REG_WRITE(&ctx
->hw
, base
, PCC_EN
);
57 static void _setup_dspp_ops(struct dpu_hw_dspp
*c
,
58 unsigned long features
)
60 if (test_bit(DPU_DSPP_PCC
, &features
))
61 c
->ops
.setup_pcc
= dpu_setup_dspp_pcc
;
64 static const struct dpu_dspp_cfg
*_dspp_offset(enum dpu_dspp dspp
,
65 const struct dpu_mdss_cfg
*m
,
67 struct dpu_hw_blk_reg_map
*b
)
71 if (!m
|| !addr
|| !b
)
72 return ERR_PTR(-EINVAL
);
74 for (i
= 0; i
< m
->dspp_count
; i
++) {
75 if (dspp
== m
->dspp
[i
].id
) {
77 b
->blk_off
= m
->dspp
[i
].base
;
78 b
->length
= m
->dspp
[i
].len
;
79 b
->hwversion
= m
->hwversion
;
80 b
->log_mask
= DPU_DBG_MASK_DSPP
;
85 return ERR_PTR(-EINVAL
);
88 static struct dpu_hw_blk_ops dpu_hw_ops
;
90 struct dpu_hw_dspp
*dpu_hw_dspp_init(enum dpu_dspp idx
,
92 const struct dpu_mdss_cfg
*m
)
94 struct dpu_hw_dspp
*c
;
95 const struct dpu_dspp_cfg
*cfg
;
98 return ERR_PTR(-EINVAL
);
100 c
= kzalloc(sizeof(*c
), GFP_KERNEL
);
102 return ERR_PTR(-ENOMEM
);
104 cfg
= _dspp_offset(idx
, m
, addr
, &c
->hw
);
105 if (IS_ERR_OR_NULL(cfg
)) {
107 return ERR_PTR(-EINVAL
);
113 _setup_dspp_ops(c
, c
->cap
->features
);
115 dpu_hw_blk_init(&c
->base
, DPU_HW_BLK_DSPP
, idx
, &dpu_hw_ops
);
120 void dpu_hw_dspp_destroy(struct dpu_hw_dspp
*dspp
)
123 dpu_hw_blk_destroy(&dspp
->base
);