~/paste/43793
~/paste/43793
~/paste/43793

  1. From patchwork Thu Aug 25 09:39:40 2016
  2. Content-Type: text/plain; charset="utf-8"
  3. MIME-Version: 1.0
  4. Content-Transfer-Encoding: 7bit
  5. X-Patchwork-Submitter: Florent Revest <florent.revest@free-electrons.com>
  6. X-Patchwork-Id: 711059
  7. Return-Path: <linux-kernel-owner@vger.kernel.org>
  8. Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
  9.         id S933256AbcHYJm0 (ORCPT <rfc822;w@1wt.eu>);
  10.         Thu, 25 Aug 2016 05:42:26 -0400
  11. Received: from down.free-electrons.com ([37.187.137.238]:34161 "EHLO
  12.         mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org
  13.         with ESMTP id S1757777AbcHYJkE (ORCPT
  14.         <rfc822;linux-kernel@vger.kernel.org>);
  15.         Thu, 25 Aug 2016 05:40:04 -0400
  16. From: Florent Revest <florent.revest@free-electrons.com>
  17. To: linux-media@vger.kernel.org
  18. Cc: florent.revest@free-electrons.com, linux-sunxi@googlegroups.com,
  19.         maxime.ripard@free-electrons.com, posciak@chromium.org,
  20.         hans.verkuil@cisco.com, thomas.petazzoni@free-electrons.com,
  21.         mchehab@kernel.org, linux-kernel@vger.kernel.org, wens@csie.org
  22. Subject: [RFC 01/10] clk: sunxi-ng: Add a couple of A13 clocks
  23. Date: Thu, 25 Aug 2016 11:39:40 +0200
  24. Message-Id:
  25.  <1472117989-21455-2-git-send-email-florent.revest@free-electrons.com>
  26. X-Mailer: git-send-email 2.7.4
  27. In-Reply-To:
  28.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  29. References:
  30.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  31. Sender: linux-kernel-owner@vger.kernel.org
  32. List-ID: <linux-kernel.vger.kernel.org>
  33. X-Mailing-List: linux-kernel@vger.kernel.org
  34. Content-Length: 11513
  35. Lines: 324
  36.  
  37. Add a new style driver for the clock control unit in Allwinner A13.
  38.  
  39. Only AVS and VE are supported since they weren't provided until now and are
  40. needed for "sunxi-cedrus".
  41.  
  42. Signed-off-by: Florent Revest <florent.revest@free-electrons.com>
  43. ---
  44. .../devicetree/bindings/clock/sunxi-ccu.txt        |  1 +
  45.  arch/arm/boot/dts/sun5i-a13.dtsi                   | 11 +++
  46.  drivers/clk/sunxi-ng/Kconfig                       | 11 +++
  47.  drivers/clk/sunxi-ng/Makefile                      |  1 +
  48.  drivers/clk/sunxi-ng/ccu-sun5i-a13.c               | 80 ++++++++++++++++++++++
  49.  drivers/clk/sunxi-ng/ccu-sun5i-a13.h               | 25 +++++++
  50.  include/dt-bindings/clock/sun5i-a13-ccu.h          | 49 +++++++++++++
  51.  include/dt-bindings/reset/sun5i-a13-ccu.h          | 48 +++++++++++++
  52.  8 files changed, 226 insertions(+)
  53.  create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i-a13.c
  54.  create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i-a13.h
  55.  create mode 100644 include/dt-bindings/clock/sun5i-a13-ccu.h
  56.  create mode 100644 include/dt-bindings/reset/sun5i-a13-ccu.h
  57.  
  58. diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
  59. index cb91507..7bb7a6a 100644
  60. --- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
  61. +++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
  62. @@ -4,6 +4,7 @@ Allwinner Clock Control Unit Binding
  63.  Required properties :
  64.  - compatible: must contain one of the following compatible:
  65.                 - "allwinner,sun8i-h3-ccu"
  66. +               - "allwinner,sun5i-a13-ccu"
  67.  
  68.  - reg: Must contain the registers base address and length
  69.  - clocks: phandle to the oscillators feeding the CCU. Two are needed:
  70. diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
  71. index e012890..2afe05fb 100644
  72. --- a/arch/arm/boot/dts/sun5i-a13.dtsi
  73. +++ b/arch/arm/boot/dts/sun5i-a13.dtsi
  74. @@ -46,8 +46,10 @@
  75.  
  76.  #include "sun5i.dtsi"
  77.  
  78. +#include <dt-bindings/clock/sun5i-a13-ccu.h>
  79.  #include <dt-bindings/pinctrl/sun4i-a10.h>
  80.  #include <dt-bindings/thermal/thermal.h>
  81. +#include <dt-bindings/reset/sun5i-a13-ccu.h>
  82.  
  83.  / {
  84.         interrupt-parent = <&intc>;
  85. @@ -327,6 +329,15 @@
  86.                                 };
  87.                         };
  88.                 };
  89. +
  90. +               ccu: clock@01c20000 {
  91. +                       compatible = "allwinner,sun5i-a13-ccu";
  92. +                       reg = <0x01c20000 0x400>;
  93. +                       clocks = <&osc24M>, <&osc32k>;
  94. +                       clock-names = "hosc", "losc";
  95. +                       #clock-cells = <1>;
  96. +                       #reset-cells = <1>;
  97. +               };
  98.         };
  99.  };
  100.  
  101. diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
  102. index 2afcbd3..8faba4e 100644
  103. --- a/drivers/clk/sunxi-ng/Kconfig
  104. +++ b/drivers/clk/sunxi-ng/Kconfig
  105. @@ -51,6 +51,17 @@ config SUNXI_CCU_MP
  106.  
  107.  # SoC Drivers
  108.  
  109. +config SUN5I_A13_CCU
  110. +       bool "Support for the Allwinner A13 CCU"
  111. +       select SUNXI_CCU_DIV
  112. +       select SUNXI_CCU_NK
  113. +       select SUNXI_CCU_NKM
  114. +       select SUNXI_CCU_NKMP
  115. +       select SUNXI_CCU_NM
  116. +       select SUNXI_CCU_MP
  117. +       select SUNXI_CCU_PHASE
  118. +       default ARCH_SUN5I
  119. +
  120.  config SUN8I_H3_CCU
  121.         bool "Support for the Allwinner H3 CCU"
  122.         select SUNXI_CCU_DIV
  123. diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
  124. index 633ce64..1710745 100644
  125. --- a/drivers/clk/sunxi-ng/Makefile
  126. +++ b/drivers/clk/sunxi-ng/Makefile
  127. @@ -17,4 +17,5 @@ obj-$(CONFIG_SUNXI_CCU_NM)    += ccu_nm.o
  128.  obj-$(CONFIG_SUNXI_CCU_MP)     += ccu_mp.o
  129.  
  130.  # SoC support
  131. +obj-$(CONFIG_SUN5I_A13_CCU)    += ccu-sun5i-a13.o
  132.  obj-$(CONFIG_SUN8I_H3_CCU)     += ccu-sun8i-h3.o
  133. diff --git a/drivers/clk/sunxi-ng/ccu-sun5i-a13.c b/drivers/clk/sunxi-ng/ccu-sun5i-a13.c
  134. new file mode 100644
  135. index 0000000..7f1da20
  136. --- /dev/null
  137. +++ b/drivers/clk/sunxi-ng/ccu-sun5i-a13.c
  138. @@ -0,0 +1,80 @@
  139. +/*
  140. + * Copyright (c) 2016 Maxime Ripard. All rights reserved.
  141. + *
  142. + * This software is licensed under the terms of the GNU General Public
  143. + * License version 2, as published by the Free Software Foundation, and
  144. + * may be copied, distributed, and modified under those terms.
  145. + *
  146. + * This program is distributed in the hope that it will be useful,
  147. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  148. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  149. + * GNU General Public License for more details.
  150. + */
  151. +
  152. +#include <linux/clk-provider.h>
  153. +#include <linux/of_address.h>
  154. +
  155. +#include "ccu_common.h"
  156. +#include "ccu_reset.h"
  157. +
  158. +#include "ccu_div.h"
  159. +#include "ccu_gate.h"
  160. +#include "ccu_mp.h"
  161. +#include "ccu_mult.h"
  162. +#include "ccu_nk.h"
  163. +#include "ccu_nkm.h"
  164. +#include "ccu_nkmp.h"
  165. +#include "ccu_nm.h"
  166. +#include "ccu_phase.h"
  167. +
  168. +#include "ccu-sun5i-a13.h"
  169. +
  170. +static SUNXI_CCU_GATE(ve_clk, "ve", "pll4",
  171. +                     0x13c, BIT(31), CLK_SET_RATE_PARENT);
  172. +
  173. +static SUNXI_CCU_GATE(avs_clk, "avs",  "osc24M",
  174. +                     0x144, BIT(31), 0);
  175. +
  176. +static struct ccu_common *sun5i_a13_ccu_clks[] = {
  177. +       &ve_clk.common,
  178. +       &avs_clk.common,
  179. +};
  180. +
  181. +static struct clk_hw_onecell_data sun5i_a13_hw_clks = {
  182. +       .hws    = {
  183. +               [CLK_VE]                = &ve_clk.common.hw,
  184. +               [CLK_AVS]               = &avs_clk.common.hw,
  185. +       },
  186. +       .num    = CLK_NUMBER,
  187. +};
  188. +
  189. +static struct ccu_reset_map sun5i_a13_ccu_resets[] = {
  190. +       [RST_VE]                =  { 0x13c, BIT(0) },
  191. +};
  192. +
  193. +static const struct sunxi_ccu_desc sun5i_a13_ccu_desc = {
  194. +       .ccu_clks       = sun5i_a13_ccu_clks,
  195. +       .num_ccu_clks   = ARRAY_SIZE(sun5i_a13_ccu_clks),
  196. +
  197. +       .hw_clks        = &sun5i_a13_hw_clks,
  198. +
  199. +       .resets         = sun5i_a13_ccu_resets,
  200. +       .num_resets     = ARRAY_SIZE(sun5i_a13_ccu_resets),
  201. +};
  202. +
  203. +static void __init sun5i_a13_ccu_setup(struct device_node *node)
  204. +{
  205. +       void __iomem *reg;
  206. +
  207. +       reg = of_iomap(node, 0);
  208. +       if (IS_ERR(reg)) {
  209. +               pr_err("%s: Could not map the clock registers\n",
  210. +                      of_node_full_name(node));
  211. +               return;
  212. +       }
  213. +
  214. +       sunxi_ccu_probe(node, reg, &sun5i_a13_ccu_desc);
  215. +}
  216. +
  217. +CLK_OF_DECLARE(sun5i_A13_ccu, "allwinner,sun5i-a13-ccu",
  218. +              sun5i_a13_ccu_setup);
  219. diff --git a/drivers/clk/sunxi-ng/ccu-sun5i-a13.h b/drivers/clk/sunxi-ng/ccu-sun5i-a13.h
  220. new file mode 100644
  221. index 0000000..a52af0b
  222. --- /dev/null
  223. +++ b/drivers/clk/sunxi-ng/ccu-sun5i-a13.h
  224. @@ -0,0 +1,25 @@
  225. +/*
  226. + * Copyright 2016 Maxime Ripard
  227. + *
  228. + * Maxime Ripard <maxime.ripard@free-electrons.com>
  229. + *
  230. + * This program is free software; you can redistribute it and/or modify
  231. + * it under the terms of the GNU General Public License as published by
  232. + * the Free Software Foundation; either version 2 of the License, or
  233. + * (at your option) any later version.
  234. + *
  235. + * This program is distributed in the hope that it will be useful,
  236. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  237. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  238. + * GNU General Public License for more details.
  239. + */
  240. +
  241. +#ifndef _CCU_SUN5I_A13_H_
  242. +#define _CCU_SUN5I_A13_H_
  243. +
  244. +#include <dt-bindings/clock/sun5i-a13-ccu.h>
  245. +#include <dt-bindings/reset/sun5i-a13-ccu.h>
  246. +
  247. +#define CLK_NUMBER             2
  248. +
  249. +#endif /* _CCU_SUN5I_A13_H_ */
  250. diff --git a/include/dt-bindings/clock/sun5i-a13-ccu.h b/include/dt-bindings/clock/sun5i-a13-ccu.h
  251. new file mode 100644
  252. index 0000000..1218338
  253. --- /dev/null
  254. +++ b/include/dt-bindings/clock/sun5i-a13-ccu.h
  255. @@ -0,0 +1,49 @@
  256. +/*
  257. + * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
  258. + *
  259. + * This file is dual-licensed: you can use it either under the terms
  260. + * of the GPL or the X11 license, at your option. Note that this dual
  261. + * licensing only applies to this file, and not this project as a
  262. + * whole.
  263. + *
  264. + *  a) This file is free software; you can redistribute it and/or
  265. + *     modify it under the terms of the GNU General Public License as
  266. + *     published by the Free Software Foundation; either version 2 of the
  267. + *     License, or (at your option) any later version.
  268. + *
  269. + *     This file is distributed in the hope that it will be useful,
  270. + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  271. + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  272. + *     GNU General Public License for more details.
  273. + *
  274. + * Or, alternatively,
  275. + *
  276. + *  b) Permission is hereby granted, free of charge, to any person
  277. + *     obtaining a copy of this software and associated documentation
  278. + *     files (the "Software"), to deal in the Software without
  279. + *     restriction, including without limitation the rights to use,
  280. + *     copy, modify, merge, publish, distribute, sublicense, and/or
  281. + *     sell copies of the Software, and to permit persons to whom the
  282. + *     Software is furnished to do so, subject to the following
  283. + *     conditions:
  284. + *
  285. + *     The above copyright notice and this permission notice shall be
  286. + *     included in all copies or substantial portions of the Software.
  287. + *
  288. + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  289. + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  290. + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  291. + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  292. + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  293. + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  294. + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  295. + *     OTHER DEALINGS IN THE SOFTWARE.
  296. + */
  297. +
  298. +#ifndef _DT_BINDINGS_CLK_SUN8I_a13_H_
  299. +#define _DT_BINDINGS_CLK_SUN8I_a13_H_
  300. +
  301. +#define CLK_VE                 0
  302. +#define CLK_AVS                        1
  303. +
  304. +#endif /* _DT_BINDINGS_CLK_SUN8I_A13_H_ */
  305. diff --git a/include/dt-bindings/reset/sun5i-a13-ccu.h b/include/dt-bindings/reset/sun5i-a13-ccu.h
  306. new file mode 100644
  307. index 0000000..f20b4f6
  308. --- /dev/null
  309. +++ b/include/dt-bindings/reset/sun5i-a13-ccu.h
  310. @@ -0,0 +1,48 @@
  311. +/*
  312. + * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
  313. + *
  314. + * This file is dual-licensed: you can use it either under the terms
  315. + * of the GPL or the X11 license, at your option. Note that this dual
  316. + * licensing only applies to this file, and not this project as a
  317. + * whole.
  318. + *
  319. + *  a) This file is free software; you can redistribute it and/or
  320. + *     modify it under the terms of the GNU General Public License as
  321. + *     published by the Free Software Foundation; either version 2 of the
  322. + *     License, or (at your option) any later version.
  323. + *
  324. + *     This file is distributed in the hope that it will be useful,
  325. + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  326. + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  327. + *     GNU General Public License for more details.
  328. + *
  329. + * Or, alternatively,
  330. + *
  331. + *  b) Permission is hereby granted, free of charge, to any person
  332. + *     obtaining a copy of this software and associated documentation
  333. + *     files (the "Software"), to deal in the Software without
  334. + *     restriction, including without limitation the rights to use,
  335. + *     copy, modify, merge, publish, distribute, sublicense, and/or
  336. + *     sell copies of the Software, and to permit persons to whom the
  337. + *     Software is furnished to do so, subject to the following
  338. + *     conditions:
  339. + *
  340. + *     The above copyright notice and this permission notice shall be
  341. + *     included in all copies or substantial portions of the Software.
  342. + *
  343. + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  344. + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  345. + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  346. + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  347. + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  348. + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  349. + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  350. + *     OTHER DEALINGS IN THE SOFTWARE.
  351. + */
  352. +
  353. +#ifndef _DT_BINDINGS_RST_SUN5I_A13_H_
  354. +#define _DT_BINDINGS_RST_SUN5I_A13_H_
  355. +
  356. +#define RST_VE                 0
  357. +
  358. +#endif /* _DT_BINDINGS_RST_SUN5I_A13_H_ */
  359.  
  360. From patchwork Thu Aug 25 09:39:41 2016
  361. Content-Type: text/plain; charset="utf-8"
  362. MIME-Version: 1.0
  363. Content-Transfer-Encoding: 7bit
  364. X-Patchwork-Submitter: Florent Revest <florent.revest@free-electrons.com>
  365. X-Patchwork-Id: 711058
  366. Return-Path: <linux-kernel-owner@vger.kernel.org>
  367. Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
  368.         id S933138AbcHYJmM (ORCPT <rfc822;w@1wt.eu>);
  369.         Thu, 25 Aug 2016 05:42:12 -0400
  370. Received: from down.free-electrons.com ([37.187.137.238]:34171 "EHLO
  371.         mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org
  372.         with ESMTP id S1757885AbcHYJkE (ORCPT
  373.         <rfc822;linux-kernel@vger.kernel.org>);
  374.         Thu, 25 Aug 2016 05:40:04 -0400
  375. From: Florent Revest <florent.revest@free-electrons.com>
  376. To: linux-media@vger.kernel.org
  377. Cc: florent.revest@free-electrons.com, linux-sunxi@googlegroups.com,
  378.         maxime.ripard@free-electrons.com, posciak@chromium.org,
  379.         hans.verkuil@cisco.com, thomas.petazzoni@free-electrons.com,
  380.         mchehab@kernel.org, linux-kernel@vger.kernel.org, wens@csie.org
  381. Subject: [RFC 02/10] v4l: Add private compound control type.
  382. Date: Thu, 25 Aug 2016 11:39:41 +0200
  383. Message-Id:
  384.  <1472117989-21455-3-git-send-email-florent.revest@free-electrons.com>
  385. X-Mailer: git-send-email 2.7.4
  386. In-Reply-To:
  387.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  388. References:
  389.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  390. Sender: linux-kernel-owner@vger.kernel.org
  391. List-ID: <linux-kernel.vger.kernel.org>
  392. X-Mailing-List: linux-kernel@vger.kernel.org
  393. Content-Length: 1370
  394. Lines: 43
  395.  
  396. From: Pawel Osciak <posciak@chromium.org>
  397.  
  398. V4L2_CTRL_TYPE_PRIVATE is to be used for private driver compound
  399. controls that use the "ptr" member of struct v4l2_ext_control.
  400.  
  401. Signed-off-by: Pawel Osciak <posciak@chromium.org>
  402. Signed-off-by: Jung Zhao <jung.zhao@rock-chips.com>
  403. Signed-off-by: Florent Revest <florent.revest@free-electrons.com>
  404. ---
  405. drivers/media/v4l2-core/v4l2-ctrls.c | 4 ++++
  406.  include/uapi/linux/videodev2.h       | 2 ++
  407.  2 files changed, 6 insertions(+)
  408.  
  409. diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
  410. index f7333fe..60056b0 100644
  411. --- a/drivers/media/v4l2-core/v4l2-ctrls.c
  412. +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
  413. @@ -1543,6 +1543,10 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
  414.                         return -ERANGE;
  415.                 return 0;
  416.  
  417. +       /* FIXME:just return 0 for now */
  418. +       case V4L2_CTRL_TYPE_PRIVATE:
  419. +               return 0;
  420. +
  421.         default:
  422.                 return -EINVAL;
  423.         }
  424. diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
  425. index 3eafd3f..904c44c 100644
  426. --- a/include/uapi/linux/videodev2.h
  427. +++ b/include/uapi/linux/videodev2.h
  428. @@ -1521,6 +1521,8 @@ enum v4l2_ctrl_type {
  429.         V4L2_CTRL_TYPE_U8            = 0x0100,
  430.         V4L2_CTRL_TYPE_U16           = 0x0101,
  431.         V4L2_CTRL_TYPE_U32           = 0x0102,
  432. +
  433. +       V4L2_CTRL_TYPE_PRIVATE       = 0xffff,
  434.  };
  435.  
  436.  /*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
  437.  
  438. From patchwork Thu Aug 25 09:39:42 2016
  439. Content-Type: text/plain; charset="utf-8"
  440. MIME-Version: 1.0
  441. Content-Transfer-Encoding: 7bit
  442. X-Patchwork-Submitter: Florent Revest <florent.revest@free-electrons.com>
  443. X-Patchwork-Id: 711051
  444. Return-Path: <linux-kernel-owner@vger.kernel.org>
  445. Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
  446.         id S1758923AbcHYJkN (ORCPT <rfc822;w@1wt.eu>);
  447.         Thu, 25 Aug 2016 05:40:13 -0400
  448. Received: from down.free-electrons.com ([37.187.137.238]:34179 "EHLO
  449.         mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org
  450.         with ESMTP id S1758718AbcHYJkL (ORCPT
  451.         <rfc822;linux-kernel@vger.kernel.org>);
  452.         Thu, 25 Aug 2016 05:40:11 -0400
  453. From: Florent Revest <florent.revest@free-electrons.com>
  454. To: linux-media@vger.kernel.org
  455. Cc: florent.revest@free-electrons.com, linux-sunxi@googlegroups.com,
  456.         maxime.ripard@free-electrons.com, posciak@chromium.org,
  457.         hans.verkuil@cisco.com, thomas.petazzoni@free-electrons.com,
  458.         mchehab@kernel.org, linux-kernel@vger.kernel.org, wens@csie.org
  459. Subject: [RFC 03/10] v4l: Add sunxi Video Engine pixel format
  460. Date: Thu, 25 Aug 2016 11:39:42 +0200
  461. Message-Id:
  462.  <1472117989-21455-4-git-send-email-florent.revest@free-electrons.com>
  463. X-Mailer: git-send-email 2.7.4
  464. In-Reply-To:
  465.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  466. References:
  467.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  468. Sender: linux-kernel-owner@vger.kernel.org
  469. List-ID: <linux-kernel.vger.kernel.org>
  470. X-Mailing-List: linux-kernel@vger.kernel.org
  471. Content-Length: 1140
  472. Lines: 25
  473.  
  474. Add support for the allwinner's proprietary pixel format described in
  475. details here: http://linux-sunxi.org/File:Ve_tile_format_v1.pdf
  476.  
  477. This format is similar to V4L2_PIX_FMT_NV12M but the planes are divided
  478. in tiles of 32x32px.
  479.  
  480. Signed-off-by: Florent Revest <florent.revest@free-electrons.com>
  481. ---
  482. include/uapi/linux/videodev2.h | 1 +
  483.  1 file changed, 1 insertion(+)
  484.  
  485. diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
  486. index 904c44c..96e034d 100644
  487. --- a/include/uapi/linux/videodev2.h
  488. +++ b/include/uapi/linux/videodev2.h
  489. @@ -627,6 +627,7 @@ struct v4l2_pix_format {
  490.  #define V4L2_PIX_FMT_Y8I      v4l2_fourcc('Y', '8', 'I', ' ') /* Greyscale 8-bit L/R interleaved */
  491.  #define V4L2_PIX_FMT_Y12I     v4l2_fourcc('Y', '1', '2', 'I') /* Greyscale 12-bit L/R interleaved */
  492.  #define V4L2_PIX_FMT_Z16      v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */
  493. +#define V4L2_PIX_FMT_SUNXI    v4l2_fourcc('S', 'X', 'I', 'Y') /* Sunxi VE's 32x32 tiled NV12 */
  494.  
  495.  /* SDR formats - used only for Software Defined Radio devices */
  496.  #define V4L2_SDR_FMT_CU8          v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */
  497.  
  498. From patchwork Thu Aug 25 09:39:43 2016
  499. Content-Type: text/plain; charset="utf-8"
  500. MIME-Version: 1.0
  501. Content-Transfer-Encoding: 7bit
  502. X-Patchwork-Submitter: Florent Revest <florent.revest@free-electrons.com>
  503. X-Patchwork-Id: 711050
  504. Return-Path: <linux-kernel-owner@vger.kernel.org>
  505. Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
  506.         id S1758784AbcHYJkK (ORCPT <rfc822;w@1wt.eu>);
  507.         Thu, 25 Aug 2016 05:40:10 -0400
  508. Received: from down.free-electrons.com ([37.187.137.238]:34187 "EHLO
  509.         mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org
  510.         with ESMTP id S1757887AbcHYJkI (ORCPT
  511.         <rfc822;linux-kernel@vger.kernel.org>);
  512.         Thu, 25 Aug 2016 05:40:08 -0400
  513. From: Florent Revest <florent.revest@free-electrons.com>
  514. To: linux-media@vger.kernel.org
  515. Cc: florent.revest@free-electrons.com, linux-sunxi@googlegroups.com,
  516.         maxime.ripard@free-electrons.com, posciak@chromium.org,
  517.         hans.verkuil@cisco.com, thomas.petazzoni@free-electrons.com,
  518.         mchehab@kernel.org, linux-kernel@vger.kernel.org, wens@csie.org
  519. Subject: [RFC 04/10] v4l: Add MPEG2 low-level decoder API control
  520. Date: Thu, 25 Aug 2016 11:39:43 +0200
  521. Message-Id:
  522.  <1472117989-21455-5-git-send-email-florent.revest@free-electrons.com>
  523. X-Mailer: git-send-email 2.7.4
  524. In-Reply-To:
  525.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  526. References:
  527.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  528. Sender: linux-kernel-owner@vger.kernel.org
  529. List-ID: <linux-kernel.vger.kernel.org>
  530. X-Mailing-List: linux-kernel@vger.kernel.org
  531. Content-Length: 5301
  532. Lines: 139
  533.  
  534. This control is to be used with the new low-level decoder API for
  535. MPEG2 to provide additional parameters for the hardware that cannot parse
  536. the input stream.
  537.  
  538. Signed-off-by: Florent Revest <florent.revest@free-electrons.com>
  539. ---
  540. drivers/media/v4l2-core/v4l2-ctrls.c | 11 +++++++++++
  541.  drivers/media/v4l2-core/v4l2-ioctl.c |  1 +
  542.  include/uapi/linux/v4l2-controls.h   | 26 ++++++++++++++++++++++++++
  543.  include/uapi/linux/videodev2.h       |  3 +++
  544.  4 files changed, 41 insertions(+)
  545.  
  546. diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
  547. index 60056b0..331d009 100644
  548. --- a/drivers/media/v4l2-core/v4l2-ctrls.c
  549. +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
  550. @@ -760,6 +760,8 @@ const char *v4l2_ctrl_get_name(u32 id)
  551.         case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER:             return "Repeat Sequence Header";
  552.         case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:               return "Force Key Frame";
  553.  
  554. +       case V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR:               return "MPEG2 Frame Header";
  555. +
  556.         /* VPX controls */
  557.         case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS:            return "VPX Number of Partitions";
  558.         case V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4:           return "VPX Intra Mode Decision Disable";
  559. @@ -1143,6 +1145,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
  560.         case V4L2_CID_RDS_TX_ALT_FREQS:
  561.                 *type = V4L2_CTRL_TYPE_U32;
  562.                 break;
  563. +       case V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR:
  564. +               *type = V4L2_CTRL_TYPE_MPEG2_FRAME_HDR;
  565. +               break;
  566.         default:
  567.                 *type = V4L2_CTRL_TYPE_INTEGER;
  568.                 break;
  569. @@ -1543,6 +1548,9 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
  570.                         return -ERANGE;
  571.                 return 0;
  572.  
  573. +       case V4L2_CTRL_TYPE_MPEG2_FRAME_HDR:
  574. +               return 0;
  575. +
  576.         /* FIXME:just return 0 for now */
  577.         case V4L2_CTRL_TYPE_PRIVATE:
  578.                 return 0;
  579. @@ -2096,6 +2104,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
  580.         case V4L2_CTRL_TYPE_U32:
  581.                 elem_size = sizeof(u32);
  582.                 break;
  583. +       case V4L2_CTRL_TYPE_MPEG2_FRAME_HDR:
  584. +               elem_size = sizeof(struct v4l2_ctrl_mpeg2_frame_hdr);
  585. +               break;
  586.         default:
  587.                 if (type < V4L2_CTRL_COMPOUND_TYPES)
  588.                         elem_size = sizeof(s32);
  589. diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
  590. index f19b666..de382a1 100644
  591. --- a/drivers/media/v4l2-core/v4l2-ioctl.c
  592. +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
  593. @@ -1273,6 +1273,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
  594.                 case V4L2_PIX_FMT_VC1_ANNEX_G:  descr = "VC-1 (SMPTE 412M Annex G)"; break;
  595.                 case V4L2_PIX_FMT_VC1_ANNEX_L:  descr = "VC-1 (SMPTE 412M Annex L)"; break;
  596.                 case V4L2_PIX_FMT_VP8:          descr = "VP8"; break;
  597. +               case V4L2_PIX_FMT_MPEG2_FRAME:  descr = "MPEG2 FRAME"; break;
  598.                 case V4L2_PIX_FMT_CPIA1:        descr = "GSPCA CPiA YUV"; break;
  599.                 case V4L2_PIX_FMT_WNVA:         descr = "WNVA"; break;
  600.                 case V4L2_PIX_FMT_SN9C10X:      descr = "GSPCA SN9C10X"; break;
  601. diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
  602. index b6a357a..cdf9497 100644
  603. --- a/include/uapi/linux/v4l2-controls.h
  604. +++ b/include/uapi/linux/v4l2-controls.h
  605. @@ -547,6 +547,8 @@ enum v4l2_mpeg_video_mpeg4_profile {
  606.  };
  607.  #define V4L2_CID_MPEG_VIDEO_MPEG4_QPEL         (V4L2_CID_MPEG_BASE+407)
  608.  
  609. +#define V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR     (V4L2_CID_MPEG_BASE+450)
  610. +
  611.  /*  Control IDs for VP8 streams
  612.   *  Although VP8 is not part of MPEG we add these controls to the MPEG class
  613.   *  as that class is already handling other video compression standards
  614. @@ -974,4 +976,28 @@ enum v4l2_detect_md_mode {
  615.  #define V4L2_CID_DETECT_MD_THRESHOLD_GRID      (V4L2_CID_DETECT_CLASS_BASE + 3)
  616.  #define V4L2_CID_DETECT_MD_REGION_GRID         (V4L2_CID_DETECT_CLASS_BASE + 4)
  617.  
  618. +struct v4l2_ctrl_mpeg2_frame_hdr {
  619. +       __u32 slice_len;
  620. +       __u32 slice_pos;
  621. +       enum { MPEG1, MPEG2 } type;
  622. +
  623. +       __u16 width;
  624. +       __u16 height;
  625. +
  626. +       enum { PCT_I = 1, PCT_P, PCT_B, PCT_D } picture_coding_type;
  627. +       __u8 f_code[2][2];
  628. +
  629. +       __u8 intra_dc_precision;
  630. +       __u8 picture_structure;
  631. +       __u8 top_field_first;
  632. +       __u8 frame_pred_frame_dct;
  633. +       __u8 concealment_motion_vectors;
  634. +       __u8 q_scale_type;
  635. +       __u8 intra_vlc_format;
  636. +       __u8 alternate_scan;
  637. +
  638. +       __u8 backward_index;
  639. +       __u8 forward_index;
  640. +};
  641. +
  642.  #endif
  643. diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
  644. index 96e034d..feff200 100644
  645. --- a/include/uapi/linux/videodev2.h
  646. +++ b/include/uapi/linux/videodev2.h
  647. @@ -596,6 +596,7 @@ struct v4l2_pix_format {
  648.  #define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */
  649.  #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */
  650.  #define V4L2_PIX_FMT_VP8      v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
  651. +#define V4L2_PIX_FMT_MPEG2_FRAME  v4l2_fourcc('M', 'G', '2', 'F') /* MPEG2 frame */
  652.  
  653.  /*  Vendor-specific formats   */
  654.  #define V4L2_PIX_FMT_CPIA1    v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */
  655. @@ -1478,6 +1479,7 @@ struct v4l2_ext_control {
  656.                 __u8 __user *p_u8;
  657.                 __u16 __user *p_u16;
  658.                 __u32 __user *p_u32;
  659. +               struct v4l2_ctrl_mpeg2_frame_hdr __user *p_mpeg2_frame_hdr;
  660.                 void __user *ptr;
  661.         };
  662.  } __attribute__ ((packed));
  663. @@ -1522,6 +1524,7 @@ enum v4l2_ctrl_type {
  664.         V4L2_CTRL_TYPE_U8            = 0x0100,
  665.         V4L2_CTRL_TYPE_U16           = 0x0101,
  666.         V4L2_CTRL_TYPE_U32           = 0x0102,
  667. +       V4L2_CTRL_TYPE_MPEG2_FRAME_HDR  = 0x0109,
  668.  
  669.         V4L2_CTRL_TYPE_PRIVATE       = 0xffff,
  670.  };
  671.  
  672. From patchwork Thu Aug 25 09:39:44 2016
  673. Content-Type: text/plain; charset="utf-8"
  674. MIME-Version: 1.0
  675. Content-Transfer-Encoding: 7bit
  676. X-Patchwork-Submitter: Florent Revest <florent.revest@free-electrons.com>
  677. X-Patchwork-Id: 711054
  678. Return-Path: <linux-kernel-owner@vger.kernel.org>
  679. Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
  680.         id S1759139AbcHYJkd (ORCPT <rfc822;w@1wt.eu>);
  681.         Thu, 25 Aug 2016 05:40:33 -0400
  682. Received: from down.free-electrons.com ([37.187.137.238]:34231 "EHLO
  683.         mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org
  684.         with ESMTP id S1759034AbcHYJka (ORCPT
  685.         <rfc822;linux-kernel@vger.kernel.org>);
  686.         Thu, 25 Aug 2016 05:40:30 -0400
  687. From: Florent Revest <florent.revest@free-electrons.com>
  688. To: linux-media@vger.kernel.org
  689. Cc: florent.revest@free-electrons.com, linux-sunxi@googlegroups.com,
  690.         maxime.ripard@free-electrons.com, posciak@chromium.org,
  691.         hans.verkuil@cisco.com, thomas.petazzoni@free-electrons.com,
  692.         mchehab@kernel.org, linux-kernel@vger.kernel.org, wens@csie.org
  693. Subject: [RFC 05/10] v4l: Add MPEG4 low-level decoder API control
  694. Date: Thu, 25 Aug 2016 11:39:44 +0200
  695. Message-Id:
  696.  <1472117989-21455-6-git-send-email-florent.revest@free-electrons.com>
  697. X-Mailer: git-send-email 2.7.4
  698. In-Reply-To:
  699.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  700. References:
  701.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  702. Sender: linux-kernel-owner@vger.kernel.org
  703. List-ID: <linux-kernel.vger.kernel.org>
  704. X-Mailing-List: linux-kernel@vger.kernel.org
  705. Content-Length: 5754
  706. Lines: 154
  707.  
  708. This control is to be used with the new low-level decoder API for MPEG4
  709. to provide additional parameters for the hardware that cannot parse the
  710. input stream.
  711.  
  712. Some fields are still missing for this structure to be complete.
  713.  
  714. Signed-off-by: Florent Revest <florent.revest@free-electrons.com>
  715. ---
  716. drivers/media/v4l2-core/v4l2-ctrls.c |  8 +++++++
  717.  drivers/media/v4l2-core/v4l2-ioctl.c |  1 +
  718.  include/uapi/linux/v4l2-controls.h   | 42 ++++++++++++++++++++++++++++++++++++
  719.  include/uapi/linux/videodev2.h       |  3 +++
  720.  4 files changed, 54 insertions(+)
  721.  
  722. diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
  723. index 331d009..302c744 100644
  724. --- a/drivers/media/v4l2-core/v4l2-ctrls.c
  725. +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
  726. @@ -761,6 +761,7 @@ const char *v4l2_ctrl_get_name(u32 id)
  727.         case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:               return "Force Key Frame";
  728.  
  729.         case V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR:               return "MPEG2 Frame Header";
  730. +       case V4L2_CID_MPEG_VIDEO_MPEG4_FRAME_HDR:               return "MPEG4 Frame Header";
  731.  
  732.         /* VPX controls */
  733.         case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS:            return "VPX Number of Partitions";
  734. @@ -1148,6 +1149,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
  735.         case V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR:
  736.                 *type = V4L2_CTRL_TYPE_MPEG2_FRAME_HDR;
  737.                 break;
  738. +       case V4L2_CID_MPEG_VIDEO_MPEG4_FRAME_HDR:
  739. +               *type = V4L2_CTRL_TYPE_MPEG4_FRAME_HDR;
  740. +               break;
  741.         default:
  742.                 *type = V4L2_CTRL_TYPE_INTEGER;
  743.                 break;
  744. @@ -1549,6 +1553,7 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
  745.                 return 0;
  746.  
  747.         case V4L2_CTRL_TYPE_MPEG2_FRAME_HDR:
  748. +       case V4L2_CTRL_TYPE_MPEG4_FRAME_HDR:
  749.                 return 0;
  750.  
  751.         /* FIXME:just return 0 for now */
  752. @@ -2107,6 +2112,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
  753.         case V4L2_CTRL_TYPE_MPEG2_FRAME_HDR:
  754.                 elem_size = sizeof(struct v4l2_ctrl_mpeg2_frame_hdr);
  755.                 break;
  756. +       case V4L2_CTRL_TYPE_MPEG4_FRAME_HDR:
  757. +               elem_size = sizeof(struct v4l2_ctrl_mpeg4_frame_hdr);
  758. +               break;
  759.         default:
  760.                 if (type < V4L2_CTRL_COMPOUND_TYPES)
  761.                         elem_size = sizeof(s32);
  762. diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
  763. index de382a1..be7973e 100644
  764. --- a/drivers/media/v4l2-core/v4l2-ioctl.c
  765. +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
  766. @@ -1274,6 +1274,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
  767.                 case V4L2_PIX_FMT_VC1_ANNEX_L:  descr = "VC-1 (SMPTE 412M Annex L)"; break;
  768.                 case V4L2_PIX_FMT_VP8:          descr = "VP8"; break;
  769.                 case V4L2_PIX_FMT_MPEG2_FRAME:  descr = "MPEG2 FRAME"; break;
  770. +               case V4L2_PIX_FMT_MPEG4_FRAME:  descr = "MPEG4 FRAME"; break;
  771.                 case V4L2_PIX_FMT_CPIA1:        descr = "GSPCA CPiA YUV"; break;
  772.                 case V4L2_PIX_FMT_WNVA:         descr = "WNVA"; break;
  773.                 case V4L2_PIX_FMT_SN9C10X:      descr = "GSPCA SN9C10X"; break;
  774. diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
  775. index cdf9497..af466ca 100644
  776. --- a/include/uapi/linux/v4l2-controls.h
  777. +++ b/include/uapi/linux/v4l2-controls.h
  778. @@ -548,6 +548,7 @@ enum v4l2_mpeg_video_mpeg4_profile {
  779.  #define V4L2_CID_MPEG_VIDEO_MPEG4_QPEL         (V4L2_CID_MPEG_BASE+407)
  780.  
  781.  #define V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR     (V4L2_CID_MPEG_BASE+450)
  782. +#define V4L2_CID_MPEG_VIDEO_MPEG4_FRAME_HDR     (V4L2_CID_MPEG_BASE+451)
  783.  
  784.  /*  Control IDs for VP8 streams
  785.   *  Although VP8 is not part of MPEG we add these controls to the MPEG class
  786. @@ -1000,4 +1001,45 @@ struct v4l2_ctrl_mpeg2_frame_hdr {
  787.         __u8 forward_index;
  788.  };
  789.  
  790. +struct v4l2_ctrl_mpeg4_frame_hdr {
  791. +       __u32 slice_len;
  792. +       __u32 slice_pos;
  793. +       unsigned char quant_scale;
  794. +
  795. +       __u16 width;
  796. +       __u16 height;
  797. +
  798. +       struct {
  799. +               unsigned int short_video_header         : 1;
  800. +               unsigned int chroma_format                      : 2;
  801. +               unsigned int interlaced                 : 1;
  802. +               unsigned int obmc_disable                       : 1;
  803. +               unsigned int sprite_enable                      : 2;
  804. +               unsigned int sprite_warping_accuracy    : 2;
  805. +               unsigned int quant_type                 : 1;
  806. +               unsigned int quarter_sample                     : 1;
  807. +               unsigned int data_partitioned           : 1;
  808. +               unsigned int reversible_vlc                     : 1;
  809. +               unsigned int resync_marker_disable              : 1;
  810. +       } vol_fields;
  811. +
  812. +       struct {
  813. +               unsigned int vop_coding_type            : 2;
  814. +               unsigned int backward_reference_vop_coding_type : 2;
  815. +               unsigned int vop_rounding_type          : 1;
  816. +               unsigned int intra_dc_vlc_thr           : 3;
  817. +               unsigned int top_field_first            : 1;
  818. +               unsigned int alternate_vertical_scan_flag       : 1;
  819. +       } vop_fields;
  820. +
  821. +       unsigned char vop_fcode_forward;
  822. +       unsigned char vop_fcode_backward;
  823. +
  824. +       short trb;
  825. +       short trd;
  826. +
  827. +       __u8 backward_index;
  828. +       __u8 forward_index;
  829. +};
  830. +
  831.  #endif
  832. diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
  833. index feff200..18958e2 100644
  834. --- a/include/uapi/linux/videodev2.h
  835. +++ b/include/uapi/linux/videodev2.h
  836. @@ -597,6 +597,7 @@ struct v4l2_pix_format {
  837.  #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */
  838.  #define V4L2_PIX_FMT_VP8      v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
  839.  #define V4L2_PIX_FMT_MPEG2_FRAME  v4l2_fourcc('M', 'G', '2', 'F') /* MPEG2 frame */
  840. +#define V4L2_PIX_FMT_MPEG4_FRAME  v4l2_fourcc('M', 'G', '4', 'F') /* MPEG4 frame */
  841.  
  842.  /*  Vendor-specific formats   */
  843.  #define V4L2_PIX_FMT_CPIA1    v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */
  844. @@ -1480,6 +1481,7 @@ struct v4l2_ext_control {
  845.                 __u16 __user *p_u16;
  846.                 __u32 __user *p_u32;
  847.                 struct v4l2_ctrl_mpeg2_frame_hdr __user *p_mpeg2_frame_hdr;
  848. +               struct v4l2_ctrl_mpeg4_frame_hdr __user *p_mpeg4_frame_hdr;
  849.                 void __user *ptr;
  850.         };
  851.  } __attribute__ ((packed));
  852. @@ -1525,6 +1527,7 @@ enum v4l2_ctrl_type {
  853.         V4L2_CTRL_TYPE_U16           = 0x0101,
  854.         V4L2_CTRL_TYPE_U32           = 0x0102,
  855.         V4L2_CTRL_TYPE_MPEG2_FRAME_HDR  = 0x0109,
  856. +       V4L2_CTRL_TYPE_MPEG4_FRAME_HDR  = 0x010A,
  857.  
  858.         V4L2_CTRL_TYPE_PRIVATE       = 0xffff,
  859.  };
  860.  
  861. From patchwork Thu Aug 25 09:39:45 2016
  862. Content-Type: text/plain; charset="utf-8"
  863. MIME-Version: 1.0
  864. Content-Transfer-Encoding: 7bit
  865. X-Patchwork-Submitter: Florent Revest <florent.revest@free-electrons.com>
  866. X-Patchwork-Id: 711057
  867. Return-Path: <linux-kernel-owner@vger.kernel.org>
  868. Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
  869.         id S933084AbcHYJle (ORCPT <rfc822;w@1wt.eu>);
  870.         Thu, 25 Aug 2016 05:41:34 -0400
  871. Received: from down.free-electrons.com ([37.187.137.238]:34197 "EHLO
  872.         mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org
  873.         with ESMTP id S1758928AbcHYJkV (ORCPT
  874.         <rfc822;linux-kernel@vger.kernel.org>);
  875.         Thu, 25 Aug 2016 05:40:21 -0400
  876. From: Florent Revest <florent.revest@free-electrons.com>
  877. To: linux-media@vger.kernel.org
  878. Cc: florent.revest@free-electrons.com, linux-sunxi@googlegroups.com,
  879.         maxime.ripard@free-electrons.com, posciak@chromium.org,
  880.         hans.verkuil@cisco.com, thomas.petazzoni@free-electrons.com,
  881.         mchehab@kernel.org, linux-kernel@vger.kernel.org, wens@csie.org
  882. Subject: [RFC 06/10] media: platform: Add Sunxi Cedrus decoder driver
  883. Date: Thu, 25 Aug 2016 11:39:45 +0200
  884. Message-Id:
  885.  <1472117989-21455-7-git-send-email-florent.revest@free-electrons.com>
  886. X-Mailer: git-send-email 2.7.4
  887. In-Reply-To:
  888.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  889. References:
  890.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  891. Sender: linux-kernel-owner@vger.kernel.org
  892. List-ID: <linux-kernel.vger.kernel.org>
  893. X-Mailing-List: linux-kernel@vger.kernel.org
  894. Content-Length: 39950
  895. Lines: 1387
  896.  
  897. This patch adds a "sunxi-cedrus" v4l2 m2m decoder driver for
  898. Allwinner's Video Processing Unit. This VPU has a low-level interface
  899. which requires manual registers writing for frame headers. Hence, it
  900. depends on the Request API to synchronize buffers with controls.
  901.  
  902. Most of the reverse engineering on which I based my work comes from the
  903. "Cedrus" project: http://linux-sunxi.org/Cedrus
  904.  
  905. The driver currently only runs on the A13 and this patch doesn't
  906. include any codec.
  907.  
  908. Signed-off-by: Florent Revest <florent.revest@free-electrons.com>
  909. ---
  910. drivers/media/platform/Kconfig                     |  13 +
  911.  drivers/media/platform/Makefile                    |   1 +
  912.  drivers/media/platform/sunxi-cedrus/Makefile       |   2 +
  913.  drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c | 248 ++++++++++
  914.  .../platform/sunxi-cedrus/sunxi_cedrus_common.h    |  86 ++++
  915.  .../media/platform/sunxi-cedrus/sunxi_cedrus_dec.c | 544 +++++++++++++++++++++
  916.  .../media/platform/sunxi-cedrus/sunxi_cedrus_dec.h |  33 ++
  917.  .../media/platform/sunxi-cedrus/sunxi_cedrus_hw.c  | 153 ++++++
  918.  .../media/platform/sunxi-cedrus/sunxi_cedrus_hw.h  |  32 ++
  919.  .../platform/sunxi-cedrus/sunxi_cedrus_regs.h      | 170 +++++++
  920.  10 files changed, 1282 insertions(+)
  921.  create mode 100644 drivers/media/platform/sunxi-cedrus/Makefile
  922.  create mode 100644 drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c
  923.  create mode 100644 drivers/media/platform/sunxi-cedrus/sunxi_cedrus_common.h
  924.  create mode 100644 drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.c
  925.  create mode 100644 drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.h
  926.  create mode 100644 drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.c
  927.  create mode 100644 drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.h
  928.  create mode 100644 drivers/media/platform/sunxi-cedrus/sunxi_cedrus_regs.h
  929.  
  930. diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
  931. index f25344b..92c92d3 100644
  932. --- a/drivers/media/platform/Kconfig
  933. +++ b/drivers/media/platform/Kconfig
  934. @@ -315,6 +315,19 @@ config VIDEO_TI_VPE
  935.           Support for the TI VPE(Video Processing Engine) block
  936.           found on DRA7XX SoC.
  937.  
  938. +config VIDEO_SUNXI_CEDRUS
  939. +       tristate "Sunxi CEDRUS VPU driver"
  940. +       depends on VIDEO_DEV && VIDEO_V4L2
  941. +       depends on ARCH_SUNXI
  942. +       depends on HAS_DMA
  943. +       select VIDEOBUF2_DMA_CONTIG
  944. +       select V4L2_MEM2MEM_DEV
  945. +       ---help---
  946. +         Support for the VPU video codec found on Sunxi SoC.
  947. +
  948. +         To compile this driver as a module, choose M here: the module
  949. +         will be called sunxi-cedrus.
  950. +
  951.  config VIDEO_TI_VPE_DEBUG
  952.         bool "VPE debug messages"
  953.         depends on VIDEO_TI_VPE
  954. diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
  955. index 21771c1..1419749 100644
  956. --- a/drivers/media/platform/Makefile
  957. +++ b/drivers/media/platform/Makefile
  958. @@ -53,6 +53,7 @@ obj-$(CONFIG_VIDEO_RENESAS_VSP1)      += vsp1/
  959.  obj-y  += omap/
  960.  
  961.  obj-$(CONFIG_VIDEO_AM437X_VPFE)                += am437x/
  962. +obj-$(CONFIG_VIDEO_SUNXI_CEDRUS)       += sunxi-cedrus/
  963.  
  964.  obj-$(CONFIG_VIDEO_XILINX)             += xilinx/
  965.  
  966. diff --git a/drivers/media/platform/sunxi-cedrus/Makefile b/drivers/media/platform/sunxi-cedrus/Makefile
  967. new file mode 100644
  968. index 0000000..14c2f7a
  969. --- /dev/null
  970. +++ b/drivers/media/platform/sunxi-cedrus/Makefile
  971. @@ -0,0 +1,2 @@
  972. +obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += sunxi_cedrus.o sunxi_cedrus_hw.o \
  973. +                                   sunxi_cedrus_dec.o
  974. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c
  975. new file mode 100644
  976. index 0000000..17af34c
  977. --- /dev/null
  978. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c
  979. @@ -0,0 +1,248 @@
  980. +/*
  981. + * Sunxi Cedrus codec driver
  982. + *
  983. + * Copyright (C) 2016 Florent Revest
  984. + * Florent Revest <florent.revest@free-electrons.com>
  985. + *
  986. + * Based on vim2m
  987. + *
  988. + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
  989. + * Pawel Osciak, <pawel@osciak.com>
  990. + * Marek Szyprowski, <m.szyprowski@samsung.com>
  991. + *
  992. + * This software is licensed under the terms of the GNU General Public
  993. + * License version 2, as published by the Free Software Foundation, and
  994. + * may be copied, distributed, and modified under those terms.
  995. + *
  996. + * This program is distributed in the hope that it will be useful,
  997. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  998. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  999. + * GNU General Public License for more details.
  1000. + */
  1001. +
  1002. +#include "sunxi_cedrus_common.h"
  1003. +
  1004. +#include <linux/clk.h>
  1005. +#include <linux/module.h>
  1006. +#include <linux/delay.h>
  1007. +#include <linux/fs.h>
  1008. +#include <linux/sched.h>
  1009. +#include <linux/slab.h>
  1010. +#include <linux/of.h>
  1011. +
  1012. +#include <linux/platform_device.h>
  1013. +#include <media/v4l2-mem2mem.h>
  1014. +#include <media/v4l2-device.h>
  1015. +#include <media/v4l2-ioctl.h>
  1016. +#include <media/v4l2-ctrls.h>
  1017. +#include <media/v4l2-event.h>
  1018. +#include <media/videobuf2-dma-contig.h>
  1019. +
  1020. +#include "sunxi_cedrus_dec.h"
  1021. +#include "sunxi_cedrus_hw.h"
  1022. +
  1023. +static int sunxi_cedrus_s_ctrl(struct v4l2_ctrl *ctrl)
  1024. +{
  1025. +       struct sunxi_cedrus_ctx *ctx =
  1026. +               container_of(ctrl->handler, struct sunxi_cedrus_ctx, hdl);
  1027. +
  1028. +       v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
  1029. +       return -EINVAL;
  1030. +}
  1031. +
  1032. +static const struct v4l2_ctrl_ops sunxi_cedrus_ctrl_ops = {
  1033. +       .s_ctrl = sunxi_cedrus_s_ctrl,
  1034. +};
  1035. +
  1036. +/*
  1037. + * File operations
  1038. + */
  1039. +static int sunxi_cedrus_open(struct file *file)
  1040. +{
  1041. +       struct sunxi_cedrus_dev *dev = video_drvdata(file);
  1042. +       struct sunxi_cedrus_ctx *ctx = NULL;
  1043. +       struct v4l2_ctrl_handler *hdl;
  1044. +       int rc = 0;
  1045. +
  1046. +       if (mutex_lock_interruptible(&dev->dev_mutex))
  1047. +               return -ERESTARTSYS;
  1048. +       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
  1049. +       if (!ctx) {
  1050. +               rc = -ENOMEM;
  1051. +               goto open_unlock;
  1052. +       }
  1053. +
  1054. +       v4l2_fh_init(&ctx->fh, video_devdata(file));
  1055. +       file->private_data = &ctx->fh;
  1056. +       ctx->dev = dev;
  1057. +       hdl = &ctx->hdl;
  1058. +       v4l2_ctrl_handler_init(hdl, 1);
  1059. +
  1060. +       if (hdl->error) {
  1061. +               rc = hdl->error;
  1062. +               v4l2_ctrl_handler_free(hdl);
  1063. +               goto open_unlock;
  1064. +       }
  1065. +       ctx->fh.ctrl_handler = hdl;
  1066. +       v4l2_ctrl_handler_setup(hdl);
  1067. +
  1068. +       ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
  1069. +
  1070. +       if (IS_ERR(ctx->fh.m2m_ctx)) {
  1071. +               rc = PTR_ERR(ctx->fh.m2m_ctx);
  1072. +
  1073. +               v4l2_ctrl_handler_free(hdl);
  1074. +               kfree(ctx);
  1075. +               goto open_unlock;
  1076. +       }
  1077. +
  1078. +       v4l2_fh_add(&ctx->fh);
  1079. +
  1080. +       dev_dbg(dev->dev, "Created instance: %p, m2m_ctx: %p\n",
  1081. +               ctx, ctx->fh.m2m_ctx);
  1082. +
  1083. +open_unlock:
  1084. +       mutex_unlock(&dev->dev_mutex);
  1085. +       return rc;
  1086. +}
  1087. +
  1088. +static int sunxi_cedrus_release(struct file *file)
  1089. +{
  1090. +       struct sunxi_cedrus_dev *dev = video_drvdata(file);
  1091. +       struct sunxi_cedrus_ctx *ctx = container_of(file->private_data,
  1092. +                       struct sunxi_cedrus_ctx, fh);
  1093. +
  1094. +       dev_dbg(dev->dev, "Releasing instance %p\n", ctx);
  1095. +
  1096. +       v4l2_fh_del(&ctx->fh);
  1097. +       v4l2_fh_exit(&ctx->fh);
  1098. +       v4l2_ctrl_handler_free(&ctx->hdl);
  1099. +       mutex_lock(&dev->dev_mutex);
  1100. +       v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
  1101. +       mutex_unlock(&dev->dev_mutex);
  1102. +       kfree(ctx);
  1103. +
  1104. +       return 0;
  1105. +}
  1106. +
  1107. +static const struct v4l2_file_operations sunxi_cedrus_fops = {
  1108. +       .owner          = THIS_MODULE,
  1109. +       .open           = sunxi_cedrus_open,
  1110. +       .release        = sunxi_cedrus_release,
  1111. +       .poll           = v4l2_m2m_fop_poll,
  1112. +       .unlocked_ioctl = video_ioctl2,
  1113. +       .mmap           = v4l2_m2m_fop_mmap,
  1114. +};
  1115. +
  1116. +static struct video_device sunxi_cedrus_viddev = {
  1117. +       .name           = SUNXI_CEDRUS_NAME,
  1118. +       .vfl_dir        = VFL_DIR_M2M,
  1119. +       .fops           = &sunxi_cedrus_fops,
  1120. +       .ioctl_ops      = &sunxi_cedrus_ioctl_ops,
  1121. +       .minor          = -1,
  1122. +       .release        = video_device_release_empty,
  1123. +};
  1124. +
  1125. +static struct v4l2_m2m_ops m2m_ops = {
  1126. +       .device_run     = device_run,
  1127. +       .job_abort      = job_abort,
  1128. +};
  1129. +
  1130. +static int sunxi_cedrus_probe(struct platform_device *pdev)
  1131. +{
  1132. +       struct sunxi_cedrus_dev *dev;
  1133. +       struct video_device *vfd;
  1134. +       int ret;
  1135. +
  1136. +       dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
  1137. +       if (!dev)
  1138. +               return -ENOMEM;
  1139. +
  1140. +       dev->dev = &pdev->dev;
  1141. +       dev->pdev = pdev;
  1142. +
  1143. +       ret = sunxi_cedrus_hw_probe(dev);
  1144. +       if (ret) {
  1145. +               dev_err(&pdev->dev, "sunxi_cedrus_hw_probe failed\n");
  1146. +               return ret;
  1147. +       }
  1148. +
  1149. +       spin_lock_init(&dev->irqlock);
  1150. +
  1151. +       ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
  1152. +       if (ret)
  1153. +               return ret;
  1154. +
  1155. +       mutex_init(&dev->dev_mutex);
  1156. +
  1157. +       dev->vfd = sunxi_cedrus_viddev;
  1158. +       vfd = &dev->vfd;
  1159. +       vfd->lock = &dev->dev_mutex;
  1160. +       vfd->v4l2_dev = &dev->v4l2_dev;
  1161. +
  1162. +       ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
  1163. +       if (ret) {
  1164. +               v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
  1165. +               goto unreg_dev;
  1166. +       }
  1167. +
  1168. +       video_set_drvdata(vfd, dev);
  1169. +       snprintf(vfd->name, sizeof(vfd->name), "%s", sunxi_cedrus_viddev.name);
  1170. +       v4l2_info(&dev->v4l2_dev,
  1171. +                 "Device registered as /dev/video%d\n", vfd->num);
  1172. +
  1173. +       platform_set_drvdata(pdev, dev);
  1174. +
  1175. +       dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
  1176. +       if (IS_ERR(dev->m2m_dev)) {
  1177. +               v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
  1178. +               ret = PTR_ERR(dev->m2m_dev);
  1179. +               goto err_m2m;
  1180. +       }
  1181. +
  1182. +       return 0;
  1183. +
  1184. +err_m2m:
  1185. +       v4l2_m2m_release(dev->m2m_dev);
  1186. +       video_unregister_device(&dev->vfd);
  1187. +unreg_dev:
  1188. +       v4l2_device_unregister(&dev->v4l2_dev);
  1189. +
  1190. +       return ret;
  1191. +}
  1192. +
  1193. +static int sunxi_cedrus_remove(struct platform_device *pdev)
  1194. +{
  1195. +       struct sunxi_cedrus_dev *dev = platform_get_drvdata(pdev);
  1196. +
  1197. +       v4l2_info(&dev->v4l2_dev, "Removing " SUNXI_CEDRUS_NAME);
  1198. +       v4l2_m2m_release(dev->m2m_dev);
  1199. +       video_unregister_device(&dev->vfd);
  1200. +       v4l2_device_unregister(&dev->v4l2_dev);
  1201. +       sunxi_cedrus_hw_remove(dev);
  1202. +
  1203. +       return 0;
  1204. +}
  1205. +
  1206. +#ifdef CONFIG_OF
  1207. +static const struct of_device_id of_sunxi_cedrus_match[] = {
  1208. +       { .compatible = "allwinner,sun5i-a13-video-engine" },
  1209. +       { /* sentinel */ }
  1210. +};
  1211. +MODULE_DEVICE_TABLE(of, of_sunxi_cedrus_match);
  1212. +#endif
  1213. +
  1214. +static struct platform_driver sunxi_cedrus_driver = {
  1215. +       .probe          = sunxi_cedrus_probe,
  1216. +       .remove         = sunxi_cedrus_remove,
  1217. +       .driver         = {
  1218. +               .name   = SUNXI_CEDRUS_NAME,
  1219. +               .owner = THIS_MODULE,
  1220. +               .of_match_table = of_match_ptr(of_sunxi_cedrus_match),
  1221. +       },
  1222. +};
  1223. +module_platform_driver(sunxi_cedrus_driver);
  1224. +
  1225. +MODULE_LICENSE("GPL v2");
  1226. +MODULE_AUTHOR("Florent Revest <florent.revest@free-electrons.com>");
  1227. +MODULE_DESCRIPTION("Sunxi Cedrus codec driver");
  1228. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_common.h b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_common.h
  1229. new file mode 100644
  1230. index 0000000..6b8d87a
  1231. --- /dev/null
  1232. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_common.h
  1233. @@ -0,0 +1,86 @@
  1234. +/*
  1235. + * Sunxi Cedrus codec driver
  1236. + *
  1237. + * Copyright (C) 2016 Florent Revest
  1238. + * Florent Revest <florent.revest@free-electrons.com>
  1239. + *
  1240. + * Based on vim2m
  1241. + *
  1242. + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
  1243. + * Pawel Osciak, <pawel@osciak.com>
  1244. + * Marek Szyprowski, <m.szyprowski@samsung.com>
  1245. + *
  1246. + * This software is licensed under the terms of the GNU General Public
  1247. + * License version 2, as published by the Free Software Foundation, and
  1248. + * may be copied, distributed, and modified under those terms.
  1249. + *
  1250. + * This program is distributed in the hope that it will be useful,
  1251. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1252. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1253. + * GNU General Public License for more details.
  1254. + */
  1255. +
  1256. +#ifndef SUNXI_CEDRUS_COMMON_H_
  1257. +#define SUNXI_CEDRUS_COMMON_H_
  1258. +
  1259. +#include "sunxi_cedrus_regs.h"
  1260. +
  1261. +#include <media/v4l2-device.h>
  1262. +#include <media/v4l2-ctrls.h>
  1263. +
  1264. +#define SUNXI_CEDRUS_NAME              "sunxi-cedrus"
  1265. +
  1266. +struct sunxi_cedrus_dev {
  1267. +       struct v4l2_device      v4l2_dev;
  1268. +       struct video_device     vfd;
  1269. +       struct platform_device  *pdev;
  1270. +       struct device           *dev;
  1271. +       struct v4l2_m2m_dev     *m2m_dev;
  1272. +
  1273. +       /* Mutex for device file */
  1274. +       struct mutex            dev_mutex;
  1275. +       /* Spinlock for interrupt */
  1276. +       spinlock_t              irqlock;
  1277. +
  1278. +       struct clk *mod_clk;
  1279. +       struct clk *ahb_clk;
  1280. +       struct clk *ram_clk;
  1281. +
  1282. +       struct reset_control *rstc;
  1283. +
  1284. +       char *base;
  1285. +};
  1286. +
  1287. +struct sunxi_cedrus_fmt {
  1288. +       u32     fourcc;
  1289. +       int     depth;
  1290. +       u32     types;
  1291. +       unsigned int num_planes;
  1292. +};
  1293. +
  1294. +struct sunxi_cedrus_ctx {
  1295. +       struct v4l2_fh          fh;
  1296. +       struct sunxi_cedrus_dev *dev;
  1297. +
  1298. +       struct sunxi_cedrus_fmt *vpu_src_fmt;
  1299. +       struct v4l2_pix_format_mplane src_fmt;
  1300. +       struct sunxi_cedrus_fmt *vpu_dst_fmt;
  1301. +       struct v4l2_pix_format_mplane dst_fmt;
  1302. +
  1303. +       struct v4l2_ctrl_handler hdl;
  1304. +
  1305. +       struct vb2_buffer *dst_bufs[VIDEO_MAX_FRAME];
  1306. +};
  1307. +
  1308. +static inline void sunxi_cedrus_write(struct sunxi_cedrus_dev *vpu,
  1309. +                                     u32 val, u32 reg)
  1310. +{
  1311. +       writel(val, vpu->base + reg);
  1312. +}
  1313. +
  1314. +static inline u32 sunxi_cedrus_read(struct sunxi_cedrus_dev *vpu, u32 reg)
  1315. +{
  1316. +       return readl(vpu->base + reg);
  1317. +}
  1318. +
  1319. +#endif /* SUNXI_CEDRUS_COMMON_H_ */
  1320. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.c b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.c
  1321. new file mode 100644
  1322. index 0000000..71ef34b
  1323. --- /dev/null
  1324. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.c
  1325. @@ -0,0 +1,544 @@
  1326. +/*
  1327. + * Sunxi Cedrus codec driver
  1328. + *
  1329. + * Copyright (C) 2016 Florent Revest
  1330. + * Florent Revest <florent.revest@free-electrons.com>
  1331. + *
  1332. + * Based on vim2m
  1333. + *
  1334. + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
  1335. + * Pawel Osciak, <pawel@osciak.com>
  1336. + * Marek Szyprowski, <m.szyprowski@samsung.com>
  1337. + *
  1338. + * This software is licensed under the terms of the GNU General Public
  1339. + * License version 2, as published by the Free Software Foundation, and
  1340. + * may be copied, distributed, and modified under those terms.
  1341. + *
  1342. + * This program is distributed in the hope that it will be useful,
  1343. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1344. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1345. + * GNU General Public License for more details.
  1346. + */
  1347. +
  1348. +#include "sunxi_cedrus_common.h"
  1349. +
  1350. +#include <media/v4l2-mem2mem.h>
  1351. +#include <media/v4l2-device.h>
  1352. +#include <media/v4l2-ioctl.h>
  1353. +#include <media/v4l2-ctrls.h>
  1354. +#include <media/v4l2-event.h>
  1355. +#include <media/videobuf2-dma-contig.h>
  1356. +
  1357. +#include "sunxi_cedrus_dec.h"
  1358. +#include "sunxi_cedrus_hw.h"
  1359. +
  1360. +/* Flags that indicate a format can be used for capture/output */
  1361. +#define SUNXI_CEDRUS_CAPTURE   BIT(0)
  1362. +#define SUNXI_CEDRUS_OUTPUT    BIT(1)
  1363. +
  1364. +#define SUNXI_CEDRUS_MIN_WIDTH 16U
  1365. +#define SUNXI_CEDRUS_MIN_HEIGHT 16U
  1366. +#define SUNXI_CEDRUS_MAX_WIDTH 3840U
  1367. +#define SUNXI_CEDRUS_MAX_HEIGHT 2160U
  1368. +
  1369. +static struct sunxi_cedrus_fmt formats[] = {
  1370. +       {
  1371. +               .fourcc = V4L2_PIX_FMT_SUNXI,
  1372. +               .types  = SUNXI_CEDRUS_CAPTURE,
  1373. +               .depth = 8,
  1374. +               .num_planes = 2,
  1375. +       },
  1376. +};
  1377. +
  1378. +#define NUM_FORMATS ARRAY_SIZE(formats)
  1379. +
  1380. +static struct sunxi_cedrus_fmt *find_format(struct v4l2_format *f)
  1381. +{
  1382. +       struct sunxi_cedrus_fmt *fmt;
  1383. +       unsigned int k;
  1384. +
  1385. +       for (k = 0; k < NUM_FORMATS; k++) {
  1386. +               fmt = &formats[k];
  1387. +               if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
  1388. +                       break;
  1389. +       }
  1390. +
  1391. +       if (k == NUM_FORMATS)
  1392. +               return NULL;
  1393. +
  1394. +       return &formats[k];
  1395. +}
  1396. +
  1397. +static inline struct sunxi_cedrus_ctx *file2ctx(struct file *file)
  1398. +{
  1399. +       return container_of(file->private_data, struct sunxi_cedrus_ctx, fh);
  1400. +}
  1401. +
  1402. +/*
  1403. + * mem2mem callbacks
  1404. + */
  1405. +
  1406. +void job_abort(void *priv)
  1407. +{}
  1408. +
  1409. +/*
  1410. + * device_run() - prepares and starts processing
  1411. + */
  1412. +void device_run(void *priv)
  1413. +{
  1414. +       struct sunxi_cedrus_ctx *ctx = priv;
  1415. +       struct vb2_v4l2_buffer *in_vb, *out_vb;
  1416. +       dma_addr_t in_buf, out_luma, out_chroma;
  1417. +
  1418. +       in_vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
  1419. +       out_vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
  1420. +
  1421. +       v4l2_ctrl_apply_request(&ctx->hdl, in_vb->request);
  1422. +
  1423. +       in_buf = vb2_dma_contig_plane_dma_addr(&in_vb->vb2_buf, 0);
  1424. +       out_luma = vb2_dma_contig_plane_dma_addr(&out_vb->vb2_buf, 0);
  1425. +       out_chroma = vb2_dma_contig_plane_dma_addr(&out_vb->vb2_buf, 1);
  1426. +       if (!in_buf || !out_luma || !out_chroma) {
  1427. +               v4l2_err(&ctx->dev->v4l2_dev,
  1428. +                        "Acquiring kernel pointers to buffers failed\n");
  1429. +               return;
  1430. +       }
  1431. +
  1432. +       /*
  1433. +        * The VPU is only able to handle bus addresses so we have to subtract
  1434. +        * the RAM offset to the physcal addresses
  1435. +        */
  1436. +       in_buf     -= PHYS_OFFSET;
  1437. +       out_luma   -= PHYS_OFFSET;
  1438. +       out_chroma -= PHYS_OFFSET;
  1439. +
  1440. +       out_vb->vb2_buf.timestamp = in_vb->vb2_buf.timestamp;
  1441. +       if (in_vb->flags & V4L2_BUF_FLAG_TIMECODE)
  1442. +               out_vb->timecode = in_vb->timecode;
  1443. +       out_vb->field = in_vb->field;
  1444. +       out_vb->flags = in_vb->flags & (V4L2_BUF_FLAG_TIMECODE |
  1445. +                V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_PFRAME |
  1446. +                V4L2_BUF_FLAG_BFRAME   | V4L2_BUF_FLAG_TSTAMP_SRC_MASK);
  1447. +
  1448. +       v4l2_m2m_buf_done(in_vb, VB2_BUF_STATE_ERROR);
  1449. +       v4l2_m2m_buf_done(out_vb, VB2_BUF_STATE_ERROR);
  1450. +}
  1451. +
  1452. +/*
  1453. + * video ioctls
  1454. + */
  1455. +static int vidioc_querycap(struct file *file, void *priv,
  1456. +                          struct v4l2_capability *cap)
  1457. +{
  1458. +       strncpy(cap->driver, SUNXI_CEDRUS_NAME, sizeof(cap->driver) - 1);
  1459. +       strncpy(cap->card, SUNXI_CEDRUS_NAME, sizeof(cap->card) - 1);
  1460. +       snprintf(cap->bus_info, sizeof(cap->bus_info),
  1461. +                "platform:%s", SUNXI_CEDRUS_NAME);
  1462. +       cap->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
  1463. +       cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
  1464. +       return 0;
  1465. +}
  1466. +
  1467. +static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
  1468. +{
  1469. +       int i, num;
  1470. +       struct sunxi_cedrus_fmt *fmt;
  1471. +
  1472. +       num = 0;
  1473. +
  1474. +       for (i = 0; i < NUM_FORMATS; ++i) {
  1475. +               if (formats[i].types & type) {
  1476. +                       /* index-th format of type type found ? */
  1477. +                       if (num == f->index)
  1478. +                               break;
  1479. +                       /*
  1480. +                        * Correct type but haven't reached our index yet,
  1481. +                        * just increment per-type index
  1482. +                        */
  1483. +                       ++num;
  1484. +               }
  1485. +       }
  1486. +
  1487. +       if (i < NUM_FORMATS) {
  1488. +               /* Format found */
  1489. +               fmt = &formats[i];
  1490. +               f->pixelformat = fmt->fourcc;
  1491. +               return 0;
  1492. +       }
  1493. +
  1494. +       /* Format not found */
  1495. +       return -EINVAL;
  1496. +}
  1497. +
  1498. +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
  1499. +                                  struct v4l2_fmtdesc *f)
  1500. +{
  1501. +       return enum_fmt(f, SUNXI_CEDRUS_CAPTURE);
  1502. +}
  1503. +
  1504. +static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
  1505. +                                  struct v4l2_fmtdesc *f)
  1506. +{
  1507. +       return enum_fmt(f, SUNXI_CEDRUS_OUTPUT);
  1508. +}
  1509. +
  1510. +static int vidioc_g_fmt(struct sunxi_cedrus_ctx *ctx, struct v4l2_format *f)
  1511. +{
  1512. +       switch (f->type) {
  1513. +       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
  1514. +               f->fmt.pix_mp = ctx->dst_fmt;
  1515. +               break;
  1516. +       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
  1517. +               f->fmt.pix_mp = ctx->src_fmt;
  1518. +               break;
  1519. +       default:
  1520. +               dev_dbg(ctx->dev->dev, "invalid buf type\n");
  1521. +               return -EINVAL;
  1522. +       }
  1523. +
  1524. +       return 0;
  1525. +}
  1526. +
  1527. +static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
  1528. +                               struct v4l2_format *f)
  1529. +{
  1530. +       return vidioc_g_fmt(file2ctx(file), f);
  1531. +}
  1532. +
  1533. +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
  1534. +                               struct v4l2_format *f)
  1535. +{
  1536. +       return vidioc_g_fmt(file2ctx(file), f);
  1537. +}
  1538. +
  1539. +static int vidioc_try_fmt(struct v4l2_format *f, struct sunxi_cedrus_fmt *fmt)
  1540. +{
  1541. +       int i;
  1542. +       __u32 bpl;
  1543. +
  1544. +       f->fmt.pix_mp.field = V4L2_FIELD_NONE;
  1545. +       f->fmt.pix_mp.num_planes = fmt->num_planes;
  1546. +
  1547. +       switch (f->type) {
  1548. +       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
  1549. +               if (f->fmt.pix_mp.plane_fmt[0].sizeimage == 0)
  1550. +                       return -EINVAL;
  1551. +
  1552. +               f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
  1553. +               break;
  1554. +       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
  1555. +               /* Limit to hardware min/max. */
  1556. +               f->fmt.pix_mp.width = clamp(f->fmt.pix_mp.width,
  1557. +                       SUNXI_CEDRUS_MIN_WIDTH, SUNXI_CEDRUS_MAX_WIDTH);
  1558. +               f->fmt.pix_mp.height = clamp(f->fmt.pix_mp.height,
  1559. +                       SUNXI_CEDRUS_MIN_HEIGHT, SUNXI_CEDRUS_MAX_HEIGHT);
  1560. +
  1561. +               for (i = 0; i < f->fmt.pix_mp.num_planes; ++i) {
  1562. +                       bpl = (f->fmt.pix_mp.width * fmt->depth) >> 3;
  1563. +                       f->fmt.pix_mp.plane_fmt[i].bytesperline = bpl;
  1564. +                       f->fmt.pix_mp.plane_fmt[i].sizeimage =
  1565. +                               f->fmt.pix_mp.height * bpl;
  1566. +               }
  1567. +               break;
  1568. +       }
  1569. +       return 0;
  1570. +}
  1571. +
  1572. +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
  1573. +                                 struct v4l2_format *f)
  1574. +{
  1575. +       struct sunxi_cedrus_fmt *fmt;
  1576. +       struct sunxi_cedrus_ctx *ctx = file2ctx(file);
  1577. +
  1578. +       fmt = find_format(f);
  1579. +       if (!fmt) {
  1580. +               f->fmt.pix_mp.pixelformat = formats[0].fourcc;
  1581. +               fmt = find_format(f);
  1582. +       }
  1583. +       if (!(fmt->types & SUNXI_CEDRUS_CAPTURE)) {
  1584. +               v4l2_err(&ctx->dev->v4l2_dev,
  1585. +                        "Fourcc format (0x%08x) invalid.\n",
  1586. +                        f->fmt.pix_mp.pixelformat);
  1587. +               return -EINVAL;
  1588. +       }
  1589. +
  1590. +       return vidioc_try_fmt(f, fmt);
  1591. +}
  1592. +
  1593. +static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
  1594. +                                 struct v4l2_format *f)
  1595. +{
  1596. +       struct sunxi_cedrus_fmt *fmt;
  1597. +       struct sunxi_cedrus_ctx *ctx = file2ctx(file);
  1598. +
  1599. +       fmt = find_format(f);
  1600. +       if (!fmt) {
  1601. +               f->fmt.pix_mp.pixelformat = formats[0].fourcc;
  1602. +               fmt = find_format(f);
  1603. +       }
  1604. +       if (!(fmt->types & SUNXI_CEDRUS_OUTPUT)) {
  1605. +               v4l2_err(&ctx->dev->v4l2_dev,
  1606. +                        "Fourcc format (0x%08x) invalid.\n",
  1607. +                        f->fmt.pix_mp.pixelformat);
  1608. +               return -EINVAL;
  1609. +       }
  1610. +
  1611. +       return vidioc_try_fmt(f, fmt);
  1612. +}
  1613. +
  1614. +static int vidioc_s_fmt(struct sunxi_cedrus_ctx *ctx, struct v4l2_format *f)
  1615. +{
  1616. +       struct sunxi_cedrus_dev *dev = ctx->dev;
  1617. +       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
  1618. +       struct sunxi_cedrus_fmt *fmt;
  1619. +       int i, ret = 0;
  1620. +
  1621. +       switch (f->type) {
  1622. +       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
  1623. +               ctx->vpu_src_fmt = find_format(f);
  1624. +               ctx->src_fmt = *pix_fmt_mp;
  1625. +               break;
  1626. +       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
  1627. +               fmt = find_format(f);
  1628. +               ctx->vpu_dst_fmt = fmt;
  1629. +
  1630. +               for (i = 0; i < fmt->num_planes; ++i) {
  1631. +                       pix_fmt_mp->plane_fmt[i].bytesperline =
  1632. +                               pix_fmt_mp->width * fmt->depth;
  1633. +                       pix_fmt_mp->plane_fmt[i].sizeimage =
  1634. +                               pix_fmt_mp->plane_fmt[i].bytesperline
  1635. +                               * pix_fmt_mp->height;
  1636. +               }
  1637. +               ctx->dst_fmt = *pix_fmt_mp;
  1638. +               break;
  1639. +       default:
  1640. +               dev_dbg(ctx->dev->dev, "invalid buf type\n");
  1641. +               return -EINVAL;
  1642. +       }
  1643. +
  1644. +       return ret;
  1645. +}
  1646. +
  1647. +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
  1648. +                               struct v4l2_format *f)
  1649. +{
  1650. +       int ret;
  1651. +
  1652. +       ret = vidioc_try_fmt_vid_cap(file, priv, f);
  1653. +       if (ret)
  1654. +               return ret;
  1655. +
  1656. +       return vidioc_s_fmt(file2ctx(file), f);
  1657. +}
  1658. +
  1659. +static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
  1660. +                               struct v4l2_format *f)
  1661. +{
  1662. +       int ret;
  1663. +
  1664. +       ret = vidioc_try_fmt_vid_out(file, priv, f);
  1665. +       if (ret)
  1666. +               return ret;
  1667. +
  1668. +       ret = vidioc_s_fmt(file2ctx(file), f);
  1669. +       return ret;
  1670. +}
  1671. +
  1672. +const struct v4l2_ioctl_ops sunxi_cedrus_ioctl_ops = {
  1673. +       .vidioc_querycap        = vidioc_querycap,
  1674. +
  1675. +       .vidioc_enum_fmt_vid_cap        = vidioc_enum_fmt_vid_cap,
  1676. +       .vidioc_g_fmt_vid_cap_mplane    = vidioc_g_fmt_vid_cap,
  1677. +       .vidioc_try_fmt_vid_cap_mplane  = vidioc_try_fmt_vid_cap,
  1678. +       .vidioc_s_fmt_vid_cap_mplane    = vidioc_s_fmt_vid_cap,
  1679. +
  1680. +       .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out,
  1681. +       .vidioc_g_fmt_vid_out_mplane    = vidioc_g_fmt_vid_out,
  1682. +       .vidioc_try_fmt_vid_out_mplane  = vidioc_try_fmt_vid_out,
  1683. +       .vidioc_s_fmt_vid_out_mplane    = vidioc_s_fmt_vid_out,
  1684. +
  1685. +       .vidioc_reqbufs         = v4l2_m2m_ioctl_reqbufs,
  1686. +       .vidioc_querybuf        = v4l2_m2m_ioctl_querybuf,
  1687. +       .vidioc_qbuf            = v4l2_m2m_ioctl_qbuf,
  1688. +       .vidioc_dqbuf           = v4l2_m2m_ioctl_dqbuf,
  1689. +       .vidioc_prepare_buf     = v4l2_m2m_ioctl_prepare_buf,
  1690. +       .vidioc_create_bufs     = v4l2_m2m_ioctl_create_bufs,
  1691. +       .vidioc_expbuf          = v4l2_m2m_ioctl_expbuf,
  1692. +
  1693. +       .vidioc_streamon        = v4l2_m2m_ioctl_streamon,
  1694. +       .vidioc_streamoff       = v4l2_m2m_ioctl_streamoff,
  1695. +
  1696. +       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
  1697. +       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
  1698. +};
  1699. +
  1700. +/*
  1701. + * Queue operations
  1702. + */
  1703. +
  1704. +static int sunxi_cedrus_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
  1705. +                                   unsigned int *nplanes, unsigned int sizes[],
  1706. +                                   struct device *alloc_devs[])
  1707. +{
  1708. +       struct sunxi_cedrus_ctx *ctx = vb2_get_drv_priv(vq);
  1709. +
  1710. +       if (*nbufs < 1)
  1711. +               *nbufs = 1;
  1712. +
  1713. +       if (*nbufs > VIDEO_MAX_FRAME)
  1714. +               *nbufs = VIDEO_MAX_FRAME;
  1715. +
  1716. +       switch (vq->type) {
  1717. +       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
  1718. +               *nplanes = ctx->vpu_src_fmt->num_planes;
  1719. +
  1720. +               sizes[0] = ctx->src_fmt.plane_fmt[0].sizeimage;
  1721. +               break;
  1722. +
  1723. +       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
  1724. +               *nplanes = ctx->vpu_dst_fmt->num_planes;
  1725. +
  1726. +               sizes[0] = round_up(ctx->dst_fmt.plane_fmt[0].sizeimage, 8);
  1727. +               sizes[1] = sizes[0];
  1728. +               break;
  1729. +
  1730. +       default:
  1731. +               dev_dbg(ctx->dev->dev, "invalid queue type: %d\n", vq->type);
  1732. +               return -EINVAL;
  1733. +       }
  1734. +
  1735. +       return 0;
  1736. +}
  1737. +
  1738. +static int sunxi_cedrus_buf_init(struct vb2_buffer *vb)
  1739. +{
  1740. +       struct vb2_queue *vq = vb->vb2_queue;
  1741. +       struct sunxi_cedrus_ctx *ctx = container_of(vq->drv_priv,
  1742. +                       struct sunxi_cedrus_ctx, fh);
  1743. +
  1744. +       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
  1745. +               ctx->dst_bufs[vb->index] = vb;
  1746. +
  1747. +       return 0;
  1748. +}
  1749. +
  1750. +static void sunxi_cedrus_buf_cleanup(struct vb2_buffer *vb)
  1751. +{
  1752. +       struct vb2_queue *vq = vb->vb2_queue;
  1753. +       struct sunxi_cedrus_ctx *ctx = container_of(vq->drv_priv,
  1754. +                       struct sunxi_cedrus_ctx, fh);
  1755. +
  1756. +       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
  1757. +               ctx->dst_bufs[vb->index] = NULL;
  1758. +}
  1759. +
  1760. +static int sunxi_cedrus_buf_prepare(struct vb2_buffer *vb)
  1761. +{
  1762. +       struct sunxi_cedrus_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
  1763. +       struct vb2_queue *vq = vb->vb2_queue;
  1764. +       int i;
  1765. +
  1766. +       dev_dbg(ctx->dev->dev, "type: %d\n", vb->vb2_queue->type);
  1767. +
  1768. +       switch (vq->type) {
  1769. +       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
  1770. +               if (vb2_plane_size(vb, 0)
  1771. +                   < ctx->src_fmt.plane_fmt[0].sizeimage) {
  1772. +                       dev_dbg(ctx->dev->dev, "plane too small for output\n");
  1773. +                       return -EINVAL;
  1774. +               }
  1775. +               break;
  1776. +
  1777. +       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
  1778. +               for (i = 0; i < ctx->vpu_dst_fmt->num_planes; ++i) {
  1779. +                       if (vb2_plane_size(vb, i)
  1780. +                           < ctx->dst_fmt.plane_fmt[i].sizeimage) {
  1781. +                               dev_dbg(ctx->dev->dev,
  1782. +                                       "plane %d too small for capture\n", i);
  1783. +                               break;
  1784. +                       }
  1785. +               }
  1786. +
  1787. +               if (i != ctx->vpu_dst_fmt->num_planes)
  1788. +                       return -EINVAL;
  1789. +               break;
  1790. +
  1791. +       default:
  1792. +               dev_dbg(ctx->dev->dev, "invalid queue type: %d\n", vq->type);
  1793. +               return -EINVAL;
  1794. +       }
  1795. +
  1796. +       return 0;
  1797. +}
  1798. +
  1799. +static void sunxi_cedrus_stop_streaming(struct vb2_queue *q)
  1800. +{
  1801. +       struct sunxi_cedrus_ctx *ctx = vb2_get_drv_priv(q);
  1802. +       struct vb2_v4l2_buffer *vbuf;
  1803. +       unsigned long flags;
  1804. +
  1805. +       for (;;) {
  1806. +               if (V4L2_TYPE_IS_OUTPUT(q->type))
  1807. +                       vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
  1808. +               else
  1809. +                       vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
  1810. +               if (!vbuf)
  1811. +                       return;
  1812. +               spin_lock_irqsave(&ctx->dev->irqlock, flags);
  1813. +               v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
  1814. +               spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
  1815. +       }
  1816. +}
  1817. +
  1818. +static void sunxi_cedrus_buf_queue(struct vb2_buffer *vb)
  1819. +{
  1820. +       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
  1821. +       struct sunxi_cedrus_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
  1822. +
  1823. +       v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
  1824. +}
  1825. +
  1826. +static struct vb2_ops sunxi_cedrus_qops = {
  1827. +       .queue_setup     = sunxi_cedrus_queue_setup,
  1828. +       .buf_prepare     = sunxi_cedrus_buf_prepare,
  1829. +       .buf_init        = sunxi_cedrus_buf_init,
  1830. +       .buf_cleanup     = sunxi_cedrus_buf_cleanup,
  1831. +       .buf_queue       = sunxi_cedrus_buf_queue,
  1832. +       .stop_streaming  = sunxi_cedrus_stop_streaming,
  1833. +       .wait_prepare    = vb2_ops_wait_prepare,
  1834. +       .wait_finish     = vb2_ops_wait_finish,
  1835. +};
  1836. +
  1837. +int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
  1838. +{
  1839. +       struct sunxi_cedrus_ctx *ctx = priv;
  1840. +       int ret;
  1841. +
  1842. +       src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
  1843. +       src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
  1844. +       src_vq->drv_priv = ctx;
  1845. +       src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
  1846. +       src_vq->ops = &sunxi_cedrus_qops;
  1847. +       src_vq->mem_ops = &vb2_dma_contig_memops;
  1848. +       src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
  1849. +       src_vq->lock = &ctx->dev->dev_mutex;
  1850. +       src_vq->v4l2_allow_requests = true;
  1851. +       src_vq->dev = ctx->dev->dev;
  1852. +
  1853. +       ret = vb2_queue_init(src_vq);
  1854. +       if (ret)
  1855. +               return ret;
  1856. +
  1857. +       dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
  1858. +       dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
  1859. +       dst_vq->drv_priv = ctx;
  1860. +       dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
  1861. +       dst_vq->ops = &sunxi_cedrus_qops;
  1862. +       dst_vq->mem_ops = &vb2_dma_contig_memops;
  1863. +       dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
  1864. +       dst_vq->lock = &ctx->dev->dev_mutex;
  1865. +       dst_vq->v4l2_allow_requests = true;
  1866. +       dst_vq->dev = ctx->dev->dev;
  1867. +
  1868. +       return vb2_queue_init(dst_vq);
  1869. +}
  1870. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.h b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.h
  1871. new file mode 100644
  1872. index 0000000..f0ac921
  1873. --- /dev/null
  1874. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.h
  1875. @@ -0,0 +1,33 @@
  1876. +/*
  1877. + * Sunxi Cedrus codec driver
  1878. + *
  1879. + * Copyright (C) 2016 Florent Revest
  1880. + * Florent Revest <florent.revest@free-electrons.com>
  1881. + *
  1882. + * Based on vim2m
  1883. + *
  1884. + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
  1885. + * Pawel Osciak, <pawel@osciak.com>
  1886. + * Marek Szyprowski, <m.szyprowski@samsung.com>
  1887. + *
  1888. + * This software is licensed under the terms of the GNU General Public
  1889. + * License version 2, as published by the Free Software Foundation, and
  1890. + * may be copied, distributed, and modified under those terms.
  1891. + *
  1892. + * This program is distributed in the hope that it will be useful,
  1893. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1894. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1895. + * GNU General Public License for more details.
  1896. + */
  1897. +
  1898. +#ifndef SUNXI_CEDRUS_DEC_H_
  1899. +#define SUNXI_CEDRUS_DEC_H_
  1900. +
  1901. +int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq);
  1902. +
  1903. +void job_abort(void *priv);
  1904. +void device_run(void *priv);
  1905. +
  1906. +extern const struct v4l2_ioctl_ops sunxi_cedrus_ioctl_ops;
  1907. +
  1908. +#endif /* SUNXI_CEDRUS_DEC_H_ */
  1909. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.c b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.c
  1910. new file mode 100644
  1911. index 0000000..72b9df4
  1912. --- /dev/null
  1913. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.c
  1914. @@ -0,0 +1,153 @@
  1915. +/*
  1916. + * Sunxi Cedrus codec driver
  1917. + *
  1918. + * Copyright (C) 2016 Florent Revest
  1919. + * Florent Revest <florent.revest@free-electrons.com>
  1920. + *
  1921. + * Based on vim2m
  1922. + *
  1923. + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
  1924. + * Pawel Osciak, <pawel@osciak.com>
  1925. + * Marek Szyprowski, <m.szyprowski@samsung.com>
  1926. + *
  1927. + * And reverse engineering efforts of the 'Cedrus' project
  1928. + * Copyright (c) 2013-2014 Jens Kuske <jenskuske@gmail.com>
  1929. + *
  1930. + * This software is licensed under the terms of the GNU General Public
  1931. + * License version 2, as published by the Free Software Foundation, and
  1932. + * may be copied, distributed, and modified under those terms.
  1933. + *
  1934. + * This program is distributed in the hope that it will be useful,
  1935. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1936. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1937. + * GNU General Public License for more details.
  1938. + */
  1939. +
  1940. +#include "sunxi_cedrus_common.h"
  1941. +
  1942. +#include <linux/clk.h>
  1943. +#include <linux/interrupt.h>
  1944. +#include <linux/dma-mapping.h>
  1945. +#include <linux/platform_device.h>
  1946. +#include <linux/of_reserved_mem.h>
  1947. +#include <linux/reset.h>
  1948. +
  1949. +#include <media/v4l2-mem2mem.h>
  1950. +#include <media/videobuf2-core.h>
  1951. +
  1952. +/*
  1953. + * Interrupt handlers.
  1954. + */
  1955. +
  1956. +static irqreturn_t sunxi_cedrus_ve_irq(int irq, void *dev_id)
  1957. +{
  1958. +       struct sunxi_cedrus_dev *vpu = dev_id;
  1959. +       struct sunxi_cedrus_ctx *curr_ctx;
  1960. +       struct vb2_v4l2_buffer *src_vb, *dst_vb;
  1961. +       int val;
  1962. +       unsigned long flags;
  1963. +
  1964. +       curr_ctx = v4l2_m2m_get_curr_priv(vpu->m2m_dev);
  1965. +
  1966. +       if (!curr_ctx) {
  1967. +               pr_err("Instance released before the end of transaction\n");
  1968. +               return IRQ_HANDLED;
  1969. +       }
  1970. +
  1971. +       src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
  1972. +       dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
  1973. +
  1974. +       spin_lock_irqsave(&vpu->irqlock, flags);
  1975. +       v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
  1976. +       v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
  1977. +       spin_unlock_irqrestore(&vpu->irqlock, flags);
  1978. +
  1979. +       v4l2_m2m_job_finish(vpu->m2m_dev, curr_ctx->fh.m2m_ctx);
  1980. +
  1981. +       return IRQ_HANDLED;
  1982. +}
  1983. +
  1984. +/*
  1985. + * Initialization/clean-up.
  1986. + */
  1987. +
  1988. +int sunxi_cedrus_hw_probe(struct sunxi_cedrus_dev *vpu)
  1989. +{
  1990. +       struct resource *res;
  1991. +       int irq_dec;
  1992. +       int ret;
  1993. +
  1994. +       irq_dec = platform_get_irq(vpu->pdev, 0);
  1995. +       if (irq_dec <= 0) {
  1996. +               dev_err(vpu->dev, "could not get ve IRQ\n");
  1997. +               return -ENXIO;
  1998. +       }
  1999. +       ret = devm_request_irq(vpu->dev, irq_dec, sunxi_cedrus_ve_irq, 0,
  2000. +                              dev_name(vpu->dev), vpu);
  2001. +       if (ret) {
  2002. +               dev_err(vpu->dev, "could not request ve IRQ\n");
  2003. +               return -ENXIO;
  2004. +       }
  2005. +
  2006. +       ret = of_reserved_mem_device_init(vpu->dev);
  2007. +       if (ret) {
  2008. +               dev_err(vpu->dev, "could not reserve memory\n");
  2009. +               return -ENODEV;
  2010. +       }
  2011. +
  2012. +       vpu->ahb_clk = devm_clk_get(vpu->dev, "ahb");
  2013. +       if (IS_ERR(vpu->ahb_clk)) {
  2014. +               dev_err(vpu->dev, "failed to get ahb clock\n");
  2015. +               return PTR_ERR(vpu->ahb_clk);
  2016. +       }
  2017. +       vpu->mod_clk = devm_clk_get(vpu->dev, "mod");
  2018. +       if (IS_ERR(vpu->mod_clk)) {
  2019. +               dev_err(vpu->dev, "failed to get mod clock\n");
  2020. +               return PTR_ERR(vpu->mod_clk);
  2021. +       }
  2022. +       vpu->ram_clk = devm_clk_get(vpu->dev, "ram");
  2023. +       if (IS_ERR(vpu->ram_clk)) {
  2024. +               dev_err(vpu->dev, "failed to get ram clock\n");
  2025. +               return PTR_ERR(vpu->ram_clk);
  2026. +       }
  2027. +
  2028. +       vpu->rstc = devm_reset_control_get(vpu->dev, NULL);
  2029. +
  2030. +       res = platform_get_resource(vpu->pdev, IORESOURCE_MEM, 0);
  2031. +       vpu->base = devm_ioremap_resource(vpu->dev, res);
  2032. +       if (!vpu->base)
  2033. +               dev_err(vpu->dev, "could not maps MACC registers\n");
  2034. +
  2035. +       ret = clk_prepare_enable(vpu->ahb_clk);
  2036. +       if (ret) {
  2037. +               dev_err(vpu->dev, "could not enable ahb clock\n");
  2038. +               return -EFAULT;
  2039. +       }
  2040. +       ret = clk_prepare_enable(vpu->mod_clk);
  2041. +       if (ret) {
  2042. +               clk_disable_unprepare(vpu->ahb_clk);
  2043. +               dev_err(vpu->dev, "could not enable mod clock\n");
  2044. +               return -EFAULT;
  2045. +       }
  2046. +       ret = clk_prepare_enable(vpu->ram_clk);
  2047. +       if (ret) {
  2048. +               clk_disable_unprepare(vpu->mod_clk);
  2049. +               clk_disable_unprepare(vpu->ahb_clk);
  2050. +               dev_err(vpu->dev, "could not enable ram clock\n");
  2051. +               return -EFAULT;
  2052. +       }
  2053. +
  2054. +       reset_control_assert(vpu->rstc);
  2055. +       reset_control_deassert(vpu->rstc);
  2056. +
  2057. +       return 0;
  2058. +}
  2059. +
  2060. +void sunxi_cedrus_hw_remove(struct sunxi_cedrus_dev *vpu)
  2061. +{
  2062. +       clk_disable_unprepare(vpu->ram_clk);
  2063. +       clk_disable_unprepare(vpu->mod_clk);
  2064. +       clk_disable_unprepare(vpu->ahb_clk);
  2065. +
  2066. +       of_reserved_mem_device_release(vpu->dev);
  2067. +}
  2068. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.h b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.h
  2069. new file mode 100644
  2070. index 0000000..3c9199b
  2071. --- /dev/null
  2072. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.h
  2073. @@ -0,0 +1,32 @@
  2074. +/*
  2075. + * Sunxi Cedrus codec driver
  2076. + *
  2077. + * Copyright (C) 2016 Florent Revest
  2078. + * Florent Revest <florent.revest@free-electrons.com>
  2079. + *
  2080. + * Based on vim2m
  2081. + *
  2082. + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
  2083. + * Pawel Osciak, <pawel@osciak.com>
  2084. + * Marek Szyprowski, <m.szyprowski@samsung.com>
  2085. + *
  2086. + * This software is licensed under the terms of the GNU General Public
  2087. + * License version 2, as published by the Free Software Foundation, and
  2088. + * may be copied, distributed, and modified under those terms.
  2089. + *
  2090. + * This program is distributed in the hope that it will be useful,
  2091. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2092. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2093. + * GNU General Public License for more details.
  2094. + */
  2095. +
  2096. +#ifndef SUNXI_CEDRUS_HW_H_
  2097. +#define SUNXI_CEDRUS_HW_H_
  2098. +
  2099. +struct sunxi_cedrus_dev;
  2100. +struct sunxi_cedrus_ctx;
  2101. +
  2102. +int sunxi_cedrus_hw_probe(struct sunxi_cedrus_dev *vpu);
  2103. +void sunxi_cedrus_hw_remove(struct sunxi_cedrus_dev *vpu);
  2104. +
  2105. +#endif /* SUNXI_CEDRUS_HW_H_ */
  2106. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_regs.h b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_regs.h
  2107. new file mode 100644
  2108. index 0000000..7384daa
  2109. --- /dev/null
  2110. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_regs.h
  2111. @@ -0,0 +1,170 @@
  2112. +/*
  2113. + * Sunxi Cedrus codec driver
  2114. + *
  2115. + * Copyright (C) 2016 Florent Revest
  2116. + * Florent Revest <florent.revest@free-electrons.com>
  2117. + *
  2118. + * Based on Cedrus
  2119. + *
  2120. + * Copyright (c) 2013 Jens Kuske <jenskuske@gmail.com>
  2121. + *
  2122. + * This software is licensed under the terms of the GNU General Public
  2123. + * License version 2, as published by the Free Software Foundation, and
  2124. + * may be copied, distributed, and modified under those terms.
  2125. + *
  2126. + * This program is distributed in the hope that it will be useful,
  2127. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2128. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2129. + * GNU General Public License for more details.
  2130. + */
  2131. +
  2132. +#ifndef SUNXI_CEDRUS_REGS_H
  2133. +#define SUNXI_CEDRUS_REGS_H
  2134. +
  2135. +/*
  2136. + * For more information consult http://linux-sunxi.org/VE_Register_guide
  2137. + */
  2138. +
  2139. +/* Special registers values */
  2140. +
  2141. +/* VE_CTRL:
  2142. + * The first 3 bits indicate the engine (0 for MPEG, 1 for H264, b for AVC...)
  2143. + * The 16th and 17th bits indicate the memory type (3 for DDR3 32 bits)
  2144. + * The 20th bit is unknown but needed
  2145. + */
  2146. +#define VE_CTRL_MPEG           0x130000
  2147. +#define VE_CTRL_H264           0x130001
  2148. +#define VE_CTRL_AVC            0x13000b
  2149. +#define VE_CTRL_REINIT         0x130007
  2150. +
  2151. +/* VE_MPEG_CTRL:
  2152. + * The bit 3 (0x8) is used to enable IRQs
  2153. + * The other bits are unknown but needed
  2154. + */
  2155. +#define VE_MPEG_CTRL_MPEG2     0x800001b8
  2156. +#define VE_MPEG_CTRL_MPEG4     (0x80084118 | BIT(7))
  2157. +#define VE_MPEG_CTRL_MPEG4_P   (VE_MPEG_CTRL_MPEG4 | BIT(12))
  2158. +
  2159. +/* VE_MPEG_VLD_ADDR:
  2160. + * The bits 27 to 4 are used for the address
  2161. + * The bits 31 to 28 (0x7) are used to select the MPEG or JPEG engine
  2162. + */
  2163. +#define VE_MPEG_VLD_ADDR_VAL(x)        ((x & 0x0ffffff0) | (x >> 28) | (0x7 << 28))
  2164. +
  2165. +/* VE_MPEG_TRIGGER:
  2166. + * The first three bits are used to trigger the engine
  2167. + * The bits 24 to 26 are used to select the input format (1 for MPEG1, 2 for
  2168. + *                           MPEG2, 4 for MPEG4)
  2169. + * The bit 21 (0x8) is used to disable bitstream error handling
  2170. + *
  2171. + * In MPEG4 the w*h value is somehow used for an offset, unknown but needed
  2172. + */
  2173. +#define VE_TRIG_MPEG1          0x8100000f
  2174. +#define VE_TRIG_MPEG2          0x8200000f
  2175. +#define VE_TRIG_MPEG4(w, h)    (0x8400000d | ((w * h) << 8))
  2176. +
  2177. +/* VE_MPEG_SDROT_CTRL:
  2178. + * The bit 8 at zero is used to disable x downscaling
  2179. + * The bit 10 at 0 is used to disable y downscaling
  2180. + * The other bits are unknown but needed
  2181. + */
  2182. +#define VE_NO_SDROT_CTRL       0x40620000
  2183. +
  2184. +/* Decent size fo video buffering verifier */
  2185. +#define VBV_SIZE               (1024 * 1024)
  2186. +
  2187. +/* Registers addresses */
  2188. +#define VE_CTRL                                0x000
  2189. +#define VE_VERSION                     0x0f0
  2190. +
  2191. +#define VE_MPEG_PIC_HDR                        0x100
  2192. +#define VE_MPEG_VOP_HDR                        0x104
  2193. +#define VE_MPEG_SIZE                   0x108
  2194. +#define VE_MPEG_FRAME_SIZE             0x10c
  2195. +#define VE_MPEG_MBA                    0x110
  2196. +#define VE_MPEG_CTRL                   0x114
  2197. +#define VE_MPEG_TRIGGER                        0x118
  2198. +#define VE_MPEG_STATUS                 0x11c
  2199. +#define VE_MPEG_TRBTRD_FIELD           0x120
  2200. +#define VE_MPEG_TRBTRD_FRAME           0x124
  2201. +#define VE_MPEG_VLD_ADDR               0x128
  2202. +#define VE_MPEG_VLD_OFFSET             0x12c
  2203. +#define VE_MPEG_VLD_LEN                        0x130
  2204. +#define VE_MPEG_VLD_END                        0x134
  2205. +#define VE_MPEG_MBH_ADDR               0x138
  2206. +#define VE_MPEG_DCAC_ADDR              0x13c
  2207. +#define VE_MPEG_NCF_ADDR               0x144
  2208. +#define VE_MPEG_REC_LUMA               0x148
  2209. +#define VE_MPEG_REC_CHROMA             0x14c
  2210. +#define VE_MPEG_FWD_LUMA               0x150
  2211. +#define VE_MPEG_FWD_CHROMA             0x154
  2212. +#define VE_MPEG_BACK_LUMA              0x158
  2213. +#define VE_MPEG_BACK_CHROMA            0x15c
  2214. +#define VE_MPEG_IQ_MIN_INPUT           0x180
  2215. +#define VE_MPEG_QP_INPUT               0x184
  2216. +#define VE_MPEG_JPEG_SIZE              0x1b8
  2217. +#define VE_MPEG_JPEG_RES_INT           0x1c0
  2218. +#define VE_MPEG_ERROR                  0x1c4
  2219. +#define VE_MPEG_CTR_MB                 0x1c8
  2220. +#define VE_MPEG_ROT_LUMA               0x1cc
  2221. +#define VE_MPEG_ROT_CHROMA             0x1d0
  2222. +#define VE_MPEG_SDROT_CTRL             0x1d4
  2223. +#define VE_MPEG_RAM_WRITE_PTR          0x1e0
  2224. +#define VE_MPEG_RAM_WRITE_DATA         0x1e4
  2225. +
  2226. +#define VE_H264_FRAME_SIZE             0x200
  2227. +#define VE_H264_PIC_HDR                        0x204
  2228. +#define VE_H264_SLICE_HDR              0x208
  2229. +#define VE_H264_SLICE_HDR2             0x20c
  2230. +#define VE_H264_PRED_WEIGHT            0x210
  2231. +#define VE_H264_QP_PARAM               0x21c
  2232. +#define VE_H264_CTRL                   0x220
  2233. +#define VE_H264_TRIGGER                        0x224
  2234. +#define VE_H264_STATUS                 0x228
  2235. +#define VE_H264_CUR_MB_NUM             0x22c
  2236. +#define VE_H264_VLD_ADDR               0x230
  2237. +#define VE_H264_VLD_OFFSET             0x234
  2238. +#define VE_H264_VLD_LEN                        0x238
  2239. +#define VE_H264_VLD_END                        0x23c
  2240. +#define VE_H264_SDROT_CTRL             0x240
  2241. +#define VE_H264_OUTPUT_FRAME_IDX       0x24c
  2242. +#define VE_H264_EXTRA_BUFFER1          0x250
  2243. +#define VE_H264_EXTRA_BUFFER2          0x254
  2244. +#define VE_H264_BASIC_BITS             0x2dc
  2245. +#define VE_H264_RAM_WRITE_PTR          0x2e0
  2246. +#define VE_H264_RAM_WRITE_DATA         0x2e4
  2247. +
  2248. +#define VE_SRAM_H264_PRED_WEIGHT_TABLE 0x000
  2249. +#define VE_SRAM_H264_FRAMEBUFFER_LIST  0x400
  2250. +#define VE_SRAM_H264_REF_LIST0         0x640
  2251. +#define VE_SRAM_H264_REF_LIST1         0x664
  2252. +#define VE_SRAM_H264_SCALING_LISTS     0x800
  2253. +
  2254. +#define VE_ISP_INPUT_SIZE              0xa00
  2255. +#define VE_ISP_INPUT_STRIDE            0xa04
  2256. +#define VE_ISP_CTRL                    0xa08
  2257. +#define VE_ISP_INPUT_LUMA              0xa78
  2258. +#define VE_ISP_INPUT_CHROMA            0xa7c
  2259. +
  2260. +#define VE_AVC_PARAM                   0xb04
  2261. +#define VE_AVC_QP                      0xb08
  2262. +#define VE_AVC_MOTION_EST              0xb10
  2263. +#define VE_AVC_CTRL                    0xb14
  2264. +#define VE_AVC_TRIGGER                 0xb18
  2265. +#define VE_AVC_STATUS                  0xb1c
  2266. +#define VE_AVC_BASIC_BITS              0xb20
  2267. +#define VE_AVC_UNK_BUF                 0xb60
  2268. +#define VE_AVC_VLE_ADDR                        0xb80
  2269. +#define VE_AVC_VLE_END                 0xb84
  2270. +#define VE_AVC_VLE_OFFSET              0xb88
  2271. +#define VE_AVC_VLE_MAX                 0xb8c
  2272. +#define VE_AVC_VLE_LENGTH              0xb90
  2273. +#define VE_AVC_REF_LUMA                        0xba0
  2274. +#define VE_AVC_REF_CHROMA              0xba4
  2275. +#define VE_AVC_REC_LUMA                        0xbb0
  2276. +#define VE_AVC_REC_CHROMA              0xbb4
  2277. +#define VE_AVC_REF_SLUMA               0xbb8
  2278. +#define VE_AVC_REC_SLUMA               0xbbc
  2279. +#define VE_AVC_MB_INFO                 0xbc0
  2280. +
  2281. +#endif /* SUNXI_CEDRUS_REGS_H */
  2282.  
  2283. From patchwork Thu Aug 25 09:39:46 2016
  2284. Content-Type: text/plain; charset="utf-8"
  2285. MIME-Version: 1.0
  2286. Content-Transfer-Encoding: 7bit
  2287. X-Patchwork-Submitter: Florent Revest <florent.revest@free-electrons.com>
  2288. X-Patchwork-Id: 711052
  2289. Return-Path: <linux-kernel-owner@vger.kernel.org>
  2290. Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
  2291.         id S1758966AbcHYJkZ (ORCPT <rfc822;w@1wt.eu>);
  2292.         Thu, 25 Aug 2016 05:40:25 -0400
  2293. Received: from down.free-electrons.com ([37.187.137.238]:34204 "EHLO
  2294.         mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org
  2295.         with ESMTP id S1758941AbcHYJkW (ORCPT
  2296.         <rfc822;linux-kernel@vger.kernel.org>);
  2297.         Thu, 25 Aug 2016 05:40:22 -0400
  2298. From: Florent Revest <florent.revest@free-electrons.com>
  2299. To: linux-media@vger.kernel.org
  2300. Cc: florent.revest@free-electrons.com, linux-sunxi@googlegroups.com,
  2301.         maxime.ripard@free-electrons.com, posciak@chromium.org,
  2302.         hans.verkuil@cisco.com, thomas.petazzoni@free-electrons.com,
  2303.         mchehab@kernel.org, linux-kernel@vger.kernel.org, wens@csie.org
  2304. Subject: [RFC 07/10] sunxi-cedrus: Add a MPEG 2 codec
  2305. Date: Thu, 25 Aug 2016 11:39:46 +0200
  2306. Message-Id:
  2307.  <1472117989-21455-8-git-send-email-florent.revest@free-electrons.com>
  2308. X-Mailer: git-send-email 2.7.4
  2309. In-Reply-To:
  2310.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  2311. References:
  2312.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  2313. Sender: linux-kernel-owner@vger.kernel.org
  2314. List-ID: <linux-kernel.vger.kernel.org>
  2315. X-Mailing-List: linux-kernel@vger.kernel.org
  2316. Content-Length: 12799
  2317. Lines: 335
  2318.  
  2319. This patch introduces the support of MPEG2 video decoding to the
  2320. sunxi-cedrus video decoder driver.
  2321.  
  2322. Signed-off-by: Florent Revest <florent.revest@free-electrons.com>
  2323. ---
  2324. drivers/media/platform/sunxi-cedrus/Makefile       |   2 +-
  2325.  drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c |  26 +++-
  2326.  .../platform/sunxi-cedrus/sunxi_cedrus_common.h    |   2 +
  2327.  .../media/platform/sunxi-cedrus/sunxi_cedrus_dec.c |  15 +-
  2328.  .../media/platform/sunxi-cedrus/sunxi_cedrus_hw.c  |  17 ++-
  2329.  .../media/platform/sunxi-cedrus/sunxi_cedrus_hw.h  |   4 +
  2330.  .../platform/sunxi-cedrus/sunxi_cedrus_mpeg2.c     | 152 +++++++++++++++++++++
  2331.  7 files changed, 211 insertions(+), 7 deletions(-)
  2332.  create mode 100644 drivers/media/platform/sunxi-cedrus/sunxi_cedrus_mpeg2.c
  2333.  
  2334. diff --git a/drivers/media/platform/sunxi-cedrus/Makefile b/drivers/media/platform/sunxi-cedrus/Makefile
  2335. index 14c2f7a..2d495a2 100644
  2336. --- a/drivers/media/platform/sunxi-cedrus/Makefile
  2337. +++ b/drivers/media/platform/sunxi-cedrus/Makefile
  2338. @@ -1,2 +1,2 @@
  2339.  obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += sunxi_cedrus.o sunxi_cedrus_hw.o \
  2340. -                                   sunxi_cedrus_dec.o
  2341. +                                   sunxi_cedrus_dec.o sunxi_cedrus_mpeg2.o
  2342. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c
  2343. index 17af34c..d1c957a 100644
  2344. --- a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c
  2345. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c
  2346. @@ -46,14 +46,31 @@ static int sunxi_cedrus_s_ctrl(struct v4l2_ctrl *ctrl)
  2347.         struct sunxi_cedrus_ctx *ctx =
  2348.                 container_of(ctrl->handler, struct sunxi_cedrus_ctx, hdl);
  2349.  
  2350. -       v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
  2351. -       return -EINVAL;
  2352. +       switch (ctrl->id) {
  2353. +       case V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR:
  2354. +               /* This is kept in memory and used directly. */
  2355. +               break;
  2356. +       default:
  2357. +               v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
  2358. +               return -EINVAL;
  2359. +       }
  2360. +
  2361. +       return 0;
  2362.  }
  2363.  
  2364.  static const struct v4l2_ctrl_ops sunxi_cedrus_ctrl_ops = {
  2365.         .s_ctrl = sunxi_cedrus_s_ctrl,
  2366.  };
  2367.  
  2368. +static const struct v4l2_ctrl_config sunxi_cedrus_ctrl_mpeg2_frame_hdr = {
  2369. +       .ops = &sunxi_cedrus_ctrl_ops,
  2370. +       .id = V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR,
  2371. +       .type = V4L2_CTRL_TYPE_PRIVATE,
  2372. +       .name = "MPEG2 Frame Header Parameters",
  2373. +       .max_reqs = VIDEO_MAX_FRAME,
  2374. +       .elem_size = sizeof(struct v4l2_ctrl_mpeg2_frame_hdr),
  2375. +};
  2376. +
  2377.  /*
  2378.   * File operations
  2379.   */
  2380. @@ -78,6 +95,10 @@ static int sunxi_cedrus_open(struct file *file)
  2381.         hdl = &ctx->hdl;
  2382.         v4l2_ctrl_handler_init(hdl, 1);
  2383.  
  2384. +       ctx->mpeg2_frame_hdr_ctrl = v4l2_ctrl_new_custom(hdl,
  2385. +                       &sunxi_cedrus_ctrl_mpeg2_frame_hdr, NULL);
  2386. +       ctx->mpeg2_frame_hdr_ctrl->flags |= V4L2_CTRL_FLAG_REQ_KEEP;
  2387. +
  2388.         if (hdl->error) {
  2389.                 rc = hdl->error;
  2390.                 v4l2_ctrl_handler_free(hdl);
  2391. @@ -117,6 +138,7 @@ static int sunxi_cedrus_release(struct file *file)
  2392.         v4l2_fh_del(&ctx->fh);
  2393.         v4l2_fh_exit(&ctx->fh);
  2394.         v4l2_ctrl_handler_free(&ctx->hdl);
  2395. +       ctx->mpeg2_frame_hdr_ctrl = NULL;
  2396.         mutex_lock(&dev->dev_mutex);
  2397.         v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
  2398.         mutex_unlock(&dev->dev_mutex);
  2399. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_common.h b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_common.h
  2400. index 6b8d87a..e715184 100644
  2401. --- a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_common.h
  2402. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_common.h
  2403. @@ -70,6 +70,8 @@ struct sunxi_cedrus_ctx {
  2404.         struct v4l2_ctrl_handler hdl;
  2405.  
  2406.         struct vb2_buffer *dst_bufs[VIDEO_MAX_FRAME];
  2407. +
  2408. +       struct v4l2_ctrl *mpeg2_frame_hdr_ctrl;
  2409.  };
  2410.  
  2411.  static inline void sunxi_cedrus_write(struct sunxi_cedrus_dev *vpu,
  2412. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.c b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.c
  2413. index 71ef34b..38e8a3a 100644
  2414. --- a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.c
  2415. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.c
  2416. @@ -48,6 +48,11 @@ static struct sunxi_cedrus_fmt formats[] = {
  2417.                 .depth = 8,
  2418.                 .num_planes = 2,
  2419.         },
  2420. +       {
  2421. +               .fourcc = V4L2_PIX_FMT_MPEG2_FRAME,
  2422. +               .types  = SUNXI_CEDRUS_OUTPUT,
  2423. +               .num_planes = 1,
  2424. +       },
  2425.  };
  2426.  
  2427.  #define NUM_FORMATS ARRAY_SIZE(formats)
  2428. @@ -120,8 +125,14 @@ void device_run(void *priv)
  2429.                  V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_PFRAME |
  2430.                  V4L2_BUF_FLAG_BFRAME   | V4L2_BUF_FLAG_TSTAMP_SRC_MASK);
  2431.  
  2432. -       v4l2_m2m_buf_done(in_vb, VB2_BUF_STATE_ERROR);
  2433. -       v4l2_m2m_buf_done(out_vb, VB2_BUF_STATE_ERROR);
  2434. +       if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_MPEG2_FRAME) {
  2435. +               struct v4l2_ctrl_mpeg2_frame_hdr *frame_hdr =
  2436. +                               ctx->mpeg2_frame_hdr_ctrl->p_new.p;
  2437. +               process_mpeg2(ctx, in_buf, out_luma, out_chroma, frame_hdr);
  2438. +       } else {
  2439. +               v4l2_m2m_buf_done(in_vb, VB2_BUF_STATE_ERROR);
  2440. +               v4l2_m2m_buf_done(out_vb, VB2_BUF_STATE_ERROR);
  2441. +       }
  2442.  }
  2443.  
  2444.  /*
  2445. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.c b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.c
  2446. index 72b9df4..160de17 100644
  2447. --- a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.c
  2448. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.c
  2449. @@ -47,6 +47,13 @@ static irqreturn_t sunxi_cedrus_ve_irq(int irq, void *dev_id)
  2450.         int val;
  2451.         unsigned long flags;
  2452.  
  2453. +       /* Disable MPEG interrupts and stop the MPEG engine */
  2454. +       val = sunxi_cedrus_read(vpu, VE_MPEG_CTRL);
  2455. +       sunxi_cedrus_write(vpu, val & (~0xf), VE_MPEG_CTRL);
  2456. +       val = sunxi_cedrus_read(vpu, VE_MPEG_STATUS);
  2457. +       sunxi_cedrus_write(vpu, 0x0000c00f, VE_MPEG_STATUS);
  2458. +       sunxi_cedrus_write(vpu, VE_CTRL_REINIT, VE_CTRL);
  2459. +
  2460.         curr_ctx = v4l2_m2m_get_curr_priv(vpu->m2m_dev);
  2461.  
  2462.         if (!curr_ctx) {
  2463. @@ -57,9 +64,15 @@ static irqreturn_t sunxi_cedrus_ve_irq(int irq, void *dev_id)
  2464.         src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
  2465.         dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
  2466.  
  2467. +       /* First bit of MPEG_STATUS means success */
  2468.         spin_lock_irqsave(&vpu->irqlock, flags);
  2469. -       v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
  2470. -       v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
  2471. +       if (val & 0x1) {
  2472. +               v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
  2473. +               v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
  2474. +       } else {
  2475. +               v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
  2476. +               v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
  2477. +       }
  2478.         spin_unlock_irqrestore(&vpu->irqlock, flags);
  2479.  
  2480.         v4l2_m2m_job_finish(vpu->m2m_dev, curr_ctx->fh.m2m_ctx);
  2481. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.h b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.h
  2482. index 3c9199b..78625e5 100644
  2483. --- a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.h
  2484. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.h
  2485. @@ -29,4 +29,8 @@ struct sunxi_cedrus_ctx;
  2486.  int sunxi_cedrus_hw_probe(struct sunxi_cedrus_dev *vpu);
  2487.  void sunxi_cedrus_hw_remove(struct sunxi_cedrus_dev *vpu);
  2488.  
  2489. +void process_mpeg2(struct sunxi_cedrus_ctx *ctx, dma_addr_t in_buf,
  2490. +                  dma_addr_t out_luma, dma_addr_t out_chroma,
  2491. +                  struct v4l2_ctrl_mpeg2_frame_hdr *frame_hdr);
  2492. +
  2493.  #endif /* SUNXI_CEDRUS_HW_H_ */
  2494. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_mpeg2.c b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_mpeg2.c
  2495. new file mode 100644
  2496. index 0000000..9381c63
  2497. --- /dev/null
  2498. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_mpeg2.c
  2499. @@ -0,0 +1,152 @@
  2500. +/*
  2501. + * Sunxi Cedrus codec driver
  2502. + *
  2503. + * Copyright (C) 2016 Florent Revest
  2504. + * Florent Revest <florent.revest@free-electrons.com>
  2505. + *
  2506. + * Based on reverse engineering efforts of the 'Cedrus' project
  2507. + * Copyright (c) 2013-2014 Jens Kuske <jenskuske@gmail.com>
  2508. + *
  2509. + * This software is licensed under the terms of the GNU General Public
  2510. + * License version 2, as published by the Free Software Foundation, and
  2511. + * may be copied, distributed, and modified under those terms.
  2512. + *
  2513. + * This program is distributed in the hope that it will be useful,
  2514. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2515. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2516. + * GNU General Public License for more details.
  2517. + */
  2518. +
  2519. +#include "sunxi_cedrus_common.h"
  2520. +
  2521. +#include <media/videobuf2-dma-contig.h>
  2522. +
  2523. +static const u8 mpeg_default_intra_quant[64] = {
  2524. +        8, 16, 16, 19, 16, 19, 22, 22,
  2525. +       22, 22, 22, 22, 26, 24, 26, 27,
  2526. +       27, 27, 26, 26, 26, 26, 27, 27,
  2527. +       27, 29, 29, 29, 34, 34, 34, 29,
  2528. +       29, 29, 27, 27, 29, 29, 32, 32,
  2529. +       34, 34, 37, 38, 37, 35, 35, 34,
  2530. +       35, 38, 38, 40, 40, 40, 48, 48,
  2531. +       46, 46, 56, 56, 58, 69, 69, 83
  2532. +};
  2533. +
  2534. +#define m_iq(i) (((64 + i) << 8) | mpeg_default_intra_quant[i])
  2535. +
  2536. +static const u8 mpeg_default_non_intra_quant[64] = {
  2537. +       16, 16, 16, 16, 16, 16, 16, 16,
  2538. +       16, 16, 16, 16, 16, 16, 16, 16,
  2539. +       16, 16, 16, 16, 16, 16, 16, 16,
  2540. +       16, 16, 16, 16, 16, 16, 16, 16,
  2541. +       16, 16, 16, 16, 16, 16, 16, 16,
  2542. +       16, 16, 16, 16, 16, 16, 16, 16,
  2543. +       16, 16, 16, 16, 16, 16, 16, 16,
  2544. +       16, 16, 16, 16, 16, 16, 16, 16
  2545. +};
  2546. +
  2547. +#define m_niq(i) ((i << 8) | mpeg_default_non_intra_quant[i])
  2548. +
  2549. +void process_mpeg2(struct sunxi_cedrus_ctx *ctx, dma_addr_t in_buf,
  2550. +                  dma_addr_t out_luma, dma_addr_t out_chroma,
  2551. +                  struct v4l2_ctrl_mpeg2_frame_hdr *frame_hdr)
  2552. +{
  2553. +       struct sunxi_cedrus_dev *dev = ctx->dev;
  2554. +
  2555. +       u16 width = DIV_ROUND_UP(frame_hdr->width, 16);
  2556. +       u16 height = DIV_ROUND_UP(frame_hdr->height, 16);
  2557. +
  2558. +       u32 pic_header = 0;
  2559. +       u32 vld_len = frame_hdr->slice_len - frame_hdr->slice_pos;
  2560. +       int i;
  2561. +
  2562. +       struct vb2_buffer *fwd_vb2_buf, *bwd_vb2_buf;
  2563. +       dma_addr_t fwd_luma = 0, fwd_chroma = 0, bwd_luma = 0, bwd_chroma = 0;
  2564. +
  2565. +       /*
  2566. +        * The VPU is only able to handle bus addresses so we have to subtract
  2567. +        * the RAM offset to the physcal addresses
  2568. +        */
  2569. +       fwd_vb2_buf = ctx->dst_bufs[frame_hdr->forward_index];
  2570. +       if (fwd_vb2_buf) {
  2571. +               fwd_luma   = vb2_dma_contig_plane_dma_addr(fwd_vb2_buf, 0);
  2572. +               fwd_chroma = vb2_dma_contig_plane_dma_addr(fwd_vb2_buf, 1);
  2573. +               fwd_luma   -= PHYS_OFFSET;
  2574. +               fwd_chroma -= PHYS_OFFSET;
  2575. +       }
  2576. +
  2577. +       bwd_vb2_buf = ctx->dst_bufs[frame_hdr->backward_index];
  2578. +       if (bwd_vb2_buf) {
  2579. +               bwd_luma   = vb2_dma_contig_plane_dma_addr(bwd_vb2_buf, 0);
  2580. +               bwd_chroma = vb2_dma_contig_plane_dma_addr(bwd_vb2_buf, 1);
  2581. +               bwd_chroma -= PHYS_OFFSET;
  2582. +               bwd_luma   -= PHYS_OFFSET;
  2583. +       }
  2584. +
  2585. +       /* Activates MPEG engine */
  2586. +       sunxi_cedrus_write(dev, VE_CTRL_MPEG, VE_CTRL);
  2587. +
  2588. +       /* Upload quantization matrices */
  2589. +       for (i = 0; i < 64; i++) {
  2590. +               sunxi_cedrus_write(dev, m_iq(i),  VE_MPEG_IQ_MIN_INPUT);
  2591. +               sunxi_cedrus_write(dev, m_niq(i), VE_MPEG_IQ_MIN_INPUT);
  2592. +       }
  2593. +
  2594. +       /* Image's dimensions */
  2595. +       sunxi_cedrus_write(dev, width << 8  | height,      VE_MPEG_SIZE);
  2596. +       sunxi_cedrus_write(dev, width << 20 | height << 4, VE_MPEG_FRAME_SIZE);
  2597. +
  2598. +       /* MPEG picture's header */
  2599. +       pic_header |= (frame_hdr->picture_coding_type        & 0xf) << 28;
  2600. +       pic_header |= (frame_hdr->f_code[0][0]               & 0xf) << 24;
  2601. +       pic_header |= (frame_hdr->f_code[0][1]               & 0xf) << 20;
  2602. +       pic_header |= (frame_hdr->f_code[1][0]               & 0xf) << 16;
  2603. +       pic_header |= (frame_hdr->f_code[1][1]               & 0xf) << 12;
  2604. +       pic_header |= (frame_hdr->intra_dc_precision         & 0x3) << 10;
  2605. +       pic_header |= (frame_hdr->picture_structure          & 0x3) << 8;
  2606. +       pic_header |= (frame_hdr->top_field_first            & 0x1) << 7;
  2607. +       pic_header |= (frame_hdr->frame_pred_frame_dct       & 0x1) << 6;
  2608. +       pic_header |= (frame_hdr->concealment_motion_vectors & 0x1) << 5;
  2609. +       pic_header |= (frame_hdr->q_scale_type               & 0x1) << 4;
  2610. +       pic_header |= (frame_hdr->intra_vlc_format           & 0x1) << 3;
  2611. +       pic_header |= (frame_hdr->alternate_scan             & 0x1) << 2;
  2612. +       sunxi_cedrus_write(dev, pic_header, VE_MPEG_PIC_HDR);
  2613. +
  2614. +       /* Enable interrupt and an unknown control flag */
  2615. +       sunxi_cedrus_write(dev, VE_MPEG_CTRL_MPEG2, VE_MPEG_CTRL);
  2616. +
  2617. +       /* Macroblock address */
  2618. +       sunxi_cedrus_write(dev, 0, VE_MPEG_MBA);
  2619. +
  2620. +       /* Clear previous errors */
  2621. +       sunxi_cedrus_write(dev, 0, VE_MPEG_ERROR);
  2622. +
  2623. +       /* Unknown register */
  2624. +       sunxi_cedrus_write(dev, 0, VE_MPEG_CTR_MB);
  2625. +
  2626. +       /* Forward and backward prediction buffers (cached in dst_bufs) */
  2627. +       sunxi_cedrus_write(dev, fwd_luma,   VE_MPEG_FWD_LUMA);
  2628. +       sunxi_cedrus_write(dev, fwd_chroma, VE_MPEG_FWD_CHROMA);
  2629. +       sunxi_cedrus_write(dev, bwd_luma,   VE_MPEG_BACK_LUMA);
  2630. +       sunxi_cedrus_write(dev, bwd_chroma, VE_MPEG_BACK_CHROMA);
  2631. +
  2632. +       /* Output luma and chroma buffers */
  2633. +       sunxi_cedrus_write(dev, out_luma,   VE_MPEG_REC_LUMA);
  2634. +       sunxi_cedrus_write(dev, out_chroma, VE_MPEG_REC_CHROMA);
  2635. +       sunxi_cedrus_write(dev, out_luma,   VE_MPEG_ROT_LUMA);
  2636. +       sunxi_cedrus_write(dev, out_chroma, VE_MPEG_ROT_CHROMA);
  2637. +
  2638. +       /* Input offset and length in bits */
  2639. +       sunxi_cedrus_write(dev, frame_hdr->slice_pos, VE_MPEG_VLD_OFFSET);
  2640. +       sunxi_cedrus_write(dev, vld_len, VE_MPEG_VLD_LEN);
  2641. +
  2642. +       /* Input beginning and end addresses */
  2643. +       sunxi_cedrus_write(dev, VE_MPEG_VLD_ADDR_VAL(in_buf), VE_MPEG_VLD_ADDR);
  2644. +       sunxi_cedrus_write(dev, in_buf + VBV_SIZE - 1, VE_MPEG_VLD_END);
  2645. +
  2646. +       /* Starts the MPEG engine */
  2647. +       if (frame_hdr->type == MPEG2)
  2648. +               sunxi_cedrus_write(dev, VE_TRIG_MPEG2, VE_MPEG_TRIGGER);
  2649. +       else
  2650. +               sunxi_cedrus_write(dev, VE_TRIG_MPEG1, VE_MPEG_TRIGGER);
  2651. +}
  2652.  
  2653. From patchwork Thu Aug 25 09:39:47 2016
  2654. Content-Type: text/plain; charset="utf-8"
  2655. MIME-Version: 1.0
  2656. Content-Transfer-Encoding: 7bit
  2657. X-Patchwork-Submitter: Florent Revest <florent.revest@free-electrons.com>
  2658. X-Patchwork-Id: 711055
  2659. Return-Path: <linux-kernel-owner@vger.kernel.org>
  2660. Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
  2661.         id S1759323AbcHYJkw (ORCPT <rfc822;w@1wt.eu>);
  2662.         Thu, 25 Aug 2016 05:40:52 -0400
  2663. Received: from down.free-electrons.com ([37.187.137.238]:34217 "EHLO
  2664.         mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org
  2665.         with ESMTP id S1758992AbcHYJk2 (ORCPT
  2666.         <rfc822;linux-kernel@vger.kernel.org>);
  2667.         Thu, 25 Aug 2016 05:40:28 -0400
  2668. From: Florent Revest <florent.revest@free-electrons.com>
  2669. To: linux-media@vger.kernel.org
  2670. Cc: florent.revest@free-electrons.com, linux-sunxi@googlegroups.com,
  2671.         maxime.ripard@free-electrons.com, posciak@chromium.org,
  2672.         hans.verkuil@cisco.com, thomas.petazzoni@free-electrons.com,
  2673.         mchehab@kernel.org, linux-kernel@vger.kernel.org, wens@csie.org
  2674. Subject: [RFC 08/10] sunxi-cedrus: Add a MPEG 4 codec
  2675. Date: Thu, 25 Aug 2016 11:39:47 +0200
  2676. Message-Id:
  2677.  <1472117989-21455-9-git-send-email-florent.revest@free-electrons.com>
  2678. X-Mailer: git-send-email 2.7.4
  2679. In-Reply-To:
  2680.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  2681. References:
  2682.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  2683. Sender: linux-kernel-owner@vger.kernel.org
  2684. List-ID: <linux-kernel.vger.kernel.org>
  2685. X-Mailing-List: linux-kernel@vger.kernel.org
  2686. Content-Length: 12626
  2687. Lines: 322
  2688.  
  2689. This patch introduces the support of MPEG4 video decoding to the
  2690. sunxi-cedrus video decoder driver.
  2691.  
  2692. Signed-off-by: Florent Revest <florent.revest@free-electrons.com>
  2693. ---
  2694. drivers/media/platform/sunxi-cedrus/Makefile       |   3 +-
  2695.  drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c |  15 +++
  2696.  .../platform/sunxi-cedrus/sunxi_cedrus_common.h    |  13 ++
  2697.  .../media/platform/sunxi-cedrus/sunxi_cedrus_dec.c |  33 +++++
  2698.  .../media/platform/sunxi-cedrus/sunxi_cedrus_hw.h  |   3 +
  2699.  .../platform/sunxi-cedrus/sunxi_cedrus_mpeg4.c     | 140 +++++++++++++++++++++
  2700.  6 files changed, 206 insertions(+), 1 deletion(-)
  2701.  create mode 100644 drivers/media/platform/sunxi-cedrus/sunxi_cedrus_mpeg4.c
  2702.  
  2703. diff --git a/drivers/media/platform/sunxi-cedrus/Makefile b/drivers/media/platform/sunxi-cedrus/Makefile
  2704. index 2d495a2..823d611 100644
  2705. --- a/drivers/media/platform/sunxi-cedrus/Makefile
  2706. +++ b/drivers/media/platform/sunxi-cedrus/Makefile
  2707. @@ -1,2 +1,3 @@
  2708.  obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += sunxi_cedrus.o sunxi_cedrus_hw.o \
  2709. -                                   sunxi_cedrus_dec.o sunxi_cedrus_mpeg2.o
  2710. +                                   sunxi_cedrus_dec.o sunxi_cedrus_mpeg2.o \
  2711. +                                   sunxi_cedrus_mpeg4.o
  2712. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c
  2713. index d1c957a..3001440 100644
  2714. --- a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c
  2715. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus.c
  2716. @@ -47,6 +47,7 @@ static int sunxi_cedrus_s_ctrl(struct v4l2_ctrl *ctrl)
  2717.                 container_of(ctrl->handler, struct sunxi_cedrus_ctx, hdl);
  2718.  
  2719.         switch (ctrl->id) {
  2720. +       case V4L2_CID_MPEG_VIDEO_MPEG4_FRAME_HDR:
  2721.         case V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR:
  2722.                 /* This is kept in memory and used directly. */
  2723.                 break;
  2724. @@ -71,6 +72,15 @@ static const struct v4l2_ctrl_config sunxi_cedrus_ctrl_mpeg2_frame_hdr = {
  2725.         .elem_size = sizeof(struct v4l2_ctrl_mpeg2_frame_hdr),
  2726.  };
  2727.  
  2728. +static const struct v4l2_ctrl_config sunxi_cedrus_ctrl_mpeg4_frame_hdr = {
  2729. +       .ops = &sunxi_cedrus_ctrl_ops,
  2730. +       .id = V4L2_CID_MPEG_VIDEO_MPEG4_FRAME_HDR,
  2731. +       .type = V4L2_CTRL_TYPE_PRIVATE,
  2732. +       .name = "MPEG4 Frame Header Parameters",
  2733. +       .max_reqs = VIDEO_MAX_FRAME,
  2734. +       .elem_size = sizeof(struct v4l2_ctrl_mpeg4_frame_hdr),
  2735. +};
  2736. +
  2737.  /*
  2738.   * File operations
  2739.   */
  2740. @@ -99,6 +109,10 @@ static int sunxi_cedrus_open(struct file *file)
  2741.                         &sunxi_cedrus_ctrl_mpeg2_frame_hdr, NULL);
  2742.         ctx->mpeg2_frame_hdr_ctrl->flags |= V4L2_CTRL_FLAG_REQ_KEEP;
  2743.  
  2744. +       ctx->mpeg4_frame_hdr_ctrl = v4l2_ctrl_new_custom(hdl,
  2745. +                       &sunxi_cedrus_ctrl_mpeg4_frame_hdr, NULL);
  2746. +       ctx->mpeg4_frame_hdr_ctrl->flags |= V4L2_CTRL_FLAG_REQ_KEEP;
  2747. +
  2748.         if (hdl->error) {
  2749.                 rc = hdl->error;
  2750.                 v4l2_ctrl_handler_free(hdl);
  2751. @@ -139,6 +153,7 @@ static int sunxi_cedrus_release(struct file *file)
  2752.         v4l2_fh_exit(&ctx->fh);
  2753.         v4l2_ctrl_handler_free(&ctx->hdl);
  2754.         ctx->mpeg2_frame_hdr_ctrl = NULL;
  2755. +       ctx->mpeg4_frame_hdr_ctrl = NULL;
  2756.         mutex_lock(&dev->dev_mutex);
  2757.         v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
  2758.         mutex_unlock(&dev->dev_mutex);
  2759. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_common.h b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_common.h
  2760. index e715184..33fa891 100644
  2761. --- a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_common.h
  2762. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_common.h
  2763. @@ -49,6 +49,18 @@ struct sunxi_cedrus_dev {
  2764.         struct reset_control *rstc;
  2765.  
  2766.         char *base;
  2767. +
  2768. +       unsigned int mbh_buf;
  2769. +       unsigned int dcac_buf;
  2770. +       unsigned int ncf_buf;
  2771. +
  2772. +       void *mbh_buf_virt;
  2773. +       void *dcac_buf_virt;
  2774. +       void *ncf_buf_virt;
  2775. +
  2776. +       unsigned int mbh_buf_size;
  2777. +       unsigned int dcac_buf_size;
  2778. +       unsigned int ncf_buf_size;
  2779.  };
  2780.  
  2781.  struct sunxi_cedrus_fmt {
  2782. @@ -72,6 +84,7 @@ struct sunxi_cedrus_ctx {
  2783.         struct vb2_buffer *dst_bufs[VIDEO_MAX_FRAME];
  2784.  
  2785.         struct v4l2_ctrl *mpeg2_frame_hdr_ctrl;
  2786. +       struct v4l2_ctrl *mpeg4_frame_hdr_ctrl;
  2787.  };
  2788.  
  2789.  static inline void sunxi_cedrus_write(struct sunxi_cedrus_dev *vpu,
  2790. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.c b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.c
  2791. index 38e8a3a..8ce635d 100644
  2792. --- a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.c
  2793. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_dec.c
  2794. @@ -53,6 +53,11 @@ static struct sunxi_cedrus_fmt formats[] = {
  2795.                 .types  = SUNXI_CEDRUS_OUTPUT,
  2796.                 .num_planes = 1,
  2797.         },
  2798. +       {
  2799. +               .fourcc = V4L2_PIX_FMT_MPEG4_FRAME,
  2800. +               .types  = SUNXI_CEDRUS_OUTPUT,
  2801. +               .num_planes = 1,
  2802. +       },
  2803.  };
  2804.  
  2805.  #define NUM_FORMATS ARRAY_SIZE(formats)
  2806. @@ -129,6 +134,10 @@ void device_run(void *priv)
  2807.                 struct v4l2_ctrl_mpeg2_frame_hdr *frame_hdr =
  2808.                                 ctx->mpeg2_frame_hdr_ctrl->p_new.p;
  2809.                 process_mpeg2(ctx, in_buf, out_luma, out_chroma, frame_hdr);
  2810. +       } else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_MPEG4_FRAME) {
  2811. +               struct v4l2_ctrl_mpeg4_frame_hdr *frame_hdr =
  2812. +                               ctx->mpeg4_frame_hdr_ctrl->p_new.p;
  2813. +               process_mpeg4(ctx, in_buf, out_luma, out_chroma, frame_hdr);
  2814.         } else {
  2815.                 v4l2_m2m_buf_done(in_vb, VB2_BUF_STATE_ERROR);
  2816.                 v4l2_m2m_buf_done(out_vb, VB2_BUF_STATE_ERROR);
  2817. @@ -306,8 +315,32 @@ static int vidioc_s_fmt(struct sunxi_cedrus_ctx *ctx, struct v4l2_format *f)
  2818.  
  2819.         switch (f->type) {
  2820.         case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
  2821. +               if (ctx->vpu_src_fmt && ctx->vpu_src_fmt->fourcc ==
  2822. +                      V4L2_PIX_FMT_MPEG4_FRAME && dev->mbh_buf_virt) {
  2823. +                       dma_free_coherent(dev->dev, dev->mbh_buf_size,
  2824. +                                         dev->mbh_buf_virt, dev->mbh_buf);
  2825. +                       dma_free_coherent(dev->dev, dev->dcac_buf_size,
  2826. +                                         dev->dcac_buf_virt, dev->dcac_buf);
  2827. +                       dma_free_coherent(dev->dev, dev->ncf_buf_size,
  2828. +                                         dev->ncf_buf_virt, dev->ncf_buf);
  2829. +               }
  2830. +
  2831.                 ctx->vpu_src_fmt = find_format(f);
  2832.                 ctx->src_fmt = *pix_fmt_mp;
  2833. +
  2834. +               if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_MPEG4_FRAME) {
  2835. +                       dev->mbh_buf_size  = pix_fmt_mp->height * 2048;
  2836. +                       dev->dcac_buf_size = 2 * pix_fmt_mp->width *
  2837. +                                              pix_fmt_mp->height;
  2838. +                       dev->ncf_buf_size  = 4 * 1024;
  2839. +
  2840. +                       dev->mbh_buf_virt = dma_alloc_coherent(dev->dev,
  2841. +                              dev->mbh_buf_size, &dev->mbh_buf, GFP_KERNEL);
  2842. +                       dev->dcac_buf_virt = dma_alloc_coherent(dev->dev,
  2843. +                              dev->dcac_buf_size, &dev->dcac_buf, GFP_KERNEL);
  2844. +                       dev->ncf_buf_virt = dma_alloc_coherent(dev->dev,
  2845. +                              dev->ncf_buf_size, &dev->ncf_buf, GFP_KERNEL);
  2846. +               }
  2847.                 break;
  2848.         case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
  2849.                 fmt = find_format(f);
  2850. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.h b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.h
  2851. index 78625e5..d5f8b47 100644
  2852. --- a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.h
  2853. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_hw.h
  2854. @@ -32,5 +32,8 @@ void sunxi_cedrus_hw_remove(struct sunxi_cedrus_dev *vpu);
  2855.  void process_mpeg2(struct sunxi_cedrus_ctx *ctx, dma_addr_t in_buf,
  2856.                    dma_addr_t out_luma, dma_addr_t out_chroma,
  2857.                    struct v4l2_ctrl_mpeg2_frame_hdr *frame_hdr);
  2858. +void process_mpeg4(struct sunxi_cedrus_ctx *ctx, dma_addr_t in_buf,
  2859. +                  dma_addr_t out_luma, dma_addr_t out_chroma,
  2860. +                  struct v4l2_ctrl_mpeg4_frame_hdr *frame_hdr);
  2861.  
  2862.  #endif /* SUNXI_CEDRUS_HW_H_ */
  2863. diff --git a/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_mpeg4.c b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_mpeg4.c
  2864. new file mode 100644
  2865. index 0000000..656fb6f
  2866. --- /dev/null
  2867. +++ b/drivers/media/platform/sunxi-cedrus/sunxi_cedrus_mpeg4.c
  2868. @@ -0,0 +1,140 @@
  2869. +/*
  2870. + * Sunxi Cedrus codec driver
  2871. + *
  2872. + * Copyright (C) 2016 Florent Revest
  2873. + * Florent Revest <florent.revest@free-electrons.com>
  2874. + *
  2875. + * Based on reverse engineering efforts of the 'Cedrus' project
  2876. + * Copyright (c) 2013-2014 Jens Kuske <jenskuske@gmail.com>
  2877. + *
  2878. + * This software is licensed under the terms of the GNU General Public
  2879. + * License version 2, as published by the Free Software Foundation, and
  2880. + * may be copied, distributed, and modified under those terms.
  2881. + *
  2882. + * This program is distributed in the hope that it will be useful,
  2883. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2884. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2885. + * GNU General Public License for more details.
  2886. + */
  2887. +
  2888. +#include "sunxi_cedrus_common.h"
  2889. +
  2890. +#include <media/videobuf2-dma-contig.h>
  2891. +
  2892. +#define VOP_I  0
  2893. +#define VOP_P  1
  2894. +#define VOP_B  2
  2895. +#define VOP_S  3
  2896. +
  2897. +void process_mpeg4(struct sunxi_cedrus_ctx *ctx, dma_addr_t in_buf,
  2898. +                  dma_addr_t out_luma, dma_addr_t out_chroma,
  2899. +                  struct v4l2_ctrl_mpeg4_frame_hdr *frame_hdr)
  2900. +{
  2901. +       struct sunxi_cedrus_dev *dev = ctx->dev;
  2902. +
  2903. +       u16 width = DIV_ROUND_UP(frame_hdr->width, 16);
  2904. +       u16 height = DIV_ROUND_UP(frame_hdr->height, 16);
  2905. +
  2906. +       u32 vop_header = 0;
  2907. +       u32 vld_len = frame_hdr->slice_len - frame_hdr->slice_pos;
  2908. +
  2909. +       struct vb2_buffer *fwd_vb2_buf, *bwd_vb2_buf;
  2910. +       dma_addr_t fwd_luma = 0, fwd_chroma = 0, bwd_luma = 0, bwd_chroma = 0;
  2911. +
  2912. +       /*
  2913. +        * The VPU is only able to handle bus addresses so we have to subtract
  2914. +        * the RAM offset to the physcal addresses
  2915. +        */
  2916. +       fwd_vb2_buf = ctx->dst_bufs[frame_hdr->forward_index];
  2917. +       if (fwd_vb2_buf) {
  2918. +               fwd_luma   = vb2_dma_contig_plane_dma_addr(fwd_vb2_buf, 0);
  2919. +               fwd_chroma = vb2_dma_contig_plane_dma_addr(fwd_vb2_buf, 1);
  2920. +               fwd_luma   -= PHYS_OFFSET;
  2921. +               fwd_chroma -= PHYS_OFFSET;
  2922. +       }
  2923. +
  2924. +       bwd_vb2_buf = ctx->dst_bufs[frame_hdr->backward_index];
  2925. +       if (bwd_vb2_buf) {
  2926. +               bwd_luma   = vb2_dma_contig_plane_dma_addr(bwd_vb2_buf, 0);
  2927. +               bwd_chroma = vb2_dma_contig_plane_dma_addr(bwd_vb2_buf, 1);
  2928. +               bwd_chroma -= PHYS_OFFSET;
  2929. +               bwd_luma   -= PHYS_OFFSET;
  2930. +       }
  2931. +
  2932. +       /* Activates MPEG engine */
  2933. +       sunxi_cedrus_write(dev, VE_CTRL_MPEG, VE_CTRL);
  2934. +
  2935. +       /* Quantization parameter */
  2936. +       sunxi_cedrus_write(dev, frame_hdr->quant_scale, VE_MPEG_QP_INPUT);
  2937. +
  2938. +       /* Intermediate buffers needed by the VPU */
  2939. +       sunxi_cedrus_write(dev, dev->mbh_buf  - PHYS_OFFSET, VE_MPEG_MBH_ADDR);
  2940. +       sunxi_cedrus_write(dev, dev->dcac_buf - PHYS_OFFSET, VE_MPEG_DCAC_ADDR);
  2941. +       sunxi_cedrus_write(dev, dev->ncf_buf  - PHYS_OFFSET, VE_MPEG_NCF_ADDR);
  2942. +
  2943. +       /* Image's dimensions */
  2944. +       sunxi_cedrus_write(dev, width << 8  | height,      VE_MPEG_SIZE);
  2945. +       sunxi_cedrus_write(dev, width << 20 | height << 4, VE_MPEG_FRAME_SIZE);
  2946. +
  2947. +       /* MPEG VOP's header */
  2948. +       vop_header |= (frame_hdr->vop_fields.vop_coding_type == VOP_B) << 28;
  2949. +       vop_header |= frame_hdr->vol_fields.quant_type << 24;
  2950. +       vop_header |= frame_hdr->vol_fields.quarter_sample << 23;
  2951. +       vop_header |= frame_hdr->vol_fields.resync_marker_disable << 22;
  2952. +       vop_header |= frame_hdr->vop_fields.vop_coding_type << 18;
  2953. +       vop_header |= frame_hdr->vop_fields.vop_rounding_type << 17;
  2954. +       vop_header |= frame_hdr->vop_fields.intra_dc_vlc_thr << 8;
  2955. +       vop_header |= frame_hdr->vop_fields.top_field_first << 7;
  2956. +       vop_header |= frame_hdr->vop_fields.alternate_vertical_scan_flag << 6;
  2957. +       if (frame_hdr->vop_fields.vop_coding_type != VOP_I)
  2958. +               vop_header |= frame_hdr->vop_fcode_forward << 3;
  2959. +       if (frame_hdr->vop_fields.vop_coding_type == VOP_B)
  2960. +               vop_header |= frame_hdr->vop_fcode_backward << 0;
  2961. +       sunxi_cedrus_write(dev, vop_header, VE_MPEG_VOP_HDR);
  2962. +
  2963. +       /* Enable interrupt and an unknown control flag */
  2964. +       if (frame_hdr->vop_fields.vop_coding_type == VOP_P)
  2965. +               sunxi_cedrus_write(dev, VE_MPEG_CTRL_MPEG4_P, VE_MPEG_CTRL);
  2966. +       else
  2967. +               sunxi_cedrus_write(dev, VE_MPEG_CTRL_MPEG4, VE_MPEG_CTRL);
  2968. +
  2969. +       /* Temporal distances of B frames */
  2970. +       if (frame_hdr->vop_fields.vop_coding_type == VOP_B) {
  2971. +               u32 trbtrd = (frame_hdr->trb << 16) | frame_hdr->trd;
  2972. +
  2973. +               sunxi_cedrus_write(dev, trbtrd, VE_MPEG_TRBTRD_FRAME);
  2974. +               sunxi_cedrus_write(dev, 0, VE_MPEG_TRBTRD_FIELD);
  2975. +       }
  2976. +
  2977. +       /* Don't rotate or scale buffer */
  2978. +       sunxi_cedrus_write(dev, VE_NO_SDROT_CTRL, VE_MPEG_SDROT_CTRL);
  2979. +
  2980. +       /* Macroblock number */
  2981. +       sunxi_cedrus_write(dev, 0, VE_MPEG_MBA);
  2982. +
  2983. +       /* Clear previous status */
  2984. +       sunxi_cedrus_write(dev, 0xffffffff, VE_MPEG_STATUS);
  2985. +
  2986. +       /* Forward and backward prediction buffers (cached in dst_bufs) */
  2987. +       sunxi_cedrus_write(dev, fwd_luma,   VE_MPEG_FWD_LUMA);
  2988. +       sunxi_cedrus_write(dev, fwd_chroma, VE_MPEG_FWD_CHROMA);
  2989. +       sunxi_cedrus_write(dev, bwd_luma,   VE_MPEG_BACK_LUMA);
  2990. +       sunxi_cedrus_write(dev, bwd_chroma, VE_MPEG_BACK_CHROMA);
  2991. +
  2992. +       /* Output luma and chroma buffers */
  2993. +       sunxi_cedrus_write(dev, out_luma,   VE_MPEG_REC_LUMA);
  2994. +       sunxi_cedrus_write(dev, out_chroma, VE_MPEG_REC_CHROMA);
  2995. +       sunxi_cedrus_write(dev, out_luma,   VE_MPEG_ROT_LUMA);
  2996. +       sunxi_cedrus_write(dev, out_chroma, VE_MPEG_ROT_CHROMA);
  2997. +
  2998. +       /* Input offset and length in bits */
  2999. +       sunxi_cedrus_write(dev, frame_hdr->slice_pos, VE_MPEG_VLD_OFFSET);
  3000. +       sunxi_cedrus_write(dev, vld_len, VE_MPEG_VLD_LEN);
  3001. +
  3002. +       /* Input beginning and end addresses */
  3003. +       sunxi_cedrus_write(dev, VE_MPEG_VLD_ADDR_VAL(in_buf), VE_MPEG_VLD_ADDR);
  3004. +       sunxi_cedrus_write(dev, in_buf + VBV_SIZE - 1, VE_MPEG_VLD_END);
  3005. +
  3006. +       /* Starts the MPEG engine */
  3007. +       sunxi_cedrus_write(dev, VE_TRIG_MPEG4(width, height), VE_MPEG_TRIGGER);
  3008. +}
  3009.  
  3010. From patchwork Thu Aug 25 09:39:48 2016
  3011. Content-Type: text/plain; charset="utf-8"
  3012. MIME-Version: 1.0
  3013. Content-Transfer-Encoding: 7bit
  3014. X-Patchwork-Submitter: Florent Revest <florent.revest@free-electrons.com>
  3015. X-Patchwork-Id: 711056
  3016. Return-Path: <linux-kernel-owner@vger.kernel.org>
  3017. Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
  3018.         id S1759295AbcHYJkv (ORCPT <rfc822;w@1wt.eu>);
  3019.         Thu, 25 Aug 2016 05:40:51 -0400
  3020. Received: from down.free-electrons.com ([37.187.137.238]:34220 "EHLO
  3021.         mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org
  3022.         with ESMTP id S1758997AbcHYJk2 (ORCPT
  3023.         <rfc822;linux-kernel@vger.kernel.org>);
  3024.         Thu, 25 Aug 2016 05:40:28 -0400
  3025. From: Florent Revest <florent.revest@free-electrons.com>
  3026. To: linux-media@vger.kernel.org
  3027. Cc: florent.revest@free-electrons.com, linux-sunxi@googlegroups.com,
  3028.         maxime.ripard@free-electrons.com, posciak@chromium.org,
  3029.         hans.verkuil@cisco.com, thomas.petazzoni@free-electrons.com,
  3030.         mchehab@kernel.org, linux-kernel@vger.kernel.org, wens@csie.org
  3031. Subject: [RFC 09/10] ARM: dts: sun5i: Use video-engine node
  3032. Date: Thu, 25 Aug 2016 11:39:48 +0200
  3033. Message-Id:
  3034.  <1472117989-21455-10-git-send-email-florent.revest@free-electrons.com>
  3035. X-Mailer: git-send-email 2.7.4
  3036. In-Reply-To:
  3037.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  3038. References:
  3039.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  3040. Sender: linux-kernel-owner@vger.kernel.org
  3041. List-ID: <linux-kernel.vger.kernel.org>
  3042. X-Mailing-List: linux-kernel@vger.kernel.org
  3043. Content-Length: 1480
  3044. Lines: 63
  3045.  
  3046. Now that we have a driver matching "allwinner,sun5i-a13-video-engine" we
  3047. can load it.
  3048.  
  3049. The "video-engine" node depends on the new sunxi-ng's CCU clock and
  3050. reset bindings. This patch also includes a ve_reserved DMA pool for
  3051. videobuf2 buffer allocations in sunxi-cedrus.
  3052.  
  3053. Signed-off-by: Florent Revest <florent.revest@free-electrons.com>
  3054. ---
  3055. arch/arm/boot/dts/sun5i-a13.dtsi | 31 +++++++++++++++++++++++++++++++
  3056.  1 file changed, 31 insertions(+)
  3057.  
  3058. diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
  3059. index 2afe05fb..384b645 100644
  3060. --- a/arch/arm/boot/dts/sun5i-a13.dtsi
  3061. +++ b/arch/arm/boot/dts/sun5i-a13.dtsi
  3062. @@ -69,6 +69,19 @@
  3063.                 };
  3064.         };
  3065.  
  3066. +       reserved-memory {
  3067. +               #address-cells = <1>;
  3068. +               #size-cells = <1>;
  3069. +               ranges;
  3070. +
  3071. +               ve_reserved: cma {
  3072. +                       compatible = "shared-dma-pool";
  3073. +                       reg = <0x43d00000 0x9000000>;
  3074. +                       no-map;
  3075. +                       linux,cma-default;
  3076. +               };
  3077. +       };
  3078. +
  3079.         thermal-zones {
  3080.                 cpu_thermal {
  3081.                         /* milliseconds */
  3082. @@ -330,6 +343,24 @@
  3083.                         };
  3084.                 };
  3085.  
  3086. +               video-engine {
  3087. +                       compatible = "allwinner,sun5i-a13-video-engine";
  3088. +                       memory-region = <&ve_reserved>;
  3089. +
  3090. +                       clocks = <&ahb_gates 32>, <&ccu CLK_VE>,
  3091. +                                <&dram_gates 0>;
  3092. +                       clock-names = "ahb", "mod", "ram";
  3093. +
  3094. +                       assigned-clocks = <&ccu CLK_VE>;
  3095. +                       assigned-clock-rates = <320000000>;
  3096. +
  3097. +                       resets = <&ccu RST_VE>;
  3098. +
  3099. +                       interrupts = <53>;
  3100. +
  3101. +                       reg = <0x01c0e000 4096>;
  3102. +               };
  3103. +
  3104.                 ccu: clock@01c20000 {
  3105.                         compatible = "allwinner,sun5i-a13-ccu";
  3106.                         reg = <0x01c20000 0x400>;
  3107.  
  3108. From patchwork Thu Aug 25 09:39:49 2016
  3109. Content-Type: text/plain; charset="utf-8"
  3110. MIME-Version: 1.0
  3111. Content-Transfer-Encoding: 7bit
  3112. X-Patchwork-Submitter: Florent Revest <florent.revest@free-electrons.com>
  3113. X-Patchwork-Id: 711053
  3114. Return-Path: <linux-kernel-owner@vger.kernel.org>
  3115. Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
  3116.         id S1759049AbcHYJka (ORCPT <rfc822;w@1wt.eu>);
  3117.         Thu, 25 Aug 2016 05:40:30 -0400
  3118. Received: from down.free-electrons.com ([37.187.137.238]:34209 "EHLO
  3119.         mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org
  3120.         with ESMTP id S1758962AbcHYJk0 (ORCPT
  3121.         <rfc822;linux-kernel@vger.kernel.org>);
  3122.         Thu, 25 Aug 2016 05:40:26 -0400
  3123. From: Florent Revest <florent.revest@free-electrons.com>
  3124. To: linux-media@vger.kernel.org
  3125. Cc: florent.revest@free-electrons.com, linux-sunxi@googlegroups.com,
  3126.         maxime.ripard@free-electrons.com, posciak@chromium.org,
  3127.         hans.verkuil@cisco.com, thomas.petazzoni@free-electrons.com,
  3128.         mchehab@kernel.org, linux-kernel@vger.kernel.org, wens@csie.org
  3129. Subject: [RFC 10/10] sunxi-cedrus: Add device tree binding document
  3130. Date: Thu, 25 Aug 2016 11:39:49 +0200
  3131. Message-Id:
  3132.  <1472117989-21455-11-git-send-email-florent.revest@free-electrons.com>
  3133. X-Mailer: git-send-email 2.7.4
  3134. In-Reply-To:
  3135.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  3136. References:
  3137.  <1472117989-21455-1-git-send-email-florent.revest@free-electrons.com>
  3138. Sender: linux-kernel-owner@vger.kernel.org
  3139. List-ID: <linux-kernel.vger.kernel.org>
  3140. X-Mailing-List: linux-kernel@vger.kernel.org
  3141. Content-Length: 1708
  3142. Lines: 60
  3143.  
  3144. Device Tree bindings for the Allwinner's video engine
  3145.  
  3146. Signed-off-by: Florent Revest <florent.revest@free-electrons.com>
  3147. ---
  3148. .../devicetree/bindings/media/sunxi-cedrus.txt     | 44 ++++++++++++++++++++++
  3149.  1 file changed, 44 insertions(+)
  3150.  create mode 100644 Documentation/devicetree/bindings/media/sunxi-cedrus.txt
  3151.  
  3152. diff --git a/Documentation/devicetree/bindings/media/sunxi-cedrus.txt b/Documentation/devicetree/bindings/media/sunxi-cedrus.txt
  3153. new file mode 100644
  3154. index 0000000..26f2e09
  3155. --- /dev/null
  3156. +++ b/Documentation/devicetree/bindings/media/sunxi-cedrus.txt
  3157. @@ -0,0 +1,44 @@
  3158. +Device-Tree bindings for SUNXI video engine found in sunXi SoC family
  3159. +
  3160. +Required properties:
  3161. +- compatible       : "allwinner,sun5i-a13-video-engine";
  3162. +- memory-region     : DMA pool for buffers allocation;
  3163. +- clocks           : list of clock specifiers, corresponding to
  3164. +                     entries in clock-names property;
  3165. +- clock-names      : should contain "ahb", "mod" and "ram" entries;
  3166. +- resets           : phandle for reset;
  3167. +- interrupts       : should contain VE interrupt number;
  3168. +- reg              : should contain register base and length of VE.
  3169. +
  3170. +Example:
  3171. +
  3172. +reserved-memory {
  3173. +       #address-cells = <1>;
  3174. +       #size-cells = <1>;
  3175. +       ranges;
  3176. +
  3177. +       ve_reserved: cma {
  3178. +               compatible = "shared-dma-pool";
  3179. +               reg = <0x43d00000 0x9000000>;
  3180. +               no-map;
  3181. +               linux,cma-default;
  3182. +       };
  3183. +};
  3184. +
  3185. +video-engine {
  3186. +       compatible = "allwinner,sun5i-a13-video-engine";
  3187. +       memory-region = <&ve_reserved>;
  3188. +
  3189. +       clocks = <&ahb_gates 32>, <&ccu CLK_VE>,
  3190. +                <&dram_gates 0>;
  3191. +       clock-names = "ahb", "mod", "ram";
  3192. +
  3193. +       assigned-clocks = <&ccu CLK_VE>;
  3194. +       assigned-clock-rates = <320000000>;
  3195. +
  3196. +       resets = <&ccu RST_VE>;
  3197. +
  3198. +       interrupts = <53>;
  3199. +
  3200. +       reg = <0x01c0e000 4096>;
  3201. +};
  3202.  
Language: diff
Posted by Anonymous at 05 Aug 2018, 08:54:45 UTC