From patchwork Thu Jan 26 14:44:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 2685 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-pg1-f197.google.com (mail-pg1-f197.google.com [209.85.215.197]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id 021413F046 for ; Thu, 26 Jan 2023 15:47:12 +0100 (CET) Received: by mail-pg1-f197.google.com with SMTP id 84-20020a630257000000b00477f88d334esf854188pgc.11 for ; Thu, 26 Jan 2023 06:47:11 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1674744430; cv=pass; d=google.com; s=arc-20160816; b=krDPbhvrO0g04jQ0D9pKNM1Rv5ZjuceH+3s9dLAA6AwjMIX0rIGnX8RsvrPRaYh5uh LiqvncgpFoyEmK03XKYxQuMDacFwowCvQPgUJHm+4eCdWwYyC3+HUMWofdQ6BkyKRzzC DTr+6/svY/4+oZmJWoqlqneyueZBv1KWlrB26F6ggs+3FWIYW+Wv63N8lpFK4fy0LRKd 3HXcMOwv5DMNiStI9OETWA9JY+nZr61fyovFDpAy/gJ1hOglnL6PBBgK9PN7xEKO91Fp p9LXQwnQVyYXYXa8769HaTjV1BsRrHsQRUaDiOD3hk3TQHb3+hePEmGcFcL7hkA7yCrI AlbQ== 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=Wu3O+tp+trEbJkKWkFFdDgrlQJS1RHf4YwM+9PCGUaM=; b=mkke1wEpaBDm7mGYP26VZPDSiOV7bINLbqVKhaVNcEuG4Lvy9JT2LxrsR6ctDTU1B/ m/P7Jk1gE3X1axon8MnVdb96Wy5TbSUpuqNkSPVaLVF6vdq4YuWNbSsXCUQukVfQlanl K/ArtJDW0Z6h7WF2SWbvpg1RMEQ26V0+yB+h8bsIa2NmwhvoZKqs6QHMh31aU6AUcYcj cEV4Q1pB27/1Y65Ocu2cRpi1usoLcxva+yibLCF6T4ScgLnSHLCHXGIqopnvv+B74GNK /49xnHOHrcYTWoU9x/irkgMY05SANgABgyFkcw3Vj6mZi366DJrprzfS8SrloFN10kjK 8xvw== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=CUCJGPZq; 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=Wu3O+tp+trEbJkKWkFFdDgrlQJS1RHf4YwM+9PCGUaM=; b=TydGQwavuO5Mlsg/dQEWqUn5jvIvmotTN5f3P7cNcDBa8TxgokPCTTk8NYHY6B3sn2 S49AGHg5eEdCx6viSlRDZHaw+kPqKplXqZWOlkyR3Qtjkt8S3KS0A/Yky/199gjGkgL9 2evvxErXn64dK3SOn9rkDaEEgUpaD51y0O9PQ= 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=Wu3O+tp+trEbJkKWkFFdDgrlQJS1RHf4YwM+9PCGUaM=; b=MmVkm0vvVCWBoIRdvIzB7HyJMuusY2x903p44i35zvrkM1c0lMpTO3Bg2oKMa+igi0 0pEg8NopflXrFFsjA/0hmf2RS3dtvoOyAHEUbBDx8ZErXRX4435QvukNOJ4KEEVUxahK id0QNW2+tHsldgEt0cIIViIaAxTz3Eih0CbmaqFcK67lDIZvmJimN4A1PVOirjkBDexx js33eIydCYemwUi2sXZUvDUPBUwuMbOsF3bu/5MjRafUanD27T4T3xu7Qg69NMc9pddy y59jqAfqT7VJZqcQltI9nZgCOyefhlZ44RJUKs4tNCG3y7MA9AUOtW4ip6MJ3Mhz4Tch DNUw== X-Gm-Message-State: AFqh2ko5ZSQI6mcaf1tbwhrxDOHuuzODG15LPtcQNnEnXeBql4beTPH4 68uJfOHn5Cgtp/7NF5WMhQU4aC8W X-Google-Smtp-Source: AMrXdXupbGo+aVdhS3w6KgCuB3TssDTjD1HHrDMYrBPP9PGYsg4riR7O07ekuESSYcLO8j9IzK4Wjg== X-Received: by 2002:a17:90a:640d:b0:227:2469:27ed with SMTP id g13-20020a17090a640d00b00227246927edmr5139865pjj.140.1674744430719; Thu, 26 Jan 2023 06:47:10 -0800 (PST) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a17:90b:3656:b0:22c:104:b982 with SMTP id nh22-20020a17090b365600b0022c0104b982ls2639831pjb.3.-pod-control-gmail; Thu, 26 Jan 2023 06:47:10 -0800 (PST) X-Received: by 2002:a17:90a:bb8f:b0:226:cdcf:da83 with SMTP id v15-20020a17090abb8f00b00226cdcfda83mr36890843pjr.46.1674744429766; Thu, 26 Jan 2023 06:47:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1674744429; cv=none; d=google.com; s=arc-20160816; b=T68riC4AiYom5H52C0gg1tBY3s/E3ZcSqcGtadbFlFVkfRvok/N4AT7uAX9B8B+skD 4UMIEgyNfaPGEBZ/g8Rcvd9rSl3Clju914EgSbbX7TwVKvzFxGlBCXAP/5RRacQ1L7kM WCfzXXktjOPiNGqEgRPHuL/5Fy8B9fULyd5ioY/LK1nZLnGq0h5WvzLBxKEmsNFWvdSw iQK3c1VTcEjvWoMof5swPRBG8OokvtZTpQvSYPqjBsBouwQqdqigAEzajKz8fQ3NqzQr SbcI+RNpZS1UzBgQ+XesgegNGbCE39RF+vHB6n4v0bNs/7+4lcJbmL7svIFRhAS65KHo I+Cg== 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=yo9iZG7thbeh/Q27IofLDMHgJmskqvn2YbJQaVoxMqQ=; b=dDEaf0s6gcYNEs5VVCVLEpClHuQkK0CGm4z7z2gT/r6+9RNLS0tYhal9KOKc97z2dN IUhJI6t2vzu1xNjrK/vj91+awFvi43wVh2gVY1M59y+Hsy/ec9QW87MzmXKuivM1Nhip PCrz3o3ruyBf788tlQqJoNr+WB53wgspoXQnynNJ7n9IC4NoJgKotAimY4Q7NK9ZAnG1 nQwrd5ps3jK0PBhfBm1Gn0humFfkdi+Wwsg1ha+QiHY1OE28NciDOcONjb031PPoNW8M CRN8dfRb44sJRMEY1HZHUnCPrQa/tazthSEOB2wq7lCtdBQxEsBJUQ9YA5o51pa2cl3H kH1Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=CUCJGPZq; 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 r30-20020a17090a43a100b0022659d7a878sor714880pjg.17.2023.01.26.06.47.09 for (Google Transport Security); Thu, 26 Jan 2023 06:47:09 -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:90b:4c43:b0:22b:b392:96be with SMTP id np3-20020a17090b4c4300b0022bb39296bemr23651311pjb.6.1674744429421; Thu, 26 Jan 2023 06:47:09 -0800 (PST) Received: from localhost.localdomain ([2405:201:c00a:a238:3cb1:2156:ef87:8af5]) by smtp.gmail.com with ESMTPSA id d197-20020a6336ce000000b0042988a04bfdsm823660pga.9.2023.01.26.06.46.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Jan 2023 06:47:08 -0800 (PST) From: Jagan Teki To: Andrzej Hajda , Inki Dae , Marek Szyprowski , Seung-Woo Kim , Kyungmin Park , Frieder Schrempf , Tim Harvey , Adam Ford , Robert Foss , 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 v12 12/18] drm: exynos: dsi: Consolidate component and bridge Date: Thu, 26 Jan 2023 20:14:21 +0530 Message-Id: <20230126144427.607098-13-jagan@amarulasolutions.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230126144427.607098-1-jagan@amarulasolutions.com> References: <20230126144427.607098-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=CUCJGPZq; 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 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 9459c138d0e0..488fae218205 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; int ret; dsi->out_bridge = devm_drm_of_dsi_get_bridge(dev, dev->of_node, 1, 0); @@ -1605,35 +1618,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; } @@ -1642,12 +1635,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); @@ -1721,11 +1716,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; @@ -1743,7 +1794,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); } @@ -1753,6 +1804,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, }; @@ -1847,7 +1932,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; @@ -1938,24 +2025,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[] = {