From d0e59a23fe9c3e835bd2a9e4c18077a7b23486c6 Mon Sep 17 00:00:00 2001 From: heitbaum Date: Sat, 9 Oct 2021 19:12:46 +1100 Subject: [PATCH] linux (Rockchip): patches upstreamed in 5.15 --- ...ch => linux-0001-rockchip-from-5.16.patch} | 1387 ++--------------- .../default/linux-0010-v4l2-from-5.15.patch | 1210 -------------- .../linux-2001-v4l-wip-rkvdec-hevc.patch | 50 - 3 files changed, 131 insertions(+), 2516 deletions(-) rename projects/Rockchip/patches/linux/default/{linux-0001-rockchip-from-5.15.patch => linux-0001-rockchip-from-5.16.patch} (63%) delete mode 100644 projects/Rockchip/patches/linux/default/linux-0010-v4l2-from-5.15.patch diff --git a/projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.15.patch b/projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.16.patch similarity index 63% rename from projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.15.patch rename to projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.16.patch index ac5bbdd8bd..566916de34 100644 --- a/projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.15.patch +++ b/projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.16.patch @@ -1,339 +1,3 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Morgan -Date: Tue, 13 Jul 2021 17:47:13 +0800 -Subject: [PATCH] clk: rockchip: add dt-binding clkid for hclk_sfc on rk3036 - -Add dt-binding for hclk_sfc on rk3036 - -Signed-off-by: Chris Morgan -Signed-off-by: Jon Lin -Acked-by: Stephen Boyd -Link: https://lore.kernel.org/r/20210713094718.1709-1-jon.lin@rock-chips.com -Signed-off-by: Heiko Stuebner ---- - include/dt-bindings/clock/rk3036-cru.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/include/dt-bindings/clock/rk3036-cru.h b/include/dt-bindings/clock/rk3036-cru.h -index 35a5a01f9697..a96a9870ad59 100644 ---- a/include/dt-bindings/clock/rk3036-cru.h -+++ b/include/dt-bindings/clock/rk3036-cru.h -@@ -81,6 +81,7 @@ - #define HCLK_OTG0 449 - #define HCLK_OTG1 450 - #define HCLK_NANDC 453 -+#define HCLK_SFC 454 - #define HCLK_SDMMC 456 - #define HCLK_SDIO 457 - #define HCLK_EMMC 459 - -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jon Lin -Date: Tue, 13 Jul 2021 17:44:50 +0800 -Subject: [PATCH] clk: rockchip: rk3036: fix up the sclk_sfc parent error - -Choose the correct pll - -Signed-off-by: Elaine Zhang -Signed-off-by: Jon Lin -Acked-by: Stephen Boyd -Link: https://lore.kernel.org/r/20210713094456.23288-5-jon.lin@rock-chips.com -Signed-off-by: Heiko Stuebner ---- - drivers/clk/rockchip/clk-rk3036.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c -index 614845cc5b4a..c38ad4ec8746 100644 ---- a/drivers/clk/rockchip/clk-rk3036.c -+++ b/drivers/clk/rockchip/clk-rk3036.c -@@ -121,6 +121,7 @@ PNAME(mux_pll_src_3plls_p) = { "apll", "dpll", "gpll" }; - PNAME(mux_timer_p) = { "xin24m", "pclk_peri_src" }; - - PNAME(mux_pll_src_apll_dpll_gpll_usb480m_p) = { "apll", "dpll", "gpll", "usb480m" }; -+PNAME(mux_pll_src_dmyapll_dpll_gpll_xin24_p) = { "dummy_apll", "dpll", "gpll", "xin24m" }; - - PNAME(mux_mmc_src_p) = { "apll", "dpll", "gpll", "xin24m" }; - PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" }; -@@ -340,7 +341,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { - RK2928_CLKSEL_CON(16), 8, 2, MFLAGS, 10, 5, DFLAGS, - RK2928_CLKGATE_CON(10), 4, GFLAGS), - -- COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_apll_dpll_gpll_usb480m_p, 0, -+ COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_dmyapll_dpll_gpll_xin24_p, 0, - RK2928_CLKSEL_CON(16), 0, 2, MFLAGS, 2, 5, DFLAGS, - RK2928_CLKGATE_CON(10), 5, GFLAGS), - - -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jon Lin -Date: Tue, 13 Jul 2021 17:47:14 +0800 -Subject: [PATCH] clk: rockchip: Add support for hclk_sfc on rk3036 - -Add support for the bus clock for the serial flash controller on the -rk3036. Taken from the Rockchip BSP kernel but not tested on real -hardware (as I lack a 3036 based SoC to test). - -Signed-off-by: Chris Morgan -Signed-off-by: Jon Lin -Acked-by: Stephen Boyd -Link: https://lore.kernel.org/r/20210713094718.1709-2-jon.lin@rock-chips.com -Signed-off-by: Heiko Stuebner ---- - drivers/clk/rockchip/clk-rk3036.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c -index c38ad4ec8746..d644bc155ec6 100644 ---- a/drivers/clk/rockchip/clk-rk3036.c -+++ b/drivers/clk/rockchip/clk-rk3036.c -@@ -404,7 +404,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { - GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS), - GATE(HCLK_OTG1, "hclk_otg1", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 3, GFLAGS), - GATE(HCLK_I2S, "hclk_i2s", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), -- GATE(0, "hclk_sfc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS), -+ GATE(HCLK_SFC, "hclk_sfc", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS), - GATE(HCLK_MAC, "hclk_mac", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS), - - /* pclk_peri gates */ - -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= - -Date: Thu, 10 Jun 2021 14:56:13 -0300 -Subject: [PATCH] dt-bindings: clk: Convert rockchip,rk3399-cru to DT schema -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Convert the rockchip,rk3399-cru binding to DT schema format. -Tested with -ARCH=arm64 make dt_binding_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml -ARCH=arm64 make dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml - -Signed-off-by: NĂ­colas F. R. A. Prado -Reviewed-by: Rob Herring -Link: https://lore.kernel.org/r/20210610175613.167601-1-nfraprado@collabora.com -Signed-off-by: Heiko Stuebner ---- - .../bindings/clock/rockchip,rk3399-cru.txt | 68 -------------- - .../bindings/clock/rockchip,rk3399-cru.yaml | 92 +++++++++++++++++++ - 2 files changed, 92 insertions(+), 68 deletions(-) - delete mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt - create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml - -diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt -deleted file mode 100644 -index 3bc56fae90ac..000000000000 ---- a/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt -+++ /dev/null -@@ -1,68 +0,0 @@ --* Rockchip RK3399 Clock and Reset Unit -- --The RK3399 clock controller generates and supplies clock to various --controllers within the SoC and also implements a reset controller for SoC --peripherals. -- --Required Properties: -- --- compatible: PMU for CRU should be "rockchip,rk3399-pmucru" --- compatible: CRU should be "rockchip,rk3399-cru" --- reg: physical base address of the controller and length of memory mapped -- region. --- #clock-cells: should be 1. --- #reset-cells: should be 1. -- --Optional Properties: -- --- rockchip,grf: phandle to the syscon managing the "general register files". -- It is used for GRF muxes, if missing any muxes present in the GRF will not -- be available. -- --Each clock is assigned an identifier and client nodes can use this identifier --to specify the clock which they consume. All available clocks are defined as --preprocessor macros in the dt-bindings/clock/rk3399-cru.h headers and can be --used in device tree sources. Similar macros exist for the reset sources in --these files. -- --External clocks: -- --There are several clocks that are generated outside the SoC. It is expected --that they are defined using standard clock bindings with following --clock-output-names: -- - "xin24m" - crystal input - required, -- - "xin32k" - rtc clock - optional, -- - "clkin_gmac" - external GMAC clock - optional, -- - "clkin_i2s" - external I2S clock - optional, -- - "pclkin_cif" - external ISP clock - optional, -- - "clk_usbphy0_480m" - output clock of the pll in the usbphy0 -- - "clk_usbphy1_480m" - output clock of the pll in the usbphy1 -- --Example: Clock controller node: -- -- pmucru: pmu-clock-controller@ff750000 { -- compatible = "rockchip,rk3399-pmucru"; -- reg = <0x0 0xff750000 0x0 0x1000>; -- #clock-cells = <1>; -- #reset-cells = <1>; -- }; -- -- cru: clock-controller@ff760000 { -- compatible = "rockchip,rk3399-cru"; -- reg = <0x0 0xff760000 0x0 0x1000>; -- #clock-cells = <1>; -- #reset-cells = <1>; -- }; -- --Example: UART controller node that consumes the clock generated by the clock -- controller: -- -- uart0: serial@ff1a0000 { -- compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; -- reg = <0x0 0xff180000 0x0 0x100>; -- clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; -- clock-names = "baudclk", "apb_pclk"; -- interrupts = ; -- reg-shift = <2>; -- reg-io-width = <4>; -- }; -diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml -new file mode 100644 -index 000000000000..72b286a1beba ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml -@@ -0,0 +1,92 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/clock/rockchip,rk3399-cru.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Rockchip RK3399 Clock and Reset Unit -+ -+maintainers: -+ - Xing Zheng -+ - Heiko Stuebner -+ -+description: | -+ The RK3399 clock controller generates and supplies clock to various -+ controllers within the SoC and also implements a reset controller for SoC -+ peripherals. -+ Each clock is assigned an identifier and client nodes can use this identifier -+ to specify the clock which they consume. All available clocks are defined as -+ preprocessor macros in the dt-bindings/clock/rk3399-cru.h headers and can be -+ used in device tree sources. Similar macros exist for the reset sources in -+ these files. -+ There are several clocks that are generated outside the SoC. It is expected -+ that they are defined using standard clock bindings with following -+ clock-output-names: -+ - "xin24m" - crystal input - required, -+ - "xin32k" - rtc clock - optional, -+ - "clkin_gmac" - external GMAC clock - optional, -+ - "clkin_i2s" - external I2S clock - optional, -+ - "pclkin_cif" - external ISP clock - optional, -+ - "clk_usbphy0_480m" - output clock of the pll in the usbphy0 -+ - "clk_usbphy1_480m" - output clock of the pll in the usbphy1 -+ -+properties: -+ compatible: -+ enum: -+ - rockchip,rk3399-pmucru -+ - rockchip,rk3399-cru -+ -+ reg: -+ maxItems: 1 -+ -+ "#clock-cells": -+ const: 1 -+ -+ "#reset-cells": -+ const: 1 -+ -+ clocks: -+ minItems: 1 -+ -+ assigned-clocks: -+ minItems: 1 -+ maxItems: 64 -+ -+ assigned-clock-parents: -+ minItems: 1 -+ maxItems: 64 -+ -+ assigned-clock-rates: -+ minItems: 1 -+ maxItems: 64 -+ -+ rockchip,grf: -+ $ref: /schemas/types.yaml#/definitions/phandle -+ description: > -+ phandle to the syscon managing the "general register files". It is used -+ for GRF muxes, if missing any muxes present in the GRF will not be -+ available. -+ -+required: -+ - compatible -+ - reg -+ - "#clock-cells" -+ - "#reset-cells" -+ -+additionalProperties: false -+ -+examples: -+ - | -+ pmucru: pmu-clock-controller@ff750000 { -+ compatible = "rockchip,rk3399-pmucru"; -+ reg = <0xff750000 0x1000>; -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ }; -+ - | -+ cru: clock-controller@ff760000 { -+ compatible = "rockchip,rk3399-cru"; -+ reg = <0xff760000 0x1000>; -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ }; - -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Yunhao Tian -Date: Wed, 21 Jul 2021 20:48:16 +0800 -Subject: [PATCH] clk: rockchip: make rk3308 ddrphy4x clock critical - -Currently, no driver support for DDR memory controller (DMC) is present, -as a result, no driver is explicitly consuming the ddrphy clock. This means -that VPLL1 (parent of ddr clock) will be shutdown if we enable -and then disable any child clock of VPLL1 (e.g. SCLK_I2S0_8CH_TX). -If VPLL1 is disabled, the whole system will freeze, because the DDR -controller will lose its clock. So, it's necessary to prevent VPLL1 from -shutting down, by marking the ddrphy4x CLK_IS_CRITICAL. - -This bug was discovered when I was porting rockchip_i2s_tdm driver to -mainline kernel from Rockchip 4.4 kernel. I guess that other Rockchip -SoCs without DMC driver may need the same patch. If this applies to -other devices, please let us know. - -Signed-off-by: Yunhao Tian -Link: https://lore.kernel.org/r/BYAPR20MB24886765F888A9705CBEB70789E39@BYAPR20MB2488.namprd20.prod.outlook.com -[adapted subject, changed to add the clock to the critical list] -Signed-off-by: Heiko Stuebner ---- - drivers/clk/rockchip/clk-rk3308.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/clk/rockchip/clk-rk3308.c b/drivers/clk/rockchip/clk-rk3308.c -index 2c3bd0c749f2..db3396c3e6e9 100644 ---- a/drivers/clk/rockchip/clk-rk3308.c -+++ b/drivers/clk/rockchip/clk-rk3308.c -@@ -911,6 +911,7 @@ static const char *const rk3308_critical_clocks[] __initconst = { - "hclk_audio", - "pclk_audio", - "sclk_ddrc", -+ "clk_ddrphy4x", - }; - - static void __init rk3308_clk_init(struct device_node *np) - From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Johan Jonker Date: Sun, 11 Jul 2021 16:34:30 +0200 @@ -2496,928 +2160,139 @@ index 7fc674a99a6c..35218c2771a2 100644 status = "okay"; }; -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Morgan -Date: Thu, 12 Aug 2021 21:45:41 +0800 -Subject: [PATCH] spi: rockchip-sfc: Bindings for Rockchip serial flash - controller +From 6594988fd625ff0d9a8f90f1788e16185358a3e6 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 16 Oct 2021 12:50:22 +0200 +Subject: clk: composite: Use rate_ops.determine_rate when also a mux is + available -Add bindings for the Rockchip serial flash controller. New device -specific parameter of rockchip,sfc-no-dma included in documentation. +Update clk_composite_determine_rate() to use rate_ops.determine_rate +when available in combination with a mux. So far clk_divider_ops provide +both, .round_rate and .determine_rate. Removing the former would make +clk-composite fail silently for example on Rockchip platforms (which +heavily use composite clocks). +Add support for using rate_ops.determine_rate when either +rate_ops.round_rate is not available or both (.round_rate and +.determine_rate) are provided. -Signed-off-by: Chris Morgan -Signed-off-by: Jon Lin -Tested-by: Peter Geis -Link: https://lore.kernel.org/r/20210812134546.31340-2-jon.lin@rock-chips.com -Signed-off-by: Mark Brown +Suggested-by: Alex Bee +Signed-off-by: Martin Blumenstingl +Link: https://lore.kernel.org/r/20211016105022.303413-3-martin.blumenstingl@googlemail.com +Tested-by: Alex Bee +Tested-by: Chen-Yu Tsai +Signed-off-by: Stephen Boyd --- - .../devicetree/bindings/spi/rockchip-sfc.yaml | 91 +++++++++++++++++++ - 1 file changed, 91 insertions(+) - create mode 100644 Documentation/devicetree/bindings/spi/rockchip-sfc.yaml + drivers/clk/clk-composite.c | 68 ++++++++++++++++++++++++++++++++------------- + 1 file changed, 48 insertions(+), 20 deletions(-) -diff --git a/Documentation/devicetree/bindings/spi/rockchip-sfc.yaml b/Documentation/devicetree/bindings/spi/rockchip-sfc.yaml -new file mode 100644 -index 000000000000..339fb39529f3 ---- /dev/null -+++ b/Documentation/devicetree/bindings/spi/rockchip-sfc.yaml -@@ -0,0 +1,91 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/spi/rockchip-sfc.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Rockchip Serial Flash Controller (SFC) -+ -+maintainers: -+ - Heiko Stuebner -+ - Chris Morgan -+ -+allOf: -+ - $ref: spi-controller.yaml# -+ -+properties: -+ compatible: -+ const: rockchip,sfc -+ description: -+ The rockchip sfc controller is a standalone IP with version register, -+ and the driver can handle all the feature difference inside the IP -+ depending on the version register. -+ -+ reg: -+ maxItems: 1 -+ -+ interrupts: -+ maxItems: 1 -+ -+ clocks: -+ items: -+ - description: Bus Clock -+ - description: Module Clock -+ -+ clock-names: -+ items: -+ - const: clk_sfc -+ - const: hclk_sfc -+ -+ power-domains: -+ maxItems: 1 -+ -+ rockchip,sfc-no-dma: -+ description: Disable DMA and utilize FIFO mode only -+ type: boolean -+ -+patternProperties: -+ "^flash@[0-3]$": -+ type: object -+ properties: -+ reg: -+ minimum: 0 -+ maximum: 3 -+ -+required: -+ - compatible -+ - reg -+ - interrupts -+ - clocks -+ - clock-names -+ -+unevaluatedProperties: false -+ -+examples: -+ - | -+ #include -+ #include -+ #include -+ -+ sfc: spi@ff3a0000 { -+ compatible = "rockchip,sfc"; -+ reg = <0xff3a0000 0x4000>; -+ interrupts = ; -+ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>; -+ clock-names = "clk_sfc", "hclk_sfc"; -+ pinctrl-0 = <&sfc_clk &sfc_cs &sfc_bus2>; -+ pinctrl-names = "default"; -+ power-domains = <&power PX30_PD_MMC_NAND>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ flash@0 { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <108000000>; -+ spi-rx-bus-width = <2>; -+ spi-tx-bus-width = <2>; -+ }; -+ }; -+ -+... - -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Morgan -Date: Thu, 12 Aug 2021 21:45:42 +0800 -Subject: [PATCH] spi: rockchip-sfc: add rockchip serial flash controller - -Add the rockchip serial flash controller (SFC) driver. - -Signed-off-by: Chris Morgan -Signed-off-by: Jon Lin -Tested-by: Peter Geis -Tested-by: Chris Morgan -Link: https://lore.kernel.org/r/20210812134546.31340-3-jon.lin@rock-chips.com -Signed-off-by: Mark Brown ---- - drivers/spi/Kconfig | 12 + - drivers/spi/Makefile | 1 + - drivers/spi/spi-rockchip-sfc.c | 694 +++++++++++++++++++++++++++++++++ - 3 files changed, 707 insertions(+) - create mode 100644 drivers/spi/spi-rockchip-sfc.c - -diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index e71a4c514f7b..83e352b0c8f9 100644 ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -658,6 +658,18 @@ config SPI_ROCKCHIP - The main usecase of this controller is to use spi flash as boot - device. - -+config SPI_ROCKCHIP_SFC -+ tristate "Rockchip Serial Flash Controller (SFC)" -+ depends on ARCH_ROCKCHIP || COMPILE_TEST -+ depends on HAS_IOMEM && HAS_DMA -+ help -+ This enables support for Rockchip serial flash controller. This -+ is a specialized controller used to access SPI flash on some -+ Rockchip SOCs. -+ -+ ROCKCHIP SFC supports DMA and PIO modes. When DMA is not available, -+ the driver automatically falls back to PIO mode. -+ - config SPI_RB4XX - tristate "Mikrotik RB4XX SPI master" - depends on SPI_MASTER && ATH79 -diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile -index 13e54c45e9df..699db95c8441 100644 ---- a/drivers/spi/Makefile -+++ b/drivers/spi/Makefile -@@ -95,6 +95,7 @@ obj-$(CONFIG_SPI_QCOM_GENI) += spi-geni-qcom.o - obj-$(CONFIG_SPI_QCOM_QSPI) += spi-qcom-qspi.o - obj-$(CONFIG_SPI_QUP) += spi-qup.o - obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o -+obj-$(CONFIG_SPI_ROCKCHIP_SFC) += spi-rockchip-sfc.o - obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o - obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o - obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o -diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c -new file mode 100644 -index 000000000000..7c4d47fe80c2 ---- /dev/null -+++ b/drivers/spi/spi-rockchip-sfc.c -@@ -0,0 +1,694 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Rockchip Serial Flash Controller Driver -+ * -+ * Copyright (c) 2017-2021, Rockchip Inc. -+ * Author: Shawn Lin -+ * Chris Morgan -+ * Jon Lin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* System control */ -+#define SFC_CTRL 0x0 -+#define SFC_CTRL_PHASE_SEL_NEGETIVE BIT(1) -+#define SFC_CTRL_CMD_BITS_SHIFT 8 -+#define SFC_CTRL_ADDR_BITS_SHIFT 10 -+#define SFC_CTRL_DATA_BITS_SHIFT 12 -+ -+/* Interrupt mask */ -+#define SFC_IMR 0x4 -+#define SFC_IMR_RX_FULL BIT(0) -+#define SFC_IMR_RX_UFLOW BIT(1) -+#define SFC_IMR_TX_OFLOW BIT(2) -+#define SFC_IMR_TX_EMPTY BIT(3) -+#define SFC_IMR_TRAN_FINISH BIT(4) -+#define SFC_IMR_BUS_ERR BIT(5) -+#define SFC_IMR_NSPI_ERR BIT(6) -+#define SFC_IMR_DMA BIT(7) -+ -+/* Interrupt clear */ -+#define SFC_ICLR 0x8 -+#define SFC_ICLR_RX_FULL BIT(0) -+#define SFC_ICLR_RX_UFLOW BIT(1) -+#define SFC_ICLR_TX_OFLOW BIT(2) -+#define SFC_ICLR_TX_EMPTY BIT(3) -+#define SFC_ICLR_TRAN_FINISH BIT(4) -+#define SFC_ICLR_BUS_ERR BIT(5) -+#define SFC_ICLR_NSPI_ERR BIT(6) -+#define SFC_ICLR_DMA BIT(7) -+ -+/* FIFO threshold level */ -+#define SFC_FTLR 0xc -+#define SFC_FTLR_TX_SHIFT 0 -+#define SFC_FTLR_TX_MASK 0x1f -+#define SFC_FTLR_RX_SHIFT 8 -+#define SFC_FTLR_RX_MASK 0x1f -+ -+/* Reset FSM and FIFO */ -+#define SFC_RCVR 0x10 -+#define SFC_RCVR_RESET BIT(0) -+ -+/* Enhanced mode */ -+#define SFC_AX 0x14 -+ -+/* Address Bit number */ -+#define SFC_ABIT 0x18 -+ -+/* Interrupt status */ -+#define SFC_ISR 0x1c -+#define SFC_ISR_RX_FULL_SHIFT BIT(0) -+#define SFC_ISR_RX_UFLOW_SHIFT BIT(1) -+#define SFC_ISR_TX_OFLOW_SHIFT BIT(2) -+#define SFC_ISR_TX_EMPTY_SHIFT BIT(3) -+#define SFC_ISR_TX_FINISH_SHIFT BIT(4) -+#define SFC_ISR_BUS_ERR_SHIFT BIT(5) -+#define SFC_ISR_NSPI_ERR_SHIFT BIT(6) -+#define SFC_ISR_DMA_SHIFT BIT(7) -+ -+/* FIFO status */ -+#define SFC_FSR 0x20 -+#define SFC_FSR_TX_IS_FULL BIT(0) -+#define SFC_FSR_TX_IS_EMPTY BIT(1) -+#define SFC_FSR_RX_IS_EMPTY BIT(2) -+#define SFC_FSR_RX_IS_FULL BIT(3) -+#define SFC_FSR_TXLV_MASK GENMASK(12, 8) -+#define SFC_FSR_TXLV_SHIFT 8 -+#define SFC_FSR_RXLV_MASK GENMASK(20, 16) -+#define SFC_FSR_RXLV_SHIFT 16 -+ -+/* FSM status */ -+#define SFC_SR 0x24 -+#define SFC_SR_IS_IDLE 0x0 -+#define SFC_SR_IS_BUSY 0x1 -+ -+/* Raw interrupt status */ -+#define SFC_RISR 0x28 -+#define SFC_RISR_RX_FULL BIT(0) -+#define SFC_RISR_RX_UNDERFLOW BIT(1) -+#define SFC_RISR_TX_OVERFLOW BIT(2) -+#define SFC_RISR_TX_EMPTY BIT(3) -+#define SFC_RISR_TRAN_FINISH BIT(4) -+#define SFC_RISR_BUS_ERR BIT(5) -+#define SFC_RISR_NSPI_ERR BIT(6) -+#define SFC_RISR_DMA BIT(7) -+ -+/* Version */ -+#define SFC_VER 0x2C -+#define SFC_VER_3 0x3 -+#define SFC_VER_4 0x4 -+#define SFC_VER_5 0x5 -+ -+/* Delay line controller resiter */ -+#define SFC_DLL_CTRL0 0x3C -+#define SFC_DLL_CTRL0_SCLK_SMP_DLL BIT(15) -+#define SFC_DLL_CTRL0_DLL_MAX_VER4 0xFFU -+#define SFC_DLL_CTRL0_DLL_MAX_VER5 0x1FFU -+ -+/* Master trigger */ -+#define SFC_DMA_TRIGGER 0x80 -+#define SFC_DMA_TRIGGER_START 1 -+ -+/* Src or Dst addr for master */ -+#define SFC_DMA_ADDR 0x84 -+ -+/* Length control register extension 32GB */ -+#define SFC_LEN_CTRL 0x88 -+#define SFC_LEN_CTRL_TRB_SEL 1 -+#define SFC_LEN_EXT 0x8C -+ -+/* Command */ -+#define SFC_CMD 0x100 -+#define SFC_CMD_IDX_SHIFT 0 -+#define SFC_CMD_DUMMY_SHIFT 8 -+#define SFC_CMD_DIR_SHIFT 12 -+#define SFC_CMD_DIR_RD 0 -+#define SFC_CMD_DIR_WR 1 -+#define SFC_CMD_ADDR_SHIFT 14 -+#define SFC_CMD_ADDR_0BITS 0 -+#define SFC_CMD_ADDR_24BITS 1 -+#define SFC_CMD_ADDR_32BITS 2 -+#define SFC_CMD_ADDR_XBITS 3 -+#define SFC_CMD_TRAN_BYTES_SHIFT 16 -+#define SFC_CMD_CS_SHIFT 30 -+ -+/* Address */ -+#define SFC_ADDR 0x104 -+ -+/* Data */ -+#define SFC_DATA 0x108 -+ -+/* The controller and documentation reports that it supports up to 4 CS -+ * devices (0-3), however I have only been able to test a single CS (CS 0) -+ * due to the configuration of my device. -+ */ -+#define SFC_MAX_CHIPSELECT_NUM 4 -+ -+/* The SFC can transfer max 16KB - 1 at one time -+ * we set it to 15.5KB here for alignment. -+ */ -+#define SFC_MAX_IOSIZE_VER3 (512 * 31) -+ -+/* DMA is only enabled for large data transmission */ -+#define SFC_DMA_TRANS_THRETHOLD (0x40) -+ -+/* Maximum clock values from datasheet suggest keeping clock value under -+ * 150MHz. No minimum or average value is suggested. -+ */ -+#define SFC_MAX_SPEED (150 * 1000 * 1000) -+ -+struct rockchip_sfc { -+ struct device *dev; -+ void __iomem *regbase; -+ struct clk *hclk; -+ struct clk *clk; -+ u32 frequency; -+ /* virtual mapped addr for dma_buffer */ -+ void *buffer; -+ dma_addr_t dma_buffer; -+ struct completion cp; -+ bool use_dma; -+ u32 max_iosize; -+ u16 version; -+}; -+ -+static int rockchip_sfc_reset(struct rockchip_sfc *sfc) -+{ -+ int err; -+ u32 status; -+ -+ writel_relaxed(SFC_RCVR_RESET, sfc->regbase + SFC_RCVR); -+ -+ err = readl_poll_timeout(sfc->regbase + SFC_RCVR, status, -+ !(status & SFC_RCVR_RESET), 20, -+ jiffies_to_usecs(HZ)); -+ if (err) -+ dev_err(sfc->dev, "SFC reset never finished\n"); -+ -+ /* Still need to clear the masked interrupt from RISR */ -+ writel_relaxed(0xFFFFFFFF, sfc->regbase + SFC_ICLR); -+ -+ dev_dbg(sfc->dev, "reset\n"); -+ -+ return err; -+} -+ -+static u16 rockchip_sfc_get_version(struct rockchip_sfc *sfc) -+{ -+ return (u16)(readl(sfc->regbase + SFC_VER) & 0xffff); -+} -+ -+static u32 rockchip_sfc_get_max_iosize(struct rockchip_sfc *sfc) -+{ -+ return SFC_MAX_IOSIZE_VER3; -+} -+ -+static void rockchip_sfc_irq_unmask(struct rockchip_sfc *sfc, u32 mask) -+{ -+ u32 reg; -+ -+ /* Enable transfer complete interrupt */ -+ reg = readl(sfc->regbase + SFC_IMR); -+ reg &= ~mask; -+ writel(reg, sfc->regbase + SFC_IMR); -+} -+ -+static void rockchip_sfc_irq_mask(struct rockchip_sfc *sfc, u32 mask) -+{ -+ u32 reg; -+ -+ /* Disable transfer finish interrupt */ -+ reg = readl(sfc->regbase + SFC_IMR); -+ reg |= mask; -+ writel(reg, sfc->regbase + SFC_IMR); -+} -+ -+static int rockchip_sfc_init(struct rockchip_sfc *sfc) -+{ -+ writel(0, sfc->regbase + SFC_CTRL); -+ writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR); -+ rockchip_sfc_irq_mask(sfc, 0xFFFFFFFF); -+ if (rockchip_sfc_get_version(sfc) >= SFC_VER_4) -+ writel(SFC_LEN_CTRL_TRB_SEL, sfc->regbase + SFC_LEN_CTRL); -+ -+ return 0; -+} -+ -+static int rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us) -+{ -+ int ret = 0; -+ u32 status; -+ -+ ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status, -+ status & SFC_FSR_TXLV_MASK, 0, -+ timeout_us); -+ if (ret) { -+ dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n"); -+ -+ ret = -ETIMEDOUT; -+ } -+ -+ return (status & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT; -+} -+ -+static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us) -+{ -+ int ret = 0; -+ u32 status; -+ -+ ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status, -+ status & SFC_FSR_RXLV_MASK, 0, -+ timeout_us); -+ if (ret) { -+ dev_dbg(sfc->dev, "sfc wait rx fifo timeout\n"); -+ -+ ret = -ETIMEDOUT; -+ } -+ -+ return (status & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT; -+} -+ -+static void rockchip_sfc_adjust_op_work(struct spi_mem_op *op) -+{ -+ if (unlikely(op->dummy.nbytes && !op->addr.nbytes)) { -+ /* -+ * SFC not support output DUMMY cycles right after CMD cycles, so -+ * treat it as ADDR cycles. -+ */ -+ op->addr.nbytes = op->dummy.nbytes; -+ op->addr.buswidth = op->dummy.buswidth; -+ op->addr.val = 0xFFFFFFFFF; -+ -+ op->dummy.nbytes = 0; -+ } -+} -+ -+static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc, -+ struct spi_mem *mem, -+ const struct spi_mem_op *op, -+ u32 len) -+{ -+ u32 ctrl = 0, cmd = 0; -+ -+ /* set CMD */ -+ cmd = op->cmd.opcode; -+ ctrl |= ((op->cmd.buswidth >> 1) << SFC_CTRL_CMD_BITS_SHIFT); -+ -+ /* set ADDR */ -+ if (op->addr.nbytes) { -+ if (op->addr.nbytes == 4) { -+ cmd |= SFC_CMD_ADDR_32BITS << SFC_CMD_ADDR_SHIFT; -+ } else if (op->addr.nbytes == 3) { -+ cmd |= SFC_CMD_ADDR_24BITS << SFC_CMD_ADDR_SHIFT; -+ } else { -+ cmd |= SFC_CMD_ADDR_XBITS << SFC_CMD_ADDR_SHIFT; -+ writel(op->addr.nbytes * 8 - 1, sfc->regbase + SFC_ABIT); -+ } -+ -+ ctrl |= ((op->addr.buswidth >> 1) << SFC_CTRL_ADDR_BITS_SHIFT); -+ } -+ -+ /* set DUMMY */ -+ if (op->dummy.nbytes) { -+ if (op->dummy.buswidth == 4) -+ cmd |= op->dummy.nbytes * 2 << SFC_CMD_DUMMY_SHIFT; -+ else if (op->dummy.buswidth == 2) -+ cmd |= op->dummy.nbytes * 4 << SFC_CMD_DUMMY_SHIFT; -+ else -+ cmd |= op->dummy.nbytes * 8 << SFC_CMD_DUMMY_SHIFT; -+ } -+ -+ /* set DATA */ -+ if (sfc->version >= SFC_VER_4) /* Clear it if no data to transfer */ -+ writel(len, sfc->regbase + SFC_LEN_EXT); -+ else -+ cmd |= len << SFC_CMD_TRAN_BYTES_SHIFT; -+ if (len) { -+ if (op->data.dir == SPI_MEM_DATA_OUT) -+ cmd |= SFC_CMD_DIR_WR << SFC_CMD_DIR_SHIFT; -+ -+ ctrl |= ((op->data.buswidth >> 1) << SFC_CTRL_DATA_BITS_SHIFT); -+ } -+ if (!len && op->addr.nbytes) -+ cmd |= SFC_CMD_DIR_WR << SFC_CMD_DIR_SHIFT; -+ -+ /* set the Controller */ -+ ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE; -+ cmd |= mem->spi->chip_select << SFC_CMD_CS_SHIFT; -+ -+ dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n", -+ op->addr.nbytes, op->addr.buswidth, -+ op->dummy.nbytes, op->dummy.buswidth); -+ dev_dbg(sfc->dev, "sfc ctrl=%x cmd=%x addr=%llx len=%x\n", -+ ctrl, cmd, op->addr.val, len); -+ -+ writel(ctrl, sfc->regbase + SFC_CTRL); -+ writel(cmd, sfc->regbase + SFC_CMD); -+ if (op->addr.nbytes) -+ writel(op->addr.val, sfc->regbase + SFC_ADDR); -+ -+ return 0; -+} -+ -+static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int len) -+{ -+ u8 bytes = len & 0x3; -+ u32 dwords; -+ int tx_level; -+ u32 write_words; -+ u32 tmp = 0; -+ -+ dwords = len >> 2; -+ while (dwords) { -+ tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000); -+ if (tx_level < 0) -+ return tx_level; -+ write_words = min_t(u32, tx_level, dwords); -+ iowrite32_rep(sfc->regbase + SFC_DATA, buf, write_words); -+ buf += write_words << 2; -+ dwords -= write_words; -+ } -+ -+ /* write the rest non word aligned bytes */ -+ if (bytes) { -+ tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000); -+ if (tx_level < 0) -+ return tx_level; -+ memcpy(&tmp, buf, bytes); -+ writel(tmp, sfc->regbase + SFC_DATA); -+ } -+ -+ return len; -+} -+ -+static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len) -+{ -+ u8 bytes = len & 0x3; -+ u32 dwords; -+ u8 read_words; -+ int rx_level; -+ int tmp; -+ -+ /* word aligned access only */ -+ dwords = len >> 2; -+ while (dwords) { -+ rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000); -+ if (rx_level < 0) -+ return rx_level; -+ read_words = min_t(u32, rx_level, dwords); -+ ioread32_rep(sfc->regbase + SFC_DATA, buf, read_words); -+ buf += read_words << 2; -+ dwords -= read_words; -+ } -+ -+ /* read the rest non word aligned bytes */ -+ if (bytes) { -+ rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000); -+ if (rx_level < 0) -+ return rx_level; -+ tmp = readl(sfc->regbase + SFC_DATA); -+ memcpy(buf, &tmp, bytes); -+ } -+ -+ return len; -+} -+ -+static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t dma_buf, size_t len) -+{ -+ writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR); -+ writel((u32)dma_buf, sfc->regbase + SFC_DMA_ADDR); -+ writel(SFC_DMA_TRIGGER_START, sfc->regbase + SFC_DMA_TRIGGER); -+ -+ return len; -+} -+ -+static int rockchip_sfc_xfer_data_poll(struct rockchip_sfc *sfc, -+ const struct spi_mem_op *op, u32 len) -+{ -+ dev_dbg(sfc->dev, "sfc xfer_poll len=%x\n", len); -+ -+ if (op->data.dir == SPI_MEM_DATA_OUT) -+ return rockchip_sfc_write_fifo(sfc, op->data.buf.out, len); -+ else -+ return rockchip_sfc_read_fifo(sfc, op->data.buf.in, len); -+} -+ -+static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc, -+ const struct spi_mem_op *op, u32 len) -+{ -+ int ret; -+ -+ dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n", len); -+ -+ if (op->data.dir == SPI_MEM_DATA_OUT) -+ memcpy_toio(sfc->buffer, op->data.buf.out, len); -+ -+ ret = rockchip_sfc_fifo_transfer_dma(sfc, sfc->dma_buffer, len); -+ if (!wait_for_completion_timeout(&sfc->cp, msecs_to_jiffies(2000))) { -+ dev_err(sfc->dev, "DMA wait for transfer finish timeout\n"); -+ ret = -ETIMEDOUT; -+ } -+ rockchip_sfc_irq_mask(sfc, SFC_IMR_DMA); -+ if (op->data.dir == SPI_MEM_DATA_IN) -+ memcpy_fromio(op->data.buf.in, sfc->buffer, len); -+ -+ return ret; -+} -+ -+static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us) -+{ -+ int ret = 0; -+ u32 status; -+ -+ ret = readl_poll_timeout(sfc->regbase + SFC_SR, status, -+ !(status & SFC_SR_IS_BUSY), -+ 20, timeout_us); -+ if (ret) { -+ dev_err(sfc->dev, "wait sfc idle timeout\n"); -+ rockchip_sfc_reset(sfc); -+ -+ ret = -EIO; -+ } -+ -+ return ret; -+} -+ -+static int rockchip_sfc_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) -+{ -+ struct rockchip_sfc *sfc = spi_master_get_devdata(mem->spi->master); -+ u32 len = op->data.nbytes; -+ int ret; -+ -+ if (unlikely(mem->spi->max_speed_hz != sfc->frequency)) { -+ ret = clk_set_rate(sfc->clk, mem->spi->max_speed_hz); -+ if (ret) -+ return ret; -+ sfc->frequency = mem->spi->max_speed_hz; -+ dev_dbg(sfc->dev, "set_freq=%dHz real_freq=%ldHz\n", -+ sfc->frequency, clk_get_rate(sfc->clk)); -+ } -+ -+ rockchip_sfc_adjust_op_work((struct spi_mem_op *)op); -+ rockchip_sfc_xfer_setup(sfc, mem, op, len); -+ if (len) { -+ if (likely(sfc->use_dma) && len >= SFC_DMA_TRANS_THRETHOLD) { -+ init_completion(&sfc->cp); -+ rockchip_sfc_irq_unmask(sfc, SFC_IMR_DMA); -+ ret = rockchip_sfc_xfer_data_dma(sfc, op, len); -+ } else { -+ ret = rockchip_sfc_xfer_data_poll(sfc, op, len); -+ } -+ -+ if (ret != len) { -+ dev_err(sfc->dev, "xfer data failed ret %d dir %d\n", ret, op->data.dir); -+ -+ return -EIO; -+ } -+ } -+ -+ return rockchip_sfc_xfer_done(sfc, 100000); -+} -+ -+static int rockchip_sfc_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) -+{ -+ struct rockchip_sfc *sfc = spi_master_get_devdata(mem->spi->master); -+ -+ op->data.nbytes = min(op->data.nbytes, sfc->max_iosize); -+ -+ return 0; -+} -+ -+static const struct spi_controller_mem_ops rockchip_sfc_mem_ops = { -+ .exec_op = rockchip_sfc_exec_mem_op, -+ .adjust_op_size = rockchip_sfc_adjust_op_size, -+}; -+ -+static irqreturn_t rockchip_sfc_irq_handler(int irq, void *dev_id) -+{ -+ struct rockchip_sfc *sfc = dev_id; -+ u32 reg; -+ -+ reg = readl(sfc->regbase + SFC_RISR); -+ -+ /* Clear interrupt */ -+ writel_relaxed(reg, sfc->regbase + SFC_ICLR); -+ -+ if (reg & SFC_RISR_DMA) { -+ complete(&sfc->cp); -+ -+ return IRQ_HANDLED; -+ } -+ -+ return IRQ_NONE; -+} -+ -+static int rockchip_sfc_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct spi_master *master; -+ struct resource *res; -+ struct rockchip_sfc *sfc; -+ int ret; -+ -+ master = devm_spi_alloc_master(&pdev->dev, sizeof(*sfc)); -+ if (!master) -+ return -ENOMEM; -+ -+ master->flags = SPI_MASTER_HALF_DUPLEX; -+ master->mem_ops = &rockchip_sfc_mem_ops; -+ master->dev.of_node = pdev->dev.of_node; -+ master->mode_bits = SPI_TX_QUAD | SPI_TX_DUAL | SPI_RX_QUAD | SPI_RX_DUAL; -+ master->max_speed_hz = SFC_MAX_SPEED; -+ master->num_chipselect = SFC_MAX_CHIPSELECT_NUM; -+ -+ sfc = spi_master_get_devdata(master); -+ sfc->dev = dev; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ sfc->regbase = devm_ioremap_resource(dev, res); -+ if (IS_ERR(sfc->regbase)) -+ return PTR_ERR(sfc->regbase); -+ -+ sfc->clk = devm_clk_get(&pdev->dev, "clk_sfc"); -+ if (IS_ERR(sfc->clk)) { -+ dev_err(&pdev->dev, "Failed to get sfc interface clk\n"); -+ return PTR_ERR(sfc->clk); -+ } -+ -+ sfc->hclk = devm_clk_get(&pdev->dev, "hclk_sfc"); -+ if (IS_ERR(sfc->hclk)) { -+ dev_err(&pdev->dev, "Failed to get sfc ahb clk\n"); -+ return PTR_ERR(sfc->hclk); -+ } -+ -+ sfc->use_dma = !of_property_read_bool(sfc->dev->of_node, -+ "rockchip,sfc-no-dma"); -+ -+ if (sfc->use_dma) { -+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); -+ if (ret) { -+ dev_warn(dev, "Unable to set dma mask\n"); -+ return ret; -+ } -+ -+ sfc->buffer = dmam_alloc_coherent(dev, SFC_MAX_IOSIZE_VER3, -+ &sfc->dma_buffer, -+ GFP_KERNEL); -+ if (!sfc->buffer) -+ return -ENOMEM; -+ } -+ -+ ret = clk_prepare_enable(sfc->hclk); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to enable ahb clk\n"); -+ goto err_hclk; -+ } -+ -+ ret = clk_prepare_enable(sfc->clk); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to enable interface clk\n"); -+ goto err_clk; -+ } -+ -+ /* Find the irq */ -+ ret = platform_get_irq(pdev, 0); -+ if (ret < 0) { -+ dev_err(dev, "Failed to get the irq\n"); -+ goto err_irq; -+ } -+ -+ ret = devm_request_irq(dev, ret, rockchip_sfc_irq_handler, -+ 0, pdev->name, sfc); -+ if (ret) { -+ dev_err(dev, "Failed to request irq\n"); -+ -+ return ret; -+ } -+ -+ ret = rockchip_sfc_init(sfc); -+ if (ret) -+ goto err_irq; -+ -+ sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc); -+ sfc->version = rockchip_sfc_get_version(sfc); -+ -+ ret = spi_register_master(master); -+ if (ret) -+ goto err_irq; -+ -+ return 0; -+ -+err_irq: -+ clk_disable_unprepare(sfc->clk); -+err_clk: -+ clk_disable_unprepare(sfc->hclk); -+err_hclk: -+ return ret; -+} -+ -+static int rockchip_sfc_remove(struct platform_device *pdev) -+{ -+ struct spi_master *master = platform_get_drvdata(pdev); -+ struct rockchip_sfc *sfc = platform_get_drvdata(pdev); -+ -+ spi_unregister_master(master); -+ -+ clk_disable_unprepare(sfc->clk); -+ clk_disable_unprepare(sfc->hclk); -+ -+ return 0; -+} -+ -+static const struct of_device_id rockchip_sfc_dt_ids[] = { -+ { .compatible = "rockchip,sfc"}, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, rockchip_sfc_dt_ids); -+ -+static struct platform_driver rockchip_sfc_driver = { -+ .driver = { -+ .name = "rockchip-sfc", -+ .of_match_table = rockchip_sfc_dt_ids, -+ }, -+ .probe = rockchip_sfc_probe, -+ .remove = rockchip_sfc_remove, -+}; -+module_platform_driver(rockchip_sfc_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION("Rockchip Serial Flash Controller Driver"); -+MODULE_AUTHOR("Shawn Lin "); -+MODULE_AUTHOR("Chris Morgan "); -+MODULE_AUTHOR("Jon Lin "); -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Punit Agrawal -Date: Wed, 29 Sep 2021 22:50:49 +0900 -Subject: [PATCH] net: stmmac: dwmac-rk: Fix ethernet on rk3399 based devices - -Commit 2d26f6e39afb ("net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable warnings") -while getting rid of a runtime PM warning ended up breaking ethernet -on rk3399 based devices. By dropping an extra reference to the device, -the commit ends up enabling suspend / resume of the ethernet device - -which appears to be broken. - -While the issue with runtime pm is being investigated, partially -revert commit 2d26f6e39afb to restore the network on rk3399. - -Fixes: 2d26f6e39afb ("net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable warnings") -Suggested-by: Heiko Stuebner -Signed-off-by: Punit Agrawal -Cc: Michael Riesch -Tested-by: Heiko Stuebner ---- - drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c -index ed817011a94a..6924a6aacbd5 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - - #include "stmmac_platform.h" - -@@ -1528,6 +1529,8 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) - return ret; - } - -+ pm_runtime_get_sync(dev); -+ - if (bsp_priv->integrated_phy) - rk_gmac_integrated_phy_powerup(bsp_priv); - -@@ -1539,6 +1542,8 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac) - if (gmac->integrated_phy) - rk_gmac_integrated_phy_powerdown(gmac); - -+ pm_runtime_put_sync(&gmac->pdev->dev); -+ - phy_power_on(gmac, false); - gmac_clk_enable(gmac, false); +diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c +index 510a9965633bb..075c7f2a7ec4d 100644 +--- a/drivers/clk/clk-composite.c ++++ b/drivers/clk/clk-composite.c +@@ -42,6 +42,29 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw, + return rate_ops->recalc_rate(rate_hw, parent_rate); } + ++static int clk_composite_determine_rate_for_parent(struct clk_hw *rate_hw, ++ struct clk_rate_request *req, ++ struct clk_hw *parent_hw, ++ const struct clk_ops *rate_ops) ++{ ++ long rate; ++ ++ req->best_parent_hw = parent_hw; ++ req->best_parent_rate = clk_hw_get_rate(parent_hw); ++ ++ if (rate_ops->determine_rate) ++ return rate_ops->determine_rate(rate_hw, req); ++ ++ rate = rate_ops->round_rate(rate_hw, req->rate, ++ &req->best_parent_rate); ++ if (rate < 0) ++ return rate; ++ ++ req->rate = rate; ++ ++ return 0; ++} ++ + static int clk_composite_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) + { +@@ -51,51 +74,56 @@ static int clk_composite_determine_rate(struct clk_hw *hw, + struct clk_hw *rate_hw = composite->rate_hw; + struct clk_hw *mux_hw = composite->mux_hw; + struct clk_hw *parent; +- unsigned long parent_rate; +- long tmp_rate, best_rate = 0; + unsigned long rate_diff; + unsigned long best_rate_diff = ULONG_MAX; +- long rate; +- int i; ++ unsigned long best_rate = 0; ++ int i, ret; + +- if (rate_hw && rate_ops && rate_ops->round_rate && ++ if (rate_hw && rate_ops && ++ (rate_ops->determine_rate || rate_ops->round_rate) && + mux_hw && mux_ops && mux_ops->set_parent) { + req->best_parent_hw = NULL; + + if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) { ++ struct clk_rate_request tmp_req = *req; ++ + parent = clk_hw_get_parent(mux_hw); +- req->best_parent_hw = parent; +- req->best_parent_rate = clk_hw_get_rate(parent); + +- rate = rate_ops->round_rate(rate_hw, req->rate, +- &req->best_parent_rate); +- if (rate < 0) +- return rate; ++ ret = clk_composite_determine_rate_for_parent(rate_hw, ++ &tmp_req, ++ parent, ++ rate_ops); ++ if (ret) ++ return ret; ++ ++ req->rate = tmp_req.rate; ++ req->best_parent_rate = tmp_req.best_parent_rate; + +- req->rate = rate; + return 0; + } + + for (i = 0; i < clk_hw_get_num_parents(mux_hw); i++) { ++ struct clk_rate_request tmp_req = *req; ++ + parent = clk_hw_get_parent_by_index(mux_hw, i); + if (!parent) + continue; + +- parent_rate = clk_hw_get_rate(parent); +- +- tmp_rate = rate_ops->round_rate(rate_hw, req->rate, +- &parent_rate); +- if (tmp_rate < 0) ++ ret = clk_composite_determine_rate_for_parent(rate_hw, ++ &tmp_req, ++ parent, ++ rate_ops); ++ if (ret) + continue; + +- rate_diff = abs(req->rate - tmp_rate); ++ rate_diff = abs(req->rate - tmp_req.rate); + + if (!rate_diff || !req->best_parent_hw + || best_rate_diff > rate_diff) { + req->best_parent_hw = parent; +- req->best_parent_rate = parent_rate; ++ req->best_parent_rate = tmp_req.best_parent_rate; + best_rate_diff = rate_diff; +- best_rate = tmp_rate; ++ best_rate = tmp_req.rate; + } + + if (!rate_diff) diff --git a/projects/Rockchip/patches/linux/default/linux-0010-v4l2-from-5.15.patch b/projects/Rockchip/patches/linux/default/linux-0010-v4l2-from-5.15.patch deleted file mode 100644 index 7f916173a2..0000000000 --- a/projects/Rockchip/patches/linux/default/linux-0010-v4l2-from-5.15.patch +++ /dev/null @@ -1,1210 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Mon, 19 Jul 2021 22:52:34 +0200 -Subject: [PATCH] media: hantro: Make struct hantro_variant.init() optional - -The hantro_variant.init() function is there for platforms -to perform hardware-specific initialization, such as -clock rate bumping. - -Not all platforms require it, so make it optional. - -Signed-off-by: Ezequiel Garcia -Tested-by: Alex Bee -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/staging/media/hantro/hantro.h | 4 ++-- - drivers/staging/media/hantro/hantro_drv.c | 10 ++++++---- - drivers/staging/media/hantro/sama5d4_vdec_hw.c | 6 ------ - 3 files changed, 8 insertions(+), 12 deletions(-) - -diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h -index a70c386de6f1..c2e2dca38628 100644 ---- a/drivers/staging/media/hantro/hantro.h -+++ b/drivers/staging/media/hantro/hantro.h -@@ -61,8 +61,8 @@ struct hantro_irq { - * @num_postproc_fmts: Number of post-processor formats. - * @codec: Supported codecs - * @codec_ops: Codec ops. -- * @init: Initialize hardware. -- * @runtime_resume: reenable hardware after power gating -+ * @init: Initialize hardware, optional. -+ * @runtime_resume: reenable hardware after power gating, optional. - * @irqs: array of irq names and interrupt handlers - * @num_irqs: number of irqs in the array - * @clk_names: array of clock names -diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c -index 31d8449ca1d2..9b5415176bfe 100644 ---- a/drivers/staging/media/hantro/hantro_drv.c -+++ b/drivers/staging/media/hantro/hantro_drv.c -@@ -942,10 +942,12 @@ static int hantro_probe(struct platform_device *pdev) - } - } - -- ret = vpu->variant->init(vpu); -- if (ret) { -- dev_err(&pdev->dev, "Failed to init VPU hardware\n"); -- return ret; -+ if (vpu->variant->init) { -+ ret = vpu->variant->init(vpu); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to init VPU hardware\n"); -+ return ret; -+ } - } - - pm_runtime_set_autosuspend_delay(vpu->dev, 100); -diff --git a/drivers/staging/media/hantro/sama5d4_vdec_hw.c b/drivers/staging/media/hantro/sama5d4_vdec_hw.c -index 58ae72c2b723..9c3b8cd0b239 100644 ---- a/drivers/staging/media/hantro/sama5d4_vdec_hw.c -+++ b/drivers/staging/media/hantro/sama5d4_vdec_hw.c -@@ -64,11 +64,6 @@ static const struct hantro_fmt sama5d4_vdec_fmts[] = { - }, - }; - --static int sama5d4_hw_init(struct hantro_dev *vpu) --{ -- return 0; --} -- - /* - * Supported codec ops. - */ -@@ -109,7 +104,6 @@ const struct hantro_variant sama5d4_vdec_variant = { - .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER | - HANTRO_H264_DECODER, - .codec_ops = sama5d4_vdec_codec_ops, -- .init = sama5d4_hw_init, - .irqs = sama5d4_irqs, - .num_irqs = ARRAY_SIZE(sama5d4_irqs), - .clk_names = sama5d4_clk_names, - -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Mon, 19 Jul 2021 22:52:35 +0200 -Subject: [PATCH] media: hantro: Avoid redundant hantro_get_{dst,src}_buf() - calls - -Getting the next src/dst buffer is relatively expensive -so avoid doing it multiple times. - -Signed-off-by: Ezequiel Garcia -Tested-by: Alex Bee -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - .../staging/media/hantro/hantro_g1_h264_dec.c | 17 ++++++++--------- - .../staging/media/hantro/hantro_g1_vp8_dec.c | 18 +++++++++--------- - .../media/hantro/rockchip_vpu2_hw_vp8_dec.c | 19 +++++++++---------- - 3 files changed, 26 insertions(+), 28 deletions(-) - -diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c -index 5c792b7bcb79..2aa37baad0c3 100644 ---- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c -+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c -@@ -19,13 +19,12 @@ - #include "hantro_hw.h" - #include "hantro_v4l2.h" - --static void set_params(struct hantro_ctx *ctx) -+static void set_params(struct hantro_ctx *ctx, struct vb2_v4l2_buffer *src_buf) - { - const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls; - const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode; - const struct v4l2_ctrl_h264_sps *sps = ctrls->sps; - const struct v4l2_ctrl_h264_pps *pps = ctrls->pps; -- struct vb2_v4l2_buffer *src_buf = hantro_get_src_buf(ctx); - struct hantro_dev *vpu = ctx->dev; - u32 reg; - -@@ -226,22 +225,20 @@ static void set_ref(struct hantro_ctx *ctx) - } - } - --static void set_buffers(struct hantro_ctx *ctx) -+static void set_buffers(struct hantro_ctx *ctx, struct vb2_v4l2_buffer *src_buf) - { - const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls; -- struct vb2_v4l2_buffer *src_buf, *dst_buf; -+ struct vb2_v4l2_buffer *dst_buf; - struct hantro_dev *vpu = ctx->dev; - dma_addr_t src_dma, dst_dma; - size_t offset = 0; - -- src_buf = hantro_get_src_buf(ctx); -- dst_buf = hantro_get_dst_buf(ctx); -- - /* Source (stream) buffer. */ - src_dma = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); - vdpu_write_relaxed(vpu, src_dma, G1_REG_ADDR_STR); - - /* Destination (decoded frame) buffer. */ -+ dst_buf = hantro_get_dst_buf(ctx); - dst_dma = hantro_get_dec_buf_addr(ctx, &dst_buf->vb2_buf); - /* Adjust dma addr to start at second line for bottom field */ - if (ctrls->decode->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) -@@ -276,6 +273,7 @@ static void set_buffers(struct hantro_ctx *ctx) - int hantro_g1_h264_dec_run(struct hantro_ctx *ctx) - { - struct hantro_dev *vpu = ctx->dev; -+ struct vb2_v4l2_buffer *src_buf; - int ret; - - /* Prepare the H264 decoder context. */ -@@ -284,9 +282,10 @@ int hantro_g1_h264_dec_run(struct hantro_ctx *ctx) - return ret; - - /* Configure hardware registers. */ -- set_params(ctx); -+ src_buf = hantro_get_src_buf(ctx); -+ set_params(ctx, src_buf); - set_ref(ctx); -- set_buffers(ctx); -+ set_buffers(ctx, src_buf); - - hantro_end_prepare_run(ctx); - -diff --git a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c -index 2afd5996d75f..6180b23e7d94 100644 ---- a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c -+++ b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c -@@ -367,13 +367,12 @@ static void cfg_tap(struct hantro_ctx *ctx, - } - - static void cfg_ref(struct hantro_ctx *ctx, -- const struct v4l2_ctrl_vp8_frame *hdr) -+ const struct v4l2_ctrl_vp8_frame *hdr, -+ struct vb2_v4l2_buffer *vb2_dst) - { - struct hantro_dev *vpu = ctx->dev; -- struct vb2_v4l2_buffer *vb2_dst; - dma_addr_t ref; - -- vb2_dst = hantro_get_dst_buf(ctx); - - ref = hantro_get_ref(ctx, hdr->last_frame_ts); - if (!ref) { -@@ -405,16 +404,14 @@ static void cfg_ref(struct hantro_ctx *ctx, - } - - static void cfg_buffers(struct hantro_ctx *ctx, -- const struct v4l2_ctrl_vp8_frame *hdr) -+ const struct v4l2_ctrl_vp8_frame *hdr, -+ struct vb2_v4l2_buffer *vb2_dst) - { - const struct v4l2_vp8_segment *seg = &hdr->segment; - struct hantro_dev *vpu = ctx->dev; -- struct vb2_v4l2_buffer *vb2_dst; - dma_addr_t dst_dma; - u32 reg; - -- vb2_dst = hantro_get_dst_buf(ctx); -- - /* Set probability table buffer address */ - vdpu_write_relaxed(vpu, ctx->vp8_dec.prob_tbl.dma, - G1_REG_ADDR_QTABLE); -@@ -436,6 +433,7 @@ int hantro_g1_vp8_dec_run(struct hantro_ctx *ctx) - { - const struct v4l2_ctrl_vp8_frame *hdr; - struct hantro_dev *vpu = ctx->dev; -+ struct vb2_v4l2_buffer *vb2_dst; - size_t height = ctx->dst_fmt.height; - size_t width = ctx->dst_fmt.width; - u32 mb_width, mb_height; -@@ -499,8 +497,10 @@ int hantro_g1_vp8_dec_run(struct hantro_ctx *ctx) - cfg_qp(ctx, hdr); - cfg_parts(ctx, hdr); - cfg_tap(ctx, hdr); -- cfg_ref(ctx, hdr); -- cfg_buffers(ctx, hdr); -+ -+ vb2_dst = hantro_get_dst_buf(ctx); -+ cfg_ref(ctx, hdr, vb2_dst); -+ cfg_buffers(ctx, hdr, vb2_dst); - - hantro_end_prepare_run(ctx); - -diff --git a/drivers/staging/media/hantro/rockchip_vpu2_hw_vp8_dec.c b/drivers/staging/media/hantro/rockchip_vpu2_hw_vp8_dec.c -index 704607511b57..d079075448c9 100644 ---- a/drivers/staging/media/hantro/rockchip_vpu2_hw_vp8_dec.c -+++ b/drivers/staging/media/hantro/rockchip_vpu2_hw_vp8_dec.c -@@ -444,14 +444,12 @@ static void cfg_tap(struct hantro_ctx *ctx, - } - - static void cfg_ref(struct hantro_ctx *ctx, -- const struct v4l2_ctrl_vp8_frame *hdr) -+ const struct v4l2_ctrl_vp8_frame *hdr, -+ struct vb2_v4l2_buffer *vb2_dst) - { - struct hantro_dev *vpu = ctx->dev; -- struct vb2_v4l2_buffer *vb2_dst; - dma_addr_t ref; - -- vb2_dst = hantro_get_dst_buf(ctx); -- - ref = hantro_get_ref(ctx, hdr->last_frame_ts); - if (!ref) { - vpu_debug(0, "failed to find last frame ts=%llu\n", -@@ -482,16 +480,14 @@ static void cfg_ref(struct hantro_ctx *ctx, - } - - static void cfg_buffers(struct hantro_ctx *ctx, -- const struct v4l2_ctrl_vp8_frame *hdr) -+ const struct v4l2_ctrl_vp8_frame *hdr, -+ struct vb2_v4l2_buffer *vb2_dst) - { - const struct v4l2_vp8_segment *seg = &hdr->segment; - struct hantro_dev *vpu = ctx->dev; -- struct vb2_v4l2_buffer *vb2_dst; - dma_addr_t dst_dma; - u32 reg; - -- vb2_dst = hantro_get_dst_buf(ctx); -- - /* Set probability table buffer address */ - vdpu_write_relaxed(vpu, ctx->vp8_dec.prob_tbl.dma, - VDPU_REG_ADDR_QTABLE); -@@ -514,6 +510,7 @@ int rockchip_vpu2_vp8_dec_run(struct hantro_ctx *ctx) - { - const struct v4l2_ctrl_vp8_frame *hdr; - struct hantro_dev *vpu = ctx->dev; -+ struct vb2_v4l2_buffer *vb2_dst; - size_t height = ctx->dst_fmt.height; - size_t width = ctx->dst_fmt.width; - u32 mb_width, mb_height; -@@ -590,8 +587,10 @@ int rockchip_vpu2_vp8_dec_run(struct hantro_ctx *ctx) - cfg_qp(ctx, hdr); - cfg_parts(ctx, hdr); - cfg_tap(ctx, hdr); -- cfg_ref(ctx, hdr); -- cfg_buffers(ctx, hdr); -+ -+ vb2_dst = hantro_get_dst_buf(ctx); -+ cfg_ref(ctx, hdr, vb2_dst); -+ cfg_buffers(ctx, hdr, vb2_dst); - - hantro_end_prepare_run(ctx); - - -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Mon, 19 Jul 2021 22:52:36 +0200 -Subject: [PATCH] media: hantro: h264: Move DPB valid and long-term bitmaps - -In order to reuse these bitmaps, move this process to -struct hantro_h264_dec_hw_ctx. This will be used by -the Rockchip VDPU2 H.264 driver. - -This idea was originally proposed by Jonas Karlman -in "[RFC 08/12] media: hantro: Fix H264 decoding of field encoded content" -which was posted a while ago. - -Link: https://lore.kernel.org/linux-media/HE1PR06MB4011EA39133818A85768B91FACBF0@HE1PR06MB4011.eurprd06.prod.outlook.com/ - -Signed-off-by: Ezequiel Garcia -Tested-by: Alex Bee -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - .../staging/media/hantro/hantro_g1_h264_dec.c | 17 ++--------------- - drivers/staging/media/hantro/hantro_h264.c | 13 +++++++++++++ - drivers/staging/media/hantro/hantro_hw.h | 4 ++++ - 3 files changed, 19 insertions(+), 15 deletions(-) - -diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c -index 2aa37baad0c3..6faacfc44c7c 100644 ---- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c -+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c -@@ -129,25 +129,12 @@ static void set_ref(struct hantro_ctx *ctx) - struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb; - const u8 *b0_reflist, *b1_reflist, *p_reflist; - struct hantro_dev *vpu = ctx->dev; -- u32 dpb_longterm = 0; -- u32 dpb_valid = 0; - int reg_num; - u32 reg; - int i; - -- /* -- * Set up bit maps of valid and long term DPBs. -- * NOTE: The bits are reversed, i.e. MSb is DPB 0. -- */ -- for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) { -- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) -- dpb_valid |= BIT(HANTRO_H264_DPB_SIZE - 1 - i); -- -- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) -- dpb_longterm |= BIT(HANTRO_H264_DPB_SIZE - 1 - i); -- } -- vdpu_write_relaxed(vpu, dpb_valid << 16, G1_REG_VALID_REF); -- vdpu_write_relaxed(vpu, dpb_longterm << 16, G1_REG_LT_REF); -+ vdpu_write_relaxed(vpu, ctx->h264_dec.dpb_valid, G1_REG_VALID_REF); -+ vdpu_write_relaxed(vpu, ctx->h264_dec.dpb_longterm, G1_REG_LT_REF); - - /* - * Set up reference frame picture numbers. -diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c -index ed6eaf11d96f..6d72136760e7 100644 ---- a/drivers/staging/media/hantro/hantro_h264.c -+++ b/drivers/staging/media/hantro/hantro_h264.c -@@ -229,12 +229,25 @@ static void prepare_table(struct hantro_ctx *ctx) - const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode; - struct hantro_h264_dec_priv_tbl *tbl = ctx->h264_dec.priv.cpu; - const struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb; -+ u32 dpb_longterm = 0; -+ u32 dpb_valid = 0; - int i; - - for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) { - tbl->poc[i * 2] = dpb[i].top_field_order_cnt; - tbl->poc[i * 2 + 1] = dpb[i].bottom_field_order_cnt; -+ -+ /* -+ * Set up bit maps of valid and long term DPBs. -+ * NOTE: The bits are reversed, i.e. MSb is DPB 0. -+ */ -+ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) -+ dpb_valid |= BIT(HANTRO_H264_DPB_SIZE - 1 - i); -+ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) -+ dpb_longterm |= BIT(HANTRO_H264_DPB_SIZE - 1 - i); - } -+ ctx->h264_dec.dpb_valid = dpb_valid << 16; -+ ctx->h264_dec.dpb_longterm = dpb_longterm << 16; - - tbl->poc[32] = dec_param->top_field_order_cnt; - tbl->poc[33] = dec_param->bottom_field_order_cnt; -diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h -index 5dcf65805396..ce678fedaad6 100644 ---- a/drivers/staging/media/hantro/hantro_hw.h -+++ b/drivers/staging/media/hantro/hantro_hw.h -@@ -89,12 +89,16 @@ struct hantro_h264_dec_reflists { - * @dpb: DPB - * @reflists: P/B0/B1 reflists - * @ctrls: V4L2 controls attached to a run -+ * @dpb_longterm: DPB long-term -+ * @dpb_valid: DPB valid - */ - struct hantro_h264_dec_hw_ctx { - struct hantro_aux_buf priv; - struct v4l2_h264_dpb_entry dpb[HANTRO_H264_DPB_SIZE]; - struct hantro_h264_dec_reflists reflists; - struct hantro_h264_dec_ctrls ctrls; -+ u32 dpb_longterm; -+ u32 dpb_valid; - }; - - /** - -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Mon, 19 Jul 2021 22:52:37 +0200 -Subject: [PATCH] media: hantro: h264: Move reference picture number to a - helper - -Add a hantro_h264_get_ref_nbr() helper function to get the reference -picture numbers. This will be used by the Rockchip VDPU2 H.264 driver. - -This idea was originally proposed by Jonas Karlman in -"[RFC 09/12] media: hantro: Refactor G1 H264 code" -posted a while ago. - -Link: https://lore.kernel.org/linux-media/HE1PR06MB401165F2BA0AD8A634FDFAF2ACBF0@HE1PR06MB4011.eurprd06.prod.outlook.com/ - -Signed-off-by: Ezequiel Garcia -Tested-by: Alex Bee -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/staging/media/hantro/hantro_g1_h264_dec.c | 14 ++------------ - drivers/staging/media/hantro/hantro_h264.c | 11 +++++++++++ - drivers/staging/media/hantro/hantro_hw.h | 2 ++ - 3 files changed, 15 insertions(+), 12 deletions(-) - -diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c -index 6faacfc44c7c..236ce24ca00c 100644 ---- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c -+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c -@@ -126,7 +126,6 @@ static void set_params(struct hantro_ctx *ctx, struct vb2_v4l2_buffer *src_buf) - - static void set_ref(struct hantro_ctx *ctx) - { -- struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb; - const u8 *b0_reflist, *b1_reflist, *p_reflist; - struct hantro_dev *vpu = ctx->dev; - int reg_num; -@@ -143,17 +142,8 @@ static void set_ref(struct hantro_ctx *ctx) - * subsequential reference pictures. - */ - for (i = 0; i < HANTRO_H264_DPB_SIZE; i += 2) { -- reg = 0; -- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) -- reg |= G1_REG_REF_PIC_REFER0_NBR(dpb[i].pic_num); -- else -- reg |= G1_REG_REF_PIC_REFER0_NBR(dpb[i].frame_num); -- -- if (dpb[i + 1].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) -- reg |= G1_REG_REF_PIC_REFER1_NBR(dpb[i + 1].pic_num); -- else -- reg |= G1_REG_REF_PIC_REFER1_NBR(dpb[i + 1].frame_num); -- -+ reg = G1_REG_REF_PIC_REFER0_NBR(hantro_h264_get_ref_nbr(ctx, i)) | -+ G1_REG_REF_PIC_REFER1_NBR(hantro_h264_get_ref_nbr(ctx, i + 1)); - vdpu_write_relaxed(vpu, reg, G1_REG_REF_PIC(i / 2)); - } - -diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c -index 6d72136760e7..0b4d2491be3b 100644 ---- a/drivers/staging/media/hantro/hantro_h264.c -+++ b/drivers/staging/media/hantro/hantro_h264.c -@@ -348,6 +348,17 @@ dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx, - return dma_addr; - } - -+u16 hantro_h264_get_ref_nbr(struct hantro_ctx *ctx, unsigned int dpb_idx) -+{ -+ const struct v4l2_h264_dpb_entry *dpb = &ctx->h264_dec.dpb[dpb_idx]; -+ -+ if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) -+ return 0; -+ if (dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) -+ return dpb->pic_num; -+ return dpb->frame_num; -+} -+ - int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx) - { - struct hantro_h264_dec_hw_ctx *h264_ctx = &ctx->h264_dec; -diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h -index ce678fedaad6..7a8048afe357 100644 ---- a/drivers/staging/media/hantro/hantro_hw.h -+++ b/drivers/staging/media/hantro/hantro_hw.h -@@ -238,6 +238,8 @@ void hantro_jpeg_enc_done(struct hantro_ctx *ctx); - - dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx, - unsigned int dpb_idx); -+u16 hantro_h264_get_ref_nbr(struct hantro_ctx *ctx, -+ unsigned int dpb_idx); - int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx); - int hantro_g1_h264_dec_run(struct hantro_ctx *ctx); - int hantro_h264_dec_init(struct hantro_ctx *ctx); - -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jonas Karlman -Date: Mon, 19 Jul 2021 22:52:38 +0200 -Subject: [PATCH] media: hantro: Add H.264 support for Rockchip VDPU2 - -Rockchip VDPU2 core is present on RK3328, RK3326/PX30, RK3399 -and others. It's similar to Hantro G1, but it's not compatible with it. - -Signed-off-by: Jonas Karlman -Signed-off-by: Ezequiel Garcia -Tested-by: Alex Bee -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/staging/media/hantro/Makefile | 1 + - drivers/staging/media/hantro/hantro_hw.h | 1 + - .../media/hantro/rockchip_vpu2_hw_h264_dec.c | 491 ++++++++++++++++++ - 3 files changed, 493 insertions(+) - create mode 100644 drivers/staging/media/hantro/rockchip_vpu2_hw_h264_dec.c - -diff --git a/drivers/staging/media/hantro/Makefile b/drivers/staging/media/hantro/Makefile -index 287370188d2a..90036831fec4 100644 ---- a/drivers/staging/media/hantro/Makefile -+++ b/drivers/staging/media/hantro/Makefile -@@ -13,6 +13,7 @@ hantro-vpu-y += \ - hantro_g2_hevc_dec.o \ - hantro_g1_vp8_dec.o \ - rockchip_vpu2_hw_jpeg_enc.o \ -+ rockchip_vpu2_hw_h264_dec.o \ - rockchip_vpu2_hw_mpeg2_dec.o \ - rockchip_vpu2_hw_vp8_dec.o \ - hantro_jpeg.o \ -diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h -index 7a8048afe357..9296624654a6 100644 ---- a/drivers/staging/media/hantro/hantro_hw.h -+++ b/drivers/staging/media/hantro/hantro_hw.h -@@ -241,6 +241,7 @@ dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx, - u16 hantro_h264_get_ref_nbr(struct hantro_ctx *ctx, - unsigned int dpb_idx); - int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx); -+int rockchip_vpu2_h264_dec_run(struct hantro_ctx *ctx); - int hantro_g1_h264_dec_run(struct hantro_ctx *ctx); - int hantro_h264_dec_init(struct hantro_ctx *ctx); - void hantro_h264_dec_exit(struct hantro_ctx *ctx); -diff --git a/drivers/staging/media/hantro/rockchip_vpu2_hw_h264_dec.c b/drivers/staging/media/hantro/rockchip_vpu2_hw_h264_dec.c -new file mode 100644 -index 000000000000..64a6330475eb ---- /dev/null -+++ b/drivers/staging/media/hantro/rockchip_vpu2_hw_h264_dec.c -@@ -0,0 +1,491 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Hantro VPU codec driver -+ * -+ * Copyright (c) 2014 Rockchip Electronics Co., Ltd. -+ * Hertz Wong -+ * Herman Chen -+ * -+ * Copyright (C) 2014 Google, Inc. -+ * Tomasz Figa -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "hantro_hw.h" -+#include "hantro_v4l2.h" -+ -+#define VDPU_SWREG(nr) ((nr) * 4) -+ -+#define VDPU_REG_DEC_OUT_BASE VDPU_SWREG(63) -+#define VDPU_REG_RLC_VLC_BASE VDPU_SWREG(64) -+#define VDPU_REG_QTABLE_BASE VDPU_SWREG(61) -+#define VDPU_REG_DIR_MV_BASE VDPU_SWREG(62) -+#define VDPU_REG_REFER_BASE(i) (VDPU_SWREG(84 + (i))) -+#define VDPU_REG_DEC_E(v) ((v) ? BIT(0) : 0) -+ -+#define VDPU_REG_DEC_ADV_PRE_DIS(v) ((v) ? BIT(11) : 0) -+#define VDPU_REG_DEC_SCMD_DIS(v) ((v) ? BIT(10) : 0) -+#define VDPU_REG_FILTERING_DIS(v) ((v) ? BIT(8) : 0) -+#define VDPU_REG_PIC_FIXED_QUANT(v) ((v) ? BIT(7) : 0) -+#define VDPU_REG_DEC_LATENCY(v) (((v) << 1) & GENMASK(6, 1)) -+ -+#define VDPU_REG_INIT_QP(v) (((v) << 25) & GENMASK(30, 25)) -+#define VDPU_REG_STREAM_LEN(v) (((v) << 0) & GENMASK(23, 0)) -+ -+#define VDPU_REG_APF_THRESHOLD(v) (((v) << 17) & GENMASK(30, 17)) -+#define VDPU_REG_STARTMB_X(v) (((v) << 8) & GENMASK(16, 8)) -+#define VDPU_REG_STARTMB_Y(v) (((v) << 0) & GENMASK(7, 0)) -+ -+#define VDPU_REG_DEC_MODE(v) (((v) << 0) & GENMASK(3, 0)) -+ -+#define VDPU_REG_DEC_STRENDIAN_E(v) ((v) ? BIT(5) : 0) -+#define VDPU_REG_DEC_STRSWAP32_E(v) ((v) ? BIT(4) : 0) -+#define VDPU_REG_DEC_OUTSWAP32_E(v) ((v) ? BIT(3) : 0) -+#define VDPU_REG_DEC_INSWAP32_E(v) ((v) ? BIT(2) : 0) -+#define VDPU_REG_DEC_OUT_ENDIAN(v) ((v) ? BIT(1) : 0) -+#define VDPU_REG_DEC_IN_ENDIAN(v) ((v) ? BIT(0) : 0) -+ -+#define VDPU_REG_DEC_DATA_DISC_E(v) ((v) ? BIT(22) : 0) -+#define VDPU_REG_DEC_MAX_BURST(v) (((v) << 16) & GENMASK(20, 16)) -+#define VDPU_REG_DEC_AXI_WR_ID(v) (((v) << 8) & GENMASK(15, 8)) -+#define VDPU_REG_DEC_AXI_RD_ID(v) (((v) << 0) & GENMASK(7, 0)) -+ -+#define VDPU_REG_START_CODE_E(v) ((v) ? BIT(22) : 0) -+#define VDPU_REG_CH_8PIX_ILEAV_E(v) ((v) ? BIT(21) : 0) -+#define VDPU_REG_RLC_MODE_E(v) ((v) ? BIT(20) : 0) -+#define VDPU_REG_PIC_INTERLACE_E(v) ((v) ? BIT(17) : 0) -+#define VDPU_REG_PIC_FIELDMODE_E(v) ((v) ? BIT(16) : 0) -+#define VDPU_REG_PIC_TOPFIELD_E(v) ((v) ? BIT(13) : 0) -+#define VDPU_REG_WRITE_MVS_E(v) ((v) ? BIT(10) : 0) -+#define VDPU_REG_SEQ_MBAFF_E(v) ((v) ? BIT(7) : 0) -+#define VDPU_REG_PICORD_COUNT_E(v) ((v) ? BIT(6) : 0) -+#define VDPU_REG_DEC_TIMEOUT_E(v) ((v) ? BIT(5) : 0) -+#define VDPU_REG_DEC_CLK_GATE_E(v) ((v) ? BIT(4) : 0) -+ -+#define VDPU_REG_PRED_BC_TAP_0_0(v) (((v) << 22) & GENMASK(31, 22)) -+#define VDPU_REG_PRED_BC_TAP_0_1(v) (((v) << 12) & GENMASK(21, 12)) -+#define VDPU_REG_PRED_BC_TAP_0_2(v) (((v) << 2) & GENMASK(11, 2)) -+ -+#define VDPU_REG_REFBU_E(v) ((v) ? BIT(31) : 0) -+ -+#define VDPU_REG_PINIT_RLIST_F9(v) (((v) << 25) & GENMASK(29, 25)) -+#define VDPU_REG_PINIT_RLIST_F8(v) (((v) << 20) & GENMASK(24, 20)) -+#define VDPU_REG_PINIT_RLIST_F7(v) (((v) << 15) & GENMASK(19, 15)) -+#define VDPU_REG_PINIT_RLIST_F6(v) (((v) << 10) & GENMASK(14, 10)) -+#define VDPU_REG_PINIT_RLIST_F5(v) (((v) << 5) & GENMASK(9, 5)) -+#define VDPU_REG_PINIT_RLIST_F4(v) (((v) << 0) & GENMASK(4, 0)) -+ -+#define VDPU_REG_PINIT_RLIST_F15(v) (((v) << 25) & GENMASK(29, 25)) -+#define VDPU_REG_PINIT_RLIST_F14(v) (((v) << 20) & GENMASK(24, 20)) -+#define VDPU_REG_PINIT_RLIST_F13(v) (((v) << 15) & GENMASK(19, 15)) -+#define VDPU_REG_PINIT_RLIST_F12(v) (((v) << 10) & GENMASK(14, 10)) -+#define VDPU_REG_PINIT_RLIST_F11(v) (((v) << 5) & GENMASK(9, 5)) -+#define VDPU_REG_PINIT_RLIST_F10(v) (((v) << 0) & GENMASK(4, 0)) -+ -+#define VDPU_REG_REFER1_NBR(v) (((v) << 16) & GENMASK(31, 16)) -+#define VDPU_REG_REFER0_NBR(v) (((v) << 0) & GENMASK(15, 0)) -+ -+#define VDPU_REG_REFER3_NBR(v) (((v) << 16) & GENMASK(31, 16)) -+#define VDPU_REG_REFER2_NBR(v) (((v) << 0) & GENMASK(15, 0)) -+ -+#define VDPU_REG_REFER5_NBR(v) (((v) << 16) & GENMASK(31, 16)) -+#define VDPU_REG_REFER4_NBR(v) (((v) << 0) & GENMASK(15, 0)) -+ -+#define VDPU_REG_REFER7_NBR(v) (((v) << 16) & GENMASK(31, 16)) -+#define VDPU_REG_REFER6_NBR(v) (((v) << 0) & GENMASK(15, 0)) -+ -+#define VDPU_REG_REFER9_NBR(v) (((v) << 16) & GENMASK(31, 16)) -+#define VDPU_REG_REFER8_NBR(v) (((v) << 0) & GENMASK(15, 0)) -+ -+#define VDPU_REG_REFER11_NBR(v) (((v) << 16) & GENMASK(31, 16)) -+#define VDPU_REG_REFER10_NBR(v) (((v) << 0) & GENMASK(15, 0)) -+ -+#define VDPU_REG_REFER13_NBR(v) (((v) << 16) & GENMASK(31, 16)) -+#define VDPU_REG_REFER12_NBR(v) (((v) << 0) & GENMASK(15, 0)) -+ -+#define VDPU_REG_REFER15_NBR(v) (((v) << 16) & GENMASK(31, 16)) -+#define VDPU_REG_REFER14_NBR(v) (((v) << 0) & GENMASK(15, 0)) -+ -+#define VDPU_REG_BINIT_RLIST_F5(v) (((v) << 25) & GENMASK(29, 25)) -+#define VDPU_REG_BINIT_RLIST_F4(v) (((v) << 20) & GENMASK(24, 20)) -+#define VDPU_REG_BINIT_RLIST_F3(v) (((v) << 15) & GENMASK(19, 15)) -+#define VDPU_REG_BINIT_RLIST_F2(v) (((v) << 10) & GENMASK(14, 10)) -+#define VDPU_REG_BINIT_RLIST_F1(v) (((v) << 5) & GENMASK(9, 5)) -+#define VDPU_REG_BINIT_RLIST_F0(v) (((v) << 0) & GENMASK(4, 0)) -+ -+#define VDPU_REG_BINIT_RLIST_F11(v) (((v) << 25) & GENMASK(29, 25)) -+#define VDPU_REG_BINIT_RLIST_F10(v) (((v) << 20) & GENMASK(24, 20)) -+#define VDPU_REG_BINIT_RLIST_F9(v) (((v) << 15) & GENMASK(19, 15)) -+#define VDPU_REG_BINIT_RLIST_F8(v) (((v) << 10) & GENMASK(14, 10)) -+#define VDPU_REG_BINIT_RLIST_F7(v) (((v) << 5) & GENMASK(9, 5)) -+#define VDPU_REG_BINIT_RLIST_F6(v) (((v) << 0) & GENMASK(4, 0)) -+ -+#define VDPU_REG_BINIT_RLIST_F15(v) (((v) << 15) & GENMASK(19, 15)) -+#define VDPU_REG_BINIT_RLIST_F14(v) (((v) << 10) & GENMASK(14, 10)) -+#define VDPU_REG_BINIT_RLIST_F13(v) (((v) << 5) & GENMASK(9, 5)) -+#define VDPU_REG_BINIT_RLIST_F12(v) (((v) << 0) & GENMASK(4, 0)) -+ -+#define VDPU_REG_BINIT_RLIST_B5(v) (((v) << 25) & GENMASK(29, 25)) -+#define VDPU_REG_BINIT_RLIST_B4(v) (((v) << 20) & GENMASK(24, 20)) -+#define VDPU_REG_BINIT_RLIST_B3(v) (((v) << 15) & GENMASK(19, 15)) -+#define VDPU_REG_BINIT_RLIST_B2(v) (((v) << 10) & GENMASK(14, 10)) -+#define VDPU_REG_BINIT_RLIST_B1(v) (((v) << 5) & GENMASK(9, 5)) -+#define VDPU_REG_BINIT_RLIST_B0(v) (((v) << 0) & GENMASK(4, 0)) -+ -+#define VDPU_REG_BINIT_RLIST_B11(v) (((v) << 25) & GENMASK(29, 25)) -+#define VDPU_REG_BINIT_RLIST_B10(v) (((v) << 20) & GENMASK(24, 20)) -+#define VDPU_REG_BINIT_RLIST_B9(v) (((v) << 15) & GENMASK(19, 15)) -+#define VDPU_REG_BINIT_RLIST_B8(v) (((v) << 10) & GENMASK(14, 10)) -+#define VDPU_REG_BINIT_RLIST_B7(v) (((v) << 5) & GENMASK(9, 5)) -+#define VDPU_REG_BINIT_RLIST_B6(v) (((v) << 0) & GENMASK(4, 0)) -+ -+#define VDPU_REG_BINIT_RLIST_B15(v) (((v) << 15) & GENMASK(19, 15)) -+#define VDPU_REG_BINIT_RLIST_B14(v) (((v) << 10) & GENMASK(14, 10)) -+#define VDPU_REG_BINIT_RLIST_B13(v) (((v) << 5) & GENMASK(9, 5)) -+#define VDPU_REG_BINIT_RLIST_B12(v) (((v) << 0) & GENMASK(4, 0)) -+ -+#define VDPU_REG_PINIT_RLIST_F3(v) (((v) << 15) & GENMASK(19, 15)) -+#define VDPU_REG_PINIT_RLIST_F2(v) (((v) << 10) & GENMASK(14, 10)) -+#define VDPU_REG_PINIT_RLIST_F1(v) (((v) << 5) & GENMASK(9, 5)) -+#define VDPU_REG_PINIT_RLIST_F0(v) (((v) << 0) & GENMASK(4, 0)) -+ -+#define VDPU_REG_REFER_LTERM_E(v) (((v) << 0) & GENMASK(31, 0)) -+ -+#define VDPU_REG_REFER_VALID_E(v) (((v) << 0) & GENMASK(31, 0)) -+ -+#define VDPU_REG_STRM_START_BIT(v) (((v) << 0) & GENMASK(5, 0)) -+ -+#define VDPU_REG_CH_QP_OFFSET2(v) (((v) << 22) & GENMASK(26, 22)) -+#define VDPU_REG_CH_QP_OFFSET(v) (((v) << 17) & GENMASK(21, 17)) -+#define VDPU_REG_PIC_MB_HEIGHT_P(v) (((v) << 9) & GENMASK(16, 9)) -+#define VDPU_REG_PIC_MB_WIDTH(v) (((v) << 0) & GENMASK(8, 0)) -+ -+#define VDPU_REG_WEIGHT_BIPR_IDC(v) (((v) << 16) & GENMASK(17, 16)) -+#define VDPU_REG_REF_FRAMES(v) (((v) << 0) & GENMASK(4, 0)) -+ -+#define VDPU_REG_FILT_CTRL_PRES(v) ((v) ? BIT(31) : 0) -+#define VDPU_REG_RDPIC_CNT_PRES(v) ((v) ? BIT(30) : 0) -+#define VDPU_REG_FRAMENUM_LEN(v) (((v) << 16) & GENMASK(20, 16)) -+#define VDPU_REG_FRAMENUM(v) (((v) << 0) & GENMASK(15, 0)) -+ -+#define VDPU_REG_REFPIC_MK_LEN(v) (((v) << 16) & GENMASK(26, 16)) -+#define VDPU_REG_IDR_PIC_ID(v) (((v) << 0) & GENMASK(15, 0)) -+ -+#define VDPU_REG_PPS_ID(v) (((v) << 24) & GENMASK(31, 24)) -+#define VDPU_REG_REFIDX1_ACTIVE(v) (((v) << 19) & GENMASK(23, 19)) -+#define VDPU_REG_REFIDX0_ACTIVE(v) (((v) << 14) & GENMASK(18, 14)) -+#define VDPU_REG_POC_LENGTH(v) (((v) << 0) & GENMASK(7, 0)) -+ -+#define VDPU_REG_IDR_PIC_E(v) ((v) ? BIT(8) : 0) -+#define VDPU_REG_DIR_8X8_INFER_E(v) ((v) ? BIT(7) : 0) -+#define VDPU_REG_BLACKWHITE_E(v) ((v) ? BIT(6) : 0) -+#define VDPU_REG_CABAC_E(v) ((v) ? BIT(5) : 0) -+#define VDPU_REG_WEIGHT_PRED_E(v) ((v) ? BIT(4) : 0) -+#define VDPU_REG_CONST_INTRA_E(v) ((v) ? BIT(3) : 0) -+#define VDPU_REG_8X8TRANS_FLAG_E(v) ((v) ? BIT(2) : 0) -+#define VDPU_REG_TYPE1_QUANT_E(v) ((v) ? BIT(1) : 0) -+#define VDPU_REG_FIELDPIC_FLAG_E(v) ((v) ? BIT(0) : 0) -+ -+static void set_params(struct hantro_ctx *ctx, struct vb2_v4l2_buffer *src_buf) -+{ -+ const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls; -+ const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode; -+ const struct v4l2_ctrl_h264_sps *sps = ctrls->sps; -+ const struct v4l2_ctrl_h264_pps *pps = ctrls->pps; -+ struct hantro_dev *vpu = ctx->dev; -+ u32 reg; -+ -+ reg = VDPU_REG_DEC_ADV_PRE_DIS(0) | -+ VDPU_REG_DEC_SCMD_DIS(0) | -+ VDPU_REG_FILTERING_DIS(0) | -+ VDPU_REG_PIC_FIXED_QUANT(0) | -+ VDPU_REG_DEC_LATENCY(0); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(50)); -+ -+ reg = VDPU_REG_INIT_QP(pps->pic_init_qp_minus26 + 26) | -+ VDPU_REG_STREAM_LEN(vb2_get_plane_payload(&src_buf->vb2_buf, 0)); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(51)); -+ -+ reg = VDPU_REG_APF_THRESHOLD(8) | -+ VDPU_REG_STARTMB_X(0) | -+ VDPU_REG_STARTMB_Y(0); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(52)); -+ -+ reg = VDPU_REG_DEC_MODE(0); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(53)); -+ -+ reg = VDPU_REG_DEC_STRENDIAN_E(1) | -+ VDPU_REG_DEC_STRSWAP32_E(1) | -+ VDPU_REG_DEC_OUTSWAP32_E(1) | -+ VDPU_REG_DEC_INSWAP32_E(1) | -+ VDPU_REG_DEC_OUT_ENDIAN(1) | -+ VDPU_REG_DEC_IN_ENDIAN(0); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(54)); -+ -+ reg = VDPU_REG_DEC_DATA_DISC_E(0) | -+ VDPU_REG_DEC_MAX_BURST(16) | -+ VDPU_REG_DEC_AXI_WR_ID(0) | -+ VDPU_REG_DEC_AXI_RD_ID(0xff); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(56)); -+ -+ reg = VDPU_REG_START_CODE_E(1) | -+ VDPU_REG_CH_8PIX_ILEAV_E(0) | -+ VDPU_REG_RLC_MODE_E(0) | -+ VDPU_REG_PIC_INTERLACE_E(!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) && -+ (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD || -+ dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC)) | -+ VDPU_REG_PIC_FIELDMODE_E(dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) | -+ VDPU_REG_PIC_TOPFIELD_E(!(dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD)) | -+ VDPU_REG_WRITE_MVS_E((sps->profile_idc > 66) && dec_param->nal_ref_idc) | -+ VDPU_REG_SEQ_MBAFF_E(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD) | -+ VDPU_REG_PICORD_COUNT_E(sps->profile_idc > 66) | -+ VDPU_REG_DEC_TIMEOUT_E(1) | -+ VDPU_REG_DEC_CLK_GATE_E(1); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(57)); -+ -+ reg = VDPU_REG_PRED_BC_TAP_0_0(1) | -+ VDPU_REG_PRED_BC_TAP_0_1((u32)-5) | -+ VDPU_REG_PRED_BC_TAP_0_2(20); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(59)); -+ -+ reg = VDPU_REG_REFBU_E(0); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(65)); -+ -+ reg = VDPU_REG_STRM_START_BIT(0); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(109)); -+ -+ reg = VDPU_REG_CH_QP_OFFSET2(pps->second_chroma_qp_index_offset) | -+ VDPU_REG_CH_QP_OFFSET(pps->chroma_qp_index_offset) | -+ VDPU_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->src_fmt.height)) | -+ VDPU_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->src_fmt.width)); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(110)); -+ -+ reg = VDPU_REG_WEIGHT_BIPR_IDC(pps->weighted_bipred_idc) | -+ VDPU_REG_REF_FRAMES(sps->max_num_ref_frames); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(111)); -+ -+ reg = VDPU_REG_FILT_CTRL_PRES(pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT) | -+ VDPU_REG_RDPIC_CNT_PRES(pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT) | -+ VDPU_REG_FRAMENUM_LEN(sps->log2_max_frame_num_minus4 + 4) | -+ VDPU_REG_FRAMENUM(dec_param->frame_num); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(112)); -+ -+ reg = VDPU_REG_REFPIC_MK_LEN(dec_param->dec_ref_pic_marking_bit_size) | -+ VDPU_REG_IDR_PIC_ID(dec_param->idr_pic_id); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(113)); -+ -+ reg = VDPU_REG_PPS_ID(pps->pic_parameter_set_id) | -+ VDPU_REG_REFIDX1_ACTIVE(pps->num_ref_idx_l1_default_active_minus1 + 1) | -+ VDPU_REG_REFIDX0_ACTIVE(pps->num_ref_idx_l0_default_active_minus1 + 1) | -+ VDPU_REG_POC_LENGTH(dec_param->pic_order_cnt_bit_size); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(114)); -+ -+ reg = VDPU_REG_IDR_PIC_E(dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC) | -+ VDPU_REG_DIR_8X8_INFER_E(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE) | -+ VDPU_REG_BLACKWHITE_E(sps->profile_idc >= 100 && sps->chroma_format_idc == 0) | -+ VDPU_REG_CABAC_E(pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE) | -+ VDPU_REG_WEIGHT_PRED_E(pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) | -+ VDPU_REG_CONST_INTRA_E(pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED) | -+ VDPU_REG_8X8TRANS_FLAG_E(pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE) | -+ VDPU_REG_TYPE1_QUANT_E(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT) | -+ VDPU_REG_FIELDPIC_FLAG_E(!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(115)); -+} -+ -+static void set_ref(struct hantro_ctx *ctx) -+{ -+ const u8 *b0_reflist, *b1_reflist, *p_reflist; -+ struct hantro_dev *vpu = ctx->dev; -+ u32 reg; -+ int i; -+ -+ b0_reflist = ctx->h264_dec.reflists.b0; -+ b1_reflist = ctx->h264_dec.reflists.b1; -+ p_reflist = ctx->h264_dec.reflists.p; -+ -+ reg = VDPU_REG_PINIT_RLIST_F9(p_reflist[9]) | -+ VDPU_REG_PINIT_RLIST_F8(p_reflist[8]) | -+ VDPU_REG_PINIT_RLIST_F7(p_reflist[7]) | -+ VDPU_REG_PINIT_RLIST_F6(p_reflist[6]) | -+ VDPU_REG_PINIT_RLIST_F5(p_reflist[5]) | -+ VDPU_REG_PINIT_RLIST_F4(p_reflist[4]); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(74)); -+ -+ reg = VDPU_REG_PINIT_RLIST_F15(p_reflist[15]) | -+ VDPU_REG_PINIT_RLIST_F14(p_reflist[14]) | -+ VDPU_REG_PINIT_RLIST_F13(p_reflist[13]) | -+ VDPU_REG_PINIT_RLIST_F12(p_reflist[12]) | -+ VDPU_REG_PINIT_RLIST_F11(p_reflist[11]) | -+ VDPU_REG_PINIT_RLIST_F10(p_reflist[10]); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(75)); -+ -+ reg = VDPU_REG_REFER1_NBR(hantro_h264_get_ref_nbr(ctx, 1)) | -+ VDPU_REG_REFER0_NBR(hantro_h264_get_ref_nbr(ctx, 0)); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(76)); -+ -+ reg = VDPU_REG_REFER3_NBR(hantro_h264_get_ref_nbr(ctx, 3)) | -+ VDPU_REG_REFER2_NBR(hantro_h264_get_ref_nbr(ctx, 2)); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(77)); -+ -+ reg = VDPU_REG_REFER5_NBR(hantro_h264_get_ref_nbr(ctx, 5)) | -+ VDPU_REG_REFER4_NBR(hantro_h264_get_ref_nbr(ctx, 4)); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(78)); -+ -+ reg = VDPU_REG_REFER7_NBR(hantro_h264_get_ref_nbr(ctx, 7)) | -+ VDPU_REG_REFER6_NBR(hantro_h264_get_ref_nbr(ctx, 6)); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(79)); -+ -+ reg = VDPU_REG_REFER9_NBR(hantro_h264_get_ref_nbr(ctx, 9)) | -+ VDPU_REG_REFER8_NBR(hantro_h264_get_ref_nbr(ctx, 8)); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(80)); -+ -+ reg = VDPU_REG_REFER11_NBR(hantro_h264_get_ref_nbr(ctx, 11)) | -+ VDPU_REG_REFER10_NBR(hantro_h264_get_ref_nbr(ctx, 10)); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(81)); -+ -+ reg = VDPU_REG_REFER13_NBR(hantro_h264_get_ref_nbr(ctx, 13)) | -+ VDPU_REG_REFER12_NBR(hantro_h264_get_ref_nbr(ctx, 12)); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(82)); -+ -+ reg = VDPU_REG_REFER15_NBR(hantro_h264_get_ref_nbr(ctx, 15)) | -+ VDPU_REG_REFER14_NBR(hantro_h264_get_ref_nbr(ctx, 14)); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(83)); -+ -+ reg = VDPU_REG_BINIT_RLIST_F5(b0_reflist[5]) | -+ VDPU_REG_BINIT_RLIST_F4(b0_reflist[4]) | -+ VDPU_REG_BINIT_RLIST_F3(b0_reflist[3]) | -+ VDPU_REG_BINIT_RLIST_F2(b0_reflist[2]) | -+ VDPU_REG_BINIT_RLIST_F1(b0_reflist[1]) | -+ VDPU_REG_BINIT_RLIST_F0(b0_reflist[0]); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(100)); -+ -+ reg = VDPU_REG_BINIT_RLIST_F11(b0_reflist[11]) | -+ VDPU_REG_BINIT_RLIST_F10(b0_reflist[10]) | -+ VDPU_REG_BINIT_RLIST_F9(b0_reflist[9]) | -+ VDPU_REG_BINIT_RLIST_F8(b0_reflist[8]) | -+ VDPU_REG_BINIT_RLIST_F7(b0_reflist[7]) | -+ VDPU_REG_BINIT_RLIST_F6(b0_reflist[6]); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(101)); -+ -+ reg = VDPU_REG_BINIT_RLIST_F15(b0_reflist[15]) | -+ VDPU_REG_BINIT_RLIST_F14(b0_reflist[14]) | -+ VDPU_REG_BINIT_RLIST_F13(b0_reflist[13]) | -+ VDPU_REG_BINIT_RLIST_F12(b0_reflist[12]); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(102)); -+ -+ reg = VDPU_REG_BINIT_RLIST_B5(b1_reflist[5]) | -+ VDPU_REG_BINIT_RLIST_B4(b1_reflist[4]) | -+ VDPU_REG_BINIT_RLIST_B3(b1_reflist[3]) | -+ VDPU_REG_BINIT_RLIST_B2(b1_reflist[2]) | -+ VDPU_REG_BINIT_RLIST_B1(b1_reflist[1]) | -+ VDPU_REG_BINIT_RLIST_B0(b1_reflist[0]); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(103)); -+ -+ reg = VDPU_REG_BINIT_RLIST_B11(b1_reflist[11]) | -+ VDPU_REG_BINIT_RLIST_B10(b1_reflist[10]) | -+ VDPU_REG_BINIT_RLIST_B9(b1_reflist[9]) | -+ VDPU_REG_BINIT_RLIST_B8(b1_reflist[8]) | -+ VDPU_REG_BINIT_RLIST_B7(b1_reflist[7]) | -+ VDPU_REG_BINIT_RLIST_B6(b1_reflist[6]); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(104)); -+ -+ reg = VDPU_REG_BINIT_RLIST_B15(b1_reflist[15]) | -+ VDPU_REG_BINIT_RLIST_B14(b1_reflist[14]) | -+ VDPU_REG_BINIT_RLIST_B13(b1_reflist[13]) | -+ VDPU_REG_BINIT_RLIST_B12(b1_reflist[12]); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(105)); -+ -+ reg = VDPU_REG_PINIT_RLIST_F3(p_reflist[3]) | -+ VDPU_REG_PINIT_RLIST_F2(p_reflist[2]) | -+ VDPU_REG_PINIT_RLIST_F1(p_reflist[1]) | -+ VDPU_REG_PINIT_RLIST_F0(p_reflist[0]); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(106)); -+ -+ reg = VDPU_REG_REFER_LTERM_E(ctx->h264_dec.dpb_longterm); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(107)); -+ -+ reg = VDPU_REG_REFER_VALID_E(ctx->h264_dec.dpb_valid); -+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(108)); -+ -+ /* Set up addresses of DPB buffers. */ -+ for (i = 0; i < HANTRO_H264_DPB_SIZE; i++) { -+ dma_addr_t dma_addr = hantro_h264_get_ref_buf(ctx, i); -+ -+ vdpu_write_relaxed(vpu, dma_addr, VDPU_REG_REFER_BASE(i)); -+ } -+} -+ -+static void set_buffers(struct hantro_ctx *ctx, struct vb2_v4l2_buffer *src_buf) -+{ -+ const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls; -+ struct vb2_v4l2_buffer *dst_buf; -+ struct hantro_dev *vpu = ctx->dev; -+ dma_addr_t src_dma, dst_dma; -+ size_t offset = 0; -+ -+ /* Source (stream) buffer. */ -+ src_dma = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); -+ vdpu_write_relaxed(vpu, src_dma, VDPU_REG_RLC_VLC_BASE); -+ -+ /* Destination (decoded frame) buffer. */ -+ dst_buf = hantro_get_dst_buf(ctx); -+ dst_dma = hantro_get_dec_buf_addr(ctx, &dst_buf->vb2_buf); -+ /* Adjust dma addr to start at second line for bottom field */ -+ if (ctrls->decode->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) -+ offset = ALIGN(ctx->src_fmt.width, MB_DIM); -+ vdpu_write_relaxed(vpu, dst_dma + offset, VDPU_REG_DEC_OUT_BASE); -+ -+ /* Higher profiles require DMV buffer appended to reference frames. */ -+ if (ctrls->sps->profile_idc > 66 && ctrls->decode->nal_ref_idc) { -+ unsigned int bytes_per_mb = 384; -+ -+ /* DMV buffer for monochrome start directly after Y-plane */ -+ if (ctrls->sps->profile_idc >= 100 && -+ ctrls->sps->chroma_format_idc == 0) -+ bytes_per_mb = 256; -+ offset = bytes_per_mb * MB_WIDTH(ctx->src_fmt.width) * -+ MB_HEIGHT(ctx->src_fmt.height); -+ -+ /* -+ * DMV buffer is split in two for field encoded frames, -+ * adjust offset for bottom field -+ */ -+ if (ctrls->decode->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) -+ offset += 32 * MB_WIDTH(ctx->src_fmt.width) * -+ MB_HEIGHT(ctx->src_fmt.height); -+ vdpu_write_relaxed(vpu, dst_dma + offset, VDPU_REG_DIR_MV_BASE); -+ } -+ -+ /* Auxiliary buffer prepared in hantro_g1_h264_dec_prepare_table(). */ -+ vdpu_write_relaxed(vpu, ctx->h264_dec.priv.dma, VDPU_REG_QTABLE_BASE); -+} -+ -+int rockchip_vpu2_h264_dec_run(struct hantro_ctx *ctx) -+{ -+ struct hantro_dev *vpu = ctx->dev; -+ struct vb2_v4l2_buffer *src_buf; -+ u32 reg; -+ int ret; -+ -+ /* Prepare the H264 decoder context. */ -+ ret = hantro_h264_dec_prepare_run(ctx); -+ if (ret) -+ return ret; -+ -+ src_buf = hantro_get_src_buf(ctx); -+ set_params(ctx, src_buf); -+ set_ref(ctx); -+ set_buffers(ctx, src_buf); -+ -+ hantro_end_prepare_run(ctx); -+ -+ /* Start decoding! */ -+ reg = vdpu_read(vpu, VDPU_SWREG(57)) | VDPU_REG_DEC_E(1); -+ vdpu_write(vpu, reg, VDPU_SWREG(57)); -+ -+ return 0; -+} - -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Mon, 19 Jul 2021 22:52:39 +0200 -Subject: [PATCH] media: hantro: Enable H.264 on Rockchip VDPU2 - -Given H.264 support for VDPU2 was just added, let's enable it. -For now, this is only enabled on platform that don't have -an RKVDEC core, such as RK3328. - -Signed-off-by: Ezequiel Garcia -Tested-by: Alex Bee -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - .../staging/media/hantro/rockchip_vpu_hw.c | 26 ++++++++++++++++++- - 1 file changed, 25 insertions(+), 1 deletion(-) - -diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c -index 3ccc16413f42..e4e3b5e7689b 100644 ---- a/drivers/staging/media/hantro/rockchip_vpu_hw.c -+++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c -@@ -162,6 +162,19 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { - .fourcc = V4L2_PIX_FMT_NV12, - .codec_mode = HANTRO_MODE_NONE, - }, -+ { -+ .fourcc = V4L2_PIX_FMT_H264_SLICE, -+ .codec_mode = HANTRO_MODE_H264_DEC, -+ .max_depth = 2, -+ .frmsize = { -+ .min_width = 48, -+ .max_width = 1920, -+ .step_width = MB_DIM, -+ .min_height = 48, -+ .max_height = 1088, -+ .step_height = MB_DIM, -+ }, -+ }, - { - .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, - .codec_mode = HANTRO_MODE_MPEG2_DEC, -@@ -388,6 +401,12 @@ static const struct hantro_codec_ops rk3399_vpu_codec_ops[] = { - .init = hantro_jpeg_enc_init, - .exit = hantro_jpeg_enc_exit, - }, -+ [HANTRO_MODE_H264_DEC] = { -+ .run = rockchip_vpu2_h264_dec_run, -+ .reset = rockchip_vpu2_dec_reset, -+ .init = hantro_h264_dec_init, -+ .exit = hantro_h264_dec_exit, -+ }, - [HANTRO_MODE_MPEG2_DEC] = { - .run = rockchip_vpu2_mpeg2_dec_run, - .reset = rockchip_vpu2_dec_reset, -@@ -433,6 +452,8 @@ static const char * const rockchip_vpu_clk_names[] = { - "aclk", "hclk" - }; - -+/* VDPU1/VEPU1 */ -+ - const struct hantro_variant rk3036_vpu_variant = { - .dec_offset = 0x400, - .dec_fmts = rk3066_vpu_dec_fmts, -@@ -495,11 +516,14 @@ const struct hantro_variant rk3288_vpu_variant = { - .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names) - }; - -+/* VDPU2/VEPU2 */ -+ - const struct hantro_variant rk3328_vpu_variant = { - .dec_offset = 0x400, - .dec_fmts = rk3399_vpu_dec_fmts, - .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), -- .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER, -+ .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER | -+ HANTRO_H264_DECODER, - .codec_ops = rk3399_vpu_codec_ops, - .irqs = rockchip_vdpu2_irqs, - .num_irqs = ARRAY_SIZE(rockchip_vdpu2_irqs), - -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Kocialkowski -Date: Mon, 19 Jul 2021 22:52:41 +0200 -Subject: [PATCH] media: dt-bindings: media: rockchip-vpu: Add PX30 compatible - -The Rockchip PX30 SoC has a Hantro VPU that features a decoder (VDPU2) -and an encoder (VEPU2). - -Suggested-by: Alex Bee -Signed-off-by: Paul Kocialkowski -Signed-off-by: Ezequiel Garcia -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - Documentation/devicetree/bindings/media/rockchip-vpu.yaml | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml -index b88172a59de7..bacb60a34989 100644 ---- a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml -+++ b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml -@@ -22,6 +22,7 @@ properties: - - rockchip,rk3288-vpu - - rockchip,rk3328-vpu - - rockchip,rk3399-vpu -+ - rockchip,px30-vpu - - items: - - const: rockchip,rk3188-vpu - - const: rockchip,rk3066-vpu - -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Kocialkowski -Date: Mon, 19 Jul 2021 22:52:40 +0200 -Subject: [PATCH] media: hantro: Add support for the Rockchip PX30 - -The PX30 SoC includes both the VDPU2 and VEPU2 blocks which are similar -to the RK3399 (Hantro G1/H1 with shuffled registers). - -Signed-off-by: Paul Kocialkowski -Signed-off-by: Ezequiel Garcia -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/staging/media/hantro/hantro_drv.c | 1 + - drivers/staging/media/hantro/hantro_hw.h | 1 + - drivers/staging/media/hantro/rockchip_vpu_hw.c | 17 +++++++++++++++++ - 3 files changed, 19 insertions(+) - -diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c -index 9b5415176bfe..8a2edd67f2c6 100644 ---- a/drivers/staging/media/hantro/hantro_drv.c -+++ b/drivers/staging/media/hantro/hantro_drv.c -@@ -582,6 +582,7 @@ static const struct v4l2_file_operations hantro_fops = { - - static const struct of_device_id of_hantro_match[] = { - #ifdef CONFIG_VIDEO_HANTRO_ROCKCHIP -+ { .compatible = "rockchip,px30-vpu", .data = &px30_vpu_variant, }, - { .compatible = "rockchip,rk3036-vpu", .data = &rk3036_vpu_variant, }, - { .compatible = "rockchip,rk3066-vpu", .data = &rk3066_vpu_variant, }, - { .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, }, -diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h -index 9296624654a6..df7b5e3a57b9 100644 ---- a/drivers/staging/media/hantro/hantro_hw.h -+++ b/drivers/staging/media/hantro/hantro_hw.h -@@ -209,6 +209,7 @@ enum hantro_enc_fmt { - - extern const struct hantro_variant imx8mq_vpu_g2_variant; - extern const struct hantro_variant imx8mq_vpu_variant; -+extern const struct hantro_variant px30_vpu_variant; - extern const struct hantro_variant rk3036_vpu_variant; - extern const struct hantro_variant rk3066_vpu_variant; - extern const struct hantro_variant rk3288_vpu_variant; -diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c -index e4e3b5e7689b..d4f52957cc53 100644 ---- a/drivers/staging/media/hantro/rockchip_vpu_hw.c -+++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c -@@ -548,3 +548,20 @@ const struct hantro_variant rk3399_vpu_variant = { - .clk_names = rockchip_vpu_clk_names, - .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names) - }; -+ -+const struct hantro_variant px30_vpu_variant = { -+ .enc_offset = 0x0, -+ .enc_fmts = rockchip_vpu_enc_fmts, -+ .num_enc_fmts = ARRAY_SIZE(rockchip_vpu_enc_fmts), -+ .dec_offset = 0x400, -+ .dec_fmts = rk3399_vpu_dec_fmts, -+ .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), -+ .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER | -+ HANTRO_VP8_DECODER | HANTRO_H264_DECODER, -+ .codec_ops = rk3399_vpu_codec_ops, -+ .irqs = rockchip_vpu2_irqs, -+ .num_irqs = ARRAY_SIZE(rockchip_vpu2_irqs), -+ .init = rk3036_vpu_hw_init, -+ .clk_names = rockchip_vpu_clk_names, -+ .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names) -+}; diff --git a/projects/Rockchip/patches/linux/default/linux-2001-v4l-wip-rkvdec-hevc.patch b/projects/Rockchip/patches/linux/default/linux-2001-v4l-wip-rkvdec-hevc.patch index 6c72bcb544..e60383eaf2 100644 --- a/projects/Rockchip/patches/linux/default/linux-2001-v4l-wip-rkvdec-hevc.patch +++ b/projects/Rockchip/patches/linux/default/linux-2001-v4l-wip-rkvdec-hevc.patch @@ -189,56 +189,6 @@ index 53c0038c792b..0e5c4a2eecff 100644 #define V4L2_CID_CODEC_HANTRO_BASE (V4L2_CTRL_CLASS_CODEC | 0x1200) /* -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sun, 6 Jun 2021 10:23:13 +0200 -Subject: [PATCH] media: hevc: Add segment address field - -If HEVC frame consists of multiple slices, segment address has to be -known in order to properly decode it. - -Add segment address field to slice parameters. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 3 +++ - include/media/hevc-ctrls.h | 3 ++- - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -index dc08368d62fe..9b25674fcd40 100644 ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -3000,6 +3000,9 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - - * - __u8 - - ``pic_struct`` - - -+ * - __u32 -+ - ``slice_segment_addr`` -+ - - * - __u8 - - ``ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` - - The list of L0 reference elements as indices in the DPB. -diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h -index 0e5c4a2eecff..ef63bc205756 100644 ---- a/include/media/hevc-ctrls.h -+++ b/include/media/hevc-ctrls.h -@@ -198,10 +198,11 @@ struct v4l2_ctrl_hevc_slice_params { - __u8 pic_struct; - - /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ -+ __u32 slice_segment_addr; - __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - -- __u8 padding[5]; -+ __u8 padding; - - /* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */ - struct v4l2_hevc_pred_weight_table pred_weight_table; - From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 23 May 2020 15:03:46 +0000