Rockchip · AI & Linux Hub

Экран и звук

Rockchip RK628 For-All: полное руководство по переносу Display, HDMI IN, аудио и отладке

Полное руководство RK628D/F/H For-All: перенос драйверов, DTS, регулировка сигналов, HDMI IN, аудио, тестирование и устранение неисправностей.

· ArmSoM Editorial · Rockchip source documentation · 139 мин чтения

Применимость к ArmSoM

Это справочный материал по платформе Rockchip, а не отчёт об испытаниях ArmSoM. RK628D/F/H — внешние микросхемы-мосты; применение на конкретной плате ArmSoM зависит от выведенных сигналов, питания, I2C, GPIO, прерываний, тактовых сигналов и целевого SDK/BSP. Исходник отдельно описывает драйверы Misc, Media и U-Boot для RK3399, RK356x, RK3588, RK3576, RK3562 и разных ветвей ядра. Это не означает поддержку на каждой плате. Необходимо проверить условия каждой конфигурации. Аппаратная проверка не проводилась.

По согласованию с пользователем общая основа всех трёх языков — китайская версия V2.7 (122 страницы). Английская V2.3 (117 страниц) используется для сопоставления и оригинальных иллюстраций. Отсутствующие или отличающиеся разделы полностью переведены с китайского: перенос драйверов, регулировка сигналов/SSC, перестановка линий GVI и настройка Media. Китайская статья содержит китайские оригиналы рисунков; английская и русская — соответствующие английские оригиналы с указанием страниц. Редактируемые расшифровки снимков основаны на новой китайской версии.

Безопасность и противоречия исходника: запись регистров, chmod 0666 и setenforce 0 — исходные примеры отладки, а не рекомендации для эксплуатации. Расхождения в именах узлов, описании сигнальных трактов и перечнях платформ сохранены и перечислены в редакторском протоколе. Нумерация начинается с главы 2, поскольку глава оглавления удалена.

Редакторский протокол · Документация ArmSoM

2. Введение

RK628 имеет тракт Display и тракт HDMI IN. В версии SDK Display основан на DRM, а HDMI IN — на V4L2. Для разных фреймворков и версий ядра требуются разные драйверы; эта версия предназначена только для платформ Rockchip. Для поддержки других платформ и упрощения переноса создан драйвер For-All. Сейчас он поддерживает RK628D и RK628F/H. Управление версиями патчей описано в инструкции по версиям драйвера RK628 из пакета патчей SDK.

For-All также разделён на Display и HDMI IN. Драйвер Display находится в drivers/misc/rk628/; входы: RGB / BT1120 / HDMI, выходы: RGB / BT1120 / LVDS / GVI / DSI / HDMI. Драйвер HDMI IN находится в drivers/media/i2c/rk628/; вход HDMI, выходы CSI / BT1120. Далее Misc и Media обозначают эти два независимых драйвера, которые можно компилировать и запускать отдельно.

2.1 Блок-схема RK628

Оригинальный технический рисунок — EN V2.3, p9

Оригинальный технический рисунок: EN V2.3, p9.

2.2 Типовая аппаратная схема RK628

Оригинальный технический рисунок — EN V2.3, p9

Оригинальный технический рисунок: EN V2.3, p9.

2.3 Основные характеристики RK628

2.3.1 Основные характеристики RK628D

Входной видеоинтерфейс Типовое разрешение Типовой формат
HDMI IN 4K@30 YUV420(4K@60) / YUV422 / YUV444 /
RGB888
BT1120 IN 1080P@60 YUV422 8bit
RGB IN 1080P@60 RGB888
Выходной видеоинтерфейс Типовое разрешение Типовой формат
GVI OUT 4K@60 RGB888
MIPI CSI 4K@30 YUV422 8bit
MIPI DSI 1080P@60 /
2.5K@60
RGB888
LVDS OUT 720P@60 /
1080P@60
RGB888
BT1120 OUT 1080P@60 YUV422 8bit
RGB OUT 1080P@60 RGB888
HDMI OUT 1080P@60 RGB888/YUV444 8bit

2.3.2 Основные характеристики RK628F

Входной видеоинтерфейс Типовое разрешение Типовой формат
HDMI IN 4K@60 RGB888 / YUV422 8bit / YUV422 10bit
/ YUV420 8bit (> 4k@30Hz) / YUV420 10bit
(> 4k@30Hz)
BT1120 IN 1080P@60 YUV422 8bit
RGB IN 1080P@60 RGB888
Выходной видеоинтерфейс Типовое разрешение Типовой формат
GVI OUT 4K@60 RGB888
MIPI CSI Два MIPI, 4K@60 YUV422 8bit
MIPI DSI 1080P@60 /
2.5K@60
RGB888
LVDS OUT 720P@60 /
1080P@60
RGB888
BT1120 OUT 1080P@60 YUV422 8bit
RGB OUT 1080P@60 RGB888
HDMI OUT 1080P@60 RGB888 / YUV444 8bit

2.3.3 Основные характеристики RK628H

В отличие от RK628F, RK628H не имеет интерфейса GVI.

Входной видеоинтерфейс Типовое разрешение Типовой формат
HDMI IN 4K@60 RGB888 / YUV422 8bit / YUV422 10bit
/ YUV420 8bit (> 4k@30Hz) / YUV420 10bit
(> 4k@30Hz)
BT1120 IN 1080P@60 YUV422 8bit
RGB IN 1080P@60 RGB888
Выходной видеоинтерфейс Типовое разрешение Типовой формат
MIPI CSI Два MIPI, 4K@60 YUV422 8bit
MIPI DSI 1080P@60 /
2.5K@60
RGB888
LVDS OUT 720P@60 /
1080P@60
RGB888
BT1120 OUT 1080P@60 YUV422 8bit
RGB OUT 1080P@60 RGB888
HDMI OUT 1080P@60 RGB888 / YUV444 8bit

2.4 Улучшения и оптимизации RK628F/H относительно RK628D

Функциональный блок RK628D RK628F/H
HDMIRX До 4K@60 YUV420; TMDS CLK 297M До 4K@60 RGB/YUV444; TMDS CLK 594M
HDMIRX Частоты ограничены; требуемое разрешение нужно оценивать отдельно, поддержка не гарантирована Любая частота 27M–594M для разных входных разрешений
HDMIRX DVI MODE не поддерживается DVI MODE поддерживается
HDMIRX Невозможно определить входной формат yuv422/yuv420 Контроллер определяет входной видеоформат
HDMIRX При низкой амплитуде clk lane источника RK628D rxphy не захватывает сигнал Эта проблема отсутствует
HDMIRX Проблемы обнаружения битовых ошибок HDMI RX Эта проблема отсутствует
MIPI
CSI
Один канал, 4 линии Два канала, 8 линий
MIPI
CSI
Максимум 4k@30 yuv422 8bit Максимум 4k@60 yuv422 8bit
GVI Некоторые модели панелей не включаются или показывают неправильно По исходнику, испытания нескольких доступных моделей не выявили нарушений; см. Настройка выходных модулей → Выход GVI → Проверенные модели GVI для RK628F
GVI Нужен общий источник тактирования Общий источник тактирования не требуется
audio Нет аудио mclk; при использовании кодека mclk должен выдавать основной SoC Может выдавать mclk
audio При подключении/отключении HDMI возможны переполнение I2S FIFO и ошибочное переключение каналов Устранено нарушение порядка каналов при переполнении FIFO
csc В некоторых сочетаниях входов/выходов выполняются преобразование цветового пространства или изменение дискретизации формата изображения; возможны небольшие отклонения цветовых деталей Эта проблема отсутствует
hdmi tx Нужен общий источник тактирования rgb2hdmi требует общего источника тактирования; hdmi2hdmi не требует
Несколько дисплеев Одновременный вывод rgb/bt1120 и hdmi tx с одинаковым разрешением Одновременный вывод rgb/bt1120, hdmi tx и gvi/dsi/csi/lvds с одинаковым разрешением
MCU Встроенного MCU нет Встроенный MCU

3. Перенос драйвера

For-All разделён на Display и HDMI IN. Драйвер Display для U-Boot находится в drivers/video/drm/rk628/, драйвер ядра — в drivers/misc/rk628/. Входы: RGB / BT1120 / HDMI; выходы: RGB / BT1120 / LVDS / GVI / DSI / HDMI. Драйвер HDMI IN расположен в drivers/media/i2c/rk628/, принимает HDMI и выводит CSI / DSI / BT1120.

Следующие драйверы можно переносить отдельно по необходимости:

3.1 Тракт Display

3.1.1 U-Boot (drivers/video/drm/rk628)

В U-Boot платформ Rockchip реализованы перечисленные ниже тракты отображения RK628F/H для быстрого вывода загрузочного логотипа.

IC Display Route Поддержка
RK628F/H HDMI2(Dual)DSI Поддерживается
RK628F/H HDMI2(Dual)LVDS Поддерживается
RK628F HDMI2GVI Поддерживается
RK628F/H HDMI2BT1120/RGB Поддерживается
RK628F/H BT1120/RGB2(Dual)DSI Поддерживается
RK628F/H BT1120/RGB2(Dual)LVDS Поддерживается
RK628F BT1120/RGB2GVI Поддерживается

Примечание: драйвер загрузочного логотипа U-Boot не поддерживает RK628D, поскольку его HDMIRX не работает на произвольных частотах.

При первом добавлении RK628 Misc или отсутствии драйвера RK628 в drivers/video/drm скопируйте исходники Misc RK628 для U-Boot непосредственно в drivers/video/drm и измените следующие файлы:

drivers/video/drm/rockchip_display.c
drivers/video/drm/Kconfig
drivers/video/drm/Makefile

configs/rk3568_defconfig //以rk3568平台为例

Пример изменений приведён в патче:

diff --git a/drivers/video/drm/rockchip_display.c b/drivers/video/drm/rockchip_display.c

index a1cb40a000e..041b8bdd84f 100644
--- a/drivers/video/drm/rockchip_display.c
+++ b/drivers/video/drm/rockchip_display.c
@@ -918,6 +918,23 @@ static int display_enable(struct display_state *state)
      if (state->enabled_at_spl == false)
           rockchip_connector_enable(state);

+#ifdef CONFIG_DRM_ROCKCHIP_RK628

+     /*
+     * trigger .probe helper of U_BOOT_DRIVER(rk628) in ./rk628/rk628.c
+     */
+     struct udevice * dev;
+     int phandle, ret;
+
+     phandle = ofnode_read_u32_default(state->node, "bridge", -1);
+     if (phandle < 0)
+          printf("%s failed to find bridge phandle\n",
ofnode_get_name(state->node));
+
+     ret = uclass_get_device_by_phandle_id(UCLASS_I2C_GENERIC, phandle, &dev);

+     if (ret && ret != -ENOENT)
+          printf("%s:%d failed to get rk628 device ret:%d\n", __func__,
__LINE__, ret);
+
+#endif
+
      if (crtc_state->soft_te)
           crtc_funcs->apply_soft_te(state);
diff --git a/drivers/video/drm/Kconfig b/drivers/video/drm/Kconfig
index ddc65818cba..c5073b9926b 100644
--- a/drivers/video/drm/Kconfig

+++ b/drivers/video/drm/Kconfig
@@ -191,6 +191,13 @@ config DRM_ROCKCHIP_RK618
       Choose this option to enable support for Rockchip RK618 display
       bridge chips driver. say Y to enable its driver.

+config DRM_ROCKCHIP_RK628
+     bool "Rockchip RK628 display bridge driver"
+     depends on DRM_ROCKCHIP
+     help
+      Choose this option to enable support for Rockchip RK628 display
+      bridge chips driver. say Y to enable its driver.
+
diff --git a/drivers/video/drm/Makefile b/drivers/video/drm/Makefile
index ea4219d9cf6..f11a8ff4885 100644

--- a/drivers/video/drm/Makefile
+++ b/drivers/video/drm/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_DRM_ROCKCHIP_RGB) += rockchip_rgb.o
 obj-$(CONFIG_DRM_ROCKCHIP_PANEL) += rockchip_panel.o
 obj-$(CONFIG_DRM_ROHM_BU18XL82) += rohm-bu18tl82.o rohm-bu18rl82.o
 obj-$(CONFIG_DRM_ROCKCHIP_RK618) += rk618.o rk618_lvds.o rk618_dsi.o
+obj-$(CONFIG_DRM_ROCKCHIP_RK628) += rk628/
 obj-$(CONFIG_DRM_ROCKCHIP_RK1000) += rk1000.o rk1000_tve.o
 obj-$(CONFIG_DRM_ROCKCHIP_SAMSUNG_MIPI_DCPHY) += samsung_mipi_dcphy.o
 obj-$(CONFIG_DRM_SII902X) += sii902x.o
diff --git a/configs/rk3568_defconfig b/configs/rk3568_defconfig
index acd1fb18169..94f1050eb4f 100644
--- a/configs/rk3568_defconfig

+++ b/configs/rk3568_defconfig
@@ -224,3 +224,4 @@ CONFIG_RK_AVB_LIBAVB_USER=y
 CONFIG_OPTEE_CLIENT=y
 CONFIG_OPTEE_V2=y
 CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION=y
+CONFIG_DRM_ROCKCHIP_RK628=y

Для включения логотипа U-Boot добавьте в DTS следующую конфигурацию:

Для входа RGB:

 &route_rgb {
      status = "okay";

+
+     bridge = <&i2c2_rk628>;
 };

Для входа HDMI:

