Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Jeykumar Sankaran | 1010 | 95.19% | 1 | 14.29% |
Marijn Suijten | 21 | 1.98% | 1 | 14.29% |
Angelo G. Del Regno | 12 | 1.13% | 1 | 14.29% |
Dmitry Eremin-Solenikov | 9 | 0.85% | 2 | 28.57% |
Rob Clark | 7 | 0.66% | 1 | 14.29% |
Thomas Gleixner | 2 | 0.19% | 1 | 14.29% |
Total | 1061 | 7 |
// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #include <drm/drm_managed.h> #include "dpu_hwio.h" #include "dpu_hw_catalog.h" #include "dpu_hw_vbif.h" #define VBIF_VERSION 0x0000 #define VBIF_CLK_FORCE_CTRL0 0x0008 #define VBIF_CLK_FORCE_CTRL1 0x000C #define VBIF_QOS_REMAP_00 0x0020 #define VBIF_QOS_REMAP_01 0x0024 #define VBIF_QOS_REMAP_10 0x0028 #define VBIF_QOS_REMAP_11 0x002C #define VBIF_WRITE_GATHER_EN 0x00AC #define VBIF_IN_RD_LIM_CONF0 0x00B0 #define VBIF_IN_RD_LIM_CONF1 0x00B4 #define VBIF_IN_RD_LIM_CONF2 0x00B8 #define VBIF_IN_WR_LIM_CONF0 0x00C0 #define VBIF_IN_WR_LIM_CONF1 0x00C4 #define VBIF_IN_WR_LIM_CONF2 0x00C8 #define VBIF_OUT_RD_LIM_CONF0 0x00D0 #define VBIF_OUT_WR_LIM_CONF0 0x00D4 #define VBIF_OUT_AXI_AMEMTYPE_CONF0 0x0160 #define VBIF_OUT_AXI_AMEMTYPE_CONF1 0x0164 #define VBIF_XIN_PND_ERR 0x0190 #define VBIF_XIN_SRC_ERR 0x0194 #define VBIF_XIN_CLR_ERR 0x019C #define VBIF_XIN_HALT_CTRL0 0x0200 #define VBIF_XIN_HALT_CTRL1 0x0204 #define VBIF_XINL_QOS_RP_REMAP_000 0x0550 #define VBIF_XINL_QOS_LVL_REMAP_000(vbif) (VBIF_XINL_QOS_RP_REMAP_000 + (vbif)->cap->qos_rp_remap_size) static void dpu_hw_clear_errors(struct dpu_hw_vbif *vbif, u32 *pnd_errors, u32 *src_errors) { struct dpu_hw_blk_reg_map *c; u32 pnd, src; if (!vbif) return; c = &vbif->hw; pnd = DPU_REG_READ(c, VBIF_XIN_PND_ERR); src = DPU_REG_READ(c, VBIF_XIN_SRC_ERR); if (pnd_errors) *pnd_errors = pnd; if (src_errors) *src_errors = src; DPU_REG_WRITE(c, VBIF_XIN_CLR_ERR, pnd | src); } static void dpu_hw_set_mem_type(struct dpu_hw_vbif *vbif, u32 xin_id, u32 value) { struct dpu_hw_blk_reg_map *c; u32 reg_off; u32 bit_off; u32 reg_val; /* * Assume 4 bits per bit field, 8 fields per 32-bit register so * 16 bit fields maximum across two registers */ if (!vbif || xin_id >= MAX_XIN_COUNT || xin_id >= 16) return; c = &vbif->hw; if (xin_id >= 8) { xin_id -= 8; reg_off = VBIF_OUT_AXI_AMEMTYPE_CONF1; } else { reg_off = VBIF_OUT_AXI_AMEMTYPE_CONF0; } bit_off = (xin_id & 0x7) * 4; reg_val = DPU_REG_READ(c, reg_off); reg_val &= ~(0x7 << bit_off); reg_val |= (value & 0x7) << bit_off; DPU_REG_WRITE(c, reg_off, reg_val); } static void dpu_hw_set_limit_conf(struct dpu_hw_vbif *vbif, u32 xin_id, bool rd, u32 limit) { struct dpu_hw_blk_reg_map *c = &vbif->hw; u32 reg_val; u32 reg_off; u32 bit_off; if (rd) reg_off = VBIF_IN_RD_LIM_CONF0; else reg_off = VBIF_IN_WR_LIM_CONF0; reg_off += (xin_id / 4) * 4; bit_off = (xin_id % 4) * 8; reg_val = DPU_REG_READ(c, reg_off); reg_val &= ~(0xFF << bit_off); reg_val |= (limit) << bit_off; DPU_REG_WRITE(c, reg_off, reg_val); } static u32 dpu_hw_get_limit_conf(struct dpu_hw_vbif *vbif, u32 xin_id, bool rd) { struct dpu_hw_blk_reg_map *c = &vbif->hw; u32 reg_val; u32 reg_off; u32 bit_off; u32 limit; if (rd) reg_off = VBIF_IN_RD_LIM_CONF0; else reg_off = VBIF_IN_WR_LIM_CONF0; reg_off += (xin_id / 4) * 4; bit_off = (xin_id % 4) * 8; reg_val = DPU_REG_READ(c, reg_off); limit = (reg_val >> bit_off) & 0xFF; return limit; } static void dpu_hw_set_halt_ctrl(struct dpu_hw_vbif *vbif, u32 xin_id, bool enable) { struct dpu_hw_blk_reg_map *c = &vbif->hw; u32 reg_val; reg_val = DPU_REG_READ(c, VBIF_XIN_HALT_CTRL0); if (enable) reg_val |= BIT(xin_id); else reg_val &= ~BIT(xin_id); DPU_REG_WRITE(c, VBIF_XIN_HALT_CTRL0, reg_val); } static bool dpu_hw_get_halt_ctrl(struct dpu_hw_vbif *vbif, u32 xin_id) { struct dpu_hw_blk_reg_map *c = &vbif->hw; u32 reg_val; reg_val = DPU_REG_READ(c, VBIF_XIN_HALT_CTRL1); return (reg_val & BIT(xin_id)) ? true : false; } static void dpu_hw_set_qos_remap(struct dpu_hw_vbif *vbif, u32 xin_id, u32 level, u32 remap_level) { struct dpu_hw_blk_reg_map *c; u32 reg_lvl, reg_val, reg_val_lvl, mask, reg_high, reg_shift; if (!vbif) return; c = &vbif->hw; reg_lvl = VBIF_XINL_QOS_LVL_REMAP_000(vbif); reg_high = ((xin_id & 0x8) >> 3) * 4 + (level * 8); reg_shift = (xin_id & 0x7) * 4; reg_val = DPU_REG_READ(c, VBIF_XINL_QOS_RP_REMAP_000 + reg_high); reg_val_lvl = DPU_REG_READ(c, reg_lvl + reg_high); mask = 0x7 << reg_shift; reg_val &= ~mask; reg_val |= (remap_level << reg_shift) & mask; reg_val_lvl &= ~mask; reg_val_lvl |= (remap_level << reg_shift) & mask; DPU_REG_WRITE(c, VBIF_XINL_QOS_RP_REMAP_000 + reg_high, reg_val); DPU_REG_WRITE(c, reg_lvl + reg_high, reg_val_lvl); } static void dpu_hw_set_write_gather_en(struct dpu_hw_vbif *vbif, u32 xin_id) { struct dpu_hw_blk_reg_map *c; u32 reg_val; if (!vbif || xin_id >= MAX_XIN_COUNT) return; c = &vbif->hw; reg_val = DPU_REG_READ(c, VBIF_WRITE_GATHER_EN); reg_val |= BIT(xin_id); DPU_REG_WRITE(c, VBIF_WRITE_GATHER_EN, reg_val); } static void _setup_vbif_ops(struct dpu_hw_vbif_ops *ops, unsigned long cap) { ops->set_limit_conf = dpu_hw_set_limit_conf; ops->get_limit_conf = dpu_hw_get_limit_conf; ops->set_halt_ctrl = dpu_hw_set_halt_ctrl; ops->get_halt_ctrl = dpu_hw_get_halt_ctrl; if (test_bit(DPU_VBIF_QOS_REMAP, &cap)) ops->set_qos_remap = dpu_hw_set_qos_remap; ops->set_mem_type = dpu_hw_set_mem_type; ops->clear_errors = dpu_hw_clear_errors; ops->set_write_gather_en = dpu_hw_set_write_gather_en; } struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev, const struct dpu_vbif_cfg *cfg, void __iomem *addr) { struct dpu_hw_vbif *c; c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); c->hw.blk_addr = addr + cfg->base; c->hw.log_mask = DPU_DBG_MASK_VBIF; /* * Assign ops */ c->idx = cfg->id; c->cap = cfg; _setup_vbif_ops(&c->ops, c->cap->features); /* no need to register sub-range in dpu dbg, dump entire vbif io base */ return c; }
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1