mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
Allwinner: initial project
This commit is contained in:
parent
421cc1272c
commit
5d568f9796
4
projects/Allwinner/bootloader/install
Normal file
4
projects/Allwinner/bootloader/install
Normal file
@ -0,0 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
||||
|
||||
cp -av u-boot-sunxi-with-spl.bin $INSTALL/usr/share/bootloader
|
7
projects/Allwinner/bootloader/mkimage
Normal file
7
projects/Allwinner/bootloader/mkimage
Normal file
@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
||||
|
||||
if [ -f "$RELEASE_DIR/3rdparty/bootloader/u-boot-sunxi-with-spl.bin" ]; then
|
||||
echo "Writing U-Boot to $(basename $DISK)"
|
||||
dd if="$RELEASE_DIR/3rdparty/bootloader/u-boot-sunxi-with-spl.bin" of="$DISK" bs=1K seek=8 conv=fsync,notrunc >"$SAVE_ERROR" 2>&1 || show_error
|
||||
fi
|
38
projects/Allwinner/bootloader/update.sh
Normal file
38
projects/Allwinner/bootloader/update.sh
Normal file
@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
||||
|
||||
[ -z "$BOOT_ROOT" ] && BOOT_ROOT="/flash"
|
||||
[ -z "$BOOT_PART" ] && BOOT_PART=$(df "$BOOT_ROOT" | tail -1 | awk {' print $1 '})
|
||||
if [ -z "$BOOT_DISK" ]; then
|
||||
case $BOOT_PART in
|
||||
/dev/sd[a-z][0-9]*)
|
||||
BOOT_DISK=$(echo $BOOT_PART | sed -e "s,[0-9]*,,g")
|
||||
;;
|
||||
/dev/mmcblk*)
|
||||
BOOT_DISK=$(echo $BOOT_PART | sed -e "s,p[0-9]*,,g")
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# mount $BOOT_ROOT r/w
|
||||
mount -o remount,rw $BOOT_ROOT
|
||||
|
||||
# update Device Tree Blobs
|
||||
for all_dtb in /flash/*.dtb; do
|
||||
dtb=$(basename $all_dtb)
|
||||
if [ -f $SYSTEM_ROOT/usr/share/bootloader/$dtb ]; then
|
||||
echo "*** updating Device Tree Blob: $dtb ..."
|
||||
cp -p $SYSTEM_ROOT/usr/share/bootloader/$dtb $BOOT_ROOT
|
||||
fi
|
||||
done
|
||||
|
||||
# update bootloader files
|
||||
if [ -f $SYSTEM_ROOT/usr/share/bootloader/u-boot-sunxi-with-spl.bin ]; then
|
||||
echo "*** updating U-Boot on: $BOOT_DISK ..."
|
||||
dd if=$SYSTEM_ROOT/usr/share/bootloader/u-boot-sunxi-with-spl.bin of="$BOOT_DISK" bs=1k seek=8 conv=fsync &>/dev/null
|
||||
fi
|
||||
|
||||
# mount $BOOT_ROOT r/o
|
||||
sync
|
||||
mount -o remount,ro $BOOT_ROOT
|
9
projects/Allwinner/devices/A64/bootloader/release
Normal file
9
projects/Allwinner/devices/A64/bootloader/release
Normal file
@ -0,0 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
||||
|
||||
mkdir -p $RELEASE_DIR/3rdparty/bootloader
|
||||
if [ -n "$UBOOT_SYSTEM" ]; then
|
||||
cp -a $(get_build_dir $BOOTLOADER)/u-boot-sunxi-with-spl.bin $RELEASE_DIR/3rdparty/bootloader
|
||||
fi
|
||||
|
||||
cp -a $(get_build_dir linux)/arch/$TARGET_KERNEL_ARCH/boot/dts/allwinner/sun50i-a64-*.dtb $RELEASE_DIR/3rdparty/bootloader
|
@ -0,0 +1,36 @@
|
||||
#
|
||||
# Configuration for H3 analog output
|
||||
#
|
||||
|
||||
<confdir:pcm/front.conf>
|
||||
|
||||
sun50i-a64-audi.pcm.front.0 {
|
||||
@args [ CARD ]
|
||||
@args.CARD {
|
||||
type string
|
||||
}
|
||||
type hooks
|
||||
slave.pcm {
|
||||
type hw
|
||||
card $CARD
|
||||
}
|
||||
hooks.0 {
|
||||
type ctl_elems
|
||||
hook_args [
|
||||
{
|
||||
name "Line Out Playback Volume"
|
||||
lock true
|
||||
preserve true
|
||||
optional false
|
||||
value 31
|
||||
}
|
||||
{
|
||||
name "Line Out Playback Switch"
|
||||
lock true
|
||||
preserve true
|
||||
optional false
|
||||
value [ on on ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
35
projects/Allwinner/devices/A64/options
Normal file
35
projects/Allwinner/devices/A64/options
Normal file
@ -0,0 +1,35 @@
|
||||
################################################################################
|
||||
# setup system defaults
|
||||
################################################################################
|
||||
|
||||
# The TARGET_CPU variable controls which processor should be targeted for
|
||||
# generated code.
|
||||
case $TARGET_ARCH in
|
||||
aarch64)
|
||||
TARGET_CPU="cortex-a53"
|
||||
TARGET_CPU_FLAGS="+crc+crypto"
|
||||
TARGET_FEATURES="64bit"
|
||||
TARGET_KERNEL_ARCH="arm64"
|
||||
;;
|
||||
arm)
|
||||
TARGET_KERNEL_ARCH="arm64"
|
||||
TARGET_PATCH_ARCH="aarch64"
|
||||
TARGET_FLOAT="hard"
|
||||
TARGET_CPU="cortex-a53"
|
||||
TARGET_CPU_FLAGS="+crc"
|
||||
TARGET_FPU="crypto-neon-fp-armv8"
|
||||
TARGET_FEATURES="32bit"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Kernel target
|
||||
KERNEL_TARGET="Image"
|
||||
|
||||
# ATF platform
|
||||
ATF_PLATFORM="sun50i_a64"
|
||||
|
||||
# additional drivers to install:
|
||||
ADDITIONAL_DRIVERS="$ADDITIONAL_DRIVERS gpu-sunxi"
|
||||
|
||||
# Mali GPU family
|
||||
MALI_FAMILY="400"
|
@ -0,0 +1,48 @@
|
||||
Date: Sun, 3 Dec 2017 11:43:08 -0800
|
||||
Subject: [PATCH] Add A64 HDMI sound node
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 29 +++++++++++++++++++
|
||||
2 files changed, 47 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
index 0f69f35939755..0b44018361cbf 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
@@ -727,6 +727,36 @@
|
||||
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";
|
||||
+ allwinner,playback-channels = <8>;
|
||||
+ };
|
||||
+
|
||||
+ sound_hdmi: sound_hdmi {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,format = "i2s";
|
||||
+ simple-audio-card,name = "allwinner-hdmi";
|
||||
+ simple-audio-card,mclk-fs = <256>;
|
||||
+
|
||||
+ simple-audio-card,codec {
|
||||
+ sound-dai = <&hdmi>;
|
||||
+ };
|
||||
+
|
||||
+ simple-audio-card,cpu {
|
||||
+ sound-dai = <&i2s2>;
|
||||
+ dai-tdm-slot-num = <2>;
|
||||
+ dai-tdm-slot-width = <32>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
rtc: rtc@1f00000 {
|
||||
compatible = "allwinner,sun6i-a31-rtc";
|
||||
reg = <0x01f00000 0x54>;
|
@ -0,0 +1,11 @@
|
||||
diff -Nur a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 2018-11-17 18:26:20.000000000 +0100
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 2018-11-17 19:29:15.132911602 +0100
|
||||
@@ -892,6 +892,7 @@
|
||||
};
|
||||
|
||||
hdmi: hdmi@1ee0000 {
|
||||
+ #sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun50i-a64-dw-hdmi",
|
||||
"allwinner,sun8i-a83t-dw-hdmi";
|
||||
reg = <0x01ee0000 0x10000>;
|
@ -0,0 +1,135 @@
|
||||
From c642dca33a893b38770003f92de5708b2ef82878 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Thu, 10 Jan 2019 20:00:25 +0100
|
||||
Subject: [PATCH 1/4] media: dt: bindings: sunxi-ir: Add A64 compatible
|
||||
|
||||
A64 IR is compatible with A13, so add A64 compatible with A13 as a
|
||||
fallback.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
Documentation/devicetree/bindings/media/sunxi-ir.txt | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/media/sunxi-ir.txt b/Documentation/devicetree/bindings/media/sunxi-ir.txt
|
||||
index 278098987edb..ecac6964b69b 100644
|
||||
--- a/Documentation/devicetree/bindings/media/sunxi-ir.txt
|
||||
+++ b/Documentation/devicetree/bindings/media/sunxi-ir.txt
|
||||
@@ -1,7 +1,10 @@
|
||||
Device-Tree bindings for SUNXI IR controller found in sunXi SoC family
|
||||
|
||||
Required properties:
|
||||
-- compatible : "allwinner,sun4i-a10-ir" or "allwinner,sun5i-a13-ir"
|
||||
+- compatible : value must be one of:
|
||||
+ * "allwinner,sun4i-a10-ir"
|
||||
+ * "allwinner,sun5i-a13-ir"
|
||||
+ * "allwinner,sun50i-a64-ir", "allwinner,sun5i-a13-ir"
|
||||
- clocks : list of clock specifiers, corresponding to
|
||||
entries in clock-names property;
|
||||
- clock-names : should contain "apb" and "ir" entries;
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 85923b765bbd31be033a7b7d8bf0018accb386dd Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Thu, 10 Jan 2019 20:50:15 +0100
|
||||
Subject: [PATCH 2/4] arm64: dts: allwinner: a64: Add IR pinmux
|
||||
|
||||
IR on A64 has a dedicated pin. Add pinmux setting for it.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
index 839b2ae88583..86ff1d3a4ffa 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
@@ -1043,6 +1043,11 @@
|
||||
function = "s_i2c";
|
||||
};
|
||||
|
||||
+ r_ir_pins: ir-pins {
|
||||
+ pins = "PL11";
|
||||
+ function = "s_cir_rx";
|
||||
+ };
|
||||
+
|
||||
r_pwm_pin: pwm {
|
||||
pins = "PL10";
|
||||
function = "s_pwm";
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 943855104927268a641bd4f5f35c0592398e39ec Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Thu, 10 Jan 2019 20:19:32 +0100
|
||||
Subject: [PATCH 3/4] arm64: dts: allwinner: a64: Add IR node
|
||||
|
||||
IR is similar to that in A13 and can use same driver.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
index 86ff1d3a4ffa..8238caedd90e 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
@@ -1004,6 +1004,17 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ r_ir: ir@1f02000 {
|
||||
+ compatible = "allwinner,sun50i-a64-ir",
|
||||
+ "allwinner,sun5i-a13-ir";
|
||||
+ reg = <0x01f02000 0x400>;
|
||||
+ clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>;
|
||||
+ clock-names = "apb", "ir";
|
||||
+ resets = <&r_ccu RST_APB0_IR>;
|
||||
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
r_i2c: i2c@1f02400 {
|
||||
compatible = "allwinner,sun50i-a64-i2c",
|
||||
"allwinner,sun6i-a31-i2c";
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 3020e7d85fe574cda8e6803330ffd75fffdbbf6b Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Thu, 10 Jan 2019 20:25:18 +0100
|
||||
Subject: [PATCH 4/4] arm64: dts: allwinner: a64: Orange Pi Win: Enable IR
|
||||
|
||||
OrangePi Win board contains IR receiver. Enable it.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
|
||||
index b0c64f75792c..c6c759511f5e 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
|
||||
@@ -144,6 +144,12 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&r_ir {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&r_ir_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&mdio {
|
||||
ext_rgmii_phy: ethernet-phy@1 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
--
|
||||
2.20.1
|
||||
|
9
projects/Allwinner/devices/H3/bootloader/release
Normal file
9
projects/Allwinner/devices/H3/bootloader/release
Normal file
@ -0,0 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
||||
|
||||
mkdir -p $RELEASE_DIR/3rdparty/bootloader
|
||||
if [ -n "$UBOOT_SYSTEM" ]; then
|
||||
cp -a $(get_build_dir $BOOTLOADER)/u-boot-sunxi-with-spl.bin $RELEASE_DIR/3rdparty/bootloader
|
||||
fi
|
||||
|
||||
cp -a $(get_build_dir linux)/arch/$TARGET_KERNEL_ARCH/boot/dts/sun8i-h3-*.dtb $RELEASE_DIR/3rdparty/bootloader
|
@ -0,0 +1,36 @@
|
||||
#
|
||||
# Configuration for H3 analog output
|
||||
#
|
||||
|
||||
<confdir:pcm/front.conf>
|
||||
|
||||
H3_Audio_Codec.pcm.front.0 {
|
||||
@args [ CARD ]
|
||||
@args.CARD {
|
||||
type string
|
||||
}
|
||||
type hooks
|
||||
slave.pcm {
|
||||
type hw
|
||||
card $CARD
|
||||
}
|
||||
hooks.0 {
|
||||
type ctl_elems
|
||||
hook_args [
|
||||
{
|
||||
name "Line Out Playback Volume"
|
||||
lock true
|
||||
preserve true
|
||||
optional false
|
||||
value 31
|
||||
}
|
||||
{
|
||||
name "Line Out Playback Switch"
|
||||
lock true
|
||||
preserve true
|
||||
optional false
|
||||
value [ on on ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
44
projects/Allwinner/devices/H3/options
Normal file
44
projects/Allwinner/devices/H3/options
Normal file
@ -0,0 +1,44 @@
|
||||
################################################################################
|
||||
# setup system defaults
|
||||
################################################################################
|
||||
|
||||
# The TARGET_CPU variable controls which processor should be targeted for
|
||||
# generated code.
|
||||
case $TARGET_ARCH in
|
||||
arm)
|
||||
# TARGET_CPU:
|
||||
# arm2 arm250 arm3 arm6 arm60 arm600 arm610 arm620 arm7 arm7m arm7d
|
||||
# arm7dm arm7di arm7dmi arm70 arm700 arm700i arm710 arm710c
|
||||
# arm7100 arm720 arm7500 arm7500fe arm7tdmi arm7tdmi-s arm710t
|
||||
# arm720t arm740t strongarm strongarm110 strongarm1100
|
||||
# strongarm1110 arm8 arm810 arm9 arm9e arm920 arm920t arm922t
|
||||
# arm946e-s arm966e-s arm968e-s arm926ej-s arm940t arm9tdmi
|
||||
# arm10tdmi arm1020t arm1026ej-s arm10e arm1020e arm1022e
|
||||
# arm1136j-s arm1136jf-s mpcore mpcorenovfp arm1156t2-s
|
||||
# arm1176jz-s arm1176jzf-s cortex-a8 cortex-a9 cortex-r4
|
||||
# cortex-r4f cortex-m3 cortex-m1 xscale iwmmxt iwmmxt2 ep9312.
|
||||
TARGET_CPU="cortex-a7"
|
||||
|
||||
# TARGET_FLOAT:
|
||||
# Specifies which floating-point ABI to use. Permissible values are:
|
||||
# soft softfp hard
|
||||
TARGET_FLOAT="hard"
|
||||
|
||||
# TARGET_FPU:
|
||||
# This specifies what floating point hardware (or hardware emulation) is
|
||||
# available on the target. Permissible names are:
|
||||
# fpa fpe2 fpe3 maverick vfp vfpv3 vfpv3-fp16 vfpv3-d16 vfpv3-d16-fp16
|
||||
# vfpv3xd vfpv3xd-fp16 neon neon-fp16 vfpv4 vfpv4-d16 fpv4-sp-d16
|
||||
# neon-vfpv4.
|
||||
TARGET_FPU="neon-vfpv4"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Kernel target
|
||||
KERNEL_TARGET="zImage"
|
||||
|
||||
# additional drivers to install:
|
||||
ADDITIONAL_DRIVERS="$ADDITIONAL_DRIVERS gpu-sunxi"
|
||||
|
||||
# Mali GPU family
|
||||
MALI_FAMILY="400"
|
@ -0,0 +1,56 @@
|
||||
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
index 8aa2befc..d3d70eac 100644
|
||||
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
@@ -53,6 +53,23 @@
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
+ sound_hdmi: sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,format = "i2s";
|
||||
+ simple-audio-card,name = "allwinner-hdmi";
|
||||
+ simple-audio-card,mclk-fs = <256>;
|
||||
+
|
||||
+ simple-audio-card,codec {
|
||||
+ sound-dai = <&hdmi>;
|
||||
+ };
|
||||
+
|
||||
+ simple-audio-card,cpu {
|
||||
+ sound-dai = <&i2s2>;
|
||||
+ dai-tdm-slot-num = <2>;
|
||||
+ dai-tdm-slot-width = <32>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
clocks {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
@@ -631,6 +648,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";
|
||||
+ allwinner,playback-channels = <8>;
|
||||
+ };
|
||||
+
|
||||
codec: codec@1c22c00 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun8i-h3-codec";
|
||||
@@ -110,6 +126,7 @@
|
||||
};
|
||||
|
||||
hdmi: hdmi@1ee0000 {
|
||||
+ #sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun8i-h3-dw-hdmi",
|
||||
"allwinner,sun8i-a83t-dw-hdmi";
|
||||
reg = <0x01ee0000 0x10000>;
|
9
projects/Allwinner/devices/H6/bootloader/release
Normal file
9
projects/Allwinner/devices/H6/bootloader/release
Normal file
@ -0,0 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
||||
|
||||
mkdir -p $RELEASE_DIR/3rdparty/bootloader
|
||||
if [ -n "$UBOOT_SYSTEM" ]; then
|
||||
cp -a $(get_build_dir $BOOTLOADER)/u-boot-sunxi-with-spl.bin $RELEASE_DIR/3rdparty/bootloader
|
||||
fi
|
||||
|
||||
cp -a $(get_build_dir linux)/arch/$TARGET_KERNEL_ARCH/boot/dts/allwinner/sun50i-h6-*.dtb $RELEASE_DIR/3rdparty/bootloader
|
35
projects/Allwinner/devices/H6/options
Normal file
35
projects/Allwinner/devices/H6/options
Normal file
@ -0,0 +1,35 @@
|
||||
################################################################################
|
||||
# setup system defaults
|
||||
################################################################################
|
||||
|
||||
# The TARGET_CPU variable controls which processor should be targeted for
|
||||
# generated code.
|
||||
case $TARGET_ARCH in
|
||||
aarch64)
|
||||
TARGET_CPU="cortex-a53"
|
||||
TARGET_CPU_FLAGS="+crc+crypto"
|
||||
TARGET_FEATURES="64bit"
|
||||
TARGET_KERNEL_ARCH="arm64"
|
||||
;;
|
||||
arm)
|
||||
TARGET_KERNEL_ARCH="arm64"
|
||||
TARGET_PATCH_ARCH="aarch64"
|
||||
TARGET_FLOAT="hard"
|
||||
TARGET_CPU="cortex-a53"
|
||||
TARGET_CPU_FLAGS="+crc"
|
||||
TARGET_FPU="crypto-neon-fp-armv8"
|
||||
TARGET_FEATURES="32bit"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Kernel target
|
||||
KERNEL_TARGET="Image"
|
||||
|
||||
# ATF platform
|
||||
ATF_PLATFORM="sun50i_h6"
|
||||
|
||||
# additional drivers to install:
|
||||
ADDITIONAL_DRIVERS="$ADDITIONAL_DRIVERS gpu-sunxi-midgard"
|
||||
|
||||
# Mali GPU family
|
||||
MALI_FAMILY="t720"
|
@ -0,0 +1,111 @@
|
||||
diff -Nur a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 2018-03-28 20:27:22.000000000 +0200
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 2018-04-16 19:28:43.842331161 +0200
|
||||
@@ -35,6 +35,72 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ gpu_opp_table: opp_table1 {
|
||||
+ compatible = "operating-points-v2",
|
||||
+ "operating-points-v2-mali";
|
||||
+
|
||||
+ opp@756000000 {
|
||||
+ opp-hz = /bits/ 64 <756000000>;
|
||||
+ opp-microvolt = <1040000>;
|
||||
+ };
|
||||
+ opp@624000000 {
|
||||
+ opp-hz = /bits/ 64 <624000000>;
|
||||
+ opp-microvolt = <950000>;
|
||||
+ };
|
||||
+ opp@576000000 {
|
||||
+ opp-hz = /bits/ 64 <576000000>;
|
||||
+ opp-microvolt = <930000>;
|
||||
+ };
|
||||
+ opp@540000000 {
|
||||
+ opp-hz = /bits/ 64 <540000000>;
|
||||
+ opp-microvolt = <910000>;
|
||||
+ };
|
||||
+ opp@504000000 {
|
||||
+ opp-hz = /bits/ 64 <504000000>;
|
||||
+ opp-microvolt = <890000>;
|
||||
+ };
|
||||
+ opp@456000000 {
|
||||
+ opp-hz = /bits/ 64 <456000000>;
|
||||
+ opp-microvolt = <870000>;
|
||||
+ };
|
||||
+ opp@432000000 {
|
||||
+ opp-hz = /bits/ 64 <432000000>;
|
||||
+ opp-microvolt = <860000>;
|
||||
+ };
|
||||
+ opp@420000000 {
|
||||
+ opp-hz = /bits/ 64 <420000000>;
|
||||
+ opp-microvolt = <850000>;
|
||||
+ };
|
||||
+ opp@408000000 {
|
||||
+ opp-hz = /bits/ 64 <408000000>;
|
||||
+ opp-microvolt = <840000>;
|
||||
+ };
|
||||
+ opp@384000000 {
|
||||
+ opp-hz = /bits/ 64 <384000000>;
|
||||
+ opp-microvolt = <830000>;
|
||||
+ };
|
||||
+ opp@360000000 {
|
||||
+ opp-hz = /bits/ 64 <360000000>;
|
||||
+ opp-microvolt = <820000>;
|
||||
+ };
|
||||
+ opp@336000000 {
|
||||
+ opp-hz = /bits/ 64 <336000000>;
|
||||
+ opp-microvolt = <810000>;
|
||||
+ };
|
||||
+ opp@312000000 {
|
||||
+ opp-hz = /bits/ 64 <312000000>;
|
||||
+ opp-microvolt = <810000>;
|
||||
+ };
|
||||
+ opp@264000000 {
|
||||
+ opp-hz = /bits/ 64 <264000000>;
|
||||
+ opp-microvolt = <810000>;
|
||||
+ };
|
||||
+ opp@216000000 {
|
||||
+ opp-hz = /bits/ 64 <216000000>;
|
||||
+ opp-microvolt = <810000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@@ -162,6 +228,20 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ gpu: gpu@1800000 {
|
||||
+ compatible = "arm,malit720", "arm,malit72x", "arm,malit7xx", "arm,mali-midgard";
|
||||
+ reg = <0x01800000 0x4000>;
|
||||
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "JOB", "MMU", "GPU";
|
||||
+
|
||||
+ clocks = <&ccu CLK_GPU>, <&ccu CLK_BUS_GPU>;
|
||||
+ clock-names = "clk_mali", "clk_bus_mali";
|
||||
+ resets = <&ccu RST_BUS_GPU>;
|
||||
+ operating-points-v2 = <&gpu_opp_table>;
|
||||
+ };
|
||||
+
|
||||
syscon: syscon@3000000 {
|
||||
compatible = "allwinner,sun50i-h6-system-controller",
|
||||
"syscon";
|
||||
diff -Nur a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts 2018-03-28 20:27:22.000000000 +0200
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts 2018-04-14 15:34:15.545094216 +0200
|
||||
@@ -89,6 +89,10 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&gpu {
|
||||
+ mali-supply = <®_dcdcc>;
|
||||
+};
|
||||
+
|
||||
&hdmi {
|
||||
status = "okay";
|
||||
};
|
@ -0,0 +1,13 @@
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
index 8a81f764abd0..46b72f2ed5cd 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
@@ -288,7 +288,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents, 0x670,
|
||||
0, 3, /* M */
|
||||
24, 1, /* mux */
|
||||
BIT(31), /* gate */
|
||||
- 0);
|
||||
+ CLK_SET_RATE_PARENT);
|
||||
|
||||
static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "psi-ahb1-ahb2",
|
||||
0x67c, BIT(0), 0);
|
240
projects/Allwinner/devices/H6/patches/linux/03-VPU.patch
Normal file
240
projects/Allwinner/devices/H6/patches/linux/03-VPU.patch
Normal file
@ -0,0 +1,240 @@
|
||||
From ed19ec00d4d62a74857ad9c2ea1dbf9671ac3580 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Mon, 28 Jan 2019 19:36:54 +0100
|
||||
Subject: [PATCH 1/6] dt-bindings: media: cedrus: Add H6 compatible
|
||||
|
||||
This adds a compatible for H6. H6 VPU supports 10-bit HEVC decoding and
|
||||
additional AFBC output format for HEVC.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
Documentation/devicetree/bindings/media/cedrus.txt | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/media/cedrus.txt b/Documentation/devicetree/bindings/media/cedrus.txt
|
||||
index bce0705df953..20c82fb0c343 100644
|
||||
--- a/Documentation/devicetree/bindings/media/cedrus.txt
|
||||
+++ b/Documentation/devicetree/bindings/media/cedrus.txt
|
||||
@@ -13,6 +13,7 @@ Required properties:
|
||||
- "allwinner,sun8i-h3-video-engine"
|
||||
- "allwinner,sun50i-a64-video-engine"
|
||||
- "allwinner,sun50i-h5-video-engine"
|
||||
+ - "allwinner,sun50i-h6-video-engine"
|
||||
- reg : register base and length of VE;
|
||||
- clocks : list of clock specifiers, corresponding to entries in
|
||||
the clock-names property;
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From bb6b00e1225a5b382b723d3c2190429e15a4c607 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Mon, 28 Jan 2019 19:45:38 +0100
|
||||
Subject: [PATCH 2/6] media: cedrus: Add a quirk for not setting DMA offset
|
||||
|
||||
H6 VPU doesn't work if DMA offset is set.
|
||||
|
||||
Add a quirk for it.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.h | 3 +++
|
||||
drivers/staging/media/sunxi/cedrus/cedrus_hw.c | 3 ++-
|
||||
2 files changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
index 4aedd24a9848..c57c04b41d2e 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#define CEDRUS_CAPABILITY_UNTILED BIT(0)
|
||||
|
||||
+#define CEDRUS_QUIRK_NO_DMA_OFFSET BIT(0)
|
||||
+
|
||||
enum cedrus_codec {
|
||||
CEDRUS_CODEC_MPEG2,
|
||||
|
||||
@@ -91,6 +93,7 @@ struct cedrus_dec_ops {
|
||||
|
||||
struct cedrus_variant {
|
||||
unsigned int capabilities;
|
||||
+ unsigned int quirks;
|
||||
};
|
||||
|
||||
struct cedrus_dev {
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
||||
index 0acf219a8c91..fbfff7c1c771 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
||||
@@ -177,7 +177,8 @@ int cedrus_hw_probe(struct cedrus_dev *dev)
|
||||
*/
|
||||
|
||||
#ifdef PHYS_PFN_OFFSET
|
||||
- dev->dev->dma_pfn_offset = PHYS_PFN_OFFSET;
|
||||
+ if (!(variant->quirks & CEDRUS_QUIRK_NO_DMA_OFFSET))
|
||||
+ dev->dev->dma_pfn_offset = PHYS_PFN_OFFSET;
|
||||
#endif
|
||||
|
||||
ret = of_reserved_mem_device_init(dev->dev);
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 744c66f8c328ef40b6fb246f8b9f2daa9cce4d9d Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Mon, 28 Jan 2019 19:47:33 +0100
|
||||
Subject: [PATCH 3/6] media: cedrus: Add support for H6
|
||||
|
||||
H6 has improved VPU. It supports 10-bit HEVC decoding and AFBC output
|
||||
format for HEVC.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
index ff11cbeba205..b98add3cdedd 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
@@ -396,6 +396,11 @@ static const struct cedrus_variant sun50i_h5_cedrus_variant = {
|
||||
.capabilities = CEDRUS_CAPABILITY_UNTILED,
|
||||
};
|
||||
|
||||
+static const struct cedrus_variant sun50i_h6_cedrus_variant = {
|
||||
+ .capabilities = CEDRUS_CAPABILITY_UNTILED | CEDRUS_CAPABILITY_H265_DEC,
|
||||
+ .quirks = CEDRUS_QUIRK_NO_DMA_OFFSET,
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id cedrus_dt_match[] = {
|
||||
{
|
||||
.compatible = "allwinner,sun4i-a10-video-engine",
|
||||
@@ -425,6 +430,10 @@ static const struct of_device_id cedrus_dt_match[] = {
|
||||
.compatible = "allwinner,sun50i-h5-video-engine",
|
||||
.data = &sun50i_h5_cedrus_variant,
|
||||
},
|
||||
+ {
|
||||
+ .compatible = "allwinner,sun50i-h6-video-engine",
|
||||
+ .data = &sun50i_h6_cedrus_variant,
|
||||
+ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cedrus_dt_match);
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From b4ca53c594950b80d71ac320b3505a303e7f6092 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Mon, 28 Jan 2019 20:05:47 +0100
|
||||
Subject: [PATCH 4/6] dt-bindings: sram: sunxi: Add compatible for the H6 SRAM
|
||||
C1
|
||||
|
||||
This introduces a new compatible for the H6 SRAM C1 section, that is
|
||||
compatible with the SRAM C1 section as found on the A10.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
Documentation/devicetree/bindings/sram/sunxi-sram.txt | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/sram/sunxi-sram.txt b/Documentation/devicetree/bindings/sram/sunxi-sram.txt
|
||||
index ab5a70bb9a64..380246a805f2 100644
|
||||
--- a/Documentation/devicetree/bindings/sram/sunxi-sram.txt
|
||||
+++ b/Documentation/devicetree/bindings/sram/sunxi-sram.txt
|
||||
@@ -63,6 +63,7 @@ The valid sections compatible for H5 are:
|
||||
|
||||
The valid sections compatible for H6 are:
|
||||
- allwinner,sun50i-h6-sram-c, allwinner,sun50i-a64-sram-c
|
||||
+ - allwinner,sun50i-h6-sram-c1, allwinner,sun4i-a10-sram-c1
|
||||
|
||||
The valid sections compatible for F1C100s are:
|
||||
- allwinner,suniv-f1c100s-sram-d, allwinner,sun4i-a10-sram-d
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 6a505c910b90581b2a980e52f9b6fcb03d234cb7 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Mon, 28 Jan 2019 19:53:30 +0100
|
||||
Subject: [PATCH 5/6] arm64: dts: allwinner: h6: Add support for the SRAM C1
|
||||
section
|
||||
|
||||
Add a node for H6 SRAM C1 section.
|
||||
|
||||
Manual calls it VE SRAM, but for consistency with older SoCs, SRAM C1
|
||||
name is used.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
index d93a7add67e7..247dc0a5ce89 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -167,6 +167,20 @@
|
||||
reg = <0x0000 0x1e000>;
|
||||
};
|
||||
};
|
||||
+
|
||||
+ sram_c1: sram@1a00000 {
|
||||
+ compatible = "mmio-sram";
|
||||
+ reg = <0x01a00000 0x200000>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ ranges = <0 0x01a00000 0x200000>;
|
||||
+
|
||||
+ ve_sram: sram-section@0 {
|
||||
+ compatible = "allwinner,sun50i-h6-sram-c1",
|
||||
+ "allwinner,sun4i-a10-sram-c1";
|
||||
+ reg = <0x000000 0x200000>;
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
ccu: clock@3001000 {
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From c1b3128ac98c05c0afde4e6e065d6b1f2ae1dfa7 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Mon, 28 Jan 2019 19:59:27 +0100
|
||||
Subject: [PATCH 6/6] arm64: dts: allwinner: h6: Add Video Engine node
|
||||
|
||||
This adds the Video engine node for H6. It can use whole DRAM range so
|
||||
there is no need for reserved memory node.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
index 247dc0a5ce89..de4b7a1f1012 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -146,6 +146,17 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ video-codec@1c0e000 {
|
||||
+ compatible = "allwinner,sun50i-h6-video-engine";
|
||||
+ reg = <0x01c0e000 0x2000>;
|
||||
+ clocks = <&ccu CLK_BUS_VE>, <&ccu CLK_VE>,
|
||||
+ <&ccu CLK_MBUS_VE>;
|
||||
+ clock-names = "ahb", "mod", "ram";
|
||||
+ resets = <&ccu RST_BUS_VE>;
|
||||
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ allwinner,sram = <&ve_sram 1>;
|
||||
+ };
|
||||
+
|
||||
syscon: syscon@3000000 {
|
||||
compatible = "allwinner,sun50i-h6-system-control",
|
||||
"allwinner,sun50i-a64-system-control";
|
||||
--
|
||||
2.20.1
|
||||
|
658
projects/Allwinner/devices/H6/patches/linux/04-dma.patch
Normal file
658
projects/Allwinner/devices/H6/patches/linux/04-dma.patch
Normal file
@ -0,0 +1,658 @@
|
||||
From f04472a823847403fd9ea34915803c21b8c27175 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 26 Jan 2019 09:47:17 +0100
|
||||
Subject: [PATCH 01/12] dt-bindings: arm64: allwinner: h6: Add binding for DMA
|
||||
controller
|
||||
|
||||
DMA in H6 is similar to other DMA controller, except it is first which
|
||||
supports more than 32 request sources and has 16 channels. It also needs
|
||||
additional clock to be enabled.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
Documentation/devicetree/bindings/dma/sun6i-dma.txt | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/dma/sun6i-dma.txt b/Documentation/devicetree/bindings/dma/sun6i-dma.txt
|
||||
index 7fccc20d8331..cae31f4e77ba 100644
|
||||
--- a/Documentation/devicetree/bindings/dma/sun6i-dma.txt
|
||||
+++ b/Documentation/devicetree/bindings/dma/sun6i-dma.txt
|
||||
@@ -28,12 +28,17 @@ Example:
|
||||
};
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-For A64 DMA controller:
|
||||
+For A64 and H6 DMA controller:
|
||||
|
||||
Required properties:
|
||||
-- compatible: "allwinner,sun50i-a64-dma"
|
||||
+- compatible: Must be one of
|
||||
+ "allwinner,sun50i-a64-dma"
|
||||
+ "allwinner,sun50i-h6-dma"
|
||||
- dma-channels: Number of DMA channels supported by the controller.
|
||||
Refer to Documentation/devicetree/bindings/dma/dma.txt
|
||||
+- clocks: In addition to parent AHB clock, it should also contain mbus
|
||||
+ clock (H6 only)
|
||||
+- clock-names: Should contain "bus" and "mbus" (H6 only)
|
||||
- all properties above, i.e. reg, interrupts, clocks, resets and #dma-cells
|
||||
|
||||
Optional properties:
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 638f21d14b0f22c7e9709edb4ac7b52f0e2a744e Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 26 Jan 2019 09:55:38 +0100
|
||||
Subject: [PATCH 02/12] dmaengine: sun6i: Add a quirk for additional mbus clock
|
||||
|
||||
H6 DMA controller needs additional mbus clock to be enabled.
|
||||
|
||||
Add a quirk for it and handle it accordingly.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/dma/sun6i-dma.c | 23 ++++++++++++++++++++++-
|
||||
1 file changed, 22 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
|
||||
index 0cd13f17fc11..761555080325 100644
|
||||
--- a/drivers/dma/sun6i-dma.c
|
||||
+++ b/drivers/dma/sun6i-dma.c
|
||||
@@ -129,6 +129,7 @@ struct sun6i_dma_config {
|
||||
u32 dst_burst_lengths;
|
||||
u32 src_addr_widths;
|
||||
u32 dst_addr_widths;
|
||||
+ bool mbus_clk;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -182,6 +183,7 @@ struct sun6i_dma_dev {
|
||||
struct dma_device slave;
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
+ struct clk *clk_mbus;
|
||||
int irq;
|
||||
spinlock_t lock;
|
||||
struct reset_control *rstc;
|
||||
@@ -1208,6 +1210,14 @@ static int sun6i_dma_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(sdc->clk);
|
||||
}
|
||||
|
||||
+ if (sdc->cfg->mbus_clk) {
|
||||
+ sdc->clk_mbus = devm_clk_get(&pdev->dev, "mbus");
|
||||
+ if (IS_ERR(sdc->clk_mbus)) {
|
||||
+ dev_err(&pdev->dev, "No mbus clock specified\n");
|
||||
+ return PTR_ERR(sdc->clk_mbus);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
sdc->rstc = devm_reset_control_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(sdc->rstc)) {
|
||||
dev_err(&pdev->dev, "No reset controller specified\n");
|
||||
@@ -1312,11 +1322,19 @@ static int sun6i_dma_probe(struct platform_device *pdev)
|
||||
goto err_reset_assert;
|
||||
}
|
||||
|
||||
+ if (sdc->cfg->mbus_clk) {
|
||||
+ ret = clk_prepare_enable(sdc->clk_mbus);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Couldn't enable mbus clock\n");
|
||||
+ goto err_clk_disable;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
ret = devm_request_irq(&pdev->dev, sdc->irq, sun6i_dma_interrupt, 0,
|
||||
dev_name(&pdev->dev), sdc);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Cannot request IRQ\n");
|
||||
- goto err_clk_disable;
|
||||
+ goto err_mbus_clk_disable;
|
||||
}
|
||||
|
||||
ret = dma_async_device_register(&sdc->slave);
|
||||
@@ -1341,6 +1359,8 @@ static int sun6i_dma_probe(struct platform_device *pdev)
|
||||
dma_async_device_unregister(&sdc->slave);
|
||||
err_irq_disable:
|
||||
sun6i_kill_tasklet(sdc);
|
||||
+err_mbus_clk_disable:
|
||||
+ clk_disable_unprepare(sdc->clk_mbus);
|
||||
err_clk_disable:
|
||||
clk_disable_unprepare(sdc->clk);
|
||||
err_reset_assert:
|
||||
@@ -1359,6 +1379,7 @@ static int sun6i_dma_remove(struct platform_device *pdev)
|
||||
|
||||
sun6i_kill_tasklet(sdc);
|
||||
|
||||
+ clk_disable_unprepare(sdc->clk_mbus);
|
||||
clk_disable_unprepare(sdc->clk);
|
||||
reset_control_assert(sdc->rstc);
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 74a1f9f2f199e9b23ce0b9710efabbaee82f5605 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 26 Jan 2019 12:51:35 +0100
|
||||
Subject: [PATCH 03/12] dmaengine: sun6i: Add a quirk for setting DRQ fields
|
||||
|
||||
H6 DMA has more than 32 possible DRQs. That means that current maximum
|
||||
of 31 DRQs is not enough anymore.
|
||||
|
||||
Add a quirk which will set source and destination DRQ number.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/dma/sun6i-dma.c | 48 ++++++++++++++++++++++++-----------------
|
||||
1 file changed, 28 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
|
||||
index 761555080325..9dd23b76d841 100644
|
||||
--- a/drivers/dma/sun6i-dma.c
|
||||
+++ b/drivers/dma/sun6i-dma.c
|
||||
@@ -68,15 +68,15 @@
|
||||
#define DMA_CHAN_LLI_ADDR 0x08
|
||||
|
||||
#define DMA_CHAN_CUR_CFG 0x0c
|
||||
-#define DMA_CHAN_MAX_DRQ 0x1f
|
||||
-#define DMA_CHAN_CFG_SRC_DRQ(x) ((x) & DMA_CHAN_MAX_DRQ)
|
||||
+#define DMA_CHAN_MAX_DRQ_A31 0x1f
|
||||
+#define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31)
|
||||
#define DMA_CHAN_CFG_SRC_IO_MODE BIT(5)
|
||||
#define DMA_CHAN_CFG_SRC_LINEAR_MODE (0 << 5)
|
||||
#define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7)
|
||||
#define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6)
|
||||
#define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9)
|
||||
|
||||
-#define DMA_CHAN_CFG_DST_DRQ(x) (DMA_CHAN_CFG_SRC_DRQ(x) << 16)
|
||||
+#define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16)
|
||||
#define DMA_CHAN_CFG_DST_IO_MODE (DMA_CHAN_CFG_SRC_IO_MODE << 16)
|
||||
#define DMA_CHAN_CFG_DST_LINEAR_MODE (DMA_CHAN_CFG_SRC_LINEAR_MODE << 16)
|
||||
#define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16)
|
||||
@@ -125,6 +125,7 @@ struct sun6i_dma_config {
|
||||
*/
|
||||
void (*clock_autogate_enable)(struct sun6i_dma_dev *);
|
||||
void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst);
|
||||
+ void (*set_drq)(u32 *p_cfg, s8 src_drq, s8 dst_drq);
|
||||
u32 src_burst_lengths;
|
||||
u32 dst_burst_lengths;
|
||||
u32 src_addr_widths;
|
||||
@@ -311,6 +312,12 @@ static void sun6i_set_burst_length_h3(u32 *p_cfg, s8 src_burst, s8 dst_burst)
|
||||
DMA_CHAN_CFG_DST_BURST_H3(dst_burst);
|
||||
}
|
||||
|
||||
+static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq)
|
||||
+{
|
||||
+ *p_cfg |= DMA_CHAN_CFG_SRC_DRQ_A31(src_drq) |
|
||||
+ DMA_CHAN_CFG_DST_DRQ_A31(dst_drq);
|
||||
+}
|
||||
+
|
||||
static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan)
|
||||
{
|
||||
struct sun6i_desc *txd = pchan->desc;
|
||||
@@ -634,14 +641,13 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
|
||||
|
||||
burst = convert_burst(8);
|
||||
width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES);
|
||||
- v_lli->cfg = DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) |
|
||||
- DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) |
|
||||
- DMA_CHAN_CFG_DST_LINEAR_MODE |
|
||||
+ v_lli->cfg = DMA_CHAN_CFG_DST_LINEAR_MODE |
|
||||
DMA_CHAN_CFG_SRC_LINEAR_MODE |
|
||||
DMA_CHAN_CFG_SRC_WIDTH(width) |
|
||||
DMA_CHAN_CFG_DST_WIDTH(width);
|
||||
|
||||
sdev->cfg->set_burst_length(&v_lli->cfg, burst, burst);
|
||||
+ sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, DRQ_SDRAM);
|
||||
|
||||
sun6i_dma_lli_add(NULL, v_lli, p_lli, txd);
|
||||
|
||||
@@ -695,9 +701,8 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
|
||||
v_lli->dst = sconfig->dst_addr;
|
||||
v_lli->cfg = lli_cfg |
|
||||
DMA_CHAN_CFG_DST_IO_MODE |
|
||||
- DMA_CHAN_CFG_SRC_LINEAR_MODE |
|
||||
- DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) |
|
||||
- DMA_CHAN_CFG_DST_DRQ(vchan->port);
|
||||
+ DMA_CHAN_CFG_SRC_LINEAR_MODE;
|
||||
+ sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port);
|
||||
|
||||
dev_dbg(chan2dev(chan),
|
||||
"%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n",
|
||||
@@ -710,9 +715,8 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
|
||||
v_lli->dst = sg_dma_address(sg);
|
||||
v_lli->cfg = lli_cfg |
|
||||
DMA_CHAN_CFG_DST_LINEAR_MODE |
|
||||
- DMA_CHAN_CFG_SRC_IO_MODE |
|
||||
- DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) |
|
||||
- DMA_CHAN_CFG_SRC_DRQ(vchan->port);
|
||||
+ DMA_CHAN_CFG_SRC_IO_MODE;
|
||||
+ sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM);
|
||||
|
||||
dev_dbg(chan2dev(chan),
|
||||
"%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n",
|
||||
@@ -780,17 +784,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
|
||||
v_lli->dst = sconfig->dst_addr;
|
||||
v_lli->cfg = lli_cfg |
|
||||
DMA_CHAN_CFG_DST_IO_MODE |
|
||||
- DMA_CHAN_CFG_SRC_LINEAR_MODE |
|
||||
- DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) |
|
||||
- DMA_CHAN_CFG_DST_DRQ(vchan->port);
|
||||
+ DMA_CHAN_CFG_SRC_LINEAR_MODE;
|
||||
+ sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port);
|
||||
} else {
|
||||
v_lli->src = sconfig->src_addr;
|
||||
v_lli->dst = buf_addr + period_len * i;
|
||||
v_lli->cfg = lli_cfg |
|
||||
DMA_CHAN_CFG_DST_LINEAR_MODE |
|
||||
- DMA_CHAN_CFG_SRC_IO_MODE |
|
||||
- DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) |
|
||||
- DMA_CHAN_CFG_SRC_DRQ(vchan->port);
|
||||
+ DMA_CHAN_CFG_SRC_IO_MODE;
|
||||
+ sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM);
|
||||
}
|
||||
|
||||
prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd);
|
||||
@@ -1055,6 +1057,7 @@ static struct sun6i_dma_config sun6i_a31_dma_cfg = {
|
||||
.nr_max_requests = 30,
|
||||
.nr_max_vchans = 53,
|
||||
.set_burst_length = sun6i_set_burst_length_a31,
|
||||
+ .set_drq = sun6i_set_drq_a31,
|
||||
.src_burst_lengths = BIT(1) | BIT(8),
|
||||
.dst_burst_lengths = BIT(1) | BIT(8),
|
||||
.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
@@ -1076,6 +1079,7 @@ static struct sun6i_dma_config sun8i_a23_dma_cfg = {
|
||||
.nr_max_vchans = 37,
|
||||
.clock_autogate_enable = sun6i_enable_clock_autogate_a23,
|
||||
.set_burst_length = sun6i_set_burst_length_a31,
|
||||
+ .set_drq = sun6i_set_drq_a31,
|
||||
.src_burst_lengths = BIT(1) | BIT(8),
|
||||
.dst_burst_lengths = BIT(1) | BIT(8),
|
||||
.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
@@ -1092,6 +1096,7 @@ static struct sun6i_dma_config sun8i_a83t_dma_cfg = {
|
||||
.nr_max_vchans = 39,
|
||||
.clock_autogate_enable = sun6i_enable_clock_autogate_a23,
|
||||
.set_burst_length = sun6i_set_burst_length_a31,
|
||||
+ .set_drq = sun6i_set_drq_a31,
|
||||
.src_burst_lengths = BIT(1) | BIT(8),
|
||||
.dst_burst_lengths = BIT(1) | BIT(8),
|
||||
.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
@@ -1115,6 +1120,7 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = {
|
||||
.nr_max_vchans = 34,
|
||||
.clock_autogate_enable = sun6i_enable_clock_autogate_h3,
|
||||
.set_burst_length = sun6i_set_burst_length_h3,
|
||||
+ .set_drq = sun6i_set_drq_a31,
|
||||
.src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
|
||||
.dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
|
||||
.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
@@ -1134,6 +1140,7 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = {
|
||||
static struct sun6i_dma_config sun50i_a64_dma_cfg = {
|
||||
.clock_autogate_enable = sun6i_enable_clock_autogate_h3,
|
||||
.set_burst_length = sun6i_set_burst_length_h3,
|
||||
+ .set_drq = sun6i_set_drq_a31,
|
||||
.src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
|
||||
.dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
|
||||
.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
@@ -1157,6 +1164,7 @@ static struct sun6i_dma_config sun8i_v3s_dma_cfg = {
|
||||
.nr_max_vchans = 24,
|
||||
.clock_autogate_enable = sun6i_enable_clock_autogate_a23,
|
||||
.set_burst_length = sun6i_set_burst_length_a31,
|
||||
+ .set_drq = sun6i_set_drq_a31,
|
||||
.src_burst_lengths = BIT(1) | BIT(8),
|
||||
.dst_burst_lengths = BIT(1) | BIT(8),
|
||||
.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
@@ -1272,8 +1280,8 @@ static int sun6i_dma_probe(struct platform_device *pdev)
|
||||
ret = of_property_read_u32(np, "dma-requests", &sdc->max_request);
|
||||
if (ret && !sdc->max_request) {
|
||||
dev_info(&pdev->dev, "Missing dma-requests, using %u.\n",
|
||||
- DMA_CHAN_MAX_DRQ);
|
||||
- sdc->max_request = DMA_CHAN_MAX_DRQ;
|
||||
+ DMA_CHAN_MAX_DRQ_A31);
|
||||
+ sdc->max_request = DMA_CHAN_MAX_DRQ_A31;
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 20465d9f33a6686cc283f5874428d80fbce29f46 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 26 Jan 2019 13:35:02 +0100
|
||||
Subject: [PATCH 04/12] dmaengine: sun6i: Add a quirk for setting mode fields
|
||||
|
||||
H6 DMA has mode fields in different position than any other currently
|
||||
supported DMA controller.
|
||||
|
||||
Add a quirk for that.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/dma/sun6i-dma.c | 46 ++++++++++++++++++++++++-----------------
|
||||
1 file changed, 27 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
|
||||
index 9dd23b76d841..6a37f8bb39b1 100644
|
||||
--- a/drivers/dma/sun6i-dma.c
|
||||
+++ b/drivers/dma/sun6i-dma.c
|
||||
@@ -70,15 +70,13 @@
|
||||
#define DMA_CHAN_CUR_CFG 0x0c
|
||||
#define DMA_CHAN_MAX_DRQ_A31 0x1f
|
||||
#define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31)
|
||||
-#define DMA_CHAN_CFG_SRC_IO_MODE BIT(5)
|
||||
-#define DMA_CHAN_CFG_SRC_LINEAR_MODE (0 << 5)
|
||||
+#define DMA_CHAN_CFG_SRC_MODE_A31(x) (((x) & 0x1) << 5)
|
||||
#define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7)
|
||||
#define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6)
|
||||
#define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9)
|
||||
|
||||
#define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16)
|
||||
-#define DMA_CHAN_CFG_DST_IO_MODE (DMA_CHAN_CFG_SRC_IO_MODE << 16)
|
||||
-#define DMA_CHAN_CFG_DST_LINEAR_MODE (DMA_CHAN_CFG_SRC_LINEAR_MODE << 16)
|
||||
+#define DMA_CHAN_CFG_DST_MODE_A31(x) (DMA_CHAN_CFG_SRC_MODE_A31(x) << 16)
|
||||
#define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16)
|
||||
#define DMA_CHAN_CFG_DST_BURST_H3(x) (DMA_CHAN_CFG_SRC_BURST_H3(x) << 16)
|
||||
#define DMA_CHAN_CFG_DST_WIDTH(x) (DMA_CHAN_CFG_SRC_WIDTH(x) << 16)
|
||||
@@ -98,6 +96,8 @@
|
||||
#define LLI_LAST_ITEM 0xfffff800
|
||||
#define NORMAL_WAIT 8
|
||||
#define DRQ_SDRAM 1
|
||||
+#define LINEAR_MODE 0
|
||||
+#define IO_MODE 1
|
||||
|
||||
/* forward declaration */
|
||||
struct sun6i_dma_dev;
|
||||
@@ -126,6 +126,7 @@ struct sun6i_dma_config {
|
||||
void (*clock_autogate_enable)(struct sun6i_dma_dev *);
|
||||
void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst);
|
||||
void (*set_drq)(u32 *p_cfg, s8 src_drq, s8 dst_drq);
|
||||
+ void (*set_mode)(u32 *p_cfg, s8 src_mode, s8 dst_mode);
|
||||
u32 src_burst_lengths;
|
||||
u32 dst_burst_lengths;
|
||||
u32 src_addr_widths;
|
||||
@@ -318,6 +319,12 @@ static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq)
|
||||
DMA_CHAN_CFG_DST_DRQ_A31(dst_drq);
|
||||
}
|
||||
|
||||
+static void sun6i_set_mode_a31(u32 *p_cfg, s8 src_mode, s8 dst_mode)
|
||||
+{
|
||||
+ *p_cfg |= DMA_CHAN_CFG_SRC_MODE_A31(src_mode) |
|
||||
+ DMA_CHAN_CFG_DST_MODE_A31(dst_mode);
|
||||
+}
|
||||
+
|
||||
static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan)
|
||||
{
|
||||
struct sun6i_desc *txd = pchan->desc;
|
||||
@@ -641,13 +648,12 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
|
||||
|
||||
burst = convert_burst(8);
|
||||
width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES);
|
||||
- v_lli->cfg = DMA_CHAN_CFG_DST_LINEAR_MODE |
|
||||
- DMA_CHAN_CFG_SRC_LINEAR_MODE |
|
||||
- DMA_CHAN_CFG_SRC_WIDTH(width) |
|
||||
+ v_lli->cfg = DMA_CHAN_CFG_SRC_WIDTH(width) |
|
||||
DMA_CHAN_CFG_DST_WIDTH(width);
|
||||
|
||||
sdev->cfg->set_burst_length(&v_lli->cfg, burst, burst);
|
||||
sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, DRQ_SDRAM);
|
||||
+ sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, LINEAR_MODE);
|
||||
|
||||
sun6i_dma_lli_add(NULL, v_lli, p_lli, txd);
|
||||
|
||||
@@ -699,10 +705,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
|
||||
if (dir == DMA_MEM_TO_DEV) {
|
||||
v_lli->src = sg_dma_address(sg);
|
||||
v_lli->dst = sconfig->dst_addr;
|
||||
- v_lli->cfg = lli_cfg |
|
||||
- DMA_CHAN_CFG_DST_IO_MODE |
|
||||
- DMA_CHAN_CFG_SRC_LINEAR_MODE;
|
||||
+ v_lli->cfg = lli_cfg;
|
||||
sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port);
|
||||
+ sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE);
|
||||
|
||||
dev_dbg(chan2dev(chan),
|
||||
"%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n",
|
||||
@@ -713,10 +718,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
|
||||
} else {
|
||||
v_lli->src = sconfig->src_addr;
|
||||
v_lli->dst = sg_dma_address(sg);
|
||||
- v_lli->cfg = lli_cfg |
|
||||
- DMA_CHAN_CFG_DST_LINEAR_MODE |
|
||||
- DMA_CHAN_CFG_SRC_IO_MODE;
|
||||
+ v_lli->cfg = lli_cfg;
|
||||
sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM);
|
||||
+ sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE);
|
||||
|
||||
dev_dbg(chan2dev(chan),
|
||||
"%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n",
|
||||
@@ -782,17 +786,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
|
||||
if (dir == DMA_MEM_TO_DEV) {
|
||||
v_lli->src = buf_addr + period_len * i;
|
||||
v_lli->dst = sconfig->dst_addr;
|
||||
- v_lli->cfg = lli_cfg |
|
||||
- DMA_CHAN_CFG_DST_IO_MODE |
|
||||
- DMA_CHAN_CFG_SRC_LINEAR_MODE;
|
||||
+ v_lli->cfg = lli_cfg;
|
||||
sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port);
|
||||
+ sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE);
|
||||
} else {
|
||||
v_lli->src = sconfig->src_addr;
|
||||
v_lli->dst = buf_addr + period_len * i;
|
||||
- v_lli->cfg = lli_cfg |
|
||||
- DMA_CHAN_CFG_DST_LINEAR_MODE |
|
||||
- DMA_CHAN_CFG_SRC_IO_MODE;
|
||||
+ v_lli->cfg = lli_cfg;
|
||||
sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM);
|
||||
+ sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE);
|
||||
}
|
||||
|
||||
prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd);
|
||||
@@ -1058,6 +1060,7 @@ static struct sun6i_dma_config sun6i_a31_dma_cfg = {
|
||||
.nr_max_vchans = 53,
|
||||
.set_burst_length = sun6i_set_burst_length_a31,
|
||||
.set_drq = sun6i_set_drq_a31,
|
||||
+ .set_mode = sun6i_set_mode_a31,
|
||||
.src_burst_lengths = BIT(1) | BIT(8),
|
||||
.dst_burst_lengths = BIT(1) | BIT(8),
|
||||
.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
@@ -1080,6 +1083,7 @@ static struct sun6i_dma_config sun8i_a23_dma_cfg = {
|
||||
.clock_autogate_enable = sun6i_enable_clock_autogate_a23,
|
||||
.set_burst_length = sun6i_set_burst_length_a31,
|
||||
.set_drq = sun6i_set_drq_a31,
|
||||
+ .set_mode = sun6i_set_mode_a31,
|
||||
.src_burst_lengths = BIT(1) | BIT(8),
|
||||
.dst_burst_lengths = BIT(1) | BIT(8),
|
||||
.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
@@ -1097,6 +1101,7 @@ static struct sun6i_dma_config sun8i_a83t_dma_cfg = {
|
||||
.clock_autogate_enable = sun6i_enable_clock_autogate_a23,
|
||||
.set_burst_length = sun6i_set_burst_length_a31,
|
||||
.set_drq = sun6i_set_drq_a31,
|
||||
+ .set_mode = sun6i_set_mode_a31,
|
||||
.src_burst_lengths = BIT(1) | BIT(8),
|
||||
.dst_burst_lengths = BIT(1) | BIT(8),
|
||||
.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
@@ -1121,6 +1126,7 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = {
|
||||
.clock_autogate_enable = sun6i_enable_clock_autogate_h3,
|
||||
.set_burst_length = sun6i_set_burst_length_h3,
|
||||
.set_drq = sun6i_set_drq_a31,
|
||||
+ .set_mode = sun6i_set_mode_a31,
|
||||
.src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
|
||||
.dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
|
||||
.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
@@ -1141,6 +1147,7 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = {
|
||||
.clock_autogate_enable = sun6i_enable_clock_autogate_h3,
|
||||
.set_burst_length = sun6i_set_burst_length_h3,
|
||||
.set_drq = sun6i_set_drq_a31,
|
||||
+ .set_mode = sun6i_set_mode_a31,
|
||||
.src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
|
||||
.dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
|
||||
.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
@@ -1165,6 +1172,7 @@ static struct sun6i_dma_config sun8i_v3s_dma_cfg = {
|
||||
.clock_autogate_enable = sun6i_enable_clock_autogate_a23,
|
||||
.set_burst_length = sun6i_set_burst_length_a31,
|
||||
.set_drq = sun6i_set_drq_a31,
|
||||
+ .set_mode = sun6i_set_mode_a31,
|
||||
.src_burst_lengths = BIT(1) | BIT(8),
|
||||
.dst_burst_lengths = BIT(1) | BIT(8),
|
||||
.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 7d4d497a1c5395d452930fdf0177f82520c09066 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 26 Jan 2019 13:50:24 +0100
|
||||
Subject: [PATCH 05/12] dmaengine: sun6i: Add support for H6 DMA
|
||||
|
||||
H6 DMA has more than 32 supported DRQs, which means that configuration
|
||||
register is slightly rearranged. It also needs additional clock to be
|
||||
enabled.
|
||||
|
||||
Add support for it.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/dma/sun6i-dma.c | 44 +++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 42 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
|
||||
index 6a37f8bb39b1..eceedd139651 100644
|
||||
--- a/drivers/dma/sun6i-dma.c
|
||||
+++ b/drivers/dma/sun6i-dma.c
|
||||
@@ -69,14 +69,19 @@
|
||||
|
||||
#define DMA_CHAN_CUR_CFG 0x0c
|
||||
#define DMA_CHAN_MAX_DRQ_A31 0x1f
|
||||
+#define DMA_CHAN_MAX_DRQ_H6 0x3f
|
||||
#define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31)
|
||||
+#define DMA_CHAN_CFG_SRC_DRQ_H6(x) ((x) & DMA_CHAN_MAX_DRQ_H6)
|
||||
#define DMA_CHAN_CFG_SRC_MODE_A31(x) (((x) & 0x1) << 5)
|
||||
+#define DMA_CHAN_CFG_SRC_MODE_H6(x) (((x) & 0x1) << 8)
|
||||
#define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7)
|
||||
#define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6)
|
||||
#define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9)
|
||||
|
||||
#define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16)
|
||||
+#define DMA_CHAN_CFG_DST_DRQ_H6(x) (DMA_CHAN_CFG_SRC_DRQ_H6(x) << 16)
|
||||
#define DMA_CHAN_CFG_DST_MODE_A31(x) (DMA_CHAN_CFG_SRC_MODE_A31(x) << 16)
|
||||
+#define DMA_CHAN_CFG_DST_MODE_H6(x) (DMA_CHAN_CFG_SRC_MODE_H6(x) << 16)
|
||||
#define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16)
|
||||
#define DMA_CHAN_CFG_DST_BURST_H3(x) (DMA_CHAN_CFG_SRC_BURST_H3(x) << 16)
|
||||
#define DMA_CHAN_CFG_DST_WIDTH(x) (DMA_CHAN_CFG_SRC_WIDTH(x) << 16)
|
||||
@@ -319,12 +324,24 @@ static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq)
|
||||
DMA_CHAN_CFG_DST_DRQ_A31(dst_drq);
|
||||
}
|
||||
|
||||
+static void sun6i_set_drq_h6(u32 *p_cfg, s8 src_drq, s8 dst_drq)
|
||||
+{
|
||||
+ *p_cfg |= DMA_CHAN_CFG_SRC_DRQ_H6(src_drq) |
|
||||
+ DMA_CHAN_CFG_DST_DRQ_H6(dst_drq);
|
||||
+}
|
||||
+
|
||||
static void sun6i_set_mode_a31(u32 *p_cfg, s8 src_mode, s8 dst_mode)
|
||||
{
|
||||
*p_cfg |= DMA_CHAN_CFG_SRC_MODE_A31(src_mode) |
|
||||
DMA_CHAN_CFG_DST_MODE_A31(dst_mode);
|
||||
}
|
||||
|
||||
+static void sun6i_set_mode_h6(u32 *p_cfg, s8 src_mode, s8 dst_mode)
|
||||
+{
|
||||
+ *p_cfg |= DMA_CHAN_CFG_SRC_MODE_H6(src_mode) |
|
||||
+ DMA_CHAN_CFG_DST_MODE_H6(dst_mode);
|
||||
+}
|
||||
+
|
||||
static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan)
|
||||
{
|
||||
struct sun6i_desc *txd = pchan->desc;
|
||||
@@ -1160,6 +1177,28 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = {
|
||||
BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * The H6 binding uses the number of dma channels from the
|
||||
+ * device tree node.
|
||||
+ */
|
||||
+static struct sun6i_dma_config sun50i_h6_dma_cfg = {
|
||||
+ .clock_autogate_enable = sun6i_enable_clock_autogate_h3,
|
||||
+ .set_burst_length = sun6i_set_burst_length_h3,
|
||||
+ .set_drq = sun6i_set_drq_h6,
|
||||
+ .set_mode = sun6i_set_mode_h6,
|
||||
+ .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
|
||||
+ .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
|
||||
+ .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
|
||||
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
|
||||
+ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
|
||||
+ .dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
|
||||
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
|
||||
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
|
||||
+ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
|
||||
+ .mbus_clk = true,
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* The V3s have only 8 physical channels, a maximum DRQ port id of 23,
|
||||
* and a total of 24 usable source and destination endpoints.
|
||||
@@ -1190,6 +1229,7 @@ static const struct of_device_id sun6i_dma_match[] = {
|
||||
{ .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg },
|
||||
{ .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg },
|
||||
{ .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg },
|
||||
+ { .compatible = "allwinner,sun50i-h6-dma", .data = &sun50i_h6_dma_cfg },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun6i_dma_match);
|
||||
@@ -1288,8 +1328,8 @@ static int sun6i_dma_probe(struct platform_device *pdev)
|
||||
ret = of_property_read_u32(np, "dma-requests", &sdc->max_request);
|
||||
if (ret && !sdc->max_request) {
|
||||
dev_info(&pdev->dev, "Missing dma-requests, using %u.\n",
|
||||
- DMA_CHAN_MAX_DRQ_A31);
|
||||
- sdc->max_request = DMA_CHAN_MAX_DRQ_A31;
|
||||
+ DMA_CHAN_MAX_DRQ_H6);
|
||||
+ sdc->max_request = DMA_CHAN_MAX_DRQ_H6;
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From b9d20d1b5577e4d73b47b9303798484f6699cfd4 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 26 Jan 2019 14:20:21 +0100
|
||||
Subject: [PATCH 06/12] arm64: dts: allwinner: h6: Add DMA node
|
||||
|
||||
H6 has DMA controller which supports 16 channels.
|
||||
|
||||
Add a node for it.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
index d93a7add67e7..62a0eae77639 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -178,6 +178,18 @@
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
+ dma: dma-controller@3002000 {
|
||||
+ compatible = "allwinner,sun50i-h6-dma";
|
||||
+ reg = <0x03002000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_DMA>, <&ccu CLK_MBUS_DMA>;
|
||||
+ clock-names = "bus", "mbus";
|
||||
+ dma-channels = <16>;
|
||||
+ dma-requests = <46>;
|
||||
+ resets = <&ccu RST_BUS_DMA>;
|
||||
+ #dma-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
gic: interrupt-controller@3021000 {
|
||||
compatible = "arm,gic-400";
|
||||
reg = <0x03021000 0x1000>,
|
||||
--
|
||||
2.20.1
|
142
projects/Allwinner/devices/H6/patches/linux/05-sound-hack.patch
Normal file
142
projects/Allwinner/devices/H6/patches/linux/05-sound-hack.patch
Normal file
@ -0,0 +1,142 @@
|
||||
From 026ec1598d98a0bd45785a44a74ddb7063d2f776 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Tue, 22 Jan 2019 20:16:58 +0100
|
||||
Subject: [PATCH] AW H6 I2S WIP
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 31 ++++++++++++++++++++
|
||||
drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 8 ++---
|
||||
sound/soc/sunxi/sun4i-i2s.c | 12 ++++----
|
||||
3 files changed, 41 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
index 62a0eae77639..f1c53aec6523 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -95,6 +95,23 @@
|
||||
(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||
};
|
||||
|
||||
+ sound_hdmi: sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,format = "i2s";
|
||||
+ simple-audio-card,name = "allwinner-hdmi";
|
||||
+ simple-audio-card,mclk-fs = <256>;
|
||||
+
|
||||
+ simple-audio-card,codec {
|
||||
+ sound-dai = <&hdmi>;
|
||||
+ };
|
||||
+
|
||||
+ simple-audio-card,cpu {
|
||||
+ sound-dai = <&i2s1>;
|
||||
+ dai-tdm-slot-num = <2>;
|
||||
+ dai-tdm-slot-width = <32>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
soc {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
@@ -357,6 +374,19 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ i2s1: i2s@5091000 {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "allwinner,sun8i-h3-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>;
|
||||
+ resets = <&ccu RST_BUS_I2S1>;
|
||||
+ dma-names = "tx";
|
||||
+ allwinner,playback-channels = <8>;
|
||||
+ };
|
||||
+
|
||||
usb2otg: usb@5100000 {
|
||||
compatible = "allwinner,sun50i-h6-musb",
|
||||
"allwinner,sun8i-a33-musb";
|
||||
@@ -440,6 +470,7 @@
|
||||
};
|
||||
|
||||
hdmi: hdmi@6000000 {
|
||||
+ #sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun50i-h6-dw-hdmi";
|
||||
reg = <0x06000000 0x10000>;
|
||||
reg-io-width = <1>;
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
index 139e8389615c..bdb33266a3de 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
@@ -504,7 +504,7 @@ static struct ccu_div i2s3_clk = {
|
||||
.hw.init = CLK_HW_INIT_PARENTS("i2s3",
|
||||
audio_parents,
|
||||
&ccu_div_ops,
|
||||
- 0),
|
||||
+ CLK_SET_RATE_PARENT),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -517,7 +517,7 @@ static struct ccu_div i2s0_clk = {
|
||||
.hw.init = CLK_HW_INIT_PARENTS("i2s0",
|
||||
audio_parents,
|
||||
&ccu_div_ops,
|
||||
- 0),
|
||||
+ CLK_SET_RATE_PARENT),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -530,7 +530,7 @@ static struct ccu_div i2s1_clk = {
|
||||
.hw.init = CLK_HW_INIT_PARENTS("i2s1",
|
||||
audio_parents,
|
||||
&ccu_div_ops,
|
||||
- 0),
|
||||
+ CLK_SET_RATE_PARENT),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -543,7 +543,7 @@ static struct ccu_div i2s2_clk = {
|
||||
.hw.init = CLK_HW_INIT_PARENTS("i2s2",
|
||||
audio_parents,
|
||||
&ccu_div_ops,
|
||||
- 0),
|
||||
+ CLK_SET_RATE_PARENT),
|
||||
},
|
||||
};
|
||||
|
||||
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
|
||||
index d5ec1a20499d..f286b8bfcfb3 100644
|
||||
--- a/sound/soc/sunxi/sun4i-i2s.c
|
||||
+++ b/sound/soc/sunxi/sun4i-i2s.c
|
||||
@@ -108,12 +108,12 @@
|
||||
#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK GENMASK(2, 0)
|
||||
#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan) (chan - 1)
|
||||
|
||||
-#define SUN8I_I2S_TX_CHAN_MAP_REG 0x44
|
||||
+#define SUN8I_I2S_TX_CHAN_MAP_REG 0x48
|
||||
#define SUN8I_I2S_TX_CHAN_SEL_REG 0x34
|
||||
-#define SUN8I_I2S_TX_CHAN_OFFSET_MASK GENMASK(13, 12)
|
||||
-#define SUN8I_I2S_TX_CHAN_OFFSET(offset) (offset << 12)
|
||||
-#define SUN8I_I2S_TX_CHAN_EN_MASK GENMASK(11, 4)
|
||||
-#define SUN8I_I2S_TX_CHAN_EN(num_chan) (((1 << num_chan) - 1) << 4)
|
||||
+#define SUN8I_I2S_TX_CHAN_OFFSET_MASK GENMASK(21, 20)
|
||||
+#define SUN8I_I2S_TX_CHAN_OFFSET(offset) (offset << 20)
|
||||
+#define SUN8I_I2S_TX_CHAN_EN_MASK GENMASK(15, 0)
|
||||
+#define SUN8I_I2S_TX_CHAN_EN(num_chan) (((1 << num_chan) - 1) << 0)
|
||||
|
||||
#define SUN8I_I2S_RX_CHAN_SEL_REG 0x54
|
||||
#define SUN8I_I2S_RX_CHAN_MAP_REG 0x58
|
||||
@@ -946,7 +946,7 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
|
||||
.field_fmt_mode = REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 5),
|
||||
.field_txchanmap = REG_FIELD(SUN8I_I2S_TX_CHAN_MAP_REG, 0, 31),
|
||||
.field_rxchanmap = REG_FIELD(SUN8I_I2S_RX_CHAN_MAP_REG, 0, 31),
|
||||
- .field_txchansel = REG_FIELD(SUN8I_I2S_TX_CHAN_SEL_REG, 0, 2),
|
||||
+ .field_txchansel = REG_FIELD(SUN8I_I2S_TX_CHAN_SEL_REG, 16, 19),
|
||||
.field_rxchansel = REG_FIELD(SUN8I_I2S_RX_CHAN_SEL_REG, 0, 2),
|
||||
};
|
||||
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,25 @@
|
||||
From 18c9a269e2b744ee84f32de9d5c6c66857725ef8 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 15 Dec 2018 12:56:53 +0100
|
||||
Subject: [PATCH 20/20] cedrus increase frequency
|
||||
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus_hw.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
||||
index b43c77d54b95..70677571f3d3 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
||||
@@ -16,7 +16,7 @@
|
||||
#ifndef _CEDRUS_HW_H_
|
||||
#define _CEDRUS_HW_H_
|
||||
|
||||
-#define CEDRUS_CLOCK_RATE_DEFAULT 402000000
|
||||
+#define CEDRUS_CLOCK_RATE_DEFAULT 600000000
|
||||
|
||||
int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec);
|
||||
void cedrus_engine_disable(struct cedrus_dev *dev);
|
||||
--
|
||||
2.20.0
|
||||
|
@ -0,0 +1,20 @@
|
||||
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
|
||||
index caea5a9f8f1d..ba4ce576b471 100644
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
|
||||
@@ -48,8 +48,13 @@ static enum drm_mode_status
|
||||
sun8i_dw_hdmi_mode_valid_h6(struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
- /* This is max for HDMI 2.0b (4K@60Hz) */
|
||||
- if (mode->clock > 594000)
|
||||
+ /*
|
||||
+ * Controller support maximum of 594 MHz, which correlates to
|
||||
+ * 4K@60Hz 4:4:4 or RGB. However, for frequencies greater than
|
||||
+ * 340 MHz scrambling has to be enabled. Because scrambling is
|
||||
+ * not yet implemented, just limit to 340 MHz for now.
|
||||
+ */
|
||||
+ if (mode->clock > 340000)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
return MODE_OK;
|
@ -0,0 +1,96 @@
|
||||
From 9413130f5b213551519c97482462a6daea9a5343 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Tue, 2 Apr 2019 19:32:01 +0200
|
||||
Subject: [PATCH 1/2] clk: sunxi-ng: h6: Change CEC clock parent
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
index daf78966555e..33980067b06e 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
@@ -656,6 +656,8 @@ static const char * const hdmi_cec_parents[] = { "osc32k", "pll-periph0-2x" };
|
||||
static const struct ccu_mux_fixed_prediv hdmi_cec_predivs[] = {
|
||||
{ .index = 1, .div = 36621 },
|
||||
};
|
||||
+
|
||||
+#define SUN50I_H6_HDMI_CEC_CLK_REG 0xb10
|
||||
static struct ccu_mux hdmi_cec_clk = {
|
||||
.enable = BIT(31),
|
||||
|
||||
@@ -1200,6 +1202,15 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
|
||||
val &= ~(GENMASK(21, 16) | BIT(0));
|
||||
writel(val | (7 << 16), reg + SUN50I_H6_PLL_AUDIO_REG);
|
||||
|
||||
+ /*
|
||||
+ * First clock parent (osc32K) is unusable for CEC. But since there
|
||||
+ * is no good way to force parent switch (both run with same frequency),
|
||||
+ * just set second clock parent here.
|
||||
+ */
|
||||
+ val = readl(reg + SUN50I_H6_HDMI_CEC_CLK_REG);
|
||||
+ val |= BIT(24);
|
||||
+ writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);
|
||||
+
|
||||
return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc);
|
||||
}
|
||||
|
||||
--
|
||||
2.21.0
|
||||
|
||||
|
||||
From eab64a1ccf6b7cda339fdfdbfa9e1973e4cc0c85 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Tue, 2 Apr 2019 21:15:45 +0200
|
||||
Subject: [PATCH 2/2] clk: sunxi-ng: h6: Allow video & vpu clocks to change
|
||||
parent rate
|
||||
|
||||
Video related clocks need to set rate as close as possible to the
|
||||
requested one, so they should be able to change parent clock rate.
|
||||
|
||||
VPU clock sometimes has to be set to higher than default parent clock
|
||||
rate. This is requ
|
||||
|
||||
Add CLK_SET_RATE_PARENT flag to tcon-lcd0, tcon-tv0 and ve.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
index 33980067b06e..3c32d7798f27 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
@@ -311,7 +311,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690,
|
||||
0, 3, /* M */
|
||||
24, 1, /* mux */
|
||||
BIT(31), /* gate */
|
||||
- 0);
|
||||
+ CLK_SET_RATE_PARENT);
|
||||
|
||||
static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "psi-ahb1-ahb2",
|
||||
0x69c, BIT(0), 0);
|
||||
@@ -691,7 +691,7 @@ static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0",
|
||||
tcon_lcd0_parents, 0xb60,
|
||||
24, 3, /* mux */
|
||||
BIT(31), /* gate */
|
||||
- 0);
|
||||
+ CLK_SET_RATE_PARENT);
|
||||
|
||||
static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb3",
|
||||
0xb7c, BIT(0), 0);
|
||||
@@ -706,7 +706,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0",
|
||||
8, 2, /* P */
|
||||
24, 3, /* mux */
|
||||
BIT(31), /* gate */
|
||||
- 0);
|
||||
+ CLK_SET_RATE_PARENT);
|
||||
|
||||
static SUNXI_CCU_GATE(bus_tcon_tv0_clk, "bus-tcon-tv0", "ahb3",
|
||||
0xb9c, BIT(0), 0);
|
||||
--
|
||||
2.21.0
|
||||
|
608
projects/Allwinner/devices/H6/patches/u-boot/001-update-dt.patch
Normal file
608
projects/Allwinner/devices/H6/patches/u-boot/001-update-dt.patch
Normal file
@ -0,0 +1,608 @@
|
||||
diff --git a/arch/arm/dts/sun50i-h6-pine-h64.dts b/arch/arm/dts/sun50i-h6-pine-h64.dts
|
||||
index ceffc40810..bdb8470fc8 100644
|
||||
--- a/arch/arm/dts/sun50i-h6-pine-h64.dts
|
||||
+++ b/arch/arm/dts/sun50i-h6-pine-h64.dts
|
||||
@@ -14,6 +14,7 @@
|
||||
compatible = "pine64,pine-h64", "allwinner,sun50i-h6";
|
||||
|
||||
aliases {
|
||||
+ ethernet0 = &emac;
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
@@ -21,6 +22,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";
|
||||
|
||||
@@ -39,6 +51,56 @@
|
||||
gpios = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */
|
||||
};
|
||||
};
|
||||
+
|
||||
+ reg_usb_vbus: vbus {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "usb-vbus";
|
||||
+ regulator-min-microvolt = <5000000>;
|
||||
+ regulator-max-microvolt = <5000000>;
|
||||
+ startup-delay-us = <100000>;
|
||||
+ gpio = <&r_pio 0 5 GPIO_ACTIVE_HIGH>;
|
||||
+ enable-active-high;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&emac {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&ext_rgmii_pins>;
|
||||
+ phy-mode = "rgmii";
|
||||
+ phy-handle = <&ext_rgmii_phy>;
|
||||
+ phy-supply = <®_aldo2>;
|
||||
+ allwinner,rx-delay-ps = <200>;
|
||||
+ allwinner,tx-delay-ps = <200>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&mdio {
|
||||
+ ext_rgmii_phy: ethernet-phy@1 {
|
||||
+ compatible = "ethernet-phy-ieee802.3-c22";
|
||||
+ reg = <1>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&de {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi_out {
|
||||
+ hdmi_out_con: endpoint {
|
||||
+ remote-endpoint = <&hdmi_con_in>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&ehci0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ehci3 {
|
||||
+ status = "okay";
|
||||
};
|
||||
|
||||
&mmc0 {
|
||||
@@ -46,6 +108,7 @@
|
||||
pinctrl-0 = <&mmc0_pins>;
|
||||
vmmc-supply = <®_cldo1>;
|
||||
cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
|
||||
+ bus-width = <4>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -56,6 +119,15 @@
|
||||
vqmmc-supply = <®_bldo2>;
|
||||
non-removable;
|
||||
cap-mmc-hw-reset;
|
||||
+ bus-width = <8>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ohci0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ohci3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -83,6 +155,7 @@
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-name = "vcc-ac200";
|
||||
+ regulator-enable-ramp-delay = <100000>;
|
||||
};
|
||||
|
||||
reg_aldo3: aldo3 {
|
||||
@@ -183,3 +256,14 @@
|
||||
pinctrl-0 = <&uart0_ph_pins>;
|
||||
status = "okay";
|
||||
};
|
||||
+
|
||||
+&usb2otg {
|
||||
+ dr_mode = "host";
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb2phy {
|
||||
+ usb0_vbus-supply = <®_usb_vbus>;
|
||||
+ usb3_vbus-supply = <®_usb_vbus>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
diff --git a/arch/arm/dts/sun50i-h6.dtsi b/arch/arm/dts/sun50i-h6.dtsi
|
||||
index cfa5fffcf6..c9e861a50a 100644
|
||||
--- a/arch/arm/dts/sun50i-h6.dtsi
|
||||
+++ b/arch/arm/dts/sun50i-h6.dtsi
|
||||
@@ -6,8 +6,11 @@
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/sun50i-h6-ccu.h>
|
||||
#include <dt-bindings/clock/sun50i-h6-r-ccu.h>
|
||||
+#include <dt-bindings/clock/sun8i-de2.h>
|
||||
+#include <dt-bindings/clock/sun8i-tcon-top.h>
|
||||
#include <dt-bindings/reset/sun50i-h6-ccu.h>
|
||||
#include <dt-bindings/reset/sun50i-h6-r-ccu.h>
|
||||
+#include <dt-bindings/reset/sun8i-de2.h>
|
||||
|
||||
/ {
|
||||
interrupt-parent = <&gic>;
|
||||
@@ -19,34 +22,40 @@
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu0: cpu@0 {
|
||||
- compatible = "arm,cortex-a53", "arm,armv8";
|
||||
+ compatible = "arm,cortex-a53";
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
enable-method = "psci";
|
||||
};
|
||||
|
||||
cpu1: cpu@1 {
|
||||
- compatible = "arm,cortex-a53", "arm,armv8";
|
||||
+ compatible = "arm,cortex-a53";
|
||||
device_type = "cpu";
|
||||
reg = <1>;
|
||||
enable-method = "psci";
|
||||
};
|
||||
|
||||
cpu2: cpu@2 {
|
||||
- compatible = "arm,cortex-a53", "arm,armv8";
|
||||
+ compatible = "arm,cortex-a53";
|
||||
device_type = "cpu";
|
||||
reg = <2>;
|
||||
enable-method = "psci";
|
||||
};
|
||||
|
||||
cpu3: cpu@3 {
|
||||
- compatible = "arm,cortex-a53", "arm,armv8";
|
||||
+ compatible = "arm,cortex-a53";
|
||||
device_type = "cpu";
|
||||
reg = <3>;
|
||||
enable-method = "psci";
|
||||
};
|
||||
};
|
||||
|
||||
+ de: display-engine {
|
||||
+ compatible = "allwinner,sun50i-h6-display-engine";
|
||||
+ allwinner,pipelines = <&mixer0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
iosc: internal-osc-clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
@@ -92,6 +101,88 @@
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
+ display-engine@1000000 {
|
||||
+ compatible = "allwinner,sun50i-h6-de3",
|
||||
+ "allwinner,sun50i-a64-de2";
|
||||
+ reg = <0x1000000 0x400000>;
|
||||
+ allwinner,sram = <&de2_sram 1>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ ranges = <0 0x1000000 0x400000>;
|
||||
+
|
||||
+ display_clocks: clock@0 {
|
||||
+ compatible = "allwinner,sun50i-h6-de3-clk";
|
||||
+ reg = <0x0 0x10000>;
|
||||
+ clocks = <&ccu CLK_DE>,
|
||||
+ <&ccu CLK_BUS_DE>;
|
||||
+ clock-names = "mod",
|
||||
+ "bus";
|
||||
+ resets = <&ccu RST_BUS_DE>;
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ mixer0: mixer@100000 {
|
||||
+ compatible = "allwinner,sun50i-h6-de3-mixer-0";
|
||||
+ reg = <0x100000 0x100000>;
|
||||
+ clocks = <&display_clocks CLK_BUS_MIXER0>,
|
||||
+ <&display_clocks CLK_MIXER0>;
|
||||
+ clock-names = "bus",
|
||||
+ "mod";
|
||||
+ resets = <&display_clocks RST_MIXER0>;
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ mixer0_out: port@1 {
|
||||
+ reg = <1>;
|
||||
+
|
||||
+ mixer0_out_tcon_top_mixer0: endpoint {
|
||||
+ remote-endpoint = <&tcon_top_mixer0_in_mixer0>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ syscon: syscon@3000000 {
|
||||
+ compatible = "allwinner,sun50i-h6-system-control",
|
||||
+ "allwinner,sun50i-a64-system-control";
|
||||
+ reg = <0x03000000 0x1000>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ ranges;
|
||||
+
|
||||
+ sram_c: sram@28000 {
|
||||
+ compatible = "mmio-sram";
|
||||
+ reg = <0x00028000 0x1e000>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ ranges = <0 0x00028000 0x1e000>;
|
||||
+
|
||||
+ de2_sram: sram-section@0 {
|
||||
+ compatible = "allwinner,sun50i-h6-sram-c",
|
||||
+ "allwinner,sun50i-a64-sram-c";
|
||||
+ reg = <0x0000 0x1e000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ sram_c1: sram@1a00000 {
|
||||
+ compatible = "mmio-sram";
|
||||
+ reg = <0x01a00000 0x200000>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ ranges = <0 0x01a00000 0x200000>;
|
||||
+
|
||||
+ ve_sram: sram-section@0 {
|
||||
+ compatible = "allwinner,sun50i-h6-sram-c1",
|
||||
+ "allwinner,sun4i-a10-sram-c1";
|
||||
+ reg = <0x000000 0x200000>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
ccu: clock@3001000 {
|
||||
compatible = "allwinner,sun50i-h6-ccu";
|
||||
reg = <0x03001000 0x1000>;
|
||||
@@ -101,17 +192,6 @@
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
- gic: interrupt-controller@3021000 {
|
||||
- compatible = "arm,gic-400";
|
||||
- reg = <0x03021000 0x1000>,
|
||||
- <0x03022000 0x2000>,
|
||||
- <0x03024000 0x2000>,
|
||||
- <0x03026000 0x2000>;
|
||||
- interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||
- interrupt-controller;
|
||||
- #interrupt-cells = <3>;
|
||||
- };
|
||||
-
|
||||
pio: pinctrl@300b000 {
|
||||
compatible = "allwinner,sun50i-h6-pinctrl";
|
||||
reg = <0x0300b000 0x400>;
|
||||
@@ -126,6 +206,19 @@
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
|
||||
+ ext_rgmii_pins: rgmii_pins {
|
||||
+ pins = "PD0", "PD1", "PD2", "PD3", "PD4",
|
||||
+ "PD5", "PD7", "PD8", "PD9", "PD10",
|
||||
+ "PD11", "PD12", "PD13", "PD19", "PD20";
|
||||
+ function = "emac";
|
||||
+ drive-strength = <40>;
|
||||
+ };
|
||||
+
|
||||
+ hdmi_pins: hdmi-pins {
|
||||
+ pins = "PH8", "PH9", "PH10";
|
||||
+ function = "hdmi";
|
||||
+ };
|
||||
+
|
||||
mmc0_pins: mmc0-pins {
|
||||
pins = "PF0", "PF1", "PF2", "PF3",
|
||||
"PF4", "PF5";
|
||||
@@ -149,6 +242,17 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ gic: interrupt-controller@3021000 {
|
||||
+ compatible = "arm,gic-400";
|
||||
+ reg = <0x03021000 0x1000>,
|
||||
+ <0x03022000 0x2000>,
|
||||
+ <0x03024000 0x2000>,
|
||||
+ <0x03026000 0x2000>;
|
||||
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <3>;
|
||||
+ };
|
||||
+
|
||||
mmc0: mmc@4020000 {
|
||||
compatible = "allwinner,sun50i-h6-mmc",
|
||||
"allwinner,sun50i-a64-mmc";
|
||||
@@ -235,6 +339,250 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ emac: ethernet@5020000 {
|
||||
+ compatible = "allwinner,sun50i-h6-emac",
|
||||
+ "allwinner,sun50i-a64-emac";
|
||||
+ syscon = <&syscon>;
|
||||
+ reg = <0x05020000 0x10000>;
|
||||
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "macirq";
|
||||
+ resets = <&ccu RST_BUS_EMAC>;
|
||||
+ reset-names = "stmmaceth";
|
||||
+ clocks = <&ccu CLK_BUS_EMAC>;
|
||||
+ clock-names = "stmmaceth";
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ mdio: mdio {
|
||||
+ compatible = "snps,dwmac-mdio";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ usb2otg: usb@5100000 {
|
||||
+ compatible = "allwinner,sun50i-h6-musb",
|
||||
+ "allwinner,sun8i-a33-musb";
|
||||
+ reg = <0x05100000 0x0400>;
|
||||
+ clocks = <&ccu CLK_BUS_OTG>;
|
||||
+ resets = <&ccu RST_BUS_OTG>;
|
||||
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "mc";
|
||||
+ phys = <&usb2phy 0>;
|
||||
+ phy-names = "usb";
|
||||
+ extcon = <&usb2phy 0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ usb2phy: phy@5100400 {
|
||||
+ compatible = "allwinner,sun50i-h6-usb-phy";
|
||||
+ reg = <0x05100400 0x24>,
|
||||
+ <0x05101800 0x4>,
|
||||
+ <0x05311800 0x4>;
|
||||
+ reg-names = "phy_ctrl",
|
||||
+ "pmu0",
|
||||
+ "pmu3";
|
||||
+ clocks = <&ccu CLK_USB_PHY0>,
|
||||
+ <&ccu CLK_USB_PHY3>;
|
||||
+ clock-names = "usb0_phy",
|
||||
+ "usb3_phy";
|
||||
+ resets = <&ccu RST_USB_PHY0>,
|
||||
+ <&ccu RST_USB_PHY3>;
|
||||
+ reset-names = "usb0_reset",
|
||||
+ "usb3_reset";
|
||||
+ status = "disabled";
|
||||
+ #phy-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ ehci0: usb@5101000 {
|
||||
+ compatible = "allwinner,sun50i-h6-ehci", "generic-ehci";
|
||||
+ reg = <0x05101000 0x100>;
|
||||
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_OHCI0>,
|
||||
+ <&ccu CLK_BUS_EHCI0>,
|
||||
+ <&ccu CLK_USB_OHCI0>;
|
||||
+ resets = <&ccu RST_BUS_OHCI0>,
|
||||
+ <&ccu RST_BUS_EHCI0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ ohci0: usb@5101400 {
|
||||
+ compatible = "allwinner,sun50i-h6-ohci", "generic-ohci";
|
||||
+ reg = <0x05101400 0x100>;
|
||||
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_OHCI0>,
|
||||
+ <&ccu CLK_USB_OHCI0>;
|
||||
+ resets = <&ccu RST_BUS_OHCI0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ ehci3: usb@5311000 {
|
||||
+ compatible = "allwinner,sun50i-h6-ehci", "generic-ehci";
|
||||
+ reg = <0x05311000 0x100>;
|
||||
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_OHCI3>,
|
||||
+ <&ccu CLK_BUS_EHCI3>,
|
||||
+ <&ccu CLK_USB_OHCI3>;
|
||||
+ resets = <&ccu RST_BUS_OHCI3>,
|
||||
+ <&ccu RST_BUS_EHCI3>;
|
||||
+ phys = <&usb2phy 3>;
|
||||
+ phy-names = "usb";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ ohci3: usb@5311400 {
|
||||
+ compatible = "allwinner,sun50i-h6-ohci", "generic-ohci";
|
||||
+ reg = <0x05311400 0x100>;
|
||||
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_OHCI3>,
|
||||
+ <&ccu CLK_USB_OHCI3>;
|
||||
+ resets = <&ccu RST_BUS_OHCI3>;
|
||||
+ phys = <&usb2phy 3>;
|
||||
+ phy-names = "usb";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ hdmi: hdmi@6000000 {
|
||||
+ compatible = "allwinner,sun50i-h6-dw-hdmi";
|
||||
+ reg = <0x06000000 0x10000>;
|
||||
+ reg-io-width = <1>;
|
||||
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_SLOW>,
|
||||
+ <&ccu CLK_HDMI>, <&ccu CLK_HDMI_CEC>,
|
||||
+ <&ccu CLK_HDCP>, <&ccu CLK_BUS_HDCP>;
|
||||
+ clock-names = "iahb", "isfr", "tmds", "cec", "hdcp",
|
||||
+ "hdcp-bus";
|
||||
+ resets = <&ccu RST_BUS_HDMI_SUB>, <&ccu RST_BUS_HDCP>;
|
||||
+ reset-names = "ctrl", "hdcp";
|
||||
+ phys = <&hdmi_phy>;
|
||||
+ phy-names = "hdmi-phy";
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&hdmi_pins>;
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ hdmi_in: port@0 {
|
||||
+ reg = <0>;
|
||||
+
|
||||
+ hdmi_in_tcon_top: endpoint {
|
||||
+ remote-endpoint = <&tcon_top_hdmi_out_hdmi>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ hdmi_out: port@1 {
|
||||
+ reg = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ hdmi_phy: hdmi-phy@6010000 {
|
||||
+ compatible = "allwinner,sun50i-h6-hdmi-phy";
|
||||
+ reg = <0x06010000 0x10000>;
|
||||
+ clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_SLOW>;
|
||||
+ clock-names = "bus", "mod";
|
||||
+ resets = <&ccu RST_BUS_HDMI>;
|
||||
+ reset-names = "phy";
|
||||
+ #phy-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ tcon_top: tcon-top@6510000 {
|
||||
+ compatible = "allwinner,sun50i-h6-tcon-top";
|
||||
+ reg = <0x06510000 0x1000>;
|
||||
+ clocks = <&ccu CLK_BUS_TCON_TOP>,
|
||||
+ <&ccu CLK_TCON_TV0>;
|
||||
+ clock-names = "bus",
|
||||
+ "tcon-tv0";
|
||||
+ clock-output-names = "tcon-top-tv0";
|
||||
+ resets = <&ccu RST_BUS_TCON_TOP>;
|
||||
+ reset-names = "rst";
|
||||
+ #clock-cells = <1>;
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ tcon_top_mixer0_in: port@0 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = <0>;
|
||||
+
|
||||
+ tcon_top_mixer0_in_mixer0: endpoint@0 {
|
||||
+ reg = <0>;
|
||||
+ remote-endpoint = <&mixer0_out_tcon_top_mixer0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ tcon_top_mixer0_out: port@1 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = <1>;
|
||||
+
|
||||
+ tcon_top_mixer0_out_tcon_tv: endpoint@2 {
|
||||
+ reg = <2>;
|
||||
+ remote-endpoint = <&tcon_tv_in_tcon_top_mixer0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ tcon_top_hdmi_in: port@4 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = <4>;
|
||||
+
|
||||
+ tcon_top_hdmi_in_tcon_tv: endpoint@0 {
|
||||
+ reg = <0>;
|
||||
+ remote-endpoint = <&tcon_tv_out_tcon_top>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ tcon_top_hdmi_out: port@5 {
|
||||
+ reg = <5>;
|
||||
+
|
||||
+ tcon_top_hdmi_out_hdmi: endpoint {
|
||||
+ remote-endpoint = <&hdmi_in_tcon_top>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ tcon_tv: lcd-controller@6515000 {
|
||||
+ compatible = "allwinner,sun50i-h6-tcon-tv",
|
||||
+ "allwinner,sun8i-r40-tcon-tv";
|
||||
+ reg = <0x06515000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_TCON_TV0>,
|
||||
+ <&tcon_top CLK_TCON_TOP_TV0>;
|
||||
+ clock-names = "ahb",
|
||||
+ "tcon-ch1";
|
||||
+ resets = <&ccu RST_BUS_TCON_TV0>;
|
||||
+ reset-names = "lcd";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ tcon_tv_in: port@0 {
|
||||
+ reg = <0>;
|
||||
+
|
||||
+ tcon_tv_in_tcon_top_mixer0: endpoint {
|
||||
+ remote-endpoint = <&tcon_top_mixer0_out_tcon_tv>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ tcon_tv_out: port@1 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = <1>;
|
||||
+
|
||||
+ tcon_tv_out_tcon_top: endpoint@1 {
|
||||
+ reg = <1>;
|
||||
+ remote-endpoint = <&tcon_top_hdmi_in_tcon_tv>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
r_ccu: clock@7010000 {
|
||||
compatible = "allwinner,sun50i-h6-r-ccu";
|
||||
reg = <0x07010000 0x400>;
|
||||
diff --git a/include/dt-bindings/clock/sun8i-tcon-top.h b/include/dt-bindings/clock/sun8i-tcon-top.h
|
||||
new file mode 100644
|
||||
index 0000000000..25164d7678
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/clock/sun8i-tcon-top.h
|
||||
@@ -0,0 +1,11 @@
|
||||
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
|
||||
+/* Copyright (C) 2018 Jernej Skrabec <jernej.skrabec@siol.net> */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_CLOCK_SUN8I_TCON_TOP_H_
|
||||
+#define _DT_BINDINGS_CLOCK_SUN8I_TCON_TOP_H_
|
||||
+
|
||||
+#define CLK_TCON_TOP_TV0 0
|
||||
+#define CLK_TCON_TOP_TV1 1
|
||||
+#define CLK_TCON_TOP_DSI 2
|
||||
+
|
||||
+#endif /* _DT_BINDINGS_CLOCK_SUN8I_TCON_TOP_H_ */
|
@ -0,0 +1,23 @@
|
||||
[Unit]
|
||||
Description=Debug Shell on /dev/console
|
||||
DefaultDependencies=no
|
||||
ConditionKernelCommandLine=console
|
||||
|
||||
[Service]
|
||||
WorkingDirectory=/storage
|
||||
Environment="ENV=/etc/profile"
|
||||
ExecStartPre=/bin/sh -c 'echo -en "\033[?25h"'
|
||||
ExecStart=/bin/sh
|
||||
Restart=always
|
||||
RestartSec=0
|
||||
StandardInput=tty
|
||||
TTYPath=/dev/console
|
||||
TTYReset=yes
|
||||
TTYVHangup=yes
|
||||
KillMode=process
|
||||
IgnoreSIGPIPE=no
|
||||
# bash ignores SIGTERM
|
||||
KillSignal=SIGHUP
|
||||
|
||||
[Install]
|
||||
WantedBy=sysinit.target
|
@ -0,0 +1,34 @@
|
||||
#
|
||||
# Configuration for HDMI
|
||||
#
|
||||
|
||||
<confdir:pcm/hdmi.conf>
|
||||
|
||||
allwinner-hdmi.pcm.hdmi.0 {
|
||||
@args [ CARD AES0 AES1 AES2 AES3 ]
|
||||
@args.CARD { type string }
|
||||
@args.AES0 { type integer }
|
||||
@args.AES1 { type integer }
|
||||
@args.AES2 { type integer }
|
||||
@args.AES3 { type integer }
|
||||
type hooks
|
||||
slave.pcm {
|
||||
type hw
|
||||
card $CARD
|
||||
device 0
|
||||
}
|
||||
hooks.0 {
|
||||
type ctl_elems
|
||||
hook_args [
|
||||
{
|
||||
interface MIXER
|
||||
name "IEC958 Playback Default"
|
||||
lock true
|
||||
preserve true
|
||||
optional true
|
||||
value [ $AES0 $AES1 $AES2 $AES3 ]
|
||||
}
|
||||
]
|
||||
}
|
||||
hint.device 0
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
#
|
||||
# Configuration for SPDIF
|
||||
#
|
||||
|
||||
<confdir:pcm/iec958.conf>
|
||||
|
||||
On-board_SPDIF.pcm.iec958.0 {
|
||||
@args [ CARD AES0 AES1 AES2 AES3 ]
|
||||
@args.CARD { type string }
|
||||
@args.AES0 { type integer }
|
||||
@args.AES1 { type integer }
|
||||
@args.AES2 { type integer }
|
||||
@args.AES3 { type integer }
|
||||
type hooks
|
||||
slave.pcm {
|
||||
type hw
|
||||
card $CARD
|
||||
device 0
|
||||
}
|
||||
hooks.0 {
|
||||
type ctl_elems
|
||||
hook_args [
|
||||
{
|
||||
interface MIXER
|
||||
name "IEC958 Playback Default"
|
||||
lock true
|
||||
preserve true
|
||||
optional true
|
||||
value [ $AES0 $AES1 $AES2 $AES3 ]
|
||||
}
|
||||
]
|
||||
}
|
||||
hint.device 0
|
||||
}
|
22
projects/Allwinner/kodi/appliance.xml
Normal file
22
projects/Allwinner/kodi/appliance.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<settings version="1">
|
||||
|
||||
<section id="system">
|
||||
<category id="display">
|
||||
<group id="1">
|
||||
<setting id="videoscreen.limitguisize">
|
||||
<visible>false</visible>
|
||||
<default>3</default>
|
||||
</setting>
|
||||
</group>
|
||||
</category>
|
||||
<category id="audio">
|
||||
<group id="1">
|
||||
<setting id="audiooutput.audiodevice">
|
||||
<default>ALSA:hdmi:CARD=allwinnerhdmi,DEV=0</default>
|
||||
</setting>
|
||||
</group>
|
||||
</category>
|
||||
</section>
|
||||
|
||||
</settings>
|
5620
projects/Allwinner/linux/linux.aarch64.conf
Normal file
5620
projects/Allwinner/linux/linux.aarch64.conf
Normal file
File diff suppressed because it is too large
Load Diff
5282
projects/Allwinner/linux/linux.arm.conf
Normal file
5282
projects/Allwinner/linux/linux.arm.conf
Normal file
File diff suppressed because it is too large
Load Diff
84
projects/Allwinner/options
Normal file
84
projects/Allwinner/options
Normal file
@ -0,0 +1,84 @@
|
||||
################################################################################
|
||||
# setup system defaults
|
||||
################################################################################
|
||||
|
||||
# Bootloader to use (syslinux / u-boot / bcm2835-bootloader)
|
||||
BOOTLOADER="u-boot"
|
||||
|
||||
# u-boot version to use (default)
|
||||
UBOOT_VERSION="default"
|
||||
|
||||
# Configuration for u-boot
|
||||
UBOOT_CONFIG=""
|
||||
|
||||
# Target Configfile for u-boot
|
||||
UBOOT_CONFIGFILE=""
|
||||
|
||||
# Kernel extra targets to build
|
||||
KERNEL_UBOOT_EXTRA_TARGET=""
|
||||
|
||||
# Additional kernel make parameters (for example to specify the u-boot loadaddress)
|
||||
KERNEL_MAKE_EXTRACMD="dtbs"
|
||||
|
||||
# Kernel to use. values can be:
|
||||
# default: default mainline kernel
|
||||
LINUX="default"
|
||||
|
||||
EXTRA_CMDLINE="console=ttyS0,115200 console=tty1"
|
||||
|
||||
################################################################################
|
||||
# setup build defaults
|
||||
################################################################################
|
||||
|
||||
# Project CFLAGS
|
||||
PROJECT_CFLAGS=""
|
||||
|
||||
# SquashFS compression method (gzip / lzo / xz / zstd)
|
||||
SQUASHFS_COMPRESSION="zstd"
|
||||
|
||||
################################################################################
|
||||
# setup project defaults
|
||||
################################################################################
|
||||
|
||||
# build and install ALSA Audio support (yes / no)
|
||||
ALSA_SUPPORT="yes"
|
||||
|
||||
# OpenGL(X) implementation to use (no / mesa)
|
||||
OPENGL="no"
|
||||
|
||||
# OpenGL-ES implementation to use (no / bcm2835-driver / gpu-viv-bin-mx6q)
|
||||
OPENGLES="libmali"
|
||||
|
||||
# include uvesafb support (yes / no)
|
||||
UVESAFB_SUPPORT="no"
|
||||
|
||||
# Displayserver to use (x11 / no)
|
||||
DISPLAYSERVER="no"
|
||||
|
||||
# Windowmanager to use (ratpoison / fluxbox / none)
|
||||
WINDOWMANAGER="none"
|
||||
|
||||
# Xorg Graphic drivers to use (all / i915,i965,r200,r300,r600,nvidia)
|
||||
# Space separated list is supported,
|
||||
# e.g. GRAPHIC_DRIVERS="i915 i965 r300 r600 radeonsi nvidia"
|
||||
GRAPHIC_DRIVERS=""
|
||||
|
||||
# KODI Player implementation to use (default / bcm2835-driver / libfslvpuwrap)
|
||||
KODIPLAYER_DRIVER="$OPENGLES"
|
||||
|
||||
# Modules to install in initramfs for early boot
|
||||
INITRAMFS_MODULES=""
|
||||
|
||||
# additional Firmware to use (dvb-firmware, misc-firmware, wlan-firmware)
|
||||
# Space separated list is supported,
|
||||
# e.g. FIRMWARE="dvb-firmware misc-firmware wlan-firmware"
|
||||
FIRMWARE="misc-firmware wlan-firmware dvb-firmware"
|
||||
|
||||
# build and install ATV IR remote support (yes / no)
|
||||
ATVCLIENT_SUPPORT="no"
|
||||
|
||||
# build and install CEC framework support (yes / no)
|
||||
CEC_FRAMEWORK_SUPPORT="yes"
|
||||
|
||||
# build with installer (yes / no)
|
||||
INSTALLER_SUPPORT="no"
|
@ -0,0 +1,18 @@
|
||||
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||
index 3b0d0d832d..221f48f061 100644
|
||||
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||
@@ -243,12 +362,6 @@ bool CDVDVideoCodecDRMPRIME::Open(CDVDStreamInfo& hints, CDVDCodecOptions& optio
|
||||
return false;
|
||||
}
|
||||
|
||||
- if (m_pCodecContext->pix_fmt != AV_PIX_FMT_DRM_PRIME)
|
||||
- {
|
||||
- CLog::Log(LOGNOTICE, "CDVDVideoCodecDRMPRIME::%s - unexpected pix fmt %s", __FUNCTION__, av_get_pix_fmt_name(m_pCodecContext->pix_fmt));
|
||||
- avcodec_free_context(&m_pCodecContext);
|
||||
- return false;
|
||||
- }
|
||||
|
||||
const char* pixFmtName = av_get_pix_fmt_name(m_pCodecContext->pix_fmt);
|
||||
m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : "");
|
||||
|
153
projects/Allwinner/patches/kodi/0002-guisize.patch
Normal file
153
projects/Allwinner/patches/kodi/0002-guisize.patch
Normal file
@ -0,0 +1,153 @@
|
||||
From 7a88b0ad7a90a8ac2266f87ccb08dca5df0c0867 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Sun, 14 Oct 2018 14:20:03 +0200
|
||||
Subject: [PATCH] WIP: windowing/gbm: add option to limit gui size
|
||||
|
||||
---
|
||||
.../resources/strings.po | 52 ++++++++++++++++++-
|
||||
system/settings/gbm.xml | 15 ++++++
|
||||
xbmc/windowing/gbm/DRMUtils.cpp | 28 ++++++++++
|
||||
3 files changed, 94 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
|
||||
index 97211d3b718a..eaa5b3fed759 100644
|
||||
--- a/addons/resource.language.en_gb/resources/strings.po
|
||||
+++ b/addons/resource.language.en_gb/resources/strings.po
|
||||
@@ -7256,7 +7256,57 @@ msgctxt "#13465"
|
||||
msgid "EGL"
|
||||
msgstr ""
|
||||
|
||||
-#empty strings from id 13466 to 13504
|
||||
+#empty strings from id 13466 to 13485
|
||||
+
|
||||
+#. String for options 3 of setting with label #13482 "HDMI Quantization Range"
|
||||
+#: system/settings/gbm.xml
|
||||
+msgctxt "#13486"
|
||||
+msgid "Limited"
|
||||
+msgstr ""
|
||||
+
|
||||
+#. Option for setting Limit GUI Size
|
||||
+#: system/settings/gbm.xml
|
||||
+msgctxt "#13487"
|
||||
+msgid "Limit GUI Size"
|
||||
+msgstr ""
|
||||
+
|
||||
+#. Description of setting with label #13487 "Limit GUI Size"
|
||||
+#: system/settings/gbm.xml
|
||||
+msgctxt "#13488"
|
||||
+msgid "This option limits GUI size for screen resolutions above 1080p. Requires restart."
|
||||
+msgstr ""
|
||||
+
|
||||
+#. String for options 1 of setting with label #13487 "Limit GUI Size"
|
||||
+#: system/settings/gbm.xml
|
||||
+msgctxt "#13489"
|
||||
+msgid "No limit"
|
||||
+msgstr ""
|
||||
+
|
||||
+#. String for options 2 of setting with label #13487 "Limit GUI Size"
|
||||
+#: system/settings/gbm.xml
|
||||
+msgctxt "#13490"
|
||||
+msgid "720p"
|
||||
+msgstr ""
|
||||
+
|
||||
+#. String for options 3 of setting with label #13487 "Limit GUI Size"
|
||||
+#: system/settings/gbm.xml
|
||||
+msgctxt "#13491"
|
||||
+msgid "1080p / 720p (>30hz)"
|
||||
+msgstr ""
|
||||
+
|
||||
+#. String for options 4 of setting with label #13487 "Limit GUI Size"
|
||||
+#: system/settings/gbm.xml
|
||||
+msgctxt "#13492"
|
||||
+msgid "1080p"
|
||||
+msgstr ""
|
||||
+
|
||||
+#. String for options 5 of setting with label #13487 "Limit GUI Size"
|
||||
+#: system/settings/gbm.xml
|
||||
+msgctxt "#13493"
|
||||
+msgid "No limit / 1080p (>30hz)"
|
||||
+msgstr ""
|
||||
+
|
||||
+#empty strings from id 13494 to 13504
|
||||
|
||||
#: system/settings/settings.xml
|
||||
msgctxt "#13505"
|
||||
diff --git a/system/settings/gbm.xml b/system/settings/gbm.xml
|
||||
index c5e4d98e0bef..830576c156a6 100644
|
||||
--- a/system/settings/gbm.xml
|
||||
+++ b/system/settings/gbm.xml
|
||||
@@ -41,6 +41,21 @@
|
||||
<setting id="videoscreen.screen">
|
||||
<visible>false</visible>
|
||||
</setting>
|
||||
+ <setting id="videoscreen.limitguisize" type="integer" label="13487" help="13488">
|
||||
+ <visible>false</visible>
|
||||
+ <level>3</level>
|
||||
+ <default>0</default>
|
||||
+ <constraints>
|
||||
+ <options>
|
||||
+ <option label="13489">0</option> <!-- No limit -->
|
||||
+ <option label="13490">1</option> <!-- 720p -->
|
||||
+ <option label="13491">2</option> <!-- 1080p / 720p (>30hz) -->
|
||||
+ <option label="13492">3</option> <!-- 1080p -->
|
||||
+ <option label="13493">4</option> <!-- No limit / 1080p (>30hz) -->
|
||||
+ </options>
|
||||
+ </constraints>
|
||||
+ <control type="list" format="string" />
|
||||
+ </setting>
|
||||
<setting id="videoscreen.limitedrange" type="boolean" label="36042" help="36359">
|
||||
<level>3</level>
|
||||
<default>false</default>
|
||||
diff --git a/xbmc/windowing/gbm/DRMUtils.cpp b/xbmc/windowing/gbm/DRMUtils.cpp
|
||||
index fceaf770d363..21a6f8f1b926 100644
|
||||
--- a/xbmc/windowing/gbm/DRMUtils.cpp
|
||||
+++ b/xbmc/windowing/gbm/DRMUtils.cpp
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "platform/linux/XTimeUtils.h"
|
||||
+#include "settings/Settings.h"
|
||||
+#include "settings/SettingsComponent.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/StringUtils.h"
|
||||
#include "windowing/GraphicContext.h"
|
||||
@@ -25,6 +27,8 @@
|
||||
|
||||
using namespace KODI::WINDOWING::GBM;
|
||||
|
||||
+const std::string SETTING_VIDEOSCREEN_LIMITGUISIZE = "videoscreen.limitguisize";
|
||||
+
|
||||
CDRMUtils::CDRMUtils()
|
||||
: m_connector(new connector)
|
||||
, m_encoder(new encoder)
|
||||
@@ -731,6 +735,30 @@ RESOLUTION_INFO CDRMUtils::GetResolutionInfo(drmModeModeInfoPtr mode)
|
||||
res.iWidth = res.iScreenWidth;
|
||||
res.iHeight = res.iScreenHeight;
|
||||
|
||||
+ int limit = CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(SETTING_VIDEOSCREEN_LIMITGUISIZE);
|
||||
+ if (limit > 0 && res.iScreenWidth > 1920 && res.iScreenHeight > 1080)
|
||||
+ {
|
||||
+ switch (limit)
|
||||
+ {
|
||||
+ case 1:
|
||||
+ res.iWidth = 1280;
|
||||
+ res.iHeight = 720;
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ res.iWidth = mode->vrefresh > 30 ? 1280 : 1920;
|
||||
+ res.iHeight = mode->vrefresh > 30 ? 720 : 1080;
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ res.iWidth = 1920;
|
||||
+ res.iHeight = 1080;
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ res.iWidth = mode->vrefresh > 30 ? 1920 : res.iScreenWidth;
|
||||
+ res.iHeight = mode->vrefresh > 30 ? 1080 : res.iScreenHeight;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (mode->clock % 5 != 0)
|
||||
res.fRefreshRate = static_cast<float>(mode->vrefresh) * (1000.0f/1001.0f);
|
||||
else
|
1864
projects/Allwinner/patches/linux/0001-hdmi-sound-improvements.patch
Normal file
1864
projects/Allwinner/patches/linux/0001-hdmi-sound-improvements.patch
Normal file
File diff suppressed because it is too large
Load Diff
1824
projects/Allwinner/patches/linux/0002-fixes-from-5.1.patch
Normal file
1824
projects/Allwinner/patches/linux/0002-fixes-from-5.1.patch
Normal file
File diff suppressed because it is too large
Load Diff
676
projects/Allwinner/patches/linux/0003-fixes-from-5.2.patch
Normal file
676
projects/Allwinner/patches/linux/0003-fixes-from-5.2.patch
Normal file
@ -0,0 +1,676 @@
|
||||
From 2495f39ce1fa027aab0c3161c14f074295f81c71 Mon Sep 17 00:00:00 2001
|
||||
From: Dafna Hirschfeld <dafna3@gmail.com>
|
||||
Date: Wed, 6 Mar 2019 16:13:40 -0500
|
||||
Subject: [PATCH] media: vicodec: Introducing stateless fwht defs and structs
|
||||
|
||||
Add structs and definitions needed to implement stateless
|
||||
decoder for fwht and add I/P-frames QP controls to the
|
||||
public api.
|
||||
|
||||
Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
|
||||
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
||||
---
|
||||
drivers/media/platform/vicodec/vicodec-core.c | 41 ++++++-------------
|
||||
drivers/media/v4l2-core/v4l2-ctrls.c | 12 ++++++
|
||||
include/media/fwht-ctrls.h | 31 ++++++++++++++
|
||||
include/media/v4l2-ctrls.h | 5 ++-
|
||||
include/uapi/linux/v4l2-controls.h | 4 ++
|
||||
include/uapi/linux/videodev2.h | 1 +
|
||||
6 files changed, 65 insertions(+), 29 deletions(-)
|
||||
create mode 100644 include/media/fwht-ctrls.h
|
||||
|
||||
diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
|
||||
index b86985babdb1..a3a9d8ac4a33 100644
|
||||
--- a/drivers/media/platform/vicodec/vicodec-core.c
|
||||
+++ b/drivers/media/platform/vicodec/vicodec-core.c
|
||||
@@ -64,6 +64,10 @@ static const struct v4l2_fwht_pixfmt_info pixfmt_fwht = {
|
||||
V4L2_PIX_FMT_FWHT, 0, 3, 1, 1, 1, 1, 1, 0, 1
|
||||
};
|
||||
|
||||
+static const struct v4l2_fwht_pixfmt_info pixfmt_stateless_fwht = {
|
||||
+ V4L2_PIX_FMT_FWHT_STATELESS, 0, 3, 1, 1, 1, 1, 1, 0, 1
|
||||
+};
|
||||
+
|
||||
static void vicodec_dev_release(struct device *dev)
|
||||
{
|
||||
}
|
||||
@@ -1524,10 +1528,6 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
|
||||
return vb2_queue_init(dst_vq);
|
||||
}
|
||||
|
||||
-#define VICODEC_CID_CUSTOM_BASE (V4L2_CID_MPEG_BASE | 0xf000)
|
||||
-#define VICODEC_CID_I_FRAME_QP (VICODEC_CID_CUSTOM_BASE + 0)
|
||||
-#define VICODEC_CID_P_FRAME_QP (VICODEC_CID_CUSTOM_BASE + 1)
|
||||
-
|
||||
static int vicodec_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct vicodec_ctx *ctx = container_of(ctrl->handler,
|
||||
@@ -1537,10 +1537,10 @@ static int vicodec_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
|
||||
ctx->state.gop_size = ctrl->val;
|
||||
return 0;
|
||||
- case VICODEC_CID_I_FRAME_QP:
|
||||
+ case V4L2_CID_FWHT_I_FRAME_QP:
|
||||
ctx->state.i_frame_qp = ctrl->val;
|
||||
return 0;
|
||||
- case VICODEC_CID_P_FRAME_QP:
|
||||
+ case V4L2_CID_FWHT_P_FRAME_QP:
|
||||
ctx->state.p_frame_qp = ctrl->val;
|
||||
return 0;
|
||||
}
|
||||
@@ -1551,26 +1551,9 @@ static const struct v4l2_ctrl_ops vicodec_ctrl_ops = {
|
||||
.s_ctrl = vicodec_s_ctrl,
|
||||
};
|
||||
|
||||
-static const struct v4l2_ctrl_config vicodec_ctrl_i_frame = {
|
||||
- .ops = &vicodec_ctrl_ops,
|
||||
- .id = VICODEC_CID_I_FRAME_QP,
|
||||
- .name = "FWHT I-Frame QP Value",
|
||||
- .type = V4L2_CTRL_TYPE_INTEGER,
|
||||
- .min = 1,
|
||||
- .max = 31,
|
||||
- .def = 20,
|
||||
- .step = 1,
|
||||
-};
|
||||
-
|
||||
-static const struct v4l2_ctrl_config vicodec_ctrl_p_frame = {
|
||||
- .ops = &vicodec_ctrl_ops,
|
||||
- .id = VICODEC_CID_P_FRAME_QP,
|
||||
- .name = "FWHT P-Frame QP Value",
|
||||
- .type = V4L2_CTRL_TYPE_INTEGER,
|
||||
- .min = 1,
|
||||
- .max = 31,
|
||||
- .def = 20,
|
||||
- .step = 1,
|
||||
+static const struct v4l2_ctrl_config vicodec_ctrl_stateless_state = {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_FWHT_PARAMS,
|
||||
+ .elem_size = sizeof(struct v4l2_ctrl_fwht_params),
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1603,8 +1586,10 @@ static int vicodec_open(struct file *file)
|
||||
v4l2_ctrl_handler_init(hdl, 4);
|
||||
v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE,
|
||||
1, 16, 1, 10);
|
||||
- v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_i_frame, NULL);
|
||||
- v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_p_frame, NULL);
|
||||
+ v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_I_FRAME_QP,
|
||||
+ 1, 31, 1, 20);
|
||||
+ v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_P_FRAME_QP,
|
||||
+ 1, 31, 1, 20);
|
||||
if (hdl->error) {
|
||||
rc = hdl->error;
|
||||
v4l2_ctrl_handler_free(hdl);
|
||||
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
index 54d66dbc2a31..aed1c3a06500 100644
|
||||
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
@@ -849,6 +849,9 @@ const char *v4l2_ctrl_get_name(u32 id)
|
||||
case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: return "Force Key Frame";
|
||||
case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: return "MPEG-2 Slice Parameters";
|
||||
case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: return "MPEG-2 Quantization Matrices";
|
||||
+ case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS: return "FWHT Stateless Parameters";
|
||||
+ case V4L2_CID_FWHT_I_FRAME_QP: return "FWHT I-Frame QP Value";
|
||||
+ case V4L2_CID_FWHT_P_FRAME_QP: return "FWHT P-Frame QP Value";
|
||||
|
||||
/* VPX controls */
|
||||
case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: return "VPX Number of Partitions";
|
||||
@@ -1303,6 +1306,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
|
||||
case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION:
|
||||
*type = V4L2_CTRL_TYPE_MPEG2_QUANTIZATION;
|
||||
break;
|
||||
+ case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
|
||||
+ *type = V4L2_CTRL_TYPE_FWHT_PARAMS;
|
||||
+ break;
|
||||
default:
|
||||
*type = V4L2_CTRL_TYPE_INTEGER;
|
||||
break;
|
||||
@@ -1669,6 +1675,9 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
|
||||
case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION:
|
||||
return 0;
|
||||
|
||||
+ case V4L2_CTRL_TYPE_FWHT_PARAMS:
|
||||
+ return 0;
|
||||
+
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -2249,6 +2258,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
|
||||
case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION:
|
||||
elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization);
|
||||
break;
|
||||
+ case V4L2_CTRL_TYPE_FWHT_PARAMS:
|
||||
+ elem_size = sizeof(struct v4l2_ctrl_fwht_params);
|
||||
+ break;
|
||||
default:
|
||||
if (type < V4L2_CTRL_COMPOUND_TYPES)
|
||||
elem_size = sizeof(s32);
|
||||
diff --git a/include/media/fwht-ctrls.h b/include/media/fwht-ctrls.h
|
||||
new file mode 100644
|
||||
index 000000000000..615027410e47
|
||||
--- /dev/null
|
||||
+++ b/include/media/fwht-ctrls.h
|
||||
@@ -0,0 +1,31 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * These are the FWHT state controls for use with stateless FWHT
|
||||
+ * codec drivers.
|
||||
+ *
|
||||
+ * It turns out that these structs are not stable yet and will undergo
|
||||
+ * more changes. So keep them private until they are stable and ready to
|
||||
+ * become part of the official public API.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _FWHT_CTRLS_H_
|
||||
+#define _FWHT_CTRLS_H_
|
||||
+
|
||||
+#define V4L2_CTRL_TYPE_FWHT_PARAMS 0x0105
|
||||
+
|
||||
+#define V4L2_CID_MPEG_VIDEO_FWHT_PARAMS (V4L2_CID_MPEG_BASE + 292)
|
||||
+
|
||||
+struct v4l2_ctrl_fwht_params {
|
||||
+ __u64 backward_ref_ts;
|
||||
+ __u32 version;
|
||||
+ __u32 width;
|
||||
+ __u32 height;
|
||||
+ __u32 flags;
|
||||
+ __u32 colorspace;
|
||||
+ __u32 xfer_func;
|
||||
+ __u32 ycbcr_enc;
|
||||
+ __u32 quantization;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+#endif
|
||||
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
|
||||
index 200f8a66ecaa..bd621cec65a5 100644
|
||||
--- a/include/media/v4l2-ctrls.h
|
||||
+++ b/include/media/v4l2-ctrls.h
|
||||
@@ -23,10 +23,11 @@
|
||||
#include <media/media-request.h>
|
||||
|
||||
/*
|
||||
- * Include the mpeg2 stateless codec compound control definitions.
|
||||
+ * Include the mpeg2 and fwht stateless codec compound control definitions.
|
||||
* This will move to the public headers once this API is fully stable.
|
||||
*/
|
||||
#include <media/mpeg2-ctrls.h>
|
||||
+#include <media/fwht-ctrls.h>
|
||||
|
||||
/* forward references */
|
||||
struct file;
|
||||
@@ -49,6 +50,7 @@ struct poll_table_struct;
|
||||
* @p_char: Pointer to a string.
|
||||
* @p_mpeg2_slice_params: Pointer to a MPEG2 slice parameters structure.
|
||||
* @p_mpeg2_quantization: Pointer to a MPEG2 quantization data structure.
|
||||
+ * @p_fwht_params: Pointer to a FWHT stateless parameters structure.
|
||||
* @p: Pointer to a compound value.
|
||||
*/
|
||||
union v4l2_ctrl_ptr {
|
||||
@@ -60,6 +62,7 @@ union v4l2_ctrl_ptr {
|
||||
char *p_char;
|
||||
struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
|
||||
struct v4l2_ctrl_mpeg2_quantization *p_mpeg2_quantization;
|
||||
+ struct v4l2_ctrl_fwht_params *p_fwht_params;
|
||||
void *p;
|
||||
};
|
||||
|
||||
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
|
||||
index 06479f2fb3ae..78816ec88751 100644
|
||||
--- a/include/uapi/linux/v4l2-controls.h
|
||||
+++ b/include/uapi/linux/v4l2-controls.h
|
||||
@@ -404,6 +404,10 @@ enum v4l2_mpeg_video_multi_slice_mode {
|
||||
#define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE (V4L2_CID_MPEG_BASE+228)
|
||||
#define V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME (V4L2_CID_MPEG_BASE+229)
|
||||
|
||||
+/* CIDs for the FWHT codec as used by the vicodec driver. */
|
||||
+#define V4L2_CID_FWHT_I_FRAME_QP (V4L2_CID_MPEG_BASE + 290)
|
||||
+#define V4L2_CID_FWHT_P_FRAME_QP (V4L2_CID_MPEG_BASE + 291)
|
||||
+
|
||||
#define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300)
|
||||
#define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301)
|
||||
#define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302)
|
||||
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
|
||||
index 1db220da3bcc..496e6453450c 100644
|
||||
--- a/include/uapi/linux/videodev2.h
|
||||
+++ b/include/uapi/linux/videodev2.h
|
||||
@@ -669,6 +669,7 @@ struct v4l2_pix_format {
|
||||
#define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') /* VP9 */
|
||||
#define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC aka H.265 */
|
||||
#define V4L2_PIX_FMT_FWHT v4l2_fourcc('F', 'W', 'H', 'T') /* Fast Walsh Hadamard Transform (vicodec) */
|
||||
+#define V4L2_PIX_FMT_FWHT_STATELESS v4l2_fourcc('S', 'F', 'W', 'H') /* Stateless FWHT (vicodec) */
|
||||
|
||||
/* Vendor-specific formats */
|
||||
#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */
|
||||
--
|
||||
2.21.0
|
||||
|
||||
From 97ed8eab2a0067bee21aa634c938454660e76a38 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Date: Tue, 2 Apr 2019 12:31:49 +0200
|
||||
Subject: [PATCH] staging: add missing SPDX lines to Makefile files
|
||||
|
||||
There are a few remaining drivers/staging/*/Makefile files that do not
|
||||
have SPDX identifiers in them. Add the correct GPL-2.0 identifier to
|
||||
them to make scanning tools happy.
|
||||
|
||||
Reviewed-by: Mukesh Ojha <mojha@codeaurora.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/staging/media/sunxi/Makefile | 1 +
|
||||
drivers/staging/media/sunxi/cedrus/Makefile | 1 +
|
||||
56 files changed, 56 insertions(+)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/Makefile b/drivers/staging/media/sunxi/Makefile
|
||||
index cee2846c3ecf..b87140b0e15f 100644
|
||||
--- a/drivers/staging/media/sunxi/Makefile
|
||||
+++ b/drivers/staging/media/sunxi/Makefile
|
||||
@@ -1 +1,2 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += cedrus/
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/Makefile b/drivers/staging/media/sunxi/cedrus/Makefile
|
||||
index e9dc68b7bcb6..808842f0119e 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/Makefile
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/Makefile
|
||||
@@ -1,3 +1,4 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
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
|
||||
--
|
||||
2.21.0
|
||||
|
||||
From 6ece1909256d809df8cf975a62bddd565d03eb1a Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Thu, 28 Feb 2019 18:57:48 +0100
|
||||
Subject: [PATCH 1/3] clk: sunxi-ng: Allow DE clock to set parent rate
|
||||
|
||||
DE2/DE3 mixers have to run at specific frequency in order to work
|
||||
optimally. This wasn't actually possible for some SoCs because "de"
|
||||
clock wasn't allowed to adjust parent rate.
|
||||
|
||||
Add CLK_SET_RATE_PARENT flag to all "de" clocks which didn't have it
|
||||
yet.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 3 ++-
|
||||
drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 2 +-
|
||||
drivers/clk/sunxi-ng/ccu-sun8i-v3s.c | 3 ++-
|
||||
3 files changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
|
||||
index 932836d26e2b..be0deee70182 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
|
||||
@@ -531,7 +531,8 @@ static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "dram",
|
||||
|
||||
static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" };
|
||||
static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
|
||||
- 0x104, 0, 4, 24, 3, BIT(31), 0);
|
||||
+ 0x104, 0, 4, 24, 3, BIT(31),
|
||||
+ CLK_SET_RATE_PARENT);
|
||||
|
||||
static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" };
|
||||
static const u8 tcon0_table[] = { 0, 2, };
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
index 139e8389615c..daf78966555e 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
|
||||
@@ -266,7 +266,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, 0x600,
|
||||
0, 4, /* M */
|
||||
24, 1, /* mux */
|
||||
BIT(31), /* gate */
|
||||
- 0);
|
||||
+ CLK_SET_RATE_PARENT);
|
||||
|
||||
static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "psi-ahb1-ahb2",
|
||||
0x60c, BIT(0), 0);
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
|
||||
index 621b1cd996db..ee170bf21cdf 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
|
||||
@@ -325,7 +325,8 @@ static SUNXI_CCU_GATE(dram_ohci_clk, "dram-ohci", "dram",
|
||||
|
||||
static const char * const de_parents[] = { "pll-video", "pll-periph0" };
|
||||
static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
|
||||
- 0x104, 0, 4, 24, 2, BIT(31), 0);
|
||||
+ 0x104, 0, 4, 24, 2, BIT(31),
|
||||
+ CLK_SET_RATE_PARENT);
|
||||
|
||||
static const char * const tcon_parents[] = { "pll-video" };
|
||||
static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents,
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 3622c17fc40031cd2ca7b4030b83e6fad0c4e127 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Mon, 24 Dec 2018 18:11:56 +0100
|
||||
Subject: [PATCH 2/3] drm/sun4i: Add VI scaler line size quirk for DE2/DE3
|
||||
|
||||
While all RGB scalers have maximum line size of 2048, some YUV scalers
|
||||
have maximum line size of 2048 and some have line size of 4096.
|
||||
|
||||
Since there is no rule for that, add a quirk.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/gpu/drm/sun4i/sun8i_mixer.c | 9 +++++++++
|
||||
drivers/gpu/drm/sun4i/sun8i_mixer.h | 2 ++
|
||||
2 files changed, 11 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
|
||||
index 44a9ba7d8433..e46edacb7ab4 100644
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
|
||||
@@ -554,6 +554,7 @@ static int sun8i_mixer_remove(struct platform_device *pdev)
|
||||
static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = {
|
||||
.ccsc = 0,
|
||||
.scaler_mask = 0xf,
|
||||
+ .scanline_yuv = 2048,
|
||||
.ui_num = 3,
|
||||
.vi_num = 1,
|
||||
};
|
||||
@@ -561,6 +562,7 @@ static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = {
|
||||
static const struct sun8i_mixer_cfg sun8i_a83t_mixer1_cfg = {
|
||||
.ccsc = 1,
|
||||
.scaler_mask = 0x3,
|
||||
+ .scanline_yuv = 2048,
|
||||
.ui_num = 1,
|
||||
.vi_num = 1,
|
||||
};
|
||||
@@ -569,6 +571,7 @@ static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = {
|
||||
.ccsc = 0,
|
||||
.mod_rate = 432000000,
|
||||
.scaler_mask = 0xf,
|
||||
+ .scanline_yuv = 2048,
|
||||
.ui_num = 3,
|
||||
.vi_num = 1,
|
||||
};
|
||||
@@ -577,6 +580,7 @@ static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg = {
|
||||
.ccsc = 0,
|
||||
.mod_rate = 297000000,
|
||||
.scaler_mask = 0xf,
|
||||
+ .scanline_yuv = 2048,
|
||||
.ui_num = 3,
|
||||
.vi_num = 1,
|
||||
};
|
||||
@@ -585,6 +589,7 @@ static const struct sun8i_mixer_cfg sun8i_r40_mixer1_cfg = {
|
||||
.ccsc = 1,
|
||||
.mod_rate = 297000000,
|
||||
.scaler_mask = 0x3,
|
||||
+ .scanline_yuv = 2048,
|
||||
.ui_num = 1,
|
||||
.vi_num = 1,
|
||||
};
|
||||
@@ -593,6 +598,7 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
|
||||
.vi_num = 2,
|
||||
.ui_num = 1,
|
||||
.scaler_mask = 0x3,
|
||||
+ .scanline_yuv = 2048,
|
||||
.ccsc = 0,
|
||||
.mod_rate = 150000000,
|
||||
};
|
||||
@@ -601,6 +607,7 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer0_cfg = {
|
||||
.ccsc = 0,
|
||||
.mod_rate = 297000000,
|
||||
.scaler_mask = 0xf,
|
||||
+ .scanline_yuv = 4096,
|
||||
.ui_num = 3,
|
||||
.vi_num = 1,
|
||||
};
|
||||
@@ -609,6 +616,7 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = {
|
||||
.ccsc = 1,
|
||||
.mod_rate = 297000000,
|
||||
.scaler_mask = 0x3,
|
||||
+ .scanline_yuv = 2048,
|
||||
.ui_num = 1,
|
||||
.vi_num = 1,
|
||||
};
|
||||
@@ -618,6 +626,7 @@ static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = {
|
||||
.is_de3 = true,
|
||||
.mod_rate = 600000000,
|
||||
.scaler_mask = 0xf,
|
||||
+ .scanline_yuv = 4096,
|
||||
.ui_num = 3,
|
||||
.vi_num = 1,
|
||||
};
|
||||
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
||||
index 913d14ce68b0..80e084caa084 100644
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
||||
@@ -159,6 +159,7 @@ struct de2_fmt_info {
|
||||
* @mod_rate: module clock rate that needs to be set in order to have
|
||||
* a functional block.
|
||||
* @is_de3: true, if this is next gen display engine 3.0, false otherwise.
|
||||
+ * @scaline_yuv: size of a scanline for VI scaler for YUV formats.
|
||||
*/
|
||||
struct sun8i_mixer_cfg {
|
||||
int vi_num;
|
||||
@@ -167,6 +168,7 @@ struct sun8i_mixer_cfg {
|
||||
int ccsc;
|
||||
unsigned long mod_rate;
|
||||
unsigned int is_de3 : 1;
|
||||
+ unsigned int scanline_yuv;
|
||||
};
|
||||
|
||||
struct sun8i_mixer {
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 6d1be62144db6bebfdbcb8c50a11ac428dcdc741 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Mon, 24 Dec 2018 18:16:50 +0100
|
||||
Subject: [PATCH 3/3] drm/sun4i: Improve VI scaling for DE2/DE3
|
||||
|
||||
VI planes support coarse scaling which helps to overcome VI scaler
|
||||
limitations. While exact working of coarse scaling isn't known, it seems
|
||||
that it just skips programmed amount of rows and columns. This is
|
||||
especially useful for downscaling very big planes (4K down to 1080p).
|
||||
|
||||
Horizontal coarse scaling is currently used to fit one line to VI scaler
|
||||
buffer.
|
||||
|
||||
Vertical coarse scaling is used to assure that VI scaler is actually
|
||||
capable of processing framebuffer in one frame time.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 54 ++++++++++++++++++++++++--
|
||||
drivers/gpu/drm/sun4i/sun8i_vi_layer.h | 11 ++++++
|
||||
2 files changed, 62 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
|
||||
index 87be898f9b7a..ce42560aa9df 100644
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
|
||||
@@ -80,6 +80,8 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
|
||||
u32 bld_base, ch_base;
|
||||
u32 outsize, insize;
|
||||
u32 hphase, vphase;
|
||||
+ u32 hn = 0, hm = 0;
|
||||
+ u32 vn = 0, vm = 0;
|
||||
bool subsampled;
|
||||
|
||||
DRM_DEBUG_DRIVER("Updating VI channel %d overlay %d\n",
|
||||
@@ -137,12 +139,41 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
|
||||
subsampled = format->hsub > 1 || format->vsub > 1;
|
||||
|
||||
if (insize != outsize || subsampled || hphase || vphase) {
|
||||
- u32 hscale, vscale;
|
||||
+ unsigned int scanline, required;
|
||||
+ struct drm_display_mode *mode;
|
||||
+ u32 hscale, vscale, fps;
|
||||
+ u64 ability;
|
||||
|
||||
DRM_DEBUG_DRIVER("HW scaling is enabled\n");
|
||||
|
||||
- hscale = state->src_w / state->crtc_w;
|
||||
- vscale = state->src_h / state->crtc_h;
|
||||
+ mode = &plane->state->crtc->state->mode;
|
||||
+ fps = (mode->clock * 1000) / (mode->vtotal * mode->htotal);
|
||||
+ ability = clk_get_rate(mixer->mod_clk);
|
||||
+ /* BSP algorithm assumes 80% efficiency of VI scaler unit */
|
||||
+ ability *= 80;
|
||||
+ do_div(ability, mode->vdisplay * fps * max(src_w, dst_w));
|
||||
+
|
||||
+ required = src_h * 100 / dst_h;
|
||||
+
|
||||
+ if (ability < required) {
|
||||
+ DRM_DEBUG_DRIVER("Using vertical coarse scaling\n");
|
||||
+ vm = src_h;
|
||||
+ vn = (u32)ability * dst_h / 100;
|
||||
+ src_h = vn;
|
||||
+ }
|
||||
+
|
||||
+ /* it seems that every RGB scaler has buffer for 2048 pixels */
|
||||
+ scanline = subsampled ? mixer->cfg->scanline_yuv : 2048;
|
||||
+
|
||||
+ if (src_w > scanline) {
|
||||
+ DRM_DEBUG_DRIVER("Using horizontal coarse scaling\n");
|
||||
+ hm = src_w;
|
||||
+ hn = scanline;
|
||||
+ src_w = hn;
|
||||
+ }
|
||||
+
|
||||
+ hscale = (src_w << 16) / dst_w;
|
||||
+ vscale = (src_h << 16) / dst_h;
|
||||
|
||||
sun8i_vi_scaler_setup(mixer, channel, src_w, src_h, dst_w,
|
||||
dst_h, hscale, vscale, hphase, vphase,
|
||||
@@ -153,6 +184,23 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
|
||||
sun8i_vi_scaler_enable(mixer, channel, false);
|
||||
}
|
||||
|
||||
+ regmap_write(mixer->engine.regs,
|
||||
+ SUN8I_MIXER_CHAN_VI_HDS_Y(ch_base),
|
||||
+ SUN8I_MIXER_CHAN_VI_DS_N(hn) |
|
||||
+ SUN8I_MIXER_CHAN_VI_DS_M(hm));
|
||||
+ regmap_write(mixer->engine.regs,
|
||||
+ SUN8I_MIXER_CHAN_VI_HDS_UV(ch_base),
|
||||
+ SUN8I_MIXER_CHAN_VI_DS_N(hn) |
|
||||
+ SUN8I_MIXER_CHAN_VI_DS_M(hm));
|
||||
+ regmap_write(mixer->engine.regs,
|
||||
+ SUN8I_MIXER_CHAN_VI_VDS_Y(ch_base),
|
||||
+ SUN8I_MIXER_CHAN_VI_DS_N(vn) |
|
||||
+ SUN8I_MIXER_CHAN_VI_DS_M(vm));
|
||||
+ regmap_write(mixer->engine.regs,
|
||||
+ SUN8I_MIXER_CHAN_VI_VDS_UV(ch_base),
|
||||
+ SUN8I_MIXER_CHAN_VI_DS_N(vn) |
|
||||
+ SUN8I_MIXER_CHAN_VI_DS_M(vm));
|
||||
+
|
||||
/* Set base coordinates */
|
||||
DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n",
|
||||
state->dst.x1, state->dst.y1);
|
||||
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
|
||||
index 8a5e6d01c85d..a223a4839f45 100644
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
|
||||
@@ -24,6 +24,14 @@
|
||||
((base) + 0x30 * (layer) + 0x18 + 4 * (plane))
|
||||
#define SUN8I_MIXER_CHAN_VI_OVL_SIZE(base) \
|
||||
((base) + 0xe8)
|
||||
+#define SUN8I_MIXER_CHAN_VI_HDS_Y(base) \
|
||||
+ ((base) + 0xf0)
|
||||
+#define SUN8I_MIXER_CHAN_VI_HDS_UV(base) \
|
||||
+ ((base) + 0xf4)
|
||||
+#define SUN8I_MIXER_CHAN_VI_VDS_Y(base) \
|
||||
+ ((base) + 0xf8)
|
||||
+#define SUN8I_MIXER_CHAN_VI_VDS_UV(base) \
|
||||
+ ((base) + 0xfc)
|
||||
|
||||
#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN BIT(0)
|
||||
/* RGB mode should be set for RGB formats and cleared for YCbCr */
|
||||
@@ -33,6 +41,9 @@
|
||||
#define SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK GENMASK(31, 24)
|
||||
#define SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(x) ((x) << 24)
|
||||
|
||||
+#define SUN8I_MIXER_CHAN_VI_DS_N(x) ((x) << 16)
|
||||
+#define SUN8I_MIXER_CHAN_VI_DS_M(x) ((x) << 0)
|
||||
+
|
||||
struct sun8i_mixer;
|
||||
|
||||
struct sun8i_vi_layer {
|
||||
--
|
||||
2.20.1
|
||||
|
||||
From 05f640b80bb6797ec11c328d16e9905884653f98 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sun, 7 Apr 2019 20:36:40 +0200
|
||||
Subject: [PATCH] media: cedrus: Fix initialization order
|
||||
|
||||
Currently, MEDIA_IOC_G_TOPOLOGY ioctl on cedrus fails due to incorrect
|
||||
initialization order. Fix that by moving video_register_device() before
|
||||
v4l2_m2m_register_media_controller() and while at it, fix error path.
|
||||
|
||||
Reported-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.c | 24 ++++++++++-----------
|
||||
1 file changed, 12 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
index b98add3cdedd..d0429c0e6b6b 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
@@ -300,7 +300,7 @@ static int cedrus_probe(struct platform_device *pdev)
|
||||
"Failed to initialize V4L2 M2M device\n");
|
||||
ret = PTR_ERR(dev->m2m_dev);
|
||||
|
||||
- goto err_video;
|
||||
+ goto err_v4l2;
|
||||
}
|
||||
|
||||
dev->mdev.dev = &pdev->dev;
|
||||
@@ -310,23 +310,23 @@ static int cedrus_probe(struct platform_device *pdev)
|
||||
dev->mdev.ops = &cedrus_m2m_media_ops;
|
||||
dev->v4l2_dev.mdev = &dev->mdev;
|
||||
|
||||
- ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd,
|
||||
- MEDIA_ENT_F_PROC_VIDEO_DECODER);
|
||||
- if (ret) {
|
||||
- v4l2_err(&dev->v4l2_dev,
|
||||
- "Failed to initialize V4L2 M2M media controller\n");
|
||||
- goto err_m2m;
|
||||
- }
|
||||
-
|
||||
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
|
||||
if (ret) {
|
||||
v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
|
||||
- goto err_v4l2;
|
||||
+ goto err_m2m;
|
||||
}
|
||||
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
"Device registered as /dev/video%d\n", vfd->num);
|
||||
|
||||
+ ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd,
|
||||
+ MEDIA_ENT_F_PROC_VIDEO_DECODER);
|
||||
+ if (ret) {
|
||||
+ v4l2_err(&dev->v4l2_dev,
|
||||
+ "Failed to initialize V4L2 M2M media controller\n");
|
||||
+ goto err_video;
|
||||
+ }
|
||||
+
|
||||
ret = media_device_register(&dev->mdev);
|
||||
if (ret) {
|
||||
v4l2_err(&dev->v4l2_dev, "Failed to register media device\n");
|
||||
@@ -339,10 +339,10 @@ static int cedrus_probe(struct platform_device *pdev)
|
||||
|
||||
err_m2m_mc:
|
||||
v4l2_m2m_unregister_media_controller(dev->m2m_dev);
|
||||
-err_m2m:
|
||||
- v4l2_m2m_release(dev->m2m_dev);
|
||||
err_video:
|
||||
video_unregister_device(&dev->vfd);
|
||||
+err_m2m:
|
||||
+ v4l2_m2m_release(dev->m2m_dev);
|
||||
err_v4l2:
|
||||
v4l2_device_unregister(&dev->v4l2_dev);
|
||||
|
||||
--
|
||||
2.21.0
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
133
projects/Allwinner/patches/linux/0007-H264-improvements.patch
Normal file
133
projects/Allwinner/patches/linux/0007-H264-improvements.patch
Normal file
@ -0,0 +1,133 @@
|
||||
From e41186f41a546d1c60797f090001da969f5eda5a Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Thu, 14 Feb 2019 22:50:12 +0100
|
||||
Subject: [PATCH] cedrus: Improve H264
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
.../staging/media/sunxi/cedrus/cedrus_h264.c | 69 +++++++++++--------
|
||||
1 file changed, 41 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
index a5c5f13ffecb..405545947b85 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
@@ -38,7 +38,7 @@ struct cedrus_h264_sram_ref_pic {
|
||||
#define CEDRUS_H264_FRAME_NUM 18
|
||||
|
||||
#define CEDRUS_NEIGHBOR_INFO_BUF_SIZE (16 * SZ_1K)
|
||||
-#define CEDRUS_PIC_INFO_BUF_SIZE (128 * SZ_1K)
|
||||
+#define CEDRUS_PIC_INFO_BUF_SIZE (336 * SZ_1K)
|
||||
|
||||
static void cedrus_h264_write_sram(struct cedrus_dev *dev,
|
||||
enum cedrus_h264_sram_off off,
|
||||
@@ -101,7 +101,7 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
unsigned long used_dpbs = 0;
|
||||
unsigned int position;
|
||||
- unsigned int output = 0;
|
||||
+ int output = -1;
|
||||
unsigned int i;
|
||||
|
||||
memset(pic_list, 0, sizeof(pic_list));
|
||||
@@ -126,6 +126,11 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
||||
position = cedrus_buf->codec.h264.position;
|
||||
used_dpbs |= BIT(position);
|
||||
|
||||
+ if (run->dst->vb2_buf.timestamp == dpb->reference_ts) {
|
||||
+ output = position;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
|
||||
continue;
|
||||
|
||||
@@ -133,13 +138,11 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
||||
dpb->top_field_order_cnt,
|
||||
dpb->bottom_field_order_cnt,
|
||||
&pic_list[position]);
|
||||
-
|
||||
- output = max(position, output);
|
||||
}
|
||||
|
||||
- position = find_next_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM,
|
||||
- output);
|
||||
- if (position >= CEDRUS_H264_FRAME_NUM)
|
||||
+ if (output >= 0)
|
||||
+ position = output;
|
||||
+ else
|
||||
position = find_first_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM);
|
||||
|
||||
output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
|
||||
@@ -165,6 +168,10 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
||||
|
||||
#define CEDRUS_MAX_REF_IDX 32
|
||||
|
||||
+#define REF_IDX(v) (v & GENMASK(5, 0))
|
||||
+#define REF_FIELD(v) (v >> 6)
|
||||
+#define REF_FIELD_BOTTOM 2
|
||||
+
|
||||
static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
|
||||
struct cedrus_run *run,
|
||||
const u8 *ref_list, u8 num_ref,
|
||||
@@ -187,7 +194,7 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
|
||||
int buf_idx;
|
||||
u8 dpb_idx;
|
||||
|
||||
- dpb_idx = ref_list[i];
|
||||
+ dpb_idx = REF_IDX(ref_list[i]);
|
||||
dpb = &decode->dpb[dpb_idx];
|
||||
|
||||
if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
|
||||
@@ -206,7 +213,8 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
|
||||
position = cedrus_buf->codec.h264.position;
|
||||
|
||||
sram_array[i] |= position << 1;
|
||||
- if (ref_buf->field == V4L2_FIELD_BOTTOM)
|
||||
+ /* set bottom field flag when reference is to bottom field */
|
||||
+ if (REF_FIELD(ref_list[i]) == REF_FIELD_BOTTOM)
|
||||
sram_array[i] |= BIT(0);
|
||||
}
|
||||
|
||||
@@ -309,6 +317,8 @@ static void cedrus_set_params(struct cedrus_ctx *ctx,
|
||||
dma_addr_t src_buf_addr;
|
||||
u32 offset = slice->header_bit_size;
|
||||
u32 len = (slice->size * 8) - offset;
|
||||
+ unsigned int pic_width_in_mbs;
|
||||
+ bool mbaff_picture;
|
||||
u32 reg;
|
||||
|
||||
cedrus_write(dev, VE_H264_VLD_LEN, len);
|
||||
@@ -378,12 +387,19 @@ static void cedrus_set_params(struct cedrus_ctx *ctx,
|
||||
reg |= VE_H264_SPS_DIRECT_8X8_INFERENCE;
|
||||
cedrus_write(dev, VE_H264_SPS, reg);
|
||||
|
||||
+ mbaff_picture = !(slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) &&
|
||||
+ (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
|
||||
+ pic_width_in_mbs = sps->pic_width_in_mbs_minus1 + 1;
|
||||
+
|
||||
// slice parameters
|
||||
reg = 0;
|
||||
+ reg |= ((slice->first_mb_in_slice % pic_width_in_mbs) & 0xff) << 24;
|
||||
+ reg |= (((slice->first_mb_in_slice / pic_width_in_mbs) * (mbaff_picture ? 2 : 1)) & 0xff) << 16;
|
||||
reg |= decode->nal_ref_idc ? BIT(12) : 0;
|
||||
reg |= (slice->slice_type & 0xf) << 8;
|
||||
reg |= slice->cabac_init_idc & 0x3;
|
||||
- reg |= VE_H264_SHS_FIRST_SLICE_IN_PIC;
|
||||
+ if (decode->num_slices == 1)
|
||||
+ reg |= VE_H264_SHS_FIRST_SLICE_IN_PIC;
|
||||
if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)
|
||||
reg |= VE_H264_SHS_FIELD_PIC;
|
||||
if (slice->flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)
|
||||
@@ -531,7 +541,7 @@ static int cedrus_h264_start(struct cedrus_ctx *ctx)
|
||||
* we need to work on.
|
||||
*/
|
||||
field_size = field_size * 2;
|
||||
- ctx->codec.h264.mv_col_buf_field_size = field_size;
|
||||
+ ctx->codec.h264.mv_col_buf_field_size = ALIGN(field_size, 1024);
|
||||
|
||||
mv_col_size = field_size * 2 * CEDRUS_H264_FRAME_NUM;
|
||||
ctx->codec.h264.mv_col_buf_size = mv_col_size;
|
||||
--
|
||||
2.20.1
|
||||
|
703
projects/Allwinner/patches/linux/0008-HEVC-improvements.patch
Normal file
703
projects/Allwinner/patches/linux/0008-HEVC-improvements.patch
Normal file
@ -0,0 +1,703 @@
|
||||
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
index 3bab9d4e3304..a14762dff91d 100644
|
||||
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
@@ -916,6 +916,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";
|
||||
+ case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX: return "HEVC Scaling Matrix";
|
||||
|
||||
/* CAMERA controls */
|
||||
/* Keep the order of the 'case's the same as in v4l2-controls.h! */
|
||||
@@ -1332,6 +1333,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:
|
||||
*type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS;
|
||||
break;
|
||||
+ case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX:
|
||||
+ *type = V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX;
|
||||
+ break;
|
||||
default:
|
||||
*type = V4L2_CTRL_TYPE_INTEGER;
|
||||
break;
|
||||
@@ -1708,6 +1712,7 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
|
||||
case V4L2_CTRL_TYPE_HEVC_SPS:
|
||||
case V4L2_CTRL_TYPE_HEVC_PPS:
|
||||
case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
|
||||
+ case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
@@ -2314,6 +2319,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
|
||||
case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
|
||||
elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params);
|
||||
break;
|
||||
+ case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
|
||||
+ elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix);
|
||||
+ break;
|
||||
default:
|
||||
if (type < V4L2_CTRL_COMPOUND_TYPES)
|
||||
elem_size = sizeof(s32);
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
index a713630ce7ba..3040f483e0a2 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
@@ -87,6 +87,12 @@ static const struct cedrus_control cedrus_controls[] = {
|
||||
.codec = CEDRUS_CODEC_H265,
|
||||
.required = true,
|
||||
},
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX,
|
||||
+ .elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix),
|
||||
+ .codec = CEDRUS_CODEC_H265,
|
||||
+ .required = true,
|
||||
+ },
|
||||
};
|
||||
|
||||
#define CEDRUS_CONTROLS_COUNT ARRAY_SIZE(cedrus_controls)
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
index b5d083812bea..deb9fa1de97c 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -72,6 +72,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 {
|
||||
@@ -88,6 +89,10 @@ struct cedrus_run {
|
||||
struct cedrus_buffer {
|
||||
struct v4l2_m2m_buffer m2m_buf;
|
||||
|
||||
+ void *mv_col_buf;
|
||||
+ dma_addr_t mv_col_buf_dma;
|
||||
+ ssize_t mv_col_buf_size;
|
||||
+
|
||||
union {
|
||||
struct {
|
||||
unsigned int position;
|
||||
@@ -121,12 +126,10 @@ struct cedrus_ctx {
|
||||
dma_addr_t neighbor_info_buf_dma;
|
||||
} h264;
|
||||
struct {
|
||||
- void *mv_col_buf;
|
||||
- dma_addr_t mv_col_buf_addr;
|
||||
- ssize_t mv_col_buf_size;
|
||||
- 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;
|
||||
};
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
|
||||
index c50397f8692f..80c6d920142d 100644
|
||||
--- 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)
|
||||
V4L2_CID_MPEG_VIDEO_HEVC_PPS);
|
||||
run.h265.slice_params = cedrus_find_control_data(ctx,
|
||||
V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS);
|
||||
+ run.h265.scaling_matrix = cedrus_find_control_data(ctx,
|
||||
+ V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX);
|
||||
break;
|
||||
|
||||
default:
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
index f1c3665e95ab..2cc36d69548e 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
@@ -77,24 +77,25 @@ static void cedrus_h265_sram_write_offset(struct cedrus_dev *dev, u32 offset)
|
||||
cedrus_write(dev, VE_DEC_H265_SRAM_OFFSET, offset);
|
||||
}
|
||||
|
||||
-static void cedrus_h265_sram_write_data(struct cedrus_dev *dev, void *data,
|
||||
+static void cedrus_h265_sram_write_data(struct cedrus_dev *dev, const void *data,
|
||||
unsigned int size)
|
||||
{
|
||||
- u32 *word = data;
|
||||
+ size_t count = DIV_ROUND_UP(size, 4);
|
||||
+ const u32 *word = data;
|
||||
|
||||
- while (size >= sizeof(u32)) {
|
||||
+ while (count--)
|
||||
cedrus_write(dev, VE_DEC_H265_SRAM_DATA, *word++);
|
||||
- size -= sizeof(u32);
|
||||
- }
|
||||
}
|
||||
|
||||
static inline dma_addr_t
|
||||
cedrus_h265_frame_info_mv_col_buf_addr(struct cedrus_ctx *ctx,
|
||||
- unsigned int index, unsigned int field)
|
||||
+ unsigned int index)
|
||||
{
|
||||
- return ctx->codec.h265.mv_col_buf_addr + index *
|
||||
- ctx->codec.h265.mv_col_buf_unit_size +
|
||||
- field * ctx->codec.h265.mv_col_buf_unit_size / 2;
|
||||
+ struct cedrus_buffer *cedrus_buf;
|
||||
+
|
||||
+ cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[index]);
|
||||
+
|
||||
+ return cedrus_buf->mv_col_buf_dma;
|
||||
}
|
||||
|
||||
static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
|
||||
@@ -107,9 +108,8 @@ static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
|
||||
dma_addr_t dst_luma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 0);
|
||||
dma_addr_t dst_chroma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 1);
|
||||
dma_addr_t mv_col_buf_addr[2] = {
|
||||
- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index, 0),
|
||||
- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index,
|
||||
- field_pic ? 1 : 0)
|
||||
+ cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index),
|
||||
+ cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index)
|
||||
};
|
||||
u32 offset = VE_DEC_H265_SRAM_OFFSET_FRAME_INFO +
|
||||
VE_DEC_H265_SRAM_OFFSET_FRAME_INFO_UNIT * index;
|
||||
@@ -157,28 +157,24 @@ static void cedrus_h265_ref_pic_list_write(struct cedrus_dev *dev,
|
||||
u8 num_ref_idx_active,
|
||||
u32 sram_offset)
|
||||
{
|
||||
+ u8 sram_array[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
unsigned int i;
|
||||
- u32 word = 0;
|
||||
+
|
||||
+ memset(sram_array, 0, sizeof(sram_array));
|
||||
+ num_ref_idx_active = min(num_ref_idx_active,
|
||||
+ (u8)V4L2_HEVC_DPB_ENTRIES_NUM_MAX);
|
||||
|
||||
cedrus_h265_sram_write_offset(dev, sram_offset);
|
||||
|
||||
for (i = 0; i < num_ref_idx_active; i++) {
|
||||
- unsigned int shift = (i % 4) * 8;
|
||||
unsigned int index = list[i];
|
||||
- u8 value = list[i];
|
||||
|
||||
+ sram_array[i] = index;
|
||||
if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
|
||||
- value |= VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF;
|
||||
-
|
||||
- /* Each SRAM word gathers up to 4 references. */
|
||||
- word |= value << shift;
|
||||
-
|
||||
- /* Write the word to SRAM and clear it for the next batch. */
|
||||
- if ((i % 4) == 3 || i == (num_ref_idx_active - 1)) {
|
||||
- cedrus_h265_sram_write_data(dev, &word, sizeof(word));
|
||||
- word = 0;
|
||||
- }
|
||||
+ sram_array[i] |= VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF;
|
||||
}
|
||||
+
|
||||
+ cedrus_h265_sram_write_data(dev, &sram_array, num_ref_idx_active);
|
||||
}
|
||||
|
||||
static void cedrus_h265_pred_weight_write(struct cedrus_dev *dev,
|
||||
@@ -219,6 +215,105 @@ static void cedrus_h265_pred_weight_write(struct cedrus_dev *dev,
|
||||
}
|
||||
}
|
||||
|
||||
+static void cedrus_h265_write_scaling_list(struct cedrus_ctx *ctx,
|
||||
+ struct cedrus_run *run)
|
||||
+{
|
||||
+ const struct v4l2_ctrl_hevc_scaling_matrix *scaling;
|
||||
+ struct cedrus_dev *dev = ctx->dev;
|
||||
+
|
||||
+ scaling = run->h265.scaling_matrix;
|
||||
+
|
||||
+ cedrus_write(dev, VE_DEC_H265_SCALING_LIST_DC_COEF0,
|
||||
+ (scaling->scaling_list_dc_coef_32x32[1] << 24) |
|
||||
+ (scaling->scaling_list_dc_coef_32x32[0] << 16) |
|
||||
+ (scaling->scaling_list_dc_coef_16x16[1] << 8) |
|
||||
+ (scaling->scaling_list_dc_coef_16x16[0] << 0));
|
||||
+
|
||||
+ cedrus_write(dev, VE_DEC_H265_SCALING_LIST_DC_COEF1,
|
||||
+ (scaling->scaling_list_dc_coef_16x16[5] << 24) |
|
||||
+ (scaling->scaling_list_dc_coef_16x16[4] << 16) |
|
||||
+ (scaling->scaling_list_dc_coef_16x16[3] << 8) |
|
||||
+ (scaling->scaling_list_dc_coef_16x16[2] << 0));
|
||||
+
|
||||
+ cedrus_h265_sram_write_offset(dev, VE_DEC_H265_SRAM_OFFSET_SCALING_LISTS_8x8);
|
||||
+ cedrus_h265_sram_write_data(dev, scaling->scaling_list_8x8,
|
||||
+ sizeof(scaling->scaling_list_8x8));
|
||||
+
|
||||
+ cedrus_h265_sram_write_offset(dev, VE_DEC_H265_SRAM_OFFSET_SCALING_LISTS_32x32);
|
||||
+ cedrus_h265_sram_write_data(dev, scaling->scaling_list_32x32,
|
||||
+ sizeof(scaling->scaling_list_32x32));
|
||||
+
|
||||
+ cedrus_h265_sram_write_offset(dev, VE_DEC_H265_SRAM_OFFSET_SCALING_LISTS_16x16);
|
||||
+ cedrus_h265_sram_write_data(dev, scaling->scaling_list_16x16,
|
||||
+ sizeof(scaling->scaling_list_16x16));
|
||||
+
|
||||
+ cedrus_h265_sram_write_offset(dev, VE_DEC_H265_SRAM_OFFSET_SCALING_LISTS_4x4);
|
||||
+ cedrus_h265_sram_write_data(dev, scaling->scaling_list_4x4,
|
||||
+ sizeof(scaling->scaling_list_4x4));
|
||||
+}
|
||||
+
|
||||
+static void write_entry_point_list(struct cedrus_ctx *ctx,
|
||||
+ struct cedrus_run *run)
|
||||
+{
|
||||
+ const struct v4l2_ctrl_hevc_slice_params *slice_params;
|
||||
+ unsigned int ctb_size_luma, width_in_ctb_luma;
|
||||
+ unsigned int log2_max_luma_coding_block_size;
|
||||
+ const struct v4l2_ctrl_hevc_pps *pps;
|
||||
+ const struct v4l2_ctrl_hevc_sps *sps;
|
||||
+ struct cedrus_dev *dev = ctx->dev;
|
||||
+ uint32_t *entry_points;
|
||||
+ int i, x, tx, y, ty;
|
||||
+
|
||||
+ pps = run->h265.pps;
|
||||
+ sps = run->h265.sps;
|
||||
+ slice_params = run->h265.slice_params;
|
||||
+
|
||||
+ log2_max_luma_coding_block_size =
|
||||
+ sps->log2_min_luma_coding_block_size_minus3 + 3 +
|
||||
+ sps->log2_diff_max_min_luma_coding_block_size;
|
||||
+ ctb_size_luma = 1 << log2_max_luma_coding_block_size;
|
||||
+ width_in_ctb_luma = DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_luma);
|
||||
+
|
||||
+ for (x = 0, tx = 0; tx < pps->num_tile_columns_minus1 + 1; tx++) {
|
||||
+ if (x + pps->column_width_minus1[tx] + 1 > (slice_params->slice_segment_addr % width_in_ctb_luma))
|
||||
+ break;
|
||||
+
|
||||
+ x += pps->column_width_minus1[tx] + 1;
|
||||
+ }
|
||||
+
|
||||
+ for (y = 0, ty = 0; ty < pps->num_tile_rows_minus1 + 1; ty++) {
|
||||
+ if (y + pps->row_height_minus1[ty] + 1 > (slice_params->slice_segment_addr / width_in_ctb_luma))
|
||||
+ break;
|
||||
+
|
||||
+ y += pps->row_height_minus1[ty] + 1;
|
||||
+ }
|
||||
+
|
||||
+ cedrus_write(dev, VE_DEC_H265_TILE_START_CTB, (y << 16) | (x << 0));
|
||||
+ cedrus_write(dev, VE_DEC_H265_TILE_END_CTB,
|
||||
+ ((y + pps->row_height_minus1[ty]) << 16) |
|
||||
+ ((x + pps->column_width_minus1[tx]) << 0));
|
||||
+
|
||||
+ entry_points = ctx->codec.h265.entry_points_buf;
|
||||
+ if (pps->entropy_coding_sync_enabled_flag) {
|
||||
+ for (i = 0; i < slice_params->num_entry_point_offsets; i++)
|
||||
+ entry_points[i] = slice_params->entry_point_offset_minus1[i] + 1;
|
||||
+ } else {
|
||||
+ for (i = 0; i < slice_params->num_entry_point_offsets; i++) {
|
||||
+ if (tx + 1 >= pps->num_tile_columns_minus1 + 1) {
|
||||
+ x = tx = 0;
|
||||
+ y += pps->row_height_minus1[ty++] + 1;
|
||||
+ } else {
|
||||
+ x += pps->column_width_minus1[tx++] + 1;
|
||||
+ }
|
||||
+
|
||||
+ entry_points[i * 4 + 0] = slice_params->entry_point_offset_minus1[i] + 1;
|
||||
+ entry_points[i * 4 + 1] = 0x0;
|
||||
+ entry_points[i * 4 + 2] = (y << 16) | (x << 0);
|
||||
+ entry_points[i * 4 + 3] = ((y + pps->row_height_minus1[ty]) << 16) | ((x + pps->column_width_minus1[tx]) << 0);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
struct cedrus_run *run)
|
||||
{
|
||||
@@ -227,6 +322,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
const struct v4l2_ctrl_hevc_pps *pps;
|
||||
const struct v4l2_ctrl_hevc_slice_params *slice_params;
|
||||
const struct v4l2_hevc_pred_weight_table *pred_weight_table;
|
||||
+ struct cedrus_buffer *cedrus_buf;
|
||||
dma_addr_t src_buf_addr;
|
||||
dma_addr_t src_buf_end_addr;
|
||||
u32 chroma_log2_weight_denom;
|
||||
@@ -239,43 +335,10 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
slice_params = run->h265.slice_params;
|
||||
pred_weight_table = &slice_params->pred_weight_table;
|
||||
|
||||
- /* MV column buffer size and allocation. */
|
||||
- if (!ctx->codec.h265.mv_col_buf_size) {
|
||||
- unsigned int num_buffers =
|
||||
- run->dst->vb2_buf.vb2_queue->num_buffers;
|
||||
- unsigned int log2_max_luma_coding_block_size =
|
||||
- sps->log2_min_luma_coding_block_size_minus3 + 3 +
|
||||
- sps->log2_diff_max_min_luma_coding_block_size;
|
||||
- unsigned int ctb_size_luma =
|
||||
- 1 << log2_max_luma_coding_block_size;
|
||||
-
|
||||
- /*
|
||||
- * Each CTB requires a MV col buffer with a specific unit size.
|
||||
- * Since the address is given with missing lsb bits, 1 KiB is
|
||||
- * added to each buffer to ensure proper alignment.
|
||||
- */
|
||||
- ctx->codec.h265.mv_col_buf_unit_size =
|
||||
- DIV_ROUND_UP(ctx->src_fmt.width, ctb_size_luma) *
|
||||
- DIV_ROUND_UP(ctx->src_fmt.height, ctb_size_luma) *
|
||||
- CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE + SZ_1K;
|
||||
-
|
||||
- ctx->codec.h265.mv_col_buf_size = num_buffers *
|
||||
- ctx->codec.h265.mv_col_buf_unit_size;
|
||||
-
|
||||
- ctx->codec.h265.mv_col_buf =
|
||||
- dma_alloc_coherent(dev->dev,
|
||||
- ctx->codec.h265.mv_col_buf_size,
|
||||
- &ctx->codec.h265.mv_col_buf_addr,
|
||||
- GFP_KERNEL);
|
||||
- if (!ctx->codec.h265.mv_col_buf) {
|
||||
- ctx->codec.h265.mv_col_buf_size = 0;
|
||||
- // TODO: Abort the process here.
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
/* Activate H265 engine. */
|
||||
cedrus_engine_enable(dev, CEDRUS_CODEC_H265);
|
||||
+ if (sps->pic_width_in_luma_samples > 2048)
|
||||
+ cedrus_write(dev, VE_MODE, cedrus_read(dev, VE_MODE) | BIT(21));
|
||||
|
||||
/* Source offset and length in bits. */
|
||||
|
||||
@@ -299,18 +362,35 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
src_buf_end_addr = src_buf_addr +
|
||||
DIV_ROUND_UP(slice_params->bit_size, 8);
|
||||
|
||||
- reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_end_addr);
|
||||
+ reg = VE_DEC_H265_BITS_END_ADDR_BASE(ALIGN(src_buf_end_addr, 1024) - 1);
|
||||
cedrus_write(dev, VE_DEC_H265_BITS_END_ADDR, reg);
|
||||
|
||||
- /* Coding tree block address: start at the beginning. */
|
||||
- reg = VE_DEC_H265_DEC_CTB_ADDR_X(0) | VE_DEC_H265_DEC_CTB_ADDR_Y(0);
|
||||
- cedrus_write(dev, VE_DEC_H265_DEC_CTB_ADDR, reg);
|
||||
-
|
||||
cedrus_write(dev, VE_DEC_H265_TILE_START_CTB, 0);
|
||||
cedrus_write(dev, VE_DEC_H265_TILE_END_CTB, 0);
|
||||
|
||||
+ if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag)
|
||||
+ write_entry_point_list(ctx, run);
|
||||
+
|
||||
+ /* Coding tree block address */
|
||||
+ reg = 0;
|
||||
+ if (!slice_params->first_slice_segment_in_pic_flag) {
|
||||
+ unsigned int ctb_size_luma, width_in_ctb_luma;
|
||||
+ unsigned int log2_max_luma_coding_block_size;
|
||||
+
|
||||
+ log2_max_luma_coding_block_size =
|
||||
+ sps->log2_min_luma_coding_block_size_minus3 + 3 +
|
||||
+ sps->log2_diff_max_min_luma_coding_block_size;
|
||||
+ ctb_size_luma = 1 << log2_max_luma_coding_block_size;
|
||||
+ width_in_ctb_luma = DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_luma);
|
||||
+
|
||||
+ reg = VE_DEC_H265_DEC_CTB_ADDR_X(slice_params->slice_segment_addr % width_in_ctb_luma);
|
||||
+ reg |= VE_DEC_H265_DEC_CTB_ADDR_Y(slice_params->slice_segment_addr / width_in_ctb_luma);
|
||||
+ }
|
||||
+ cedrus_write(dev, VE_DEC_H265_DEC_CTB_ADDR, reg);
|
||||
+
|
||||
/* Clear the number of correctly-decoded coding tree blocks. */
|
||||
- cedrus_write(dev, VE_DEC_H265_DEC_CTB_NUM, 0);
|
||||
+ if (slice_params->first_slice_segment_in_pic_flag)
|
||||
+ cedrus_write(dev, VE_DEC_H265_DEC_CTB_NUM, 0);
|
||||
|
||||
/* Initialize bitstream access. */
|
||||
cedrus_write(dev, VE_DEC_H265_TRIGGER, VE_DEC_H265_TRIGGER_INIT_SWDEC);
|
||||
@@ -333,6 +413,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
VE_DEC_H265_DEC_SPS_HDR_LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE(sps->log2_diff_max_min_luma_coding_block_size) |
|
||||
VE_DEC_H265_DEC_SPS_HDR_LOG2_MIN_LUMA_CODING_BLOCK_SIZE_MINUS3(sps->log2_min_luma_coding_block_size_minus3) |
|
||||
VE_DEC_H265_DEC_SPS_HDR_BIT_DEPTH_CHROMA_MINUS8(sps->bit_depth_chroma_minus8) |
|
||||
+ VE_DEC_H265_DEC_SPS_HDR_BIT_DEPTH_LUMA_MINUS8(sps->bit_depth_luma_minus8) |
|
||||
VE_DEC_H265_DEC_SPS_HDR_SEPARATE_COLOUR_PLANE_FLAG(sps->separate_colour_plane_flag) |
|
||||
VE_DEC_H265_DEC_SPS_HDR_CHROMA_FORMAT_IDC(sps->chroma_format_idc);
|
||||
|
||||
@@ -362,7 +443,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
VE_DEC_H265_DEC_PPS_CTRL1_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG(pps->pps_loop_filter_across_slices_enabled_flag) |
|
||||
VE_DEC_H265_DEC_PPS_CTRL1_LOOP_FILTER_ACROSS_TILES_ENABLED_FLAG(pps->loop_filter_across_tiles_enabled_flag) |
|
||||
VE_DEC_H265_DEC_PPS_CTRL1_ENTROPY_CODING_SYNC_ENABLED_FLAG(pps->entropy_coding_sync_enabled_flag) |
|
||||
- VE_DEC_H265_DEC_PPS_CTRL1_TILES_ENABLED_FLAG(0) |
|
||||
+ VE_DEC_H265_DEC_PPS_CTRL1_TILES_ENABLED_FLAG(pps->tiles_enabled_flag) |
|
||||
VE_DEC_H265_DEC_PPS_CTRL1_TRANSQUANT_BYPASS_ENABLE_FLAG(pps->transquant_bypass_enabled_flag) |
|
||||
VE_DEC_H265_DEC_PPS_CTRL1_WEIGHTED_BIPRED_FLAG(pps->weighted_bipred_flag) |
|
||||
VE_DEC_H265_DEC_PPS_CTRL1_WEIGHTED_PRED_FLAG(pps->weighted_pred_flag);
|
||||
@@ -383,7 +464,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
VE_DEC_H265_DEC_SLICE_HDR_INFO0_COLOUR_PLANE_ID(slice_params->colour_plane_id) |
|
||||
VE_DEC_H265_DEC_SLICE_HDR_INFO0_SLICE_TYPE(slice_params->slice_type) |
|
||||
VE_DEC_H265_DEC_SLICE_HDR_INFO0_DEPENDENT_SLICE_SEGMENT_FLAG(pps->dependent_slice_segment_flag) |
|
||||
- VE_DEC_H265_DEC_SLICE_HDR_INFO0_FIRST_SLICE_SEGMENT_IN_PIC_FLAG(1);
|
||||
+ VE_DEC_H265_DEC_SLICE_HDR_INFO0_FIRST_SLICE_SEGMENT_IN_PIC_FLAG(slice_params->first_slice_segment_in_pic_flag);
|
||||
|
||||
cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO0, reg);
|
||||
|
||||
@@ -400,34 +481,68 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
|
||||
chroma_log2_weight_denom = pred_weight_table->luma_log2_weight_denom +
|
||||
pred_weight_table->delta_chroma_log2_weight_denom;
|
||||
- reg = VE_DEC_H265_DEC_SLICE_HDR_INFO2_NUM_ENTRY_POINT_OFFSETS(0) |
|
||||
+ reg = VE_DEC_H265_DEC_SLICE_HDR_INFO2_NUM_ENTRY_POINT_OFFSETS(slice_params->num_entry_point_offsets) |
|
||||
VE_DEC_H265_DEC_SLICE_HDR_INFO2_CHROMA_LOG2_WEIGHT_DENOM(chroma_log2_weight_denom) |
|
||||
VE_DEC_H265_DEC_SLICE_HDR_INFO2_LUMA_LOG2_WEIGHT_DENOM(pred_weight_table->luma_log2_weight_denom);
|
||||
|
||||
cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO2, reg);
|
||||
|
||||
+ cedrus_write(dev, VE_DEC_H265_ENTRY_POINT_OFFSET_ADDR, ctx->codec.h265.entry_points_buf_addr >> 8);
|
||||
+
|
||||
/* Decoded picture size. */
|
||||
|
||||
- reg = VE_DEC_H265_DEC_PIC_SIZE_WIDTH(ctx->src_fmt.width) |
|
||||
- VE_DEC_H265_DEC_PIC_SIZE_HEIGHT(ctx->src_fmt.height);
|
||||
+ reg = VE_DEC_H265_DEC_PIC_SIZE_WIDTH(sps->pic_width_in_luma_samples) |
|
||||
+ VE_DEC_H265_DEC_PIC_SIZE_HEIGHT(sps->pic_height_in_luma_samples);
|
||||
|
||||
cedrus_write(dev, VE_DEC_H265_DEC_PIC_SIZE, reg);
|
||||
|
||||
- /* Scaling list. */
|
||||
+ /* Scaling list */
|
||||
|
||||
- reg = VE_DEC_H265_SCALING_LIST_CTRL0_DEFAULT;
|
||||
+ if (sps->scaling_list_enabled_flag) {
|
||||
+ cedrus_h265_write_scaling_list(ctx, run);
|
||||
+ reg = VE_DEC_H265_SCALING_LIST_CTRL0_ENABLED_FLAG(1);
|
||||
+ } else {
|
||||
+ reg = VE_DEC_H265_SCALING_LIST_CTRL0_DEFAULT;
|
||||
+ }
|
||||
cedrus_write(dev, VE_DEC_H265_SCALING_LIST_CTRL0, reg);
|
||||
|
||||
/* Neightbor information address. */
|
||||
reg = VE_DEC_H265_NEIGHBOR_INFO_ADDR_BASE(ctx->codec.h265.neighbor_info_buf_addr);
|
||||
cedrus_write(dev, VE_DEC_H265_NEIGHBOR_INFO_ADDR, reg);
|
||||
|
||||
+ cedrus_write(dev, VE_DEC_H265_LOW_ADDR, 0);
|
||||
+
|
||||
/* Write decoded picture buffer in pic list. */
|
||||
cedrus_h265_frame_info_write_dpb(ctx, slice_params->dpb,
|
||||
slice_params->num_active_dpb_entries);
|
||||
|
||||
/* Output frame. */
|
||||
|
||||
+ cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[run->dst->vb2_buf.index]);
|
||||
+ if (!cedrus_buf->mv_col_buf_size) {
|
||||
+ unsigned int ctb_size_luma, width_in_ctb_luma;
|
||||
+ unsigned int log2_max_luma_coding_block_size;
|
||||
+
|
||||
+ log2_max_luma_coding_block_size =
|
||||
+ sps->log2_min_luma_coding_block_size_minus3 + 3 +
|
||||
+ sps->log2_diff_max_min_luma_coding_block_size;
|
||||
+ ctb_size_luma = 1 << log2_max_luma_coding_block_size;
|
||||
+ width_in_ctb_luma = DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_luma);
|
||||
+
|
||||
+ cedrus_buf->mv_col_buf_size = ALIGN(width_in_ctb_luma *
|
||||
+ DIV_ROUND_UP(sps->pic_height_in_luma_samples, ctb_size_luma) *
|
||||
+ CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE, 1024);
|
||||
+
|
||||
+ cedrus_buf->mv_col_buf =
|
||||
+ dma_alloc_coherent(dev->dev,
|
||||
+ cedrus_buf->mv_col_buf_size,
|
||||
+ &cedrus_buf->mv_col_buf_dma,
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ if (!cedrus_buf->mv_col_buf)
|
||||
+ cedrus_buf->mv_col_buf_size = 0;
|
||||
+ }
|
||||
+
|
||||
output_pic_list_index = V4L2_HEVC_DPB_ENTRIES_NUM_MAX;
|
||||
pic_order_cnt[0] = slice_params->slice_pic_order_cnt;
|
||||
pic_order_cnt[1] = slice_params->slice_pic_order_cnt;
|
||||
@@ -443,36 +558,36 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
if (slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_I) {
|
||||
cedrus_h265_ref_pic_list_write(dev, slice_params->dpb,
|
||||
slice_params->ref_idx_l0,
|
||||
- slice_params->num_ref_idx_l0_active_minus1 + 1,
|
||||
- VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST0);
|
||||
+ slice_params->num_ref_idx_l0_active_minus1 + 1,
|
||||
+ VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST0);
|
||||
|
||||
if (pps->weighted_pred_flag || pps->weighted_bipred_flag)
|
||||
cedrus_h265_pred_weight_write(dev,
|
||||
- pred_weight_table->delta_luma_weight_l0,
|
||||
- pred_weight_table->luma_offset_l0,
|
||||
- pred_weight_table->delta_chroma_weight_l0,
|
||||
- pred_weight_table->chroma_offset_l0,
|
||||
- slice_params->num_ref_idx_l0_active_minus1 + 1,
|
||||
- VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L0,
|
||||
- VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L0);
|
||||
+ pred_weight_table->delta_luma_weight_l0,
|
||||
+ pred_weight_table->luma_offset_l0,
|
||||
+ pred_weight_table->delta_chroma_weight_l0,
|
||||
+ pred_weight_table->chroma_offset_l0,
|
||||
+ slice_params->num_ref_idx_l0_active_minus1 + 1,
|
||||
+ VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L0,
|
||||
+ VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L0);
|
||||
}
|
||||
|
||||
/* Reference picture list 1 (for B frames). */
|
||||
if (slice_params->slice_type == V4L2_HEVC_SLICE_TYPE_B) {
|
||||
cedrus_h265_ref_pic_list_write(dev, slice_params->dpb,
|
||||
slice_params->ref_idx_l1,
|
||||
- slice_params->num_ref_idx_l1_active_minus1 + 1,
|
||||
- VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST1);
|
||||
+ slice_params->num_ref_idx_l1_active_minus1 + 1,
|
||||
+ VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST1);
|
||||
|
||||
if (pps->weighted_bipred_flag)
|
||||
cedrus_h265_pred_weight_write(dev,
|
||||
- pred_weight_table->delta_luma_weight_l1,
|
||||
- pred_weight_table->luma_offset_l1,
|
||||
- pred_weight_table->delta_chroma_weight_l1,
|
||||
- pred_weight_table->chroma_offset_l1,
|
||||
- slice_params->num_ref_idx_l1_active_minus1 + 1,
|
||||
- VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L1,
|
||||
- VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L1);
|
||||
+ pred_weight_table->delta_luma_weight_l1,
|
||||
+ pred_weight_table->luma_offset_l1,
|
||||
+ pred_weight_table->delta_chroma_weight_l1,
|
||||
+ pred_weight_table->chroma_offset_l1,
|
||||
+ slice_params->num_ref_idx_l1_active_minus1 + 1,
|
||||
+ VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L1,
|
||||
+ VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L1);
|
||||
}
|
||||
|
||||
/* Enable appropriate interruptions. */
|
||||
@@ -483,9 +598,6 @@ static int cedrus_h265_start(struct cedrus_ctx *ctx)
|
||||
{
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
|
||||
- /* The buffer size is calculated at setup time. */
|
||||
- ctx->codec.h265.mv_col_buf_size = 0;
|
||||
-
|
||||
ctx->codec.h265.neighbor_info_buf =
|
||||
dma_alloc_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
|
||||
&ctx->codec.h265.neighbor_info_buf_addr,
|
||||
@@ -493,6 +605,17 @@ static int cedrus_h265_start(struct cedrus_ctx *ctx)
|
||||
if (!ctx->codec.h265.neighbor_info_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
+ ctx->codec.h265.entry_points_buf =
|
||||
+ dma_alloc_coherent(dev->dev, CEDRUS_H265_ENTRY_POINTS_BUF_SIZE,
|
||||
+ &ctx->codec.h265.entry_points_buf_addr,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!ctx->codec.h265.entry_points_buf) {
|
||||
+ dma_free_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
|
||||
+ ctx->codec.h265.neighbor_info_buf,
|
||||
+ ctx->codec.h265.neighbor_info_buf_addr);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -500,17 +623,12 @@ static void cedrus_h265_stop(struct cedrus_ctx *ctx)
|
||||
{
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
|
||||
- if (ctx->codec.h265.mv_col_buf_size > 0) {
|
||||
- dma_free_coherent(dev->dev, ctx->codec.h265.mv_col_buf_size,
|
||||
- ctx->codec.h265.mv_col_buf,
|
||||
- ctx->codec.h265.mv_col_buf_addr);
|
||||
-
|
||||
- ctx->codec.h265.mv_col_buf_size = 0;
|
||||
- }
|
||||
-
|
||||
dma_free_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
|
||||
ctx->codec.h265.neighbor_info_buf,
|
||||
ctx->codec.h265.neighbor_info_buf_addr);
|
||||
+ dma_free_coherent(dev->dev, CEDRUS_H265_ENTRY_POINTS_BUF_SIZE,
|
||||
+ ctx->codec.h265.entry_points_buf,
|
||||
+ ctx->codec.h265.entry_points_buf_addr);
|
||||
}
|
||||
|
||||
static void cedrus_h265_trigger(struct cedrus_ctx *ctx)
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
index 87651d6b6227..a2931f322c7a 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
@@ -496,6 +496,9 @@
|
||||
#define VE_DEC_H265_TILE_START_CTB (VE_ENGINE_DEC_H265 + 0x68)
|
||||
#define VE_DEC_H265_TILE_END_CTB (VE_ENGINE_DEC_H265 + 0x6c)
|
||||
|
||||
+#define VE_DEC_H265_SCALING_LIST_DC_COEF0 (VE_ENGINE_DEC_H265 + 0x78)
|
||||
+#define VE_DEC_H265_SCALING_LIST_DC_COEF1 (VE_ENGINE_DEC_H265 + 0x7c)
|
||||
+
|
||||
#define VE_DEC_H265_LOW_ADDR (VE_ENGINE_DEC_H265 + 0x80)
|
||||
|
||||
#define VE_DEC_H265_LOW_ADDR_PRIMARY_CHROMA(a) \
|
||||
@@ -513,7 +516,10 @@
|
||||
#define VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L1 0x80
|
||||
#define VE_DEC_H265_SRAM_OFFSET_FRAME_INFO 0x400
|
||||
#define VE_DEC_H265_SRAM_OFFSET_FRAME_INFO_UNIT 0x20
|
||||
-#define VE_DEC_H265_SRAM_OFFSET_SCALING_LISTS 0x800
|
||||
+#define VE_DEC_H265_SRAM_OFFSET_SCALING_LISTS_8x8 0x800
|
||||
+#define VE_DEC_H265_SRAM_OFFSET_SCALING_LISTS_32x32 0x980
|
||||
+#define VE_DEC_H265_SRAM_OFFSET_SCALING_LISTS_16x16 0xa00
|
||||
+#define VE_DEC_H265_SRAM_OFFSET_SCALING_LISTS_4x4 0xb80
|
||||
#define VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST0 0xc00
|
||||
#define VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST1 0xc10
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
index b9acdc03c839..adf00513c15f 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
@@ -423,8 +423,18 @@ static void cedrus_buf_cleanup(struct vb2_buffer *vb)
|
||||
struct vb2_queue *vq = vb->vb2_queue;
|
||||
struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
|
||||
|
||||
- if (!V4L2_TYPE_IS_OUTPUT(vq->type))
|
||||
+ if (!V4L2_TYPE_IS_OUTPUT(vq->type)) {
|
||||
+ struct cedrus_buffer *cedrus_buf;
|
||||
+
|
||||
+ cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[vb->index]);
|
||||
+
|
||||
+ if (cedrus_buf->mv_col_buf_size)
|
||||
+ dma_free_coherent(ctx->dev->dev,
|
||||
+ cedrus_buf->mv_col_buf_size,
|
||||
+ cedrus_buf->mv_col_buf,
|
||||
+ cedrus_buf->mv_col_buf_dma);
|
||||
ctx->dst_bufs[vb->index] = NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
static int cedrus_buf_out_validate(struct vb2_buffer *vb)
|
||||
diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
|
||||
index 005c71c67163..4bf3d79047f4 100644
|
||||
--- a/include/media/hevc-ctrls.h
|
||||
+++ b/include/media/hevc-ctrls.h
|
||||
@@ -14,11 +14,13 @@
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_SPS (V4L2_CID_MPEG_BASE + 645)
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_PPS (V4L2_CID_MPEG_BASE + 646)
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (V4L2_CID_MPEG_BASE + 647)
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (V4L2_CID_MPEG_BASE + 648)
|
||||
|
||||
/* enum v4l2_ctrl_type type values */
|
||||
#define V4L2_CTRL_TYPE_HEVC_SPS 0x0115
|
||||
#define V4L2_CTRL_TYPE_HEVC_PPS 0x0116
|
||||
#define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0117
|
||||
+#define V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX 0x0118
|
||||
|
||||
#define V4L2_HEVC_SLICE_TYPE_B 0
|
||||
#define V4L2_HEVC_SLICE_TYPE_P 1
|
||||
@@ -91,7 +93,7 @@ struct v4l2_ctrl_hevc_pps {
|
||||
__u8 lists_modification_present_flag;
|
||||
__u8 log2_parallel_merge_level_minus2;
|
||||
__u8 slice_segment_header_extension_present_flag;
|
||||
- __u8 padding;
|
||||
+ __u8 scaling_list_enable_flag;
|
||||
};
|
||||
|
||||
#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE 0x01
|
||||
@@ -175,7 +177,21 @@ struct v4l2_ctrl_hevc_slice_params {
|
||||
/* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */
|
||||
struct v4l2_hevc_pred_weight_table pred_weight_table;
|
||||
|
||||
- __u8 padding[2];
|
||||
+ __u32 slice_segment_addr;
|
||||
+ __u32 num_entry_point_offsets;
|
||||
+ __u32 entry_point_offset_minus1[256];
|
||||
+ __u8 first_slice_segment_in_pic_flag;
|
||||
+
|
||||
+ __u8 padding;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_ctrl_hevc_scaling_matrix {
|
||||
+ __u8 scaling_list_4x4[6][16];
|
||||
+ __u8 scaling_list_8x8[6][64];
|
||||
+ __u8 scaling_list_16x16[6][64];
|
||||
+ __u8 scaling_list_32x32[2][64];
|
||||
+ __u8 scaling_list_dc_coef_16x16[6];
|
||||
+ __u8 scaling_list_dc_coef_32x32[2];
|
||||
};
|
||||
|
||||
#endif
|
358
projects/Allwinner/patches/linux/0009-cedrus-h264-4k.patch
Normal file
358
projects/Allwinner/patches/linux/0009-cedrus-h264-4k.patch
Normal file
@ -0,0 +1,358 @@
|
||||
From bd5fed9f390fea4ef8df1abb5f4ac6b64fab5974 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Mon, 18 Feb 2019 21:51:31 +0100
|
||||
Subject: [PATCH] cedrus h264 4k
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.h | 12 +-
|
||||
.../staging/media/sunxi/cedrus/cedrus_h264.c | 117 +++++++++++-------
|
||||
.../staging/media/sunxi/cedrus/cedrus_h265.c | 4 +-
|
||||
.../staging/media/sunxi/cedrus/cedrus_hw.c | 11 +-
|
||||
.../staging/media/sunxi/cedrus/cedrus_hw.h | 3 +-
|
||||
.../staging/media/sunxi/cedrus/cedrus_mpeg2.c | 2 +-
|
||||
.../staging/media/sunxi/cedrus/cedrus_regs.h | 4 +
|
||||
.../staging/media/sunxi/cedrus/cedrus_video.c | 4 +-
|
||||
8 files changed, 98 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
index deb9fa1de97c..8815332fe1c1 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -116,14 +116,18 @@ struct cedrus_ctx {
|
||||
|
||||
union {
|
||||
struct {
|
||||
- void *mv_col_buf;
|
||||
- dma_addr_t mv_col_buf_dma;
|
||||
- ssize_t mv_col_buf_field_size;
|
||||
- ssize_t mv_col_buf_size;
|
||||
void *pic_info_buf;
|
||||
dma_addr_t pic_info_buf_dma;
|
||||
void *neighbor_info_buf;
|
||||
dma_addr_t neighbor_info_buf_dma;
|
||||
+
|
||||
+ void *deblk_buf;
|
||||
+ dma_addr_t deblk_buf_dma;
|
||||
+ ssize_t deblk_buf_size;
|
||||
+
|
||||
+ void *intra_pred_buf;
|
||||
+ dma_addr_t intra_pred_buf_dma;
|
||||
+ ssize_t intra_pred_buf_size;
|
||||
} h264;
|
||||
struct {
|
||||
void *neighbor_info_buf;
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
index 405545947b85..737a317fd1ee 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
@@ -55,16 +55,14 @@ static void cedrus_h264_write_sram(struct cedrus_dev *dev,
|
||||
}
|
||||
|
||||
static dma_addr_t cedrus_h264_mv_col_buf_addr(struct cedrus_ctx *ctx,
|
||||
- unsigned int position,
|
||||
+ struct cedrus_buffer *buf,
|
||||
unsigned int field)
|
||||
{
|
||||
- dma_addr_t addr = ctx->codec.h264.mv_col_buf_dma;
|
||||
-
|
||||
- /* Adjust for the position */
|
||||
- addr += position * ctx->codec.h264.mv_col_buf_field_size * 2;
|
||||
+ dma_addr_t addr = buf->mv_col_buf_dma;
|
||||
|
||||
/* Adjust for the field */
|
||||
- addr += field * ctx->codec.h264.mv_col_buf_field_size;
|
||||
+ if (field)
|
||||
+ addr += buf->mv_col_buf_size / 2;
|
||||
|
||||
return addr;
|
||||
}
|
||||
@@ -76,7 +74,6 @@ static void cedrus_fill_ref_pic(struct cedrus_ctx *ctx,
|
||||
struct cedrus_h264_sram_ref_pic *pic)
|
||||
{
|
||||
struct vb2_buffer *vbuf = &buf->m2m_buf.vb.vb2_buf;
|
||||
- unsigned int position = buf->codec.h264.position;
|
||||
|
||||
pic->top_field_order_cnt = top_field_order_cnt;
|
||||
pic->bottom_field_order_cnt = bottom_field_order_cnt;
|
||||
@@ -84,8 +81,8 @@ static void cedrus_fill_ref_pic(struct cedrus_ctx *ctx,
|
||||
|
||||
pic->luma_ptr = cedrus_buf_addr(vbuf, &ctx->dst_fmt, 0);
|
||||
pic->chroma_ptr = cedrus_buf_addr(vbuf, &ctx->dst_fmt, 1);
|
||||
- pic->mv_col_top_ptr = cedrus_h264_mv_col_buf_addr(ctx, position, 0);
|
||||
- pic->mv_col_bot_ptr = cedrus_h264_mv_col_buf_addr(ctx, position, 1);
|
||||
+ pic->mv_col_top_ptr = cedrus_h264_mv_col_buf_addr(ctx, buf, 0);
|
||||
+ pic->mv_col_bot_ptr = cedrus_h264_mv_col_buf_addr(ctx, buf, 1);
|
||||
}
|
||||
|
||||
static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
||||
@@ -148,6 +145,28 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
||||
output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
|
||||
output_buf->codec.h264.position = position;
|
||||
|
||||
+ if (!output_buf->mv_col_buf_size) {
|
||||
+ const struct v4l2_ctrl_h264_sps *sps = run->h264.sps;
|
||||
+ unsigned int field_size;
|
||||
+
|
||||
+ field_size = DIV_ROUND_UP(ctx->src_fmt.width, 16) *
|
||||
+ DIV_ROUND_UP(ctx->src_fmt.height, 16) * 16;
|
||||
+ if (!(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE))
|
||||
+ field_size = field_size * 2;
|
||||
+ if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY))
|
||||
+ field_size = field_size * 2;
|
||||
+
|
||||
+ output_buf->mv_col_buf_size = ALIGN(field_size, 1024) * 2;
|
||||
+ output_buf->mv_col_buf =
|
||||
+ dma_alloc_coherent(dev->dev,
|
||||
+ output_buf->mv_col_buf_size,
|
||||
+ &output_buf->mv_col_buf_dma,
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ if (!output_buf->mv_col_buf)
|
||||
+ output_buf->mv_col_buf_size = 0;
|
||||
+ }
|
||||
+
|
||||
if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)
|
||||
output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_FIELD;
|
||||
else if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
|
||||
@@ -331,6 +350,14 @@ static void cedrus_set_params(struct cedrus_ctx *ctx,
|
||||
VE_H264_VLD_ADDR_FIRST | VE_H264_VLD_ADDR_VALID |
|
||||
VE_H264_VLD_ADDR_LAST);
|
||||
|
||||
+ if (((sps->pic_width_in_mbs_minus1 + 1) * 16) > 2048) {
|
||||
+ cedrus_write(dev, VE_DBLK_INTRAPRED_BUF_CTRL, 0x5);
|
||||
+ cedrus_write(dev, VE_DBLK_DRAM_BUF_ADDR,
|
||||
+ ctx->codec.h264.deblk_buf_dma);
|
||||
+ cedrus_write(dev, VE_INTRAPRED_DRAM_BUF_ADDR,
|
||||
+ ctx->codec.h264.intra_pred_buf_dma);
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* FIXME: Since the bitstream parsing is done in software, and
|
||||
* in userspace, this shouldn't be needed anymore. But it
|
||||
@@ -471,7 +498,8 @@ static void cedrus_h264_setup(struct cedrus_ctx *ctx,
|
||||
{
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
|
||||
- cedrus_engine_enable(dev, CEDRUS_CODEC_H264);
|
||||
+ cedrus_engine_enable(dev, CEDRUS_CODEC_H264,
|
||||
+ ctx->src_fmt.width);
|
||||
|
||||
cedrus_write(dev, VE_H264_SDROT_CTRL, 0);
|
||||
cedrus_write(dev, VE_H264_EXTRA_BUFFER1,
|
||||
@@ -490,8 +518,6 @@ static void cedrus_h264_setup(struct cedrus_ctx *ctx,
|
||||
static int cedrus_h264_start(struct cedrus_ctx *ctx)
|
||||
{
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
- unsigned int field_size;
|
||||
- unsigned int mv_col_size;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@@ -523,44 +549,42 @@ static int cedrus_h264_start(struct cedrus_ctx *ctx)
|
||||
goto err_pic_buf;
|
||||
}
|
||||
|
||||
- field_size = DIV_ROUND_UP(ctx->src_fmt.width, 16) *
|
||||
- DIV_ROUND_UP(ctx->src_fmt.height, 16) * 16;
|
||||
-
|
||||
- /*
|
||||
- * FIXME: This is actually conditional to
|
||||
- * V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE not being set, we
|
||||
- * might have to rework this if memory efficiency ever is
|
||||
- * something we need to work on.
|
||||
- */
|
||||
- field_size = field_size * 2;
|
||||
+ if (ctx->src_fmt.width > 2048) {
|
||||
+ ctx->codec.h264.deblk_buf_size =
|
||||
+ ALIGN(ctx->src_fmt.width, 32) * 12;
|
||||
+ ctx->codec.h264.deblk_buf =
|
||||
+ dma_alloc_coherent(dev->dev,
|
||||
+ ctx->codec.h264.deblk_buf_size,
|
||||
+ &ctx->codec.h264.deblk_buf_dma,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!ctx->codec.h264.deblk_buf) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_neighbor_buf;
|
||||
+ }
|
||||
|
||||
- /*
|
||||
- * FIXME: This is actually conditional to
|
||||
- * V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY not being set, we might
|
||||
- * have to rework this if memory efficiency ever is something
|
||||
- * we need to work on.
|
||||
- */
|
||||
- field_size = field_size * 2;
|
||||
- ctx->codec.h264.mv_col_buf_field_size = ALIGN(field_size, 1024);
|
||||
-
|
||||
- mv_col_size = field_size * 2 * CEDRUS_H264_FRAME_NUM;
|
||||
- ctx->codec.h264.mv_col_buf_size = mv_col_size;
|
||||
- ctx->codec.h264.mv_col_buf = dma_alloc_coherent(dev->dev,
|
||||
- ctx->codec.h264.mv_col_buf_size,
|
||||
- &ctx->codec.h264.mv_col_buf_dma,
|
||||
- GFP_KERNEL);
|
||||
- if (!ctx->codec.h264.mv_col_buf) {
|
||||
- ret = -ENOMEM;
|
||||
- goto err_neighbor_buf;
|
||||
+ ctx->codec.h264.intra_pred_buf_size =
|
||||
+ ALIGN(ctx->src_fmt.width, 64) * 5;
|
||||
+ ctx->codec.h264.intra_pred_buf =
|
||||
+ dma_alloc_coherent(dev->dev,
|
||||
+ ctx->codec.h264.intra_pred_buf_size,
|
||||
+ &ctx->codec.h264.intra_pred_buf_dma,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!ctx->codec.h264.intra_pred_buf) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_deblk_buf;
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
+err_deblk_buf:
|
||||
+ dma_free_coherent(dev->dev, ctx->codec.h264.deblk_buf_size,
|
||||
+ ctx->codec.h264.deblk_buf,
|
||||
+ ctx->codec.h264.deblk_buf_dma);
|
||||
err_neighbor_buf:
|
||||
dma_free_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
|
||||
ctx->codec.h264.neighbor_info_buf,
|
||||
ctx->codec.h264.neighbor_info_buf_dma);
|
||||
-
|
||||
err_pic_buf:
|
||||
dma_free_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
|
||||
ctx->codec.h264.pic_info_buf,
|
||||
@@ -572,15 +596,20 @@ static void cedrus_h264_stop(struct cedrus_ctx *ctx)
|
||||
{
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
|
||||
- dma_free_coherent(dev->dev, ctx->codec.h264.mv_col_buf_size,
|
||||
- ctx->codec.h264.mv_col_buf,
|
||||
- ctx->codec.h264.mv_col_buf_dma);
|
||||
dma_free_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
|
||||
ctx->codec.h264.neighbor_info_buf,
|
||||
ctx->codec.h264.neighbor_info_buf_dma);
|
||||
dma_free_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
|
||||
ctx->codec.h264.pic_info_buf,
|
||||
ctx->codec.h264.pic_info_buf_dma);
|
||||
+ if (ctx->codec.h264.deblk_buf_size)
|
||||
+ dma_free_coherent(dev->dev, ctx->codec.h264.deblk_buf_size,
|
||||
+ ctx->codec.h264.deblk_buf,
|
||||
+ ctx->codec.h264.deblk_buf_dma);
|
||||
+ if (ctx->codec.h264.intra_pred_buf_size)
|
||||
+ dma_free_coherent(dev->dev, ctx->codec.h264.intra_pred_buf_size,
|
||||
+ ctx->codec.h264.intra_pred_buf,
|
||||
+ ctx->codec.h264.intra_pred_buf_dma);
|
||||
}
|
||||
|
||||
static void cedrus_h264_trigger(struct cedrus_ctx *ctx)
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
index 2cc36d69548e..246d747d3fa9 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
@@ -336,9 +336,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
pred_weight_table = &slice_params->pred_weight_table;
|
||||
|
||||
/* Activate H265 engine. */
|
||||
- cedrus_engine_enable(dev, CEDRUS_CODEC_H265);
|
||||
- if (sps->pic_width_in_luma_samples > 2048)
|
||||
- cedrus_write(dev, VE_MODE, cedrus_read(dev, VE_MODE) | BIT(21));
|
||||
+ cedrus_engine_enable(dev, CEDRUS_CODEC_H265, ctx->src_fmt.width);
|
||||
|
||||
/* Source offset and length in bits. */
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
||||
index 6be604c52d5c..4b6c69010e39 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
||||
@@ -30,7 +30,8 @@
|
||||
#include "cedrus_hw.h"
|
||||
#include "cedrus_regs.h"
|
||||
|
||||
-int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec)
|
||||
+int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec,
|
||||
+ unsigned int width)
|
||||
{
|
||||
u32 reg = 0;
|
||||
|
||||
@@ -58,6 +59,11 @@ int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ if (width >= 4096)
|
||||
+ reg |= BIT(22);
|
||||
+ if (width > 2048)
|
||||
+ reg |= BIT(21);
|
||||
+
|
||||
cedrus_write(dev, VE_MODE, reg);
|
||||
|
||||
return 0;
|
||||
@@ -83,9 +89,6 @@ void cedrus_dst_format_set(struct cedrus_dev *dev,
|
||||
reg = VE_PRIMARY_OUT_FMT_NV12;
|
||||
cedrus_write(dev, VE_PRIMARY_OUT_FMT, reg);
|
||||
|
||||
- reg = VE_CHROMA_BUF_LEN_SDRT(chroma_size / 2);
|
||||
- cedrus_write(dev, VE_CHROMA_BUF_LEN, reg);
|
||||
-
|
||||
reg = chroma_size / 2;
|
||||
cedrus_write(dev, VE_PRIMARY_CHROMA_BUF_LEN, reg);
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
||||
index b43c77d54b95..40b44722b7c0 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
||||
@@ -18,7 +18,8 @@
|
||||
|
||||
#define CEDRUS_CLOCK_RATE_DEFAULT 320000000
|
||||
|
||||
-int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec);
|
||||
+int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec,
|
||||
+ unsigned int width);
|
||||
void cedrus_engine_disable(struct cedrus_dev *dev);
|
||||
|
||||
void cedrus_dst_format_set(struct cedrus_dev *dev,
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
|
||||
index cb45fda9aaeb..2f6384ca385d 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
|
||||
@@ -96,7 +96,7 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
|
||||
quantization = run->mpeg2.quantization;
|
||||
|
||||
/* Activate MPEG engine. */
|
||||
- cedrus_engine_enable(dev, CEDRUS_CODEC_MPEG2);
|
||||
+ cedrus_engine_enable(dev, CEDRUS_CODEC_MPEG2, ctx->src_fmt.width);
|
||||
|
||||
/* Set intra quantization matrix. */
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
index a2931f322c7a..df000b7c99be 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
@@ -41,6 +41,10 @@
|
||||
#define VE_MODE_DEC_H264 (0x01 << 0)
|
||||
#define VE_MODE_DEC_MPEG (0x00 << 0)
|
||||
|
||||
+#define VE_DBLK_INTRAPRED_BUF_CTRL 0x50
|
||||
+#define VE_DBLK_DRAM_BUF_ADDR 0x54
|
||||
+#define VE_INTRAPRED_DRAM_BUF_ADDR 0x58
|
||||
+
|
||||
#define VE_PRIMARY_CHROMA_BUF_LEN 0xc4
|
||||
#define VE_PRIMARY_FB_LINE_STRIDE 0xc8
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
index adf00513c15f..b24317b26fd2 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
@@ -29,8 +29,8 @@
|
||||
|
||||
#define CEDRUS_MIN_WIDTH 16U
|
||||
#define CEDRUS_MIN_HEIGHT 16U
|
||||
-#define CEDRUS_MAX_WIDTH 3840U
|
||||
-#define CEDRUS_MAX_HEIGHT 2160U
|
||||
+#define CEDRUS_MAX_WIDTH 4096U
|
||||
+#define CEDRUS_MAX_HEIGHT 2768U
|
||||
|
||||
static struct cedrus_format cedrus_formats[] = {
|
||||
{
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,62 @@
|
||||
From 9ce5c66f0f98cc968598307f7f7feb39a83d7342 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Tue, 26 Feb 2019 20:45:14 +0000
|
||||
Subject: [PATCH] WIP: dw-hdmi-cec: sleep 100ms on error
|
||||
|
||||
---
|
||||
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 18 ++++++++++++++++--
|
||||
1 file changed, 16 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
|
||||
index 6c323510f128..b5a1a85c8700 100644
|
||||
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
|
||||
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
|
||||
@@ -7,6 +7,7 @@
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
+#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
@@ -132,8 +133,15 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
|
||||
|
||||
dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
|
||||
|
||||
- if (stat & CEC_STAT_ERROR_INIT) {
|
||||
- cec->tx_status = CEC_TX_STATUS_ERROR;
|
||||
+ /* Status with both done and error_initiator bits have been seen
|
||||
+ * on Rockchip RK3328 devices, transmit attempt seems to have failed
|
||||
+ * when this happens, report as low drive and block cec-framework
|
||||
+ * 100ms before core retransmits the failed message, this seems to
|
||||
+ * mitigate the issue with failed transmit attempts.
|
||||
+ */
|
||||
+ if ((stat & (CEC_STAT_DONE|CEC_STAT_ERROR_INIT)) == (CEC_STAT_DONE|CEC_STAT_ERROR_INIT)) {
|
||||
+ pr_info("dw_hdmi_cec_hardirq: stat=%02x LOW_DRIVE\n", stat);
|
||||
+ cec->tx_status = CEC_TX_STATUS_LOW_DRIVE;
|
||||
cec->tx_done = true;
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
} else if (stat & CEC_STAT_DONE) {
|
||||
@@ -144,6 +152,10 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
|
||||
cec->tx_status = CEC_TX_STATUS_NACK;
|
||||
cec->tx_done = true;
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
+ } else if (stat & CEC_STAT_ERROR_INIT) {
|
||||
+ cec->tx_status = CEC_TX_STATUS_ERROR;
|
||||
+ cec->tx_done = true;
|
||||
+ ret = IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
if (stat & CEC_STAT_EOM) {
|
||||
@@ -176,6 +188,8 @@ static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
|
||||
|
||||
if (cec->tx_done) {
|
||||
cec->tx_done = false;
|
||||
+ if (cec->tx_status == CEC_TX_STATUS_LOW_DRIVE)
|
||||
+ msleep(100);
|
||||
cec_transmit_attempt_done(adap, cec->tx_status);
|
||||
}
|
||||
if (cec->rx_done) {
|
||||
--
|
||||
2.20.1
|
||||
|
232
projects/Allwinner/patches/linux/0013-cec-improvements.patch
Normal file
232
projects/Allwinner/patches/linux/0013-cec-improvements.patch
Normal file
@ -0,0 +1,232 @@
|
||||
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||||
index a63e5f0dae56..fdda26f8b056 100644
|
||||
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||||
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||||
@@ -2634,7 +2634,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
|
||||
hdmi->audio = platform_device_register_full(&pdevinfo);
|
||||
}
|
||||
|
||||
- if (config0 & HDMI_CONFIG0_CEC) {
|
||||
+ if (!plat_data->is_cec_unusable && (config0 & HDMI_CONFIG0_CEC)) {
|
||||
cec.hdmi = hdmi;
|
||||
cec.ops = &dw_hdmi_cec_ops;
|
||||
cec.irq = irq;
|
||||
diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
|
||||
index 1dbbc3a1b763..7149c72e44c8 100644
|
||||
--- a/drivers/gpu/drm/sun4i/Kconfig
|
||||
+++ b/drivers/gpu/drm/sun4i/Kconfig
|
||||
@@ -60,6 +60,16 @@ config DRM_SUN8I_DW_HDMI
|
||||
DesignWare HDMI controller with custom HDMI PHY. If M is
|
||||
selected the module will be called sun8i_dw_hdmi.
|
||||
|
||||
+config DRM_SUN8I_DW_HDMI_CEC
|
||||
+ bool "Allwinner DesignWare HDMI CEC Support for 40nm SoCs"
|
||||
+ depends on DRM_SUN8I_DW_HDMI
|
||||
+ select CEC_CORE
|
||||
+ select CEC_PIN
|
||||
+ help
|
||||
+ Choose this option if you have an 40nm Allwinner SoC with
|
||||
+ the DesignWare HDMI controller with custom HDMI PHY and
|
||||
+ you want to use CEC.
|
||||
+
|
||||
config DRM_SUN8I_MIXER
|
||||
tristate "Support for Allwinner Display Engine 2.0 Mixer"
|
||||
default MACH_SUN8I
|
||||
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
|
||||
index 720c5aa8adc1..82dd84094638 100644
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/reset.h>
|
||||
+#include <media/cec-pin.h>
|
||||
|
||||
#define SUN8I_HDMI_PHY_DBG_CTRL_REG 0x0000
|
||||
#define SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK BIT(0)
|
||||
@@ -144,6 +145,13 @@
|
||||
#define SUN8I_HDMI_PHY_ANA_STS_RCAL_MASK GENMASK(5, 0)
|
||||
|
||||
#define SUN8I_HDMI_PHY_CEC_REG 0x003c
|
||||
+#define SUN8I_HDMI_PHY_CEC_PIN_CTRL BIT(7)
|
||||
+/*
|
||||
+ * Documentation says that this bit is output enable. However,
|
||||
+ * it seems that this bit is actually output disable.
|
||||
+ */
|
||||
+#define SUN8I_HDMI_PHY_CEC_OUT_DIS BIT(2)
|
||||
+#define SUN8I_HDMI_PHY_CEC_IN_DATA BIT(1)
|
||||
|
||||
struct sun8i_hdmi_phy;
|
||||
|
||||
@@ -151,6 +159,7 @@ struct sun8i_hdmi_phy_variant {
|
||||
bool has_phy_clk;
|
||||
bool has_second_pll;
|
||||
unsigned int is_custom_phy : 1;
|
||||
+ unsigned int bit_bang_cec : 1;
|
||||
const struct dw_hdmi_curr_ctrl *cur_ctr;
|
||||
const struct dw_hdmi_mpll_config *mpll_cfg;
|
||||
const struct dw_hdmi_phy_config *phy_cfg;
|
||||
@@ -163,6 +172,8 @@ struct sun8i_hdmi_phy_variant {
|
||||
};
|
||||
|
||||
struct sun8i_hdmi_phy {
|
||||
+ struct cec_adapter *cec_adapter;
|
||||
+ struct cec_notifier *cec_notifier;
|
||||
struct clk *clk_bus;
|
||||
struct clk *clk_mod;
|
||||
struct clk *clk_phy;
|
||||
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
|
||||
index 66ea3a902e36..70e291353569 100644
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
|
||||
@@ -503,8 +503,9 @@ static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy)
|
||||
regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
|
||||
SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK, 0);
|
||||
|
||||
- /* set HW control of CEC pins */
|
||||
- regmap_write(phy->regs, SUN8I_HDMI_PHY_CEC_REG, 0);
|
||||
+ /* manual control of CEC pins */
|
||||
+ regmap_write(phy->regs, SUN8I_HDMI_PHY_CEC_REG,
|
||||
+ SUN8I_HDMI_PHY_CEC_PIN_CTRL);
|
||||
|
||||
/* read calibration data */
|
||||
regmap_read(phy->regs, SUN8I_HDMI_PHY_ANA_STS_REG, &val);
|
||||
@@ -530,8 +531,49 @@ void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy,
|
||||
plat_data->cur_ctr = variant->cur_ctr;
|
||||
plat_data->phy_config = variant->phy_cfg;
|
||||
}
|
||||
+ plat_data->is_cec_unusable = phy->variant->bit_bang_cec;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_DRM_SUN8I_DW_HDMI_CEC
|
||||
+static bool sun8i_hdmi_phy_cec_pin_read(struct cec_adapter *adap)
|
||||
+{
|
||||
+ struct sun8i_hdmi_phy *phy = cec_get_drvdata(adap);
|
||||
+ unsigned int val;
|
||||
+
|
||||
+ regmap_read(phy->regs, SUN8I_HDMI_PHY_CEC_REG, &val);
|
||||
+
|
||||
+ return val & SUN8I_HDMI_PHY_CEC_IN_DATA;
|
||||
+}
|
||||
+
|
||||
+static void sun8i_hdmi_phy_cec_pin_low(struct cec_adapter *adap)
|
||||
+{
|
||||
+ struct sun8i_hdmi_phy *phy = cec_get_drvdata(adap);
|
||||
+
|
||||
+ /* Start driving the CEC pin low */
|
||||
+ regmap_write(phy->regs, SUN8I_HDMI_PHY_CEC_REG,
|
||||
+ SUN8I_HDMI_PHY_CEC_PIN_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void sun8i_hdmi_phy_cec_pin_high(struct cec_adapter *adap)
|
||||
+{
|
||||
+ struct sun8i_hdmi_phy *phy = cec_get_drvdata(adap);
|
||||
+
|
||||
+ /*
|
||||
+ * Stop driving the CEC pin, the pull up will take over
|
||||
+ * unless another CEC device is driving the pin low.
|
||||
+ */
|
||||
+ regmap_write(phy->regs, SUN8I_HDMI_PHY_CEC_REG,
|
||||
+ SUN8I_HDMI_PHY_CEC_PIN_CTRL |
|
||||
+ SUN8I_HDMI_PHY_CEC_OUT_DIS);
|
||||
+}
|
||||
+
|
||||
+static const struct cec_pin_ops sun8i_hdmi_phy_cec_pin_ops = {
|
||||
+ .read = sun8i_hdmi_phy_cec_pin_read,
|
||||
+ .low = sun8i_hdmi_phy_cec_pin_low,
|
||||
+ .high = sun8i_hdmi_phy_cec_pin_high,
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
static struct regmap_config sun8i_hdmi_phy_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
@@ -548,6 +590,7 @@ static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
|
||||
};
|
||||
|
||||
static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = {
|
||||
+ .bit_bang_cec = true,
|
||||
.has_phy_clk = true,
|
||||
.is_custom_phy = true,
|
||||
.phy_init = &sun8i_hdmi_phy_init_h3,
|
||||
@@ -556,6 +599,7 @@ static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = {
|
||||
};
|
||||
|
||||
static const struct sun8i_hdmi_phy_variant sun8i_r40_hdmi_phy = {
|
||||
+ .bit_bang_cec = true,
|
||||
.has_phy_clk = true,
|
||||
.has_second_pll = true,
|
||||
.is_custom_phy = true,
|
||||
@@ -565,6 +609,7 @@ static const struct sun8i_hdmi_phy_variant sun8i_r40_hdmi_phy = {
|
||||
};
|
||||
|
||||
static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = {
|
||||
+ .bit_bang_cec = true,
|
||||
.has_phy_clk = true,
|
||||
.is_custom_phy = true,
|
||||
.phy_init = &sun8i_hdmi_phy_init_h3,
|
||||
@@ -708,10 +753,40 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
|
||||
goto err_disable_clk_bus;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_DRM_SUN8I_DW_HDMI_CEC
|
||||
+ if (phy->variant->bit_bang_cec) {
|
||||
+ phy->cec_notifier = cec_notifier_get(dev);
|
||||
+ if (!phy->cec_notifier) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_disable_clk_mod;
|
||||
+ }
|
||||
+
|
||||
+ phy->cec_adapter =
|
||||
+ cec_pin_allocate_adapter(&sun8i_hdmi_phy_cec_pin_ops,
|
||||
+ phy, "sun8i-cec",
|
||||
+ CEC_CAP_DEFAULTS);
|
||||
+ ret = PTR_ERR_OR_ZERO(phy->cec_adapter);
|
||||
+ if (ret < 0)
|
||||
+ goto err_put_cec_notifier;
|
||||
+
|
||||
+ ret = cec_register_adapter(phy->cec_adapter, dev);
|
||||
+ if (ret < 0)
|
||||
+ goto err_delete_cec_adapter;
|
||||
+
|
||||
+ cec_register_cec_notifier(phy->cec_adapter, phy->cec_notifier);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
hdmi->phy = phy;
|
||||
|
||||
return 0;
|
||||
|
||||
+err_delete_cec_adapter:
|
||||
+ cec_delete_adapter(phy->cec_adapter);
|
||||
+err_put_cec_notifier:
|
||||
+ cec_notifier_put(phy->cec_notifier);
|
||||
+err_disable_clk_mod:
|
||||
+ clk_disable_unprepare(phy->clk_mod);
|
||||
err_disable_clk_bus:
|
||||
clk_disable_unprepare(phy->clk_bus);
|
||||
err_deassert_rst_phy:
|
||||
@@ -736,6 +811,10 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi)
|
||||
{
|
||||
struct sun8i_hdmi_phy *phy = hdmi->phy;
|
||||
|
||||
+ cec_unregister_adapter(phy->cec_adapter);
|
||||
+ if (phy->cec_notifier)
|
||||
+ cec_notifier_put(phy->cec_notifier);
|
||||
+
|
||||
clk_disable_unprepare(phy->clk_mod);
|
||||
clk_disable_unprepare(phy->clk_bus);
|
||||
clk_disable_unprepare(phy->clk_phy);
|
||||
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
|
||||
index 66e70770cce5..764b8bcfa62c 100644
|
||||
--- a/include/drm/bridge/dw_hdmi.h
|
||||
+++ b/include/drm/bridge/dw_hdmi.h
|
||||
@@ -144,6 +144,8 @@ struct dw_hdmi_plat_data {
|
||||
int (*configure_phy)(struct dw_hdmi *hdmi,
|
||||
const struct dw_hdmi_plat_data *pdata,
|
||||
unsigned long mpixelclock);
|
||||
+
|
||||
+ unsigned int is_cec_unusable : 1;
|
||||
};
|
||||
|
||||
struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
|
@ -0,0 +1,25 @@
|
||||
From 18c9a269e2b744ee84f32de9d5c6c66857725ef8 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 15 Dec 2018 12:56:53 +0100
|
||||
Subject: [PATCH 20/20] cedrus increase frequency
|
||||
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus_hw.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
||||
index b43c77d54b95..70677571f3d3 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
||||
@@ -16,7 +16,7 @@
|
||||
#ifndef _CEDRUS_HW_H_
|
||||
#define _CEDRUS_HW_H_
|
||||
|
||||
-#define CEDRUS_CLOCK_RATE_DEFAULT 320000000
|
||||
+#define CEDRUS_CLOCK_RATE_DEFAULT 402000000
|
||||
|
||||
int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec);
|
||||
void cedrus_engine_disable(struct cedrus_dev *dev);
|
||||
--
|
||||
2.20.0
|
||||
|
@ -0,0 +1,280 @@
|
||||
From patchwork Thu Nov 15 10:39:03 2018
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: [U-Boot,v3] sun8i: h3: Add support for the Beelink-x2 STB
|
||||
X-Patchwork-Submitter: Code Kipper <codekipper@gmail.com>
|
||||
X-Patchwork-Id: 998268
|
||||
Message-Id: <20181115103903.7348-1-codekipper@gmail.com>
|
||||
To: maxime.ripard@free-electrons.com
|
||||
Cc: u-boot@lists.denx.de, linux-sunxi@googlegroups.com, jagan@openedev.com,
|
||||
Marcus Cooper <codekipper@gmail.com>
|
||||
Date: Thu, 15 Nov 2018 11:39:03 +0100
|
||||
From: codekipper@gmail.com
|
||||
List-Id: U-Boot discussion <u-boot.lists.denx.de>
|
||||
|
||||
From: Marcus Cooper <codekipper@gmail.com>
|
||||
|
||||
The Beelink X2 is an STB based on the Allwinner H3 SoC with a uSD slot,
|
||||
2 USB ports( 1 * USB-2 Host, 1 USB OTG), a 10/100M ethernet port using the
|
||||
SoC's integrated PHY, Wifi via an sdio wifi chip, HDMI, an IR receiver, a
|
||||
dual colour LED and an optical S/PDIF connector.
|
||||
|
||||
Signed-off-by: Marcus Cooper <codekipper@gmail.com>
|
||||
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
|
||||
---
|
||||
Changes in v3:
|
||||
- Removed incorrect commit author
|
||||
- Included v1-v2 change info
|
||||
|
||||
Changes in v2:
|
||||
- updated dts to reflex current linux kernel status
|
||||
|
||||
---
|
||||
arch/arm/dts/Makefile | 1 +
|
||||
arch/arm/dts/sun8i-h3-beelink-x2.dts | 179 +++++++++++++++++++++++++++
|
||||
board/sunxi/MAINTAINERS | 5 +
|
||||
configs/beelink_x2_defconfig | 19 +++
|
||||
4 files changed, 204 insertions(+)
|
||||
create mode 100644 arch/arm/dts/sun8i-h3-beelink-x2.dts
|
||||
create mode 100644 configs/beelink_x2_defconfig
|
||||
|
||||
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
|
||||
index 1cbb45d679..cc217d4f98 100644
|
||||
--- a/arch/arm/dts/Makefile
|
||||
+++ b/arch/arm/dts/Makefile
|
||||
@@ -370,6 +370,7 @@ dtb-$(CONFIG_MACH_SUN8I_H3) += \
|
||||
sun8i-h2-plus-orangepi-r1.dtb \
|
||||
sun8i-h2-plus-orangepi-zero.dtb \
|
||||
sun8i-h3-bananapi-m2-plus.dtb \
|
||||
+ sun8i-h3-beelink-x2.dtb \
|
||||
sun8i-h3-libretech-all-h3-cc.dtb \
|
||||
sun8i-h3-nanopi-m1.dtb \
|
||||
sun8i-h3-nanopi-m1-plus.dtb \
|
||||
diff --git a/arch/arm/dts/sun8i-h3-beelink-x2.dts b/arch/arm/dts/sun8i-h3-beelink-x2.dts
|
||||
new file mode 100644
|
||||
index 0000000000..683c5c31a9
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/sun8i-h3-beelink-x2.dts
|
||||
@@ -0,0 +1,180 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+//
|
||||
+// Device Tree Source for Beelink X2
|
||||
+//
|
||||
+// Copyright (C) 2018 Marcus Cooper <codekipper@gmail.com>
|
||||
+/dts-v1/;
|
||||
+#include "sun8i-h3.dtsi"
|
||||
+#include "sunxi-common-regulators.dtsi"
|
||||
+
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include <dt-bindings/input/input.h>
|
||||
+
|
||||
+/ {
|
||||
+ model = "Beelink X2";
|
||||
+ compatible = "roofull,beelink-x2", "allwinner,sun8i-h3";
|
||||
+
|
||||
+ aliases {
|
||||
+ serial0 = &uart0;
|
||||
+ /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */
|
||||
+ ethernet0 = &emac;
|
||||
+ ethernet1 = &sdiowifi;
|
||||
+ };
|
||||
+
|
||||
+ chosen {
|
||||
+ stdout-path = "serial0:115200n8";
|
||||
+ };
|
||||
+
|
||||
+ connector {
|
||||
+ compatible = "hdmi-connector";
|
||||
+ type = "a";
|
||||
+
|
||||
+ port {
|
||||
+ hdmi_con_in: endpoint {
|
||||
+ remote-endpoint = <&hdmi_out_con>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+
|
||||
+ blue {
|
||||
+ label = "beelink-x2:blue:pwr";
|
||||
+ gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */
|
||||
+ default-state = "on";
|
||||
+ };
|
||||
+
|
||||
+ red {
|
||||
+ label = "beelink-x2:red:standby";
|
||||
+ gpios = <&pio 0 15 GPIO_ACTIVE_HIGH>; /* PA15 */
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ wifi_pwrseq: wifi_pwrseq {
|
||||
+ compatible = "mmc-pwrseq-simple";
|
||||
+ reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
|
||||
+ };
|
||||
+
|
||||
+ sound_spdif {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "On-board SPDIF";
|
||||
+
|
||||
+ simple-audio-card,cpu {
|
||||
+ sound-dai = <&spdif>;
|
||||
+ };
|
||||
+
|
||||
+ simple-audio-card,codec {
|
||||
+ sound-dai = <&spdif_out>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ spdif_out: spdif-out {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "linux,spdif-dit";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&de {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ehci0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ehci1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&emac {
|
||||
+ phy-handle = <&int_mii_phy>;
|
||||
+ phy-mode = "mii";
|
||||
+ allwinner,leds-active-low;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi_out {
|
||||
+ hdmi_out_con: endpoint {
|
||||
+ remote-endpoint = <&hdmi_con_in>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&ir {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&ir_pins_a>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&mmc0 {
|
||||
+ vmmc-supply = <®_vcc3v3>;
|
||||
+ bus-width = <4>;
|
||||
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&mmc1 {
|
||||
+ vmmc-supply = <®_vcc3v3>;
|
||||
+ bus-width = <4>;
|
||||
+ non-removable;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ /*
|
||||
+ * Explicitly define the sdio device, so that we can add an ethernet
|
||||
+ * alias for it (which e.g. makes u-boot set a mac-address).
|
||||
+ */
|
||||
+ sdiowifi: sdio_wifi@1 {
|
||||
+ reg = <1>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&mmc2 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&mmc2_8bit_pins>;
|
||||
+ vmmc-supply = <®_vcc3v3>;
|
||||
+ bus-width = <8>;
|
||||
+ non-removable;
|
||||
+ cap-mmc-hw-reset;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ohci0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ohci1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+®_usb0_vbus {
|
||||
+ gpio = <&r_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&spdif {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&spdif_tx_pins_a>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&uart0 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart0_pins_a>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb_otg {
|
||||
+ dr_mode = "otg";
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usbphy {
|
||||
+ /* USB VBUS is always on except for the OTG port */
|
||||
+ status = "okay";
|
||||
+ usb0_id_det-gpios = <&pio 0 7 GPIO_ACTIVE_HIGH>; /* PA07 */
|
||||
+ usb0_vbus-supply = <®_usb0_vbus>;
|
||||
+};
|
||||
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
|
||||
index 478e37285f..6417158fd1 100644
|
||||
--- a/board/sunxi/MAINTAINERS
|
||||
+++ b/board/sunxi/MAINTAINERS
|
||||
@@ -159,6 +159,11 @@ M: Jagan Teki <jagan@amarulasolutions.com>
|
||||
S: Maintained
|
||||
F: configs/bananapi_m64_defconfig
|
||||
|
||||
+BEELINK X2 BOARD
|
||||
+M: Marcus Cooper <codekipper@gmail.com>
|
||||
+S: Maintained
|
||||
+F: configs/beelink_x2_defconfig
|
||||
+
|
||||
COLOMBUS BOARD
|
||||
M: Maxime Ripard <maxime.ripard@bootlin.com>
|
||||
S: Maintained
|
||||
diff --git a/configs/beelink_x2_defconfig b/configs/beelink_x2_defconfig
|
||||
new file mode 100644
|
||||
index 0000000000..6508e470a0
|
||||
--- /dev/null
|
||||
+++ b/configs/beelink_x2_defconfig
|
||||
@@ -0,0 +1,19 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_ARCH_SUNXI=y
|
||||
+CONFIG_SPL=y
|
||||
+CONFIG_MACH_SUN8I_H3=y
|
||||
+CONFIG_DRAM_CLK=624
|
||||
+CONFIG_DRAM_ZQ=3881979
|
||||
+CONFIG_DRAM_ODT_EN=y
|
||||
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-beelink-x2"
|
||||
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
+CONFIG_CONSOLE_MUX=y
|
||||
+CONFIG_SPL_I2C_SUPPORT=y
|
||||
+# CONFIG_CMD_FLASH is not set
|
||||
+# CONFIG_SPL_DOS_PARTITION is not set
|
||||
+# CONFIG_SPL_EFI_PARTITION is not set
|
||||
+CONFIG_SUN8I_EMAC=y
|
||||
+CONFIG_SY8106A_POWER=y
|
||||
+CONFIG_USB_EHCI_HCD=y
|
||||
+CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
|
@ -0,0 +1,13 @@
|
||||
diff -Nur a/arch/arm/Kconfig usb/arch/arm/Kconfig
|
||||
--- a/arch/arm/Kconfig 2016-09-12 16:05:51.000000000 +0200
|
||||
+++ usb/arch/arm/Kconfig 2016-09-21 19:19:44.533396743 +0200
|
||||
@@ -590,9 +590,8 @@
|
||||
select SPL_SYS_THUMB_BUILD if !ARM64
|
||||
select SYS_NS16550
|
||||
select SYS_THUMB_BUILD if !ARM64
|
||||
select USB if DISTRO_DEFAULTS
|
||||
- select USB_KEYBOARD if DISTRO_DEFAULTS
|
||||
select USB_STORAGE if DISTRO_DEFAULTS
|
||||
select USE_TINY_PRINTF
|
||||
imply CMD_DM
|
||||
imply CMD_GPT
|
135
projects/Allwinner/patches/u-boot/003-fix-hdmi-clocks.patch
Normal file
135
projects/Allwinner/patches/u-boot/003-fix-hdmi-clocks.patch
Normal file
@ -0,0 +1,135 @@
|
||||
diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c
|
||||
index 9dbea649a0..a2aced2cab 100644
|
||||
--- a/drivers/video/sunxi/sunxi_dw_hdmi.c
|
||||
+++ b/drivers/video/sunxi/sunxi_dw_hdmi.c
|
||||
@@ -132,7 +132,7 @@ static int sunxi_dw_hdmi_wait_for_hpd(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
-static void sunxi_dw_hdmi_phy_set(uint clock)
|
||||
+static void sunxi_dw_hdmi_phy_set(uint clock, int phy_div)
|
||||
{
|
||||
struct sunxi_hdmi_phy * const phy =
|
||||
(struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS);
|
||||
@@ -146,7 +146,7 @@ static void sunxi_dw_hdmi_phy_set(uint clock)
|
||||
switch (div) {
|
||||
case 1:
|
||||
writel(0x30dc5fc0, &phy->pll);
|
||||
- writel(0x800863C0, &phy->clk);
|
||||
+ writel(0x800863C0 | (phy_div - 1), &phy->clk);
|
||||
mdelay(10);
|
||||
writel(0x00000001, &phy->unk3);
|
||||
setbits_le32(&phy->pll, BIT(25));
|
||||
@@ -164,7 +164,7 @@ static void sunxi_dw_hdmi_phy_set(uint clock)
|
||||
break;
|
||||
case 2:
|
||||
writel(0x39dc5040, &phy->pll);
|
||||
- writel(0x80084381, &phy->clk);
|
||||
+ writel(0x80084380 | (phy_div - 1), &phy->clk);
|
||||
mdelay(10);
|
||||
writel(0x00000001, &phy->unk3);
|
||||
setbits_le32(&phy->pll, BIT(25));
|
||||
@@ -178,7 +178,7 @@ static void sunxi_dw_hdmi_phy_set(uint clock)
|
||||
break;
|
||||
case 4:
|
||||
writel(0x39dc5040, &phy->pll);
|
||||
- writel(0x80084343, &phy->clk);
|
||||
+ writel(0x80084340 | (phy_div - 1), &phy->clk);
|
||||
mdelay(10);
|
||||
writel(0x00000001, &phy->unk3);
|
||||
setbits_le32(&phy->pll, BIT(25));
|
||||
@@ -192,7 +192,7 @@ static void sunxi_dw_hdmi_phy_set(uint clock)
|
||||
break;
|
||||
case 11:
|
||||
writel(0x39dc5040, &phy->pll);
|
||||
- writel(0x8008430a, &phy->clk);
|
||||
+ writel(0x80084300 | (phy_div - 1), &phy->clk);
|
||||
mdelay(10);
|
||||
writel(0x00000001, &phy->unk3);
|
||||
setbits_le32(&phy->pll, BIT(25));
|
||||
@@ -207,36 +207,46 @@ static void sunxi_dw_hdmi_phy_set(uint clock)
|
||||
}
|
||||
}
|
||||
|
||||
-static void sunxi_dw_hdmi_pll_set(uint clk_khz)
|
||||
+static void sunxi_dw_hdmi_pll_set(uint clk_khz, int *phy_div)
|
||||
{
|
||||
- int value, n, m, div = 0, diff;
|
||||
- int best_n = 0, best_m = 0, best_diff = 0x0FFFFFFF;
|
||||
-
|
||||
- div = sunxi_dw_hdmi_get_divider(clk_khz * 1000);
|
||||
+ int value, n, m, div, diff;
|
||||
+ int best_n = 0, best_m = 0, best_div = 0, best_diff = 0x0FFFFFFF;
|
||||
|
||||
/*
|
||||
* Find the lowest divider resulting in a matching clock. If there
|
||||
* is no match, pick the closest lower clock, as monitors tend to
|
||||
* not sync to higher frequencies.
|
||||
*/
|
||||
- for (m = 1; m <= 16; m++) {
|
||||
- n = (m * div * clk_khz) / 24000;
|
||||
-
|
||||
- if ((n >= 1) && (n <= 128)) {
|
||||
- value = (24000 * n) / m / div;
|
||||
- diff = clk_khz - value;
|
||||
- if (diff < best_diff) {
|
||||
- best_diff = diff;
|
||||
- best_m = m;
|
||||
- best_n = n;
|
||||
+ for (div = 1; div <= 16; div++) {
|
||||
+ int target = clk_khz * div;
|
||||
+
|
||||
+ if (target < 192000)
|
||||
+ continue;
|
||||
+ if (target > 912000)
|
||||
+ continue;
|
||||
+
|
||||
+ for (m = 1; m <= 16; m++) {
|
||||
+ n = (m * target) / 24000;
|
||||
+
|
||||
+ if ((n >= 1) && (n <= 128)) {
|
||||
+ value = (24000 * n) / m / div;
|
||||
+ diff = clk_khz - value;
|
||||
+ if (diff < best_diff) {
|
||||
+ best_diff = diff;
|
||||
+ best_m = m;
|
||||
+ best_n = n;
|
||||
+ best_div = div;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ *phy_div = best_div;
|
||||
+
|
||||
clock_set_pll3_factors(best_m, best_n);
|
||||
debug("dotclock: %dkHz = %dkHz: (24MHz * %d) / %d / %d\n",
|
||||
- clk_khz, (clock_get_pll3() / 1000) / div,
|
||||
- best_n, best_m, div);
|
||||
+ clk_khz, (clock_get_pll3() / 1000) / best_div,
|
||||
+ best_n, best_m, best_div);
|
||||
}
|
||||
|
||||
static void sunxi_dw_hdmi_lcdc_init(int mux, const struct display_timing *edid,
|
||||
@@ -244,7 +254,7 @@ static void sunxi_dw_hdmi_lcdc_init(int mux, const struct display_timing *edid,
|
||||
{
|
||||
struct sunxi_ccm_reg * const ccm =
|
||||
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
|
||||
- int div = sunxi_dw_hdmi_get_divider(edid->pixelclock.typ);
|
||||
+ int div = clock_get_pll3() / edid->pixelclock.typ;
|
||||
struct sunxi_lcdc_reg *lcdc;
|
||||
|
||||
if (mux == 0) {
|
||||
@@ -276,8 +286,10 @@ static void sunxi_dw_hdmi_lcdc_init(int mux, const struct display_timing *edid,
|
||||
|
||||
static int sunxi_dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock)
|
||||
{
|
||||
- sunxi_dw_hdmi_pll_set(mpixelclock/1000);
|
||||
- sunxi_dw_hdmi_phy_set(mpixelclock);
|
||||
+ int phy_div;
|
||||
+
|
||||
+ sunxi_dw_hdmi_pll_set(mpixelclock/1000, &phy_div);
|
||||
+ sunxi_dw_hdmi_phy_set(mpixelclock, phy_div);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user