RK3588 HDMIIN-Debugging (HDMI zu MIPI-CSI)

In diesem Dokument werden die Debugging- und Konfigurationsschritte der RK3588-Plattform HDMI zu MIPI-CSI vorgestellt. Im vorherigen Artikel wurde das Debuggen von RK356X HDMIIN vorgestellt, und in diesem Artikel wird das Debuggen auf der RK3588-Plattform vorgestellt. Zusätzlich zu seinem eigenen HDMIIN kann der RK3588 über einen Adapterchip auch HDMI-Signale in MIPI-CSI-Signale umwandeln und diese als kameraähnliches Gerät empfangen und verarbeiten.

Inhaltsverzeichnis

(1) Einführung häufig verwendeter Adapterchips für HDMI zu MIPICSI

1. LT6911UXC/LT6911UXE-Spezifikationen

2.IT6616

3.RK628D

(2) Debuggen des Adapter-Chip-Treibers

1. Treiberbezogene Schnittstellenkonfiguration

①lt6911uxe_get_detected_timings

②lt6911uxe_query_dv_timings

③lt6911uxe_g_mbus_config

④lt6911uxe_get_fmt

⑤Auflösungsänderungsereignis

⑥Bericht über das Trennereignis

2. DTS-Konfiguration

(3) Android HAL-Anpassung

(4) Zusammenfassung


(1) Einführung häufig verwendeter Adapterchips für HDMI zu MIPICSI

Im vorherigen Artikel wurden die Spezifikationen von RK3588 MIPI-CSI vorgestellt. Insgesamt gibt es vier 4-spurige MIPI-Schnittstellen. Die DPHY-Rate kann 2,5 Gbit/s und die Gesamtbandbreite 10 Gbit/s erreichen, was bedeutet, dass 4K60 YUV422-Eingabe unterstützt werden kann. Ob HDMI 4K60 unterstützt werden kann, hängt hauptsächlich von der Spezifikation des MIPI TX DPHY des Adapterchips ab. Hier sind einige gängige Adapterchips.

1. LT6911UXC/LT6911UXE-Spezifikationen

LT6911UXC und LT6911UXE sind von Longxun entwickelte Bridge-Chips, die HDMI zu MIPI-CSI unterstützen.

LT6911UXC: Die Spezifikation von MIPI TX DPHY ist die DPHY1.2-Version, die maximale Rate beträgt 2,0 Gbit/s, ein einzelner MIPI-PORT (4 Lanes) unterstützt keine 4K60-Ausgabe und kann nur die Spezifikation von 4K30 erreichen. In dem Szenario, in dem zwei MIPI-PORTs insgesamt 8 Lanes haben, kann 4K60 ausgegeben werden (anscheinend unterstützt RK3588 diese Methode bereits).

LT6911UXE: Die MIPI TX DPHY-Spezifikation ist die DPHY1.2-Version, die maximale Rate beträgt 2,5 Gbit/s, ein einzelner MIPI-PORT (4 Lanes) unterstützt die 4K60-Ausgabe, durch die Anpassung an RK3588 kann ein MIPI DPHY-Port für die Hauptsteuerung eingespart werden.

2.IT6616

IT6616 ist ein von ITE entwickelter HDMI-zu-MIPI-CSI-Brückenchip. Die DPHY-Rate beträgt bis zu 2,0 Gbit/s, unterstützt HDMI1.4 und kann 4K30 YUV422MIPI-Ausgabe unterstützen, aber nicht 4K60 YUV422.

3.RK628D

RK628D ist ein von RK entwickelter Bridge-Chip. Er unterstützt HDMI1.4, die MIPI TX DPHY-Rate beträgt 1,2 Gbit/s und unterstützt den MIPI TX-Ausgang YUV422 4K30.

(2) Debuggen des Adapter-Chip-Treibers

Der HDMI-zu-MIPI-CSI-Adapterchip kann als kameraähnliches Gerät behandelt, basierend auf dem V4L2-Framework implementiert und mit dem VICAP-Controller von RK3588 verbunden werden. Nehmen Sie hier als Beispiel LT6911UXE.

1. Treiberbezogene Schnittstellenkonfiguration

Die relevante Schnittstelle des Treibers entspricht in etwa der der Kamera, und die Hauptschnittstellenkonfiguration ist wie folgt:

①lt6911uxe_get_detected_timings

