Skip to content

Commit 7b49235

Browse files
Laurent Pinchartmchehab
authored andcommitted
[media] v4l: Add Renesas R-Car FCP driver
The FCP is a companion module of video processing modules in the Renesas R-Car Gen3 SoCs. It provides data compression and decompression, data caching, and conversion of AXI transactions in order to reduce the memory bandwidth. The driver is not meant to be used standalone but provides an API to the video processing modules to control the FCP. Signed-off-by: Laurent Pinchart <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent 60135db commit 7b49235

File tree

5 files changed

+242
-0
lines changed

5 files changed

+242
-0
lines changed

MAINTAINERS

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7312,6 +7312,16 @@ L: [email protected]
73127312
S: Maintained
73137313
F: drivers/iio/potentiometer/mcp4531.c
73147314

7315+
MEDIA DRIVERS FOR RENESAS - FCP
7316+
M: Laurent Pinchart <[email protected]>
7317+
7318+
7319+
T: git git://linuxtv.org/media_tree.git
7320+
S: Supported
7321+
F: Documentation/devicetree/bindings/media/renesas,fcp.txt
7322+
F: drivers/media/platform/rcar-fcp.c
7323+
F: include/media/rcar-fcp.h
7324+
73157325
MEDIA DRIVERS FOR RENESAS - VSP1
73167326
M: Laurent Pinchart <[email protected]>
73177327

drivers/media/platform/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,19 @@ config VIDEO_RENESAS_JPU
248248
To compile this driver as a module, choose M here: the module
249249
will be called rcar_jpu.
250250

251+
config VIDEO_RENESAS_FCP
252+
tristate "Renesas Frame Compression Processor"
253+
depends on ARCH_RENESAS || COMPILE_TEST
254+
depends on OF
255+
---help---
256+
This is a driver for the Renesas Frame Compression Processor (FCP).
257+
The FCP is a companion module of video processing modules in the
258+
Renesas R-Car Gen3 SoCs. It handles memory access for the codec,
259+
VSP and FDP modules.
260+
261+
To compile this driver as a module, choose M here: the module
262+
will be called rcar-fcp.
263+
251264
config VIDEO_RENESAS_VSP1
252265
tristate "Renesas VSP1 Video Processing Engine"
253266
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA

drivers/media/platform/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o
4646

4747
obj-$(CONFIG_SOC_CAMERA) += soc_camera/
4848

49+
obj-$(CONFIG_VIDEO_RENESAS_FCP) += rcar-fcp.o
4950
obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o
5051
obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/
5152