&route_hdmi {
      status = "okay";
+

+     bridge = <&i2c2_rk628>;
      force-bus-format = <MEDIA_BUS_FMT_RGB888_1X24>;
      force-output;
      force_timing{

Чтобы избежать мерцания при переходе от логотипа U-Boot к логотипу ядра, убедитесь, что ядро содержит патч со следующими сведениями о коммите:

misc: rk628: add support uboot logo

Type: Function

Redmine ID: #496880 #491750
Associated modifications: NULL
Test: NULL

Change-Id: I311e2c9682f835b377ea9082e1d3a88688167172
Signed-off-by: Guochun Huang <hero.huang@rock-chips.com>

3.1.2 Ядро (drivers/misc/rk628)

При первом добавлении RK628 Misc в ядро Rockchip или отсутствии RK628 в drivers/misc скопируйте исходники Misc RK628 непосредственно в drivers/misc. Измените drivers/misc/Kconfig, drivers/misc/Makefile и arch/arm64/configs/rockchip_defconfig, добавив сборку RK628. Пример патча:

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 276c7c4fef15..8481b9613bc9 100644
--- a/drivers/misc/Kconfig

+++ b/drivers/misc/Kconfig
@@ -5,6 +5,8 @@

 menu "Misc devices"

+source "drivers/misc/rk628/Kconfig"
+
 config RK803
      tristate "RK803"
      default n
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index b296e760fd47..14642c54a2bc 100644

--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -3,6 +3,7 @@
 # Makefile for misc devices that really don't fit anywhere else.
 #

+obj-y                 += rk628/
 obj-$(CONFIG_RK803)   += rk803.o
 obj-y                 += rockchip/
 obj-$(CONFIG_LT7911D_FB_NOTIFIER) += lt7911d-fb-notifier.o
diff --git a/arch/arm64/configs/rockchip_defconfig b/arch/arm64/configs/rockchip_defconfig
index 28340b4bdfae..dbb7d9e55b62 100644

--- a/arch/arm64/configs/rockchip_defconfig
+++ b/arch/arm64/configs/rockchip_defconfig
@@ -294,6 +294,8 @@ CONFIG_BLK_DEV_LOOP_MIN_COUNT=16
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_BLK_DEV_NVME=y
+CONFIG_RK628_MISC=y
+CONFIG_RK628_MISC_HDMITX=y
 CONFIG_LT7911D_FB_NOTIFIER=y
 CONFIG_SRAM=y
 CONFIG_UID_SYS_STATS=y
@@ -557,7 +559,6 @@ CONFIG_ROCKCHIP_THERMAL=y

 CONFIG_WATCHDOG=y
 CONFIG_DW_WATCHDOG=y
 CONFIG_MFD_RK618=y
-CONFIG_MFD_RK628=y
 CONFIG_MFD_RK630_I2C=y
 CONFIG_MFD_RK806_I2C=y
 CONFIG_MFD_RK806_SPI=y
@@ -640,7 +641,6 @@ CONFIG_ROCKCHIP_LVDS=y
 CONFIG_ROCKCHIP_RGB=y
 CONFIG_ROCKCHIP_DW_HDCP2=y
 CONFIG_DRM_ROCKCHIP_RK618=y
-CONFIG_DRM_ROCKCHIP_RK628=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_MAXIM_MAX96752F=y
CONFIG_DRM_PANEL_MAXIM_MAX96772=y

Важно: CONFIG_MFD_RK628 и CONFIG_DRM_ROCKCHIP_RK628 относятся к старым драйверам RK628; их необходимо удалить из rockchip_defconfig.

Драйверы Misc компилируются по умолчанию; выбор запускаемого драйвера выполняется через DTS.

3.2 Тракт HDMI IN (drivers/media/i2c/rk628)

Для ядер до 5.10 используйте пакет rk628_for-all; для ядра 5.10 — kernel_5.10_rk628_media_patch. Скопируйте драйвер Media RK628 в drivers/media/i2c/rk628/ и измените drivers/media/i2c/Kconfig, drivers/media/i2c/Makefile и arch/arm64/configs/rockchip_defconfig, добавив сборку RK628. Пример:

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index f3273756c612..609bb5e3db07 100644
--- a/drivers/media/i2c/Kconfig

+++ b/drivers/media/i2c/Kconfig
@@ -414,6 +414,8 @@ config VIDEO_OTP_EEPROM
      help
       This driver supports OTP load from eeprom.

+source "drivers/media/i2c/rk628/Kconfig"
+
 config VIDEO_SAA7110
      tristate "Philips SAA7110 video decoder"
      depends on VIDEO_V4L2 && I2C
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 26edd6f7590e..d6f4128b19a5 100644

--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -141,6 +141,7 @@ obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
 obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
 obj-$(CONFIG_VIDEO_TC358743) += tc358743.o
 obj-$(CONFIG_VIDEO_TC35874X) += tc35874x.o
+obj-$(CONFIG_VIDEO_RK628) += rk628/
 obj-$(CONFIG_VIDEO_AR0230) += ar0230.o
 obj-$(CONFIG_VIDEO_GC02M2) += gc02m2.o
 obj-$(CONFIG_VIDEO_GC08A3) += gc08a3.o
diff --git a/arch/arm64/configs/rockchip_defconfig b/arch/arm64/configs/rockchip_defconfig
index 95ad81b12a69..c66f67ecd0c2 100644

--- a/arch/arm64/configs/rockchip_defconfig
+++ b/arch/arm64/configs/rockchip_defconfig
@@ -567,6 +567,8 @@ CONFIG_VIDEO_ROCKCHIP_ISPP=y
 CONFIG_VIDEO_ROCKCHIP_HDMIRX=y
 CONFIG_VIDEO_LT6911UXC=y
 CONFIG_VIDEO_LT7911D=y
+CONFIG_VIDEO_RK628_CSI=y
+CONFIG_VIDEO_RK628_BT1120=y
 CONFIG_VIDEO_TC35874X=y
 CONFIG_VIDEO_GC0312=y
 CONFIG_VIDEO_GC2145=y

Драйверы Media компилируются по умолчанию; DTS определяет, какой драйвер работает.

4. Связь SoC с RK628 по I2C

SoC обменивается данными с RK628 по I2C. Типовой 7-битный адрес RK628 — 0x50. Если на одной шине несколько RK628, их адреса можно изменить посредством GPIO RK628:

Оригинальный технический рисунок — EN V2.3, p13

Оригинальный технический рисунок: EN V2.3, p13.

Текст рисунка: адрес I2C содержит 7 бит. Старшие четыре бита идентифицируют устройство и равны 4’b1010; младшие три задают адрес устройства. Адрес ведомого устройства можно программировать через GPIO для разных сценариев. Типичный адрес — 7’b1010000.

Бит адреса Имя вывода Настройка GPIO
cfg_slvadr[2] IO_GPIO0a1 GPIO0A_OE[1]=1’b1
cfg_slvadr[1] IO_GPIO0a0 GPIO0A_OE[0]=1’b1
cfg_slvadr[0] IO_GPIO3b3 GPIO3B_OE[2]=1’b1

Пример для адресов ведомого устройства 0x50 и 0x51:

Оригинальный технический рисунок — EN V2.3, p13

Оригинальный технический рисунок: EN V2.3, p13.

Оригинальный технический рисунок — EN V2.3, p13

Оригинальный технический рисунок: EN V2.3, p13.

I2C SEL I2C ADDR
0 7’b1010000 (0x50)
1 7’b1010001 (0x51)

GPIO0a0 и GPIO0a1 удерживаются на низком уровне. При высоком уровне GPIO3b3 адрес равен 0x51 (7’b1010001), при низком — 0x50 (7’b1010000).

5. Misc

5.1 Обзор драйвера MISC

RK628 Misc реализует тракт Display для преобразования протоколов отображения. Входы: RGB, BT1120 или HDMI; выходы: LVDS, GVI, DSI, RGB, BT1120 или HDMI.

5.1.1 Перенос драйвера

См. Перенос драйвера → Тракт Display.

5.1.2 Структура каталога драйвера U-Boot

drivers/video/drm/rk628/
├── Makefile

├── panel.c
├── panel.h
├── rk628.c
├── rk628_combtxphy.c
├── rk628_combtxphy.h
├── rk628_cru.c
├── rk628_cru.h
├── rk628_dsi.c
├── rk628_dsi.h
├── rk628_gvi.c
├── rk628_gvi.h
├── rk628.h

├── rk628_hdmirx.c
├── rk628_hdmirx.h
├── rk628_hdmitx.h
├── rk628_lvds.c
├── rk628_lvds.h
├── rk628_post_process.c
├── rk628_post_process.h
├── rk628_rgb.c
└── rk628_rgb.h

5.1.3 Структура каталога драйвера ядра

drivers/misc/rk628/
├── Kconfig
├── Makefile

├── panel.c
├── panel.h
├── rk628.c
├── rk628_combrxphy.c
├── rk628_combrxphy.h
├── rk628_combtxphy.c
├── rk628_combtxphy.h
├── rk628_config.c

├── rk628_config.h
├── rk628_cru.c
├── rk628_cru.h
├── rk628_csi.c
├── rk628_csi.h
├── rk628_dsi.c
├── rk628_dsi.h
├── rk628_efuse.c
├── rk628_efuse.h
├── rk628_gpio.h
├── rk628_grf.h
├── rk628_gvi.c

├── rk628_gvi.h
├── rk628.h
├── rk628_hdmirx.c
├── rk628_hdmirx.h
├── rk628_hdmitx.c
├── rk628_hdmitx.h
├── rk628_lvds.c
├── rk628_lvds.h
├── rk628_pinctrl.c
├── rk628_pinctrl.h
├── rk628_post_process.c
├── rk628_post_process.h
├── rk628_rgb.c

├── rk628_rgb.h

5.1.4 Обзор конфигурации DTS

Пример: RGB → DSI.

&i2c2 {
   clock-frequency = <400000>;

   status = "okay";

   i2c2_rk628: rk628@50 {
      compatible = "rockchip,rk628";
      reg = <0x50>;
      interrupt-parent = <&gpio0>;
      interrupts = <20 IRQ_TYPE_LEVEL_HIGH>;
      enable-gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>;
      reset-gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>;
      pinctrl-names = "default";
      pinctrl-0 = <&rk628_reset>;
      status = "okay";
   };

};

&pinctrl {
   rk628 {
      rk628_reset: rk628-reset {
         rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
      };

   };
};

&i2c2_rk628 {
   /* soc_24M optional */
   pinctrl-names = "default";
   pinctrl-0 = <&rk628_reset &refclk_pins>;
   assigned-clocks = <&pmucru CLK_WIFI>;
   assigned-clock-rates = <24000000>;
   clocks = <&pmucru CLK_WIFI>;
   clock-names = "soc_24M";


   panel-backlight = <&backlight>;
   panel-power-supply = <&vcc3v3_lcd0_n>;
   panel-enable-gpios = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>;

   panel-reset-delay-ms = <10>;
   panel-enable-delay-ms = <10>;
   panel-prepare-delay-ms = <60>;
   panel-unprepare-delay-ms = <10>;
   panel-disable-delay-ms = <60>;
   panel-init-delay-ms = <60>;

   rk628-rgb-in;
   rk628-dsi-out {

      dsi,eotp;
      dsi,video-mode;
      dsi,format = "rgb888";
      dsi,lanes = <4>;
      status = "okay";

      rk628-panel {
         panel-init-sequence = [
            05 78 01 11
            05 78 01 29
         ];


         panel-exit-sequence = [
            05 00 01 28
            05 00 01 10
         ];
      };
   };

   display-timings {
      src-timing {
         clock-frequency = <148500000>;
         hactive = <1920>;
         vactive = <1080>;
         hfront-porch = <88>;

         hsync-len = <44>;
         hback-porch = <148>;
         vfront-porch = <4>;
         vsync-len = <5>;
         vback-porch = <36>;
         hsync-active = <1>;

         vsync-active = <1>;
         de-active = <0>;
         pixelclk-active = <0>;
      };

      dst-timing {
         clock-frequency = <148500000>;
         hactive = <1920>;
         vactive = <1080>;
         hfront-porch = <88>;
         hsync-len = <44>;
         hback-porch = <148>;

         vfront-porch = <4>;
         vsync-len = <5>;
         vback-porch = <36>;
         hsync-active = <1>;
         vsync-active = <1>;
         de-active = <0>;
         pixelclk-active = <0>;
      };
   };
};

5.2 Основная конфигурация драйвера

5.2.1 Узел RK628

SoC обменивается данными с RK628 по I2C. Для RK3568 добавьте узел RK628 (i2c2_rk628: rk628@50) в узел I2C i2c2 дерева DTS:

&i2c2 {
   clock-frequency = <400000>;

   status = "okay";

   i2c2_rk628: rk628@50 {
      compatible = "rockchip,rk628";
      reg = <0x50>;
      enable-gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>;
      reset-gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>;
      pinctrl-names = "default";
      pinctrl-0 = <&rk628_reset>;
      status = "okay";
   };
};


&pinctrl {
   rk628 {
      rk628_reset: rk628-reset {
         rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
      };
   };
};

Свойства узла RK628:

Свойство Описание Option Value
compatible compatible Для RK628 Misc задайте compatible = “rockchip,rk628”
reg Адрес ведомого RK628 на I2C 0x50/0x51, согласно аппаратной схеме
enable-gpios Ссылка на GPIO включения RK628 Согласно аппаратной схеме
reset-gpios Ссылка на GPIO сброса RK628 Согласно аппаратной схеме
pinctrl-names Переключение вывода reset RK628 в функцию GPIO Согласно аппаратной схеме
pinctrl-0 Переключение вывода reset RK628 в функцию GPIO Согласно аппаратной схеме

5.2.2 Рабочая частота 24 МГц

Рабочая частота RK628 24 МГц может поступать от внешнего кварца 24M или вывода CLK SoC 24 МГц. При внешнем кварце следующая конфигурация не требуется.

В трактах RK628D HDMI / GVI OUT и RK628F/H RGB → HDMI необходимо использовать выход CLK SoC 24 МГц как рабочий источник RK628 для общего тактирования. Внешний кварц 24M может вызвать нарушения изображения. В RK628F/H этот механизм улучшен: TMDS CLK, обнаруженный HDMI RX, используется как опорный сигнал CRU PLL, поэтому для HDMI IN не требуется опорная частота 24 МГц от SoC.

На RK3568 частоту 24 МГц могут выдавать несколько выводов: REF_CLKOUT (clk_wifi / gpio0_a0), CAM_CLKOUT1 (clk_cam1_out / gpio4_b0), ETH_REFCLK_25M_M0 (clk_mac1_out / gpio3_b0). Ниже используется первый вариант. Другие платформы Rockchip описаны в разделе об источнике тактирования RK628 24M от другого SoC.

1. Добавьте ссылки на следующую конфигурацию в узел RK628 DTS:

&i2c2_rk628 {
   /* soc_24M optional */
   pinctrl-names = "default";

   pinctrl-0 = <&rk628_reset &refclk_pins>;
   assigned-clocks = <&pmucru CLK_WIFI>;
   assigned-clock-rates = <24000000>;
   clocks = <&pmucru CLK_WIFI>;
   clock-names = "soc_24M";
   ......
};

2. Следующая конфигурация уже присутствует в rk3568-pinctrl.dtsi:

&pinctrl {
   ......
   refclk {

      /omit-if-no-ref/
      refclk_pins: refclk-pins {
         rockchip,pins =
           /* refclk_ou */
           <0 RK_PA0 1 &pcfg_pull_none>;
      };
   };
   ......
};

Свойства CLK 24 МГц:

Свойство Описание Option Value
pinctrl-names Мультиплексирование вывода refclk Согласно аппаратной схеме. Поскольку переопределяются свойства RK628 выше, добавьте также ссылку rk628_reset
pinctrl-0 Мультиплексирование вывода refclk Согласно аппаратной схеме. Поскольку переопределяются свойства RK628 выше, добавьте также ссылку rk628_reset
assigned-clocks Ссылка на тактовый сигнал RK628 Согласно аппаратной схеме
assigned-clock-rates Частота сигнала, назначенного RK628 (Hz) <24000000>
clocks Список дескрипторов тактовых сигналов Согласно аппаратной схеме
clock-names Имя тактового сигнала “soc_24M”

5.2.3 Выбор входных и выходных модулей

В узле RK628 DTS задайте свойства требуемых входов/выходов типа boolean или соответствующие узлы. Параметры функций задаются внутри узла модуля:

&i2c2_rk628 {
   ......

   rk628-rgb-in;
   rk628-dsi-out {
      ......
   };
   ......
};

Для RGB → DSI свойство “rk628-rgb-in;” выбирает вход RGB, а узел “rk628-dsi-out” — выход DSI. Входы Misc: RGB IN, BT1120 IN, HDMI IN; выходы: LVDS, GVI, DSI, HDMI. Подробности приведены в разделах настройки входных и выходных модулей.

5.2.4 Настройка панели

В узле RK628 DTS задайте подсветку, питание, вывод сброса, временные параметры включения и отображения согласно спецификации панели. Для тракта HDMITX это не требуется:

&i2c2_rk628 {
   ......

   panel-backlight = <&backlight>;
   panel-power-supply = <&vcc3v3_lcd0_n>;
   panel-enable-gpios = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>;

   panel-reset-delay-ms = <10>;
   panel-enable-delay-ms = <10>;
   panel-prepare-delay-ms = <60>;
   panel-unprepare-delay-ms = <10>;
   panel-disable-delay-ms = <60>;
   panel-init-delay-ms = <60>;
   ......
   display-timings {
      src-timing {

         clock-frequency = <148500000>;
         hactive = <1920>;
         vactive = <1080>;
         hfront-porch = <88>;
         hsync-len = <44>;
         hback-porch = <148>;
         vfront-porch = <4>;
         vsync-len = <5>;
         vback-porch = <36>;
         hsync-active = <1>;
         vsync-active = <1>;
         de-active = <0>;

         pixelclk-active = <0>;
      };

      dst-timing {
         clock-frequency = <148500000>;
         hactive = <1920>;
         vactive = <1080>;
         hfront-porch = <88>;
         hsync-len = <44>;
         hback-porch = <148>;
         vfront-porch = <4>;
         vsync-len = <5>;
         vback-porch = <36>;

         hsync-active = <1>;
         vsync-active = <1>;
         de-active = <0>;
         pixelclk-active = <0>;
      };
   };
   ......
};

Свойства панели:

Свойство Описание Option Value
panel-enable-gpios GPIO включения панели [необязательно] Согласно аппаратной схеме
panel-reset-gpios GPIO сброса панели [необязательно] Согласно аппаратной схеме
panel-backlight Подсветка панели [необязательно] Согласно аппаратной схеме
panel-reset-delay-ms Последовательность включения питания панели См. спецификацию панели
panel-enable-delay-ms Последовательность включения питания панели См. спецификацию панели
panel-prepare-delay-ms Последовательность включения питания панели См. спецификацию панели
panel-unprepare-delay-ms Последовательность включения питания панели См. спецификацию панели
panel-disable-delay-ms Последовательность включения питания панели См. спецификацию панели
panel-init-delay-ms Последовательность включения питания панели См. спецификацию панели
src-timing Узел временных параметров отображения от SoC к RK628 Масштабирование относительно dst-timing отдельно по горизонтали и вертикали
dst-timing Узел временных параметров панели См. спецификацию панели
clock-frequency Временные параметры отображения См. спецификацию панели и фактическую настройку scaler
hactive Временные параметры отображения См. спецификацию панели и фактическую настройку scaler
vactive Временные параметры отображения См. спецификацию панели и фактическую настройку scaler
hfront-porch Временные параметры отображения См. спецификацию панели и фактическую настройку scaler
hback-porch Временные параметры отображения См. спецификацию панели и фактическую настройку scaler
hsync-len Временные параметры отображения См. спецификацию панели и фактическую настройку scaler
vfront-porch Временные параметры отображения См. спецификацию панели и фактическую настройку scaler
vback-porch Временные параметры отображения См. спецификацию панели и фактическую настройку scaler
vsync-len Временные параметры отображения См. спецификацию панели и фактическую настройку scaler
hsync-active Временные параметры отображения См. спецификацию панели и фактическую настройку scaler
vsync-active Временные параметры отображения См. спецификацию панели и фактическую настройку scaler
de-active Временные параметры отображения См. спецификацию панели и фактическую настройку scaler
pixelclk-active Временные параметры отображения См. спецификацию панели и фактическую настройку scaler

При масштабировании между разными входным и выходным разрешениями задайте входные параметры в src-timing, а выходные — в dst-timing. Активная область и интервалы гашения должны масштабироваться с одинаковым коэффициентом:

src: hactive / dst: hactive = src: hblanking / dst: hblanking
src: vactive / dst: vactive = src: vblanking / dst: vblanking
hblanking = hfront-porch + hback-porch + hsync-len

vblanking = vfront-porch + vback-porch + vsync-len

Частота кадров до и после масштабирования также должна совпадать.

src: clock-frequency / (htotal * vtotal) = dst: clock-frequency / (htotal *
vtotal)
htotal = hactive + hfront-porch + hback-porch + hsync-len

vtotal = vactive + vfront-porch + vback-porch + vsync-len

При одинаковом входном и выходном разрешении задайте одинаковые целевые временные параметры в src-timing и dst-timing.

Для двух панелей DSI одинакового разрешения или двух панелей LVDS одинакового разрешения значения clock-frequency, hactive, hfront-porch, hback-porch и hsync-len в src-timing и dst-timing нужно умножить на 2 относительно конфигурации одной панели.

5.2.5 Комбинации трактов отображения

См. следующие примеры DTS. Подробности приведены в разделе комбинаций, поддерживаемых DTS.

arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2bt1120-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-dual-ddr4-v10.dts

arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2gvi-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-dual-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2gvi-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2hdmi-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-dual-ddr4-v10.dts

5.2.6 Настройка выходных сигналов

5.2.6.1 Настройка GVI / LVDS / MIPI TX

1. Регистры comb_tx для напряжения и предыскажения независимо настраивают 10 пар линий (tx0 ~ tx9). Соответствие интерфейсам:

COMB_TX GVI LVDS / MIPI
TX0 P/N GVI_TX0 P/N L/M0_TX0 P/N
TX1 P/N GVI_TX1 P/N L/M0_TX1 P/N
TX2 P/N / L/M0_TXCLK P/N
TX3 P/N GVI_TX2 P/N L/M0_TX2 P/N
TX4 P/N GVI_TX3 P/N L/M0_TX3 P/N
TX5 P/N GVI_TX4 P/N L/M1_TX0 P/N
TX6 P/N GVI_TX5 P/N L/M1_TX1 P/N
TX7 P/N / L/M1_TXCLK P/N
TX8 P/N GVI_TX6 P/N L/M1_TX2 P/N
TX9 P/N GVI_TX7 P/N L/M1_TX3 P/N

2. Для проверки сигнала записывайте регистры непосредственно. После перезагрузки настройки теряются; для постоянной конфигурации измените приведённый ниже патч.

# 1. 电压缩放 N=0(75%), 1/2(100%), 3(125%) (通常无需调节)
# echo 0x90004 $val > /d/rk628/2-0050/registers/combtxphy

# $val:
#   tx0[Bit1:0], tx1[Bit3:2], tx2[Bit5:4], tx3[Bit7:6], tx4[Bit9:8]
#   tx5[Bit17:16], tx6[Bit19:18], tx7[Bit21:20], tx8[Bit23:22], tx9[Bit25:24]
# 以 1(100%) 为例:
echo 0x90004 0x01550155 > /d/rk628/2-0050/registers/combtxphy

# 2. 电压调节 N=0~7
# echo 0x90008 $val > /d/rk628/2-0050/registers/combtxphy
# $val:
#   tx0[Bit2:0], tx1[Bit5:3], tx2[Bit8:6], tx3[Bit11:9], tx4[Bit14:12]
#   tx5[Bit18:16], tx6[Bit21:19], tx7[Bit24:22], tx8[Bit27:25], tx9[Bit30:28]
# 以 3 档为例:
echo 0x90008 0x36db36db > /d/rk628/2-0050/registers/combtxphy


# 3. 预加重调节 N=0~9
# echo 0x9000c $val > /d/rk628/2-0050/registers/combtxphy
# $val: tx0[Bit3:0], tx1[Bit7:4], tx2[Bit11:8], tx3[Bit15:12], tx4[Bit19:16]
# echo 0x90010 $val > /d/rk628/2-0050/registers/combtxphy
# $val: tx5[Bit3:0], tx6[Bit7:4], tx7[Bit11:8], tx8[Bit15:12], tx9[Bit19:16]
# 以 5 档为例:
echo 0x9000c 0x55555 > /d/rk628/2-0050/registers/combtxphy
echo 0x90010 0x55555 > /d/rk628/2-0050/registers/combtxphy

3. Патч настройки выходного сигнала на примере GVI TX. Значения выбирайте по описанию выше.

diff --git a/drivers/misc/rk628/rk628_combtxphy.c b/drivers/misc/rk628/rk628_combtxphy.c

index 3387d8bd73b9..70d7a5422a35 100644
--- a/drivers/misc/rk628/rk628_combtxphy.c
+++ b/drivers/misc/rk628/rk628_combtxphy.c
@@ -139,6 +139,14 @@ static void rk628_combtxphy_gvi_power_on(struct rk628
*rk628)
      usleep_range(100, 200);

      rk628_i2c_update_bits(rk628, COMBTXPHY_CON0,
                      SW_TX_IDLE_MASK, 0);
+
+     // amplitude scale
+     rk628_i2c_write(rk628, COMBTXPHY_CON1, 0x01550155);
+     // amplitude level
+     rk628_i2c_write(rk628, COMBTXPHY_CON2, 0x36db36db);
+     // emphasis level
+     rk628_i2c_write(rk628, COMBTXPHY_CON3, 0x00055555);
+     rk628_i2c_write(rk628, COMBTXPHY_CON4, 0x00055555);
 }


 void rk628_combtxphy_power_on(struct rk628 *rk628)
5.2.6.2 Настройка HDMI TX

1. Для проверки записывайте регистры непосредственно. Настройки не сохраняются после перезагрузки; для постоянной конфигурации измените патч ниже.

# 1. 驱动强度调节
# echo 0x70388 $val > /d/rk628/2-0050/registers/hdmi

# $val: clk_driver_strength[Bit7:4], data_driver_strength[Bit3:0]
#      范围(强度从低到高):0x0  ~ 0xF
# 以 0x8 为例:
echo 0x70388 0x88 > /d/rk628/2-0050/registers/hdmi

# 2. 预加重调节
# echo 0x7038c $val > /d/rk628/2-0050/registers/hdmi
# $val: pre_emphasis_strength[Bit6:4]
#      范围(强度从低到高):0x0  ~ 0x7
#     clk_pre_driver_strength[Bit3:2], data_pre_driver_strength[Bit1:0]
#      范围(强度从低到高):0x0  ~ 0x3
# 以 pre_emphasis_strength = 0x3, clk/data_pre_driver_strength = 0x3 为例:

echo 0x7038c 0x3f > /d/rk628/2-0050/registers/hdmi

2. Патч настройки HDMI: пример разделения диапазона (74.25M, 165M] на (74.25M, 148.5M] и (148.5M, 165M].

{ верхняя граница частотного диапазона, предыскажение, нагрузочная способность }: значения выбирайте по описанию выше.

diff --git a/drivers/misc/rk628/rk628_hdmitx.c b/drivers/misc/rk628/rk628_hdmitx.c
index f28b78a6b525..2120cf504ebe 100644

--- a/drivers/misc/rk628/rk628_hdmitx.c
+++ b/drivers/misc/rk628/rk628_hdmitx.c
@@ -231,6 +231,7 @@ static void rk628_hdmi_sys_power(struct rk628_hdmi *hdmi,
bool enable)
 static struct rk628_hdmi_phy_config rk628_hdmi_phy_config[] = {
      /* pixelclk pre-emp vlev */
      { 74250000, 0x3f, 0x88 },
+     { 148500000, 0x3f, 0x88 },
      { 165000000, 0x3f, 0x88 },
      { ~0UL,  0x00, 0x00 }
 };
5.2.6.3 SSC (расширение спектра)

1. Глобальная модуляция CPLL расширяет спектр выходного сигнала в тракте GVI TX.

# echo 0xc000c $((val | 0xffff0000)) > /d/rk628/2-0050/registers/cru
# $val:
#   ssmod_spread[Bit12:8](Spread amplitude / 0.1%)

#   ssmod_divval[Bit7:4](Divider required to set the modulation frequency)
#   参数说明⻅下方描述
# 例 ssmod_spread = 3, ssmod_divval = 6 (推荐值):
echo 0xc000c 0xffff0360 > /d/rk628/2-0050/registers/cru

(1) ssmod_spread [Bit12:8]: глубина модуляции. Обычно не выше 5000 ppm, однако из-за сложности реальных условий определяющими являются измерения: измеренное значение не должно превышать 0.3%. Рекомендуемая настройка — 0.3%. То есть spread = 3.

(2) ssmod_divval [Bit7:4]: частота модуляции, определяющая скорость изменения частоты. Формула:

f_mod = f_CLKSSCG / (128 × divval); f_CLKSSCG = f_PFD = f_REF / refdiv.

Здесь f_mod — частота модуляции 30–33 кГц; f_REF — опорная частота кварца; refdiv по умолчанию равен 1. Рекомендуется divval = 6, при котором f_mod = 31.25 кГц.

2. Патч SSC на примере GVI TX; значения выбирайте по описанию выше.

diff --git a/drivers/misc/rk628/rk628_combtxphy.c b/drivers/misc/rk628/rk628_combtxphy.c

index 3387d8bd73b9..70d7a5422a35 100644
--- a/drivers/misc/rk628/rk628_combtxphy.c
+++ b/drivers/misc/rk628/rk628_combtxphy.c
@@ -139,6 +139,9 @@ static void rk628_combtxphy_gvi_power_on(struct rk628 *rk628)
      usleep_range(100, 200);
      rk628_i2c_update_bits(rk628, COMBTXPHY_CON0,
                      SW_TX_IDLE_MASK, 0);
+
+     // ssmod
+     rk628_i2c_write(rk628, CRU_CPLL_CON3, 0xffff0360);
 }
void rk628_combtxphy_power_on(struct rk628 *rk628)

5.3 Настройка входных модулей

5.3.1 Вход RGB

5.3.1.1 Настройка входа RGB

1. Добавьте логическое свойство “rk628-rgb-in;” в узел RK628 DTS:

&i2c2_rk628 {
   ......

   rk628-rgb-in;
   ......
};

RGB IN / RGB OUT / BT1120 IN / BT1120 OUT используют общие выводы, поэтому эти четыре функции нельзя включить одновременно.

2. Настройте выход RGB SoC. На RK3568 он использует DRM, а RK628 представлен виртуальной панелью:

/ {
   panel@0 {
      compatible = "simple-panel";


      disp_timings3: display-timings {
         native-mode = <&rgb2dsi_timing>;
         rgb2dsi_timing: timing0 {
           clock-frequency = <148500000>;
           hactive = <1920>;
           vactive = <1080>;
           hfront-porch = <88>;
           hsync-len = <44>;
           hback-porch = <148>;
           vfront-porch = <4>;
           vsync-len = <5>;
           vback-porch = <36>;

           hsync-active = <1>;
           vsync-active = <1>;
           de-active = <0>;
           pixelclk-active = <0>;
         };
      };

      port {
         panel_in_rgb: endpoint {
           remote-endpoint = <&rgb_out_panel>;
         };
      };

   };
};
&route_rgb {
   status = "okay";


   /* for u-boot logo display */
   bridge = <&i2c2_rk628>;
};

&rgb_in_vp2 {
   status = "okay";
};

&rgb {
   status = "okay";


   ports {
      port@1 {
         reg = <1>;

         rgb_out_panel: endpoint {
           remote-endpoint = <&panel_in_rgb>;
         };
      };
   };c
};

Временные параметры “panel@0/display-timings/timing0” должны совпадать с “&i2c2_rk628/display-timings/src-timing”.

5.3.2 Вход BT1120

5.3.2.1 Настройка входа BT1120

Следуйте настройке входа RGB, заменив логическое свойство “rk628-rgb-in;” на “rk628-bt1120-in;” в узле RK628 DTS:

&i2c2_rk628 {
   ......

   rk628-bt1120-in;
   // bt1120-dual-edge;
   // bt1120-yc-swap;
   // bt1120-uv-swap;
   ......
};

Для BT1120 по обоим фронтам добавьте логическое свойство “bt1120-dual-edge;”.

Свойства “bt1120-yc-swap” и “bt1120-uv-swap” изменяют интерпретацию порядка сигналов BT1120 на кабеле. Попробуйте их, если геометрия изображения правильная, но цвета нарушены.

RGB IN / RGB OUT / BT1120 IN / BT1120 OUT используют общие выводы и не могут работать одновременно.

5.3.3 Вход HDMI

5.3.3.1 Настройка входа HDMI

Вход HDMI может быть подключён непосредственно к SoC или через кабель HDMI.

5.3.3.2 Прямое соединение с SoC

Конфигурация узла RK628 DTS:

&i2c2_rk628 {
   ......
   rk628-hdmi-in;

   // src-mode-4k-yuv420;
   ......
};

При прямом соединении источник HDMI должен выдавать сигнал по умолчанию. RK628 не требуется вывод IO для обнаружения подключения источника; переключение разрешения не поддерживается. Драйвер обнаруживает входной HDMI-сигнал опросом.

Если источник выдаёт 4K YUV420 (force-bus-format = MEDIA_BUS_FMT_UYYVYY8_0_5X24 и force_timing задаёт 4K), добавьте логическое свойство “src-mode-4k-yuv420” в RK628: HDMIRX не может заранее определить, использует ли источник YUV420.

Принудительное задание разрешения источника HDMI SoC:

Для RK3568 настройте принудительный выход HDMI, указав временные параметры и bus-format:

#include <dt-bindings/display/media-bus-format.h>

&hdmi {

   status = "okay";
   force-bus-format = <MEDIA_BUS_FMT_RGB888_1X24>;
   force-output;
   force_timing{
      clock-frequency = <594000000>;
      hactive = <3840>;
      vactive = <2160>;
      hback-porch = <296>;
      hfront-porch = <176>;
      vback-porch = <72>;
      vfront-porch = <8>;
      hsync-len = <88>;
      vsync-len = <10>;

      hsync-active = <1>;
      vsync-active = <1>;
      de-active = <0>;
      pixelclk-active = <0>;
   };
};

&hdmi_in_vp0 {
   status = "okay";
};


&hdmi_in_vp1 {
   status = "disabled";
};

&route_hdmi {
   status = "okay";

   /* for u-boot logo display */
   bridge = <&i2c2_rk628>;
   force-bus-format = <MEDIA_BUS_FMT_RGB888_1X24>;
   force-output;
   force_timing{

      clock-frequency = <594000000>;
      hactive = <3840>;
      vactive = <2160>;
      hback-porch = <296>;
      hfront-porch = <176>;
      vback-porch = <72>;
      vfront-porch = <8>;
      hsync-len = <88>;
      vsync-len = <10>;
      hsync-active = <1>;
      vsync-active = <1>;
      de-active = <0>;
      pixelclk-active = <0>;

   };
};

Узел “&route_hdmi” включается для вывода загрузочного логотипа ядра через HDMIRX. Его “force-output”, “force-bus-format” и “force_timing” должны совпадать с узлом “hdmi”.

При настройке force-bus-format включите в DTS заголовок <dt-bindings/display/media-bus-format.h>, содержащий определения форматов отображения.

Патч принудительного HDMI-выхода SoC

На платформах Rockchip для принудительного HDMI-выхода с заданным разрешением требуется соответствующий патч ниже. Сравните его с исходным кодом, чтобы проверить, не применён ли он ранее:

Список патчей commit message Описание патча
0190-drm-bridge-dw-hdmi-qp-Support-hdmi-force-output-kernel-5-10.patch drm/bridge: dw-hdmi-qp:
Support hdmi force
output
Добавьте, если отсутствует в драйвере HDMI TX ядра Rockchip 5.10
0190-drm-bridge-synopsys-Support-hdmi-force-output-kernel-5-10.patch drm/bridge: synopsys:
Support hdmi force
output
Добавьте, если отсутствует в драйвере HDMI TX ядра Rockchip 5.10
0190-drm-bridge-synopsys-Support-hdmi-force-output-kernel-4-19.patch drm/bridge: synopsys:
Support hdmi force
output
Добавьте, если отсутствует в драйвере HDMI TX ядра Rockchip 4.19
0190-drm-bridge-synopsys-Support-hdmi-force-output.patch drm/bridge: synopsys:
Support hdmi force
output
Добавьте, если отсутствует в драйвере HDMI TX ядра Rockchip 4.4
0189-drm-bridge-synopsys-dw-hdmi-Support-force-logo-displ.patch drm/bridge: synopsys:
dw-hdmi: Support force
logo display
Добавьте, если отсутствует в драйвере HDMI TX ядра Rockchip 4.4
5.3.3.3 Соединение кабелем HDMI

Конфигурация узла RK628 DTS:

&i2c2_rk628 {
   ......
   interrupt-parent = <&gpio0>;

   interrupts = <20 IRQ_TYPE_LEVEL_HIGH>;
   plugin-det-gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>;
   // hpd-output-inverted;
   rk628-hdmi-in;
   ......
};

При кабельном соединении RK628 обнаруживает подключение источника через IO, а также поддерживает смену разрешения и цветового формата. Задайте “plugin-det-gpios”, “interrupt-parent” и “interrupts”. Этот вывод обнаруживает источник HDMI со стороны RK628, а не RK628 со стороны HDMI; обычно обе стороны должны обнаруживать друг друга.

Логическое свойство “hpd-output-inverted” инвертирует описанный IO обнаружения подключения. Включите его, если схема инвертирует выходной уровень HPD. Программную инверсию обычно можно задать и через GPIO_ACTIVE_LOW / GPIO_ACTIVE_HIGH.

Для изменения разрешения HDMIRX в кабельном режиме задайте требуемое разрешение в src-timing, описанном в разделе настройки панели.

5.3.3.4 Настройка аудио

При входе HDMI RK628 выводит аудио по I2S в роли master. Конфигурация звуковой карты DTS:

