[PATCH 2/3] drm/bridge/sii8620: Fix display of packed pixel modes
Current implementation does not guarantee packed pixel modes working with every dongle. There are some dongles, which require selecting the output mode explicitly. Write proper values to registers in packed_pixel mode, based on how it is done in vendor's code. Select output color space: RGB (no packed pixel) or YCBCR422 (packed pixel). This reverts commit e8b92efa629dac0e70ea4145c5e70616de5f89c8 ("drm/bridge/sii8620: fix display of packed pixel modes in MHL2"). Signed-off-by: Maciej Purski --- drivers/gpu/drm/bridge/sil-sii8620.c | 17 - 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index bd30ccf..16fe7ea 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -1015,21 +1015,36 @@ static void sii8620_stop_video(struct sii8620 *ctx) static void sii8620_set_format(struct sii8620 *ctx) { + u8 out_fmt; + if (sii8620_is_mhl3(ctx)) { sii8620_setbits(ctx, REG_M3_P0CTRL, BIT_M3_P0CTRL_MHL3_P0_PIXEL_MODE_PACKED, ctx->use_packed_pixel ? ~0 : 0); } else { + if (ctx->use_packed_pixel) { + sii8620_write_seq_static(ctx, + REG_VID_MODE, BIT_VID_MODE_M1080P, + REG_MHL_TOP_CTL, BIT_MHL_TOP_CTL_MHL_PP_SEL | 1, + REG_MHLTX_CTL6, 0x60 + ); + } else { sii8620_write_seq_static(ctx, REG_VID_MODE, 0, REG_MHL_TOP_CTL, 1, REG_MHLTX_CTL6, 0xa0 ); + } } + if (ctx->use_packed_pixel) + out_fmt = VAL_TPI_FORMAT(YCBCR422, FULL); + else + out_fmt = VAL_TPI_FORMAT(RGB, FULL); + sii8620_write_seq(ctx, REG_TPI_INPUT, VAL_TPI_FORMAT(RGB, FULL), - REG_TPI_OUTPUT, VAL_TPI_FORMAT(RGB, FULL), + REG_TPI_OUTPUT, out_fmt, ); } -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/3] drm/bridge/sii8620: Fix link mode selection
Current link mode values do not allow to enable packed pixel modes. Select packed pixel clock mode, if needed, every time the link mode register gets updated. Signed-off-by: Maciej Purski --- drivers/gpu/drm/bridge/sil-sii8620.c | 30 -- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 16fe7ea..a6e8f45 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -1165,8 +1165,14 @@ static void sii8620_start_video(struct sii8620 *ctx) sii8620_set_format(ctx); if (!sii8620_is_mhl3(ctx)) { - sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE), - MHL_DST_LM_CLK_MODE_NORMAL | MHL_DST_LM_PATH_ENABLED); + u8 link_mode = MHL_DST_LM_PATH_ENABLED; + + if (ctx->use_packed_pixel) + link_mode |= MHL_DST_LM_CLK_MODE_PACKED_PIXEL; + else + link_mode |= MHL_DST_LM_CLK_MODE_NORMAL; + + sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE), link_mode); sii8620_set_auto_zone(ctx); } else { static const struct { @@ -1677,14 +1683,18 @@ static void sii8620_status_dcap_ready(struct sii8620 *ctx) static void sii8620_status_changed_path(struct sii8620 *ctx) { - if (ctx->stat[MHL_DST_LINK_MODE] & MHL_DST_LM_PATH_ENABLED) { - sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE), - MHL_DST_LM_CLK_MODE_NORMAL - | MHL_DST_LM_PATH_ENABLED); - } else { - sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE), - MHL_DST_LM_CLK_MODE_NORMAL); - } + u8 link_mode; + + if (ctx->use_packed_pixel) + link_mode = MHL_DST_LM_CLK_MODE_PACKED_PIXEL; + else + link_mode = MHL_DST_LM_CLK_MODE_NORMAL; + + if (ctx->stat[MHL_DST_LINK_MODE] & MHL_DST_LM_PATH_ENABLED) + link_mode |= MHL_DST_LM_PATH_ENABLED; + + sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE), + link_mode); } static void sii8620_msc_mr_write_stat(struct sii8620 *ctx) -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/3] Fix packed pixel modes display on MHL2
Hi all, this patchset is a next attempt to fix packed pixel modes display on MHL2. It appeared, that the current implementation does not work well with every dongle. Thanks to bigger number of test devices I managed to prepare a patchset, which should finally fix display of packed pixel modes on MHL2, while not breaking it on MHL3. Best regards, Maciej Purski Maciej Purski (3): drm/bridge/sii8620: Send AVI infoframe in all MHL versions drm/bridge/sii8620: Fix display of packed pixel modes drm/bridge/sii8620: Fix link mode selection drivers/gpu/drm/bridge/sil-sii8620.c | 86 +++- 1 file changed, 55 insertions(+), 31 deletions(-) -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/3] drm/bridge/sii8620: Send AVI infoframe in all MHL versions
Currently AVI infoframe is sent only in MHL3. However, some MHL2 dongles need AVI infoframe to work correctly in either packed pixel mode or non-packed pixel mode. Send AVI infoframe in set_infoframes() in every case. Create an infoframe using drm_hdmi_infoframe_from_display_mode() instead of manually filling each infoframe structure's field. Signed-off-by: Maciej Purski --- drivers/gpu/drm/bridge/sil-sii8620.c | 39 ++-- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 250effa..bd30ccf 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -72,9 +73,7 @@ struct sii8620 { struct regulator_bulk_data supplies[2]; struct mutex lock; /* context lock, protects fields below */ int error; - int pixel_clock; unsigned int use_packed_pixel:1; - int video_code; enum sii8620_mode mode; enum sii8620_sink_type sink_type; u8 cbus_status; @@ -82,7 +81,6 @@ struct sii8620 { u8 xstat[MHL_XDS_SIZE]; u8 devcap[MHL_DCAP_SIZE]; u8 xdevcap[MHL_XDC_SIZE]; - u8 avif[HDMI_INFOFRAME_SIZE(AVI)]; bool feature_complete; bool devcap_read; bool sink_detected; @@ -1082,18 +1080,28 @@ static ssize_t mhl3_infoframe_pack(struct mhl3_infoframe *frame, return frm_len; } -static void sii8620_set_infoframes(struct sii8620 *ctx) +static void sii8620_set_infoframes(struct sii8620 *ctx, + struct drm_display_mode *mode) { struct mhl3_infoframe mhl_frm; union hdmi_infoframe frm; u8 buf[31]; int ret; + ret = drm_hdmi_avi_infoframe_from_display_mode(, + mode, + true); + if (ctx->use_packed_pixel) + frm.avi.colorspace = HDMI_COLORSPACE_YUV422; + + if (!ret) + ret = hdmi_avi_infoframe_pack(, buf, ARRAY_SIZE(buf)); + if (ret > 0) + sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, buf + 3, ret - 3); + if (!sii8620_is_mhl3(ctx) || !ctx->use_packed_pixel) { sii8620_write(ctx, REG_TPI_SC, BIT_TPI_SC_TPI_OUTPUT_MODE_0_HDMI); - sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, ctx->avif + 3, - ARRAY_SIZE(ctx->avif) - 3); sii8620_write(ctx, REG_PKT_FILTER_0, BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT | BIT_PKT_FILTER_0_DROP_MPEG_PKT | @@ -1102,16 +1110,6 @@ static void sii8620_set_infoframes(struct sii8620 *ctx) return; } - ret = hdmi_avi_infoframe_init(); - frm.avi.colorspace = HDMI_COLORSPACE_YUV422; - frm.avi.active_aspect = HDMI_ACTIVE_ASPECT_PICTURE; - frm.avi.picture_aspect = HDMI_PICTURE_ASPECT_16_9; - frm.avi.colorimetry = HDMI_COLORIMETRY_ITU_709; - frm.avi.video_code = ctx->video_code; - if (!ret) - ret = hdmi_avi_infoframe_pack(, buf, ARRAY_SIZE(buf)); - if (ret > 0) - sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, buf + 3, ret - 3); sii8620_write(ctx, REG_PKT_FILTER_0, BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT | BIT_PKT_FILTER_0_DROP_MPEG_PKT | @@ -1131,6 +1129,9 @@ static void sii8620_set_infoframes(struct sii8620 *ctx) static void sii8620_start_video(struct sii8620 *ctx) { + struct drm_display_mode *mode = + >bridge.encoder->crtc->state->adjusted_mode; + if (!sii8620_is_mhl3(ctx)) sii8620_stop_video(ctx); @@ -1167,7 +1168,7 @@ static void sii8620_start_video(struct sii8620 *ctx) MHL_XDS_LINK_RATE_6_0_GBPS, 0x40 }, }; u8 p0_ctrl = BIT_M3_P0CTRL_MHL3_P0_PORT_EN; - int clk = ctx->pixel_clock * (ctx->use_packed_pixel ? 2 : 3); + int clk = mode->clock * (ctx->use_packed_pixel ? 2 : 3); int i; for (i = 0; i < ARRAY_SIZE(clk_spec) - 1; ++i) @@ -1196,7 +1197,7 @@ static void sii8620_start_video(struct sii8620 *ctx) clk_spec[i].link_rate); } - sii8620_set_infoframes(ctx); + sii8620_set_infoframes(ctx, mode); } static void sii8620_disable_hpd(struct sii8620 *ctx) @@ -2242,8 +2243,6 @@ static bool sii8620_mode_fixup(struct drm_bridge *bridge, mutex_lock(>lock); ctx->use_packed_pixel = sii8620_is_packing_required(ctx, adjusted_mode); - ctx->video_code = drm_match_cea_mode(adjusted_mode); - ctx->pixel_clock = adjusted_mode->clock; mutex_unlock(>lock); -- 2.7.4
[PATCH v3 4/9] dt-bindings: display: add DT bindings for BOE HV070WSA-100 panel
From: Andrzej Hajda The patch adds bindings to BOE HV070-WSA WSVGA panel. Bindings are compatible with simple panel bindings. Signed-off-by: Andrzej Hajda Signed-off-by: Maciej Purski --- .../bindings/display/panel/boe,hv070wsa-100.txt| 28 ++ 1 file changed, 28 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt diff --git a/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt b/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt new file mode 100644 index 000..9e8eea8 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt @@ -0,0 +1,28 @@ +BOE HV070WSA-100 7.01" WSVGA TFT LCD panel + +Required properties: +- compatible: should be "boe,hv070wsa-100" +- power-supply: regulator to provide the VCC supply voltage (3.3 volts) +- enable-gpio: GPIO pin to enable and disable panel (active high) + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. + +The device node can contain one 'port' child node with one child +'endpoint' node, according to the bindings defined in [1]. This +node should describe panel's video bus. + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt + +Example: + + panel: panel { + compatible = "boe,hv070wsa-100"; + power-supply = <_3v3_reg>; + enable-gpios = < 3 GPIO_ACTIVE_HIGH>; + port { + panel_ep: endpoint { + remote-endpoint = <_out_ep>; + }; + }; + }; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 1/9] drm/exynos: rename "bridge_node" to "mic_bridge_node"
When adding support for peripheral out bridges, the "bridge" name becomes imprecise as it refers to a different device than the "out_bridge". Signed-off-by: Maciej Purski --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index eae44fd..9599e6b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -279,7 +279,7 @@ struct exynos_dsi { struct list_head transfer_list; const struct exynos_dsi_driver_data *driver_data; - struct device_node *bridge_node; + struct device_node *mic_bridge_node; }; #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host) @@ -1631,7 +1631,7 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi) if (ret < 0) return ret; - dsi->bridge_node = of_graph_get_remote_node(node, DSI_PORT_IN, 0); + dsi->mic_bridge_node = of_graph_get_remote_node(node, DSI_PORT_IN, 0); return 0; } @@ -1642,7 +1642,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master, struct drm_encoder *encoder = dev_get_drvdata(dev); struct exynos_dsi *dsi = encoder_to_dsi(encoder); struct drm_device *drm_dev = data; - struct drm_bridge *bridge; + struct drm_bridge *mic_bridge; int ret; drm_encoder_init(drm_dev, encoder, _dsi_encoder_funcs, @@ -1661,10 +1661,10 @@ static int exynos_dsi_bind(struct device *dev, struct device *master, return ret; } - if (dsi->bridge_node) { - bridge = of_drm_find_bridge(dsi->bridge_node); - if (bridge) - drm_bridge_attach(encoder, bridge, NULL); + if (dsi->mic_bridge_node) { + mic_bridge = of_drm_find_bridge(dsi->mic_bridge_node); + if (mic_bridge) + drm_bridge_attach(encoder, mic_bridge, NULL); } return mipi_dsi_host_register(>dsi_host); @@ -1783,7 +1783,7 @@ static int exynos_dsi_remove(struct platform_device *pdev) { struct exynos_dsi *dsi = platform_get_drvdata(pdev); - of_node_put(dsi->bridge_node); + of_node_put(dsi->mic_bridge_node); pm_runtime_disable(>dev); -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 7/9] drm/bridge: tc358764: Add DSI to LVDS bridge driver
From: Andrzej Hajda Add a drm_bridge driver for the Toshiba TC358764 DSI to LVDS bridge. Signed-off-by: Andrzej Hajda Signed-off-by: Maciej Purski --- drivers/gpu/drm/bridge/Kconfig| 8 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/tc358764.c | 521 ++ 3 files changed, 530 insertions(+) create mode 100644 drivers/gpu/drm/bridge/tc358764.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index fa2c799..f3da8a7 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -110,6 +110,14 @@ config DRM_THINE_THC63LVD1024 ---help--- Thine THC63LVD1024 LVDS/parallel converter driver. +config DRM_TOSHIBA_TC358764 + tristate "TC358764 DSI/LVDS bridge" + depends on DRM && DRM_PANEL + depends on OF + select DRM_MIPI_DSI + help + Toshiba TC358764 DSI/LVDS bridge driver. + config DRM_TOSHIBA_TC358767 tristate "Toshiba TC358767 eDP bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 35f88d4..bf7c0ce 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o obj-$(CONFIG_DRM_SII902X) += sii902x.o obj-$(CONFIG_DRM_SII9234) += sii9234.o obj-$(CONFIG_DRM_THINE_THC63LVD1024) += thc63lvd1024.o +obj-$(CONFIG_DRM_TOSHIBA_TC358764) += tc358764.o obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ diff --git a/drivers/gpu/drm/bridge/tc358764.c b/drivers/gpu/drm/bridge/tc358764.c new file mode 100644 index 000..0aee155 --- /dev/null +++ b/drivers/gpu/drm/bridge/tc358764.c @@ -0,0 +1,521 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Samsung Electronics Co., Ltd + * + * Authors: + * Andrzej Hajda + * Maciej Purski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. + * + */ + +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#define FLD_MASK(start, end)(((1 << ((start) - (end) + 1)) - 1) << (end)) +#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) + +/* PPI layer registers */ +#define PPI_STARTPPI 0x0104 /* START control bit */ +#define PPI_LPTXTIMECNT0x0114 /* LPTX timing signal */ +#define PPI_LANEENABLE 0x0134 /* Enables each lane */ +#define PPI_TX_RX_TA 0x013C /* BTA timing parameters */ +#define PPI_D0S_CLRSIPOCOUNT 0x0164 /* Assertion timer for Lane 0 */ +#define PPI_D1S_CLRSIPOCOUNT 0x0168 /* Assertion timer for Lane 1 */ +#define PPI_D2S_CLRSIPOCOUNT 0x016C /* Assertion timer for Lane 2 */ +#define PPI_D3S_CLRSIPOCOUNT 0x0170 /* Assertion timer for Lane 3 */ +#define PPI_START_FUNCTION 1 + +/* DSI layer registers */ +#define DSI_STARTDSI 0x0204 /* START control bit of DSI-TX */ +#define DSI_LANEENABLE 0x0210 /* Enables each lane */ +#define DSI_RX_START 1 + +/* Video path registers */ +#define VP_CTRL0x0450 /* Video Path Control */ +#define VP_CTRL_MSF(v) FLD_VAL(v, 0, 0) /* Magic square in RGB666 */ +#define VP_CTRL_VTGEN(v) FLD_VAL(v, 4, 4) /* Use chip clock for timing */ +#define VP_CTRL_EVTMODE(v) FLD_VAL(v, 5, 5) /* Event mode */ +#define VP_CTRL_RGB888(v) FLD_VAL(v, 8, 8) /* RGB888 mode */ +#define VP_CTRL_VSDELAY(v) FLD_VAL(v, 31, 20) /* VSYNC delay */ +#define VP_CTRL_HSPOL BIT(17) /* Polarity of HSYNC signal */ +#define VP_CTRL_DEPOL BIT(18) /* Polarity of DE signal */ +#define VP_CTRL_VSPOL BIT(19) /* Polarity of VSYNC signal */ +#define VP_HTIM1 0x0454 /* Horizontal Timing Control 1 */ +#define VP_HTIM1_HBP(v)FLD_VAL(v, 24, 16) +#define VP_HTIM1_HSYNC(v) FLD_VAL(v, 8, 0) +#define VP_HTIM2 0x0458 /* Horizontal Timing Control 2 */ +#define VP_HTIM2_HFP(v)FLD_VAL(v, 24, 16) +#define VP_HTIM2_HACT(v) FLD_VAL(v, 10, 0) +#define VP_VTIM1 0x045C /* Vertical Timing Control 1 */ +#define VP_VTIM1_VBP(v)FLD_VAL(v, 23, 16) +#define VP_VTIM1_VSYNC(v) FLD_VAL(v, 7, 0) +#define VP_VTIM2 0x0460 /* Vertical Timing Control 2 */ +#define VP_VTIM2_VFP(v)
[PATCH v3 9/9] ARM: dts: exynos5250-arndale: add DSI and panel nodes
From: Andrzej Hajda The patch adds bridge and panel nodes. It adds also DSI properties specific for arndale board and regulators required by the bridge. Signed-off-by: Andrzej Hajda Signed-off-by: Maciej Purski --- arch/arm/boot/dts/exynos5250-arndale.dts | 61 1 file changed, 61 insertions(+) diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index 7a8a5c5..816d89d 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -71,6 +71,17 @@ }; }; + panel: panel { + compatible = "boe,hv070wsa-100"; + power-supply = <_3v3_reg>; + enable-gpios = < 3 GPIO_ACTIVE_HIGH>; + port { + panel_ep: endpoint { + remote-endpoint = <_out_ep>; + }; + }; + }; + regulators { compatible = "simple-bus"; #address-cells = <1>; @@ -97,6 +108,30 @@ reg = <2>; regulator-name = "hdmi-en"; }; + + vcc_1v2_reg: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "VCC_1V2"; + regulator-min-microvolt = <120>; + regulator-max-microvolt = <120>; + }; + + vcc_1v8_reg: regulator@4 { + compatible = "regulator-fixed"; + reg = <4>; + regulator-name = "VCC_1V8"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + }; + + vcc_3v3_reg: regulator@5 { + compatible = "regulator-fixed"; + reg = <5>; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + }; }; fixed-rate-clocks { @@ -119,6 +154,32 @@ cpu0-supply = <_reg>; }; +_0 { + vddcore-supply = <_reg>; + vddio-supply = <_reg>; + samsung,pll-clock-frequency = <2400>; + samsung,burst-clock-frequency = <32000>; + samsung,esc-clock-frequency = <1000>; + status = "okay"; + + bridge@0 { + reg = <0>; + compatible = "toshiba,tc358764"; + vddc-supply = <_1v2_reg>; + vddio-supply = <_1v8_reg>; + vddlvds-supply = <_3v3_reg>; + reset-gpios = < 6 GPIO_ACTIVE_LOW>; + #address-cells = <1>; + #size-cells = <0>; + port@1 { + reg = <1>; + bridge_out_ep: endpoint { + remote-endpoint = <_ep>; + }; + }; + }; +}; + { status = "okay"; samsung,color-space = <0>; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 2/9] drm/exynos: move connector creation to attach callback
The current implementation assumes that the only possible peripheral device for DSIM is a panel. Using an output bridge child device should also be possible. If an output bridge is available, don't create a new connector. Instead, call drm_bridge_attach() and set encoder's bridge to NULL in order to avoid an out bridge from being visible by the framework, as the DSI bus needs control on enabling its child output bridge. Such sequence is required by Toshiba TC358764 bridge, which is a DSI peripheral bridge device. Signed-off-by: Maciej Purski --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 38 ++--- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 9599e6b..c0408c0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -255,6 +255,7 @@ struct exynos_dsi { struct mipi_dsi_host dsi_host; struct drm_connector connector; struct drm_panel *panel; + struct drm_bridge *out_bridge; struct device *dev; void __iomem *reg_base; @@ -1499,7 +1500,30 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct exynos_dsi *dsi = host_to_dsi(host); - struct drm_device *drm = dsi->connector.dev; + struct drm_encoder *encoder = >encoder; + struct drm_device *drm = encoder->dev; + struct drm_bridge *out_bridge; + + out_bridge = of_drm_find_bridge(device->dev.of_node); + if (out_bridge) { + drm_bridge_attach(encoder, out_bridge, NULL); + dsi->out_bridge = out_bridge; + encoder->bridge = NULL; + } else { + int ret = exynos_dsi_create_connector(encoder); + + if (ret) { + DRM_ERROR("failed to create connector ret = %d\n", ret); + drm_encoder_cleanup(encoder); + return ret; + } + + dsi->panel = of_drm_find_panel(device->dev.of_node); + if (dsi->panel) { + drm_panel_attach(dsi->panel, >connector); + dsi->connector.status = connector_status_connected; + } + } /* * This is a temporary solution and should be made by more generic way. @@ -1518,11 +1542,6 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, dsi->lanes = device->lanes; dsi->format = device->format; dsi->mode_flags = device->mode_flags; - dsi->panel = of_drm_find_panel(device->dev.of_node); - if (dsi->panel) { - drm_panel_attach(dsi->panel, >connector); - dsi->connector.status = connector_status_connected; - } exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode = !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO); @@ -1654,13 +1673,6 @@ static int exynos_dsi_bind(struct device *dev, struct device *master, if (ret < 0) return ret; - ret = exynos_dsi_create_connector(encoder); - if (ret) { - DRM_ERROR("failed to create connector ret = %d\n", ret); - drm_encoder_cleanup(encoder); - return ret; - } - if (dsi->mic_bridge_node) { mic_bridge = of_drm_find_bridge(dsi->mic_bridge_node); if (mic_bridge) -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 3/9] drm/exynos: enable out_bridge in exynos_dsi_enable()
As the out bridge will not be enabled directly by the framework, it should be enabled by DSI. Exynos_dsi_enable() should handle a case, when there is an out_bridge connected as a DSI peripheral. Signed-off-by: Maciej Purski --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 34 + 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index c0408c0..8aa7ace 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1386,25 +1386,33 @@ static void exynos_dsi_enable(struct drm_encoder *encoder) dsi->state |= DSIM_STATE_ENABLED; - ret = drm_panel_prepare(dsi->panel); - if (ret < 0) { - dsi->state &= ~DSIM_STATE_ENABLED; - pm_runtime_put_sync(dsi->dev); - return; + if (dsi->panel) { + ret = drm_panel_prepare(dsi->panel); + if (ret < 0) { + dsi->state &= ~DSIM_STATE_ENABLED; + return; + } } + if (dsi->out_bridge) + drm_bridge_pre_enable(dsi->out_bridge); + exynos_dsi_set_display_mode(dsi); exynos_dsi_set_display_enable(dsi, true); - ret = drm_panel_enable(dsi->panel); - if (ret < 0) { - dsi->state &= ~DSIM_STATE_ENABLED; - exynos_dsi_set_display_enable(dsi, false); - drm_panel_unprepare(dsi->panel); - pm_runtime_put_sync(dsi->dev); - return; + if (dsi->panel) { + ret = drm_panel_enable(dsi->panel); + if (ret < 0) { + dsi->state &= ~DSIM_STATE_ENABLED; + exynos_dsi_set_display_enable(dsi, false); + drm_panel_unprepare(dsi->panel); + return; + } } + if (dsi->out_bridge) + drm_bridge_enable(dsi->out_bridge); + dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE; } @@ -1418,8 +1426,10 @@ static void exynos_dsi_disable(struct drm_encoder *encoder) dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE; drm_panel_disable(dsi->panel); + drm_bridge_disable(dsi->out_bridge); exynos_dsi_set_display_enable(dsi, false); drm_panel_unprepare(dsi->panel); + drm_bridge_post_disable(dsi->out_bridge); dsi->state &= ~DSIM_STATE_ENABLED; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 8/9] ARM: dts: exynos5250: add DSI node
From: Andrzej Hajda The patch adds common part of DSI node for Exynos5250 platforms and a required mipi-phy node. Signed-off-by: Andrzej Hajda Signed-off-by: Maciej Purski --- arch/arm/boot/dts/exynos5250.dtsi | 21 + 1 file changed, 21 insertions(+) diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 2daf505..9965eca 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -733,6 +733,27 @@ #phy-cells = <0>; }; + mipi_phy: video-phy@10040710 { + compatible = "samsung,s5pv210-mipi-video-phy"; + reg = <0x10040710 0x100>; + #phy-cells = <1>; + syscon = <_system_controller>; + }; + + dsi_0: dsi@1450 { + compatible = "samsung,exynos4210-mipi-dsi"; + reg = <0x1450 0x1>; + interrupts = ; + samsung,power-domain = <_disp1>; + phys = <_phy 3>; + phy-names = "dsim"; + clocks = < CLK_DSIM0>, < CLK_SCLK_MIPI1>; + clock-names = "bus_clk", "sclk_mipi"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + adc: adc@12d1 { compatible = "samsung,exynos-adc-v1"; reg = <0x12D1 0x100>; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 5/9] drm/panel: add support for BOE HV070WSA-100 panel to simple-panel
From: Andrzej Hajda The patch adds support for BOE HV070WSA-100 WSVGA 7.01 inch panel in panel-simple driver. The panel is used in Exynos5250-arndale boards. Signed-off-by: Andrzej Hajda Signed-off-by: Maciej Purski --- drivers/gpu/drm/panel/panel-simple.c | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index cbf1ab4..d5da58d 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -745,6 +745,28 @@ static const struct panel_desc avic_tm070ddh03 = { }, }; +static const struct drm_display_mode boe_hv070wsa_mode = { + .clock = 40800, + .hdisplay = 1024, + .hsync_start = 1024 + 90, + .hsync_end = 1024 + 90 + 90, + .htotal = 1024 + 90 + 90 + 90, + .vdisplay = 600, + .vsync_start = 600 + 3, + .vsync_end = 600 + 3 + 4, + .vtotal = 600 + 3 + 4 + 3, + .vrefresh = 60, +}; + +static const struct panel_desc boe_hv070wsa = { + .modes = _hv070wsa_mode, + .num_modes = 1, + .size = { + .width = 154, + .height = 90, + }, +}; + static const struct drm_display_mode boe_nv101wxmn51_modes[] = { { .clock = 71900, @@ -2113,6 +2135,9 @@ static const struct of_device_id platform_of_match[] = { .compatible = "avic,tm070ddh03", .data = _tm070ddh03, }, { + .compatible = "boe,hv070wsa-100", + .data = _hv070wsa + }, { .compatible = "boe,nv101wxmn51", .data = _nv101wxmn51, }, { -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 6/9] dt-bindings: tc358754: add DT bindings
From: Andrzej Hajda The patch adds bindings to Toshiba DSI/LVDS bridge TC358764. Bindings describe power supplies, reset gpio and video interfaces. Signed-off-by: Andrzej Hajda Signed-off-by: Maciej Purski --- .../bindings/display/bridge/toshiba,tc358764.txt | 35 ++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt new file mode 100644 index 000..8f9abf2 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt @@ -0,0 +1,35 @@ +TC358764 MIPI-DSI to LVDS panel bridge + +Required properties: + - compatible: "toshiba,tc358764" + - reg: the virtual channel number of a DSI peripheral + - vddc-supply: core voltage supply, 1.2V + - vddio-supply: I/O voltage supply, 1.8V or 3.3V + - vddlvds-supply: LVDS1/2 voltage supply, 3.3V + - reset-gpios: a GPIO spec for the reset pin + +The device node can contain following 'port' child nodes, +according to the OF graph bindings defined in [1]: + 0: DSI Input, not required, if the bridge is DSI controlled + 1: LVDS Output, mandatory + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt + +Example: + + bridge@0 { + reg = <0>; + compatible = "toshiba,tc358764"; + vddc-supply = <_1v2_reg>; + vddio-supply = <_1v8_reg>; + vddlvds-supply = <_3v3_reg>; + reset-gpios = < 6 GPIO_ACTIVE_LOW>; + #address-cells = <1>; + #size-cells = <0>; + port@1 { + reg = <1>; + lvds_ep: endpoint { + remote-endpoint = <_ep>; + }; + }; + }; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 0/9] Add TOSHIBA TC358764 DSI/LVDS bridge driver
Hi all, this patchset is a next attempt to add the tc358764 driver. The previous one can be found here: https://lists.freedesktop.org/archives/dri-devel/2014-February/053705.html Back then, TC358764 was added as a panel driver. The bridge is supposed to be a DSI peripheral. Currently exynos_dsi accepts only panels as its peripherals. Therefore, some logic in exynos_dsi had to be ammended. That is implemented in first 3 patches. Apart from the driver this patchset adds support for BOE HV070WSA-100 panel, which is used by TC358764 and dts nodes to exynos5250.dtsi and exynos5250-arndale.dtsi. Best regards, Maciej Purski --- Changes in v3: - call drm_bridge_enable() and drm_bridge_pre_enable() in exynos_drm_dsi_enable() and make the bridge invisible for the framework in order to prevent it from being enabled by the framework - expand panel binding description - fix tc358744 binding, make port 1 mandatory and port 0 optional - get rid of useless select VIDEOMODE_HELPERS in bridge Kconfig - add missing SPDX license to drm/bridge/tc358764.c - use mipi_dsi_generic_read() and mipi_dsi_generic_write() helpers in toshiba driver's read, write functions - fix commit messages Changes in v2: - fix commits authorship - don't call pm_runtime_put_sync() in exyons_dsi_disable(), if pm_runtime_get_sync() has not been called - squash dts commits - merge some redundant regulators in tc358764 bindings and in DTS - fix kbuild robot errors Andrzej Hajda (6): dt-bindings: display: add DT bindings for BOE HV070WSA-100 panel drm/panel: add support for BOE HV070WSA-100 panel to simple-panel dt-bindings: tc358754: add DT bindings drm/bridge: tc358764: Add DSI to LVDS bridge driver ARM: dts: exynos5250: add DSI node ARM: dts: exynos5250-arndale: add DSI and panel nodes Maciej Purski (3): drm/exynos: rename "bridge_node" to "mic_bridge_node" drm/exynos: move connector creation to attach callback drm/exynos: enable out_bridge in exynos_dsi_enable() .../bindings/display/bridge/toshiba,tc358764.txt | 35 ++ .../bindings/display/panel/boe,hv070wsa-100.txt| 28 ++ arch/arm/boot/dts/exynos5250-arndale.dts | 61 +++ arch/arm/boot/dts/exynos5250.dtsi | 21 + drivers/gpu/drm/bridge/Kconfig | 8 + drivers/gpu/drm/bridge/Makefile| 1 + drivers/gpu/drm/bridge/tc358764.c | 521 + drivers/gpu/drm/exynos/exynos_drm_dsi.c| 88 ++-- drivers/gpu/drm/panel/panel-simple.c | 25 + 9 files changed, 755 insertions(+), 33 deletions(-) create mode 100644 Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt create mode 100644 Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt create mode 100644 drivers/gpu/drm/bridge/tc358764.c -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 07/10] dt-bindings: tc358754: add DT bindings
On 05/30/2018 02:36 PM, Laurent Pinchart wrote: > Hi Maciej, > > On Wednesday, 30 May 2018 15:15:58 EEST Maciej Purski wrote: >> From: Andrzej Hajda >> >> The patch adds bindings to Toshiba DSI/LVDS bridge TC358764. >> Bindings describe power supplies, reset gpio and video interfaces. >> >> Signed-off-by: Andrzej Hajda >> Signed-off-by: Maciej Purski >> --- >> .../bindings/display/bridge/toshiba,tc358764.txt | 37 +++ >> 1 file changed, 37 insertions(+) >> create mode 100644 >> Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt >> >> diff --git >> a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt >> b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt new >> file mode 100644 >> index 000..6eda14f >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt >> @@ -0,0 +1,37 @@ >> +TC358764 MIPI-DSI to LVDS panel bridge >> + >> +Required properties: >> + - compatible: "toshiba,tc358764" >> + - reg: the virtual channel number of a DSI peripheral >> + - vddc-supply: core voltage supply, 1.2V >> + - vddio-supply: I/O voltage supply, 1.8V or 3.3V >> + - vddlvds-supply: LVDS1/2 voltage supply, 3.3V >> + - reset-gpios: a GPIO spec for the reset pin >> + >> +The device node can contain zero to two 'port' child nodes, each with one >> +child 'endpoint' node, according to the bindings defined in [1]. >> +The following are properties specific to those nodes. >> + >> +port: >> + - reg: (required) can be 0 for DSI port or 1 for LVDS port; >> + >> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt > > Could you please take the comments I made on v1 into account when you'll post > v3 ? > For now I'm going to stick with the old convention and make port 0 optional, when the bridge is a DSI child and LVDS port 1 mandatory. The current policy does not seem to have been changed. There's a quiet new binding, which follows the old convention: Documentation/devicetree/bindings/connector/usb-connector.txt If you can find an example of new bindings, which follow your convention and you convince Rob, then I'll be completely okay with it and I'll change it the way you propose. >> +Example: >> + >> +bridge@0 { >> +reg = <0>; >> +compatible = "toshiba,tc358764"; >> +vddc-supply = <_1v2_reg>; >> +vddio-supply = <_1v8_reg>; >> +vddlvds-supply = <_3v3_reg>; >> +reset-gpios = < 6 GPIO_ACTIVE_LOW>; >> +#address-cells = <1>; >> +#size-cells = <0>; >> +port@1 { >> +reg = <1>; >> +lvds_ep: endpoint { >> +remote-endpoint = <_ep>; >> +}; >> +}; >> +}; > > Best regards, Maciej Purski ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 07/10] dt-bindings: tc358754: add DT bindings
On 05/31/2018 06:02 AM, Rob Herring wrote: > On Wed, May 30, 2018 at 02:15:58PM +0200, Maciej Purski wrote: >> From: Andrzej Hajda >> >> The patch adds bindings to Toshiba DSI/LVDS bridge TC358764. >> Bindings describe power supplies, reset gpio and video interfaces. >> >> Signed-off-by: Andrzej Hajda >> Signed-off-by: Maciej Purski >> --- >> .../bindings/display/bridge/toshiba,tc358764.txt | 37 >> ++ >> 1 file changed, 37 insertions(+) >> create mode 100644 >> Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt >> >> diff --git >> a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt >> b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt >> new file mode 100644 >> index 000..6eda14f >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt >> @@ -0,0 +1,37 @@ >> +TC358764 MIPI-DSI to LVDS panel bridge >> + >> +Required properties: >> + - compatible: "toshiba,tc358764" >> + - reg: the virtual channel number of a DSI peripheral >> + - vddc-supply: core voltage supply, 1.2V >> + - vddio-supply: I/O voltage supply, 1.8V or 3.3V >> + - vddlvds-supply: LVDS1/2 voltage supply, 3.3V >> + - reset-gpios: a GPIO spec for the reset pin >> + >> +The device node can contain zero to two 'port' child nodes, each with one > > How would 0 ports be valid? > I'll fix this. In my opinion the output LVDS port should be mandatory and the input DSI port should be optional, as the bridge might be a DSI child node. According to documentation, the bridge can also be I2C controlled. In this case, it should contain a DSI input port and LVDS output port. >> +child 'endpoint' node, according to the bindings defined in [1]. >> +The following are properties specific to those nodes. >> + >> +port: >> + - reg: (required) can be 0 for DSI port or 1 for LVDS port; >> + >> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt >> + >> +Example: >> + >> +bridge@0 { >> +reg = <0>; >> +compatible = "toshiba,tc358764"; >> +vddc-supply = <_1v2_reg>; >> +vddio-supply = <_1v8_reg>; >> +vddlvds-supply = <_3v3_reg>; >> +reset-gpios = < 6 GPIO_ACTIVE_LOW>; >> +#address-cells = <1>; >> +#size-cells = <0>; >> +port@1 { >> +reg = <1>; >> +lvds_ep: endpoint { >> +remote-endpoint = <_ep>; >> +}; >> +}; >> +}; >> -- >> 2.7.4 >> > > > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 08/10] drm/bridge: tc358764: Add DSI to LVDS bridge driver
On 05/31/2018 08:51 AM, Archit Taneja wrote: > Hi, > > On Wednesday 30 May 2018 05:45 PM, Maciej Purski wrote: >> From: Andrzej Hajda >> >> Add a drm_bridge driver for the Toshiba TC358764 DSI to LVDS bridge. >> >> Signed-off-by: Andrzej Hajda >> Signed-off-by: Maciej Purski >> --- >> drivers/gpu/drm/bridge/Kconfig | 9 + >> drivers/gpu/drm/bridge/Makefile | 1 + >> drivers/gpu/drm/bridge/tc358764.c | 547 >> ++ >> 3 files changed, 557 insertions(+) >> create mode 100644 drivers/gpu/drm/bridge/tc358764.c >> >> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig >> index fa2c799..9bd3eb8 100644 >> --- a/drivers/gpu/drm/bridge/Kconfig >> +++ b/drivers/gpu/drm/bridge/Kconfig >> @@ -110,6 +110,15 @@ config DRM_THINE_THC63LVD1024 >> ---help--- >> Thine THC63LVD1024 LVDS/parallel converter driver. >> +config DRM_TOSHIBA_TC358764 >> + tristate "TC358764 DSI/LVDS bridge" >> + depends on DRM && DRM_PANEL >> + depends on OF >> + select DRM_MIPI_DSI >> + select VIDEOMODE_HELPERS > > I don't see videomode usage in the driver, can we drop this if it isn't > used? > It seems that those are some remains of old versions. It is not required now. >> + help >> + Toshiba TC358764 DSI/LVDS bridge driver >> + >> config DRM_TOSHIBA_TC358767 >> tristate "Toshiba TC358767 eDP bridge" >> depends on OF >> diff --git a/drivers/gpu/drm/bridge/Makefile >> b/drivers/gpu/drm/bridge/Makefile >> index 35f88d4..bf7c0ce 100644 >> --- a/drivers/gpu/drm/bridge/Makefile >> +++ b/drivers/gpu/drm/bridge/Makefile >> @@ -10,6 +10,7 @@ obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o >> obj-$(CONFIG_DRM_SII902X) += sii902x.o >> obj-$(CONFIG_DRM_SII9234) += sii9234.o >> obj-$(CONFIG_DRM_THINE_THC63LVD1024) += thc63lvd1024.o >> +obj-$(CONFIG_DRM_TOSHIBA_TC358764) += tc358764.o >> obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o >> obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ >> obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ >> diff --git a/drivers/gpu/drm/bridge/tc358764.c >> b/drivers/gpu/drm/bridge/tc358764.c >> new file mode 100644 >> index 000..3109eba >> --- /dev/null >> +++ b/drivers/gpu/drm/bridge/tc358764.c >> @@ -0,0 +1,547 @@ > > We'd need a SPDX license here? >> +/* >> + * Copyright (C) 2018 Samsung Electronics Co., Ltd >> + * >> + * Authors: >> + * Andrzej Hajda >> + * Maciej Purski >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 as >> + * published by the Free Software Foundation. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + * >> + * You should have received a copy of the GNU General Public License >> + * along with this program. >> + * >> + */ >> + >> +#include >> + >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> + >> +#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << >> (end)) >> +#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) >> + >> +/* PPI layer registers */ >> +#define PPI_STARTPPI 0x0104 /* START control bit */ >> +#define PPI_LPTXTIMECNT 0x0114 /* LPTX timing signal */ >> +#define PPI_LANEENABLE 0x0134 /* Enables each lane */ >> +#define PPI_TX_RX_TA 0x013C /* BTA timing parameters */ >> +#define PPI_D0S_CLRSIPOCOUNT 0x0164 /* Assertion timer for Lane 0 */ >> +#define PPI_D1S_CLRSIPOCOUNT 0x0168 /* Assertion timer for Lane 1 */ >> +#define PPI_D2S_CLRSIPOCOUNT 0x016C /* Assertion timer for Lane 2 */ >> +#define PPI_D3S_CLRSIPOCOUNT 0x0170 /* Assertion timer for Lane 3 */ >> +#define PPI_START_FUNCTION 1 >> + >> +/* DSI layer registers */ >> +#define DSI_STARTDSI 0x0204 /* START control bit of DSI-TX */ >> +#define DSI_LANEENABLE 0x0210 /* Enables each lane */ >> +#define DSI_RX_START 1 >&g
Re: [PATCH 3/3] drm/bridge/sii8620: fix loops in EDID fetch logic
Hi Andrzej, On 01/15/2018 06:33 PM, Andrzej Hajda wrote: > Function should constantly check if cable is connected and finish > in finite time. > > Signed-off-by: Andrzej Hajda Looks fine to me. Reviewed-by: Maciej Purski > --- > drivers/gpu/drm/bridge/sil-sii8620.c | 31 --- > 1 file changed, 20 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c > b/drivers/gpu/drm/bridge/sil-sii8620.c > index 7c46847fef18..f65e14836c0e 100644 > --- a/drivers/gpu/drm/bridge/sil-sii8620.c > +++ b/drivers/gpu/drm/bridge/sil-sii8620.c > @@ -801,6 +801,7 @@ static void sii8620_burst_rx_all(struct sii8620 *ctx) > static void sii8620_fetch_edid(struct sii8620 *ctx) > { > u8 lm_ddc, ddc_cmd, int3, cbus; > + unsigned long timeout; > int fetched, i; > int edid_len = EDID_LENGTH; > u8 *edid; > @@ -850,23 +851,31 @@ static void sii8620_fetch_edid(struct sii8620 *ctx) > REG_DDC_CMD, ddc_cmd | VAL_DDC_CMD_ENH_DDC_READ_NO_ACK > ); > > - do { > - int3 = sii8620_readb(ctx, REG_INTR3); > + int3 = 0; > + timeout = jiffies + msecs_to_jiffies(200); > + for (;;) { > cbus = sii8620_readb(ctx, REG_CBUS_STATUS); > - > - if (int3 & BIT_DDC_CMD_DONE) > - break; > - > - if (!(cbus & BIT_CBUS_STATUS_CBUS_CONNECTED)) { > + if (~cbus & BIT_CBUS_STATUS_CBUS_CONNECTED) { > + kfree(edid); > + edid = NULL; > + goto end; > + } > + if (int3 & BIT_DDC_CMD_DONE) { > + if (sii8620_readb(ctx, REG_DDC_DOUT_CNT) > + >= FETCH_SIZE) > + break; > + } else { > + int3 = sii8620_readb(ctx, REG_INTR3); > + } > + if (time_is_before_jiffies(timeout)) { > + ctx->error = -ETIMEDOUT; > + dev_err(ctx->dev, "timeout during EDID read\n"); > kfree(edid); > edid = NULL; > goto end; > } > - } while (1); > - > - sii8620_readb(ctx, REG_DDC_STATUS); > - while (sii8620_readb(ctx, REG_DDC_DOUT_CNT) < FETCH_SIZE) > usleep_range(10, 20); > + } > > sii8620_read_buf(ctx, REG_DDC_DATA, edid + fetched, FETCH_SIZE); > if (fetched + FETCH_SIZE == EDID_LENGTH) { > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2] drm/bridge/sii8620: simplify hardware reset procedure
Hi Andrzej, On 06/08/2018 08:04 AM, Andrzej Hajda wrote: > There is no need to flip reset pin twice. Also delays can be changed to > values present in vendor's code. > > Signed-off-by: Andrzej Hajda Reviewed-by: Maciej Purski > --- > Hi, > > This is v2 of forgotten patch, awaiting reviewers, any volunteers. > Also "drm/bridge/sii8620: fix loops in EDID fetch logic" waits for reviewers. > > In this version I have completely removed reset function, and moved its body > to sii8620_hw_on. > > Regards > Andrzej > --- > drivers/gpu/drm/bridge/sil-sii8620.c | 23 ++- > 1 file changed, 10 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c > b/drivers/gpu/drm/bridge/sil-sii8620.c > index 7ab36042a822..d1e780fba4b6 100644 > --- a/drivers/gpu/drm/bridge/sil-sii8620.c > +++ b/drivers/gpu/drm/bridge/sil-sii8620.c > @@ -971,8 +971,17 @@ static int sii8620_hw_on(struct sii8620 *ctx) > ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); > if (ret) > return ret; > + > usleep_range(1, 2); > - return clk_prepare_enable(ctx->clk_xtal); > + ret = clk_prepare_enable(ctx->clk_xtal); > + if (ret) > + return ret; > + > + msleep(100); > + gpiod_set_value(ctx->gpio_reset, 0); > + msleep(100); > + > + return 0; > } > > static int sii8620_hw_off(struct sii8620 *ctx) > @@ -982,17 +991,6 @@ static int sii8620_hw_off(struct sii8620 *ctx) > return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); > } > > -static void sii8620_hw_reset(struct sii8620 *ctx) > -{ > - usleep_range(1, 2); > - gpiod_set_value(ctx->gpio_reset, 0); > - usleep_range(5000, 2); > - gpiod_set_value(ctx->gpio_reset, 1); > - usleep_range(1, 2); > - gpiod_set_value(ctx->gpio_reset, 0); > - msleep(300); > -} > - > static void sii8620_cbus_reset(struct sii8620 *ctx) > { > sii8620_write(ctx, REG_PWD_SRST, BIT_PWD_SRST_CBUS_RST > @@ -2112,7 +2110,6 @@ static void sii8620_cable_in(struct sii8620 *ctx) > dev_err(dev, "Error powering on, %d.\n", ret); > return; > } > - sii8620_hw_reset(ctx); > > sii8620_read_buf(ctx, REG_VND_IDL, ver, ARRAY_SIZE(ver)); > ret = sii8620_clear_error(ctx); > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 01/10] drm/exynos: rename "bridge_node" to "mic_bridge_node"
When adding support for peripheral out bridges, the "bridge" name becomes imprecise as it refers to a different device than the "out_bridge". Signed-off-by: Maciej Purski --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index eae44fd..9599e6b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -279,7 +279,7 @@ struct exynos_dsi { struct list_head transfer_list; const struct exynos_dsi_driver_data *driver_data; - struct device_node *bridge_node; + struct device_node *mic_bridge_node; }; #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host) @@ -1631,7 +1631,7 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi) if (ret < 0) return ret; - dsi->bridge_node = of_graph_get_remote_node(node, DSI_PORT_IN, 0); + dsi->mic_bridge_node = of_graph_get_remote_node(node, DSI_PORT_IN, 0); return 0; } @@ -1642,7 +1642,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master, struct drm_encoder *encoder = dev_get_drvdata(dev); struct exynos_dsi *dsi = encoder_to_dsi(encoder); struct drm_device *drm_dev = data; - struct drm_bridge *bridge; + struct drm_bridge *mic_bridge; int ret; drm_encoder_init(drm_dev, encoder, _dsi_encoder_funcs, @@ -1661,10 +1661,10 @@ static int exynos_dsi_bind(struct device *dev, struct device *master, return ret; } - if (dsi->bridge_node) { - bridge = of_drm_find_bridge(dsi->bridge_node); - if (bridge) - drm_bridge_attach(encoder, bridge, NULL); + if (dsi->mic_bridge_node) { + mic_bridge = of_drm_find_bridge(dsi->mic_bridge_node); + if (mic_bridge) + drm_bridge_attach(encoder, mic_bridge, NULL); } return mipi_dsi_host_register(>dsi_host); @@ -1783,7 +1783,7 @@ static int exynos_dsi_remove(struct platform_device *pdev) { struct exynos_dsi *dsi = platform_get_drvdata(pdev); - of_node_put(dsi->bridge_node); + of_node_put(dsi->mic_bridge_node); pm_runtime_disable(>dev); -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 00/10] Add TOSHIBA TC358764 DSI/LVDS bridge driver
Hi all, this patchset is a next attempt to add the tc358764 driver. The previous one can be found here: https://lists.freedesktop.org/archives/dri-devel/2014-February/053705.html Back then, TC358764 was added as a panel driver. The bridge is supposed to be a DSI peripheral. Currently exynos_dsi accepts only panels as its peripherals. Therefore, some logic in exynos_dsi had to be ammended. That is implemented in first 4 patches. Apart from the driver this patchset adds support for BOE HV070WSA-100 panel, which is used by TC358764 and dts nodes to exynos5250.dtsi and exynos5250-arndale.dtsi. Best regards, Maciej Purski --- Changes in v2: - fix commits authorship - don't call pm_runtime_put_sync() in exyons_dsi_disable(), if pm_runtime_get_sync() has not been called - squash dts commits - merge some redundant regulators in tc358764 bindings and in DTS - fix kbuild robot errors Andrzej Hajda (6): panel/hv070wsa-100: add DT bindings drm/panel: add support for BOE HV070WSA-100 panel to simple-panel dt-bindings: tc358754: add DT bindings drm/bridge: tc358764: Add DSI to LVDS bridge driver ARM: dts: exynos5250: add DSI node ARM: dts: exynos5250-arndale: add DSI and panel nodes Maciej Purski (4): drm/exynos: rename "bridge_node" to "mic_bridge_node" drm/exynos: move pm_runtime_get_sync() to exynos_dsi_init() drm/exynos: move connector creation to attach callback drm/exynos: add non-panel path to exynos_dsi_enable() .../bindings/display/bridge/toshiba,tc358764.txt | 37 ++ .../bindings/display/panel/boe,hv070wsa-100.txt| 7 + arch/arm/boot/dts/exynos5250-arndale.dts | 61 +++ arch/arm/boot/dts/exynos5250.dtsi | 21 + drivers/gpu/drm/bridge/Kconfig | 9 + drivers/gpu/drm/bridge/Makefile| 1 + drivers/gpu/drm/bridge/tc358764.c | 547 + drivers/gpu/drm/exynos/exynos_drm_dsi.c| 88 ++-- drivers/gpu/drm/panel/panel-simple.c | 25 + 9 files changed, 755 insertions(+), 41 deletions(-) create mode 100644 Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt create mode 100644 Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt create mode 100644 drivers/gpu/drm/bridge/tc358764.c -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 10/10] ARM: dts: exynos5250-arndale: add DSI and panel nodes
From: Andrzej Hajda The patch adds bridge and panel nodes. It adds also DSI properties specific for arndale board and regulators required by the bridge. Signed-off-by: Andrzej Hajda Signed-off-by: Maciej Purski --- arch/arm/boot/dts/exynos5250-arndale.dts | 61 1 file changed, 61 insertions(+) diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index 7a8a5c5..816d89d 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -71,6 +71,17 @@ }; }; + panel: panel { + compatible = "boe,hv070wsa-100"; + power-supply = <_3v3_reg>; + enable-gpios = < 3 GPIO_ACTIVE_HIGH>; + port { + panel_ep: endpoint { + remote-endpoint = <_out_ep>; + }; + }; + }; + regulators { compatible = "simple-bus"; #address-cells = <1>; @@ -97,6 +108,30 @@ reg = <2>; regulator-name = "hdmi-en"; }; + + vcc_1v2_reg: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "VCC_1V2"; + regulator-min-microvolt = <120>; + regulator-max-microvolt = <120>; + }; + + vcc_1v8_reg: regulator@4 { + compatible = "regulator-fixed"; + reg = <4>; + regulator-name = "VCC_1V8"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + }; + + vcc_3v3_reg: regulator@5 { + compatible = "regulator-fixed"; + reg = <5>; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + }; }; fixed-rate-clocks { @@ -119,6 +154,32 @@ cpu0-supply = <_reg>; }; +_0 { + vddcore-supply = <_reg>; + vddio-supply = <_reg>; + samsung,pll-clock-frequency = <2400>; + samsung,burst-clock-frequency = <32000>; + samsung,esc-clock-frequency = <1000>; + status = "okay"; + + bridge@0 { + reg = <0>; + compatible = "toshiba,tc358764"; + vddc-supply = <_1v2_reg>; + vddio-supply = <_1v8_reg>; + vddlvds-supply = <_3v3_reg>; + reset-gpios = < 6 GPIO_ACTIVE_LOW>; + #address-cells = <1>; + #size-cells = <0>; + port@1 { + reg = <1>; + bridge_out_ep: endpoint { + remote-endpoint = <_ep>; + }; + }; + }; +}; + { status = "okay"; samsung,color-space = <0>; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 07/10] dt-bindings: tc358754: add DT bindings
From: Andrzej Hajda The patch adds bindings to Toshiba DSI/LVDS bridge TC358764. Bindings describe power supplies, reset gpio and video interfaces. Signed-off-by: Andrzej Hajda Signed-off-by: Maciej Purski --- .../bindings/display/bridge/toshiba,tc358764.txt | 37 ++ 1 file changed, 37 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt new file mode 100644 index 000..6eda14f --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt @@ -0,0 +1,37 @@ +TC358764 MIPI-DSI to LVDS panel bridge + +Required properties: + - compatible: "toshiba,tc358764" + - reg: the virtual channel number of a DSI peripheral + - vddc-supply: core voltage supply, 1.2V + - vddio-supply: I/O voltage supply, 1.8V or 3.3V + - vddlvds-supply: LVDS1/2 voltage supply, 3.3V + - reset-gpios: a GPIO spec for the reset pin + +The device node can contain zero to two 'port' child nodes, each with one +child 'endpoint' node, according to the bindings defined in [1]. +The following are properties specific to those nodes. + +port: + - reg: (required) can be 0 for DSI port or 1 for LVDS port; + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt + +Example: + + bridge@0 { + reg = <0>; + compatible = "toshiba,tc358764"; + vddc-supply = <_1v2_reg>; + vddio-supply = <_1v8_reg>; + vddlvds-supply = <_3v3_reg>; + reset-gpios = < 6 GPIO_ACTIVE_LOW>; + #address-cells = <1>; + #size-cells = <0>; + port@1 { + reg = <1>; + lvds_ep: endpoint { + remote-endpoint = <_ep>; + }; + }; + }; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 02/10] drm/exynos: move pm_runtime_get_sync() to exynos_dsi_init()
In order to allow bridge drivers to use DSI transfers in their pre_enable callbacks, pm_runtime_get_sync() should be performed before exynos_dsi_enable(). DSIM_STATE_ENABLED flag now should not guard from calling dsi_host_transfer() before enabling. Signed-off-by: Maciej Purski --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 9599e6b..85eb2262 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1312,6 +1312,7 @@ static int exynos_dsi_init(struct exynos_dsi *dsi) { const struct exynos_dsi_driver_data *driver_data = dsi->driver_data; + pm_runtime_get_sync(dsi->dev); exynos_dsi_reset(dsi); exynos_dsi_enable_irq(dsi); @@ -1388,7 +1389,6 @@ static void exynos_dsi_enable(struct drm_encoder *encoder) ret = drm_panel_prepare(dsi->panel); if (ret < 0) { dsi->state &= ~DSIM_STATE_ENABLED; - pm_runtime_put_sync(dsi->dev); return; } @@ -1400,7 +1400,6 @@ static void exynos_dsi_enable(struct drm_encoder *encoder) dsi->state &= ~DSIM_STATE_ENABLED; exynos_dsi_set_display_enable(dsi, false); drm_panel_unprepare(dsi->panel); - pm_runtime_put_sync(dsi->dev); return; } @@ -1422,7 +1421,10 @@ static void exynos_dsi_disable(struct drm_encoder *encoder) dsi->state &= ~DSIM_STATE_ENABLED; - pm_runtime_put_sync(dsi->dev); + if (dsi->state & DSIM_STATE_INITIALIZED) { + pm_runtime_put_sync(dsi->dev); + dsi->state &= ~DSIM_STATE_INITIALIZED; + } } static enum drm_connector_status @@ -1566,9 +1568,6 @@ static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host, struct exynos_dsi_transfer xfer; int ret; - if (!(dsi->state & DSIM_STATE_ENABLED)) - return -EINVAL; - if (!(dsi->state & DSIM_STATE_INITIALIZED)) { ret = exynos_dsi_init(dsi); if (ret) -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 09/10] ARM: dts: exynos5250: add DSI node
From: Andrzej Hajda The patch adds common part of DSI node for Exynos5250 platforms and a required mipi-phy node. Signed-off-by: Andrzej Hajda Signed-off-by: Maciej Purski --- arch/arm/boot/dts/exynos5250.dtsi | 21 + 1 file changed, 21 insertions(+) diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 2daf505..9965eca 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -733,6 +733,27 @@ #phy-cells = <0>; }; + mipi_phy: video-phy@10040710 { + compatible = "samsung,s5pv210-mipi-video-phy"; + reg = <0x10040710 0x100>; + #phy-cells = <1>; + syscon = <_system_controller>; + }; + + dsi_0: dsi@1450 { + compatible = "samsung,exynos4210-mipi-dsi"; + reg = <0x1450 0x1>; + interrupts = ; + samsung,power-domain = <_disp1>; + phys = <_phy 3>; + phy-names = "dsim"; + clocks = < CLK_DSIM0>, < CLK_SCLK_MIPI1>; + clock-names = "bus_clk", "sclk_mipi"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + adc: adc@12d1 { compatible = "samsung,exynos-adc-v1"; reg = <0x12D1 0x100>; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 03/10] drm/exynos: move connector creation to attach callback
The current implementation assumes that the only possible peripheral device for DSIM is a panel. Using an output bridge should also be possible. If an output bridge in available, don't create a new connector. Instead add bridge to DSIM encdoer in dsi_host_attach(). Signed-off-by: Maciej Purski --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 35 + 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 85eb2262..7b50bad 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1501,7 +1501,28 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct exynos_dsi *dsi = host_to_dsi(host); - struct drm_device *drm = dsi->connector.dev; + struct drm_encoder *encoder = >encoder; + struct drm_device *drm = encoder->dev; + struct drm_bridge *out_bridge; + + out_bridge = of_drm_find_bridge(device->dev.of_node); + if (out_bridge) { + drm_bridge_attach(encoder, out_bridge, NULL); + } else { + int ret = exynos_dsi_create_connector(encoder); + + if (ret) { + DRM_ERROR("failed to create connector ret = %d\n", ret); + drm_encoder_cleanup(encoder); + return ret; + } + + dsi->panel = of_drm_find_panel(device->dev.of_node); + if (dsi->panel) { + drm_panel_attach(dsi->panel, >connector); + dsi->connector.status = connector_status_connected; + } + } /* * This is a temporary solution and should be made by more generic way. @@ -1520,11 +1541,6 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, dsi->lanes = device->lanes; dsi->format = device->format; dsi->mode_flags = device->mode_flags; - dsi->panel = of_drm_find_panel(device->dev.of_node); - if (dsi->panel) { - drm_panel_attach(dsi->panel, >connector); - dsi->connector.status = connector_status_connected; - } exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode = !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO); @@ -1653,13 +1669,6 @@ static int exynos_dsi_bind(struct device *dev, struct device *master, if (ret < 0) return ret; - ret = exynos_dsi_create_connector(encoder); - if (ret) { - DRM_ERROR("failed to create connector ret = %d\n", ret); - drm_encoder_cleanup(encoder); - return ret; - } - if (dsi->mic_bridge_node) { mic_bridge = of_drm_find_bridge(dsi->mic_bridge_node); if (mic_bridge) -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 04/10] drm/exynos: add non-panel path to exynos_dsi_enable()
As DSIM can now have a bridge connected as a peripheral, it should be possible to successfully enable exynos_dsi, when there is no panel provided. Signed-off-by: Maciej Purski --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 26 -- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 7b50bad..7f6a0b1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1382,27 +1382,25 @@ static void exynos_dsi_enable(struct drm_encoder *encoder) if (dsi->state & DSIM_STATE_ENABLED) return; - pm_runtime_get_sync(dsi->dev); - - dsi->state |= DSIM_STATE_ENABLED; - - ret = drm_panel_prepare(dsi->panel); - if (ret < 0) { - dsi->state &= ~DSIM_STATE_ENABLED; - return; + if (dsi->panel) { + ret = drm_panel_prepare(dsi->panel); + if (ret < 0) + return; } exynos_dsi_set_display_mode(dsi); exynos_dsi_set_display_enable(dsi, true); - ret = drm_panel_enable(dsi->panel); - if (ret < 0) { - dsi->state &= ~DSIM_STATE_ENABLED; - exynos_dsi_set_display_enable(dsi, false); - drm_panel_unprepare(dsi->panel); - return; + if (dsi->panel) { + ret = drm_panel_enable(dsi->panel); + if (ret < 0) { + exynos_dsi_set_display_enable(dsi, false); + drm_panel_unprepare(dsi->panel); + return; + } } + dsi->state |= DSIM_STATE_ENABLED; dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE; } -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 05/10] panel/hv070wsa-100: add DT bindings
From: Andrzej Hajda The patch adds bindings to BOE HV070-WSA WSVGA panel. Bindings are compatible with simple panel bindings. Signed-off-by: Andrzej Hajda Signed-off-by: Maciej Purski --- .../devicetree/bindings/display/panel/boe,hv070wsa-100.txt | 7 +++ 1 file changed, 7 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt diff --git a/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt b/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt new file mode 100644 index 000..bfc20ac --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt @@ -0,0 +1,7 @@ +BOE HV070WSA-100 7.01" WSVGA TFT LCD panel + +Required properties: +- compatible: should be "boe,hv070wsa-100" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 06/10] drm/panel: add support for BOE HV070WSA-100 panel to simple-panel
From: Andrzej Hajda The patch adds support for BOE HV070WSA-100 WSVGA 7.01 inch panel in panel-simple driver. The panel is used in Exynos5250-arndale boards. Signed-off-by: Andrzej Hajda Signed-off-by: Maciej Purski --- drivers/gpu/drm/panel/panel-simple.c | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index cbf1ab4..d5da58d 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -745,6 +745,28 @@ static const struct panel_desc avic_tm070ddh03 = { }, }; +static const struct drm_display_mode boe_hv070wsa_mode = { + .clock = 40800, + .hdisplay = 1024, + .hsync_start = 1024 + 90, + .hsync_end = 1024 + 90 + 90, + .htotal = 1024 + 90 + 90 + 90, + .vdisplay = 600, + .vsync_start = 600 + 3, + .vsync_end = 600 + 3 + 4, + .vtotal = 600 + 3 + 4 + 3, + .vrefresh = 60, +}; + +static const struct panel_desc boe_hv070wsa = { + .modes = _hv070wsa_mode, + .num_modes = 1, + .size = { + .width = 154, + .height = 90, + }, +}; + static const struct drm_display_mode boe_nv101wxmn51_modes[] = { { .clock = 71900, @@ -2113,6 +2135,9 @@ static const struct of_device_id platform_of_match[] = { .compatible = "avic,tm070ddh03", .data = _tm070ddh03, }, { + .compatible = "boe,hv070wsa-100", + .data = _hv070wsa + }, { .compatible = "boe,nv101wxmn51", .data = _nv101wxmn51, }, { -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 08/10] drm/bridge: tc358764: Add DSI to LVDS bridge driver
From: Andrzej Hajda Add a drm_bridge driver for the Toshiba TC358764 DSI to LVDS bridge. Signed-off-by: Andrzej Hajda Signed-off-by: Maciej Purski --- drivers/gpu/drm/bridge/Kconfig| 9 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/tc358764.c | 547 ++ 3 files changed, 557 insertions(+) create mode 100644 drivers/gpu/drm/bridge/tc358764.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index fa2c799..9bd3eb8 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -110,6 +110,15 @@ config DRM_THINE_THC63LVD1024 ---help--- Thine THC63LVD1024 LVDS/parallel converter driver. +config DRM_TOSHIBA_TC358764 + tristate "TC358764 DSI/LVDS bridge" + depends on DRM && DRM_PANEL + depends on OF + select DRM_MIPI_DSI + select VIDEOMODE_HELPERS + help + Toshiba TC358764 DSI/LVDS bridge driver + config DRM_TOSHIBA_TC358767 tristate "Toshiba TC358767 eDP bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 35f88d4..bf7c0ce 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o obj-$(CONFIG_DRM_SII902X) += sii902x.o obj-$(CONFIG_DRM_SII9234) += sii9234.o obj-$(CONFIG_DRM_THINE_THC63LVD1024) += thc63lvd1024.o +obj-$(CONFIG_DRM_TOSHIBA_TC358764) += tc358764.o obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ diff --git a/drivers/gpu/drm/bridge/tc358764.c b/drivers/gpu/drm/bridge/tc358764.c new file mode 100644 index 000..3109eba --- /dev/null +++ b/drivers/gpu/drm/bridge/tc358764.c @@ -0,0 +1,547 @@ +/* + * Copyright (C) 2018 Samsung Electronics Co., Ltd + * + * Authors: + * Andrzej Hajda + * Maciej Purski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. + * + */ + +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#define FLD_MASK(start, end)(((1 << ((start) - (end) + 1)) - 1) << (end)) +#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) + +/* PPI layer registers */ +#define PPI_STARTPPI 0x0104 /* START control bit */ +#define PPI_LPTXTIMECNT0x0114 /* LPTX timing signal */ +#define PPI_LANEENABLE 0x0134 /* Enables each lane */ +#define PPI_TX_RX_TA 0x013C /* BTA timing parameters */ +#define PPI_D0S_CLRSIPOCOUNT 0x0164 /* Assertion timer for Lane 0 */ +#define PPI_D1S_CLRSIPOCOUNT 0x0168 /* Assertion timer for Lane 1 */ +#define PPI_D2S_CLRSIPOCOUNT 0x016C /* Assertion timer for Lane 2 */ +#define PPI_D3S_CLRSIPOCOUNT 0x0170 /* Assertion timer for Lane 3 */ +#define PPI_START_FUNCTION 1 + +/* DSI layer registers */ +#define DSI_STARTDSI 0x0204 /* START control bit of DSI-TX */ +#define DSI_LANEENABLE 0x0210 /* Enables each lane */ +#define DSI_RX_START 1 + +/* Video path registers */ +#define VP_CTRL0x0450 /* Video Path Control */ +#define VP_CTRL_MSF(v) FLD_VAL(v, 0, 0) /* Magic square in RGB666 */ +#define VP_CTRL_VTGEN(v) FLD_VAL(v, 4, 4) /* Use chip clock for timing */ +#define VP_CTRL_EVTMODE(v) FLD_VAL(v, 5, 5) /* Event mode */ +#define VP_CTRL_RGB888(v) FLD_VAL(v, 8, 8) /* RGB888 mode */ +#define VP_CTRL_VSDELAY(v) FLD_VAL(v, 31, 20) /* VSYNC delay */ +#define VP_CTRL_HSPOL BIT(17) /* Polarity of HSYNC signal */ +#define VP_CTRL_DEPOL BIT(18) /* Polarity of DE signal */ +#define VP_CTRL_VSPOL BIT(19) /* Polarity of VSYNC signal */ +#define VP_HTIM1 0x0454 /* Horizontal Timing Control 1 */ +#define VP_HTIM1_HBP(v)FLD_VAL(v, 24, 16) +#define VP_HTIM1_HSYNC(v) FLD_VAL(v, 8, 0) +#define VP_HTIM2 0x0458 /* Horizontal Timing Control 2 */ +#define VP_HTIM2_HFP(v)FLD_VAL(v, 24, 16) +#define VP_HTIM2_HACT(v) FLD_VAL(v, 10, 0) +#define VP_VTIM1 0x045C /* Vertical Timing Control 1 */ +#define VP_VTIM1_VBP(v)FLD_VAL(v, 23, 16) +#define VP_VTIM1_VSYNC(v) FLD_VAL(v, 7, 0) +#define VP_VTIM2 0x0460 /* Vertical Timing Control 2 */ +#defin
[PATCH 09/12] ARM: dts: exynos5250: add mipi-phy node
The patch adds phy node, required by MIPI devices. Signed-off-by: Andrzej Hajda <a.ha...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- arch/arm/boot/dts/exynos5250.dtsi | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 2daf505..a63b655 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -733,6 +733,12 @@ #phy-cells = <0>; }; + mipi_phy: video-phy@10040710 { + compatible = "samsung,s5pv210-mipi-video-phy"; + #phy-cells = <1>; + syscon = <_system_controller>; + }; + adc: adc@12d1 { compatible = "samsung,exynos-adc-v1"; reg = <0x12D1 0x100>; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 11/12] ARM: dts: exynos5250-arndale: add display regulators
The patch adds fixed regulators used by DSI/LVDS bridge and panel. Regulators are named according to schematics. Signed-off-by: Andrzej Hajda <a.ha...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- arch/arm/boot/dts/exynos5250-arndale.dts | 24 1 file changed, 24 insertions(+) diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index 7a8a5c5..80221fa 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -97,6 +97,30 @@ reg = <2>; regulator-name = "hdmi-en"; }; + + vcc_1v2_reg: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "VCC_1V2"; + regulator-min-microvolt = <120>; + regulator-max-microvolt = <120>; + }; + + vcc_1v8_reg: regulator@4 { + compatible = "regulator-fixed"; + reg = <4>; + regulator-name = "VCC_1V8"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + }; + + vcc_3v3_reg: regulator@5 { + compatible = "regulator-fixed"; + reg = <5>; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + }; }; fixed-rate-clocks { -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 08/12] drm/bridge: tc358764: Add DSI to LVDS bridge driver
Add a drm_bridge driver for the Toshiba TC358764 DSI to LVDS bridge. Signed-off-by: Andrzej Hajda <a.ha...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/bridge/Kconfig| 7 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/tc358764.c | 547 ++ 3 files changed, 555 insertions(+) create mode 100644 drivers/gpu/drm/bridge/tc358764.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index fa2c799..58e19af 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -110,6 +110,13 @@ config DRM_THINE_THC63LVD1024 ---help--- Thine THC63LVD1024 LVDS/parallel converter driver. +config DRM_TOSHIBA_TC358764 + tristate "TC358764 DSI/LVDS bridge" + depends on DRM && DRM_PANEL + depends on OF + select DRM_MIPI_DSI + select VIDEOMODE_HELPERS + config DRM_TOSHIBA_TC358767 tristate "Toshiba TC358767 eDP bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 35f88d4..bf7c0ce 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o obj-$(CONFIG_DRM_SII902X) += sii902x.o obj-$(CONFIG_DRM_SII9234) += sii9234.o obj-$(CONFIG_DRM_THINE_THC63LVD1024) += thc63lvd1024.o +obj-$(CONFIG_DRM_TOSHIBA_TC358764) += tc358764.o obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ diff --git a/drivers/gpu/drm/bridge/tc358764.c b/drivers/gpu/drm/bridge/tc358764.c new file mode 100644 index 000..0bd520a --- /dev/null +++ b/drivers/gpu/drm/bridge/tc358764.c @@ -0,0 +1,547 @@ +/* + * Copyright (C) 2018 Samsung Electronics Co., Ltd + * + * Authors: + * Andrzej Hajda <a.ha...@samsung.com> + * Maciej Purski <m.pur...@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. + * + */ + +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#define FLD_MASK(start, end)(((1 << ((start) - (end) + 1)) - 1) << (end)) +#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) + +/* PPI layer registers */ +#define PPI_STARTPPI 0x0104 /* START control bit */ +#define PPI_LPTXTIMECNT0x0114 /* LPTX timing signal */ +#define PPI_LANEENABLE 0x0134 /* Enables each lane */ +#define PPI_TX_RX_TA 0x013C /* BTA timing parameters */ +#define PPI_D0S_CLRSIPOCOUNT 0x0164 /* Assertion timer for Lane 0 */ +#define PPI_D1S_CLRSIPOCOUNT 0x0168 /* Assertion timer for Lane 1 */ +#define PPI_D2S_CLRSIPOCOUNT 0x016C /* Assertion timer for Lane 2 */ +#define PPI_D3S_CLRSIPOCOUNT 0x0170 /* Assertion timer for Lane 3 */ +#define PPI_START_FUNCTION 1 + +/* DSI layer registers */ +#define DSI_STARTDSI 0x0204 /* START control bit of DSI-TX */ +#define DSI_LANEENABLE 0x0210 /* Enables each lane */ +#define DSI_RX_START 1 + +/* Video path registers */ +#define VP_CTRL0x0450 /* Video Path Control */ +#define VP_CTRL_MSF(v) FLD_VAL(v, 0, 0) /* Magic square in RGB666 */ +#define VP_CTRL_VTGEN(v) FLD_VAL(v, 4, 4) /* Use chip clock for timing */ +#define VP_CTRL_EVTMODE(v) FLD_VAL(v, 5, 5) /* Event mode */ +#define VP_CTRL_RGB888(v) FLD_VAL(v, 8, 8) /* RGB888 mode */ +#define VP_CTRL_VSDELAY(v) FLD_VAL(v, 31, 20) /* VSYNC delay */ +#define VP_CTRL_HSPOL BIT(17) /* Polarity of HSYNC signal */ +#define VP_CTRL_DEPOL BIT(18) /* Polarity of DE signal */ +#define VP_CTRL_VSPOL BIT(19) /* Polarity of VSYNC signal */ +#define VP_HTIM1 0x0454 /* Horizontal Timing Control 1 */ +#define VP_HTIM1_HBP(v)FLD_VAL(v, 24, 16) +#define VP_HTIM1_HSYNC(v) FLD_VAL(v, 8, 0) +#define VP_HTIM2 0x0458 /* Horizontal Timing Control 2 */ +#define VP_HTIM2_HFP(v)FLD_VAL(v, 24, 16) +#define VP_HTIM2_HACT(v) FLD_VAL(v, 10, 0) +#define VP_VTIM1 0x045C /* Vertical Timing Control 1 */ +#define VP_VTIM1_VBP(v)FLD_VAL(v, 23, 16) +#define VP_VTIM1_VSYNC(v) FLD_VAL(v, 7, 0) +#define VP_VTIM2 0x0460 /* Vertical Tim
[PATCH 06/12] drm/panel: add support for BOE HV070WSA-100 panel to simple-panel
The patch adds support for BOE HV070WSA-100 WSVGA 7.01 inch panel in panel-simple driver. The panel is used in Exynos5250-arndale boards. Signed-off-by: Andrzej Hajda <a.ha...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/panel/panel-simple.c | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index cbf1ab4..d5da58d 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -745,6 +745,28 @@ static const struct panel_desc avic_tm070ddh03 = { }, }; +static const struct drm_display_mode boe_hv070wsa_mode = { + .clock = 40800, + .hdisplay = 1024, + .hsync_start = 1024 + 90, + .hsync_end = 1024 + 90 + 90, + .htotal = 1024 + 90 + 90 + 90, + .vdisplay = 600, + .vsync_start = 600 + 3, + .vsync_end = 600 + 3 + 4, + .vtotal = 600 + 3 + 4 + 3, + .vrefresh = 60, +}; + +static const struct panel_desc boe_hv070wsa = { + .modes = _hv070wsa_mode, + .num_modes = 1, + .size = { + .width = 154, + .height = 90, + }, +}; + static const struct drm_display_mode boe_nv101wxmn51_modes[] = { { .clock = 71900, @@ -2113,6 +2135,9 @@ static const struct of_device_id platform_of_match[] = { .compatible = "avic,tm070ddh03", .data = _tm070ddh03, }, { + .compatible = "boe,hv070wsa-100", + .data = _hv070wsa + }, { .compatible = "boe,nv101wxmn51", .data = _nv101wxmn51, }, { -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 04/12] drm/exynos: add non-panel path to exynos_dsi_enable()
As DSIM can now have a bridge connected as a peripheral, it should be possible to successfully enable exynos_dsi, when there is no panel provided. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 27 +-- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 8957faf..7d92e50 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1382,27 +1382,26 @@ static void exynos_dsi_enable(struct drm_encoder *encoder) if (dsi->state & DSIM_STATE_ENABLED) return; - pm_runtime_get_sync(dsi->dev); - - dsi->state |= DSIM_STATE_ENABLED; - - ret = drm_panel_prepare(dsi->panel); - if (ret < 0) { - dsi->state &= ~DSIM_STATE_ENABLED; - return; + if (dsi->panel) { + ret = drm_panel_prepare(dsi->panel); + if (ret < 0) { + return; + } } exynos_dsi_set_display_mode(dsi); exynos_dsi_set_display_enable(dsi, true); - ret = drm_panel_enable(dsi->panel); - if (ret < 0) { - dsi->state &= ~DSIM_STATE_ENABLED; - exynos_dsi_set_display_enable(dsi, false); - drm_panel_unprepare(dsi->panel); - return; + if (dsi->panel) { + ret = drm_panel_enable(dsi->panel); + if (ret < 0) { + exynos_dsi_set_display_enable(dsi, false); + drm_panel_unprepare(dsi->panel); + return; + } } + dsi->state |= DSIM_STATE_ENABLED; dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE; } -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 05/12] panel/hv070wsa-100: add DT bindings
The patch adds bindings to BOE HV070-WSA WSVGA panel. Bindings are compatible with simple panel bindings. Signed-off-by: Andrzej Hajda <a.ha...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- .../devicetree/bindings/display/panel/boe,hv070wsa-100.txt | 7 +++ 1 file changed, 7 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt diff --git a/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt b/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt new file mode 100644 index 000..bfc20ac --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt @@ -0,0 +1,7 @@ +BOE HV070WSA-100 7.01" WSVGA TFT LCD panel + +Required properties: +- compatible: should be "boe,hv070wsa-100" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 07/12] dt-bindings: tc358754: add DT bindings
The patch adds bindings to Toshiba DSI/LVDS bridge TC358764. Bindings describe power supplies, reset gpio and video interfaces. Signed-off-by: Andrzej Hajda <a.ha...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- .../bindings/display/bridge/toshiba,tc358764.txt | 42 ++ 1 file changed, 42 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt new file mode 100644 index 000..d09bdc2 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt @@ -0,0 +1,42 @@ +TC358764 MIPI-DSI to LVDS panel bridge + +Required properties: + - compatible: "toshiba,tc358764" + - reg: the virtual channel number of a DSI peripheral + - vddc-supply: core voltage supply + - vddio-supply: I/O voltage supply + - vddmipi-supply: MIPI voltage supply + - vddlvds133-supply: LVDS1 3.3V voltage supply + - vddlvds112-supply: LVDS1 1.2V voltage supply + - reset-gpios: a GPIO spec for the reset pin + +The device node can contain zero to two 'port' child nodes, each with one +child +'endpoint' node, according to the bindings defined in [1]. +The following are properties specific to those nodes. + +port: + - reg: (required) can be 0 for DSI port or 1 for LVDS port; + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt + +Example: + + bridge@0 { + reg = <0>; + compatible = "toshiba,tc358764"; + vddc-supply = <_1v2_reg>; + vddio-supply = <_1v8_reg>; + vddmipi-supply = <_1v2_reg>; + vddlvds133-supply = <_3v3_reg>; + vddlvds112-supply = <_1v2_reg>; + reset-gpios = < 6 GPIO_ACTIVE_LOW>; + #address-cells = <1>; + #size-cells = <0>; + port@1 { + reg = <1>; + lvds_ep: endpoint { + remote-endpoint = <_ep>; + }; + }; + }; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 12/12] ARM: dts: exynos5250-arndale: add dsi and panel nodes
The patch adds bridge and panel nodes. It adds also DSI properties specific for arndale board. Signed-off-by: Andrzej Hajda <a.ha...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- arch/arm/boot/dts/exynos5250-arndale.dts | 39 1 file changed, 39 insertions(+) diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index 80221fa..6f0b1c4 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -71,6 +71,17 @@ }; }; + panel: panel { + compatible = "boe,hv070wsa-100"; + power-supply = <_3v3_reg>; + enable-gpios = < 3 GPIO_ACTIVE_HIGH>; + port { + panel_ep: endpoint { + remote-endpoint = <_out_ep>; + }; + }; + }; + regulators { compatible = "simple-bus"; #address-cells = <1>; @@ -476,6 +487,34 @@ }; }; +_0 { + vddcore-supply = <_reg>; + vddio-supply = <_reg>; + samsung,pll-clock-frequency = <2400>; + samsung,burst-clock-frequency = <32000>; + samsung,esc-clock-frequency = <1000>; + status = "okay"; + + bridge@0 { + reg = <0>; + compatible = "toshiba,tc358764"; + vddc-supply = <_1v2_reg>; + vddio-supply = <_1v8_reg>; + vddmipi-supply = <_1v2_reg>; + vddlvds133-supply = <_3v3_reg>; + vddlvds112-supply = <_1v2_reg>; + reset-gpios = < 6 GPIO_ACTIVE_LOW>; + #address-cells = <1>; + #size-cells = <0>; + port@1 { + reg = <1>; + bridge_out_ep: endpoint { + remote-endpoint = <_ep>; + }; + }; + }; +}; + _2 { status = "okay"; /* used by HDMI DDC */ -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 02/12] drm/exynos: move pm_runtime_get_sync() to exynos_dsi_init()
In order to allow bridge drivers to use DSI transfers in their pre_enable callbacks, pm_runtime_get_sync() should be performed before exynos_dsi_enable(). DSIM_STATE_ENABLED flag now should not guard from calling dsi_host_transfer() before enabling. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 9599e6b..94460b0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1312,6 +1312,7 @@ static int exynos_dsi_init(struct exynos_dsi *dsi) { const struct exynos_dsi_driver_data *driver_data = dsi->driver_data; + pm_runtime_get_sync(dsi->dev); exynos_dsi_reset(dsi); exynos_dsi_enable_irq(dsi); @@ -1388,7 +1389,6 @@ static void exynos_dsi_enable(struct drm_encoder *encoder) ret = drm_panel_prepare(dsi->panel); if (ret < 0) { dsi->state &= ~DSIM_STATE_ENABLED; - pm_runtime_put_sync(dsi->dev); return; } @@ -1400,7 +1400,6 @@ static void exynos_dsi_enable(struct drm_encoder *encoder) dsi->state &= ~DSIM_STATE_ENABLED; exynos_dsi_set_display_enable(dsi, false); drm_panel_unprepare(dsi->panel); - pm_runtime_put_sync(dsi->dev); return; } @@ -1566,9 +1565,6 @@ static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host, struct exynos_dsi_transfer xfer; int ret; - if (!(dsi->state & DSIM_STATE_ENABLED)) - return -EINVAL; - if (!(dsi->state & DSIM_STATE_INITIALIZED)) { ret = exynos_dsi_init(dsi); if (ret) -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 10/12] ARM: dts: exynos5250: add DSI node
The patch adds common part of DSI node for Exynos5250 platforms. Signed-off-by: Andrzej Hajda <a.ha...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- arch/arm/boot/dts/exynos5250.dtsi | 14 ++ 1 file changed, 14 insertions(+) diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index a63b655..7403b96 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -739,6 +739,20 @@ syscon = <_system_controller>; }; + dsi_0: dsi@1450 { + compatible = "samsung,exynos4210-mipi-dsi"; + reg = <0x1450 0x1>; + interrupts = ; + samsung,power-domain = <_disp1>; + phys = <_phy 3>; + phy-names = "dsim"; + clocks = < CLK_DSIM0>, < CLK_SCLK_MIPI1>; + clock-names = "bus_clk", "sclk_mipi"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + adc: adc@12d1 { compatible = "samsung,exynos-adc-v1"; reg = <0x12D1 0x100>; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 01/12] drm/exynos: rename "bridge_node" to "mic_bridge_node"
When adding support for peripheral out bridges, the "bridge" name becomes imprecise as it refers to a different device than the "out_bridge". Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index eae44fd..9599e6b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -279,7 +279,7 @@ struct exynos_dsi { struct list_head transfer_list; const struct exynos_dsi_driver_data *driver_data; - struct device_node *bridge_node; + struct device_node *mic_bridge_node; }; #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host) @@ -1631,7 +1631,7 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi) if (ret < 0) return ret; - dsi->bridge_node = of_graph_get_remote_node(node, DSI_PORT_IN, 0); + dsi->mic_bridge_node = of_graph_get_remote_node(node, DSI_PORT_IN, 0); return 0; } @@ -1642,7 +1642,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master, struct drm_encoder *encoder = dev_get_drvdata(dev); struct exynos_dsi *dsi = encoder_to_dsi(encoder); struct drm_device *drm_dev = data; - struct drm_bridge *bridge; + struct drm_bridge *mic_bridge; int ret; drm_encoder_init(drm_dev, encoder, _dsi_encoder_funcs, @@ -1661,10 +1661,10 @@ static int exynos_dsi_bind(struct device *dev, struct device *master, return ret; } - if (dsi->bridge_node) { - bridge = of_drm_find_bridge(dsi->bridge_node); - if (bridge) - drm_bridge_attach(encoder, bridge, NULL); + if (dsi->mic_bridge_node) { + mic_bridge = of_drm_find_bridge(dsi->mic_bridge_node); + if (mic_bridge) + drm_bridge_attach(encoder, mic_bridge, NULL); } return mipi_dsi_host_register(>dsi_host); @@ -1783,7 +1783,7 @@ static int exynos_dsi_remove(struct platform_device *pdev) { struct exynos_dsi *dsi = platform_get_drvdata(pdev); - of_node_put(dsi->bridge_node); + of_node_put(dsi->mic_bridge_node); pm_runtime_disable(>dev); -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 03/12] drm/exynos: move connector creation to attach callback
The current implementation assumes that the only possible peripheral device for DSIM is a panel. Using an output bridge should also be possible. If an output bridge in available, don't create a new connector. Instead add bridge to DSIM encdoer in dsi_host_attach(). Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 35 + 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 94460b0..8957faf 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1498,7 +1498,28 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct exynos_dsi *dsi = host_to_dsi(host); - struct drm_device *drm = dsi->connector.dev; + struct drm_encoder *encoder = >encoder; + struct drm_device *drm = encoder->dev; + struct drm_bridge *out_bridge; + + out_bridge = of_drm_find_bridge(device->dev.of_node); + if (out_bridge) { + drm_bridge_attach(encoder, out_bridge, NULL); + } else { + int ret = exynos_dsi_create_connector(encoder); + + if (ret) { + DRM_ERROR("failed to create connector ret = %d\n", ret); + drm_encoder_cleanup(encoder); + return ret; + } + + dsi->panel = of_drm_find_panel(device->dev.of_node); + if (dsi->panel) { + drm_panel_attach(dsi->panel, >connector); + dsi->connector.status = connector_status_connected; + } + } /* * This is a temporary solution and should be made by more generic way. @@ -1517,11 +1538,6 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, dsi->lanes = device->lanes; dsi->format = device->format; dsi->mode_flags = device->mode_flags; - dsi->panel = of_drm_find_panel(device->dev.of_node); - if (dsi->panel) { - drm_panel_attach(dsi->panel, >connector); - dsi->connector.status = connector_status_connected; - } exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode = !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO); @@ -1650,13 +1666,6 @@ static int exynos_dsi_bind(struct device *dev, struct device *master, if (ret < 0) return ret; - ret = exynos_dsi_create_connector(encoder); - if (ret) { - DRM_ERROR("failed to create connector ret = %d\n", ret); - drm_encoder_cleanup(encoder); - return ret; - } - if (dsi->mic_bridge_node) { mic_bridge = of_drm_find_bridge(dsi->mic_bridge_node); if (mic_bridge) -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 00/12] Add TOSHIBA TC358764 DSI/LVDS bridge driver
Hi all, this patchset is a next attempt to add the tc358764 driver. The previous one can be found here: https://lists.freedesktop.org/archives/dri-devel/2014-February/053705.html Back then, TC358764 was added as a panel driver. The bridge is supposed to be a DSI peripheral. Currently exynos_dsi accepts only panels as its peripherals. Therefore, some logic in exynos_dsi had to be ammended. That is implemented in first 4 patches. Apart from the driver this patchset adds support for BOE HV070WSA-100 panel, which is used by TC358764 and dts nodes to exynos5250.dtsi and exynos5250-arndale.dtsi. Best regards, Maciej Purski Maciej Purski (12): drm/exynos: rename "bridge_node" to "mic_bridge_node" drm/exynos: move pm_runtime_get_sync() to exynos_dsi_init() drm/exynos: move connector creation to attach callback drm/exynos: add non-panel path to exynos_dsi_enable() panel/hv070wsa-100: add DT bindings drm/panel: add support for BOE HV070WSA-100 panel to simple-panel dt-bindings: tc358754: add DT bindings drm/bridge: tc358764: Add DSI to LVDS bridge driver ARM: dts: exynos5250: add mipi-phy node ARM: dts: exynos5250: add DSI node ARM: dts: exynos5250-arndale: add display regulators ARM: dts: exynos5250-arndale: add dsi and panel nodes .../bindings/display/bridge/toshiba,tc358764.txt | 42 ++ .../bindings/display/panel/boe,hv070wsa-100.txt| 7 + arch/arm/boot/dts/exynos5250-arndale.dts | 63 +++ arch/arm/boot/dts/exynos5250.dtsi | 20 + drivers/gpu/drm/bridge/Kconfig | 7 + drivers/gpu/drm/bridge/Makefile| 1 + drivers/gpu/drm/bridge/tc358764.c | 547 + drivers/gpu/drm/exynos/exynos_drm_dsi.c| 84 ++-- drivers/gpu/drm/panel/panel-simple.c | 25 + 9 files changed, 756 insertions(+), 40 deletions(-) create mode 100644 Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt create mode 100644 Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt create mode 100644 drivers/gpu/drm/bridge/tc358764.c -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 8/8] [media] s5p-mfc: Use clk bulk API
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk functions instead of iterating over an array of clks. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 6 ++-- drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 41 + 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 76119a8..da3f0b3 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h @@ -192,9 +192,9 @@ struct s5p_mfc_buf { * struct s5p_mfc_pm - power management data structure */ struct s5p_mfc_pm { - struct clk *clock_gate; - const char * const *clk_names; - struct clk *clocks[MFC_MAX_CLOCKS]; + struct clk *clock_gate; + const char * const *clk_names; + struct clk_bulk_data*clocks; int num_clocks; booluse_clock_gating; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c index eb85ced..857f6ea 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c @@ -24,7 +24,7 @@ static atomic_t clk_ref; int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) { - int i; + int ret; pm = >pm; p_dev = dev; @@ -35,17 +35,17 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) pm->clock_gate = NULL; /* clock control */ - for (i = 0; i < pm->num_clocks; i++) { - pm->clocks[i] = devm_clk_get(pm->device, pm->clk_names[i]); - if (IS_ERR(pm->clocks[i])) { - mfc_err("Failed to get clock: %s\n", - pm->clk_names[i]); - return PTR_ERR(pm->clocks[i]); - } - } + pm->clocks = devm_clk_bulk_alloc(pm->device, pm->num_clocks, +pm->clk_names); + if (IS_ERR(pm->clocks)) + return PTR_ERR(pm->clocks); + + ret = devm_clk_bulk_get(pm->device, pm->num_clocks, pm->clocks); + if (ret < 0) + return ret; if (dev->variant->use_clock_gating) - pm->clock_gate = pm->clocks[0]; + pm->clock_gate = pm->clocks[0].clk; pm_runtime_enable(pm->device); atomic_set(_ref, 0); @@ -75,43 +75,32 @@ void s5p_mfc_clock_off(void) int s5p_mfc_power_on(void) { - int i, ret = 0; + int ret = 0; ret = pm_runtime_get_sync(pm->device); if (ret < 0) return ret; /* clock control */ - for (i = 0; i < pm->num_clocks; i++) { - ret = clk_prepare_enable(pm->clocks[i]); - if (ret < 0) { - mfc_err("clock prepare failed for clock: %s\n", - pm->clk_names[i]); - i++; - goto err; - } - } + ret = clk_bulk_prepare_enable(pm->num_clocks, pm->clocks); + if (ret < 0) + goto err; /* prepare for software clock gating */ clk_disable(pm->clock_gate); return 0; err: - while (--i > 0) - clk_disable_unprepare(pm->clocks[i]); pm_runtime_put(pm->device); return ret; } int s5p_mfc_power_off(void) { - int i; - /* finish software clock gating */ clk_enable(pm->clock_gate); - for (i = 0; i < pm->num_clocks; i++) - clk_disable_unprepare(pm->clocks[i]); + clk_bulk_disable_unprepare(pm->num_clocks, pm->clocks); return pm_runtime_put_sync(pm->device); } -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 5/8] drm/exynos: mic: Use clk bulk API
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk functions instead of iterating over an array of clks. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/exynos/exynos_drm_mic.c | 41 +++-- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c index 2174814..276558a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c @@ -88,7 +88,7 @@ #define MIC_BS_SIZE_2D(x) ((x) & 0x3fff) -static char *clk_names[] = { "pclk_mic0", "sclk_rgb_vclk_to_mic0" }; +static const char *const clk_names[] = { "pclk_mic0", "sclk_rgb_vclk_to_mic0" }; #define NUM_CLKS ARRAY_SIZE(clk_names) static DEFINE_MUTEX(mic_mutex); @@ -96,7 +96,7 @@ struct exynos_mic { struct device *dev; void __iomem *reg; struct regmap *sysreg; - struct clk *clks[NUM_CLKS]; + struct clk_bulk_data *clks; bool i80_mode; struct videomode vm; @@ -338,10 +338,8 @@ static const struct component_ops exynos_mic_component_ops = { static int exynos_mic_suspend(struct device *dev) { struct exynos_mic *mic = dev_get_drvdata(dev); - int i; - for (i = NUM_CLKS - 1; i > -1; i--) - clk_disable_unprepare(mic->clks[i]); + clk_bulk_disable_unprepare(NUM_CLKS, mic->clks); return 0; } @@ -349,19 +347,8 @@ static int exynos_mic_suspend(struct device *dev) static int exynos_mic_resume(struct device *dev) { struct exynos_mic *mic = dev_get_drvdata(dev); - int ret, i; - - for (i = 0; i < NUM_CLKS; i++) { - ret = clk_prepare_enable(mic->clks[i]); - if (ret < 0) { - DRM_ERROR("Failed to enable clock (%s)\n", - clk_names[i]); - while (--i > -1) - clk_disable_unprepare(mic->clks[i]); - return ret; - } - } - return 0; + + return clk_bulk_prepare_enable(NUM_CLKS, mic->clks); } #endif @@ -374,7 +361,7 @@ static int exynos_mic_probe(struct platform_device *pdev) struct device *dev = >dev; struct exynos_mic *mic; struct resource res; - int ret, i; + int ret; mic = devm_kzalloc(dev, sizeof(*mic), GFP_KERNEL); if (!mic) { @@ -405,16 +392,16 @@ static int exynos_mic_probe(struct platform_device *pdev) goto err; } - for (i = 0; i < NUM_CLKS; i++) { - mic->clks[i] = devm_clk_get(dev, clk_names[i]); - if (IS_ERR(mic->clks[i])) { - DRM_ERROR("mic: Failed to get clock (%s)\n", - clk_names[i]); - ret = PTR_ERR(mic->clks[i]); - goto err; - } + mic->clks = devm_clk_bulk_alloc(dev, NUM_CLKS, clk_names); + if (IS_ERR(mic->clks)) { + ret = PTR_ERR(mic->clks); + goto err; } + ret = devm_clk_bulk_get(dev, NUM_CLKS, mic->clks); + if (ret < 0) + goto err; + platform_set_drvdata(pdev, mic); mic->bridge.funcs = _bridge_funcs; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 4/8] drm/exynos/dsi: Use clk bulk API
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk functions instead of iterating over an array of clks. In order to achieve consistency with other drivers, define clock names in driver's variants structures. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 68 +++-- 1 file changed, 30 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 7904ffa..46a8b5c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -209,11 +209,7 @@ #define DSI_XFER_TIMEOUT_MS100 #define DSI_RX_FIFO_EMPTY 0x3082 -#define OLD_SCLK_MIPI_CLK_NAME "pll_clk" - -static char *clk_names[5] = { "bus_clk", "sclk_mipi", - "phyclk_mipidphy0_bitclkdiv8", "phyclk_mipidphy0_rxclkesc0", - "sclk_rgb_vclk_to_dsim0" }; +#define DSI_MAX_CLOCKS 5 enum exynos_dsi_transfer_type { EXYNOS_DSI_TX, @@ -243,6 +239,7 @@ struct exynos_dsi_driver_data { unsigned int plltmr_reg; unsigned int has_freqband:1; unsigned int has_clklane_stop:1; + const char *clock_names[DSI_MAX_CLOCKS]; unsigned int num_clks; unsigned int max_freq; unsigned int wait_for_reset; @@ -259,7 +256,7 @@ struct exynos_dsi { void __iomem *reg_base; struct phy *phy; - struct clk **clks; + struct clk_bulk_data *clks; struct regulator_bulk_data supplies[2]; int irq; int te_gpio; @@ -453,6 +450,7 @@ static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = { .plltmr_reg = 0x50, .has_freqband = 1, .has_clklane_stop = 1, + .clock_names = {"bus_clk", "pll_clk"}, .num_clks = 2, .max_freq = 1000, .wait_for_reset = 1, @@ -465,6 +463,7 @@ static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = { .plltmr_reg = 0x50, .has_freqband = 1, .has_clklane_stop = 1, + .clock_names = {"bus_clk", "sclk_mipi"}, .num_clks = 2, .max_freq = 1000, .wait_for_reset = 1, @@ -475,6 +474,7 @@ static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = { static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = { .reg_ofs = exynos_reg_ofs, .plltmr_reg = 0x58, + .clock_names = {"bus_clk", "pll_clk"}, .num_clks = 2, .max_freq = 1000, .wait_for_reset = 1, @@ -486,6 +486,10 @@ static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = { .reg_ofs = exynos5433_reg_ofs, .plltmr_reg = 0xa0, .has_clklane_stop = 1, + .clock_names = {"bus_clk", "phyclk_mipidphy0_bitclkdiv8", + "phyclk_mipidphy0_rxclkesc0", + "sclk_rgb_vclk_to_dsim0", + "sclk_mipi"}, .num_clks = 5, .max_freq = 1500, .wait_for_reset = 0, @@ -497,6 +501,7 @@ static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = { .reg_ofs = exynos5433_reg_ofs, .plltmr_reg = 0xa0, .has_clklane_stop = 1, + .clock_names = {"bus_clk", "pll_clk"}, .num_clks = 2, .max_freq = 1500, .wait_for_reset = 1, @@ -1711,7 +1716,7 @@ static int exynos_dsi_probe(struct platform_device *pdev) struct device *dev = >dev; struct resource *res; struct exynos_dsi *dsi; - int ret, i; + int ret; dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); if (!dsi) @@ -1743,26 +1748,15 @@ static int exynos_dsi_probe(struct platform_device *pdev) return -EPROBE_DEFER; } - dsi->clks = devm_kzalloc(dev, - sizeof(*dsi->clks) * dsi->driver_data->num_clks, - GFP_KERNEL); - if (!dsi->clks) - return -ENOMEM; + dsi->clks = devm_clk_bulk_alloc(dev, dsi->driver_data->num_clks, + dsi->driver_data->clock_names); + if (IS_ERR(dsi->clks)) + return PTR_ERR(dsi->clks); - for (i = 0; i < dsi->driver_data->num_clks; i++) { - dsi->clks[i] = devm_clk_get(dev, clk_names[i]); - if (IS_ERR(dsi->clks[i])) { - if (strcmp(clk_names[i], "sclk_mipi") == 0) { - strcpy(clk_names[i], OLD_SCLK_MIPI_CLK_NAME); - i--; - continue; - } - - dev_info(dev, "failed to get the clock: %s\n&qu
[PATCH 7/8] [media] exynos-gsc: Use clk bulk API
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk functions instead of iterating over an array of clks. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/media/platform/exynos-gsc/gsc-core.c | 55 ++-- drivers/media/platform/exynos-gsc/gsc-core.h | 2 +- 2 files changed, 20 insertions(+), 37 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 17854a3..fa7e993 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1149,7 +1149,6 @@ static int gsc_probe(struct platform_device *pdev) struct device *dev = >dev; const struct gsc_driverdata *drv_data = of_device_get_match_data(dev); int ret; - int i; gsc = devm_kzalloc(dev, sizeof(struct gsc_dev), GFP_KERNEL); if (!gsc) @@ -1187,25 +1186,19 @@ static int gsc_probe(struct platform_device *pdev) return -ENXIO; } - for (i = 0; i < gsc->num_clocks; i++) { - gsc->clock[i] = devm_clk_get(dev, drv_data->clk_names[i]); - if (IS_ERR(gsc->clock[i])) { - dev_err(dev, "failed to get clock: %s\n", - drv_data->clk_names[i]); - return PTR_ERR(gsc->clock[i]); - } - } + gsc->clocks = devm_clk_bulk_alloc(dev, gsc->num_clocks, + drv_data->clk_names); + if (IS_ERR(gsc->clocks)) + return PTR_ERR(gsc->clocks); - for (i = 0; i < gsc->num_clocks; i++) { - ret = clk_prepare_enable(gsc->clock[i]); - if (ret) { - dev_err(dev, "clock prepare failed for clock: %s\n", - drv_data->clk_names[i]); - while (--i >= 0) - clk_disable_unprepare(gsc->clock[i]); - return ret; - } - } + ret = devm_clk_bulk_get(dev, gsc->num_clocks, + gsc->clocks); + if (ret) + return ret; + + ret = clk_bulk_prepare_enable(gsc->num_clocks, gsc->clocks); + if (ret) + return ret; ret = devm_request_irq(dev, res->start, gsc_irq_handler, 0, pdev->name, gsc); @@ -1239,15 +1232,14 @@ static int gsc_probe(struct platform_device *pdev) err_v4l2: v4l2_device_unregister(>v4l2_dev); err_clk: - for (i = gsc->num_clocks - 1; i >= 0; i--) - clk_disable_unprepare(gsc->clock[i]); + clk_bulk_disable_unprepare(gsc->num_clocks, gsc->clocks); + return ret; } static int gsc_remove(struct platform_device *pdev) { struct gsc_dev *gsc = platform_get_drvdata(pdev); - int i; pm_runtime_get_sync(>dev); @@ -1255,8 +1247,7 @@ static int gsc_remove(struct platform_device *pdev) v4l2_device_unregister(>v4l2_dev); vb2_dma_contig_clear_max_seg_size(>dev); - for (i = 0; i < gsc->num_clocks; i++) - clk_disable_unprepare(gsc->clock[i]); + clk_bulk_disable_unprepare(gsc->num_clocks, gsc->clocks); pm_runtime_put_noidle(>dev); pm_runtime_disable(>dev); @@ -1307,18 +1298,12 @@ static int gsc_runtime_resume(struct device *dev) { struct gsc_dev *gsc = dev_get_drvdata(dev); int ret = 0; - int i; pr_debug("gsc%d: state: 0x%lx\n", gsc->id, gsc->state); - for (i = 0; i < gsc->num_clocks; i++) { - ret = clk_prepare_enable(gsc->clock[i]); - if (ret) { - while (--i >= 0) - clk_disable_unprepare(gsc->clock[i]); - return ret; - } - } + ret = clk_bulk_prepare_enable(gsc->num_clocks, gsc->clocks); + if (ret) + return ret; gsc_hw_set_sw_reset(gsc); gsc_wait_reset(gsc); @@ -1331,14 +1316,12 @@ static int gsc_runtime_suspend(struct device *dev) { struct gsc_dev *gsc = dev_get_drvdata(dev); int ret = 0; - int i; ret = gsc_m2m_suspend(gsc); if (ret) return ret; - for (i = gsc->num_clocks - 1; i >= 0; i--) - clk_disable_unprepare(gsc->clock[i]); + clk_bulk_disable_unprepare(gsc->num_clocks, gsc->clocks); pr_debug("gsc%d: state: 0x%lx\n", gsc->id, gsc->state); return ret; diff --git a/drivers/media/platform/exynos-gsc/gsc-core.h b/drivers/media/platform/exynos-gsc/gsc-core.h index 715d9c9d..08ff7b9 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.h +++ b/drivers/m
[PATCH 3/8] drm/exynos/decon: Use clk bulk API
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk functions instead of iterating over an array of clks. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 50 --- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 1c330f2..1760fcb 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -55,7 +55,7 @@ struct decon_context { struct exynos_drm_plane_config configs[WINDOWS_NR]; void __iomem*addr; struct regmap *sysreg; - struct clk *clks[ARRAY_SIZE(decon_clks_name)]; + struct clk_bulk_data*clks; unsigned intirq; unsigned intirq_vsync; unsigned intirq_lcd_sys; @@ -485,15 +485,13 @@ static irqreturn_t decon_te_irq_handler(int irq, void *dev_id) static void decon_clear_channels(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = crtc->ctx; - int win, i, ret; + int win, ret; DRM_DEBUG_KMS("%s\n", __FILE__); - for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) { - ret = clk_prepare_enable(ctx->clks[i]); - if (ret < 0) - goto err; - } + ret = clk_bulk_prepare_enable(ARRAY_SIZE(decon_clks_name), ctx->clks); + if (ret < 0) + return; decon_shadow_protect(ctx, true); for (win = 0; win < WINDOWS_NR; win++) @@ -504,10 +502,6 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc) /* TODO: wait for possible vsync */ msleep(50); - -err: - while (--i >= 0) - clk_disable_unprepare(ctx->clks[i]); } static enum drm_mode_status decon_mode_valid(struct exynos_drm_crtc *crtc, @@ -638,10 +632,8 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id) static int exynos5433_decon_suspend(struct device *dev) { struct decon_context *ctx = dev_get_drvdata(dev); - int i = ARRAY_SIZE(decon_clks_name); - while (--i >= 0) - clk_disable_unprepare(ctx->clks[i]); + clk_bulk_disable_unprepare(ARRAY_SIZE(decon_clks_name), ctx->clks); return 0; } @@ -649,19 +641,9 @@ static int exynos5433_decon_suspend(struct device *dev) static int exynos5433_decon_resume(struct device *dev) { struct decon_context *ctx = dev_get_drvdata(dev); - int i, ret; - - for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) { - ret = clk_prepare_enable(ctx->clks[i]); - if (ret < 0) - goto err; - } - - return 0; + int ret; -err: - while (--i >= 0) - clk_disable_unprepare(ctx->clks[i]); + ret = clk_bulk_prepare_enable(ARRAY_SIZE(decon_clks_name), ctx->clks); return ret; } @@ -719,7 +701,6 @@ static int exynos5433_decon_probe(struct platform_device *pdev) struct decon_context *ctx; struct resource *res; int ret; - int i; ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) @@ -732,15 +713,14 @@ static int exynos5433_decon_probe(struct platform_device *pdev) if (ctx->out_type & IFTYPE_HDMI) ctx->first_win = 1; - for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) { - struct clk *clk; - - clk = devm_clk_get(ctx->dev, decon_clks_name[i]); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ctx->clks = devm_clk_bulk_alloc(dev, ARRAY_SIZE(decon_clks_name), + decon_clks_name); + if (IS_ERR(ctx->clks)) + return PTR_ERR(ctx->clks); - ctx->clks[i] = clk; - } + ret = devm_clk_bulk_get(dev, ARRAY_SIZE(decon_clks_name), ctx->clks); + if (ret < 0) + return ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ctx->addr = devm_ioremap_resource(dev, res); -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 6/8] drm/exynos/hdmi: Use clk bulk API
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk functions instead of iterating over an array of clks. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/exynos/exynos_hdmi.c | 97 ++-- 1 file changed, 27 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index a4b75a4..6c208f7 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -136,8 +136,8 @@ struct hdmi_context { int irq; struct regmap *pmureg; struct regmap *sysreg; - struct clk **clk_gates; - struct clk **clk_muxes; + struct clk_bulk_data*clk_gates; + struct clk_bulk_data*clk_muxes; struct regulator_bulk_data regul_bulk[ARRAY_SIZE(supply)]; struct regulator*reg_hdmi_en; struct exynos_drm_clk phy_clk; @@ -739,43 +739,16 @@ static int hdmiphy_reg_write_buf(struct hdmi_context *hdata, } } -static int hdmi_clk_enable_gates(struct hdmi_context *hdata) -{ - int i, ret; - - for (i = 0; i < hdata->drv_data->clk_gates.count; ++i) { - ret = clk_prepare_enable(hdata->clk_gates[i]); - if (!ret) - continue; - - dev_err(hdata->dev, "Cannot enable clock '%s', %d\n", - hdata->drv_data->clk_gates.data[i], ret); - while (i--) - clk_disable_unprepare(hdata->clk_gates[i]); - return ret; - } - - return 0; -} - -static void hdmi_clk_disable_gates(struct hdmi_context *hdata) -{ - int i = hdata->drv_data->clk_gates.count; - - while (i--) - clk_disable_unprepare(hdata->clk_gates[i]); -} - static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy) { struct device *dev = hdata->dev; int ret = 0; + struct clk_bulk_data *clk_muxes = hdata->clk_muxes; int i; for (i = 0; i < hdata->drv_data->clk_muxes.count; i += 3) { - struct clk **c = >clk_muxes[i]; - - ret = clk_set_parent(c[2], c[to_phy]); + ret = clk_set_parent(clk_muxes[i + 2].clk, +clk_muxes[i + to_phy].clk); if (!ret) continue; @@ -1655,54 +1628,36 @@ static irqreturn_t hdmi_irq_thread(int irq, void *arg) return IRQ_HANDLED; } -static int hdmi_clks_get(struct hdmi_context *hdata, -const struct string_array_spec *names, -struct clk **clks) +static struct clk_bulk_data *hdmi_clks_alloc_get(struct hdmi_context *hdata, + const struct string_array_spec *names) { - struct device *dev = hdata->dev; - int i; - - for (i = 0; i < names->count; ++i) { - struct clk *clk = devm_clk_get(dev, names->data[i]); - - if (IS_ERR(clk)) { - int ret = PTR_ERR(clk); + struct clk_bulk_data *ptr; + int ret; - dev_err(dev, "Cannot get clock %s, %d\n", - names->data[i], ret); + ptr = devm_clk_bulk_alloc(hdata->dev, names->count, names->data); + if (IS_ERR(ptr)) + return ptr; - return ret; - } - - clks[i] = clk; - } + ret = devm_clk_bulk_get(hdata->dev, names->count, ptr); + if (ret < 0) + return ERR_PTR(ret); - return 0; + return ptr; } static int hdmi_clk_init(struct hdmi_context *hdata) { const struct hdmi_driver_data *drv_data = hdata->drv_data; - int count = drv_data->clk_gates.count + drv_data->clk_muxes.count; - struct device *dev = hdata->dev; - struct clk **clks; - int ret; - if (!count) - return 0; - - clks = devm_kzalloc(dev, sizeof(*clks) * count, GFP_KERNEL); - if (!clks) - return -ENOMEM; + hdata->clk_muxes = hdmi_clks_alloc_get(hdata, _data->clk_muxes); + if (IS_ERR(hdata->clk_muxes)) + return PTR_ERR(hdata->clk_muxes); - hdata->clk_gates = clks; - hdata->clk_muxes = clks + drv_data->clk_gates.count; + hdata->clk_gates = hdmi_clks_alloc_get(hdata, _data->clk_gates); + if (IS_ERR(hdata->clk_gates)) + return PTR_ERR(hdata->clk_gates); - ret = hdmi_clks_get(hdata, _data->clk_gates, hdata->clk_gates); - if (ret) - return ret; - - return hdmi_clks_get(hdata, _data-&
[PATCH 0/8] Use clk bulk API in exynos5433 drivers
Hi all, the main goal of this patchset is to simplify clk management code in exynos5433 drivers by using clk bulk API. In order to achieve that, patch #1 adds a new function to clk core, which dynamically allocates clk_bulk_data array and fills its id fields. Best regards, Maciej Purski Maciej Purski (8): clk: Add clk_bulk_alloc functions media: s5p-jpeg: Use bulk clk API drm/exynos/decon: Use clk bulk API drm/exynos/dsi: Use clk bulk API drm/exynos: mic: Use clk bulk API drm/exynos/hdmi: Use clk bulk API [media] exynos-gsc: Use clk bulk API [media] s5p-mfc: Use clk bulk API drivers/clk/clk-bulk.c | 16 + drivers/clk/clk-devres.c| 37 +-- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 50 +-- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 68 +--- drivers/gpu/drm/exynos/exynos_drm_mic.c | 44 + drivers/gpu/drm/exynos/exynos_hdmi.c| 85 - drivers/media/platform/exynos-gsc/gsc-core.c| 55 ++-- drivers/media/platform/exynos-gsc/gsc-core.h| 2 +- drivers/media/platform/s5p-jpeg/jpeg-core.c | 45 ++--- drivers/media/platform/s5p-jpeg/jpeg-core.h | 2 +- drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 6 +- drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 41 +--- include/linux/clk.h | 64 +++ 13 files changed, 263 insertions(+), 252 deletions(-) -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/8] media: s5p-jpeg: Use bulk clk API
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk functions instead of iterating over an array of clks. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 45 - drivers/media/platform/s5p-jpeg/jpeg-core.h | 2 +- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 79b63da..681a515 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -2903,7 +2903,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev) { struct s5p_jpeg *jpeg; struct resource *res; - int i, ret; + int ret; /* JPEG IP abstraction struct */ jpeg = devm_kzalloc(>dev, sizeof(struct s5p_jpeg), GFP_KERNEL); @@ -2938,15 +2938,16 @@ static int s5p_jpeg_probe(struct platform_device *pdev) } /* clocks */ - for (i = 0; i < jpeg->variant->num_clocks; i++) { - jpeg->clocks[i] = devm_clk_get(>dev, - jpeg->variant->clk_names[i]); - if (IS_ERR(jpeg->clocks[i])) { - dev_err(>dev, "failed to get clock: %s\n", - jpeg->variant->clk_names[i]); - return PTR_ERR(jpeg->clocks[i]); - } - } + jpeg->clocks = devm_clk_bulk_alloc(>dev, + jpeg->variant->num_clocks, + jpeg->variant->clk_names); + if (IS_ERR(jpeg->clocks)) + return PTR_ERR(jpeg->clocks); + + ret = devm_clk_bulk_get(>dev, jpeg->variant->num_clocks, + jpeg->clocks); + if (ret < 0) + return ret; /* v4l2 device */ ret = v4l2_device_register(>dev, >v4l2_dev); @@ -3047,7 +3048,6 @@ static int s5p_jpeg_probe(struct platform_device *pdev) static int s5p_jpeg_remove(struct platform_device *pdev) { struct s5p_jpeg *jpeg = platform_get_drvdata(pdev); - int i; pm_runtime_disable(jpeg->dev); @@ -3058,8 +3058,8 @@ static int s5p_jpeg_remove(struct platform_device *pdev) v4l2_device_unregister(>v4l2_dev); if (!pm_runtime_status_suspended(>dev)) { - for (i = jpeg->variant->num_clocks - 1; i >= 0; i--) - clk_disable_unprepare(jpeg->clocks[i]); + clk_bulk_disable_unprepare(jpeg->variant->num_clocks, + jpeg->clocks); } return 0; @@ -3069,10 +3069,8 @@ static int s5p_jpeg_remove(struct platform_device *pdev) static int s5p_jpeg_runtime_suspend(struct device *dev) { struct s5p_jpeg *jpeg = dev_get_drvdata(dev); - int i; - for (i = jpeg->variant->num_clocks - 1; i >= 0; i--) - clk_disable_unprepare(jpeg->clocks[i]); + clk_bulk_disable_unprepare(jpeg->variant->num_clocks, jpeg->clocks); return 0; } @@ -3081,16 +3079,11 @@ static int s5p_jpeg_runtime_resume(struct device *dev) { struct s5p_jpeg *jpeg = dev_get_drvdata(dev); unsigned long flags; - int i, ret; - - for (i = 0; i < jpeg->variant->num_clocks; i++) { - ret = clk_prepare_enable(jpeg->clocks[i]); - if (ret) { - while (--i >= 0) - clk_disable_unprepare(jpeg->clocks[i]); - return ret; - } - } + int ret; + + ret = clk_bulk_prepare_enable(jpeg->variant->num_clocks, jpeg->clocks); + if (ret) + return ret; spin_lock_irqsave(>slock, flags); diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h index a46465e..dc6ed98 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.h +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h @@ -133,7 +133,7 @@ struct s5p_jpeg { void __iomem*regs; unsigned intirq; enum exynos4_jpeg_result irq_ret; - struct clk *clocks[JPEG_MAX_CLOCKS]; + struct clk_bulk_data*clocks; struct device *dev; struct s5p_jpeg_variant *variant; u32 irq_status; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/8] clk: Add clk_bulk_alloc functions
When a driver is going to use clk_bulk_get() function, it has to initialize an array of clk_bulk_data, by filling its id fields. Add a new function to the core, which dynamically allocates clk_bulk_data array and fills its id fields. Add clk_bulk_free() function, which frees the array allocated by clk_bulk_alloc() function. Add a managed version of clk_bulk_alloc(). Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/clk/clk-bulk.c | 16 drivers/clk/clk-devres.c | 37 +--- include/linux/clk.h | 64 3 files changed, 113 insertions(+), 4 deletions(-) diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c index 4c10456..2f16941 100644 --- a/drivers/clk/clk-bulk.c +++ b/drivers/clk/clk-bulk.c @@ -19,6 +19,22 @@ #include #include #include +#include + +struct clk_bulk_data *clk_bulk_alloc(int num_clocks, const char *const *clk_ids) +{ + struct clk_bulk_data *ptr; + int i; + + ptr = kcalloc(num_clocks, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < num_clocks; i++) + ptr[i].id = clk_ids[i]; + + return ptr; +} void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) { diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c index d854e26..2115b97 100644 --- a/drivers/clk/clk-devres.c +++ b/drivers/clk/clk-devres.c @@ -9,6 +9,39 @@ #include #include +struct clk_bulk_devres { + struct clk_bulk_data *clks; + int num_clks; +}; + +static void devm_clk_alloc_release(struct device *dev, void *res) +{ + struct clk_bulk_devres *devres = res; + + clk_bulk_free(devres->clks); +} + +struct clk_bulk_data *devm_clk_bulk_alloc(struct device *dev, int num_clks, + const char *const *clk_ids) +{ + struct clk_bulk_data **ptr, *clk_bulk; + + ptr = devres_alloc(devm_clk_alloc_release, + num_clks * sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + clk_bulk = clk_bulk_alloc(num_clks, clk_ids); + if (clk_bulk) { + *ptr = clk_bulk; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return clk_bulk; +} + static void devm_clk_release(struct device *dev, void *res) { clk_put(*(struct clk **)res); @@ -34,10 +67,6 @@ struct clk *devm_clk_get(struct device *dev, const char *id) } EXPORT_SYMBOL(devm_clk_get); -struct clk_bulk_devres { - struct clk_bulk_data *clks; - int num_clks; -}; static void devm_clk_bulk_release(struct device *dev, void *res) { diff --git a/include/linux/clk.h b/include/linux/clk.h index 4c4ef9f..7d66f41 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -15,6 +15,7 @@ #include #include #include +#include struct device; struct clk; @@ -240,6 +241,52 @@ static inline void clk_bulk_unprepare(int num_clks, struct clk_bulk_data *clks) #endif #ifdef CONFIG_HAVE_CLK + +/** + * clk_bulk_alloc - allocates an array of clk_bulk_data and fills their + * id field + * @num_clks: number of clk_bulk_data + * @clk_ids: array of clock consumer ID's + * + * This function allows drivers to dynamically create an array of clk_bulk_data + * and fill their id field in one operation. If successful, it allows calling + * clk_bulk_get on the pointer returned by this function. + * + * Returns a pointer to a clk_bulk_data array, or valid IS_ERR() condition + * containing errno. + */ +struct clk_bulk_data *clk_bulk_alloc(int num_clks, const char *const *clk_ids); + +/** + * devm_clk_bulk_alloc - allocates an array of clk_bulk_data and fills their + * id field + * @dev: device for clock "consumer" + * @num_clks: number of clk_bulk_data + * @clk_ids: array of clock consumer ID's + * + * This function allows drivers to dynamically create an array of clk_bulk_data + * and fill their id field in one operation with management, the array will + * automatically be freed when the device is unbound. If successful, it allows + * calling clk_bulk_get on the pointer returned by this function. + * + * Returns a pointer to a clk_bulk_data array, or valid IS_ERR() condition + * containing errno. + */ +struct clk_bulk_data *devm_clk_bulk_alloc(struct device *dev, int num_clks, + const char * const *clk_ids); + +/** + * clk_bulk_free - frees the array of clk_bulk_data + * @clks: pointer to clk_bulk_data array + * + * This function frees the array allocated by clk_bulk_data. It must be called + * when all clks are freed. + */ +static inline void clk_bulk_free(struct clk_bulk_data *clks) +{ + kfree(clks); +} + /** * clk_get - lookup and obtain a reference to a clock producer. * @dev: device for clock "consumer" @@ -598,6 +645,23 @@ st
[PATCH v2] drm/bridge/sii8620: fix display modes validation
Current implementation of mode_valid() and mode_fixup() callbacks handle packed pixel modes improperly. Fix it by using proper maximum clock values from the documentation. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- Changes in v2: - simplify is_packing_required() function - fix uninitialized variable detected by kbuild robot in mode_valid() --- drivers/gpu/drm/bridge/sil-sii8620.c | 81 +++- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 5168783..912d8c2 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -34,8 +34,11 @@ #define SII8620_BURST_BUF_LEN 288 #define VAL_RX_HDMI_CTRL2_DEFVAL VAL_RX_HDMI_CTRL2_IDLE_CNT(3) -#define MHL1_MAX_LCLK 225000 -#define MHL3_MAX_LCLK 60 + +#define MHL1_MAX_PCLK 75000 +#define MHL1_MAX_PCLK_PP_MODE 15 +#define MHL3_MAX_PCLK 20 +#define MHL3_MAX_PCLK_PP_MODE 30 enum sii8620_mode { CM_DISCONNECTED, @@ -2123,61 +2126,61 @@ static void sii8620_detach(struct drm_bridge *bridge) rc_unregister_device(ctx->rc_dev); } +static int sii8620_is_packing_required(struct sii8620 *ctx, +const struct drm_display_mode *mode) +{ + int max_pclk, max_pclk_pp_mode; + + if (sii8620_is_mhl3(ctx)) { + max_pclk = MHL3_MAX_PCLK; + max_pclk_pp_mode = MHL3_MAX_PCLK_PP_MODE; + } else { + max_pclk = MHL1_MAX_PCLK; + max_pclk_pp_mode = MHL1_MAX_PCLK_PP_MODE; + } + + if (mode->clock < max_pclk) + return 0; + else if (mode->clock < max_pclk_pp_mode) + return 1; + else + return -1; +} + static enum drm_mode_status sii8620_mode_valid(struct drm_bridge *bridge, const struct drm_display_mode *mode) { struct sii8620 *ctx = bridge_to_sii8620(bridge); + int pack_required = sii8620_is_packing_required(ctx, mode); bool can_pack = ctx->devcap[MHL_DCAP_VID_LINK_MODE] & MHL_DCAP_VID_LINK_PPIXEL; - unsigned int max_pclk = sii8620_is_mhl3(ctx) ? MHL3_MAX_LCLK : - MHL1_MAX_LCLK; - max_pclk /= can_pack ? 2 : 3; - return (mode->clock > max_pclk) ? MODE_CLOCK_HIGH : MODE_OK; + switch (pack_required) { + case 0: + return MODE_OK; + case 1: + return (can_pack) ? MODE_OK : MODE_CLOCK_HIGH; + default: + return MODE_CLOCK_HIGH; + } } + static bool sii8620_mode_fixup(struct drm_bridge *bridge, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { struct sii8620 *ctx = bridge_to_sii8620(bridge); - int max_lclk; - bool ret = true; mutex_lock(>lock); - max_lclk = sii8620_is_mhl3(ctx) ? MHL3_MAX_LCLK : MHL1_MAX_LCLK; - if (max_lclk > 3 * adjusted_mode->clock) { - ctx->use_packed_pixel = 0; - goto end; - } - if ((ctx->devcap[MHL_DCAP_VID_LINK_MODE] & MHL_DCAP_VID_LINK_PPIXEL) && - max_lclk > 2 * adjusted_mode->clock) { - ctx->use_packed_pixel = 1; - goto end; - } - ret = false; -end: - if (ret) { - u8 vic = drm_match_cea_mode(adjusted_mode); - - if (!vic) { - union hdmi_infoframe frm; - u8 mhl_vic[] = { 0, 95, 94, 93, 98 }; - - /* FIXME: We need the connector here */ - drm_hdmi_vendor_infoframe_from_display_mode( - , NULL, adjusted_mode); - vic = frm.vendor.hdmi.vic; - if (vic >= ARRAY_SIZE(mhl_vic)) - vic = 0; - vic = mhl_vic[vic]; - } - ctx->video_code = vic; - ctx->pixel_clock = adjusted_mode->clock; - } + ctx->use_packed_pixel = sii8620_is_packing_required(ctx, adjusted_mode); + ctx->video_code = drm_match_cea_mode(adjusted_mode); + ctx->pixel_clock = adjusted_mode->clock; + mutex_unlock(>lock); - return ret; + + return true; } static const struct drm_bridge_funcs sii8620_bridge_funcs = { -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2] drm/bridge/sii8620: fix HDMI cable connection to dongle
MHL bridge is usually connected to TV via MHL dongle. Currently plugging HDMI cable to dongle is handled improperly. Fix it by splitting connecting of a dongle and a HDMI cable. The driver should now handle unplugging a sink from a dongle and plugging a different sink with new edid. Tested on MHL1, MHL2 and MHL3 using various vendors' dongles both in DVI and HDMI mode. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- Changes in v2: - handle MHL1 and MHL2 initialization sequence - rename hpd_plugged() function to identify_sink(), as it is now used in different contexts - fix commit message --- drivers/gpu/drm/bridge/sil-sii8620.c | 64 +++- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 46ccceb..5168783 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -78,6 +78,9 @@ struct sii8620 { u8 devcap[MHL_DCAP_SIZE]; u8 xdevcap[MHL_XDC_SIZE]; u8 avif[HDMI_INFOFRAME_SIZE(AVI)]; + bool feature_complete; + bool devcap_read; + bool sink_detected; struct edid *edid; unsigned int gen2_write_burst:1; enum sii8620_mt_state mt_state; @@ -470,7 +473,7 @@ static void sii8620_update_array(u8 *dst, u8 *src, int count) } } -static void sii8620_sink_detected(struct sii8620 *ctx, int ret) +static void sii8620_identify_sink(struct sii8620 *ctx) { static const char * const sink_str[] = { [SINK_NONE] = "NONE", @@ -481,7 +484,7 @@ static void sii8620_sink_detected(struct sii8620 *ctx, int ret) char sink_name[20]; struct device *dev = ctx->dev; - if (ret < 0) + if (!ctx->sink_detected || !ctx->devcap_read) return; sii8620_fetch_edid(ctx); @@ -490,6 +493,7 @@ static void sii8620_sink_detected(struct sii8620 *ctx, int ret) sii8620_mhl_disconnected(ctx); return; } + sii8620_set_upstream_edid(ctx); if (drm_detect_hdmi_monitor(ctx->edid)) ctx->sink_type = SINK_HDMI; @@ -502,15 +506,6 @@ static void sii8620_sink_detected(struct sii8620 *ctx, int ret) sink_str[ctx->sink_type], sink_name); } -static void sii8620_edid_read(struct sii8620 *ctx, int ret) -{ - if (ret < 0) - return; - - sii8620_set_upstream_edid(ctx); - sii8620_enable_hpd(ctx); -} - static void sii8620_mr_devcap(struct sii8620 *ctx) { u8 dcap[MHL_DCAP_SIZE]; @@ -526,6 +521,8 @@ static void sii8620_mr_devcap(struct sii8620 *ctx) dcap[MHL_DCAP_ADOPTER_ID_H], dcap[MHL_DCAP_ADOPTER_ID_L], dcap[MHL_DCAP_DEVICE_ID_H], dcap[MHL_DCAP_DEVICE_ID_L]); sii8620_update_array(ctx->devcap, dcap, MHL_DCAP_SIZE); + ctx->devcap_read = true; + sii8620_identify_sink(ctx); } static void sii8620_mr_xdevcap(struct sii8620 *ctx) @@ -1491,6 +1488,16 @@ static void sii8620_set_mode(struct sii8620 *ctx, enum sii8620_mode mode) ); } +static void sii8620_hpd_unplugged(struct sii8620 *ctx) +{ + sii8620_disable_hpd(ctx); + ctx->sink_type = SINK_NONE; + ctx->sink_detected = false; + ctx->feature_complete = false; + kfree(ctx->edid); + ctx->edid = NULL; +} + static void sii8620_disconnect(struct sii8620 *ctx) { sii8620_disable_gen2_write_burst(ctx); @@ -1518,7 +1525,7 @@ static void sii8620_disconnect(struct sii8620 *ctx) REG_MHL_DP_CTL6, 0x2A, REG_MHL_DP_CTL7, 0x03 ); - sii8620_disable_hpd(ctx); + sii8620_hpd_unplugged(ctx); sii8620_write_seq_static(ctx, REG_M3_CTRL, VAL_M3_CTRL_MHL3_VALUE, REG_MHL_COC_CTL1, 0x07, @@ -1566,10 +1573,8 @@ static void sii8620_disconnect(struct sii8620 *ctx) memset(ctx->xstat, 0, sizeof(ctx->xstat)); memset(ctx->devcap, 0, sizeof(ctx->devcap)); memset(ctx->xdevcap, 0, sizeof(ctx->xdevcap)); + ctx->devcap_read = false; ctx->cbus_status = 0; - ctx->sink_type = SINK_NONE; - kfree(ctx->edid); - ctx->edid = NULL; sii8620_mt_cleanup(ctx); } @@ -1660,9 +1665,6 @@ static void sii8620_status_changed_path(struct sii8620 *ctx) sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE), MHL_DST_LM_CLK_MODE_NORMAL | MHL_DST_LM_PATH_ENABLED); - if (!sii8620_is_mhl3(ctx)) - sii8620_mt_read_devcap(ctx, false); - sii8620_mt_set_cont(ctx, sii8620_sink_detected); } else { sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE), MHL_DST_LM_CLK_MODE_NORMAL); @@ -1679,9 +1681,
[PATCH] drm/bridge/sii8620: fix display of packed pixel modes in MHL2
Currently packed pixel modes in MHL2 can't be displayed. The device automatically recognizes output format, so setting format other than RGB causes failure. Fix it by writing proper values to registers. Tested on MHL1 and MHL2 using various vendors' dongles both in DVI and HDMI mode. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/bridge/sil-sii8620.c | 17 + 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 1718c2e..e13708d 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -1005,20 +1005,11 @@ static void sii8620_stop_video(struct sii8620 *ctx) static void sii8620_set_format(struct sii8620 *ctx) { - u8 out_fmt; - if (sii8620_is_mhl3(ctx)) { sii8620_setbits(ctx, REG_M3_P0CTRL, BIT_M3_P0CTRL_MHL3_P0_PIXEL_MODE_PACKED, ctx->use_packed_pixel ? ~0 : 0); } else { - if (ctx->use_packed_pixel) - sii8620_write_seq_static(ctx, - REG_VID_MODE, BIT_VID_MODE_M1080P, - REG_MHL_TOP_CTL, BIT_MHL_TOP_CTL_MHL_PP_SEL | 1, - REG_MHLTX_CTL6, 0x60 - ); - else sii8620_write_seq_static(ctx, REG_VID_MODE, 0, REG_MHL_TOP_CTL, 1, @@ -1026,15 +1017,9 @@ static void sii8620_set_format(struct sii8620 *ctx) ); } - if (ctx->use_packed_pixel) - out_fmt = VAL_TPI_FORMAT(YCBCR422, FULL) | - BIT_TPI_OUTPUT_CSCMODE709; - else - out_fmt = VAL_TPI_FORMAT(RGB, FULL); - sii8620_write_seq(ctx, REG_TPI_INPUT, VAL_TPI_FORMAT(RGB, FULL), - REG_TPI_OUTPUT, out_fmt, + REG_TPI_OUTPUT, VAL_TPI_FORMAT(RGB, FULL), ); } -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/bridge/sii8620: fix display modes validation
Current implementation of mode_valid() and mode_fixup() callbacks handle packed pixel modes improperly. Fix it by using proper maximum clock values from the documentation. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/bridge/sil-sii8620.c | 90 1 file changed, 51 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 5168783..1718c2e 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -34,8 +34,11 @@ #define SII8620_BURST_BUF_LEN 288 #define VAL_RX_HDMI_CTRL2_DEFVAL VAL_RX_HDMI_CTRL2_IDLE_CNT(3) -#define MHL1_MAX_LCLK 225000 -#define MHL3_MAX_LCLK 60 + +#define MHL1_MAX_PCLK 75000 +#define MHL1_MAX_PCLK_PP_MODE 15 +#define MHL3_MAX_PCLK 20 +#define MHL3_MAX_PCLK_PP_MODE 30 enum sii8620_mode { CM_DISCONNECTED, @@ -2123,61 +2126,70 @@ static void sii8620_detach(struct drm_bridge *bridge) rc_unregister_device(ctx->rc_dev); } +static int sii8620_is_packing_required(struct sii8620 *ctx, +const struct drm_display_mode *mode) +{ + int ret; + + if (sii8620_is_mhl3(ctx)) { + if (mode->clock < MHL3_MAX_PCLK) + ret = 0; + else if (mode->clock < MHL3_MAX_PCLK_PP_MODE) + ret = 1; + else + ret = -1; + } else { + if (mode->clock < MHL1_MAX_PCLK) + ret = 0; + else if (mode->clock < MHL1_MAX_PCLK_PP_MODE) + ret = 1; + else + ret = -1; + } + + return ret; +} + static enum drm_mode_status sii8620_mode_valid(struct drm_bridge *bridge, const struct drm_display_mode *mode) { + enum drm_mode_status ret; struct sii8620 *ctx = bridge_to_sii8620(bridge); + int pack_required = sii8620_is_packing_required(ctx, mode); bool can_pack = ctx->devcap[MHL_DCAP_VID_LINK_MODE] & MHL_DCAP_VID_LINK_PPIXEL; - unsigned int max_pclk = sii8620_is_mhl3(ctx) ? MHL3_MAX_LCLK : - MHL1_MAX_LCLK; - max_pclk /= can_pack ? 2 : 3; - return (mode->clock > max_pclk) ? MODE_CLOCK_HIGH : MODE_OK; + switch (pack_required) { + case -1: + ret = MODE_CLOCK_HIGH; + break; + case 1: + ret = (can_pack) ? MODE_OK : MODE_CLOCK_HIGH; + break; + case 0: + ret = MODE_OK; + break; + } + + return ret; } + static bool sii8620_mode_fixup(struct drm_bridge *bridge, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { struct sii8620 *ctx = bridge_to_sii8620(bridge); - int max_lclk; - bool ret = true; mutex_lock(>lock); - max_lclk = sii8620_is_mhl3(ctx) ? MHL3_MAX_LCLK : MHL1_MAX_LCLK; - if (max_lclk > 3 * adjusted_mode->clock) { - ctx->use_packed_pixel = 0; - goto end; - } - if ((ctx->devcap[MHL_DCAP_VID_LINK_MODE] & MHL_DCAP_VID_LINK_PPIXEL) && - max_lclk > 2 * adjusted_mode->clock) { - ctx->use_packed_pixel = 1; - goto end; - } - ret = false; -end: - if (ret) { - u8 vic = drm_match_cea_mode(adjusted_mode); - - if (!vic) { - union hdmi_infoframe frm; - u8 mhl_vic[] = { 0, 95, 94, 93, 98 }; - - /* FIXME: We need the connector here */ - drm_hdmi_vendor_infoframe_from_display_mode( - , NULL, adjusted_mode); - vic = frm.vendor.hdmi.vic; - if (vic >= ARRAY_SIZE(mhl_vic)) - vic = 0; - vic = mhl_vic[vic]; - } - ctx->video_code = vic; - ctx->pixel_clock = adjusted_mode->clock; - } + ctx->use_packed_pixel = sii8620_is_packing_required(ctx, adjusted_mode); + ctx->video_code = drm_match_cea_mode(adjusted_mode); + ctx->pixel_clock = adjusted_mode->clock; + mutex_unlock(>lock); - return ret; + + return true; } static const struct drm_bridge_funcs sii8620_bridge_funcs = { -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/2] drm/bridge/sii8620: fix HDMI cable connection to dongle
MHL bridge is usually connected to TV via MHL dongle. Currently plugging HDMI cable to dongle is handled improperly. This patch fixes it. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/bridge/sil-sii8620.c | 49 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 35ccc90..857d2cb5 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -78,6 +78,7 @@ struct sii8620 { u8 devcap[MHL_DCAP_SIZE]; u8 xdevcap[MHL_XDC_SIZE]; u8 avif[HDMI_INFOFRAME_SIZE(AVI)]; + bool feature_complete; struct edid *edid; unsigned int gen2_write_burst:1; enum sii8620_mt_state mt_state; @@ -470,7 +471,7 @@ static void sii8620_update_array(u8 *dst, u8 *src, int count) } } -static void sii8620_sink_detected(struct sii8620 *ctx, int ret) +static void sii8620_hpd_plugged(struct sii8620 *ctx) { static const char * const sink_str[] = { [SINK_NONE] = "NONE", @@ -481,15 +482,13 @@ static void sii8620_sink_detected(struct sii8620 *ctx, int ret) char sink_name[20]; struct device *dev = ctx->dev; - if (ret < 0) - return; - sii8620_fetch_edid(ctx); if (!ctx->edid) { dev_err(ctx->dev, "Cannot fetch EDID\n"); sii8620_mhl_disconnected(ctx); return; } + sii8620_set_upstream_edid(ctx); if (drm_detect_hdmi_monitor(ctx->edid)) ctx->sink_type = SINK_HDMI; @@ -502,15 +501,6 @@ static void sii8620_sink_detected(struct sii8620 *ctx, int ret) sink_str[ctx->sink_type], sink_name); } -static void sii8620_edid_read(struct sii8620 *ctx, int ret) -{ - if (ret < 0) - return; - - sii8620_set_upstream_edid(ctx); - sii8620_enable_hpd(ctx); -} - static void sii8620_mr_devcap(struct sii8620 *ctx) { u8 dcap[MHL_DCAP_SIZE]; @@ -1490,6 +1480,15 @@ static void sii8620_set_mode(struct sii8620 *ctx, enum sii8620_mode mode) ); } +static void sii8620_hpd_unplugged(struct sii8620 *ctx) +{ + sii8620_disable_hpd(ctx); + ctx->sink_type = SINK_NONE; + ctx->feature_complete = false; + kfree(ctx->edid); + ctx->edid = NULL; +} + static void sii8620_disconnect(struct sii8620 *ctx) { sii8620_disable_gen2_write_burst(ctx); @@ -1517,7 +1516,7 @@ static void sii8620_disconnect(struct sii8620 *ctx) REG_MHL_DP_CTL6, 0x2A, REG_MHL_DP_CTL7, 0x03 ); - sii8620_disable_hpd(ctx); + sii8620_hpd_unplugged(ctx); sii8620_write_seq_static(ctx, REG_M3_CTRL, VAL_M3_CTRL_MHL3_VALUE, REG_MHL_COC_CTL1, 0x07, @@ -1566,9 +1565,6 @@ static void sii8620_disconnect(struct sii8620 *ctx) memset(ctx->devcap, 0, sizeof(ctx->devcap)); memset(ctx->xdevcap, 0, sizeof(ctx->xdevcap)); ctx->cbus_status = 0; - ctx->sink_type = SINK_NONE; - kfree(ctx->edid); - ctx->edid = NULL; sii8620_mt_cleanup(ctx); } @@ -1661,7 +1657,6 @@ static void sii8620_status_changed_path(struct sii8620 *ctx) | MHL_DST_LM_PATH_ENABLED); if (!sii8620_is_mhl3(ctx)) sii8620_mt_read_devcap(ctx, false); - sii8620_mt_set_cont(ctx, sii8620_sink_detected); } else { sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE), MHL_DST_LM_CLK_MODE_NORMAL); @@ -1764,8 +1759,11 @@ static void sii8620_msc_mr_set_int(struct sii8620 *ctx) } if (ints[MHL_INT_RCHANGE] & MHL_INT_RC_FEAT_REQ) sii8620_send_features(ctx); - if (ints[MHL_INT_RCHANGE] & MHL_INT_RC_FEAT_COMPLETE) - sii8620_edid_read(ctx, 0); + if (ints[MHL_INT_RCHANGE] & MHL_INT_RC_FEAT_COMPLETE) { + ctx->feature_complete = true; + if (ctx->edid) + sii8620_enable_hpd(ctx); + } } static struct sii8620_mt_msg *sii8620_msc_msg_first(struct sii8620 *ctx) @@ -1840,6 +1838,13 @@ static void sii8620_irq_msc(struct sii8620 *ctx) if (stat & BIT_CBUS_MSC_MR_WRITE_STAT) sii8620_msc_mr_write_stat(ctx); + if (stat & BIT_CBUS_HPD_CHG) { + if (ctx->cbus_status & BIT_CBUS_STATUS_CBUS_HPD) + sii8620_hpd_plugged(ctx); + else + sii8620_hpd_unplugged(ctx); + } + if (stat & BIT_CBUS_MSC_MR_SET_INT) sii8620_msc_mr_set_int(ctx); @@ -1951,11 +1956,11 @@ static void sii8620_irq_ddc(struct sii8620 *ctx) if
[PATCH 1/2] drm/bridge/sii8620: remove HSIC initialization
HSIC initialization was taken from the vendor code. HSIC in MHL circuit is not connected, so it is not possible to test it. Tests prove that without HSIC the device works well. Therefore it can be removed. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/bridge/sil-sii8620.c | 38 1 file changed, 38 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index e81c96a..35ccc90 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -502,50 +502,12 @@ static void sii8620_sink_detected(struct sii8620 *ctx, int ret) sink_str[ctx->sink_type], sink_name); } -static void sii8620_hsic_init(struct sii8620 *ctx) -{ - if (!sii8620_is_mhl3(ctx)) - return; - - sii8620_write(ctx, REG_FCGC, - BIT_FCGC_HSIC_HOSTMODE | BIT_FCGC_HSIC_ENABLE); - sii8620_setbits(ctx, REG_HRXCTRL3, - BIT_HRXCTRL3_HRX_STAY_RESET | BIT_HRXCTRL3_STATUS_EN, ~0); - sii8620_setbits(ctx, REG_TTXNUMB, MSK_TTXNUMB_TTX_NUMBPS, 4); - sii8620_setbits(ctx, REG_TRXCTRL, BIT_TRXCTRL_TRX_FROM_SE_COC, ~0); - sii8620_setbits(ctx, REG_HTXCTRL, BIT_HTXCTRL_HTX_DRVCONN1, 0); - sii8620_setbits(ctx, REG_KEEPER, MSK_KEEPER_MODE, VAL_KEEPER_MODE_HOST); - sii8620_write_seq_static(ctx, - REG_TDMLLCTL, 0, - REG_UTSRST, BIT_UTSRST_HRX_SRST | BIT_UTSRST_HTX_SRST | - BIT_UTSRST_KEEPER_SRST | BIT_UTSRST_FC_SRST, - REG_UTSRST, BIT_UTSRST_HRX_SRST | BIT_UTSRST_HTX_SRST, - REG_HRXINTL, 0xff, - REG_HRXINTH, 0xff, - REG_TTXINTL, 0xff, - REG_TTXINTH, 0xff, - REG_TRXINTL, 0xff, - REG_TRXINTH, 0xff, - REG_HTXINTL, 0xff, - REG_HTXINTH, 0xff, - REG_FCINTR0, 0xff, - REG_FCINTR1, 0xff, - REG_FCINTR2, 0xff, - REG_FCINTR3, 0xff, - REG_FCINTR4, 0xff, - REG_FCINTR5, 0xff, - REG_FCINTR6, 0xff, - REG_FCINTR7, 0xff - ); -} - static void sii8620_edid_read(struct sii8620 *ctx, int ret) { if (ret < 0) return; sii8620_set_upstream_edid(ctx); - sii8620_hsic_init(ctx); sii8620_enable_hpd(ctx); } -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/bridge/sii8620: start MHL transmission after HDMI signal detection
The vendor code waits for infoframe to detect video mode set by source. We do not need to follow this pattern, because video mode information is provided by drm core. As a result most of the infoframe handling code can be removed. Start transmission immediately after detecting stream on HDMI lines in irq_scdt() function without waiting for infoframe interrupt. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/bridge/sil-sii8620.c | 53 ++-- 1 file changed, 2 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 86789f8..e81c96a 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -1925,14 +1925,6 @@ static void sii8620_irq_edid(struct sii8620 *ctx) ctx->mt_state = MT_STATE_DONE; } -static void sii8620_scdt_high(struct sii8620 *ctx) -{ - sii8620_write_seq_static(ctx, - REG_INTR8_MASK, BIT_CEA_NEW_AVI | BIT_CEA_NEW_VSI, - REG_TPI_SC, BIT_TPI_SC_TPI_OUTPUT_MODE_0_HDMI, - ); -} - static void sii8620_irq_scdt(struct sii8620 *ctx) { u8 stat = sii8620_readb(ctx, REG_INTR5); @@ -1940,53 +1932,13 @@ static void sii8620_irq_scdt(struct sii8620 *ctx) if (stat & BIT_INTR_SCDT_CHANGE) { u8 cstat = sii8620_readb(ctx, REG_TMDS_CSTAT_P3); - if (cstat & BIT_TMDS_CSTAT_P3_SCDT) { - if (ctx->sink_type == SINK_HDMI) - /* enable infoframe interrupt */ - sii8620_scdt_high(ctx); - else - sii8620_start_video(ctx); - } + if (cstat & BIT_TMDS_CSTAT_P3_SCDT) + sii8620_start_video(ctx); } sii8620_write(ctx, REG_INTR5, stat); } -static void sii8620_new_vsi(struct sii8620 *ctx) -{ - u8 vsif[11]; - - sii8620_write(ctx, REG_RX_HDMI_CTRL2, - VAL_RX_HDMI_CTRL2_DEFVAL | - BIT_RX_HDMI_CTRL2_VSI_MON_SEL_VSI); - sii8620_read_buf(ctx, REG_RX_HDMI_MON_PKT_HEADER1, vsif, -ARRAY_SIZE(vsif)); -} - -static void sii8620_new_avi(struct sii8620 *ctx) -{ - sii8620_write(ctx, REG_RX_HDMI_CTRL2, VAL_RX_HDMI_CTRL2_DEFVAL); - sii8620_read_buf(ctx, REG_RX_HDMI_MON_PKT_HEADER1, ctx->avif, -ARRAY_SIZE(ctx->avif)); -} - -static void sii8620_irq_infr(struct sii8620 *ctx) -{ - u8 stat = sii8620_readb(ctx, REG_INTR8) - & (BIT_CEA_NEW_VSI | BIT_CEA_NEW_AVI); - - sii8620_write(ctx, REG_INTR8, stat); - - if (stat & BIT_CEA_NEW_VSI) - sii8620_new_vsi(ctx); - - if (stat & BIT_CEA_NEW_AVI) - sii8620_new_avi(ctx); - - if (stat & (BIT_CEA_NEW_VSI | BIT_CEA_NEW_AVI)) - sii8620_start_video(ctx); -} - static void sii8620_got_xdevcap(struct sii8620 *ctx, int ret) { if (ret < 0) @@ -2068,7 +2020,6 @@ static irqreturn_t sii8620_irq_thread(int irq, void *data) { BIT_FAST_INTR_STAT_EDID, sii8620_irq_edid }, { BIT_FAST_INTR_STAT_DDC, sii8620_irq_ddc }, { BIT_FAST_INTR_STAT_SCDT, sii8620_irq_scdt }, - { BIT_FAST_INTR_STAT_INFR, sii8620_irq_infr }, }; struct sii8620 *ctx = data; u8 stats[LEN_FAST_INTR_STAT]; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/bridge/sii8620: fix potential buffer overflow
Buffer overflow error should not occur, as mode_fixup() callback filters pixel clock value and it should never exceed 60. However, current implementation is not obviously safe and relies on implementation of mode_fixup(). Make 'i' variable never reach unsafe value in order to avoid buffer overflow error. Reported-by: Dan Carpenter <dan.carpen...@oracle.com> Fixes: bf1722ca ("drm/bridge/sii8620: rewrite hdmi start sequence") Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/bridge/sil-sii8620.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index d58db13..25ae0e5 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -1210,7 +1210,7 @@ static void sii8620_start_video(struct sii8620 *ctx) int clk = ctx->pixel_clock * (ctx->use_packed_pixel ? 2 : 3); int i; - for (i = 0; i < ARRAY_SIZE(clk_spec); ++i) + for (i = 0; i < ARRAY_SIZE(clk_spec) - 1; ++i) if (clk < clk_spec[i].max_clk) break; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2] drm/bridge/sii8620: add DVI mode support
If the sink device is in HDMI mode, enable infoframe interrupt in scdt irq handle function else call start_video function immediately, because in DVI mode, there is no infoframe interrupt provided. Rename start_hdmi function to start_video and get rid of the old start_video function. In start_video, if the sink is DVI and mode is MHL1 or MHl2, write appropriate values to registers else the path should remain the same as in HDMI mode. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- v2: - remove redundant defines --- drivers/gpu/drm/bridge/sil-sii8620.c | 36 ++-- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index b7eb704..bbf5200 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -1169,8 +1169,18 @@ static void sii8620_set_infoframes(struct sii8620 *ctx) sii8620_write_buf(ctx, REG_TPI_INFO_B0, buf, ret); } -static void sii8620_start_hdmi(struct sii8620 *ctx) +static void sii8620_start_video(struct sii8620 *ctx) { + if (!sii8620_is_mhl3(ctx)) + sii8620_stop_video(ctx); + + if (ctx->sink_type == SINK_DVI && !sii8620_is_mhl3(ctx)) { + sii8620_write(ctx, REG_RX_HDMI_CTRL2, + VAL_RX_HDMI_CTRL2_DEFVAL); + sii8620_write(ctx, REG_TPI_SC, 0); + return; + } + sii8620_write_seq_static(ctx, REG_RX_HDMI_CTRL2, VAL_RX_HDMI_CTRL2_DEFVAL | BIT_RX_HDMI_CTRL2_USE_AV_MUTE, @@ -1229,21 +1239,6 @@ static void sii8620_start_hdmi(struct sii8620 *ctx) sii8620_set_infoframes(ctx); } -static void sii8620_start_video(struct sii8620 *ctx) -{ - if (!sii8620_is_mhl3(ctx)) - sii8620_stop_video(ctx); - - switch (ctx->sink_type) { - case SINK_HDMI: - sii8620_start_hdmi(ctx); - break; - case SINK_DVI: - default: - break; - } -} - static void sii8620_disable_hpd(struct sii8620 *ctx) { sii8620_setbits(ctx, REG_EDID_CTRL, BIT_EDID_CTRL_EDID_PRIME_VALID, 0); @@ -1945,8 +1940,13 @@ static void sii8620_irq_scdt(struct sii8620 *ctx) if (stat & BIT_INTR_SCDT_CHANGE) { u8 cstat = sii8620_readb(ctx, REG_TMDS_CSTAT_P3); - if (cstat & BIT_TMDS_CSTAT_P3_SCDT) - sii8620_scdt_high(ctx); + if (cstat & BIT_TMDS_CSTAT_P3_SCDT) { + if (ctx->sink_type == SINK_HDMI) + /* enable infoframe interrupt */ + sii8620_scdt_high(ctx); + else + sii8620_start_video(ctx); + } } sii8620_write(ctx, REG_INTR5, stat); -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/bridge/sii8620: add DVI mode support
If the sink device is in HDMI mode, enable infoframe interrupt in scdt irq handle function else call start_video function immediately, because in DVI mode, there is no infoframe interrupt provided. Rename start_hdmi function to start_video and get rid of the old start_video function. In start_video, if the sink is DVI and mode is MHL1 or MHl2, write appropriate values to registers else the path should remain the same as in HDMI mode. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/bridge/sil-sii8620.c | 37 ++-- drivers/gpu/drm/bridge/sil-sii8620.h | 2 ++ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index b7eb704..657a453 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -1169,8 +1169,19 @@ static void sii8620_set_infoframes(struct sii8620 *ctx) sii8620_write_buf(ctx, REG_TPI_INFO_B0, buf, ret); } -static void sii8620_start_hdmi(struct sii8620 *ctx) +static void sii8620_start_video(struct sii8620 *ctx) { + if (!sii8620_is_mhl3(ctx)) + sii8620_stop_video(ctx); + + if (ctx->sink_type == SINK_DVI && !sii8620_is_mhl3(ctx)) { + sii8620_write(ctx, REG_RX_HDMI_CTRL2, + VAL_RX_HDMI_CTRL2_DEFVAL_DVI); + sii8620_write(ctx, REG_TPI_SC, + BIT_TPI_SC_TPI_OUTPUT_MODE_0_DVI); + return; + } + sii8620_write_seq_static(ctx, REG_RX_HDMI_CTRL2, VAL_RX_HDMI_CTRL2_DEFVAL | BIT_RX_HDMI_CTRL2_USE_AV_MUTE, @@ -1229,21 +1240,6 @@ static void sii8620_start_hdmi(struct sii8620 *ctx) sii8620_set_infoframes(ctx); } -static void sii8620_start_video(struct sii8620 *ctx) -{ - if (!sii8620_is_mhl3(ctx)) - sii8620_stop_video(ctx); - - switch (ctx->sink_type) { - case SINK_HDMI: - sii8620_start_hdmi(ctx); - break; - case SINK_DVI: - default: - break; - } -} - static void sii8620_disable_hpd(struct sii8620 *ctx) { sii8620_setbits(ctx, REG_EDID_CTRL, BIT_EDID_CTRL_EDID_PRIME_VALID, 0); @@ -1945,8 +1941,13 @@ static void sii8620_irq_scdt(struct sii8620 *ctx) if (stat & BIT_INTR_SCDT_CHANGE) { u8 cstat = sii8620_readb(ctx, REG_TMDS_CSTAT_P3); - if (cstat & BIT_TMDS_CSTAT_P3_SCDT) - sii8620_scdt_high(ctx); + if (cstat & BIT_TMDS_CSTAT_P3_SCDT) { + if (ctx->sink_type == SINK_HDMI) + /* enable infoframe interrupt */ + sii8620_scdt_high(ctx); + else + sii8620_start_video(ctx); + } } sii8620_write(ctx, REG_INTR5, stat); diff --git a/drivers/gpu/drm/bridge/sil-sii8620.h b/drivers/gpu/drm/bridge/sil-sii8620.h index 51ab540..c2f19b80 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.h +++ b/drivers/gpu/drm/bridge/sil-sii8620.h @@ -554,6 +554,7 @@ #define REG_RX_HDMI_CTRL2 0x02a3 #define MSK_RX_HDMI_CTRL2_IDLE_CNT 0xf0 #define VAL_RX_HDMI_CTRL2_IDLE_CNT(n) ((n) << 4) +#define VAL_RX_HDMI_CTRL2_DEFVAL_DVI 0x30 #define BIT_RX_HDMI_CTRL2_USE_AV_MUTE BIT(3) #define BIT_RX_HDMI_CTRL2_VSI_MON_SEL_VSI BIT(0) @@ -1024,6 +1025,7 @@ #define BIT_TPI_SC_TPI_AV_MUTE BIT(3) #define BIT_TPI_SC_DDC_GPU_REQUEST BIT(2) #define BIT_TPI_SC_DDC_TPI_SW BIT(1) +#define BIT_TPI_SC_TPI_OUTPUT_MODE_0_DVI BIT(1) #define BIT_TPI_SC_TPI_OUTPUT_MODE_0_HDMI BIT(0) /* TPI COPP Query Data, default value: 0x00 */ -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RESEND PATCH v5] ARM: dts: exynos: Add HDMI and Sil9234 to Trats2 board
Add HDMI and Sil9234 MHL converter to Trats2 board. Following in SoC devices have been enabled: - HDMI (HDMI signal encoder), - Mixer (video buffer scanout device), - I2C_5 bus (used for HDMI DDC) - I2C_8 bus (used for HDMI_PHY control). Based on previous work by: Tomasz Stanislawski <t.stanisl...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> Reviewed-by: Andrzej Hajda <a.ha...@samsung.com> --- arch/arm/boot/dts/exynos4412-trats2.dts | 111 1 file changed, 111 insertions(+) diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index bceb919..d7f77a6 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -18,6 +18,7 @@ #include #include #include +#include / { model = "Samsung Trats 2 based on Exynos4412"; @@ -97,6 +98,34 @@ gpio = < 5 GPIO_ACTIVE_HIGH>; enable-active-high; }; + + vsil12: voltage-regulator-6 { + compatible = "regulator-fixed"; + regulator-name = "VSIL_1.2V"; + regulator-min-microvolt = <120>; + regulator-max-microvolt = <120>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <_reg>; + }; + + vcc33mhl: voltage-regulator-7 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3.3_MHL"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vcc18mhl: voltage-regulator-8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1.8_MHL"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; gpio-keys { @@ -229,6 +258,36 @@ }; }; + i2c-mhl { + compatible = "i2c-gpio"; + gpios = < 4 GPIO_ACTIVE_HIGH>, < 6 GPIO_ACTIVE_HIGH>; + i2c-gpio,delay-us = <100>; + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <_mhl_bus>; + pinctrl-names = "default"; + status = "okay"; + + sii9234: hdmi-bridge@39 { + compatible = "sil,sii9234"; + avcc33-supply = <>; + iovcc18-supply = <>; + avcc12-supply = <>; + cvcc12-supply = <>; + reset-gpios = < 4 GPIO_ACTIVE_LOW>; + interrupt-parent = <>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x39>; + + port { + mhl_to_hdmi: endpoint { + remote-endpoint = <_to_mhl>; + }; + }; + }; + }; + camera: camera { pinctrl-0 = <_port_a_clk_active _port_b_clk_active>; pinctrl-names = "default"; @@ -501,6 +560,29 @@ status = "okay"; }; + { + hpd-gpios = < 7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <_hpd>; + vdd-supply = <_reg>; + vdd_osc-supply = <_reg>; + vdd_pll-supply = <_reg>; + ddc = <_5>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + hdmi_to_mhl: endpoint { + remote-endpoint = <_to_hdmi>; + }; + }; + }; +}; + { vusb_d-supply = <_reg>; vusb_a-supply = <_reg>; @@ -579,6 +661,10 @@ }; }; +_5 { + status = "okay"; +}; + _7 { samsung,i2c-sda-delay = <100>; samsung,i2c-slave-addr = <0x10>; @@ -873,12 +959,20 @@ }; }; +_8 { + status = "okay"; +}; + { pinctrl-0 = <_bus>; pinctrl-n
[PATCH v5 1/2] drm/bridge: add Silicon Image SiI9234 driver
SiI9234 transmitter converts eTMDS/HDMI signal to MHL 1.0. It is controlled via I2C bus. Its interaction with other devices in video pipeline is performed mainly on HW level. The only interaction it does on device driver level is filtering-out unsupported video modes, it exposes drm_bridge interface to perform this operation. This patch is based on the code refactored by Tomasz Stanislawski <t.stanisl...@samsung.com>, which was initially developed by: Adam Hampson <ahamp...@sta.samsung.com> Erik Gilling <konk...@android.com> Shankar Bandal <shanka...@samsung.com> Dharam Kumar <dharam...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> Acked-by: Rob Herring <r...@kernel.org> [for dt bindings] --- .../devicetree/bindings/display/bridge/sii9234.txt | 49 + drivers/gpu/drm/bridge/Kconfig | 8 + drivers/gpu/drm/bridge/Makefile| 1 + drivers/gpu/drm/bridge/sii9234.c | 994 + 4 files changed, 1052 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii9234.txt create mode 100644 drivers/gpu/drm/bridge/sii9234.c diff --git a/Documentation/devicetree/bindings/display/bridge/sii9234.txt b/Documentation/devicetree/bindings/display/bridge/sii9234.txt new file mode 100644 index 000..88041ba --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/sii9234.txt @@ -0,0 +1,49 @@ +Silicon Image SiI9234 HDMI/MHL bridge bindings + +Required properties: + - compatible : "sil,sii9234". + - reg : I2C address for TPI interface, use 0x39 + - avcc33-supply : MHL/USB Switch Supply Voltage (3.3V) + - iovcc18-supply : I/O Supply Voltage (1.8V) + - avcc12-supply : TMDS Analog Supply Voltage (1.2V) + - cvcc12-supply : Digital Core Supply Voltage (1.2V) + - interrupts, interrupt-parent: interrupt specifier of INT pin + - reset-gpios: gpio specifier of RESET pin (active low) + - video interfaces: Device node can contain two video interface port + nodes for HDMI encoder and connector according to [1]. + - port@0 - MHL to HDMI + - port@1 - MHL to connector + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt + + +Example: + sii9234@39 { + compatible = "sil,sii9234"; + reg = <0x39>; + avcc33-supply = <>; + iovcc18-supply = <>; + avcc12-supply = <>; + cvcc12-supply = <>; + reset-gpios = < 4 GPIO_ACTIVE_LOW>; + interrupt-parent = <>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + mhl_to_hdmi: endpoint { + remote-endpoint = <_to_mhl>; + }; + }; + port@1 { + reg = <1>; + mhl_to_connector: endpoint { + remote-endpoint = <_to_mhl>; + }; + }; + }; + }; diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index adf9ae0..9dba16fd 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -84,6 +84,14 @@ config DRM_SII902X ---help--- Silicon Image sii902x bridge chip driver. +config DRM_SII9234 + tristate "Silicon Image SII9234 HDMI/MHL bridge" + depends on OF + ---help--- + Say Y here if you want support for the MHL interface. + It is an I2C driver, that detects connection of MHL bridge + and starts encapsulation of HDMI signal. + config DRM_TOSHIBA_TC358767 tristate "Toshiba TC358767 eDP bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index defcf1e..e3d5eb0 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o obj-$(CONFIG_DRM_SII902X) += sii902x.o +obj-$(CONFIG_DRM_SII9234) += sii9234.o obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ diff --git a/drivers/gpu/drm/bridge/sii9234.c b/drivers/gpu/drm/bridge/sii9234.c new file mode 100644 index 000..c770006 --- /dev/null +++ b/drivers/gpu/drm/bridge/sii9234
[PATCH v5 2/2] ARM: dts: exynos: Add HDMI and Sil9234 to Trats2 board
Add HDMI and Sil9234 MHL converter to Trats2 board. Following in SoC devices have been enabled: - HDMI (HDMI signal encoder), - Mixer (video buffer scanout device), - I2C_5 bus (used for HDMI DDC) - I2C_8 bus (used for HDMI_PHY control). Based on previous work by: Tomasz Stanislawski <t.stanisl...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- arch/arm/boot/dts/exynos4412-trats2.dts | 111 1 file changed, 111 insertions(+) diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index 35e9b94..4483deb 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -18,6 +18,7 @@ #include #include #include +#include / { model = "Samsung Trats 2 based on Exynos4412"; @@ -97,6 +98,34 @@ gpio = < 5 GPIO_ACTIVE_HIGH>; enable-active-high; }; + + vsil12: voltage-regulator-6 { + compatible = "regulator-fixed"; + regulator-name = "VSIL_1.2V"; + regulator-min-microvolt = <120>; + regulator-max-microvolt = <120>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <_reg>; + }; + + vcc33mhl: voltage-regulator-7 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3.3_MHL"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vcc18mhl: voltage-regulator-8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1.8_MHL"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; gpio-keys { @@ -229,6 +258,36 @@ }; }; + i2c-mhl { + compatible = "i2c-gpio"; + gpios = < 4 GPIO_ACTIVE_HIGH>, < 6 GPIO_ACTIVE_HIGH>; + i2c-gpio,delay-us = <100>; + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <_mhl_bus>; + pinctrl-names = "default"; + status = "okay"; + + sii9234: hdmi-bridge@39 { + compatible = "sil,sii9234"; + avcc33-supply = <>; + iovcc18-supply = <>; + avcc12-supply = <>; + cvcc12-supply = <>; + reset-gpios = < 4 GPIO_ACTIVE_LOW>; + interrupt-parent = <>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x39>; + + port { + mhl_to_hdmi: endpoint { + remote-endpoint = <_to_mhl>; + }; + }; + }; + }; + camera: camera { pinctrl-0 = <_port_a_clk_active _port_b_clk_active>; pinctrl-names = "default"; @@ -522,6 +581,29 @@ status = "okay"; }; + { + hpd-gpios = < 7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <_hpd>; + vdd-supply = <_reg>; + vdd_osc-supply = <_reg>; + vdd_pll-supply = <_reg>; + ddc = <_5>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + hdmi_to_mhl: endpoint { + remote-endpoint = <_to_hdmi>; + }; + }; + }; +}; + { vusb_d-supply = <_reg>; vusb_a-supply = <_reg>; @@ -600,6 +682,10 @@ }; }; +_5 { + status = "okay"; +}; + _7 { samsung,i2c-sda-delay = <100>; samsung,i2c-slave-addr = <0x10>; @@ -894,12 +980,20 @@ }; }; +_8 { + status = "okay"; +}; + { pinctrl-0 = <_bus>; pinctrl-names = "default"; status = "oka
[PATCH v5 0/2] add Silicon Image SiI9234 driver
Hi everyone, These patches are a continuation of work by Tomasz Stanislawski on sii9324 driver, which was described in th following letter: https://lists.freedesktop.org/archives/dri-devel/2014-April/057481.html The main differences from the previous code are: * driver moved to /gpu/drm/bridge/ and integrated with drm/bridge subsystem * added filtering-out unsupported display modes * changed gpio interface to up-to-date * changed interrupt handling * improve code style * add hdmi and sii9324 to exynos4412-trats2 device tree All comments are welcome. Regards, Maciej Purski Changes in v5: - fix checkpatch warnings - fix gpios property in i2c-mhl Changes in v4: - change documentation to more accurate - use msleep() instead of usleep() and usleep_range() - improve code style Changes in v3: - change sii9234 device tree node name - use defines from dt-bindings/pinctrl/samsung.h Changes in v2: - regulators used in driver now model all physical regulators used by the device - substitute some of the magic values with macros - improve coding style - improve error handling in sii9234_probe() - fix commit message Maciej Purski (2): drm/bridge: add Silicon Image SiI9234 driver ARM: dts: exynos: Add HDMI and Sil9234 to Trats2 board .../devicetree/bindings/display/bridge/sii9234.txt | 49 + arch/arm/boot/dts/exynos4412-trats2.dts| 112 +++ drivers/gpu/drm/bridge/Kconfig | 8 + drivers/gpu/drm/bridge/Makefile| 1 + drivers/gpu/drm/bridge/sii9234.c | 996 + 5 files changed, 1166 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii9234.txt create mode 100644 drivers/gpu/drm/bridge/sii9234.c -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4] drm/bridge/sii8620: add remote control support
Hi Hans, some time ago in reply to your email I described what messages does the MHL driver receive and at what time intervals. Regarding that information, do you think that a similar solution as in [1] is required? Would it be OK, if I just set REP_DELAY and REP_PERIOD to values, which I presented in my last email? Best Regards, Maciej [1] https://git.linuxtv.org/media_tree.git/commit/drivers/media/cec/cec-adap.c?id=a9a249a2c997506a64eaee22f1458fda893f62a8 On 08/27/2017 02:40 PM, Hans Verkuil wrote: Hi Maciej, On 24/08/17 10:58, Maciej Purski wrote: MHL specification defines Remote Control Protocol(RCP) to send input events between MHL devices. The driver now recognizes RCP messages and reacts to them by reporting key events to input subsystem, allowing a user to control a device using TV remote control. Before I Ack this I would like to know how this behaves w.r.t. autorepeat. If you keep pressing a remote key, what RCP messages do you receive and at what time intervals? If that's similar to what CEC does, then it is very likely that the same rules apply and I will have to review this patch again with that in mind. See the commit log for the patching fixing the CEC 'Press and Hold' behavior: https://git.linuxtv.org/media_tree.git/commit/drivers/media/cec/cec-adap.c?id=a9a249a2c997506a64eaee22f1458fda893f62a8 If you have access to the HDMI 2.0 specification, then that spec describes the CEC 'Press and Hold' behavior in detail. Regards, Hans Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- Changes in v2: - use RC subsystem (including CEC keymap) - RC device initialized in attach drm_bridge callback and removed in detach callback. This is necessary, because RC_CORE, which is needed during rc_dev init, is loaded after sii8620. DRM bridge is binded later which solves the problem. - add RC_CORE dependency Changes in v3: - fix error handling in init_rcp and in attach callback Changes in v4: - usage of rc-core API compatible with upcoming changes - fix error handling in init_rcp - fix commit message --- drivers/gpu/drm/bridge/Kconfig | 2 +- drivers/gpu/drm/bridge/sil-sii8620.c | 96 ++-- include/drm/bridge/mhl.h | 4 ++ 3 files changed, 96 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index adf9ae0..6ef901c 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -71,7 +71,7 @@ config DRM_PARADE_PS8622 config DRM_SIL_SII8620 tristate "Silicon Image SII8620 HDMI/MHL bridge" - depends on OF + depends on OF && RC_CORE select DRM_KMS_HELPER help Silicon Image SII8620 HDMI/MHL bridge chip driver. diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 2d51a22..ecb26c4 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -28,6 +28,8 @@ #include #include +#include + #include "sil-sii8620.h" #define SII8620_BURST_BUF_LEN 288 @@ -58,6 +60,7 @@ enum sii8620_mt_state { struct sii8620 { struct drm_bridge bridge; struct device *dev; + struct rc_dev *rc_dev; struct clk *clk_xtal; struct gpio_desc *gpio_reset; struct gpio_desc *gpio_int; @@ -431,6 +434,16 @@ static void sii8620_mt_rap(struct sii8620 *ctx, u8 code) sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RAP, code); } +static void sii8620_mt_rcpk(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPK, code); +} + +static void sii8620_mt_rcpe(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPE, code); +} + static void sii8620_mt_read_devcap_send(struct sii8620 *ctx, struct sii8620_mt_msg *msg) { @@ -1753,6 +1766,25 @@ static void sii8620_send_features(struct sii8620 *ctx) sii8620_write_buf(ctx, REG_MDT_XMIT_WRITE_PORT, buf, ARRAY_SIZE(buf)); } +static bool sii8620_rcp_consume(struct sii8620 *ctx, u8 scancode) +{ + bool pressed = !(scancode & MHL_RCP_KEY_RELEASED_MASK); + + scancode &= MHL_RCP_KEY_ID_MASK; + + if (!ctx->rc_dev) { + dev_dbg(ctx->dev, "RCP input device not initialized\n"); + return false; + } + + if (pressed) + rc_keydown(ctx->rc_dev, RC_PROTO_CEC, scancode, 0); + else + rc_keyup(ctx->rc_dev); + + return true; +} + static void sii8620_msc_mr_set_int(struct sii8620 *ctx) { u8 ints[MHL_INT_SIZE]; @@ -1804,19 +1836,25 @@ static void sii8620_msc_mt_done(struct sii8620 *ctx) static void sii8620_msc_mr_msc_msg(struct sii8620 *ctx) { - struct sii8620_mt_msg *msg = sii8620_msc_msg_first(ctx); + struct sii8620_mt_msg *msg; u8 buf[2]; - i
[PATCH v4 2/2] ARM: dts: exynos: Add HDMI and Sil9234 to Trats2 board
Add HDMI and Sil9234 MHL converter to Trats2 board. Following in SoC devices have been enabled: - HDMI (HDMI signal encoder), - Mixer (video buffer scanout device), - I2C_5 bus (used for HDMI DDC) - I2C_8 bus (used for HDMI_PHY control). Based on previous work by: Tomasz Stanislawski <t.stanisl...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- arch/arm/boot/dts/exynos4412-trats2.dts | 112 1 file changed, 112 insertions(+) diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index 35e9b94..742e02a 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -18,6 +18,7 @@ #include #include #include +#include / { model = "Samsung Trats 2 based on Exynos4412"; @@ -97,6 +98,34 @@ gpio = < 5 GPIO_ACTIVE_HIGH>; enable-active-high; }; + + vsil12: voltage-regulator-6 { + compatible = "regulator-fixed"; + regulator-name = "VSIL_1.2V"; + regulator-min-microvolt = <120>; + regulator-max-microvolt = <120>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <_reg>; + }; + + vcc33mhl: voltage-regulator-7 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3.3_MHL"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vcc18mhl: voltage-regulator-8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1.8_MHL"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; gpio-keys { @@ -229,6 +258,36 @@ }; }; + i2c-mhl { + compatible = "i2c-gpio"; + gpios = < 4 GPIO_ACTIVE_HIGH 6 GPIO_ACTIVE_HIGH>; + i2c-gpio,delay-us = <100>; + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <_mhl_bus>; + pinctrl-names = "default"; + status = "okay"; + + sii9234: hdmi-bridge@39 { + compatible = "sil,sii9234"; + avcc33-supply = <>; + iovcc18-supply = <>; + avcc12-supply = <>; + cvcc12-supply = <>; + reset-gpios = < 4 GPIO_ACTIVE_LOW>; + interrupt-parent = <>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x39>; + + port { + mhl_to_hdmi: endpoint { + remote-endpoint = <_to_mhl>; + }; + }; + }; + }; + camera: camera { pinctrl-0 = <_port_a_clk_active _port_b_clk_active>; pinctrl-names = "default"; @@ -522,6 +581,29 @@ status = "okay"; }; + { + hpd-gpios = < 7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <_hpd>; + vdd-supply = <_reg>; + vdd_osc-supply = <_reg>; + vdd_pll-supply = <_reg>; + ddc = <_5>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + hdmi_to_mhl: endpoint { + remote-endpoint = <_to_hdmi>; + }; + }; + }; +}; + { vusb_d-supply = <_reg>; vusb_a-supply = <_reg>; @@ -600,6 +682,11 @@ }; }; + +_5 { + status = "okay"; +}; + _7 { samsung,i2c-sda-delay = <100>; samsung,i2c-slave-addr = <0x10>; @@ -894,12 +981,20 @@ }; }; +_8 { + status = "okay"; +}; + { pinctrl-0 = <_bus>; pinctrl-names = "default"; status = "okay"
[PATCH v4 1/2] drm/bridge: add Silicon Image SiI9234 driver
SiI9234 transmitter converts eTMDS/HDMI signal to MHL 1.0. It is controlled via I2C bus. Its interaction with other devices in video pipeline is performed mainly on HW level. The only interaction it does on device driver level is filtering-out unsupported video modes, it exposes drm_bridge interface to perform this operation. This patch is based on the code refactored by Tomasz Stanislawski <t.stanisl...@samsung.com>, which was initially developed by: Adam Hampson <ahamp...@sta.samsung.com> Erik Gilling <konk...@android.com> Shankar Bandal <shanka...@samsung.com> Dharam Kumar <dharam...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- .../devicetree/bindings/display/bridge/sii9234.txt | 49 + drivers/gpu/drm/bridge/Kconfig | 8 + drivers/gpu/drm/bridge/Makefile| 1 + drivers/gpu/drm/bridge/sii9234.c | 996 + 4 files changed, 1054 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii9234.txt create mode 100644 drivers/gpu/drm/bridge/sii9234.c diff --git a/Documentation/devicetree/bindings/display/bridge/sii9234.txt b/Documentation/devicetree/bindings/display/bridge/sii9234.txt new file mode 100644 index 000..88041ba --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/sii9234.txt @@ -0,0 +1,49 @@ +Silicon Image SiI9234 HDMI/MHL bridge bindings + +Required properties: + - compatible : "sil,sii9234". + - reg : I2C address for TPI interface, use 0x39 + - avcc33-supply : MHL/USB Switch Supply Voltage (3.3V) + - iovcc18-supply : I/O Supply Voltage (1.8V) + - avcc12-supply : TMDS Analog Supply Voltage (1.2V) + - cvcc12-supply : Digital Core Supply Voltage (1.2V) + - interrupts, interrupt-parent: interrupt specifier of INT pin + - reset-gpios: gpio specifier of RESET pin (active low) + - video interfaces: Device node can contain two video interface port + nodes for HDMI encoder and connector according to [1]. + - port@0 - MHL to HDMI + - port@1 - MHL to connector + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt + + +Example: + sii9234@39 { + compatible = "sil,sii9234"; + reg = <0x39>; + avcc33-supply = <>; + iovcc18-supply = <>; + avcc12-supply = <>; + cvcc12-supply = <>; + reset-gpios = < 4 GPIO_ACTIVE_LOW>; + interrupt-parent = <>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + mhl_to_hdmi: endpoint { + remote-endpoint = <_to_mhl>; + }; + }; + port@1 { + reg = <1>; + mhl_to_connector: endpoint { + remote-endpoint = <_to_mhl>; + }; + }; + }; + }; diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index adf9ae0..9dba16fd 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -84,6 +84,14 @@ config DRM_SII902X ---help--- Silicon Image sii902x bridge chip driver. +config DRM_SII9234 + tristate "Silicon Image SII9234 HDMI/MHL bridge" + depends on OF + ---help--- + Say Y here if you want support for the MHL interface. + It is an I2C driver, that detects connection of MHL bridge + and starts encapsulation of HDMI signal. + config DRM_TOSHIBA_TC358767 tristate "Toshiba TC358767 eDP bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index defcf1e..e3d5eb0 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o obj-$(CONFIG_DRM_SII902X) += sii902x.o +obj-$(CONFIG_DRM_SII9234) += sii9234.o obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ diff --git a/drivers/gpu/drm/bridge/sii9234.c b/drivers/gpu/drm/bridge/sii9234.c new file mode 100644 index 000..9a67546 --- /dev/null +++ b/drivers/gpu/drm/bridge/sii9234.c @@ -0,0 +1,996 @@ +/* + * Copyright (C) 2017 Samsung Electr
[PATCH v4 0/2] add Silicon Image SiI9234 driver
Hi everyone, These patches are a continuation of work by Tomasz Stanislawski on sii9324 driver, which was described in th following letter: https://lists.freedesktop.org/archives/dri-devel/2014-April/057481.html The main differences from the previous code are: * driver moved to /gpu/drm/bridge/ and integrated with drm/bridge subsystem * added filtering-out unsupported display modes * changed gpio interface to up-to-date * changed interrupt handling * improve code style * add hdmi and sii9324 to exynos4412-trats2 device tree All comments are welcome. Regards, Maciej Purski Changes in v4: - change documentation to more accurate - use msleep() instead of usleep() and usleep_range() - improve code style Changes in v3: - change sii9234 device tree node name - use defines from dt-bindings/pinctrl/samsung.h Changes in v2: - regulators used in driver now model all physical regulators used by the device - substitute some of the magic values with macros - improve coding style - improve error handling in sii9234_probe() - fix commit message Maciej Purski (2): drm/bridge: add Silicon Image SiI9234 driver ARM: dts: exynos: Add HDMI and Sil9234 to Trats2 board .../devicetree/bindings/display/bridge/sii9234.txt | 49 + arch/arm/boot/dts/exynos4412-trats2.dts| 112 +++ drivers/gpu/drm/bridge/Kconfig | 8 + drivers/gpu/drm/bridge/Makefile| 1 + drivers/gpu/drm/bridge/sii9234.c | 996 + 5 files changed, 1166 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii9234.txt create mode 100644 drivers/gpu/drm/bridge/sii9234.c -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 1/2] drm/bridge: add Silicon Image SiI9234 driver
Hi Krzysztof, thank you for your comments. On 08.09.2017 at 19:05, Krzysztof Kozlowski wrote: On Tue, Sep 05, 2017 at 04:01:38PM +0200, Maciej Purski wrote: SiI9234 transmitter converts eTMDS/HDMI signal to MHL 1.0. It is controlled via I2C bus. Its interaction with other devices in video pipeline is performed mainly on HW level. The only interaction it does on device driver level is filtering-out unsupported video modes, it exposes drm_bridge interface to perform this operation. This patch is based on the code refactored by Tomasz Stanislawski <t.stanisl...@samsung.com>, which was initially developed by: Adam Hampson <ahamp...@sta.samsung.com> Erik Gilling <konk...@android.com> Shankar Bandal <shanka...@samsung.com> Dharam Kumar <dharam...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- .../devicetree/bindings/display/bridge/sii9234.txt | 34 + drivers/gpu/drm/bridge/Kconfig | 8 + drivers/gpu/drm/bridge/Makefile| 1 + drivers/gpu/drm/bridge/sii9234.c | 993 + 4 files changed, 1036 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii9234.txt create mode 100644 drivers/gpu/drm/bridge/sii9234.c diff --git a/Documentation/devicetree/bindings/display/bridge/sii9234.txt b/Documentation/devicetree/bindings/display/bridge/sii9234.txt new file mode 100644 index 000..3ce7413 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/sii9234.txt @@ -0,0 +1,34 @@ +Silicon Image SiI9234 HDMI/MHL bridge bindings + +Required properties: + - compatible : "sil,sii9234". + - reg : I2C address for TPI interface, use 0x39 + - avcc33-supply : MHL/USB Switch Supply Voltage (3.3V) + - iovcc18-supply : I/O Supply Voltage (1.8V) + - avcc12-supply : TMDS Analog Supply Voltage (1.2V) + - cvcc12-supply : Digital Core Supply Voltage (1.2V) + - interrupts, interrupt-parent: interrupt specifier of INT pin + - reset-gpios: gpio specifier of RESET pin (active low) + - video interfaces: Device node can contain video interface port + node for HDMI encoder according to [1]. + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt + +Example: + sii9234@39 { + compatible = "sil,sii9234"; + reg = <0x39>; + avcc33-supply = <>; + iovcc18-supply = <>; + avcc12-supply = <>; + cvcc12-supply = <>; + reset-gpios = < 4 GPIO_ACTIVE_LOW>; + interrupt-parent = <>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + + port { + mhl_to_hdmi: endpoint { + remote-endpoint = <_to_mhl>; + }; + }; + }; diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index adf9ae0..9dba16fd 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -84,6 +84,14 @@ config DRM_SII902X ---help--- Silicon Image sii902x bridge chip driver. +config DRM_SII9234 + tristate "Silicon Image SII9234 HDMI/MHL bridge" + depends on OF + ---help--- + Say Y here if you want support for the MHL interface. + It is an I2C driver, that detects connection of MHL bridge + and starts encapsulation of HDMI signal. + config DRM_TOSHIBA_TC358767 tristate "Toshiba TC358767 eDP bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index defcf1e..e3d5eb0 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o obj-$(CONFIG_DRM_SII902X) += sii902x.o +obj-$(CONFIG_DRM_SII9234) += sii9234.o obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ diff --git a/drivers/gpu/drm/bridge/sii9234.c b/drivers/gpu/drm/bridge/sii9234.c new file mode 100644 index 000..b70d69a --- /dev/null +++ b/drivers/gpu/drm/bridge/sii9234.c @@ -0,0 +1,993 @@ +/* + * Copyright (C) 2017 Samsung Electronics + * + * Authors: + *Tomasz Stanislawski <t.stanisl...@samsung.com> + *Maciej Purski <m.pur...@samsung.com> + * + * Based on sii9234 driver created by: + *Adam Hampson <ahamp...@sta.samsung.com> + *Erik Gilling <konk...@android.com> + *Shankar Bandal <shanka...@samsung.com> + *Dharam Kumar <dharam...@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under th
[PATCH v3 1/2] drm/bridge: add Silicon Image SiI9234 driver
SiI9234 transmitter converts eTMDS/HDMI signal to MHL 1.0. It is controlled via I2C bus. Its interaction with other devices in video pipeline is performed mainly on HW level. The only interaction it does on device driver level is filtering-out unsupported video modes, it exposes drm_bridge interface to perform this operation. This patch is based on the code refactored by Tomasz Stanislawski <t.stanisl...@samsung.com>, which was initially developed by: Adam Hampson <ahamp...@sta.samsung.com> Erik Gilling <konk...@android.com> Shankar Bandal <shanka...@samsung.com> Dharam Kumar <dharam...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- .../devicetree/bindings/display/bridge/sii9234.txt | 34 + drivers/gpu/drm/bridge/Kconfig | 8 + drivers/gpu/drm/bridge/Makefile| 1 + drivers/gpu/drm/bridge/sii9234.c | 993 + 4 files changed, 1036 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii9234.txt create mode 100644 drivers/gpu/drm/bridge/sii9234.c diff --git a/Documentation/devicetree/bindings/display/bridge/sii9234.txt b/Documentation/devicetree/bindings/display/bridge/sii9234.txt new file mode 100644 index 000..3ce7413 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/sii9234.txt @@ -0,0 +1,34 @@ +Silicon Image SiI9234 HDMI/MHL bridge bindings + +Required properties: + - compatible : "sil,sii9234". + - reg : I2C address for TPI interface, use 0x39 + - avcc33-supply : MHL/USB Switch Supply Voltage (3.3V) + - iovcc18-supply : I/O Supply Voltage (1.8V) + - avcc12-supply : TMDS Analog Supply Voltage (1.2V) + - cvcc12-supply : Digital Core Supply Voltage (1.2V) + - interrupts, interrupt-parent: interrupt specifier of INT pin + - reset-gpios: gpio specifier of RESET pin (active low) + - video interfaces: Device node can contain video interface port + node for HDMI encoder according to [1]. + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt + +Example: + sii9234@39 { + compatible = "sil,sii9234"; + reg = <0x39>; + avcc33-supply = <>; + iovcc18-supply = <>; + avcc12-supply = <>; + cvcc12-supply = <>; + reset-gpios = < 4 GPIO_ACTIVE_LOW>; + interrupt-parent = <>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + + port { + mhl_to_hdmi: endpoint { + remote-endpoint = <_to_mhl>; + }; + }; + }; diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index adf9ae0..9dba16fd 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -84,6 +84,14 @@ config DRM_SII902X ---help--- Silicon Image sii902x bridge chip driver. +config DRM_SII9234 + tristate "Silicon Image SII9234 HDMI/MHL bridge" + depends on OF + ---help--- + Say Y here if you want support for the MHL interface. + It is an I2C driver, that detects connection of MHL bridge + and starts encapsulation of HDMI signal. + config DRM_TOSHIBA_TC358767 tristate "Toshiba TC358767 eDP bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index defcf1e..e3d5eb0 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o obj-$(CONFIG_DRM_SII902X) += sii902x.o +obj-$(CONFIG_DRM_SII9234) += sii9234.o obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ diff --git a/drivers/gpu/drm/bridge/sii9234.c b/drivers/gpu/drm/bridge/sii9234.c new file mode 100644 index 000..b70d69a --- /dev/null +++ b/drivers/gpu/drm/bridge/sii9234.c @@ -0,0 +1,993 @@ +/* + * Copyright (C) 2017 Samsung Electronics + * + * Authors: + *Tomasz Stanislawski <t.stanisl...@samsung.com> + *Maciej Purski <m.pur...@samsung.com> + * + * Based on sii9234 driver created by: + *Adam Hampson <ahamp...@sta.samsung.com> + *Erik Gilling <konk...@android.com> + *Shankar Bandal <shanka...@samsung.com> + *Dharam Kumar <dharam...@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + *
[PATCH v3 2/2] ARM: dts: exynos: Add HDMI and Sil9234 to Trats2 board
Add HDMI and Sil9234 MHL converter to Trats2 board. Following in SoC devices have been enabled: - HDMI (HDMI signal encoder), - Mixer (video buffer scanout device), - I2C_5 bus (used for HDMI DDC) - I2C_8 bus (used for HDMI_PHY control). Based on previous work by: Tomasz Stanislawski <t.stanisl...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- arch/arm/boot/dts/exynos4412-trats2.dts | 112 1 file changed, 112 insertions(+) diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index 35e9b94..742e02a 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -18,6 +18,7 @@ #include #include #include +#include / { model = "Samsung Trats 2 based on Exynos4412"; @@ -97,6 +98,34 @@ gpio = < 5 GPIO_ACTIVE_HIGH>; enable-active-high; }; + + vsil12: voltage-regulator-6 { + compatible = "regulator-fixed"; + regulator-name = "VSIL_1.2V"; + regulator-min-microvolt = <120>; + regulator-max-microvolt = <120>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <_reg>; + }; + + vcc33mhl: voltage-regulator-7 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3.3_MHL"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vcc18mhl: voltage-regulator-8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1.8_MHL"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; gpio-keys { @@ -229,6 +258,36 @@ }; }; + i2c-mhl { + compatible = "i2c-gpio"; + gpios = < 4 GPIO_ACTIVE_HIGH 6 GPIO_ACTIVE_HIGH>; + i2c-gpio,delay-us = <100>; + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <_mhl_bus>; + pinctrl-names = "default"; + status = "okay"; + + sii9234: hdmi-bridge@39 { + compatible = "sil,sii9234"; + avcc33-supply = <>; + iovcc18-supply = <>; + avcc12-supply = <>; + cvcc12-supply = <>; + reset-gpios = < 4 GPIO_ACTIVE_LOW>; + interrupt-parent = <>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x39>; + + port { + mhl_to_hdmi: endpoint { + remote-endpoint = <_to_mhl>; + }; + }; + }; + }; + camera: camera { pinctrl-0 = <_port_a_clk_active _port_b_clk_active>; pinctrl-names = "default"; @@ -522,6 +581,29 @@ status = "okay"; }; + { + hpd-gpios = < 7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <_hpd>; + vdd-supply = <_reg>; + vdd_osc-supply = <_reg>; + vdd_pll-supply = <_reg>; + ddc = <_5>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + hdmi_to_mhl: endpoint { + remote-endpoint = <_to_hdmi>; + }; + }; + }; +}; + { vusb_d-supply = <_reg>; vusb_a-supply = <_reg>; @@ -600,6 +682,11 @@ }; }; + +_5 { + status = "okay"; +}; + _7 { samsung,i2c-sda-delay = <100>; samsung,i2c-slave-addr = <0x10>; @@ -894,12 +981,20 @@ }; }; +_8 { + status = "okay"; +}; + { pinctrl-0 = <_bus>; pinctrl-names = "default"; status = "okay"
[PATCH v3 0/2] add Silicon Image SiI9234 driver
Hi everyone, These patches are a continuation of work by Tomasz Stanislawski on sii9324 driver, which was described in th following letter: https://lists.freedesktop.org/archives/dri-devel/2014-April/057481.html The main differences from the previous code are: * driver moved to /gpu/drm/bridge/ and integrated with drm/bridge subsystem * added filtering-out unsupported display modes * changed gpio interface to up-to-date * changed interrupt handling * improve code style * add hdmi and sii9324 to exynos4412-trats2 device tree All comments are welcome. Regards, Maciej Purski Changes in v3: - change sii9234 device tree node name - use defines from dt-bindings/pinctrl/samsung.h Changes in v2: - regulators used in driver now model all physical regulators used by the device - substitute some of the magic values with macros - improve coding style - improve error handling in sii9234_probe() - fix commit message Maciej Purski (2): drm/bridge: add Silicon Image SiI9234 driver ARM: dts: exynos: Add HDMI and Sil9234 to Trats2 board .../devicetree/bindings/display/bridge/sii9234.txt | 34 + arch/arm/boot/dts/exynos4412-trats2.dts| 111 +++ drivers/gpu/drm/bridge/Kconfig | 8 + drivers/gpu/drm/bridge/Makefile| 1 + drivers/gpu/drm/bridge/sii9234.c | 993 + 5 files changed, 1147 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii9234.txt create mode 100644 drivers/gpu/drm/bridge/sii9234.c -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 1/2] drm/bridge: add Silicon Image SiI9234 driver
Hi Laurent, Thank you for your reply. The problem was already discussed when adding sil8620 driver. It can be solved later. I'm CC-ing Andrzej Hajda, as he used to discuss it with you. https://patchwork.freedesktop.org/patch/114224/ https://lists.freedesktop.org/archives/dri-devel/2015-December/096756.html Regards, Maciej On 31/08/17 15:30, Laurent Pinchart wrote: Hi Maciej, Thank you for the patch. On Thursday, 31 August 2017 15:27:13 EEST Maciej Purski wrote: SiI9234 transmitter converts eTMDS/HDMI signal to MHL 1.0. It is controlled via I2C bus. Its interaction with other devices in video pipeline is performed mainly on HW level. The only interaction it does on device driver level is filtering-out unsupported video modes, it exposes drm_bridge interface to perform this operation. This patch is based on the code refactored by Tomasz Stanislawski <t.stanisl...@samsung.com>, which was initially developed by: Adam Hampson <ahamp...@sta.samsung.com> Erik Gilling <konk...@android.com> Shankar Bandal <shanka...@samsung.com> Dharam Kumar <dharam...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- Changes in v2: - use bulk_requlators instead of single one - substitute some of the magic values with macros - improve coding style - improved error handling in sii9234_probe() --- .../devicetree/bindings/display/bridge/sii9234.txt | 34 + drivers/gpu/drm/bridge/Kconfig | 8 + drivers/gpu/drm/bridge/Makefile| 1 + drivers/gpu/drm/bridge/sii9234.c | 993 ++ 4 files changed, 1036 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii9234.txt create mode 100644 drivers/gpu/drm/bridge/sii9234.c diff --git a/Documentation/devicetree/bindings/display/bridge/sii9234.txt b/Documentation/devicetree/bindings/display/bridge/sii9234.txt new file mode 100644 index 000..3ce7413 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/sii9234.txt @@ -0,0 +1,34 @@ +Silicon Image SiI9234 HDMI/MHL bridge bindings + +Required properties: + - compatible : "sil,sii9234". + - reg : I2C address for TPI interface, use 0x39 + - avcc33-supply : MHL/USB Switch Supply Voltage (3.3V) + - iovcc18-supply : I/O Supply Voltage (1.8V) + - avcc12-supply : TMDS Analog Supply Voltage (1.2V) + - cvcc12-supply : Digital Core Supply Voltage (1.2V) + - interrupts, interrupt-parent: interrupt specifier of INT pin + - reset-gpios: gpio specifier of RESET pin (active low) + - video interfaces: Device node can contain video interface port + node for HDMI encoder according to [1]. + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt Doesn't this chip have two ports, one input connected to the SoC and one output connected to an HDMI connector ? If so there should be two ports in DT too. +Example: + sii9234@39 { + compatible = "sil,sii9234"; + reg = <0x39>; + avcc33-supply = <>; + iovcc18-supply = <>; + avcc12-supply = <>; + cvcc12-supply = <>; + reset-gpios = < 4 GPIO_ACTIVE_LOW>; + interrupt-parent = <>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + + port { + mhl_to_hdmi: endpoint { + remote-endpoint = <_to_mhl>; It would be useful to include the remote DT nodes in the example too. + }; + }; + }; ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/exynos/hdmi: Fix unsafe list iteration
Function hdmi_mode_fixup() used bare list_for_each entry, which was unsafe and caused memory corruption detected by kasan. It now uses drm_for_each_connector_iter macro, which is now recommended by the documentation and safe. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/exynos/exynos_hdmi.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 214fa5e..0109ff4 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -944,22 +944,27 @@ static bool hdmi_mode_fixup(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct drm_connector *connector; struct drm_display_mode *m; + struct drm_connector_list_iter conn_iter; int mode_ok; drm_mode_set_crtcinfo(adjusted_mode, 0); - list_for_each_entry(connector, >mode_config.connector_list, head) { + drm_connector_list_iter_begin(dev, _iter); + drm_for_each_connector_iter(connector, _iter) { if (connector->encoder == encoder) break; } + if (connector) + drm_connector_get(connector); + drm_connector_list_iter_end(_iter); - if (connector->encoder != encoder) + if (!connector) return true; mode_ok = hdmi_mode_valid(connector, adjusted_mode); if (mode_ok == MODE_OK) - return true; + goto cleanup; /* * Find the most suitable mode and copy it to adjusted_mode. @@ -979,6 +984,9 @@ static bool hdmi_mode_fixup(struct drm_encoder *encoder, } } +cleanup: + drm_connector_put(connector); + return true; } -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4] drm/bridge/sii8620: add remote control support
Hi Hans, According to my tests, when pressing 'Press and Hold' key, the messages received are always the same until the button is released. The second message is received after ~550 ms and each next message is received every ~100 ms. Regards, Maciej On 27/08/2017 14:40, Hans Verkuil wrote: Hi Maciej, On 24/08/17 10:58, Maciej Purski wrote: MHL specification defines Remote Control Protocol(RCP) to send input events between MHL devices. The driver now recognizes RCP messages and reacts to them by reporting key events to input subsystem, allowing a user to control a device using TV remote control. Before I Ack this I would like to know how this behaves w.r.t. autorepeat. If you keep pressing a remote key, what RCP messages do you receive and at what time intervals? If that's similar to what CEC does, then it is very likely that the same rules apply and I will have to review this patch again with that in mind. See the commit log for the patching fixing the CEC 'Press and Hold' behavior: https://git.linuxtv.org/media_tree.git/commit/drivers/media/cec/cec-adap.c?id=a9a249a2c997506a64eaee22f1458fda893f62a8 If you have access to the HDMI 2.0 specification, then that spec describes the CEC 'Press and Hold' behavior in detail. Regards, Hans Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- Changes in v2: - use RC subsystem (including CEC keymap) - RC device initialized in attach drm_bridge callback and removed in detach callback. This is necessary, because RC_CORE, which is needed during rc_dev init, is loaded after sii8620. DRM bridge is binded later which solves the problem. - add RC_CORE dependency Changes in v3: - fix error handling in init_rcp and in attach callback Changes in v4: - usage of rc-core API compatible with upcoming changes - fix error handling in init_rcp - fix commit message --- drivers/gpu/drm/bridge/Kconfig | 2 +- drivers/gpu/drm/bridge/sil-sii8620.c | 96 ++-- include/drm/bridge/mhl.h | 4 ++ 3 files changed, 96 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index adf9ae0..6ef901c 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -71,7 +71,7 @@ config DRM_PARADE_PS8622 config DRM_SIL_SII8620 tristate "Silicon Image SII8620 HDMI/MHL bridge" - depends on OF + depends on OF && RC_CORE select DRM_KMS_HELPER help Silicon Image SII8620 HDMI/MHL bridge chip driver. diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 2d51a22..ecb26c4 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -28,6 +28,8 @@ #include #include +#include + #include "sil-sii8620.h" #define SII8620_BURST_BUF_LEN 288 @@ -58,6 +60,7 @@ enum sii8620_mt_state { struct sii8620 { struct drm_bridge bridge; struct device *dev; + struct rc_dev *rc_dev; struct clk *clk_xtal; struct gpio_desc *gpio_reset; struct gpio_desc *gpio_int; @@ -431,6 +434,16 @@ static void sii8620_mt_rap(struct sii8620 *ctx, u8 code) sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RAP, code); } +static void sii8620_mt_rcpk(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPK, code); +} + +static void sii8620_mt_rcpe(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPE, code); +} + static void sii8620_mt_read_devcap_send(struct sii8620 *ctx, struct sii8620_mt_msg *msg) { @@ -1753,6 +1766,25 @@ static void sii8620_send_features(struct sii8620 *ctx) sii8620_write_buf(ctx, REG_MDT_XMIT_WRITE_PORT, buf, ARRAY_SIZE(buf)); } +static bool sii8620_rcp_consume(struct sii8620 *ctx, u8 scancode) +{ + bool pressed = !(scancode & MHL_RCP_KEY_RELEASED_MASK); + + scancode &= MHL_RCP_KEY_ID_MASK; + + if (!ctx->rc_dev) { + dev_dbg(ctx->dev, "RCP input device not initialized\n"); + return false; + } + + if (pressed) + rc_keydown(ctx->rc_dev, RC_PROTO_CEC, scancode, 0); + else + rc_keyup(ctx->rc_dev); + + return true; +} + static void sii8620_msc_mr_set_int(struct sii8620 *ctx) { u8 ints[MHL_INT_SIZE]; @@ -1804,19 +1836,25 @@ static void sii8620_msc_mt_done(struct sii8620 *ctx) static void sii8620_msc_mr_msc_msg(struct sii8620 *ctx) { - struct sii8620_mt_msg *msg = sii8620_msc_msg_first(ctx); + struct sii8620_mt_msg *msg; u8 buf[2]; - if (!msg) - return; - sii8620_read_buf(ctx, REG_MSC_MR_MSC_MSG_RCVD_1ST_DATA, buf, 2); switch (buf[0]) { case MHL_MSC_MSG_RAPK: + msg = sii8620_msc_msg_first(ctx); +
[PATCH v2 2/2] ARM: dts: exynos: Add HDMI and Sil9234 to Trats2 board
Add HDMI and Sil9234 MHL converter to Trats2 board. Following in SoC devices have been enabled: - HDMI (HDMI signal encoder), - Mixer (video buffer scanout device), - I2C_5 bus (used for HDMI DDC) - I2C_8 bus (used for HDMI_PHY control). Based on previous work by: Tomasz Stanislawski <t.stanisl...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- Changes in v2: - fix commit message - add regulators nodes to model actual physical connections --- arch/arm/boot/dts/exynos4412-trats2.dts | 111 1 file changed, 111 insertions(+) diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index 35e9b94..0180753 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -97,6 +97,34 @@ gpio = < 5 GPIO_ACTIVE_HIGH>; enable-active-high; }; + + vsil12: voltage-regulator-6 { + compatible = "regulator-fixed"; + regulator-name = "VSIL_1.2V"; + regulator-min-microvolt = <120>; + regulator-max-microvolt = <120>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <_reg>; + }; + + vcc33mhl: voltage-regulator-7 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3.3_MHL"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vcc18mhl: voltage-regulator-8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1.8_MHL"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; gpio-keys { @@ -229,6 +257,36 @@ }; }; + i2c-mhl { + compatible = "i2c-gpio"; + gpios = < 4 GPIO_ACTIVE_HIGH 6 GPIO_ACTIVE_HIGH>; + i2c-gpio,delay-us = <100>; + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <_mhl_bus>; + pinctrl-names = "default"; + status = "okay"; + + sii9234: sii9234@39 { + compatible = "sil,sii9234"; + avcc33-supply = <>; + iovcc18-supply = <>; + avcc12-supply = <>; + cvcc12-supply = <>; + reset-gpios = < 4 GPIO_ACTIVE_LOW>; + interrupt-parent = <>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x39>; + + port { + mhl_to_hdmi: endpoint { + remote-endpoint = <_to_mhl>; + }; + }; + }; + }; + camera: camera { pinctrl-0 = <_port_a_clk_active _port_b_clk_active>; pinctrl-names = "default"; @@ -522,6 +580,29 @@ status = "okay"; }; + { + hpd-gpios = < 7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <_hpd>; + vdd-supply = <_reg>; + vdd_osc-supply = <_reg>; + vdd_pll-supply = <_reg>; + ddc = <_5>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + hdmi_to_mhl: endpoint { + remote-endpoint = <_to_hdmi>; + }; + }; + }; +}; + { vusb_d-supply = <_reg>; vusb_a-supply = <_reg>; @@ -600,6 +681,11 @@ }; }; + +_5 { + status = "okay"; +}; + _7 { samsung,i2c-sda-delay = <100>; samsung,i2c-slave-addr = <0x10>; @@ -894,12 +980,20 @@ }; }; +_8 { + status = "okay"; +}; + { pinctrl-0 = <_bus>; pinctrl-names = "default"; status = "okay"; }; + { + stat
[PATCH v2 0/2] add Silicon Image SiI9234 driver
Hi everyone, These patches are a continuation of work by Tomasz Stanislawski on sii9324 driver, which was described in th following letter: https://lists.freedesktop.org/archives/dri-devel/2014-April/057481.html The main differences from the previous code are: * driver moved to /gpu/drm/bridge/ and integrated with drm/bridge subsystem * added filtering-out unsupported display modes * changed gpio interface to up-to-date * changed interrupt handling * improve code style * add hdmi and sii9324 to exynos4412-trats2 device tree All comments are welcome. Regards, Maciej Purski Changes in v2: - regulators used in driver now model all physical regulators used by the device - substitute some of the magic values with macros - improve coding style - improve error handling in sii9234_probe() - fix commit message Maciej Purski (2): drm/bridge: add Silicon Image SiI9234 driver ARM: dts: exynos: Add HDMI and Sil9234 to Trats2 board .../devicetree/bindings/display/bridge/sii9234.txt | 34 + arch/arm/boot/dts/exynos4412-trats2.dts| 111 +++ drivers/gpu/drm/bridge/Kconfig | 8 + drivers/gpu/drm/bridge/Makefile| 1 + drivers/gpu/drm/bridge/sii9234.c | 993 + 5 files changed, 1147 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii9234.txt create mode 100644 drivers/gpu/drm/bridge/sii9234.c -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 1/2] drm/bridge: add Silicon Image SiI9234 driver
SiI9234 transmitter converts eTMDS/HDMI signal to MHL 1.0. It is controlled via I2C bus. Its interaction with other devices in video pipeline is performed mainly on HW level. The only interaction it does on device driver level is filtering-out unsupported video modes, it exposes drm_bridge interface to perform this operation. This patch is based on the code refactored by Tomasz Stanislawski <t.stanisl...@samsung.com>, which was initially developed by: Adam Hampson <ahamp...@sta.samsung.com> Erik Gilling <konk...@android.com> Shankar Bandal <shanka...@samsung.com> Dharam Kumar <dharam...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- Changes in v2: - use bulk_requlators instead of single one - substitute some of the magic values with macros - improve coding style - improved error handling in sii9234_probe() --- .../devicetree/bindings/display/bridge/sii9234.txt | 34 + drivers/gpu/drm/bridge/Kconfig | 8 + drivers/gpu/drm/bridge/Makefile| 1 + drivers/gpu/drm/bridge/sii9234.c | 993 + 4 files changed, 1036 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii9234.txt create mode 100644 drivers/gpu/drm/bridge/sii9234.c diff --git a/Documentation/devicetree/bindings/display/bridge/sii9234.txt b/Documentation/devicetree/bindings/display/bridge/sii9234.txt new file mode 100644 index 000..3ce7413 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/sii9234.txt @@ -0,0 +1,34 @@ +Silicon Image SiI9234 HDMI/MHL bridge bindings + +Required properties: + - compatible : "sil,sii9234". + - reg : I2C address for TPI interface, use 0x39 + - avcc33-supply : MHL/USB Switch Supply Voltage (3.3V) + - iovcc18-supply : I/O Supply Voltage (1.8V) + - avcc12-supply : TMDS Analog Supply Voltage (1.2V) + - cvcc12-supply : Digital Core Supply Voltage (1.2V) + - interrupts, interrupt-parent: interrupt specifier of INT pin + - reset-gpios: gpio specifier of RESET pin (active low) + - video interfaces: Device node can contain video interface port + node for HDMI encoder according to [1]. + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt + +Example: + sii9234@39 { + compatible = "sil,sii9234"; + reg = <0x39>; + avcc33-supply = <>; + iovcc18-supply = <>; + avcc12-supply = <>; + cvcc12-supply = <>; + reset-gpios = < 4 GPIO_ACTIVE_LOW>; + interrupt-parent = <>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + + port { + mhl_to_hdmi: endpoint { + remote-endpoint = <_to_mhl>; + }; + }; + }; diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index adf9ae0..9dba16fd 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -84,6 +84,14 @@ config DRM_SII902X ---help--- Silicon Image sii902x bridge chip driver. +config DRM_SII9234 + tristate "Silicon Image SII9234 HDMI/MHL bridge" + depends on OF + ---help--- + Say Y here if you want support for the MHL interface. + It is an I2C driver, that detects connection of MHL bridge + and starts encapsulation of HDMI signal. + config DRM_TOSHIBA_TC358767 tristate "Toshiba TC358767 eDP bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index defcf1e..e3d5eb0 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o obj-$(CONFIG_DRM_SII902X) += sii902x.o +obj-$(CONFIG_DRM_SII9234) += sii9234.o obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ diff --git a/drivers/gpu/drm/bridge/sii9234.c b/drivers/gpu/drm/bridge/sii9234.c new file mode 100644 index 000..b70d69a --- /dev/null +++ b/drivers/gpu/drm/bridge/sii9234.c @@ -0,0 +1,993 @@ +/* + * Copyright (C) 2017 Samsung Electronics + * + * Authors: + *Tomasz Stanislawski <t.stanisl...@samsung.com> + *Maciej Purski <m.pur...@samsung.com> + * + * Based on sii9234 driver created by: + *Adam Hampson <ahamp...@sta.samsung.com> + *Erik Gilling <konk...@android.com> + *Shankar Bandal <shanka...@samsung.com> + *Dharam Kumar <dharam...@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under th
[PATCH v4] drm/bridge/sii8620: add remote control support
MHL specification defines Remote Control Protocol(RCP) to send input events between MHL devices. The driver now recognizes RCP messages and reacts to them by reporting key events to input subsystem, allowing a user to control a device using TV remote control. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- Changes in v2: - use RC subsystem (including CEC keymap) - RC device initialized in attach drm_bridge callback and removed in detach callback. This is necessary, because RC_CORE, which is needed during rc_dev init, is loaded after sii8620. DRM bridge is binded later which solves the problem. - add RC_CORE dependency Changes in v3: - fix error handling in init_rcp and in attach callback Changes in v4: - usage of rc-core API compatible with upcoming changes - fix error handling in init_rcp - fix commit message --- drivers/gpu/drm/bridge/Kconfig | 2 +- drivers/gpu/drm/bridge/sil-sii8620.c | 96 ++-- include/drm/bridge/mhl.h | 4 ++ 3 files changed, 96 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index adf9ae0..6ef901c 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -71,7 +71,7 @@ config DRM_PARADE_PS8622 config DRM_SIL_SII8620 tristate "Silicon Image SII8620 HDMI/MHL bridge" - depends on OF + depends on OF && RC_CORE select DRM_KMS_HELPER help Silicon Image SII8620 HDMI/MHL bridge chip driver. diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 2d51a22..ecb26c4 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -28,6 +28,8 @@ #include #include +#include + #include "sil-sii8620.h" #define SII8620_BURST_BUF_LEN 288 @@ -58,6 +60,7 @@ enum sii8620_mt_state { struct sii8620 { struct drm_bridge bridge; struct device *dev; + struct rc_dev *rc_dev; struct clk *clk_xtal; struct gpio_desc *gpio_reset; struct gpio_desc *gpio_int; @@ -431,6 +434,16 @@ static void sii8620_mt_rap(struct sii8620 *ctx, u8 code) sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RAP, code); } +static void sii8620_mt_rcpk(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPK, code); +} + +static void sii8620_mt_rcpe(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPE, code); +} + static void sii8620_mt_read_devcap_send(struct sii8620 *ctx, struct sii8620_mt_msg *msg) { @@ -1753,6 +1766,25 @@ static void sii8620_send_features(struct sii8620 *ctx) sii8620_write_buf(ctx, REG_MDT_XMIT_WRITE_PORT, buf, ARRAY_SIZE(buf)); } +static bool sii8620_rcp_consume(struct sii8620 *ctx, u8 scancode) +{ + bool pressed = !(scancode & MHL_RCP_KEY_RELEASED_MASK); + + scancode &= MHL_RCP_KEY_ID_MASK; + + if (!ctx->rc_dev) { + dev_dbg(ctx->dev, "RCP input device not initialized\n"); + return false; + } + + if (pressed) + rc_keydown(ctx->rc_dev, RC_PROTO_CEC, scancode, 0); + else + rc_keyup(ctx->rc_dev); + + return true; +} + static void sii8620_msc_mr_set_int(struct sii8620 *ctx) { u8 ints[MHL_INT_SIZE]; @@ -1804,19 +1836,25 @@ static void sii8620_msc_mt_done(struct sii8620 *ctx) static void sii8620_msc_mr_msc_msg(struct sii8620 *ctx) { - struct sii8620_mt_msg *msg = sii8620_msc_msg_first(ctx); + struct sii8620_mt_msg *msg; u8 buf[2]; - if (!msg) - return; - sii8620_read_buf(ctx, REG_MSC_MR_MSC_MSG_RCVD_1ST_DATA, buf, 2); switch (buf[0]) { case MHL_MSC_MSG_RAPK: + msg = sii8620_msc_msg_first(ctx); + if (!msg) + return; msg->ret = buf[1]; ctx->mt_state = MT_STATE_DONE; break; + case MHL_MSC_MSG_RCP: + if (!sii8620_rcp_consume(ctx, buf[1])) + sii8620_mt_rcpe(ctx, + MHL_RCPE_STATUS_INEFFECTIVE_KEY_CODE); + sii8620_mt_rcpk(ctx, buf[1]); + break; default: dev_err(ctx->dev, "%s message type %d,%d not supported", __func__, buf[0], buf[1]); @@ -2102,11 +2140,57 @@ static void sii8620_cable_in(struct sii8620 *ctx) enable_irq(to_i2c_client(ctx->dev)->irq); } +static void sii8620_init_rcp_input_dev(struct sii8620 *ctx) +{ + struct rc_dev *rc_dev; + int ret; + + rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE); + if (!rc_dev) { + dev_err(ctx->dev, "Failed to allocate RC device\n"); + ctx->error = -ENOMEM; +
[PATCH] drm/bridge/sii8620: Fix memory corruption
Function sii8620_mt_read_devcap_reg_recv() used to read array index from a wrong msg register, which caused writing out of array bounds. It led to writing on other fields of struct sii8620. Signed-off-by: Maciej Purski <m.pur...@samsung.com> Fixes: e9c6da270 ("drm/bridge/sii8620: add reading device capability registers") --- drivers/gpu/drm/bridge/sil-sii8620.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 2d51a22..5131bfb 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -597,9 +597,9 @@ static void sii8620_mt_read_devcap(struct sii8620 *ctx, bool xdevcap) static void sii8620_mt_read_devcap_reg_recv(struct sii8620 *ctx, struct sii8620_mt_msg *msg) { - u8 reg = msg->reg[0] & 0x7f; + u8 reg = msg->reg[1] & 0x7f; - if (msg->reg[0] & 0x80) + if (msg->reg[1] & 0x80) ctx->xdevcap[reg] = msg->ret; else ctx->devcap[reg] = msg->ret; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3] drm/bridge/sii8620: add remote control support
MHL specification defines Remote Control Protocol(RCP) to send input events between MHL devices. The driver now recognizes RCP messages and reacts to them by reporting key events to input subsystem, allowing a user to control a device using TV remote control. Changes in v2: - use RC subsystem (including CEC keymap) - RC device initialized in attach drm_bridge callback and removed in detach callback. This is necessary, because RC_CORE, which is needed during rc_dev init, is loaded after sii8620. DRM bridge is binded later which solves the problem. - add RC_CORE dependency Changes in v3: - fix error handling in init_rcp and in attach callback Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/bridge/Kconfig | 2 +- drivers/gpu/drm/bridge/sil-sii8620.c | 101 +-- include/drm/bridge/mhl.h | 4 ++ 3 files changed, 101 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index adf9ae0..6ef901c 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -71,7 +71,7 @@ config DRM_PARADE_PS8622 config DRM_SIL_SII8620 tristate "Silicon Image SII8620 HDMI/MHL bridge" - depends on OF + depends on OF && RC_CORE select DRM_KMS_HELPER help Silicon Image SII8620 HDMI/MHL bridge chip driver. diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 2d51a22..e072bca 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -28,6 +28,8 @@ #include #include +#include + #include "sil-sii8620.h" #define SII8620_BURST_BUF_LEN 288 @@ -58,6 +60,7 @@ enum sii8620_mt_state { struct sii8620 { struct drm_bridge bridge; struct device *dev; + struct rc_dev *rc_dev; struct clk *clk_xtal; struct gpio_desc *gpio_reset; struct gpio_desc *gpio_int; @@ -431,6 +434,16 @@ static void sii8620_mt_rap(struct sii8620 *ctx, u8 code) sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RAP, code); } +static void sii8620_mt_rcpk(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPK, code); +} + +static void sii8620_mt_rcpe(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPE, code); +} + static void sii8620_mt_read_devcap_send(struct sii8620 *ctx, struct sii8620_mt_msg *msg) { @@ -1753,6 +1766,25 @@ static void sii8620_send_features(struct sii8620 *ctx) sii8620_write_buf(ctx, REG_MDT_XMIT_WRITE_PORT, buf, ARRAY_SIZE(buf)); } +static bool sii8620_rcp_consume(struct sii8620 *ctx, u8 scancode) +{ + bool pressed = !(scancode & MHL_RCP_KEY_RELEASED_MASK); + + scancode &= MHL_RCP_KEY_ID_MASK; + + if (!ctx->rc_dev) { + dev_dbg(ctx->dev, "RCP input device not initialized\n"); + return false; + } + + if (pressed) + rc_keydown(ctx->rc_dev, RC_TYPE_CEC, scancode, 0); + else + rc_keyup(ctx->rc_dev); + + return true; +} + static void sii8620_msc_mr_set_int(struct sii8620 *ctx) { u8 ints[MHL_INT_SIZE]; @@ -1804,19 +1836,25 @@ static void sii8620_msc_mt_done(struct sii8620 *ctx) static void sii8620_msc_mr_msc_msg(struct sii8620 *ctx) { - struct sii8620_mt_msg *msg = sii8620_msc_msg_first(ctx); + struct sii8620_mt_msg *msg; u8 buf[2]; - if (!msg) - return; - sii8620_read_buf(ctx, REG_MSC_MR_MSC_MSG_RCVD_1ST_DATA, buf, 2); switch (buf[0]) { case MHL_MSC_MSG_RAPK: + msg = sii8620_msc_msg_first(ctx); + if (!msg) + return; msg->ret = buf[1]; ctx->mt_state = MT_STATE_DONE; break; + case MHL_MSC_MSG_RCP: + if (!sii8620_rcp_consume(ctx, buf[1])) + sii8620_mt_rcpe(ctx, + MHL_RCPE_STATUS_INEFFECTIVE_KEY_CODE); + sii8620_mt_rcpk(ctx, buf[1]); + break; default: dev_err(ctx->dev, "%s message type %d,%d not supported", __func__, buf[0], buf[1]); @@ -2102,11 +2140,62 @@ static void sii8620_cable_in(struct sii8620 *ctx) enable_irq(to_i2c_client(ctx->dev)->irq); } +static void sii8620_init_rcp_input_dev(struct sii8620 *ctx) +{ + struct rc_dev *rc_dev; + int ret; + + rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE); + if (!rc_dev) { + dev_err(ctx->dev, "Failed to allocate RC device\n"); + ctx->error = -ENOMEM; + return; + } + + rc_dev->input_phys = "sii8620/input0"; + rc_dev->input_id.bustype = BUS_VI
[PATCH v2] drm/bridge/sii8620: add remote control support
MHL specification defines Remote Control Protocol(RCP) to send input events between MHL devices. The driver now recognizes RCP messages and reacts to them by reporting key events to input subsystem, allowing a user to control a device using TV remote control. Changes in v2: - use RC subsystem (including CEC keymap) - RC device initialized in attach drm_bridge callback and removed in detach callback. This is necessary, because RC_CORE, which is needed during rc_dev init, is loaded after sii8620. DRM bridge is binded later which solves the problem. - add RC_CORE dependency Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/bridge/Kconfig | 2 +- drivers/gpu/drm/bridge/sil-sii8620.c | 99 ++-- include/drm/bridge/mhl.h | 4 ++ 3 files changed, 99 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index adf9ae0..6ef901c 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -71,7 +71,7 @@ config DRM_PARADE_PS8622 config DRM_SIL_SII8620 tristate "Silicon Image SII8620 HDMI/MHL bridge" - depends on OF + depends on OF && RC_CORE select DRM_KMS_HELPER help Silicon Image SII8620 HDMI/MHL bridge chip driver. diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 2d51a22..413806b 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -28,6 +28,8 @@ #include #include +#include + #include "sil-sii8620.h" #define SII8620_BURST_BUF_LEN 288 @@ -58,6 +60,7 @@ enum sii8620_mt_state { struct sii8620 { struct drm_bridge bridge; struct device *dev; + struct rc_dev *rc_dev; struct clk *clk_xtal; struct gpio_desc *gpio_reset; struct gpio_desc *gpio_int; @@ -431,6 +434,16 @@ static void sii8620_mt_rap(struct sii8620 *ctx, u8 code) sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RAP, code); } +static void sii8620_mt_rcpk(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPK, code); +} + +static void sii8620_mt_rcpe(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPE, code); +} + static void sii8620_mt_read_devcap_send(struct sii8620 *ctx, struct sii8620_mt_msg *msg) { @@ -1753,6 +1766,25 @@ static void sii8620_send_features(struct sii8620 *ctx) sii8620_write_buf(ctx, REG_MDT_XMIT_WRITE_PORT, buf, ARRAY_SIZE(buf)); } +static bool sii8620_rcp_consume(struct sii8620 *ctx, u8 scancode) +{ + bool pressed = !(scancode & MHL_RCP_KEY_RELEASED_MASK); + + scancode &= MHL_RCP_KEY_ID_MASK; + + if (!ctx->rc_dev) { + dev_dbg(ctx->dev, "RCP input device not initialized\n"); + return false; + } + + if (pressed) + rc_keydown(ctx->rc_dev, RC_TYPE_CEC, scancode, 0); + else + rc_keyup(ctx->rc_dev); + + return true; +} + static void sii8620_msc_mr_set_int(struct sii8620 *ctx) { u8 ints[MHL_INT_SIZE]; @@ -1804,19 +1836,25 @@ static void sii8620_msc_mt_done(struct sii8620 *ctx) static void sii8620_msc_mr_msc_msg(struct sii8620 *ctx) { - struct sii8620_mt_msg *msg = sii8620_msc_msg_first(ctx); + struct sii8620_mt_msg *msg; u8 buf[2]; - if (!msg) - return; - sii8620_read_buf(ctx, REG_MSC_MR_MSC_MSG_RCVD_1ST_DATA, buf, 2); switch (buf[0]) { case MHL_MSC_MSG_RAPK: + msg = sii8620_msc_msg_first(ctx); + if (!msg) + return; msg->ret = buf[1]; ctx->mt_state = MT_STATE_DONE; break; + case MHL_MSC_MSG_RCP: + if (!sii8620_rcp_consume(ctx, buf[1])) + sii8620_mt_rcpe(ctx, + MHL_RCPE_STATUS_INEFFECTIVE_KEY_CODE); + sii8620_mt_rcpk(ctx, buf[1]); + break; default: dev_err(ctx->dev, "%s message type %d,%d not supported", __func__, buf[0], buf[1]); @@ -2102,11 +2140,60 @@ static void sii8620_cable_in(struct sii8620 *ctx) enable_irq(to_i2c_client(ctx->dev)->irq); } +static void sii8620_init_rcp_input_dev(struct sii8620 *ctx) +{ + struct rc_dev *rc_dev; + int ret; + + rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE); + if (!rc_dev) { + dev_err(ctx->dev, "Failed to allocate RC device\n"); + ctx->error = -ENOMEM; + } + + rc_dev->input_phys = "sii8620/input0"; + rc_dev->input_id.bustype = BUS_VIRTUAL; + rc_dev->map_name = RC_MAP_CEC; + rc_dev->allowed_protocols = RC_BIT_
[PATCH 0/2] add Silicon Image SiI9234 driver
Hi everyone, These patches are a continuation of work by Tomasz Stanislawski on sii9324 driver, which was described in th following letter: https://lists.freedesktop.org/archives/dri-devel/2014-April/057481.html The main differences from the previous code are: * driver moved to /gpu/drm/bridge/ and integrated with drm/bridge subsystem * added filtering-out unsupported display modes * changed gpio interface to up-to-date * changed interrupt handling * improve code style * add hdmi and sii9324 to exynos4412-trats2 device tree All comments are welcome. Regards, Maciej Purski Patch summary: Maciej Purski (2): drm/bridge: add Silicon Image SiI9234 driver ARM: dts: exynos: Add HDMI and Sil9234 to Trats2 board .../devicetree/bindings/display/bridge/sii9234.txt | 20 + arch/arm/boot/dts/exynos4412-trats2.dts| 93 ++ drivers/gpu/drm/bridge/Kconfig |8 + drivers/gpu/drm/bridge/Makefile|1 + drivers/gpu/drm/bridge/sii9234.c | 1019 5 files changed, 1141 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii9234.txt create mode 100644 drivers/gpu/drm/bridge/sii9234.c -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/2] arm64: dts: exynos: add extcon phandle
Sii8620 driver can now use extcon in order to switch on and off the device. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi index 0943dec..ed991b3 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi @@ -784,6 +784,7 @@ reset-gpios = < 0 GPIO_ACTIVE_LOW>; clocks = <_system_controller 0>; clock-names = "xtal"; + extcon = <>; port { mhl_to_hdmi: endpoint { -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/2] drm/bridge/sii8620: add external connector handle
The driver should be switched on if an external connector is plugged and switched off if it is unplugged. Extcon is optional. If it is not found, the driver stays in "always-on" mode. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- .../bindings/display/bridge/sil-sii8620.txt| 4 ++ drivers/gpu/drm/bridge/sil-sii8620.c | 83 +- 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/bridge/sil-sii8620.txt b/Documentation/devicetree/bindings/display/bridge/sil-sii8620.txt index 9409d9c..1f230bf 100644 --- a/Documentation/devicetree/bindings/display/bridge/sil-sii8620.txt +++ b/Documentation/devicetree/bindings/display/bridge/sil-sii8620.txt @@ -10,6 +10,9 @@ Required properties: - clocks, clock-names: specification and name of "xtal" clock - video interfaces: Device node can contain video interface port node for HDMI encoder according to [1]. +Optional properties: + - extcon: phandle to external connector for MHL cable changes + detection [1]: Documentation/devicetree/bindings/media/video-interfaces.txt @@ -24,6 +27,7 @@ Example: reset-gpio = < 0 0>; clocks = <_system_controller 0>; clock-names = "xtal"; + extcon = <>; port { mhl_to_hdmi: endpoint { diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 2d51a22..5002654 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -78,6 +79,10 @@ struct sii8620 { struct edid *edid; unsigned int gen2_write_burst:1; enum sii8620_mt_state mt_state; + struct extcon_dev *extcon; + struct notifier_block extcon_nb; + struct work_struct extcon_wq; + bool extcon_attached; struct list_head mt_queue; struct { int r_size; @@ -2102,6 +2107,72 @@ static void sii8620_cable_in(struct sii8620 *ctx) enable_irq(to_i2c_client(ctx->dev)->irq); } +static void sii8620_cable_out(struct sii8620 *ctx) +{ + disable_irq(to_i2c_client(ctx->dev)->irq); + sii8620_hw_off(ctx); +} + +static void sii8620_extcon_work(struct work_struct *work) +{ + struct sii8620 *ctx = + container_of(work, struct sii8620, extcon_wq); + + if (ctx->extcon_attached) + sii8620_cable_in(ctx); + else + sii8620_cable_out(ctx); +} + +static int sii8620_extcon_notifier(struct notifier_block *self, + unsigned long event, void *ptr) +{ + struct sii8620 *ctx = + container_of(self, struct sii8620, extcon_nb); + + ctx->extcon_attached = event; + schedule_work(>extcon_wq); + + return NOTIFY_DONE; +} + +static int sii8620_extcon_init(struct sii8620 *ctx) +{ + struct extcon_dev *edev; + int ret; + + INIT_WORK(>extcon_wq, sii8620_extcon_work); + + if (!of_property_read_bool(ctx->dev->of_node, "extcon")) { + dev_info(ctx->dev, "no extcon found, switching to 'always on' mode\n"); + ctx->extcon_attached = true; + return 0; + } + + edev = extcon_get_edev_by_phandle(ctx->dev, 0); + if (IS_ERR(edev)) { + if (PTR_ERR(edev) == -EPROBE_DEFER) + return -EPROBE_DEFER; + dev_err(ctx->dev, "Invalid or missing extcon\n"); + return PTR_ERR(edev); + } + + ctx->extcon_attached = extcon_get_cable_state_(edev, EXTCON_DISP_MHL); + dev_info(ctx->dev, "extcon(MHL) = %d\n", ctx->extcon_attached); + + ctx->extcon = edev; + ctx->extcon_nb.notifier_call = sii8620_extcon_notifier; + ret = devm_extcon_register_notifier(ctx->dev, edev, + EXTCON_DISP_MHL, >extcon_nb); + + if (ret) { + dev_err(ctx->dev, "failed to register notifier for MHL\n"); + return ret; + } + + return 0; +} + static inline struct sii8620 *bridge_to_sii8620(struct drm_bridge *bridge) { return container_of(bridge, struct sii8620, bridge); @@ -2201,13 +2272,20 @@ static int sii8620_probe(struct i2c_client *client, if (ret) return ret; + ret = sii8620_extcon_init(ctx); + if (ret < 0) { + dev_err(ctx->dev, "failed to initialize EXTCON\n"); + return ret; + } + i2c_set_clientdata(client, ctx); ctx->bridge.funcs = _bridge_funcs; ctx->bridge.of_node = dev->of_node; drm_br
[PATCH 0/2] drm/bridge/sii8620: add external connector handle
Hi everyone, These patches add external connector handling to sii8620 driver. The first patch documents the extcon binding and add extcon handling to the driver. The second adds support for this in exynos5433-tm2-common.dtsi. All comments are welcome. Regards, Maciej Purski Patch summary: Maciej Purski (2): drm/bridge/sii8620: add external connector handle arm64: dts: exynos: add extcon phandle .../bindings/display/bridge/sil-sii8620.txt| 4 ++ .../boot/dts/exynos/exynos5433-tm2-common.dtsi | 1 + drivers/gpu/drm/bridge/sil-sii8620.c | 83 +- 3 files changed, 86 insertions(+), 2 deletions(-) -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge/sii8620: add remote control support
Hi Hans, Thank you for your reply. All dongles that we used to work with in Samsung convert CEC protocol to RCP which we get through MHL Sideband Channel. All we can do in the driver is to report RCP messages to user-space. On the RC subsystem: your point is right, which was confirmed by Sean and I'm going to use RC subsystem there. Regards, Maciej Purski On 08/03/2017 10:28 AM, Hans Verkuil wrote: Hi Maciej, Unfortunately I do not have the MHL spec, but I was wondering what the relationship between RCP and CEC is. CEC has remote control support as well, so is RCP that subset of the CEC specification or is it completely separate? I'm CC-ing Sean Young and the linux-media mailinglist as well since Sean maintains the rc subsystem. Which you probably should use, but I'm not the expert on that. Regards, Hans On 08/03/17 09:44, Maciej Purski wrote: MHL specification defines Remote Control Protocol(RCP) to send input events between MHL devices. The driver now recognizes RCP messages and reacts to them by reporting key events to input subsystem, allowing a user to control a device using TV remote control. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/bridge/sil-sii8620.c | 188 ++- include/drm/bridge/mhl.h | 4 + 2 files changed, 187 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 2d51a22..7e75f2f 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,7 @@ enum sii8620_mt_state { struct sii8620 { struct drm_bridge bridge; struct device *dev; + struct input_dev *rcp_input_dev; struct clk *clk_xtal; struct gpio_desc *gpio_reset; struct gpio_desc *gpio_int; @@ -106,6 +108,82 @@ struct sii8620_mt_msg { sii8620_cb continuation; }; +static struct { + u16 key; + u16 extra_key; + bool autorepeat; +} rcp_keymap[] = { + [0x00] = { KEY_SELECT }, + [0x01] = { KEY_UP, 0, true }, + [0x02] = { KEY_DOWN, 0, true }, + [0x03] = { KEY_LEFT, 0, true }, + [0x04] = { KEY_RIGHT, 0, true }, + + [0x05] = { KEY_RIGHT, KEY_UP, true }, + [0x06] = { KEY_RIGHT, KEY_DOWN, true }, + [0x07] = { KEY_LEFT, KEY_UP, true }, + [0x08] = { KEY_LEFT, KEY_DOWN, true }, + + [0x09] = { KEY_MENU }, + [0x0A] = { KEY_UNKNOWN }, + [0x0B] = { KEY_UNKNOWN }, + [0x0C] = { KEY_BOOKMARKS }, + [0x0D] = { KEY_EXIT }, + + [0x20] = { KEY_NUMERIC_0 }, + [0x21] = { KEY_NUMERIC_1 }, + [0x22] = { KEY_NUMERIC_2 }, + [0x23] = { KEY_NUMERIC_3 }, + [0x24] = { KEY_NUMERIC_4 }, + [0x25] = { KEY_NUMERIC_5 }, + [0x26] = { KEY_NUMERIC_6 }, + [0x27] = { KEY_NUMERIC_7 }, + [0x28] = { KEY_NUMERIC_8 }, + [0x29] = { KEY_NUMERIC_9 }, + + [0x2A] = { KEY_DOT }, + [0x2B] = { KEY_ENTER }, + [0x2C] = { KEY_CLEAR }, + + [0x30] = { KEY_CHANNELUP, 0, true }, + [0x31] = { KEY_CHANNELDOWN, 0, true }, + + [0x33] = { KEY_SOUND }, + [0x35] = { KEY_PROGRAM }, /* Show Information */ + + [0x37] = { KEY_PAGEUP, 0, true }, + [0x38] = { KEY_PAGEDOWN, 0, true }, + + [0x41] = { KEY_VOLUMEUP, 0, true }, + [0x42] = { KEY_VOLUMEDOWN, 0, true }, + [0x43] = { KEY_MUTE }, + [0x44] = { KEY_PLAY }, + [0x45] = { KEY_STOP }, + [0x46] = { KEY_PLAYPAUSE }, /* Pause */ + [0x47] = { KEY_RECORD }, + [0x48] = { KEY_REWIND, 0, true }, + [0x49] = { KEY_FASTFORWARD, 0, true }, + [0x4A] = { KEY_EJECTCD }, + [0x4B] = { KEY_NEXTSONG, 0, true }, /* Forward */ + [0x4C] = { KEY_PREVIOUSSONG, 0, true }, /* Backward */ + + [0x60] = { KEY_PLAYPAUSE }, /* Play */ + [0x61] = { KEY_PLAYPAUSE }, /* Pause the Play */ + [0x62] = { KEY_RECORD }, + [0x63] = { KEY_PAUSE }, + [0x64] = { KEY_STOP }, + [0x65] = { KEY_MUTE }, + [0x66] = { KEY_MUTE }, /* Restore Mute */ + + [0x71] = { KEY_F1 }, + [0x72] = { KEY_F2 }, + [0x73] = { KEY_F3 }, + [0x74] = { KEY_F4 }, + [0x75] = { KEY_F5 }, + + [0x7E] = { KEY_VENDOR }, +}; + static const u8 sii8620_i2c_page[] = { 0x39, /* Main System */ 0x3d, /* TDM and HSIC */ @@ -431,6 +509,16 @@ static void sii8620_mt_rap(struct sii8620 *ctx, u8 code) sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RAP, code); } +static void sii8620_mt_rcpk(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPK, code); +} + +static void sii8620_mt_rcpe(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPE, code); +} + static void sii8620_mt_read_devcap_send(struct sii862
[PATCH 0/2] add Silicon Image SiI9234 driver
Hi everyone, These patches are a continuation of work by Tomasz Stanislawski on sii9324 driver, which was described in th following letter: https://lists.freedesktop.org/archives/dri-devel/2014-April/057481.html The main differences from the previous code are: * driver moved to /gpu/drm/bridge/ and integrated with drm/bridge subsystem * added filtering-out unsupported display modes * changed gpio interface to up-to-date * changed interrupt handling * improve code style * add hdmi and sii9324 to exynos4412-trats2 device tree All comments are welcome. Regards, Maciej Purski Patch summary: Maciej Purski (2): drm/bridge: add Silicon Image SiI9234 driver ARM: dts: exynos: Add HDMI and Sil9234 to Trats2 board .../devicetree/bindings/display/bridge/sii9234.txt | 20 + arch/arm/boot/dts/exynos4412-trats2.dts| 93 ++ drivers/gpu/drm/bridge/Kconfig |8 + drivers/gpu/drm/bridge/Makefile|1 + drivers/gpu/drm/bridge/sii9234.c | 1019 5 files changed, 1141 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii9234.txt create mode 100644 drivers/gpu/drm/bridge/sii9234.c -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/2] ARM: dts: exynos: Add HDMI and Sil9234 to Trats2 board
This patch adds HDMI and Sil9234 MHL converter to Trats2 board. Based on previous work by: Tomasz Stanislawski <t.stanisl...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- arch/arm/boot/dts/exynos4412-trats2.dts | 93 + 1 file changed, 93 insertions(+) diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index 35e9b94..39940f6 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -97,6 +97,16 @@ gpio = < 5 GPIO_ACTIVE_HIGH>; enable-active-high; }; + + vsil: voltage-regulator-vsil { + compatible = "regulator-fixed"; + regulator-name = "HDMI_5V"; + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + gpio = < 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <_reg>; + }; }; gpio-keys { @@ -229,6 +239,34 @@ }; }; + i2c-mhl { + compatible = "i2c-gpio"; + gpios = < 4 GPIO_ACTIVE_HIGH 6 GPIO_ACTIVE_HIGH>; + i2c-gpio,delay-us = <100>; + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <_mhl_bus>; + pinctrl-names = "default"; + status = "okay"; + + sii9234: sii9234@39 { + compatible = "sil,sii9234"; + vcc-supply = <>; + reset-gpios = < 4 GPIO_ACTIVE_HIGH>; + interrupt-parent = <>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x39>; + + + port { + mhl_to_hdmi: endpoint { + remote-endpoint = <_to_mhl>; + }; + }; + }; + }; + camera: camera { pinctrl-0 = <_port_a_clk_active _port_b_clk_active>; pinctrl-names = "default"; @@ -522,6 +560,31 @@ status = "okay"; }; + { + hpd-gpios = < 7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <_hpd>; + hdmi-en-supply = <>; + vdd-supply = <_reg>; + vdd_osc-supply = <_reg>; + vdd_pll-supply = <_reg>; + ddc = <_5>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + hdmi_to_mhl: endpoint { + remote-endpoint = <_to_hdmi>; + }; + }; + }; + +}; + { vusb_d-supply = <_reg>; vusb_a-supply = <_reg>; @@ -600,6 +663,11 @@ }; }; + +_5 { + status = "okay"; +}; + _7 { samsung,i2c-sda-delay = <100>; samsung,i2c-slave-addr = <0x10>; @@ -894,12 +962,20 @@ }; }; +_8 { + status = "okay"; +}; + { pinctrl-0 = <_bus>; pinctrl-names = "default"; status = "okay"; }; + { + status = "okay"; +}; + _0 { num-slots = <1>; broken-cd; @@ -926,6 +1002,18 @@ pinctrl-names = "default"; pinctrl-0 = <>; + mhl_int: mhl-int { + samsung,pins = "gpf3-5"; + samsung,pin-pud = <0>; + }; + + i2c_mhl_bus: i2c-mhl-bus { + samsung,pins = "gpf0-4", "gpf0-6"; + samsung,pin-function = <2>; + samsung,pin-pud = <1>; + samsung,pin-drv = <0>; + }; + sleep0: sleep-states { PIN_SLP(gpa0-0, INPUT, NONE); PIN_SLP(gpa0-1, OUT0, NONE); @@ -1029,6 +1117,11 @@ pinctrl-names = "default"; pinctrl-0 = <>; + hdmi_hpd: hdmi-hpd { + samsung,pins = "gpx3-7"; + samsung,pin-pud = ; + }; + sleep1: sleep-states { PIN_SLP(gpk0-0, PREV, NONE); PIN_SLP(gpk0-1, PREV, NONE); -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/2] drm/bridge: add Silicon Image SiI9234 driver
SiI9234 transmitter converts eTMDS/HDMI signal to MHL 1.0. It is controlled via I2C bus. Its interaction with other devices in video pipeline is performed mainly on HW level. The only interaction it does on device driver level is filtering-out unsupported video modes, it exposes drm_bridge interface to perform this operation. This patch is based on the code refactored by Tomasz Stanislawski <t.stanisl...@samsung.com>, which was initially developed by: Adam Hampson <ahamp...@sta.samsung.com> Erik Gilling <konk...@android.com> Shankar Bandal <shanka...@samsung.com> Dharam Kumar <dharam...@samsung.com> Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- .../devicetree/bindings/display/bridge/sii9234.txt | 20 + drivers/gpu/drm/bridge/Kconfig |8 + drivers/gpu/drm/bridge/Makefile|1 + drivers/gpu/drm/bridge/sii9234.c | 1019 4 files changed, 1048 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii9234.txt create mode 100644 drivers/gpu/drm/bridge/sii9234.c diff --git a/Documentation/devicetree/bindings/display/bridge/sii9234.txt b/Documentation/devicetree/bindings/display/bridge/sii9234.txt new file mode 100644 index 000..2cdf286 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/sii9234.txt @@ -0,0 +1,20 @@ +SiI9234 Mobile HD Link Transmitter + +Required properties: +- compatible : "sil,sii9234". +- reg : I2C address for TPI interface, use 0x39 +- vcc-supply : regulator that supplies the chip +- interrupts, interrupt-parent: interrupt specifier of INT pin +- reset-gpios: gpio specifier of RESET pin + +Additional compatible properties are also allowed. + +Example: + sii9234@39 { + compatible = "sil,sii9234"; + reg = <0x39>; + vcc-supply = <>; + reset-gpios = < 4 GPIO_ACTIVE_HIGH>; + interrupt-parent = <>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + }; diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index adf9ae0..f5784e5 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -100,6 +100,14 @@ config DRM_TI_TFP410 ---help--- Texas Instruments TFP410 DVI/HDMI Transmitter driver +config DRM_SII9234 + tristate "Silicon Image SII9234 Driver" + depends on I2C + help + Say Y here if you want support for the MHL interface. + It is an I2C driver, that detects connection of MHL bridge + and starts encapsulation of HDMI signal. + source "drivers/gpu/drm/bridge/analogix/Kconfig" source "drivers/gpu/drm/bridge/adv7511/Kconfig" diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index defcf1e..e3d5eb0 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o obj-$(CONFIG_DRM_SII902X) += sii902x.o +obj-$(CONFIG_DRM_SII9234) += sii9234.o obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ diff --git a/drivers/gpu/drm/bridge/sii9234.c b/drivers/gpu/drm/bridge/sii9234.c new file mode 100644 index 000..9c436e7 --- /dev/null +++ b/drivers/gpu/drm/bridge/sii9234.c @@ -0,0 +1,1019 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * + * Author: Tomasz Stanislawski <t.stanisl...@samsung.com> + * + * Based on sii9234 driver created by: + *Adam Hampson <ahamp...@sta.samsung.com> + *Erik Gilling <konk...@android.com> + *Shankar Bandal <shanka...@samsung.com> + *Dharam Kumar <dharam...@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program + * + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* MHL Tx registers and bits */ +#define MHL_TX_SRST 0x05 +#define MHL_TX_SYSSTAT_REG 0x09 +#define MHL_TX_INTR1_RE
[PATCH] drm/bridge/sii8620: add remote control support
MHL specification defines Remote Control Protocol(RCP) to send input events between MHL devices. The driver now recognizes RCP messages and reacts to them by reporting key events to input subsystem, allowing a user to control a device using TV remote control. Signed-off-by: Maciej Purski <m.pur...@samsung.com> --- drivers/gpu/drm/bridge/sil-sii8620.c | 188 ++- include/drm/bridge/mhl.h | 4 + 2 files changed, 187 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 2d51a22..7e75f2f 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,7 @@ enum sii8620_mt_state { struct sii8620 { struct drm_bridge bridge; struct device *dev; + struct input_dev *rcp_input_dev; struct clk *clk_xtal; struct gpio_desc *gpio_reset; struct gpio_desc *gpio_int; @@ -106,6 +108,82 @@ struct sii8620_mt_msg { sii8620_cb continuation; }; +static struct { + u16 key; + u16 extra_key; + bool autorepeat; +} rcp_keymap[] = { + [0x00] = { KEY_SELECT }, + [0x01] = { KEY_UP, 0, true }, + [0x02] = { KEY_DOWN, 0, true }, + [0x03] = { KEY_LEFT, 0, true }, + [0x04] = { KEY_RIGHT, 0, true }, + + [0x05] = { KEY_RIGHT, KEY_UP, true }, + [0x06] = { KEY_RIGHT, KEY_DOWN, true }, + [0x07] = { KEY_LEFT, KEY_UP, true }, + [0x08] = { KEY_LEFT, KEY_DOWN, true }, + + [0x09] = { KEY_MENU }, + [0x0A] = { KEY_UNKNOWN }, + [0x0B] = { KEY_UNKNOWN }, + [0x0C] = { KEY_BOOKMARKS }, + [0x0D] = { KEY_EXIT }, + + [0x20] = { KEY_NUMERIC_0 }, + [0x21] = { KEY_NUMERIC_1 }, + [0x22] = { KEY_NUMERIC_2 }, + [0x23] = { KEY_NUMERIC_3 }, + [0x24] = { KEY_NUMERIC_4 }, + [0x25] = { KEY_NUMERIC_5 }, + [0x26] = { KEY_NUMERIC_6 }, + [0x27] = { KEY_NUMERIC_7 }, + [0x28] = { KEY_NUMERIC_8 }, + [0x29] = { KEY_NUMERIC_9 }, + + [0x2A] = { KEY_DOT }, + [0x2B] = { KEY_ENTER }, + [0x2C] = { KEY_CLEAR }, + + [0x30] = { KEY_CHANNELUP, 0, true }, + [0x31] = { KEY_CHANNELDOWN, 0, true }, + + [0x33] = { KEY_SOUND }, + [0x35] = { KEY_PROGRAM }, /* Show Information */ + + [0x37] = { KEY_PAGEUP, 0, true }, + [0x38] = { KEY_PAGEDOWN, 0, true }, + + [0x41] = { KEY_VOLUMEUP, 0, true }, + [0x42] = { KEY_VOLUMEDOWN, 0, true }, + [0x43] = { KEY_MUTE }, + [0x44] = { KEY_PLAY }, + [0x45] = { KEY_STOP }, + [0x46] = { KEY_PLAYPAUSE }, /* Pause */ + [0x47] = { KEY_RECORD }, + [0x48] = { KEY_REWIND, 0, true }, + [0x49] = { KEY_FASTFORWARD, 0, true }, + [0x4A] = { KEY_EJECTCD }, + [0x4B] = { KEY_NEXTSONG, 0, true }, /* Forward */ + [0x4C] = { KEY_PREVIOUSSONG, 0, true }, /* Backward */ + + [0x60] = { KEY_PLAYPAUSE }, /* Play */ + [0x61] = { KEY_PLAYPAUSE }, /* Pause the Play */ + [0x62] = { KEY_RECORD }, + [0x63] = { KEY_PAUSE }, + [0x64] = { KEY_STOP }, + [0x65] = { KEY_MUTE }, + [0x66] = { KEY_MUTE }, /* Restore Mute */ + + [0x71] = { KEY_F1 }, + [0x72] = { KEY_F2 }, + [0x73] = { KEY_F3 }, + [0x74] = { KEY_F4 }, + [0x75] = { KEY_F5 }, + + [0x7E] = { KEY_VENDOR }, +}; + static const u8 sii8620_i2c_page[] = { 0x39, /* Main System */ 0x3d, /* TDM and HSIC */ @@ -431,6 +509,16 @@ static void sii8620_mt_rap(struct sii8620 *ctx, u8 code) sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RAP, code); } +static void sii8620_mt_rcpk(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPK, code); +} + +static void sii8620_mt_rcpe(struct sii8620 *ctx, u8 code) +{ + sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPE, code); +} + static void sii8620_mt_read_devcap_send(struct sii8620 *ctx, struct sii8620_mt_msg *msg) { @@ -1753,6 +1841,43 @@ static void sii8620_send_features(struct sii8620 *ctx) sii8620_write_buf(ctx, REG_MDT_XMIT_WRITE_PORT, buf, ARRAY_SIZE(buf)); } +static void sii8620_rcp_report_key(struct sii8620 *ctx, u8 keycode, bool pressed) +{ + input_report_key(ctx->rcp_input_dev, + rcp_keymap[keycode].key, pressed); + + if (rcp_keymap[keycode].extra_key) + input_report_key(ctx->rcp_input_dev, + rcp_keymap[keycode].extra_key, pressed); +} + +static bool sii8620_rcp_consume(struct sii8620 *ctx, u8 keycode) +{ + bool pressed = !(keycode & MHL_RCP_KEY_RELEASED_MASK); + + if (!ctx->rcp_input_dev) { + dev_dbg(ctx->dev, "RCP input device not initialized\n"); + return false; + } + +