Erhalten Sie das Timing der vom Adapterchip erkannten Eingangsquelle. Im Allgemeinen ruft die Interrupt-Funktion diese Funktion auf.

②lt6911uxe_query_dv_timings

Fragen Sie das entsprechende Timing ab und stellen Sie Informationen wie die Abfrageauflösung für Anwendungen der oberen Ebene bereit.

static int lt6911uxe_query_dv_timings(struct v4l2_subdev *sd,
				struct v4l2_dv_timings *timings)
{
	struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);

	*timings = lt6911uxe->timings;
	if (debug)
		v4l2_print_dv_timings(sd->name,
				"query_dv_timings: ", timings, false);

	if (!v4l2_valid_dv_timings(timings, &lt6911uxe_timings_cap, NULL,
				NULL)) {
		v4l2_dbg(1, debug, sd, "%s: timings out of range\n",
				__func__);

		return -ERANGE;
	}

	return 0;
}

③lt6911uxe_g_mbus_config

Die Einstellung busbezogener Informationen, der Anzahl der Spuren, der Anzahl der Kanäle usw.

static int lt6911uxe_g_mbus_config(struct v4l2_subdev *sd,
			unsigned int pad, struct v4l2_mbus_config *cfg)
{
	struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);
	u32 lane_num = lt6911uxe->bus_cfg.bus.mipi_csi2.num_data_lanes;
	u32 val = 0;

	val = 1 << (lane_num - 1) |
		V4L2_MBUS_CSI2_CHANNEL_0 |
		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;

	cfg->type = lt6911uxe->bus_cfg.bus_type;
	cfg->flags = val;

	return 0;
}

④lt6911uxe_get_fmt

Erhalten Sie relevante Auflösungsinformationen usw.

static int lt6911uxe_get_fmt(struct v4l2_subdev *sd,
			struct v4l2_subdev_pad_config *cfg,
			struct v4l2_subdev_format *format)
{
	struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);
	const struct lt6911uxe_mode *mode;

	mutex_lock(&lt6911uxe->confctl_mutex);
	format->format.code = lt6911uxe->mbus_fmt_code;
	format->format.width = lt6911uxe->timings.bt.width;
	format->format.height = lt6911uxe->timings.bt.height;
	format->format.field =
		lt6911uxe->timings.bt.interlaced ?
		V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
	format->format.colorspace = V4L2_COLORSPACE_SRGB;
	mutex_unlock(&lt6911uxe->confctl_mutex);

	mode = lt6911uxe_find_best_fit(lt6911uxe);
	lt6911uxe->cur_mode = mode;

	__v4l2_ctrl_s_ctrl_int64(lt6911uxe->pixel_rate,
				LT6911UXE_PIXEL_RATE);
	__v4l2_ctrl_s_ctrl(lt6911uxe->link_freq,
				mode->mipi_freq_idx);

	v4l2_dbg(1, debug, sd, "%s: mode->mipi_freq_idx(%d)", __func__, mode->mipi_freq_idx);

	v4l2_dbg(1, debug, sd, "%s: fmt code:%d, w:%d, h:%d, field code:%d\n",
			__func__, format->format.code, format->format.width,
			format->format.height, format->format.field);

	return 0;
}

⑤Auflösungsänderungsereignis

Der größte Unterschied zwischen dem HDMI-zu-MIPI-CSI-Treiber und dem herkömmlichen Kameratreiber besteht darin, dass der Treiber die Änderung der Auflösung der Eingangsquelle und die Änderung beim Ein- und Ausstecken erkennen und dies in Form einer Meldung melden muss Ereignis. Nachdem die Anwendung ein Ereignis empfangen hat, muss sie eine neue Auflösungsvorschau verwenden.

Ereignisabonnement: Auflösungsänderungen registrieren bzw. Ereignisse entfernen.

static int lt6911uxe_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
				    struct v4l2_event_subscription *sub)
{
	switch (sub->type) {
	case V4L2_EVENT_SOURCE_CHANGE:
		return v4l2_src_change_event_subdev_subscribe(sd, fh, sub);
	case V4L2_EVENT_CTRL:
		return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);
	default:
		return -EINVAL;
	}
}

Das Auflösungsänderungsereignis wird im Allgemeinen im Auflösungsänderungsinterrupt gemeldet, und die Schnittstelle v4l2_subdev_notify_event meldet das Ereignis.