rk628_dc: rk628-dc {
   compatible = "rockchip,dummy-codec";
   #sound-dai-cells = <0>;

};

&i2s0 {
   rockchip,capture-only;
   status = "okay";
};

/ {
   hdmiin-sound {
      compatible = "simple-audio-card";
      simple-audio-card,format = "i2s";
      simple-audio-card,name = "rockchip,hdmiin";

      simple-audio-card,bitclock-master = <&dailink0_master>;
      simple-audio-card,frame-master = <&dailink0_master>;
      status = "okay";
      simple-audio-card,cpu {
         sound-dai = <&i2s0>;
      };
      dailink0_master: simple-audio-card,codec {
         sound-dai = <&rk628_dc>;
      };
   };
};

Когда I2S SoC работает как slave, драйвер ожидает появления тактового сигнала. Слишком долгое ожидание может вызвать сбой Android. Следующий патч изменяет тайм-аут:

diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c

index 9bc29fdd13c5..230c350c6765
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -468,6 +468,9 @@ static int rockchip_i2s_trigger(struct snd_pcm_substream
*substream,
           ret = -EINVAL;
           break;
      }
+     if(substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+          substream->wait_time = msecs_to_jiffies(100);
+     }

      return ret;

 }
diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
index b0c4ce01e2be..0602df42c309
--- a/sound/soc/rockchip/rockchip_i2s_tdm.c
+++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
@@ -1776,6 +1776,9 @@ static int rockchip_i2s_tdm_trigger(struct

snd_pcm_substream *substream,
           ret = -EINVAL;
           break;
      }
+     if(substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+          substream->wait_time = msecs_to_jiffies(100);
+     }

      return ret;
 }

5.4 Настройка выходных модулей

5.4.1 Выход RGB

5.4.1.1 Настройка выхода RGB

Добавьте логическое свойство “rk628-rgb-out;” в узел RK628 DTS:

&i2c2_rk628 {
   ......
   rk628-rgb-out;

   ......
};

RGB IN / RGB OUT / BT1120 IN / BT1120 OUT используют общие выводы и не могут работать одновременно.

5.4.2 Выход BT1120

5.4.2.1 Настройка выхода BT1120

Добавьте логическое свойство “rk628-bt1120-out;” в узел RK628 DTS:

&i2c2_rk628 {
   ......
   rk628-bt1120-out;

   // bt1120-dual-edge;
   ......
};

Для работы BT1120 по обоим фронтам добавьте “bt1120-dual-edge;”. RGB IN / RGB OUT / BT1120 IN / BT1120 OUT используют общие выводы и несовместимы при одновременном включении.

5.4.3 Выход DSI

5.4.3.1 Настройка выхода DSI

Добавьте узел “rk628-dsi-out” в узел RK628 DTS:

&i2c2_rk628 {
   ......
   rk628-dsi-out {

      // rockchip,lane-mbps = <1100>;
      // rockchip,dual-channel;
      dsi,eotp;
      dsi,video-mode;
      // dsi,clk-non-continuous;
      dsi,format = "rgb888";
      dsi,lanes = <4>;
      status = "okay";

      rk628-panel {
         panel-init-sequence = [
           ......

           05 78 01 11
           05 78 01 29
         ];

         panel-exit-sequence = [
           05 00 01 28
           05 00 01 10
         ];
      };
   };
   ......
};

Свойства узла “rk628-dsi-out”:

Свойство Описание Option Value
rockchip,lane-mbps Заданная полоса данных MIPI [необязательно]  
rockchip,dual-channel Один/два MIPI [необязательно] По умолчанию один MIPI; свойство включает два MIPI
dsi,eotp EOT PACKET [option]  
dsi,video-mode Video mode / Command mode [необязательно] По умолчанию Command mode; свойство включает Video mode
dsi,clk-non-continuous Непрерывное/прерывистое тактирование [необязательно] По умолчанию непрерывное; свойство включает прерывистое тактирование
dsi,format Формат данных DSI “rgb888” / “rgb666” / “rgb666-packed”
/ “rgb565”
dsi,lanes DSI lanes При двух MIPI число линий задаётся как для одного MIPI
panel-init-sequence Последовательность инициализации панели Столбец 1: data type; 2: mdelays; 3: payload_lenth каждой команды; остальные столбцы: payload команды
panel-exit-sequence Последовательность завершения работы панели Как выше

Распространённые типы данных

Тип данных Описание Размер пакета
0x03 Универсальная короткая запись WRITE без параметров Короткий
0x13 Универсальная короткая запись WRITE с 1 параметром Короткий
0x23 Универсальная короткая запись WRITE с 2 параметрами Короткий
0x29 Универсальная длинная запись WRITE Длинный
0x05 Короткая запись DCS WRITE без параметров Короткий
0x15 Короткая запись DCS WRITE с 1 параметром Короткий
5.4.3.2 Настройка выходного сигнала

См. Основная конфигурация драйвера → Настройка выходных сигналов → GVI / LVDS / MIPI TX.

5.4.4 Выход LVDS

5.4.4.1 Настройка выхода LVDS

Добавьте узел “rk628-lvds-out” в узел RK628 DTS:

&i2c2_rk628 {
   ......
   rk628-lvds {

      bus-format = <MEDIA_BUS_FMT_RGB888_1X7X4_SPWG>;
      link-type = "single_link";
      status = "okay";
   };
   ......
};

Свойства узла “rk628-lvds-out”:

Свойство Описание Option Value
bus-format Формат шины /
/
link-type Тип соединения “single_link”: один канал
“dual_link_odd_even_pixels”: два канала; левый/правый передают нечётные/чётные пиксели
“dual_link_even_odd_pixels”: два канала; левый/правый передают чётные/нечётные пиксели
“dual_link_left_right_pixels”: два канала, левая/правая панели
“dual_link_right_left_pixels”: два канала, правая/левая панели
5.4.4.2 Настройка выходного сигнала

См. Основная конфигурация драйвера → Настройка выходных сигналов → GVI / LVDS / MIPI TX.

5.4.5 Выход GVI

5.4.5.1 Настройка выхода GVI

Добавьте узел “rk628-gvi-out” в узел RK628 DTS:

&i2c2_rk628 {
   ......
   rk628-gvi-out {

      bus-format = "rgb888";
      gvi,lanes = <8>;
      // rockchip,division-mode;
      // rockchip, gvi-frm-rst;
      status = "okay";
   };
   ......
};

Свойства узла “rk628-gvi-out”:

Свойство Описание Option Value
bus-format Формат шины “rgb666” / “rgb888” / “rgb101010” /
“yuyv8” / “yuyv10”
gvi,lanes Линии GVI 1、2、4、8
rockchip,division-mode Одна секция / две секции
[необязательно]
По умолчанию one section; свойство включает two section
rockchip, gvi-frm-rst Включить сброс GVI в начале кадра
[необязательно]
По умолчанию disabled; свойство задаёт enable
5.4.5.2 Изменение порядка линий

Если соседние пиксели регулярно меняются местами, настройте следующие регистры соответствия combtx lane и gvi_phy_datalane:

# echo 0x80004 $val > /d/rk628/2-0050/registers/combtxphy
# $val(combtx_lane_n):

#   lane0[Bit2:0], lane1[Bit6:4], lane2[Bit10:8], lane3[Bit14:12]
#   lane4[Bit18:16], lane5[Bit22:20], lane6[Bit26:24], lane7[Bit30:28]
# 显示异常时可以优先考虑如下常用   val 值:
# 0x01234567 0x76543210 0x10325476 0x67452301 0x45670123 0x32107654 0x54761023
0x23016745
# 例:
echo 0x80004 0x01234567 > /d/rk628/2-0050/registers/combtxphy

Соответствующее место изменения в программном коде:

diff --git a/drivers/misc/rk628/rk628_gvi.c b/drivers/misc/rk628/rk628_gvi.c
index fb41c2143bb5..ef47e58ad377 100644
--- a/drivers/misc/rk628/rk628_gvi.c

+++ b/drivers/misc/rk628/rk628_gvi.c
@@ -150,6 +150,8 @@ static void rk628_gvi_pre_enable(struct rk628 *rk628, struct
rk628_gvi *gvi)

      rk628_i2c_update_bits(rk628, GVI_SYS_CTRL1, SYS_CTRL1_COLOR_DEPTH_MASK,
                      SYS_CTRL1_COLOR_DEPTH(gvi->color_depth));
