From patchwork Fri Mar 3 14:51:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 2773 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id 09F2C44AA6 for ; Fri, 3 Mar 2023 15:53:10 +0100 (CET) Received: by mail-pf1-f198.google.com with SMTP id y35-20020a056a00182300b005e8e2c6afe2sf1469366pfa.12 for ; Fri, 03 Mar 2023 06:53:09 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1677855188; cv=pass; d=google.com; s=arc-20160816; b=uy4G7G6GQNDBwz1YrK13i0hMnt44/3tg+tphUJqhofIOrg3h0d/qn2SDmBHcoztiOt Zp6sVKNFF5WcV4ndCLiutjWSj4Ph6CNKs+B/51FVkynSTkn52y89R8Xwgi2HG3fpwKOm zEjgXeZliB6kwpYOJSwDu1FMwZvQBDubCwnLRgfilmNhB2rlntFg7sDIY+tBFYslT2Xp EZk8+8hq1zIuvxgr4RcH5q92v3TIB4A1GmwFaGMViLl3s3k+WwmD4ueAO/Ra763F7FBK SkmlFy7TR/CTVDVHOfvP0ppCu77vp+b/zN7Ig0reCob1Ox8rZtJ1K17FMSHnOKbNQCIs zfNw== 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=PgL+yJXjuBKhsa38TUPJ5D6UxS3ecNDACpeknNu6RQs=; b=RjYKHvTaDZpE7we2PeIF8DtW80pOWiYLl9KewCSkCdzs7LOGcaoClbaYAKAU7I///j 535BlV/zrlxU5bX2wQeYpxqZVXluq1XEstsBQ/2apokJt2kGk5/sJKl3e06WZE7flRnM KO4ksQN6SWNXYOjNdxDN8pJNg1/oODfFdxJJ6h3jy+b0pLZ10dYgB0U1knnrSw278Ne5 95xx2vafUt9033Awzu43ikrJxAqdi19Z1DV2P/vDeVTekRumclitdgngkEqUGIZsRu4O 42frbajLZPKBmwom5qHU2itQtJMGTefXmChURLm9UlWjv6Nf9c1S/uviN8xCW1/fpMkE 3VWA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=UXnLPNPA; 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; t=1677855188; 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=PgL+yJXjuBKhsa38TUPJ5D6UxS3ecNDACpeknNu6RQs=; b=hkLSOK5hylI3snxSYdWB/0Q6Z3YT4xlieeoza4w1zrux37pYMspOhBy/4YpRgkzKaV h+4KwSqmmEdd683jN327ble/7Cm3q7LekkuRr+HD8ocVoqR42bnzNyH1glWDi5sYsz7b bx8f3gQ+pNC/e/9BS8X2Kg9kd2h12O8L9f62E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677855188; 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=PgL+yJXjuBKhsa38TUPJ5D6UxS3ecNDACpeknNu6RQs=; b=10bNIUi7a7uVG+KNBz4nP42W/9LvB/sllatn4RriKHVRuz1fy1Pn+/+Zib2lF3+0Vo TNsGa/L7T9r5A8csP3xs1nQR3C2wCa0cnjNgF5TkB56z0+NijbZvn9yJDC/46QDD8SFx mpeyhtjIF862PgrpjwXaL2r1ztjjwxm3hV6G8JPP7hWh0aETsYjl3+4QHpfOiXt2rbXX gFQF5WhRXqXVsndIXUqrJ7nc3n5jDPer9vTyuPgLIKgrfcSICt5AY002zBE0TgSRmDGL 1O3zDgOhl4iVhOgVvSWjPgGhapyhC3+zqUzjHd7z6LEv46MugvYKZ2zKaVz7Gal8gqYT evyw== X-Gm-Message-State: AO0yUKVYhj93kV2ww80t4X3NjYPv8A1L9fUyrFuBGQBrdUVJZP7zKYtw zK56MYW4uI3niA/nwdaBL4cw+Vru X-Google-Smtp-Source: AK7set+W8tGJL2kPF4YvtJKKNJc0xH2d2BZXXI1Td0lsOk8ZUimkICb4QLTRfMGvha+/8ECcYvdG6Q== X-Received: by 2002:a17:903:428a:b0:19e:651b:9429 with SMTP id ju10-20020a170903428a00b0019e651b9429mr797583plb.3.1677855188790; Fri, 03 Mar 2023 06:53:08 -0800 (PST) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a17:902:e742:b0:19c:2b1c:4d75 with SMTP id p2-20020a170902e74200b0019c2b1c4d75ls924283plf.0.-pod-prod-gmail; Fri, 03 Mar 2023 06:53:08 -0800 (PST) X-Received: by 2002:a17:902:d381:b0:19a:b033:2bb1 with SMTP id e1-20020a170902d38100b0019ab0332bb1mr1951567pld.44.1677855187738; Fri, 03 Mar 2023 06:53:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1677855187; cv=none; d=google.com; s=arc-20160816; b=GNX78yxNPINVshJWGXJ84pHfxMUogR3WZPtJmZ4fbFPJGc6BroNKI+rdcm2/Hd794P rHvKw3GO7+w9CSl+4nhzf1HExUiQQ/SFTnSiN0wtxYNUYUcWX4SvwS6cXdQjSqiINbyj e2BimB3wfqGTSyxKXdqXdJJfdFd4NGOyROY+Esbvwca3fgNMvE/Z4ZrsFx2BzttubeRN uJUZ+1Pfiz/luH6HC1ISoFdug9IbqxPKHBrvCFhHHNqhs3BKytHBI2an0udFFXG0nrPo qewD4TFhMAIWm6LOiNn2m8nwXnp/w9iKf1aL9kA7ALYHmtRTbpOPVv3xSt3eJGeAigPC xv2Q== 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=KpLWAK14peIKe8R0E4tzY6GUsUPXTajM4OP5jILu6lM=; b=JX+cNvyR1AiegSGK99XKUSSqSNPNz/+i90+/uTh9RDC7n5sL+zaKPIvxhrXQfbW1Ld sDbxI5wQnYt8VwTdBUdnOTRXSRQgD36BHlSEn7Q+c/7MElyo0j80FnBQcgpsxe45SiDt AnQ5VScDFnVpbbhVjIPwc4lR075ij7NaX4FuCJCUBhNy6LJAUEdfc46PHH5WWoNRXXCu QaLzG1Hwp/WbDlIARB+Y2lG7ww090zE0IcWhzlePFbW4YJXZ385Am3RxdiRSPGvhaN3P ycGsWcjaXxiqDN3lDrFp7+Kerzt+OJW9g70GIm8wtZXevgmVoP1HRpnIuy5fk0RNBSpE R/RA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=UXnLPNPA; 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 f17-20020a170902ab9100b0019bb4f93fa8sor1088706plr.116.2023.03.03.06.53.07 for (Google Transport Security); Fri, 03 Mar 2023 06:53:07 -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:a05:6a21:32a2:b0:cb:8d74:112e with SMTP id yt34-20020a056a2132a200b000cb8d74112emr2340673pzb.45.1677855187397; Fri, 03 Mar 2023 06:53:07 -0800 (PST) Received: from localhost.localdomain ([183.83.137.89]) by smtp.gmail.com with ESMTPSA id z4-20020a63e544000000b00502fd70b0bdsm1660856pgj.52.2023.03.03.06.53.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Mar 2023 06:53:06 -0800 (PST) From: Jagan Teki To: Andrzej Hajda , Inki Dae , Marek Szyprowski , Neil Armstrong , Marek Vasut , Maxime Ripard Cc: Seung-Woo Kim , Kyungmin Park , Frieder Schrempf , Tim Harvey , Adam Ford , Matteo Lisi , dri-devel@lists.freedesktop.org, linux-samsung-soc@vger.kernel.org, linux-amarula , Jagan Teki Subject: [PATCH v15 10/16] drm: exynos: dsi: Consolidate component and bridge Date: Fri, 3 Mar 2023 20:21:32 +0530 Message-Id: <20230303145138.29233-11-jagan@amarulasolutions.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230303145138.29233-1-jagan@amarulasolutions.com> References: <20230303145138.29233-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=UXnLPNPA; 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. Reviewed-by: Marek Vasut Signed-off-by: Marek Szyprowski Signed-off-by: Jagan Teki --- Changes for v15: - remove leading underscores in function names Changes for v13: - none Changes for v12: - fix unneeded decleration - collect RB from Marek 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 | 169 +++++++++++++++++++----- 1 file changed, 134 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index c8829f33f36e..afe2d293c785 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -283,10 +283,10 @@ struct exynos_dsi_driver_data { 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 +316,19 @@ struct exynos_dsi { const struct exynos_dsi_driver_data *driver_data; const struct exynos_dsi_plat_data *plat_data; + + void *priv; +}; + +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_enc { + struct drm_encoder encoder; }; #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host) @@ -1320,7 +1333,8 @@ 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 drm_encoder *encoder = &dsi->encoder; + struct exynos_dsi_enc *dsi_enc = dsi->priv; + struct drm_encoder *encoder = &dsi_enc->encoder; if (dsi->state & DSIM_STATE_VIDOUT_AVAILABLE) exynos_drm_crtc_te_handler(encoder->crtc); @@ -1589,9 +1603,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; struct device_node *np = dev->of_node; struct device_node *remote; struct drm_panel *panel; @@ -1648,35 +1661,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; } @@ -1685,14 +1678,16 @@ 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; + const struct exynos_dsi_plat_data *pdata = dsi->plat_data; + int ret; dsi->out_bridge = NULL; - if (drm->mode_config.poll_enabled) - drm_kms_helper_hotplug_event(drm); - - 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); @@ -1766,11 +1761,67 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi) return 0; } +static int exynos_dsim_host_attach(struct exynos_dsi *dsim, + struct mipi_dsi_device *device) +{ + struct exynos_dsi_enc *dsi_enc = dsim->priv; + struct drm_encoder *encoder = &dsi_enc->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_dsim_host_detach(struct exynos_dsi *dsim, + struct mipi_dsi_device *device) +{ + struct exynos_dsi_enc *dsi_enc = dsim->priv; + struct drm_device *drm = dsi_enc->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 drm_encoder *encoder = &dsi->encoder; + struct exynos_dsi_enc *dsi_enc = dsi->priv; + struct drm_encoder *encoder = &dsi_enc->encoder; struct drm_device *drm_dev = data; int ret; @@ -1788,7 +1839,7 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master, { struct exynos_dsi *dsi = dev_get_drvdata(dev); - exynos_dsi_atomic_disable(&dsi->bridge, NULL); + dsi->bridge.funcs->atomic_disable(&dsi->bridge, NULL); mipi_dsi_host_unregister(&dsi->dsi_host); } @@ -1798,6 +1849,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_enc; + + dsi_enc = devm_kzalloc(dsim->dev, sizeof(*dsi_enc), GFP_KERNEL); + if (!dsi_enc) + return -ENOMEM; + + dsim->priv = dsi_enc; + 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, }; @@ -1892,7 +1977,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; @@ -1983,24 +2070,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_dsim_host_attach, + .detach = exynos_dsim_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[] = {