From patchwork Mon Feb 27 11:39:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 2752 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-pl1-f200.google.com (mail-pl1-f200.google.com [209.85.214.200]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id 8B6883F9C2 for ; Mon, 27 Feb 2023 12:41:02 +0100 (CET) Received: by mail-pl1-f200.google.com with SMTP id s8-20020a170902b18800b0019c92f56a8asf3510167plr.22 for ; Mon, 27 Feb 2023 03:41:02 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1677498061; cv=pass; d=google.com; s=arc-20160816; b=v7uiKMj3mpcpqz+4iKmlUubg3EcPgnTs1XrFzWd61SodG5FR6GBdwfylO1shy1IjuE xLVpM4ISEcka/wPu0cY1oPptNOiKOz8e/vxF6Y4e7YALo1CwviQ099aUu+bWV/xcTpzd dde+irP9ir9/8JBG1gjN+RJ69W8yc8P8zx9eXKUmRKkS6KMSKWNXnaHrBqe4Dw0T3dSu MpHSh+Waetd8Zh4YcXqT1Y8lPFuWv6WylKePq3RiIAFZqIzz3AMGfIz+o93Oqqsy1BMz 8betIVGnKOQ+r30DSoD/WJHVHGFTn+E4xYKUAnBt4Tb4D2W35lg6jcpjKskawLX8b1Te 8Pdw== 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=SegeWF6S9BunpXDFhbO6R7dBqxqsGRYr3cXoZtW0Fho=; b=LdaEKqeT13QzI9mYe6uSPlBAUP7H68r5vUYcUGjXcb4NsxMwUuMKYjyRYIpaDdJTJm IVgOfmmH6Rw/kk7vcDYqVkSnbJNZ5jH1ilH02UC0uNPn2j4yrXgSdcrz+DVoDt0xp8sM jQ4k9zA5kHLRuwiDVHe197vgjT8hwDpbopFeO0aHhwrN3FVZkPl4ltwhlqDwzdohiuyu ghShY1Pg7qHC31pe2L0P2zjxjYDPf7EmDdwmSDH7OmYJA8G0+naHV7GwrSfZINE4+51U i/IVcWjuVY2Za1dyUeiSNx1WvIxyOqpoeuxKaslazvQ+tqT4B7BbXalQELB08wf41dcn JqBA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=Xjfy4NB+; 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=SegeWF6S9BunpXDFhbO6R7dBqxqsGRYr3cXoZtW0Fho=; b=WcHOWIMz8FX1VfbQbmLP8oQaaOxy8T3J3hjB0aKCjzXb3ckJkV3TCrrR+qOy8+5abW pCrvxumsWrVZuhDFKGqdqWpBkhI8eKJRfuJ9XGKZyYSkS0UmlsSDyiv8bE+LPIkzVvAg echg9juzHi9R+hVva6qVtY1BwnO+IQ34Rl98o= 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=SegeWF6S9BunpXDFhbO6R7dBqxqsGRYr3cXoZtW0Fho=; b=Et+IvV3FbbAzTBychb+9IkjoaN5LKbr4T3XvyRD/HjKGSnwBGUp4ljUg/Xol9IyP21 DTKdAhimRr4dGlc/h4hVkuYB6T+gnPDMhERth0A37SamxRF+CG3/bjgECVkp60yy9+vI NSplFr330IjidUMrpGR4CP5ut+qwYNjVJxsnJEvZrVfBgEEUZZ42yN35v6qh/EaE9SoT E+3rAxp3HHJzeAAAjryxVjcKnBYc77hTwSna0EvCUa1A2mgVsEx5rdytyQ4kOI1xd/I+ YNDTy0bT/1+tAi04gZtDJVf6iV8v+GsCTKe8UIvabdDb4iayMV+7WhZKcZBkAmTgyz+M TGXg== X-Gm-Message-State: AO0yUKXj2uuswjNqEzT0BSobdGqmLyoaMaEX2HHa0TpYrgdV1wEn/hOA NC4hd1kj5e2ibX5pnRaPkX5DZE16 X-Google-Smtp-Source: AK7set93563mSe3ahpxOZqRJ8aQf18CXsLaa9SJYQpA09sq6lBP5iQfHnfDXVTu9Bz6/3KbLVsjoUQ== X-Received: by 2002:a17:902:f782:b0:19c:b7da:d2ef with SMTP id q2-20020a170902f78200b0019cb7dad2efmr4731431pln.12.1677498061306; Mon, 27 Feb 2023 03:41:01 -0800 (PST) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a17:902:ef4c:b0:19c:a86d:b340 with SMTP id e12-20020a170902ef4c00b0019ca86db340ls10459819plx.9.-pod-prod-gmail; Mon, 27 Feb 2023 03:41:00 -0800 (PST) X-Received: by 2002:a17:902:e5cc:b0:19a:b754:4053 with SMTP id u12-20020a170902e5cc00b0019ab7544053mr30138285plf.26.1677498060398; Mon, 27 Feb 2023 03:41:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1677498060; cv=none; d=google.com; s=arc-20160816; b=iPnsRWqBhWDWbpWoV2o/GwC9Qgt+yhfN5IuYTSN9cz4REfcksdHwnwLORdlQUDsBAh IJXCxf+yAiagiC8Zqr3/SeyXOKtgvYFz2VaHzvKggLaAPECEe4epox25rbeuJspewBSw Jks9OG67kMfm2zykxRo9lFUQfXSzY2oMeMmwOtfaxzK5GUpaZu9az5ezvDOZcTx8n/HW s4ib1docR0V/ym+11NkfPdKI0UOlDU9i6KurmaML8tqtpGSwvFXkl987ESgssDXULRte y6SJRoXuEqp1i+mIKdBt/A2ZN86+AHyGERmc6peggqcX2ZZxNK2K38cS+ifNI0rcDGaR yB1g== 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=gqI591/7pV38dOGca+aLBhhdwvSSpofrW8ilT0Vq6Zg=; b=FlxhYbfmHUe2WBcM+yqsbZoXDCSxP1gAls73kRbZ7r4uYbAOtvQV+mfDQLCA0z204G WFm1lSVCuxFhvTwCRO1/JZ5qU/asTWgbWhMcg7wgnmU0derdhXFH13K20wkTtwYmrY9l TbmQpH8+mWOQi5AJ/MYAAv3Ddm7UVLOz7hKVIvMMU/FfXICKkywlGYEzSPrFCfr+jXYl V2EBppcdeAtwRw3VTLuUUDeOWaHfPbLj54LiCy2EN3QrSg5DEZmqK14tbYg1BVW+16JH 91mI2MZk8x5TXW82/e/SaYJXAcItiP+DQt+G+3tsa1fkJW8ZzjVAS+L7n52k9eDg5uVN SJbQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=Xjfy4NB+; 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 e14-20020a170902ed8e00b0019ac86db5a9sor2220077plj.58.2023.02.27.03.41.00 for (Google Transport Security); Mon, 27 Feb 2023 03:41:00 -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:903:6c7:b0:19c:a395:4acf with SMTP id kj7-20020a17090306c700b0019ca3954acfmr17002454plb.40.1677498060056; Mon, 27 Feb 2023 03:41:00 -0800 (PST) Received: from localhost.localdomain ([94.140.8.120]) by smtp.gmail.com with ESMTPSA id k10-20020a170902ba8a00b0019c919bccf8sm4395277pls.86.2023.02.27.03.40.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Feb 2023 03:40:59 -0800 (PST) From: Jagan Teki To: Andrzej Hajda , Inki Dae , Marek Szyprowski , Seung-Woo Kim , Kyungmin Park , Frieder Schrempf , Tim Harvey , Adam Ford , Laurent Pinchart , 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: [PATCH v13 12/18] drm: exynos: dsi: Consolidate component and bridge Date: Mon, 27 Feb 2023 17:09:19 +0530 Message-Id: <20230227113925.875425-13-jagan@amarulasolutions.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230227113925.875425-1-jagan@amarulasolutions.com> References: <20230227113925.875425-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=Xjfy4NB+; 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 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 aea56b6fbf17..de8604450fb9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -284,10 +284,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; @@ -317,6 +317,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) @@ -1321,7 +1334,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); @@ -1590,9 +1604,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 drm_bridge *bridge; struct drm_panel *panel; int ret; @@ -1617,35 +1630,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; } @@ -1654,12 +1647,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); @@ -1733,11 +1728,67 @@ 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_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_dsi_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; @@ -1755,7 +1806,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); } @@ -1765,6 +1816,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, }; @@ -1859,7 +1944,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; @@ -1950,24 +2037,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[] = {