From patchwork Mon Jan 23 15:12:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 2666 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id AC1B53F039 for ; Mon, 23 Jan 2023 16:13:57 +0100 (CET) Received: by mail-pf1-f199.google.com with SMTP id a18-20020a62bd12000000b0056e7b61ec78sf5423453pff.17 for ; Mon, 23 Jan 2023 07:13:57 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1674486837; cv=pass; d=google.com; s=arc-20160816; b=k2f8s4BS78yahNENMWJtc7u0R7nBwyiYUqnm9b1UrTLml0NGIlViw2T3nowCVfF/PD x5/BmVzq7CJ+H/2spc87nYCv4u9g/4dvvIdAW4ssm0x1yWjcV4gDQ5hN3yD096oRIaOo zJcxN0iPEwkUX9ZLAQih/xXBFqwu7//oD6vMKAbb3rORDVGCHbIN6EgtrVY675vIpxBY UwE125W573hwbzmhiMoIG2EmryrAlf5XkvB0UVjs/If2evv0X47ojeC3tDYNTKct+YWn 0nvRwNYeSJaaTSftIDWx/5RejOcfjrl58fiGTGw6yOyIwFDYU0wAmLyxf2Fc3o6rhUpe h4KA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Ge7MJxAutVJgWNessVyjzICG2mii8Eo/s8AbZCdboXg=; b=WfmOM+Fexw+hoey7MIYb2IX52ySjjZ5ynLPGMw9nTkMDL1BLYEeFGzZyGAuejgK7nx Ut0AoUkYLE/ZYGFcpz6dQxxnHhFTD2YKYSfZ9yj9WLaY0SMLRxal9hvQvrkOOleHX7SL R789m/t1GgiwAge4mbUZm3WCmNwVTO6cyzQjQ4AyywWwKP79atuglJ716lju5G610W86 zMrLJKYgbQthgIjyALKNaptIJCA17fd/BG7AXg2zZPX9+IJZyPnfz8vrPpNtRfbR+x58 wf/IorR/aFgFX+OJEDZUKXT1+YLJ0kASbtPK5oaCsnTRlQ5Od37pY4qsZBwoxj++rWcA t1bQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=O3tW1Izw; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:x-original-authentication-results :x-original-sender:content-transfer-encoding:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=Ge7MJxAutVJgWNessVyjzICG2mii8Eo/s8AbZCdboXg=; b=FyX7kpgB16pqR3T3hu0VCMnxgPS0fz26yjTrMcWWLyI7tu/zP+lSE1R90R60JQOEBG mweQ58kV6kKX6vC8BNMLe2d3VkVPt0IsBtxBN5pMm/u9ZrfLKW4T06LK/9hBI4QV628r Yt/GqiddEeG39Zi245Q66NJCoEQF+rrhL0sAo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=list-unsubscribe:list-archive:list-help:list-post :x-spam-checked-in-group:list-id:mailing-list:precedence :x-original-authentication-results:x-original-sender :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ge7MJxAutVJgWNessVyjzICG2mii8Eo/s8AbZCdboXg=; b=coIq2tf3C/rGyipSwwCsSYkV9Rl89afvmgn2cATSewXDjv9/Zxj2yb2eByOYvfhmo7 ejYbuEMVMGHC0+GypAtcBvCGRyOLpv2BqzWRhaHIvG8JhxOB3U3DpDAQ+0FPCwwtwPcd 5YBfb8XfClAAkdoK/nmWJ7EBATqJ+l9BuWoACs3eEx8BZZB3ee2XlGZYHgxLuQScV7U1 PWtakI2HaEvBmDCwFmn1f6rSadaFjlZH+f7gatTIwYS04FJnuySePSEzAUwk+eEfBKbN ANgdAy59e68uTKemcXNeO5rhGBCATXwQWJqqSWkThf3Vnr2emdsb/EyUICe+u83xGG5k 507Q== X-Gm-Message-State: AFqh2kpLjORmgMwht+b8qY26smCNWtj5F2+eA1i6SKalZqIkMKDPQes0 qXwh2oe9xWAioCdBetM4D3vuvbRN X-Google-Smtp-Source: AMrXdXsuVyh4dnh6XPfmxbZk7qiTc142Gupf60cLAxJRE46TC36xxFk/dnzWiKM+4GK3hDSTOkrNhg== X-Received: by 2002:a65:4d4b:0:b0:4d4:18ad:b6b9 with SMTP id j11-20020a654d4b000000b004d418adb6b9mr897486pgt.51.1674486837293; Mon, 23 Jan 2023 07:13:57 -0800 (PST) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a17:902:e5c3:b0:192:62df:a3e7 with SMTP id u3-20020a170902e5c300b0019262dfa3e7ls13087664plf.9.-pod-prod-gmail; Mon, 23 Jan 2023 07:13:56 -0800 (PST) X-Received: by 2002:a17:902:8f86:b0:194:5c63:364c with SMTP id z6-20020a1709028f8600b001945c63364cmr25735956plo.62.1674486836398; Mon, 23 Jan 2023 07:13:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1674486836; cv=none; d=google.com; s=arc-20160816; b=DddcdEUbJxuEWxQ5cgqJrov2M5AEeF3ccTGGOg1tV0Zw/5r7eprOZ4/vP7Kd7QxmsN kkIFWbLx47O7sO32tXYK5ygPz9BfV58ri0HYEdwZWVrQyVHMFVde21t32MVmTV8MlW8Y ZTfK5ApPaWQ+YTsYY1h4fRE+hNtmzwrRmozYcrB7RNHjrYS6898SP0dpVRK4pkcnVmsG zV/PK2OeSqVMl6TCLlZisi29lYKQ6Wc3fjNAOjJjSHXNqwiOZpqA6uOUC+/L9egPqURK MrUZ/UMlGoI0KxjS4aVT1cL8pNIS347B2p7kfeRLpKe4MF4bfqv5JhxyRlrEuP1YEd3m mlMw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=M1hJXJQdt5ZCT1mSKIuiHURptg88R24MKTm4kRNQiUQ=; b=iCaZTZdtsk0ps2Xz5BcQKBzcGJsgGy1m3bFPIrc58xZHWy8nqiyENsSeUoOEpWj8dl G0f7JOyvkJ9zDTaTATvHbJFHkY2G47C7H84KQgQVQgsYdJu/oogEYm0oCG3ArElX99YK //Ps+PBL3H8xEb+TpyNmBiriFWHpjuXV7algupFQSIlw7H+/y5oI2Vk/O4rF9ceoTGqN aLF3sP42TSji/5R46fxBbm5zz8wRJJcrnP9zVulrXikrtNvBnwPQOJfbposn8I3uSEDN eVEA/dZq3sPqhrRIlJ2QlN/ajuAXizy11mEnejVwsfM7rZQIrnI5P0vs9czdDgxDzJJq B8PQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=O3tW1Izw; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id r10-20020a1709028bca00b0019482352535sor1386256plo.1.2023.01.23.07.13.56 for (Google Transport Security); Mon, 23 Jan 2023 07:13:56 -0800 (PST) Received-SPF: pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; X-Received: by 2002:a17:902:c3c6:b0:192:c014:f6ba with SMTP id j6-20020a170902c3c600b00192c014f6bamr24929553plj.33.1674486836050; Mon, 23 Jan 2023 07:13:56 -0800 (PST) Received: from localhost.localdomain ([2405:201:c00a:a15f:2279:f361:f93b:7971]) by smtp.gmail.com with ESMTPSA id d5-20020a170903230500b001754fa42065sm19207111plh.143.2023.01.23.07.13.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 07:13:55 -0800 (PST) From: Jagan Teki To: Andrzej Hajda , Inki Dae , Marek Szyprowski , Joonyoung Shim , Seung-Woo Kim , Kyungmin Park , Frieder Schrempf , Fancy Fang , Tim Harvey , Michael Nazzareno Trimarchi , Adam Ford , Neil Armstrong , Robert Foss , Laurent Pinchart , Tommaso Merciai , Marek Vasut Cc: Matteo Lisi , dri-devel@lists.freedesktop.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, NXP Linux Team , linux-amarula , Jagan Teki Subject: [RESEND PATCH v11 12/18] drm: exynos: dsi: Consolidate component and bridge Date: Mon, 23 Jan 2023 20:42:06 +0530 Message-Id: <20230123151212.269082-13-jagan@amarulasolutions.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230123151212.269082-1-jagan@amarulasolutions.com> References: <20230123151212.269082-1-jagan@amarulasolutions.com> MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" X-Original-Sender: jagan@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=O3tW1Izw; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , DSI host registration, attach and detach operations are quite different for the component and bridge-based DRM drivers.  Supporting generic bridge driver to use both component and bridge based DRM drivers can be tricky and would require additional host related operation hooks. Add host operation hooks for registering and unregistering Exynos and generic drivers, where Exynos hooks are used in existing Exynos component based DRM drivers and generic hooks are used in i.MX8M bridge based DRM drivers.  Add host attach and detach operation hooks for Exynos component DRM drivers and those get invoked while DSI core host attach and detach gets called. Signed-off-by: Marek Szyprowski Signed-off-by: Jagan Teki Reviewed-by: Marek Vasut --- Changes for v11: - none Changes for v10: - split from previous series patch "drm: bridge: Generalize Exynos-DSI driver into a Samsung DSIM bridge" drivers/gpu/drm/exynos/exynos_drm_dsi.c | 179 ++++++++++++++++++------ 1 file changed, 140 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 7afbbe30d1d3..fc7f00ab01b4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -250,6 +250,8 @@ struct exynos_dsi_transfer { u16 rx_done; }; +struct exynos_dsi; + #define DSIM_STATE_ENABLED BIT(0) #define DSIM_STATE_INITIALIZED BIT(1) #define DSIM_STATE_CMD_LPM BIT(2) @@ -281,12 +283,19 @@ struct exynos_dsi_driver_data { const unsigned int *reg_values; }; +struct exynos_dsim_host_ops { + int (*register_host)(struct exynos_dsi *dsim); + void (*unregister_host)(struct exynos_dsi *dsim); + int (*attach)(struct exynos_dsi *dsim, struct mipi_dsi_device *device); + int (*detach)(struct exynos_dsi *dsim, struct mipi_dsi_device *device); +}; + struct exynos_dsi_plat_data { enum exynos_dsi_type hw_type; + const struct exynos_dsim_host_ops *host_ops; }; struct exynos_dsi { - struct drm_encoder encoder; struct mipi_dsi_host dsi_host; struct drm_bridge bridge; struct drm_bridge *out_bridge; @@ -316,6 +325,12 @@ struct exynos_dsi { const struct exynos_dsi_driver_data *driver_data; const struct exynos_dsi_plat_data *plat_data; + + void *priv; +}; + +struct exynos_dsi_enc { + struct drm_encoder encoder; }; #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host) @@ -1319,10 +1334,11 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id) static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id) { - struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id; + struct exynos_dsi *dsim = (struct exynos_dsi *)dev_id; + struct exynos_dsi_enc *dsi = dsim->priv; struct drm_encoder *encoder = &dsi->encoder; - if (dsi->state & DSIM_STATE_VIDOUT_AVAILABLE) + if (dsim->state & DSIM_STATE_VIDOUT_AVAILABLE) exynos_drm_crtc_te_handler(encoder->crtc); return IRQ_HANDLED; @@ -1595,9 +1611,8 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct exynos_dsi *dsi = host_to_dsi(host); + const struct exynos_dsi_plat_data *pdata = dsi->plat_data; struct device *dev = dsi->dev; - struct drm_encoder *encoder = &dsi->encoder; - struct drm_device *drm = encoder->dev; int ret; dsi->out_bridge = devm_drm_of_dsi_get_bridge(dev, dev->of_node, 1, 0); @@ -1611,35 +1626,15 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, drm_bridge_add(&dsi->bridge); - drm_bridge_attach(encoder, &dsi->bridge, - list_first_entry_or_null(&encoder->bridge_chain, - struct drm_bridge, - chain_node), 0); - - /* - * This is a temporary solution and should be made by more generic way. - * - * If attached panel device is for command mode one, dsi should register - * TE interrupt handler. - */ - if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) { - ret = exynos_dsi_register_te_irq(dsi, &device->dev); - if (ret) + if (pdata->host_ops && pdata->host_ops->attach) { + ret = pdata->host_ops->attach(dsi, device); + if (ret < 0) return ret; } - mutex_lock(&drm->mode_config.mutex); - dsi->lanes = device->lanes; dsi->format = device->format; dsi->mode_flags = device->mode_flags; - exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode = - !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO); - - mutex_unlock(&drm->mode_config.mutex); - - if (drm->mode_config.poll_enabled) - drm_kms_helper_hotplug_event(drm); return 0; } @@ -1648,12 +1643,14 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct exynos_dsi *dsi = host_to_dsi(host); - struct drm_device *drm = dsi->encoder.dev; - - if (drm->mode_config.poll_enabled) - drm_kms_helper_hotplug_event(drm); + const struct exynos_dsi_plat_data *pdata = dsi->plat_data; + int ret; - exynos_dsi_unregister_te_irq(dsi); + if (pdata->host_ops && pdata->host_ops->detach) { + ret = pdata->host_ops->detach(dsi, device); + if (ret < 0) + return ret; + } drm_bridge_remove(&dsi->bridge); @@ -1727,10 +1724,66 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi) return 0; } +static int _exynos_dsi_host_attach(struct exynos_dsi *dsim, + struct mipi_dsi_device *device) +{ + struct exynos_dsi_enc *dsi = dsim->priv; + struct drm_encoder *encoder = &dsi->encoder; + struct drm_device *drm = encoder->dev; + int ret; + + drm_bridge_attach(encoder, &dsim->bridge, + list_first_entry_or_null(&encoder->bridge_chain, + struct drm_bridge, + chain_node), 0); + + /* + * This is a temporary solution and should be made by more generic way. + * + * If attached panel device is for command mode one, dsi should register + * TE interrupt handler. + */ + if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) { + ret = exynos_dsi_register_te_irq(dsim, &device->dev); + if (ret) + return ret; + } + + mutex_lock(&drm->mode_config.mutex); + + dsim->lanes = device->lanes; + dsim->format = device->format; + dsim->mode_flags = device->mode_flags; + exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode = + !(dsim->mode_flags & MIPI_DSI_MODE_VIDEO); + + mutex_unlock(&drm->mode_config.mutex); + + if (drm->mode_config.poll_enabled) + drm_kms_helper_hotplug_event(drm); + + return 0; +} + +static int _exynos_dsi_host_detach(struct exynos_dsi *dsim, + struct mipi_dsi_device *device) +{ + struct exynos_dsi_enc *dsi = dsim->priv; + struct drm_device *drm = dsi->encoder.dev; + + if (drm->mode_config.poll_enabled) + drm_kms_helper_hotplug_event(drm); + + exynos_dsi_unregister_te_irq(dsim); + + return 0; +} + static int exynos_dsi_bind(struct device *dev, struct device *master, void *data) { - struct exynos_dsi *dsi = dev_get_drvdata(dev); + struct exynos_dsi *dsim = dev_get_drvdata(dev); + struct exynos_dsi_enc *dsi = dsim->priv; struct drm_encoder *encoder = &dsi->encoder; struct drm_device *drm_dev = data; int ret; @@ -1741,17 +1794,17 @@ static int exynos_dsi_bind(struct device *dev, struct device *master, if (ret < 0) return ret; - return mipi_dsi_host_register(&dsi->dsi_host); + return mipi_dsi_host_register(&dsim->dsi_host); } static void exynos_dsi_unbind(struct device *dev, struct device *master, void *data) { - struct exynos_dsi *dsi = dev_get_drvdata(dev); + struct exynos_dsi *dsim = dev_get_drvdata(dev); - exynos_dsi_atomic_disable(&dsi->bridge, NULL); + dsim->bridge.funcs->atomic_disable(&dsim->bridge, NULL); - mipi_dsi_host_unregister(&dsi->dsi_host); + mipi_dsi_host_unregister(&dsim->dsi_host); } static const struct component_ops exynos_dsi_component_ops = { @@ -1759,6 +1812,40 @@ static const struct component_ops exynos_dsi_component_ops = { .unbind = exynos_dsi_unbind, }; +static int exynos_dsi_register_host(struct exynos_dsi *dsim) +{ + struct exynos_dsi_enc *dsi; + + dsi = devm_kzalloc(dsim->dev, sizeof(*dsi), GFP_KERNEL); + if (!dsi) + return -ENOMEM; + + dsim->priv = dsi; + dsim->bridge.pre_enable_prev_first = true; + + return component_add(dsim->dev, &exynos_dsi_component_ops); +} + +static void exynos_dsi_unregister_host(struct exynos_dsi *dsim) +{ + component_del(dsim->dev, &exynos_dsi_component_ops); +} + +static int generic_dsim_register_host(struct exynos_dsi *dsim) +{ + return mipi_dsi_host_register(&dsim->dsi_host); +} + +static void generic_dsim_unregister_host(struct exynos_dsi *dsim) +{ + mipi_dsi_host_unregister(&dsim->dsi_host); +} + +static const struct exynos_dsim_host_ops generic_dsim_host_ops = { + .register_host = generic_dsim_register_host, + .unregister_host = generic_dsim_unregister_host, +}; + static const struct drm_bridge_timings dsim_bridge_timings_de_low = { .input_bus_flags = DRM_BUS_FLAG_DE_LOW, }; @@ -1853,7 +1940,9 @@ static int exynos_dsi_probe(struct platform_device *pdev) if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MM) dsi->bridge.timings = &dsim_bridge_timings_de_low; - ret = component_add(dev, &exynos_dsi_component_ops); + if (dsi->plat_data->host_ops && dsi->plat_data->host_ops->register_host) + ret = dsi->plat_data->host_ops->register_host(dsi); + if (ret) goto err_disable_runtime; @@ -1944,24 +2033,36 @@ static const struct dev_pm_ops exynos_dsi_pm_ops = { pm_runtime_force_resume) }; +static const struct exynos_dsim_host_ops exynos_dsi_host_ops = { + .register_host = exynos_dsi_register_host, + .unregister_host = exynos_dsi_unregister_host, + .attach = _exynos_dsi_host_attach, + .detach = _exynos_dsi_host_detach, +}; + static const struct exynos_dsi_plat_data exynos3250_dsi_pdata = { .hw_type = DSIM_TYPE_EXYNOS3250, + .host_ops = &exynos_dsi_host_ops, }; static const struct exynos_dsi_plat_data exynos4210_dsi_pdata = { .hw_type = DSIM_TYPE_EXYNOS4210, + .host_ops = &exynos_dsi_host_ops, }; static const struct exynos_dsi_plat_data exynos5410_dsi_pdata = { .hw_type = DSIM_TYPE_EXYNOS5410, + .host_ops = &exynos_dsi_host_ops, }; static const struct exynos_dsi_plat_data exynos5422_dsi_pdata = { .hw_type = DSIM_TYPE_EXYNOS5422, + .host_ops = &exynos_dsi_host_ops, }; static const struct exynos_dsi_plat_data exynos5433_dsi_pdata = { .hw_type = DSIM_TYPE_EXYNOS5433, + .host_ops = &exynos_dsi_host_ops, }; static const struct of_device_id exynos_dsi_of_match[] = {