Skip to content

Commit 45d1a2b

Browse files
NasChungHans Verkuil
authored and
Hans Verkuil
committed
media: chips-media: wave5: Add vpuapi layer
Add the vpuapi layer of the wave5 codec driver. This layer is used to configure the hardware according to the parameters. Signed-off-by: Sebastian Fricke <[email protected]> Signed-off-by: Nicolas Dufresne <[email protected]> Signed-off-by: Dafna Hirschfeld <[email protected]> Signed-off-by: Robert Beckett <[email protected]> Signed-off-by: Nas Chung <[email protected]> Signed-off-by: Hans Verkuil <[email protected]>
1 parent 02a8b42 commit 45d1a2b

File tree

9 files changed

+5839
-0
lines changed

9 files changed

+5839
-0
lines changed

drivers/media/platform/chips-media/wave5/wave5-hw.c

+2,554
Large diffs are not rendered by default.

drivers/media/platform/chips-media/wave5/wave5-regdefine.h

+732
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
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+
vpu_dev->common_mem.size = SIZE_COMMON;
22+
ret = wave5_vdi_allocate_dma_memory(vpu_dev, &vpu_dev->common_mem);
23+
if (ret) {
24+
dev_err(dev, "unable to allocate common buffer\n");
25+
return ret;
26+
}
27+
}
28+
29+
dev_dbg(dev, "[VDI] common_mem: daddr=%pad size=%zu vaddr=0x%p\n",
30+
&vpu_dev->common_mem.daddr, vpu_dev->common_mem.size, vpu_dev->common_mem.vaddr);
31+
32+
return 0;
33+
}
34+
35+
int wave5_vdi_init(struct device *dev)
36+
{
37+
struct vpu_device *vpu_dev = dev_get_drvdata(dev);
38+
int ret;
39+
40+
ret = wave5_vdi_allocate_common_memory(dev);
41+
if (ret < 0) {
42+
dev_err(dev, "[VDI] failed to get vpu common buffer from driver\n");
43+
return ret;
44+
}
45+
46+
if (!PRODUCT_CODE_W_SERIES(vpu_dev->product_code)) {
47+
WARN_ONCE(1, "unsupported product code: 0x%x\n", vpu_dev->product_code);
48+
return -EOPNOTSUPP;
49+
}
50+
51+
/* if BIT processor is not running. */
52+
if (wave5_vdi_read_register(vpu_dev, W5_VCPU_CUR_PC) == 0) {
53+
int i;
54+
55+
for (i = 0; i < 64; i++)
56+
wave5_vdi_write_register(vpu_dev, (i * 4) + 0x100, 0x0);
57+
}
58+
59+
dev_dbg(dev, "[VDI] driver initialized successfully\n");
60+
61+
return 0;
62+
}
63+
64+
int wave5_vdi_release(struct device *dev)
65+
{
66+
struct vpu_device *vpu_dev = dev_get_drvdata(dev);
67+
68+
vpu_dev->vdb_register = NULL;
69+
wave5_vdi_free_dma_memory(vpu_dev, &vpu_dev->common_mem);
70+
71+
return 0;
72+
}
73+
74+
void wave5_vdi_write_register(struct vpu_device *vpu_dev, u32 addr, u32 data)
75+
{
76+
writel(data, vpu_dev->vdb_register + addr);
77+
}
78+
79+
unsigned int wave5_vdi_read_register(struct vpu_device *vpu_dev, u32 addr)
80+
{
81+
return readl(vpu_dev->vdb_register + addr);
82+
}
83+
84+
int wave5_vdi_clear_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb)
85+
{
86+
if (!vb || !vb->vaddr) {
87+
dev_err(vpu_dev->dev, "%s: unable to clear unmapped buffer\n", __func__);
88+
return -EINVAL;
89+
}
90+
91+
memset(vb->vaddr, 0, vb->size);
92+
return vb->size;
93+
}
94+
95+
int wave5_vdi_write_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb, size_t offset,
96+
u8 *data, size_t len)
97+
{
98+
if (!vb || !vb->vaddr) {
99+
dev_err(vpu_dev->dev, "%s: unable to write to unmapped buffer\n", __func__);
100+
return -EINVAL;
101+
}
102+
103+
if (offset > vb->size || len > vb->size || offset + len > vb->size) {
104+
dev_err(vpu_dev->dev, "%s: buffer too small\n", __func__);
105+
return -ENOSPC;
106+
}
107+
108+
memcpy(vb->vaddr + offset, data, len);
109+
110+
return len;
111+
}
112+
113+
int wave5_vdi_allocate_dma_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb)
114+
{
115+
void *vaddr;
116+
dma_addr_t daddr;
117+
118+
if (!vb->size) {
119+
dev_err(vpu_dev->dev, "%s: requested size==0\n", __func__);
120+
return -EINVAL;
121+
}
122+
123+
vaddr = dma_alloc_coherent(vpu_dev->dev, vb->size, &daddr, GFP_KERNEL);
124+
if (!vaddr)
125+
return -ENOMEM;
126+
vb->vaddr = vaddr;
127+
vb->daddr = daddr;
128+
129+
return 0;
130+
}
131+
132+
int wave5_vdi_free_dma_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb)
133+
{
134+
if (vb->size == 0)
135+
return -EINVAL;
136+
137+
if (!vb->vaddr)
138+
dev_err(vpu_dev->dev, "%s: requested free of unmapped buffer\n", __func__);
139+
else
140+
dma_free_coherent(vpu_dev->dev, vb->size, vb->vaddr, vb->daddr);
141+
142+
memset(vb, 0, sizeof(*vb));
143+
144+
return 0;
145+
}
146+
147+
int wave5_vdi_allocate_array(struct vpu_device *vpu_dev, struct vpu_buf *array, unsigned int count,
148+
size_t size)
149+
{
150+
struct vpu_buf vb_buf;
151+
int i, ret = 0;
152+
153+
vb_buf.size = size;
154+
155+
for (i = 0; i < count; i++) {
156+
if (array[i].size == size)
157+
continue;
158+
159+
if (array[i].size != 0)
160+
wave5_vdi_free_dma_memory(vpu_dev, &array[i]);
161+
162+
ret = wave5_vdi_allocate_dma_memory(vpu_dev, &vb_buf);
163+
if (ret)
164+
return -ENOMEM;
165+
array[i] = vb_buf;
166+
}
167+
168+
for (i = count; i < MAX_REG_FRAME; i++)
169+
wave5_vdi_free_dma_memory(vpu_dev, &array[i]);
170+
171+
return 0;
172+
}
173+
174+
void wave5_vdi_allocate_sram(struct vpu_device *vpu_dev)
175+
{
176+
struct vpu_buf *vb = &vpu_dev->sram_buf;
177+
178+
if (!vpu_dev->sram_pool || !vpu_dev->sram_size)
179+
return;
180+
181+
if (!vb->vaddr) {
182+
vb->size = vpu_dev->sram_size;
183+
vb->vaddr = gen_pool_dma_alloc(vpu_dev->sram_pool, vb->size,
184+
&vb->daddr);
185+
if (!vb->vaddr)
186+
vb->size = 0;
187+
}
188+
189+
dev_dbg(vpu_dev->dev, "%s: sram daddr: %pad, size: %zu, vaddr: 0x%p\n",
190+
__func__, &vb->daddr, vb->size, vb->vaddr);
191+
}
192+
193+
void wave5_vdi_free_sram(struct vpu_device *vpu_dev)
194+
{
195+
struct vpu_buf *vb = &vpu_dev->sram_buf;
196+
197+
if (!vb->size || !vb->vaddr)
198+
return;
199+
200+
if (vb->vaddr)
201+
gen_pool_free(vpu_dev->sram_pool, (unsigned long)vb->vaddr,
202+
vb->size);
203+
204+
memset(vb, 0, sizeof(*vb));
205+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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+
#ifndef _VDI_H_
9+
#define _VDI_H_
10+
11+
#include "wave5-vpuconfig.h"
12+
#include <linux/string.h>
13+
#include <linux/slab.h>
14+
#include <linux/device.h>
15+
16+
/************************************************************************/
17+
/* COMMON REGISTERS */
18+
/************************************************************************/
19+
#define VPU_PRODUCT_CODE_REGISTER 0x1044
20+
21+
/* system register write */
22+
#define vpu_write_reg(VPU_INST, ADDR, DATA) wave5_vdi_write_register(VPU_INST, ADDR, DATA)
23+
/* system register read */
24+
#define vpu_read_reg(CORE, ADDR) wave5_vdi_read_register(CORE, ADDR)
25+
26+
struct vpu_buf {
27+
size_t size;
28+
dma_addr_t daddr;
29+
void *vaddr;
30+
};
31+
32+
int wave5_vdi_init(struct device *dev);
33+
int wave5_vdi_release(struct device *dev); //this function may be called only at system off.
34+
35+
#endif //#ifndef _VDI_H_

0 commit comments

Comments
 (0)