+
+     rk628_i2c_write(rk628, GVI_SYS_CTRL3, 0x01234567);
 }

 static void rk628_gvi_enable_color_bar(struct rk628 *rk628,
5.4.5.3 Настройка сигнала и расширение спектра

См. Основная конфигурация драйвера → Настройка выходных сигналов → GVI / LVDS / MIPI TX.

Для SSC см. Основная конфигурация драйвера → Настройка выходных сигналов → SSC.

5.4.5.4 Проверенные модели GVI для RK628F
TCON Модель Производитель панели Разрешение
IN8205A M280DGJ-L30 Innolux 3840*2160
IN8205A M315DJJ Innolux  
Изначально IN8908A; в конце 2021 года заменён на IN8210 S500DJ2-KS5 Innolux  
Изначально IN8908A; в конце 2021 года заменён на IN8210 V500DJ2-KS5 Innolux  
SW0894A LC860EQY-FJA5 Xunshi (в исходнике: 巡视)  
  LC550EGE LGDisplay  
Hi3231V530 HV550QUB-N8D BOE  
SW0894A MZ860004-07 ACT  
SW0894A 86S13DCX    
TLi2461MC ACT-MZ750004-07    
LP71517      
SW08006A 848.2    
TLi2380EP ist-ITV-016 FunTV  
SW08008      
10301 L22650USWL1 Lenove  
10302 HV860QUB-E1D    
CSQ12-B0S SG8561D03-1    
CSTU01-A0H H750D4-BA080AA    
CSTU01-A0W SL(LX)-23    
KV7636-VPP ST7461D02-6    
KV7626      
AUO-12417      
AUO-12415 ICB-VN65 HiteVision  
NT71120MFG-001      
EK76603E V650DK-KS5    
iLITEK-2326      
IN8205A      
MST6M60FV TN2A1FV4LCZZ    
  HS-86AW-L09PA    
  HV650QUB-F70    
  CEJZ650L07Q1 CSOT  
  MT5461D01-1 CSOT  
  BOEI650WQ1    
  UV650QUB-N90    
  LC650EQQ-SMA5    

5.4.6 Выход HDMI

Для переключения между разрешениями RK628 Misc реализован как мост DRM:

Оригинальный технический рисунок — EN V2.3, p37

Оригинальный технический рисунок: EN V2.3, p37.

5.4.6.1 Настройка выхода HDMI

Добавьте логическое свойство “rk628-hdmi-out” в узел RK628 DTS и свяжите узлы “&rgb” и RK628 через “remote-endpoint”:

&i2c2_rk628 {
   pinctrl-names = "default";

   pinctrl-0 = <&rk628_reset &refclk_pins>;
   assigned-clocks = <&pmucru CLK_WIFI>;
   assigned-clock-rates = <24000000>;
   clock-names = "soc_24M";
   clocks = <&pmucru CLK_WIFI>;

   rk628-rgb-in;
   rk628-hdmi-out;
   // mode-sync-pol = <0>;
   status = "okay";

   port {

      rgb_in_hdmi: endpoint {
         remote-endpoint = <&rgb_out_hdmi>;
      };
   };
};
&route_rgb {
   status = "disabled";

};

&rgb_in_vp2 {
   status = "okay";
};

&rgb {
   status = "okay";

   ports {
      port@1 {
         reg = <1>;


         rgb_out_hdmi: endpoint {
           remote-endpoint = <&rgb_in_hdmi>;
         };
      };
   };
};

Разрешение и полярность HDMITX меняются согласно стандартным режимам, поэтому параметры панели не задаются. Для входа RGB/BT1120 настройте mode-sync-pol по фактическим hsync-active и vsync-active. Свойство одно, поэтому hsync-active и vsync-active должны совпадать. По умолчанию полярность равна 1, положительная. При искажениях изображения попробуйте добавить это свойство.

Тракт HDMITX требует общего источника тактирования, иначе возможны нарушения изображения. См. Основная конфигурация драйвера → Рабочая частота 24 МГц.

5.4.6.2 Настройка выходного сигнала

См. Основная конфигурация драйвера → Настройка выходных сигналов → HDMI TX.

5.4.6.3 Настройка аудио
&i2s0 {
   rockchip,playback-only;

   status = "oaky";
};

/ {
   rk628_sound: rk628-sound {
      compatible = "simple-audio-card";
      simple-audio-card,format = "i2s";
      simple-audio-card,mclk-fs = <128>;
      simple-audio-card,name = "rockchip,hdmi-rk628";
      status = "oaky";
      simple-audio-card,cpu {
         sound-dai = <&i2s0>;
      };
      simple-audio-card,codec {
         sound-dai = <&i2c2_rk628>;
      };

   };
}

5.5 Комбинации, поддерживаемые DTS

5.5.1 Преобразование RGB → DSI

Пример DTS:

arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts

Эти DTS расширяют rk3568-evb.dtsi поддержкой RK628 RGB → MIPI DSI. Сопоставьте код с описаниями входных и выходных модулей для определения различий.

Вывод RGB SoC с заданными временными параметрами описан в разделе Настройка входных модулей → Вход RGB.

5.5.2 Преобразование RGB → LVDS

Пример DTS:

arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-dual-ddr4-v10.dts

Исходник описывает эти DTS как добавление RK628 RGB → MIPI DSI к rk3568-evb.dtsi, хотя раздел посвящён LVDS. rk3568-evb-rk628-rgb2lvds-ddr4-v10.dts задаёт одноканальный LVDS, rk3568-evb-rk628-rgb2lvds-dual-ddr4-v10.dts — двухканальный. Сопоставьте код с описаниями входных и выходных модулей.

Вывод RGB SoC с заданными временными параметрами описан в разделе Настройка входных модулей → Вход RGB.

5.5.3 Преобразование RGB → GVI

Пример DTS:

arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2gvi-ddr4-v10.dts

Эти DTS расширяют rk3568-evb.dtsi преобразованием RK628 RGB → GVI. Сравните код с описаниями входных и выходных модулей.

Вывод RGB SoC с заданными временными параметрами описан в разделе Настройка входных модулей → Вход RGB.

5.5.4 Преобразование RGB → HDMI

Пример DTS:

arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2hdmi-ddr4-v10.dts

Эти DTS расширяют rk3568-evb.dtsi преобразованием RK628 RGB → HDMI. Сравните код с описаниями входных и выходных модулей.

HDMITX определяет поддерживаемые панелью разрешения и выбирает целевое; временные параметры RGB-выхода SoC поэтому не заданы в DTS.

5.5.5 Преобразование HDMI → DSI

Пример DTS:

arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts

arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-dual-ddr4-v10.dts

Эти DTS расширяют rk3568-evb.dtsi преобразованием RK628 HDMI → DSI при прямом соединении с SoC. rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts задаёт один MIPI DSI, rk3568-evb-rk628-hdmi2dsi-dual-ddr4-v10.dts — два. Сравните код с описаниями входных и выходных модулей.

Для вывода SoC с заданными временными параметрами исходник упоминает RGB, но ссылается на раздел Вход HDMI. Эта терминология требует проверки.

5.5.6 Преобразование HDMI → LVDS

Пример DTS:

arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-ddr4-v10.dts

arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-dual-ddr4-v10.dts

Эти DTS расширяют rk3568-evb.dtsi преобразованием RK628 HDMI → LVDS при прямом соединении с SoC. rk3568-evb-rk628-hdmi2lvds-ddr4-v10.dts задаёт одноканальный LVDS, rk3568-evb-rk628-hdmi2lvds-dual-ddr4-v10.dts — двухканальный. Сравните код с описаниями входных и выходных модулей.

Для вывода SoC с заданными временными параметрами исходник упоминает RGB, но ссылается на раздел Вход HDMI. Эта терминология требует проверки.

5.5.7 Преобразование HDMI → GVI

Пример DTS:

arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2gvi-ddr4-v10.dts

Эти DTS расширяют rk3568-evb.dtsi преобразованием RK628 HDMI → GVI при прямом соединении с SoC. Сравните код с описаниями входных и выходных модулей.

Для вывода SoC с заданными временными параметрами исходник упоминает RGB, но ссылается на раздел Вход HDMI. Эта терминология требует проверки.

5.6 Основные команды отладки

5.6.1 Узлы отладки регистров

В /sys/kernel/debug/regmap:

rk3568_t:/ # ls /sys/kernel/debug/regmap/
0-001c        2-0050-dsi1 2-0050-hdmirx 4-0050-gpio0
0-0020        2-0050-efuse 4-0050-adapter 4-0050-gpio1

0-0020-rk817-codec 2-0050-gpio0 4-0050-combrxphy 4-0050-gpio2
2-0050-adapter 2-0050-gpio1 4-0050-combtxphy 4-0050-gpio3
2-0050-combrxphy 2-0050-gpio2 4-0050-cru 4-0050-grf
2-0050-combtxphy 2-0050-gpio3 4-0050-csi 4-0050-gvi
2-0050-cru    2-0050-grf 4-0050-dsi0  4-0050-hdmi
2-0050-csi    2-0050-gvi 4-0050-dsi1  4-0050-hdmirx
2-0050-dsi0   2-0050-hdmi 4-0050-efuse ......

Или в /sys/kernel/debug/rk628/x-xxxx/registers:

rk3568_t:/ # ls /sys/kernel/debug/rk628/2-0050/registers/
adapter combrxphy combtxphy cru csi dsi0 dsi1 efuse gpio0 gpio1 gpio2
gpio3 grf gvi hdmi hdmirx

Здесь 2 — номер шины I2C, 0050 — адрес ведомого RK628.

1. Чтение регистров на примере GRF:

В /sys/kernel/debug/regmap:

rk3568_t:/ # cat /sys/kernel/debug/regmap/2-0050-grf/registers
000: 06000088
004: ffffffff

008: 00000000
00c: 00000000
010: 00000001
014: 00000000
018: 00050000
01c: 002c0898
020: 00c00840
......

rk3568_t:/ # cat /sys/kernel/debug/regmap/2-0050-grf/registers | grep 200:
200: 20230321

Или в /sys/kernel/debug/rk628/x-xxxx/registers:

rk3568_t:/ # cat /sys/kernel/debug/rk628/2-0050/registers/grf
rk628_grf:


0x0000: 06000298 ffffffff 00000000 00000001
0x0010: 00000001 00000000 000404b6 002804ba
0x0020: 0046047e 000a079e 00140794 0046047e
0x0030: 00140794 00000004 00000000 00000000
0x0040: 04380004 80000000 00000000 00000000
0x0050: 80000000 00000000 10000000 00000000
0x0060: 000002ea 01f0ea00 00000000 01f00000
0x0070: 0000155c 00005602 00000000 00000000
0x0080: 00006000 00000000 00000000 00000000
......

rk3568_t:/ # cat /sys/kernel/debug/rk628/2-0050/registers/grf | grep 0200:

0x0200: 20230321 00000000 00000000 00000000

2. Запись регистров на примере GRF:

В /sys/kernel/debug/regmap:

rk3568_t:/ # echo 0x010 0x02000200 > /sys/kernel/debug/regmap/2-0050-
grf/registers

Или в /sys/kernel/debug/rk628/x-xxxx/registers:

rk3568_t:/ # echo 0x010 0x02000200 > /sys/kernel/debug/rk628/2-0050/registers/grf

5.6.2 Команды самопроверки

Если изображение неправильное, следующая команда помогает определить, относится ли проблема ко входу или выходу RK628. Доступно только для RK628F/H.

# Enable horizontal color bar
rk3568_t:/ # echo 1 > /sys/kernel/debug/rk628/2-0050/scaler_color_bar


# Enable vertical color bar
rk3568_t:/ # echo 2 > /sys/kernel/debug/rk628/2-0050/scaler_color_bar

# Disable color bar
rk3568_t:/ # echo 0 > /sys/kernel/debug/rk628/2-0050/scaler_color_bar

Если цветовые полосы scaler отображаются правильно, проверяйте выход основного SoC, вход RK628 и настройки RK628 Process. Иначе сначала проверяйте выход RK628; затем полосами отдельных интерфейсов ниже проверяйте контроллер, PHY и панель. Если полосы модулей работают, но scaler color всё ещё не отображается, продолжайте проверять вход RK628.

Следующие команды проверяют контроллер выхода, его PHY и путь до панели:

1. Цветовые полосы HDMITX

# Enable normal color bar
rk3568_t:/ # echo 1 > /sys/kernel/debug/rk628/2-0050/hdmitx_color_bar


# Enable special color bar
rk3568_t:/ # echo 2 > /sys/kernel/debug/rk628/2-0050/hdmitx_color_bar

# Enable black color bar
rk3568_t:/ # echo 3 > /sys/kernel/debug/rk628/2-0050/hdmitx_color_bar

# Disable color bar
rk3568_t:/ # echo 0 > /sys/kernel/debug/rk628/2-0050/hdmitx_color_bar

2. Цветовые полосы DSI

# Enable dsi color bar
rk3568_t:/ # echo 1 > /sys/kernel/debug/rk628/2-0050/dsi_color_bar


# Disable dsi color bar
rk3568_t:/ # echo 0 > /sys/kernel/debug/rk628/2-0050/dsi_color_bar

3. Цветовые полосы GVI

# Enable color bar
rk3568_t:/ # echo 1 > /sys/kernel/debug/rk628/2-0050/gvi_color_bar


# Disable color bar
rk3568_t:/ # echo 0 > /sys/kernel/debug/rk628/2-0050/gvi_color_bar

5.6.3 Отладка RGB IN (только RK628F/H)

Следующая команда показывает фактически принятое RGB IN разрешение, позволяя проверить работу RGB RX на RK628F/H:

rk3568_t:/ # cat /sys/kernel/debug/rk628/2-0050/rgb_resolution
1080x1920 pclk:131967000

5.7 Типовые проблемы отображения

5.7.1 Узел regmap не создан

Проверьте журналы на ошибки RK628, мешающие успешному probe, например:

rk3568_t:/ # dmesg | grep rk628
[  0.294331] rk628 2-0050: the driver version is 0.1.0 of RK628-F/B/G

[  0.294426] rk628 2-0050: failed to request enable GPIO: -16

5.7.2 Ошибка связи I2C

Такие журналы указывают на ошибки I2C RK628, из-за которых модули не регистрируются. Проверьте последовательность питания RK628, опорные 24 МГц (раздел типовых требований) и IOMUX соответствующих выводов.

[  0.960609] rk628 1-0050: failed to access register: -6

5.7.3 Изображение DSI/GVI присутствует, но искажено

Попробуйте изменить полярности интервалов гашения в src-timing DTS. Это применимо к DSI и GVI.

Например:

--- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts
@@ -347,8 +347,8 @@ src-timing {

                       vfront-porch = <15>;
                       hsync-len = <2>;
                       vsync-len = <2>;
-                      hsync-active = <0>;
-                      vsync-active = <0>;
+                      hsync-active = <1>;
+                      vsync-active = <1>;
                       de-active = <0>;
                       pixelclk-active = <0>;

5.7.4 DSI не показывает после увеличения clock-frequency

Для повышения частоты обновления обычно увеличивают clock-frequency, например:

--- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts
@@ -338,7 +338,7 @@ rk628-panel {


           display-timings {
                 src-timing {
-                      clock-frequency = <132000000>;
+                      clock-frequency = <148500000>;
                       hactive = <1080>;
                       vactive = <1920>;
                       hback-porch = <30>;
@@ -354,7 +354,7 @@ src-timing {
                 };

                 dst-timing {

-                      clock-frequency = <132000000>;
+                      clock-frequency = <148500000>;
                       hactive = <1080>;
                       vactive = <1920>;
                       hback-porch = <30>;

Повышение CLK может вызвать мерцание или отсутствие изображения. В таком случае попробуйте изменить скорость линий:

--- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts
@@ -57,6 +57,7 @@ &i2c2_rk628 {


           rk628-rgb-in;
           rk628-dsi-out {
+                rockchip,lane-mbps = <1000>;
                 //rockchip,dual-channel;
                 dsi,eotp;
                 dsi,video-mode;

5.7.5 Смещение изображения

Например, при входе HDMI и смещённом изображении на выходе измените параметры гашения панели согласно направлению смещения: hfront-porch/hback-porch/hsync-len и vfront-porch/vback-porch/vsync-len в src-timing/dst-timing DTS. Выходной clock-frequency должен совпадать с входным HDMI, например 148500000 с обеих сторон.

--- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts
@@ -314,7 +314,7 @@ src-timing {

                 hfront-porch = <60>;
                 vback-porch = <10>;
                 vfront-porch = <10>;
-                hsync-len = <20>;
+                hsync-len = <40>;
                 vsync-len = <10>;
                 hsync-active = <1>;
                 vsync-active = <1>;

5.7.6 Управление GPIO RK628

В нужном месте вызывайте интерфейс GPIO, включив заголовки rk628_pinctrl.h и rk628_gpio.h. Он задаёт IOMUX, направление и уровень. Следующий пример переводит I2S_D2_M0 в GPIO и устанавливает высокий уровень:

#include "rk628_pinctrl.h"
#include "rk628_gpio.h"


rk628_misc_gpio_direction_output(rk628, GPIO0_A6, 1);

Для восстановления исходной функции вызовите:

rk628_misc_pinctrl_set_mux(rk628, GPIO0_A6, I2SM0D2);

6. Media

6.1 Обзор драйвера

Оригинальный технический рисунок — EN V2.3, p46

Оригинальный технический рисунок: EN V2.3, p46.

Media — код драйвера тракта HDMI IN RK628. RK628 используется как устройство типа камеры для реализации показанных выше функций.

6.1.1 Улучшения RK628F/H относительно RK628D

Драйвер media в основном соединяет HDMI2CSI, HDMI2DSI или HDMI2BT1120 с ведущей SoC. Основные улучшения RK628F/H относительно RK628D в этой области:

主要改进点

Модуль

Поддерживает HDMI2.0 и вход RGB 4K60.

HDMIRX поддерживает дополнительные частотные точки.

Поддерживает режим DVI с более быстрым и устойчивым захватом синхронизации.

解决了不同图像格式输入,格式转换下采样引入的色偏问题
增加一路  MIPI-CSI,双 MIPI-CSI 支持 4K60 输出

MIPI-CSI

В CSC добавлена матрица для более гибкого преобразования цветового пространства изображения.

6.1.2 Структура каталогов драйвера

Код драйвера RK628 media зависит от версии ядра. До kernel-5.10 используется пакет rk628_for-all; для kernel-5.10 — kernel_5.10_rk628_media_patch.

Для ядер до kernel-5.10 структура каталогов следующая:

drivers/media/i2c/rk628
├── Makefile

├── rk628_bt1120_v4l2.c
├── rk628.c
├── rk628_combrxphy.c
├── rk628_combrxphy.h
├── rk628_combtxphy.c
├── rk628_combtxphy.h
├── rk628_cru.c
├── rk628_cru.h
├── rk628_csi.c
├── rk628_csi.h
├── rk628_csi_v4l2.c
├── rk628_dsi.c

├── rk628_dsi.h
├── rk628_gpio.h
├── rk628_grf.h
├── rk628.h
├── rk628_hdmirx.c
├── rk628_hdmirx.h
├── rk628_mipi_dphy.c
├── rk628_mipi_dphy.h
├── rk628_pinctrl.c
├── rk628_pinctrl.h
├── rk628_post_process.c
├── rk628_post_process.h

└── rk628_v4l2_controls.h

Для kernel-5.10 каталог драйвера следующий:

drivers/media/i2c/rk628
├── Makefile

├── rk628_bt1120_v4l2.c
├── rk628.c
├── rk628_combrxphy.c
├── rk628_combrxphy.h
├── rk628_combtxphy.c
├── rk628_combtxphy.h
├── rk628_cru.c
├── rk628_cru.h
├── rk628_csi.c
├── rk628_csi.h
├── rk628_csi_v4l2.c
├── rk628_dsi.c
├── rk628_dsi.h

├── rk628.h
├── rk628_hdmirx.c
├── rk628_hdmirx.h
├── rk628_mipi_dphy.c
├── rk628_mipi_dphy.h
├── rk628_post_process.c
└── rk628_post_process.h

Основные файлы драйвера и области применения:

rk628_csi.c: HDMI2CSI для CameraHal1 и сторонних SoC.

rk628_csi_v4l2.c: HDMI2CSI / HDMI2DSI для платформ V4L2, например CameraHal3 и TV input.

rk628_bt1120_v4l2.c: HDMI2BT1120 для платформ V4L2, например CameraHal3.

6.1.3 Перенос драйвера

См. раздел переноса драйвера → тракт HDMI IN (drivers/media/i2c/rk628).

6.2 Видеоподсистема HDMI IN

Для HDMI IN video RK628 моделируется как камера MIPI SoC. Подсистема camera или TV принимает видео для вывода в APK. Для HDMI IN добавлены горячее подключение и автоматическая адаптация разрешения.

Android9/10/11 использует cameraHAL3. См. Rockchip_Developer_Guide_HDMI_IN_Based_On_CameraHal3_CN.pdf в RKDocs/common/camera/hdmi-in SDK.

Android12/13 использует cameraHAL3/TVinput. См. следующий документ в RKDocs/common/camera/hdmi-in SDK:

Rockchip_Developer_Guide_Android12+_HDMI_IN_Bridge_CN

6.2.1 Порядок работы APK HDMI IN

Общий порядок работы APK показан ниже:

Оригинальный технический рисунок — EN V2.3, p49

Оригинальный технический рисунок: EN V2.3, p49.

Для kernel-4.19 или kernel-4.4 (Android 9/10/11) предпросмотр можно открыть непосредственно через rkCamera2.

Для kernel-5.10 (Android 12/13) необходимо различать подсистемы camera и TV. См.:

Rockchip_Developer_Guide_Android12+_HDMI_IN_Bridge_CN

6.2.2 Архитектура драйвера RK628

Особого внимания требуют три части драйвера: инициализация, обработка прерывания горячего подключения и обработка прерывания смены разрешения. Схемы приведены ниже:

Оригинальный технический рисунок — EN V2.3, p51

Оригинальный технический рисунок: EN V2.3, p51.

Оригинальный технический рисунок — EN V2.3, p50

Оригинальный технический рисунок: EN V2.3, p50.

Оригинальный технический рисунок — EN V2.3, p52

Оригинальный технический рисунок: EN V2.3, p52.

6.3 Настройка DTS

6.3.1 Настройка узла RK628

&i2c5 {
   status = "okay";


   rk628_csi: rk628_csi@50 {
      reg = <0x50>;
      compatible = "rockchip,rk628-csi-v4l2";
      status = "okay";
      power-domains = <&power RK3588_PD_VI>;
      pinctrl-names = "default";
      pinctrl-0 = <&rk628_pin>;
      interrupt-parent = <&gpio2>;
      interrupts = <RK_PC4 IRQ_TYPE_LEVEL_HIGH>;
      enable-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
      reset-gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
      plugin-det-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>;

      continues-clk = <1>;

      rockchip,camera-module-index = <0>;
      rockchip,camera-module-facing = "back";
      rockchip,camera-module-name = "HDMI-MIPI";
      rockchip,camera-module-lens-name = "RK628-CSI";

      multi-dev-info {
         dev-idx-l = <0>;
         dev-idx-r = <1>;
         combine-idx = <0>;
         pixel-offset = <0>;

         dev-num = <2>;
      };

      port {
         hdmiin_out0: endpoint {
           remote-endpoint = <&hdmi_mipi0_in>;
           data-lanes = <1 2 3 4>;
         };
      };
   };
};

reg: адрес I2C. Типичный 7-битный адрес RK628 — 0x50. При нескольких RK628 адрес можно менять через GPIO RK628; см. связь SoC–RK628 по I2C.

compatible:

compatible = “rockchip,rk628-csi” соответствует rk628_csi.c; compatible = “rockchip,rk628-csi-v4l2” — rk628_csi_v4l2.c; compatible = “rockchip,rk628-bt1120-v4l2” — rk628_bt1120_v4l2.c.

interrupt-parent/interrupts: контакт GPIO, соединённый с прерыванием RK628.

enable-gpios: GPIO управления питанием RK628; при постоянном питании можно не задавать.

reset-gpios: GPIO управления сбросом RK628.

hpd-output-inverted: инверсия выхода HPD. Включите, если аппаратная схема инвертирует уровень HPD.

Оригинальный технический рисунок — EN V2.3, p54

Оригинальный технический рисунок: EN V2.3, p54.

plugin-det-gpios: GPIO обнаружения подключения HDMI. Проверьте инверсию уровня в схеме и правильно задайте активный уровень.

Оригинальный технический рисунок — EN V2.3, p54

Оригинальный технический рисунок: EN V2.3, p54.

power-gpios: GPIO питания домена MIPI RX ведущей Rockchip; при постоянном питании можно не задавать.

hdcp-enable: включение HDCP.

continues-clk: выбор непрерывного или прерывистого тактового сигнала выхода MIPI CSI.

multi-dev-info: требуется для 4K60 через два MIPI (только RK628F/H). В оригинале указаны RK3588/RK3562/RK3576 и ядра 5.10 или новее.

6.3.2 Тракты приёма изображения

Разрабатывайте преобразователь RK628 как устройство типа камеры с драйвером V4L2, аналогично сенсору камеры. Настройка тракта данных соответствует MIPI SoC Sensor. Три типичных варианта:

RK628 → HDMI2CSI → SoC

RK628 → HDMI2DSI → SoC

RK628 → HDMI2BT1120 → SoC

6.3.3 Тракт HDMI2CSI

6.3.3.1 RK628D

Пример RK3288 + CSI_V4L2: настройка тракта rk628 + isp1.

&rk628_csi {
   status = "okay";
   /*

   * If the hpd output level is inverted on the circuit,
   * the following configuration needs to be enabled.
   */
   /* hpd-output-inverted; */
   plugin-det-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
   power-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
   rockchip,camera-module-index = <0>;
   rockchip,camera-module-facing = "back";
   rockchip,camera-module-name = "RK628-CSI";

   rockchip,camera-module-lens-name = "NC";

   port {
      hdmiin_out0: endpoint {
         remote-endpoint = <&mipi_in>;
         data-lanes = <1 2 3 4>;
      };
   };
};

&mipi_phy_rx0 {
   status = "okay";


   ports {
      #address-cells = <1>;
      #size-cells = <0>;

      port@0 {
         reg = <0>;
         #address-cells = <1>;
         #size-cells = <0>;

         mipi_in: endpoint@1 {
            reg = <1>;
            remote-endpoint = <&hdmiin_out0>;

            data-lanes = <1 2 3 4>;
         };
      };

      port@1 {
         reg = <1>;
         #address-cells = <1>;
         #size-cells = <0>;

         dphy_rx_out: endpoint@0 {
            reg = <0>;
            remote-endpoint = <&isp_mipi_in>;

         };
      };
   };
};

&rkisp1 {
   status = "okay";
   port {
      #address-cells = <1>;
      #size-cells = <0>;

      isp_mipi_in: endpoint@0 {
         reg = <0>;

         remote-endpoint = <&dphy_rx_out>;
      };
   };
};

&isp_mmu {

   status = "okay";
};

Пример RK3568 + CSI_V4L2: настройка тракта rk628 + isp2:

&i2c2 {
   status = "okay";

   pinctrl-names = "default";
   pinctrl-0 = <&i2c2m1_xfer>;

   rk628_csi: rk628_csi@32 {
      compatible = "rockchip,rk628-csi-v4l2";
      reg = <0x50>;
      interrupt-parent = <&gpio4>;
      interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
      pinctrl-names = "default";
      pinctrl-0 = <&rk628_irq>;
      reset-gpios = <&gpio4 RK_PD2 GPIO_ACTIVE_LOW>;
      plugin-det-gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
      rockchip,camera-module-index = <0>;

      rockchip,camera-module-facing = "back";
      rockchip,camera-module-name = "RK628-CSI";
      rockchip,camera-module-lens-name = "NC";
      port {
         rk628_out: endpoint {
           remote-endpoint = <&mipi_in>;
           data-lanes = <1 2 3 4>;
         };
      };
   };
};


&csi2_dphy_hw {
   status = "okay";
};

&csi2_dphy0 {
   status = "okay";

   ports {
      #address-cells = <1>;
      #size-cells = <0>;
      port@0 {
         reg = <0>;
         #address-cells = <1>;

         #size-cells = <0>;

         mipi_in: endpoint@0 {
           reg = <0>;
           remote-endpoint = <&rk628_out>;
           data-lanes = <1 2 3 4>;
         };
      };
      port@1 {
         reg = <1>;

         #address-cells = <1>;
         #size-cells = <0>;

         csidphy0_out: endpoint@0 {
           reg = <0>;
           remote-endpoint = <&isp0_in>;
         };
      };
   };
};

&rkisp {

   status = "okay";
};

&rkisp_mmu {
   status = "okay";
};

&rkisp_vir0 {
   status = "okay";

   port {
      #address-cells = <1>;
      #size-cells = <0>;


      isp0_in: endpoint@0 {
         reg = <0>;
         remote-endpoint = <&csidphy0_out>;
      };
   };
};

Настройка тракта rk628 + vicap для RK3568:

&i2c2 {
   status = "okay";
   pinctrl-names = "default";

   pinctrl-0 = <&i2c2m1_xfer>;

   rk628_csi: rk628_csi@32 {
      compatible = "rockchip,rk628-csi-v4l2";
      reg = <0x50>;
      //clocks = <&ext_cam_clk>;
      //clock-names = "xvclk";

      interrupt-parent = <&gpio4>;
      interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
      pinctrl-names = "default";
      pinctrl-0 = <&rk628_irq>;

      //power-gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
      reset-gpios = <&gpio4 RK_PD2 GPIO_ACTIVE_LOW>;
      plugin-det-gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
      rockchip,camera-module-index = <0>;
      rockchip,camera-module-facing = "back";

      rockchip,camera-module-name = "RK628-CSI";
      rockchip,camera-module-lens-name = "NC";
      port {
         rk628_out: endpoint {
            remote-endpoint = <&mipi_in>;
            data-lanes = <1 2 3 4>;
         };
      };
   };
};

&csi2_dphy_hw {

   status = "okay";
};

&csi2_dphy0 {
   status = "okay";

   ports {
      #address-cells = <1>;
      #size-cells = <0>;
      port@0 {
         reg = <0>;
         #address-cells = <1>;
         #size-cells = <0>;


         mipi_in: endpoint@0 {
            reg = <0>;
            remote-endpoint = <&rk628_out>;
            data-lanes = <1 2 3 4>;
         };
      };
      port@1 {
         reg = <1>;
         #address-cells = <1>;
         #size-cells = <0>;


         csidphy0_out: endpoint@0 {
            reg = <0>;
            remote-endpoint = <&mipi_csi2_input>;
            data-lanes = <1 2 3 4>;
         };
      };
   };
};

&mipi_csi2 {
   status = "okay";

   ports {

      #address-cells = <1>;
      #size-cells = <0>;
      port@0 {
         reg = <0>;
         #address-cells = <1>;

         #size-cells = <0>;

         mipi_csi2_input: endpoint@1 {
           reg = <1>;
           remote-endpoint = <&csidphy0_out>;
           data-lanes = <1 2 3 4>;
         };
      };

      port@1 {
         reg = <1>;
         #address-cells = <1>;

         #size-cells = <0>;

         mipi_csi2_output: endpoint@0 {
           reg = <0>;
           remote-endpoint = <&cif_mipi_in>;
           data-lanes = <1 2 3 4>;
         };
      };
   };
};

&rkcif {
   status = "okay";

};

&rkcif_mipi_lvds {
   status = "okay";

   port {
      cif_mipi_in: endpoint {
         remote-endpoint = <&mipi_csi2_output>;
         data-lanes = <1 2 3 4>;
      };
   };
};


&rkcif_mmu {
   status = "okay";
};
6.3.3.2 RK628F/H

Настройка DTS соединения RK628F/H с SoC в основном аналогична RK628D; используйте соответствующий пример.

RK628F/H поддерживает два MIPI. В этом абзаце перечислены только ведущие RK3588/RK3562. Следующий пример двух MIPI RK3588 соединяет CSI0/CSI1 RK628F/H с CSI0/CSI1 RK3588 через vicap.

&csi2_dphy0 {
   status = "okay";
   ports {
      #address-cells = <1>;

      #size-cells = <0>;
      port@0 {
         reg = <0>;
         #address-cells = <1>;
         #size-cells = <0>;

         hdmi_mipi2_in: endpoint@1 {
            reg = <1>;
            remote-endpoint = <&hdmiin_out1>;
            data-lanes = <1 2 3 4>;
         };
      };

      port@1 {
         reg = <1>;
         #address-cells = <1>;
         #size-cells = <0>;

         csidphy0_out: endpoint@0 {
            reg = <0>;
            remote-endpoint = <&mipi2_csi2_input>;
         };
      };
   };
};


&csi2_dphy0_hw {
   status = "okay";
};

&csi2_dphy1_hw {
   status = "okay";
};

&i2c3 {
   status = "okay";
   clock-frequency = <400000>;


   rk628_csi: rk628_csi@50 {
      reg = <0x50>;
      compatible = "rockchip,rk628-csi-v4l2";
      status = "okay";
      power-domains = <&power RK3588_PD_VI>;
      pinctrl-names = "default";
      pinctrl-0 = <&rk628_pin>;
      interrupt-parent = <&gpio1>;
      interrupts = <RK_PB2 IRQ_TYPE_LEVEL_HIGH>;
      enable-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>;
      reset-gpios = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>;
      plugin-det-gpios = <&gpio2 RK_PB6 GPIO_ACTIVE_LOW>;
      continues-clk = <1>;


      rockchip,camera-module-index = <0>;
      rockchip,camera-module-facing = "back";
      rockchip,camera-module-name = "HDMI-MIPI2";
      rockchip,camera-module-lens-name = "RK628-CSI";


      multi-dev-info {
         dev-idx-l = <2>;
         dev-idx-r = <4>;
         combine-idx = <2>;
         pixel-offset = <0>;
         dev-num = <2>;
      };

      port {
         hdmiin_out1: endpoint {
            remote-endpoint = <&hdmi_mipi2_in>;
            data-lanes = <1 2 3 4>;

         };
      };
   };
};

&mipi_dcphy0 {
   status = "okay";
};

&mipi_dcphy1 {
   status = "okay";
};


&mipi2_csi2 {
   status = "okay";

   ports {
      #address-cells = <1>;
      #size-cells = <0>;

      port@0 {
         reg = <0>;
         #address-cells = <1>;
         #size-cells = <0>;


         mipi2_csi2_input: endpoint@1 {
            reg = <1>;
            remote-endpoint = <&csidphy0_out>;
         };
      };

      port@1 {
         reg = <1>;
         #address-cells = <1>;
         #size-cells = <0>;

         mipi2_csi2_output: endpoint@0 {
            reg = <0>;

            remote-endpoint = <&cif_mipi_in2>;
         };
      };
   };
};


&rkcif {
   status = "okay";
};

&rkcif_mipi_lvds2 {
   status = "okay";

   port {
      cif_mipi_in2: endpoint {
         remote-endpoint = <&mipi2_csi2_output>;
      };
   };

};

&rkcif_mmu {
   status = "okay";
};

6.3.4 Преобразование HDMI2DSI

6.3.4.1 RK628D

При HDMI-to-MIPI-CSI на RK628D преобразование цветового пространства или повышение/понижение дискретизации может слегка менять цветовые детали. Альтернатива — HDMI-to-MIPI-DSI: хост принимает RGB888 напрямую, а приложение преобразует формат библиотекой rgb2yuv. Учитывайте:

Максимальное разрешение: 1080P60.

AP с поддержкой приёма MIPI DSI: RK1109, RK1126, RK3566, RK3568, RK3588, RK3562 и RK3576 (обозначения оригинала сохранены).

Ранние AP, например RK3288, RK3326, RK3368 и RK3399, не поддерживают приём MIPI DSI.

Код CSI и DSI совместим; различие задаётся compatible в DTS:

CSI: compatible = “rockchip,rk628-csi-v4l2”;

DSI: compatible = “rockchip,rk628-dsi-v4l2”;

Пример RK3568:

&i2c2 {
   status = "okay";
   pinctrl-names = "default";

   pinctrl-0 = <&i2c2m1_xfer>;

   rk628_csi: rk628_csi@32 {
      compatible = "rockchip,rk628-dsi-v4l2";
      reg = <0x50>;

      interrupt-parent = <&gpio4>;
      interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
      pinctrl-names = "default";
      pinctrl-0 = <&rk628_irq>;
      //power-gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
      reset-gpios = <&gpio4 RK_PD2 GPIO_ACTIVE_LOW>;

      plugin-det-gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
      rockchip,camera-module-index = <0>;
      rockchip,camera-module-facing = "back";
      rockchip,camera-module-name = "RK628-CSI";
      rockchip,camera-module-lens-name = "NC";
      port {
         rk628_out: endpoint {
            remote-endpoint = <&hdmi2mipi_in>;
            data-lanes = <1 2 3 4>;
         };
      };
   };

};

&mipi_csi2 {
   status = "okay";

   ports {
      #address-cells = <1>;
      #size-cells = <0>;

      port@0 {
         reg = <0>;
         #address-cells = <1>;
         #size-cells = <0>;


         mipi_csi2_input: endpoint@1 {
            reg = <1>;
            remote-endpoint = <&csidphy_out>;
            data-lanes = <1 2 3 4>;
         };
      };

      port@1 {
         reg = <1>;
         #address-cells = <1>;
         #size-cells = <0>;


         mipi_csi2_output: endpoint@0 {
            reg = <0>;
            remote-endpoint = <&cif_mipi_in>;
            data-lanes = <1 2 3 4>;
         };
      };
   };
};

&rkcif {
   status = "okay";
};


&rkcif_mipi_lvds {
   status = "okay";
   port {
      cif_mipi_in: endpoint {

         remote-endpoint = <&mipi_csi2_output>;
         data-lanes = <1 2 3 4>;
      };
   };
};

&rkcif_mmu {
   status = "okay";
};

&csi2_dphy_hw {
   status = "okay";

};

&csi2_dphy0 {
   status = "okay";

   ports {
      #address-cells = <1>;
      #size-cells = <0>;
      port@0 {
         reg = <0>;
         #address-cells = <1>;
         #size-cells = <0>;


         hdmi2mipi_in: endpoint@0 {
           reg = <1>;
           remote-endpoint = <&rk628_out>;
           data-lanes = <1 2 3 4>;
         };
      };
      port@1 {
         reg = <1>;
         #address-cells = <1>;
         #size-cells = <0>;

         csidphy_out: endpoint@0 {

           reg = <0>;
           remote-endpoint = <&mipi_csi2_input>;
         };
      };
   };
};

Для ведущего RK3568 со старым кодом CIF требуется следующий коммит для приёма RGB888:

Драйверы RK3588 kernel-5.10 поддерживают RGB888 по умолчанию.

From e925e385a41a857e8e50020b5df9a2d41b166d83 Mon Sep 17 00:00:00 2001
From: Zefa Chen <zefa.chen@rock-chips.com>
Date: Thu, 02 Sep 2021 15:07:13 +0800

Subject: [PATCH] media: rockchip: cif fix errors in rgb24 data format
Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com>
Change-Id: I0766997860f06dc25e604c2ea8425049a987fdc5

---

diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c
index 6c0aa7d..36bd2c9 100644
--- a/drivers/media/platform/rockchip/cif/capture.c
+++ b/drivers/media/platform/rockchip/cif/capture.c
@@ -1785,13 +1785,11 @@
     * needs aligned with :ALIGN(bits_per_pixel * width * 2, 8), to optimize
reading and
     * writing of ddr, aliged with 256
     */

-   if (fmt->fmt_type == CIF_FMT_TYPE_RAW && stream->is_compact) {
+   if (fmt->fmt_type == CIF_FMT_TYPE_RAW && stream->is_compact &&
+      fmt->csi_fmt_val != CSI_WRDDR_TYPE_RGB888) {
       channel->virtual_width = ALIGN(channel->width * fmt->raw_bpp / 8, 256);
    } else {
-      if (fmt->fmt_type == CIF_FMT_TYPE_RAW && fmt->csi_fmt_val !=
CSI_WRDDR_TYPE_RAW8)
-         channel->virtual_width = ALIGN(channel->width * 2, 8);
-      else
-         channel->virtual_width = ALIGN(channel->width * fmt->bpp[0] / 8, 8);
+      channel->virtual_width = ALIGN(channel->width * fmt->bpp[0] / 8, 8);
    }


    if (channel->fmt_val == CSI_WRDDR_TYPE_RGB888)
@@ -3240,7 +3238,8 @@

       if (fmt->fmt_type == CIF_FMT_TYPE_RAW && stream->is_compact &&
          (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2 ||
-         dev->active_sensor->mbus.type == V4L2_MBUS_CCP2)) {
+         dev->active_sensor->mbus.type == V4L2_MBUS_CCP2) &&
+         fmt->csi_fmt_val != CSI_WRDDR_TYPE_RGB888) {
          bpl = ALIGN(width * fmt->raw_bpp / 8, 256);
       } else {
          bpp = rkcif_align_bits_per_pixel(stream, fmt, i);
@@ -4659,13 +4658,11 @@

     * needs aligned with :ALIGN(bits_per_pixel * width * 2, 8), to optimize
reading and
     * writing of ddr, aliged with 256
     */
-   if (fmt->fmt_type == CIF_FMT_TYPE_RAW && stream->is_compact) {
+   if (fmt->fmt_type == CIF_FMT_TYPE_RAW && stream->is_compact &&
+      fmt->csi_fmt_val != CSI_WRDDR_TYPE_RGB888) {
       *crop_vwidth = ALIGN(raw_width * fmt->raw_bpp / 8, 256);
    } else {
-      if (fmt->fmt_type == CIF_FMT_TYPE_RAW)
-         *crop_vwidth = ALIGN(raw_width * 2, 8);
-      else
-         *crop_vwidth = ALIGN(raw_width * fmt->bpp[0] / 8, 8);

+      *crop_vwidth = ALIGN(raw_width * fmt->bpp[0] / 8, 8);
    }
if (channel->fmt_val == CSI_WRDDR_TYPE_RGB888)

rk628-dsi по умолчанию выводит command mode; приём CIF также должен использовать command mode. Изменения:

diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c

index 36bd2c99c707..fc4181daed2c 100644
--- a/drivers/media/platform/rockchip/cif/capture.c
+++ b/drivers/media/platform/rockchip/cif/capture.c
@@ -1753,7 +1753,7 @@ static int rkcif_csi_channel_init(struct rkcif_stream
*stream,

      channel->fmt_val = stream->cif_fmt_out->csi_fmt_val;

-     channel->cmd_mode_en = 0; /* default use DSI Video Mode */
+     channel->cmd_mode_en = 1; /* default use DSI Video Mode */

      if (stream->crop_enable) {
           channel->crop_en = 1;

Подключение к подсистеме camera

Ведущие RK356X могут использовать только camera, которая не передаёт RGB напрямую на дисплей. Добавьте библиотеку rgb2yuv.

Добавьте следующую библиотеку rgb2yuv в CameraHal. Для SDK Android 11-R9 примените rk356x_HAL3_support_rgb2yuv_patch.rar напрямую.

Для R10 или R11 сначала внесите следующее изменение в hardware/rockchip/camera, затем примените указанный патч.

diff --git a/psl/rkisp2/RKISP2GraphConfig.cpp b/psl/rkisp2/RKISP2GraphConfig.cpp
index 2a5fa5a..3d2409c 100755
--- a/psl/rkisp2/RKISP2GraphConfig.cpp

+++ b/psl/rkisp2/RKISP2GraphConfig.cpp
@@ -76,6 +76,7 @@ const string MEDIACTL_POSTVIEWNAME = "postview";

 const string MEDIACTL_STATNAME = "rkisp1-statistics";
 const string MEDIACTL_VIDEONAME_CIF = "stream_cif_dvp_id0";
+const string MEDIACTL_VIDEONAME_CIF_MIPI_ID0 = "stream_cif_mipi_id0";

 RKISP2GraphConfig::RKISP2GraphConfig() :
      mManager(nullptr),
@@ -2620,6 +2621,13 @@ status_t RKISP2GraphConfig::getImguMediaCtlConfig(int32_t
cameraId,
            addLinkParams("rkisp-isp-subdev", 2, "rkisp_mainpath", 0, 1,

MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
            addLinkParams("rkisp-isp-subdev", 2, "rkisp_selfpath", 0, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
         }
+     } else if(mipName2.find("mipi") != std::string::npos) {
+        addLinkParams(mipName, mipSrcPad, mipName2, csiSinkPad, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
+        addLinkParams(mipName2, 1, "stream_cif_mipi_id0", 0, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
+        addLinkParams(mipName2, 2, "stream_cif_mipi_id1", 0, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
+        addLinkParams(mipName2, 3, "stream_cif_mipi_id2", 0, 1,

MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
+        addLinkParams(mipName2, 4, "stream_cif_mipi_id3", 0, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
+        mSensorLinkedToCIF = true;
      } else {
         addLinkParams(mipName, mipSrcPad, csiName, csiSinkPad, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
         addLinkParams(csiName, csiSrcPad, IspName, ispSinkPad, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
@@ -2628,6 +2636,12 @@ status_t RKISP2GraphConfig::getImguMediaCtlConfig(int32_t
cameraId,
         addLinkParams(csiName, 5, "rkisp_rawwr3", 0, 1,

MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
      }
   }
+  if(mSensorLinkedToCIF){
+     addImguVideoNode(IMGU_NODE_VIDEO, MEDIACTL_VIDEONAME_CIF_MIPI_ID0,
mediaCtlConfig);
+     addFormatParams(MEDIACTL_VIDEONAME_CIF_MIPI_ID0, mCurSensorFormat.width,
mCurSensorFormat.height,
+           0, V4L2_PIX_FMT_NV12, 0, 0, mediaCtlConfig);
+     return OK;
+  }
   // isp input pad format and selection config
   addFormatParams(IspName, ispInWidth, ispInHeight, ispSinkPad, ispInFormat,

0, 0, mediaCtlConfig);
   addSelectionParams(IspName, ispInWidth, ispInHeight, 0, 0,
V4L2_SEL_TGT_CROP, ispSinkPad, mediaCtlConfig);

Этот патч применим только к RK3568+ANDROID11.

Подключение к подсистеме TV

С RK3588 или RK3576 тракт HDMI-to-DSI может использовать TV для прямого вывода RGB888 без библиотеки rgb2yuv. См. адаптацию APK ниже.

6.3.4.2 RK628F/H

RK628F/H устраняет отклонения цвета RK628D, вызванные преобразованием/понижением дискретизации разных входных форматов.

Для приложений с высокими требованиями к качеству RK628F/H может выводить RGB888 через DSI. Ведущие вроде RK3588 принимают RGB888 и выводят через TV без преобразования цвета, сохраняя качество согласно оригиналу. RK628F/H имеет два MIPI-DSI и поддерживает подключение к RK3588 через два MIPI.

Пример RK3588 + RK628F/H с двумя MIPI:

Достаточно изменить compatible на значение DSI.

......
&i2c3 {

   status = "okay";
   clock-frequency = <400000>;
   rk628_csi: rk628_csi@50 {
      reg = <0x50>;

      compatible = "rockchip,rk628-dsi-v4l2";
      status = "okay";
      power-domains = <&power RK3588_PD_VI>;
      pinctrl-names = "default";
      pinctrl-0 = <&rk628_pin>;
      interrupt-parent = <&gpio1>;
      interrupts = <RK_PB2 IRQ_TYPE_LEVEL_HIGH>;
      enable-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>;
      reset-gpios = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>;
      plugin-det-gpios = <&gpio2 RK_PB6 GPIO_ACTIVE_LOW>;

      rockchip,camera-module-index = <0>;

      rockchip,camera-module-facing = "back";
      rockchip,camera-module-name = "HDMI-MIPI2";
      rockchip,camera-module-lens-name = "RK628-CSI";

      multi-dev-info {
         dev-idx-l = <2>;
         dev-idx-r = <4>;
         combine-idx = <2>;
         pixel-offset = <0>;
         dev-num = <2>;
      };

      port {

         hdmiin_out1: endpoint {
           remote-endpoint = <&hdmi_mipi2_in>;
           data-lanes = <1 2 3 4>;
         };
      };
   };
};
......

6.3.5 Преобразование HDMI2BT1120

Настройка HDMI2BT1120 в основном одинакова для RK628D и RK628F/H, поэтому повторно не описывается.

Пример RK3568 + BT1120_V4L2:

&i2c4 {
   pinctrl-names = "default";
   pinctrl-0 = <&i2c4m1_xfer>;

   clock-frequency = <400000>;
   status = "okay";

   rk628_bt1120: rk628_bt1120@50 {
      compatible = "rockchip,rk628-bt1120-v4l2";
      reg = <0x50>;
      status = "disabled";
      pinctrl-names = "default";
      pinctrl-0 = <&cif_dvp_clk &cif_dvp_bus16 &cif_dvp_bus8>;
      interrupt-parent = <&gpio2>;
      interrupts = <15 IRQ_TYPE_LEVEL_HIGH>;

      enable-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
      reset-gpios = <&gpio2 RK_PB0 GPIO_ACTIVE_LOW>;
      plugin-det-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>;
      rockchip,camera-module-index = <0>;
      rockchip,camera-module-facing = "back";
      rockchip,camera-module-name = "RK628-BT1120";
      rockchip,camera-module-lens-name = "NC";
      dual-edge = <1>;

      port {
         lt8619c_out: endpoint {
           remote-endpoint = <&cif_para_in>;

           bus-width = <16>;
           pclk-sample = <1>;
         };
      };
   };
};

&rkcif_dvp {
   status = "okay";

   port {
      /* Parallel bus endpoint */
      cif_para_in: endpoint {

         remote-endpoint = <&lt8619c_out>;
      };
   };
};

&rkcif {
   status = "okay";
};

&rkcif_mmu {
   status = "okay";
};

6.4 Включение HDCP

HDMIRX RK628 поддерживает HDCP1.4. По умолчанию HDCP отключён; при необходимости включите:

1. Включите HDCP в узле RK628 DTS.

           reset-gpios = <&gpio7 RK_PB4 GPIO_ACTIVE_LOW>;
           plugin-det-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;

           power-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+          hdcp-enable = <1>;

2. Запишите ключ HDCP RX.

Ключи HDCP необходимо приобрести у ассоциации HDCP; Rockchip их не предоставляет. В оригинале различаются TX и “RK Key” и требуется “RK Key”. Это обозначение противоречит заголовку RX и сохранено как вопрос к оригиналу, а не исправлено молча.

Получив исходный файл ключей, разделите их KeyConverter и преобразуйте в файлы .skf для записи; следуйте руководству инструмента.

Запишите .skf через RKDevInfoWriteTool, который шифрует ключ. См. руководство инструмента.

6.5 Включение scaler

Некоторые ведущие не принимают MIPI 4K, хотя HDMI IN RK628 принимает 4K. Для вывода CSI 1080P независимо от входного разрешения добавьте настройку DTS:

           reset-gpios = <&gpio7 RK_PB4 GPIO_ACTIVE_LOW>;
           plugin-det-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
           power-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;

+          scaler-en = <1>;

6.6 CSI с двумя линиями

По умолчанию CSI использует 4 линии:

csi->csi_lanes_in_use = USE_4_LANES;

Для 2 линий задайте csi->csi_lanes_in_use равным 2.

6.7 Непрерывный и прерывистый режимы MIPI

Для непрерывного режима MIPI настройте DTS:

continues-clk = <1>;

6.8 Настройка двух MIPI (только RK628F/H)

Скорость MIPI DPHY ограничивает RK628F/H до 4K30 на одном интерфейсе MIPI. RK628F/H имеет два MIPI-CSI. С ведущими вроде RK3588/RK3562 с несколькими CSI-входами разделите 4K60 на левую и правую половины, передайте по двум четырёхлинейным MIPI-CSI и объедините в 4K60 на хосте.

По оригиналу ведущие вроде RK3588 объединяют изображения непосредственно в драйвере VI без дополнительной задержки и нагрузки. Это утверждение источника, а не измерение ArmSoM.

6.8.1 Режим split двух MIPI

RK628F/H может внутри разделить изображение HDMIRX на левую и правую половины и передать каждую через отдельный CSI:

Оригинальный технический рисунок — EN V2.3, p72

Оригинальный технический рисунок: EN V2.3, p72.

Это позволяет ведущим с несколькими MIPI, например RK3588, принимать 4K60 через два MIPI. Функциональная схема ниже.

Оригинальный технический рисунок — EN V2.3, p72

Оригинальный технический рисунок: EN V2.3, p72.

6.8.2 Настройка двух MIPI

Ниже настраиваются два MIPI RK628F/H с RK3588 для 4K60 HDMI-IN.

Отладка двух MIPI с Rockchip SoC описана в Rockchip_RK3588_HDMI_To_CSI_Dual_Mipi_Developer_Guide в RKDocs/common/camera/HAL3 SDK.

6.8.2.1 Настройка RK628F/H

Драйвер RK628F/H поддерживает два MIPI и по умолчанию использует два CSI для 4K60 HDMI-IN. Поля multi-dev-info в DTS:

dev-idx-l: индекс MIPI для левой половины изображения.

dev-idx-r: индекс MIPI для правой половины изображения.

combine-idx: индекс, в который объединяются половины изображения; тракт DTS задаётся по этому индексу.

pixel-offset: смещение пикселей, по умолчанию 0.

dev-num: число объединяемых устройств MIPI.

Пример: CSI0/1 RK628F/H подключены к CSI0/1 RX RK3588:

&i2c3 {
   status = "okay";

   clock-frequency = <400000>;

   rk628_csi: rk628_csi@50 {
      reg = <0x50>;
      compatible = "rockchip,rk628-csi-v4l2";
      status = "okay";
      power-domains = <&power RK3588_PD_VI>;
      pinctrl-names = "default";
      pinctrl-0 = <&rk628_pin>;
      interrupt-parent = <&gpio1>;
      interrupts = <RK_PB2 IRQ_TYPE_LEVEL_HIGH>;
      enable-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>;
      reset-gpios = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>;

      plugin-det-gpios = <&gpio2 RK_PB6 GPIO_ACTIVE_LOW>;
      continues-clk = <1>;

      rockchip,camera-module-index = <0>;
      rockchip,camera-module-facing = "back";
      rockchip,camera-module-name = "HDMI-MIPI2";
      rockchip,camera-module-lens-name = "RK628-CSI";

      multi-dev-info {
         dev-idx-l = <2>;
         dev-idx-r = <4>;
         combine-idx = <2>;

         pixel-offset = <0>;
         dev-num = <2>;
      };

      port {
         hdmiin_out1: endpoint {
           remote-endpoint = <&hdmi_mipi2_in>;
           data-lanes = <1 2 3 4>;
         };
      };
   };
};
6.8.2.2 Требования к драйверу ведущей SoC

В оригинале поддержка двух MIPI указана для RK3588/RK3562/RK3576 и поколения kernel-5.10 и последующего кода. Требуется достаточно новый код ведущей SoC; оригинал рекомендует обновить SDK Android 12/13. Обновление только драйвера kernel-

5.10 RK628 может привести к ошибке сборки, если остальной SDK слишком стар для двух MIPI. Обновите SDK либо обратитесь к инженерам Rockchip через Redmine.

6.9 Возможности приёма разных микросхем

Максимальные возможности приёма зависят от производительности ISP/VICAP платформы. См. таблицу:

Платформа SoC Контроллер приёма Максимальное разрешение
RK3288/RK3326/RK3368 isp 1920x1080P60
RK3399 isp 3840x2160P30 (нужен разгон isp)
RK3566/RK3568 vicap/isp 3840x2160P30 (при подключении ISP максимум 1080P60)
RK3588/RK3562/RK3576 vicap 3840x2160P60 (два MIPI)

6.9.1 Настройка повышения частоты ISP

Задайте PLL_NPLL RK3399 как 650M:

--- a/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi
@@ -148,7 +148,7 @@

                  <50000000>, <100000000>,
                  <75000000>, <75000000>,
                  <816000000>, <816000000>,
-                 <600000000>, <200000000>,
+                 <650000000>, <200000000>,
                  <800000000>, <150000000>,
                  <75000000>, <37500000>,
                  <300000000>, <100000000>,

Измените максимальную поддерживаемую частоту ISP RK3399 на 650M:

--- a/drivers/media/platform/rockchip/isp1/dev.c
+++ b/drivers/media/platform/rockchip/isp1/dev.c
@@ -757,7 +757,7 @@ static const unsigned int rk3368_isp_clk_rate[] = {


 /* isp clock adjustment table (MHz) */
 static const unsigned int rk3399_isp_clk_rate[] = {
-     300, 400, 600
+     300, 400, 650
 };

 static struct isp_irqs_data rk1808_isp_irqs[] = {

При периодических ошибках ISP RK3288 также можно попробовать повысить частоту ISP. Обычно достаточно оставить только максимальную частоту. Изменение предназначено только для диагностики.

--- a/drivers/media/platform/rockchip/isp1/dev.c
+++ b/drivers/media/platform/rockchip/isp1/dev.c
@@ -849,7 +849,7 @@ static const unsigned int rk1808_isp_clk_rate[] = {


 /* isp clock adjustment table (MHz) */
static const unsigned int rk3288_isp_clk_rate[] = {
-     150, 384, 500, 594
+     594
 };

Настройте частоту ISP в драйвере преобразователя.

#define RK628_CSI_PIXEL_RATE_HIGH 600000000
...


static int rk628_csi_set_fmt(struct v4l2_subdev *sd,
           struct v4l2_subdev_pad_config *cfg,
           struct v4l2_subdev_format *format)
{
...
      if ((mode->width == 3840) && (mode->height == 2160)) {
           v4l2_dbg(1, debug, sd,
                 "%s res wxh:%dx%d, link freq:%llu, pixrate:%u\n",
                 __func__, mode->width, mode->height,
                 link_freq_menu_items[1], RK628_CSI_PIXEL_RATE_HIGH);
           __v4l2_ctrl_s_ctrl(csi->link_freq, 1);
           __v4l2_ctrl_s_ctrl_int64(csi->pixel_rate,

                 RK628_CSI_PIXEL_RATE_HIGH);
      }
...
}

Драйвер ISP добавляет 25% запаса к заданной частоте, поэтому задайте подходящее RK628_CSI_PIXEL_RATE_HIGH в драйвере.

drivers/media/platform/rockchip/isp1/dev.c

static int __isp_pipeline_s_isp_clk(struct rkisp1_pipeline *p)

{
...
      ctrl = v4l2_ctrl_find(sd->ctrl_handler, V4L2_CID_PIXEL_RATE);
      if (!ctrl) {
           v4l2_warn(sd, "No pixel rate control in subdev\n");
           return -EPIPE;
      }

      /* calculate data rate */
      data_rate = v4l2_ctrl_g_ctrl_int64(ctrl) *
              dev->isp_sdev.in_fmt.bus_width;
      data_rate >>= 3;
      do_div(data_rate, 1000 * 1000);


      /* increase 25% margin */
      data_rate += data_rate >> 2;
...
}

6.9.2 Настройка памяти CMA для ISP

На некоторых платформах нагрузка системы может вызвать нехватку пропускной способности при HDMI IN, пропуски кадров или ошибки MIPI. Пример журнала:

[ 228.999567] rkisp1: MIPI mis error: 0x00800000
[ 228.999925] rkisp1: CIF_ISP_PIC_SIZE_ERROR (0x00000001)
[ 228.999976] rkisp1: CIF_ISP_PIC_SIZE_ERROR (0x00000001)rkisp1:

CIF_ISP_PIC_SIZE_ERROR (0x00000001)
[ 229.000081] rkisp1: CIF_ISP_PIC_SIZE_ERROR (0x00000001)rkisp1:
CIF_ISP_PIC_SIZE_ERROR (0x00000001)
[ 229.000187] rkisp1: CIF_ISP_PIC_SIZE_ERROR (0x00000001)rkisp1:
CIF_ISP_PIC_SIZE_ERROR (0x00000001)
[ 229.000294] rkisp1: CIF_ISP_PIC_SIZE_ERROR (0x00000001)rkisp1:
CIF_ISP_PIC_SIZE_ERROR (0x00000001)

Повысьте частоту DDR. Если это не помогает, зарезервируйте память CMA для ISP:

Зарезервируйте 128MB CMA в rockchip_defconfig.

CONFIG_CMA=y
CONFIG_CMA_SIZE_MBYTES=128

Отключите IOMMU ISP в DTS и используйте CMA.

&isp_mmu {
      status = "disabled";

};

6.10 Настройка EDID

RK628 поддерживает настройку EDID. Драйвер оригинала объявляет распространённые разрешения:

3840x2160P60, 3840x2160P30, 1920x1080P60, 1920x1080P30, 1280x720P60, 720x576P50 и 720x480P60. Для изменения поддерживаемых разрешений отредактируйте EDID непосредственно в драйвере:

static u8 rk628f_edid_init_data[] = {
   0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
   0x24, 0xD0, 0x8F, 0x62, 0x01, 0x00, 0x00, 0x00,

   0x2D, 0x21, 0x01, 0x03, 0x80, 0x78, 0x44, 0x78,
   0x0A, 0xCF, 0x74, 0xA3, 0x57, 0x4C, 0xB0, 0x23,
   0x09, 0x48, 0x4C, 0x21, 0x08, 0x00, 0x61, 0x40,
   0x01, 0x01, 0x81, 0x00, 0x95, 0x00, 0xA9, 0xC0,
   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0xE8,
   0x00, 0x30, 0xF2, 0x70, 0x5A, 0x80, 0xB0, 0x58,
   0x8A, 0x00, 0xC4, 0x8E, 0x21, 0x00, 0x00, 0x1E,
   0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40,
   0x58, 0x2C, 0x45, 0x00, 0xB9, 0xA8, 0x42, 0x00,
   0x00, 0x1E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x49,
   0x46, 0x50, 0x20, 0x44, 0x69, 0x73, 0x70, 0x6C,

   0x61, 0x79, 0x0A, 0x20, 0x00, 0x00, 0x00, 0xFD,
   0x00, 0x3B, 0x46, 0x1F, 0x8C, 0x3C, 0x00, 0x0A,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xA8,

   0x02, 0x03, 0x39, 0xF2, 0x4D, 0x01, 0x03, 0x12,
   0x13, 0x84, 0x22, 0x1F, 0x90, 0x5D, 0x5E, 0x5F,
   0x60, 0x61, 0x23, 0x09, 0x07, 0x07, 0x83, 0x01,
   0x00, 0x00, 0x6D, 0x03, 0x0C, 0x00, 0x10, 0x00,
   0x00, 0x44, 0x20, 0x00, 0x60, 0x03, 0x02, 0x01,
   0x67, 0xD8, 0x5D, 0xC4, 0x01, 0x78, 0xC0, 0x00,
   0xE3, 0x05, 0x03, 0x01, 0xE4, 0x0F, 0x00, 0x18,
   0x00, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D,

   0x40, 0x58, 0x2C, 0x45, 0x00, 0xB9, 0xA8, 0x42,
   0x00, 0x00, 0x1E, 0x08, 0xE8, 0x00, 0x30, 0xF2,
   0x70, 0x5A, 0x80, 0xB0, 0x58, 0x8A, 0x00, 0xC4,
   0x8E, 0x21, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93,
};

Оригинал рекомендует этот редактор EDID (историческая ссылка, актуальность загрузки не подтверждена): http://www.quantumdata.com/support/downloads/980/release_5_05/R_980mgr_5.05_Win32.msi

6.11 Настройка camera3_profiles.xml

Для предпросмотра через camera необходимо адаптировать camera3_profiles.xml и зарегистрировать камеру.

camera3_profiles.xml находится в каталоге SDK соответствующей микросхемы:

hardware/rockchip/camera/etc/camera/camera3_profiles_rk3xxx.xml

Основные настройки приведены ниже. Подробнее см. настройку SoC Sensor.

name: должен совпадать с именем драйвера с учётом регистра.

moduleId: должен совпадать с index в DTS драйвера.

Оригинальный технический рисунок — EN V2.3, p78

Оригинальный технический рисунок: EN V2.3, p78.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

</Profiles>
<Profiles cameraId="0" name="rk628-csi" moduleId="m00">
    <Supported_hardware>
        <hwType value="SUPPORTED_HW_RKISP1"/>

Оригинальный технический рисунок — EN V2.3, p78

Оригинальный технический рисунок: EN V2.3, p78.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

&rk628_csi {
    status = "okay";
    /*
     * If the hpd output level is inverted on the circuit,
     * the following configuration needs to be enabled.
     */
    /* hpd-output-inverted; */
    plugin-det-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
    power-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
    rockchip,camera-module-index = <0>;
    rockchip,camera-module-facing = "back";
    rockchip,camera-module-name = "RK628-CSI";
    rockchip,camera-module-lens-name = "NC";

scaler.availableStreamConfigurations/scaler.availableMinFrameDurations/scaler.availableStallDurations: правильно задайте поддерживаемые разрешения и минимальные межкадровые интервалы. При добавлении разрешения в драйвер добавьте соответствующие записи здесь.

Оригинальный технический рисунок — EN V2.3, p79

Оригинальный технический рисунок: EN V2.3, p79.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

<scaler.availableStreamConfigurations value="BLOB,3840x2160,OUTPUT,
    BLOB,1920x1080,OUTPUT,
    BLOB,1280x720,OUTPUT,
    BLOB,720x576,OUTPUT,
    BLOB,720x480,OUTPUT,
    YCbCr_420_888,3840x2160,OUTPUT,
    YCbCr_420_888,1920x1080,OUTPUT,
    YCbCr_420_888,1280x720,OUTPUT,
    YCbCr_420_888,720x576,OUTPUT,
    YCbCr_420_888,720x480,OUTPUT,
    IMPLEMENTATION_DEFINED,3840x2160,OUTPUT,
    IMPLEMENTATION_DEFINED,1920x1080,OUTPUT,
    IMPLEMENTATION_DEFINED,1280x720,OUTPUT,
    IMPLEMENTATION_DEFINED,720x576,OUTPUT,
    IMPLEMENTATION_DEFINED,720x480,OUTPUT" />
<scaler.availableMinFrameDurations value="BLOB,3840x2160,33333333,
    BLOB,1920x1080,16666667,
    BLOB,1280x720,16666667,
    BLOB,720x576,20000000,
    BLOB,720x480,16666667,
    YCbCr_420_888,3840x2160,33333333,
    YCbCr_420_888,1920x1080,16666667,
    YCbCr_420_888,1280x720,16666667,
    YCbCr_420_888,720x576,20000000,
    YCbCr_420_888,720x480,16666667,
    IMPLEMENTATION_DEFINED,3840x2160,33333333,
    IMPLEMENTATION_DEFINED,1920x1080,16666667,
    IMPLEMENTATION_DEFINED,1280x720,16666667,
    IMPLEMENTATION_DEFINED,720x576,20000000,
    IMPLEMENTATION_DEFINED,720x480,16666667"/>
<scaler.availableStallDurations value="BLOB,3840x2160,33333333,
    BLOB,1920x1080,16666667,
    BLOB,1280x720,16666667,
    BLOB,720x576,20000000,
    BLOB,720x480,16666667"/>

sensor.orientation: поворот изображения; поддерживает 0, 90, 180 и 270.

Оригинальный технический рисунок — EN V2.3, p79

Оригинальный технический рисунок: EN V2.3, p79.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

<sensor.maxAnalogSensitivity value="2400"/>
<sensor.orientation value="0"/>
<sensor.profileHueSatMapDimensions value="0,0,0"/>

6.12 Адаптация APK HDMI IN

6.12.1 Android 9/10/11

Android 9/10/11 использует kernel-4.4/kernel-4.19 и пакет патчей for-all. Доступна только cameraHAL3.

6.12.1.1 Получение и сборка исходников APK

Исходники APK находятся в следующем каталоге SDK:

RKDocs/common/hdmi-in/apk/rkCamera2_based_on_CameraHal3_V1.3.tar.gz

Скопируйте и распакуйте исходники в:

packages/apps/

Для RK3288 измените device/rockchip/rk3288/ следующим образом для сборки rkCamera2:

diff --git a/device.mk b/device.mk
index 6667b5c..96f08f1 100644

--- a/device.mk
+++ b/device.mk
@@ -17,7 +17,8 @@
 PRODUCT_PACKAGES += \
   memtrack.$(TARGET_BOARD_PLATFORM) \
   WallpaperPicker \
-  Launcher3
+  Launcher3 \
+  rkCamera2

 #$_rbox_$_modify_$_zhengyang: add displayd
 PRODUCT_PACKAGES += \
6.12.1.2 Адаптация исходников APK

APK обращается к узлу RK628 через ioctl для получения состояния подключения и разрешения. Узел может различаться для isp1/isp2/vicap. Адаптируйте исходники APK к фактическому узлу; способ его определения см. в примерах команд отладки.

rkCamera2/jni/native.cpp

Оригинальный технический рисунок — EN V2.3, p81

Оригинальный технический рисунок: EN V2.3, p81.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

static void openDevice(JNIEnv *env, jobject thiz)
{
    (void)*env;
    (void)thiz;

    char video_name[64];
    memset(video_name, 0, sizeof(video_name));
    strcat(video_name, "/dev/v4l-subdev2");

    camFd = open(video_name, O_RDWR);
    if (camFd < 0) {
        LOGE("open %s failed,erro=%s",video_name,strerror(errno));
    } else {
        LOGD("open %s success,fd=%d",video_name,camFd);
    }
}

Код получения состояния подключения и разрешения:

Оригинальный технический рисунок — EN V2.3, p81

Оригинальный технический рисунок: EN V2.3, p81.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

static void getDeviceFormat(int *format)
{
    struct v4l2_control control;
    memset(&control, 0, sizeof(struct v4l2_control));
    control.id = V4L2_CID_DV_RX_POWER_PRESENT;
    int err = ioctl(camFd, VIDIOC_G_CTRL, &control);
    if (err < 0) {
        LOGV("Set POWER_PRESENT failed ,%d(%s)", errno, strerror(errno));
    }

    unsigned int noSignalAndSync = 0;
    ioctl(camFd, VIDIOC_G_INPUT, &noSignalAndSync);
    LOGV("noSignalAndSync ? %s",noSignalAndSync?"YES":"NO");

    struct v4l2_dv_timings dv_timings;
    memset(&dv_timings, 0 ,sizeof(struct v4l2_dv_timings));
    err = ioctl(camFd, VIDIOC_SUBDEV_QUERY_DV_TIMINGS, &dv_timings);
    if (err < 0) {
        LOGV("Set VIDIOC_SUBDEV_QUERY_DV_TIMINGS failed ,%d(%s)", errno, strerror(errno));
    }

    format[0] = dv_timings.bt.width;
    format[1] = dv_timings.bt.height;
    format[2] = control.value && !noSignalAndSync;
}

Поскольку APK обращается к узлу устройства, оригинал предлагает проверить отключение SELinux командой getenforce. Это инструкция отладки оригинала, а не рекомендация по безопасности рабочей системы:

Оригинальный технический рисунок — EN V2.3, p81

Оригинальный технический рисунок: EN V2.3, p81.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

rk3288:/ # getenforce
Enforcing
rk3288:/ # setenforce 0
rk3288:/ #
rk3288:/ # getenforce
Permissive
6.12.1.3 Подготовка к отладке APK

Сначала завершите отладку драйвера (см. соответствующий раздел). Затем проверьте регистрацию камеры в CameraHal следующей командой. При ошибке регистрации проверьте camera3_profiles.xml по разделу его настройки.

Оригинальный технический рисунок — EN V2.3, p82

Оригинальный технический рисунок: EN V2.3, p82.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

rk3288:/ #
rk3288:/ # dumpsys media.camera

== Service global info: ==

Number of camera devices: 1
Number of normal camera devices: 1
    Device 0 maps to "0"
Active Camera Clients:
[]
Allowed user IDs: 0

== Camera service events log (most recent at top): ==
  04-08 11:08:31 : USER_SWITCH previous allowed user IDs: <None>, current allowed user IDs: 0
  01-18 08:50:15 : ADD device 0, reason: (Device status changed from 0 to 1)
  01-18 08:50:15 : ADD device 0, reason: (Device added)

6.12.2 Android 12+

Android 12/13 использует kernel-5.10 и соответствующий пакет патчей драйвера. Приложения используют camera либо TV (далее также TIF). Отладка описана в Rockchip_Android12+_HDMI_TO_MIPI_Developer_Guide.

Android14 использует kernel-6.1; драйвер включён в SDK. Оригинал рекомендует подсистему TV.

6.12.2.1 Исходники APK

packages/apps/TV/partner_support/samples: служба данных источника TV, взаимодействующая через framework с HAL и APK предпросмотра. Это скрытая служба, запускаемая при загрузке; значок APK в launcher скрыт.

hardware/rockchip/tv_input: код TVHAL, обменивающийся с драйвером командами запуска/остановки потока, горячего подключения и смены разрешения.

hardware/rockchip/camera: код cameraHAL, реализующий получение потока, фотосъёмку и другие функции камеры.

vendor/rockchip/hardware/interfaces/hdmi: используется camera; отслеживает изменения разрешения и горячее подключение, взаимодействует с драйвером и APK.

packages/apps/rkCamera2: APK предпросмотра с двумя экранами. MainActivity по умолчанию использует TIF и взаимодействует со службой источника TV через framework. RockchipCamera2 использует Camera и стандартный Camera API для открытия cameraid узла MIPI. Значок приложения называется HdmiIn. Заказчики обычно заменяют его собственным APK предпросмотра.

В SDK по умолчанию HDMI IN отключён. Задайте следующее свойство для включения и сборки соответствующих модулей, включая указанные APK:

vim device/rockchip/rk3588/BoardConfig.mk
BOARD_HDMI_IN_SUPPORT := true

Для camera включите:

vim device/rockchip/rk3588/BoardConfig.mk
CAMERA_SUPPORT_HDMI := true

Если задан только CAMERA_SUPPORT_HDMI без BOARD_HDMI_IN_SUPPORT, для предпросмотра rkCamera2 через camera добавьте rkCamera2 в сборку и задайте persist.sys.hdmiinmode равным 2. Дополнительно см.:

Rockchip_Developer_Guide_HDMI_RX_CN

PRODUCT_PACKAGES += \
   rkCamera2
6.12.2.2 Предпросмотр APK

APK поддерживает предпросмотр тракта HDMI RX RK3588 либо HDMI-to-MIPI-CSI; выберите нужный тракт.

Для предпросмотра TIF выберите тракт MIPI-CSI2:

setprop vendor.tvinput.hdmiin.type 1

Для предпросмотра camera откройте RockchipCamera2 и убедитесь, что CAMERA_SUPPORT_HDMI включён.

setprop persist.sys.hdmiinmode 2
6.12.2.3 Различия предпросмотра TIF и camera
  TIF Camera
Преимущества Низкая задержка Приложение получает данные предпросмотра для постобработки
Недостатки Не поддерживаются поворот, разделение экрана и картинка в картинке; приложение не получает данные буфера предпросмотра; команды снимка screencap не поддерживаются Задержка выше, чем у TIF

6.13 Типичные методы отладки драйвера

Отладка драйвера выполняется как для SoC Sensor. Дополнительная информация приведена в документе Redmine:

https://redmine.rock-chips.com/documents/53

6.13.1 Получение инструментов отладки

Требуются media-ctl и v4l2-ctl. Описанный SDK автоматически включает их в прошивку при сборке; каталог в SDK:

hardware/rockchip/camera/etc/tools/

Для старых SDK получите их через Redmine:

https://redmine.rock-chips.com/documents/104

Скопируйте media-ctl и v4l2-ctl в /vendor/bin/ устройства через adb push.

6.13.2 Примеры команд отладки

Пример использует RK3288 + RK628 с приёмом 1920x1080P. Адаптируйте его к реальной системе. Вводите команды по порядку: пропуск предварительной настройки может привести к неработоспособности.

Просмотр топологии связей:

Просмотрите топологию media-узла командой. В зависимости от платформы и соединений это /dev/media0 или /dev/media1.

media-ctl -d /dev/media0 –p

В фрагменте RK628 устройство — /dev/v4l-subdev2, обнаруженное разрешение HDMI IN — 1920x1080.

...
- entity 8: m00_b_rk628-csi rk628-csi (1 pad, 1 link)
         type V4L2 subdev subtype Sensor

         device node name /dev/v4l-subdev2
      pad0: Source
           [fmt:UYVY2X8/1920x1080]
           -> "rockchip-mipi-dphy-rx":0 [ENABLED]
...

Настройка связей:

После сброса и запуска связи по умолчанию включены. Открытие и закрытие HDMI IN APK отключает их. Восстанавливайте связь только при отсутствии [ENABLED] в топологии.

media-ctl -d /dev/media0 -l \
'"m00_b_rk628-csi rk628-csi":0->"rockchip-mipi-dphy-rx":0 [1]'

media-ctl -d /dev/media0 -l \
'"rockchip-mipi-dphy-rx":1->"rkisp1-isp-subdev":0 [1]'
media-ctl -d /dev/media0 -l '"rkisp1-input-params":0->"rkisp1-isp-subdev":1 [1]'
media-ctl -d /dev/media0 -l '"rkisp1-isp-subdev":2->"rkisp1_mainpath":0 [1]'
media-ctl -d /dev/media0 -l '"rkisp1-isp-subdev":2->"rkisp1_selfpath":0 [1]'
media-ctl -d /dev/media0 -l '"rkisp1-isp-subdev":3->"rkisp1-statistics":0 [1]'

Настройка разрешения:

media-ctl -d /dev/media0 \
--set-v4l2 '"rkisp1-isp-subdev":0[fmt:UYVY2X8/1920x1080]'
media-ctl -d /dev/media0 \

--set-v4l2 '"rkisp1-isp-subdev":0[crop:(0,0)/1920x1080]'
media-ctl -d /dev/media0 \
--set-v4l2 '"rkisp1-isp-subdev":2[fmt:UYVY2X8/1920x1080]'
media-ctl -d /dev/media0 \
--set-v4l2 '"rkisp1-isp-subdev":2[crop:(0,0)/1920x1080]'

Получение потока изображения:

Проверка результатов настройки:

media-ctl -d /dev/media0 –p

Получение потока изображения:

v4l2-ctl --verbose -d /dev/video0 --set-fmt-
video=width=1920,height=1080,pixelformat='NV12' --stream-mmap=4

Сохраните YUV-файл, получите его через adb pull и просмотрите, например, в 7yuv:

v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat='NV12'
--stream-mmap=3 --stream-skip=4 --stream-to=/data/1920x1080p60_nv12.yuv --stream-
count=5 --stream-poll

При нормальном приёме данных выводится частота кадров. Пример журнала из оригинала:

VIDIOC_QUERYCAP: ok
VIDIOC_G_FMT: ok
VIDIOC_S_FMT: ok

Format Video Capture Multiplanar:
      Width/Height : 1920/1080
      Pixel Format : 'NV12'
      Field        : None
      Number of planes : 1
      Flags        :
      Colorspace   : Default
      Transfer Function : Default
      YCbCr Encoding : Default
      Quantization : Full Range
      Plane 0      :
        Bytes per Line : 1920
        Size Image : 3110400

VIDIOC_G_SELECTION: ok
VIDIOC_S_SELECTION: ok
VIDIOC_REQBUFS: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok

VIDIOC_STREAMON: ok
idx: 0 seq: 0 bytesused: 3110400 ts: 131.560377
idx: 1 seq: 1 bytesused: 3110400 ts: 131.577023 delta: 16.646 ms
idx: 2 seq: 2 bytesused: 3110400 ts: 131.593697 delta: 16.674 ms
idx: 3 seq: 3 bytesused: 3110400 ts: 131.610363 delta: 16.666 ms
idx: 0 seq: 4 bytesused: 3110400 ts: 131.627033 delta: 16.670 ms fps: 60.01
idx: 1 seq: 5 bytesused: 3110400 ts: 131.643721 delta: 16.688 ms fps: 59.99
idx: 2 seq: 6 bytesused: 3110400 ts: 131.660390 delta: 16.669 ms fps: 59.99
idx: 3 seq: 7 bytesused: 3110400 ts: 131.677058 delta: 16.668 ms fps: 59.99

6.13.3 Включение журналов

Включите журналы RK628 следующей командой, затем получите журнал ядра. Оригинал пишет demsg; проверьте фактическую команду dmesg на целевой системе.

echo 1 > /sys/kernel/debug/rk628/x-0050/debug //x为挂载的i2c总线,50为对应的i2c地址
echo 2 > /sys/module/rk628_csi/parameters/debug
echo 2 > /sys/module/rk628_csi_v4l2/parameters/debug //内核为linux4.4或者4.19

dmesg -n 8

Для журнала включения и загрузки измените код и пересоберите/прошивайте компоненты ядра:

diff --git a/drivers/media/i2c/rk628_csi.c b/drivers/media/i2c/rk628_csi.c
index c763a9558169..bd7f3effb45a 100644
--- a/drivers/media/i2c/rk628_csi_v4l2.c

+++ b/drivers/media/i2c/rk628_csi_v4l2.c
@@ -34,7 +34,7 @@
 #include <video/videomode.h>
 #include "rk628_csi.h"

-static int debug;
+static int debug = 1;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "debug level (0-3)");

diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 1cc0c5ba16b3..e74f3a85f0b8 100644
--- a/include/media/v4l2-common.h

+++ b/include/media/v4l2-common.h
@@ -75,7 +75,7 @@
 #define v4l2_dbg(level, debug, dev, fmt, arg...)   \
      do {                                          \
           if (debug >= (level))                    \
-                v4l2_printk(KERN_DEBUG, dev, fmt , ## arg); \
+                v4l2_printk(KERN_INFO, dev, fmt , ## arg); \
      } while (0)

6.13.4 Чтение и запись регистров

Ниже отладочные узлы регистров RK628. В примере RK628 подключён к I2C3 по адресу 0x50:

console:/ # ls /sys/kernel/debug/rk628/3-0050/registers/
adapter combtxphy csi dsi0 gpio0 gpio2 grf hdmirxphy

combrxphy cru   csi1 dsi1 gpio1 gpio3 hdmirx

Узлы регистров поддерживают чтение и запись.

Чтение регистров:

console:/ # cat /sys/kernel/debug/rk628/3-0050/registers/cru
rk628_cru:


0xc0000: 00001031 00000441 00800000 00000007
0xc0010: 00007f00
0xc0020: 00001028 00000441 00f5c28f 00000007
0xc0030: 00007f00
0xc0040: 00005019 00000541 0099735e 00000007
0xc0050: 00007f00
0xc0060: 00000015
0xc0080: 00008989 00000003 00000007 00004b80
0xc0090: 03355460 000080d7 00008004 0000003b
0xc00a0: 00002c00 00000000 00000000 00000000
0xc00b0: 00285f58 00010008 00010008 00000103
0xc00c0: 00000300 00000703 0000000b 00000008

0xc00d0: 0001000a 00000b07
0xc0180: 00000000 00000000 00000000 00000000
0xc0190: 00000000 00000000
0xc0200: 00000000 00000000 00000000 00000000
0xc0210: 00000000

Запись регистров:

rk3288:/ # echo 0x000 0xffffffff > /sys/kernel/debug/rk628/3-0050/registers/grf

6.13.5 Чтение состояния HDMI-RX

Получите сведения HDMI-RX: разрешение, захват, подключение и цветовой формат, командой:

console:/ # cat /sys/kernel/debug/rk628/3-0050/hdmirx/status
status: plugin

Clk-Ch:Lock Ch0:Lock   Ch1:Lock    Ch2:Lock
Color Format: RGB
Timing: 1920x1080p60 (2200x1125)   hfp:88 hs:45 hbp:147 vfp:4
vs:5 vbp:36
Pixel Clk: 148500000
Mode: HDMI
Color Depth: 8 bit
Color Range: Limited
Color Space: RGB

6.13.6 Вывод тестового изображения

RK628 поддерживает вывод цветовых полос scaler. Команды:

echo 1 > /sys/kernel/debug/rk628/3-0050/scaler_color_bar

//pattern 模式选择

echo 2 > /sys/kernel/debug/rk628/3-0050/scaler_color_bar

6.14 Аудиомодуль

Направление звука определяется использованием HDMIRX или HDMITX. Для HDMIRX принятый звук HDMI распаковывается и выводится через I2S. Для HDMITX I2S RK628D принимает звук, который упаковывается и передаётся через HDMITX. Ниже обе конфигурации:

6.14.1 HDMIRX

HDMIRX обычно инициализирует звук при загрузке драйвера без дополнительной настройки. При воспроизведении звука передатчиком HDMI RK628 выводит его через I2S и должен быть master. I2S RK628 подключается напрямую к DAC или SoC с I2S. Формат I2S:

Оригинальный технический рисунок — EN V2.3, p86

Оригинальный технический рисунок: EN V2.3, p86.

При подключении к SoC дополнительная настройка I2S RK628 не нужна; создайте звуковую карту через dummy_codec:

rk628_dc: rk628-dc {
      compatible = "rockchip,dummy-codec";
      #sound-dai-cells = <0>;

};

hdmiin-sound {
      compatible = "simple-audio-card";
      simple-audio-card,format = "i2s";
      simple-audio-card,name = "rockchip,hdmiin";
      simple-audio-card,bitclock-master = <&dailink0_master>;
      simple-audio-card,frame-master = <&dailink0_master>;
      status = "okay";
      simple-audio-card,cpu {
                 sound-dai = <&i2s0>;
      };

      dailink0_master: simple-audio-card,codec {
                 sound-dai = <&rk628_dc>;
      };
};

При подключении DAC настройка звуковой карты выше не нужна: DAC непосредственно выдаёт аналоговый сигнал. Большинство DAC требует MCLK, который в RK628 не предусмотрен. Обходной способ оригинала использует GPIO1_A0 (H7) как TEST_CLKO с частотой 128FS. Оригинал сообщает о совместимости со многими DAC и проверке CS4344 и ES7144; это не испытания ArmSoM. Для MCLK на GPIO1_A0 вызовите следующий интерфейс инициализации, выбрав драйвер проекта:

--- a/drivers/media/i2c/rk628/rk628_hdmirx.h
+++ b/drivers/media/i2c/rk628/rk628_hdmirx.h
@@ -392,5 +392,5 @@ bool rk628_audio_ctsnints_enabled(HAUDINFO info);
 void rk628_csi_isr_ctsn(HAUDINFO info, u32 pdec_ints);

 void rk628_csi_isr_fifoints(HAUDINFO info, u32 fifo_ints);
 int rk628_is_avi_ready(struct rk628 *rk628, bool avi_rcv_rdy);
+void rk628_hdmirx_audio_set_mclk_output(HAUDINFO info);

--- a/drivers/media/i2c/rk628/rk628_csi.c
+++ b/drivers/media/i2c/rk628/rk628_csi.c
@@ -957,6 +957,9 @@ static void rk628_csi_initial_setup(struct rk628_csi *csi)
 {
      struct v4l2_subdev_edid def_edid;

+     //enable rk628 mclk
+     rk628_hdmirx_audio_set_mclk_output(csi->audio_info);


--- a/drivers/media/i2c/rk628/rk628_csi_v4l2.c
+++ b/drivers/media/i2c/rk628/rk628_csi_v4l2.c
@@ -1096,6 +1096,9 @@ static void rk628_csi_initial_setup(struct v4l2_subdev *sd)
      struct rk628_csi *csi = to_csi(sd);
      struct v4l2_subdev_edid def_edid;

+     //enable rk628 mclk
+     rk628_hdmirx_audio_set_mclk_output(csi->audio_info);

Для RK3288 EVB оригинал указывает подключение RK3288 I2S к RT5651 I2S2 и также RK628 I2S к RT5651 I2S2. Переключение внутренних маршрутов RT5651 выбирает пути записи и воспроизведения. DTS:

hdmiin-sound {
      compatible = "rockchip,rockchip-rt5651-rk628-sound";
      rockchip,cpu = <&i2s>;

      rockchip,codec = <&rt5651>;
      status = "okay";
};

По умолчанию I2S выводит только при предварительном просмотре. Для постоянного вывода добавьте i2s-enable-default в DTS.

&i2c4 {
      clock-frequency = <400000>;
      status = "okay";

      rk628_csi_v4l2: rk628_csi_v4l2@50 {
           reg = <0x50>;
           compatible = "rockchip,rk628-csi-v4l2";
           ....
           i2s-enable-default;
           ....
      };
};

6.14.2 HDMITX

Для HDMITX достаточно настроить звуковую карту HDMI. Здесь I2S RK628 соединён с I2S0 SoC:

hdmi_sound: hdmi-sound {
      compatible = "simple-audio-card";
      simple-audio-card,format = "i2s";

      simple-audio-card,name = "hdmi-sound";
      status = "okay";
      simple-audio-card,cpu {
           sound-dai = <&i2s0>;
      };
      simple-audio-card,codec {
           sound-dai = <&rk628_hdmi>;
      };
};

6.14.3 Диагностика звука

6.14.3.1 Нет вывода I2S
echo 0x000 0x6000220 > /sys/kernel/debug/regmap/0-0050-grf/registers //i2s 的
IOMUX

echo 0x70 0xfffff55c > /sys/kernel/debug/regmap/0-0050-grf/registers
echo 0x70 0x155c155c > /sys/kernel/debug/regmap/0-0050-grf/registers // 设置输出
6.14.3.2 Включение вывода v4l2_dbg
diff --git a/drivers/media/i2c/rk628_csi.c b/drivers/media/i2c/rk628_csi.c
index 5e8e3710a82f..638ac2acc472 100644

--- a/drivers/media/i2c/rk628_csi.c
+++ b/drivers/media/i2c/rk628_csi.c
@@ -34,7 +34,7 @@
 #include <video/videomode.h>
 #include "rk628_csi.h"

-static int debug;
+static int debug = 3;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "debug level (0-3)");

diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index cdc87ec61e54..f159118d4a6b 100644

--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -82,7 +82,7 @@
 #define v4l2_dbg(level, debug, dev, fmt, arg...)   \
      do {                                          \
           if (debug >= (level))                    \
-                v4l2_printk(KERN_DEBUG, dev, fmt , ## arg); \
+                v4l2_printk(KERN_INFO, dev, fmt , ## arg); \
      } while (0)


 /**
6.14.3.3 Шум в записи приложения

Причиной может быть несовпадение частоты дискретизации передатчика HDMI и записи HAL.

(1) Проверьте частоту дискретизации HDMITX.

Включите журнал ядра: echo 3 > /sys/module/rk628_csi/parameters/debug

(2) После включения определите частоту дискретизации TX по выводу ниже.

m00_b_rk628-csi rk628-csi: rk628_hdmirx_audio_fs: clkrate:1500 tmdsclk:74250000,
n_decoded:6144, cts_decoded:74250, fs_audio:48000

m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:
HDMI_RX_AUD_FIFO_FILLSTS1:0xfe, single offset:0, total offset:-2
m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:
HDMI_RX_AUD_FIFO_ISTS:0x4
m00_b_rk628-csi rk628-csi: rk628_hdmirx_audio_fs: clkrate:1500 tmdsclk:74250000,
n_decoded:6144, cts_decoded:74250, fs_audio:48000
m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:
HDMI_RX_AUD_FIFO_FILLSTS1:0xfc, single offset:-2, total offset:-4
m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:
HDMI_RX_AUD_FIFO_ISTS:0x4
m00_b_rk628-csi rk628-csi: rk628_hdmirx_audio_fs: clkrate:1500 tmdsclk:74250000,
n_decoded:6144, cts_decoded:74250, fs_audio:48000
m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:

HDMI_RX_AUD_FIFO_FILLSTS1:0xfc, single offset:0, total offset:-4
m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:
HDMI_RX_AUD_FIFO_ISTS:0x4
m00_b_rk628-csi rk628-csi: rk628_hdmirx_audio_fs: clkrate:1500 tmdsclk:74250000,
n_decoded:6144, cts_decoded:74250, fs_audio:48000
m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:
HDMI_RX_AUD_FIFO_FILLSTS1:0xfc, single offset:0, total offset:-4
m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:
HDMI_RX_AUD_FIFO_ISTS:0x4
m00_b_rk628-csi rk628-csi: rk628_hdmirx_audio_fs: clkrate:1500 tmdsclk:74250000,
n_decoded:6144, cts_decoded:74250, fs_audio:48000
m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:

HDMI_RX_AUD_FIFO_FILLSTS1:0xfa, single offset:-2, total offset:-6
m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:
HDMI_RX_AUD_FIFO_ISTS:0x4
m00_b_rk628-csi rk628-csi: rk628_hdmirx_audio_fs: clkrate:1500 tmdsclk:74250000,
n_decoded:6144, cts_decoded:74250, fs_audio:48000
m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:
HDMI_RX_AUD_FIFO_FILLSTS1:0xfc, single offset:2, total offset:-4
m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:
HDMI_RX_AUD_FIFO_ISTS:0x4
m00_b_rk628-csi rk628-csi: rk628_hdmirx_audio_fs: clkrate:1500 tmdsclk:74250000,
n_decoded:6144, cts_decoded:74250, fs_audio:48000
m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:
HDMI_RX_AUD_FIFO_FILLSTS1:0xfa, single offset:-2, total offset:-6
m00_b_rk628-csi rk628-csi: rk628_csi_delayed_work_audio:

HDMI_RX_AUD_FIFO_ISTS:0x4

(3) Частота дискретизации записи HAL:

getprop vendor.hdmiin.audiorate
6.14.3.4 Прямая настройка IOMUX
 static void rk628_hdmirx_initial_setup(struct rk628_hdmirx *hdmirx)
 {
      struct v4l2_subdev_edid def_edid;

@@ -783,6 +937,8 @@ static void rk628_hdmirx_initial_setup(struct rk628_hdmirx
*hdmirx)

      // ddc and hpd pinctrl
      regmap_write(hdmirx->grf, GRF_GPIO1AB_SEL_CON, 0x07000700);
+     //i2s pinctrl
+     regmap_write(hdmirx->grf, GRF_GPIO0AB_SEL_CON, 0x155c155c);

      rk628_hdmirx_controller_reset(hdmirx);
6.14.3.5 Ошибочный расчёт tmdsclk

1. Согласуйте bitmask с частотой.

git sholsh@rk-intel-1:~/rk-sdk/android11-rk3399/kernel$ git show
007131063748ea69facbf4bbe7aaee71c34fd921

commit 007131063748ea69facbf4bbe7aaee71c34fd921
Author: Shunhua Lan <lsh@rock-chips.com>
Date: Fri Apr 23 18:43:59 2021 +0800

   media: i2c: rk628csi: fix mask for clkrate and fs audio align to 100

   Signed-off-by: Shunhua Lan <lsh@rock-chips.com>
   Change-Id: I15b290319463f1b41e6908e54caa99ef9c6db4f4

diff --git a/drivers/media/i2c/rk628_csi.c b/drivers/media/i2c/rk628_csi.c
index 89c4a926a985..a970bc621e0e 100644
--- a/drivers/media/i2c/rk628_csi.c
+++ b/drivers/media/i2c/rk628_csi.c

@@ -1064,7 +1064,7 @@ static void rk628_csi_delayed_work_audio(struct work_struct
*work)

      /* fout=128*fs=ftmds*N/CTS */
      regmap_read(csi->hdmirx_regmap, HDMI_RX_HDMI_CKM_RESULT, &clkrate);
-     clkrate = clkrate & 0xfff;
+     clkrate = clkrate & 0xffff;
      /* tmdsclk = (clkrate/1000) * 49500000 */
      tmdsclk = clkrate * (49500000 / 1000);
      regmap_read(csi->hdmirx_regmap, HDMI_RX_PDEC_ACR_CTS, &cts_decoded);
@@ -1073,6 +1073,8 @@ static void rk628_csi_delayed_work_audio(struct work_struct

*work)
      if (cts_decoded != 0) {
           fs_audio = div_u64((tmdsclk * n_decoded), cts_decoded);
           fs_audio = div_u64(fs_audio, 128);
+          fs_audio = div_u64(fs_audio + 50, 100);
+          fs_audio *= 100;
      }
      v4l2_dbg(2, debug, sd,
           "%s: clkrate:%d tmdsclk:%llu, n_decoded:%d, cts_decoded:%d,
fs_audio:%llu\n",

Журнал ошибки:

[67.440094] m00_b_rk628-csi rk628-csi:rk628_csi_delayed_work_audio:clkrate:1904
tmdsclk:94248000,n_decoded:6144,cts_decoded:297000,fs_audio:15232

Для 4K-дисплея в этом примере расчётный tmdsclk должен быть 297M.

tmdsclk = clkrate * (49500000 / 1000);

1904 —> 0x770

6000 —> 0x1770

tmdsclk 6*49500000 = 297000000

6.14.3.6 Вывод test clk через GPIO

Быстрая настройка:

grf: gpio0 相关 iomux 切换,配置为 IO 口:
echo 0x70 0x0fff0000 > registers


gpio0 配置为输出口, 1-0051-rk628-pinctrl:
echo 0xd0008 0x00EC00EC > registers

grf,选择在哪一级拉出信号:
HDMI_RX:
echo 0x300 0x11 > registers
ASYNC_IN:
echo 0x300 0x14 > registers
ASYNC_OUT:
echo 0x300 0x15 > registers
SCALER:
echo 0x300 0x16 > registers
6.14.3.7 Особенности IOMUX RK356X

Каждый интерфейс I2S RK356X может использовать несколько групп выводов, поэтому требуется дополнительная настройка GRF_IOFUNC_SEL4:

Бит Атрибут Значение сброса Описание
14 RW 0x0 i2s3_iomux_sel Выбор мультиплексирования I2S3
1’b0:M0 схема мультиплексирования
1’b1:M1 схема мультиплексирования
12 RW 0x0 i2s2_iomux_sel Выбор мультиплексирования I2S2
1’b0:M0 схема мультиплексирования
1’b1:M1 схема мультиплексирования
11:10 RW 0x0 i2s1_iomux_sel Выбор мультиплексирования I2S1
2’b00:M0 схема мультиплексирования
2’b01:M1 схема мультиплексирования
2’b10:M2 схема мультиплексирования
2’b11: Зарезервировано

Драйвер pinctrl настраивает биты GRF по выбранному mclk. Код:

static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
   ....
   RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO

mux M0 */
   RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO
mux M1 */
   RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO
mux M2 */
   RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO
mux M0 */
   RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO
mux M1 */
   RK_MUXROUTE_GRF(3, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO
mux M0 */
   RK_MUXROUTE_GRF(4, RK_PC4, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO
mux M1 */

   ....
}

Применения вроде RK628, которым mclk не нужен, не настраивают его, поэтому биты не устанавливаются. Добавьте обработку вручную. I2S обычно использует sclk, поэтому здесь добавляется sclk. Оригинал обещает патч в последующем SDK RK356X; проверьте фактический SDK.

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-
rockchip.c

index 871c49ef0c2a..3d10e6c2ed27 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -1046,13 +1046,26 @@ static struct rockchip_mux_route_data
rk3568_mux_route_data[] = {
      RK_MUXROUTE_GRF(2, RK_PB0, 3, 0x0310, WRITE_MASK_VAL(9, 8, 0)), /* UART9
IO mux M0 */
      RK_MUXROUTE_GRF(4, RK_PC5, 4, 0x0310, WRITE_MASK_VAL(9, 8, 1)), /* UART9
IO mux M1 */
      RK_MUXROUTE_GRF(4, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(9, 8, 2)), /* UART9

IO mux M2 */
+
      RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1
IO mux M0 */
      RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1
IO mux M1 */
      RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1
IO mux M2 */
+     RK_MUXROUTE_GRF(1, RK_PA3, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1
IO mux sclk tx M0 */
+     RK_MUXROUTE_GRF(1, RK_PA4, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1
IO mux sclk rx M0 */

+     RK_MUXROUTE_GRF(3, RK_PC7, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1
IO mux sclk tx M1 */
+     RK_MUXROUTE_GRF(4, RK_PA6, 5, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1
IO mux sclk rx M1 */
+     RK_MUXROUTE_GRF(2, RK_PD1, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1
IO mux sclk tx M2 */
+     RK_MUXROUTE_GRF(3, RK_PC3, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1
IO mux sclk rx M2 */
      RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2
IO mux M0 */
      RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2
IO mux M1 */
+     RK_MUXROUTE_GRF(2, RK_PC2, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2

IO mux sclk tx M0 */
+     RK_MUXROUTE_GRF(2, RK_PB7, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2
IO mux sclk rx M0 */
+     RK_MUXROUTE_GRF(4, RK_PB7, 4, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S1
IO mux sclk tx M1 */
+     RK_MUXROUTE_GRF(4, RK_PC1, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S1
IO mux sclk rx M1 */
      RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3
IO mux M0 */
      RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3
IO mux M1 */
+     RK_MUXROUTE_GRF(3, RK_PA3, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3

IO mux sclk M0 */
+     RK_MUXROUTE_GRF(4, RK_PC3, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3
IO mux sclk M1 */
      RK_MUXROUTE_GRF(1, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO
mux M0 */
      RK_MUXROUTE_GRF(1, RK_PA6, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO
mux M0 */
      RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO
mux M1 */
6.14.3.8 Особенности LRCK RK3399

Неверное направление может исключить приём данных после открытия звуковой карты. Типичный журнал ниже; адаптируйте пути узлов к устройству:

console:/ # cat /proc/asound/cards
 0 [rockchiphdmi ]: rockchip_hdmi - rockchip,hdmi
                rockchip,hdmi

 1 [rockchiphdmiin ]: rockchip_hdmiin - rockchip,hdmiin
                rockchip,hdmiin

console:/ # cat /proc/asound/card1/pcm0c/sub0/status
state: RUNNING
owner_pid : 1415
trigger_time: 1632716135.151992694
tstamp   : 0.000000000
delay    : 0
avail    : 0
avail_max : 0
-----

hw_ptr   : 0
appl_ptr : 0

Нормальный вывод должен выглядеть примерно так:

console:/ # cat /proc/asound/card1/pcm0c/sub0/status
state: RUNNING
owner_pid : 1421

trigger_time: 1632892868.412331044
tstamp   : 1632892881.181113577
delay    : 232
avail    : 232
avail_max : 264
-----
hw_ptr   : 543736
appl_ptr : 543504

RK628 является master, RK3399 — slave, поэтому настройка зависит от разводки. Если к RK628 подключён LRCK_TX, задайте rockchip,clk-trcm следующим образом:

+&i2s0 {
+     rockchip,clk-trcm = <1>;

+     status = "okay";
+};

console:/ # io -4 0xff880008
ff880008: 18071f1f

Если к RK628 подключён LRCK_RX, задайте rockchip,clk-trcm следующим образом:

+&i2s0 {
+     rockchip,clk-trcm = <2>;
+     status = "okay";

+};
正常寄存器如下:
console:/ # io -4 0xff880008
ff880008: 28071f1f

Биты 29:28 регистра I2S_CKR определены следующим образом:

Tx and Rx Common Use
2'b00/2'b11:tx_lrck/rx_lrck are used as synchronous signal for TX
/RX respectively.

2'b01:only tx_lrck is used as synchronous signal for TX and RX.
2'b10:only rx_lrck is used as synchronous signal for TX and RX.

Обновите код RK628 до v15-210926 или новее и используйте пример звука в arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-rk628-hdmi2csi-v4l2-avb.dts.

6.14.3.9 Неверный выбор звуковой карты HDMI-IN

При открытии APK сопоставляет звуковые карты по имени. Ранний код может выбрать неверное имя и не открыть карту HDMI-IN. Пример ошибки:

09-28 07:03:13.341 261 1386 D AudioHardwareTiny: card0 id:rockchiphdmi
09-28 07:03:13.341 261 1386 D AudioHardwareTiny: SPEAKER card, got
card=0,device=0

09-28 07:03:13.341 261 1386 D AudioHardwareTiny: HDMI card, got
card=0,device=0
09-28 07:03:13.341 261 1386 D AudioHardwareTiny: SPDIF card, got
card=0,device=0
09-28 07:03:13.341 261 1386 D AudioHardwareTiny: BT card, got card=0,device=0
09-28 07:03:13.342 261 1386 D AudioHardwareTiny: card1 id:rockchiphdmiin
09-28 07:03:13.342 261 1386 D AudioHardwareTiny: SPEAKER card, got
card=1,device=0
09-28 07:03:13.342 261 1386 D AudioHardwareTiny: HDMI card, got
card=1,device=0
09-28 07:03:13.342 261 1386 D AudioHardwareTiny: SPDIF card, got
card=1,device=0

09-28 07:03:13.342 261 1386 D AudioHardwareTiny: BT card, got card=1,device=0
09-28 07:03:13.342 261 1386 D AudioHardwareTiny: No exist
proc/asound/card2/id, break and finish parsing
09-28 07:03:13.343 261 1386 D AudioHardwareTiny: dump out device info
09-28 07:03:13.343 261 1386 D AudioHardwareTiny: dev_info SPEAKER card=1,
device:0
09-28 07:03:13.343 261 1386 D AudioHardwareTiny: dev_info HDMI card=1,
device:0
09-28 07:03:13.343 261 1386 D AudioHardwareTiny: dev_info SPDIF card=1,
device:0
09-28 07:03:13.343 261 1386 D AudioHardwareTiny: dev_info BT card=1, device:0

HDMI card, got card=1,device=0 не соответствует реальному устройству, поэтому карта не открывается.

Примените следующий патч либо обновите код RK628 до V15-210926 или новее.

hardware/rockchip/audio
commit 1b51a62fc62e9d63850e4e5a39f1e3cff0aa9b88 (HEAD)
Author: Shunhua Lan <lsh@rock-chips.com>

Date: Tue Sep 28 17:25:44 2021 +0800

   [audio hal] use levenshtein distance for sound card matching

   Signed-off-by: Shunhua Lan <lsh@rock-chips.com>
   Change-Id: I16f1692715d710a0693ae74875b0272669a04ba2

6.14.4 Дополнительные документы по звуку

Для прямого соединения RK628 с SoC см. RK628-DIRECT-TO-SOC.pdf.

Для соединения через аудиокодек см. RK628-RT5640-AUDIO-CONFIG.pdf.

Для звуковых проблем HDMI-IN APK см. RK628-HDMIIN-APP-AUDIO.pdf.

При расхождениях или противоречиях с другими документами приоритет имеет данное исходное руководство.

6.15 Диагностика типичных неисправностей

6.15.1 Ошибки clk det

6.15.1.1 RK628D

Если COMBRXPHY не обнаруживает сигнал, возможна неверная полярность обнаружения подключения HDMI или HPD, мешающая передаче источника. Проверьте plugin-det-gpios и hpd-output-inverted в rk628_csi и измерьте HPD мультиметром.

При ошибке выполняются повторы до retry 2. Если повтор успешен, оригинал считает сигнал нормальным.

rk628-csi-v4l2 1-0051: clk det over cnt:10, reg_0x6654:0x403f0000
rk628-csi-v4l2 1-0051: |d2_p| level detection anomaly
rk628-csi-v4l2 1-0051: clock detected failed, cfg resistance manual!

rk628-csi-v4l2 1-0051: err, clk not stable, reg_0x6630:0x87000d,
reg_0x6608:0x110100
m00_b_rk628-csi 1-0051: hdmi rxphy power on failed

Журнал выше указывает на ошибку определения напряжения data2_p: возможно отсутствие сигнала или малая амплитуда.

rk628-csi-v4l2 1-0051: clk det over cnt:10, reg_0x6654:0x403f0000
rk628-csi-v4l2 1-0051: Clock detection anomaly
rk628-csi-v4l2 1-0051: clock detected failed, cfg resistance manual!

rk628-csi-v4l2 1-0051: err, clk not stable, reg_0x6630:0x87000d,
reg_0x6608:0x110100
m00_b_rk628-csi 1-0051: hdmi rxphy power on failed

Журнал выше указывает на ошибку определения частоты, возможно вне диапазона RK628D. Описанный HDMIRX поддерживает следующие частоты:

25175, 27000, 33750, 40000, 59400, 65000, 68250, 74250,
75000, 83500, 85500, 88750, 928125, 101000, 102250, 108000,
118800, 119000, 135000, 148500, 150000, 162000, 165000, 297000

6.15.2 Проверка нормальной работы HDMI RX

После захвата COMBRXPHY контроллер HDMI RX должен корректно определять тайминги. Расчётные значения могут иметь небольшую погрешность, часто на 1. Подробные тайминги приведены в стандартах CEA.

Оригинальный технический рисунок — EN V2.3, p100

Оригинальный технический рисунок: EN V2.3, p100.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

m00_b_rk628-csi rk628-csi: cnt_num:1000, tmds_cnt:3000, hs_cnt:15, vs_cnt:3667, hofs:192
m00_b_rk628-csi rk628-csi: SCDC_REGS1:0xffff0f00, act:1920x1080, total:2200x1125, fps:60,
m00_b_rk628-csi rk628-csi: hfp:88, hs:45, hbp:147, vfp:4, vs:5, vbp:36, interlace:0
m00_b_rk628-csi rk628-csi: rk628_csi_s_dv_timings: 1920x1080p60.0 (2200x1125)
m00_b_rk628-csi rk628-csi: enable_stream: disable

6.15.3 Ошибка прав при открытии subdev

Оригинальный технический рисунок — EN V2.3, p100

Оригинальный технический рисунок: EN V2.3, p100.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

D JNI     : JNI CAMERA CALL init
I HdmiInput-native: JNI OnLoad
I HdmiInput-native: Apk Version: V1.2
E HdmiInput-native: openDevice(91): open /dev/v4l-subdev2 failed,erro=Permission denied
D RockchipCamera2: remove fake pic button
D RockchipCamera2: recreateTextureview
D RockchipCamera2: textureView remove
D RockchipCamera2: onResume

Проверьте режим 666 для /dev/v4l-subdev*, требуемый примером оригинала. Команда на устройстве:

rk3288:/ # cat /vendor/ueventd.rc | grep subdev
/dev/v4l-subdev*   0666 media   camera

Описанный SDK уже содержит коммит. Если его нет, адаптируйте изменение в device/rockchip/common/:

Оригинальный технический рисунок — EN V2.3, p100

Оригинальный технический рисунок: EN V2.3, p100.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

wendingxian@ubuntu:~/rk3288_9.0_int/device/rockchip/common$ git show
commit 17112e1430b0f10a88b57c73ad19203e58f0eeff (HEAD -> mid_9.0, rk/rk/rk33/mid/9.0/develop)
Author: Dingxian Wen <shawn.wen@rock-chips.com>
Date:   Tue Apr 27 21:26:48 2021 +0800

    ueventd.rockchip.rc: modify the /dev/v4l-subdev* permission to 666

    Signed-off-by: Dingxian Wen <shawn.wen@rock-chips.com>
    Change-Id: Id4848209fd983f7e525761f19c7f0420b9fee747

diff --git a/ueventd.rockchip.rc b/ueventd.rockchip.rc
index 1914490b..52935d49 100755
--- a/ueventd.rockchip.rc
+++ b/ueventd.rockchip.rc
@@ -178,7 +178,7 @@
 /dev/ovr0                0664   system     system
 
 #for rk_isp1
-/dev/v4l-subdev*         0660   media      camera
+/dev/v4l-subdev*         0666   media      camera

 /dev/video0             0660   media      camera
 /dev/video1             0660   media      camera

6.15.4 Сигнал не обнаружен

Шаг 1. Если подключение/отключение HDMI не даёт журналов RK628 в UART, неверно настроен GPIO det.

Шаг 2. Если журнал есть при отключении, но отсутствует при подключении, полярность plugin-det-gpios обратная. При инвертирующем транзисторе используйте GPIO_ACTIVE_LOW. Для проверки замените static int debug; на static int debug = 3; в rk628_csi_v4l2.c. Правильно: tx_5v_power_present: 1 при подключении и tx_5v_power_present: 0 при отключении.

Шаг 3. Если после подключения корректный сигнал не обнаруживается, проверьте следующие случаи:

Случай 1: инверсия HPD. Для вывода источника на разъёме HDMI IN должен быть высокий HPD. При инверторе RK628 должен выдавать низкий уровень, чтобы на разъёме получился высокий. Добавьте hpd-output-inverted; в DTS.

Случай 2: PHY не захватывает сигнал; см. диагностику clk det.

Случай 3: разрешение не фиксируется; HDMIRX может обнаруживать битрейт вне допустимого диапазона.

Случай 4: разрешение определено, но AVI не готов. После захвата avi_rcv_rdy должен стать 1. Повторяющийся avi_rcv_rdy:0 при определённом разрешении может указывать на ненастроенный вывод прерывания. Сначала проверьте его настройку.

rk628d 1-0050: rk628_is_avi_ready PDEC_AVI_PB:0x10000840, avi_rcv_rdy:0
rk628d 1-0050: SCDC_REGS1:0x80000f00, act:1920x1080, total:2200x1125, fps:60,

pixclk:148500000

Оригинал сообщает о периодическом разделении изображения при захвате на RK3288 в таком состоянии; это не испытание ArmSoM.

6.15.5 Нарушения изображения

(1) Проверьте режим DVI источника: RK628D не поддерживает DVI. Проверьте журнал:

rk628-csi-v4l2 1-0051: DVI mode detected

(2) Проверьте шифрование HDCP источника. При его наличии включите HDCP HDMIRX RK628.

6.15.6 Выводится только половина изображения

Вероятная причина — источник HDMI 4K60 и старый хост с одним MIPI, например RK3399, RK3568 или RK3288. RK628F/H делит 4K60 на левую и правую половины, и хост получает лишь одну. Ограничьте EDID до 4K30, используя EDID RK628D:

diff --git a/drivers/media/i2c/rk628/rk628_csi_v4l2.c b/drivers/media/i2c/rk628/rk628_csi_v4l2.c
index 32182d4433605..36568f5a081e0 100644

--- a/drivers/media/i2c/rk628/rk628_csi_v4l2.c
+++ b/drivers/media/i2c/rk628/rk628_csi_v4l2.c
@@ -1347,7 +1347,7 @@ static void rk628_csi_initial_setup(struct v4l2_subdev *sd)
      def_edid.start_block = 0;
      def_edid.blocks = 2;
      if (csi->rk628->version >= RK628F_VERSION)
-          def_edid.edid = rk628f_edid_init_data;
+          def_edid.edid = edid_init_data;
      else
           def_edid.edid = edid_init_data;
      rk628_csi_s_edid(sd, &def_edid);

6.15.7 Ошибки захвата

(1) Android 9.0 и новее, Linux

Для захвата на Rockchip Android 9.0 и новее или Linux используйте v4l2-ctl. Сначала выполните media-ctl -d /dev/mediaX -p. Нумерация зависит от платформы. При отключении CIF часто остаётся media0; RK3399 с PHY1 может использовать media1. Учитывайте конфигурацию камеры платформы. При отсутствии RK628 в топологии проверьте DTS. Если разрешения топологии отличаются от входного, согласуйте их через media-ctl.

Затем выполните:

v4l2-ctl -d /dev/video0 --set-fmt-
video=width=1920,height=1080,pixelformat=NV12 --stream-mmap=3`

Постоянный вывод ««««« означает нормальный захват и обычно исправную работу драйвера. При постоянных или периодических ошибках:

rkisp1: MIPI mis error:

Причина может быть аппаратной. Проверьте разветвления HDMI и согласование импеданса. Некоторые платы добавляют последовательные резисторы, отсутствующие в эталонной схеме; оригинал использует 0 Ом без особой необходимости. Ненулевые значения могут вызывать периодические ошибки. Анализируйте конкретную плату и сигналы между RK628 и хостом.

Другой возможный журнал:

rkisp-vir0: MIPI error: overflow: 0x00000001

Такой журнал возможен на RK356X/RV11XX при входе 4K в ISP. Оригинал рекомендует путь RK628+VICAP; см. настройку VICAP в руководстве.

SIZE_ERROR может указывать на несовпадение разрешений, например вход 720p при захвате 1080p. Проверьте все разрешения топологии и v4l2-ctl. Оригинал рекомендует сначала тестировать везде 1080p.

rkisp1 ff910000.rkisp1: CIF_ISP_PIC_SIZE_ERROR

Обычно система определяет разрешение через /dev/v4l-subdev2, но media-ctl -p может показывать /dev/v4l-subdev3:

 - entity 70: m00_b_rk628-csi rk628-csi (1 pad, 1 link)
       type V4L2 subdev subtype Sensor
       device node name /dev/v4l-subdev3

pad0: Source
   [fmt:UYVY2X8/1280x720]
   -> "rockchip-csi2-dphy0":0 []

Тогда приложение не определяет разрешение и может выводить CIF_ISP_PIC_SIZE_ERROR. Измените jni/native.cpp приложения Android следующим образом:

strcat(video_name, "/dev/v4l-subdev2");

Замените на:

strcat(video_name, "/dev/v4l-subdev3");

(2) Нет кадров при 4K

4K использует более высокие частоты, поэтому причиной может быть качество сигнала. ISP RK3399 также требует повышенной частоты; см. способ настройки разгона ISP RK3399.

6.15.8 APK не открывается

Выпущенный патч содержит исходники rkCamera2. Соберите их в дереве системы, например разместив в корне и выполнив mmm для каталога APK. Возможные причины сбоя:

(1) Библиотеки-зависимости

Установка только APK может вызвать:

AndroidRuntime: java.lang.UnsatisfiedLinkError: dlopen failed: library
"/system/lib64/libhdmiinput_jni.so" needed or dlopened by

"/apex/com.android.runtime/lib64/libnativeloader.so" is not accessible for
the namespace "classloader-namespace"

Соберите и упакуйте в SDK, чтобы библиотеки вошли в образ.

(2) Права файлов

APK обращается к узлам RK628 через ioctl, например:

HdmiInput-navtive: openDevice(113): open /dev/v4l-subdev2
failed,erro=Permission denied

Сначала проверьте права: исходный патч задаёт режим 666. Поскольку APK обращается к узлам устройств, оригинал также предлагает проверить отключение SELinux командой getenforce. Это описание исходной отладочной среды, а не рекомендация ослаблять защиту серийной системы.

(3) Настройка верхнего уровня

Для Android 9.0 и новее настройте camera3_profiles.xml, для более ранних — cam_board.xml. Проверьте dumpsys media.camera: отсутствие записей может означать отсутствие настройки:

$ dumpsys media.camera

== Service global info: ==


Number of camera devices: 1
Number of normal camera devices: 1

(4) Сбой библиотеки камеры

Следующая ошибка может быть вызвана неверным именем камеры: имя из getDataFromXmlFile не совпадает с драйвером, что приводит к сбою.

09-29 04:43:30.673 405 405 W ServiceManagement: Waited one second for
android.hardware.camera.provider@2.4::ICameraProvider/legacy/0. Waiting

another...
09-29 04:43:31.673 405 405 W ServiceManagement: Waited one second for
android.hardware.camera.provider@2.4::ICameraProvider/legacy/0. Waiting
another...
...
09-29 04:43:31.904 1404 1404 F DEBUG : backtrace:
09-29 04:43:31.904 1404 1404 F DEBUG : #00 pc 0007214e
/vendor/lib/hw/camera.rk30board.so
(android::camera2::ChromeCameraProfiles::handleAndroidStaticMetadata(char const*,
char const**)+546)
09-29 04:43:31.904 1404 1404 F DEBUG : #01 pc 00007895 /system/lib/vndk-
28/libexpat.so (doContent+432)
09-29 04:43:31.905 1404 1404 F DEBUG : #02 pc 0000637b /system/lib/vndk-

28/libexpat.so (contentProcessor+40)
09-29 04:43:31.905 1404 1404 F DEBUG : #03 pc 00003825 /system/lib/vndk-
28/libexpat.so (XML_ParseBuffer+84)
09-29 04:43:31.905 1404 1404 F DEBUG : #04 pc 000711ad
/vendor/lib/hw/camera.rk30board.so
(android::camera2::CameraProfiles::getDataFromXmlFile()+148)
09-29 04:43:31.905 1404 1404 F DEBUG : #05 pc 00071e97
/vendor/lib/hw/camera.rk30board.so
(android::camera2::ChromeCameraProfiles::init()+86)
09-29 04:43:31.905 1404 1404 F DEBUG : #06 pc 000734c7
/vendor/lib/hw/camera.rk30board.so (android::camera2::PlatformData::init()+198)
09-29 04:43:31.905 1404 1404 F DEBUG : #07 pc 000cecb3

/vendor/lib/hw/camera.rk30board.so (initCameraHAL()+46)
...

Если требуется V4L2 (Android 9.0 и новее), замените name=”rk628-csi” на name=”rk628-csi-v4l2” в camera3_profiles_rk3399.xml, как показано ниже:

hardware/rockchip/camera
--- a/etc/camera/camera3_profiles_rk3399.xml
+++ b/etc/camera/camera3_profiles_rk3399.xml

@@ -769,7 +769,7 @@

 <!-- ******************PSL specific section end
**************************************************************-->
   </Profiles>
-  <Profiles cameraId="0" name="rk628-csi" moduleId="m00">
+  <Profiles cameraId="0" name="rk628-csi-v4l2" moduleId="m00">

(5) Сбои APK из-за разрешений

Журнал при этой проблеме обычно выглядит следующим образом:

Если требуется V4L2 (Android 9.0 и новее), переименуйте rk628-csi в rk628-csi-v4l2.

09-24 10:21:20.154 1552 1570 E AndroidRuntime: FATAL EXCEPTION: Thread-2
09-24 10:21:20.154 1552 1570 E AndroidRuntime: Process:

com.android.rockchip.camera2, PID: 1552
09-24 10:21:20.154 1552 1570 E AndroidRuntime: java.lang.IllegalStateException:
startRecording() called on an uninitialized AudioRecord.
09-24 10:21:20.154 1552 1570 E AndroidRuntime: at
android.media.AudioRecord.startRecording(AudioRecord.java:983)
09-24 10:21:20.154 1552 1570 E AndroidRuntime: at
com.android.rockchip.camera2.AudioStream$recordSound.run(AudioStream.java:199)
09-24 10:21:20.154 1552 1570 E AndroidRuntime: at
java.lang.Thread.run(Thread.java:764)
09-24 10:21:20.164 464 820 W ActivityManager: Force finishing activity
com.android.rockchip.camera2/.RockchipCamera2
09-24 10:21:20.183 1552 1552 D RockchipCamera2: onPause

Для устранения проблемы можно использовать следующий патч:

packages/apps/rkCamera2
--- a/AndroidManifest.xml

+++ b/AndroidManifest.xml
@@ -4,7 +4,8 @@
   package="com.android.rockchip.camera2">

      <uses-permission android:name="android.permission.CAMERA" />
-     <uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
/>
+     <uses-permission android:name="android.permission.RECORD_AUDIO" />
   <application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"

diff --git a/src/com/android/rockchip/camera2/RockchipCamera2.java b/src/com/android/rockchip/camera2/RockchipCamera2.java
index 9dc29b8..02ee104 100755
--- a/src/com/android/rockchip/camera2/RockchipCamera2.java
+++ b/src/com/android/rockchip/camera2/RockchipCamera2.java
@@ -100,9 +100,11 @@ public class RockchipCamera2 extends Activity {
      if (ActivityCompat.checkSelfPermission(this,
         Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
         && ActivityCompat.checkSelfPermission(this,
-             Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
+             Manifest.permission.WRITE_EXTERNAL_STORAGE) !=

PackageManager.PERMISSION_GRANTED
+        && ActivityCompat.checkSelfPermission(this,
+             Manifest.permission.RECORD_AUDIO) !=
PackageManager.PERMISSION_GRANTED) {
         ActivityCompat.requestPermissions(RockchipCamera2.this,
-          new String[] { Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE },
+          new String[] { Manifest.permission.CAMERA,

Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO},
           REQUEST_CAMERA_PERMISSION);
         return;
      }

6.15.9 Подключение к rkcif в DTS: предварительный просмотр в APK не работает

На RK356X с Android 11, версия кода R10/R11, если DTS подключает RK628 к rkcif и захват кадров работает, но предварительный просмотр в APK не запускается, причиной может быть отсутствие поддержки этой цепочки в cameraHAL версий R10 и R11. Согласно исходному документу, в R9 этой проблемы нет. Порядок диагностики и устранения:

(1) Включите отладку cameraHAL:

setprop persist.vendor.camera.hal.debug 5

(2) Сохраните logcat при ошибке открытия APK. Ключевые записи журнала:

Оригинальный технический рисунок — EN V2.3, p107

Оригинальный технический рисунок: EN V2.3, p107.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

I RkCamera: <HAL> RKISP2GraphConfig: @addLinkParams, srcName:rockchip-csi2-dphy0, srcPad:1, sinkName:none, sinkPad:0, enable:1, flags:1
I RkCamera: <HAL> RKISP2GraphConfig: @addLinkParams, srcName:none, srcPad:1, sinkName:none, sinkPad:0, enable:1, flags:1
I RkCamera: <HAL> RKISP2GraphConfig: @addLinkParams, srcName:none, srcPad:2, sinkName:rkisp_rawwr0, sinkPad:0, enable:1, flags:1
I RkCamera: <HAL> RKISP2GraphConfig: @addLinkParams, srcName:none, srcPad:4, sinkName:rkisp_rawwr2, sinkPad:0, enable:1, flags:1
I RkCamera: <HAL> RKISP2GraphConfig: @addLinkParams, srcName:none, srcPad:5, sinkName:rkisp_rawwr3, sinkPad:0, enable:1, flags:1
I RkCamera: <HAL> RKISP2GraphConfig: @addFormatParams, entityName:none, width:1920, height:1080, pad:0, format:0x2006:V4L2_MBUS_FMT_UYVY8_2X8, field:0
I RkCamera: <HAL> RKISP2GraphConfig: @addSelectionParams, width:1920, height:1080, left:0, top:0, target:0, pad:0, entityName:none
I RkCamera: <HAL> RKISP2GraphConfig: @addSelectionParams, width:1920, height:1080, left:0, top:0, target:0, pad:2, entityName:none
I RkCamera: <HAL> RKISP2GraphConfig: @addFormatParams, entityName:none, width:1920, height:1080, pad:2, format:0x2008:V4L2_MBUS_FMT_YUYV8_2X8, field:0
I RkCamera: <HAL> RKISP2GraphConfig: @addLinkParams, srcName:none, srcPad:3, sinkName:none, sinkPad:0, enable:1, flags:1
I RkCamera: <HAL> RKISP2GraphConfig: @addLinkParams, srcName:none, srcPad:0, sinkName:none, sinkPad:1, enable:1, flags:1
D RkCamera: <HAL> RKISP2GraphConfig: @ isNeedPathCrop : stream ratios: 1.777778
D RkCamera: <HAL> RKISP2GraphConfig: @ isNeedPathCrop : mp_need_crop 1, sp_need_crop 0, sp_enabled 0
D RkCamera: <HAL> RKISP2GraphConfig: @ calc_crop : src_ratio:1.777778, dst_ratio:1.777778, src(1920x1080), dst(1920x1080)
I RkCamera: <HAL> RKISP2GraphConfig: @addSelectionVideoParams, width:1920, height:1080, left:0, top:0, target:0, type:1, flags:0 entityName:none
I RkCamera: <HAL> RKISP2GraphConfig: @addFormatParams, entityName:none, width:1920, height:1080, pad:0, format:0x3231564e:V4L2_PIX_FMT_NV12, field:0
I RkCamera: <HAL> RKISP2GraphConfig: @addLinkParams, srcName:none, srcPad:2, sinkName:none, sinkPad:0, enable:1, flags:1
I RkCamera: <HAL> RKISP2GraphConfig: @getImguMediaCtlConfig : No need for selfPath

Если появляются приведённые записи, cameraHAL по умолчанию настроил соответствующую цепочку на rkisp, тогда как DTS задаёт rkcif. В этом месте исходника cameraHAL написано как ameraHAL.

(3) Устранение

Внесите следующие изменения в hardware/rockchip/camera:

diff --git a/psl/rkisp2/RKISP2GraphConfig.cpp b/psl/rkisp2/RKISP2GraphConfig.cpp
index 2a5fa5a..3d2409c 100755
--- a/psl/rkisp2/RKISP2GraphConfig.cpp

+++ b/psl/rkisp2/RKISP2GraphConfig.cpp
@@ -76,6 +76,7 @@ const string MEDIACTL_POSTVIEWNAME = "postview";

 const string MEDIACTL_STATNAME = "rkisp1-statistics";
 const string MEDIACTL_VIDEONAME_CIF = "stream_cif_dvp_id0";
+const string MEDIACTL_VIDEONAME_CIF_MIPI_ID0 = "stream_cif_mipi_id0";

 RKISP2GraphConfig::RKISP2GraphConfig() :
      mManager(nullptr),
@@ -2620,6 +2621,13 @@ status_t RKISP2GraphConfig::getImguMediaCtlConfig(int32_t
cameraId,
            addLinkParams("rkisp-isp-subdev", 2, "rkisp_mainpath", 0, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);

            addLinkParams("rkisp-isp-subdev", 2, "rkisp_selfpath", 0, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
         }
+     } else if(mipName2.find("mipi") != std::string::npos) {
+        addLinkParams(mipName, mipSrcPad, mipName2, csiSinkPad, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);

+        addLinkParams(mipName2, 1, "stream_cif_mipi_id0", 0, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
+        addLinkParams(mipName2, 2, "stream_cif_mipi_id1", 0, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
+        addLinkParams(mipName2, 3, "stream_cif_mipi_id2", 0, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
+        addLinkParams(mipName2, 4, "stream_cif_mipi_id3", 0, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
+        mSensorLinkedToCIF = true;
      } else {
         addLinkParams(mipName, mipSrcPad, csiName, csiSinkPad, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);

         addLinkParams(csiName, csiSrcPad, IspName, ispSinkPad, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
@@ -2628,6 +2636,12 @@ status_t RKISP2GraphConfig::getImguMediaCtlConfig(int32_t
cameraId,
         addLinkParams(csiName, 5, "rkisp_rawwr3", 0, 1,
MEDIA_LNK_FL_ENABLED, mediaCtlConfig);
      }
   }
+  if(mSensorLinkedToCIF){
+     addImguVideoNode(IMGU_NODE_VIDEO, MEDIACTL_VIDEONAME_CIF_MIPI_ID0,
mediaCtlConfig);
+     addFormatParams(MEDIACTL_VIDEONAME_CIF_MIPI_ID0, mCurSensorFormat.width,
mCurSensorFormat.height,

+           0, V4L2_PIX_FMT_NV12, 0, 0, mediaCtlConfig);
+     return OK;
+  }
   // isp input pad format and selection config
   addFormatParams(IspName, ispInWidth, ispInHeight, ispSinkPad, ispInFormat,
0, 0, mediaCtlConfig);
   addSelectionParams(IspName, ispInWidth, ispInHeight, 0, 0,
V4L2_SEL_TGT_CROP, ispSinkPad, mediaCtlConfig);

6.15.10 Управление GPIO RK628

В месте, где требуется управление GPIO, непосредственно вызовите интерфейс GPIO. Он включает настройку IOMUX, направления GPIO и уровня сигнала. Например, следующие операции переводят I2C_SDA_HDMI и I2C_SCL_HDMI в режим GPIO.

rk628_gpio_direction_output(rk628, GPIO1_B1, GPIO_REG_HIGH);
rk628_gpio_direction_output(rk628, GPIO1_B2, GPIO_REG_HIGH);

Для восстановления исходной функции вызовите следующий интерфейс:

rk628_pinctrl_set_mux(rk628, GPIO1_B1, DDCM0SDARX);
rk628_pinctrl_set_mux(rk628, GPIO1_B2, DDCM0SCLRX);

6.15.11 Ошибка регистрации звуковой карты

В следующем примере после запуска системы звуковая карта hdmiin не обнаруживается:

# cat /proc/asound/cards
 1 [rockchiphdmiin ]: rockchip_hdmiin - rockchip,hdmiin
                rockchip,hdmiin

Сначала проверьте, успешно ли загружены устройства soc dai и codec dai, от которых зависит звуковая карта:

rk3399:/ # cat /sys/kernel/debug/asoc/components
...
dummy-codec

ff8a0000.i2s
ff8a0000.i2s
ff880000.i2s
ff880000.i2s
...
rk3399:/ # cat /sys/kernel/debug/asoc/dais
...
ff8a0000.i2s
ff880000.i2s
dummy-codec
....

Если эти узлы не загружаются, проверьте defconfig и DTS.

Если soc dai и codec dai зарегистрированы успешно, а звуковая карта — нет, возможно, недостаточно ресурсов DMA. В исходнике отмечено, что это особенно часто встречается на RK3399. Для ядер 4.19 и новее добавьте в узел i2s следующее свойство:

--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi

@@ -1788,6 +1788,7 @@
           clocks = <&cru SCLK_I2S2_8CH>, <&cru HCLK_I2S2_8CH>;
           resets = <&cru SRST_I2S2_8CH>, <&cru SRST_H_I2S2_8CH>;
           reset-names = "reset-m", "reset-h";
+          rockchip,capture-only;
           power-domains = <&power RK3399_PD_SDIOAUDIO>;
           status = "disabled";

7. Типовые задачи

7.1 Настройка тактового сигнала 24M RK628 от другого SoC

Ниже приведены настройки для нескольких ведущих SoC Rockchip. Предполагается, что все тактовые сигналы, заданные в примерах DTS, включены в коде. Если они не включены, после загрузки сигнал 24M будет отключён, что вызовет ошибки связи I2C.

7.1.1 Добавление поддержки 24M на RK3399

(1) Укажите следующую настройку в DTS rk628:

pinctrl-names = "default";
pinctrl-0 = <&rk628_rst>, <&clk_testout2>;
assigned-clocks = <&cru SCLK_TESTCLKOUT2>;

assigned-clock-rates = <24000000>;
clocks = <&cru SCLK_TESTCLKOUT2>;
clock-names = "soc_24M";

(2) Добавьте настройку PINCTRL выводов ввода-вывода согласно фактическим аппаратным соединениям:

&pinctrl {
      test {
           clk_testout2: clk_testout2 {

           rockchip,pins = <0 8 RK_FUNC_3 &pcfg_pull_none>;
      };
};

7.1.2 Добавление поддержки 24M на RK3288

(1) Укажите следующую настройку в DTS rk628:

pinctrl-names = "default";
pinctrl-0 = <&test_clkout>;
assigned-clocks = <&cru SCLK_TESTOUT_SRC>;

assigned-clock-parents = <&xin24m>;
clocks = <&cru SCLK_TESTOUT>;
clock-names = "soc_24M";

(2) Добавьте настройку PINCTRL выводов ввода-вывода согласно фактическим аппаратным соединениям:

&pinctrl {
      test {
           test_clkout: test-clkout {

                 rockchip,pins = <0 17 RK_FUNC_1 &pcfg_pull_none>;
           };
      };
};

7.1.3 Добавление поддержки 24M на RK356X

RK356X имеет несколько выводов, способных выдавать 24 МГц, в том числе REF_CLKOUT (clk_wifi/gpio0_a0), CAM_CLKOUT1 (clk_cam1_out/gpio4_b0) и ETH_REFCLK_25M_M0 (clk_mac1_out/gpio3_b0). В следующем примере используется clk_wifi.

(1) Укажите следующую настройку в DTS rk628:


&i2c2_rk628 {
   pinctrl-names = "default";
   pinctrl-0 = <&rk628_reset &refclk_pins>;

   assigned-clocks = <&pmucru CLK_WIFI>;
   assigned-clock-rates = <24000000>;
   clocks = <&pmucru CLK_WIFI>;
   clock-names = "soc_24M";
};

&pinctrl {
   rk628 {
      rk628_reset: rk628-reset {
         rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
      };
   };

};

(2) Следующая настройка уже присутствует в rk3568-pinctrl.dtsi:

&pinctrl {
   ......

   refclk {
      /omit-if-no-ref/
      refclk_pins: refclk-pins {
         rockchip,pins =
           /* refclk_ou */
           <0 RK_PA0 1 &pcfg_pull_none>;
      };
   };
   ......
};

Для микросхем Rockchip, не перечисленных здесь, настройка сигнала 24M описана в Rockchip_Develop_Guide_Gpio_Output_Clocks_CN.pdf.

7.2 Поддержка двух RK628

7.2.1 Поддержка HDMI2CSI + HDMI2CSI

7.2.1.1 Важные замечания

(1) Два RK628 работают аналогично системе с двумя камерами. Для одновременной работы обоих RK628 ведущий SoC должен поддерживать два контроллера ISP, одновременно обрабатывающих два входных потока, как, например, RK3399.

(2) При разработке аппаратной части подключите два RK628 к разным шинам I2C либо к одной шине I2C, задав им разные адреса I2C.

(3) Настройка DTS должна соответствовать аппаратной схеме. Подключение конкретного RK628 к mipi_phy_rx0 или mipi_phy_tx1rx1 должно быть соответствующим образом отражено в DTS.

(4) При использовании двух RK628 для HDMI2CSI нельзя использовать одинаковые управляющие линии RESET и INT для обоих устройств: это приведёт к некорректной работе.

7.2.1.2 Настройка DTS ядра

В следующем примере два RK628 настраиваются для RK3399.

(1) rk628 -> mipi_dphy_rx0 -> rkisp1_0: для первого тракта index равен 0, а facing задан как back.

&i2c1 {
   status = "okay";


   rk628_csi_v4l2: rk628_csi_v4l2@50 {
      compatible = "rockchip,rk628-csi-v4l2";
      reg = <0x50>;
      //clocks = <&ext_cam_clk>;
      //clock-names = "xvclk";

      interrupt-parent = <&gpio4>;
      interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
      pinctrl-names = "default";
      pinctrl-0 = <&rk628_irq>;
      //power-gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
      reset-gpios = <&gpio4 RK_PD2 GPIO_ACTIVE_LOW>;

      plugin-det-gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
      rockchip,camera-module-index = <0>;
      rockchip,camera-module-facing = "back";
      rockchip,camera-module-name = "RK628-CSI";
      rockchip,camera-module-lens-name = "NC";
      port {
         rk628_out: endpoint {
           remote-endpoint = <&hdmi2mipi_in>;
           data-lanes = <1 2 3 4>;
         };
      };
   };

};

&mipi_dphy_rx0 {
   status = "okay";

   ports {
      #address-cells = <1>;
      #size-cells = <0>;

      port@0 {
         reg = <0>;
         #address-cells = <1>;
         #size-cells = <0>;


         hdmi2mipi_in: endpoint@1 {
           reg = <1>;
           remote-endpoint = <&rk628_out>;
           data-lanes = <1 2 3 4>;
         };
      };

      port@1 {
         reg = <1>;
         #address-cells = <1>;
         #size-cells = <0>;


         dphy_rx0_out: endpoint@0 {
           reg = <0>;
           remote-endpoint = <&isp0_mipi_in>;
         };
      };
   };
};

&rkisp1_0 {
   status = "okay";


   port {
      #address-cells = <1>;
      #size-cells = <0>;

      isp0_mipi_in: endpoint@0 {
         reg = <0>;
         remote-endpoint = <&dphy_rx0_out>;
      };
   };
};

(2) rk628 -> mipi_dphy_tx1rx1 -> rkisp1_1: для второго тракта index равен 1, а facing задан как front.

&i2c4 {
   status = "okay";


   rk628_csi_v4l2_1: rk628_csi_v4l2_1@50 {
      compatible = "rockchip,rk628-csi-v4l2";
      reg = <0x50>;
      //clocks = <&ext_cam_clk>;
      //clock-names = "xvclk";

      interrupt-parent = <&gpio3>;
      interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
      pinctrl-names = "default";
      pinctrl-0 = <&rk628_irq1>;
      //power-gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
      reset-gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_LOW>;

      plugin-det-gpios = <&gpio0 RK_PD7 GPIO_ACTIVE_LOW>;
      rockchip,camera-module-index = <1>;
      rockchip,camera-module-facing = "front";
      rockchip,camera-module-name = "RK628-CSI";
      rockchip,camera-module-lens-name = "NC";
      port {
         rk628_out1: endpoint {
           remote-endpoint = <&hdmi2mipi_in1>;
           data-lanes = <1 2 3 4>;
         };
      };
   };
};

&mipi_dphy_tx1rx1 {

   status = "okay";

   ports {
      #address-cells = <1>;
      #size-cells = <0>;

      port@0 {
         reg = <0>;
         #address-cells = <1>;
         #size-cells = <0>;

         hdmi2mipi_in1: endpoint@1 {

           reg = <1>;
           remote-endpoint = <&rk628_out1>;
           data-lanes = <1 2 3 4>;
         };
      };

      port@1 {
         reg = <1>;
         #address-cells = <1>;
         #size-cells = <0>;

         dphy_tx1rx1_out: endpoint@0 {
           reg = <0>;

           remote-endpoint = <&isp1_mipi_in>;
         };
      };
   };
};

&rkisp1_1 {
   status = "okay";

   port {
      #address-cells = <1>;
      #size-cells = <0>;


      isp1_mipi_in: endpoint@0 {
         reg = <0>;
         remote-endpoint = <&dphy_tx1rx1_out>;
      };
   };
};
7.2.1.3 Настройка Android

(1) Замечания по настройке camera3_profiles.xml:

moduleId должен совпадать с index в DTS.

Первый RK628:

Оригинальный технический рисунок — EN V2.3, p115

Оригинальный технический рисунок: EN V2.3, p115.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

</Profiles>
<Profiles cameraId="0" name="rk628-csi" moduleId="m00">
    <Supported_hardware>
        <hwType value="SUPPORTED_HW_RKISP1"/>
    </Supported_hardware>

Второй RK628:

Оригинальный технический рисунок — EN V2.3, p115

Оригинальный технический рисунок: EN V2.3, p115.

Редактируемая расшифровка полностью видимого текста снимка. Обрезанные символы не восстановлены предположениями; фрагменты не обязательно пригодны для самостоятельного выполнения.

</Profiles>
<Profiles cameraId="1" name="rk628-csi" moduleId="m01">
    <Supported_hardware>
        <hwType value="SUPPORTED_HW_RKISP1"/>
    </Supported_hardware>

(2) Для одновременного использования обоих RK628 добавьте поддержку в cameraHAL, внеся следующие изменения в SDK/hardware/rockchip/camera:

diff --git a/common/platformdata/PlatformData.cpp b/common/platformdata/PlatformData.cpp

index 36d2ac9..d3fcb4b 100755
--- a/common/platformdata/PlatformData.cpp
+++ b/common/platformdata/PlatformData.cpp
@@ -1047,7 +1047,7 @@ CameraHWInfo::CameraHWInfo() :
   mProductName = "<not_set>";
   mManufacturerName = "<not set>";
   mCameraDeviceAPIVersion = CAMERA_DEVICE_API_VERSION_3_3;
-  mSupportDualVideo = false;
+  mSupportDualVideo = true;
   mSupportExtendedMakernote = false;
   mSupportFullColorRange = true;
   mSupportIPUAcceleration = false;

7.2.2 Поддержка HDMI2CSI + HDMI2DSI

7.2.2.1 Настройка DTS ядра

В комбинации HDMI2CSI + HDMI2DSI один RK628 подключается к ведущему SoC через подсистему камеры, а другой — к дисплею. В следующем примере используется RK3399.

(1) Настройка HDMI2CSI

Используйте rk628 -> mipi_phy_rx0 -> rkisp1_0 либо rk628 -> mipi_dphy_tx1rx1 -> rkisp1_1. В примере используется подключение к rkisp1_0.

&i2c1 {
   status = "okay";


   rk628_csi_v4l2: rk628_csi_v4l2@50 {
      compatible = "rockchip,rk628-csi-v4l2";
      reg = <0x50>;
      //clocks = <&ext_cam_clk>;
      //clock-names = "xvclk";

      interrupt-parent = <&gpio4>;
      interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
      pinctrl-names = "default";
      pinctrl-0 = <&rk628_irq>;
      //power-gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;

      reset-gpios = <&gpio4 RK_PD2 GPIO_ACTIVE_LOW>;
      plugin-det-gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
      rockchip,camera-module-index = <0>;
      rockchip,camera-module-facing = "back";
      rockchip,camera-module-name = "RK628-CSI";
      rockchip,camera-module-lens-name = "NC";
      port {
         rk628_out: endpoint {
            remote-endpoint = <&hdmi2mipi_in>;
            data-lanes = <1 2 3 4>;
         };
      };

   };
};

&mipi_dphy_rx0 {
   status = "okay";

   ports {
      #address-cells = <1>;
      #size-cells = <0>;

      port@0 {
         reg = <0>;
         #address-cells = <1>;

         #size-cells = <0>;

         hdmi2mipi_in: endpoint@1 {
            reg = <1>;
            remote-endpoint = <&rk628_out>;
            data-lanes = <1 2 3 4>;
         };
      };

      port@1 {
         reg = <1>;
         #address-cells = <1>;

         #size-cells = <0>;

         dphy_rx0_out: endpoint@0 {
            reg = <0>;
            remote-endpoint = <&isp0_mipi_in>;
         };
      };
   };
};

&rkisp1_0 {
   status = "okay";


   port {
      #address-cells = <1>;
      #size-cells = <0>;
      isp0_mipi_in: endpoint@0 {
         reg = <0>;

         remote-endpoint = <&dphy_rx0_out>;
      };
   };
};

(2) Настройка HDMI2DSI

Используйте настройку преобразования HDMI2DSI из раздела 2.4.5.

7.2.2.2 Настройка Android

(1) HDMI2CSI: используйте настройку одного тракта RK628 HDMI2CSI и правильно настройте camera3_profiles.xml.

(2) HDMI2DSI: настройка со стороны Android не требуется.

Другие статьи по теме → · Учебные маршруты →