1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 /* 3 * Wave5 series multi-standard codec IP - low level access functions 4 * 5 * Copyright (C) 2021-2023 CHIPS&MEDIA INC 6 */ 7 8 #include <linux/bug.h> 9 #include "wave5-vdi.h" 10 #include "wave5-vpu.h" 11 #include "wave5-regdefine.h" 12 #include <linux/delay.h> 13 14 static int wave5_vdi_allocate_common_memory(struct device *dev) 15 { 16 struct vpu_device *vpu_dev = dev_get_drvdata(dev); 17 18 if (!vpu_dev->common_mem.vaddr) { 19 int ret; 20 21 if (vpu_dev->product_code == WAVE515_CODE) 22 vpu_dev->common_mem.size = WAVE515_SIZE_COMMON; 23 else 24 vpu_dev->common_mem.size = WAVE521_SIZE_COMMON; 25 26 ret = wave5_vdi_allocate_dma_memory(vpu_dev, &vpu_dev->common_mem); 27 if (ret) { 28 dev_err(dev, "unable to allocate common buffer\n"); 29 return ret; 30 } 31 } 32 33 dev_dbg(dev, "[VDI] common_mem: daddr=%pad size=%zu vaddr=0x%p\n", 34 &vpu_dev->common_mem.daddr, vpu_dev->common_mem.size, vpu_dev->common_mem.vaddr); 35 36 return 0; 37 } 38 39 int wave5_vdi_init(struct device *dev) 40 { 41 struct vpu_device *vpu_dev = dev_get_drvdata(dev); 42 int ret; 43 44 ret = wave5_vdi_allocate_common_memory(dev); 45 if (ret < 0) { 46 dev_err(dev, "[VDI] failed to get vpu common buffer from driver\n"); 47 return ret; 48 } 49 50 if (!PRODUCT_CODE_W_SERIES(vpu_dev->product_code)) { 51 WARN_ONCE(1, "unsupported product code: 0x%x\n", vpu_dev->product_code); 52 return -EOPNOTSUPP; 53 } 54 55 /* if BIT processor is not running. */ 56 if (wave5_vdi_read_register(vpu_dev, W5_VCPU_CUR_PC) == 0) { 57 int i; 58 59 for (i = 0; i < 64; i++) 60 wave5_vdi_write_register(vpu_dev, (i * 4) + 0x100, 0x0); 61 } 62 63 dev_dbg(dev, "[VDI] driver initialized successfully\n"); 64 65 return 0; 66 } 67 68 int wave5_vdi_release(struct device *dev) 69 { 70 struct vpu_device *vpu_dev = dev_get_drvdata(dev); 71 72 vpu_dev->vdb_register = NULL; 73 wave5_vdi_free_dma_memory(vpu_dev, &vpu_dev->common_mem); 74 75 return 0; 76 } 77 78 void wave5_vdi_write_register(struct vpu_device *vpu_dev, u32 addr, u32 data) 79 { 80 writel(data, vpu_dev->vdb_register + addr); 81 } 82 83 unsigned int wave5_vdi_read_register(struct vpu_device *vpu_dev, u32 addr) 84 { 85 return readl(vpu_dev->vdb_register + addr); 86 } 87 88 int wave5_vdi_clear_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb) 89 { 90 if (!vb || !vb->vaddr) { 91 dev_err(vpu_dev->dev, "%s: unable to clear unmapped buffer\n", __func__); 92 return -EINVAL; 93 } 94 95 memset(vb->vaddr, 0, vb->size); 96 return vb->size; 97 } 98 99 int wave5_vdi_write_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb, size_t offset, 100 u8 *data, size_t len) 101 { 102 if (!vb || !vb->vaddr) { 103 dev_err(vpu_dev->dev, "%s: unable to write to unmapped buffer\n", __func__); 104 return -EINVAL; 105 } 106 107 if (offset > vb->size || len > vb->size || offset + len > vb->size) { 108 dev_err(vpu_dev->dev, "%s: buffer too small\n", __func__); 109 return -ENOSPC; 110 } 111 112 memcpy(vb->vaddr + offset, data, len); 113 114 return len; 115 } 116 117 int wave5_vdi_allocate_dma_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb) 118 { 119 void *vaddr; 120 dma_addr_t daddr; 121 122 if (!vb->size) { 123 dev_err(vpu_dev->dev, "%s: requested size==0\n", __func__); 124 return -EINVAL; 125 } 126 127 vaddr = dma_alloc_coherent(vpu_dev->dev, vb->size, &daddr, GFP_KERNEL); 128 if (!vaddr) 129 return -ENOMEM; 130 vb->vaddr = vaddr; 131 vb->daddr = daddr; 132 133 return 0; 134 } 135 136 int wave5_vdi_free_dma_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb) 137 { 138 if (vb->size == 0) 139 return -EINVAL; 140 141 if (!vb->vaddr) 142 dev_err(vpu_dev->dev, "%s: requested free of unmapped buffer\n", __func__); 143 else 144 dma_free_coherent(vpu_dev->dev, vb->size, vb->vaddr, vb->daddr); 145 146 memset(vb, 0, sizeof(*vb)); 147 148 return 0; 149 } 150 151 int wave5_vdi_allocate_array(struct vpu_device *vpu_dev, struct vpu_buf *array, unsigned int count, 152 size_t size) 153 { 154 struct vpu_buf vb_buf; 155 int i, ret = 0; 156 157 vb_buf.size = size; 158 159 for (i = 0; i < count; i++) { 160 if (array[i].size == size) 161 continue; 162 163 if (array[i].size != 0) 164 wave5_vdi_free_dma_memory(vpu_dev, &array[i]); 165 166 ret = wave5_vdi_allocate_dma_memory(vpu_dev, &vb_buf); 167 if (ret) 168 return -ENOMEM; 169 array[i] = vb_buf; 170 } 171 172 for (i = count; i < MAX_REG_FRAME; i++) 173 wave5_vdi_free_dma_memory(vpu_dev, &array[i]); 174 175 return 0; 176 } 177 178 void wave5_vdi_allocate_sram(struct vpu_device *vpu_dev) 179 { 180 struct vpu_buf *vb = &vpu_dev->sram_buf; 181 dma_addr_t daddr; 182 void *vaddr; 183 size_t size; 184 185 if (!vpu_dev->sram_pool || vb->vaddr) 186 return; 187 188 size = min_t(size_t, vpu_dev->sram_size, gen_pool_avail(vpu_dev->sram_pool)); 189 vaddr = gen_pool_dma_alloc(vpu_dev->sram_pool, size, &daddr); 190 if (vaddr) { 191 vb->vaddr = vaddr; 192 vb->daddr = daddr; 193 vb->size = size; 194 } 195 196 dev_dbg(vpu_dev->dev, "%s: sram daddr: %pad, size: %zu, vaddr: 0x%p\n", 197 __func__, &vb->daddr, vb->size, vb->vaddr); 198 } 199 200 void wave5_vdi_free_sram(struct vpu_device *vpu_dev) 201 { 202 struct vpu_buf *vb = &vpu_dev->sram_buf; 203 204 if (!vb->size || !vb->vaddr) 205 return; 206 207 gen_pool_free(vpu_dev->sram_pool, (unsigned long)vb->vaddr, vb->size); 208 209 memset(vb, 0, sizeof(*vb)); 210 } 211