mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
Merge pull request #3405 from LibreELEC/allwinner
Add Allwinner project
This commit is contained in:
commit
afae8c6a20
@ -2,6 +2,7 @@
|
||||
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
|
||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
||||
|
||||
# setup alsa (especially the mixer config)
|
||||
|
||||
@ -114,6 +115,13 @@ else
|
||||
|
||||
# NVidia CK804 sound devices
|
||||
mixer $card 'IEC958 Playback AC97-SPSA' 100%
|
||||
|
||||
# Allwinner H3 Analog
|
||||
mixer $card 'Line Out' 0db on
|
||||
|
||||
# Allwinner A64 Analog
|
||||
mixer $card Headphone 0db on
|
||||
mixer $card 'AIF1 Slot 0 Digital DAC' on
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
27
packages/linux-drivers/gpu-sunxi-midgard/package.mk
Normal file
27
packages/linux-drivers/gpu-sunxi-midgard/package.mk
Normal file
@ -0,0 +1,27 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
||||
|
||||
PKG_NAME="gpu-sunxi-midgard"
|
||||
PKG_VERSION="r22p0-01rel0"
|
||||
PKG_SHA256="02f80e777dc945d645fce888afc926555ec61b70079c1da289bf1a3a9544452f"
|
||||
PKG_ARCH="arm aarch64"
|
||||
PKG_LICENSE="GPL"
|
||||
PKG_SITE="https://developer.arm.com/products/software/mali-drivers/"
|
||||
PKG_URL="https://developer.arm.com/-/media/Files/downloads/mali-drivers/kernel/mali-midgard-gpu/TX011-SW-99002-$PKG_VERSION.tgz"
|
||||
PKG_DEPENDS_TARGET="toolchain linux"
|
||||
PKG_NEED_UNPACK="$LINUX_DEPENDS"
|
||||
PKG_LONGDESC="gpu-sunxi-midgard: Linux drivers for Mali GPUs found in Allwinner SoCs"
|
||||
PKG_TOOLCHAIN="manual"
|
||||
PKG_IS_KERNEL_PKG="yes"
|
||||
|
||||
make_target() {
|
||||
kernel_make -C $(kernel_path) M=$PKG_BUILD/driver/product/kernel/drivers/gpu/arm/midgard/ \
|
||||
EXTRA_CFLAGS="-DCONFIG_MALI_PLATFORM_DEVICETREE -DCONFIG_MALI_BACKEND=gpu -DCONFIG_MALI_DEVFREQ" CONFIG_MALI_DEVFREQ=y \
|
||||
CONFIG_MALI_MIDGARD=m CONFIG_MALI_PLATFORM_DEVICETREE=y CONFIG_MALI_BACKEND=gpu modules
|
||||
}
|
||||
|
||||
makeinstall_target() {
|
||||
kernel_make -C $(kernel_path) M=$PKG_BUILD/driver/product/kernel/drivers/gpu/arm/midgard/ \
|
||||
INSTALL_MOD_PATH=$INSTALL/$(get_kernel_overlay_dir) INSTALL_MOD_STRIP=1 DEPMOD=: \
|
||||
modules_install
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
diff -Nur a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c
|
||||
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c 2018-03-06 18:05:25.000000000 +0100
|
||||
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c 2018-04-04 22:26:50.310273475 +0200
|
||||
@@ -3225,6 +3225,20 @@
|
||||
}
|
||||
#endif /* LINUX_VERSION_CODE >= 3, 12, 0 */
|
||||
|
||||
+ kbdev->mali_rst = of_reset_control_get_by_index(kbdev->dev->of_node, 0);
|
||||
+ if (IS_ERR(kbdev->mali_rst)) {
|
||||
+ dev_err(kbdev->dev, "Couldn't get mali reset line\n");
|
||||
+ err = PTR_ERR(kbdev->mali_rst);
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ kbdev->bus_clk = of_clk_get(kbdev->dev->of_node, 1);
|
||||
+ if (IS_ERR(kbdev->bus_clk)) {
|
||||
+ dev_err(kbdev->dev, "Couldn't get the mali bus clock\n");
|
||||
+ err = PTR_ERR(kbdev->bus_clk);
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
kbdev->clock = of_clk_get(kbdev->dev->of_node, 0);
|
||||
if (IS_ERR_OR_NULL(kbdev->clock)) {
|
||||
err = PTR_ERR(kbdev->clock);
|
||||
@@ -3236,6 +3250,8 @@
|
||||
dev_info(kbdev->dev, "Continuing without Mali clock control\n");
|
||||
/* Allow probe to continue without clock. */
|
||||
} else {
|
||||
+ reset_control_deassert(kbdev->mali_rst);
|
||||
+ clk_prepare_enable(kbdev->bus_clk);
|
||||
err = clk_prepare_enable(kbdev->clock);
|
||||
if (err) {
|
||||
dev_err(kbdev->dev,
|
||||
@@ -3268,6 +3284,16 @@
|
||||
kbdev->clock = NULL;
|
||||
}
|
||||
|
||||
+if (kbdev->bus_clk) {
|
||||
+ clk_put(kbdev->bus_clk);
|
||||
+ kbdev->bus_clk = NULL;
|
||||
+}
|
||||
+
|
||||
+if (kbdev->mali_rst) {
|
||||
+ reset_control_put(kbdev->mali_rst);
|
||||
+ kbdev->mali_rst = NULL;
|
||||
+}
|
||||
+
|
||||
#ifdef CONFIG_REGULATOR
|
||||
if (NULL != kbdev->regulator) {
|
||||
regulator_put(kbdev->regulator);
|
||||
@@ -3293,6 +3319,18 @@
|
||||
kbdev->clock = NULL;
|
||||
}
|
||||
|
||||
+ if (kbdev->bus_clk) {
|
||||
+ clk_disable_unprepare(kbdev->bus_clk);
|
||||
+ clk_put(kbdev->bus_clk);
|
||||
+ kbdev->bus_clk = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (kbdev->mali_rst) {
|
||||
+ reset_control_assert(kbdev->mali_rst);
|
||||
+ reset_control_put(kbdev->mali_rst);
|
||||
+ kbdev->mali_rst = NULL;
|
||||
+ }
|
||||
+
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) && defined(CONFIG_OF) \
|
||||
&& defined(CONFIG_REGULATOR)
|
||||
if (kbdev->regulator) {
|
||||
diff -Nur a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h
|
||||
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h 2018-03-06 18:05:25.000000000 +0100
|
||||
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h 2018-04-04 22:05:56.017916193 +0200
|
||||
@@ -68,6 +68,7 @@
|
||||
#endif /* CONFIG_MALI_DEVFREQ */
|
||||
|
||||
#include <linux/clk.h>
|
||||
+#include <linux/reset.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#if defined(CONFIG_PM_RUNTIME) || \
|
||||
@@ -1434,6 +1435,8 @@
|
||||
} irqs[3];
|
||||
|
||||
struct clk *clock;
|
||||
+ struct clk *bus_clk;
|
||||
+ struct reset_control *mali_rst;
|
||||
#ifdef CONFIG_REGULATOR
|
||||
struct regulator *regulator;
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,98 @@
|
||||
From ee7f0a678fff8316ec0be973f1b3780a63f50942 Mon Sep 17 00:00:00 2001
|
||||
From: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
Date: Mon, 11 Dec 2017 21:04:56 +0100
|
||||
Subject: [PATCH] gpu: arm: Midgard: setup_timer() -> timer_setup()
|
||||
|
||||
This patch is due the changes provoked by series of commit ending
|
||||
at 513ae785c63c30741e46f43960213d4ae5382ec0, and removing the
|
||||
setup_timer macros.
|
||||
The previous patches replaced made sure that timers were all set
|
||||
up with setup_timer and replaced setup_timer calls by timer_setup
|
||||
calls.
|
||||
|
||||
This changed was introduced in the 4.15-rc1.
|
||||
|
||||
Signed-off-by: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
---
|
||||
drivers/gpu/arm/midgard/mali_kbase.h | 2 +-
|
||||
drivers/gpu/arm/midgard/mali_kbase_context.c | 4 ++--
|
||||
drivers/gpu/arm/midgard/mali_kbase_softjobs.c | 4 ++--
|
||||
drivers/gpu/arm/midgard/mali_kbase_tlstream.c | 6 ++----
|
||||
4 files changed, 7 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase.h
|
||||
index a4ceab9e0..27bde3b71 100644
|
||||
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase.h
|
||||
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase.h
|
||||
@@ -213,7 +213,7 @@ int kbase_soft_event_update(struct kbase_context *kctx,
|
||||
|
||||
bool kbase_replay_process(struct kbase_jd_atom *katom);
|
||||
|
||||
-void kbasep_soft_job_timeout_worker(unsigned long data);
|
||||
+void kbasep_soft_job_timeout_worker(struct timer_list *t);
|
||||
void kbasep_complete_triggered_soft_events(struct kbase_context *kctx, u64 evt);
|
||||
|
||||
/* api used internally for register access. Contains validation and tracing */
|
||||
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_context.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_context.c
|
||||
index f43db48fd..589df768c 100644
|
||||
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_context.c
|
||||
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_context.c
|
||||
@@ -165,9 +165,9 @@ kbase_create_context(struct kbase_device *kbdev, bool is_compat)
|
||||
|
||||
mutex_init(&kctx->vinstr_cli_lock);
|
||||
|
||||
- setup_timer(&kctx->soft_job_timeout,
|
||||
+ timer_setup(&kctx->soft_job_timeout,
|
||||
kbasep_soft_job_timeout_worker,
|
||||
- (uintptr_t)kctx);
|
||||
+ 0);
|
||||
|
||||
return kctx;
|
||||
|
||||
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_softjobs.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_softjobs.c
|
||||
index 127ada07f..019edf562 100644
|
||||
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_softjobs.c
|
||||
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_softjobs.c
|
||||
@@ -370,9 +370,9 @@ static void kbase_fence_debug_timeout(struct kbase_jd_atom *katom)
|
||||
}
|
||||
#endif /* CONFIG_MALI_FENCE_DEBUG */
|
||||
|
||||
-void kbasep_soft_job_timeout_worker(unsigned long data)
|
||||
+void kbasep_soft_job_timeout_worker(struct timer_list *t)
|
||||
{
|
||||
- struct kbase_context *kctx = (struct kbase_context *)data;
|
||||
+ struct kbase_context *kctx = from_timer(kctx, t, soft_job_timeout);
|
||||
u32 timeout_ms = (u32)atomic_read(
|
||||
&kctx->kbdev->js_data.soft_job_timeout_ms);
|
||||
struct timer_list *timer = &kctx->soft_job_timeout;
|
||||
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.c
|
||||
index d01aa23b2..11d8b59c7 100644
|
||||
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.c
|
||||
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.c
|
||||
@@ -1042,13 +1042,11 @@ static void kbasep_tlstream_flush_stream(enum tl_stream_type stype)
|
||||
* Timer is executed periodically to check if any of the stream contains
|
||||
* buffer ready to be submitted to user space.
|
||||
*/
|
||||
-static void kbasep_tlstream_autoflush_timer_callback(unsigned long data)
|
||||
+static void kbasep_tlstream_autoflush_timer_callback(struct timer_list *unused)
|
||||
{
|
||||
enum tl_stream_type stype;
|
||||
int rcode;
|
||||
|
||||
- CSTD_UNUSED(data);
|
||||
-
|
||||
for (stype = 0; stype < TL_STREAM_TYPE_COUNT; stype++) {
|
||||
struct tl_stream *stream = tl_stream[stype];
|
||||
unsigned long flags;
|
||||
@@ -1371,7 +1369,7 @@ int kbase_tlstream_init(void)
|
||||
|
||||
/* Initialize autoflush timer. */
|
||||
atomic_set(&autoflush_timer_active, 0);
|
||||
- setup_timer(&autoflush_timer,
|
||||
+ timer_setup(&autoflush_timer,
|
||||
kbasep_tlstream_autoflush_timer_callback,
|
||||
0);
|
||||
|
||||
--
|
||||
2.14.1
|
||||
|
@ -0,0 +1,35 @@
|
||||
From 44a5ba2e969adfb64c84f294c16490194988dcc7 Mon Sep 17 00:00:00 2001
|
||||
From: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
Date: Sun, 24 Dec 2017 19:30:12 +0100
|
||||
Subject: [PATCH] drivers: gpu: Arm: Midgard: Replace ACCESS_ONCE by READ_ONCE
|
||||
|
||||
The ACCESS_ONCE macro has now been removed in the 4.15.0-rc4,
|
||||
and every ACCESS_ONCE call has been replaced by either READ_ONCE or
|
||||
WRITE_ONCE calls.
|
||||
Since the Midgard GPU drivers are not mainlined, the change
|
||||
needs to be applied manually.
|
||||
|
||||
See commit b899a850431e2dd0943205a63a68573f3e312d0d and its parents,
|
||||
for more informations.
|
||||
|
||||
Signed-off-by: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
---
|
||||
drivers/gpu/arm/midgard/mali_kbase_mem.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.h
|
||||
index e9a8d5dd6..eac685699 100644
|
||||
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.h
|
||||
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.h
|
||||
@@ -591,7 +591,7 @@ void kbase_mem_pool_free_pages(struct kbase_mem_pool *pool, size_t nr_pages,
|
||||
*/
|
||||
static inline size_t kbase_mem_pool_size(struct kbase_mem_pool *pool)
|
||||
{
|
||||
- return ACCESS_ONCE(pool->cur_size);
|
||||
+ return READ_ONCE(pool->cur_size);
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
2.14.1
|
||||
|
@ -0,0 +1,32 @@
|
||||
From 47e8aad9419ff8843a373c3e5aa2c9d261d8cd07 Mon Sep 17 00:00:00 2001
|
||||
From: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
Date: Mon, 23 Apr 2018 20:54:13 +0200
|
||||
Subject: [PATCH] gpu: arm: midgard: Remove sys_close references
|
||||
|
||||
sys_close is now replaced by ksys_close in an effort to remove
|
||||
in-kernel system calls references.
|
||||
|
||||
See 2ca2a09d6215fd9621aa3e2db7cc9428a61f2911 and
|
||||
https://lkml.org/lkml/2018/3/25/93 for more details.
|
||||
|
||||
Signed-off-by: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
---
|
||||
drivers/gpu/arm/midgard/mali_kbase_sync.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_sync.h b/drivers/gpu/arm/midgard/mali_kbase_sync.h
|
||||
index de72147d..33b58059 100644
|
||||
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_sync.h
|
||||
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_sync.h
|
||||
@@ -156,7 +156,7 @@ void kbase_sync_fence_out_remove(struct kbase_jd_atom *katom);
|
||||
*/
|
||||
static inline void kbase_sync_fence_close_fd(int fd)
|
||||
{
|
||||
- sys_close(fd);
|
||||
+ ksys_close(fd);
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
2.14.1
|
||||
|
@ -0,0 +1,60 @@
|
||||
diff -Nur a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c c/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c
|
||||
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c 2018-12-01 17:49:08.000000000 +0100
|
||||
+++ c/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c 2018-12-01 20:27:42.057964019 +0100
|
||||
@@ -1668,6 +1668,7 @@
|
||||
struct kbase_cpu_mapping *map = vma->vm_private_data;
|
||||
pgoff_t rel_pgoff;
|
||||
size_t i;
|
||||
+ int ret = VM_FAULT_SIGBUS;
|
||||
pgoff_t addr;
|
||||
|
||||
KBASE_DEBUG_ASSERT(map);
|
||||
@@ -1693,9 +1694,9 @@
|
||||
addr = (pgoff_t)(vmf->address >> PAGE_SHIFT);
|
||||
#endif
|
||||
while (i < map->alloc->nents && (addr < vma->vm_end >> PAGE_SHIFT)) {
|
||||
- int ret = vm_insert_pfn(vma, addr << PAGE_SHIFT,
|
||||
+ ret = vmf_insert_pfn(vma, addr << PAGE_SHIFT,
|
||||
PFN_DOWN(as_phys_addr_t(map->alloc->pages[i])));
|
||||
- if (ret < 0 && ret != -EBUSY)
|
||||
+ if (unlikely(ret & VM_FAULT_ERROR))
|
||||
goto locked_bad_fault;
|
||||
|
||||
i++; addr++;
|
||||
@@ -1707,7 +1708,7 @@
|
||||
|
||||
locked_bad_fault:
|
||||
kbase_gpu_vm_unlock(map->kctx);
|
||||
- return VM_FAULT_SIGBUS;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
const struct vm_operations_struct kbase_vm_ops = {
|
||||
@@ -1776,10 +1777,11 @@
|
||||
phys_addr_t phys;
|
||||
|
||||
phys = as_phys_addr_t(page_array[i + start_off]);
|
||||
- err = vm_insert_pfn(vma, addr, PFN_DOWN(phys));
|
||||
- if (WARN_ON(err))
|
||||
+ err = vmf_insert_pfn(vma, addr, PFN_DOWN(phys));
|
||||
+ if (unlikely(WARN_ON(err & VM_FAULT_ERROR)))
|
||||
break;
|
||||
|
||||
+ err = 0;
|
||||
addr += PAGE_SIZE;
|
||||
}
|
||||
} else {
|
||||
diff -Nur a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_smc.c c/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_smc.c
|
||||
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_smc.c 2018-01-13 23:26:00.000000000 +0100
|
||||
+++ c/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_smc.c 2018-12-01 20:03:30.071690693 +0100
|
||||
@@ -27,6 +27,10 @@
|
||||
|
||||
#include <linux/compiler.h>
|
||||
|
||||
+#ifndef __asmeq
|
||||
+#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
|
||||
+#endif
|
||||
+
|
||||
static noinline u64 invoke_smc_fid(u64 function_id,
|
||||
u64 arg0, u64 arg1, u64 arg2)
|
||||
{
|
@ -0,0 +1,30 @@
|
||||
diff -Nur a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c
|
||||
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c 2018-12-01 21:10:15.000000000 +0100
|
||||
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c 2018-12-01 23:28:48.956901556 +0100
|
||||
@@ -3815,12 +3815,18 @@
|
||||
"Continuing without Mali regulator control\n");
|
||||
/* Allow probe to continue without regulator */
|
||||
}
|
||||
+ err = regulator_enable(kbdev->regulator);
|
||||
+ if (err) {
|
||||
+ dev_err(kbdev->dev, "Failed to enable regulator\n");
|
||||
+ return err;
|
||||
+ }
|
||||
#endif /* LINUX_VERSION_CODE >= 3, 12, 0 */
|
||||
|
||||
kbdev->mali_rst = of_reset_control_get_by_index(kbdev->dev->of_node, 0);
|
||||
if (IS_ERR(kbdev->mali_rst)) {
|
||||
dev_err(kbdev->dev, "Couldn't get mali reset line\n");
|
||||
err = PTR_ERR(kbdev->mali_rst);
|
||||
+ kbdev->mali_rst = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -3828,6 +3834,7 @@
|
||||
if (IS_ERR(kbdev->bus_clk)) {
|
||||
dev_err(kbdev->dev, "Couldn't get the mali bus clock\n");
|
||||
err = PTR_ERR(kbdev->bus_clk);
|
||||
+ kbdev->bus_clk = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
diff -Nur a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpuprops.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpuprops.c
|
||||
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpuprops.c 2019-02-09 23:20:20.000000000 +0100
|
||||
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpuprops.c 2019-02-10 08:26:47.874751287 +0100
|
||||
@@ -243,7 +243,11 @@
|
||||
/* Populate the base_gpu_props structure */
|
||||
kbase_gpuprops_update_core_props_gpu_id(gpu_props);
|
||||
gpu_props->core_props.log2_program_counter_size = KBASE_GPU_PC_SIZE_LOG2;
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0)
|
||||
+ gpu_props->core_props.gpu_available_memory_size = totalram_pages() << PAGE_SHIFT;
|
||||
+#else
|
||||
gpu_props->core_props.gpu_available_memory_size = totalram_pages << PAGE_SHIFT;
|
||||
+#endif
|
||||
|
||||
for (i = 0; i < BASE_GPU_NUM_TEXTURE_FEATURES_REGISTERS; i++)
|
||||
gpu_props->core_props.texture_features[i] = gpu_props->raw_props.texture_features[i];
|
28
packages/linux-drivers/gpu-sunxi/package.mk
Normal file
28
packages/linux-drivers/gpu-sunxi/package.mk
Normal file
@ -0,0 +1,28 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
||||
|
||||
PKG_NAME="gpu-sunxi"
|
||||
PKG_VERSION="r9p0-01rel0"
|
||||
PKG_SHA256="7a67127341d17640c1fff5dad80258fb2a37c8a2121b81525fe2327e4532ce2b"
|
||||
PKG_ARCH="arm aarch64"
|
||||
PKG_LICENSE="GPL"
|
||||
PKG_SITE="https://developer.arm.com/products/software/mali-drivers/utgard-kernel"
|
||||
PKG_URL="https://developer.arm.com/-/media/Files/downloads/mali-drivers/kernel/mali-utgard-gpu/DX910-SW-99002-$PKG_VERSION.tgz"
|
||||
PKG_DEPENDS_TARGET="toolchain linux"
|
||||
PKG_NEED_UNPACK="$LINUX_DEPENDS"
|
||||
PKG_LONGDESC="gpu-sunxi: Linux drivers for Mali GPUs found in Allwinner SoCs"
|
||||
PKG_TOOLCHAIN="manual"
|
||||
PKG_IS_KERNEL_PKG="yes"
|
||||
|
||||
make_target() {
|
||||
kernel_make -C $(kernel_path) M=$PKG_BUILD/driver/src/devicedrv/mali/ \
|
||||
MALI_PLATFORM_FILES=platform/sunxi/sunxi.c \
|
||||
EXTRA_CFLAGS="-DMALI_FAKE_PLATFORM_DEVICE=1 -DCONFIG_MALI_DMA_BUF_MAP_ON_ATTACH" \
|
||||
CONFIG_MALI400=m
|
||||
}
|
||||
|
||||
makeinstall_target() {
|
||||
kernel_make -C $(kernel_path) M=$PKG_BUILD/driver/src/devicedrv/mali/ \
|
||||
INSTALL_MOD_PATH=$INSTALL/$(get_kernel_overlay_dir) INSTALL_MOD_STRIP=1 DEPMOD=: \
|
||||
modules_install
|
||||
}
|
@ -0,0 +1,426 @@
|
||||
From 2b56fc78a4acbffbdebf5b690035d1ba70ef592c Mon Sep 17 00:00:00 2001
|
||||
From: Maxime Ripard <maxime.ripard@free-electrons.com>
|
||||
Date: Tue, 29 Nov 2016 10:18:40 +0100
|
||||
Subject: [PATCH 4/4] mali: Add sunxi platform
|
||||
|
||||
Add a platform for the Mali GPU integrated in the Allwinner SoCs.
|
||||
|
||||
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
|
||||
---
|
||||
src/devicedrv/mali/platform/sunxi/sunxi.c | 404 +++++++++++++++++++++++
|
||||
1 file changed, 404 insertions(+)
|
||||
create mode 100644 src/devicedrv/mali/platform/sunxi/sunxi.c
|
||||
|
||||
--- /dev/null
|
||||
+++ b/driver/src/devicedrv/mali/platform/sunxi/sunxi.c
|
||||
@@ -0,0 +1,410 @@
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/clkdev.h>
|
||||
+#include <linux/cma.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/dma-contiguous.h>
|
||||
+#include <linux/dma-mapping.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/of_reserved_mem.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#include <linux/clk/clk-conf.h>
|
||||
+
|
||||
+#include <linux/mali/mali_utgard.h>
|
||||
+
|
||||
+#include "mali_kernel_linux.h"
|
||||
+
|
||||
+struct mali {
|
||||
+ struct clk *bus_clk;
|
||||
+ struct clk *core_clk;
|
||||
+
|
||||
+ struct reset_control *reset;
|
||||
+
|
||||
+ struct platform_device *dev;
|
||||
+};
|
||||
+
|
||||
+struct mali *mali;
|
||||
+
|
||||
+struct resource *mali_create_mp1_resources(unsigned long address,
|
||||
+ int irq_gp, int irq_gpmmu,
|
||||
+ int irq_pp0, int irq_ppmmu0,
|
||||
+ int *len)
|
||||
+{
|
||||
+ struct resource target[] = {
|
||||
+ MALI_GPU_RESOURCES_MALI400_MP1_PMU(address,
|
||||
+ irq_gp, irq_gpmmu,
|
||||
+ irq_pp0, irq_ppmmu0)
|
||||
+ };
|
||||
+ struct resource *res;
|
||||
+
|
||||
+ res = kzalloc(sizeof(target), GFP_KERNEL);
|
||||
+ if (!res)
|
||||
+ return NULL;
|
||||
+
|
||||
+ memcpy(res, target, sizeof(target));
|
||||
+
|
||||
+ *len = ARRAY_SIZE(target);
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
+struct resource *mali_create_mp2_resources(unsigned long address,
|
||||
+ int irq_gp, int irq_gpmmu,
|
||||
+ int irq_pp0, int irq_ppmmu0,
|
||||
+ int irq_pp1, int irq_ppmmu1,
|
||||
+ int *len)
|
||||
+{
|
||||
+ struct resource target[] = {
|
||||
+ MALI_GPU_RESOURCES_MALI400_MP2_PMU(address,
|
||||
+ irq_gp, irq_gpmmu,
|
||||
+ irq_pp0, irq_ppmmu0,
|
||||
+ irq_pp1, irq_ppmmu1)
|
||||
+ };
|
||||
+ struct resource *res;
|
||||
+
|
||||
+ res = kzalloc(sizeof(target), GFP_KERNEL);
|
||||
+ if (!res)
|
||||
+ return NULL;
|
||||
+
|
||||
+ memcpy(res, target, sizeof(target));
|
||||
+
|
||||
+ *len = ARRAY_SIZE(target);
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
+struct resource *mali_create_450mp4_resources(unsigned long address,
|
||||
+ int irq_gp, int irq_gpmmu,
|
||||
+ int irq_pp0, int irq_ppmmu0,
|
||||
+ int irq_pp1, int irq_ppmmu1,
|
||||
+ int irq_pp2, int irq_ppmmu2,
|
||||
+ int irq_pp3, int irq_ppmmu3,
|
||||
+ int irq_pp, int *len)
|
||||
+{
|
||||
+ struct resource target[] = {
|
||||
+ MALI_GPU_RESOURCES_MALI450_MP4(address,
|
||||
+ irq_gp, irq_gpmmu,
|
||||
+ irq_pp0, irq_ppmmu0,
|
||||
+ irq_pp1, irq_ppmmu1,
|
||||
+ irq_pp2, irq_ppmmu2,
|
||||
+ irq_pp3, irq_ppmmu3,
|
||||
+ irq_pp)
|
||||
+ };
|
||||
+ struct resource *res;
|
||||
+
|
||||
+ res = kzalloc(sizeof(target), GFP_KERNEL);
|
||||
+ if (!res)
|
||||
+ return NULL;
|
||||
+
|
||||
+ memcpy(res, target, sizeof(target));
|
||||
+
|
||||
+ *len = ARRAY_SIZE(target);
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mali_dt_ids[] = {
|
||||
+ { .compatible = "allwinner,sun4i-a10-mali" },
|
||||
+ { .compatible = "allwinner,sun7i-a20-mali" },
|
||||
+ { .compatible = "allwinner,sun8i-h3-mali" },
|
||||
+ { .compatible = "allwinner,sun50i-a64-mali" },
|
||||
+ { .compatible = "allwinner,sun50i-h5-mali" },
|
||||
+ { .compatible = "arm,mali-400" },
|
||||
+ { .compatible = "arm,mali-450" },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mali_dt_ids);
|
||||
+
|
||||
+static struct mali_gpu_device_data mali_gpu_data = {
|
||||
+ .max_job_runtime = 60000,
|
||||
+};
|
||||
+int mali_platform_device_register(void)
|
||||
+{
|
||||
+ int irq_gp, irq_gpmmu;
|
||||
+ int irq_pp0, irq_ppmmu0;
|
||||
+ int irq_pp1 = -EINVAL, irq_ppmmu1 = -EINVAL;
|
||||
+ int irq_pp2 = -EINVAL, irq_ppmmu2 = -EINVAL;
|
||||
+ int irq_pp3 = -EINVAL, irq_ppmmu3 = -EINVAL;
|
||||
+ int irq_pp = -EINVAL;
|
||||
+ int irq_pmu;
|
||||
+ struct resource *mali_res = NULL, res;
|
||||
+ struct device_node *np;
|
||||
+ struct device *dev;
|
||||
+ int ret, len;
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0)
|
||||
+ mali_gpu_data.shared_mem_size = totalram_pages() * PAGE_SIZE;
|
||||
+#else
|
||||
+ mali_gpu_data.shared_mem_size = totalram_pages * PAGE_SIZE;
|
||||
+#endif
|
||||
+
|
||||
+ np = of_find_matching_node(NULL, mali_dt_ids);
|
||||
+ if (!np) {
|
||||
+ pr_err("Couldn't find the mali node\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ mali = kzalloc(sizeof(*mali), GFP_KERNEL);
|
||||
+ if (!mali) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_put_node;
|
||||
+ }
|
||||
+
|
||||
+ ret = of_clk_set_defaults(np, false);
|
||||
+ if (ret) {
|
||||
+ pr_err("Couldn't set clock defaults\n");
|
||||
+ goto err_free_mem;
|
||||
+ }
|
||||
+
|
||||
+ mali->bus_clk = of_clk_get_by_name(np, "bus");
|
||||
+ if (IS_ERR(mali->bus_clk)) {
|
||||
+ pr_err("Couldn't retrieve our bus clock\n");
|
||||
+ ret = PTR_ERR(mali->bus_clk);
|
||||
+ goto err_free_mem;
|
||||
+ }
|
||||
+ clk_prepare_enable(mali->bus_clk);
|
||||
+
|
||||
+ mali->core_clk = of_clk_get_by_name(np, "core");
|
||||
+ if (IS_ERR(mali->core_clk)) {
|
||||
+ pr_err("Couldn't retrieve our module clock\n");
|
||||
+ ret = PTR_ERR(mali->core_clk);
|
||||
+ goto err_put_bus;
|
||||
+ }
|
||||
+ clk_prepare_enable(mali->core_clk);
|
||||
+
|
||||
+ if (of_device_is_compatible(np, "allwinner,sun4i-a10-mali") ||
|
||||
+ of_device_is_compatible(np, "allwinner,sun7i-a20-mali") ||
|
||||
+ of_device_is_compatible(np, "allwinner,sun8i-h3-mali") ||
|
||||
+ of_device_is_compatible(np, "allwinner,sun50i-a64-mali") ||
|
||||
+ of_device_is_compatible(np, "allwinner,sun50i-h5-mali")) {
|
||||
+ mali->reset = of_reset_control_get(np, NULL);
|
||||
+ if (IS_ERR(mali->reset)) {
|
||||
+ pr_err("Couldn't retrieve our reset handle\n");
|
||||
+ ret = PTR_ERR(mali->reset);
|
||||
+ goto err_put_mod;
|
||||
+ }
|
||||
+ reset_control_deassert(mali->reset);
|
||||
+ }
|
||||
+
|
||||
+ ret = of_address_to_resource(np, 0, &res);
|
||||
+ if (ret) {
|
||||
+ pr_err("Couldn't retrieve our base address\n");
|
||||
+ goto err_put_reset;
|
||||
+ }
|
||||
+
|
||||
+ irq_gp = of_irq_get_byname(np, "gp");
|
||||
+ if (irq_gp < 0) {
|
||||
+ pr_err("Couldn't retrieve our GP interrupt\n");
|
||||
+ ret = irq_gp;
|
||||
+ goto err_put_reset;
|
||||
+ }
|
||||
+
|
||||
+ irq_gpmmu = of_irq_get_byname(np, "gpmmu");
|
||||
+ if (irq_gpmmu < 0) {
|
||||
+ pr_err("Couldn't retrieve our GP MMU interrupt\n");
|
||||
+ ret = irq_gpmmu;
|
||||
+ goto err_put_reset;
|
||||
+ }
|
||||
+
|
||||
+ irq_pp0 = of_irq_get_byname(np, "pp0");
|
||||
+ if (irq_pp0 < 0) {
|
||||
+ pr_err("Couldn't retrieve our PP0 interrupt %d\n", irq_pp0);
|
||||
+ ret = irq_pp0;
|
||||
+ goto err_put_reset;
|
||||
+ }
|
||||
+
|
||||
+ irq_ppmmu0 = of_irq_get_byname(np, "ppmmu0");
|
||||
+ if (irq_ppmmu0 < 0) {
|
||||
+ pr_err("Couldn't retrieve our PP0 MMU interrupt\n");
|
||||
+ ret = irq_ppmmu0;
|
||||
+ goto err_put_reset;
|
||||
+ }
|
||||
+
|
||||
+ irq_pp1 = of_irq_get_byname(np, "pp1");
|
||||
+ irq_ppmmu1 = of_irq_get_byname(np, "ppmmu1");
|
||||
+ if ((irq_pp1 < 0) ^ (irq_ppmmu1 < 0 )) {
|
||||
+ pr_err("Couldn't retrieve our PP1 interrupts\n");
|
||||
+ ret = (irq_pp1 < 0) ? irq_pp1 : irq_ppmmu1;
|
||||
+ goto err_put_reset;
|
||||
+ }
|
||||
+
|
||||
+ if (of_device_is_compatible(np, "allwinner,sun50i-h5-mali")) {
|
||||
+ irq_pp2 = of_irq_get_byname(np, "pp2");
|
||||
+ if (irq_pp2 < 0) {
|
||||
+ pr_err("Couldn't retrieve our PP2 interrupt\n");
|
||||
+ ret = irq_pp2;
|
||||
+ goto err_put_reset;
|
||||
+ }
|
||||
+
|
||||
+ irq_ppmmu2 = of_irq_get_byname(np, "ppmmu2");
|
||||
+ if (irq_ppmmu2 < 0) {
|
||||
+ pr_err("Couldn't retrieve our PP2 interrupts\n");
|
||||
+ ret = irq_ppmmu2;
|
||||
+ goto err_put_reset;
|
||||
+ }
|
||||
+
|
||||
+ irq_pp3 = of_irq_get_byname(np, "pp3");
|
||||
+ if (irq_pp3 < 0) {
|
||||
+ pr_err("Couldn't retrieve our PP3 interrupt\n");
|
||||
+ ret = irq_pp3;
|
||||
+ goto err_put_reset;
|
||||
+ }
|
||||
+
|
||||
+ irq_ppmmu3 = of_irq_get_byname(np, "ppmmu3");
|
||||
+ if (irq_ppmmu3 < 0) {
|
||||
+ pr_err("Couldn't retrieve our PP3 interrupts\n");
|
||||
+ ret = irq_ppmmu3;
|
||||
+ goto err_put_reset;
|
||||
+ }
|
||||
+
|
||||
+ irq_pp = of_irq_get_byname(np, "pp");
|
||||
+ if (irq_pp < 0) {
|
||||
+ pr_err("Couldn't retrieve our PP broadcast interrupt\n");
|
||||
+ ret = irq_pp;
|
||||
+ goto err_put_reset;
|
||||
+ }
|
||||
+ } else {
|
||||
+ irq_pmu = of_irq_get_byname(np, "pmu");
|
||||
+ if (irq_pmu < 0) {
|
||||
+ pr_err("Couldn't retrieve our PMU interrupt\n");
|
||||
+ ret = irq_pmu;
|
||||
+ goto err_put_reset;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ mali->dev = platform_device_alloc("mali-utgard", 0);
|
||||
+ if (!mali->dev) {
|
||||
+ pr_err("Couldn't create platform device\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto err_put_reset;
|
||||
+ }
|
||||
+ dev = &mali->dev->dev;
|
||||
+ dev_set_name(dev, "mali-utgard");
|
||||
+ dev->of_node = np;
|
||||
+ dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
+ dev->dma_mask = &dev->coherent_dma_mask;
|
||||
+ dev->bus = &platform_bus_type;
|
||||
+
|
||||
+ ret = of_reserved_mem_device_init(&mali->dev->dev);
|
||||
+ if (ret && ret != -ENODEV) {
|
||||
+ pr_err("Couldn't claim our reserved memory region\n");
|
||||
+ goto err_free_mem_region;
|
||||
+ }
|
||||
+
|
||||
+ if (of_device_is_compatible(np, "allwinner,sun50i-h5-mali"))
|
||||
+ mali_res = mali_create_450mp4_resources(res.start,
|
||||
+ irq_gp, irq_gpmmu,
|
||||
+ irq_pp0, irq_ppmmu0,
|
||||
+ irq_pp1, irq_ppmmu1,
|
||||
+ irq_pp2, irq_ppmmu2,
|
||||
+ irq_pp3, irq_ppmmu3,
|
||||
+ irq_pp, &len);
|
||||
+ else if ((irq_pp1 >= 0) && (irq_ppmmu1 >= 0))
|
||||
+ mali_res = mali_create_mp2_resources(res.start,
|
||||
+ irq_gp, irq_gpmmu,
|
||||
+ irq_pp0, irq_ppmmu0,
|
||||
+ irq_pp1, irq_ppmmu1,
|
||||
+ &len);
|
||||
+ else
|
||||
+ mali_res = mali_create_mp1_resources(res.start,
|
||||
+ irq_gp, irq_gpmmu,
|
||||
+ irq_pp0, irq_ppmmu0,
|
||||
+ &len);
|
||||
+
|
||||
+ if (!mali_res) {
|
||||
+ pr_err("Couldn't create target resources\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto err_free_mem_region;
|
||||
+ }
|
||||
+
|
||||
+ clk_register_clkdev(mali->core_clk, "clk_mali", NULL);
|
||||
+
|
||||
+ ret = platform_device_add_resources(mali->dev, mali_res, len);
|
||||
+ kfree(mali_res);
|
||||
+ if (ret) {
|
||||
+ pr_err("Couldn't add our resources\n");
|
||||
+ goto err_free_mem_region;
|
||||
+ }
|
||||
+
|
||||
+ ret = platform_device_add_data(mali->dev, &mali_gpu_data,
|
||||
+ sizeof(mali_gpu_data));
|
||||
+ if (ret) {
|
||||
+ pr_err("Couldn't add our platform data\n");
|
||||
+ goto err_free_mem_region;
|
||||
+ }
|
||||
+
|
||||
+ ret = platform_device_add(mali->dev);
|
||||
+ if (ret) {
|
||||
+ pr_err("Couldn't add our device\n");
|
||||
+ goto err_free_mem_region;
|
||||
+ }
|
||||
+
|
||||
+#ifdef CONFIG_PM_RUNTIME
|
||||
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
|
||||
+ pm_runtime_set_autosuspend_delay(&mali->dev->dev, 1000);
|
||||
+ pm_runtime_use_autosuspend(&mali->dev->dev);
|
||||
+#endif
|
||||
+ pm_runtime_enable(&mali->dev->dev);
|
||||
+#endif
|
||||
+
|
||||
+ pr_info("Allwinner sunXi mali glue initialized\n");
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_free_mem_region:
|
||||
+ of_reserved_mem_device_release(dev);
|
||||
+ platform_device_put(mali->dev);
|
||||
+err_put_reset:
|
||||
+ if (!IS_ERR_OR_NULL(mali->reset)) {
|
||||
+ reset_control_assert(mali->reset);
|
||||
+ reset_control_put(mali->reset);
|
||||
+ }
|
||||
+err_put_mod:
|
||||
+ clk_disable_unprepare(mali->core_clk);
|
||||
+ clk_put(mali->core_clk);
|
||||
+err_put_bus:
|
||||
+ clk_disable_unprepare(mali->bus_clk);
|
||||
+ clk_put(mali->bus_clk);
|
||||
+err_free_mem:
|
||||
+ kfree(mali);
|
||||
+err_put_node:
|
||||
+ of_node_put(np);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int mali_platform_device_unregister(void)
|
||||
+{
|
||||
+ struct device *dev = &mali->dev->dev;
|
||||
+
|
||||
+#ifdef CONFIG_PM_RUNTIME
|
||||
+ pm_runtime_disable(dev);
|
||||
+#endif
|
||||
+
|
||||
+ of_reserved_mem_device_release(dev);
|
||||
+
|
||||
+ platform_device_del(mali->dev);
|
||||
+ of_node_put(dev->of_node);
|
||||
+ platform_device_put(mali->dev);
|
||||
+
|
||||
+ if (!IS_ERR_OR_NULL(mali->reset)) {
|
||||
+ reset_control_assert(mali->reset);
|
||||
+ reset_control_put(mali->reset);
|
||||
+ }
|
||||
+
|
||||
+ clk_disable_unprepare(mali->core_clk);
|
||||
+ clk_put(mali->core_clk);
|
||||
+
|
||||
+ clk_disable_unprepare(mali->bus_clk);
|
||||
+ clk_put(mali->bus_clk);
|
||||
+
|
||||
+ kfree(mali);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
@ -0,0 +1,155 @@
|
||||
From 246fdac477cf109c354011c1ae0a7a8d928cb504 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Mon, 12 Mar 2018 23:02:55 +0100
|
||||
Subject: [PATCH] v4.16 build fix
|
||||
|
||||
---
|
||||
.../driver/src/devicedrv/mali/common/mali_control_timer.c | 2 +-
|
||||
src/devicedrv/mali/common/mali_group.c | 8 ++++---
|
||||
src/devicedrv/mali/common/mali_osk_types.h | 8 ++++++-
|
||||
.../devicedrv/mali/linux/mali_memory_os_alloc.c | 6 +++++
|
||||
.../driver/src/devicedrv/mali/linux/mali_memory_secure.c | 4 ++++
|
||||
src/devicedrv/mali/linux/mali_osk_timers.c | 20 +++++++++++-----
|
||||
11 files changed, 84 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/driver/src/devicedrv/mali/common/mali_control_timer.c b/driver/src/devicedrv/mali/common/mali_control_timer.c
|
||||
index 1296ffe..bfe975f 100644
|
||||
--- a/driver/src/devicedrv/mali/common/mali_control_timer.c
|
||||
+++ b/driver/src/devicedrv/mali/common/mali_control_timer.c
|
||||
@@ -28,7 +28,7 @@ void mali_control_timer_add(u32 timeout)
|
||||
_mali_osk_timer_add(mali_control_timer, _mali_osk_time_mstoticks(timeout));
|
||||
}
|
||||
|
||||
-static void mali_control_timer_callback(void *arg)
|
||||
+static void mali_control_timer_callback(struct timer_list *t)
|
||||
{
|
||||
if (mali_utilization_enabled()) {
|
||||
struct mali_gpu_utilization_data *util_data = NULL;
|
||||
diff --git a/driver/src/devicedrv/mali/common/mali_group.c b/driver/src/devicedrv/mali/common/mali_group.c
|
||||
index e9005e1..4a43753 100644
|
||||
--- a/driver/src/devicedrv/mali/common/mali_group.c
|
||||
+++ b/driver/src/devicedrv/mali/common/mali_group.c
|
||||
@@ -44,7 +44,7 @@ int mali_max_job_runtime = MALI_MAX_JOB_RUNTIME_DEFAULT;
|
||||
static void mali_group_bottom_half_mmu(void *data);
|
||||
static void mali_group_bottom_half_gp(void *data);
|
||||
static void mali_group_bottom_half_pp(void *data);
|
||||
-static void mali_group_timeout(void *data);
|
||||
+static void mali_group_timeout(struct timer_list *t);
|
||||
static void mali_group_reset_pp(struct mali_group *group);
|
||||
static void mali_group_reset_mmu(struct mali_group *group);
|
||||
|
||||
@@ -1761,9 +1761,11 @@ static void mali_group_bottom_half_pp(void *data)
|
||||
0xFFFFFFFF, 0);
|
||||
}
|
||||
|
||||
-static void mali_group_timeout(void *data)
|
||||
+static void mali_group_timeout(struct timer_list *t)
|
||||
{
|
||||
- struct mali_group *group = (struct mali_group *)data;
|
||||
+ _mali_osk_timer_t *tim = container_of(t, _mali_osk_timer_t, timer);
|
||||
+ struct mali_group *group = container_of(&tim, struct mali_group, timeout_timer);
|
||||
+
|
||||
MALI_DEBUG_ASSERT_POINTER(group);
|
||||
|
||||
MALI_DEBUG_PRINT(2, ("Group: timeout handler for %s at %u\n",
|
||||
diff --git a/driver/src/devicedrv/mali/common/mali_osk_types.h b/driver/src/devicedrv/mali/common/mali_osk_types.h
|
||||
index 03161cf..c9d0fec 100644
|
||||
--- a/driver/src/devicedrv/mali/common/mali_osk_types.h
|
||||
+++ b/driver/src/devicedrv/mali/common/mali_osk_types.h
|
||||
@@ -50,6 +50,7 @@ typedef unsigned long long u64;
|
||||
#include <linux/types.h>
|
||||
#endif
|
||||
|
||||
+#include <linux/timer.h>
|
||||
/** @brief Mali Boolean type which uses MALI_TRUE and MALI_FALSE
|
||||
*/
|
||||
typedef unsigned long mali_bool;
|
||||
@@ -395,7 +396,12 @@ typedef struct _mali_osk_notification_t_struct {
|
||||
* by any callers of _mali_osk_timer_del(). Otherwise, a deadlock may occur.
|
||||
*
|
||||
* @param arg Function-specific data */
|
||||
-typedef void (*_mali_osk_timer_callback_t)(void *arg);
|
||||
+typedef void (*_mali_osk_timer_callback_t)(struct timer_list *t);
|
||||
+
|
||||
+
|
||||
+struct _mali_osk_timer_t_struct {
|
||||
+ struct timer_list timer;
|
||||
+};
|
||||
|
||||
/** @brief Private type for Timer Callback Objects */
|
||||
typedef struct _mali_osk_timer_t_struct _mali_osk_timer_t;
|
||||
diff --git a/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.c b/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.c
|
||||
index 5fe1270..92c245a 100644
|
||||
--- a/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.c
|
||||
+++ b/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.c
|
||||
@@ -202,7 +202,9 @@ int mali_mem_os_alloc_pages(mali_mem_os_mem *os_mem, u32 size)
|
||||
/* Allocate new pages, if needed. */
|
||||
for (i = 0; i < remaining; i++) {
|
||||
dma_addr_t dma_addr;
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
|
||||
+ gfp_t flags = __GFP_ZERO | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
|
||||
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
||||
gfp_t flags = __GFP_ZERO | __GFP_RETRY_MAYFAIL | __GFP_NOWARN | __GFP_COLD;
|
||||
#else
|
||||
gfp_t flags = __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD;
|
||||
diff --git a/driver/src/devicedrv/mali/linux/mali_memory_secure.c b/driver/src/devicedrv/mali/linux/mali_memory_secure.c
|
||||
index 2836b1b..4f55fa5 100644
|
||||
--- a/driver/src/devicedrv/mali/linux/mali_memory_secure.c
|
||||
+++ b/driver/src/devicedrv/mali/linux/mali_memory_secure.c
|
||||
@@ -13,7 +13,11 @@
|
||||
#include "mali_memory_secure.h"
|
||||
#include "mali_osk.h"
|
||||
#include <linux/mutex.h>
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
|
||||
+#include <linux/dma-direct.h>
|
||||
+#else
|
||||
#include <linux/dma-mapping.h>
|
||||
+#endif
|
||||
#include <linux/dma-buf.h>
|
||||
|
||||
_mali_osk_errcode_t mali_mem_secure_attach_dma_buf(mali_mem_secure *secure_mem, u32 size, int mem_fd)
|
||||
diff --git a/driver/src/devicedrv/mali/linux/mali_osk_timers.c b/driver/src/devicedrv/mali/linux/mali_osk_timers.c
|
||||
index e5d7238..701051a 100644
|
||||
--- a/driver/src/devicedrv/mali/linux/mali_osk_timers.c
|
||||
+++ b/driver/src/devicedrv/mali/linux/mali_osk_timers.c
|
||||
@@ -18,16 +18,25 @@
|
||||
#include "mali_osk.h"
|
||||
#include "mali_kernel_common.h"
|
||||
|
||||
-struct _mali_osk_timer_t_struct {
|
||||
- struct timer_list timer;
|
||||
-};
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
+
|
||||
+#define TIMER_DATA_TYPE unsigned long
|
||||
+#define TIMER_FUNC_TYPE void (*)(TIMER_DATA_TYPE)
|
||||
+
|
||||
+static inline void timer_setup(struct timer_list *timer,
|
||||
+ void (*callback)(struct timer_list *),
|
||||
+ unsigned int flags)
|
||||
+{
|
||||
+ __setup_timer(timer, (TIMER_FUNC_TYPE)callback,
|
||||
+ (TIMER_DATA_TYPE)timer, flags);
|
||||
+}
|
||||
+#endif
|
||||
|
||||
typedef void (*timer_timeout_function_t)(unsigned long);
|
||||
|
||||
_mali_osk_timer_t *_mali_osk_timer_init(void)
|
||||
{
|
||||
_mali_osk_timer_t *t = (_mali_osk_timer_t *)kmalloc(sizeof(_mali_osk_timer_t), GFP_KERNEL);
|
||||
- if (NULL != t) init_timer(&t->timer);
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -65,8 +74,7 @@ mali_bool _mali_osk_timer_pending(_mali_osk_timer_t *tim)
|
||||
void _mali_osk_timer_setcallback(_mali_osk_timer_t *tim, _mali_osk_timer_callback_t callback, void *data)
|
||||
{
|
||||
MALI_DEBUG_ASSERT_POINTER(tim);
|
||||
- tim->timer.data = (unsigned long)data;
|
||||
- tim->timer.function = (timer_timeout_function_t)callback;
|
||||
+ timer_setup(&tim->timer, callback, 0);
|
||||
}
|
||||
|
||||
void _mali_osk_timer_term(_mali_osk_timer_t *tim)
|
@ -0,0 +1,128 @@
|
||||
diff -Nur a/driver/src/devicedrv/mali/linux/mali_memory_block_alloc.c b/driver/src/devicedrv/mali/linux/mali_memory_block_alloc.c
|
||||
--- a/driver/src/devicedrv/mali/linux/mali_memory_block_alloc.c 2018-09-13 08:52:20.000000000 +0200
|
||||
+++ b/driver/src/devicedrv/mali/linux/mali_memory_block_alloc.c 2018-12-08 12:22:51.978513336 +0100
|
||||
@@ -309,9 +309,9 @@
|
||||
|
||||
list_for_each_entry(m_page, &block_mem->pfns, list) {
|
||||
MALI_DEBUG_ASSERT(m_page->type == MALI_PAGE_NODE_BLOCK);
|
||||
- ret = vm_insert_pfn(vma, addr, _mali_page_node_get_pfn(m_page));
|
||||
+ ret = vmf_insert_pfn(vma, addr, _mali_page_node_get_pfn(m_page));
|
||||
|
||||
- if (unlikely(0 != ret)) {
|
||||
+ if (unlikely(ret & VM_FAULT_ERROR)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
addr += _MALI_OSK_MALI_PAGE_SIZE;
|
||||
diff -Nur a/driver/src/devicedrv/mali/linux/mali_memory_cow.c b/driver/src/devicedrv/mali/linux/mali_memory_cow.c
|
||||
--- a/driver/src/devicedrv/mali/linux/mali_memory_cow.c 2018-09-13 08:52:20.000000000 +0200
|
||||
+++ b/driver/src/devicedrv/mali/linux/mali_memory_cow.c 2018-12-08 12:27:17.681815893 +0100
|
||||
@@ -532,10 +532,10 @@
|
||||
* flush which makes it way slower than remap_pfn_range or vm_insert_pfn.
|
||||
ret = vm_insert_page(vma, addr, page);
|
||||
*/
|
||||
- ret = vm_insert_pfn(vma, addr, _mali_page_node_get_pfn(m_page));
|
||||
+ ret = vmf_insert_pfn(vma, addr, _mali_page_node_get_pfn(m_page));
|
||||
|
||||
- if (unlikely(0 != ret)) {
|
||||
- return ret;
|
||||
+ if (unlikely(ret & VM_FAULT_ERROR)) {
|
||||
+ return -EFAULT;
|
||||
}
|
||||
addr += _MALI_OSK_MALI_PAGE_SIZE;
|
||||
}
|
||||
@@ -569,9 +569,9 @@
|
||||
|
||||
list_for_each_entry(m_page, &cow->pages, list) {
|
||||
if ((count >= offset) && (count < offset + num)) {
|
||||
- ret = vm_insert_pfn(vma, vaddr, _mali_page_node_get_pfn(m_page));
|
||||
+ ret = vmf_insert_pfn(vma, vaddr, _mali_page_node_get_pfn(m_page));
|
||||
|
||||
- if (unlikely(0 != ret)) {
|
||||
+ if (unlikely(ret & VM_FAULT_ERROR)) {
|
||||
if (count == offset) {
|
||||
return _MALI_OSK_ERR_FAULT;
|
||||
} else {
|
||||
diff -Nur a/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.c b/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.c
|
||||
--- a/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.c 2018-12-08 12:15:38.000000000 +0100
|
||||
+++ b/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.c 2018-12-08 12:30:37.730811640 +0100
|
||||
@@ -376,9 +376,9 @@
|
||||
ret = vm_insert_page(vma, addr, page);
|
||||
*/
|
||||
page = m_page->page;
|
||||
- ret = vm_insert_pfn(vma, addr, page_to_pfn(page));
|
||||
+ ret = vmf_insert_pfn(vma, addr, page_to_pfn(page));
|
||||
|
||||
- if (unlikely(0 != ret)) {
|
||||
+ if (unlikely(ret & VM_FAULT_ERROR)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
addr += _MALI_OSK_MALI_PAGE_SIZE;
|
||||
@@ -414,16 +414,11 @@
|
||||
|
||||
vm_end -= _MALI_OSK_MALI_PAGE_SIZE;
|
||||
if (mapping_page_num > 0) {
|
||||
- ret = vm_insert_pfn(vma, vm_end, page_to_pfn(m_page->page));
|
||||
+ ret = vmf_insert_pfn(vma, vm_end, page_to_pfn(m_page->page));
|
||||
|
||||
- if (unlikely(0 != ret)) {
|
||||
- /*will return -EBUSY If the page has already been mapped into table, but it's OK*/
|
||||
- if (-EBUSY == ret) {
|
||||
- break;
|
||||
- } else {
|
||||
- MALI_DEBUG_PRINT(1, ("OS Mem: mali_mem_os_resize_cpu_map_locked failed, ret = %d, offset is %d,page_count is %d\n",
|
||||
- ret, offset + mapping_page_num, os_mem->count));
|
||||
- }
|
||||
+ if (unlikely(ret & VM_FAULT_ERROR)) {
|
||||
+ MALI_DEBUG_PRINT(1, ("OS Mem: mali_mem_os_resize_cpu_map_locked failed, ret = %d, offset is %d,page_count is %d\n",
|
||||
+ ret, offset + mapping_page_num, os_mem->count));
|
||||
return _MALI_OSK_ERR_FAULT;
|
||||
}
|
||||
} else {
|
||||
@@ -437,16 +432,11 @@
|
||||
list_for_each_entry(m_page, &os_mem->pages, list) {
|
||||
if (count >= offset) {
|
||||
|
||||
- ret = vm_insert_pfn(vma, vstart, page_to_pfn(m_page->page));
|
||||
+ ret = vmf_insert_pfn(vma, vstart, page_to_pfn(m_page->page));
|
||||
|
||||
- if (unlikely(0 != ret)) {
|
||||
- /*will return -EBUSY If the page has already been mapped into table, but it's OK*/
|
||||
- if (-EBUSY == ret) {
|
||||
- break;
|
||||
- } else {
|
||||
- MALI_DEBUG_PRINT(1, ("OS Mem: mali_mem_os_resize_cpu_map_locked failed, ret = %d, count is %d, offset is %d,page_count is %d\n",
|
||||
- ret, count, offset, os_mem->count));
|
||||
- }
|
||||
+ if (unlikely(ret & VM_FAULT_ERROR)) {
|
||||
+ MALI_DEBUG_PRINT(1, ("OS Mem: mali_mem_os_resize_cpu_map_locked failed, ret = %d, count is %d, offset is %d,page_count is %d\n",
|
||||
+ ret, count, offset, os_mem->count));
|
||||
return _MALI_OSK_ERR_FAULT;
|
||||
}
|
||||
}
|
||||
diff -Nur a/driver/src/devicedrv/mali/linux/mali_memory_secure.c b/driver/src/devicedrv/mali/linux/mali_memory_secure.c
|
||||
--- a/driver/src/devicedrv/mali/linux/mali_memory_secure.c 2018-12-08 12:15:38.000000000 +0100
|
||||
+++ b/driver/src/devicedrv/mali/linux/mali_memory_secure.c 2018-12-08 12:31:05.461174554 +0100
|
||||
@@ -132,9 +132,9 @@
|
||||
MALI_DEBUG_ASSERT(0 == size % _MALI_OSK_MALI_PAGE_SIZE);
|
||||
|
||||
for (j = 0; j < size / _MALI_OSK_MALI_PAGE_SIZE; j++) {
|
||||
- ret = vm_insert_pfn(vma, addr, PFN_DOWN(phys));
|
||||
+ ret = vmf_insert_pfn(vma, addr, PFN_DOWN(phys));
|
||||
|
||||
- if (unlikely(0 != ret)) {
|
||||
+ if (unlikely(ret & VM_FAULT_ERROR)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
addr += _MALI_OSK_MALI_PAGE_SIZE;
|
||||
diff -Nur a/driver/src/devicedrv/mali/linux/mali_osk_time.c b/driver/src/devicedrv/mali/linux/mali_osk_time.c
|
||||
--- a/driver/src/devicedrv/mali/linux/mali_osk_time.c 2018-09-13 08:52:20.000000000 +0200
|
||||
+++ b/driver/src/devicedrv/mali/linux/mali_osk_time.c 2018-12-08 12:32:12.632086846 +0100
|
||||
@@ -53,7 +53,5 @@
|
||||
|
||||
u64 _mali_osk_boot_time_get_ns(void)
|
||||
{
|
||||
- struct timespec tsval;
|
||||
- get_monotonic_boottime(&tsval);
|
||||
- return (u64)timespec_to_ns(&tsval);
|
||||
+ return (u64)ktime_to_ns(ktime_get_boottime());
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
diff -Nur a/driver/src/devicedrv/mali/linux/mali_ukk_mem.c b/driver/src/devicedrv/mali/linux/mali_ukk_mem.c
|
||||
--- a/driver/src/devicedrv/mali/linux/mali_ukk_mem.c 2018-09-13 08:52:20.000000000 +0200
|
||||
+++ b/driver/src/devicedrv/mali/linux/mali_ukk_mem.c 2019-02-09 20:10:06.867561465 +0100
|
||||
@@ -207,10 +207,17 @@
|
||||
kargs.ctx = (uintptr_t)session_data;
|
||||
|
||||
/* Check if we can access the buffers */
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0)
|
||||
+ if (!access_ok(kargs.dest, kargs.size)
|
||||
+ || !access_ok(kargs.src, kargs.size)) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+#else
|
||||
if (!access_ok(VERIFY_WRITE, kargs.dest, kargs.size)
|
||||
|| !access_ok(VERIFY_READ, kargs.src, kargs.size)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
+#endif
|
||||
|
||||
/* Check if size wraps */
|
||||
if ((kargs.size + kargs.dest) <= kargs.dest
|
||||
@@ -266,8 +273,13 @@
|
||||
goto err_exit;
|
||||
|
||||
user_buffer = (void __user *)(uintptr_t)kargs.buffer;
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0)
|
||||
+ if (!access_ok(user_buffer, kargs.size))
|
||||
+ goto err_exit;
|
||||
+#else
|
||||
if (!access_ok(VERIFY_WRITE, user_buffer, kargs.size))
|
||||
goto err_exit;
|
||||
+#endif
|
||||
|
||||
/* allocate temporary buffer (kernel side) to store mmu page table info */
|
||||
if (kargs.size <= 0)
|
@ -44,6 +44,13 @@ else
|
||||
PKG_FFMPEG_RKMPP="--disable-rkmpp"
|
||||
fi
|
||||
|
||||
if [ "$PROJECT" = "Allwinner" ]; then
|
||||
PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libdrm systemd" # systemd is needed for libudev
|
||||
PKG_FFMPEG_V4L2_REQUEST="--enable-v4l2-request --enable-libudev --enable-libdrm"
|
||||
else
|
||||
PKG_FFMPEG_V4L2_REQUEST="--disable-v4l2-request --disable-libudev"
|
||||
fi
|
||||
|
||||
if build_with_debug; then
|
||||
PKG_FFMPEG_DEBUG="--enable-debug --disable-stripping"
|
||||
else
|
||||
@ -138,6 +145,7 @@ configure_target() {
|
||||
$PKG_FFMPEG_VDPAU \
|
||||
$PKG_FFMPEG_RPI \
|
||||
$PKG_FFMPEG_RKMPP \
|
||||
$PKG_FFMPEG_V4L2_REQUEST \
|
||||
--enable-runtime-cpudetect \
|
||||
--disable-hardcoded-tables \
|
||||
--disable-encoders \
|
||||
|
@ -0,0 +1,54 @@
|
||||
From 7ab07a6b9a8ac8a91213bcbba4a63dc9db03cb53 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Mon, 3 Dec 2018 23:48:04 +0100
|
||||
Subject: [PATCH 1/6] avutil: add av_buffer_pool_reclaim()
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
libavutil/buffer.c | 13 +++++++++++++
|
||||
libavutil/buffer.h | 5 +++++
|
||||
2 files changed, 18 insertions(+)
|
||||
|
||||
diff --git a/libavutil/buffer.c b/libavutil/buffer.c
|
||||
index 8d1aa5fa84..9c5d530c7a 100644
|
||||
--- a/libavutil/buffer.c
|
||||
+++ b/libavutil/buffer.c
|
||||
@@ -272,6 +272,19 @@ static void buffer_pool_free(AVBufferPool *pool)
|
||||
av_freep(&pool);
|
||||
}
|
||||
|
||||
+void av_buffer_pool_reclaim(AVBufferPool *pool)
|
||||
+{
|
||||
+ ff_mutex_lock(&pool->mutex);
|
||||
+ while (pool->pool) {
|
||||
+ BufferPoolEntry *buf = pool->pool;
|
||||
+ pool->pool = buf->next;
|
||||
+
|
||||
+ buf->free(buf->opaque, buf->data);
|
||||
+ av_freep(&buf);
|
||||
+ }
|
||||
+ ff_mutex_unlock(&pool->mutex);
|
||||
+}
|
||||
+
|
||||
void av_buffer_pool_uninit(AVBufferPool **ppool)
|
||||
{
|
||||
AVBufferPool *pool;
|
||||
diff --git a/libavutil/buffer.h b/libavutil/buffer.h
|
||||
index 73b6bd0b14..fab745f853 100644
|
||||
--- a/libavutil/buffer.h
|
||||
+++ b/libavutil/buffer.h
|
||||
@@ -266,6 +266,11 @@ AVBufferPool *av_buffer_pool_init2(int size, void *opaque,
|
||||
AVBufferRef* (*alloc)(void *opaque, int size),
|
||||
void (*pool_free)(void *opaque));
|
||||
|
||||
+/**
|
||||
+ * Free all available buffers in a buffer pool.
|
||||
+ */
|
||||
+ void av_buffer_pool_reclaim(AVBufferPool *pool);
|
||||
+
|
||||
/**
|
||||
* Mark the pool as being available for freeing. It will actually be freed only
|
||||
* once all the allocated buffers associated with the pool are released. Thus it
|
||||
--
|
||||
2.21.0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,247 @@
|
||||
From de3bcf7557503e5d61b43cdc32d0844deab1c295 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Sat, 15 Dec 2018 22:32:16 +0100
|
||||
Subject: [PATCH 3/6] Add V4L2 request API mpeg2 hwaccel
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
configure | 3 +
|
||||
libavcodec/Makefile | 1 +
|
||||
libavcodec/hwaccels.h | 1 +
|
||||
libavcodec/mpeg12dec.c | 6 ++
|
||||
libavcodec/v4l2_request_mpeg2.c | 154 ++++++++++++++++++++++++++++++++
|
||||
5 files changed, 165 insertions(+)
|
||||
create mode 100644 libavcodec/v4l2_request_mpeg2.c
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index ed587ec05e..c93d67056d 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -2846,6 +2846,8 @@ mpeg2_dxva2_hwaccel_deps="dxva2"
|
||||
mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
|
||||
mpeg2_nvdec_hwaccel_deps="nvdec"
|
||||
mpeg2_nvdec_hwaccel_select="mpeg2video_decoder"
|
||||
+mpeg2_v4l2request_hwaccel_deps="v4l2_request mpeg2_v4l2_request"
|
||||
+mpeg2_v4l2request_hwaccel_select="mpeg2video_decoder"
|
||||
mpeg2_vaapi_hwaccel_deps="vaapi"
|
||||
mpeg2_vaapi_hwaccel_select="mpeg2video_decoder"
|
||||
mpeg2_vdpau_hwaccel_deps="vdpau"
|
||||
@@ -6237,6 +6239,7 @@ check_cc vp8_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP8;"
|
||||
check_cc vp9_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;"
|
||||
|
||||
check_func_headers "linux/media.h linux/videodev2.h" v4l2_timeval_to_ns
|
||||
+check_cc mpeg2_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2_SLICE;"
|
||||
|
||||
check_header sys/videoio.h
|
||||
test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete
|
||||
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
|
||||
index 48f6e06545..9b945e3f64 100644
|
||||
--- a/libavcodec/Makefile
|
||||
+++ b/libavcodec/Makefile
|
||||
@@ -871,6 +871,7 @@ OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL) += dxva2_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_NVDEC_HWACCEL) += nvdec_mpeg12.o
|
||||
OBJS-$(CONFIG_MPEG2_QSV_HWACCEL) += qsvdec_other.o
|
||||
+OBJS-$(CONFIG_MPEG2_V4L2REQUEST_HWACCEL) += v4l2_request_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o
|
||||
OBJS-$(CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o
|
||||
diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h
|
||||
index 7d73da8676..ef54de2a3b 100644
|
||||
--- a/libavcodec/hwaccels.h
|
||||
+++ b/libavcodec/hwaccels.h
|
||||
@@ -47,6 +47,7 @@ extern const AVHWAccel ff_mpeg2_d3d11va_hwaccel;
|
||||
extern const AVHWAccel ff_mpeg2_d3d11va2_hwaccel;
|
||||
extern const AVHWAccel ff_mpeg2_nvdec_hwaccel;
|
||||
extern const AVHWAccel ff_mpeg2_dxva2_hwaccel;
|
||||
+extern const AVHWAccel ff_mpeg2_v4l2request_hwaccel;
|
||||
extern const AVHWAccel ff_mpeg2_vaapi_hwaccel;
|
||||
extern const AVHWAccel ff_mpeg2_vdpau_hwaccel;
|
||||
extern const AVHWAccel ff_mpeg2_videotoolbox_hwaccel;
|
||||
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
|
||||
index 83e537884b..305127bc94 100644
|
||||
--- a/libavcodec/mpeg12dec.c
|
||||
+++ b/libavcodec/mpeg12dec.c
|
||||
@@ -1156,6 +1156,9 @@ static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = {
|
||||
#endif
|
||||
#if CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL
|
||||
AV_PIX_FMT_VIDEOTOOLBOX,
|
||||
+#endif
|
||||
+#if CONFIG_MPEG2_V4L2REQUEST_HWACCEL
|
||||
+ AV_PIX_FMT_DRM_PRIME,
|
||||
#endif
|
||||
AV_PIX_FMT_YUV420P,
|
||||
AV_PIX_FMT_NONE
|
||||
@@ -2941,6 +2944,9 @@ AVCodec ff_mpeg2video_decoder = {
|
||||
#endif
|
||||
#if CONFIG_MPEG2_XVMC_HWACCEL
|
||||
HWACCEL_XVMC(mpeg2),
|
||||
+#endif
|
||||
+#if CONFIG_MPEG2_V4L2REQUEST_HWACCEL
|
||||
+ HWACCEL_V4L2REQUEST(mpeg2),
|
||||
#endif
|
||||
NULL
|
||||
},
|
||||
diff --git a/libavcodec/v4l2_request_mpeg2.c b/libavcodec/v4l2_request_mpeg2.c
|
||||
new file mode 100644
|
||||
index 0000000000..782b9c2471
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/v4l2_request_mpeg2.c
|
||||
@@ -0,0 +1,154 @@
|
||||
+/*
|
||||
+ * This file is part of FFmpeg.
|
||||
+ *
|
||||
+ * FFmpeg is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * FFmpeg is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with FFmpeg; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
+ */
|
||||
+
|
||||
+#include "hwaccel.h"
|
||||
+#include "mpegvideo.h"
|
||||
+#include "v4l2_request.h"
|
||||
+
|
||||
+typedef struct V4L2RequestControlsMPEG2 {
|
||||
+ struct v4l2_ctrl_mpeg2_slice_params slice_params;
|
||||
+ struct v4l2_ctrl_mpeg2_quantization quantization;
|
||||
+} V4L2RequestControlsMPEG2;
|
||||
+
|
||||
+static int v4l2_request_mpeg2_start_frame(AVCodecContext *avctx,
|
||||
+ av_unused const uint8_t *buffer,
|
||||
+ av_unused uint32_t size)
|
||||
+{
|
||||
+ const MpegEncContext *s = avctx->priv_data;
|
||||
+ V4L2RequestControlsMPEG2 *controls = s->current_picture_ptr->hwaccel_picture_private;
|
||||
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)s->current_picture_ptr->f->data[0];
|
||||
+
|
||||
+ controls->slice_params = (struct v4l2_ctrl_mpeg2_slice_params) {
|
||||
+ .bit_size = 0,
|
||||
+ .data_bit_offset = 0,
|
||||
+
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Slice */
|
||||
+ .quantiser_scale_code = s->qscale >> 1,
|
||||
+
|
||||
+ .sequence = {
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence header */
|
||||
+ .horizontal_size = s->width,
|
||||
+ .vertical_size = s->height,
|
||||
+ .vbv_buffer_size = req->output.size,
|
||||
+
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence extension */
|
||||
+ .profile_and_level_indication = 0,
|
||||
+ .progressive_sequence = s->progressive_sequence,
|
||||
+ .chroma_format = s->chroma_format,
|
||||
+ },
|
||||
+
|
||||
+ .picture = {
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture header */
|
||||
+ .picture_coding_type = s->pict_type,
|
||||
+
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture coding extension */
|
||||
+ .f_code[0][0] = s->mpeg_f_code[0][0],
|
||||
+ .f_code[0][1] = s->mpeg_f_code[0][1],
|
||||
+ .f_code[1][0] = s->mpeg_f_code[1][0],
|
||||
+ .f_code[1][1] = s->mpeg_f_code[1][1],
|
||||
+ .intra_dc_precision = s->intra_dc_precision,
|
||||
+ .picture_structure = s->picture_structure,
|
||||
+ .top_field_first = s->top_field_first,
|
||||
+ .frame_pred_frame_dct = s->frame_pred_frame_dct,
|
||||
+ .concealment_motion_vectors = s->concealment_motion_vectors,
|
||||
+ .q_scale_type = s->q_scale_type,
|
||||
+ .intra_vlc_format = s->intra_vlc_format,
|
||||
+ .alternate_scan = s->alternate_scan,
|
||||
+ .repeat_first_field = s->repeat_first_field,
|
||||
+ .progressive_frame = s->progressive_frame,
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ switch (s->pict_type) {
|
||||
+ case AV_PICTURE_TYPE_B:
|
||||
+ controls->slice_params.backward_ref_ts = ff_v4l2_request_get_capture_timestamp(s->next_picture.f);
|
||||
+ // fall-through
|
||||
+ case AV_PICTURE_TYPE_P:
|
||||
+ controls->slice_params.forward_ref_ts = ff_v4l2_request_get_capture_timestamp(s->last_picture.f);
|
||||
+ }
|
||||
+
|
||||
+ controls->quantization = (struct v4l2_ctrl_mpeg2_quantization) {
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */
|
||||
+ .load_intra_quantiser_matrix = 1,
|
||||
+ .load_non_intra_quantiser_matrix = 1,
|
||||
+ .load_chroma_intra_quantiser_matrix = 1,
|
||||
+ .load_chroma_non_intra_quantiser_matrix = 1,
|
||||
+ };
|
||||
+
|
||||
+ for (int i = 0; i < 64; i++) {
|
||||
+ int n = s->idsp.idct_permutation[ff_zigzag_direct[i]];
|
||||
+ controls->quantization.intra_quantiser_matrix[i] = s->intra_matrix[n];
|
||||
+ controls->quantization.non_intra_quantiser_matrix[i] = s->inter_matrix[n];
|
||||
+ controls->quantization.chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[n];
|
||||
+ controls->quantization.chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[n];
|
||||
+ }
|
||||
+
|
||||
+ return ff_v4l2_request_reset_frame(avctx, s->current_picture_ptr->f);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
|
||||
+{
|
||||
+ const MpegEncContext *s = avctx->priv_data;
|
||||
+
|
||||
+ return ff_v4l2_request_append_output_buffer(avctx, s->current_picture_ptr->f, buffer, size);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_mpeg2_end_frame(AVCodecContext *avctx)
|
||||
+{
|
||||
+ const MpegEncContext *s = avctx->priv_data;
|
||||
+ V4L2RequestControlsMPEG2 *controls = s->current_picture_ptr->hwaccel_picture_private;
|
||||
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)s->current_picture_ptr->f->data[0];
|
||||
+
|
||||
+ struct v4l2_ext_control control[] = {
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
|
||||
+ .ptr = &controls->slice_params,
|
||||
+ .size = sizeof(controls->slice_params),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION,
|
||||
+ .ptr = &controls->quantization,
|
||||
+ .size = sizeof(controls->quantization),
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ controls->slice_params.bit_size = req->output.used * 8;
|
||||
+
|
||||
+ return ff_v4l2_request_decode_frame(avctx, s->current_picture_ptr->f, control, FF_ARRAY_ELEMS(control));
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_mpeg2_init(AVCodecContext *avctx)
|
||||
+{
|
||||
+ return ff_v4l2_request_init(avctx, V4L2_PIX_FMT_MPEG2_SLICE, 1024 * 1024, NULL, 0);
|
||||
+}
|
||||
+
|
||||
+const AVHWAccel ff_mpeg2_v4l2request_hwaccel = {
|
||||
+ .name = "mpeg2_v4l2request",
|
||||
+ .type = AVMEDIA_TYPE_VIDEO,
|
||||
+ .id = AV_CODEC_ID_MPEG2VIDEO,
|
||||
+ .pix_fmt = AV_PIX_FMT_DRM_PRIME,
|
||||
+ .start_frame = v4l2_request_mpeg2_start_frame,
|
||||
+ .decode_slice = v4l2_request_mpeg2_decode_slice,
|
||||
+ .end_frame = v4l2_request_mpeg2_end_frame,
|
||||
+ .frame_priv_data_size = sizeof(V4L2RequestControlsMPEG2),
|
||||
+ .init = v4l2_request_mpeg2_init,
|
||||
+ .uninit = ff_v4l2_request_uninit,
|
||||
+ .priv_data_size = sizeof(V4L2RequestContext),
|
||||
+ .frame_params = ff_v4l2_request_frame_params,
|
||||
+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
|
||||
+};
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,475 @@
|
||||
From bc1ed76cbc2dad2ec308801552e2398fc2de0a07 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 15 Dec 2018 22:32:16 +0100
|
||||
Subject: [PATCH 4/6] Add V4L2 request API h264 hwaccel
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
configure | 3 +
|
||||
libavcodec/Makefile | 1 +
|
||||
libavcodec/h264_slice.c | 4 +
|
||||
libavcodec/h264dec.c | 3 +
|
||||
libavcodec/hwaccels.h | 1 +
|
||||
libavcodec/v4l2_request_h264.c | 368 +++++++++++++++++++++++++++++++++
|
||||
6 files changed, 380 insertions(+)
|
||||
create mode 100644 libavcodec/v4l2_request_h264.c
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index c93d67056d..296ca78ce7 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -2804,6 +2804,8 @@ h264_dxva2_hwaccel_deps="dxva2"
|
||||
h264_dxva2_hwaccel_select="h264_decoder"
|
||||
h264_nvdec_hwaccel_deps="nvdec"
|
||||
h264_nvdec_hwaccel_select="h264_decoder"
|
||||
+h264_v4l2request_hwaccel_deps="v4l2_request h264_v4l2_request"
|
||||
+h264_v4l2request_hwaccel_select="h264_decoder"
|
||||
h264_vaapi_hwaccel_deps="vaapi"
|
||||
h264_vaapi_hwaccel_select="h264_decoder"
|
||||
h264_vdpau_hwaccel_deps="vdpau"
|
||||
@@ -6239,6 +6241,7 @@ check_cc vp8_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP8;"
|
||||
check_cc vp9_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;"
|
||||
|
||||
check_func_headers "linux/media.h linux/videodev2.h" v4l2_timeval_to_ns
|
||||
+check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_H264_SLICE_RAW;"
|
||||
check_cc mpeg2_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2_SLICE;"
|
||||
|
||||
check_header sys/videoio.h
|
||||
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
|
||||
index 9b945e3f64..2bdfaabb5f 100644
|
||||
--- a/libavcodec/Makefile
|
||||
+++ b/libavcodec/Makefile
|
||||
@@ -852,6 +852,7 @@ OBJS-$(CONFIG_H264_D3D11VA_HWACCEL) += dxva2_h264.o
|
||||
OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o
|
||||
OBJS-$(CONFIG_H264_NVDEC_HWACCEL) += nvdec_h264.o
|
||||
OBJS-$(CONFIG_H264_QSV_HWACCEL) += qsvdec_h2645.o
|
||||
+OBJS-$(CONFIG_H264_V4L2REQUEST_HWACCEL) += v4l2_request_h264.o
|
||||
OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o
|
||||
OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_h264.o
|
||||
OBJS-$(CONFIG_H264_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o
|
||||
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
|
||||
index f78f9f87b0..688d6c4ac2 100644
|
||||
--- a/libavcodec/h264_slice.c
|
||||
+++ b/libavcodec/h264_slice.c
|
||||
@@ -758,6 +758,7 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
|
||||
#define HWACCEL_MAX (CONFIG_H264_DXVA2_HWACCEL + \
|
||||
(CONFIG_H264_D3D11VA_HWACCEL * 2) + \
|
||||
CONFIG_H264_NVDEC_HWACCEL + \
|
||||
+ CONFIG_H264_V4L2REQUEST_HWACCEL + \
|
||||
CONFIG_H264_VAAPI_HWACCEL + \
|
||||
CONFIG_H264_VIDEOTOOLBOX_HWACCEL + \
|
||||
CONFIG_H264_VDPAU_HWACCEL)
|
||||
@@ -842,6 +843,9 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
|
||||
#endif
|
||||
#if CONFIG_H264_VIDEOTOOLBOX_HWACCEL
|
||||
*fmt++ = AV_PIX_FMT_VIDEOTOOLBOX;
|
||||
+#endif
|
||||
+#if CONFIG_H264_V4L2REQUEST_HWACCEL
|
||||
+ *fmt++ = AV_PIX_FMT_DRM_PRIME;
|
||||
#endif
|
||||
if (h->avctx->codec->pix_fmts)
|
||||
choices = h->avctx->codec->pix_fmts;
|
||||
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
|
||||
index 33e1056d87..3ccfa60621 100644
|
||||
--- a/libavcodec/h264dec.c
|
||||
+++ b/libavcodec/h264dec.c
|
||||
@@ -1078,6 +1078,9 @@ AVCodec ff_h264_decoder = {
|
||||
#endif
|
||||
#if CONFIG_H264_VIDEOTOOLBOX_HWACCEL
|
||||
HWACCEL_VIDEOTOOLBOX(h264),
|
||||
+#endif
|
||||
+#if CONFIG_H264_V4L2REQUEST_HWACCEL
|
||||
+ HWACCEL_V4L2REQUEST(h264),
|
||||
#endif
|
||||
NULL
|
||||
},
|
||||
diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h
|
||||
index ef54de2a3b..003200edea 100644
|
||||
--- a/libavcodec/hwaccels.h
|
||||
+++ b/libavcodec/hwaccels.h
|
||||
@@ -27,6 +27,7 @@ extern const AVHWAccel ff_h264_d3d11va_hwaccel;
|
||||
extern const AVHWAccel ff_h264_d3d11va2_hwaccel;
|
||||
extern const AVHWAccel ff_h264_dxva2_hwaccel;
|
||||
extern const AVHWAccel ff_h264_nvdec_hwaccel;
|
||||
+extern const AVHWAccel ff_h264_v4l2request_hwaccel;
|
||||
extern const AVHWAccel ff_h264_vaapi_hwaccel;
|
||||
extern const AVHWAccel ff_h264_vdpau_hwaccel;
|
||||
extern const AVHWAccel ff_h264_videotoolbox_hwaccel;
|
||||
diff --git a/libavcodec/v4l2_request_h264.c b/libavcodec/v4l2_request_h264.c
|
||||
new file mode 100644
|
||||
index 0000000000..a5c56d81c3
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/v4l2_request_h264.c
|
||||
@@ -0,0 +1,368 @@
|
||||
+/*
|
||||
+ * This file is part of FFmpeg.
|
||||
+ *
|
||||
+ * FFmpeg is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * FFmpeg is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with FFmpeg; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
+ */
|
||||
+
|
||||
+#include "h264dec.h"
|
||||
+#include "hwaccel.h"
|
||||
+#include "v4l2_request.h"
|
||||
+
|
||||
+typedef struct V4L2RequestControlsH264 {
|
||||
+ struct v4l2_ctrl_h264_sps sps;
|
||||
+ struct v4l2_ctrl_h264_pps pps;
|
||||
+ struct v4l2_ctrl_h264_scaling_matrix scaling_matrix;
|
||||
+ struct v4l2_ctrl_h264_decode_params decode_params;
|
||||
+ struct v4l2_ctrl_h264_slice_params slice_params;
|
||||
+} V4L2RequestControlsH264;
|
||||
+
|
||||
+static void fill_weight_factors(struct v4l2_h264_weight_factors *factors, int list, const H264SliceContext *sl)
|
||||
+{
|
||||
+ for (int i = 0; i < sl->ref_count[list]; i++) {
|
||||
+ if (sl->pwt.luma_weight_flag[list]) {
|
||||
+ factors->luma_weight[i] = sl->pwt.luma_weight[i][list][0];
|
||||
+ factors->luma_offset[i] = sl->pwt.luma_weight[i][list][1];
|
||||
+ } else {
|
||||
+ factors->luma_weight[i] = 1 << sl->pwt.luma_log2_weight_denom;
|
||||
+ factors->luma_offset[i] = 0;
|
||||
+ }
|
||||
+ for (int j = 0; j < 2; j++) {
|
||||
+ if (sl->pwt.chroma_weight_flag[list]) {
|
||||
+ factors->chroma_weight[i][j] = sl->pwt.chroma_weight[i][list][j][0];
|
||||
+ factors->chroma_offset[i][j] = sl->pwt.chroma_weight[i][list][j][1];
|
||||
+ } else {
|
||||
+ factors->chroma_weight[i][j] = 1 << sl->pwt.chroma_log2_weight_denom;
|
||||
+ factors->chroma_offset[i][j] = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void fill_dpb_entry(struct v4l2_h264_dpb_entry *entry, const H264Picture *pic)
|
||||
+{
|
||||
+ entry->reference_ts = ff_v4l2_request_get_capture_timestamp(pic->f);
|
||||
+ entry->frame_num = pic->frame_num;
|
||||
+ entry->pic_num = pic->pic_id;
|
||||
+ entry->flags = V4L2_H264_DPB_ENTRY_FLAG_VALID;
|
||||
+ if (pic->reference)
|
||||
+ entry->flags |= V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
|
||||
+ if (pic->long_ref)
|
||||
+ entry->flags |= V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM;
|
||||
+ entry->top_field_order_cnt = pic->field_poc[0];
|
||||
+ entry->bottom_field_order_cnt = pic->field_poc[1];
|
||||
+}
|
||||
+
|
||||
+static void fill_dpb(struct v4l2_ctrl_h264_decode_params *decode, const H264Context *h)
|
||||
+{
|
||||
+ int entries = 0;
|
||||
+
|
||||
+ for (int i = 0; i < h->short_ref_count; i++) {
|
||||
+ const H264Picture *pic = h->short_ref[i];
|
||||
+ if (pic)
|
||||
+ fill_dpb_entry(&decode->dpb[entries++], pic);
|
||||
+ }
|
||||
+
|
||||
+ if (!h->long_ref_count)
|
||||
+ return;
|
||||
+
|
||||
+ for (int i = 0; i < FF_ARRAY_ELEMS(h->long_ref); i++) {
|
||||
+ const H264Picture *pic = h->long_ref[i];
|
||||
+ if (pic)
|
||||
+ fill_dpb_entry(&decode->dpb[entries++], pic);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static uint8_t get_dpb_index(struct v4l2_ctrl_h264_decode_params *decode, const H264Ref *ref)
|
||||
+{
|
||||
+ uint64_t timestamp;
|
||||
+
|
||||
+ if (!ref->parent)
|
||||
+ return 0;
|
||||
+
|
||||
+ timestamp = ff_v4l2_request_get_capture_timestamp(ref->parent->f);
|
||||
+
|
||||
+ for (uint8_t i = 0; i < FF_ARRAY_ELEMS(decode->dpb); i++) {
|
||||
+ struct v4l2_h264_dpb_entry *entry = &decode->dpb[i];
|
||||
+ if ((entry->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID) &&
|
||||
+ entry->reference_ts == timestamp)
|
||||
+ // TODO: signal reference type, possible using top 2 bits
|
||||
+ return i | ((ref->reference & 3) << 6);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void fill_sps(struct v4l2_ctrl_h264_sps *ctrl, const H264Context *h)
|
||||
+{
|
||||
+ const SPS *sps = h->ps.sps;
|
||||
+
|
||||
+ *ctrl = (struct v4l2_ctrl_h264_sps) {
|
||||
+ .profile_idc = sps->profile_idc,
|
||||
+ .constraint_set_flags = sps->constraint_set_flags,
|
||||
+ .level_idc = sps->level_idc,
|
||||
+ .seq_parameter_set_id = sps->sps_id,
|
||||
+ .chroma_format_idc = sps->chroma_format_idc,
|
||||
+ .bit_depth_luma_minus8 = sps->bit_depth_luma - 8,
|
||||
+ .bit_depth_chroma_minus8 = sps->bit_depth_chroma - 8,
|
||||
+ .log2_max_frame_num_minus4 = sps->log2_max_frame_num - 4,
|
||||
+ .pic_order_cnt_type = sps->poc_type,
|
||||
+ .log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4,
|
||||
+ .max_num_ref_frames = sps->ref_frame_count,
|
||||
+ .num_ref_frames_in_pic_order_cnt_cycle = sps->poc_cycle_length,
|
||||
+ //.offset_for_ref_frame[255] - not required? not set by libva-v4l2-request - copy sps->offset_for_ref_frame
|
||||
+ .offset_for_non_ref_pic = sps->offset_for_non_ref_pic,
|
||||
+ .offset_for_top_to_bottom_field = sps->offset_for_top_to_bottom_field,
|
||||
+ .pic_width_in_mbs_minus1 = h->mb_width - 1,
|
||||
+ .pic_height_in_map_units_minus1 = sps->frame_mbs_only_flag ? h->mb_height - 1 : h->mb_height / 2 - 1,
|
||||
+ };
|
||||
+
|
||||
+ if (sps->residual_color_transform_flag)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE;
|
||||
+ if (sps->transform_bypass)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS;
|
||||
+ if (sps->delta_pic_order_always_zero_flag)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO;
|
||||
+ if (sps->gaps_in_frame_num_allowed_flag)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED;
|
||||
+ if (sps->frame_mbs_only_flag)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY;
|
||||
+ if (sps->mb_aff)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD;
|
||||
+ if (sps->direct_8x8_inference_flag)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE;
|
||||
+}
|
||||
+
|
||||
+static void fill_pps(struct v4l2_ctrl_h264_pps *ctrl, const H264Context *h)
|
||||
+{
|
||||
+ const PPS *pps = h->ps.pps;
|
||||
+ const H264SliceContext *sl = &h->slice_ctx[0];
|
||||
+
|
||||
+ *ctrl = (struct v4l2_ctrl_h264_pps) {
|
||||
+ .pic_parameter_set_id = sl->pps_id,
|
||||
+ .seq_parameter_set_id = pps->sps_id,
|
||||
+ .num_slice_groups_minus1 = pps->slice_group_count - 1,
|
||||
+ .num_ref_idx_l0_default_active_minus1 = pps->ref_count[0] - 1,
|
||||
+ .num_ref_idx_l1_default_active_minus1 = pps->ref_count[1] - 1,
|
||||
+ .weighted_bipred_idc = pps->weighted_bipred_idc,
|
||||
+ .pic_init_qp_minus26 = pps->init_qp - 26,
|
||||
+ .pic_init_qs_minus26 = pps->init_qs - 26,
|
||||
+ .chroma_qp_index_offset = pps->chroma_qp_index_offset[0],
|
||||
+ .second_chroma_qp_index_offset = pps->chroma_qp_index_offset[1],
|
||||
+ };
|
||||
+
|
||||
+ if (pps->cabac)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE;
|
||||
+ if (pps->pic_order_present)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT;
|
||||
+ if (pps->weighted_pred)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_WEIGHTED_PRED;
|
||||
+ if (pps->deblocking_filter_parameters_present)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT;
|
||||
+ if (pps->constrained_intra_pred)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED;
|
||||
+ if (pps->redundant_pic_cnt_present)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT;
|
||||
+ if (pps->transform_8x8_mode)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE;
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_h264_start_frame(AVCodecContext *avctx,
|
||||
+ av_unused const uint8_t *buffer,
|
||||
+ av_unused uint32_t size)
|
||||
+{
|
||||
+ const H264Context *h = avctx->priv_data;
|
||||
+ const PPS *pps = h->ps.pps;
|
||||
+ V4L2RequestControlsH264 *controls = h->cur_pic_ptr->hwaccel_picture_private;
|
||||
+
|
||||
+ fill_sps(&controls->sps, h);
|
||||
+ fill_pps(&controls->pps, h);
|
||||
+
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_4x4, pps->scaling_matrix4, sizeof(controls->scaling_matrix.scaling_list_4x4));
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8, pps->scaling_matrix8, sizeof(controls->scaling_matrix.scaling_list_8x8));
|
||||
+
|
||||
+ controls->decode_params = (struct v4l2_ctrl_h264_decode_params) {
|
||||
+ .num_slices = 0,
|
||||
+ .nal_ref_idc = h->nal_ref_idc,
|
||||
+ //.ref_pic_list_p0[32] - not required? not set by libva-v4l2-request
|
||||
+ //.ref_pic_list_b0[32] - not required? not set by libva-v4l2-request
|
||||
+ //.ref_pic_list_b1[32] - not required? not set by libva-v4l2-request
|
||||
+ .top_field_order_cnt = h->cur_pic_ptr->field_poc[0],
|
||||
+ .bottom_field_order_cnt = h->cur_pic_ptr->field_poc[1],
|
||||
+ };
|
||||
+
|
||||
+ if (h->picture_idr)
|
||||
+ controls->decode_params.flags |= V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC;
|
||||
+
|
||||
+ fill_dpb(&controls->decode_params, h);
|
||||
+
|
||||
+ return ff_v4l2_request_reset_frame(avctx, h->cur_pic_ptr->f);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_h264_end_frame(AVCodecContext *avctx)
|
||||
+{
|
||||
+ const H264Context *h = avctx->priv_data;
|
||||
+ V4L2RequestControlsH264 *controls = h->cur_pic_ptr->hwaccel_picture_private;
|
||||
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)h->cur_pic_ptr->f->data[0];
|
||||
+
|
||||
+ struct v4l2_ext_control control[] = {
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_SPS,
|
||||
+ .ptr = &controls->sps,
|
||||
+ .size = sizeof(controls->sps),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_PPS,
|
||||
+ .ptr = &controls->pps,
|
||||
+ .size = sizeof(controls->pps),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX,
|
||||
+ .ptr = &controls->scaling_matrix,
|
||||
+ .size = sizeof(controls->scaling_matrix),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS,
|
||||
+ .ptr = &controls->slice_params,
|
||||
+ .size = sizeof(controls->slice_params),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS,
|
||||
+ .ptr = &controls->decode_params,
|
||||
+ .size = sizeof(controls->decode_params),
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ controls->slice_params.size = req->output.used;
|
||||
+
|
||||
+ return ff_v4l2_request_decode_frame(avctx, h->cur_pic_ptr->f, control, FF_ARRAY_ELEMS(control));
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
|
||||
+{
|
||||
+ const H264Context *h = avctx->priv_data;
|
||||
+ const PPS *pps = h->ps.pps;
|
||||
+ const H264SliceContext *sl = &h->slice_ctx[0];
|
||||
+ V4L2RequestControlsH264 *controls = h->cur_pic_ptr->hwaccel_picture_private;
|
||||
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)h->cur_pic_ptr->f->data[0];
|
||||
+ int i, count;
|
||||
+
|
||||
+ // HACK: trigger decode per slice
|
||||
+ if (req->output.used) {
|
||||
+ v4l2_request_h264_end_frame(avctx);
|
||||
+ ff_v4l2_request_reset_frame(avctx, h->cur_pic_ptr->f);
|
||||
+ }
|
||||
+
|
||||
+ controls->decode_params.num_slices++;
|
||||
+
|
||||
+ controls->slice_params = (struct v4l2_ctrl_h264_slice_params) {
|
||||
+ /* Size in bytes, including header */
|
||||
+ .size = 0,
|
||||
+ /* Offset in bits to slice_data() from the beginning of this slice. */
|
||||
+ .header_bit_size = get_bits_count(&sl->gb),
|
||||
+
|
||||
+ .first_mb_in_slice = sl->first_mb_addr,
|
||||
+ .slice_type = ff_h264_get_slice_type(sl),
|
||||
+ .pic_parameter_set_id = sl->pps_id,
|
||||
+ .colour_plane_id = 0, /* what is this? */
|
||||
+ .frame_num = h->poc.frame_num,
|
||||
+ .idr_pic_id = 0, /* what is this? */
|
||||
+ .pic_order_cnt_lsb = sl->poc_lsb,
|
||||
+ .delta_pic_order_cnt_bottom = sl->delta_poc_bottom,
|
||||
+ .delta_pic_order_cnt0 = sl->delta_poc[0],
|
||||
+ .delta_pic_order_cnt1 = sl->delta_poc[1],
|
||||
+ .redundant_pic_cnt = sl->redundant_pic_count,
|
||||
+
|
||||
+ /* Size in bits of dec_ref_pic_marking() syntax element. */
|
||||
+ .dec_ref_pic_marking_bit_size = 0,
|
||||
+ /* Size in bits of pic order count syntax. */
|
||||
+ .pic_order_cnt_bit_size = 0,
|
||||
+
|
||||
+ .cabac_init_idc = sl->cabac_init_idc,
|
||||
+ .slice_qp_delta = sl->qscale - pps->init_qp,
|
||||
+ .slice_qs_delta = 0, /* XXX not implemented by FFmpeg */
|
||||
+ .disable_deblocking_filter_idc = sl->deblocking_filter < 2 ? !sl->deblocking_filter : sl->deblocking_filter,
|
||||
+ .slice_alpha_c0_offset_div2 = sl->slice_alpha_c0_offset / 2,
|
||||
+ .slice_beta_offset_div2 = sl->slice_beta_offset / 2,
|
||||
+ .slice_group_change_cycle = 0, /* what is this? */
|
||||
+
|
||||
+ .num_ref_idx_l0_active_minus1 = sl->list_count > 0 ? sl->ref_count[0] - 1 : 0,
|
||||
+ .num_ref_idx_l1_active_minus1 = sl->list_count > 1 ? sl->ref_count[1] - 1 : 0,
|
||||
+ };
|
||||
+
|
||||
+ if (FIELD_PICTURE(h))
|
||||
+ controls->slice_params.flags |= V4L2_H264_SLICE_FLAG_FIELD_PIC;
|
||||
+ if (h->picture_structure == PICT_BOTTOM_FIELD)
|
||||
+ controls->slice_params.flags |= V4L2_H264_SLICE_FLAG_BOTTOM_FIELD;
|
||||
+ if (sl->slice_type == AV_PICTURE_TYPE_B && sl->direct_spatial_mv_pred)
|
||||
+ controls->slice_params.flags |= V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED;
|
||||
+
|
||||
+ controls->slice_params.pred_weight_table.chroma_log2_weight_denom = sl->pwt.chroma_log2_weight_denom;
|
||||
+ controls->slice_params.pred_weight_table.luma_log2_weight_denom = sl->pwt.luma_log2_weight_denom;
|
||||
+
|
||||
+ count = sl->list_count > 0 ? sl->ref_count[0] : 0;
|
||||
+ for (i = 0; i < count; i++)
|
||||
+ controls->slice_params.ref_pic_list0[i] = get_dpb_index(&controls->decode_params, &sl->ref_list[0][i]);
|
||||
+ if (count)
|
||||
+ fill_weight_factors(&controls->slice_params.pred_weight_table.weight_factors[0], 0, sl);
|
||||
+
|
||||
+ count = sl->list_count > 1 ? sl->ref_count[1] : 0;
|
||||
+ for (i = 0; i < count; i++)
|
||||
+ controls->slice_params.ref_pic_list1[i] = get_dpb_index(&controls->decode_params, &sl->ref_list[1][i]);
|
||||
+ if (count)
|
||||
+ fill_weight_factors(&controls->slice_params.pred_weight_table.weight_factors[1], 1, sl);
|
||||
+
|
||||
+ return ff_v4l2_request_append_output_buffer(avctx, h->cur_pic_ptr->f, buffer, size);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_h264_init(AVCodecContext *avctx)
|
||||
+{
|
||||
+ const H264Context *h = avctx->priv_data;
|
||||
+ struct v4l2_ctrl_h264_sps sps;
|
||||
+ struct v4l2_ctrl_h264_pps pps;
|
||||
+
|
||||
+ struct v4l2_ext_control control[] = {
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_SPS,
|
||||
+ .ptr = &sps,
|
||||
+ .size = sizeof(sps),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_PPS,
|
||||
+ .ptr = &pps,
|
||||
+ .size = sizeof(pps),
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ fill_sps(&sps, h);
|
||||
+ fill_pps(&pps, h);
|
||||
+
|
||||
+ return ff_v4l2_request_init(avctx, V4L2_PIX_FMT_H264_SLICE_RAW, 2 * 1024 * 1024, control, FF_ARRAY_ELEMS(control));
|
||||
+}
|
||||
+
|
||||
+const AVHWAccel ff_h264_v4l2request_hwaccel = {
|
||||
+ .name = "h264_v4l2request",
|
||||
+ .type = AVMEDIA_TYPE_VIDEO,
|
||||
+ .id = AV_CODEC_ID_H264,
|
||||
+ .pix_fmt = AV_PIX_FMT_DRM_PRIME,
|
||||
+ .start_frame = v4l2_request_h264_start_frame,
|
||||
+ .decode_slice = v4l2_request_h264_decode_slice,
|
||||
+ .end_frame = v4l2_request_h264_end_frame,
|
||||
+ .frame_priv_data_size = sizeof(V4L2RequestControlsH264),
|
||||
+ .init = v4l2_request_h264_init,
|
||||
+ .uninit = ff_v4l2_request_uninit,
|
||||
+ .priv_data_size = sizeof(V4L2RequestContext),
|
||||
+ .frame_params = ff_v4l2_request_frame_params,
|
||||
+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
|
||||
+};
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,503 @@
|
||||
From 25065e4e219c6bd688e6b62e40be74f1cfa08e72 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 15 Dec 2018 22:32:16 +0100
|
||||
Subject: [PATCH 5/6] Add V4L2 request API hevc hwaccel
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
configure | 3 +
|
||||
libavcodec/Makefile | 1 +
|
||||
libavcodec/hevcdec.c | 10 +
|
||||
libavcodec/hwaccels.h | 1 +
|
||||
libavcodec/v4l2_request_hevc.c | 391 +++++++++++++++++++++++++++++++++
|
||||
5 files changed, 406 insertions(+)
|
||||
create mode 100644 libavcodec/v4l2_request_hevc.c
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index 296ca78ce7..9252ca5794 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -2820,6 +2820,8 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC"
|
||||
hevc_dxva2_hwaccel_select="hevc_decoder"
|
||||
hevc_nvdec_hwaccel_deps="nvdec"
|
||||
hevc_nvdec_hwaccel_select="hevc_decoder"
|
||||
+hevc_v4l2request_hwaccel_deps="v4l2_request hevc_v4l2_request"
|
||||
+hevc_v4l2request_hwaccel_select="hevc_decoder"
|
||||
hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC"
|
||||
hevc_vaapi_hwaccel_select="hevc_decoder"
|
||||
hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC"
|
||||
@@ -6242,6 +6244,7 @@ check_cc vp9_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;"
|
||||
|
||||
check_func_headers "linux/media.h linux/videodev2.h" v4l2_timeval_to_ns
|
||||
check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_H264_SLICE_RAW;"
|
||||
+check_cc hevc_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_HEVC_SLICE;"
|
||||
check_cc mpeg2_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2_SLICE;"
|
||||
|
||||
check_header sys/videoio.h
|
||||
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
|
||||
index 2bdfaabb5f..a4c959e0f5 100644
|
||||
--- a/libavcodec/Makefile
|
||||
+++ b/libavcodec/Makefile
|
||||
@@ -860,6 +860,7 @@ OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL) += dxva2_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_NVDEC_HWACCEL) += nvdec_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec_h2645.o
|
||||
+OBJS-$(CONFIG_HEVC_V4L2REQUEST_HWACCEL) += v4l2_request_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o
|
||||
OBJS-$(CONFIG_MJPEG_NVDEC_HWACCEL) += nvdec_mjpeg.o
|
||||
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
|
||||
index c8877626d2..df33433150 100644
|
||||
--- a/libavcodec/hevcdec.c
|
||||
+++ b/libavcodec/hevcdec.c
|
||||
@@ -362,6 +362,7 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
|
||||
#define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL + \
|
||||
CONFIG_HEVC_D3D11VA_HWACCEL * 2 + \
|
||||
CONFIG_HEVC_NVDEC_HWACCEL + \
|
||||
+ CONFIG_HEVC_V4L2REQUEST_HWACCEL + \
|
||||
CONFIG_HEVC_VAAPI_HWACCEL + \
|
||||
CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL + \
|
||||
CONFIG_HEVC_VDPAU_HWACCEL)
|
||||
@@ -388,6 +389,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
|
||||
#endif
|
||||
#if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL
|
||||
*fmt++ = AV_PIX_FMT_VIDEOTOOLBOX;
|
||||
+#endif
|
||||
+#if CONFIG_HEVC_V4L2REQUEST_HWACCEL
|
||||
+ *fmt++ = AV_PIX_FMT_DRM_PRIME;
|
||||
#endif
|
||||
break;
|
||||
case AV_PIX_FMT_YUV420P10:
|
||||
@@ -406,6 +410,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
|
||||
#endif
|
||||
#if CONFIG_HEVC_NVDEC_HWACCEL
|
||||
*fmt++ = AV_PIX_FMT_CUDA;
|
||||
+#endif
|
||||
+#if CONFIG_HEVC_V4L2REQUEST_HWACCEL
|
||||
+ *fmt++ = AV_PIX_FMT_DRM_PRIME;
|
||||
#endif
|
||||
break;
|
||||
case AV_PIX_FMT_YUV420P12:
|
||||
@@ -3556,6 +3563,9 @@ AVCodec ff_hevc_decoder = {
|
||||
#endif
|
||||
#if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL
|
||||
HWACCEL_VIDEOTOOLBOX(hevc),
|
||||
+#endif
|
||||
+#if CONFIG_HEVC_V4L2REQUEST_HWACCEL
|
||||
+ HWACCEL_V4L2REQUEST(hevc),
|
||||
#endif
|
||||
NULL
|
||||
},
|
||||
diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h
|
||||
index 003200edea..d183675abe 100644
|
||||
--- a/libavcodec/hwaccels.h
|
||||
+++ b/libavcodec/hwaccels.h
|
||||
@@ -35,6 +35,7 @@ extern const AVHWAccel ff_hevc_d3d11va_hwaccel;
|
||||
extern const AVHWAccel ff_hevc_d3d11va2_hwaccel;
|
||||
extern const AVHWAccel ff_hevc_dxva2_hwaccel;
|
||||
extern const AVHWAccel ff_hevc_nvdec_hwaccel;
|
||||
+extern const AVHWAccel ff_hevc_v4l2request_hwaccel;
|
||||
extern const AVHWAccel ff_hevc_vaapi_hwaccel;
|
||||
extern const AVHWAccel ff_hevc_vdpau_hwaccel;
|
||||
extern const AVHWAccel ff_hevc_videotoolbox_hwaccel;
|
||||
diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c
|
||||
new file mode 100644
|
||||
index 0000000000..300c1866ce
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/v4l2_request_hevc.c
|
||||
@@ -0,0 +1,391 @@
|
||||
+/*
|
||||
+ * This file is part of FFmpeg.
|
||||
+ *
|
||||
+ * FFmpeg is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * FFmpeg is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with FFmpeg; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
+ */
|
||||
+
|
||||
+#include "hevcdec.h"
|
||||
+#include "hwaccel.h"
|
||||
+#include "v4l2_request.h"
|
||||
+
|
||||
+typedef struct V4L2RequestControlsHEVC {
|
||||
+ struct v4l2_ctrl_hevc_sps sps;
|
||||
+ struct v4l2_ctrl_hevc_pps pps;
|
||||
+ struct v4l2_ctrl_hevc_scaling_matrix scaling_matrix;
|
||||
+ struct v4l2_ctrl_hevc_slice_params slice_params;
|
||||
+} V4L2RequestControlsHEVC;
|
||||
+
|
||||
+static void v4l2_request_hevc_fill_pred_table(const HEVCContext *h, struct v4l2_hevc_pred_weight_table *table)
|
||||
+{
|
||||
+ int32_t luma_weight_denom, chroma_weight_denom;
|
||||
+ const SliceHeader *sh = &h->sh;
|
||||
+
|
||||
+ if (sh->slice_type == HEVC_SLICE_I ||
|
||||
+ (sh->slice_type == HEVC_SLICE_P && !h->ps.pps->weighted_pred_flag) ||
|
||||
+ (sh->slice_type == HEVC_SLICE_B && !h->ps.pps->weighted_bipred_flag))
|
||||
+ return;
|
||||
+
|
||||
+ table->luma_log2_weight_denom = sh->luma_log2_weight_denom;
|
||||
+
|
||||
+ if (h->ps.sps->chroma_format_idc)
|
||||
+ table->delta_chroma_log2_weight_denom = sh->chroma_log2_weight_denom - sh->luma_log2_weight_denom;
|
||||
+
|
||||
+ luma_weight_denom = (1 << sh->luma_log2_weight_denom);
|
||||
+ chroma_weight_denom = (1 << sh->chroma_log2_weight_denom);
|
||||
+
|
||||
+ for (int i = 0; i < 15 && i < sh->nb_refs[L0]; i++) {
|
||||
+ table->delta_luma_weight_l0[i] = sh->luma_weight_l0[i] - luma_weight_denom;
|
||||
+ table->luma_offset_l0[i] = sh->luma_offset_l0[i];
|
||||
+ table->delta_chroma_weight_l0[i][0] = sh->chroma_weight_l0[i][0] - chroma_weight_denom;
|
||||
+ table->delta_chroma_weight_l0[i][1] = sh->chroma_weight_l0[i][1] - chroma_weight_denom;
|
||||
+ table->chroma_offset_l0[i][0] = sh->chroma_offset_l0[i][0];
|
||||
+ table->chroma_offset_l0[i][1] = sh->chroma_offset_l0[i][1];
|
||||
+ }
|
||||
+
|
||||
+ if (sh->slice_type != HEVC_SLICE_B)
|
||||
+ return;
|
||||
+
|
||||
+ for (int i = 0; i < 15 && i < sh->nb_refs[L1]; i++) {
|
||||
+ table->delta_luma_weight_l1[i] = sh->luma_weight_l1[i] - luma_weight_denom;
|
||||
+ table->luma_offset_l1[i] = sh->luma_offset_l1[i];
|
||||
+ table->delta_chroma_weight_l1[i][0] = sh->chroma_weight_l1[i][0] - chroma_weight_denom;
|
||||
+ table->delta_chroma_weight_l1[i][1] = sh->chroma_weight_l1[i][1] - chroma_weight_denom;
|
||||
+ table->chroma_offset_l1[i][0] = sh->chroma_offset_l1[i][0];
|
||||
+ table->chroma_offset_l1[i][1] = sh->chroma_offset_l1[i][1];
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int find_frame_rps_type(const HEVCContext *h, uint64_t timestamp)
|
||||
+{
|
||||
+ const HEVCFrame *frame;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < h->rps[ST_CURR_BEF].nb_refs; i++) {
|
||||
+ frame = h->rps[ST_CURR_BEF].ref[i];
|
||||
+ if (frame && timestamp == ff_v4l2_request_get_capture_timestamp(frame->frame))
|
||||
+ return V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < h->rps[ST_CURR_AFT].nb_refs; i++) {
|
||||
+ frame = h->rps[ST_CURR_AFT].ref[i];
|
||||
+ if (frame && timestamp == ff_v4l2_request_get_capture_timestamp(frame->frame))
|
||||
+ return V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < h->rps[LT_CURR].nb_refs; i++) {
|
||||
+ frame = h->rps[LT_CURR].ref[i];
|
||||
+ if (frame && timestamp == ff_v4l2_request_get_capture_timestamp(frame->frame))
|
||||
+ return V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static uint8_t get_ref_pic_index(const HEVCContext *h, const HEVCFrame *frame,
|
||||
+ struct v4l2_ctrl_hevc_slice_params *slice_params)
|
||||
+{
|
||||
+ uint64_t timestamp;
|
||||
+
|
||||
+ if (!frame)
|
||||
+ return 0;
|
||||
+
|
||||
+ timestamp = ff_v4l2_request_get_capture_timestamp(frame->frame);
|
||||
+
|
||||
+ for (uint8_t i = 0; i < slice_params->num_active_dpb_entries; i++) {
|
||||
+ struct v4l2_hevc_dpb_entry *entry = &slice_params->dpb[i];
|
||||
+ if (entry->timestamp == timestamp)
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void v4l2_request_hevc_fill_slice_params(const HEVCContext *h,
|
||||
+ struct v4l2_ctrl_hevc_slice_params *slice_params)
|
||||
+{
|
||||
+ const HEVCFrame *pic = h->ref;
|
||||
+ const SliceHeader *sh = &h->sh;
|
||||
+ int i, entries = 0;
|
||||
+ RefPicList *rpl;
|
||||
+
|
||||
+ *slice_params = (struct v4l2_ctrl_hevc_slice_params) {
|
||||
+ .bit_size = 0,
|
||||
+ .data_bit_offset = get_bits_count(&h->HEVClc->gb),
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */
|
||||
+ .nal_unit_type = h->nal_unit_type,
|
||||
+ .nuh_temporal_id_plus1 = h->temporal_id + 1,
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ .slice_type = sh->slice_type,
|
||||
+ .colour_plane_id = sh->colour_plane_id,
|
||||
+ .slice_pic_order_cnt = pic->poc,
|
||||
+ .slice_sao_luma_flag = sh->slice_sample_adaptive_offset_flag[0],
|
||||
+ .slice_sao_chroma_flag = sh->slice_sample_adaptive_offset_flag[1],
|
||||
+ .slice_temporal_mvp_enabled_flag = sh->slice_temporal_mvp_enabled_flag,
|
||||
+ .num_ref_idx_l0_active_minus1 = sh->nb_refs[L0] ? sh->nb_refs[L0] - 1 : 0,
|
||||
+ .num_ref_idx_l1_active_minus1 = sh->nb_refs[L1] ? sh->nb_refs[L1] - 1 : 0,
|
||||
+ .mvd_l1_zero_flag = sh->mvd_l1_zero_flag,
|
||||
+ .cabac_init_flag = sh->cabac_init_flag,
|
||||
+ .collocated_from_l0_flag = sh->collocated_list == L0 ? 1 : 0,
|
||||
+ .collocated_ref_idx = sh->slice_temporal_mvp_enabled_flag ? sh->collocated_ref_idx : 0,
|
||||
+ .five_minus_max_num_merge_cand = sh->slice_type == HEVC_SLICE_I ? 0 : 5 - sh->max_num_merge_cand,
|
||||
+ .use_integer_mv_flag = 0,
|
||||
+ .slice_qp_delta = sh->slice_qp_delta,
|
||||
+ .slice_cb_qp_offset = sh->slice_cb_qp_offset,
|
||||
+ .slice_cr_qp_offset = sh->slice_cr_qp_offset,
|
||||
+ .slice_act_y_qp_offset = 0,
|
||||
+ .slice_act_cb_qp_offset = 0,
|
||||
+ .slice_act_cr_qp_offset = 0,
|
||||
+ .slice_deblocking_filter_disabled_flag = sh->disable_deblocking_filter_flag,
|
||||
+ .slice_beta_offset_div2 = sh->beta_offset / 2,
|
||||
+ .slice_tc_offset_div2 = sh->tc_offset / 2,
|
||||
+ .slice_loop_filter_across_slices_enabled_flag = sh->slice_loop_filter_across_slices_enabled_flag,
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture timing SEI message */
|
||||
+ .pic_struct = h->sei.picture_timing.picture_struct,
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ .num_rps_poc_st_curr_before = h->rps[ST_CURR_BEF].nb_refs,
|
||||
+ .num_rps_poc_st_curr_after = h->rps[ST_CURR_AFT].nb_refs,
|
||||
+ .num_rps_poc_lt_curr = h->rps[LT_CURR].nb_refs,
|
||||
+
|
||||
+ .slice_segment_addr = sh->slice_segment_addr,
|
||||
+ .first_slice_segment_in_pic_flag = sh->first_slice_in_pic_flag,
|
||||
+ };
|
||||
+
|
||||
+ for (i = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) {
|
||||
+ const HEVCFrame *frame = &h->DPB[i];
|
||||
+ if (frame != pic && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) {
|
||||
+ struct v4l2_hevc_dpb_entry *entry = &slice_params->dpb[entries++];
|
||||
+
|
||||
+ entry->timestamp = ff_v4l2_request_get_capture_timestamp(frame->frame);
|
||||
+ entry->rps = find_frame_rps_type(h, entry->timestamp);
|
||||
+ entry->field_pic = frame->frame->interlaced_frame;
|
||||
+
|
||||
+ /* TODO: Interleaved: Get the POC for each field. */
|
||||
+ entry->pic_order_cnt[0] = frame->poc;
|
||||
+ entry->pic_order_cnt[1] = frame->poc;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ slice_params->num_active_dpb_entries = entries;
|
||||
+
|
||||
+ if (sh->slice_type != HEVC_SLICE_I) {
|
||||
+ rpl = &h->ref->refPicList[0];
|
||||
+ for (i = 0; i < rpl->nb_refs; i++)
|
||||
+ slice_params->ref_idx_l0[i] = get_ref_pic_index(h, rpl->ref[i], slice_params);
|
||||
+ }
|
||||
+
|
||||
+ if (sh->slice_type == HEVC_SLICE_B) {
|
||||
+ rpl = &h->ref->refPicList[1];
|
||||
+ for (i = 0; i < rpl->nb_refs; i++)
|
||||
+ slice_params->ref_idx_l1[i] = get_ref_pic_index(h, rpl->ref[i], slice_params);
|
||||
+ }
|
||||
+
|
||||
+ v4l2_request_hevc_fill_pred_table(h, &slice_params->pred_weight_table);
|
||||
+
|
||||
+ slice_params->num_entry_point_offsets = sh->num_entry_point_offsets;
|
||||
+ if (slice_params->num_entry_point_offsets > 256) {
|
||||
+ slice_params->num_entry_point_offsets = 256;
|
||||
+ av_log(NULL, AV_LOG_ERROR, "%s: Currently only 256 entry points are supported, but slice has %d entry points.\n", __func__, sh->num_entry_point_offsets);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < slice_params->num_entry_point_offsets; i++)
|
||||
+ slice_params->entry_point_offset_minus1[i] = sh->entry_point_offset[i] - 1;
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_start_frame(AVCodecContext *avctx,
|
||||
+ av_unused const uint8_t *buffer,
|
||||
+ av_unused uint32_t size)
|
||||
+{
|
||||
+ const HEVCContext *h = avctx->priv_data;
|
||||
+ const HEVCSPS *sps = h->ps.sps;
|
||||
+ const HEVCPPS *pps = h->ps.pps;
|
||||
+ const ScalingList *sl = pps->scaling_list_data_present_flag ?
|
||||
+ &pps->scaling_list :
|
||||
+ sps->scaling_list_enable_flag ?
|
||||
+ &sps->scaling_list : NULL;
|
||||
+ V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */
|
||||
+ controls->sps = (struct v4l2_ctrl_hevc_sps) {
|
||||
+ .chroma_format_idc = sps->chroma_format_idc,
|
||||
+ .separate_colour_plane_flag = sps->separate_colour_plane_flag,
|
||||
+ .pic_width_in_luma_samples = sps->width,
|
||||
+ .pic_height_in_luma_samples = sps->height,
|
||||
+ .bit_depth_luma_minus8 = sps->bit_depth - 8,
|
||||
+ .bit_depth_chroma_minus8 = sps->bit_depth - 8,
|
||||
+ .log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4,
|
||||
+ .sps_max_dec_pic_buffering_minus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering - 1,
|
||||
+ .sps_max_num_reorder_pics = sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics,
|
||||
+ .sps_max_latency_increase_plus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_latency_increase + 1,
|
||||
+ .log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3,
|
||||
+ .log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_coding_block_size,
|
||||
+ .log2_min_luma_transform_block_size_minus2 = sps->log2_min_tb_size - 2,
|
||||
+ .log2_diff_max_min_luma_transform_block_size = sps->log2_max_trafo_size - sps->log2_min_tb_size,
|
||||
+ .max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter,
|
||||
+ .max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra,
|
||||
+ .scaling_list_enabled_flag = sps->scaling_list_enable_flag,
|
||||
+ .amp_enabled_flag = sps->amp_enabled_flag,
|
||||
+ .sample_adaptive_offset_enabled_flag = sps->sao_enabled,
|
||||
+ .pcm_enabled_flag = sps->pcm_enabled_flag,
|
||||
+ .pcm_sample_bit_depth_luma_minus1 = sps->pcm.bit_depth - 1,
|
||||
+ .pcm_sample_bit_depth_chroma_minus1 = sps->pcm.bit_depth_chroma - 1,
|
||||
+ .log2_min_pcm_luma_coding_block_size_minus3 = sps->pcm.log2_min_pcm_cb_size - 3,
|
||||
+ .log2_diff_max_min_pcm_luma_coding_block_size = sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size,
|
||||
+ .pcm_loop_filter_disabled_flag = sps->pcm.loop_filter_disable_flag,
|
||||
+ .num_short_term_ref_pic_sets = sps->nb_st_rps,
|
||||
+ .long_term_ref_pics_present_flag = sps->long_term_ref_pics_present_flag,
|
||||
+ .num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps,
|
||||
+ .sps_temporal_mvp_enabled_flag = sps->sps_temporal_mvp_enabled_flag,
|
||||
+ .strong_intra_smoothing_enabled_flag = sps->sps_strong_intra_smoothing_enable_flag,
|
||||
+ };
|
||||
+
|
||||
+ if (sl) {
|
||||
+ for (int i = 0; i < 6; i++) {
|
||||
+ for (int j = 0; j < 16; j++)
|
||||
+ controls->scaling_matrix.scaling_list_4x4[i][j] = sl->sl[0][i][j];
|
||||
+ for (int j = 0; j < 64; j++) {
|
||||
+ controls->scaling_matrix.scaling_list_8x8[i][j] = sl->sl[1][i][j];
|
||||
+ controls->scaling_matrix.scaling_list_16x16[i][j] = sl->sl[2][i][j];
|
||||
+ if (i < 2)
|
||||
+ controls->scaling_matrix.scaling_list_32x32[i][j] = sl->sl[3][i * 3][j];
|
||||
+ }
|
||||
+ controls->scaling_matrix.scaling_list_dc_coef_16x16[i] = sl->sl_dc[0][i];
|
||||
+ if (i < 2)
|
||||
+ controls->scaling_matrix.scaling_list_dc_coef_32x32[i] = sl->sl_dc[1][i * 3];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */
|
||||
+ controls->pps = (struct v4l2_ctrl_hevc_pps) {
|
||||
+ .dependent_slice_segment_flag = pps->dependent_slice_segments_enabled_flag,
|
||||
+ .output_flag_present_flag = pps->output_flag_present_flag,
|
||||
+ .num_extra_slice_header_bits = pps->num_extra_slice_header_bits,
|
||||
+ .sign_data_hiding_enabled_flag = pps->sign_data_hiding_flag,
|
||||
+ .cabac_init_present_flag = pps->cabac_init_present_flag,
|
||||
+ .init_qp_minus26 = pps->pic_init_qp_minus26,
|
||||
+ .constrained_intra_pred_flag = pps->constrained_intra_pred_flag,
|
||||
+ .transform_skip_enabled_flag = pps->transform_skip_enabled_flag,
|
||||
+ .cu_qp_delta_enabled_flag = pps->cu_qp_delta_enabled_flag,
|
||||
+ .diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth,
|
||||
+ .pps_cb_qp_offset = pps->cb_qp_offset,
|
||||
+ .pps_cr_qp_offset = pps->cr_qp_offset,
|
||||
+ .pps_slice_chroma_qp_offsets_present_flag = pps->pic_slice_level_chroma_qp_offsets_present_flag,
|
||||
+ .weighted_pred_flag = pps->weighted_pred_flag,
|
||||
+ .weighted_bipred_flag = pps->weighted_bipred_flag,
|
||||
+ .transquant_bypass_enabled_flag = pps->transquant_bypass_enable_flag,
|
||||
+ .tiles_enabled_flag = pps->tiles_enabled_flag,
|
||||
+ .entropy_coding_sync_enabled_flag = pps->entropy_coding_sync_enabled_flag,
|
||||
+ .loop_filter_across_tiles_enabled_flag = pps->loop_filter_across_tiles_enabled_flag,
|
||||
+ .pps_loop_filter_across_slices_enabled_flag = pps->seq_loop_filter_across_slices_enabled_flag,
|
||||
+ .deblocking_filter_override_enabled_flag = pps->deblocking_filter_override_enabled_flag,
|
||||
+ .pps_disable_deblocking_filter_flag = pps->disable_dbf,
|
||||
+ .pps_beta_offset_div2 = pps->beta_offset / 2,
|
||||
+ .pps_tc_offset_div2 = pps->tc_offset / 2,
|
||||
+ .lists_modification_present_flag = pps->lists_modification_present_flag,
|
||||
+ .log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2,
|
||||
+ .slice_segment_header_extension_present_flag = pps->slice_header_extension_present_flag,
|
||||
+ .scaling_list_enable_flag = pps->scaling_list_data_present_flag, // pps_scaling_list_data_present_flag
|
||||
+ };
|
||||
+
|
||||
+ if (pps->tiles_enabled_flag) {
|
||||
+ controls->pps.num_tile_columns_minus1 = pps->num_tile_columns - 1;
|
||||
+ controls->pps.num_tile_rows_minus1 = pps->num_tile_rows - 1;
|
||||
+
|
||||
+ av_log(avctx, AV_LOG_DEBUG, "%s: avctx=%p tiles_enabled_flag=%d num_tile_columns=%d num_tile_rows=%d\n", __func__, avctx, pps->tiles_enabled_flag, pps->num_tile_columns, pps->num_tile_rows);
|
||||
+
|
||||
+ for (int i = 0; i < pps->num_tile_columns; i++)
|
||||
+ controls->pps.column_width_minus1[i] = pps->column_width[i] - 1;
|
||||
+
|
||||
+ for (int i = 0; i < pps->num_tile_rows; i++)
|
||||
+ controls->pps.row_height_minus1[i] = pps->row_height[i] - 1;
|
||||
+ }
|
||||
+
|
||||
+ return ff_v4l2_request_reset_frame(avctx, h->ref->frame);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_end_frame(AVCodecContext *avctx)
|
||||
+{
|
||||
+ const HEVCContext *h = avctx->priv_data;
|
||||
+ V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private;
|
||||
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)h->ref->frame->data[0];
|
||||
+
|
||||
+ struct v4l2_ext_control control[] = {
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS,
|
||||
+ .ptr = &controls->sps,
|
||||
+ .size = sizeof(controls->sps),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS,
|
||||
+ .ptr = &controls->pps,
|
||||
+ .size = sizeof(controls->pps),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX,
|
||||
+ .ptr = &controls->scaling_matrix,
|
||||
+ .size = sizeof(controls->scaling_matrix),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS,
|
||||
+ .ptr = &controls->slice_params,
|
||||
+ .size = sizeof(controls->slice_params),
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ controls->slice_params.bit_size = req->output.used * 8;
|
||||
+
|
||||
+ return ff_v4l2_request_decode_frame(avctx, h->ref->frame, control, FF_ARRAY_ELEMS(control));
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
|
||||
+{
|
||||
+ const HEVCContext *h = avctx->priv_data;
|
||||
+ V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private;
|
||||
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)h->ref->frame->data[0];
|
||||
+
|
||||
+ // HACK: trigger decode per slice
|
||||
+ if (req->output.used) {
|
||||
+ v4l2_request_hevc_end_frame(avctx);
|
||||
+ ff_v4l2_request_reset_frame(avctx, h->ref->frame);
|
||||
+ }
|
||||
+
|
||||
+ v4l2_request_hevc_fill_slice_params(h, &controls->slice_params);
|
||||
+
|
||||
+ return ff_v4l2_request_append_output_buffer(avctx, h->ref->frame, buffer, size);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_init(AVCodecContext *avctx)
|
||||
+{
|
||||
+ return ff_v4l2_request_init(avctx, V4L2_PIX_FMT_HEVC_SLICE, 2 * 1024 * 1024, NULL, 0);
|
||||
+}
|
||||
+
|
||||
+const AVHWAccel ff_hevc_v4l2request_hwaccel = {
|
||||
+ .name = "hevc_v4l2request",
|
||||
+ .type = AVMEDIA_TYPE_VIDEO,
|
||||
+ .id = AV_CODEC_ID_HEVC,
|
||||
+ .pix_fmt = AV_PIX_FMT_DRM_PRIME,
|
||||
+ .start_frame = v4l2_request_hevc_start_frame,
|
||||
+ .decode_slice = v4l2_request_hevc_decode_slice,
|
||||
+ .end_frame = v4l2_request_hevc_end_frame,
|
||||
+ .frame_priv_data_size = sizeof(V4L2RequestControlsHEVC),
|
||||
+ .init = v4l2_request_hevc_init,
|
||||
+ .uninit = ff_v4l2_request_uninit,
|
||||
+ .priv_data_size = sizeof(V4L2RequestContext),
|
||||
+ .frame_params = ff_v4l2_request_frame_params,
|
||||
+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
|
||||
+};
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,546 @@
|
||||
From 583677006f15ee59600f6f30f5e79aa5f81935b9 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Thu, 14 Feb 2019 23:20:05 +0100
|
||||
Subject: [PATCH 6/6] Add and use private linux headers for V4L2 request API
|
||||
ctrls
|
||||
|
||||
---
|
||||
libavcodec/h264-ctrls.h | 192 +++++++++++++++++++++++++++++++
|
||||
libavcodec/hevc-ctrls.h | 197 ++++++++++++++++++++++++++++++++
|
||||
libavcodec/mpeg2-ctrls.h | 82 +++++++++++++
|
||||
libavcodec/v4l2_request_h264.c | 1 +
|
||||
libavcodec/v4l2_request_hevc.c | 1 +
|
||||
libavcodec/v4l2_request_mpeg2.c | 1 +
|
||||
6 files changed, 474 insertions(+)
|
||||
create mode 100644 libavcodec/h264-ctrls.h
|
||||
create mode 100644 libavcodec/hevc-ctrls.h
|
||||
create mode 100644 libavcodec/mpeg2-ctrls.h
|
||||
|
||||
diff --git a/libavcodec/h264-ctrls.h b/libavcodec/h264-ctrls.h
|
||||
new file mode 100644
|
||||
index 0000000000..e2f83b3cdb
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/h264-ctrls.h
|
||||
@@ -0,0 +1,192 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * These are the H.264 state controls for use with stateless H.264
|
||||
+ * 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 _H264_CTRLS_H_
|
||||
+#define _H264_CTRLS_H_
|
||||
+
|
||||
+/*
|
||||
+ * This is put insanely high to avoid conflicting with controls that
|
||||
+ * would be added during the phase where those controls are not
|
||||
+ * stable. It should be fixed eventually.
|
||||
+ */
|
||||
+#define V4L2_CID_MPEG_VIDEO_H264_SPS (V4L2_CID_MPEG_BASE+1000)
|
||||
+#define V4L2_CID_MPEG_VIDEO_H264_PPS (V4L2_CID_MPEG_BASE+1001)
|
||||
+#define V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (V4L2_CID_MPEG_BASE+1002)
|
||||
+#define V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (V4L2_CID_MPEG_BASE+1003)
|
||||
+#define V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (V4L2_CID_MPEG_BASE+1004)
|
||||
+
|
||||
+/* enum v4l2_ctrl_type type values */
|
||||
+#define V4L2_CTRL_TYPE_H264_SPS 0x0110
|
||||
+#define V4L2_CTRL_TYPE_H264_PPS 0x0111
|
||||
+#define V4L2_CTRL_TYPE_H264_SCALING_MATRIX 0x0112
|
||||
+#define V4L2_CTRL_TYPE_H264_SLICE_PARAMS 0x0113
|
||||
+#define V4L2_CTRL_TYPE_H264_DECODE_PARAMS 0x0114
|
||||
+
|
||||
+#define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG 0x01
|
||||
+#define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG 0x02
|
||||
+#define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG 0x04
|
||||
+#define V4L2_H264_SPS_CONSTRAINT_SET3_FLAG 0x08
|
||||
+#define V4L2_H264_SPS_CONSTRAINT_SET4_FLAG 0x10
|
||||
+#define V4L2_H264_SPS_CONSTRAINT_SET5_FLAG 0x20
|
||||
+
|
||||
+#define V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE 0x01
|
||||
+#define V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS 0x02
|
||||
+#define V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO 0x04
|
||||
+#define V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED 0x08
|
||||
+#define V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY 0x10
|
||||
+#define V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD 0x20
|
||||
+#define V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE 0x40
|
||||
+
|
||||
+struct v4l2_ctrl_h264_sps {
|
||||
+ __u8 profile_idc;
|
||||
+ __u8 constraint_set_flags;
|
||||
+ __u8 level_idc;
|
||||
+ __u8 seq_parameter_set_id;
|
||||
+ __u8 chroma_format_idc;
|
||||
+ __u8 bit_depth_luma_minus8;
|
||||
+ __u8 bit_depth_chroma_minus8;
|
||||
+ __u8 log2_max_frame_num_minus4;
|
||||
+ __u8 pic_order_cnt_type;
|
||||
+ __u8 log2_max_pic_order_cnt_lsb_minus4;
|
||||
+ __u8 max_num_ref_frames;
|
||||
+ __u8 num_ref_frames_in_pic_order_cnt_cycle;
|
||||
+ __s32 offset_for_ref_frame[255];
|
||||
+ __s32 offset_for_non_ref_pic;
|
||||
+ __s32 offset_for_top_to_bottom_field;
|
||||
+ __u16 pic_width_in_mbs_minus1;
|
||||
+ __u16 pic_height_in_map_units_minus1;
|
||||
+ __u32 flags;
|
||||
+};
|
||||
+
|
||||
+#define V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE 0x0001
|
||||
+#define V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT 0x0002
|
||||
+#define V4L2_H264_PPS_FLAG_WEIGHTED_PRED 0x0004
|
||||
+#define V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT 0x0008
|
||||
+#define V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED 0x0010
|
||||
+#define V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT 0x0020
|
||||
+#define V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE 0x0040
|
||||
+#define V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT 0x0080
|
||||
+
|
||||
+struct v4l2_ctrl_h264_pps {
|
||||
+ __u8 pic_parameter_set_id;
|
||||
+ __u8 seq_parameter_set_id;
|
||||
+ __u8 num_slice_groups_minus1;
|
||||
+ __u8 num_ref_idx_l0_default_active_minus1;
|
||||
+ __u8 num_ref_idx_l1_default_active_minus1;
|
||||
+ __u8 weighted_bipred_idc;
|
||||
+ __s8 pic_init_qp_minus26;
|
||||
+ __s8 pic_init_qs_minus26;
|
||||
+ __s8 chroma_qp_index_offset;
|
||||
+ __s8 second_chroma_qp_index_offset;
|
||||
+ __u16 flags;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_ctrl_h264_scaling_matrix {
|
||||
+ __u8 scaling_list_4x4[6][16];
|
||||
+ __u8 scaling_list_8x8[6][64];
|
||||
+};
|
||||
+
|
||||
+struct v4l2_h264_weight_factors {
|
||||
+ __s16 luma_weight[32];
|
||||
+ __s16 luma_offset[32];
|
||||
+ __s16 chroma_weight[32][2];
|
||||
+ __s16 chroma_offset[32][2];
|
||||
+};
|
||||
+
|
||||
+struct v4l2_h264_pred_weight_table {
|
||||
+ __u16 luma_log2_weight_denom;
|
||||
+ __u16 chroma_log2_weight_denom;
|
||||
+ struct v4l2_h264_weight_factors weight_factors[2];
|
||||
+};
|
||||
+
|
||||
+#define V4L2_H264_SLICE_TYPE_P 0
|
||||
+#define V4L2_H264_SLICE_TYPE_B 1
|
||||
+#define V4L2_H264_SLICE_TYPE_I 2
|
||||
+#define V4L2_H264_SLICE_TYPE_SP 3
|
||||
+#define V4L2_H264_SLICE_TYPE_SI 4
|
||||
+
|
||||
+#define V4L2_H264_SLICE_FLAG_FIELD_PIC 0x01
|
||||
+#define V4L2_H264_SLICE_FLAG_BOTTOM_FIELD 0x02
|
||||
+#define V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x04
|
||||
+#define V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH 0x08
|
||||
+
|
||||
+struct v4l2_ctrl_h264_slice_params {
|
||||
+ /* Size in bytes, including header */
|
||||
+ __u32 size;
|
||||
+ /* Offset in bits to slice_data() from the beginning of this slice. */
|
||||
+ __u32 header_bit_size;
|
||||
+
|
||||
+ __u16 first_mb_in_slice;
|
||||
+ __u8 slice_type;
|
||||
+ __u8 pic_parameter_set_id;
|
||||
+ __u8 colour_plane_id;
|
||||
+ __u8 redundant_pic_cnt;
|
||||
+ __u16 frame_num;
|
||||
+ __u16 idr_pic_id;
|
||||
+ __u16 pic_order_cnt_lsb;
|
||||
+ __s32 delta_pic_order_cnt_bottom;
|
||||
+ __s32 delta_pic_order_cnt0;
|
||||
+ __s32 delta_pic_order_cnt1;
|
||||
+
|
||||
+ struct v4l2_h264_pred_weight_table pred_weight_table;
|
||||
+ /* Size in bits of dec_ref_pic_marking() syntax element. */
|
||||
+ __u32 dec_ref_pic_marking_bit_size;
|
||||
+ /* Size in bits of pic order count syntax. */
|
||||
+ __u32 pic_order_cnt_bit_size;
|
||||
+
|
||||
+ __u8 cabac_init_idc;
|
||||
+ __s8 slice_qp_delta;
|
||||
+ __s8 slice_qs_delta;
|
||||
+ __u8 disable_deblocking_filter_idc;
|
||||
+ __s8 slice_alpha_c0_offset_div2;
|
||||
+ __s8 slice_beta_offset_div2;
|
||||
+ __u8 num_ref_idx_l0_active_minus1;
|
||||
+ __u8 num_ref_idx_l1_active_minus1;
|
||||
+ __u32 slice_group_change_cycle;
|
||||
+
|
||||
+ /*
|
||||
+ * Entries on each list are indices into
|
||||
+ * v4l2_ctrl_h264_decode_params.dpb[].
|
||||
+ */
|
||||
+ __u8 ref_pic_list0[32];
|
||||
+ __u8 ref_pic_list1[32];
|
||||
+
|
||||
+ __u32 flags;
|
||||
+};
|
||||
+
|
||||
+#define V4L2_H264_DPB_ENTRY_FLAG_VALID 0x01
|
||||
+#define V4L2_H264_DPB_ENTRY_FLAG_ACTIVE 0x02
|
||||
+#define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM 0x04
|
||||
+
|
||||
+struct v4l2_h264_dpb_entry {
|
||||
+ __u64 reference_ts;
|
||||
+ __u16 frame_num;
|
||||
+ __u16 pic_num;
|
||||
+ /* Note that field is indicated by v4l2_buffer.field */
|
||||
+ __s32 top_field_order_cnt;
|
||||
+ __s32 bottom_field_order_cnt;
|
||||
+ __u32 flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
|
||||
+};
|
||||
+
|
||||
+#define V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC 0x01
|
||||
+
|
||||
+struct v4l2_ctrl_h264_decode_params {
|
||||
+ struct v4l2_h264_dpb_entry dpb[16];
|
||||
+ __u16 num_slices;
|
||||
+ __u16 nal_ref_idc;
|
||||
+ __u8 ref_pic_list_p0[32];
|
||||
+ __u8 ref_pic_list_b0[32];
|
||||
+ __u8 ref_pic_list_b1[32];
|
||||
+ __s32 top_field_order_cnt;
|
||||
+ __s32 bottom_field_order_cnt;
|
||||
+ __u32 flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
diff --git a/libavcodec/hevc-ctrls.h b/libavcodec/hevc-ctrls.h
|
||||
new file mode 100644
|
||||
index 0000000000..c8c61079c6
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/hevc-ctrls.h
|
||||
@@ -0,0 +1,197 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * These are the HEVC state controls for use with stateless HEVC
|
||||
+ * 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 _HEVC_CTRLS_H_
|
||||
+#define _HEVC_CTRLS_H_
|
||||
+
|
||||
+#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
|
||||
+#define V4L2_HEVC_SLICE_TYPE_I 2
|
||||
+
|
||||
+struct v4l2_ctrl_hevc_sps {
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */
|
||||
+ __u8 chroma_format_idc;
|
||||
+ __u8 separate_colour_plane_flag;
|
||||
+ __u16 pic_width_in_luma_samples;
|
||||
+ __u16 pic_height_in_luma_samples;
|
||||
+ __u8 bit_depth_luma_minus8;
|
||||
+ __u8 bit_depth_chroma_minus8;
|
||||
+ __u8 log2_max_pic_order_cnt_lsb_minus4;
|
||||
+ __u8 sps_max_dec_pic_buffering_minus1;
|
||||
+ __u8 sps_max_num_reorder_pics;
|
||||
+ __u8 sps_max_latency_increase_plus1;
|
||||
+ __u8 log2_min_luma_coding_block_size_minus3;
|
||||
+ __u8 log2_diff_max_min_luma_coding_block_size;
|
||||
+ __u8 log2_min_luma_transform_block_size_minus2;
|
||||
+ __u8 log2_diff_max_min_luma_transform_block_size;
|
||||
+ __u8 max_transform_hierarchy_depth_inter;
|
||||
+ __u8 max_transform_hierarchy_depth_intra;
|
||||
+ __u8 scaling_list_enabled_flag;
|
||||
+ __u8 amp_enabled_flag;
|
||||
+ __u8 sample_adaptive_offset_enabled_flag;
|
||||
+ __u8 pcm_enabled_flag;
|
||||
+ __u8 pcm_sample_bit_depth_luma_minus1;
|
||||
+ __u8 pcm_sample_bit_depth_chroma_minus1;
|
||||
+ __u8 log2_min_pcm_luma_coding_block_size_minus3;
|
||||
+ __u8 log2_diff_max_min_pcm_luma_coding_block_size;
|
||||
+ __u8 pcm_loop_filter_disabled_flag;
|
||||
+ __u8 num_short_term_ref_pic_sets;
|
||||
+ __u8 long_term_ref_pics_present_flag;
|
||||
+ __u8 num_long_term_ref_pics_sps;
|
||||
+ __u8 sps_temporal_mvp_enabled_flag;
|
||||
+ __u8 strong_intra_smoothing_enabled_flag;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_ctrl_hevc_pps {
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */
|
||||
+ __u8 dependent_slice_segment_flag;
|
||||
+ __u8 output_flag_present_flag;
|
||||
+ __u8 num_extra_slice_header_bits;
|
||||
+ __u8 sign_data_hiding_enabled_flag;
|
||||
+ __u8 cabac_init_present_flag;
|
||||
+ __s8 init_qp_minus26;
|
||||
+ __u8 constrained_intra_pred_flag;
|
||||
+ __u8 transform_skip_enabled_flag;
|
||||
+ __u8 cu_qp_delta_enabled_flag;
|
||||
+ __u8 diff_cu_qp_delta_depth;
|
||||
+ __s8 pps_cb_qp_offset;
|
||||
+ __s8 pps_cr_qp_offset;
|
||||
+ __u8 pps_slice_chroma_qp_offsets_present_flag;
|
||||
+ __u8 weighted_pred_flag;
|
||||
+ __u8 weighted_bipred_flag;
|
||||
+ __u8 transquant_bypass_enabled_flag;
|
||||
+ __u8 tiles_enabled_flag;
|
||||
+ __u8 entropy_coding_sync_enabled_flag;
|
||||
+ __u8 num_tile_columns_minus1;
|
||||
+ __u8 num_tile_rows_minus1;
|
||||
+ __u8 column_width_minus1[20];
|
||||
+ __u8 row_height_minus1[22];
|
||||
+ __u8 loop_filter_across_tiles_enabled_flag;
|
||||
+ __u8 pps_loop_filter_across_slices_enabled_flag;
|
||||
+ __u8 deblocking_filter_override_enabled_flag;
|
||||
+ __u8 pps_disable_deblocking_filter_flag;
|
||||
+ __s8 pps_beta_offset_div2;
|
||||
+ __s8 pps_tc_offset_div2;
|
||||
+ __u8 lists_modification_present_flag;
|
||||
+ __u8 log2_parallel_merge_level_minus2;
|
||||
+ __u8 slice_segment_header_extension_present_flag;
|
||||
+ __u8 scaling_list_enable_flag;
|
||||
+};
|
||||
+
|
||||
+#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE 0x01
|
||||
+#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER 0x02
|
||||
+#define V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR 0x03
|
||||
+
|
||||
+#define V4L2_HEVC_DPB_ENTRIES_NUM_MAX 16
|
||||
+
|
||||
+struct v4l2_hevc_dpb_entry {
|
||||
+ __u64 timestamp;
|
||||
+ __u8 rps;
|
||||
+ __u8 field_pic;
|
||||
+ __u16 pic_order_cnt[2];
|
||||
+ __u8 padding[2];
|
||||
+};
|
||||
+
|
||||
+struct v4l2_hevc_pred_weight_table {
|
||||
+ __u8 luma_log2_weight_denom;
|
||||
+ __s8 delta_chroma_log2_weight_denom;
|
||||
+
|
||||
+ __s8 delta_luma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __s8 luma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __s8 delta_chroma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
||||
+ __s8 chroma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
||||
+
|
||||
+ __s8 delta_luma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __s8 luma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __s8 delta_chroma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
||||
+ __s8 chroma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
||||
+
|
||||
+ __u8 padding[2];
|
||||
+};
|
||||
+
|
||||
+struct v4l2_ctrl_hevc_slice_params {
|
||||
+ __u32 bit_size;
|
||||
+ __u32 data_bit_offset;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */
|
||||
+ __u8 nal_unit_type;
|
||||
+ __u8 nuh_temporal_id_plus1;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ __u8 slice_type;
|
||||
+ __u8 colour_plane_id;
|
||||
+ __u16 slice_pic_order_cnt;
|
||||
+ __u8 slice_sao_luma_flag;
|
||||
+ __u8 slice_sao_chroma_flag;
|
||||
+ __u8 slice_temporal_mvp_enabled_flag;
|
||||
+ __u8 num_ref_idx_l0_active_minus1;
|
||||
+ __u8 num_ref_idx_l1_active_minus1;
|
||||
+ __u8 mvd_l1_zero_flag;
|
||||
+ __u8 cabac_init_flag;
|
||||
+ __u8 collocated_from_l0_flag;
|
||||
+ __u8 collocated_ref_idx;
|
||||
+ __u8 five_minus_max_num_merge_cand;
|
||||
+ __u8 use_integer_mv_flag;
|
||||
+ __s8 slice_qp_delta;
|
||||
+ __s8 slice_cb_qp_offset;
|
||||
+ __s8 slice_cr_qp_offset;
|
||||
+ __s8 slice_act_y_qp_offset;
|
||||
+ __s8 slice_act_cb_qp_offset;
|
||||
+ __s8 slice_act_cr_qp_offset;
|
||||
+ __u8 slice_deblocking_filter_disabled_flag;
|
||||
+ __s8 slice_beta_offset_div2;
|
||||
+ __s8 slice_tc_offset_div2;
|
||||
+ __u8 slice_loop_filter_across_slices_enabled_flag;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture timing SEI message */
|
||||
+ __u8 pic_struct;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __u8 num_active_dpb_entries;
|
||||
+ __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+
|
||||
+ __u8 num_rps_poc_st_curr_before;
|
||||
+ __u8 num_rps_poc_st_curr_after;
|
||||
+ __u8 num_rps_poc_lt_curr;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */
|
||||
+ struct v4l2_hevc_pred_weight_table pred_weight_table;
|
||||
+
|
||||
+ __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
|
||||
diff --git a/libavcodec/mpeg2-ctrls.h b/libavcodec/mpeg2-ctrls.h
|
||||
new file mode 100644
|
||||
index 0000000000..6601455b3d
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/mpeg2-ctrls.h
|
||||
@@ -0,0 +1,82 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * These are the MPEG2 state controls for use with stateless MPEG-2
|
||||
+ * 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 _MPEG2_CTRLS_H_
|
||||
+#define _MPEG2_CTRLS_H_
|
||||
+
|
||||
+#define V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (V4L2_CID_MPEG_BASE+250)
|
||||
+#define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION (V4L2_CID_MPEG_BASE+251)
|
||||
+
|
||||
+/* enum v4l2_ctrl_type type values */
|
||||
+#define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0103
|
||||
+#define V4L2_CTRL_TYPE_MPEG2_QUANTIZATION 0x0104
|
||||
+
|
||||
+#define V4L2_MPEG2_PICTURE_CODING_TYPE_I 1
|
||||
+#define V4L2_MPEG2_PICTURE_CODING_TYPE_P 2
|
||||
+#define V4L2_MPEG2_PICTURE_CODING_TYPE_B 3
|
||||
+#define V4L2_MPEG2_PICTURE_CODING_TYPE_D 4
|
||||
+
|
||||
+struct v4l2_mpeg2_sequence {
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence header */
|
||||
+ __u16 horizontal_size;
|
||||
+ __u16 vertical_size;
|
||||
+ __u32 vbv_buffer_size;
|
||||
+
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence extension */
|
||||
+ __u16 profile_and_level_indication;
|
||||
+ __u8 progressive_sequence;
|
||||
+ __u8 chroma_format;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_mpeg2_picture {
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture header */
|
||||
+ __u8 picture_coding_type;
|
||||
+
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture coding extension */
|
||||
+ __u8 f_code[2][2];
|
||||
+ __u8 intra_dc_precision;
|
||||
+ __u8 picture_structure;
|
||||
+ __u8 top_field_first;
|
||||
+ __u8 frame_pred_frame_dct;
|
||||
+ __u8 concealment_motion_vectors;
|
||||
+ __u8 q_scale_type;
|
||||
+ __u8 intra_vlc_format;
|
||||
+ __u8 alternate_scan;
|
||||
+ __u8 repeat_first_field;
|
||||
+ __u16 progressive_frame;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_ctrl_mpeg2_slice_params {
|
||||
+ __u32 bit_size;
|
||||
+ __u32 data_bit_offset;
|
||||
+ __u64 backward_ref_ts;
|
||||
+ __u64 forward_ref_ts;
|
||||
+
|
||||
+ struct v4l2_mpeg2_sequence sequence;
|
||||
+ struct v4l2_mpeg2_picture picture;
|
||||
+
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Slice */
|
||||
+ __u32 quantiser_scale_code;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_ctrl_mpeg2_quantization {
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */
|
||||
+ __u8 load_intra_quantiser_matrix;
|
||||
+ __u8 load_non_intra_quantiser_matrix;
|
||||
+ __u8 load_chroma_intra_quantiser_matrix;
|
||||
+ __u8 load_chroma_non_intra_quantiser_matrix;
|
||||
+
|
||||
+ __u8 intra_quantiser_matrix[64];
|
||||
+ __u8 non_intra_quantiser_matrix[64];
|
||||
+ __u8 chroma_intra_quantiser_matrix[64];
|
||||
+ __u8 chroma_non_intra_quantiser_matrix[64];
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
diff --git a/libavcodec/v4l2_request_h264.c b/libavcodec/v4l2_request_h264.c
|
||||
index a5c56d81c3..a5dbc08a8d 100644
|
||||
--- a/libavcodec/v4l2_request_h264.c
|
||||
+++ b/libavcodec/v4l2_request_h264.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "h264dec.h"
|
||||
#include "hwaccel.h"
|
||||
#include "v4l2_request.h"
|
||||
+#include "h264-ctrls.h"
|
||||
|
||||
typedef struct V4L2RequestControlsH264 {
|
||||
struct v4l2_ctrl_h264_sps sps;
|
||||
diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c
|
||||
index 300c1866ce..7c7948cfbf 100644
|
||||
--- a/libavcodec/v4l2_request_hevc.c
|
||||
+++ b/libavcodec/v4l2_request_hevc.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "hevcdec.h"
|
||||
#include "hwaccel.h"
|
||||
#include "v4l2_request.h"
|
||||
+#include "hevc-ctrls.h"
|
||||
|
||||
typedef struct V4L2RequestControlsHEVC {
|
||||
struct v4l2_ctrl_hevc_sps sps;
|
||||
diff --git a/libavcodec/v4l2_request_mpeg2.c b/libavcodec/v4l2_request_mpeg2.c
|
||||
index 782b9c2471..37a4eae62c 100644
|
||||
--- a/libavcodec/v4l2_request_mpeg2.c
|
||||
+++ b/libavcodec/v4l2_request_mpeg2.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "hwaccel.h"
|
||||
#include "mpegvideo.h"
|
||||
#include "v4l2_request.h"
|
||||
+#include "mpeg2-ctrls.h"
|
||||
|
||||
typedef struct V4L2RequestControlsMPEG2 {
|
||||
struct v4l2_ctrl_mpeg2_slice_params slice_params;
|
||||
--
|
||||
2.21.0
|
||||
|
26
packages/sysutils/v4l-utils/keymaps/pine64
Normal file
26
packages/sysutils/v4l-utils/keymaps/pine64
Normal file
@ -0,0 +1,26 @@
|
||||
# table pine64, type: NEC
|
||||
0x404000 KEY_NUMERIC_0
|
||||
0x404001 KEY_NUMERIC_1
|
||||
0x404002 KEY_NUMERIC_2
|
||||
0x404003 KEY_NUMERIC_3
|
||||
0x404004 KEY_NUMERIC_4
|
||||
0x404005 KEY_NUMERIC_5
|
||||
0x404006 KEY_NUMERIC_6
|
||||
0x404007 KEY_NUMERIC_7
|
||||
0x404008 KEY_NUMERIC_8
|
||||
0x404009 KEY_NUMERIC_9
|
||||
0x40400a KEY_MUTE
|
||||
0x40400b KEY_UP
|
||||
0x40400c KEY_BACKSPACE
|
||||
0x40400d KEY_OK
|
||||
0x40400e KEY_DOWN
|
||||
0x404010 KEY_LEFT
|
||||
0x404011 KEY_RIGHT
|
||||
0x404017 KEY_VOLUMEDOWN
|
||||
0x404018 KEY_VOLUMEUP
|
||||
0x40401a KEY_HOME
|
||||
0x40401d KEY_MENU
|
||||
0x40401f KEY_WWW
|
||||
0x404045 KEY_BACK
|
||||
0x404047 KEY_INFO
|
||||
0x40404d KEY_POWER
|
21
packages/tools/atf/package.mk
Normal file
21
packages/tools/atf/package.mk
Normal file
@ -0,0 +1,21 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2018-present Team LibreELEC
|
||||
|
||||
PKG_NAME="atf"
|
||||
PKG_VERSION="v2.1"
|
||||
PKG_SHA256="7c4c00a4f28d3cfbb235fd1a1fb28c4d2fc1d657c9301686e7d8824ef575d059"
|
||||
PKG_ARCH="arm aarch64"
|
||||
PKG_LICENSE="BSD-3c"
|
||||
PKG_SITE="https://github.com/ARM-software/arm-trusted-firmware"
|
||||
PKG_URL="https://github.com/ARM-software/arm-trusted-firmware/archive/$PKG_VERSION.tar.gz"
|
||||
PKG_LONGDESC="ARM Trusted Firmware is a reference implementation of secure world software, including a Secure Monitor executing at Exception Level 3 and various Arm interface standards."
|
||||
PKG_TOOLCHAIN="manual"
|
||||
PKG_IS_KERNEL_PKG="yes"
|
||||
|
||||
make_target() {
|
||||
CROSS_COMPILE="$TARGET_KERNEL_PREFIX" LDFLAGS="" CFLAGS="" make PLAT=$ATF_PLATFORM bl31
|
||||
}
|
||||
|
||||
post_make_target() {
|
||||
cp -av build/$ATF_PLATFORM/release/bl31.bin .
|
||||
}
|
@ -11,6 +11,8 @@ PKG_LONGDESC="Das U-Boot is a cross-platform bootloader for embedded systems."
|
||||
PKG_IS_KERNEL_PKG="yes"
|
||||
PKG_STAMP="$UBOOT_SYSTEM"
|
||||
|
||||
[ -n "$ATF_PLATFORM" ] && PKG_DEPENDS_TARGET+=" atf"
|
||||
|
||||
PKG_NEED_UNPACK="$PROJECT_DIR/$PROJECT/bootloader"
|
||||
[ -n "$DEVICE" ] && PKG_NEED_UNPACK+=" $PROJECT_DIR/$PROJECT/devices/$DEVICE/bootloader"
|
||||
|
||||
@ -24,8 +26,8 @@ case "$PROJECT" in
|
||||
PKG_NEED_UNPACK+=" $(get_pkg_directory rkbin)"
|
||||
;;
|
||||
*)
|
||||
PKG_VERSION="2018.09"
|
||||
PKG_SHA256="839bf23cfe8ce613a77e583a60375179d0ad324e92c82fbdd07bebf0fd142268"
|
||||
PKG_VERSION="2019.01"
|
||||
PKG_SHA256="50bd7e5a466ab828914d080d5f6a432345b500e8fba1ad3b7b61e95e60d51c22"
|
||||
PKG_URL="http://ftp.denx.de/pub/u-boot/u-boot-$PKG_VERSION.tar.bz2"
|
||||
;;
|
||||
esac
|
||||
@ -36,9 +38,10 @@ make_target() {
|
||||
echo "see './scripts/uboot_helper' for more information"
|
||||
else
|
||||
[ "${BUILD_WITH_DEBUG}" = "yes" ] && PKG_DEBUG=1 || PKG_DEBUG=0
|
||||
[ -n "$ATF_PLATFORM" ] && cp -av $(get_build_dir atf)/bl31.bin .
|
||||
DEBUG=${PKG_DEBUG} CROSS_COMPILE="$TARGET_KERNEL_PREFIX" LDFLAGS="" ARCH=arm make mrproper
|
||||
DEBUG=${PKG_DEBUG} CROSS_COMPILE="$TARGET_KERNEL_PREFIX" LDFLAGS="" ARCH=arm make $($ROOT/$SCRIPTS/uboot_helper $PROJECT $DEVICE $UBOOT_SYSTEM config)
|
||||
DEBUG=${PKG_DEBUG} CROSS_COMPILE="$TARGET_KERNEL_PREFIX" LDFLAGS="" ARCH=arm make HOSTCC="$HOST_CC" HOSTSTRIP="true"
|
||||
DEBUG=${PKG_DEBUG} CROSS_COMPILE="$TARGET_KERNEL_PREFIX" LDFLAGS="" ARCH=arm _python_sysroot="$TOOLCHAIN" _python_prefix=/ _python_exec_prefix=/ make HOSTCC="$HOST_CC" HOSTLDFLAGS="-L$TOOLCHAIN/lib" HOSTSTRIP="true"
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
diff --git a/dts/Kconfig b/dts/Kconfig
|
||||
index 0cef225ba9..e4e3455d4c 100644
|
||||
--- a/dts/Kconfig
|
||||
+++ b/dts/Kconfig
|
||||
@@ -13,7 +13,6 @@ config PYLIBFDT
|
||||
|
||||
config DTOC
|
||||
bool
|
||||
- select PYLIBFDT
|
||||
|
||||
config BINMAN
|
||||
bool
|
||||
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
|
||||
index dbc338653b..04f3c5935c 100644
|
||||
--- a/tools/dtoc/fdt.py
|
||||
+++ b/tools/dtoc/fdt.py
|
||||
@@ -10,7 +10,7 @@ import struct
|
||||
import sys
|
||||
|
||||
import fdt_util
|
||||
-import libfdt
|
||||
+from pylibfdt import libfdt
|
||||
from libfdt import QUIET_NOTFOUND
|
||||
|
||||
# This deals with a device tree, presenting it as an assortment of Node and
|
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;
|
||||
}
|
@ -9,6 +9,28 @@ devices = {
|
||||
},
|
||||
},
|
||||
|
||||
'Allwinner' : {
|
||||
'A64' : {
|
||||
'pine64' : { 'dtb' : 'sun50i-a64-pine64.dtb', 'config' : 'pine64_plus_defconfig' },
|
||||
'pine64_plus' : { 'dtb' : 'sun50i-a64-pine64-plus.dtb', 'config' : 'pine64_plus_defconfig' },
|
||||
'pine64_lts' : { 'dtb' : 'sun50i-a64-sopine-baseboard.dtb', 'config' : 'sopine_baseboard_defconfig' },
|
||||
'orangepi_win' : { 'dtb' : 'sun50i-a64-orangepi-win.dtb', 'config' : 'orangepi_win_defconfig' },
|
||||
},
|
||||
'H3' : {
|
||||
'bananapi_m2p' : { 'dtb' : 'sun8i-h3-bananapi-m2-plus.dtb', 'config' : 'Sinovoip_BPI_M2_Plus_defconfig' },
|
||||
'beelink_x2' : { 'dtb' : 'sun8i-h3-beelink-x2.dtb', 'config' : 'beelink_x2_defconfig' },
|
||||
'libretech_h3' : { 'dtb' : 'sun8i-h3-libretech-all-h3-cc.dtb', 'config' : 'libretech_all_h3_cc_h3_defconfig' },
|
||||
'orangepi_2' : { 'dtb' : 'sun8i-h3-orangepi-2.dtb', 'config' : 'orangepi_2_defconfig' },
|
||||
'orangepi_pc': { 'dtb': 'sun8i-h3-orangepi-pc.dtb', 'config': 'orangepi_pc_defconfig' },
|
||||
'orangepi_pc_plus': { 'dtb': 'sun8i-h3-orangepi-pc-plus.dtb', 'config': 'orangepi_pc_plus_defconfig' },
|
||||
'orangepi_plus2e': { 'dtb': 'sun8i-h3-orangepi-plus2e.dtb', 'config': 'orangepi_plus2e_defconfig' },
|
||||
'orangepi_plus': { 'dtb': 'sun8i-h3-orangepi-plus.dtb', 'config': 'orangepi_plus_defconfig' },
|
||||
},
|
||||
'H6' : {
|
||||
'pine_h64' : { 'dtb' : 'sun50i-h6-pine-h64.dtb', 'config' : 'pine_h64_defconfig' },
|
||||
},
|
||||
},
|
||||
|
||||
'Rockchip' : {
|
||||
'MiQi' : { 'rk3288' : { 'dtb' : 'rk3288-miqi.dtb', 'config' : 'miqi-rk3288_config' }, },
|
||||
'RK3328' : {
|
||||
|
Loading…
x
Reference in New Issue
Block a user