1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 3 */ 4 5 #include <linux/iopoll.h> 6 7 #include "dpu_hw_mdss.h" 8 #include "dpu_hwio.h" 9 #include "dpu_hw_catalog.h" 10 #include "dpu_hw_merge3d.h" 11 #include "dpu_kms.h" 12 #include "dpu_trace.h" 13 14 #define MERGE_3D_MUX 0x000 15 #define MERGE_3D_MODE 0x004 16 17 static const struct dpu_merge_3d_cfg *_merge_3d_offset(enum dpu_merge_3d idx, 18 const struct dpu_mdss_cfg *m, 19 void __iomem *addr, 20 struct dpu_hw_blk_reg_map *b) 21 { 22 int i; 23 24 for (i = 0; i < m->merge_3d_count; i++) { 25 if (idx == m->merge_3d[i].id) { 26 b->base_off = addr; 27 b->blk_off = m->merge_3d[i].base; 28 b->length = m->merge_3d[i].len; 29 b->hwversion = m->hwversion; 30 b->log_mask = DPU_DBG_MASK_PINGPONG; 31 return &m->merge_3d[i]; 32 } 33 } 34 35 return ERR_PTR(-EINVAL); 36 } 37 38 static void dpu_hw_merge_3d_setup_3d_mode(struct dpu_hw_merge_3d *merge_3d, 39 enum dpu_3d_blend_mode mode_3d) 40 { 41 struct dpu_hw_blk_reg_map *c; 42 u32 data; 43 44 45 c = &merge_3d->hw; 46 if (mode_3d == BLEND_3D_NONE) { 47 DPU_REG_WRITE(c, MERGE_3D_MODE, 0); 48 DPU_REG_WRITE(c, MERGE_3D_MUX, 0); 49 } else { 50 data = BIT(0) | ((mode_3d - 1) << 1); 51 DPU_REG_WRITE(c, MERGE_3D_MODE, data); 52 } 53 } 54 55 static void _setup_merge_3d_ops(struct dpu_hw_merge_3d *c, 56 unsigned long features) 57 { 58 c->ops.setup_3d_mode = dpu_hw_merge_3d_setup_3d_mode; 59 }; 60 61 static struct dpu_hw_blk_ops dpu_hw_ops; 62 63 struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(enum dpu_merge_3d idx, 64 void __iomem *addr, 65 const struct dpu_mdss_cfg *m) 66 { 67 struct dpu_hw_merge_3d *c; 68 const struct dpu_merge_3d_cfg *cfg; 69 70 c = kzalloc(sizeof(*c), GFP_KERNEL); 71 if (!c) 72 return ERR_PTR(-ENOMEM); 73 74 cfg = _merge_3d_offset(idx, m, addr, &c->hw); 75 if (IS_ERR_OR_NULL(cfg)) { 76 kfree(c); 77 return ERR_PTR(-EINVAL); 78 } 79 80 c->idx = idx; 81 c->caps = cfg; 82 _setup_merge_3d_ops(c, c->caps->features); 83 84 dpu_hw_blk_init(&c->base, DPU_HW_BLK_MERGE_3D, idx, &dpu_hw_ops); 85 86 return c; 87 } 88 89 void dpu_hw_merge_3d_destroy(struct dpu_hw_merge_3d *hw) 90 { 91 if (hw) 92 dpu_hw_blk_destroy(&hw->base); 93 kfree(hw); 94 } 95