* [RFC PATCH 6/8] dts: coresight: Clean up the device tree graph bindings
From: Suzuki K Poulose @ 2018-06-13 13:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5448BBB7-93FE-400F-9D87-FABF5DE0539C@arm.com>
Hi Matt,
Thanks for your comments, responses inline.
On 13/06/18 13:49, Matt Sealey wrote:
> Suzuki,
>
> Why not use ?unit??
>
> I believe we had this discussion years ago about numbering serial ports and sdhci (i.e. how do you know it?s UART0 or UART1 from just the address? Some SoC?s don?t address sequentially *or* in a forward direction) - I believe it?s not exactly codified in ePAPR, not am I sure where it may be otherwise, but it exists.
We have different situation here. We need to know *the port number* as understood by the
hardware, so that we can enable *the specific* port for a given path.
>
> I agree with Rob on the slave-mode nonsense, this is an SPI controller concept weirdly stuffed into a directed graph which implicitly tells you the data direction - it?s a rooted tree (just like DT!).
Btw, the "slave-mode" is not a standard DT graph binding. It is not part of the
generic DT graph binding. In fact the generic bindings stay away from the direction
aspect and explicitly mentions the same.
>
> For the case of a funnel each device supplying trace should end up into an input node - numbered with a unit - and all those nodes should point to the output node as endpoints. Describing the hardware as a black box is probably less of a good idea than showing that it?s a funnel, or replicator by showing the internal paths. You wouldn?t need to ?number? ports with a unit except where the HW needs to differentiate between them, and you don?t need reg or a node address to do it.
>
As I mentioned above, we need the hardware numbers to enable the "specific" port.
E.g, :
static void funnel_enable_hw(struct funnel_drvdata *drvdata, int port)
{
u32 functl;
CS_UNLOCK(drvdata->base);
functl = readl_relaxed(drvdata->base + FUNNEL_FUNCTL);
functl &= ~FUNNEL_HOLDTIME_MASK;
functl |= FUNNEL_HOLDTIME;
functl |= (1 << port);
writel_relaxed(functl, drvdata->base + FUNNEL_FUNCTL);
writel_relaxed(drvdata->priority, drvdata->base + FUNNEL_PRICTL);
CS_LOCK(drvdata->base);
}
> If you really need to parse full graphs in both directions (find root, find leaf) then could we simply introduce properties which list the phandles of all uplink sources, as linked lists point to the list head?
No we don't need to parse it in both ways, up and down. Btw, the trace paths
are not statically created. They are done at runtime, as configured by the
user. So all we need to do is have a list of the ports and the devices it
is connected to (of course with direction information). I would stay
away from duplicating the platform code when something already does
a good job.
>
> This gives a way to validate that the graph starts and ends the way we expect, and also allows every port to be associated with being a required path between any two devices without parsing the *whole* graph (although you still need to do that to find the route to sinks).
Coming back to your suggestion of "unit", what does it imply ?
Its too generic a term for something as concrete as a port number.
Cheers
Suzuki
>
> Ta,
> Matt
>
> Sent from my iPhone
>
>> On Jun 13, 2018, at 04:45, Suzuki K Poulose <Suzuki.Poulose@arm.com> wrote:
>>
>> Hi Rob,
>>
>>> On 12/06/18 21:48, Rob Herring wrote:
>>>> On Fri, Jun 01, 2018 at 02:16:05PM +0100, Suzuki K Poulose wrote:
>>>> The coresight drivers relied on default bindings for graph
>>>> in DT, while reusing the "reg" field of the "ports" to indicate
>>>> the actual hardware port number for the connections. However,
>>>> with the rules getting stricter w.r.t to the address mismatch
>>>> with the label, it is no longer possible to use the port address
>>>> field for the hardware port number. Hence, we add an explicit
>>>> property to denote the hardware port number, "coresight,hwid"
>>>> which must be specified for each "endpoint".
>>>>
>>>> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
>>>> Cc: Sudeep Holla <sudeep.holla@arm.com>
>>>> Cc: Rob Herring <robh@kernel.org>
>>>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>>>> ---
>>>> .../devicetree/bindings/arm/coresight.txt | 26 +++++++++---
>>>> drivers/hwtracing/coresight/of_coresight.c | 46 ++++++++++++++++------
>>>> 2 files changed, 54 insertions(+), 18 deletions(-)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
>>>> index bd36e40..385581a 100644
>>>> --- a/Documentation/devicetree/bindings/arm/coresight.txt
>>>> +++ b/Documentation/devicetree/bindings/arm/coresight.txt
>>>> @@ -104,7 +104,11 @@ properties to uniquely identify the connection details.
>>>> "slave-mode"
>>>> * Hardware Port number at the component:
>>>> - - The hardware port number is assumed to be the address of the "port" component.
>>>> + - (Obsolete) The hardware port number is assumed to be the address of the "port" component.
>>>> + - Each "endpoint" must define the hardware port of the local end of the
>>>> + connection using the following property:
>>>> + "coresight,hwid" - 32bit integer, hardware port number at the local end.
>>> "coresight" is not a vendor and properties are in the form
>>> [<vendor>,]<prop-name>.
>>
>> OK. The issue here is that a coresight component could be an Arm IP or
>> a custom partner IP. So, the vendor could be either arm or the partner id.
>> However, this property is kind of a generic one for the Coresight family,
>> which is why we opted for "coresight". What is the guideline for such
>> cases ?
>>
>> Or in other words I see the following possible options :
>>
>> 1) coresight,hwid - coresight generic
>> 2) arm,coresight-hwid - arm vendor, however the device could be from any vendor.
>> 3) hwid - Generic
>> 4) none of the above, something completely different.
>>
>> What do you recommend from the above ?
>>
>>>> +
>>>> Example:
>>>> @@ -120,6 +124,7 @@ Example:
>>>> etb_in_port: endpoint at 0 {
>>> There shouldn't be a unit address here because there is no reg property.
>>>> slave-mode;
>>>> remote-endpoint = <&replicator_out_port0>;
>>>> + coresight,hwid = <0>;
>>> It doesn't make sense for these to be in the endpoint. If you had
>>> multiple endpoints, then you would have to duplicate it. "ports" are
>>> a single data stream. "endpoints" are connections to that stream. So if
>>> you have a muxed (input) or fanout/1-to-many (output) connection, then
>>> you have multiple endpoints.
>>
>> We do have many-to-1 input (e.g, funnels) and 1-to-many outputs
>> (e.g replicators). However, we have (so far) used only one endpoint per
>> port.
>>
>> Also we could potentially have multiple data streams flowing through
>> the ports, which gets filtered to different ports in 1-to-many components
>> (read programmable-replicator).
>>
>> So the point is we have a shared path which carries different data
>> streams with mux/demux components. I am open for suggestions based on
>> the above facts.
>>
>>> The same applied to the slave-mode property, but that ship has sailed.
>>> No reason to continue that though.
>>>> };
>>>> };
>>>> };
>>>> @@ -134,6 +139,7 @@ Example:
>>>> tpiu_in_port: endpoint at 0 {
>>>> slave-mode;
>>>> remote-endpoint = <&replicator_out_port1>;
>>>> + coresight,hwid = <0>;
>>>> };
>>>> };
>>>> };
>>>> @@ -154,6 +160,7 @@ Example:
>>>> reg = <0>;
>>>> replicator_out_port0: endpoint {
>>>> remote-endpoint = <&etb_in_port>;
>>>> + coresight,hwid = <0>;
>>>> };
>>>> };
>>>> @@ -161,15 +168,17 @@ Example:
>>>> reg = <1>;
>>>> replicator_out_port1: endpoint {
>>>> remote-endpoint = <&tpiu_in_port>;
>>>> + coresight,hwid = <1>;
>>>> };
>>>> };
>>>> /* replicator input port */
>>>> port at 2 {
>>>> - reg = <0>;
>>>> + reg = <1>;
>>> This will still get flagged as an error. reg must be 2 here.
>>
>> Sorry, thats a mistake. I will fix it.
>>
>> Cheers
>> Suzuki
^ permalink raw reply
* [PATCH 2/4] ARM: Introduce ability to enable invalidate of BTB with ICIALLU on Cortex-A15 for CVE-2017-5715
From: Nishanth Menon @ 2018-06-13 13:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <6BFD98F8-FACB-43DE-82DC-E0A134D4E1C0@gmail.com>
On 00:30-20180613, Florian Fainelli wrote:
> On June 12, 2018 1:24:09 PM PDT, Nishanth Menon <nm@ti.com> wrote:
> >As recommended by Arm in [1], ACTLR[0] (Enable invalidates of BTB)
> >needs to be set[2] for BTB to be invalidated on ICIALLU. This needs to
> >be done unconditionally for Cortex-A15 processors. Provide a config
> >option for platforms to enable this option based on impact analysis
> >for products.
> >
> >NOTE: This patch in itself is NOT the final solution, this requires:
> >a) Implementation of v7_arch_cp15_set_acr on SoCs which may not
> > provide direct access to ACR register.
> >b) Operating Systems such as Linux to provide adequate workaround in
> >the
> > right locations.
>
> This is the case as of 4.18 so you could probably reference CONFIG_CPU_SPECTRE and CONFIG_HARDEN_BRANCH_PREDICTOR in a v2.
Did'nt want to tie the description too deep to Linux specifics.. Linux
documents itself and users are encouraged to read that documentation,
correct?
>
> >c) This workaround applies to only the boot processor. It is important
> > to apply workaround as necessary (context-save-restore) around low
> > power context loss OR additional processors as necessary in either
> > firmware support OR elsewhere in OS.
>
> About that, I don't know enough of uboot but are there existing PSCI or
> other seemingly standard secondary core support in uboot that would make
> us go through the same initialization as the boot CPU? If not, is
> everything going to be largely implementation specific and
> scattered between uboot and the hypervisors or kernel?
in ARMV7 SoCs, unfortunately, we lived in a world of no-exact-standard.
even within TI, Few of the SoCs use PSCI, others did implement custom
SMC calls (since they existed in an architecture prior to PSCI).
>
> FWIW, this is what prompted me to submit this:
>
> https://patchwork.kernel.org/patch/10453643/
That wont work in a generic manner for precisely the same reason I had to do
it with weak function in u-boot (some SoCs will only permit 'mcr
p15, 0, r0, c1, c0, 1' in secure world and you need to make a custom smc
call to make it happen). Unfortunately, IMHO, at least at this
point, there'd be custom implementations per SoC and layers depending on
where to implement it.
--
Regards,
Nishanth Menon
^ permalink raw reply
* [PATCH] mm: cma: honor __GFP_ZERO flag in cma_alloc()
From: Michal Hocko @ 2018-06-13 13:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613125546.GB32016@infradead.org>
On Wed 13-06-18 05:55:46, Christoph Hellwig wrote:
> On Wed, Jun 13, 2018 at 02:40:00PM +0200, Marek Szyprowski wrote:
> > It is not only the matter of the spinlocks. GFP_ATOMIC is not supported
> > by the
> > memory compaction code, which is used in alloc_contig_range(). Right, this
> > should be also noted in the documentation.
>
> Documentation is good, asserts are better. The code should reject any
> flag not explicitly supported, or even better have its own flags type
> with the few actually supported flags.
Agreed. Is the cma allocator used for anything other than GFP_KERNEL
btw.? If not then, shouldn't we simply drop the gfp argument altogether
rather than give users a false hope for differen gfp modes that are not
really supported and grow broken code?
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* [PATCH 3/4] ARM: mach-omap2: omap5/dra7: Enable ACTLR[0] (Enable invalidates of BTB) to facilitate CVE_2017-5715 WA in OS
From: Nishanth Menon @ 2018-06-13 13:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <780935f6-6506-0915-dfb2-b584c074b70d@gmail.com>
On 23:06-20180612, Marek Vasut wrote:
> On 06/12/2018 10:24 PM, Nishanth Menon wrote:
> > Enable CVE_2017_5715 and since we have our own v7_arch_cp15_set_acr
> > function to setup the bits, we are able to override the settings.
> >
> > Without this enabled, Linux kernel reports:
> > CPU0: Spectre v2: firmware did not set auxiliary control register IBE bit, system vulnerable
> >
> > With this enabled, Linux kernel reports:
> > CPU0: Spectre v2: using ICIALLU workaround
> >
> > NOTE: This by itself does not enable the workaround for CPU1 (on
> > OMAP5 and DRA72/AM572 SoCs) and may require additional kernel patches.
> >
> > Signed-off-by: Nishanth Menon <nm@ti.com>
> > ---
> > arch/arm/mach-omap2/Kconfig | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
> > index 3bb1ecb58de0..77820cc8d1e4 100644
> > --- a/arch/arm/mach-omap2/Kconfig
> > +++ b/arch/arm/mach-omap2/Kconfig
> > @@ -53,6 +53,7 @@ config OMAP54XX
> > bool "OMAP54XX SoC"
> > select ARM_ERRATA_798870
> > select SYS_THUMB_BUILD
> > + select ARM_CORTEX_A15_CVE_2017_5715
> > imply NAND_OMAP_ELM
> > imply NAND_OMAP_GPMC
> > imply SPL_DISPLAY_PRINT
> >
>
> Can this be enabled for all CA15 systems somehow ? I am sure there are
> more that are vulnerable.
I just dont know how to make smc call convention generic. This is the
reason why v7_arch_cp15_set_acr is setup as a weak function. you'd have
to implement it specific to SoC (in many newer SoCs, you might
potentially be able to make at least few implementations generic using
PSCI). NOTE: this is the same trouble with erratum 801819 implementation
as well.
--
Regards,
Nishanth Menon
^ permalink raw reply
* [RFC PATCH 6/8] dts: coresight: Clean up the device tree graph bindings
From: Rob Herring @ 2018-06-13 13:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <c0d531ec-9201-bfd8-e6c3-9140698b0697@arm.com>
On Wed, Jun 13, 2018 at 7:35 AM, Suzuki K Poulose
<Suzuki.Poulose@arm.com> wrote:
> Hi Matt,
>
> Thanks for your comments, responses inline.
>
> On 13/06/18 13:49, Matt Sealey wrote:
>>
>> Suzuki,
>>
>> Why not use ?unit??
>>
>> I believe we had this discussion years ago about numbering serial ports
>> and sdhci (i.e. how do you know it?s UART0 or UART1 from just the address?
>> Some SoC?s don?t address sequentially *or* in a forward direction) - I
>> believe it?s not exactly codified in ePAPR, not am I sure where it may be
>> otherwise, but it exists.
>
>
> We have different situation here. We need to know *the port number* as
> understood by the
> hardware, so that we can enable *the specific* port for a given path.
>
>>
>> I agree with Rob on the slave-mode nonsense, this is an SPI controller
>> concept weirdly stuffed into a directed graph which implicitly tells you the
>> data direction - it?s a rooted tree (just like DT!).
OF graph is not directional. All links must be bi-directional and in
fact dtc checks that now. The parent node should know the numbering
and direction of each port.
> Btw, the "slave-mode" is not a standard DT graph binding. It is not part of
> the
> generic DT graph binding. In fact the generic bindings stay away from the
> direction
> aspect and explicitly mentions the same.
I really don't like slave-mode nor coresight,hwid.
I would prefer to see getting rid of both and splitting ports into
"in-ports" and "out-ports" nodes instead of a single "ports" node.
Then you don't need any of these properties and reg can be used as the
hwid.
Rob
^ permalink raw reply
* [PATCH 0/9] media: cedrus: Add H264 decoding support
From: Maxime Ripard @ 2018-06-13 14:07 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Here is a preliminary version of the H264 decoding support in the
cedrus driver.
As you might already know, the cedrus driver relies on the Request
API, and is a reverse engineered driver for the video decoding engine
found on the Allwinner SoCs.
This work has been possible thanks to the work done by the people
behind libvdpau-sunxi found here:
https://github.com/linux-sunxi/libvdpau-sunxi/
This driver is based on the last version of the cedrus driver sent by
Paul, based on Request API v13 sent by Hans:
https://lkml.org/lkml/2018/5/7/316
This driver has been tested only with baseline profile videos, and is
missing a few key features to decode videos with higher profiles.
This has been tested using our cedrus-frame-test tool, which should be
a quite generic v4l2-to-drm decoder using the request API to
demonstrate the video decoding:
https://github.com/free-electrons/cedrus-frame-test/, branch h264
However, sending this preliminary version, I'd really like to start a
discussion and get some feedback on the user-space API for the H264
controls exposed through the request API.
I've been using the controls currently integrated into ChromeOS that
have a working version of this particular setup. However, these
controls have a number of shortcomings and inconsistencies with other
decoding API. I've worked with libva so far, but I've noticed already
that:
- The kernel UAPI expects to have the nal_ref_idc variable, while
libva only exposes whether that frame is a reference frame or
not. I've looked at the rockchip driver in the ChromeOS tree, and
our own driver, and they both need only the information about
whether the frame is a reference one or not, so maybe we should
change this?
- The H264 bitstream exposes the picture default reference list (for
both list 0 and list 1), the slice reference list and an override
flag. The libva will only pass the reference list to be used (so
either the picture default's or the slice's) depending on the
override flag. The kernel UAPI wants the picture default reference
list and the slice reference list, but doesn't expose the override
flag, which prevents us from configuring properly the
hardware. Our video decoding engine needs the three information,
but we can easily adapt to having only one. However, having two
doesn't really work for us.
It's pretty much the only one I've noticed so far, but we should
probably fix them already. And there's probably other, feel free to
step in.
Maxime Ripard (8):
media: cedrus: Add wrappers around container_of for our buffers
media: cedrus: Add a macro to check for the validity of a control
media: cedrus: make engine type more generic
media: cedrus: Remove MPEG1 support
media: cedrus: Add ops structure
media: cedrus: Move IRQ maintainance to cedrus_dec_ops
media: cedrus: Add start and stop decoder operations
media: cedrus: Add H264 decoding support
Pawel Osciak (1):
CHROMIUM: v4l: Add H264 low-level decoder API compound controls.
drivers/media/platform/sunxi/cedrus/Makefile | 2 +-
.../platform/sunxi/cedrus/sunxi_cedrus.c | 23 +
.../sunxi/cedrus/sunxi_cedrus_common.h | 81 +++-
.../platform/sunxi/cedrus/sunxi_cedrus_dec.c | 38 +-
.../platform/sunxi/cedrus/sunxi_cedrus_h264.c | 443 ++++++++++++++++++
.../platform/sunxi/cedrus/sunxi_cedrus_hw.c | 35 +-
.../platform/sunxi/cedrus/sunxi_cedrus_hw.h | 6 +-
.../sunxi/cedrus/sunxi_cedrus_mpeg2.c | 52 +-
.../sunxi/cedrus/sunxi_cedrus_mpeg2.h | 33 --
.../platform/sunxi/cedrus/sunxi_cedrus_regs.h | 22 +-
.../sunxi/cedrus/sunxi_cedrus_video.c | 37 +-
drivers/media/v4l2-core/v4l2-ctrls.c | 42 ++
include/media/v4l2-ctrls.h | 10 +
include/uapi/linux/v4l2-controls.h | 164 +++++++
include/uapi/linux/videodev2.h | 11 +
15 files changed, 912 insertions(+), 87 deletions(-)
create mode 100644 drivers/media/platform/sunxi/cedrus/sunxi_cedrus_h264.c
delete mode 100644 drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.h
--
2.17.0
^ permalink raw reply
* [PATCH 1/9] CHROMIUM: v4l: Add H264 low-level decoder API compound controls.
From: Maxime Ripard @ 2018-06-13 14:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613140714.1686-1-maxime.ripard@bootlin.com>
From: Pawel Osciak <posciak@chromium.org>
Signed-off-by: Pawel Osciak <posciak@chromium.org>
Reviewed-by: Wu-cheng Li <wuchengli@chromium.org>
Tested-by: Tomasz Figa <tfiga@chromium.org>
[rebase44(groeck): include linux/types.h in v4l2-controls.h]
Signed-off-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
drivers/media/v4l2-core/v4l2-ctrls.c | 42 +++++++
include/media/v4l2-ctrls.h | 10 ++
include/uapi/linux/v4l2-controls.h | 164 +++++++++++++++++++++++++++
include/uapi/linux/videodev2.h | 11 ++
4 files changed, 227 insertions(+)
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index cdf860c8e3d8..1f63c725bad1 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -807,6 +807,11 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:return "H264 Number of HC Layers";
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP:
return "H264 Set QP Value for HC Layers";
+ case V4L2_CID_MPEG_VIDEO_H264_SPS: return "H264 SPS";
+ case V4L2_CID_MPEG_VIDEO_H264_PPS: return "H264 PPS";
+ case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX: return "H264 Scaling Matrix";
+ case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAM: return "H264 Slice Parameters";
+ case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAM: return "H264 Decode Parameters";
case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value";
case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value";
case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value";
@@ -1272,6 +1277,21 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_RDS_TX_ALT_FREQS:
*type = V4L2_CTRL_TYPE_U32;
break;
+ case V4L2_CID_MPEG_VIDEO_H264_SPS:
+ *type = V4L2_CTRL_TYPE_H264_SPS;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_PPS:
+ *type = V4L2_CTRL_TYPE_H264_PPS;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX:
+ *type = V4L2_CTRL_TYPE_H264_SCALING_MATRIX;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAM:
+ *type = V4L2_CTRL_TYPE_H264_SLICE_PARAM;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAM:
+ *type = V4L2_CTRL_TYPE_H264_DECODE_PARAM;
+ break;
case V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR:
*type = V4L2_CTRL_TYPE_MPEG2_FRAME_HDR;
break;
@@ -1598,6 +1618,13 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
case V4L2_CTRL_TYPE_MPEG2_FRAME_HDR:
return 0;
+ case V4L2_CTRL_TYPE_H264_SPS:
+ case V4L2_CTRL_TYPE_H264_PPS:
+ case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
+ case V4L2_CTRL_TYPE_H264_SLICE_PARAM:
+ case V4L2_CTRL_TYPE_H264_DECODE_PARAM:
+ return 0;
+
default:
return -EINVAL;
}
@@ -2172,6 +2199,21 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
case V4L2_CTRL_TYPE_U32:
elem_size = sizeof(u32);
break;
+ case V4L2_CTRL_TYPE_H264_SPS:
+ elem_size = sizeof(struct v4l2_ctrl_h264_sps);
+ break;
+ case V4L2_CTRL_TYPE_H264_PPS:
+ elem_size = sizeof(struct v4l2_ctrl_h264_pps);
+ break;
+ case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
+ elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix);
+ break;
+ case V4L2_CTRL_TYPE_H264_SLICE_PARAM:
+ elem_size = sizeof(struct v4l2_ctrl_h264_slice_param);
+ break;
+ case V4L2_CTRL_TYPE_H264_DECODE_PARAM:
+ elem_size = sizeof(struct v4l2_ctrl_h264_decode_param);
+ break;
case V4L2_CTRL_TYPE_MPEG2_FRAME_HDR:
elem_size = sizeof(struct v4l2_ctrl_mpeg2_frame_hdr);
break;
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 963c37b02363..9c223793a16a 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -41,6 +41,11 @@ struct poll_table_struct;
* @p_u16: Pointer to a 16-bit unsigned value.
* @p_u32: Pointer to a 32-bit unsigned value.
* @p_char: Pointer to a string.
+ * @p_h264_sps: Pointer to a struct v4l2_ctrl_h264_sps.
+ * @p_h264_pps: Pointer to a struct v4l2_ctrl_h264_pps.
+ * @p_h264_scal_mtrx: Pointer to a struct v4l2_ctrl_h264_scaling_matrix.
+ * @p_h264_slice_param: Pointer to a struct v4l2_ctrl_h264_slice_param.
+ * @p_h264_decode_param: Pointer to a struct v4l2_ctrl_h264_decode_param.
* @p: Pointer to a compound value.
*/
union v4l2_ctrl_ptr {
@@ -50,6 +55,11 @@ union v4l2_ctrl_ptr {
u16 *p_u16;
u32 *p_u32;
char *p_char;
+ struct v4l2_ctrl_h264_sps *p_h264_sps;
+ struct v4l2_ctrl_h264_pps *p_h264_pps;
+ struct v4l2_ctrl_h264_scaling_matrix *p_h264_scal_mtrx;
+ struct v4l2_ctrl_h264_slice_param *p_h264_slice_param;
+ struct v4l2_ctrl_h264_decode_param *p_h264_decode_param;
void *p;
};
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 23da8bfa7e6f..ac307c59683c 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -50,6 +50,8 @@
#ifndef __LINUX_V4L2_CONTROLS_H
#define __LINUX_V4L2_CONTROLS_H
+#include <linux/types.h>
+
/* Control classes */
#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */
#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */
@@ -531,6 +533,12 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type {
};
#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER (V4L2_CID_MPEG_BASE+381)
#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP (V4L2_CID_MPEG_BASE+382)
+#define V4L2_CID_MPEG_VIDEO_H264_SPS (V4L2_CID_MPEG_BASE+383)
+#define V4L2_CID_MPEG_VIDEO_H264_PPS (V4L2_CID_MPEG_BASE+384)
+#define V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (V4L2_CID_MPEG_BASE+385)
+#define V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAM (V4L2_CID_MPEG_BASE+386)
+#define V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAM (V4L2_CID_MPEG_BASE+387)
+
#define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE+400)
#define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE+401)
#define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE+402)
@@ -1078,6 +1086,162 @@ enum v4l2_detect_md_mode {
#define V4L2_CID_DETECT_MD_THRESHOLD_GRID (V4L2_CID_DETECT_CLASS_BASE + 3)
#define V4L2_CID_DETECT_MD_REGION_GRID (V4L2_CID_DETECT_CLASS_BASE + 4)
+/* Complex controls */
+
+#define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG 0x01
+#define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG 0x02
+#define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG 0x04
+#define V4L2_H264_SPS_CONSTRAINT_SET3_FLAG 0x08
+#define V4L2_H264_SPS_CONSTRAINT_SET4_FLAG 0x10
+#define V4L2_H264_SPS_CONSTRAINT_SET5_FLAG 0x20
+
+#define V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE 0x01
+#define V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS 0x02
+#define V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO 0x04
+#define V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED 0x08
+#define V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY 0x10
+#define V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD 0x20
+#define V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE 0x40
+struct v4l2_ctrl_h264_sps {
+ __u8 profile_idc;
+ __u8 constraint_set_flags;
+ __u8 level_idc;
+ __u8 seq_parameter_set_id;
+ __u8 chroma_format_idc;
+ __u8 bit_depth_luma_minus8;
+ __u8 bit_depth_chroma_minus8;
+ __u8 log2_max_frame_num_minus4;
+ __u8 pic_order_cnt_type;
+ __u8 log2_max_pic_order_cnt_lsb_minus4;
+ __s32 offset_for_non_ref_pic;
+ __s32 offset_for_top_to_bottom_field;
+ __u8 num_ref_frames_in_pic_order_cnt_cycle;
+ __s32 offset_for_ref_frame[255];
+ __u8 max_num_ref_frames;
+ __u16 pic_width_in_mbs_minus1;
+ __u16 pic_height_in_map_units_minus1;
+ __u8 flags;
+};
+
+#define V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE 0x0001
+#define V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT 0x0002
+#define V4L2_H264_PPS_FLAG_WEIGHTED_PRED 0x0004
+#define V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT 0x0008
+#define V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED 0x0010
+#define V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT 0x0020
+#define V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE 0x0040
+#define V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT 0x0080
+struct v4l2_ctrl_h264_pps {
+ __u8 pic_parameter_set_id;
+ __u8 seq_parameter_set_id;
+ __u8 num_slice_groups_minus1;
+ __u8 num_ref_idx_l0_default_active_minus1;
+ __u8 num_ref_idx_l1_default_active_minus1;
+ __u8 weighted_bipred_idc;
+ __s8 pic_init_qp_minus26;
+ __s8 pic_init_qs_minus26;
+ __s8 chroma_qp_index_offset;
+ __s8 second_chroma_qp_index_offset;
+ __u8 flags;
+};
+
+struct v4l2_ctrl_h264_scaling_matrix {
+ __u8 scaling_list_4x4[6][16];
+ __u8 scaling_list_8x8[6][64];
+};
+
+struct v4l2_h264_weight_factors {
+ __s8 luma_weight[32];
+ __s8 luma_offset[32];
+ __s8 chroma_weight[32][2];
+ __s8 chroma_offset[32][2];
+};
+
+struct v4l2_h264_pred_weight_table {
+ __u8 luma_log2_weight_denom;
+ __u8 chroma_log2_weight_denom;
+ struct v4l2_h264_weight_factors weight_factors[2];
+};
+
+enum v4l2_h264_slice_type {
+ V4L2_H264_SLICE_TYPE_P = 0,
+ V4L2_H264_SLICE_TYPE_B = 1,
+ V4L2_H264_SLICE_TYPE_I = 2,
+ V4L2_H264_SLICE_TYPE_SP = 3,
+ V4L2_H264_SLICE_TYPE_SI = 4,
+};
+
+#define V4L2_SLICE_FLAG_FIELD_PIC 0x01
+#define V4L2_SLICE_FLAG_BOTTOM_FIELD 0x02
+#define V4L2_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x04
+#define V4L2_SLICE_FLAG_SP_FOR_SWITCH 0x08
+struct v4l2_ctrl_h264_slice_param {
+ /* Size in bytes, including header */
+ __u32 size;
+ /* Offset in bits to slice_data() from the beginning of this slice. */
+ __u32 header_bit_size;
+
+ __u16 first_mb_in_slice;
+ enum v4l2_h264_slice_type slice_type;
+ __u8 pic_parameter_set_id;
+ __u8 colour_plane_id;
+ __u16 frame_num;
+ __u16 idr_pic_id;
+ __u16 pic_order_cnt_lsb;
+ __s32 delta_pic_order_cnt_bottom;
+ __s32 delta_pic_order_cnt0;
+ __s32 delta_pic_order_cnt1;
+ __u8 redundant_pic_cnt;
+
+ struct v4l2_h264_pred_weight_table pred_weight_table;
+ /* Size in bits of dec_ref_pic_marking() syntax element. */
+ __u32 dec_ref_pic_marking_bit_size;
+ /* Size in bits of pic order count syntax. */
+ __u32 pic_order_cnt_bit_size;
+
+ __u8 cabac_init_idc;
+ __s8 slice_qp_delta;
+ __s8 slice_qs_delta;
+ __u8 disable_deblocking_filter_idc;
+ __s8 slice_alpha_c0_offset_div2;
+ __s8 slice_beta_offset_div2;
+ __u32 slice_group_change_cycle;
+
+ __u8 num_ref_idx_l0_active_minus1;
+ __u8 num_ref_idx_l1_active_minus1;
+ /* Entries on each list are indices
+ * into v4l2_ctrl_h264_decode_param.dpb[]. */
+ __u8 ref_pic_list0[32];
+ __u8 ref_pic_list1[32];
+
+ __u8 flags;
+};
+
+/* If not set, this entry is unused for reference. */
+#define V4L2_H264_DPB_ENTRY_FLAG_ACTIVE 0x01
+#define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM 0x02
+struct v4l2_h264_dpb_entry {
+ __u32 buf_index; /* v4l2_buffer index */
+ __u16 frame_num;
+ __u16 pic_num;
+ /* Note that field is indicated by v4l2_buffer.field */
+ __s32 top_field_order_cnt;
+ __s32 bottom_field_order_cnt;
+ __u8 flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
+};
+
+struct v4l2_ctrl_h264_decode_param {
+ __u32 num_slices;
+ __u8 idr_pic_flag;
+ __u8 nal_ref_idc;
+ __s32 top_field_order_cnt;
+ __s32 bottom_field_order_cnt;
+ __u8 ref_pic_list_p0[32];
+ __u8 ref_pic_list_b0[32];
+ __u8 ref_pic_list_b1[32];
+ struct v4l2_h264_dpb_entry dpb[16];
+};
+
struct v4l2_ctrl_mpeg2_frame_hdr {
__u32 slice_len;
__u32 slice_pos;
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 242a6bfa1440..4b4a1b25a0db 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -626,6 +626,7 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */
#define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */
#define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */
+#define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */
#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */
#define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */
#define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */
@@ -1589,6 +1590,11 @@ struct v4l2_ext_control {
__u8 __user *p_u8;
__u16 __user *p_u16;
__u32 __user *p_u32;
+ struct v4l2_ctrl_h264_sps __user *p_h264_sps;
+ struct v4l2_ctrl_h264_pps __user *p_h264_pps;
+ struct v4l2_ctrl_h264_scaling_matrix __user *p_h264_scal_mtrx;
+ struct v4l2_ctrl_h264_slice_param __user *p_h264_slice_param;
+ struct v4l2_ctrl_h264_decode_param __user *p_h264_decode_param;
struct v4l2_ctrl_mpeg2_frame_hdr __user *p_mpeg2_frame_hdr;
void __user *ptr;
};
@@ -1635,6 +1641,11 @@ enum v4l2_ctrl_type {
V4L2_CTRL_TYPE_U8 = 0x0100,
V4L2_CTRL_TYPE_U16 = 0x0101,
V4L2_CTRL_TYPE_U32 = 0x0102,
+ V4L2_CTRL_TYPE_H264_SPS = 0x0103,
+ V4L2_CTRL_TYPE_H264_PPS = 0x0104,
+ V4L2_CTRL_TYPE_H264_SCALING_MATRIX = 0x0105,
+ V4L2_CTRL_TYPE_H264_SLICE_PARAM = 0x0106,
+ V4L2_CTRL_TYPE_H264_DECODE_PARAM = 0x0107,
V4L2_CTRL_TYPE_MPEG2_FRAME_HDR = 0x0109,
};
--
2.17.0
^ permalink raw reply related
* [PATCH 2/9] media: cedrus: Add wrappers around container_of for our buffers
From: Maxime Ripard @ 2018-06-13 14:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613140714.1686-1-maxime.ripard@bootlin.com>
The cedrus driver sub-classes the vb2_v4l2_buffer structure, but doesn't
provide any function to wrap around the proper container_of call that needs
to be duplicated in every calling site.
Add wrappers to make sure its opaque to the users and they don't have to
care anymore.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
.../platform/sunxi/cedrus/sunxi_cedrus_common.h | 12 ++++++++++++
.../media/platform/sunxi/cedrus/sunxi_cedrus_hw.c | 4 ++--
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
index ee6883ef9cb7..b1ed1c8cb130 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
@@ -89,6 +89,18 @@ struct sunxi_cedrus_buffer {
struct list_head list;
};
+static inline
+struct sunxi_cedrus_buffer *vb2_v4l2_to_cedrus_buffer(const struct vb2_v4l2_buffer *p)
+{
+ return container_of(p, struct sunxi_cedrus_buffer, vb);
+}
+
+static inline
+struct sunxi_cedrus_buffer *vb2_to_cedrus_buffer(const struct vb2_buffer *p)
+{
+ return vb2_v4l2_to_cedrus_buffer(to_vb2_v4l2_buffer(p));
+}
+
struct sunxi_cedrus_dev {
struct v4l2_device v4l2_dev;
struct video_device vfd;
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c
index 5783bd985855..fc688a5c1ea3 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c
@@ -108,8 +108,8 @@ static irqreturn_t sunxi_cedrus_ve_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
- src_buffer = container_of(src_vb, struct sunxi_cedrus_buffer, vb);
- dst_buffer = container_of(dst_vb, struct sunxi_cedrus_buffer, vb);
+ src_buffer = vb2_v4l2_to_cedrus_buffer(src_vb);
+ dst_buffer = vb2_v4l2_to_cedrus_buffer(dst_vb);
/* First bit of MPEG_STATUS indicates success. */
if (ctx->job_abort || !(status & 0x01))
--
2.17.0
^ permalink raw reply related
* [PATCH 3/9] media: cedrus: Add a macro to check for the validity of a control
From: Maxime Ripard @ 2018-06-13 14:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613140714.1686-1-maxime.ripard@bootlin.com>
During our frame decoding setup, we need to check a number of controls to
make sure that they are properly filled before trying to access them.
It's not too bad with MPEG2 since there's just a single one, but with the
upcoming increase of codecs, and the integration of more complex codecs,
this logic will be duplicated a significant number of times. H264 for
example uses 4 different controls.
Add a macro that expands to the proper check in order to reduce the
duplication.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
.../platform/sunxi/cedrus/sunxi_cedrus_dec.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c
index 8c92af34ebeb..c19acf9626c4 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c
@@ -110,15 +110,16 @@ void sunxi_cedrus_device_run(void *priv)
spin_lock_irqsave(&ctx->dev->irq_lock, flags);
+#define CHECK_CONTROL(ctx, ctrl) \
+ if (!ctx->ctrls[(ctrl)]) { \
+ v4l2_err(&(ctx)->dev->v4l2_dev, "Invalid " #ctrl " control\n"); \
+ (ctx)->job_abort = 1; \
+ goto unlock_complete; \
+ }
+
switch (ctx->vpu_src_fmt->fourcc) {
case V4L2_PIX_FMT_MPEG2_FRAME:
- if (!ctx->ctrls[SUNXI_CEDRUS_CTRL_DEC_MPEG2_FRAME_HDR]) {
- v4l2_err(&ctx->dev->v4l2_dev,
- "Invalid MPEG2 frame header control\n");
- ctx->job_abort = 1;
- goto unlock_complete;
- }
-
+ CHECK_CONTROL(ctx, SUNXI_CEDRUS_CTRL_DEC_MPEG2_FRAME_HDR);
run.mpeg2.hdr = get_ctrl_ptr(ctx, SUNXI_CEDRUS_CTRL_DEC_MPEG2_FRAME_HDR);
sunxi_cedrus_mpeg2_setup(ctx, &run);
@@ -128,6 +129,7 @@ void sunxi_cedrus_device_run(void *priv)
default:
ctx->job_abort = 1;
}
+#undef CHECK_CONTROL
unlock_complete:
spin_unlock_irqrestore(&ctx->dev->irq_lock, flags);
--
2.17.0
^ permalink raw reply related
* [PATCH 4/9] media: cedrus: make engine type more generic
From: Maxime Ripard @ 2018-06-13 14:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613140714.1686-1-maxime.ripard@bootlin.com>
The sunxi_cedrus_engine enum actually enumerates pretty much the codecs to
use (or we can easily infer the codec engine from the codec).
Since we will need the codec type as well in some later refactoring, make
that structure more useful by just enumerating the codec, and converting
the existing users.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h | 6 ++++++
drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c | 6 +++---
drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.h | 6 +-----
drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c | 2 +-
4 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
index b1ed1c8cb130..a5f83c452006 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
@@ -61,6 +61,12 @@ struct sunxi_cedrus_run {
};
};
+enum sunxi_cedrus_codec {
+ SUNXI_CEDRUS_CODEC_MPEG2,
+
+ SUNXI_CEDRUS_CODEC_LAST,
+};
+
struct sunxi_cedrus_ctx {
struct v4l2_fh fh;
struct sunxi_cedrus_dev *dev;
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c
index fc688a5c1ea3..bb46a01214e0 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c
@@ -41,7 +41,7 @@
#define SYSCON_SRAM_C1_MAP_VE 0x7fffffff
int sunxi_cedrus_engine_enable(struct sunxi_cedrus_dev *dev,
- enum sunxi_cedrus_engine engine)
+ enum sunxi_cedrus_codec codec)
{
u32 reg = 0;
@@ -53,8 +53,8 @@ int sunxi_cedrus_engine_enable(struct sunxi_cedrus_dev *dev,
reg |= VE_CTRL_CACHE_BUS_BW_128;
- switch (engine) {
- case SUNXI_CEDRUS_ENGINE_MPEG:
+ switch (codec) {
+ case SUNXI_CEDRUS_CODEC_MPEG2:
reg |= VE_CTRL_DEC_MODE_MPEG;
break;
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.h b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.h
index 34f3fae462a8..3236c80bfcf4 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.h
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.h
@@ -23,12 +23,8 @@
#ifndef _SUNXI_CEDRUS_HW_H_
#define _SUNXI_CEDRUS_HW_H_
-enum sunxi_cedrus_engine {
- SUNXI_CEDRUS_ENGINE_MPEG,
-};
-
int sunxi_cedrus_engine_enable(struct sunxi_cedrus_dev *dev,
- enum sunxi_cedrus_engine engine);
+ enum sunxi_cedrus_codec codec);
void sunxi_cedrus_engine_disable(struct sunxi_cedrus_dev *dev);
int sunxi_cedrus_hw_probe(struct sunxi_cedrus_dev *dev);
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c
index 5be3e3b9ceef..85e6fc2fbdb2 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c
@@ -83,7 +83,7 @@ void sunxi_cedrus_mpeg2_setup(struct sunxi_cedrus_ctx *ctx,
}
/* Activate MPEG engine. */
- sunxi_cedrus_engine_enable(dev, SUNXI_CEDRUS_ENGINE_MPEG);
+ sunxi_cedrus_engine_enable(dev, SUNXI_CEDRUS_CODEC_MPEG2);
/* Set quantization matrices. */
for (i = 0; i < 64; i++) {
--
2.17.0
^ permalink raw reply related
* [PATCH 5/9] media: cedrus: Remove MPEG1 support
From: Maxime Ripard @ 2018-06-13 14:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613140714.1686-1-maxime.ripard@bootlin.com>
The MPEG1 codec is obsolete, and that code hasn't been tested either. Since
it stands in the way of further refactoring, remove it entirely.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c | 4 +---
drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c | 8 ++------
drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.h | 2 +-
3 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c
index c19acf9626c4..f274408ab5a7 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c
@@ -80,7 +80,6 @@ void sunxi_cedrus_device_run(void *priv)
struct sunxi_cedrus_run run = { 0 };
struct media_request *src_req, *dst_req;
unsigned long flags;
- bool mpeg1 = false;
run.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
if (!run.src) {
@@ -123,7 +122,6 @@ void sunxi_cedrus_device_run(void *priv)
run.mpeg2.hdr = get_ctrl_ptr(ctx, SUNXI_CEDRUS_CTRL_DEC_MPEG2_FRAME_HDR);
sunxi_cedrus_mpeg2_setup(ctx, &run);
- mpeg1 = run.mpeg2.hdr->type == MPEG1;
break;
default:
@@ -146,7 +144,7 @@ void sunxi_cedrus_device_run(void *priv)
if (!ctx->job_abort) {
if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_MPEG2_FRAME)
- sunxi_cedrus_mpeg2_trigger(ctx, mpeg1);
+ sunxi_cedrus_mpeg2_trigger(ctx);
} else {
v4l2_m2m_buf_done(run.src, VB2_BUF_STATE_ERROR);
v4l2_m2m_buf_done(run.dst, VB2_BUF_STATE_ERROR);
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c
index 85e6fc2fbdb2..d1d7a3cfce0d 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c
@@ -148,13 +148,9 @@ void sunxi_cedrus_mpeg2_setup(struct sunxi_cedrus_ctx *ctx,
sunxi_cedrus_write(dev, src_buf_addr + VBV_SIZE - 1, VE_MPEG_VLD_END);
}
-void sunxi_cedrus_mpeg2_trigger(struct sunxi_cedrus_ctx *ctx, bool mpeg1)
+void sunxi_cedrus_mpeg2_trigger(struct sunxi_cedrus_ctx *ctx)
{
struct sunxi_cedrus_dev *dev = ctx->dev;
- /* Trigger MPEG engine. */
- if (mpeg1)
- sunxi_cedrus_write(dev, VE_TRIG_MPEG1, VE_MPEG_TRIGGER);
- else
- sunxi_cedrus_write(dev, VE_TRIG_MPEG2, VE_MPEG_TRIGGER);
+ sunxi_cedrus_write(dev, VE_TRIG_MPEG2, VE_MPEG_TRIGGER);
}
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.h b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.h
index b572001d47f2..4c380becfa1a 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.h
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.h
@@ -28,6 +28,6 @@ struct sunxi_cedrus_run;
void sunxi_cedrus_mpeg2_setup(struct sunxi_cedrus_ctx *ctx,
struct sunxi_cedrus_run *run);
-void sunxi_cedrus_mpeg2_trigger(struct sunxi_cedrus_ctx *ctx, bool mpeg1);
+void sunxi_cedrus_mpeg2_trigger(struct sunxi_cedrus_ctx *ctx);
#endif
--
2.17.0
^ permalink raw reply related
* [PATCH 6/9] media: cedrus: Add ops structure
From: Maxime Ripard @ 2018-06-13 14:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613140714.1686-1-maxime.ripard@bootlin.com>
In order to increase the number of codecs supported, we need to decouple
the MPEG2 only code that was there up until now and turn it into something
a bit more generic.
Do that by introducing an intermediate ops structure that would need to be
filled by each supported codec. Start by implementing in that structure the
setup and trigger hooks that are currently the only functions being
implemented by codecs support.
To do so, we need to store the current codec in use, which we do at
start_streaming time.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
.../platform/sunxi/cedrus/sunxi_cedrus.c | 2 ++
.../sunxi/cedrus/sunxi_cedrus_common.h | 11 +++++++
.../platform/sunxi/cedrus/sunxi_cedrus_dec.c | 10 +++---
.../sunxi/cedrus/sunxi_cedrus_mpeg2.c | 11 +++++--
.../sunxi/cedrus/sunxi_cedrus_mpeg2.h | 33 -------------------
.../sunxi/cedrus/sunxi_cedrus_video.c | 17 +++++++++-
6 files changed, 42 insertions(+), 42 deletions(-)
delete mode 100644 drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.h
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus.c
index ccd41d9a3e41..bc80480f5dfd 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus.c
@@ -244,6 +244,8 @@ static int sunxi_cedrus_probe(struct platform_device *pdev)
if (ret)
return ret;
+ dev->dec_ops[SUNXI_CEDRUS_CODEC_MPEG2] = &sunxi_cedrus_dec_ops_mpeg2;
+
ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
if (ret)
goto unreg_media;
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
index a5f83c452006..c2e2c92d103b 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
@@ -75,6 +75,7 @@ struct sunxi_cedrus_ctx {
struct v4l2_pix_format_mplane src_fmt;
struct sunxi_cedrus_fmt *vpu_dst_fmt;
struct v4l2_pix_format_mplane dst_fmt;
+ enum sunxi_cedrus_codec current_codec;
struct v4l2_ctrl_handler hdl;
struct v4l2_ctrl *ctrls[SUNXI_CEDRUS_CTRL_MAX];
@@ -107,6 +108,14 @@ struct sunxi_cedrus_buffer *vb2_to_cedrus_buffer(const struct vb2_buffer *p)
return vb2_v4l2_to_cedrus_buffer(to_vb2_v4l2_buffer(p));
}
+struct sunxi_cedrus_dec_ops {
+ void (*setup)(struct sunxi_cedrus_ctx *ctx,
+ struct sunxi_cedrus_run *run);
+ void (*trigger)(struct sunxi_cedrus_ctx *ctx);
+};
+
+extern struct sunxi_cedrus_dec_ops sunxi_cedrus_dec_ops_mpeg2;
+
struct sunxi_cedrus_dev {
struct v4l2_device v4l2_dev;
struct video_device vfd;
@@ -130,6 +139,8 @@ struct sunxi_cedrus_dev {
struct reset_control *rstc;
struct regmap *syscon;
+
+ struct sunxi_cedrus_dec_ops *dec_ops[SUNXI_CEDRUS_CODEC_LAST];
};
static inline void sunxi_cedrus_write(struct sunxi_cedrus_dev *dev,
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c
index f274408ab5a7..5e552fa05274 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c
@@ -28,7 +28,6 @@
#include <media/v4l2-mem2mem.h>
#include "sunxi_cedrus_common.h"
-#include "sunxi_cedrus_mpeg2.h"
#include "sunxi_cedrus_dec.h"
#include "sunxi_cedrus_hw.h"
@@ -77,6 +76,7 @@ void sunxi_cedrus_device_work(struct work_struct *work)
void sunxi_cedrus_device_run(void *priv)
{
struct sunxi_cedrus_ctx *ctx = priv;
+ struct sunxi_cedrus_dev *dev = ctx->dev;
struct sunxi_cedrus_run run = { 0 };
struct media_request *src_req, *dst_req;
unsigned long flags;
@@ -120,8 +120,6 @@ void sunxi_cedrus_device_run(void *priv)
case V4L2_PIX_FMT_MPEG2_FRAME:
CHECK_CONTROL(ctx, SUNXI_CEDRUS_CTRL_DEC_MPEG2_FRAME_HDR);
run.mpeg2.hdr = get_ctrl_ptr(ctx, SUNXI_CEDRUS_CTRL_DEC_MPEG2_FRAME_HDR);
- sunxi_cedrus_mpeg2_setup(ctx, &run);
-
break;
default:
@@ -129,6 +127,9 @@ void sunxi_cedrus_device_run(void *priv)
}
#undef CHECK_CONTROL
+ if (!ctx->job_abort)
+ dev->dec_ops[ctx->current_codec]->setup(ctx, &run);
+
unlock_complete:
spin_unlock_irqrestore(&ctx->dev->irq_lock, flags);
@@ -143,8 +144,7 @@ void sunxi_cedrus_device_run(void *priv)
spin_lock_irqsave(&ctx->dev->irq_lock, flags);
if (!ctx->job_abort) {
- if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_MPEG2_FRAME)
- sunxi_cedrus_mpeg2_trigger(ctx);
+ dev->dec_ops[ctx->current_codec]->trigger(ctx);
} else {
v4l2_m2m_buf_done(run.src, VB2_BUF_STATE_ERROR);
v4l2_m2m_buf_done(run.dst, VB2_BUF_STATE_ERROR);
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c
index d1d7a3cfce0d..e25075bb5779 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c
@@ -52,8 +52,8 @@ static const u8 mpeg_default_non_intra_quant[64] = {
#define m_niq(i) ((i << 8) | mpeg_default_non_intra_quant[i])
-void sunxi_cedrus_mpeg2_setup(struct sunxi_cedrus_ctx *ctx,
- struct sunxi_cedrus_run *run)
+static void sunxi_cedrus_mpeg2_setup(struct sunxi_cedrus_ctx *ctx,
+ struct sunxi_cedrus_run *run)
{
struct sunxi_cedrus_dev *dev = ctx->dev;
const struct v4l2_ctrl_mpeg2_frame_hdr *frame_hdr = run->mpeg2.hdr;
@@ -148,9 +148,14 @@ void sunxi_cedrus_mpeg2_setup(struct sunxi_cedrus_ctx *ctx,
sunxi_cedrus_write(dev, src_buf_addr + VBV_SIZE - 1, VE_MPEG_VLD_END);
}
-void sunxi_cedrus_mpeg2_trigger(struct sunxi_cedrus_ctx *ctx)
+static void sunxi_cedrus_mpeg2_trigger(struct sunxi_cedrus_ctx *ctx)
{
struct sunxi_cedrus_dev *dev = ctx->dev;
sunxi_cedrus_write(dev, VE_TRIG_MPEG2, VE_MPEG_TRIGGER);
}
+
+struct sunxi_cedrus_dec_ops sunxi_cedrus_dec_ops_mpeg2 = {
+ .setup = sunxi_cedrus_mpeg2_setup,
+ .trigger = sunxi_cedrus_mpeg2_trigger,
+};
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.h b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.h
deleted file mode 100644
index 4c380becfa1a..000000000000
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Sunxi-Cedrus VPU driver
- *
- * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
- * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
- *
- * Based on the vim2m driver, that is:
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- * Pawel Osciak, <pawel@osciak.com>
- * Marek Szyprowski, <m.szyprowski@samsung.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef _SUNXI_CEDRUS_MPEG2_H_
-#define _SUNXI_CEDRUS_MPEG2_H_
-
-struct sunxi_cedrus_ctx;
-struct sunxi_cedrus_run;
-
-void sunxi_cedrus_mpeg2_setup(struct sunxi_cedrus_ctx *ctx,
- struct sunxi_cedrus_run *run);
-void sunxi_cedrus_mpeg2_trigger(struct sunxi_cedrus_ctx *ctx);
-
-#endif
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_video.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_video.c
index 089abfe6bfeb..fb7b081a5bb7 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_video.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_video.c
@@ -28,7 +28,6 @@
#include <media/v4l2-mem2mem.h>
#include "sunxi_cedrus_common.h"
-#include "sunxi_cedrus_mpeg2.h"
#include "sunxi_cedrus_dec.h"
#include "sunxi_cedrus_hw.h"
@@ -414,6 +413,21 @@ static int sunxi_cedrus_buf_prepare(struct vb2_buffer *vb)
return 0;
}
+static int sunxi_cedrus_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct sunxi_cedrus_ctx *ctx = vb2_get_drv_priv(q);
+
+ switch (ctx->vpu_src_fmt->fourcc) {
+ case V4L2_PIX_FMT_MPEG2_FRAME:
+ ctx->current_codec = SUNXI_CEDRUS_CODEC_MPEG2;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static void sunxi_cedrus_stop_streaming(struct vb2_queue *q)
{
struct sunxi_cedrus_ctx *ctx = vb2_get_drv_priv(q);
@@ -462,6 +476,7 @@ static struct vb2_ops sunxi_cedrus_qops = {
.buf_cleanup = sunxi_cedrus_buf_cleanup,
.buf_queue = sunxi_cedrus_buf_queue,
.buf_request_complete = sunxi_cedrus_buf_request_complete,
+ .start_streaming = sunxi_cedrus_start_streaming,
.stop_streaming = sunxi_cedrus_stop_streaming,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
--
2.17.0
^ permalink raw reply related
* [PATCH 7/9] media: cedrus: Move IRQ maintainance to cedrus_dec_ops
From: Maxime Ripard @ 2018-06-13 14:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613140714.1686-1-maxime.ripard@bootlin.com>
The IRQ handler up until now was hardcoding the use of the MPEG engine to
read the interrupt status, clear it and disable the interrupts.
Obviously, that won't work really well with the introduction of new codecs
that use a separate engine with a separate register set.
In order to make this more future proof, introduce new decodec operations
to deal with the interrupt management. The only one missing is the one to
enable the interrupts in the first place, but that's taken care of by the
trigger hook for now.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
.../sunxi/cedrus/sunxi_cedrus_common.h | 9 +++++
.../platform/sunxi/cedrus/sunxi_cedrus_hw.c | 21 ++++++------
.../sunxi/cedrus/sunxi_cedrus_mpeg2.c | 33 +++++++++++++++++++
3 files changed, 53 insertions(+), 10 deletions(-)
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
index c2e2c92d103b..a2a507eb9fc9 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
@@ -108,7 +108,16 @@ struct sunxi_cedrus_buffer *vb2_to_cedrus_buffer(const struct vb2_buffer *p)
return vb2_v4l2_to_cedrus_buffer(to_vb2_v4l2_buffer(p));
}
+enum sunxi_cedrus_irq_status {
+ SUNXI_CEDRUS_IRQ_NONE,
+ SUNXI_CEDRUS_IRQ_ERROR,
+ SUNXI_CEDRUS_IRQ_OK,
+};
+
struct sunxi_cedrus_dec_ops {
+ void (*irq_clear)(struct sunxi_cedrus_ctx *ctx);
+ void (*irq_disable)(struct sunxi_cedrus_ctx *ctx);
+ enum sunxi_cedrus_irq_status (*irq_status)(struct sunxi_cedrus_ctx *ctx);
void (*setup)(struct sunxi_cedrus_ctx *ctx,
struct sunxi_cedrus_run *run);
void (*trigger)(struct sunxi_cedrus_ctx *ctx);
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c
index bb46a01214e0..6b97cbd2834e 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c
@@ -77,27 +77,28 @@ static irqreturn_t sunxi_cedrus_ve_irq(int irq, void *dev_id)
struct sunxi_cedrus_ctx *ctx;
struct sunxi_cedrus_buffer *src_buffer, *dst_buffer;
struct vb2_v4l2_buffer *src_vb, *dst_vb;
+ enum sunxi_cedrus_irq_status status;
unsigned long flags;
- unsigned int value, status;
spin_lock_irqsave(&dev->irq_lock, flags);
- /* Disable MPEG interrupts and stop the MPEG engine */
- value = sunxi_cedrus_read(dev, VE_MPEG_CTRL);
- sunxi_cedrus_write(dev, value & (~0xf), VE_MPEG_CTRL);
-
- status = sunxi_cedrus_read(dev, VE_MPEG_STATUS);
- sunxi_cedrus_write(dev, 0x0000c00f, VE_MPEG_STATUS);
- sunxi_cedrus_engine_disable(dev);
-
ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
if (!ctx) {
pr_err("Instance released before the end of transaction\n");
spin_unlock_irqrestore(&dev->irq_lock, flags);
- return IRQ_HANDLED;
+ return IRQ_NONE;
}
+ status = dev->dec_ops[ctx->current_codec]->irq_status(ctx);
+ if (status == SUNXI_CEDRUS_IRQ_NONE) {
+ spin_unlock_irqrestore(&dev->irq_lock, flags);
+ return IRQ_NONE;
+ }
+
+ dev->dec_ops[ctx->current_codec]->irq_disable(ctx);
+ dev->dec_ops[ctx->current_codec]->irq_clear(ctx);
+
src_vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c
index e25075bb5779..51fa0c0f9bf2 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_mpeg2.c
@@ -52,6 +52,36 @@ static const u8 mpeg_default_non_intra_quant[64] = {
#define m_niq(i) ((i << 8) | mpeg_default_non_intra_quant[i])
+static enum sunxi_cedrus_irq_status
+sunxi_cedrus_mpeg2_irq_status(struct sunxi_cedrus_ctx *ctx)
+{
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+ u32 reg = sunxi_cedrus_read(dev, VE_MPEG_STATUS) & 0x7;
+
+ if (!reg)
+ return SUNXI_CEDRUS_IRQ_NONE;
+
+ if (reg & (BIT(1) | BIT(2)))
+ return SUNXI_CEDRUS_IRQ_ERROR;
+
+ return SUNXI_CEDRUS_IRQ_OK;
+}
+
+static void sunxi_cedrus_mpeg2_irq_clear(struct sunxi_cedrus_ctx *ctx)
+{
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+
+ sunxi_cedrus_write(dev, GENMASK(2, 0), VE_MPEG_STATUS);
+}
+
+static void sunxi_cedrus_mpeg2_irq_disable(struct sunxi_cedrus_ctx *ctx)
+{
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+ u32 reg = sunxi_cedrus_read(dev, VE_MPEG_CTRL) & ~BIT(3);
+
+ sunxi_cedrus_write(dev, reg, VE_MPEG_CTRL);
+}
+
static void sunxi_cedrus_mpeg2_setup(struct sunxi_cedrus_ctx *ctx,
struct sunxi_cedrus_run *run)
{
@@ -156,6 +186,9 @@ static void sunxi_cedrus_mpeg2_trigger(struct sunxi_cedrus_ctx *ctx)
}
struct sunxi_cedrus_dec_ops sunxi_cedrus_dec_ops_mpeg2 = {
+ .irq_clear = sunxi_cedrus_mpeg2_irq_clear,
+ .irq_disable = sunxi_cedrus_mpeg2_irq_disable,
+ .irq_status = sunxi_cedrus_mpeg2_irq_status,
.setup = sunxi_cedrus_mpeg2_setup,
.trigger = sunxi_cedrus_mpeg2_trigger,
};
--
2.17.0
^ permalink raw reply related
* [PATCH 8/9] media: cedrus: Add start and stop decoder operations
From: Maxime Ripard @ 2018-06-13 14:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613140714.1686-1-maxime.ripard@bootlin.com>
Some codec needs to perform some additional task when a decoding is started
and stopped, and not only at every frame.
For example, the H264 decoding support needs to allocate buffers that will
be used in the decoding process, but do not need to change over time, or at
each frame.
In order to allow that for codecs, introduce a start and stop hook that
will be called if present at start_streaming and stop_streaming time.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
.../platform/sunxi/cedrus/sunxi_cedrus_common.h | 2 ++
.../platform/sunxi/cedrus/sunxi_cedrus_video.c | 14 +++++++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
index a2a507eb9fc9..20c78ec1f037 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
@@ -120,6 +120,8 @@ struct sunxi_cedrus_dec_ops {
enum sunxi_cedrus_irq_status (*irq_status)(struct sunxi_cedrus_ctx *ctx);
void (*setup)(struct sunxi_cedrus_ctx *ctx,
struct sunxi_cedrus_run *run);
+ int (*start)(struct sunxi_cedrus_ctx *ctx);
+ void (*stop)(struct sunxi_cedrus_ctx *ctx);
void (*trigger)(struct sunxi_cedrus_ctx *ctx);
};
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_video.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_video.c
index fb7b081a5bb7..d93461178857 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_video.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_video.c
@@ -416,6 +416,8 @@ static int sunxi_cedrus_buf_prepare(struct vb2_buffer *vb)
static int sunxi_cedrus_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct sunxi_cedrus_ctx *ctx = vb2_get_drv_priv(q);
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+ int ret = 0;
switch (ctx->vpu_src_fmt->fourcc) {
case V4L2_PIX_FMT_MPEG2_FRAME:
@@ -425,16 +427,26 @@ static int sunxi_cedrus_start_streaming(struct vb2_queue *q, unsigned int count)
return -EINVAL;
}
- return 0;
+ if (V4L2_TYPE_IS_OUTPUT(q->type) &&
+ dev->dec_ops[ctx->current_codec]->start)
+ ret = dev->dec_ops[ctx->current_codec]->start(ctx);
+
+ return ret;
}
static void sunxi_cedrus_stop_streaming(struct vb2_queue *q)
{
struct sunxi_cedrus_ctx *ctx = vb2_get_drv_priv(q);
+ struct sunxi_cedrus_dev *dev = ctx->dev;
struct vb2_v4l2_buffer *vbuf;
unsigned long flags;
flush_scheduled_work();
+
+ if (V4L2_TYPE_IS_OUTPUT(q->type) &&
+ dev->dec_ops[ctx->current_codec]->stop)
+ dev->dec_ops[ctx->current_codec]->stop(ctx);
+
for (;;) {
spin_lock_irqsave(&ctx->dev->irq_lock, flags);
--
2.17.0
^ permalink raw reply related
* [PATCH 9/9] media: cedrus: Add H264 decoding support
From: Maxime Ripard @ 2018-06-13 14:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180613140714.1686-1-maxime.ripard@bootlin.com>
Introduce some basic H264 decoding support in cedrus. So far, only the
baseline profile videos have been tested, and some more advanced features
used in higher profiles are not even implemented.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
drivers/media/platform/sunxi/cedrus/Makefile | 2 +-
.../platform/sunxi/cedrus/sunxi_cedrus.c | 21 +
.../sunxi/cedrus/sunxi_cedrus_common.h | 41 +-
.../platform/sunxi/cedrus/sunxi_cedrus_dec.c | 12 +
.../platform/sunxi/cedrus/sunxi_cedrus_h264.c | 443 ++++++++++++++++++
.../platform/sunxi/cedrus/sunxi_cedrus_hw.c | 4 +
.../platform/sunxi/cedrus/sunxi_cedrus_regs.h | 22 +-
.../sunxi/cedrus/sunxi_cedrus_video.c | 8 +
8 files changed, 542 insertions(+), 11 deletions(-)
create mode 100644 drivers/media/platform/sunxi/cedrus/sunxi_cedrus_h264.c
diff --git a/drivers/media/platform/sunxi/cedrus/Makefile b/drivers/media/platform/sunxi/cedrus/Makefile
index 98f30df626a9..715f4f67b743 100644
--- a/drivers/media/platform/sunxi/cedrus/Makefile
+++ b/drivers/media/platform/sunxi/cedrus/Makefile
@@ -1,4 +1,4 @@
obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += sunxi-cedrus.o
sunxi-cedrus-y = sunxi_cedrus.o sunxi_cedrus_video.o sunxi_cedrus_hw.o \
- sunxi_cedrus_dec.o sunxi_cedrus_mpeg2.o
+ sunxi_cedrus_dec.o sunxi_cedrus_mpeg2.o sunxi_cedrus_h264.o
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus.c
index bc80480f5dfd..581a99ba00c8 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus.c
@@ -41,6 +41,10 @@ static int sunxi_cedrus_s_ctrl(struct v4l2_ctrl *ctrl)
container_of(ctrl->handler, struct sunxi_cedrus_ctx, hdl);
switch (ctrl->id) {
+ case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAM:
+ case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAM:
+ case V4L2_CID_MPEG_VIDEO_H264_SPS:
+ case V4L2_CID_MPEG_VIDEO_H264_PPS:
case V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR:
/* This is kept in memory and used directly. */
break;
@@ -57,6 +61,22 @@ static const struct v4l2_ctrl_ops sunxi_cedrus_ctrl_ops = {
};
static const struct sunxi_cedrus_control controls[] = {
+ [SUNXI_CEDRUS_CTRL_DEC_H264_DECODE_PARAM] = {
+ .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAM,
+ .elem_size = sizeof(struct v4l2_ctrl_h264_decode_param),
+ },
+ [SUNXI_CEDRUS_CTRL_DEC_H264_SLICE_PARAM] = {
+ .id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAM,
+ .elem_size = sizeof(struct v4l2_ctrl_h264_slice_param),
+ },
+ [SUNXI_CEDRUS_CTRL_DEC_H264_SPS] = {
+ .id = V4L2_CID_MPEG_VIDEO_H264_SPS,
+ .elem_size = sizeof(struct v4l2_ctrl_h264_sps),
+ },
+ [SUNXI_CEDRUS_CTRL_DEC_H264_PPS] = {
+ .id = V4L2_CID_MPEG_VIDEO_H264_PPS,
+ .elem_size = sizeof(struct v4l2_ctrl_h264_pps),
+ },
[SUNXI_CEDRUS_CTRL_DEC_MPEG2_FRAME_HDR] = {
.id = V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR,
.elem_size = sizeof(struct v4l2_ctrl_mpeg2_frame_hdr),
@@ -244,6 +264,7 @@ static int sunxi_cedrus_probe(struct platform_device *pdev)
if (ret)
return ret;
+ dev->dec_ops[SUNXI_CEDRUS_CODEC_H264] = &sunxi_cedrus_dec_ops_h264;
dev->dec_ops[SUNXI_CEDRUS_CODEC_MPEG2] = &sunxi_cedrus_dec_ops_mpeg2;
ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
index 20c78ec1f037..1ab06ee68ce6 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_common.h
@@ -32,7 +32,11 @@
#define SUNXI_CEDRUS_NAME "sunxi-cedrus"
enum sunxi_cedrus_control_id {
- SUNXI_CEDRUS_CTRL_DEC_MPEG2_FRAME_HDR = 0,
+ SUNXI_CEDRUS_CTRL_DEC_H264_DECODE_PARAM = 0,
+ SUNXI_CEDRUS_CTRL_DEC_H264_PPS,
+ SUNXI_CEDRUS_CTRL_DEC_H264_SLICE_PARAM,
+ SUNXI_CEDRUS_CTRL_DEC_H264_SPS,
+ SUNXI_CEDRUS_CTRL_DEC_MPEG2_FRAME_HDR,
SUNXI_CEDRUS_CTRL_MAX,
};
@@ -48,6 +52,13 @@ struct sunxi_cedrus_fmt {
unsigned int num_planes;
};
+struct sunxi_cedrus_h264_run {
+ const struct v4l2_ctrl_h264_decode_param *decode_param;
+ const struct v4l2_ctrl_h264_pps *pps;
+ const struct v4l2_ctrl_h264_slice_param *slice_param;
+ const struct v4l2_ctrl_h264_sps *sps;
+};
+
struct sunxi_cedrus_mpeg2_run {
const struct v4l2_ctrl_mpeg2_frame_hdr *hdr;
};
@@ -57,12 +68,14 @@ struct sunxi_cedrus_run {
struct vb2_v4l2_buffer *dst;
union {
+ struct sunxi_cedrus_h264_run h264;
struct sunxi_cedrus_mpeg2_run mpeg2;
};
};
enum sunxi_cedrus_codec {
SUNXI_CEDRUS_CODEC_MPEG2,
+ SUNXI_CEDRUS_CODEC_H264,
SUNXI_CEDRUS_CODEC_LAST,
};
@@ -88,12 +101,37 @@ struct sunxi_cedrus_ctx {
struct work_struct run_work;
struct list_head src_list;
struct list_head dst_list;
+
+ union {
+ struct {
+ void *mv_col_buf;
+ dma_addr_t mv_col_buf_dma;
+ ssize_t mv_col_buf_size;
+ void *neighbor_info_buf;
+ dma_addr_t neighbor_info_buf_dma;
+ void *pic_info_buf;
+ dma_addr_t pic_info_buf_dma;
+ } h264;
+ } codec;
+};
+
+enum sunxi_cedrus_h264_pic_type {
+ SUNXI_CEDRUS_H264_PIC_TYPE_FRAME = 0,
+ SUNXI_CEDRUS_H264_PIC_TYPE_FIELD,
+ SUNXI_CEDRUS_H264_PIC_TYPE_MBAFF,
};
struct sunxi_cedrus_buffer {
struct vb2_v4l2_buffer vb;
enum vb2_buffer_state state;
struct list_head list;
+
+ union {
+ struct {
+ unsigned int position;
+ enum sunxi_cedrus_h264_pic_type pic_type;
+ } h264;
+ } codec;
};
static inline
@@ -125,6 +163,7 @@ struct sunxi_cedrus_dec_ops {
void (*trigger)(struct sunxi_cedrus_ctx *ctx);
};
+extern struct sunxi_cedrus_dec_ops sunxi_cedrus_dec_ops_h264;
extern struct sunxi_cedrus_dec_ops sunxi_cedrus_dec_ops_mpeg2;
struct sunxi_cedrus_dev {
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c
index 5e552fa05274..c29a2582ed68 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_dec.c
@@ -122,6 +122,18 @@ void sunxi_cedrus_device_run(void *priv)
run.mpeg2.hdr = get_ctrl_ptr(ctx, SUNXI_CEDRUS_CTRL_DEC_MPEG2_FRAME_HDR);
break;
+ case V4L2_PIX_FMT_H264_SLICE:
+ CHECK_CONTROL(ctx, SUNXI_CEDRUS_CTRL_DEC_H264_DECODE_PARAM);
+ CHECK_CONTROL(ctx, SUNXI_CEDRUS_CTRL_DEC_H264_SLICE_PARAM);
+ CHECK_CONTROL(ctx, SUNXI_CEDRUS_CTRL_DEC_H264_SPS);
+ CHECK_CONTROL(ctx, SUNXI_CEDRUS_CTRL_DEC_H264_PPS);
+
+ run.h264.decode_param = get_ctrl_ptr(ctx, SUNXI_CEDRUS_CTRL_DEC_H264_DECODE_PARAM);
+ run.h264.pps = get_ctrl_ptr(ctx, SUNXI_CEDRUS_CTRL_DEC_H264_PPS);
+ run.h264.slice_param = get_ctrl_ptr(ctx, SUNXI_CEDRUS_CTRL_DEC_H264_SLICE_PARAM);
+ run.h264.sps = get_ctrl_ptr(ctx, SUNXI_CEDRUS_CTRL_DEC_H264_SPS);
+ break;
+
default:
ctx->job_abort = 1;
}
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_h264.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_h264.c
new file mode 100644
index 000000000000..0c86f66eb614
--- /dev/null
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_h264.c
@@ -0,0 +1,443 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2013 Jens Kuske <jenskuske@gmail.com>
+ * Copyright (c) 2018 Bootlin
+ */
+
+#include <linux/types.h>
+
+#include <media/videobuf2-dma-contig.h>
+
+#include "sunxi_cedrus_common.h"
+#include "sunxi_cedrus_hw.h"
+#include "sunxi_cedrus_regs.h"
+
+enum sunxi_cedrus_h264_sram_off {
+ SUNXI_CEDRUS_SRAM_H264_PRED_WEIGHT_TABLE = 0x000,
+ SUNXI_CEDRUS_SRAM_H264_FRAMEBUFFER_LIST = 0x100,
+ SUNXI_CEDRUS_SRAM_H264_REF_LIST_0 = 0x190,
+ SUNXI_CEDRUS_SRAM_H264_REF_LIST_1 = 0x199,
+ SUNXI_CEDRUS_SRAM_H264_SCALING_LIST_8x8 = 0x200,
+ SUNXI_CEDRUS_SRAM_H264_SCALING_LIST_4x4 = 0x218,
+};
+
+struct sunxi_cedrus_h264_sram_ref_pic {
+ __le32 top_field_order_cnt;
+ __le32 bottom_field_order_cnt;
+ __le32 frame_info;
+ __le32 luma_ptr;
+ __le32 chroma_ptr;
+ __le32 extra_data_ptr;
+ __le32 extra_data_end;
+ __le32 reserved;
+} __packed;
+
+/* One for the output, 16 for the reference images */
+#define SUNXI_CEDRUS_H264_FRAME_NUM 17
+
+#define SUNXI_CEDRUS_PIC_INFO_BUF_SIZE (128 * SZ_1K)
+#define SUNXI_CEDRUS_NEIGHBOR_INFO_BUF_SIZE (16 * SZ_1K)
+
+static void sunxi_cedrus_h264_write_sram(struct sunxi_cedrus_dev *dev,
+ enum sunxi_cedrus_h264_sram_off off,
+ const void *data, size_t len)
+{
+ const u32 *buffer = data;
+ size_t count = DIV_ROUND_UP(len, 4);
+
+ sunxi_cedrus_write(dev, off << 2,
+ VE_AVC_SRAM_PORT_OFFSET);
+
+ do {
+ sunxi_cedrus_write(dev, *buffer++, VE_AVC_SRAM_PORT_DATA);
+ } while (--count);
+}
+
+static void sunxi_cedrus_fill_ref_pic(struct sunxi_cedrus_h264_sram_ref_pic *pic,
+ struct vb2_buffer *buf,
+ dma_addr_t extra_buf,
+ size_t extra_buf_len,
+ unsigned int top_field_order_cnt,
+ unsigned int bottom_field_order_cnt,
+ enum sunxi_cedrus_h264_pic_type pic_type)
+{
+ pic->top_field_order_cnt = top_field_order_cnt;
+ pic->bottom_field_order_cnt = bottom_field_order_cnt;
+ pic->frame_info = pic_type << 8;
+ pic->luma_ptr = vb2_dma_contig_plane_dma_addr(buf, 0) - PHYS_OFFSET;
+ pic->chroma_ptr = vb2_dma_contig_plane_dma_addr(buf, 1) - PHYS_OFFSET;
+ pic->extra_data_ptr = extra_buf - PHYS_OFFSET;
+ pic->extra_data_end = (extra_buf - PHYS_OFFSET) + extra_buf_len;
+}
+
+static void sunxi_cedrus_write_frame_list(struct sunxi_cedrus_ctx *ctx,
+ struct sunxi_cedrus_run *run)
+{
+ struct sunxi_cedrus_h264_sram_ref_pic pic_list[SUNXI_CEDRUS_H264_FRAME_NUM];
+ const struct v4l2_ctrl_h264_decode_param *dec_param = run->h264.decode_param;
+ const struct v4l2_ctrl_h264_slice_param *slice = run->h264.slice_param;
+ const struct v4l2_ctrl_h264_sps *sps = run->h264.sps;
+ struct sunxi_cedrus_buffer *output_buf;
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+ unsigned long used_dpbs = 0;
+ unsigned int position;
+ unsigned int output = 0;
+ unsigned int i;
+
+ memset(pic_list, 0, sizeof(pic_list));
+
+ for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
+ const struct v4l2_h264_dpb_entry *dpb = &dec_param->dpb[i];
+ const struct sunxi_cedrus_buffer *cedrus_buf;
+ struct vb2_buffer *ref_buf;
+
+ if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
+ continue;
+
+ ref_buf = ctx->dst_bufs[dpb->buf_index];
+ cedrus_buf = vb2_to_cedrus_buffer(ref_buf);
+ position = cedrus_buf->codec.h264.position;
+ used_dpbs |= BIT(position);
+
+ sunxi_cedrus_fill_ref_pic(&pic_list[position], ref_buf,
+ ctx->codec.h264.mv_col_buf_dma,
+ ctx->codec.h264.mv_col_buf_size,
+ dpb->top_field_order_cnt,
+ dpb->bottom_field_order_cnt,
+ cedrus_buf->codec.h264.pic_type);
+
+ output = max(position, output);
+ }
+
+ position = find_next_zero_bit(&used_dpbs, 17, output);
+ if (position >= 17)
+ position = find_first_zero_bit(&used_dpbs, 17);
+
+ output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
+ output_buf->codec.h264.position = position;
+
+ if (slice->flags & V4L2_SLICE_FLAG_FIELD_PIC)
+ output_buf->codec.h264.pic_type = SUNXI_CEDRUS_H264_PIC_TYPE_FIELD;
+ else if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
+ output_buf->codec.h264.pic_type = SUNXI_CEDRUS_H264_PIC_TYPE_MBAFF;
+ else
+ output_buf->codec.h264.pic_type = SUNXI_CEDRUS_H264_PIC_TYPE_FRAME;
+
+ sunxi_cedrus_fill_ref_pic(&pic_list[position], &run->dst->vb2_buf,
+ ctx->codec.h264.mv_col_buf_dma,
+ ctx->codec.h264.mv_col_buf_size,
+ dec_param->top_field_order_cnt,
+ dec_param->bottom_field_order_cnt,
+ output_buf->codec.h264.pic_type);
+
+ sunxi_cedrus_h264_write_sram(dev, SUNXI_CEDRUS_SRAM_H264_FRAMEBUFFER_LIST,
+ pic_list, sizeof(pic_list));
+
+ sunxi_cedrus_write(dev, position, VE_H264_OUTPUT_FRAME_IDX);
+}
+
+#define SUNXI_CEDRUS_MAX_REF_IDX 32
+
+static void _sunxi_cedrus_write_ref_list(struct sunxi_cedrus_ctx *ctx,
+ struct sunxi_cedrus_run *run,
+ const u8 *ref_list, u8 num_ref,
+ enum sunxi_cedrus_h264_sram_off sram)
+{
+ const struct v4l2_ctrl_h264_decode_param *decode = run->h264.decode_param;
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+ u32 sram_array[SUNXI_CEDRUS_MAX_REF_IDX / sizeof(u32)];
+ unsigned int size, i;
+
+ memset(sram_array, 0, sizeof(sram_array));
+
+ for (i = 0; i < num_ref; i += 4) {
+ unsigned int j;
+
+ for (j = 0; j < 4; j++) {
+ const struct v4l2_h264_dpb_entry *dpb;
+ const struct sunxi_cedrus_buffer *cedrus_buf;
+ const struct vb2_v4l2_buffer *ref_buf;
+ unsigned int position;
+ u8 ref_idx = i + j;
+ u8 dpb_idx;
+
+ if (ref_idx >= num_ref)
+ break;
+
+ dpb_idx = ref_list[ref_idx];
+ dpb = &decode->dpb[dpb_idx];
+
+ if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
+ continue;
+
+ ref_buf = to_vb2_v4l2_buffer(ctx->dst_bufs[dpb->buf_index]);
+ cedrus_buf = vb2_v4l2_to_cedrus_buffer(ref_buf);
+ position = cedrus_buf->codec.h264.position;
+
+ sram_array[i] |= position << (j * 8 + 1);
+ if (ref_buf->field == V4L2_FIELD_BOTTOM)
+ sram_array[i] |= BIT(j * 8);
+ }
+ }
+
+ size = min((unsigned int)ALIGN(num_ref, 4), sizeof(sram_array));
+ sunxi_cedrus_h264_write_sram(dev, sram, &sram_array, size);
+}
+
+static void sunxi_cedrus_write_ref_list0(struct sunxi_cedrus_ctx *ctx,
+ struct sunxi_cedrus_run *run)
+{
+ const struct v4l2_ctrl_h264_slice_param *slice = run->h264.slice_param;
+
+ _sunxi_cedrus_write_ref_list(ctx, run,
+ slice->ref_pic_list0,
+ slice->num_ref_idx_l0_active_minus1 + 1,
+ SUNXI_CEDRUS_SRAM_H264_REF_LIST_0);
+}
+
+static void sunxi_cedrus_write_ref_list1(struct sunxi_cedrus_ctx *ctx,
+ struct sunxi_cedrus_run *run)
+{
+ const struct v4l2_ctrl_h264_slice_param *slice = run->h264.slice_param;
+
+ _sunxi_cedrus_write_ref_list(ctx, run,
+ slice->ref_pic_list1,
+ slice->num_ref_idx_l1_active_minus1 + 1,
+ SUNXI_CEDRUS_SRAM_H264_REF_LIST_1);
+}
+
+static void sunxi_cedrus_set_params(struct sunxi_cedrus_ctx *ctx,
+ struct sunxi_cedrus_run *run)
+{
+ const struct v4l2_ctrl_h264_slice_param *slice = run->h264.slice_param;
+ const struct v4l2_ctrl_h264_pps *pps = run->h264.pps;
+ const struct v4l2_ctrl_h264_sps *sps = run->h264.sps;
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+ dma_addr_t src_buf_addr;
+ u32 offset = slice->header_bit_size;
+ u32 len = (slice->size * 8) - offset;
+ u32 reg;
+
+ sunxi_cedrus_write(dev, ctx->codec.h264.pic_info_buf_dma - PHYS_OFFSET, 0x250);
+ sunxi_cedrus_write(dev, (ctx->codec.h264.pic_info_buf_dma - PHYS_OFFSET) + 0x48000, 0x254);
+
+ sunxi_cedrus_write(dev, len, VE_H264_VLD_LEN);
+ sunxi_cedrus_write(dev, offset, VE_H264_VLD_OFFSET);
+
+ src_buf_addr = vb2_dma_contig_plane_dma_addr(&run->src->vb2_buf, 0);
+ src_buf_addr -= PHYS_OFFSET;
+ sunxi_cedrus_write(dev, VE_H264_VLD_ADDR_VAL(src_buf_addr) |
+ VE_H264_VLD_ADDR_FIRST | VE_H264_VLD_ADDR_VALID | VE_H264_VLD_ADDR_LAST,
+ VE_H264_VLD_ADDR);
+ sunxi_cedrus_write(dev, src_buf_addr + VBV_SIZE - 1, VE_H264_VLD_END);
+
+ sunxi_cedrus_write(dev, VE_H264_TRIGGER_TYPE_INIT_SWDEC,
+ VE_H264_TRIGGER_TYPE);
+
+ if ((slice->slice_type == V4L2_H264_SLICE_TYPE_P) ||
+ (slice->slice_type == V4L2_H264_SLICE_TYPE_SP) ||
+ (slice->slice_type == V4L2_H264_SLICE_TYPE_B))
+ sunxi_cedrus_write_ref_list0(ctx, run);
+
+ if (slice->slice_type == V4L2_H264_SLICE_TYPE_B)
+ sunxi_cedrus_write_ref_list1(ctx, run);
+
+ // picture parameters
+ reg = 0;
+ /*
+ * FIXME: the kernel headers are allowing the default value to
+ * be passed, but the libva doesn't give us that.
+ */
+ reg |= (slice->num_ref_idx_l0_active_minus1 & 0x1f) << 10;
+ reg |= (slice->num_ref_idx_l1_active_minus1 & 0x1f) << 5;
+ reg |= (pps->weighted_bipred_idc & 0x3) << 2;
+ if (pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE)
+ reg |= BIT(15);
+ if (pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED)
+ reg |= BIT(4);
+ if (pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED)
+ reg |= BIT(1);
+ if (pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE)
+ reg |= BIT(0);
+ sunxi_cedrus_write(dev, reg, VE_H264_PIC_HDR);
+
+ // sequence parameters
+ reg = BIT(19);
+ reg |= (sps->pic_width_in_mbs_minus1 & 0xff) << 8;
+ reg |= sps->pic_height_in_map_units_minus1 & 0xff;
+ if (sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)
+ reg |= BIT(18);
+ if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
+ reg |= BIT(17);
+ if (sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE)
+ reg |= BIT(16);
+ sunxi_cedrus_write(dev, reg, VE_H264_FRAME_SIZE);
+
+ // slice parameters
+ reg = 0;
+ /*
+ * FIXME: This bit marks all the frames as references. This
+ * should probably be set based on nal_ref_idc, but the libva
+ * doesn't pass that information along, so this is not always
+ * available. We should find something else, maybe change the
+ * kernel UAPI somehow?
+ */
+ reg |= BIT(12);
+ reg |= (slice->slice_type & 0xf) << 8;
+ reg |= slice->cabac_init_idc & 0x3;
+ reg |= BIT(5);
+ if (slice->flags & V4L2_SLICE_FLAG_FIELD_PIC)
+ reg |= BIT(4);
+ if (slice->flags & V4L2_SLICE_FLAG_BOTTOM_FIELD)
+ reg |= BIT(3);
+ if (slice->flags & V4L2_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED)
+ reg |= BIT(2);
+ sunxi_cedrus_write(dev, reg, VE_H264_SLICE_HDR);
+
+ reg = 0;
+ reg |= (slice->num_ref_idx_l0_active_minus1 & 0x1f) << 24;
+ reg |= (slice->num_ref_idx_l1_active_minus1 & 0x1f) << 16;
+ reg |= (slice->disable_deblocking_filter_idc & 0x3) << 8;
+ reg |= (slice->slice_alpha_c0_offset_div2 & 0xf) << 4;
+ reg |= slice->slice_beta_offset_div2 & 0xf;
+ sunxi_cedrus_write(dev, reg, VE_H264_SLICE_HDR2);
+
+ reg = 0;
+ /*
+ * FIXME: This bit tells the video engine to use the default
+ * quantization matrices. This will obviously need to be
+ * changed to support the profiles supporting custom
+ * quantization matrices.
+ */
+ reg |= BIT(24);
+ reg |= (pps->second_chroma_qp_index_offset & 0x3f) << 16;
+ reg |= (pps->chroma_qp_index_offset & 0x3f) << 8;
+ reg |= (pps->pic_init_qp_minus26 + 26 + slice->slice_qp_delta) & 0x3f;
+ sunxi_cedrus_write(dev, reg, VE_H264_QP_PARAM);
+
+ // clear status flags
+ sunxi_cedrus_write(dev, sunxi_cedrus_read(dev, VE_H264_STATUS), VE_H264_STATUS);
+
+ // enable int
+ reg = sunxi_cedrus_read(dev, VE_H264_CTRL) | 0x7;
+ sunxi_cedrus_write(dev, reg, VE_H264_CTRL);
+}
+
+static enum sunxi_cedrus_irq_status
+sunxi_cedrus_h264_irq_status(struct sunxi_cedrus_ctx *ctx)
+{
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+ u32 reg = sunxi_cedrus_read(dev, VE_H264_STATUS) & 0x7;
+
+ if (!reg)
+ return SUNXI_CEDRUS_IRQ_NONE;
+
+ if (reg & (BIT(1) | BIT(2)))
+ return SUNXI_CEDRUS_IRQ_ERROR;
+
+ return SUNXI_CEDRUS_IRQ_OK;
+}
+
+static void sunxi_cedrus_h264_irq_clear(struct sunxi_cedrus_ctx *ctx)
+{
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+
+ sunxi_cedrus_write(dev, GENMASK(2, 0), VE_H264_STATUS);
+}
+
+static void sunxi_cedrus_h264_irq_disable(struct sunxi_cedrus_ctx *ctx)
+{
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+ u32 reg = sunxi_cedrus_read(dev, VE_H264_CTRL) & ~GENMASK(2, 0);
+
+ sunxi_cedrus_write(dev, reg, VE_H264_CTRL);
+}
+
+static void sunxi_cedrus_h264_setup(struct sunxi_cedrus_ctx *ctx,
+ struct sunxi_cedrus_run *run)
+{
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+
+ sunxi_cedrus_engine_enable(dev, SUNXI_CEDRUS_CODEC_H264);
+
+ sunxi_cedrus_write_frame_list(ctx, run);
+ sunxi_cedrus_set_params(ctx, run);
+}
+
+static int sunxi_cedrus_h264_start(struct sunxi_cedrus_ctx *ctx)
+{
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+ int ret;
+
+ ctx->codec.h264.pic_info_buf =
+ dma_alloc_coherent(dev->dev, SUNXI_CEDRUS_PIC_INFO_BUF_SIZE,
+ &ctx->codec.h264.pic_info_buf_dma,
+ GFP_KERNEL);
+ if (!ctx->codec.h264.pic_info_buf)
+ return -ENOMEM;
+
+ ctx->codec.h264.neighbor_info_buf =
+ dma_alloc_coherent(dev->dev, SUNXI_CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
+ &ctx->codec.h264.neighbor_info_buf_dma,
+ GFP_KERNEL);
+ if (!ctx->codec.h264.neighbor_info_buf) {
+ ret = -ENOMEM;
+ goto err_pic_buf;
+ }
+
+ ctx->codec.h264.mv_col_buf_size = DIV_ROUND_UP(ctx->src_fmt.width, 16) *
+ DIV_ROUND_UP(ctx->src_fmt.height, 16) * 32;
+ ctx->codec.h264.mv_col_buf = dma_alloc_coherent(dev->dev,
+ ctx->codec.h264.mv_col_buf_size,
+ &ctx->codec.h264.mv_col_buf_dma,
+ GFP_KERNEL);
+ if (!ctx->codec.h264.mv_col_buf) {
+ ret = -ENOMEM;
+ goto err_neighbor_buf;
+ }
+
+ return 0;
+
+err_neighbor_buf:
+ dma_free_coherent(dev->dev, SUNXI_CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
+ ctx->codec.h264.neighbor_info_buf,
+ ctx->codec.h264.neighbor_info_buf_dma);
+err_pic_buf:
+ dma_free_coherent(dev->dev, SUNXI_CEDRUS_PIC_INFO_BUF_SIZE,
+ ctx->codec.h264.pic_info_buf,
+ ctx->codec.h264.pic_info_buf_dma);
+ return ret;
+}
+
+static void sunxi_cedrus_h264_stop(struct sunxi_cedrus_ctx *ctx)
+{
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+
+ dma_free_coherent(dev->dev, ctx->codec.h264.mv_col_buf_size,
+ ctx->codec.h264.mv_col_buf,
+ ctx->codec.h264.mv_col_buf_dma);
+ dma_free_coherent(dev->dev, SUNXI_CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
+ ctx->codec.h264.neighbor_info_buf,
+ ctx->codec.h264.neighbor_info_buf_dma);
+ dma_free_coherent(dev->dev, SUNXI_CEDRUS_PIC_INFO_BUF_SIZE,
+ ctx->codec.h264.pic_info_buf,
+ ctx->codec.h264.pic_info_buf_dma);
+}
+
+static void sunxi_cedrus_h264_trigger(struct sunxi_cedrus_ctx *ctx)
+{
+ struct sunxi_cedrus_dev *dev = ctx->dev;
+
+ sunxi_cedrus_write(dev, VE_H264_TRIGGER_TYPE_AVC_SLICE_DECODE,
+ VE_H264_TRIGGER_TYPE);
+}
+
+struct sunxi_cedrus_dec_ops sunxi_cedrus_dec_ops_h264 = {
+ .irq_clear = sunxi_cedrus_h264_irq_clear,
+ .irq_disable = sunxi_cedrus_h264_irq_disable,
+ .irq_status = sunxi_cedrus_h264_irq_status,
+ .setup = sunxi_cedrus_h264_setup,
+ .start = sunxi_cedrus_h264_start,
+ .stop = sunxi_cedrus_h264_stop,
+ .trigger = sunxi_cedrus_h264_trigger,
+};
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c
index 6b97cbd2834e..e304457fce34 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_hw.c
@@ -58,6 +58,10 @@ int sunxi_cedrus_engine_enable(struct sunxi_cedrus_dev *dev,
reg |= VE_CTRL_DEC_MODE_MPEG;
break;
+ case SUNXI_CEDRUS_CODEC_H264:
+ reg |= VE_CTRL_DEC_MODE_H264;
+ break;
+
default:
return -EINVAL;
}
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_regs.h b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_regs.h
index 6705d41dad07..a79de1b154b0 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_regs.h
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_regs.h
@@ -124,10 +124,20 @@
#define VE_H264_PRED_WEIGHT 0x210
#define VE_H264_QP_PARAM 0x21c
#define VE_H264_CTRL 0x220
-#define VE_H264_TRIGGER 0x224
+
+#define VE_H264_TRIGGER_TYPE 0x224
+#define VE_H264_TRIGGER_TYPE_AVC_SLICE_DECODE (8 << 0)
+#define VE_H264_TRIGGER_TYPE_INIT_SWDEC (7 << 0)
+
#define VE_H264_STATUS 0x228
#define VE_H264_CUR_MB_NUM 0x22c
+
#define VE_H264_VLD_ADDR 0x230
+#define VE_H264_VLD_ADDR_FIRST BIT(30)
+#define VE_H264_VLD_ADDR_LAST BIT(29)
+#define VE_H264_VLD_ADDR_VALID BIT(28)
+#define VE_H264_VLD_ADDR_VAL(x) (((x) & 0x0ffffff0) | ((x) >> 28))
+
#define VE_H264_VLD_OFFSET 0x234
#define VE_H264_VLD_LEN 0x238
#define VE_H264_VLD_END 0x23c
@@ -136,14 +146,8 @@
#define VE_H264_EXTRA_BUFFER1 0x250
#define VE_H264_EXTRA_BUFFER2 0x254
#define VE_H264_BASIC_BITS 0x2dc
-#define VE_H264_RAM_WRITE_PTR 0x2e0
-#define VE_H264_RAM_WRITE_DATA 0x2e4
-
-#define VE_SRAM_H264_PRED_WEIGHT_TABLE 0x000
-#define VE_SRAM_H264_FRAMEBUFFER_LIST 0x400
-#define VE_SRAM_H264_REF_LIST0 0x640
-#define VE_SRAM_H264_REF_LIST1 0x664
-#define VE_SRAM_H264_SCALING_LISTS 0x800
+#define VE_AVC_SRAM_PORT_OFFSET 0x2e0
+#define VE_AVC_SRAM_PORT_DATA 0x2e4
#define VE_ISP_INPUT_SIZE 0xa00
#define VE_ISP_INPUT_STRIDE 0xa04
diff --git a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_video.c b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_video.c
index d93461178857..83e55b7825aa 100644
--- a/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_video.c
+++ b/drivers/media/platform/sunxi/cedrus/sunxi_cedrus_video.c
@@ -52,6 +52,11 @@ static struct sunxi_cedrus_fmt formats[] = {
.types = SUNXI_CEDRUS_OUTPUT,
.num_planes = 1,
},
+ {
+ .fourcc = V4L2_PIX_FMT_H264_SLICE,
+ .types = SUNXI_CEDRUS_OUTPUT,
+ .num_planes = 1,
+ },
};
#define NUM_FORMATS ARRAY_SIZE(formats)
@@ -420,6 +425,9 @@ static int sunxi_cedrus_start_streaming(struct vb2_queue *q, unsigned int count)
int ret = 0;
switch (ctx->vpu_src_fmt->fourcc) {
+ case V4L2_PIX_FMT_H264_SLICE:
+ ctx->current_codec = SUNXI_CEDRUS_CODEC_H264;
+ break;
case V4L2_PIX_FMT_MPEG2_FRAME:
ctx->current_codec = SUNXI_CEDRUS_CODEC_MPEG2;
break;
--
2.17.0
^ permalink raw reply related
* [PATCH V2 2/2] efi/fb: Convert PCI bus address to resource if translated by the bridge
From: Sinan Kaya @ 2018-06-13 14:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526653072-7153-2-git-send-email-okaya@codeaurora.org>
Hi Ard,
On 5/18/2018 10:17 AM, Sinan Kaya wrote:
> A host bridge is allowed to remap BAR addresses using _TRA attribute in
> _CRS windows.
>
> pci_bus 0000:00: root bus resource [mem 0x80100100000-0x8011fffffff window] (bus address [0x00100000-0x1fffffff])
> pci 0000:02:00.0: reg 0x10: [mem 0x8011e000000-0x8011effffff]
>
> When a VGA device is behind such a host bridge and the resource is
> translated efifb driver is trying to do ioremap against bus address
> rather than the resource address and is failing to probe.
>
> efifb: probing for efifb
> efifb: cannot reserve video memory at 0x1e000000
> efifb: framebuffer at 0x1e000000, using 1920k, total 1875k
> efifb: mode is 800x600x32, linelength=3200, pages=1
> efifb: scrolling: redraw
> efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
>
> Use the host bridge offset information to convert bus address to
> resource address in the fixup.
>
> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
> ---
I didn't see any messages about these getting picked up for 4.18.
Are they queued on your own branch?
Sinan
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH V5] ARM: shmobile: Rework the PMIC IRQ line quirk
From: Simon Horman @ 2018-06-13 14:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMuHMdUsBNU-1y+_UfX6GKSC11pOB_BUhPKO-axUiO+BfgqVmw@mail.gmail.com>
On Wed, Jun 13, 2018 at 01:21:34PM +0200, Geert Uytterhoeven wrote:
> Hi Simon,
>
> On Wed, Jun 13, 2018 at 1:06 PM Simon Horman <horms@verge.net.au> wrote:
> > On Mon, Jun 11, 2018 at 02:15:13PM +0200, Marek Vasut wrote:
> > > Rather than hard-coding the quirk topology, which stopped scaling,
> > > parse the information from DT. The code looks for all compatible
> > > PMICs -- da9063 and da9210 -- and checks if their IRQ line is tied
> > > to the same pin. If so, the code sends a matching sequence to the
> > > PMIC to deassert the IRQ.
> > >
> > > Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
> > > Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> > > Cc: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> > > Cc: Simon Horman <horms+renesas@verge.net.au>
> > > Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
> > > Cc: linux-renesas-soc at vger.kernel.org
> > > Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> > > Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> (on Koelsch)
> >
> > This looks fine to me but I will wait to see if there are other reviews
> > before applying.
> >
> > Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
>
> Note that applying it now will break gose, as its DTS doesn't describe all
> regulators yet.
Ok, so old DT will break with new kernels?
^ permalink raw reply
* [PATCH] ARM64: dts: rockchip: add some pins to rk3399
From: Shawn Lin @ 2018-06-13 14:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <B649911B-28E0-4466-B3F0-15875FFB9D43@theobroma-systems.com>
On 2018/6/13 2:21, klaus.goger at theobroma-systems.com wrote:
> Hi Randy,
-----8<-------------
>> pcie {
>> + pcie_clkreqn: pci-clkreqn {
>> + rockchip,pins =
>> + <2 26 RK_FUNC_2 &pcfg_pull_none>;
>> + };
>> +
>> + pcie_clkreqnb: pci-clkreqnb {
>> + rockchip,pins =
>> + <4 24 RK_FUNC_1 &pcfg_pull_none>;
>> + };
>> +
>
> I?m not sure if pci-clkreqn is functional at all. If not I?m not sure if we should add it to the dtsi.
> Shawn may know more about it.
Please refer to commit 461a00bb9d539e
("arm64: dts: rockchip: kill pcie_clkreqn and pcie_clkreqnb for rk3399")
CLKREQ# is used for PCI-PM L1.x, but it's not functional for rk3399, so
we have to support CPM(clock power management), thus I kill them last
year.
>
>> pcie_clkreqn_cpm: pci-clkreqn-cpm {
>> rockchip,pins =
>> - <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
>> + <2 26 RK_FUNC_GPIO &pcfg_pull_none>;
>> };
>>
>> pcie_clkreqnb_cpm: pci-clkreqnb-cpm {
>> rockchip,pins =
>> - <4 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
>> + <4 24 RK_FUNC_GPIO &pcfg_pull_none>;
>> };
>> };
>>
>> --
>> 2.14.4
>
>
> Could we actually use RK_Pxx for all new pin definitions? Would increase readability a lot.
>
> Thanks,
> Klaus
>
>
--
Best Regards
Shawn Lin
^ permalink raw reply
* [PATCH V2 2/2] efi/fb: Convert PCI bus address to resource if translated by the bridge
From: Ard Biesheuvel @ 2018-06-13 15:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <26470c5c-55db-9dff-3794-4e4a96c8bcb6@codeaurora.org>
On 13 June 2018 at 16:22, Sinan Kaya <okaya@codeaurora.org> wrote:
> Hi Ard,
>
> On 5/18/2018 10:17 AM, Sinan Kaya wrote:
>> A host bridge is allowed to remap BAR addresses using _TRA attribute in
>> _CRS windows.
>>
>> pci_bus 0000:00: root bus resource [mem 0x80100100000-0x8011fffffff window] (bus address [0x00100000-0x1fffffff])
>> pci 0000:02:00.0: reg 0x10: [mem 0x8011e000000-0x8011effffff]
>>
>> When a VGA device is behind such a host bridge and the resource is
>> translated efifb driver is trying to do ioremap against bus address
>> rather than the resource address and is failing to probe.
>>
>> efifb: probing for efifb
>> efifb: cannot reserve video memory at 0x1e000000
>> efifb: framebuffer at 0x1e000000, using 1920k, total 1875k
>> efifb: mode is 800x600x32, linelength=3200, pages=1
>> efifb: scrolling: redraw
>> efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
>>
>> Use the host bridge offset information to convert bus address to
>> resource address in the fixup.
>>
>> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
>> ---
>
> I didn't see any messages about these getting picked up for 4.18.
>
> Are they queued on your own branch?
>
No, you never cc'ed me on them until now.
^ permalink raw reply
* [PATCH/RFT v2 2/2] arm64: dts: r8a77995: Add all HSCIF nodes
From: Simon Horman @ 2018-06-13 15:09 UTC (permalink / raw)
To: linux-arm-kernel
From: Takeshi Kihara <takeshi.kihara.df@renesas.com>
This patch adds the device nodes all HSCIF serial ports
incl. clocks and power domain to the R8A77995 SoC.
Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
[simon: updated internal clock from S3D1 to S3D1C to match documentation]
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
arch/arm64/boot/dts/renesas/r8a77995.dtsi | 35 +++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
Based on renesas-devel-20180613-v4.17
diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index 16cbb34692ad..0a9caf9cdc86 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -242,6 +242,41 @@
resets = <&cpg 407>;
};
+ hscif0: serial at e6540000 {
+ compatible = "renesas,hscif-r8a77995",
+ "renesas,rcar-gen3-hscif",
+ "renesas,hscif";
+ reg = <0 0xe6540000 0 0x60>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 520>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+ <&dmac2 0x31>, <&dmac2 0x30>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 520>;
+ status = "disabled";
+ };
+
+ hscif3: serial at e66a0000 {
+ compatible = "renesas,hscif-r8a77995",
+ "renesas,rcar-gen3-hscif",
+ "renesas,hscif";
+ reg = <0 0xe66a0000 0 0x60>;
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 517>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+ dma-names = "tx", "rx";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 517>;
+ status = "disabled";
+ };
+
i2c0: i2c at e6500000 {
#address-cells = <1>;
#size-cells = <0>;
--
2.11.0
^ permalink raw reply related
* [PATCH] arm64: dts: hikey: Define wl1835 power capabilities
From: Ryan Grachek @ 2018-06-13 15:13 UTC (permalink / raw)
To: linux-arm-kernel
These properties are required for compatibility with runtime PM.
Without these properties, MMC host controller will not be aware
of power capabilities. When the wlcore driver attempts to power
on the device, it will erroneously fail with -EACCES.
Signed-off-by: Ryan Grachek <ryan@edited.us>
---
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
index 38f881955217..c5feca8cd10b 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
@@ -323,6 +323,8 @@
bus-width = <0x4>;
cap-sd-highspeed;
non-removable;
+ cap-power-off-card;
+ keep-power-in-suspend;
vmmc-supply = <®_vdd_3v3>;
mmc-pwrseq = <&wl1835_pwrseq>;
--
2.11.0
^ permalink raw reply related
* [PATCH/RFT v2 1/2] arm64: dts: r8a77995: Add SCIF-{0, 1, 3, 4, 5} device nodes
From: Simon Horman @ 2018-06-13 15:13 UTC (permalink / raw)
To: linux-arm-kernel
From: Takeshi Kihara <takeshi.kihara.df@renesas.com>
This patch adds the device nodes for SCIF-{0,1,3,4,5} serial ports,
incl. clocks and power domain.
Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
[simon: updated internal clock from S3D1 to S3D1C to match documentation]
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
arch/arm64/boot/dts/renesas/r8a77995.dtsi | 70 +++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
Based on renesas-devel-20180613-v4.17
diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index 1de6ffca4772..16cbb34692ad 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -605,6 +605,34 @@
status = "disabled";
};
+ scif0: serial at e6e60000 {
+ compatible = "renesas,scif-r8a77995",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6e60000 0 64>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 207>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 207>;
+ status = "disabled";
+ };
+
+ scif1: serial at e6e68000 {
+ compatible = "renesas,scif-r8a77995",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6e68000 0 64>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 206>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 206>;
+ status = "disabled";
+ };
+
scif2: serial at e6e88000 {
compatible = "renesas,scif-r8a77995",
"renesas,rcar-gen3-scif", "renesas,scif";
@@ -622,6 +650,48 @@
status = "disabled";
};
+ scif3: serial at e6c50000 {
+ compatible = "renesas,scif-r8a77995",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6c50000 0 64>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 204>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 204>;
+ status = "disabled";
+ };
+
+ scif4: serial at e6c40000 {
+ compatible = "renesas,scif-r8a77995",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6c40000 0 64>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 203>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 203>;
+ status = "disabled";
+ };
+
+ scif5: serial at e6f30000 {
+ compatible = "renesas,scif-r8a77995",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6f30000 0 64>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 202>,
+ <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 202>;
+ status = "disabled";
+ };
+
vin4: video at e6ef4000 {
compatible = "renesas,vin-r8a77995";
reg = <0 0xe6ef4000 0 0x1000>;
--
2.11.0
^ permalink raw reply related
* [PATCH V2 2/2] efi/fb: Convert PCI bus address to resource if translated by the bridge
From: okaya at codeaurora.org @ 2018-06-13 15:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu8UG_D0AAR8Usdi7DrucqaEs+f-JTU1voR-CcrtNY2ZEQ@mail.gmail.com>
On 2018-06-13 11:06, Ard Biesheuvel wrote:
> On 13 June 2018 at 16:22, Sinan Kaya <okaya@codeaurora.org> wrote:
>> Hi Ard,
>>
>> On 5/18/2018 10:17 AM, Sinan Kaya wrote:
>>> A host bridge is allowed to remap BAR addresses using _TRA attribute
>>> in
>>> _CRS windows.
>>>
>>> pci_bus 0000:00: root bus resource [mem 0x80100100000-0x8011fffffff
>>> window] (bus address [0x00100000-0x1fffffff])
>>> pci 0000:02:00.0: reg 0x10: [mem 0x8011e000000-0x8011effffff]
>>>
>>> When a VGA device is behind such a host bridge and the resource is
>>> translated efifb driver is trying to do ioremap against bus address
>>> rather than the resource address and is failing to probe.
>>>
>>> efifb: probing for efifb
>>> efifb: cannot reserve video memory at 0x1e000000
>>> efifb: framebuffer at 0x1e000000, using 1920k, total 1875k
>>> efifb: mode is 800x600x32, linelength=3200, pages=1
>>> efifb: scrolling: redraw
>>> efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
>>>
>>> Use the host bridge offset information to convert bus address to
>>> resource address in the fixup.
>>>
>>> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
>>> ---
>>
>> I didn't see any messages about these getting picked up for 4.18.
>>
>> Are they queued on your own branch?
>>
>
> No, you never cc'ed me on them until now.
Ouch, I hoped that you would get it via get_maintainer script. Sorry for
that.
^ permalink raw reply
* [PATCH] arm64: dts: qcom: Add pm8005 and pm8998 support
From: Stephen Boyd @ 2018-06-13 15:20 UTC (permalink / raw)
To: linux-arm-kernel
Add basic support for the pm8005 and pm8998 PMICs. For now just support
the GPIO controllers.
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
arch/arm64/boot/dts/qcom/pm8005.dtsi | 33 +++++++++++++++++
arch/arm64/boot/dts/qcom/pm8998.dtsi | 55 ++++++++++++++++++++++++++++
2 files changed, 88 insertions(+)
create mode 100644 arch/arm64/boot/dts/qcom/pm8005.dtsi
create mode 100644 arch/arm64/boot/dts/qcom/pm8998.dtsi
diff --git a/arch/arm64/boot/dts/qcom/pm8005.dtsi b/arch/arm64/boot/dts/qcom/pm8005.dtsi
new file mode 100644
index 000000000000..4d5aca3eeb69
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pm8005.dtsi
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/* Copyright 2018 Google LLC. */
+
+#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&spmi_bus {
+ pm8005_lsid0: pmic at 4 {
+ compatible = "qcom,pm8005", "qcom,spmi-pmic";
+ reg = <0x4 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pm8005_gpio: gpios at c000 {
+ compatible = "qcom,pm8005-gpio", "qcom,spmi-gpio";
+ reg = <0xc000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <0 0xc0 0 IRQ_TYPE_NONE>,
+ <0 0xc1 0 IRQ_TYPE_NONE>,
+ <0 0xc2 0 IRQ_TYPE_NONE>,
+ <0 0xc3 0 IRQ_TYPE_NONE>;
+ };
+
+ };
+
+ pm8005_lsid1: pmic at 5 {
+ compatible = "qcom,pm8005", "qcom,spmi-pmic";
+ reg = <0x5 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi b/arch/arm64/boot/dts/qcom/pm8998.dtsi
new file mode 100644
index 000000000000..92bed1e7d4bb
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pm8998.dtsi
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/* Copyright 2018 Google LLC. */
+
+#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&spmi_bus {
+ pm8998_lsid0: pmic at 0 {
+ compatible = "qcom,pm8998", "qcom,spmi-pmic";
+ reg = <0x0 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pm8998_gpio: gpios at c000 {
+ compatible = "qcom,pm8998-gpio", "qcom,spmi-gpio";
+ reg = <0xc000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <0 0xc0 0 IRQ_TYPE_NONE>,
+ <0 0xc1 0 IRQ_TYPE_NONE>,
+ <0 0xc2 0 IRQ_TYPE_NONE>,
+ <0 0xc3 0 IRQ_TYPE_NONE>,
+ <0 0xc4 0 IRQ_TYPE_NONE>,
+ <0 0xc5 0 IRQ_TYPE_NONE>,
+ <0 0xc6 0 IRQ_TYPE_NONE>,
+ <0 0xc7 0 IRQ_TYPE_NONE>,
+ <0 0xc8 0 IRQ_TYPE_NONE>,
+ <0 0xc9 0 IRQ_TYPE_NONE>,
+ <0 0xca 0 IRQ_TYPE_NONE>,
+ <0 0xcb 0 IRQ_TYPE_NONE>,
+ <0 0xcc 0 IRQ_TYPE_NONE>,
+ <0 0xcd 0 IRQ_TYPE_NONE>,
+ <0 0xce 0 IRQ_TYPE_NONE>,
+ <0 0xcf 0 IRQ_TYPE_NONE>,
+ <0 0xd0 0 IRQ_TYPE_NONE>,
+ <0 0xd1 0 IRQ_TYPE_NONE>,
+ <0 0xd2 0 IRQ_TYPE_NONE>,
+ <0 0xd3 0 IRQ_TYPE_NONE>,
+ <0 0xd4 0 IRQ_TYPE_NONE>,
+ <0 0xd5 0 IRQ_TYPE_NONE>,
+ <0 0xd6 0 IRQ_TYPE_NONE>,
+ <0 0xd7 0 IRQ_TYPE_NONE>,
+ <0 0xd8 0 IRQ_TYPE_NONE>,
+ <0 0xd9 0 IRQ_TYPE_NONE>;
+ };
+
+ };
+
+ pm8998_lsid1: pmic at 1 {
+ compatible = "qcom,pm8998", "qcom,spmi-pmic";
+ reg = <0x1 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
--
Sent by a computer through tubes
^ permalink raw reply related
* [PATCH V2 2/2] efi/fb: Convert PCI bus address to resource if translated by the bridge
From: Ard Biesheuvel @ 2018-06-13 15:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <442896963833043f84dd9d0c14d88351@codeaurora.org>
On 13 June 2018 at 17:17, <okaya@codeaurora.org> wrote:
> On 2018-06-13 11:06, Ard Biesheuvel wrote:
>>
>> On 13 June 2018 at 16:22, Sinan Kaya <okaya@codeaurora.org> wrote:
>>>
>>> Hi Ard,
>>>
>>> On 5/18/2018 10:17 AM, Sinan Kaya wrote:
>>>>
>>>> A host bridge is allowed to remap BAR addresses using _TRA attribute in
>>>> _CRS windows.
>>>>
>>>> pci_bus 0000:00: root bus resource [mem 0x80100100000-0x8011fffffff
>>>> window] (bus address [0x00100000-0x1fffffff])
>>>> pci 0000:02:00.0: reg 0x10: [mem 0x8011e000000-0x8011effffff]
>>>>
>>>> When a VGA device is behind such a host bridge and the resource is
>>>> translated efifb driver is trying to do ioremap against bus address
>>>> rather than the resource address and is failing to probe.
>>>>
>>>> efifb: probing for efifb
>>>> efifb: cannot reserve video memory at 0x1e000000
>>>> efifb: framebuffer at 0x1e000000, using 1920k, total 1875k
>>>> efifb: mode is 800x600x32, linelength=3200, pages=1
>>>> efifb: scrolling: redraw
>>>> efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
>>>>
>>>> Use the host bridge offset information to convert bus address to
>>>> resource address in the fixup.
>>>>
>>>> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
>>>> ---
>>>
>>>
>>> I didn't see any messages about these getting picked up for 4.18.
>>>
>>> Are they queued on your own branch?
>>>
>>
>> No, you never cc'ed me on them until now.
>
>
> Ouch, I hoped that you would get it via get_maintainer script. Sorry for
> that.
Actually, get_maintainer is right: this should go through the fbdev
tree not the EFI tree
Were you going to resend them? If not, I can find them in my archive
and ack them, and we will ask Bartlomiej to take them for v4.19
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox