From 072de836f53be56a70cecf70b43ae43b7ce17376 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 11 Dec 2023 10:08:36 +0000
Subject: [PATCH] mk-rootfs.sh
---
kernel/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c | 64 +++++++++++++++++++++++++------
1 files changed, 51 insertions(+), 13 deletions(-)
diff --git a/kernel/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c b/kernel/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c
index 067314d..dcd49b6 100644
--- a/kernel/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c
+++ b/kernel/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c
@@ -45,11 +45,11 @@
#include <media/videobuf2-v4l2.h>
#include <soc/rockchip/rockchip-system-status.h>
#include <sound/hdmi-codec.h>
+#include <linux/rk_hdmirx_class.h>
#include "rk_hdmirx.h"
#include "rk_hdmirx_cec.h"
#include "rk_hdmirx_hdcp.h"
-static struct class *hdmirx_class;
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "debug level (0-3)");
@@ -269,6 +269,7 @@
static void hdmirx_cancel_cpu_limit_freq(struct rk_hdmirx_dev *hdmirx_dev);
static void hdmirx_plugout(struct rk_hdmirx_dev *hdmirx_dev);
static void process_signal_change(struct rk_hdmirx_dev *hdmirx_dev);
+static void hdmirx_interrupts_setup(struct rk_hdmirx_dev *hdmirx_dev, bool en);
static u8 edid_init_data_340M[] = {
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
@@ -529,6 +530,16 @@
struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
u32 dma_cfg1;
+ if (port_no_link(hdmirx_dev)) {
+ v4l2_err(v4l2_dev, "%s port has no link!\n", __func__);
+ return -ENOLINK;
+ }
+
+ if (signal_not_lock(hdmirx_dev)) {
+ v4l2_err(v4l2_dev, "%s signal is not locked!\n", __func__);
+ return -ENOLCK;
+ }
+
*timings = hdmirx_dev->timings;
dma_cfg1 = hdmirx_readl(hdmirx_dev, DMA_CONFIG1);
v4l2_dbg(1, debug, v4l2_dev, "%s: pix_fmt: %s, DMA_CONFIG1:%#x\n",
@@ -615,8 +626,10 @@
static void hdmirx_get_pix_fmt(struct rk_hdmirx_dev *hdmirx_dev)
{
u32 val;
+ int timeout = 10;
struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
+try_loop:
val = hdmirx_readl(hdmirx_dev, DMA_STATUS11);
hdmirx_dev->pix_fmt = val & HDMIRX_FORMAT_MASK;
@@ -635,11 +648,16 @@
break;
default:
+ if (timeout-- > 0) {
+ usleep_range(200 * 1000, 200 * 1010);
+ v4l2_err(v4l2_dev, "%s: get format failed, read again!\n", __func__);
+ goto try_loop;
+ }
+ hdmirx_dev->pix_fmt = HDMIRX_RGB888;
+ hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_BGR24;
v4l2_err(v4l2_dev,
"%s: err pix_fmt: %d, set RGB888 as default\n",
__func__, hdmirx_dev->pix_fmt);
- hdmirx_dev->pix_fmt = HDMIRX_RGB888;
- hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_BGR24;
break;
}
@@ -880,9 +898,12 @@
struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
u32 last_w, last_h;
struct v4l2_bt_timings *bt = &timings->bt;
+ enum hdmirx_pix_fmt last_fmt;
last_w = 0;
last_h = 0;
+ last_fmt = HDMIRX_RGB888;
+
for (i = 0; i < try_cnt; i++) {
ret = hdmirx_get_detected_timings(hdmirx_dev, timings, from_dma);
@@ -891,7 +912,8 @@
last_h = bt->height;
}
- if (ret || (last_w != bt->width) || (last_h != bt->height))
+ if (ret || (last_w != bt->width) || (last_h != bt->height)
+ || (last_fmt != hdmirx_dev->pix_fmt))
cnt = 0;
else
cnt++;
@@ -901,6 +923,7 @@
last_w = bt->width;
last_h = bt->height;
+ last_fmt = hdmirx_dev->pix_fmt;
usleep_range(10*1000, 10*1100);
}
@@ -1545,7 +1568,7 @@
}
hdmirx_reset_dma(hdmirx_dev);
- usleep_range(200*1000, 200*1010);
+ usleep_range(500*1000, 500*1010);
hdmirx_format_change(hdmirx_dev);
return 0;
@@ -2349,6 +2372,7 @@
FIFO_UNDERFLOW_INT_EN |
HDMIRX_AXI_ERROR_INT_EN, 0);
hdmirx_reset_dma(hdmirx_dev);
+ hdmirx_interrupts_setup(hdmirx_dev, false);
v4l2_event_queue(&stream->vdev, &evt_signal_lost);
if (hdmirx_dev->hdcp && hdmirx_dev->hdcp->hdcp_stop)
hdmirx_dev->hdcp->hdcp_stop(hdmirx_dev->hdcp);
@@ -2459,13 +2483,28 @@
hdmirx_writel(hdmirx_dev, MAINUNIT_2_INT_FORCE, 0x0);
}
+/*
+ * In the normal preview, some scenarios will trigger the change interrupt
+ * by mistake, and the trigger source of the interrupt needs to be detected
+ * to avoid the problem.
+ */
static void pkt_0_int_handler(struct rk_hdmirx_dev *hdmirx_dev,
int status, bool *handled)
{
struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
+ u32 pre_fmt_fourcc = hdmirx_dev->cur_fmt_fourcc;
+ u32 pre_color_range = hdmirx_dev->cur_color_range;
+ u32 pre_color_space = hdmirx_dev->cur_color_space;
if ((status & PKTDEC_AVIIF_CHG_IRQ)) {
- process_signal_change(hdmirx_dev);
+ hdmirx_get_color_range(hdmirx_dev);
+ hdmirx_get_color_space(hdmirx_dev);
+ hdmirx_get_pix_fmt(hdmirx_dev);
+ if (hdmirx_dev->cur_fmt_fourcc != pre_fmt_fourcc ||
+ hdmirx_dev->cur_color_range != pre_color_range ||
+ hdmirx_dev->cur_color_space != pre_color_space) {
+ process_signal_change(hdmirx_dev);
+ }
v4l2_dbg(2, debug, v4l2_dev, "%s: ptk0_st:%#x\n",
__func__, status);
*handled = true;
@@ -3158,7 +3197,7 @@
struct rk_hdmirx_dev,
delayed_work_audio);
struct hdmirx_audiostate *as = &hdmirx_dev->audio_state;
- u32 fs_audio, ch_audio;
+ u32 fs_audio, ch_audio, sample_flat;
int cur_state, init_state, pre_state, fifo_status2;
unsigned long delay = 200;
@@ -3223,6 +3262,10 @@
}
}
as->pre_state = cur_state;
+
+ sample_flat = hdmirx_readl(hdmirx_dev, AUDIO_PROC_STATUS1) & AUD_SAMPLE_FLAT;
+ hdmirx_update_bits(hdmirx_dev, AUDIO_PROC_CONFIG0, I2S_EN, sample_flat ? 0 : I2S_EN);
+
exit:
schedule_delayed_work_on(hdmirx_dev->bound_cpu,
&hdmirx_dev->delayed_work_audio,
@@ -3243,7 +3286,6 @@
plugin = tx_5v_power_present(hdmirx_dev);
v4l2_dbg(1, debug, v4l2_dev, "%s: plugin:%d\n", __func__, plugin);
if (plugin) {
- hdmirx_interrupts_setup(hdmirx_dev, false);
hdmirx_submodule_init(hdmirx_dev);
hdmirx_update_bits(hdmirx_dev, SCDC_CONFIG, POWERPROVIDED,
POWERPROVIDED);
@@ -4280,7 +4322,7 @@
if (ret)
goto err_unreg_video_dev;
- hdmirx_dev->classdev = device_create_with_groups(hdmirx_class,
+ hdmirx_dev->classdev = device_create_with_groups(rk_hdmirx_class(),
dev, MKDEV(0, 0),
hdmirx_dev,
hdmirx_groups,
@@ -4438,9 +4480,6 @@
static int __init hdmirx_init(void)
{
- hdmirx_class = class_create(THIS_MODULE, "hdmirx");
- if (IS_ERR(hdmirx_class))
- return PTR_ERR(hdmirx_class);
return platform_driver_register(&hdmirx_driver);
}
module_init(hdmirx_init);
@@ -4448,7 +4487,6 @@
static void __exit hdmirx_exit(void)
{
platform_driver_unregister(&hdmirx_driver);
- class_destroy(hdmirx_class);
}
module_exit(hdmirx_exit);
--
Gitblit v1.6.2