mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-08-03 16:07:51 +00:00
linux (Allwinner): update patches for 5.13
This commit is contained in:
parent
1bfef8cc23
commit
e198af10b6
@ -37,10 +37,6 @@ esac
|
||||
|
||||
PKG_KERNEL_CFG_FILE=$(kernel_config_path) || die
|
||||
|
||||
if listcontains "${UBOOT_FIRMWARE}" "crust"; then
|
||||
PKG_PATCH_DIRS+=" crust"
|
||||
fi
|
||||
|
||||
if [ -n "${KERNEL_TOOLCHAIN}" ]; then
|
||||
PKG_DEPENDS_HOST+=" gcc-arm-${KERNEL_TOOLCHAIN}:host"
|
||||
PKG_DEPENDS_TARGET+=" gcc-arm-${KERNEL_TOOLCHAIN}:host"
|
||||
|
@ -1,26 +0,0 @@
|
||||
From 4cc652f2c660bd01bd0d8cefde272400cbe82fbe Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 16 Jan 2021 11:32:04 +0100
|
||||
Subject: [PATCH 1/2] ARM: dts: sun8i: h2-plus: bananapi-m2-zero: Increase BT
|
||||
UART speed
|
||||
|
||||
Bluetooth module on BananaPi M2 Zero can also be used for streaming
|
||||
audio. However, for that case higher UART speed is required.
|
||||
|
||||
Add a max-speed property.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts
|
||||
@@ -125,6 +125,7 @@
|
||||
|
||||
bluetooth {
|
||||
compatible = "brcm,bcm43438-bt";
|
||||
+ max-speed = <1500000>;
|
||||
clocks = <&rtc 1>;
|
||||
clock-names = "lpo";
|
||||
vbat-supply = <®_vcc3v3>;
|
@ -1,51 +0,0 @@
|
||||
From aa47c3b292cb0ffcf2c00b2a12c477ec3027a729 Mon Sep 17 00:00:00 2001
|
||||
From: PJBrs <pjbrs@floorenpj.xs4all.nl>
|
||||
Date: Sat, 16 Jan 2021 11:39:45 +0100
|
||||
Subject: [PATCH 2/2] ARM: dts: sunxi: h2-plus-bananapi-m2-zero: Add HDMI out
|
||||
|
||||
Add HDMI out, including the display engine, to the BananaPi M2 Zero.
|
||||
---
|
||||
.../dts/sun8i-h2-plus-bananapi-m2-zero.dts | 25 +++++++++++++++++++
|
||||
1 file changed, 25 insertions(+)
|
||||
|
||||
--- a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts
|
||||
@@ -26,6 +26,17 @@
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
+ connector {
|
||||
+ compatible = "hdmi-connector";
|
||||
+ type = "a";
|
||||
+
|
||||
+ port {
|
||||
+ hdmi_con_in: endpoint {
|
||||
+ remote-endpoint = <&hdmi_out_con>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
@@ -107,6 +118,20 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&de {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi_out {
|
||||
+ hdmi_out_con: endpoint {
|
||||
+ remote-endpoint = <&hdmi_con_in>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&ohci0 {
|
||||
status = "okay";
|
||||
};
|
@ -1,25 +0,0 @@
|
||||
From 54b5c2cb4fc87ca72daa662423d4d969f3b5edb8 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 16 Jan 2021 11:49:57 +0100
|
||||
Subject: [PATCH] ARM: dts: sunxi: bananapi-m2-plus: Increase BT UART speed
|
||||
|
||||
Bluetooth module on BananaPi M2 Plus can also be used for streaming
|
||||
audio. However, for that case higher UART speed is required.
|
||||
|
||||
Add a max-speed property.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi
|
||||
@@ -219,6 +219,7 @@
|
||||
|
||||
bluetooth {
|
||||
compatible = "brcm,bcm43438-bt";
|
||||
+ max-speed = <1500000>;
|
||||
clocks = <&rtc 1>;
|
||||
clock-names = "lpo";
|
||||
vbat-supply = <®_vcc3v3>;
|
@ -35,7 +35,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
soc {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
@@ -652,7 +670,6 @@
|
||||
@@ -655,7 +673,6 @@
|
||||
dmas = <&dma 4>, <&dma 4>;
|
||||
resets = <&ccu RST_BUS_I2S1>;
|
||||
dma-names = "rx", "tx";
|
||||
@ -43,7 +43,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
};
|
||||
|
||||
spdif: spdif@5093000 {
|
||||
@@ -785,6 +802,7 @@
|
||||
@@ -792,6 +809,7 @@
|
||||
};
|
||||
|
||||
hdmi: hdmi@6000000 {
|
||||
|
@ -22,7 +22,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
||||
@@ -549,12 +549,10 @@ static int sun8i_dwmac_init(struct platf
|
||||
@@ -571,12 +571,10 @@ static int sun8i_dwmac_init(struct platf
|
||||
struct sunxi_priv_data *gmac = priv;
|
||||
int ret;
|
||||
|
||||
@ -39,7 +39,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(gmac->tx_clk);
|
||||
@@ -1021,8 +1019,7 @@ static void sun8i_dwmac_exit(struct plat
|
||||
@@ -1045,8 +1043,7 @@ static void sun8i_dwmac_exit(struct plat
|
||||
|
||||
clk_disable_unprepare(gmac->tx_clk);
|
||||
|
||||
@ -49,7 +49,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
}
|
||||
|
||||
static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
|
||||
@@ -1150,12 +1147,12 @@ static int sun8i_dwmac_probe(struct plat
|
||||
@@ -1174,12 +1171,12 @@ static int sun8i_dwmac_probe(struct plat
|
||||
}
|
||||
|
||||
/* Optional regulator for PHY */
|
||||
|
@ -47,7 +47,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
struct reset_control *rst_ephy;
|
||||
const struct emac_variant *variant;
|
||||
struct regmap_field *regmap_field;
|
||||
@@ -549,9 +551,9 @@ static int sun8i_dwmac_init(struct platf
|
||||
@@ -571,9 +573,9 @@ static int sun8i_dwmac_init(struct platf
|
||||
struct sunxi_priv_data *gmac = priv;
|
||||
int ret;
|
||||
|
||||
@ -59,7 +59,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -572,8 +574,7 @@ static int sun8i_dwmac_init(struct platf
|
||||
@@ -594,8 +596,7 @@ static int sun8i_dwmac_init(struct platf
|
||||
err_disable_clk:
|
||||
clk_disable_unprepare(gmac->tx_clk);
|
||||
err_disable_regulator:
|
||||
@ -69,7 +69,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1019,7 +1020,7 @@ static void sun8i_dwmac_exit(struct plat
|
||||
@@ -1043,7 +1044,7 @@ static void sun8i_dwmac_exit(struct plat
|
||||
|
||||
clk_disable_unprepare(gmac->tx_clk);
|
||||
|
||||
@ -78,7 +78,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
}
|
||||
|
||||
static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
|
||||
@@ -1147,11 +1148,9 @@ static int sun8i_dwmac_probe(struct plat
|
||||
@@ -1171,11 +1172,9 @@ static int sun8i_dwmac_probe(struct plat
|
||||
}
|
||||
|
||||
/* Optional regulator for PHY */
|
||||
|
@ -34,7 +34,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
struct reset_control *rst_ephy;
|
||||
const struct emac_variant *variant;
|
||||
struct regmap_field *regmap_field;
|
||||
@@ -551,10 +554,16 @@ static int sun8i_dwmac_init(struct platf
|
||||
@@ -573,10 +576,16 @@ static int sun8i_dwmac_init(struct platf
|
||||
struct sunxi_priv_data *gmac = priv;
|
||||
int ret;
|
||||
|
||||
@ -52,7 +52,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(gmac->tx_clk);
|
||||
@@ -575,6 +584,8 @@ err_disable_clk:
|
||||
@@ -597,6 +606,8 @@ err_disable_clk:
|
||||
clk_disable_unprepare(gmac->tx_clk);
|
||||
err_disable_regulator:
|
||||
regulator_disable(gmac->regulator_phy);
|
||||
@ -61,7 +61,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1021,6 +1032,7 @@ static void sun8i_dwmac_exit(struct plat
|
||||
@@ -1045,6 +1056,7 @@ static void sun8i_dwmac_exit(struct plat
|
||||
clk_disable_unprepare(gmac->tx_clk);
|
||||
|
||||
regulator_disable(gmac->regulator_phy);
|
||||
@ -69,7 +69,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
}
|
||||
|
||||
static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
|
||||
@@ -1154,6 +1166,15 @@ static int sun8i_dwmac_probe(struct plat
|
||||
@@ -1178,6 +1190,15 @@ static int sun8i_dwmac_probe(struct plat
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
&mmc0 {
|
||||
vmmc-supply = <®_cldo1>;
|
||||
cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
|
||||
@@ -207,6 +246,7 @@
|
||||
@@ -211,6 +250,7 @@
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-name = "vcc33-audio-tv-ephy-mac";
|
||||
|
@ -28,7 +28,7 @@ Reviewed-by: Chen-Yu Tsai <wens@csie.org>
|
||||
&emac {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&ext_rgmii_pins>;
|
||||
@@ -331,3 +335,8 @@
|
||||
@@ -332,3 +336,8 @@
|
||||
usb3_vbus-supply = <®_usb_vbus>;
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -76,7 +76,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
/omit-if-no-ref/
|
||||
spi0_pins: spi0-pins {
|
||||
pins = "PC0", "PC2", "PC3";
|
||||
@@ -640,6 +671,31 @@
|
||||
@@ -643,6 +674,31 @@
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
|
@ -37,7 +37,7 @@ Signed-off-by: Alejandro González <alejandro.gonzalez.correo@gmail.com>
|
||||
|
||||
--- a/drivers/mmc/host/sunxi-mmc.c
|
||||
+++ b/drivers/mmc/host/sunxi-mmc.c
|
||||
@@ -1398,14 +1398,17 @@ static int sunxi_mmc_probe(struct platfo
|
||||
@@ -1421,14 +1421,17 @@ static int sunxi_mmc_probe(struct platfo
|
||||
|
||||
/*
|
||||
* Some H5 devices do not have signal traces precise enough to
|
||||
|
@ -1,45 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Thu, 29 Oct 2020 21:04:24 +0100
|
||||
Subject: [PATCH] pineh64 model b - bluetooth wip
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
.../dts/allwinner/sun50i-h6-pine-h64-model-b.dts | 16 ++++++++++++++++
|
||||
drivers/bluetooth/hci_h5.c | 3 +++
|
||||
2 files changed, 19 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts
|
||||
@@ -34,3 +34,19 @@
|
||||
non-removable;
|
||||
status = "okay";
|
||||
};
|
||||
+
|
||||
+&uart1 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
|
||||
+ uart-has-rtscts;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ bluetooth {
|
||||
+ compatible = "realtek,rtl8723bs-bt";
|
||||
+ device-wakeup-gpios = <&r_pio 1 2 GPIO_ACTIVE_HIGH>; /* PM2 */
|
||||
+ host-wakeup-gpios = <&r_pio 1 1 GPIO_ACTIVE_HIGH>; /* PM1 */
|
||||
+ enable-gpios = <&r_pio 1 4 GPIO_ACTIVE_HIGH>; /* PM4 */
|
||||
+ firmware-postfix = "OBDA8723";
|
||||
+ max-speed = <1500000>;
|
||||
+ };
|
||||
+};
|
||||
--- a/drivers/bluetooth/hci_h5.c
|
||||
+++ b/drivers/bluetooth/hci_h5.c
|
||||
@@ -820,6 +820,9 @@ static int h5_serdev_probe(struct serdev
|
||||
if (!data)
|
||||
return -ENODEV;
|
||||
|
||||
+ of_property_read_string(dev->of_node,
|
||||
+ "firmware-postfix", &h5->id);
|
||||
+
|
||||
h5->vnd = (const struct h5_vnd *)data;
|
||||
}
|
||||
|
@ -29,11 +29,9 @@ Bluetooth: hci0: RTL: loading rtl_bt/rtl8822cs_config.bin
|
||||
.../dts/allwinner/sun50i-h6-tanix-tx6.dts | 32 +++++++++++++++++++
|
||||
1 file changed, 48 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts
|
||||
index 5233ad1488..06e7820fd9 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts
|
||||
@@ -47,12 +47,29 @@ reg_vcc3v3: vcc3v3 {
|
||||
@@ -47,12 +47,29 @@
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
@ -63,7 +61,7 @@ index 5233ad1488..06e7820fd9 100644
|
||||
};
|
||||
|
||||
&ac200_pwm_clk {
|
||||
@@ -122,6 +139,22 @@ &mmc0 {
|
||||
@@ -122,6 +139,22 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@ -86,7 +84,7 @@ index 5233ad1488..06e7820fd9 100644
|
||||
&mmc2 {
|
||||
vmmc-supply = <®_vcc3v3>;
|
||||
vqmmc-supply = <®_vcc1v8>;
|
||||
@@ -158,6 +191,21 @@ &uart0 {
|
||||
@@ -158,6 +191,21 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@ -108,6 +106,3 @@ index 5233ad1488..06e7820fd9 100644
|
||||
&usb2otg {
|
||||
dr_mode = "host";
|
||||
status = "okay";
|
||||
--
|
||||
2.29.2
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,40 +0,0 @@
|
||||
From 9a7e6c2d8a18a24b013c1ad165ed04bb7d2c7716 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Tue, 25 Aug 2020 19:35:22 +0200
|
||||
Subject: [PATCH 01/44] media: cedrus: Add support for R40
|
||||
|
||||
Video engine in R40 is very similar to that in A33 but it runs on lower
|
||||
speed, at least according to OS images released by board designer.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
Link: https://lore.kernel.org/r/20200825173523.1289379-5-jernej.skrabec@siol.net
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
@@ -508,6 +508,11 @@ static const struct cedrus_variant sun8i
|
||||
.mod_rate = 402000000,
|
||||
};
|
||||
|
||||
+static const struct cedrus_variant sun8i_r40_cedrus_variant = {
|
||||
+ .capabilities = CEDRUS_CAPABILITY_UNTILED,
|
||||
+ .mod_rate = 297000000,
|
||||
+};
|
||||
+
|
||||
static const struct cedrus_variant sun50i_a64_cedrus_variant = {
|
||||
.capabilities = CEDRUS_CAPABILITY_UNTILED |
|
||||
CEDRUS_CAPABILITY_H265_DEC,
|
||||
@@ -549,6 +554,10 @@ static const struct of_device_id cedrus_
|
||||
.data = &sun8i_h3_cedrus_variant,
|
||||
},
|
||||
{
|
||||
+ .compatible = "allwinner,sun8i-r40-video-engine",
|
||||
+ .data = &sun8i_r40_cedrus_variant,
|
||||
+ },
|
||||
+ {
|
||||
.compatible = "allwinner,sun50i-a64-video-engine",
|
||||
.data = &sun50i_a64_cedrus_variant,
|
||||
},
|
@ -139,8 +139,8 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
return rc;
|
||||
--- a/drivers/clk/clk.c
|
||||
+++ b/drivers/clk/clk.c
|
||||
@@ -4188,6 +4188,37 @@ void devm_clk_hw_unregister(struct devic
|
||||
EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
|
||||
@@ -4271,6 +4271,37 @@ struct clk *devm_clk_hw_get_clk(struct d
|
||||
EXPORT_SYMBOL_GPL(devm_clk_hw_get_clk);
|
||||
|
||||
/*
|
||||
+ * clk-conf helpers
|
@ -1,99 +0,0 @@
|
||||
From f710d6403b7716d7a5319e51c4cb3c217ec85b73 Mon Sep 17 00:00:00 2001
|
||||
From: Sean Young <sean@mess.org>
|
||||
Date: Tue, 10 Nov 2020 09:30:38 +0100
|
||||
Subject: [PATCH 02/44] media: sunxi-cir: allow timeout to be set at runtime
|
||||
|
||||
This allows the timeout to be set with the LIRC_SET_REC_TIMEOUT ioctl.
|
||||
|
||||
The timeout was hardcoded at just over 20ms, but returned 120ms when
|
||||
queried with the LIRC_GET_REC_TIMEOUT ioctl.
|
||||
|
||||
This also ensures the idle threshold is set correctly with a base clock
|
||||
other than 8Mhz.
|
||||
|
||||
Acked-by: Maxime Ripard <mripard@kernel.org>
|
||||
Signed-off-by: Sean Young <sean@mess.org>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
|
||||
---
|
||||
drivers/media/rc/sunxi-cir.c | 48 ++++++++++++++++++++++++++++++------
|
||||
1 file changed, 40 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/media/rc/sunxi-cir.c
|
||||
+++ b/drivers/media/rc/sunxi-cir.c
|
||||
@@ -73,10 +73,6 @@
|
||||
#define SUNXI_IR_BASE_CLK 8000000
|
||||
/* Noise threshold in samples */
|
||||
#define SUNXI_IR_RXNOISE 1
|
||||
-/* Idle Threshold in samples */
|
||||
-#define SUNXI_IR_RXIDLE 20
|
||||
-/* Time after which device stops sending data in ms */
|
||||
-#define SUNXI_IR_TIMEOUT 120
|
||||
|
||||
/**
|
||||
* struct sunxi_ir_quirks - Differences between SoC variants.
|
||||
@@ -146,6 +142,41 @@ static irqreturn_t sunxi_ir_irq(int irqn
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+/* Convert idle threshold to usec */
|
||||
+static unsigned int sunxi_ithr_to_usec(unsigned int base_clk, unsigned int ithr)
|
||||
+{
|
||||
+ return DIV_ROUND_CLOSEST(USEC_PER_SEC * (ithr + 1),
|
||||
+ base_clk / (128 * 64));
|
||||
+}
|
||||
+
|
||||
+/* Convert usec to idle threshold */
|
||||
+static unsigned int sunxi_usec_to_ithr(unsigned int base_clk, unsigned int usec)
|
||||
+{
|
||||
+ /* make sure we don't end up with a timeout less than requested */
|
||||
+ return DIV_ROUND_UP((base_clk / (128 * 64)) * usec, USEC_PER_SEC) - 1;
|
||||
+}
|
||||
+
|
||||
+static int sunxi_ir_set_timeout(struct rc_dev *rc_dev, unsigned int timeout)
|
||||
+{
|
||||
+ struct sunxi_ir *ir = rc_dev->priv;
|
||||
+ unsigned int base_clk = clk_get_rate(ir->clk);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ unsigned int ithr = sunxi_usec_to_ithr(base_clk, timeout);
|
||||
+
|
||||
+ dev_dbg(rc_dev->dev.parent, "setting idle threshold to %u\n", ithr);
|
||||
+
|
||||
+ spin_lock_irqsave(&ir->ir_lock, flags);
|
||||
+ /* Set noise threshold and idle threshold */
|
||||
+ writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE) | REG_CIR_ITHR(ithr),
|
||||
+ ir->base + SUNXI_IR_CIR_REG);
|
||||
+ spin_unlock_irqrestore(&ir->ir_lock, flags);
|
||||
+
|
||||
+ rc_dev->timeout = sunxi_ithr_to_usec(base_clk, ithr);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int sunxi_ir_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -242,9 +273,11 @@ static int sunxi_ir_probe(struct platfor
|
||||
ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY;
|
||||
ir->rc->dev.parent = dev;
|
||||
ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
|
||||
- /* Frequency after IR internal divider with sample period in ns */
|
||||
+ /* Frequency after IR internal divider with sample period in us */
|
||||
ir->rc->rx_resolution = (USEC_PER_SEC / (b_clk_freq / 64));
|
||||
- ir->rc->timeout = MS_TO_US(SUNXI_IR_TIMEOUT);
|
||||
+ ir->rc->min_timeout = sunxi_ithr_to_usec(b_clk_freq, 0);
|
||||
+ ir->rc->max_timeout = sunxi_ithr_to_usec(b_clk_freq, 255);
|
||||
+ ir->rc->s_timeout = sunxi_ir_set_timeout;
|
||||
ir->rc->driver_name = SUNXI_IR_DEV;
|
||||
|
||||
ret = rc_register_device(ir->rc);
|
||||
@@ -272,8 +305,7 @@ static int sunxi_ir_probe(struct platfor
|
||||
writel(REG_CTL_MD, ir->base+SUNXI_IR_CTL_REG);
|
||||
|
||||
/* Set noise threshold and idle threshold */
|
||||
- writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE)|REG_CIR_ITHR(SUNXI_IR_RXIDLE),
|
||||
- ir->base + SUNXI_IR_CIR_REG);
|
||||
+ sunxi_ir_set_timeout(ir->rc, IR_DEFAULT_TIMEOUT);
|
||||
|
||||
/* Invert Input Signal */
|
||||
writel(REG_RXCTL_RPPI, ir->base + SUNXI_IR_RXCTL_REG);
|
@ -1,118 +0,0 @@
|
||||
From a8bdfe3893f9b226492dac4b4e0d37a27dbee201 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
|
||||
Date: Fri, 30 Oct 2020 15:46:35 +0100
|
||||
Subject: [PATCH 03/44] ASoC: sun4i-i2s: Change set_chan_cfg() params
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
As slots and slot_width can be set manually using set_tdm().
|
||||
These values are then kept in sun4i_i2s struct.
|
||||
So we need to check if these values are set or not.
|
||||
|
||||
This is not done actually and will trigger a bug.
|
||||
For example, if we set to the simple soundcard in the device-tree
|
||||
dai-tdm-slot-width = <32> and then start a stream using S16_LE,
|
||||
currently we would calculate BCLK for 32-bit slots, but program
|
||||
lrck_period for 16-bit slots, making the sample rate double what we
|
||||
expected.
|
||||
|
||||
To fix this, we need to check if these values are set or not but as
|
||||
this logic is already done by the caller. Avoid duplicating this
|
||||
logic and just pass the required values as params to set_chan_cfg().
|
||||
|
||||
Suggested-by: Samuel Holland <samuel@sholland.org>
|
||||
Acked-by: Maxime Ripard <mripard@kernel.org>
|
||||
Signed-off-by: Clément Péron <peron.clem@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20201030144648.397824-3-peron.clem@gmail.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sunxi/sun4i-i2s.c | 32 ++++++++++++++++++--------------
|
||||
1 file changed, 18 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/sound/soc/sunxi/sun4i-i2s.c
|
||||
+++ b/sound/soc/sunxi/sun4i-i2s.c
|
||||
@@ -162,8 +162,15 @@ struct sun4i_i2s_quirks {
|
||||
unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *);
|
||||
s8 (*get_sr)(const struct sun4i_i2s *, int);
|
||||
s8 (*get_wss)(const struct sun4i_i2s *, int);
|
||||
- int (*set_chan_cfg)(const struct sun4i_i2s *,
|
||||
- const struct snd_pcm_hw_params *);
|
||||
+
|
||||
+ /*
|
||||
+ * In the set_chan_cfg() function pointer:
|
||||
+ * @slots: channels per frame + padding slots, regardless of format
|
||||
+ * @slot_width: bits per sample + padding bits, regardless of format
|
||||
+ */
|
||||
+ int (*set_chan_cfg)(const struct sun4i_i2s *i2s,
|
||||
+ unsigned int channels, unsigned int slots,
|
||||
+ unsigned int slot_width);
|
||||
int (*set_fmt)(const struct sun4i_i2s *, unsigned int);
|
||||
};
|
||||
|
||||
@@ -399,10 +406,9 @@ static s8 sun8i_i2s_get_sr_wss(const str
|
||||
}
|
||||
|
||||
static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
|
||||
- const struct snd_pcm_hw_params *params)
|
||||
+ unsigned int channels, unsigned int slots,
|
||||
+ unsigned int slot_width)
|
||||
{
|
||||
- unsigned int channels = params_channels(params);
|
||||
-
|
||||
/* Map the channels for playback and capture */
|
||||
regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210);
|
||||
regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210);
|
||||
@@ -419,15 +425,11 @@ static int sun4i_i2s_set_chan_cfg(const
|
||||
}
|
||||
|
||||
static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
|
||||
- const struct snd_pcm_hw_params *params)
|
||||
+ unsigned int channels, unsigned int slots,
|
||||
+ unsigned int slot_width)
|
||||
{
|
||||
- unsigned int channels = params_channels(params);
|
||||
- unsigned int slots = channels;
|
||||
unsigned int lrck_period;
|
||||
|
||||
- if (i2s->slots)
|
||||
- slots = i2s->slots;
|
||||
-
|
||||
/* Map the channels for playback and capture */
|
||||
regmap_write(i2s->regmap, SUN8I_I2S_TX_CHAN_MAP_REG, 0x76543210);
|
||||
regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, 0x76543210);
|
||||
@@ -450,13 +452,13 @@ static int sun8i_i2s_set_chan_cfg(const
|
||||
switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
- lrck_period = params_physical_width(params) * slots;
|
||||
+ lrck_period = slot_width * slots;
|
||||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
case SND_SOC_DAIFMT_RIGHT_J:
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
- lrck_period = params_physical_width(params);
|
||||
+ lrck_period = slot_width;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -482,7 +484,9 @@ static int sun4i_i2s_hw_params(struct sn
|
||||
unsigned int word_size = params_width(params);
|
||||
unsigned int slot_width = params_physical_width(params);
|
||||
unsigned int channels = params_channels(params);
|
||||
+
|
||||
unsigned int slots = channels;
|
||||
+
|
||||
int ret, sr, wss;
|
||||
u32 width;
|
||||
|
||||
@@ -492,7 +496,7 @@ static int sun4i_i2s_hw_params(struct sn
|
||||
if (i2s->slot_width)
|
||||
slot_width = i2s->slot_width;
|
||||
|
||||
- ret = i2s->variant->set_chan_cfg(i2s, params);
|
||||
+ ret = i2s->variant->set_chan_cfg(i2s, channels, slots, slot_width);
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "Invalid channel configuration\n");
|
||||
return ret;
|
@ -1,295 +0,0 @@
|
||||
From 8ff0df5dffe58a2d1595a6e59ccd5ce63d6bf0e5 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Fri, 30 Oct 2020 15:46:36 +0100
|
||||
Subject: [PATCH 04/44] ASoC: sun4i-i2s: Add support for H6 I2S
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
H6 I2S is very similar to that in H3, except it supports up to 16
|
||||
channels.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Marcus Cooper <codekipper@gmail.com>
|
||||
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Acked-by: Maxime Ripard <mripard@kernel.org>
|
||||
Signed-off-by: Clément Péron <peron.clem@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20201030144648.397824-4-peron.clem@gmail.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sunxi/sun4i-i2s.c | 222 ++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 222 insertions(+)
|
||||
|
||||
--- a/sound/soc/sunxi/sun4i-i2s.c
|
||||
+++ b/sound/soc/sunxi/sun4i-i2s.c
|
||||
@@ -124,6 +124,21 @@
|
||||
#define SUN8I_I2S_RX_CHAN_SEL_REG 0x54
|
||||
#define SUN8I_I2S_RX_CHAN_MAP_REG 0x58
|
||||
|
||||
+/* Defines required for sun50i-h6 support */
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK GENMASK(21, 20)
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset) ((offset) << 20)
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_SEL_MASK GENMASK(19, 16)
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_SEL(chan) ((chan - 1) << 16)
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_EN_MASK GENMASK(15, 0)
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_EN(num_chan) (((1 << num_chan) - 1))
|
||||
+
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_MAP0_REG 0x44
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_MAP1_REG 0x48
|
||||
+
|
||||
+#define SUN50I_H6_I2S_RX_CHAN_SEL_REG 0x64
|
||||
+#define SUN50I_H6_I2S_RX_CHAN_MAP0_REG 0x68
|
||||
+#define SUN50I_H6_I2S_RX_CHAN_MAP1_REG 0x6C
|
||||
+
|
||||
struct sun4i_i2s;
|
||||
|
||||
/**
|
||||
@@ -476,6 +491,60 @@ static int sun8i_i2s_set_chan_cfg(const
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int sun50i_h6_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
|
||||
+ unsigned int channels, unsigned int slots,
|
||||
+ unsigned int slot_width)
|
||||
+{
|
||||
+ unsigned int lrck_period;
|
||||
+
|
||||
+ /* Map the channels for playback and capture */
|
||||
+ regmap_write(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_MAP0_REG, 0xFEDCBA98);
|
||||
+ regmap_write(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_MAP1_REG, 0x76543210);
|
||||
+ regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0xFEDCBA98);
|
||||
+ regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x76543210);
|
||||
+
|
||||
+ /* Configure the channels */
|
||||
+ regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL(channels));
|
||||
+ regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_SEL_REG,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL(channels));
|
||||
+
|
||||
+ regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
|
||||
+ SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
|
||||
+ SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
|
||||
+ regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
|
||||
+ SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
|
||||
+ SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
|
||||
+
|
||||
+ switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
+ case SND_SOC_DAIFMT_DSP_A:
|
||||
+ case SND_SOC_DAIFMT_DSP_B:
|
||||
+ lrck_period = slot_width * slots;
|
||||
+ break;
|
||||
+
|
||||
+ case SND_SOC_DAIFMT_LEFT_J:
|
||||
+ case SND_SOC_DAIFMT_RIGHT_J:
|
||||
+ case SND_SOC_DAIFMT_I2S:
|
||||
+ lrck_period = slot_width;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
|
||||
+ SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
|
||||
+ SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period));
|
||||
+
|
||||
+ regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_EN_MASK,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_EN(channels));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
@@ -703,6 +772,108 @@ static int sun8i_i2s_set_soc_fmt(const s
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
|
||||
+ unsigned int fmt)
|
||||
+{
|
||||
+ u32 mode, val;
|
||||
+ u8 offset;
|
||||
+
|
||||
+ /*
|
||||
+ * DAI clock polarity
|
||||
+ *
|
||||
+ * The setup for LRCK contradicts the datasheet, but under a
|
||||
+ * scope it's clear that the LRCK polarity is reversed
|
||||
+ * compared to the expected polarity on the bus.
|
||||
+ */
|
||||
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
||||
+ case SND_SOC_DAIFMT_IB_IF:
|
||||
+ /* Invert both clocks */
|
||||
+ val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
|
||||
+ break;
|
||||
+ case SND_SOC_DAIFMT_IB_NF:
|
||||
+ /* Invert bit clock */
|
||||
+ val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED |
|
||||
+ SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
|
||||
+ break;
|
||||
+ case SND_SOC_DAIFMT_NB_IF:
|
||||
+ /* Invert frame clock */
|
||||
+ val = 0;
|
||||
+ break;
|
||||
+ case SND_SOC_DAIFMT_NB_NF:
|
||||
+ val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
|
||||
+ SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
|
||||
+ SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
|
||||
+ val);
|
||||
+
|
||||
+ /* DAI Mode */
|
||||
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
+ case SND_SOC_DAIFMT_DSP_A:
|
||||
+ mode = SUN8I_I2S_CTRL_MODE_PCM;
|
||||
+ offset = 1;
|
||||
+ break;
|
||||
+
|
||||
+ case SND_SOC_DAIFMT_DSP_B:
|
||||
+ mode = SUN8I_I2S_CTRL_MODE_PCM;
|
||||
+ offset = 0;
|
||||
+ break;
|
||||
+
|
||||
+ case SND_SOC_DAIFMT_I2S:
|
||||
+ mode = SUN8I_I2S_CTRL_MODE_LEFT;
|
||||
+ offset = 1;
|
||||
+ break;
|
||||
+
|
||||
+ case SND_SOC_DAIFMT_LEFT_J:
|
||||
+ mode = SUN8I_I2S_CTRL_MODE_LEFT;
|
||||
+ offset = 0;
|
||||
+ break;
|
||||
+
|
||||
+ case SND_SOC_DAIFMT_RIGHT_J:
|
||||
+ mode = SUN8I_I2S_CTRL_MODE_RIGHT;
|
||||
+ offset = 0;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
|
||||
+ SUN8I_I2S_CTRL_MODE_MASK, mode);
|
||||
+ regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset));
|
||||
+ regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_SEL_REG,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset));
|
||||
+
|
||||
+ /* DAI clock master masks */
|
||||
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
+ case SND_SOC_DAIFMT_CBS_CFS:
|
||||
+ /* BCLK and LRCLK master */
|
||||
+ val = SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT;
|
||||
+ break;
|
||||
+
|
||||
+ case SND_SOC_DAIFMT_CBM_CFM:
|
||||
+ /* BCLK and LRCLK slave */
|
||||
+ val = 0;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
|
||||
+ SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
|
||||
+ val);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
{
|
||||
struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
|
||||
@@ -983,6 +1154,22 @@ static const struct reg_default sun8i_i2
|
||||
{ SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 },
|
||||
};
|
||||
|
||||
+static const struct reg_default sun50i_h6_i2s_reg_defaults[] = {
|
||||
+ { SUN4I_I2S_CTRL_REG, 0x00060000 },
|
||||
+ { SUN4I_I2S_FMT0_REG, 0x00000033 },
|
||||
+ { SUN4I_I2S_FMT1_REG, 0x00000030 },
|
||||
+ { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
|
||||
+ { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
|
||||
+ { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
|
||||
+ { SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
|
||||
+ { SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 },
|
||||
+ { SUN50I_H6_I2S_TX_CHAN_MAP0_REG, 0x00000000 },
|
||||
+ { SUN50I_H6_I2S_TX_CHAN_MAP1_REG, 0x00000000 },
|
||||
+ { SUN50I_H6_I2S_RX_CHAN_SEL_REG, 0x00000000 },
|
||||
+ { SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0x00000000 },
|
||||
+ { SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x00000000 },
|
||||
+};
|
||||
+
|
||||
static const struct regmap_config sun4i_i2s_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
@@ -1010,6 +1197,19 @@ static const struct regmap_config sun8i_
|
||||
.volatile_reg = sun8i_i2s_volatile_reg,
|
||||
};
|
||||
|
||||
+static const struct regmap_config sun50i_h6_i2s_regmap_config = {
|
||||
+ .reg_bits = 32,
|
||||
+ .reg_stride = 4,
|
||||
+ .val_bits = 32,
|
||||
+ .max_register = SUN50I_H6_I2S_RX_CHAN_MAP1_REG,
|
||||
+ .cache_type = REGCACHE_FLAT,
|
||||
+ .reg_defaults = sun50i_h6_i2s_reg_defaults,
|
||||
+ .num_reg_defaults = ARRAY_SIZE(sun50i_h6_i2s_reg_defaults),
|
||||
+ .writeable_reg = sun4i_i2s_wr_reg,
|
||||
+ .readable_reg = sun8i_i2s_rd_reg,
|
||||
+ .volatile_reg = sun8i_i2s_volatile_reg,
|
||||
+};
|
||||
+
|
||||
static int sun4i_i2s_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct sun4i_i2s *i2s = dev_get_drvdata(dev);
|
||||
@@ -1168,6 +1368,24 @@ static const struct sun4i_i2s_quirks sun
|
||||
.set_fmt = sun4i_i2s_set_soc_fmt,
|
||||
};
|
||||
|
||||
+static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
|
||||
+ .has_reset = true,
|
||||
+ .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG,
|
||||
+ .sun4i_i2s_regmap = &sun50i_h6_i2s_regmap_config,
|
||||
+ .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
|
||||
+ .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
|
||||
+ .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
|
||||
+ .bclk_dividers = sun8i_i2s_clk_div,
|
||||
+ .num_bclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div),
|
||||
+ .mclk_dividers = sun8i_i2s_clk_div,
|
||||
+ .num_mclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div),
|
||||
+ .get_bclk_parent_rate = sun8i_i2s_get_bclk_parent_rate,
|
||||
+ .get_sr = sun8i_i2s_get_sr_wss,
|
||||
+ .get_wss = sun8i_i2s_get_sr_wss,
|
||||
+ .set_chan_cfg = sun50i_h6_i2s_set_chan_cfg,
|
||||
+ .set_fmt = sun50i_h6_i2s_set_soc_fmt,
|
||||
+};
|
||||
+
|
||||
static int sun4i_i2s_init_regmap_fields(struct device *dev,
|
||||
struct sun4i_i2s *i2s)
|
||||
{
|
||||
@@ -1337,6 +1555,10 @@ static const struct of_device_id sun4i_i
|
||||
.compatible = "allwinner,sun50i-a64-codec-i2s",
|
||||
.data = &sun50i_a64_codec_i2s_quirks,
|
||||
},
|
||||
+ {
|
||||
+ .compatible = "allwinner,sun50i-h6-i2s",
|
||||
+ .data = &sun50i_h6_i2s_quirks,
|
||||
+ },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
|
@ -10,7 +10,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
|
||||
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
@@ -406,6 +406,7 @@
|
||||
@@ -388,6 +388,7 @@
|
||||
reg = <0x01c20000 0x400>;
|
||||
clocks = <&osc24M>, <&rtc 0>;
|
||||
clock-names = "hosc", "losc";
|
||||
@ -18,7 +18,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
@@ -894,6 +895,7 @@
|
||||
@@ -876,6 +877,7 @@
|
||||
clocks = <&osc24M>, <&rtc 0>, <&rtc 2>,
|
||||
<&ccu CLK_PLL_PERIPH0>;
|
||||
clock-names = "hosc", "losc", "iosc", "pll-periph";
|
@ -1,134 +0,0 @@
|
||||
From aec30a56043a890b75440bb8c9673a07166cf104 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
|
||||
Date: Fri, 30 Oct 2020 15:46:37 +0100
|
||||
Subject: [PATCH 05/44] ASoC: sun4i-i2s: Change get_sr() and get_wss() to be
|
||||
more explicit
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We are actually using a complex formula to just return a bunch of
|
||||
simple values. Also this formula is wrong for sun4i when calling
|
||||
get_wss() the function return 4 instead of 3.
|
||||
|
||||
Replace this with a simpler switch case.
|
||||
|
||||
Also drop the i2s params which is unused and return a simple int as
|
||||
returning an error code could be out of range for an s8 and there is
|
||||
no optim to return a s8 here.
|
||||
|
||||
Fixes: 619c15f7fac9 ("ASoC: sun4i-i2s: Change SR and WSS computation")
|
||||
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Acked-by: Maxime Ripard <mripard@kernel.org>
|
||||
Signed-off-by: Clément Péron <peron.clem@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20201030144648.397824-5-peron.clem@gmail.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sunxi/sun4i-i2s.c | 75 +++++++++++++++++++++++--------------
|
||||
1 file changed, 47 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/sound/soc/sunxi/sun4i-i2s.c
|
||||
+++ b/sound/soc/sunxi/sun4i-i2s.c
|
||||
@@ -175,8 +175,8 @@ struct sun4i_i2s_quirks {
|
||||
unsigned int num_mclk_dividers;
|
||||
|
||||
unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *);
|
||||
- s8 (*get_sr)(const struct sun4i_i2s *, int);
|
||||
- s8 (*get_wss)(const struct sun4i_i2s *, int);
|
||||
+ int (*get_sr)(unsigned int width);
|
||||
+ int (*get_wss)(unsigned int width);
|
||||
|
||||
/*
|
||||
* In the set_chan_cfg() function pointer:
|
||||
@@ -387,37 +387,56 @@ static int sun4i_i2s_set_clk_rate(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static s8 sun4i_i2s_get_sr(const struct sun4i_i2s *i2s, int width)
|
||||
+static int sun4i_i2s_get_sr(unsigned int width)
|
||||
{
|
||||
- if (width < 16 || width > 24)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- if (width % 4)
|
||||
- return -EINVAL;
|
||||
+ switch (width) {
|
||||
+ case 16:
|
||||
+ return 0;
|
||||
+ case 20:
|
||||
+ return 1;
|
||||
+ case 24:
|
||||
+ return 2;
|
||||
+ }
|
||||
|
||||
- return (width - 16) / 4;
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
-static s8 sun4i_i2s_get_wss(const struct sun4i_i2s *i2s, int width)
|
||||
+static int sun4i_i2s_get_wss(unsigned int width)
|
||||
{
|
||||
- if (width < 16 || width > 32)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- if (width % 4)
|
||||
- return -EINVAL;
|
||||
+ switch (width) {
|
||||
+ case 16:
|
||||
+ return 0;
|
||||
+ case 20:
|
||||
+ return 1;
|
||||
+ case 24:
|
||||
+ return 2;
|
||||
+ case 32:
|
||||
+ return 3;
|
||||
+ }
|
||||
|
||||
- return (width - 16) / 4;
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
-static s8 sun8i_i2s_get_sr_wss(const struct sun4i_i2s *i2s, int width)
|
||||
+static int sun8i_i2s_get_sr_wss(unsigned int width)
|
||||
{
|
||||
- if (width % 4)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- if (width < 8 || width > 32)
|
||||
- return -EINVAL;
|
||||
+ switch (width) {
|
||||
+ case 8:
|
||||
+ return 1;
|
||||
+ case 12:
|
||||
+ return 2;
|
||||
+ case 16:
|
||||
+ return 3;
|
||||
+ case 20:
|
||||
+ return 4;
|
||||
+ case 24:
|
||||
+ return 5;
|
||||
+ case 28:
|
||||
+ return 6;
|
||||
+ case 32:
|
||||
+ return 7;
|
||||
+ }
|
||||
|
||||
- return (width - 8) / 4 + 1;
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
|
||||
@@ -582,11 +601,11 @@ static int sun4i_i2s_hw_params(struct sn
|
||||
}
|
||||
i2s->playback_dma_data.addr_width = width;
|
||||
|
||||
- sr = i2s->variant->get_sr(i2s, word_size);
|
||||
+ sr = i2s->variant->get_sr(word_size);
|
||||
if (sr < 0)
|
||||
return -EINVAL;
|
||||
|
||||
- wss = i2s->variant->get_wss(i2s, slot_width);
|
||||
+ wss = i2s->variant->get_wss(slot_width);
|
||||
if (wss < 0)
|
||||
return -EINVAL;
|
||||
|
@ -10,7 +10,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
@@ -637,6 +637,7 @@
|
||||
@@ -641,6 +641,7 @@
|
||||
reg = <0x01c20000 0x400>;
|
||||
clocks = <&osc24M>, <&rtc 0>;
|
||||
clock-names = "hosc", "losc";
|
||||
@ -18,7 +18,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
@@ -1229,6 +1230,7 @@
|
||||
@@ -1233,6 +1234,7 @@
|
||||
clocks = <&osc24M>, <&rtc 0>, <&rtc 2>,
|
||||
<&ccu CLK_PLL_PERIPH0>;
|
||||
clock-names = "hosc", "losc", "iosc", "pll-periph";
|
@ -1,86 +0,0 @@
|
||||
From fe1ae019879d51633d8dcd705117c70b701b77e9 Mon Sep 17 00:00:00 2001
|
||||
From: Marcus Cooper <codekipper@gmail.com>
|
||||
Date: Fri, 30 Oct 2020 15:46:38 +0100
|
||||
Subject: [PATCH 06/44] ASoC: sun4i-i2s: Set sign extend sample
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
On the newer SoCs such as the H3 and A64 this is set by default
|
||||
to transfer a 0 after each sample in each slot. However the A10
|
||||
and A20 SoCs that this driver was developed on had a default
|
||||
setting where it padded the audio gain with zeros.
|
||||
|
||||
This isn't a problem while we have only support for 16bit audio
|
||||
but with larger sample resolution rates in the pipeline then SEXT
|
||||
bits should be cleared so that they also pad at the LSB. Without
|
||||
this the audio gets distorted.
|
||||
|
||||
Set sign extend sample for all the sunxi generations even if they
|
||||
are not affected. This will keep consistency and avoid relying on
|
||||
default.
|
||||
|
||||
Signed-off-by: Marcus Cooper <codekipper@gmail.com>
|
||||
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Acked-by: Maxime Ripard <mripard@kernel.org>
|
||||
Signed-off-by: Clément Péron <peron.clem@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20201030144648.397824-6-peron.clem@gmail.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sunxi/sun4i-i2s.c | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
--- a/sound/soc/sunxi/sun4i-i2s.c
|
||||
+++ b/sound/soc/sunxi/sun4i-i2s.c
|
||||
@@ -48,6 +48,9 @@
|
||||
#define SUN4I_I2S_FMT0_FMT_I2S (0 << 0)
|
||||
|
||||
#define SUN4I_I2S_FMT1_REG 0x08
|
||||
+#define SUN4I_I2S_FMT1_REG_SEXT_MASK BIT(8)
|
||||
+#define SUN4I_I2S_FMT1_REG_SEXT(sext) ((sext) << 8)
|
||||
+
|
||||
#define SUN4I_I2S_FIFO_TX_REG 0x0c
|
||||
#define SUN4I_I2S_FIFO_RX_REG 0x10
|
||||
|
||||
@@ -105,6 +108,9 @@
|
||||
#define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED (1 << 7)
|
||||
#define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL (0 << 7)
|
||||
|
||||
+#define SUN8I_I2S_FMT1_REG_SEXT_MASK GENMASK(5, 4)
|
||||
+#define SUN8I_I2S_FMT1_REG_SEXT(sext) ((sext) << 4)
|
||||
+
|
||||
#define SUN8I_I2S_INT_STA_REG 0x0c
|
||||
#define SUN8I_I2S_FIFO_TX_REG 0x20
|
||||
|
||||
@@ -686,6 +692,7 @@ static int sun4i_i2s_set_soc_fmt(const s
|
||||
}
|
||||
regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
|
||||
SUN4I_I2S_CTRL_MODE_MASK, val);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -788,6 +795,11 @@ static int sun8i_i2s_set_soc_fmt(const s
|
||||
SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
|
||||
val);
|
||||
|
||||
+ /* Set sign extension to pad out LSB with 0 */
|
||||
+ regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
|
||||
+ SUN8I_I2S_FMT1_REG_SEXT_MASK,
|
||||
+ SUN8I_I2S_FMT1_REG_SEXT(0));
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -890,6 +902,11 @@ static int sun50i_h6_i2s_set_soc_fmt(con
|
||||
SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
|
||||
val);
|
||||
|
||||
+ /* Set sign extension to pad out LSB with 0 */
|
||||
+ regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
|
||||
+ SUN8I_I2S_FMT1_REG_SEXT_MASK,
|
||||
+ SUN8I_I2S_FMT1_REG_SEXT(0));
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -241,6 +241,7 @@
|
||||
@@ -230,6 +230,7 @@
|
||||
reg = <0x03001000 0x1000>;
|
||||
clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
|
||||
clock-names = "hosc", "losc", "iosc";
|
||||
@ -18,7 +18,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
@@ -920,6 +921,7 @@
|
||||
@@ -916,6 +917,7 @@
|
||||
clocks = <&osc24M>, <&rtc 0>, <&rtc 2>,
|
||||
<&ccu CLK_PLL_PERIPH0>;
|
||||
clock-names = "hosc", "losc", "iosc", "pll-periph";
|
@ -1,61 +0,0 @@
|
||||
From 9c2121fe514f12c830bceea7b33872fa67af3e97 Mon Sep 17 00:00:00 2001
|
||||
From: Marcus Cooper <codekipper@gmail.com>
|
||||
Date: Fri, 30 Oct 2020 15:46:39 +0100
|
||||
Subject: [PATCH 07/44] ASoC: sun4i-i2s: Add 20 and 24 bit support
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Extend the functionality of the driver to include support of 20 and
|
||||
24 bits per sample.
|
||||
|
||||
Signed-off-by: Marcus Cooper <codekipper@gmail.com>
|
||||
Acked-by: Maxime Ripard <mripard@kernel.org>
|
||||
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Signed-off-by: Clément Péron <peron.clem@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20201030144648.397824-7-peron.clem@gmail.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sunxi/sun4i-i2s.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/sound/soc/sunxi/sun4i-i2s.c
|
||||
+++ b/sound/soc/sunxi/sun4i-i2s.c
|
||||
@@ -600,6 +600,9 @@ static int sun4i_i2s_hw_params(struct sn
|
||||
case 16:
|
||||
width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
break;
|
||||
+ case 32:
|
||||
+ width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
+ break;
|
||||
default:
|
||||
dev_err(dai->dev, "Unsupported physical sample width: %d\n",
|
||||
params_physical_width(params));
|
||||
@@ -1081,6 +1084,10 @@ static int sun4i_i2s_dai_probe(struct sn
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#define SUN4I_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
|
||||
+ SNDRV_PCM_FMTBIT_S20_LE | \
|
||||
+ SNDRV_PCM_FMTBIT_S24_LE)
|
||||
+
|
||||
static struct snd_soc_dai_driver sun4i_i2s_dai = {
|
||||
.probe = sun4i_i2s_dai_probe,
|
||||
.capture = {
|
||||
@@ -1088,14 +1095,14 @@ static struct snd_soc_dai_driver sun4i_i
|
||||
.channels_min = 1,
|
||||
.channels_max = 8,
|
||||
.rates = SNDRV_PCM_RATE_8000_192000,
|
||||
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
+ .formats = SUN4I_FORMATS,
|
||||
},
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 8,
|
||||
.rates = SNDRV_PCM_RATE_8000_192000,
|
||||
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
+ .formats = SUN4I_FORMATS,
|
||||
},
|
||||
.ops = &sun4i_i2s_dai_ops,
|
||||
.symmetric_rates = 1,
|
@ -15,7 +15,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
|
||||
--- a/drivers/rtc/rtc-sun6i.c
|
||||
+++ b/drivers/rtc/rtc-sun6i.c
|
||||
@@ -639,7 +639,6 @@ static const struct rtc_class_ops sun6i_
|
||||
@@ -641,7 +641,6 @@ static const struct rtc_class_ops sun6i_
|
||||
.alarm_irq_enable = sun6i_rtc_alarm_irq_enable
|
||||
};
|
||||
|
||||
@ -23,7 +23,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
/* Enable IRQ wake on suspend, to wake up from RTC. */
|
||||
static int sun6i_rtc_suspend(struct device *dev)
|
||||
{
|
||||
@@ -652,7 +651,7 @@ static int sun6i_rtc_suspend(struct devi
|
||||
@@ -654,7 +653,7 @@ static int sun6i_rtc_suspend(struct devi
|
||||
}
|
||||
|
||||
/* Disable IRQ wake on resume. */
|
||||
@ -32,7 +32,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
{
|
||||
struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
|
||||
|
||||
@@ -661,7 +660,6 @@ static int sun6i_rtc_resume(struct devic
|
||||
@@ -663,7 +662,6 @@ static int sun6i_rtc_resume(struct devic
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -40,7 +40,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(sun6i_rtc_pm_ops,
|
||||
sun6i_rtc_suspend, sun6i_rtc_resume);
|
||||
@@ -733,6 +731,11 @@ static int sun6i_rtc_probe(struct platfo
|
||||
@@ -735,6 +733,11 @@ static int sun6i_rtc_probe(struct platfo
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
/*
|
||||
* As far as RTC functionality goes, all models are the same. The
|
||||
* datasheets claim that different models have different number of
|
||||
@@ -753,6 +756,7 @@ MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids
|
||||
@@ -755,6 +758,7 @@ MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids
|
||||
|
||||
static struct platform_driver sun6i_rtc_driver = {
|
||||
.probe = sun6i_rtc_probe,
|
@ -1,49 +0,0 @@
|
||||
From 9f0cbed8e957216d58a2dd5c9c8e795ec39004ad Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
|
||||
Date: Fri, 30 Oct 2020 15:46:40 +0100
|
||||
Subject: [PATCH 08/44] ASoC: sun4i-i2s: Fix sun8i volatile regs
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The FIFO TX reg is volatile and sun8i i2s register
|
||||
mapping is different from sun4i.
|
||||
|
||||
Even if in this case it's doesn't create an issue,
|
||||
Avoid setting some regs that are undefined in sun8i.
|
||||
|
||||
Acked-by: Maxime Ripard <mripard@kernel.org>
|
||||
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Signed-off-by: Clément Péron <peron.clem@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20201030144648.397824-8-peron.clem@gmail.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sunxi/sun4i-i2s.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/sound/soc/sunxi/sun4i-i2s.c
|
||||
+++ b/sound/soc/sunxi/sun4i-i2s.c
|
||||
@@ -1162,12 +1162,19 @@ static bool sun8i_i2s_rd_reg(struct devi
|
||||
|
||||
static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
- if (reg == SUN8I_I2S_INT_STA_REG)
|
||||
+ switch (reg) {
|
||||
+ case SUN4I_I2S_FIFO_CTRL_REG:
|
||||
+ case SUN4I_I2S_FIFO_RX_REG:
|
||||
+ case SUN4I_I2S_FIFO_STA_REG:
|
||||
+ case SUN4I_I2S_RX_CNT_REG:
|
||||
+ case SUN4I_I2S_TX_CNT_REG:
|
||||
+ case SUN8I_I2S_FIFO_TX_REG:
|
||||
+ case SUN8I_I2S_INT_STA_REG:
|
||||
return true;
|
||||
- if (reg == SUN8I_I2S_FIFO_TX_REG)
|
||||
- return false;
|
||||
|
||||
- return sun4i_i2s_volatile_reg(dev, reg);
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
}
|
||||
|
||||
static const struct reg_default sun4i_i2s_reg_defaults[] = {
|
@ -1,53 +0,0 @@
|
||||
From de8ff7b3ac4736f5aa0c55968170bd449e46c88f Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Fri, 30 Oct 2020 15:46:41 +0100
|
||||
Subject: [PATCH 09/44] ASoC: sun4i-i2s: Fix setting of FIFO modes
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Because SUN4I_I2S_FIFO_CTRL_REG is volatile, writes done while the
|
||||
regmap is cache-only are ignored. To work around this, move the
|
||||
configuration to a callback that runs while the ASoC core has a
|
||||
runtime PM reference to the device.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Acked-by: Maxime Ripard <mripard@kernel.org>
|
||||
Signed-off-by: Clément Péron <peron.clem@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20201030144648.397824-9-peron.clem@gmail.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sunxi/sun4i-i2s.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/sound/soc/sunxi/sun4i-i2s.c
|
||||
+++ b/sound/soc/sunxi/sun4i-i2s.c
|
||||
@@ -596,6 +596,13 @@ static int sun4i_i2s_hw_params(struct sn
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ /* Set significant bits in our FIFOs */
|
||||
+ regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
|
||||
+ SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
|
||||
+ SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
|
||||
+ SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
|
||||
+ SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
|
||||
+
|
||||
switch (params_physical_width(params)) {
|
||||
case 16:
|
||||
width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
@@ -924,13 +931,6 @@ static int sun4i_i2s_set_fmt(struct snd_
|
||||
return ret;
|
||||
}
|
||||
|
||||
- /* Set significant bits in our FIFOs */
|
||||
- regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
|
||||
- SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
|
||||
- SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
|
||||
- SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
|
||||
- SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
|
||||
-
|
||||
i2s->format = fmt;
|
||||
|
||||
return 0;
|
@ -38,7 +38,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
if (ret < 0 || !rx_buf)
|
||||
goto out;
|
||||
|
||||
@@ -854,8 +855,13 @@ static void scpi_free_channels(void *dat
|
||||
@@ -856,8 +857,13 @@ static void scpi_free_channels(void *dat
|
||||
struct scpi_drvinfo *info = data;
|
||||
int i;
|
||||
|
||||
@ -54,7 +54,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
}
|
||||
|
||||
static int scpi_remove(struct platform_device *pdev)
|
||||
@@ -903,6 +909,7 @@ static int scpi_probe(struct platform_de
|
||||
@@ -905,6 +911,7 @@ static int scpi_probe(struct platform_de
|
||||
struct resource res;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
@ -62,7 +62,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
|
||||
scpi_info = devm_kzalloc(dev, sizeof(*scpi_info), GFP_KERNEL);
|
||||
if (!scpi_info)
|
||||
@@ -916,6 +923,14 @@ static int scpi_probe(struct platform_de
|
||||
@@ -918,6 +925,14 @@ static int scpi_probe(struct platform_de
|
||||
dev_err(dev, "no mboxes property in '%pOF'\n", np);
|
||||
return -ENODEV;
|
||||
}
|
||||
@ -77,7 +77,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
|
||||
scpi_info->channels = devm_kcalloc(dev, count, sizeof(struct scpi_chan),
|
||||
GFP_KERNEL);
|
||||
@@ -961,15 +976,34 @@ static int scpi_probe(struct platform_de
|
||||
@@ -963,15 +978,34 @@ static int scpi_probe(struct platform_de
|
||||
mutex_init(&pchan->xfers_lock);
|
||||
|
||||
ret = scpi_alloc_xfer_list(dev, pchan);
|
@ -34,7 +34,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
reg = <0x01d00000 0x80000>;
|
||||
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
@@ -123,6 +123,13 @@
|
||||
@@ -105,6 +105,13 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -1,44 +0,0 @@
|
||||
From 82b0eb24d554180fdea8a254553dcce22085cc74 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
|
||||
Date: Fri, 30 Oct 2020 15:46:42 +0100
|
||||
Subject: [PATCH 10/44] ASoC: sun4i-i2s: fix coding-style for callback
|
||||
definition
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Checkpatch script produces warning:
|
||||
WARNING: function definition argument 'const struct sun4i_i2s *'
|
||||
should also have an identifier name.
|
||||
|
||||
Let's fix this by adding identifier name to get_bclk_parent_rate()
|
||||
and set_fmt() callback definition.
|
||||
|
||||
Acked-by: Maxime Ripard <mripard@kernel.org>
|
||||
Signed-off-by: Clément Péron <peron.clem@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20201030144648.397824-10-peron.clem@gmail.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sunxi/sun4i-i2s.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/sound/soc/sunxi/sun4i-i2s.c
|
||||
+++ b/sound/soc/sunxi/sun4i-i2s.c
|
||||
@@ -180,7 +180,7 @@ struct sun4i_i2s_quirks {
|
||||
const struct sun4i_i2s_clk_div *mclk_dividers;
|
||||
unsigned int num_mclk_dividers;
|
||||
|
||||
- unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *);
|
||||
+ unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *i2s);
|
||||
int (*get_sr)(unsigned int width);
|
||||
int (*get_wss)(unsigned int width);
|
||||
|
||||
@@ -192,7 +192,7 @@ struct sun4i_i2s_quirks {
|
||||
int (*set_chan_cfg)(const struct sun4i_i2s *i2s,
|
||||
unsigned int channels, unsigned int slots,
|
||||
unsigned int slot_width);
|
||||
- int (*set_fmt)(const struct sun4i_i2s *, unsigned int);
|
||||
+ int (*set_fmt)(const struct sun4i_i2s *i2s, unsigned int fmt);
|
||||
};
|
||||
|
||||
struct sun4i_i2s {
|
@ -1,45 +0,0 @@
|
||||
From 51ebc019df15b46d109bafe7068ebb6fe0b266b5 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Wed, 6 Jan 2021 19:19:01 +0100
|
||||
Subject: [PATCH 11/44] ARM: dts: sun8i: r40: Add deinterlace node
|
||||
|
||||
R40 contains deinterlace core compatible to that in H3. One peculiarity
|
||||
is that RAM gate is shared with CSI1. User manual states it's separate
|
||||
but that's not true. Shared gate was verified with BSP Linux code check
|
||||
and with runtime tests (CPU crashed if CSI1 gate was not ungated).
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
Link: https://lore.kernel.org/r/20210106181901.1324075-3-jernej.skrabec@siol.net
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-r40.dtsi | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
--- a/arch/arm/boot/dts/sun8i-r40.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-r40.dtsi
|
||||
@@ -190,6 +190,25 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ deinterlace: deinterlace@1400000 {
|
||||
+ compatible = "allwinner,sun8i-r40-deinterlace",
|
||||
+ "allwinner,sun8i-h3-deinterlace";
|
||||
+ reg = <0x01400000 0x20000>;
|
||||
+ clocks = <&ccu CLK_BUS_DEINTERLACE>,
|
||||
+ <&ccu CLK_DEINTERLACE>,
|
||||
+ /*
|
||||
+ * NOTE: Contrary to what datasheet claims,
|
||||
+ * DRAM deinterlace gate doesn't exist and
|
||||
+ * it's shared with CSI1.
|
||||
+ */
|
||||
+ <&ccu CLK_DRAM_CSI1>;
|
||||
+ clock-names = "bus", "mod", "ram";
|
||||
+ resets = <&ccu RST_BUS_DEINTERLACE>;
|
||||
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interconnects = <&mbus 9>;
|
||||
+ interconnect-names = "dma-mem";
|
||||
+ };
|
||||
+
|
||||
syscon: system-control@1c00000 {
|
||||
compatible = "allwinner,sun8i-r40-system-control",
|
||||
"allwinner,sun4i-a10-system-control";
|
@ -1,38 +0,0 @@
|
||||
From 7166a5b6ab1f3d9ba0f5236b738525e828138c8e Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Wed, 6 Jan 2021 19:25:23 +0100
|
||||
Subject: [PATCH 12/44] arm64: dts: allwinner: h5: Add deinterlace node
|
||||
|
||||
Deinterlace core is completely compatible to H3.
|
||||
|
||||
Add a node for it.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
Link: https://lore.kernel.org/r/20210106182523.1325796-1-jernej.skrabec@siol.net
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
@@ -121,6 +121,19 @@
|
||||
resets = <&ccu RST_BUS_CE>;
|
||||
};
|
||||
|
||||
+ deinterlace: deinterlace@1e00000 {
|
||||
+ compatible = "allwinner,sun8i-h3-deinterlace";
|
||||
+ reg = <0x01e00000 0x20000>;
|
||||
+ clocks = <&ccu CLK_BUS_DEINTERLACE>,
|
||||
+ <&ccu CLK_DEINTERLACE>,
|
||||
+ <&ccu CLK_DRAM_DEINTERLACE>;
|
||||
+ clock-names = "bus", "mod", "ram";
|
||||
+ resets = <&ccu RST_BUS_DEINTERLACE>;
|
||||
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interconnects = <&mbus 9>;
|
||||
+ interconnect-names = "dma-mem";
|
||||
+ };
|
||||
+
|
||||
mali: gpu@1e80000 {
|
||||
compatible = "allwinner,sun50i-h5-mali", "arm,mali-450";
|
||||
reg = <0x01e80000 0x30000>;
|
@ -24,7 +24,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
timer {
|
||||
compatible = "arm,armv8-timer";
|
||||
arm,no-tick-in-suspend;
|
||||
@@ -207,6 +214,19 @@
|
||||
@@ -196,6 +203,19 @@
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
@ -9,7 +9,7 @@ Subject: [PATCH 22/44] ASoC: hdmi-codec: fix channel allocation
|
||||
|
||||
--- a/sound/soc/codecs/hdmi-codec.c
|
||||
+++ b/sound/soc/codecs/hdmi-codec.c
|
||||
@@ -195,78 +195,69 @@ static const struct snd_pcm_chmap_elem h
|
||||
@@ -194,78 +194,69 @@ static const struct snd_pcm_chmap_elem h
|
||||
*/
|
||||
static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
|
||||
{ .ca_id = 0x00, .n_ch = 2,
|
@ -1,40 +0,0 @@
|
||||
From dcd9635dc6027b04a64e19ebb3dc15aaae082400 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Tue, 18 Feb 2020 19:24:29 +0100
|
||||
Subject: [PATCH 13/44] drm/sun4i: csc: Rework DE3 CSC macros
|
||||
|
||||
Rework DE3 CSC macros to take just one coordinate instead of two. This
|
||||
will make its usage easier in subsequent commit.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/gpu/drm/sun4i/sun8i_csc.c | 2 +-
|
||||
drivers/gpu/drm/sun4i/sun8i_mixer.h | 6 ++----
|
||||
2 files changed, 3 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_csc.c
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
|
||||
@@ -194,7 +194,7 @@ static void sun8i_de3_ccsc_set_coefficie
|
||||
return;
|
||||
}
|
||||
|
||||
- base_reg = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0, 0);
|
||||
+ base_reg = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0);
|
||||
regmap_bulk_write(map, base_reg, table, 12);
|
||||
}
|
||||
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
||||
@@ -50,10 +50,8 @@
|
||||
#define SUN8I_MIXER_BLEND_CK_MIN(base, x) ((base) + 0xe0 + 0x04 * (x))
|
||||
#define SUN8I_MIXER_BLEND_OUTCTL(base) ((base) + 0xfc)
|
||||
#define SUN50I_MIXER_BLEND_CSC_CTL(base) ((base) + 0x100)
|
||||
-#define SUN50I_MIXER_BLEND_CSC_COEFF(base, layer, x, y) \
|
||||
- ((base) + 0x110 + (layer) * 0x30 + (x) * 0x10 + 4 * (y))
|
||||
-#define SUN50I_MIXER_BLEND_CSC_CONST(base, layer, i) \
|
||||
- ((base) + 0x110 + (layer) * 0x30 + (i) * 0x10 + 0x0c)
|
||||
+#define SUN50I_MIXER_BLEND_CSC_COEFF(base, layer, x) \
|
||||
+ ((base) + 0x110 + (layer) * 0x30 + (x) * 4)
|
||||
|
||||
#define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK GENMASK(12, 8)
|
||||
#define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe) BIT(8 + pipe)
|
@ -1,163 +0,0 @@
|
||||
From acdfa534d3fe6759f43c1fe0bcd2fd40f31d3797 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Tue, 18 Feb 2020 19:44:33 +0100
|
||||
Subject: [PATCH 14/44] drm/sun4i: de2/de3: Remove redundant CSC matrices
|
||||
|
||||
YUV to RGB matrices are almost identical to YVU to RGB matrices. They
|
||||
only have second and third column reversed. Do that reversion in code in
|
||||
order to lower amount of static data and redundancy.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/gpu/drm/sun4i/sun8i_csc.c | 99 +++++++++++--------------------
|
||||
1 file changed, 34 insertions(+), 65 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_csc.c
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
|
||||
@@ -46,33 +46,6 @@ static const u32 yuv2rgb[2][2][12] = {
|
||||
},
|
||||
};
|
||||
|
||||
-static const u32 yvu2rgb[2][2][12] = {
|
||||
- [DRM_COLOR_YCBCR_LIMITED_RANGE] = {
|
||||
- [DRM_COLOR_YCBCR_BT601] = {
|
||||
- 0x000004A8, 0x00000662, 0x00000000, 0xFFFC8451,
|
||||
- 0x000004A8, 0xFFFFFCC0, 0xFFFFFE6F, 0x00021E4D,
|
||||
- 0x000004A8, 0x00000000, 0x00000811, 0xFFFBACA9,
|
||||
- },
|
||||
- [DRM_COLOR_YCBCR_BT709] = {
|
||||
- 0x000004A8, 0x0000072B, 0x00000000, 0xFFFC1F99,
|
||||
- 0x000004A8, 0xFFFFFDDF, 0xFFFFFF26, 0x00013383,
|
||||
- 0x000004A8, 0x00000000, 0x00000873, 0xFFFB7BEF,
|
||||
- }
|
||||
- },
|
||||
- [DRM_COLOR_YCBCR_FULL_RANGE] = {
|
||||
- [DRM_COLOR_YCBCR_BT601] = {
|
||||
- 0x00000400, 0x0000059B, 0x00000000, 0xFFFD322E,
|
||||
- 0x00000400, 0xFFFFFD25, 0xFFFFFEA0, 0x00021DD5,
|
||||
- 0x00000400, 0x00000000, 0x00000716, 0xFFFC74BD,
|
||||
- },
|
||||
- [DRM_COLOR_YCBCR_BT709] = {
|
||||
- 0x00000400, 0x0000064C, 0x00000000, 0xFFFCD9B4,
|
||||
- 0x00000400, 0xFFFFFE21, 0xFFFFFF41, 0x00014F96,
|
||||
- 0x00000400, 0x00000000, 0x0000076C, 0xFFFC49EF,
|
||||
- }
|
||||
- },
|
||||
-};
|
||||
-
|
||||
/*
|
||||
* DE3 has a bit different CSC units. Factors are in two's complement format.
|
||||
* First three factors in a row are multiplication factors which have 17 bits
|
||||
@@ -123,33 +96,6 @@ static const u32 yuv2rgb_de3[2][2][12] =
|
||||
},
|
||||
};
|
||||
|
||||
-static const u32 yvu2rgb_de3[2][2][12] = {
|
||||
- [DRM_COLOR_YCBCR_LIMITED_RANGE] = {
|
||||
- [DRM_COLOR_YCBCR_BT601] = {
|
||||
- 0x0002542A, 0x0003312A, 0x00000000, 0xFFC00000,
|
||||
- 0x0002542A, 0xFFFE5FC3, 0xFFFF376B, 0xFE000000,
|
||||
- 0x0002542A, 0x00000000, 0x000408D2, 0xFE000000,
|
||||
- },
|
||||
- [DRM_COLOR_YCBCR_BT709] = {
|
||||
- 0x0002542A, 0x000395E2, 0x00000000, 0xFFC00000,
|
||||
- 0x0002542A, 0xFFFEEF27, 0xFFFF92D2, 0xFE000000,
|
||||
- 0x0002542A, 0x00000000, 0x0004398C, 0xFE000000,
|
||||
- }
|
||||
- },
|
||||
- [DRM_COLOR_YCBCR_FULL_RANGE] = {
|
||||
- [DRM_COLOR_YCBCR_BT601] = {
|
||||
- 0x00020000, 0x0002CDD2, 0x00000000, 0x00000000,
|
||||
- 0x00020000, 0xFFFE925D, 0xFFFF4FCE, 0xFE000000,
|
||||
- 0x00020000, 0x00000000, 0x00038B43, 0xFE000000,
|
||||
- },
|
||||
- [DRM_COLOR_YCBCR_BT709] = {
|
||||
- 0x00020000, 0x0003264C, 0x00000000, 0x00000000,
|
||||
- 0x00020000, 0xFFFF1053, 0xFFFFA018, 0xFE000000,
|
||||
- 0x00020000, 0x00000000, 0x0003B611, 0xFE000000,
|
||||
- }
|
||||
- },
|
||||
-};
|
||||
-
|
||||
static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
|
||||
enum sun8i_csc_mode mode,
|
||||
enum drm_color_encoding encoding,
|
||||
@@ -157,21 +103,30 @@ static void sun8i_csc_set_coefficients(s
|
||||
{
|
||||
const u32 *table;
|
||||
u32 base_reg;
|
||||
+ int i;
|
||||
+
|
||||
+ table = yuv2rgb[range][encoding];
|
||||
|
||||
switch (mode) {
|
||||
case SUN8I_CSC_MODE_YUV2RGB:
|
||||
- table = yuv2rgb[range][encoding];
|
||||
+ base_reg = SUN8I_CSC_COEFF(base, 0);
|
||||
+ regmap_bulk_write(map, base_reg, table, 12);
|
||||
break;
|
||||
case SUN8I_CSC_MODE_YVU2RGB:
|
||||
- table = yvu2rgb[range][encoding];
|
||||
+ for (i = 0; i < 12; i++) {
|
||||
+ if ((i & 3) == 1)
|
||||
+ base_reg = SUN8I_CSC_COEFF(base, i + 1);
|
||||
+ else if ((i & 3) == 2)
|
||||
+ base_reg = SUN8I_CSC_COEFF(base, i - 1);
|
||||
+ else
|
||||
+ base_reg = SUN8I_CSC_COEFF(base, i);
|
||||
+ regmap_write(map, base_reg, table[i]);
|
||||
+ }
|
||||
break;
|
||||
default:
|
||||
DRM_WARN("Wrong CSC mode specified.\n");
|
||||
return;
|
||||
}
|
||||
-
|
||||
- base_reg = SUN8I_CSC_COEFF(base, 0);
|
||||
- regmap_bulk_write(map, base_reg, table, 12);
|
||||
}
|
||||
|
||||
static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer,
|
||||
@@ -180,22 +135,36 @@ static void sun8i_de3_ccsc_set_coefficie
|
||||
enum drm_color_range range)
|
||||
{
|
||||
const u32 *table;
|
||||
- u32 base_reg;
|
||||
+ u32 addr;
|
||||
+ int i;
|
||||
+
|
||||
+ table = yuv2rgb_de3[range][encoding];
|
||||
|
||||
switch (mode) {
|
||||
case SUN8I_CSC_MODE_YUV2RGB:
|
||||
- table = yuv2rgb_de3[range][encoding];
|
||||
+ addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0);
|
||||
+ regmap_bulk_write(map, addr, table, 12);
|
||||
break;
|
||||
case SUN8I_CSC_MODE_YVU2RGB:
|
||||
- table = yvu2rgb_de3[range][encoding];
|
||||
+ for (i = 0; i < 12; i++) {
|
||||
+ if ((i & 3) == 1)
|
||||
+ addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE,
|
||||
+ layer,
|
||||
+ i + 1);
|
||||
+ else if ((i & 3) == 2)
|
||||
+ addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE,
|
||||
+ layer,
|
||||
+ i - 1);
|
||||
+ else
|
||||
+ addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE,
|
||||
+ layer, i);
|
||||
+ regmap_write(map, addr, table[i]);
|
||||
+ }
|
||||
break;
|
||||
default:
|
||||
DRM_WARN("Wrong CSC mode specified.\n");
|
||||
return;
|
||||
}
|
||||
-
|
||||
- base_reg = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0);
|
||||
- regmap_bulk_write(map, base_reg, table, 12);
|
||||
}
|
||||
|
||||
static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable)
|
@ -13,7 +13,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
@@ -1021,6 +1021,7 @@ const char *v4l2_ctrl_get_name(u32 id)
|
||||
@@ -1041,6 +1041,7 @@ const char *v4l2_ctrl_get_name(u32 id)
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_SPS: return "HEVC Sequence Parameter Set";
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_PPS: return "HEVC Picture Parameter Set";
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: return "HEVC Slice Parameters";
|
||||
@ -21,7 +21,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: return "HEVC Decode Mode";
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: return "HEVC Start Code";
|
||||
|
||||
@@ -1461,6 +1462,9 @@ void v4l2_ctrl_fill(u32 id, const char *
|
||||
@@ -1526,6 +1527,9 @@ void v4l2_ctrl_fill(u32 id, const char *
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:
|
||||
*type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS;
|
||||
break;
|
||||
@ -31,8 +31,8 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
case V4L2_CID_UNIT_CELL_SIZE:
|
||||
*type = V4L2_CTRL_TYPE_AREA;
|
||||
*flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
||||
@@ -1934,6 +1938,9 @@ static int std_validate_compound(const s
|
||||
zero_padding(*p_hevc_slice_params);
|
||||
@@ -2237,6 +2241,9 @@ static int std_validate_compound(const s
|
||||
|
||||
break;
|
||||
|
||||
+ case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
|
||||
@ -41,9 +41,9 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
case V4L2_CTRL_TYPE_AREA:
|
||||
area = p;
|
||||
if (!area->width || !area->height)
|
||||
@@ -2626,6 +2633,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(s
|
||||
case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
|
||||
elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params);
|
||||
@@ -2953,6 +2960,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(s
|
||||
case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY:
|
||||
elem_size = sizeof(struct v4l2_ctrl_hdr10_mastering_display);
|
||||
break;
|
||||
+ case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
|
||||
+ elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix);
|
||||
@ -54,12 +54,12 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
--- a/include/media/hevc-ctrls.h
|
||||
+++ b/include/media/hevc-ctrls.h
|
||||
@@ -19,6 +19,7 @@
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_SPS (V4L2_CID_MPEG_BASE + 1008)
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_PPS (V4L2_CID_MPEG_BASE + 1009)
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (V4L2_CID_MPEG_BASE + 1010)
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (V4L2_CID_MPEG_BASE + 1011)
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (V4L2_CID_MPEG_BASE + 1015)
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (V4L2_CID_MPEG_BASE + 1016)
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_SPS (V4L2_CID_CODEC_BASE + 1008)
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_PPS (V4L2_CID_CODEC_BASE + 1009)
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (V4L2_CID_CODEC_BASE + 1010)
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (V4L2_CID_CODEC_BASE + 1011)
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (V4L2_CID_CODEC_BASE + 1015)
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (V4L2_CID_CODEC_BASE + 1016)
|
||||
|
||||
@@ -26,6 +27,7 @@
|
||||
#define V4L2_CTRL_TYPE_HEVC_SPS 0x0120
|
@ -1,62 +0,0 @@
|
||||
From 2c9a7a5a71d5ed6db9ee28a5ccd11f0db45f574d Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Wed, 15 Apr 2020 10:24:05 +0200
|
||||
Subject: [PATCH 15/44] drm/sun4i: Add support for BT2020 to DE3
|
||||
|
||||
DE3 supports 10-bit formats, so it's only naturally to also support
|
||||
BT2020 encoding.
|
||||
|
||||
Add support for it.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/gpu/drm/sun4i/sun8i_csc.c | 12 +++++++++++-
|
||||
drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 2 ++
|
||||
2 files changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_csc.c
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
|
||||
@@ -69,7 +69,7 @@ static const u32 yuv2rgb[2][2][12] = {
|
||||
* c20 c21 c22 [d2 const2]
|
||||
*/
|
||||
|
||||
-static const u32 yuv2rgb_de3[2][2][12] = {
|
||||
+static const u32 yuv2rgb_de3[2][3][12] = {
|
||||
[DRM_COLOR_YCBCR_LIMITED_RANGE] = {
|
||||
[DRM_COLOR_YCBCR_BT601] = {
|
||||
0x0002542A, 0x00000000, 0x0003312A, 0xFFC00000,
|
||||
@@ -80,6 +80,11 @@ static const u32 yuv2rgb_de3[2][2][12] =
|
||||
0x0002542A, 0x00000000, 0x000395E2, 0xFFC00000,
|
||||
0x0002542A, 0xFFFF92D2, 0xFFFEEF27, 0xFE000000,
|
||||
0x0002542A, 0x0004398C, 0x00000000, 0xFE000000,
|
||||
+ },
|
||||
+ [DRM_COLOR_YCBCR_BT2020] = {
|
||||
+ 0x0002542A, 0x00000000, 0x00035B7B, 0xFFC00000,
|
||||
+ 0x0002542A, 0xFFFFA017, 0xFFFEB2FC, 0xFE000000,
|
||||
+ 0x0002542A, 0x00044896, 0x00000000, 0xFE000000,
|
||||
}
|
||||
},
|
||||
[DRM_COLOR_YCBCR_FULL_RANGE] = {
|
||||
@@ -92,6 +97,11 @@ static const u32 yuv2rgb_de3[2][2][12] =
|
||||
0x00020000, 0x00000000, 0x0003264C, 0x00000000,
|
||||
0x00020000, 0xFFFFA018, 0xFFFF1053, 0xFE000000,
|
||||
0x00020000, 0x0003B611, 0x00000000, 0xFE000000,
|
||||
+ },
|
||||
+ [DRM_COLOR_YCBCR_BT2020] = {
|
||||
+ 0x00020000, 0x00000000, 0x0002F2FE, 0x00000000,
|
||||
+ 0x00020000, 0xFFFFABC0, 0xFFFEDB78, 0xFE000000,
|
||||
+ 0x00020000, 0x0003C346, 0x00000000, 0xFE000000,
|
||||
}
|
||||
},
|
||||
};
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
|
||||
@@ -543,6 +543,8 @@ struct sun8i_vi_layer *sun8i_vi_layer_in
|
||||
|
||||
supported_encodings = BIT(DRM_COLOR_YCBCR_BT601) |
|
||||
BIT(DRM_COLOR_YCBCR_BT709);
|
||||
+ if (mixer->cfg->is_de3)
|
||||
+ supported_encodings |= BIT(DRM_COLOR_YCBCR_BT2020);
|
||||
|
||||
supported_ranges = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
|
||||
BIT(DRM_COLOR_YCBCR_FULL_RANGE);
|
@ -16,14 +16,13 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
@@ -126,6 +126,13 @@ static const struct cedrus_control cedru
|
||||
@@ -131,6 +131,12 @@ static const struct cedrus_control cedru
|
||||
},
|
||||
{
|
||||
.cfg = {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX,
|
||||
+ },
|
||||
+ .codec = CEDRUS_CODEC_H265,
|
||||
+ .required = true,
|
||||
+ },
|
||||
+ {
|
||||
+ .cfg = {
|
||||
@ -32,14 +31,14 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
.def = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED,
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -74,6 +74,7 @@ struct cedrus_h265_run {
|
||||
@@ -76,6 +76,7 @@ struct cedrus_h265_run {
|
||||
const struct v4l2_ctrl_hevc_sps *sps;
|
||||
const struct v4l2_ctrl_hevc_pps *pps;
|
||||
const struct v4l2_ctrl_hevc_slice_params *slice_params;
|
||||
+ const struct v4l2_ctrl_hevc_scaling_matrix *scaling_matrix;
|
||||
};
|
||||
|
||||
struct cedrus_run {
|
||||
struct cedrus_vp8_run {
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
|
||||
@@ -68,6 +68,8 @@ void cedrus_device_run(void *priv)
|
||||
@ -50,7 +49,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
+ V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX);
|
||||
break;
|
||||
|
||||
default:
|
||||
case V4L2_PIX_FMT_VP8_FRAME:
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
@@ -238,6 +238,69 @@ static void cedrus_h265_skip_bits(struct
|
||||
@ -139,7 +138,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
/* Neightbor information address. */
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
@@ -493,6 +493,8 @@
|
||||
@@ -494,6 +494,8 @@
|
||||
#define VE_DEC_H265_ENTRY_POINT_OFFSET_ADDR (VE_ENGINE_DEC_H265 + 0x64)
|
||||
#define VE_DEC_H265_TILE_START_CTB (VE_ENGINE_DEC_H265 + 0x68)
|
||||
#define VE_DEC_H265_TILE_END_CTB (VE_ENGINE_DEC_H265 + 0x6c)
|
@ -1,27 +0,0 @@
|
||||
From e689f3536e632e26166e66eac88728c6653a18b6 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Tue, 12 Jan 2021 23:24:21 -0600
|
||||
Subject: [PATCH 16/44] mmc: sunxi-mmc: Ensure host is suspended during system
|
||||
sleep
|
||||
|
||||
If the device suspend process begins before the mmc host's autosuspend
|
||||
timeout, the host will continue running during system sleep. Avoid
|
||||
this by forcing runtime suspend during a global suspend transition.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
Acked-by: Maxime Ripard <mripard@kernel.org>
|
||||
---
|
||||
drivers/mmc/host/sunxi-mmc.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/mmc/host/sunxi-mmc.c
|
||||
+++ b/drivers/mmc/host/sunxi-mmc.c
|
||||
@@ -1506,6 +1506,8 @@ static int sunxi_mmc_runtime_suspend(str
|
||||
#endif
|
||||
|
||||
static const struct dev_pm_ops sunxi_mmc_pm_ops = {
|
||||
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
|
||||
+ pm_runtime_force_resume)
|
||||
SET_RUNTIME_PM_OPS(sunxi_mmc_runtime_suspend,
|
||||
sunxi_mmc_runtime_resume,
|
||||
NULL)
|
@ -1,42 +0,0 @@
|
||||
From e019a54d084020e6acc2869da341b376700bfe4c Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Fri, 30 Oct 2020 15:46:44 +0100
|
||||
Subject: [PATCH 17/44] arm64: dts: allwinner: h6: Add I2S1 node
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add Allwinner H6 I2S1 node connected to HDMI interface.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Marcus Cooper <codekipper@gmail.com>
|
||||
Signed-off-by: Clément Péron <peron.clem@gmail.com>
|
||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
Acked-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Link: https://lore.kernel.org/r/20201030144648.397824-12-peron.clem@gmail.com
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -609,6 +609,19 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ i2s1: i2s@5091000 {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "allwinner,sun50i-h6-i2s";
|
||||
+ reg = <0x05091000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_I2S1>, <&ccu CLK_I2S1>;
|
||||
+ clock-names = "apb", "mod";
|
||||
+ dmas = <&dma 4>, <&dma 4>;
|
||||
+ resets = <&ccu RST_BUS_I2S1>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
spdif: spdif@5093000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun50i-h6-spdif";
|
@ -80,7 +80,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
@@ -332,6 +332,7 @@ static int cedrus_s_fmt_vid_out(struct f
|
||||
@@ -340,6 +340,7 @@ static int cedrus_s_fmt_vid_out(struct f
|
||||
|
||||
switch (ctx->src_fmt.pixelformat) {
|
||||
case V4L2_PIX_FMT_H264_SLICE:
|
@ -1,43 +0,0 @@
|
||||
From 0175a3d5680924d3d64ee8181b50c8b06ee715d1 Mon Sep 17 00:00:00 2001
|
||||
From: Marcus Cooper <codekipper@gmail.com>
|
||||
Date: Fri, 30 Oct 2020 15:46:45 +0100
|
||||
Subject: [PATCH 18/44] arm64: dts: allwinner: a64: Add I2S2 node
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add the I2S2 node connected to the HDMI interface.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Marcus Cooper <codekipper@gmail.com>
|
||||
Signed-off-by: Clément Péron <peron.clem@gmail.com>
|
||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
Acked-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Link: https://lore.kernel.org/r/20201030144648.397824-13-peron.clem@gmail.com
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
@@ -846,6 +846,20 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ i2s2: i2s@1c22800 {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "allwinner,sun50i-a64-i2s",
|
||||
+ "allwinner,sun8i-h3-i2s";
|
||||
+ reg = <0x01c22800 0x400>;
|
||||
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_I2S2>, <&ccu CLK_I2S2>;
|
||||
+ clock-names = "apb", "mod";
|
||||
+ resets = <&ccu RST_BUS_I2S2>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ dmas = <&dma 27>, <&dma 27>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
dai: dai@1c22c00 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun50i-a64-codec-i2s";
|
@ -12,15 +12,15 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -135,6 +135,8 @@ struct cedrus_ctx {
|
||||
@@ -142,6 +142,8 @@ struct cedrus_ctx {
|
||||
ssize_t mv_col_buf_unit_size;
|
||||
void *neighbor_info_buf;
|
||||
dma_addr_t neighbor_info_buf_addr;
|
||||
+ void *entry_points_buf;
|
||||
+ dma_addr_t entry_points_buf_addr;
|
||||
} h265;
|
||||
} codec;
|
||||
};
|
||||
struct {
|
||||
unsigned int last_frame_p_type;
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
@@ -301,6 +301,61 @@ static void cedrus_h265_write_scaling_li
|
@ -1,42 +0,0 @@
|
||||
From fd67e65487b4e5e2a93df2868043302a99f93098 Mon Sep 17 00:00:00 2001
|
||||
From: Marcus Cooper <codekipper@gmail.com>
|
||||
Date: Fri, 30 Oct 2020 15:46:48 +0100
|
||||
Subject: [PATCH 19/44] arm: dts: sunxi: h3/h5: Add I2S2 node
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add H3/H5 I2S2 node connected to the HDMI interface.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Marcus Cooper <codekipper@gmail.com>
|
||||
Signed-off-by: Clément Péron <peron.clem@gmail.com>
|
||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
Acked-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Link: https://lore.kernel.org/r/20201030144648.397824-16-peron.clem@gmail.com
|
||||
---
|
||||
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
@@ -662,6 +662,19 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ i2s2: i2s@1c22800 {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "allwinner,sun8i-h3-i2s";
|
||||
+ reg = <0x01c22800 0x400>;
|
||||
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_I2S2>, <&ccu CLK_I2S2>;
|
||||
+ clock-names = "apb", "mod";
|
||||
+ dmas = <&dma 27>;
|
||||
+ resets = <&ccu RST_BUS_I2S2>;
|
||||
+ dma-names = "tx";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
codec: codec@1c22c00 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun8i-h3-codec";
|
@ -11,7 +11,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -149,6 +149,7 @@ struct cedrus_dec_ops {
|
||||
@@ -164,6 +164,7 @@ struct cedrus_dec_ops {
|
||||
int (*start)(struct cedrus_ctx *ctx);
|
||||
void (*stop)(struct cedrus_ctx *ctx);
|
||||
void (*trigger)(struct cedrus_ctx *ctx);
|
||||
@ -21,7 +21,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
struct cedrus_variant {
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
@@ -455,6 +455,18 @@ static int cedrus_buf_prepare(struct vb2
|
||||
@@ -463,6 +463,18 @@ static int cedrus_buf_prepare(struct vb2
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
static int cedrus_start_streaming(struct vb2_queue *vq, unsigned int count)
|
||||
{
|
||||
struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
|
||||
@@ -535,6 +547,7 @@ static void cedrus_buf_request_complete(
|
||||
@@ -547,6 +559,7 @@ static void cedrus_buf_request_complete(
|
||||
static struct vb2_ops cedrus_qops = {
|
||||
.queue_setup = cedrus_queue_setup,
|
||||
.buf_prepare = cedrus_buf_prepare,
|
@ -1,47 +0,0 @@
|
||||
From 3c970c9e87e403b190407dec5c6e4745aef78e6a Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Fri, 30 Oct 2020 18:25:30 +0100
|
||||
Subject: [PATCH 20/44] arm64: dts: allwinner: h6: PineH64 model B: Add wifi
|
||||
|
||||
PineH64 model B contains RTL8723CS wifi+bt combo module.
|
||||
|
||||
Since bluetooth support is not yet squared away, only wifi is enabled
|
||||
for now.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
Tested-by: <clabbe.montjoie@gmail.com>
|
||||
Acked-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Link: https://lore.kernel.org/r/20201030172530.1096394-1-jernej.skrabec@siol.net
|
||||
---
|
||||
.../dts/allwinner/sun50i-h6-pine-h64-model-b.dts | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts
|
||||
@@ -10,6 +10,12 @@
|
||||
compatible = "pine64,pine-h64-model-b", "allwinner,sun50i-h6";
|
||||
|
||||
/delete-node/ reg_gmac_3v3;
|
||||
+
|
||||
+ wifi_pwrseq: wifi_pwrseq {
|
||||
+ compatible = "mmc-pwrseq-simple";
|
||||
+ reset-gpios = <&r_pio 1 3 GPIO_ACTIVE_LOW>; /* PM3 */
|
||||
+ post-power-on-delay-ms = <200>;
|
||||
+ };
|
||||
};
|
||||
|
||||
&hdmi_connector {
|
||||
@@ -19,3 +25,12 @@
|
||||
&emac {
|
||||
phy-supply = <®_aldo2>;
|
||||
};
|
||||
+
|
||||
+&mmc1 {
|
||||
+ vmmc-supply = <®_cldo3>;
|
||||
+ vqmmc-supply = <®_aldo1>;
|
||||
+ mmc-pwrseq = <&wifi_pwrseq>;
|
||||
+ bus-width = <4>;
|
||||
+ non-removable;
|
||||
+ status = "okay";
|
||||
+};
|
@ -11,7 +11,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -96,6 +96,11 @@ struct cedrus_buffer {
|
||||
@@ -103,6 +103,11 @@ struct cedrus_buffer {
|
||||
unsigned int position;
|
||||
enum cedrus_h264_pic_type pic_type;
|
||||
} h264;
|
||||
@ -23,7 +23,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
} codec;
|
||||
};
|
||||
|
||||
@@ -129,10 +134,6 @@ struct cedrus_ctx {
|
||||
@@ -136,10 +141,6 @@ struct cedrus_ctx {
|
||||
ssize_t intra_pred_buf_size;
|
||||
} h264;
|
||||
struct {
|
@ -11,7 +11,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -95,6 +95,9 @@ struct cedrus_buffer {
|
||||
@@ -102,6 +102,9 @@ struct cedrus_buffer {
|
||||
struct {
|
||||
unsigned int position;
|
||||
enum cedrus_h264_pic_type pic_type;
|
@ -14,7 +14,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
@@ -301,7 +301,7 @@ static int cedrus_open(struct file *file
|
||||
@@ -277,7 +277,7 @@ static int cedrus_open(struct file *file
|
||||
goto err_ctrls;
|
||||
}
|
||||
ctx->dst_fmt.pixelformat = V4L2_PIX_FMT_SUNXI_TILED_NV12;
|
||||
@ -23,7 +23,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
ctx->src_fmt.pixelformat = V4L2_PIX_FMT_MPEG2_SLICE;
|
||||
/*
|
||||
* TILED_NV12 has more strict requirements, so copy the width and
|
||||
@@ -309,7 +309,7 @@ static int cedrus_open(struct file *file
|
||||
@@ -285,7 +285,7 @@ static int cedrus_open(struct file *file
|
||||
*/
|
||||
ctx->src_fmt.width = ctx->dst_fmt.width;
|
||||
ctx->src_fmt.height = ctx->dst_fmt.height;
|
||||
@ -55,7 +55,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
reg = VE_DEC_H265_DEC_PPS_CTRL0_PPS_CR_QP_OFFSET(pps->pps_cr_qp_offset) |
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
@@ -498,6 +498,10 @@
|
||||
@@ -499,6 +499,10 @@
|
||||
|
||||
#define VE_DEC_H265_LOW_ADDR (VE_ENGINE_DEC_H265 + 0x80)
|
||||
|
||||
@ -68,7 +68,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
#define VE_DEC_H265_LOW_ADDR_SECONDARY_CHROMA(a) \
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
@@ -93,7 +93,7 @@ static struct cedrus_format *cedrus_find
|
||||
@@ -100,7 +100,7 @@ static struct cedrus_format *cedrus_find
|
||||
return &cedrus_formats[i];
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
{
|
||||
unsigned int width = pix_fmt->width;
|
||||
unsigned int height = pix_fmt->height;
|
||||
@@ -147,6 +147,17 @@ void cedrus_prepare_format(struct v4l2_p
|
||||
@@ -155,6 +155,17 @@ void cedrus_prepare_format(struct v4l2_p
|
||||
break;
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
pix_fmt->width = width;
|
||||
pix_fmt->height = height;
|
||||
|
||||
@@ -239,17 +250,27 @@ static int cedrus_try_fmt_vid_cap(struct
|
||||
@@ -247,17 +258,27 @@ static int cedrus_try_fmt_vid_cap(struct
|
||||
struct cedrus_ctx *ctx = cedrus_file2ctx(file);
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
struct v4l2_pix_format *pix_fmt = &f->fmt.pix;
|
||||
@ -124,7 +124,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -267,8 +288,7 @@ static int cedrus_try_fmt_vid_out(struct
|
||||
@@ -275,8 +296,7 @@ static int cedrus_try_fmt_vid_out(struct
|
||||
if (!fmt)
|
||||
return -EINVAL;
|
||||
|
||||
@ -134,7 +134,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -349,7 +369,7 @@ static int cedrus_s_fmt_vid_out(struct f
|
||||
@@ -357,7 +377,7 @@ static int cedrus_s_fmt_vid_out(struct f
|
||||
ctx->dst_fmt.quantization = f->fmt.pix.quantization;
|
||||
ctx->dst_fmt.width = ctx->src_fmt.width;
|
||||
ctx->dst_fmt.height = ctx->src_fmt.height;
|
@ -17,7 +17,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
+static int cedrus_try_ctrl(struct v4l2_ctrl *ctrl)
|
||||
+{
|
||||
+ if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_SPS) {
|
||||
+ if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) {
|
||||
+ const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
|
||||
+
|
||||
+ if (sps->chroma_format_idc != 1)
|
||||
@ -62,39 +62,39 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
static const struct cedrus_control cedrus_controls[] = {
|
||||
{
|
||||
.cfg = {
|
||||
@@ -60,6 +104,7 @@ static const struct cedrus_control cedru
|
||||
@@ -56,6 +100,7 @@ static const struct cedrus_control cedru
|
||||
{
|
||||
.cfg = {
|
||||
.id = V4L2_CID_MPEG_VIDEO_H264_SPS,
|
||||
.id = V4L2_CID_STATELESS_H264_SPS,
|
||||
+ .ops = &cedrus_ctrl_ops,
|
||||
},
|
||||
.codec = CEDRUS_CODEC_H264,
|
||||
.required = true,
|
||||
@@ -106,6 +151,7 @@ static const struct cedrus_control cedru
|
||||
},
|
||||
@@ -114,6 +159,7 @@ static const struct cedrus_control cedru
|
||||
{
|
||||
.cfg = {
|
||||
.id = V4L2_CID_MPEG_VIDEO_HEVC_SPS,
|
||||
+ .ops = &cedrus_ctrl_ops,
|
||||
},
|
||||
.codec = CEDRUS_CODEC_H265,
|
||||
.required = true,
|
||||
@@ -534,7 +580,8 @@ static const struct cedrus_variant sun50
|
||||
|
||||
static const struct cedrus_variant sun50i_h6_cedrus_variant = {
|
||||
.capabilities = CEDRUS_CAPABILITY_UNTILED |
|
||||
- CEDRUS_CAPABILITY_H265_DEC,
|
||||
},
|
||||
@@ -544,7 +590,8 @@ static const struct cedrus_variant sun50
|
||||
CEDRUS_CAPABILITY_MPEG2_DEC |
|
||||
CEDRUS_CAPABILITY_H264_DEC |
|
||||
CEDRUS_CAPABILITY_H265_DEC |
|
||||
- CEDRUS_CAPABILITY_VP8_DEC,
|
||||
+ CEDRUS_CAPABILITY_H265_DEC |
|
||||
+ CEDRUS_CAPABILITY_H265_10_DEC,
|
||||
.quirks = CEDRUS_QUIRK_NO_DMA_OFFSET,
|
||||
.mod_rate = 600000000,
|
||||
};
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#define CEDRUS_CAPABILITY_UNTILED BIT(0)
|
||||
#define CEDRUS_CAPABILITY_H265_DEC BIT(1)
|
||||
+#define CEDRUS_CAPABILITY_H265_10_DEC BIT(2)
|
||||
|
||||
#define CEDRUS_QUIRK_NO_DMA_OFFSET BIT(0)
|
||||
@@ -32,6 +32,7 @@
|
||||
#define CEDRUS_CAPABILITY_H264_DEC BIT(2)
|
||||
#define CEDRUS_CAPABILITY_MPEG2_DEC BIT(3)
|
||||
#define CEDRUS_CAPABILITY_VP8_DEC BIT(4)
|
||||
+#define CEDRUS_CAPABILITY_H265_10_DEC BIT(5)
|
||||
|
||||
enum cedrus_codec {
|
||||
CEDRUS_CODEC_MPEG2,
|
@ -152,10 +152,10 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
+ mixer->channel_zpos[channel] = enable ? zpos : -1;
|
||||
}
|
||||
|
||||
static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
|
||||
@@ -267,11 +240,9 @@ static void sun8i_ui_layer_atomic_disabl
|
||||
struct drm_plane_state *old_state)
|
||||
{
|
||||
static void sun8i_ui_layer_update_alpha(struct sun8i_mixer *mixer, int channel,
|
||||
@@ -294,11 +267,9 @@ static void sun8i_ui_layer_atomic_disabl
|
||||
struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
|
||||
plane);
|
||||
struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
|
||||
- unsigned int old_zpos = old_state->normalized_zpos;
|
||||
struct sun8i_mixer *mixer = layer->mixer;
|
||||
@ -166,21 +166,21 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
}
|
||||
|
||||
static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
|
||||
@@ -279,12 +250,11 @@ static void sun8i_ui_layer_atomic_update
|
||||
{
|
||||
@@ -310,12 +281,11 @@ static void sun8i_ui_layer_atomic_update
|
||||
plane);
|
||||
struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
|
||||
unsigned int zpos = plane->state->normalized_zpos;
|
||||
unsigned int zpos = new_state->normalized_zpos;
|
||||
- unsigned int old_zpos = old_state->normalized_zpos;
|
||||
struct sun8i_mixer *mixer = layer->mixer;
|
||||
|
||||
if (!plane->state->visible) {
|
||||
if (!new_state->visible) {
|
||||
sun8i_ui_layer_enable(mixer, layer->channel,
|
||||
- layer->overlay, false, 0, old_zpos);
|
||||
+ layer->overlay, false, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -295,7 +265,7 @@ static void sun8i_ui_layer_atomic_update
|
||||
@@ -328,7 +298,7 @@ static void sun8i_ui_layer_atomic_update
|
||||
sun8i_ui_layer_update_buffer(mixer, layer->channel,
|
||||
layer->overlay, plane);
|
||||
sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay,
|
||||
@ -234,10 +234,10 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
+ mixer->channel_zpos[channel] = enable ? zpos : -1;
|
||||
}
|
||||
|
||||
static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
|
||||
@@ -370,11 +344,9 @@ static void sun8i_vi_layer_atomic_disabl
|
||||
struct drm_plane_state *old_state)
|
||||
{
|
||||
static void sun8i_vi_layer_update_alpha(struct sun8i_mixer *mixer, int channel,
|
||||
@@ -398,11 +372,9 @@ static void sun8i_vi_layer_atomic_disabl
|
||||
struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
|
||||
plane);
|
||||
struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
|
||||
- unsigned int old_zpos = old_state->normalized_zpos;
|
||||
struct sun8i_mixer *mixer = layer->mixer;
|
||||
@ -248,21 +248,21 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
}
|
||||
|
||||
static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
|
||||
@@ -382,12 +354,11 @@ static void sun8i_vi_layer_atomic_update
|
||||
{
|
||||
@@ -414,12 +386,11 @@ static void sun8i_vi_layer_atomic_update
|
||||
plane);
|
||||
struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
|
||||
unsigned int zpos = plane->state->normalized_zpos;
|
||||
unsigned int zpos = new_state->normalized_zpos;
|
||||
- unsigned int old_zpos = old_state->normalized_zpos;
|
||||
struct sun8i_mixer *mixer = layer->mixer;
|
||||
|
||||
if (!plane->state->visible) {
|
||||
if (!new_state->visible) {
|
||||
sun8i_vi_layer_enable(mixer, layer->channel,
|
||||
- layer->overlay, false, 0, old_zpos);
|
||||
+ layer->overlay, false, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -398,7 +369,7 @@ static void sun8i_vi_layer_atomic_update
|
||||
@@ -432,7 +403,7 @@ static void sun8i_vi_layer_atomic_update
|
||||
sun8i_vi_layer_update_buffer(mixer, layer->channel,
|
||||
layer->overlay, plane);
|
||||
sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay,
|
@ -17,7 +17,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
--- a/drivers/media/platform/Kconfig
|
||||
+++ b/drivers/media/platform/Kconfig
|
||||
@@ -510,6 +510,19 @@ config VIDEO_QCOM_VENUS
|
||||
@@ -574,6 +574,19 @@ config VIDEO_QCOM_VENUS
|
||||
on various Qualcomm SoCs.
|
||||
To compile this driver as a module choose m here.
|
||||
|
@ -10,7 +10,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -153,6 +153,17 @@
|
||||
@@ -160,6 +160,17 @@
|
||||
};
|
||||
};
|
||||
|
@ -230,7 +230,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_SEL_REG,
|
||||
SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
|
||||
SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset));
|
||||
@@ -1198,8 +1239,14 @@ static const struct reg_default sun8i_i2
|
||||
@@ -1196,8 +1237,14 @@ static const struct reg_default sun8i_i2
|
||||
{ SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
|
||||
{ SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
|
||||
{ SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
|
||||
@ -247,7 +247,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
{ SUN8I_I2S_RX_CHAN_SEL_REG, 0x00000000 },
|
||||
{ SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 },
|
||||
};
|
||||
@@ -1212,9 +1259,18 @@ static const struct reg_default sun50i_h
|
||||
@@ -1210,9 +1257,18 @@ static const struct reg_default sun50i_h
|
||||
{ SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
|
||||
{ SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
|
||||
{ SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
|
||||
@ -269,7 +269,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
{ SUN50I_H6_I2S_RX_CHAN_SEL_REG, 0x00000000 },
|
||||
{ SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0x00000000 },
|
||||
{ SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x00000000 },
|
||||
@@ -1287,7 +1343,7 @@ static int sun4i_i2s_runtime_resume(stru
|
||||
@@ -1285,7 +1341,7 @@ static int sun4i_i2s_runtime_resume(stru
|
||||
/* Enable the first output line */
|
||||
regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
|
||||
SUN4I_I2S_CTRL_SDO_EN_MASK,
|
||||
@ -278,7 +278,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
ret = clk_prepare_enable(i2s->mod_clk);
|
||||
if (ret) {
|
||||
@@ -1529,6 +1585,7 @@ static int sun4i_i2s_probe(struct platfo
|
||||
@@ -1527,6 +1583,7 @@ static int sun4i_i2s_probe(struct platfo
|
||||
|
||||
i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
|
||||
i2s->capture_dma_data.maxburst = 8;
|
@ -1,985 +0,0 @@
|
||||
From 574ba48fa87225fbf3e39ffd2b11a6fb93cb6c98 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Wed, 20 May 2020 23:01:29 +0200
|
||||
Subject: [PATCH 33/44] media: cedrus: Add support for VP8 decoding
|
||||
|
||||
VP8 in Cedrus shares same engine as H264.
|
||||
|
||||
Note that it seems necessary to call bitstream parsing functions,
|
||||
to parse frame header, otherwise decoded image is garbage. This is
|
||||
contrary to what is driver supposed to do. However, values are not
|
||||
really used, so this might be acceptable. It's possible that bitstream
|
||||
parsing functions set some internal VPU state, which is later necessary
|
||||
for proper decoding. Biggest suspect is "VP8 probs update" trigger.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/Makefile | 3 +-
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.c | 8 +
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.h | 15 +
|
||||
.../staging/media/sunxi/cedrus/cedrus_dec.c | 5 +
|
||||
.../staging/media/sunxi/cedrus/cedrus_hw.c | 1 +
|
||||
.../staging/media/sunxi/cedrus/cedrus_regs.h | 80 ++
|
||||
.../staging/media/sunxi/cedrus/cedrus_video.c | 9 +
|
||||
.../staging/media/sunxi/cedrus/cedrus_vp8.c | 699 ++++++++++++++++++
|
||||
8 files changed, 819 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_vp8.c
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/Makefile
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/Makefile
|
||||
@@ -2,4 +2,5 @@
|
||||
obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += sunxi-cedrus.o
|
||||
|
||||
sunxi-cedrus-y = cedrus.o cedrus_video.o cedrus_hw.o cedrus_dec.o \
|
||||
- cedrus_mpeg2.o cedrus_h264.o cedrus_h265.o
|
||||
+ cedrus_mpeg2.o cedrus_h264.o cedrus_h265.o \
|
||||
+ cedrus_vp8.o
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
@@ -195,6 +195,13 @@ static const struct cedrus_control cedru
|
||||
.codec = CEDRUS_CODEC_H265,
|
||||
.required = false,
|
||||
},
|
||||
+ {
|
||||
+ .cfg = {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER,
|
||||
+ },
|
||||
+ .codec = CEDRUS_CODEC_VP8,
|
||||
+ .required = true,
|
||||
+ },
|
||||
};
|
||||
|
||||
#define CEDRUS_CONTROLS_COUNT ARRAY_SIZE(cedrus_controls)
|
||||
@@ -446,6 +453,7 @@ static int cedrus_probe(struct platform_
|
||||
dev->dec_ops[CEDRUS_CODEC_MPEG2] = &cedrus_dec_ops_mpeg2;
|
||||
dev->dec_ops[CEDRUS_CODEC_H264] = &cedrus_dec_ops_h264;
|
||||
dev->dec_ops[CEDRUS_CODEC_H265] = &cedrus_dec_ops_h265;
|
||||
+ dev->dec_ops[CEDRUS_CODEC_VP8] = &cedrus_dec_ops_vp8;
|
||||
|
||||
mutex_init(&dev->dev_mutex);
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -36,6 +36,7 @@ enum cedrus_codec {
|
||||
CEDRUS_CODEC_MPEG2,
|
||||
CEDRUS_CODEC_H264,
|
||||
CEDRUS_CODEC_H265,
|
||||
+ CEDRUS_CODEC_VP8,
|
||||
CEDRUS_CODEC_LAST,
|
||||
};
|
||||
|
||||
@@ -78,6 +79,10 @@ struct cedrus_h265_run {
|
||||
const struct v4l2_ctrl_hevc_scaling_matrix *scaling_matrix;
|
||||
};
|
||||
|
||||
+struct cedrus_vp8_run {
|
||||
+ const struct v4l2_ctrl_vp8_frame_header *slice_params;
|
||||
+};
|
||||
+
|
||||
struct cedrus_run {
|
||||
struct vb2_v4l2_buffer *src;
|
||||
struct vb2_v4l2_buffer *dst;
|
||||
@@ -86,6 +91,7 @@ struct cedrus_run {
|
||||
struct cedrus_h264_run h264;
|
||||
struct cedrus_mpeg2_run mpeg2;
|
||||
struct cedrus_h265_run h265;
|
||||
+ struct cedrus_vp8_run vp8;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -143,6 +149,14 @@ struct cedrus_ctx {
|
||||
void *entry_points_buf;
|
||||
dma_addr_t entry_points_buf_addr;
|
||||
} h265;
|
||||
+ struct {
|
||||
+ unsigned int last_frame_p_type;
|
||||
+ unsigned int last_filter_type;
|
||||
+ unsigned int last_sharpness_level;
|
||||
+
|
||||
+ u8 *entropy_probs_buf;
|
||||
+ dma_addr_t entropy_probs_buf_dma;
|
||||
+ } vp8;
|
||||
} codec;
|
||||
};
|
||||
|
||||
@@ -190,6 +204,7 @@ struct cedrus_dev {
|
||||
extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2;
|
||||
extern struct cedrus_dec_ops cedrus_dec_ops_h264;
|
||||
extern struct cedrus_dec_ops cedrus_dec_ops_h265;
|
||||
+extern struct cedrus_dec_ops cedrus_dec_ops_vp8;
|
||||
|
||||
static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val)
|
||||
{
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
|
||||
@@ -72,6 +72,11 @@ void cedrus_device_run(void *priv)
|
||||
V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX);
|
||||
break;
|
||||
|
||||
+ case V4L2_PIX_FMT_VP8_FRAME:
|
||||
+ run.vp8.slice_params = cedrus_find_control_data(ctx,
|
||||
+ V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER);
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
break;
|
||||
}
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
||||
@@ -48,6 +48,7 @@ int cedrus_engine_enable(struct cedrus_c
|
||||
break;
|
||||
|
||||
case CEDRUS_CODEC_H264:
|
||||
+ case CEDRUS_CODEC_VP8:
|
||||
reg |= VE_MODE_DEC_H264;
|
||||
break;
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
@@ -552,6 +552,7 @@
|
||||
#define VE_H264_SHS_QP_SCALING_MATRIX_DEFAULT BIT(24)
|
||||
|
||||
#define VE_H264_CTRL 0x220
|
||||
+#define VE_H264_CTRL_VP8 BIT(29)
|
||||
#define VE_H264_CTRL_VLD_DATA_REQ_INT BIT(2)
|
||||
#define VE_H264_CTRL_DECODE_ERR_INT BIT(1)
|
||||
#define VE_H264_CTRL_SLICE_DECODE_INT BIT(0)
|
||||
@@ -561,7 +562,12 @@
|
||||
VE_H264_CTRL_SLICE_DECODE_INT)
|
||||
|
||||
#define VE_H264_TRIGGER_TYPE 0x224
|
||||
+#define VE_H264_TRIGGER_TYPE_PROBABILITY(x) SHIFT_AND_MASK_BITS(x, 31, 24)
|
||||
+#define VE_H264_TRIGGER_TYPE_BIN_LENS(x) SHIFT_AND_MASK_BITS((x) - 1, 18, 16)
|
||||
#define VE_H264_TRIGGER_TYPE_N_BITS(x) (((x) & 0x3f) << 8)
|
||||
+#define VE_H264_TRIGGER_TYPE_VP8_GET_BITS (15 << 0)
|
||||
+#define VE_H264_TRIGGER_TYPE_VP8_UPDATE_COEF (14 << 0)
|
||||
+#define VE_H264_TRIGGER_TYPE_VP8_SLICE_DECODE (10 << 0)
|
||||
#define VE_H264_TRIGGER_TYPE_AVC_SLICE_DECODE (8 << 0)
|
||||
#define VE_H264_TRIGGER_TYPE_INIT_SWDEC (7 << 0)
|
||||
#define VE_H264_TRIGGER_TYPE_FLUSH_BITS (3 << 0)
|
||||
@@ -571,6 +577,7 @@
|
||||
#define VE_H264_STATUS_DECODE_ERR_INT VE_H264_CTRL_DECODE_ERR_INT
|
||||
#define VE_H264_STATUS_SLICE_DECODE_INT VE_H264_CTRL_SLICE_DECODE_INT
|
||||
#define VE_H264_STATUS_VLD_BUSY BIT(8)
|
||||
+#define VE_H264_STATUS_VP8_UPPROB_BUSY BIT(17)
|
||||
|
||||
#define VE_H264_STATUS_INT_MASK VE_H264_CTRL_INT_MASK
|
||||
|
||||
@@ -589,10 +596,83 @@
|
||||
#define VE_H264_OUTPUT_FRAME_IDX 0x24c
|
||||
#define VE_H264_EXTRA_BUFFER1 0x250
|
||||
#define VE_H264_EXTRA_BUFFER2 0x254
|
||||
+#define VE_H264_MB_ADDR 0x260
|
||||
+#define VE_H264_ERROR_CASE 0x2b8
|
||||
#define VE_H264_BASIC_BITS 0x2dc
|
||||
#define VE_AVC_SRAM_PORT_OFFSET 0x2e0
|
||||
#define VE_AVC_SRAM_PORT_DATA 0x2e4
|
||||
|
||||
+#define VE_VP8_PPS 0x214
|
||||
+#define VE_VP8_PPS_PIC_TYPE_P_FRAME BIT(31)
|
||||
+#define VE_VP8_PPS_LAST_SHARPNESS_LEVEL(v) SHIFT_AND_MASK_BITS(v, 30, 28)
|
||||
+#define VE_VP8_PPS_LAST_PIC_TYPE_P_FRAME BIT(27)
|
||||
+#define VE_VP8_PPS_ALTREF_SIGN_BIAS BIT(26)
|
||||
+#define VE_VP8_PPS_GOLDEN_SIGN_BIAS BIT(25)
|
||||
+#define VE_VP8_PPS_RELOAD_ENTROPY_PROBS BIT(24)
|
||||
+#define VE_VP8_PPS_REFRESH_ENTROPY_PROBS BIT(23)
|
||||
+#define VE_VP8_PPS_MB_NO_COEFF_SKIP BIT(22)
|
||||
+#define VE_VP8_PPS_TOKEN_PARTITION(v) SHIFT_AND_MASK_BITS(v, 21, 20)
|
||||
+#define VE_VP8_PPS_MODE_REF_LF_DELTA_UPDATE BIT(19)
|
||||
+#define VE_VP8_PPS_MODE_REF_LF_DELTA_ENABLE BIT(18)
|
||||
+#define VE_VP8_PPS_LOOP_FILTER_LEVEL(v) SHIFT_AND_MASK_BITS(v, 17, 12)
|
||||
+#define VE_VP8_PPS_LOOP_FILTER_SIMPLE BIT(11)
|
||||
+#define VE_VP8_PPS_SHARPNESS_LEVEL(v) SHIFT_AND_MASK_BITS(v, 10, 8)
|
||||
+#define VE_VP8_PPS_LAST_LOOP_FILTER_SIMPLE BIT(7)
|
||||
+#define VE_VP8_PPS_SEGMENTATION_ENABLE BIT(6)
|
||||
+#define VE_VP8_PPS_MB_SEGMENT_ABS_DELTA BIT(5)
|
||||
+#define VE_VP8_PPS_UPDATE_MB_SEGMENTATION_MAP BIT(4)
|
||||
+#define VE_VP8_PPS_FULL_PIXEL BIT(3)
|
||||
+#define VE_VP8_PPS_BILINEAR_MC_FILTER BIT(2)
|
||||
+#define VE_VP8_PPS_FILTER_TYPE_SIMPLE BIT(1)
|
||||
+#define VE_VP8_PPS_LPF_DISABLE BIT(0)
|
||||
+
|
||||
+#define VE_VP8_QP_INDEX_DELTA 0x218
|
||||
+#define VE_VP8_QP_INDEX_DELTA_UVAC(v) SHIFT_AND_MASK_BITS(v, 31, 27)
|
||||
+#define VE_VP8_QP_INDEX_DELTA_UVDC(v) SHIFT_AND_MASK_BITS(v, 26, 22)
|
||||
+#define VE_VP8_QP_INDEX_DELTA_Y2AC(v) SHIFT_AND_MASK_BITS(v, 21, 17)
|
||||
+#define VE_VP8_QP_INDEX_DELTA_Y2DC(v) SHIFT_AND_MASK_BITS(v, 16, 12)
|
||||
+#define VE_VP8_QP_INDEX_DELTA_Y1DC(v) SHIFT_AND_MASK_BITS(v, 11, 7)
|
||||
+#define VE_VP8_QP_INDEX_DELTA_BASE_QINDEX(v) SHIFT_AND_MASK_BITS(v, 6, 0)
|
||||
+
|
||||
+#define VE_VP8_PART_SIZE_OFFSET 0x21c
|
||||
+#define VE_VP8_ENTROPY_PROBS_ADDR 0x250
|
||||
+#define VE_VP8_FIRST_DATA_PART_LEN 0x254
|
||||
+
|
||||
+#define VE_VP8_FSIZE 0x258
|
||||
+#define VE_VP8_FSIZE_WIDTH(w) \
|
||||
+ SHIFT_AND_MASK_BITS(DIV_ROUND_UP(w, 16), 15, 8)
|
||||
+#define VE_VP8_FSIZE_HEIGHT(h) \
|
||||
+ SHIFT_AND_MASK_BITS(DIV_ROUND_UP(h, 16), 7, 0)
|
||||
+
|
||||
+#define VE_VP8_PICSIZE 0x25c
|
||||
+#define VE_VP8_PICSIZE_WIDTH(w) SHIFT_AND_MASK_BITS(w, 27, 16)
|
||||
+#define VE_VP8_PICSIZE_HEIGHT(h) SHIFT_AND_MASK_BITS(h, 11, 0)
|
||||
+
|
||||
+#define VE_VP8_REC_LUMA 0x2ac
|
||||
+#define VE_VP8_FWD_LUMA 0x2b0
|
||||
+#define VE_VP8_BWD_LUMA 0x2b4
|
||||
+#define VE_VP8_REC_CHROMA 0x2d0
|
||||
+#define VE_VP8_FWD_CHROMA 0x2d4
|
||||
+#define VE_VP8_BWD_CHROMA 0x2d8
|
||||
+#define VE_VP8_ALT_LUMA 0x2e8
|
||||
+#define VE_VP8_ALT_CHROMA 0x2ec
|
||||
+
|
||||
+#define VE_VP8_SEGMENT_FEAT_MB_LV0 0x2f0
|
||||
+#define VE_VP8_SEGMENT_FEAT_MB_LV1 0x2f4
|
||||
+
|
||||
+#define VE_VP8_SEGMENT3(v) SHIFT_AND_MASK_BITS(v, 31, 24)
|
||||
+#define VE_VP8_SEGMENT2(v) SHIFT_AND_MASK_BITS(v, 23, 16)
|
||||
+#define VE_VP8_SEGMENT1(v) SHIFT_AND_MASK_BITS(v, 15, 8)
|
||||
+#define VE_VP8_SEGMENT0(v) SHIFT_AND_MASK_BITS(v, 7, 0)
|
||||
+
|
||||
+#define VE_VP8_REF_LF_DELTA 0x2f8
|
||||
+#define VE_VP8_MODE_LF_DELTA 0x2fc
|
||||
+
|
||||
+#define VE_VP8_LF_DELTA3(v) SHIFT_AND_MASK_BITS(v, 30, 24)
|
||||
+#define VE_VP8_LF_DELTA2(v) SHIFT_AND_MASK_BITS(v, 22, 16)
|
||||
+#define VE_VP8_LF_DELTA1(v) SHIFT_AND_MASK_BITS(v, 14, 8)
|
||||
+#define VE_VP8_LF_DELTA0(v) SHIFT_AND_MASK_BITS(v, 6, 0)
|
||||
+
|
||||
#define VE_ISP_INPUT_SIZE 0xa00
|
||||
#define VE_ISP_INPUT_STRIDE 0xa04
|
||||
#define VE_ISP_CTRL 0xa08
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
@@ -49,6 +49,10 @@ static struct cedrus_format cedrus_forma
|
||||
.capabilities = CEDRUS_CAPABILITY_H265_DEC,
|
||||
},
|
||||
{
|
||||
+ .pixelformat = V4L2_PIX_FMT_VP8_FRAME,
|
||||
+ .directions = CEDRUS_DECODE_SRC,
|
||||
+ },
|
||||
+ {
|
||||
.pixelformat = V4L2_PIX_FMT_SUNXI_TILED_NV12,
|
||||
.directions = CEDRUS_DECODE_DST,
|
||||
},
|
||||
@@ -110,6 +114,7 @@ void cedrus_prepare_format(struct v4l2_p
|
||||
case V4L2_PIX_FMT_MPEG2_SLICE:
|
||||
case V4L2_PIX_FMT_H264_SLICE:
|
||||
case V4L2_PIX_FMT_HEVC_SLICE:
|
||||
+ case V4L2_PIX_FMT_VP8_FRAME:
|
||||
/* Zero bytes per line for encoded source. */
|
||||
bytesperline = 0;
|
||||
/* Choose some minimum size since this can't be 0 */
|
||||
@@ -506,6 +511,10 @@ static int cedrus_start_streaming(struct
|
||||
ctx->current_codec = CEDRUS_CODEC_H265;
|
||||
break;
|
||||
|
||||
+ case V4L2_PIX_FMT_VP8_FRAME:
|
||||
+ ctx->current_codec = CEDRUS_CODEC_VP8;
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
--- /dev/null
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_vp8.c
|
||||
@@ -0,0 +1,699 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * Cedrus VPU driver
|
||||
+ *
|
||||
+ * Copyright (c) 2019 Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
+#include <media/videobuf2-dma-contig.h>
|
||||
+
|
||||
+#include "cedrus.h"
|
||||
+#include "cedrus_hw.h"
|
||||
+#include "cedrus_regs.h"
|
||||
+
|
||||
+#define CEDRUS_ENTROPY_PROBS_SIZE 0x2400
|
||||
+#define VP8_PROB_HALF 128
|
||||
+
|
||||
+static const u8 prob_table_init[] = {
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xB0, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xF1, 0xFC, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xF9, 0xFD, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF4, 0xFC, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xEA, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xF6, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xEF, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFE, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0xFF, 0xFE, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFD, 0xFE, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFB, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFE, 0xFD, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFA, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xE1, 0xFC, 0xF1, 0xFD, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xEA, 0xFA, 0xF1, 0xFA, 0xFD, 0xFF, 0xFD, 0xFE,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0xFD, 0xFE, 0xFE,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xFE, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFD, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xF7, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFD, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xBA, 0xFB, 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xFB, 0xF4, 0xFE,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFB, 0xFB, 0xF3, 0xFD, 0xFE, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFD, 0xFE, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xEC, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFB, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFA, 0xFE, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFE, 0xF9, 0xFD,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFD, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6, 0xFD, 0xFD, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFC, 0xFE, 0xFB, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFC, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xF8, 0xFE, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xF5, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFE, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFB, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFD, 0xFE, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xF9, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x9C, 0xA3, 0x80,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x6F, 0x96, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x78, 0x5A, 0x4F, 0x85, 0x57, 0x55, 0x50, 0x6F,
|
||||
+ 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x93, 0x88, 0x12, 0x00, 0x6A, 0x91, 0x01, 0x00, 0xB3, 0x79, 0x01, 0x00,
|
||||
+ 0xDF, 0x01, 0x22, 0x00, 0xD0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x01, 0x8F,
|
||||
+ 0x0E, 0x12, 0x0E, 0x6B, 0x87, 0x40, 0x39, 0x44, 0x3C, 0x38, 0x80, 0x41,
|
||||
+ 0x9F, 0x86, 0x80, 0x22, 0xEA, 0xBC, 0x80, 0x1C, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x84, 0x02, 0x04, 0x06, 0x80, 0x81, 0x82, 0x83, 0x80, 0x02, 0x04, 0x06,
|
||||
+ 0x81, 0x82, 0x83, 0x84, 0x80, 0x02, 0x81, 0x04, 0x82, 0x83, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08,
|
||||
+ 0x04, 0x06, 0x80, 0x81, 0x82, 0x83, 0x0A, 0x0C, 0x84, 0x85, 0x86, 0x87,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x04, 0x06, 0x80, 0x81,
|
||||
+ 0x82, 0x83, 0x0A, 0x0C, 0x84, 0x85, 0x86, 0x87, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x83, 0x02, 0x82, 0x04, 0x80, 0x81, 0x00, 0x00, 0x80, 0x02, 0x81, 0x04,
|
||||
+ 0x82, 0x06, 0x08, 0x0C, 0x83, 0x0A, 0x85, 0x86, 0x84, 0x0E, 0x87, 0x10,
|
||||
+ 0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x8A, 0x02, 0x8B, 0x04, 0x8C, 0x8D, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x87, 0x02, 0x85, 0x04, 0x86, 0x06, 0x88, 0x89,
|
||||
+};
|
||||
+
|
||||
+static const u8 vp8_mv_update_prob[2][19] = {
|
||||
+ { 237, 246, 253, 253, 254, 254, 254, 254, 254,
|
||||
+ 254, 254, 254, 254, 254, 250, 250, 252, 254, 254 },
|
||||
+ { 231, 243, 245, 253, 254, 254, 254, 254, 254,
|
||||
+ 254, 254, 254, 254, 254, 251, 251, 254, 254, 254 }
|
||||
+};
|
||||
+
|
||||
+static uint8_t read_bits(struct cedrus_dev *dev, unsigned int bits_count,
|
||||
+ unsigned int probability)
|
||||
+{
|
||||
+ cedrus_write(dev, VE_H264_TRIGGER_TYPE,
|
||||
+ VE_H264_TRIGGER_TYPE_VP8_GET_BITS |
|
||||
+ VE_H264_TRIGGER_TYPE_BIN_LENS(bits_count) |
|
||||
+ VE_H264_TRIGGER_TYPE_PROBABILITY(probability));
|
||||
+
|
||||
+ while (cedrus_read(dev, VE_H264_STATUS) & VE_H264_STATUS_VLD_BUSY)
|
||||
+ ;
|
||||
+
|
||||
+ return cedrus_read(dev, VE_H264_BASIC_BITS);
|
||||
+}
|
||||
+
|
||||
+static void get_delta_q(struct cedrus_dev *dev)
|
||||
+{
|
||||
+ if (read_bits(dev, 1, VP8_PROB_HALF)) {
|
||||
+ read_bits(dev, 4, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void process_segmentation_info(struct cedrus_dev *dev)
|
||||
+{
|
||||
+ int update = read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+ int i;
|
||||
+
|
||||
+ if (read_bits(dev, 1, VP8_PROB_HALF)) {
|
||||
+ read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+
|
||||
+ for (i = 0; i < 4; i++)
|
||||
+ if (read_bits(dev, 1, VP8_PROB_HALF)) {
|
||||
+ read_bits(dev, 7, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 4; i++)
|
||||
+ if (read_bits(dev, 1, VP8_PROB_HALF)) {
|
||||
+ read_bits(dev, 6, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (update)
|
||||
+ for (i = 0; i < 3; i++)
|
||||
+ if (read_bits(dev, 1, VP8_PROB_HALF))
|
||||
+ read_bits(dev, 8, VP8_PROB_HALF);
|
||||
+}
|
||||
+
|
||||
+static void process_ref_lf_delta_info(struct cedrus_dev *dev)
|
||||
+{
|
||||
+ if (read_bits(dev, 1, VP8_PROB_HALF)) {
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < 4; i++)
|
||||
+ if (read_bits(dev, 1, VP8_PROB_HALF)) {
|
||||
+ read_bits(dev, 6, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 4; i++)
|
||||
+ if (read_bits(dev, 1, VP8_PROB_HALF)) {
|
||||
+ read_bits(dev, 6, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void process_ref_frame_info(struct cedrus_dev *dev)
|
||||
+{
|
||||
+ u8 refresh_golden_frame = read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+ u8 refresh_alt_ref_frame = read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+
|
||||
+ if (!refresh_golden_frame)
|
||||
+ read_bits(dev, 2, VP8_PROB_HALF);
|
||||
+
|
||||
+ if (!refresh_alt_ref_frame)
|
||||
+ read_bits(dev, 2, VP8_PROB_HALF);
|
||||
+
|
||||
+ read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+}
|
||||
+
|
||||
+static void cedrus_read_header(struct cedrus_dev *dev,
|
||||
+ const struct v4l2_ctrl_vp8_frame_header *slice)
|
||||
+{
|
||||
+ int i, j;
|
||||
+
|
||||
+ if (VP8_FRAME_IS_KEY_FRAME(slice)) {
|
||||
+ read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+ }
|
||||
+
|
||||
+ if (read_bits(dev, 1, VP8_PROB_HALF))
|
||||
+ process_segmentation_info(dev);
|
||||
+
|
||||
+ read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 6, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 3, VP8_PROB_HALF);
|
||||
+
|
||||
+ if (read_bits(dev, 1, VP8_PROB_HALF))
|
||||
+ process_ref_lf_delta_info(dev);
|
||||
+
|
||||
+ read_bits(dev, 2, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 7, VP8_PROB_HALF);
|
||||
+
|
||||
+ get_delta_q(dev);
|
||||
+ get_delta_q(dev);
|
||||
+ get_delta_q(dev);
|
||||
+ get_delta_q(dev);
|
||||
+ get_delta_q(dev);
|
||||
+
|
||||
+ if (!VP8_FRAME_IS_KEY_FRAME(slice))
|
||||
+ process_ref_frame_info(dev);
|
||||
+
|
||||
+ read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+
|
||||
+ if (!VP8_FRAME_IS_KEY_FRAME(slice))
|
||||
+ read_bits(dev, 1, VP8_PROB_HALF);
|
||||
+
|
||||
+ cedrus_write(dev, VE_H264_TRIGGER_TYPE, VE_H264_TRIGGER_TYPE_VP8_UPDATE_COEF);
|
||||
+ while (cedrus_read(dev, VE_H264_STATUS) & VE_H264_STATUS_VP8_UPPROB_BUSY)
|
||||
+ ;
|
||||
+
|
||||
+ cedrus_write(dev, VE_H264_STATUS, VE_H264_CTRL_INT_MASK);
|
||||
+
|
||||
+ if (read_bits(dev, 1, VP8_PROB_HALF))
|
||||
+ read_bits(dev, 8, VP8_PROB_HALF);
|
||||
+
|
||||
+ if (!VP8_FRAME_IS_KEY_FRAME(slice)) {
|
||||
+ read_bits(dev, 8, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 8, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 8, VP8_PROB_HALF);
|
||||
+
|
||||
+ if (read_bits(dev, 1, VP8_PROB_HALF)) {
|
||||
+ read_bits(dev, 8, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 8, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 8, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 8, VP8_PROB_HALF);
|
||||
+ }
|
||||
+
|
||||
+ if (read_bits(dev, 1, VP8_PROB_HALF)) {
|
||||
+ read_bits(dev, 8, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 8, VP8_PROB_HALF);
|
||||
+ read_bits(dev, 8, VP8_PROB_HALF);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 2; i++)
|
||||
+ for (j = 0; j < 19; j++)
|
||||
+ if (read_bits(dev, 1, vp8_mv_update_prob[i][j]))
|
||||
+ read_bits(dev, 7, VP8_PROB_HALF);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void cedrus_vp8_update_probs(const struct v4l2_ctrl_vp8_frame_header *slice,
|
||||
+ u8 *prob_table)
|
||||
+{
|
||||
+ int i, j, k;
|
||||
+
|
||||
+ memcpy(&prob_table[0x1008], slice->entropy_header.y_mode_probs, 4);
|
||||
+ memcpy(&prob_table[0x1010], slice->entropy_header.uv_mode_probs, 3);
|
||||
+
|
||||
+ memcpy(&prob_table[0x1018], slice->segment_header.segment_probs, 3);
|
||||
+
|
||||
+ prob_table[0x101c] = slice->prob_skip_false;
|
||||
+ prob_table[0x101d] = slice->prob_intra;
|
||||
+ prob_table[0x101e] = slice->prob_last;
|
||||
+ prob_table[0x101f] = slice->prob_gf;
|
||||
+
|
||||
+ memcpy(&prob_table[0x1020], slice->entropy_header.mv_probs[0], 19);
|
||||
+ memcpy(&prob_table[0x1040], slice->entropy_header.mv_probs[1], 19);
|
||||
+
|
||||
+ for (i = 0; i < 4; ++i)
|
||||
+ for (j = 0; j < 8; ++j)
|
||||
+ for (k = 0; k < 3; ++k)
|
||||
+ memcpy(&prob_table[i * 512 + j * 64 + k * 16],
|
||||
+ slice->entropy_header.coeff_probs[i][j][k], 11);
|
||||
+}
|
||||
+
|
||||
+static enum cedrus_irq_status
|
||||
+cedrus_vp8_irq_status(struct cedrus_ctx *ctx)
|
||||
+{
|
||||
+ struct cedrus_dev *dev = ctx->dev;
|
||||
+ u32 reg = cedrus_read(dev, VE_H264_STATUS);
|
||||
+
|
||||
+ if (reg & (VE_H264_STATUS_DECODE_ERR_INT |
|
||||
+ VE_H264_STATUS_VLD_DATA_REQ_INT))
|
||||
+ return CEDRUS_IRQ_ERROR;
|
||||
+
|
||||
+ if (reg & VE_H264_CTRL_SLICE_DECODE_INT)
|
||||
+ return CEDRUS_IRQ_OK;
|
||||
+
|
||||
+ return CEDRUS_IRQ_NONE;
|
||||
+}
|
||||
+
|
||||
+static void cedrus_vp8_irq_clear(struct cedrus_ctx *ctx)
|
||||
+{
|
||||
+ struct cedrus_dev *dev = ctx->dev;
|
||||
+
|
||||
+ cedrus_write(dev, VE_H264_STATUS,
|
||||
+ VE_H264_STATUS_INT_MASK);
|
||||
+}
|
||||
+
|
||||
+static void cedrus_vp8_irq_disable(struct cedrus_ctx *ctx)
|
||||
+{
|
||||
+ struct cedrus_dev *dev = ctx->dev;
|
||||
+ u32 reg = cedrus_read(dev, VE_H264_CTRL);
|
||||
+
|
||||
+ cedrus_write(dev, VE_H264_CTRL,
|
||||
+ reg & ~VE_H264_CTRL_INT_MASK);
|
||||
+}
|
||||
+
|
||||
+static void cedrus_vp8_setup(struct cedrus_ctx *ctx,
|
||||
+ struct cedrus_run *run)
|
||||
+{
|
||||
+ const struct v4l2_ctrl_vp8_frame_header *slice = run->vp8.slice_params;
|
||||
+ struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
|
||||
+ struct vb2_buffer *src_buf = &run->src->vb2_buf;
|
||||
+ struct cedrus_dev *dev = ctx->dev;
|
||||
+ dma_addr_t luma_addr, chroma_addr;
|
||||
+ dma_addr_t src_buf_addr;
|
||||
+ int header_size;
|
||||
+ int qindex;
|
||||
+ u32 reg;
|
||||
+
|
||||
+ cedrus_engine_enable(ctx, CEDRUS_CODEC_VP8);
|
||||
+
|
||||
+ cedrus_write(dev, VE_H264_CTRL, VE_H264_CTRL_VP8);
|
||||
+
|
||||
+ cedrus_vp8_update_probs(slice, ctx->codec.vp8.entropy_probs_buf);
|
||||
+
|
||||
+ reg = slice->first_part_size * 8;
|
||||
+ cedrus_write(dev, VE_VP8_FIRST_DATA_PART_LEN, reg);
|
||||
+
|
||||
+ header_size = VP8_FRAME_IS_KEY_FRAME(slice) ? 10 : 3;
|
||||
+
|
||||
+ reg = slice->first_part_size + header_size;
|
||||
+ cedrus_write(dev, VE_VP8_PART_SIZE_OFFSET, reg);
|
||||
+
|
||||
+ reg = vb2_plane_size(src_buf, 0) * 8;
|
||||
+ cedrus_write(dev, VE_H264_VLD_LEN, reg);
|
||||
+
|
||||
+ /*
|
||||
+ * FIXME: There is a problem if frame header is skipped (adding
|
||||
+ * first_part_header_bits to offset). It seems that functions
|
||||
+ * for parsing bitstreams change internal state of VPU in some
|
||||
+ * way that can't be otherwise set. Maybe this can be bypassed
|
||||
+ * by somehow fixing probability table buffer?
|
||||
+ */
|
||||
+ reg = header_size * 8;
|
||||
+ cedrus_write(dev, VE_H264_VLD_OFFSET, reg);
|
||||
+
|
||||
+ src_buf_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
|
||||
+ cedrus_write(dev, VE_H264_VLD_END,
|
||||
+ src_buf_addr + vb2_get_plane_payload(src_buf, 0));
|
||||
+ cedrus_write(dev, VE_H264_VLD_ADDR,
|
||||
+ VE_H264_VLD_ADDR_VAL(src_buf_addr) |
|
||||
+ VE_H264_VLD_ADDR_FIRST | VE_H264_VLD_ADDR_VALID |
|
||||
+ VE_H264_VLD_ADDR_LAST);
|
||||
+
|
||||
+ cedrus_write(dev, VE_H264_TRIGGER_TYPE,
|
||||
+ VE_H264_TRIGGER_TYPE_INIT_SWDEC);
|
||||
+
|
||||
+ cedrus_write(dev, VE_VP8_ENTROPY_PROBS_ADDR,
|
||||
+ ctx->codec.vp8.entropy_probs_buf_dma);
|
||||
+
|
||||
+ reg = 0;
|
||||
+ switch (slice->version) {
|
||||
+ case 1:
|
||||
+ reg |= VE_VP8_PPS_FILTER_TYPE_SIMPLE;
|
||||
+ reg |= VE_VP8_PPS_BILINEAR_MC_FILTER;
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ reg |= VE_VP8_PPS_LPF_DISABLE;
|
||||
+ reg |= VE_VP8_PPS_BILINEAR_MC_FILTER;
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ reg |= VE_VP8_PPS_LPF_DISABLE;
|
||||
+ reg |= VE_VP8_PPS_FULL_PIXEL;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (slice->segment_header.flags & V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP)
|
||||
+ reg |= VE_VP8_PPS_UPDATE_MB_SEGMENTATION_MAP;
|
||||
+ if (!(slice->segment_header.flags & V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE))
|
||||
+ reg |= VE_VP8_PPS_MB_SEGMENT_ABS_DELTA;
|
||||
+ if (slice->segment_header.flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED)
|
||||
+ reg |= VE_VP8_PPS_SEGMENTATION_ENABLE;
|
||||
+ if (ctx->codec.vp8.last_filter_type)
|
||||
+ reg |= VE_VP8_PPS_LAST_LOOP_FILTER_SIMPLE;
|
||||
+ reg |= VE_VP8_PPS_SHARPNESS_LEVEL(slice->lf_header.sharpness_level);
|
||||
+ if (slice->lf_header.flags & V4L2_VP8_LF_FILTER_TYPE_SIMPLE)
|
||||
+ reg |= VE_VP8_PPS_LOOP_FILTER_SIMPLE;
|
||||
+ reg |= VE_VP8_PPS_LOOP_FILTER_LEVEL(slice->lf_header.level);
|
||||
+ if (slice->lf_header.flags & V4L2_VP8_LF_HEADER_ADJ_ENABLE)
|
||||
+ reg |= VE_VP8_PPS_MODE_REF_LF_DELTA_ENABLE;
|
||||
+ if (slice->lf_header.flags & V4L2_VP8_LF_HEADER_DELTA_UPDATE)
|
||||
+ reg |= VE_VP8_PPS_MODE_REF_LF_DELTA_UPDATE;
|
||||
+ reg |= VE_VP8_PPS_TOKEN_PARTITION(ilog2(slice->num_dct_parts));
|
||||
+ if (slice->flags & V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF)
|
||||
+ reg |= VE_VP8_PPS_MB_NO_COEFF_SKIP;
|
||||
+ reg |= VE_VP8_PPS_RELOAD_ENTROPY_PROBS;
|
||||
+ if (slice->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN)
|
||||
+ reg |= VE_VP8_PPS_GOLDEN_SIGN_BIAS;
|
||||
+ if (slice->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT)
|
||||
+ reg |= VE_VP8_PPS_ALTREF_SIGN_BIAS;
|
||||
+ if (ctx->codec.vp8.last_frame_p_type)
|
||||
+ reg |= VE_VP8_PPS_LAST_PIC_TYPE_P_FRAME;
|
||||
+ reg |= VE_VP8_PPS_LAST_SHARPNESS_LEVEL(ctx->codec.vp8.last_sharpness_level);
|
||||
+ if (!(slice->flags & V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME))
|
||||
+ reg |= VE_VP8_PPS_PIC_TYPE_P_FRAME;
|
||||
+ cedrus_write(dev, VE_VP8_PPS, reg);
|
||||
+
|
||||
+ cedrus_read_header(dev, slice);
|
||||
+
|
||||
+ /* reset registers changed by HW */
|
||||
+ cedrus_write(dev, VE_H264_CUR_MB_NUM, 0);
|
||||
+ cedrus_write(dev, VE_H264_MB_ADDR, 0);
|
||||
+ cedrus_write(dev, VE_H264_ERROR_CASE, 0);
|
||||
+
|
||||
+ reg = 0;
|
||||
+ reg |= VE_VP8_QP_INDEX_DELTA_UVAC(slice->quant_header.uv_ac_delta);
|
||||
+ reg |= VE_VP8_QP_INDEX_DELTA_UVDC(slice->quant_header.uv_dc_delta);
|
||||
+ reg |= VE_VP8_QP_INDEX_DELTA_Y2AC(slice->quant_header.y2_ac_delta);
|
||||
+ reg |= VE_VP8_QP_INDEX_DELTA_Y2DC(slice->quant_header.y2_dc_delta);
|
||||
+ reg |= VE_VP8_QP_INDEX_DELTA_Y1DC(slice->quant_header.y_dc_delta);
|
||||
+ reg |= VE_VP8_QP_INDEX_DELTA_BASE_QINDEX(slice->quant_header.y_ac_qi);
|
||||
+ cedrus_write(dev, VE_VP8_QP_INDEX_DELTA, reg);
|
||||
+
|
||||
+ reg = 0;
|
||||
+ reg |= VE_VP8_FSIZE_WIDTH(slice->width);
|
||||
+ reg |= VE_VP8_FSIZE_HEIGHT(slice->height);
|
||||
+ cedrus_write(dev, VE_VP8_FSIZE, reg);
|
||||
+
|
||||
+ reg = 0;
|
||||
+ reg |= VE_VP8_PICSIZE_WIDTH(slice->width);
|
||||
+ reg |= VE_VP8_PICSIZE_HEIGHT(slice->height);
|
||||
+ cedrus_write(dev, VE_VP8_PICSIZE, reg);
|
||||
+
|
||||
+ reg = 0;
|
||||
+ reg |= VE_VP8_SEGMENT3(slice->segment_header.quant_update[3]);
|
||||
+ reg |= VE_VP8_SEGMENT2(slice->segment_header.quant_update[2]);
|
||||
+ reg |= VE_VP8_SEGMENT1(slice->segment_header.quant_update[1]);
|
||||
+ reg |= VE_VP8_SEGMENT0(slice->segment_header.quant_update[0]);
|
||||
+ cedrus_write(dev, VE_VP8_SEGMENT_FEAT_MB_LV0, reg);
|
||||
+
|
||||
+ reg = 0;
|
||||
+ reg |= VE_VP8_SEGMENT3(slice->segment_header.lf_update[3]);
|
||||
+ reg |= VE_VP8_SEGMENT2(slice->segment_header.lf_update[2]);
|
||||
+ reg |= VE_VP8_SEGMENT1(slice->segment_header.lf_update[1]);
|
||||
+ reg |= VE_VP8_SEGMENT0(slice->segment_header.lf_update[0]);
|
||||
+ cedrus_write(dev, VE_VP8_SEGMENT_FEAT_MB_LV1, reg);
|
||||
+
|
||||
+ reg = 0;
|
||||
+ reg |= VE_VP8_LF_DELTA3(slice->lf_header.ref_frm_delta[3]);
|
||||
+ reg |= VE_VP8_LF_DELTA2(slice->lf_header.ref_frm_delta[2]);
|
||||
+ reg |= VE_VP8_LF_DELTA1(slice->lf_header.ref_frm_delta[1]);
|
||||
+ reg |= VE_VP8_LF_DELTA0(slice->lf_header.ref_frm_delta[0]);
|
||||
+ cedrus_write(dev, VE_VP8_REF_LF_DELTA, reg);
|
||||
+
|
||||
+ reg = 0;
|
||||
+ reg |= VE_VP8_LF_DELTA3(slice->lf_header.mb_mode_delta[3]);
|
||||
+ reg |= VE_VP8_LF_DELTA2(slice->lf_header.mb_mode_delta[2]);
|
||||
+ reg |= VE_VP8_LF_DELTA1(slice->lf_header.mb_mode_delta[1]);
|
||||
+ reg |= VE_VP8_LF_DELTA0(slice->lf_header.mb_mode_delta[0]);
|
||||
+ cedrus_write(dev, VE_VP8_MODE_LF_DELTA, reg);
|
||||
+
|
||||
+ luma_addr = cedrus_dst_buf_addr(ctx, run->dst->vb2_buf.index, 0);
|
||||
+ chroma_addr = cedrus_dst_buf_addr(ctx, run->dst->vb2_buf.index, 1);
|
||||
+ cedrus_write(dev, VE_VP8_REC_LUMA, luma_addr);
|
||||
+ cedrus_write(dev, VE_VP8_REC_CHROMA, chroma_addr);
|
||||
+
|
||||
+ qindex = vb2_find_timestamp(cap_q, slice->last_frame_ts, 0);
|
||||
+ if (qindex >= 0) {
|
||||
+ luma_addr = cedrus_dst_buf_addr(ctx, qindex, 0);
|
||||
+ chroma_addr = cedrus_dst_buf_addr(ctx, qindex, 1);
|
||||
+ cedrus_write(dev, VE_VP8_FWD_LUMA, luma_addr);
|
||||
+ cedrus_write(dev, VE_VP8_FWD_CHROMA, chroma_addr);
|
||||
+ } else {
|
||||
+ cedrus_write(dev, VE_VP8_FWD_LUMA, 0);
|
||||
+ cedrus_write(dev, VE_VP8_FWD_CHROMA, 0);
|
||||
+ }
|
||||
+
|
||||
+ qindex = vb2_find_timestamp(cap_q, slice->golden_frame_ts, 0);
|
||||
+ if (qindex >= 0) {
|
||||
+ luma_addr = cedrus_dst_buf_addr(ctx, qindex, 0);
|
||||
+ chroma_addr = cedrus_dst_buf_addr(ctx, qindex, 1);
|
||||
+ cedrus_write(dev, VE_VP8_BWD_LUMA, luma_addr);
|
||||
+ cedrus_write(dev, VE_VP8_BWD_CHROMA, chroma_addr);
|
||||
+ } else {
|
||||
+ cedrus_write(dev, VE_VP8_BWD_LUMA, 0);
|
||||
+ cedrus_write(dev, VE_VP8_BWD_CHROMA, 0);
|
||||
+ }
|
||||
+
|
||||
+ qindex = vb2_find_timestamp(cap_q, slice->alt_frame_ts, 0);
|
||||
+ if (qindex >= 0) {
|
||||
+ luma_addr = cedrus_dst_buf_addr(ctx, qindex, 0);
|
||||
+ chroma_addr = cedrus_dst_buf_addr(ctx, qindex, 1);
|
||||
+ cedrus_write(dev, VE_VP8_ALT_LUMA, luma_addr);
|
||||
+ cedrus_write(dev, VE_VP8_ALT_CHROMA, chroma_addr);
|
||||
+ } else {
|
||||
+ cedrus_write(dev, VE_VP8_ALT_LUMA, 0);
|
||||
+ cedrus_write(dev, VE_VP8_ALT_CHROMA, 0);
|
||||
+ }
|
||||
+
|
||||
+ cedrus_write(dev, VE_H264_CTRL, VE_H264_CTRL_VP8 |
|
||||
+ VE_H264_CTRL_DECODE_ERR_INT |
|
||||
+ VE_H264_CTRL_SLICE_DECODE_INT);
|
||||
+
|
||||
+ if (slice->lf_header.level) {
|
||||
+ ctx->codec.vp8.last_filter_type =
|
||||
+ !!(slice->lf_header.flags & V4L2_VP8_LF_FILTER_TYPE_SIMPLE);
|
||||
+ ctx->codec.vp8.last_frame_p_type =
|
||||
+ !VP8_FRAME_IS_KEY_FRAME(slice);
|
||||
+ ctx->codec.vp8.last_sharpness_level =
|
||||
+ slice->lf_header.sharpness_level;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int cedrus_vp8_start(struct cedrus_ctx *ctx)
|
||||
+{
|
||||
+ struct cedrus_dev *dev = ctx->dev;
|
||||
+
|
||||
+ ctx->codec.vp8.entropy_probs_buf =
|
||||
+ dma_alloc_coherent(dev->dev, CEDRUS_ENTROPY_PROBS_SIZE,
|
||||
+ &ctx->codec.vp8.entropy_probs_buf_dma,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!ctx->codec.vp8.entropy_probs_buf)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ memcpy(&ctx->codec.vp8.entropy_probs_buf[2048],
|
||||
+ prob_table_init, sizeof(prob_table_init));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void cedrus_vp8_stop(struct cedrus_ctx *ctx)
|
||||
+{
|
||||
+ struct cedrus_dev *dev = ctx->dev;
|
||||
+
|
||||
+ cedrus_engine_disable(dev);
|
||||
+
|
||||
+ dma_free_coherent(dev->dev, CEDRUS_ENTROPY_PROBS_SIZE,
|
||||
+ ctx->codec.vp8.entropy_probs_buf,
|
||||
+ ctx->codec.vp8.entropy_probs_buf_dma);
|
||||
+}
|
||||
+
|
||||
+static void cedrus_vp8_trigger(struct cedrus_ctx *ctx)
|
||||
+{
|
||||
+ struct cedrus_dev *dev = ctx->dev;
|
||||
+
|
||||
+ cedrus_write(dev, VE_H264_TRIGGER_TYPE,
|
||||
+ VE_H264_TRIGGER_TYPE_VP8_SLICE_DECODE);
|
||||
+}
|
||||
+
|
||||
+struct cedrus_dec_ops cedrus_dec_ops_vp8 = {
|
||||
+ .irq_clear = cedrus_vp8_irq_clear,
|
||||
+ .irq_disable = cedrus_vp8_irq_disable,
|
||||
+ .irq_status = cedrus_vp8_irq_status,
|
||||
+ .setup = cedrus_vp8_setup,
|
||||
+ .start = cedrus_vp8_start,
|
||||
+ .stop = cedrus_vp8_stop,
|
||||
+ .trigger = cedrus_vp8_trigger,
|
||||
+};
|
@ -35,7 +35,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
clocks {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
@@ -672,7 +690,6 @@
|
||||
@@ -681,7 +699,6 @@
|
||||
dmas = <&dma 27>;
|
||||
resets = <&ccu RST_BUS_I2S2>;
|
||||
dma-names = "tx";
|
||||
@ -43,7 +43,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
};
|
||||
|
||||
codec: codec@1c22c00 {
|
||||
@@ -806,6 +823,7 @@
|
||||
@@ -815,6 +832,7 @@
|
||||
};
|
||||
|
||||
hdmi: hdmi@1ee0000 {
|
@ -4,7 +4,6 @@ Date: Sat, 30 Jan 2021 18:12:26 +0100
|
||||
Subject: [PATCH] h3/h5: power key wake up source
|
||||
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-h3-beelink-x2.dts | 11 +++++++++++
|
||||
arch/arm/boot/dts/sun8i-h3-nanopi.dtsi | 1 +
|
||||
arch/arm/boot/dts/sun8i-h3-orangepi-2.dts | 3 ++-
|
||||
arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts | 3 ++-
|
||||
@ -12,33 +11,9 @@ Subject: [PATCH] h3/h5: power key wake up source
|
||||
arch/arm/boot/dts/sunxi-libretech-all-h3-cc.dtsi | 1 +
|
||||
6 files changed, 19 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
|
||||
index 45a24441ff18..24aff65f82ca 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
|
||||
@@ -111,6 +111,17 @@ spdif_out: spdif-out {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "linux,spdif-dit";
|
||||
};
|
||||
+
|
||||
+ r_gpio_keys {
|
||||
+ compatible = "gpio-keys";
|
||||
+
|
||||
+ power {
|
||||
+ label = "power";
|
||||
+ linux,code = <KEY_POWER>;
|
||||
+ gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
|
||||
+ wakeup-source;
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&de {
|
||||
diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi b/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi
|
||||
index 4df29a65316d..684a0a1f8886 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi
|
||||
@@ -81,6 +81,7 @@ k1 {
|
||||
@@ -81,6 +81,7 @@
|
||||
label = "k1";
|
||||
linux,code = <KEY_POWER>;
|
||||
gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
|
||||
@ -46,11 +21,9 @@ index 4df29a65316d..684a0a1f8886 100644
|
||||
};
|
||||
};
|
||||
};
|
||||
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts
|
||||
index 597c425d08ec..9daffd90c12f 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts
|
||||
@@ -99,8 +99,9 @@ sw2 {
|
||||
@@ -99,8 +99,9 @@
|
||||
|
||||
sw4 {
|
||||
label = "sw4";
|
||||
@ -61,11 +34,9 @@ index 597c425d08ec..9daffd90c12f 100644
|
||||
};
|
||||
};
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
|
||||
index 5aff8ecc66cb..90f75fa85e68 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
|
||||
@@ -91,8 +91,9 @@ r_gpio_keys {
|
||||
@@ -91,8 +91,9 @@
|
||||
|
||||
sw4 {
|
||||
label = "sw4";
|
||||
@ -76,11 +47,9 @@ index 5aff8ecc66cb..90f75fa85e68 100644
|
||||
};
|
||||
};
|
||||
};
|
||||
diff --git a/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi b/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi
|
||||
index 8e5cb3b3fd68..b1066dedc1a2 100644
|
||||
--- a/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi
|
||||
@@ -82,8 +82,9 @@ gpio_keys {
|
||||
@@ -82,8 +82,9 @@
|
||||
|
||||
sw4 {
|
||||
label = "power";
|
||||
@ -91,11 +60,9 @@ index 8e5cb3b3fd68..b1066dedc1a2 100644
|
||||
};
|
||||
};
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sunxi-libretech-all-h3-cc.dtsi b/arch/arm/boot/dts/sunxi-libretech-all-h3-cc.dtsi
|
||||
index c44fd726945a..9e14fe5fdcde 100644
|
||||
--- a/arch/arm/boot/dts/sunxi-libretech-all-h3-cc.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-libretech-all-h3-cc.dtsi
|
||||
@@ -49,6 +49,7 @@ power {
|
||||
@@ -49,6 +49,7 @@
|
||||
label = "power";
|
||||
linux,code = <KEY_POWER>;
|
||||
gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
|
@ -11,27 +11,25 @@ Subject: [PATCH] wip h3/h5 cvbs
|
||||
drivers/gpu/drm/sun4i/sun8i_mixer.h | 5 +-
|
||||
6 files changed, 169 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
index 22d533d18992..f18959b2e8df 100644
|
||||
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
@@ -101,7 +101,7 @@ osc32k: osc32k_clk {
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
|
||||
de: display-engine {
|
||||
compatible = "allwinner,sun8i-h3-display-engine";
|
||||
- allwinner,pipelines = <&mixer0>;
|
||||
+ allwinner,pipelines = <&mixer0>, <&mixer1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -138,11 +138,50 @@ ports {
|
||||
|
||||
@@ -163,11 +163,50 @@
|
||||
#size-cells = <0>;
|
||||
|
||||
|
||||
mixer0_out: port@1 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
|
||||
- mixer0_out_tcon0: endpoint {
|
||||
+ mixer0_out_tcon0: endpoint@0 {
|
||||
+ reg = <0>;
|
||||
@ -76,14 +74,14 @@ index 22d533d18992..f18959b2e8df 100644
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -171,11 +210,19 @@ ports {
|
||||
@@ -196,11 +235,19 @@
|
||||
#size-cells = <0>;
|
||||
|
||||
|
||||
tcon0_in: port@0 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
|
||||
- tcon0_in_mixer0: endpoint {
|
||||
+ tcon0_in_mixer0: endpoint@0 {
|
||||
+ reg = <0>;
|
||||
@ -95,12 +93,12 @@ index 22d533d18992..f18959b2e8df 100644
|
||||
+ remote-endpoint = <&mixer1_out_tcon0>;
|
||||
+ };
|
||||
};
|
||||
|
||||
|
||||
tcon0_out: port@1 {
|
||||
@@ -191,6 +238,49 @@ tcon0_out_hdmi: endpoint@1 {
|
||||
@@ -216,6 +263,49 @@
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
+ tcon1: lcd-controller@1c0d000 {
|
||||
+ compatible = "allwinner,sun8i-h3-tcon-tv",
|
||||
+ "allwinner,sun8i-a83t-tcon-tv";
|
||||
@ -147,10 +145,10 @@ index 22d533d18992..f18959b2e8df 100644
|
||||
mmc0: mmc@1c0f000 {
|
||||
/* compatible and clocks are in per SoC .dtsi file */
|
||||
reg = <0x01c0f000 0x1000>;
|
||||
@@ -792,6 +882,21 @@ csi: camera@1cb0000 {
|
||||
@@ -831,6 +921,21 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
||||
+ tve: tv-encoder@1e00000 {
|
||||
+ compatible = "allwinner,sun8i-h3-tv-encoder",
|
||||
+ "allwinner,sun4i-a10-tv-encoder";
|
||||
@ -167,15 +165,13 @@ index 22d533d18992..f18959b2e8df 100644
|
||||
+ };
|
||||
+
|
||||
hdmi: hdmi@1ee0000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun8i-h3-dw-hdmi",
|
||||
"allwinner,sun8i-a83t-dw-hdmi";
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
|
||||
index 7e629a4493af..334b7edea3b7 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
|
||||
@@ -456,8 +456,18 @@ static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents,
|
||||
@@ -456,8 +456,18 @@ static SUNXI_CCU_M_WITH_MUX_GATE(tcon_cl
|
||||
CLK_SET_RATE_PARENT);
|
||||
|
||||
|
||||
static const char * const tve_parents[] = { "pll-de", "pll-periph1" };
|
||||
-static SUNXI_CCU_M_WITH_MUX_GATE(tve_clk, "tve", tve_parents,
|
||||
- 0x120, 0, 4, 24, 3, BIT(31), 0);
|
||||
@ -191,30 +187,26 @@ index 7e629a4493af..334b7edea3b7 100644
|
||||
+ &ccu_div_ops, 0),
|
||||
+ },
|
||||
+};
|
||||
|
||||
|
||||
static const char * const deinterlace_parents[] = { "pll-periph0", "pll-periph1" };
|
||||
static SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, "deinterlace", deinterlace_parents,
|
||||
diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
|
||||
index 0d04f2447b01..7b151994e904 100644
|
||||
--- a/drivers/gpu/drm/sun4i/Makefile
|
||||
+++ b/drivers/gpu/drm/sun4i/Makefile
|
||||
@@ -16,7 +16,7 @@ sun8i-drm-hdmi-y += sun8i_hdmi_phy_clk.o
|
||||
|
||||
@@ -16,7 +16,7 @@ sun8i-drm-hdmi-y += sun8i_hdmi_phy_clk.
|
||||
|
||||
sun8i-mixer-y += sun8i_mixer.o sun8i_ui_layer.o \
|
||||
sun8i_vi_layer.o sun8i_ui_scaler.o \
|
||||
- sun8i_vi_scaler.o sun8i_csc.o
|
||||
+ sun8i_vi_scaler.o sun8i_csc.o sun4i_tv.o
|
||||
|
||||
|
||||
sun4i-tcon-y += sun4i_crtc.o
|
||||
sun4i-tcon-y += sun4i_dotclock.o
|
||||
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
|
||||
index 5b42cf25cc86..35ca78a30087 100644
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
|
||||
@@ -32,6 +32,12 @@ struct de2_fmt_info {
|
||||
u32 de2_fmt;
|
||||
};
|
||||
|
||||
|
||||
+static const u32 sun8i_rgb2yuv_coef[12] = {
|
||||
+ 0x00000107, 0x00000204, 0x00000064, 0x00004200,
|
||||
+ 0x00001f68, 0x00001ed6, 0x000001c2, 0x00020200,
|
||||
@ -224,10 +216,10 @@ index 5b42cf25cc86..35ca78a30087 100644
|
||||
static const struct de2_fmt_info de2_formats[] = {
|
||||
{
|
||||
.drm_fmt = DRM_FORMAT_ARGB8888,
|
||||
@@ -298,9 +304,28 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm,
|
||||
@@ -341,9 +347,28 @@ static struct drm_plane **sun8i_layers_i
|
||||
return planes;
|
||||
}
|
||||
|
||||
|
||||
+static void sun8i_mixer_apply_color_correction(struct sunxi_engine *engine)
|
||||
+{
|
||||
+ DRM_DEBUG_DRIVER("Applying RGB to YUV color correction\n");
|
||||
@ -253,12 +245,12 @@ index 5b42cf25cc86..35ca78a30087 100644
|
||||
+ .apply_color_correction = sun8i_mixer_apply_color_correction,
|
||||
+ .disable_color_correction = sun8i_mixer_disable_color_correction,
|
||||
};
|
||||
|
||||
static const struct regmap_config sun8i_mixer_regmap_config = {
|
||||
@@ -560,6 +585,15 @@ static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = {
|
||||
|
||||
static bool sun8i_mixer_volatile_reg(struct device *dev, unsigned int reg)
|
||||
@@ -608,6 +633,15 @@ static const struct sun8i_mixer_cfg sun8
|
||||
.vi_num = 1,
|
||||
};
|
||||
|
||||
|
||||
+static const struct sun8i_mixer_cfg sun8i_h3_mixer1_cfg = {
|
||||
+ .ccsc = 1,
|
||||
+ .mod_rate = 432000000,
|
||||
@ -271,25 +263,23 @@ index 5b42cf25cc86..35ca78a30087 100644
|
||||
static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg = {
|
||||
.ccsc = 0,
|
||||
.mod_rate = 297000000,
|
||||
@@ -628,6 +662,10 @@ static const struct of_device_id sun8i_mixer_of_table[] = {
|
||||
.compatible = "allwinner,sun8i-h3-de2-mixer-0",
|
||||
@@ -677,6 +711,10 @@ static const struct of_device_id sun8i_m
|
||||
.data = &sun8i_h3_mixer0_cfg,
|
||||
},
|
||||
+ {
|
||||
{
|
||||
+ .compatible = "allwinner,sun8i-h3-de2-mixer-1",
|
||||
+ .data = &sun8i_h3_mixer1_cfg,
|
||||
+ },
|
||||
{
|
||||
+ {
|
||||
.compatible = "allwinner,sun8i-r40-de2-mixer-0",
|
||||
.data = &sun8i_r40_mixer0_cfg,
|
||||
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
||||
index 7576b523fdbb..6593085cecf3 100644
|
||||
},
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
||||
@@ -120,6 +120,10 @@
|
||||
/* format 20 is packed YVU444 10-bit */
|
||||
/* format 21 is packed YUV444 10-bit */
|
||||
|
||||
|
||||
+/* The DCSC sub-engine is used to do color space conversation */
|
||||
+#define SUN8I_MIXER_DCSC_EN 0xb0000
|
||||
+#define SUN8I_MIXER_DCSC_COEF_REG(x) (0xb0010 + 0x4 * (x))
|
||||
@ -302,6 +292,6 @@ index 7576b523fdbb..6593085cecf3 100644
|
||||
#define SUN8I_MIXER_ASE_EN 0xa8000
|
||||
#define SUN8I_MIXER_FCC_EN 0xaa000
|
||||
-#define SUN8I_MIXER_DCSC_EN 0xb0000
|
||||
|
||||
|
||||
#define SUN50I_MIXER_FCE_EN 0x70000
|
||||
#define SUN50I_MIXER_PEAK_EN 0x70800
|
@ -10,8 +10,6 @@ Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
include/media/hevc-ctrls.h | 16 ++++++++++++----
|
||||
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
|
||||
index 6e881b7896bc..46936bae7c30 100644
|
||||
--- a/include/media/hevc-ctrls.h
|
||||
+++ b/include/media/hevc-ctrls.h
|
||||
@@ -56,6 +56,9 @@ enum v4l2_mpeg_video_hevc_start_code {
|
@ -7,8 +7,6 @@ Subject: [PATCH] HACK: media: uapi: hevc: tiles and num_slices
|
||||
include/media/hevc-ctrls.h | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
|
||||
index 46936bae7c30..4d51c148d0ba 100644
|
||||
--- a/include/media/hevc-ctrls.h
|
||||
+++ b/include/media/hevc-ctrls.h
|
||||
@@ -80,7 +80,8 @@ struct v4l2_ctrl_hevc_sps {
|
@ -1,57 +0,0 @@
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Subject: [PATCH v2] drm/lima: add governor data with pre-defined thresholds
|
||||
Date: Wed, 27 Jan 2021 19:40:47 +0000
|
||||
|
||||
This patch adapts the panfrost pre-defined thresholds change [0] to the
|
||||
lima driver to improve real-world performance. The upthreshold value has
|
||||
been set to ramp GPU frequency to max freq faster (compared to panfrost)
|
||||
to compensate for the lower overall performance of utgard devices.
|
||||
|
||||
[0] https://patchwork.kernel.org/project/dri-devel/patch/20210121170445.19761-1-lukasz.luba@arm.com/
|
||||
|
||||
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
|
||||
Reviewed-by: Qiang Yu <yuq825@gmail.com>
|
||||
---
|
||||
drivers/gpu/drm/lima/lima_devfreq.c | 10 +++++++++-
|
||||
drivers/gpu/drm/lima/lima_devfreq.h | 2 ++
|
||||
2 files changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/gpu/drm/lima/lima_devfreq.c
|
||||
+++ b/drivers/gpu/drm/lima/lima_devfreq.c
|
||||
@@ -177,8 +177,16 @@ int lima_devfreq_init(struct lima_device
|
||||
lima_devfreq_profile.initial_freq = cur_freq;
|
||||
dev_pm_opp_put(opp);
|
||||
|
||||
+ /*
|
||||
+ * Setup default thresholds for the simple_ondemand governor.
|
||||
+ * The values are chosen based on experiments.
|
||||
+ */
|
||||
+ ldevfreq->gov_data.upthreshold = 30;
|
||||
+ ldevfreq->gov_data.downdifferential = 5;
|
||||
+
|
||||
devfreq = devm_devfreq_add_device(dev, &lima_devfreq_profile,
|
||||
- DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);
|
||||
+ DEVFREQ_GOV_SIMPLE_ONDEMAND,
|
||||
+ &ldevfreq->gov_data);
|
||||
if (IS_ERR(devfreq)) {
|
||||
dev_err(dev, "Couldn't initialize GPU devfreq\n");
|
||||
ret = PTR_ERR(devfreq);
|
||||
--- a/drivers/gpu/drm/lima/lima_devfreq.h
|
||||
+++ b/drivers/gpu/drm/lima/lima_devfreq.h
|
||||
@@ -4,6 +4,7 @@
|
||||
#ifndef __LIMA_DEVFREQ_H__
|
||||
#define __LIMA_DEVFREQ_H__
|
||||
|
||||
+#include <linux/devfreq.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/ktime.h>
|
||||
|
||||
@@ -18,6 +19,7 @@ struct lima_devfreq {
|
||||
struct opp_table *clkname_opp_table;
|
||||
struct opp_table *regulators_opp_table;
|
||||
struct thermal_cooling_device *cooling;
|
||||
+ struct devfreq_simple_ondemand_data gov_data;
|
||||
bool opp_of_table_added;
|
||||
|
||||
ktime_t busy_time;
|
@ -1,24 +0,0 @@
|
||||
From: Lukasz Luba <lukasz.luba@arm.com>
|
||||
Subject: [PATCH] drm/lima: Use delayed timer as default in devfreq profile
|
||||
Date: Wed, 27 Jan 2021 10:51:21 +0000
|
||||
|
||||
Devfreq framework supports 2 modes for monitoring devices.
|
||||
Use delayed timer as default instead of deferrable timer
|
||||
in order to monitor the GPU status regardless of CPU idle.
|
||||
|
||||
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
|
||||
Reviewed-by: Qiang Yu <yuq825@gmail.com>
|
||||
---
|
||||
drivers/gpu/drm/lima/lima_devfreq.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/gpu/drm/lima/lima_devfreq.c
|
||||
+++ b/drivers/gpu/drm/lima/lima_devfreq.c
|
||||
@@ -86,6 +86,7 @@ static int lima_devfreq_get_dev_status(s
|
||||
}
|
||||
|
||||
static struct devfreq_dev_profile lima_devfreq_profile = {
|
||||
+ .timer = DEVFREQ_TIMER_DELAYED,
|
||||
.polling_ms = 50, /* ~3 frames */
|
||||
.target = lima_devfreq_target,
|
||||
.get_dev_status = lima_devfreq_get_dev_status,
|
@ -1,59 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lukasz Luba <lukasz.luba@arm.com>
|
||||
Date: Thu, 21 Jan 2021 17:04:45 +0000
|
||||
Subject: [PATCH] drm/panfrost: Add governor data with pre-defined thresholds
|
||||
|
||||
The simple_ondemand devfreq governor uses two thresholds to decide about
|
||||
the frequency change: upthreshold, downdifferential. These two tunable
|
||||
change the behavior of the governor decision, e.g. how fast to increase
|
||||
the frequency or how rapidly limit the frequency. This patch adds needed
|
||||
governor data with thresholds values gathered experimentally in different
|
||||
workloads.
|
||||
|
||||
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Signed-off-by: Steven Price <steven.price@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20210121170445.19761-1-lukasz.luba@arm.com
|
||||
---
|
||||
drivers/gpu/drm/panfrost/panfrost_devfreq.c | 10 +++++++++-
|
||||
drivers/gpu/drm/panfrost/panfrost_devfreq.h | 2 ++
|
||||
2 files changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
|
||||
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
|
||||
@@ -134,8 +134,16 @@ int panfrost_devfreq_init(struct panfros
|
||||
panfrost_devfreq_profile.initial_freq = cur_freq;
|
||||
dev_pm_opp_put(opp);
|
||||
|
||||
+ /*
|
||||
+ * Setup default thresholds for the simple_ondemand governor.
|
||||
+ * The values are chosen based on experiments.
|
||||
+ */
|
||||
+ pfdevfreq->gov_data.upthreshold = 45;
|
||||
+ pfdevfreq->gov_data.downdifferential = 5;
|
||||
+
|
||||
devfreq = devm_devfreq_add_device(dev, &panfrost_devfreq_profile,
|
||||
- DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);
|
||||
+ DEVFREQ_GOV_SIMPLE_ONDEMAND,
|
||||
+ &pfdevfreq->gov_data);
|
||||
if (IS_ERR(devfreq)) {
|
||||
DRM_DEV_ERROR(dev, "Couldn't initialize GPU devfreq\n");
|
||||
ret = PTR_ERR(devfreq);
|
||||
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h
|
||||
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
|
||||
@@ -4,6 +4,7 @@
|
||||
#ifndef __PANFROST_DEVFREQ_H__
|
||||
#define __PANFROST_DEVFREQ_H__
|
||||
|
||||
+#include <linux/devfreq.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/ktime.h>
|
||||
|
||||
@@ -17,6 +18,7 @@ struct panfrost_devfreq {
|
||||
struct devfreq *devfreq;
|
||||
struct opp_table *regulators_opp_table;
|
||||
struct thermal_cooling_device *cooling;
|
||||
+ struct devfreq_simple_ondemand_data gov_data;
|
||||
bool opp_of_table_added;
|
||||
|
||||
ktime_t busy_time;
|
@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lukasz Luba <lukasz.luba@arm.com>
|
||||
Date: Tue, 5 Jan 2021 16:41:11 +0000
|
||||
Subject: [PATCH] drm/panfrost: Use delayed timer as default in devfreq profile
|
||||
|
||||
Devfreq framework supports 2 modes for monitoring devices.
|
||||
Use delayed timer as default instead of deferrable timer
|
||||
in order to monitor the GPU status regardless of CPU idle.
|
||||
|
||||
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Signed-off-by: Steven Price <steven.price@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20210105164111.30122-1-lukasz.luba@arm.com
|
||||
---
|
||||
drivers/gpu/drm/panfrost/panfrost_devfreq.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
|
||||
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
|
||||
@@ -81,6 +81,7 @@ static int panfrost_devfreq_get_dev_stat
|
||||
}
|
||||
|
||||
static struct devfreq_dev_profile panfrost_devfreq_profile = {
|
||||
+ .timer = DEVFREQ_TIMER_DELAYED,
|
||||
.polling_ms = 50, /* ~3 frames */
|
||||
.target = panfrost_devfreq_target,
|
||||
.get_dev_status = panfrost_devfreq_get_dev_status,
|
@ -1,34 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 3 Jan 2021 05:25:38 -0600
|
||||
Subject: [PATCH] net: stmmac: dwmac-sun8i: Return void from PHY unpower
|
||||
|
||||
This is a deinitialization function that always returned zero, and that
|
||||
return value was always ignored. Have it return void instead.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
||||
@@ -820,15 +820,14 @@ static int sun8i_dwmac_power_internal_ph
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int sun8i_dwmac_unpower_internal_phy(struct sunxi_priv_data *gmac)
|
||||
+static void sun8i_dwmac_unpower_internal_phy(struct sunxi_priv_data *gmac)
|
||||
{
|
||||
if (!gmac->internal_phy_powered)
|
||||
- return 0;
|
||||
+ return;
|
||||
|
||||
clk_disable_unprepare(gmac->ephy_clk);
|
||||
reset_control_assert(gmac->rst_ephy);
|
||||
gmac->internal_phy_powered = false;
|
||||
- return 0;
|
||||
}
|
||||
|
||||
/* MDIO multiplexing switch function
|
@ -1,29 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 3 Jan 2021 05:25:39 -0600
|
||||
Subject: [PATCH] net: stmmac: dwmac-sun8i: Remove unnecessary PHY power check
|
||||
|
||||
sun8i_dwmac_unpower_internal_phy already checks if the PHY is powered,
|
||||
so there is no need to do it again here.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
||||
@@ -1018,10 +1018,8 @@ static void sun8i_dwmac_exit(struct plat
|
||||
{
|
||||
struct sunxi_priv_data *gmac = priv;
|
||||
|
||||
- if (gmac->variant->soc_has_internal_phy) {
|
||||
- if (gmac->internal_phy_powered)
|
||||
- sun8i_dwmac_unpower_internal_phy(gmac);
|
||||
- }
|
||||
+ if (gmac->variant->soc_has_internal_phy)
|
||||
+ sun8i_dwmac_unpower_internal_phy(gmac);
|
||||
|
||||
clk_disable_unprepare(gmac->tx_clk);
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 3 Jan 2021 05:25:40 -0600
|
||||
Subject: [PATCH] net: stmmac: dwmac-sun8i: Use reset_control_reset
|
||||
|
||||
Use the appropriate function instead of reimplementing it,
|
||||
and update the error message to match the code.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
||||
@@ -806,11 +806,9 @@ static int sun8i_dwmac_power_internal_ph
|
||||
/* Make sure the EPHY is properly reseted, as U-Boot may leave
|
||||
* it at deasserted state, and thus it may fail to reset EMAC.
|
||||
*/
|
||||
- reset_control_assert(gmac->rst_ephy);
|
||||
-
|
||||
- ret = reset_control_deassert(gmac->rst_ephy);
|
||||
+ ret = reset_control_reset(gmac->rst_ephy);
|
||||
if (ret) {
|
||||
- dev_err(priv->device, "Cannot deassert internal phy\n");
|
||||
+ dev_err(priv->device, "Cannot reset internal PHY\n");
|
||||
clk_disable_unprepare(gmac->ephy_clk);
|
||||
return ret;
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 3 Jan 2021 05:25:41 -0600
|
||||
Subject: [PATCH] net: stmmac: dwmac-sun8i: Minor probe function cleanup
|
||||
|
||||
Adjust the spacing and use an explicit "return 0" in the success path
|
||||
to make the function easier to parse.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
||||
@@ -1227,6 +1227,7 @@ static int sun8i_dwmac_probe(struct plat
|
||||
|
||||
ndev = dev_get_drvdata(&pdev->dev);
|
||||
priv = netdev_priv(ndev);
|
||||
+
|
||||
/* The mux must be registered after parent MDIO
|
||||
* so after stmmac_dvr_probe()
|
||||
*/
|
||||
@@ -1245,7 +1246,8 @@ static int sun8i_dwmac_probe(struct plat
|
||||
goto dwmac_remove;
|
||||
}
|
||||
|
||||
- return ret;
|
||||
+ return 0;
|
||||
+
|
||||
dwmac_mux:
|
||||
reset_control_put(gmac->rst_ephy);
|
||||
clk_put(gmac->ephy_clk);
|
@ -1,41 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 3 Jan 2021 05:25:42 -0600
|
||||
Subject: [PATCH] net: stmmac: dwmac-sun8i: Add a shutdown callback
|
||||
|
||||
The Ethernet MAC and PHY are usually major consumers of power on boards
|
||||
which may not be able to fully power off (that have no PMIC). Powering
|
||||
down the MAC and internal PHY saves power while these boards are "off".
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
||||
@@ -1282,6 +1282,15 @@ static int sun8i_dwmac_remove(struct pla
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void sun8i_dwmac_shutdown(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
+ struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
+ struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
|
||||
+
|
||||
+ sun8i_dwmac_exit(pdev, gmac);
|
||||
+}
|
||||
+
|
||||
static const struct of_device_id sun8i_dwmac_match[] = {
|
||||
{ .compatible = "allwinner,sun8i-h3-emac",
|
||||
.data = &emac_variant_h3 },
|
||||
@@ -1302,6 +1311,7 @@ MODULE_DEVICE_TABLE(of, sun8i_dwmac_matc
|
||||
static struct platform_driver sun8i_dwmac_driver = {
|
||||
.probe = sun8i_dwmac_probe,
|
||||
.remove = sun8i_dwmac_remove,
|
||||
+ .shutdown = sun8i_dwmac_shutdown,
|
||||
.driver = {
|
||||
.name = "dwmac-sun8i",
|
||||
.pm = &stmmac_pltfr_pm_ops,
|
@ -1,237 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Wed, 12 Feb 2020 22:58:30 -0600
|
||||
Subject: [PATCH] i2c: mv64xxx: Add runtime PM support
|
||||
|
||||
To save power, gate the clock when the bus is inactive, during system
|
||||
sleep, and during shutdown. On some platforms, specifically Allwinner
|
||||
A13/A20, gating the clock implicitly resets the module as well. Since
|
||||
the module already needs to be reset after some suspend/resume cycles,
|
||||
it is simple enough to reset it during every runtime suspend/resume.
|
||||
|
||||
Because the bus may be used by wakeup source IRQ threads, it needs to
|
||||
be functional as soon as IRQs are enabled. Thus, its system PM hooks
|
||||
need to run in the noirq phase.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
drivers/i2c/busses/i2c-mv64xxx.c | 118 ++++++++++++++++++++-----------
|
||||
1 file changed, 77 insertions(+), 41 deletions(-)
|
||||
|
||||
--- a/drivers/i2c/busses/i2c-mv64xxx.c
|
||||
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mv643xx_i2c.h>
|
||||
#include <linux/platform_device.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
@@ -713,6 +714,10 @@ mv64xxx_i2c_xfer(struct i2c_adapter *ada
|
||||
struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
|
||||
int rc, ret = num;
|
||||
|
||||
+ rc = pm_runtime_resume_and_get(&adap->dev);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
BUG_ON(drv_data->msgs != NULL);
|
||||
drv_data->msgs = msgs;
|
||||
drv_data->num_msgs = num;
|
||||
@@ -728,6 +733,9 @@ mv64xxx_i2c_xfer(struct i2c_adapter *ada
|
||||
drv_data->num_msgs = 0;
|
||||
drv_data->msgs = NULL;
|
||||
|
||||
+ pm_runtime_mark_last_busy(&adap->dev);
|
||||
+ pm_runtime_put_autosuspend(&adap->dev);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -824,7 +832,6 @@ mv64xxx_of_config(struct mv64xxx_i2c_dat
|
||||
rc = PTR_ERR(drv_data->rstc);
|
||||
goto out;
|
||||
}
|
||||
- reset_control_deassert(drv_data->rstc);
|
||||
|
||||
/* Its not yet defined how timeouts will be specified in device tree.
|
||||
* So hard code the value to 1 second.
|
||||
@@ -871,6 +878,32 @@ mv64xxx_of_config(struct mv64xxx_i2c_dat
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
static int
|
||||
+mv64xxx_i2c_runtime_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct mv64xxx_i2c_data *drv_data = dev_get_drvdata(dev);
|
||||
+
|
||||
+ reset_control_assert(drv_data->rstc);
|
||||
+ clk_disable_unprepare(drv_data->reg_clk);
|
||||
+ clk_disable_unprepare(drv_data->clk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mv64xxx_i2c_runtime_resume(struct device *dev)
|
||||
+{
|
||||
+ struct mv64xxx_i2c_data *drv_data = dev_get_drvdata(dev);
|
||||
+
|
||||
+ clk_prepare_enable(drv_data->clk);
|
||||
+ clk_prepare_enable(drv_data->reg_clk);
|
||||
+ reset_control_reset(drv_data->rstc);
|
||||
+
|
||||
+ mv64xxx_i2c_hw_init(drv_data);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
mv64xxx_i2c_probe(struct platform_device *pd)
|
||||
{
|
||||
struct mv64xxx_i2c_data *drv_data;
|
||||
@@ -897,18 +930,22 @@ mv64xxx_i2c_probe(struct platform_device
|
||||
|
||||
/* Not all platforms have clocks */
|
||||
drv_data->clk = devm_clk_get(&pd->dev, NULL);
|
||||
- if (PTR_ERR(drv_data->clk) == -EPROBE_DEFER)
|
||||
- return -EPROBE_DEFER;
|
||||
- if (!IS_ERR(drv_data->clk))
|
||||
- clk_prepare_enable(drv_data->clk);
|
||||
+ if (IS_ERR(drv_data->clk)) {
|
||||
+ if (PTR_ERR(drv_data->clk) == -EPROBE_DEFER)
|
||||
+ return -EPROBE_DEFER;
|
||||
+ drv_data->clk = NULL;
|
||||
+ }
|
||||
|
||||
drv_data->reg_clk = devm_clk_get(&pd->dev, "reg");
|
||||
- if (PTR_ERR(drv_data->reg_clk) == -EPROBE_DEFER)
|
||||
- return -EPROBE_DEFER;
|
||||
- if (!IS_ERR(drv_data->reg_clk))
|
||||
- clk_prepare_enable(drv_data->reg_clk);
|
||||
+ if (IS_ERR(drv_data->reg_clk)) {
|
||||
+ if (PTR_ERR(drv_data->reg_clk) == -EPROBE_DEFER)
|
||||
+ return -EPROBE_DEFER;
|
||||
+ drv_data->reg_clk = NULL;
|
||||
+ }
|
||||
|
||||
drv_data->irq = platform_get_irq(pd, 0);
|
||||
+ if (drv_data->irq < 0)
|
||||
+ return drv_data->irq;
|
||||
|
||||
if (pdata) {
|
||||
drv_data->freq_m = pdata->freq_m;
|
||||
@@ -919,11 +956,7 @@ mv64xxx_i2c_probe(struct platform_device
|
||||
} else if (pd->dev.of_node) {
|
||||
rc = mv64xxx_of_config(drv_data, &pd->dev);
|
||||
if (rc)
|
||||
- goto exit_clk;
|
||||
- }
|
||||
- if (drv_data->irq < 0) {
|
||||
- rc = drv_data->irq;
|
||||
- goto exit_reset;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
drv_data->adapter.dev.parent = &pd->dev;
|
||||
@@ -935,7 +968,14 @@ mv64xxx_i2c_probe(struct platform_device
|
||||
platform_set_drvdata(pd, drv_data);
|
||||
i2c_set_adapdata(&drv_data->adapter, drv_data);
|
||||
|
||||
- mv64xxx_i2c_hw_init(drv_data);
|
||||
+ pm_runtime_set_autosuspend_delay(&pd->dev, MSEC_PER_SEC);
|
||||
+ pm_runtime_use_autosuspend(&pd->dev);
|
||||
+ pm_runtime_enable(&pd->dev);
|
||||
+ if (!pm_runtime_enabled(&pd->dev)) {
|
||||
+ rc = mv64xxx_i2c_runtime_resume(&pd->dev);
|
||||
+ if (rc)
|
||||
+ goto exit_disable_pm;
|
||||
+ }
|
||||
|
||||
rc = request_irq(drv_data->irq, mv64xxx_i2c_intr, 0,
|
||||
MV64XXX_I2C_CTLR_NAME, drv_data);
|
||||
@@ -943,7 +983,7 @@ mv64xxx_i2c_probe(struct platform_device
|
||||
dev_err(&drv_data->adapter.dev,
|
||||
"mv64xxx: Can't register intr handler irq%d: %d\n",
|
||||
drv_data->irq, rc);
|
||||
- goto exit_reset;
|
||||
+ goto exit_disable_pm;
|
||||
} else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {
|
||||
dev_err(&drv_data->adapter.dev,
|
||||
"mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
|
||||
@@ -954,54 +994,50 @@ mv64xxx_i2c_probe(struct platform_device
|
||||
|
||||
exit_free_irq:
|
||||
free_irq(drv_data->irq, drv_data);
|
||||
-exit_reset:
|
||||
- reset_control_assert(drv_data->rstc);
|
||||
-exit_clk:
|
||||
- clk_disable_unprepare(drv_data->reg_clk);
|
||||
- clk_disable_unprepare(drv_data->clk);
|
||||
+exit_disable_pm:
|
||||
+ pm_runtime_disable(&pd->dev);
|
||||
+ if (!pm_runtime_status_suspended(&pd->dev))
|
||||
+ mv64xxx_i2c_runtime_suspend(&pd->dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
-mv64xxx_i2c_remove(struct platform_device *dev)
|
||||
+mv64xxx_i2c_remove(struct platform_device *pd)
|
||||
{
|
||||
- struct mv64xxx_i2c_data *drv_data = platform_get_drvdata(dev);
|
||||
+ struct mv64xxx_i2c_data *drv_data = platform_get_drvdata(pd);
|
||||
|
||||
i2c_del_adapter(&drv_data->adapter);
|
||||
free_irq(drv_data->irq, drv_data);
|
||||
- reset_control_assert(drv_data->rstc);
|
||||
- clk_disable_unprepare(drv_data->reg_clk);
|
||||
- clk_disable_unprepare(drv_data->clk);
|
||||
+ pm_runtime_disable(&pd->dev);
|
||||
+ if (!pm_runtime_status_suspended(&pd->dev))
|
||||
+ mv64xxx_i2c_runtime_suspend(&pd->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_PM
|
||||
-static int mv64xxx_i2c_resume(struct device *dev)
|
||||
+static void
|
||||
+mv64xxx_i2c_shutdown(struct platform_device *pd)
|
||||
{
|
||||
- struct mv64xxx_i2c_data *drv_data = dev_get_drvdata(dev);
|
||||
-
|
||||
- mv64xxx_i2c_hw_init(drv_data);
|
||||
-
|
||||
- return 0;
|
||||
+ pm_runtime_disable(&pd->dev);
|
||||
+ if (!pm_runtime_status_suspended(&pd->dev))
|
||||
+ mv64xxx_i2c_runtime_suspend(&pd->dev);
|
||||
}
|
||||
|
||||
-static const struct dev_pm_ops mv64xxx_i2c_pm = {
|
||||
- .resume = mv64xxx_i2c_resume,
|
||||
+static const struct dev_pm_ops mv64xxx_i2c_pm_ops = {
|
||||
+ SET_RUNTIME_PM_OPS(mv64xxx_i2c_runtime_suspend,
|
||||
+ mv64xxx_i2c_runtime_resume, NULL)
|
||||
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
|
||||
+ pm_runtime_force_resume)
|
||||
};
|
||||
|
||||
-#define mv64xxx_i2c_pm_ops (&mv64xxx_i2c_pm)
|
||||
-#else
|
||||
-#define mv64xxx_i2c_pm_ops NULL
|
||||
-#endif
|
||||
-
|
||||
static struct platform_driver mv64xxx_i2c_driver = {
|
||||
.probe = mv64xxx_i2c_probe,
|
||||
.remove = mv64xxx_i2c_remove,
|
||||
+ .shutdown = mv64xxx_i2c_shutdown,
|
||||
.driver = {
|
||||
.name = MV64XXX_I2C_CTLR_NAME,
|
||||
- .pm = mv64xxx_i2c_pm_ops,
|
||||
+ .pm = &mv64xxx_i2c_pm_ops,
|
||||
.of_match_table = mv64xxx_i2c_of_match_table,
|
||||
},
|
||||
};
|
@ -1,38 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 10 Jan 2021 00:41:23 -0600
|
||||
Subject: [PATCH] media: sunxi-cir: Skip register writes during remove
|
||||
|
||||
These writes occur after the device is already put back in reset, so
|
||||
they never had any effect.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
drivers/media/rc/sunxi-cir.c | 10 ----------
|
||||
1 file changed, 10 deletions(-)
|
||||
|
||||
--- a/drivers/media/rc/sunxi-cir.c
|
||||
+++ b/drivers/media/rc/sunxi-cir.c
|
||||
@@ -342,22 +342,12 @@ exit_reset_assert:
|
||||
|
||||
static int sunxi_ir_remove(struct platform_device *pdev)
|
||||
{
|
||||
- unsigned long flags;
|
||||
struct sunxi_ir *ir = platform_get_drvdata(pdev);
|
||||
|
||||
clk_disable_unprepare(ir->clk);
|
||||
clk_disable_unprepare(ir->apb_clk);
|
||||
reset_control_assert(ir->rst);
|
||||
|
||||
- spin_lock_irqsave(&ir->ir_lock, flags);
|
||||
- /* disable IR IRQ */
|
||||
- writel(0, ir->base + SUNXI_IR_RXINT_REG);
|
||||
- /* clear All Rx Interrupt Status */
|
||||
- writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG);
|
||||
- /* disable IR */
|
||||
- writel(0, ir->base + SUNXI_IR_CTL_REG);
|
||||
- spin_unlock_irqrestore(&ir->ir_lock, flags);
|
||||
-
|
||||
rc_unregister_device(ir->rc);
|
||||
return 0;
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 10 Jan 2021 00:43:19 -0600
|
||||
Subject: [PATCH] media: sunxi-cir: Remove unnecessary spinlock
|
||||
|
||||
Only one register, SUNXI_IR_CIR_REG, is written from outside the
|
||||
interrupt handler, and that register is not written from inside it.
|
||||
There is no overlap between different contexts, so no lock is needed.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
drivers/media/rc/sunxi-cir.c | 10 ----------
|
||||
1 file changed, 10 deletions(-)
|
||||
|
||||
--- a/drivers/media/rc/sunxi-cir.c
|
||||
+++ b/drivers/media/rc/sunxi-cir.c
|
||||
@@ -86,7 +86,6 @@ struct sunxi_ir_quirks {
|
||||
};
|
||||
|
||||
struct sunxi_ir {
|
||||
- spinlock_t ir_lock;
|
||||
struct rc_dev *rc;
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
@@ -105,8 +104,6 @@ static irqreturn_t sunxi_ir_irq(int irqn
|
||||
struct sunxi_ir *ir = dev_id;
|
||||
struct ir_raw_event rawir = {};
|
||||
|
||||
- spin_lock(&ir->ir_lock);
|
||||
-
|
||||
status = readl(ir->base + SUNXI_IR_RXSTA_REG);
|
||||
|
||||
/* clean all pending statuses */
|
||||
@@ -137,8 +134,6 @@ static irqreturn_t sunxi_ir_irq(int irqn
|
||||
ir_raw_event_handle(ir->rc);
|
||||
}
|
||||
|
||||
- spin_unlock(&ir->ir_lock);
|
||||
-
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -160,17 +155,14 @@ static int sunxi_ir_set_timeout(struct r
|
||||
{
|
||||
struct sunxi_ir *ir = rc_dev->priv;
|
||||
unsigned int base_clk = clk_get_rate(ir->clk);
|
||||
- unsigned long flags;
|
||||
|
||||
unsigned int ithr = sunxi_usec_to_ithr(base_clk, timeout);
|
||||
|
||||
dev_dbg(rc_dev->dev.parent, "setting idle threshold to %u\n", ithr);
|
||||
|
||||
- spin_lock_irqsave(&ir->ir_lock, flags);
|
||||
/* Set noise threshold and idle threshold */
|
||||
writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE) | REG_CIR_ITHR(ithr),
|
||||
ir->base + SUNXI_IR_CIR_REG);
|
||||
- spin_unlock_irqrestore(&ir->ir_lock, flags);
|
||||
|
||||
rc_dev->timeout = sunxi_ithr_to_usec(base_clk, ithr);
|
||||
|
||||
@@ -199,8 +191,6 @@ static int sunxi_ir_probe(struct platfor
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
- spin_lock_init(&ir->ir_lock);
|
||||
-
|
||||
ir->fifo_size = quirks->fifo_size;
|
||||
|
||||
/* Clock */
|
@ -1,223 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 10 Jan 2021 00:50:32 -0600
|
||||
Subject: [PATCH] media: sunxi-cir: Factor out hardware initialization
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
drivers/media/rc/sunxi-cir.c | 142 ++++++++++++++++++++---------------
|
||||
1 file changed, 82 insertions(+), 60 deletions(-)
|
||||
|
||||
--- a/drivers/media/rc/sunxi-cir.c
|
||||
+++ b/drivers/media/rc/sunxi-cir.c
|
||||
@@ -90,6 +90,7 @@ struct sunxi_ir {
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
int fifo_size;
|
||||
+ u32 base_clk_freq;
|
||||
struct clk *clk;
|
||||
struct clk *apb_clk;
|
||||
struct reset_control *rst;
|
||||
@@ -169,10 +170,81 @@ static int sunxi_ir_set_timeout(struct r
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int sunxi_ir_hw_init(struct device *dev)
|
||||
+{
|
||||
+ struct sunxi_ir *ir = dev_get_drvdata(dev);
|
||||
+ unsigned long tmp;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = reset_control_deassert(ir->rst);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = clk_set_rate(ir->clk, ir->base_clk_freq);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "set ir base clock failed!\n");
|
||||
+ goto exit_reset_assert;
|
||||
+ }
|
||||
+ dev_dbg(dev, "set base clock frequency to %d Hz.\n", ir->base_clk_freq);
|
||||
+
|
||||
+ if (clk_prepare_enable(ir->apb_clk)) {
|
||||
+ dev_err(dev, "try to enable apb_ir_clk failed\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit_reset_assert;
|
||||
+ }
|
||||
+
|
||||
+ if (clk_prepare_enable(ir->clk)) {
|
||||
+ dev_err(dev, "try to enable ir_clk failed\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit_apb_clk_disable;
|
||||
+ }
|
||||
+
|
||||
+ /* Enable CIR Mode */
|
||||
+ writel(REG_CTL_MD, ir->base + SUNXI_IR_CTL_REG);
|
||||
+
|
||||
+ /* Set noise threshold and idle threshold */
|
||||
+ sunxi_ir_set_timeout(ir->rc, ir->rc->timeout);
|
||||
+
|
||||
+ /* Invert Input Signal */
|
||||
+ writel(REG_RXCTL_RPPI, ir->base + SUNXI_IR_RXCTL_REG);
|
||||
+
|
||||
+ /* Clear All Rx Interrupt Status */
|
||||
+ writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG);
|
||||
+
|
||||
+ /*
|
||||
+ * Enable IRQ on overflow, packet end, FIFO available with trigger
|
||||
+ * level
|
||||
+ */
|
||||
+ writel(REG_RXINT_ROI_EN | REG_RXINT_RPEI_EN |
|
||||
+ REG_RXINT_RAI_EN | REG_RXINT_RAL(ir->fifo_size / 2 - 1),
|
||||
+ ir->base + SUNXI_IR_RXINT_REG);
|
||||
+
|
||||
+ /* Enable IR Module */
|
||||
+ tmp = readl(ir->base + SUNXI_IR_CTL_REG);
|
||||
+ writel(tmp | REG_CTL_GEN | REG_CTL_RXEN, ir->base + SUNXI_IR_CTL_REG);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+exit_apb_clk_disable:
|
||||
+ clk_disable_unprepare(ir->apb_clk);
|
||||
+exit_reset_assert:
|
||||
+ reset_control_assert(ir->rst);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void sunxi_ir_hw_exit(struct device *dev)
|
||||
+{
|
||||
+ struct sunxi_ir *ir = dev_get_drvdata(dev);
|
||||
+
|
||||
+ clk_disable_unprepare(ir->clk);
|
||||
+ clk_disable_unprepare(ir->apb_clk);
|
||||
+ reset_control_assert(ir->rst);
|
||||
+}
|
||||
+
|
||||
static int sunxi_ir_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
- unsigned long tmp = 0;
|
||||
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *dn = dev->of_node;
|
||||
@@ -207,49 +279,26 @@ static int sunxi_ir_probe(struct platfor
|
||||
|
||||
/* Base clock frequency (optional) */
|
||||
of_property_read_u32(dn, "clock-frequency", &b_clk_freq);
|
||||
+ ir->base_clk_freq = b_clk_freq;
|
||||
|
||||
/* Reset */
|
||||
if (quirks->has_reset) {
|
||||
ir->rst = devm_reset_control_get_exclusive(dev, NULL);
|
||||
if (IS_ERR(ir->rst))
|
||||
return PTR_ERR(ir->rst);
|
||||
- ret = reset_control_deassert(ir->rst);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- ret = clk_set_rate(ir->clk, b_clk_freq);
|
||||
- if (ret) {
|
||||
- dev_err(dev, "set ir base clock failed!\n");
|
||||
- goto exit_reset_assert;
|
||||
- }
|
||||
- dev_dbg(dev, "set base clock frequency to %d Hz.\n", b_clk_freq);
|
||||
-
|
||||
- if (clk_prepare_enable(ir->apb_clk)) {
|
||||
- dev_err(dev, "try to enable apb_ir_clk failed\n");
|
||||
- ret = -EINVAL;
|
||||
- goto exit_reset_assert;
|
||||
- }
|
||||
-
|
||||
- if (clk_prepare_enable(ir->clk)) {
|
||||
- dev_err(dev, "try to enable ir_clk failed\n");
|
||||
- ret = -EINVAL;
|
||||
- goto exit_clkdisable_apb_clk;
|
||||
}
|
||||
|
||||
/* IO */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
ir->base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(ir->base)) {
|
||||
- ret = PTR_ERR(ir->base);
|
||||
- goto exit_clkdisable_clk;
|
||||
+ return PTR_ERR(ir->base);
|
||||
}
|
||||
|
||||
ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||||
if (!ir->rc) {
|
||||
dev_err(dev, "failed to allocate device\n");
|
||||
- ret = -ENOMEM;
|
||||
- goto exit_clkdisable_clk;
|
||||
+ return -ENOMEM;
|
||||
}
|
||||
|
||||
ir->rc->priv = ir;
|
||||
@@ -265,6 +314,7 @@ static int sunxi_ir_probe(struct platfor
|
||||
ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
|
||||
/* Frequency after IR internal divider with sample period in us */
|
||||
ir->rc->rx_resolution = (USEC_PER_SEC / (b_clk_freq / 64));
|
||||
+ ir->rc->timeout = IR_DEFAULT_TIMEOUT;
|
||||
ir->rc->min_timeout = sunxi_ithr_to_usec(b_clk_freq, 0);
|
||||
ir->rc->max_timeout = sunxi_ithr_to_usec(b_clk_freq, 255);
|
||||
ir->rc->s_timeout = sunxi_ir_set_timeout;
|
||||
@@ -291,41 +341,15 @@ static int sunxi_ir_probe(struct platfor
|
||||
goto exit_free_dev;
|
||||
}
|
||||
|
||||
- /* Enable CIR Mode */
|
||||
- writel(REG_CTL_MD, ir->base+SUNXI_IR_CTL_REG);
|
||||
-
|
||||
- /* Set noise threshold and idle threshold */
|
||||
- sunxi_ir_set_timeout(ir->rc, IR_DEFAULT_TIMEOUT);
|
||||
-
|
||||
- /* Invert Input Signal */
|
||||
- writel(REG_RXCTL_RPPI, ir->base + SUNXI_IR_RXCTL_REG);
|
||||
-
|
||||
- /* Clear All Rx Interrupt Status */
|
||||
- writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG);
|
||||
-
|
||||
- /*
|
||||
- * Enable IRQ on overflow, packet end, FIFO available with trigger
|
||||
- * level
|
||||
- */
|
||||
- writel(REG_RXINT_ROI_EN | REG_RXINT_RPEI_EN |
|
||||
- REG_RXINT_RAI_EN | REG_RXINT_RAL(ir->fifo_size / 2 - 1),
|
||||
- ir->base + SUNXI_IR_RXINT_REG);
|
||||
-
|
||||
- /* Enable IR Module */
|
||||
- tmp = readl(ir->base + SUNXI_IR_CTL_REG);
|
||||
- writel(tmp | REG_CTL_GEN | REG_CTL_RXEN, ir->base + SUNXI_IR_CTL_REG);
|
||||
+ ret = sunxi_ir_hw_init(dev);
|
||||
+ if (ret)
|
||||
+ goto exit_free_dev;
|
||||
|
||||
dev_info(dev, "initialized sunXi IR driver\n");
|
||||
return 0;
|
||||
|
||||
exit_free_dev:
|
||||
rc_free_device(ir->rc);
|
||||
-exit_clkdisable_clk:
|
||||
- clk_disable_unprepare(ir->clk);
|
||||
-exit_clkdisable_apb_clk:
|
||||
- clk_disable_unprepare(ir->apb_clk);
|
||||
-exit_reset_assert:
|
||||
- reset_control_assert(ir->rst);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -334,11 +358,9 @@ static int sunxi_ir_remove(struct platfo
|
||||
{
|
||||
struct sunxi_ir *ir = platform_get_drvdata(pdev);
|
||||
|
||||
- clk_disable_unprepare(ir->clk);
|
||||
- clk_disable_unprepare(ir->apb_clk);
|
||||
- reset_control_assert(ir->rst);
|
||||
-
|
||||
+ sunxi_ir_hw_exit(&pdev->dev);
|
||||
rc_unregister_device(ir->rc);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,60 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 10 Jan 2021 00:51:31 -0600
|
||||
Subject: [PATCH] media: sunxi-cir: Implement suspend/resume/shutdown callbacks
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
drivers/media/rc/sunxi-cir.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
--- a/drivers/media/rc/sunxi-cir.c
|
||||
+++ b/drivers/media/rc/sunxi-cir.c
|
||||
@@ -242,6 +242,18 @@ static void sunxi_ir_hw_exit(struct devi
|
||||
reset_control_assert(ir->rst);
|
||||
}
|
||||
|
||||
+static int __maybe_unused sunxi_ir_suspend(struct device *dev)
|
||||
+{
|
||||
+ sunxi_ir_hw_exit(dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __maybe_unused sunxi_ir_resume(struct device *dev)
|
||||
+{
|
||||
+ return sunxi_ir_hw_init(dev);
|
||||
+}
|
||||
+
|
||||
static int sunxi_ir_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -364,6 +376,11 @@ static int sunxi_ir_remove(struct platfo
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void sunxi_ir_shutdown(struct platform_device *pdev)
|
||||
+{
|
||||
+ sunxi_ir_hw_exit(&pdev->dev);
|
||||
+}
|
||||
+
|
||||
static const struct sunxi_ir_quirks sun4i_a10_ir_quirks = {
|
||||
.has_reset = false,
|
||||
.fifo_size = 16,
|
||||
@@ -396,12 +413,16 @@ static const struct of_device_id sunxi_i
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sunxi_ir_match);
|
||||
|
||||
+static SIMPLE_DEV_PM_OPS(sunxi_ir_pm_ops, sunxi_ir_suspend, sunxi_ir_resume);
|
||||
+
|
||||
static struct platform_driver sunxi_ir_driver = {
|
||||
.probe = sunxi_ir_probe,
|
||||
.remove = sunxi_ir_remove,
|
||||
+ .shutdown = sunxi_ir_shutdown,
|
||||
.driver = {
|
||||
.name = SUNXI_IR_DEV,
|
||||
.of_match_table = sunxi_ir_match,
|
||||
+ .pm = &sunxi_ir_pm_ops,
|
||||
},
|
||||
};
|
||||
|
@ -1,437 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 25 Aug 2019 05:35:08 -0500
|
||||
Subject: [PATCH] irqchip/sun6i-r: Use a stacked irqchip driver
|
||||
|
||||
The R_INTC in the A31 and newer sun8i/sun50i SoCs is more similar to the
|
||||
original sun4i interrupt controller than the sun7i/sun9i NMI controller.
|
||||
It is used for two distinct purposes:
|
||||
- To control the trigger, latch, and mask for the NMI input pin
|
||||
- To provide the interrupt input for the ARISC coprocessor
|
||||
|
||||
As this interrupt controller is not documented, information about it
|
||||
comes from vendor-provided firmware blobs and from experimentation.
|
||||
|
||||
Differences from the sun4i interrupt controller appear to be:
|
||||
- It only has one or two registers of each kind (max 32 or 64 IRQs)
|
||||
- Multiplexing logic is added to support additional inputs
|
||||
- There is no FIQ-related logic
|
||||
- There is no interrupt priority logic
|
||||
|
||||
In order to fulfill its two purposes, this hardware block combines four
|
||||
types of IRQs. First, the NMI pin is routed to the "IRQ 0" input on this
|
||||
chip, with a trigger type controlled by the NMI_CTRL_REG. The "IRQ 0
|
||||
pending" output from this chip, if enabled, is then routed to a SPI IRQ
|
||||
input on the GIC. In other words, bit 0 of IRQ_ENABLE_REG *does* affect
|
||||
the NMI IRQ seen at the GIC.
|
||||
|
||||
The NMI is followed by a contiguous block of 15 "direct" (my name for
|
||||
them) IRQ inputs that are connected in parallel to both R_INTC and the
|
||||
GIC. Or in other words, these bits of IRQ_ENABLE_REG *do not* affect the
|
||||
IRQs seen at the GIC.
|
||||
|
||||
Following the direct IRQs are the ARISC's copy of banked IRQs for shared
|
||||
peripherals. These are not relevant to Linux. The remaining IRQs are
|
||||
connected to a multiplexer and provide access to the first (up to) 128
|
||||
SPIs from the ARISC. This range of SPIs overlaps with the direct IRQs.
|
||||
|
||||
Because of the 1:1 correspondence between R_INTC and GIC inputs, this is
|
||||
a perfect scenario for using a stacked irqchip driver. We want to hook
|
||||
into setting the NMI trigger type, but not actually handle any IRQ here.
|
||||
|
||||
To allow access to all multiplexed IRQs, this driver requires a new
|
||||
binding where the interrupt number matches the GIC interrupt number.
|
||||
(This moves the NMI from number 0 to 32 or 96, depending on the SoC.)
|
||||
For simplicity, copy the three-cell GIC binding; this disambiguates
|
||||
interrupt 0 in the old binding (the NMI) from interrupt 0 in the new
|
||||
binding (SPI 0) by the number of cells.
|
||||
|
||||
Since R_INTC is in the always-on power domain, and its output is visible
|
||||
to the power management coprocessor, a stacked irqchip driver provides a
|
||||
simple way to add wakeup support to any of its IRQs. That is the next
|
||||
patch; for now, just the NMI is moved over.
|
||||
|
||||
This commit mostly reverts commit 173bda53b340 ("irqchip/sunxi-nmi:
|
||||
Support sun6i-a31-r-intc compatible").
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
arch/arm/mach-sunxi/Kconfig | 2 +
|
||||
arch/arm64/Kconfig.platforms | 2 +
|
||||
drivers/irqchip/Makefile | 1 +
|
||||
drivers/irqchip/irq-sun6i-r.c | 284 ++++++++++++++++++++++++++++++++
|
||||
drivers/irqchip/irq-sunxi-nmi.c | 26 +--
|
||||
5 files changed, 292 insertions(+), 23 deletions(-)
|
||||
create mode 100644 drivers/irqchip/irq-sun6i-r.c
|
||||
|
||||
--- a/arch/arm/mach-sunxi/Kconfig
|
||||
+++ b/arch/arm/mach-sunxi/Kconfig
|
||||
@@ -6,6 +6,8 @@ menuconfig ARCH_SUNXI
|
||||
select CLKSRC_MMIO
|
||||
select GENERIC_IRQ_CHIP
|
||||
select GPIOLIB
|
||||
+ select IRQ_DOMAIN_HIERARCHY
|
||||
+ select IRQ_FASTEOI_HIERARCHY_HANDLERS
|
||||
select PINCTRL
|
||||
select PM_OPP
|
||||
select SUN4I_TIMER
|
||||
--- a/arch/arm64/Kconfig.platforms
|
||||
+++ b/arch/arm64/Kconfig.platforms
|
||||
@@ -17,6 +17,8 @@ config ARCH_SUNXI
|
||||
bool "Allwinner sunxi 64-bit SoC Family"
|
||||
select ARCH_HAS_RESET_CONTROLLER
|
||||
select GENERIC_IRQ_CHIP
|
||||
+ select IRQ_DOMAIN_HIERARCHY
|
||||
+ select IRQ_FASTEOI_HIERARCHY_HANDLERS
|
||||
select PINCTRL
|
||||
select RESET_CONTROLLER
|
||||
help
|
||||
--- a/drivers/irqchip/Makefile
|
||||
+++ b/drivers/irqchip/Makefile
|
||||
@@ -24,6 +24,7 @@ obj-$(CONFIG_OR1K_PIC) += irq-or1k-pic
|
||||
obj-$(CONFIG_ORION_IRQCHIP) += irq-orion.o
|
||||
obj-$(CONFIG_OMAP_IRQCHIP) += irq-omap-intc.o
|
||||
obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o
|
||||
+obj-$(CONFIG_ARCH_SUNXI) += irq-sun6i-r.o
|
||||
obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o
|
||||
obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o
|
||||
obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/irqchip/irq-sun6i-r.c
|
||||
@@ -0,0 +1,284 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * The R_INTC in Allwinner A31 and newer SoCs manages several types of
|
||||
+ * interrupts, as shown below:
|
||||
+ *
|
||||
+ * NMI IRQ DIRECT IRQs MUXED IRQs
|
||||
+ * bit 0 bits 1-15^ bits 19-31
|
||||
+ *
|
||||
+ * +---------+ +---------+ +---------+ +---------+
|
||||
+ * | NMI Pad | | IRQ d | | IRQ m | | IRQ m+7 |
|
||||
+ * +---------+ +---------+ +---------+ +---------+
|
||||
+ * | | | | | | |
|
||||
+ * | | | | |......| |
|
||||
+ * +------V------+ +------------+ | | | +--V------V--+ |
|
||||
+ * | Invert/ | | Write 1 to | | | | | AND with | |
|
||||
+ * | Edge Detect | | PENDING[0] | | | | | MUX[m/8] | |
|
||||
+ * +-------------+ +------------+ | | | +------------+ |
|
||||
+ * | | | | | | |
|
||||
+ * +--V-------V--+ +--V--+ | +--V--+ | +--V--+
|
||||
+ * | Set Reset| | GIC | | | GIC | | | GIC |
|
||||
+ * | Latch | | SPI | | | SPI |... | ...| SPI |
|
||||
+ * +-------------+ | N+d | | | m | | | m+7 |
|
||||
+ * | | +-----+ | +-----+ | +-----+
|
||||
+ * | | | |
|
||||
+ * +-------V-+ +-V----------+ +---------V--+ +--------V--------+
|
||||
+ * | GIC SPI | | AND with | | AND with | | AND with |
|
||||
+ * | N (=32) | | ENABLE[0] | | ENABLE[d] | | ENABLE[19+m/8] |
|
||||
+ * +---------+ +------------+ +------------+ +-----------------+
|
||||
+ * | | |
|
||||
+ * +------V-----+ +------V-----+ +--------V--------+
|
||||
+ * | Read | | Read | | Read |
|
||||
+ * | PENDING[0] | | PENDING[d] | | PENDING[19+m/8] |
|
||||
+ * +------------+ +------------+ +-----------------+
|
||||
+ *
|
||||
+ * ^ bits 16-18 are direct IRQs for peripherals with banked interrupts, such as
|
||||
+ * the MSGBOX. These IRQs do not map to any GIC SPI.
|
||||
+ *
|
||||
+ * The H6 variant adds two more (banked) direct IRQs and implements the full
|
||||
+ * set of 128 mux bits. This requires a second set of top-level registers.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/irqchip.h>
|
||||
+#include <linux/irqdomain.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+
|
||||
+#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
+
|
||||
+#define SUN6I_NMI_CTRL (0x0c)
|
||||
+#define SUN6I_IRQ_PENDING(n) (0x10 + 4 * (n))
|
||||
+#define SUN6I_IRQ_ENABLE(n) (0x40 + 4 * (n))
|
||||
+#define SUN6I_MUX_ENABLE(n) (0xc0 + 4 * (n))
|
||||
+
|
||||
+#define SUN6I_NMI_SRC_TYPE_LEVEL_LOW 0
|
||||
+#define SUN6I_NMI_SRC_TYPE_EDGE_FALLING 1
|
||||
+#define SUN6I_NMI_SRC_TYPE_LEVEL_HIGH 2
|
||||
+#define SUN6I_NMI_SRC_TYPE_EDGE_RISING 3
|
||||
+
|
||||
+#define SUN6I_NMI_BIT BIT(0)
|
||||
+
|
||||
+#define SUN6I_NMI_NEEDS_ACK ((void *)1)
|
||||
+
|
||||
+#define SUN6I_NR_TOP_LEVEL_IRQS 64
|
||||
+#define SUN6I_NR_DIRECT_IRQS 16
|
||||
+#define SUN6I_NR_MUX_BITS 128
|
||||
+
|
||||
+static void __iomem *base;
|
||||
+static irq_hw_number_t nmi_hwirq;
|
||||
+
|
||||
+static void sun6i_r_intc_ack_nmi(void)
|
||||
+{
|
||||
+ writel(SUN6I_NMI_BIT, base + SUN6I_IRQ_PENDING(0));
|
||||
+}
|
||||
+
|
||||
+static void sun6i_r_intc_nmi_ack(struct irq_data *data)
|
||||
+{
|
||||
+ if (irqd_get_trigger_type(data) & IRQ_TYPE_EDGE_BOTH)
|
||||
+ sun6i_r_intc_ack_nmi();
|
||||
+ else
|
||||
+ data->chip_data = SUN6I_NMI_NEEDS_ACK;
|
||||
+}
|
||||
+
|
||||
+static void sun6i_r_intc_nmi_eoi(struct irq_data *data)
|
||||
+{
|
||||
+ /* For oneshot IRQs, delay the ack until the IRQ is unmasked. */
|
||||
+ if (data->chip_data == SUN6I_NMI_NEEDS_ACK && !irqd_irq_masked(data)) {
|
||||
+ sun6i_r_intc_ack_nmi();
|
||||
+ data->chip_data = 0;
|
||||
+ }
|
||||
+
|
||||
+ irq_chip_eoi_parent(data);
|
||||
+}
|
||||
+
|
||||
+static void sun6i_r_intc_nmi_unmask(struct irq_data *data)
|
||||
+{
|
||||
+ if (data->chip_data == SUN6I_NMI_NEEDS_ACK) {
|
||||
+ sun6i_r_intc_ack_nmi();
|
||||
+ data->chip_data = 0;
|
||||
+ }
|
||||
+
|
||||
+ irq_chip_unmask_parent(data);
|
||||
+}
|
||||
+
|
||||
+static int sun6i_r_intc_nmi_set_type(struct irq_data *data, unsigned int type)
|
||||
+{
|
||||
+ u32 nmi_src_type;
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case IRQ_TYPE_EDGE_RISING:
|
||||
+ nmi_src_type = SUN6I_NMI_SRC_TYPE_EDGE_RISING;
|
||||
+ break;
|
||||
+ case IRQ_TYPE_EDGE_FALLING:
|
||||
+ nmi_src_type = SUN6I_NMI_SRC_TYPE_EDGE_FALLING;
|
||||
+ break;
|
||||
+ case IRQ_TYPE_LEVEL_HIGH:
|
||||
+ nmi_src_type = SUN6I_NMI_SRC_TYPE_LEVEL_HIGH;
|
||||
+ break;
|
||||
+ case IRQ_TYPE_LEVEL_LOW:
|
||||
+ nmi_src_type = SUN6I_NMI_SRC_TYPE_LEVEL_LOW;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ writel_relaxed(nmi_src_type, base + SUN6I_NMI_CTRL);
|
||||
+
|
||||
+ /*
|
||||
+ * The "External NMI" GIC input connects to a latch inside R_INTC, not
|
||||
+ * directly to the pin. So the GIC trigger type does not depend on the
|
||||
+ * NMI pin trigger type.
|
||||
+ */
|
||||
+ return irq_chip_set_type_parent(data, IRQ_TYPE_LEVEL_HIGH);
|
||||
+}
|
||||
+
|
||||
+static int sun6i_r_intc_nmi_set_irqchip_state(struct irq_data *data,
|
||||
+ enum irqchip_irq_state which,
|
||||
+ bool state)
|
||||
+{
|
||||
+ if (which == IRQCHIP_STATE_PENDING && !state)
|
||||
+ sun6i_r_intc_ack_nmi();
|
||||
+
|
||||
+ return irq_chip_set_parent_state(data, which, state);
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip sun6i_r_intc_nmi_chip = {
|
||||
+ .name = "sun6i-r-intc",
|
||||
+ .irq_ack = sun6i_r_intc_nmi_ack,
|
||||
+ .irq_mask = irq_chip_mask_parent,
|
||||
+ .irq_unmask = sun6i_r_intc_nmi_unmask,
|
||||
+ .irq_eoi = sun6i_r_intc_nmi_eoi,
|
||||
+ .irq_set_affinity = irq_chip_set_affinity_parent,
|
||||
+ .irq_set_type = sun6i_r_intc_nmi_set_type,
|
||||
+ .irq_set_irqchip_state = sun6i_r_intc_nmi_set_irqchip_state,
|
||||
+ .flags = IRQCHIP_SET_TYPE_MASKED |
|
||||
+ IRQCHIP_SKIP_SET_WAKE,
|
||||
+};
|
||||
+
|
||||
+static int sun6i_r_intc_domain_translate(struct irq_domain *domain,
|
||||
+ struct irq_fwspec *fwspec,
|
||||
+ unsigned long *hwirq,
|
||||
+ unsigned int *type)
|
||||
+{
|
||||
+ /* Accept the old two-cell binding for the NMI only. */
|
||||
+ if (fwspec->param_count == 2 && fwspec->param[0] == 0) {
|
||||
+ *hwirq = nmi_hwirq;
|
||||
+ *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Otherwise this binding should match the GIC SPI binding. */
|
||||
+ if (fwspec->param_count < 3)
|
||||
+ return -EINVAL;
|
||||
+ if (fwspec->param[0] != GIC_SPI)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ *hwirq = fwspec->param[1];
|
||||
+ *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sun6i_r_intc_domain_alloc(struct irq_domain *domain,
|
||||
+ unsigned int virq,
|
||||
+ unsigned int nr_irqs, void *arg)
|
||||
+{
|
||||
+ struct irq_fwspec *fwspec = arg;
|
||||
+ struct irq_fwspec gic_fwspec;
|
||||
+ unsigned long hwirq;
|
||||
+ unsigned int type;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ ret = sun6i_r_intc_domain_translate(domain, fwspec, &hwirq, &type);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ if (hwirq + nr_irqs > SUN6I_NR_MUX_BITS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Construct a GIC-compatible fwspec from this fwspec. */
|
||||
+ gic_fwspec = (struct irq_fwspec) {
|
||||
+ .fwnode = domain->parent->fwnode,
|
||||
+ .param_count = 3,
|
||||
+ .param = { GIC_SPI, hwirq, type },
|
||||
+ };
|
||||
+
|
||||
+ ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_fwspec);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ for (i = 0; i < nr_irqs; ++i, ++hwirq, ++virq) {
|
||||
+ if (hwirq == nmi_hwirq) {
|
||||
+ irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
|
||||
+ &sun6i_r_intc_nmi_chip, 0);
|
||||
+ irq_set_handler(virq, handle_fasteoi_ack_irq);
|
||||
+ } else {
|
||||
+ /* Only the NMI is currently supported. */
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct irq_domain_ops sun6i_r_intc_domain_ops = {
|
||||
+ .translate = sun6i_r_intc_domain_translate,
|
||||
+ .alloc = sun6i_r_intc_domain_alloc,
|
||||
+ .free = irq_domain_free_irqs_common,
|
||||
+};
|
||||
+
|
||||
+static void sun6i_r_intc_resume(void)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ /* Only the NMI is relevant during normal operation. */
|
||||
+ writel_relaxed(SUN6I_NMI_BIT, base + SUN6I_IRQ_ENABLE(0));
|
||||
+ for (i = 1; i < BITS_TO_U32(SUN6I_NR_TOP_LEVEL_IRQS); ++i)
|
||||
+ writel_relaxed(0, base + SUN6I_IRQ_ENABLE(i));
|
||||
+}
|
||||
+
|
||||
+static int __init sun6i_r_intc_init(struct device_node *node,
|
||||
+ struct device_node *parent)
|
||||
+{
|
||||
+ struct irq_domain *domain, *parent_domain;
|
||||
+ struct of_phandle_args nmi_parent;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Extract the NMI hwirq number from the OF node. */
|
||||
+ ret = of_irq_parse_one(node, 0, &nmi_parent);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ if (nmi_parent.args_count < 3 ||
|
||||
+ nmi_parent.args[0] != GIC_SPI ||
|
||||
+ nmi_parent.args[2] != IRQ_TYPE_LEVEL_HIGH)
|
||||
+ return -EINVAL;
|
||||
+ nmi_hwirq = nmi_parent.args[1];
|
||||
+
|
||||
+ parent_domain = irq_find_host(parent);
|
||||
+ if (!parent_domain) {
|
||||
+ pr_err("%pOF: Failed to obtain parent domain\n", node);
|
||||
+ return -ENXIO;
|
||||
+ }
|
||||
+
|
||||
+ base = of_io_request_and_map(node, 0, NULL);
|
||||
+ if (IS_ERR(base)) {
|
||||
+ pr_err("%pOF: Failed to map MMIO region\n", node);
|
||||
+ return PTR_ERR(base);
|
||||
+ }
|
||||
+
|
||||
+ domain = irq_domain_add_hierarchy(parent_domain, 0, 0, node,
|
||||
+ &sun6i_r_intc_domain_ops, NULL);
|
||||
+ if (!domain) {
|
||||
+ pr_err("%pOF: Failed to allocate domain\n", node);
|
||||
+ iounmap(base);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ sun6i_r_intc_ack_nmi();
|
||||
+ sun6i_r_intc_resume();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+IRQCHIP_DECLARE(sun6i_r_intc, "allwinner,sun6i-a31-r-intc", sun6i_r_intc_init);
|
||||
--- a/drivers/irqchip/irq-sunxi-nmi.c
|
||||
+++ b/drivers/irqchip/irq-sunxi-nmi.c
|
||||
@@ -27,18 +27,12 @@
|
||||
|
||||
#define SUNXI_NMI_IRQ_BIT BIT(0)
|
||||
|
||||
-#define SUN6I_R_INTC_CTRL 0x0c
|
||||
-#define SUN6I_R_INTC_PENDING 0x10
|
||||
-#define SUN6I_R_INTC_ENABLE 0x40
|
||||
-
|
||||
/*
|
||||
* For deprecated sun6i-a31-sc-nmi compatible.
|
||||
- * Registers are offset by 0x0c.
|
||||
*/
|
||||
-#define SUN6I_R_INTC_NMI_OFFSET 0x0c
|
||||
-#define SUN6I_NMI_CTRL (SUN6I_R_INTC_CTRL - SUN6I_R_INTC_NMI_OFFSET)
|
||||
-#define SUN6I_NMI_PENDING (SUN6I_R_INTC_PENDING - SUN6I_R_INTC_NMI_OFFSET)
|
||||
-#define SUN6I_NMI_ENABLE (SUN6I_R_INTC_ENABLE - SUN6I_R_INTC_NMI_OFFSET)
|
||||
+#define SUN6I_NMI_CTRL 0x00
|
||||
+#define SUN6I_NMI_PENDING 0x04
|
||||
+#define SUN6I_NMI_ENABLE 0x34
|
||||
|
||||
#define SUN7I_NMI_CTRL 0x00
|
||||
#define SUN7I_NMI_PENDING 0x04
|
||||
@@ -61,12 +55,6 @@ struct sunxi_sc_nmi_reg_offs {
|
||||
u32 enable;
|
||||
};
|
||||
|
||||
-static const struct sunxi_sc_nmi_reg_offs sun6i_r_intc_reg_offs __initconst = {
|
||||
- .ctrl = SUN6I_R_INTC_CTRL,
|
||||
- .pend = SUN6I_R_INTC_PENDING,
|
||||
- .enable = SUN6I_R_INTC_ENABLE,
|
||||
-};
|
||||
-
|
||||
static const struct sunxi_sc_nmi_reg_offs sun6i_reg_offs __initconst = {
|
||||
.ctrl = SUN6I_NMI_CTRL,
|
||||
.pend = SUN6I_NMI_PENDING,
|
||||
@@ -232,14 +220,6 @@ fail_irqd_remove:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int __init sun6i_r_intc_irq_init(struct device_node *node,
|
||||
- struct device_node *parent)
|
||||
-{
|
||||
- return sunxi_sc_nmi_irq_init(node, &sun6i_r_intc_reg_offs);
|
||||
-}
|
||||
-IRQCHIP_DECLARE(sun6i_r_intc, "allwinner,sun6i-a31-r-intc",
|
||||
- sun6i_r_intc_irq_init);
|
||||
-
|
||||
static int __init sun6i_sc_nmi_irq_init(struct device_node *node,
|
||||
struct device_node *parent)
|
||||
{
|
@ -1,210 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 12 Jan 2020 20:00:36 -0600
|
||||
Subject: [PATCH] irqchip/sun6i-r: Add wakeup support
|
||||
|
||||
Maintain bitmaps of wake-enabled IRQs and mux inputs, and program them
|
||||
to the hardware during the syscore phase of suspend and shutdown. Then
|
||||
restore the original set of enabled IRQs (only the NMI) during resume.
|
||||
|
||||
This serves two purposes. First, it lets power management firmware
|
||||
running on the ARISC coprocessor know which wakeup sources Linux wants
|
||||
to have enabled. That way, it can avoid turning them off when it shuts
|
||||
down the remainder of the clock tree. Second, it preconfigures the
|
||||
coprocessor's interrupt controller, so the firmware's wakeup logic
|
||||
is as simple as waiting for an interrupt to arrive.
|
||||
|
||||
The suspend/resume logic is not conditional on PM_SLEEP because it is
|
||||
identical to the init/shutdown logic. Wake IRQs may be enabled during
|
||||
shutdown to allow powering the board back on. As an example, see
|
||||
commit a5c5e50cce9d ("Input: gpio-keys - add shutdown callback").
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
drivers/irqchip/irq-sun6i-r.c | 107 ++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 101 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/irqchip/irq-sun6i-r.c
|
||||
+++ b/drivers/irqchip/irq-sun6i-r.c
|
||||
@@ -39,6 +39,7 @@
|
||||
* set of 128 mux bits. This requires a second set of top-level registers.
|
||||
*/
|
||||
|
||||
+#include <linux/bitmap.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqchip.h>
|
||||
@@ -46,6 +47,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
+#include <linux/syscore_ops.h>
|
||||
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
@@ -67,8 +69,17 @@
|
||||
#define SUN6I_NR_DIRECT_IRQS 16
|
||||
#define SUN6I_NR_MUX_BITS 128
|
||||
|
||||
+struct sun6i_r_intc_variant {
|
||||
+ u32 first_mux_irq;
|
||||
+ u32 nr_mux_irqs;
|
||||
+ u32 mux_valid[BITS_TO_U32(SUN6I_NR_MUX_BITS)];
|
||||
+};
|
||||
+
|
||||
static void __iomem *base;
|
||||
static irq_hw_number_t nmi_hwirq;
|
||||
+static DECLARE_BITMAP(wake_irq_enabled, SUN6I_NR_TOP_LEVEL_IRQS);
|
||||
+static DECLARE_BITMAP(wake_mux_enabled, SUN6I_NR_MUX_BITS);
|
||||
+static DECLARE_BITMAP(wake_mux_valid, SUN6I_NR_MUX_BITS);
|
||||
|
||||
static void sun6i_r_intc_ack_nmi(void)
|
||||
{
|
||||
@@ -145,6 +156,21 @@ static int sun6i_r_intc_nmi_set_irqchip_
|
||||
return irq_chip_set_parent_state(data, which, state);
|
||||
}
|
||||
|
||||
+static int sun6i_r_intc_irq_set_wake(struct irq_data *data, unsigned int on)
|
||||
+{
|
||||
+ unsigned long offset_from_nmi = data->hwirq - nmi_hwirq;
|
||||
+
|
||||
+ if (offset_from_nmi < SUN6I_NR_DIRECT_IRQS)
|
||||
+ assign_bit(offset_from_nmi, wake_irq_enabled, on);
|
||||
+ else if (test_bit(data->hwirq, wake_mux_valid))
|
||||
+ assign_bit(data->hwirq, wake_mux_enabled, on);
|
||||
+ else
|
||||
+ /* Not wakeup capable. */
|
||||
+ return -EPERM;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static struct irq_chip sun6i_r_intc_nmi_chip = {
|
||||
.name = "sun6i-r-intc",
|
||||
.irq_ack = sun6i_r_intc_nmi_ack,
|
||||
@@ -154,8 +180,19 @@ static struct irq_chip sun6i_r_intc_nmi_
|
||||
.irq_set_affinity = irq_chip_set_affinity_parent,
|
||||
.irq_set_type = sun6i_r_intc_nmi_set_type,
|
||||
.irq_set_irqchip_state = sun6i_r_intc_nmi_set_irqchip_state,
|
||||
- .flags = IRQCHIP_SET_TYPE_MASKED |
|
||||
- IRQCHIP_SKIP_SET_WAKE,
|
||||
+ .irq_set_wake = sun6i_r_intc_irq_set_wake,
|
||||
+ .flags = IRQCHIP_SET_TYPE_MASKED,
|
||||
+};
|
||||
+
|
||||
+static struct irq_chip sun6i_r_intc_wakeup_chip = {
|
||||
+ .name = "sun6i-r-intc",
|
||||
+ .irq_mask = irq_chip_mask_parent,
|
||||
+ .irq_unmask = irq_chip_unmask_parent,
|
||||
+ .irq_eoi = irq_chip_eoi_parent,
|
||||
+ .irq_set_affinity = irq_chip_set_affinity_parent,
|
||||
+ .irq_set_type = irq_chip_set_type_parent,
|
||||
+ .irq_set_wake = sun6i_r_intc_irq_set_wake,
|
||||
+ .flags = IRQCHIP_SET_TYPE_MASKED,
|
||||
};
|
||||
|
||||
static int sun6i_r_intc_domain_translate(struct irq_domain *domain,
|
||||
@@ -215,8 +252,8 @@ static int sun6i_r_intc_domain_alloc(str
|
||||
&sun6i_r_intc_nmi_chip, 0);
|
||||
irq_set_handler(virq, handle_fasteoi_ack_irq);
|
||||
} else {
|
||||
- /* Only the NMI is currently supported. */
|
||||
- return -EINVAL;
|
||||
+ irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
|
||||
+ &sun6i_r_intc_wakeup_chip, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,6 +266,22 @@ static const struct irq_domain_ops sun6i
|
||||
.free = irq_domain_free_irqs_common,
|
||||
};
|
||||
|
||||
+static int sun6i_r_intc_suspend(void)
|
||||
+{
|
||||
+ u32 buf[BITS_TO_U32(max(SUN6I_NR_TOP_LEVEL_IRQS, SUN6I_NR_MUX_BITS))];
|
||||
+ int i;
|
||||
+
|
||||
+ /* Wake IRQs are enabled during system sleep and shutdown. */
|
||||
+ bitmap_to_arr32(buf, wake_irq_enabled, SUN6I_NR_TOP_LEVEL_IRQS);
|
||||
+ for (i = 0; i < BITS_TO_U32(SUN6I_NR_TOP_LEVEL_IRQS); ++i)
|
||||
+ writel_relaxed(buf[i], base + SUN6I_IRQ_ENABLE(i));
|
||||
+ bitmap_to_arr32(buf, wake_mux_enabled, SUN6I_NR_MUX_BITS);
|
||||
+ for (i = 0; i < BITS_TO_U32(SUN6I_NR_MUX_BITS); ++i)
|
||||
+ writel_relaxed(buf[i], base + SUN6I_MUX_ENABLE(i));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void sun6i_r_intc_resume(void)
|
||||
{
|
||||
int i;
|
||||
@@ -239,8 +292,20 @@ static void sun6i_r_intc_resume(void)
|
||||
writel_relaxed(0, base + SUN6I_IRQ_ENABLE(i));
|
||||
}
|
||||
|
||||
+static void sun6i_r_intc_shutdown(void)
|
||||
+{
|
||||
+ sun6i_r_intc_suspend();
|
||||
+}
|
||||
+
|
||||
+static struct syscore_ops sun6i_r_intc_syscore_ops = {
|
||||
+ .suspend = sun6i_r_intc_suspend,
|
||||
+ .resume = sun6i_r_intc_resume,
|
||||
+ .shutdown = sun6i_r_intc_shutdown,
|
||||
+};
|
||||
+
|
||||
static int __init sun6i_r_intc_init(struct device_node *node,
|
||||
- struct device_node *parent)
|
||||
+ struct device_node *parent,
|
||||
+ const struct sun6i_r_intc_variant *v)
|
||||
{
|
||||
struct irq_domain *domain, *parent_domain;
|
||||
struct of_phandle_args nmi_parent;
|
||||
@@ -256,6 +321,9 @@ static int __init sun6i_r_intc_init(stru
|
||||
return -EINVAL;
|
||||
nmi_hwirq = nmi_parent.args[1];
|
||||
|
||||
+ bitmap_set(wake_irq_enabled, v->first_mux_irq, v->nr_mux_irqs);
|
||||
+ bitmap_from_arr32(wake_mux_valid, v->mux_valid, SUN6I_NR_MUX_BITS);
|
||||
+
|
||||
parent_domain = irq_find_host(parent);
|
||||
if (!parent_domain) {
|
||||
pr_err("%pOF: Failed to obtain parent domain\n", node);
|
||||
@@ -276,9 +344,36 @@ static int __init sun6i_r_intc_init(stru
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
+ register_syscore_ops(&sun6i_r_intc_syscore_ops);
|
||||
+
|
||||
sun6i_r_intc_ack_nmi();
|
||||
sun6i_r_intc_resume();
|
||||
|
||||
return 0;
|
||||
}
|
||||
-IRQCHIP_DECLARE(sun6i_r_intc, "allwinner,sun6i-a31-r-intc", sun6i_r_intc_init);
|
||||
+
|
||||
+static const struct sun6i_r_intc_variant sun6i_a31_r_intc_variant __initconst = {
|
||||
+ .first_mux_irq = 19,
|
||||
+ .nr_mux_irqs = 13,
|
||||
+ .mux_valid = { 0xffffffff, 0xfff80000, 0xffffffff, 0x0000000f },
|
||||
+};
|
||||
+
|
||||
+static int __init sun6i_a31_r_intc_init(struct device_node *node,
|
||||
+ struct device_node *parent)
|
||||
+{
|
||||
+ return sun6i_r_intc_init(node, parent, &sun6i_a31_r_intc_variant);
|
||||
+}
|
||||
+IRQCHIP_DECLARE(sun6i_a31_r_intc, "allwinner,sun6i-a31-r-intc", sun6i_a31_r_intc_init);
|
||||
+
|
||||
+static const struct sun6i_r_intc_variant sun50i_h6_r_intc_variant __initconst = {
|
||||
+ .first_mux_irq = 21,
|
||||
+ .nr_mux_irqs = 16,
|
||||
+ .mux_valid = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff },
|
||||
+};
|
||||
+
|
||||
+static int __init sun50i_h6_r_intc_init(struct device_node *node,
|
||||
+ struct device_node *parent)
|
||||
+{
|
||||
+ return sun6i_r_intc_init(node, parent, &sun50i_h6_r_intc_variant);
|
||||
+}
|
||||
+IRQCHIP_DECLARE(sun50i_h6_r_intc, "allwinner,sun50i-h6-r-intc", sun50i_h6_r_intc_init);
|
@ -1,194 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Fri, 25 Dec 2020 01:48:33 -0600
|
||||
Subject: [PATCH] ARM: dts: sunxi: Rename nmi_intc to r_intc
|
||||
|
||||
The R_INTC block controls more than just the NMI, and it is a different
|
||||
hardware block than the NMI INTC found in some other Allwinner SoCs, so
|
||||
the label "nmi_intc" is inaccurate. Name it "r_intc" to match the
|
||||
compatible and to match the few references in the vendor documentation.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
arch/arm/boot/dts/sun6i-a31-hummingbird.dts | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31-m9.dts | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31.dtsi | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31s-primo81.dts | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts | 2 +-
|
||||
arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi | 2 +-
|
||||
arch/arm/boot/dts/sun8i-a23-a33.dtsi | 2 +-
|
||||
arch/arm/boot/dts/sun8i-a33-olinuxino.dts | 2 +-
|
||||
arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 2 +-
|
||||
arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts | 2 +-
|
||||
arch/arm/boot/dts/sun8i-r16-parrot.dts | 2 +-
|
||||
arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi | 2 +-
|
||||
15 files changed, 15 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
|
||||
@@ -226,7 +226,7 @@
|
||||
axp22x: pmic@68 {
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
- interrupt-parent = <&nmi_intc>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
x-powers,drive-vbus-en;
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun6i-a31-m9.dts
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31-m9.dts
|
||||
@@ -115,7 +115,7 @@
|
||||
axp22x: pmic@68 {
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
- interrupt-parent = <&nmi_intc>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts
|
||||
@@ -115,7 +115,7 @@
|
||||
axp22x: pmic@68 {
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
- interrupt-parent = <&nmi_intc>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
|
||||
@@ -1305,7 +1305,7 @@
|
||||
clock-output-names = "osc32k";
|
||||
};
|
||||
|
||||
- nmi_intc: interrupt-controller@1f00c00 {
|
||||
+ r_intc: interrupt-controller@1f00c00 {
|
||||
compatible = "allwinner,sun6i-a31-r-intc";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
--- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
|
||||
@@ -159,7 +159,7 @@
|
||||
axp22x: pmic@68 {
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
- interrupt-parent = <&nmi_intc>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
x-powers,drive-vbus-en;
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
|
||||
@@ -78,7 +78,7 @@
|
||||
axp22x: pmic@68 {
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
- interrupt-parent = <&nmi_intc>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
|
||||
@@ -148,7 +148,7 @@
|
||||
axp22x: pmic@68 {
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
- interrupt-parent = <&nmi_intc>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
eldoin-supply = <®_dcdc1>;
|
||||
x-powers,drive-vbus-en;
|
||||
--- a/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
|
||||
@@ -98,7 +98,7 @@
|
||||
axp22x: pmic@68 {
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
- interrupt-parent = <&nmi_intc>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi
|
||||
@@ -79,7 +79,7 @@
|
||||
axp22x: pmic@68 {
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
- interrupt-parent = <&nmi_intc>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
drivevbus-supply = <®_vcc5v0>;
|
||||
x-powers,drive-vbus-en;
|
||||
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
|
||||
@@ -716,7 +716,7 @@
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
- nmi_intc: interrupt-controller@1f00c00 {
|
||||
+ r_intc: interrupt-controller@1f00c00 {
|
||||
compatible = "allwinner,sun6i-a31-r-intc";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
--- a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
|
||||
@@ -98,7 +98,7 @@
|
||||
axp22x: pmic@3a3 {
|
||||
compatible = "x-powers,axp223";
|
||||
reg = <0x3a3>;
|
||||
- interrupt-parent = <&nmi_intc>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
eldoin-supply = <®_dcdc1>;
|
||||
x-powers,drive-vbus-en;
|
||||
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
|
||||
@@ -164,7 +164,7 @@
|
||||
axp22x: pmic@3a3 {
|
||||
compatible = "x-powers,axp223";
|
||||
reg = <0x3a3>;
|
||||
- interrupt-parent = <&nmi_intc>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
eldoin-supply = <®_dcdc1>;
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts
|
||||
@@ -163,7 +163,7 @@
|
||||
axp22x: pmic@3a3 {
|
||||
compatible = "x-powers,axp223";
|
||||
reg = <0x3a3>;
|
||||
- interrupt-parent = <&nmi_intc>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
eldoin-supply = <®_dcdc1>;
|
||||
x-powers,drive-vbus-en;
|
||||
--- a/arch/arm/boot/dts/sun8i-r16-parrot.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-r16-parrot.dts
|
||||
@@ -164,7 +164,7 @@
|
||||
axp22x: pmic@3a3 {
|
||||
compatible = "x-powers,axp223";
|
||||
reg = <0x3a3>;
|
||||
- interrupt-parent = <&nmi_intc>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
drivevbus-supply = <®_vcc5v0>;
|
||||
x-powers,drive-vbus-en;
|
||||
--- a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
|
||||
@@ -92,7 +92,7 @@
|
||||
axp22x: pmic@3a3 {
|
||||
compatible = "x-powers,axp223";
|
||||
reg = <0x3a3>;
|
||||
- interrupt-parent = <&nmi_intc>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
eldoin-supply = <®_dcdc1>;
|
||||
drivevbus-supply = <®_vcc5v0>;
|
@ -1,291 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Fri, 25 Dec 2020 01:49:51 -0600
|
||||
Subject: [PATCH] ARM: dts: sunxi: Use the new r_intc binding
|
||||
|
||||
The binding of R_INTC was updated to allow specifying interrupts other
|
||||
than the external NMI, since routing those interrupts through the R_INTC
|
||||
driver allows using them for wakeup.
|
||||
|
||||
Update the device trees to use the new binding.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
arch/arm/boot/dts/sun6i-a31-hummingbird.dts | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31-m9.dts | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31.dtsi | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31s-primo81.dts | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts | 2 +-
|
||||
arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts | 2 +-
|
||||
arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi | 2 +-
|
||||
arch/arm/boot/dts/sun8i-a23-a33.dtsi | 2 +-
|
||||
arch/arm/boot/dts/sun8i-a33-olinuxino.dts | 2 +-
|
||||
arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 2 +-
|
||||
arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts | 4 ++--
|
||||
arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts | 4 ++--
|
||||
arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts | 4 ++--
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 4 ++--
|
||||
arch/arm/boot/dts/sun8i-a83t.dtsi | 2 +-
|
||||
arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts | 2 +-
|
||||
arch/arm/boot/dts/sun8i-r16-parrot.dts | 2 +-
|
||||
arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi | 2 +-
|
||||
20 files changed, 24 insertions(+), 24 deletions(-)
|
||||
|
||||
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
|
||||
@@ -227,7 +227,7 @@
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
x-powers,drive-vbus-en;
|
||||
};
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun6i-a31-m9.dts
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31-m9.dts
|
||||
@@ -116,7 +116,7 @@
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
--- a/arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts
|
||||
@@ -116,7 +116,7 @@
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
|
||||
@@ -1308,7 +1308,7 @@
|
||||
r_intc: interrupt-controller@1f00c00 {
|
||||
compatible = "allwinner,sun6i-a31-r-intc";
|
||||
interrupt-controller;
|
||||
- #interrupt-cells = <2>;
|
||||
+ #interrupt-cells = <3>;
|
||||
reg = <0x01f00c00 0x400>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
|
||||
@@ -160,7 +160,7 @@
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
x-powers,drive-vbus-en;
|
||||
};
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
|
||||
@@ -79,7 +79,7 @@
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
--- a/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
|
||||
@@ -149,7 +149,7 @@
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
eldoin-supply = <®_dcdc1>;
|
||||
x-powers,drive-vbus-en;
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
|
||||
@@ -99,7 +99,7 @@
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
--- a/arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi
|
||||
@@ -80,7 +80,7 @@
|
||||
compatible = "x-powers,axp221";
|
||||
reg = <0x68>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
drivevbus-supply = <®_vcc5v0>;
|
||||
x-powers,drive-vbus-en;
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
|
||||
@@ -719,7 +719,7 @@
|
||||
r_intc: interrupt-controller@1f00c00 {
|
||||
compatible = "allwinner,sun6i-a31-r-intc";
|
||||
interrupt-controller;
|
||||
- #interrupt-cells = <2>;
|
||||
+ #interrupt-cells = <3>;
|
||||
reg = <0x01f00c00 0x400>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
|
||||
@@ -99,7 +99,7 @@
|
||||
compatible = "x-powers,axp223";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
eldoin-supply = <®_dcdc1>;
|
||||
x-powers,drive-vbus-en;
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
|
||||
@@ -165,7 +165,7 @@
|
||||
compatible = "x-powers,axp223";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
eldoin-supply = <®_dcdc1>;
|
||||
};
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts
|
||||
@@ -122,7 +122,7 @@
|
||||
compatible = "x-powers,axp818", "x-powers,axp813";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
eldoin-supply = <®_dcdc1>;
|
||||
swin-supply = <®_dcdc1>;
|
||||
};
|
||||
@@ -142,7 +142,7 @@
|
||||
ac100_rtc: rtc {
|
||||
compatible = "x-powers,ac100-rtc";
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&ac100_codec>;
|
||||
#clock-cells = <1>;
|
||||
clock-output-names = "cko1_rtc",
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts
|
||||
@@ -203,7 +203,7 @@
|
||||
compatible = "x-powers,axp813";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
eldoin-supply = <®_dcdc1>;
|
||||
fldoin-supply = <®_dcdc5>;
|
||||
swin-supply = <®_dcdc1>;
|
||||
@@ -225,7 +225,7 @@
|
||||
ac100_rtc: rtc {
|
||||
compatible = "x-powers,ac100-rtc";
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&ac100_codec>;
|
||||
#clock-cells = <1>;
|
||||
clock-output-names = "cko1_rtc",
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts
|
||||
@@ -239,7 +239,7 @@
|
||||
compatible = "x-powers,axp818", "x-powers,axp813";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
eldoin-supply = <®_dcdc1>;
|
||||
swin-supply = <®_dcdc1>;
|
||||
x-powers,drive-vbus-en;
|
||||
@@ -260,7 +260,7 @@
|
||||
ac100_rtc: rtc {
|
||||
compatible = "x-powers,ac100-rtc";
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&ac100_codec>;
|
||||
#clock-cells = <1>;
|
||||
clock-output-names = "cko1_rtc",
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -263,7 +263,7 @@
|
||||
compatible = "x-powers,axp813";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
swin-supply = <®_dcdc1>;
|
||||
x-powers,drive-vbus-en;
|
||||
};
|
||||
@@ -283,7 +283,7 @@
|
||||
ac100_rtc: rtc {
|
||||
compatible = "x-powers,ac100-rtc";
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&ac100_codec>;
|
||||
#clock-cells = <1>;
|
||||
clock-output-names = "cko1_rtc",
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
@@ -1114,7 +1114,7 @@
|
||||
compatible = "allwinner,sun8i-a83t-r-intc",
|
||||
"allwinner,sun6i-a31-r-intc";
|
||||
interrupt-controller;
|
||||
- #interrupt-cells = <2>;
|
||||
+ #interrupt-cells = <3>;
|
||||
reg = <0x01f00c00 0x400>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts
|
||||
@@ -164,7 +164,7 @@
|
||||
compatible = "x-powers,axp223";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
eldoin-supply = <®_dcdc1>;
|
||||
x-powers,drive-vbus-en;
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun8i-r16-parrot.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-r16-parrot.dts
|
||||
@@ -165,7 +165,7 @@
|
||||
compatible = "x-powers,axp223";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
drivevbus-supply = <®_vcc5v0>;
|
||||
x-powers,drive-vbus-en;
|
||||
};
|
||||
--- a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
|
||||
@@ -93,7 +93,7 @@
|
||||
compatible = "x-powers,axp223";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
eldoin-supply = <®_dcdc1>;
|
||||
drivevbus-supply = <®_vcc5v0>;
|
||||
x-powers,drive-vbus-en;
|
@ -1,33 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 12 Jan 2020 20:27:08 -0600
|
||||
Subject: [PATCH] ARM: dts: sunxi: h3/h5: Add r_intc node
|
||||
|
||||
The H3 and H5 SoCs have an additional interrupt controller in the RTC
|
||||
power domain that can be used to enable wakeup for certain IRQs.
|
||||
|
||||
Add a node for it.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
@@ -877,6 +877,15 @@
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
+ r_intc: interrupt-controller@1f00c00 {
|
||||
+ compatible = "allwinner,sun8i-h3-r-intc",
|
||||
+ "allwinner,sun6i-a31-r-intc";
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <3>;
|
||||
+ reg = <0x01f00c00 0x400>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ };
|
||||
+
|
||||
r_ccu: clock@1f01400 {
|
||||
compatible = "allwinner,sun8i-h3-r-ccu";
|
||||
reg = <0x01f01400 0x100>;
|
@ -1,139 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Fri, 25 Dec 2020 02:05:58 -0600
|
||||
Subject: [PATCH] ARM: dts: sunxi: Move wakeup-capable IRQs to r_intc
|
||||
|
||||
All IRQs that can be used to wake up the system must be routed through
|
||||
r_intc, so they are visible to firmware while the system is suspended.
|
||||
|
||||
In addition to the external NMI input, which is already routed through
|
||||
r_intc, these include PIO and R_PIO (gpio-keys), the LRADC, and the RTC.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
arch/arm/boot/dts/sun6i-a31.dtsi | 4 ++++
|
||||
arch/arm/boot/dts/sun8i-a23-a33.dtsi | 4 ++++
|
||||
arch/arm/boot/dts/sun8i-a83t.dtsi | 3 +++
|
||||
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 3 +++
|
||||
4 files changed, 14 insertions(+)
|
||||
|
||||
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
|
||||
@@ -611,6 +611,7 @@
|
||||
pio: pinctrl@1c20800 {
|
||||
compatible = "allwinner,sun6i-a31-pinctrl";
|
||||
reg = <0x01c20800 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
|
||||
@@ -802,6 +803,7 @@
|
||||
lradc: lradc@1c22800 {
|
||||
compatible = "allwinner,sun4i-a10-lradc-keys";
|
||||
reg = <0x01c22800 0x100>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -1299,6 +1301,7 @@
|
||||
#clock-cells = <1>;
|
||||
compatible = "allwinner,sun6i-a31-rtc";
|
||||
reg = <0x01f00000 0x54>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&osc32k>;
|
||||
@@ -1383,6 +1386,7 @@
|
||||
r_pio: pinctrl@1f02c00 {
|
||||
compatible = "allwinner,sun6i-a31-r-pinctrl";
|
||||
reg = <0x01f02c00 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&apb0_gates 0>, <&osc24M>, <&rtc 0>;
|
||||
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
|
||||
@@ -338,6 +338,7 @@
|
||||
pio: pinctrl@1c20800 {
|
||||
/* compatible gets set in SoC specific dtsi file */
|
||||
reg = <0x01c20800 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
/* interrupts get set in SoC specific dtsi file */
|
||||
clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&rtc 0>;
|
||||
clock-names = "apb", "hosc", "losc";
|
||||
@@ -473,6 +474,7 @@
|
||||
lradc: lradc@1c22800 {
|
||||
compatible = "allwinner,sun4i-a10-lradc-keys";
|
||||
reg = <0x01c22800 0x100>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -709,6 +711,7 @@
|
||||
rtc: rtc@1f00000 {
|
||||
compatible = "allwinner,sun8i-a23-rtc";
|
||||
reg = <0x01f00000 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-output-names = "osc32k", "osc32k-out";
|
||||
@@ -805,6 +808,7 @@
|
||||
r_pio: pinctrl@1f02c00 {
|
||||
compatible = "allwinner,sun8i-a23-r-pinctrl";
|
||||
reg = <0x01f02c00 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&apb0_gates 0>, <&osc24M>, <&rtc 0>;
|
||||
clock-names = "apb", "hosc", "losc";
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
@@ -708,6 +708,7 @@
|
||||
|
||||
pio: pinctrl@1c20800 {
|
||||
compatible = "allwinner,sun8i-a83t-pinctrl";
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
|
||||
@@ -1150,6 +1151,7 @@
|
||||
r_lradc: lradc@1f03c00 {
|
||||
compatible = "allwinner,sun8i-a83t-r-lradc";
|
||||
reg = <0x01f03c00 0x100>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -1157,6 +1159,7 @@
|
||||
r_pio: pinctrl@1f02c00 {
|
||||
compatible = "allwinner,sun8i-a83t-r-pinctrl";
|
||||
reg = <0x01f02c00 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>,
|
||||
<&osc16Md512>;
|
||||
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
@@ -413,6 +413,7 @@
|
||||
pio: pinctrl@1c20800 {
|
||||
/* compatible is in per SoC .dtsi file */
|
||||
reg = <0x01c20800 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&rtc 0>;
|
||||
@@ -870,6 +871,7 @@
|
||||
rtc: rtc@1f00000 {
|
||||
/* compatible is in per SoC .dtsi file */
|
||||
reg = <0x01f00000 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-output-names = "osc32k", "osc32k-out", "iosc";
|
||||
@@ -927,6 +929,7 @@
|
||||
r_pio: pinctrl@1f02c00 {
|
||||
compatible = "allwinner,sun8i-h3-r-pinctrl";
|
||||
reg = <0x01f02c00 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&rtc 0>;
|
||||
clock-names = "apb", "hosc", "losc";
|
@ -1,232 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Fri, 25 Dec 2020 01:56:58 -0600
|
||||
Subject: [PATCH] arm64: dts: allwinner: Use the new r_intc binding
|
||||
|
||||
The binding of R_INTC was updated to allow specifying interrupts other
|
||||
than the external NMI, since routing those interrupts through the R_INTC
|
||||
driver allows using them for wakeup.
|
||||
|
||||
Update the device trees to use the new binding.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi | 2 +-
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts | 4 ++--
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 5 ++---
|
||||
17 files changed, 19 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts
|
||||
@@ -173,7 +173,7 @@
|
||||
compatible = "x-powers,axp803";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
|
||||
};
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
|
||||
@@ -191,7 +191,7 @@
|
||||
compatible = "x-powers,axp803";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
|
||||
};
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
|
||||
@@ -152,7 +152,7 @@
|
||||
compatible = "x-powers,axp803";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
|
||||
@@ -185,7 +185,7 @@
|
||||
compatible = "x-powers,axp803";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
|
||||
};
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
|
||||
@@ -192,7 +192,7 @@
|
||||
compatible = "x-powers,axp803";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
|
||||
};
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
|
||||
@@ -139,7 +139,7 @@
|
||||
compatible = "x-powers,axp803";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
|
||||
@@ -248,7 +248,7 @@
|
||||
compatible = "x-powers,axp803";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
|
||||
@@ -245,7 +245,7 @@
|
||||
compatible = "x-powers,axp803";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts
|
||||
@@ -266,7 +266,7 @@
|
||||
compatible = "x-powers,axp803";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
x-powers,drive-vbus-en;
|
||||
};
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
|
||||
@@ -46,7 +46,7 @@
|
||||
compatible = "x-powers,axp803";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
|
||||
@@ -205,7 +205,7 @@
|
||||
compatible = "x-powers,axp803";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
|
||||
wakeup-source;
|
||||
};
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
@@ -1215,7 +1215,7 @@
|
||||
compatible = "allwinner,sun50i-a64-r-intc",
|
||||
"allwinner,sun6i-a31-r-intc";
|
||||
interrupt-controller;
|
||||
- #interrupt-cells = <2>;
|
||||
+ #interrupt-cells = <3>;
|
||||
reg = <0x01f00c00 0x400>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
|
||||
@@ -157,7 +157,7 @@
|
||||
compatible = "x-powers,axp805", "x-powers,axp806";
|
||||
reg = <0x36>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
x-powers,self-working-mode;
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
|
||||
@@ -182,7 +182,7 @@
|
||||
compatible = "x-powers,axp805", "x-powers,axp806";
|
||||
reg = <0x36>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
x-powers,self-working-mode;
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
|
||||
@@ -119,7 +119,7 @@
|
||||
compatible = "x-powers,axp805", "x-powers,axp806";
|
||||
reg = <0x36>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
x-powers,self-working-mode;
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
|
||||
@@ -167,7 +167,7 @@
|
||||
compatible = "x-powers,axp805", "x-powers,axp806";
|
||||
reg = <0x36>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
x-powers,self-working-mode;
|
||||
@@ -280,7 +280,7 @@
|
||||
compatible = "nxp,pcf8563";
|
||||
reg = <0x51>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -931,10 +931,9 @@
|
||||
};
|
||||
|
||||
r_intc: interrupt-controller@7021000 {
|
||||
- compatible = "allwinner,sun50i-h6-r-intc",
|
||||
- "allwinner,sun6i-a31-r-intc";
|
||||
+ compatible = "allwinner,sun50i-h6-r-intc";
|
||||
interrupt-controller;
|
||||
- #interrupt-cells = <2>;
|
||||
+ #interrupt-cells = <3>;
|
||||
reg = <0x07021000 0x400>;
|
||||
interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
@ -1,77 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Fri, 25 Dec 2020 02:05:58 -0600
|
||||
Subject: [PATCH] arm64: dts: allwinner: Move wakeup-capable IRQs to r_intc
|
||||
|
||||
All IRQs that can be used to wake up the system must be routed through
|
||||
r_intc, so they are visible to firmware while the system is suspended.
|
||||
|
||||
In addition to the external NMI input, which is already routed through
|
||||
r_intc, these include PIO and R_PIO (gpio-keys), the LRADC, and the RTC.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 4 ++++
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 3 +++
|
||||
2 files changed, 7 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
@@ -644,6 +644,7 @@
|
||||
pio: pinctrl@1c20800 {
|
||||
compatible = "allwinner,sun50i-a64-pinctrl";
|
||||
reg = <0x01c20800 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
|
||||
@@ -814,6 +815,7 @@
|
||||
compatible = "allwinner,sun50i-a64-lradc",
|
||||
"allwinner,sun8i-a83t-r-lradc";
|
||||
reg = <0x01c21800 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -1204,6 +1206,7 @@
|
||||
compatible = "allwinner,sun50i-a64-rtc",
|
||||
"allwinner,sun8i-h3-rtc";
|
||||
reg = <0x01f00000 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-output-names = "osc32k", "osc32k-out", "iosc";
|
||||
@@ -1275,6 +1278,7 @@
|
||||
r_pio: pinctrl@1f02c00 {
|
||||
compatible = "allwinner,sun50i-a64-r-pinctrl";
|
||||
reg = <0x01f02c00 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>;
|
||||
clock-names = "apb", "hosc", "losc";
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -305,6 +305,7 @@
|
||||
pio: pinctrl@300b000 {
|
||||
compatible = "allwinner,sun50i-h6-pinctrl";
|
||||
reg = <0x0300b000 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
|
||||
@@ -906,6 +907,7 @@
|
||||
rtc: rtc@7000000 {
|
||||
compatible = "allwinner,sun50i-h6-rtc";
|
||||
reg = <0x07000000 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-output-names = "osc32k", "osc32k-out", "iosc";
|
||||
@@ -941,6 +943,7 @@
|
||||
r_pio: pinctrl@7022000 {
|
||||
compatible = "allwinner,sun50i-h6-r-pinctrl";
|
||||
reg = <0x07022000 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&r_ccu CLK_R_APB1>, <&osc24M>, <&rtc 0>;
|
@ -1,28 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Wed, 1 Jan 2020 16:03:34 -0600
|
||||
Subject: [PATCH] [DO NOT MERGE] ARM: dts: sunxi: a83t: Protect SCP clocks
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t.dtsi | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
@@ -702,6 +702,7 @@
|
||||
reg = <0x01c20000 0x400>;
|
||||
clocks = <&osc24M>, <&osc16Md512>;
|
||||
clock-names = "hosc", "losc";
|
||||
+ protected-clocks = <CLK_BUS_MSGBOX>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
@@ -1126,6 +1127,7 @@
|
||||
clocks = <&osc24M>, <&osc16Md512>, <&osc16M>,
|
||||
<&ccu CLK_PLL_PERIPH>;
|
||||
clock-names = "hosc", "losc", "iosc", "pll-periph";
|
||||
+ protected-clocks = <CLK_APB0_TWD>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
@ -1,43 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Mon, 30 Dec 2019 17:12:42 -0600
|
||||
Subject: [PATCH] bus: sunxi-rsb: Move OF match table
|
||||
|
||||
For some reason, this driver's OF match table was placed above the
|
||||
probe/remove functions, far away from the platform_driver definition.
|
||||
Adding device PM ops would move the table even farther away. Let's move
|
||||
it to the usual place, right before the platform_driver.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
drivers/bus/sunxi-rsb.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/bus/sunxi-rsb.c
|
||||
+++ b/drivers/bus/sunxi-rsb.c
|
||||
@@ -614,12 +614,6 @@ static int of_rsb_register_devices(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static const struct of_device_id sunxi_rsb_of_match_table[] = {
|
||||
- { .compatible = "allwinner,sun8i-a23-rsb" },
|
||||
- {}
|
||||
-};
|
||||
-MODULE_DEVICE_TABLE(of, sunxi_rsb_of_match_table);
|
||||
-
|
||||
static int sunxi_rsb_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -747,6 +741,12 @@ static int sunxi_rsb_remove(struct platf
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const struct of_device_id sunxi_rsb_of_match_table[] = {
|
||||
+ { .compatible = "allwinner,sun8i-a23-rsb" },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, sunxi_rsb_of_match_table);
|
||||
+
|
||||
static struct platform_driver sunxi_rsb_driver = {
|
||||
.probe = sunxi_rsb_probe,
|
||||
.remove = sunxi_rsb_remove,
|
@ -1,210 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Mon, 30 Dec 2019 22:36:04 -0600
|
||||
Subject: [PATCH] bus: sunxi-rsb: Split out controller init/exit functions
|
||||
|
||||
This separates the resource acquisition from the hardware initialization
|
||||
phase, so the hardware initialization can be repeated after system
|
||||
suspend/resume. The same is done for the exit/remove function, except
|
||||
that there is no resource deallocation phase due to the use of devres.
|
||||
|
||||
The requested RSB clock frequency is stored in `struct sunxi_rsb` so it
|
||||
will be available when reinitializing the hardware.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
drivers/bus/sunxi-rsb.c | 127 ++++++++++++++++++++++------------------
|
||||
1 file changed, 71 insertions(+), 56 deletions(-)
|
||||
|
||||
--- a/drivers/bus/sunxi-rsb.c
|
||||
+++ b/drivers/bus/sunxi-rsb.c
|
||||
@@ -126,6 +126,7 @@ struct sunxi_rsb {
|
||||
struct completion complete;
|
||||
struct mutex lock;
|
||||
unsigned int status;
|
||||
+ u32 clk_freq;
|
||||
};
|
||||
|
||||
/* bus / slave device related functions */
|
||||
@@ -614,16 +615,74 @@ static int of_rsb_register_devices(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int sunxi_rsb_hw_init(struct sunxi_rsb *rsb)
|
||||
+{
|
||||
+ struct device *dev = rsb->dev;
|
||||
+ unsigned long p_clk_freq;
|
||||
+ u32 clk_delay, reg;
|
||||
+ int clk_div, ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(rsb->clk);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to enable clk: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = reset_control_deassert(rsb->rstc);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to deassert reset line: %d\n", ret);
|
||||
+ goto err_clk_disable;
|
||||
+ }
|
||||
+
|
||||
+ /* reset the controller */
|
||||
+ writel(RSB_CTRL_SOFT_RST, rsb->regs + RSB_CTRL);
|
||||
+ readl_poll_timeout(rsb->regs + RSB_CTRL, reg,
|
||||
+ !(reg & RSB_CTRL_SOFT_RST), 1000, 100000);
|
||||
+
|
||||
+ /*
|
||||
+ * Clock frequency and delay calculation code is from
|
||||
+ * Allwinner U-boot sources.
|
||||
+ *
|
||||
+ * From A83 user manual:
|
||||
+ * bus clock frequency = parent clock frequency / (2 * (divider + 1))
|
||||
+ */
|
||||
+ p_clk_freq = clk_get_rate(rsb->clk);
|
||||
+ clk_div = p_clk_freq / rsb->clk_freq / 2;
|
||||
+ if (!clk_div)
|
||||
+ clk_div = 1;
|
||||
+ else if (clk_div > RSB_CCR_MAX_CLK_DIV + 1)
|
||||
+ clk_div = RSB_CCR_MAX_CLK_DIV + 1;
|
||||
+
|
||||
+ clk_delay = clk_div >> 1;
|
||||
+ if (!clk_delay)
|
||||
+ clk_delay = 1;
|
||||
+
|
||||
+ dev_info(dev, "RSB running at %lu Hz\n", p_clk_freq / clk_div / 2);
|
||||
+ writel(RSB_CCR_SDA_OUT_DELAY(clk_delay) | RSB_CCR_CLK_DIV(clk_div - 1),
|
||||
+ rsb->regs + RSB_CCR);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_clk_disable:
|
||||
+ clk_disable_unprepare(rsb->clk);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void sunxi_rsb_hw_exit(struct sunxi_rsb *rsb)
|
||||
+{
|
||||
+ reset_control_assert(rsb->rstc);
|
||||
+ clk_disable_unprepare(rsb->clk);
|
||||
+}
|
||||
+
|
||||
static int sunxi_rsb_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct resource *r;
|
||||
struct sunxi_rsb *rsb;
|
||||
- unsigned long p_clk_freq;
|
||||
- u32 clk_delay, clk_freq = 3000000;
|
||||
- int clk_div, irq, ret;
|
||||
- u32 reg;
|
||||
+ u32 clk_freq = 3000000;
|
||||
+ int irq, ret;
|
||||
|
||||
of_property_read_u32(np, "clock-frequency", &clk_freq);
|
||||
if (clk_freq > RSB_MAX_FREQ) {
|
||||
@@ -638,6 +697,7 @@ static int sunxi_rsb_probe(struct platfo
|
||||
return -ENOMEM;
|
||||
|
||||
rsb->dev = dev;
|
||||
+ rsb->clk_freq = clk_freq;
|
||||
platform_set_drvdata(pdev, rsb);
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
rsb->regs = devm_ioremap_resource(dev, r);
|
||||
@@ -655,63 +715,27 @@ static int sunxi_rsb_probe(struct platfo
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = clk_prepare_enable(rsb->clk);
|
||||
- if (ret) {
|
||||
- dev_err(dev, "failed to enable clk: %d\n", ret);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- p_clk_freq = clk_get_rate(rsb->clk);
|
||||
-
|
||||
rsb->rstc = devm_reset_control_get(dev, NULL);
|
||||
if (IS_ERR(rsb->rstc)) {
|
||||
ret = PTR_ERR(rsb->rstc);
|
||||
dev_err(dev, "failed to retrieve reset controller: %d\n", ret);
|
||||
- goto err_clk_disable;
|
||||
- }
|
||||
-
|
||||
- ret = reset_control_deassert(rsb->rstc);
|
||||
- if (ret) {
|
||||
- dev_err(dev, "failed to deassert reset line: %d\n", ret);
|
||||
- goto err_clk_disable;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
init_completion(&rsb->complete);
|
||||
mutex_init(&rsb->lock);
|
||||
|
||||
- /* reset the controller */
|
||||
- writel(RSB_CTRL_SOFT_RST, rsb->regs + RSB_CTRL);
|
||||
- readl_poll_timeout(rsb->regs + RSB_CTRL, reg,
|
||||
- !(reg & RSB_CTRL_SOFT_RST), 1000, 100000);
|
||||
-
|
||||
- /*
|
||||
- * Clock frequency and delay calculation code is from
|
||||
- * Allwinner U-boot sources.
|
||||
- *
|
||||
- * From A83 user manual:
|
||||
- * bus clock frequency = parent clock frequency / (2 * (divider + 1))
|
||||
- */
|
||||
- clk_div = p_clk_freq / clk_freq / 2;
|
||||
- if (!clk_div)
|
||||
- clk_div = 1;
|
||||
- else if (clk_div > RSB_CCR_MAX_CLK_DIV + 1)
|
||||
- clk_div = RSB_CCR_MAX_CLK_DIV + 1;
|
||||
-
|
||||
- clk_delay = clk_div >> 1;
|
||||
- if (!clk_delay)
|
||||
- clk_delay = 1;
|
||||
-
|
||||
- dev_info(dev, "RSB running at %lu Hz\n", p_clk_freq / clk_div / 2);
|
||||
- writel(RSB_CCR_SDA_OUT_DELAY(clk_delay) | RSB_CCR_CLK_DIV(clk_div - 1),
|
||||
- rsb->regs + RSB_CCR);
|
||||
-
|
||||
ret = devm_request_irq(dev, irq, sunxi_rsb_irq, 0, RSB_CTRL_NAME, rsb);
|
||||
if (ret) {
|
||||
dev_err(dev, "can't register interrupt handler irq %d: %d\n",
|
||||
irq, ret);
|
||||
- goto err_reset_assert;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
+ ret = sunxi_rsb_hw_init(rsb);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
/* initialize all devices on the bus into RSB mode */
|
||||
ret = sunxi_rsb_init_device_mode(rsb);
|
||||
if (ret)
|
||||
@@ -720,14 +744,6 @@ static int sunxi_rsb_probe(struct platfo
|
||||
of_rsb_register_devices(rsb);
|
||||
|
||||
return 0;
|
||||
-
|
||||
-err_reset_assert:
|
||||
- reset_control_assert(rsb->rstc);
|
||||
-
|
||||
-err_clk_disable:
|
||||
- clk_disable_unprepare(rsb->clk);
|
||||
-
|
||||
- return ret;
|
||||
}
|
||||
|
||||
static int sunxi_rsb_remove(struct platform_device *pdev)
|
||||
@@ -735,8 +751,7 @@ static int sunxi_rsb_remove(struct platf
|
||||
struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
|
||||
|
||||
device_for_each_child(rsb->dev, NULL, sunxi_rsb_remove_devices);
|
||||
- reset_control_assert(rsb->rstc);
|
||||
- clk_disable_unprepare(rsb->clk);
|
||||
+ sunxi_rsb_hw_exit(rsb);
|
||||
|
||||
return 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user