1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 3 */ 4 5 #include "dpu_hwio.h" 6 #include "dpu_hw_catalog.h" 7 #include "dpu_hw_lm.h" 8 #include "dpu_hw_dspp.h" 9 #include "dpu_kms.h" 10 11 12 /* DSPP_PCC */ 13 #define PCC_EN BIT(0) 14 #define PCC_DIS 0 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 24 25 static void dpu_setup_dspp_pcc(struct dpu_hw_dspp *ctx, 26 struct dpu_hw_pcc_cfg *cfg) 27 { 28 29 u32 base; 30 31 if (!ctx) { 32 DRM_ERROR("invalid ctx %pK\n", ctx); 33 return; 34 } 35 36 base = ctx->cap->sblk->pcc.base; 37 38 if (!base) { 39 DRM_ERROR("invalid ctx %pK pcc base 0x%x\n", ctx, base); 40 return; 41 } 42 43 if (!cfg) { 44 DRM_DEBUG_DRIVER("disable pcc feature\n"); 45 DPU_REG_WRITE(&ctx->hw, base, PCC_DIS); 46 return; 47 } 48 49 DPU_REG_WRITE(&ctx->hw, base + PCC_RED_R_OFF, cfg->r.r); 50 DPU_REG_WRITE(&ctx->hw, base + PCC_RED_G_OFF, cfg->r.g); 51 DPU_REG_WRITE(&ctx->hw, base + PCC_RED_B_OFF, cfg->r.b); 52 53 DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_R_OFF, cfg->g.r); 54 DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_G_OFF, cfg->g.g); 55 DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_B_OFF, cfg->g.b); 56 57 DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_R_OFF, cfg->b.r); 58 DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_G_OFF, cfg->b.g); 59 DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_B_OFF, cfg->b.b); 60 61 DPU_REG_WRITE(&ctx->hw, base, PCC_EN); 62 } 63 64 static void _setup_dspp_ops(struct dpu_hw_dspp *c, 65 unsigned long features) 66 { 67 if (test_bit(DPU_DSPP_PCC, &features)) 68 c->ops.setup_pcc = dpu_setup_dspp_pcc; 69 } 70 71 struct dpu_hw_dspp *dpu_hw_dspp_init(const struct dpu_dspp_cfg *cfg, 72 void __iomem *addr) 73 { 74 struct dpu_hw_dspp *c; 75 76 if (!addr) 77 return ERR_PTR(-EINVAL); 78 79 c = kzalloc(sizeof(*c), GFP_KERNEL); 80 if (!c) 81 return ERR_PTR(-ENOMEM); 82 83 c->hw.blk_addr = addr + cfg->base; 84 c->hw.log_mask = DPU_DBG_MASK_DSPP; 85 86 /* Assign ops */ 87 c->idx = cfg->id; 88 c->cap = cfg; 89 _setup_dspp_ops(c, c->cap->features); 90 91 return c; 92 } 93 94 void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp) 95 { 96 kfree(dspp); 97 } 98 99 100