static void lt6911uxe_format_change(struct v4l2_subdev *sd)
{
	struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);
	struct v4l2_dv_timings timings;
	const struct v4l2_event lt6911uxe_ev_fmt = {
		.type = V4L2_EVENT_SOURCE_CHANGE,
		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
	};

	if (lt6911uxe_get_detected_timings(sd, &timings)) {
		enable_stream(sd, false);
		v4l2_dbg(1, debug, sd, "%s: No signal\n", __func__);
	}

	if (!v4l2_match_dv_timings(&lt6911uxe->timings, &timings, 0, false)) {
		enable_stream(sd, false);
		/* automatically set timing rather than set by user */
		lt6911uxe_s_dv_timings(sd, &timings);
		v4l2_print_dv_timings(sd->name,
				"Format_change: New format: ",
				&timings, false);
		if (sd->devnode && !lt6911uxe->i2c_client->irq)
			v4l2_subdev_notify_event(sd, &lt6911uxe_ev_fmt);
	}
	if (sd->devnode && lt6911uxe->i2c_client->irq)
		v4l2_subdev_notify_event(sd, &lt6911uxe_ev_fmt);
}

⑥Bericht über das Trennereignis

Das Unplugging-Ereignis wird über die folgende Schnittstelle festgelegt. Wenn sich die Variable ändert, wird das Ereignis gemeldet. Im Allgemeinen muss der Treiber eine Unplugging-Erkennung implementieren. Die aktuelle Methode besteht darin, die 5 V von HDMI an den IO von RK3588 anzuschließen und zu verwenden io-Status zur Erkennung von Abziehaktionen.

static int lt6911uxe_s_ctrl_detect_tx_5v(struct v4l2_subdev *sd)
{
	struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);

	return v4l2_ctrl_s_ctrl(lt6911uxe->detect_tx_5v_ctrl,
			tx_5v_power_present(sd));
}

2. DTS-Konfiguration

Die Schlüsselkonfiguration des DTS-Links lautet wie folgt: lt6911uxe-> csi2_dphy -> mipi2_csi2 -> rkcif_mipi_lvds2.

&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 = <&lt6911uxe_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";
};

&i2c3 {
	status = "okay";

	lt6911uxe_1: lt6911uxe_1@2b {
		compatible = "lontium,lt6911uxe";
		status = "okay";
		reg = <0x2b>;
		clocks = <&ext_cam_clk>;
		clock-names = "xvclk";
		power-domains = <&power RK3588_PD_VI>;
		pinctrl-names = "default";
		pinctrl-0 = <&lt6911uxe_pin_1>;
		interrupt-parent = <&gpio1>;
		interrupts = <RK_PB3 IRQ_TYPE_LEVEL_LOW>;
		// reset-gpios = <&gpio1 RK_PB1 GPIO_ACTIVE_LOW>;
		// power-gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_HIGH>;
		plugin-det-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_HIGH>;
		rockchip,camera-module-index = <0>;
		rockchip,camera-module-facing = "back";
		rockchip,camera-module-name = "HDMI-MIPI2";
		rockchip,camera-module-lens-name = "LT6911UXE-2";
		port {
			lt6911uxe_out1: endpoint {
				remote-endpoint = <&hdmi_mipi2_in>;
				data-lanes = <1 2 3 4>;
			};
		};
	};
};

&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";
};

&pinctrl {
	hdmiin {

		lt6911uxe_pin_1: lt6911uxe-pin-1 {
			rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>,
					<1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
		};
	};
};

(3) Android HAL-Anpassung

Die Anpassung von cameraHAL erfordert das Hinzufügen relevanter Konfigurationen in camera3_profiles.xml.

Der Name muss mit dem Namen des Treibers übereinstimmen. moduleid muss mit dem von dts konfigurierten Index übereinstimmen.

Unterstützte Auflösungen und Bildraten müssen hinzugefügt werden:

 Im SOC-Modus konfiguriert, ist kein Debuggen des Effekts über ISP erforderlich.

(4) Zusammenfassung

Auf der RK3588-Plattform ähnelt das HDMI-zu-MIPI-CSI-Debugging dem Kamera-Debugging. Der Treiber ist nichts anderes als das Hinzufügen eines Ereignisberichtsmechanismus für Änderungen der HDMI-Quellenauflösung oder das Ein- und Ausstecken, und dann verarbeitet die Anwendung die entsprechenden Ereignisse.

Supongo que te gusta

Origin blog.csdn.net/qq_34341546/article/details/129009091
Recomendado
Clasificación