drivers/media/platform/rcar-fcp.c

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/*
2+
* rcar-fcp.c -- R-Car Frame Compression Processor Driver
3+
*
4+
* Copyright (C) 2016 Renesas Electronics Corporation
5+
*
6+
* Contact: Laurent Pinchart ([email protected])
7+
*
8+
* This program is free software; you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation; either version 2 of the License, or
11+
* (at your option) any later version.
12+
*/
13+
14+
#include <linux/device.h>
15+
#include <linux/list.h>
16+
#include <linux/module.h>
17+
#include <linux/mutex.h>
18+
#include <linux/platform_device.h>
19+
#include <linux/pm_runtime.h>
20+
#include <linux/slab.h>
21+
22+
#include <media/rcar-fcp.h>
23+
24+
struct rcar_fcp_device {
25+
struct list_head list;
26+
struct device *dev;
27+
};
28+
29+
static LIST_HEAD(fcp_devices);
30+
static DEFINE_MUTEX(fcp_lock);
31+
32+
/* -----------------------------------------------------------------------------
33+
* Public API
34+
*/
35+
36+
/**
37+
* rcar_fcp_get - Find and acquire a reference to an FCP instance
38+
* @np: Device node of the FCP instance
39+
*
40+
* Search the list of registered FCP instances for the instance corresponding to
41+
* the given device node.
42+
*
43+
* Return a pointer to the FCP instance, or an ERR_PTR if the instance can't be
44+
* found.
45+
*/
46+
struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
47+
{
48+
struct rcar_fcp_device *fcp;
49+
50+
mutex_lock(&fcp_lock);
51+
52+
list_for_each_entry(fcp, &fcp_devices, list) {
53+
if (fcp->dev->of_node != np)
54+
continue;
55+
56+
/*
57+
* Make sure the module won't be unloaded behind our back. This
58+
* is a poor man's safety net, the module should really not be
59+
* unloaded while FCP users can be active.
60+
*/
61+
if (!try_module_get(fcp->dev->driver->owner))
62+
fcp = NULL;
63+
64+
goto done;
65+
}
66+
67+
fcp = ERR_PTR(-EPROBE_DEFER);
68+
69+
done:
70+
mutex_unlock(&fcp_lock);
71+
return fcp;
72+
}
73+
EXPORT_SYMBOL_GPL(rcar_fcp_get);
74+
75+
/**
76+
* rcar_fcp_put - Release a reference to an FCP instance
77+
* @fcp: The FCP instance
78+
*
79+
* Release the FCP instance acquired by a call to rcar_fcp_get().
80+
*/
81+
void rcar_fcp_put(struct rcar_fcp_device *fcp)
82+
{
83+
if (fcp)
84+
module_put(fcp->dev->driver->owner);
85+
}
86+
EXPORT_SYMBOL_GPL(rcar_fcp_put);
87+
88+
/**
89+
* rcar_fcp_enable - Enable an FCP
90+
* @fcp: The FCP instance
91+
*
92+
* Before any memory access through an FCP is performed by a module, the FCP
93+
* must be enabled by a call to this function. The enable calls are reference
94+
* counted, each successful call must be followed by one rcar_fcp_disable()
95+
* call when no more memory transfer can occur through the FCP.
96+
*
97+
* Return 0 on success or a negative error code if an error occurs. The enable
98+
* reference count isn't increased when this function returns an error.
99+
*/
100+
int rcar_fcp_enable(struct rcar_fcp_device *fcp)
101+
{
102+
if (!fcp)
103+
return 0;
104+
105+
return pm_runtime_get_sync(fcp->dev);
106+
}
107+
EXPORT_SYMBOL_GPL(rcar_fcp_enable);
108+
109+
/**
110+
* rcar_fcp_disable - Disable an FCP
111+
* @fcp: The FCP instance
112+
*
113+
* This function is the counterpart of rcar_fcp_enable(). As enable calls are
114+
* reference counted a disable call may not disable the FCP synchronously.
115+
*/
116+
void rcar_fcp_disable(struct rcar_fcp_device *fcp)
117+
{
118+
if (fcp)
119+
pm_runtime_put(fcp->dev);
120+
}
121+
EXPORT_SYMBOL_GPL(rcar_fcp_disable);
122+
123+
/* -----------------------------------------------------------------------------
124+
* Platform Driver
125+
*/
126+
127+
static int rcar_fcp_probe(struct platform_device *pdev)
128+
{
129+
struct rcar_fcp_device *fcp;
130+
131+
fcp = devm_kzalloc(&pdev->dev, sizeof(*fcp), GFP_KERNEL);
132+
if (fcp == NULL)
133+
return -ENOMEM;
134+
135+
fcp->dev = &pdev->dev;
136+
137+
pm_runtime_enable(&pdev->dev);
138+
139+
mutex_lock(&fcp_lock);
140+
list_add_tail(&fcp->list, &fcp_devices);
141+
mutex_unlock(&fcp_lock);
142+
143+
platform_set_drvdata(pdev, fcp);
144+
145+
return 0;
146+
}
147+
148+
static int rcar_fcp_remove(struct platform_device *pdev)
149+
{
150+
struct rcar_fcp_device *fcp = platform_get_drvdata(pdev);
151+
152+
mutex_lock(&fcp_lock);
153+
list_del(&fcp->list);
154+
mutex_unlock(&fcp_lock);
155+
156+
pm_runtime_disable(&pdev->dev);
157+
158+
return 0;
159+
}
160+
161+
static const struct of_device_id rcar_fcp_of_match[] = {
162+
{ .compatible = "renesas,fcpv" },
163+
{ },
164+
};
165+
166+
static struct platform_driver rcar_fcp_platform_driver = {
167+
.probe = rcar_fcp_probe,
168+
.remove = rcar_fcp_remove,
169+
.driver = {
170+
.name = "rcar-fcp",
171+
.of_match_table = rcar_fcp_of_match,
172+
.suppress_bind_attrs = true,
173+
},
174+
};
175+
176+
module_platform_driver(rcar_fcp_platform_driver);
177+
178+
MODULE_ALIAS("rcar-fcp");
179+
MODULE_AUTHOR("Laurent Pinchart <[email protected]>");
180+
MODULE_DESCRIPTION("Renesas FCP Driver");
181+
MODULE_LICENSE("GPL");

include/media/rcar-fcp.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* rcar-fcp.h -- R-Car Frame Compression Processor Driver
3+
*
4+
* Copyright (C) 2016 Renesas Electronics Corporation
5+
*
6+
* Contact: Laurent Pinchart ([email protected])
7+
*
8+
* This program is free software; you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation; either version 2 of the License, or
11+
* (at your option) any later version.
12+
*/
13+
#ifndef __MEDIA_RCAR_FCP_H__
14+
#define __MEDIA_RCAR_FCP_H__
15+
16+
struct device_node;
17+
struct rcar_fcp_device;
18+
19+
#if IS_ENABLED(CONFIG_VIDEO_RENESAS_FCP)
20+
struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np);
21+
void rcar_fcp_put(struct rcar_fcp_device *fcp);
22+
int rcar_fcp_enable(struct rcar_fcp_device *fcp);
23+
void rcar_fcp_disable(struct rcar_fcp_device *fcp);
24+
#else
25+
static inline struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
26+
{
27+
return ERR_PTR(-ENOENT);
28+
}
29+
static inline void rcar_fcp_put(struct rcar_fcp_device *fcp) { }
30+
static inline int rcar_fcp_enable(struct rcar_fcp_device *fcp)
31+
{
32+
return -ENOSYS;
33+
}
34+
static inline void rcar_fcp_disable(struct rcar_fcp_device *fcp) { }
35+
#endif
36+
37+
#endif /* __MEDIA_RCAR_FCP_H__ */

0 commit comments

Comments
 (0)