From patchwork Wed Dec 14 12:59:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 2563 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 9FECF3F0FB for ; Wed, 14 Dec 2022 14:01:01 +0100 (CET) Received: by mail-pg1-f197.google.com with SMTP id e37-20020a635025000000b00476bfca5d31sf1782001pgb.21 for ; Wed, 14 Dec 2022 05:01:01 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1671022860; cv=pass; d=google.com; s=arc-20160816; b=tThdXgx6mO3NI89ItESSaIiZWcle93yI77np+iTcTTcGrCj86HZnLFA6XhC9KqeUX5 rzwObljTa1jejrm7JyBmY/dktSrj5hhfSQVIeY3CbLMZcLXT8ClYZEO5t/RcG22IO7rC rUohFEXQRM131kV0u5QmghgdjWXl5sl78lbHPTFCOe9EPeLeZJkYLxzb94AhTK93mlCc LzbP9KUxt73AkvywP8QV0bwqwZ375e3VThiONEqmLMVnMOxmAOQ0y7sAR+Cp17pUE0ME ZNegsv5gAQFlNPAzj6qPDYMX0hyP2sWeO4WHLiRUWsD05zRP7N16y1rrao8d6o3vAXx0 hoyg== 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=JSwFOW3yvrUKNzw4EgibyOnIm0XXjYDsa0YaE7JkqZg=; b=Ij7j7ZTefqcSiebsF8tefL68Q4krsVYk4/cjU4ZqFIaWtd05sW1VjPZeId1+AXze4N pDlaPAxDQr4m99+kncGxy9Eaqxr/uyDOwvYbW83qpM/4fLIvb4Tq41zbQi0CIEk8jgRs U9cpkWAldCZNFjrw1TOuZ0Dv2QAxGwFWZX/BeThgrbiorN7ReBjGl18mClQD8p27cxsC 1DwKIy86J4b9D54ft4e9n9lmdUqI2xd+JRYwj0hqKxIIiH4sTmDlAGpmmXpHG0Et7YRY whVXFLy/cQCZY3iQHuVHhOybRNSahrAEmFN2MeemkEA0jycr8uQkROC76e5v3oE+CWzI 8N7A== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=Jq3ptjES; 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=JSwFOW3yvrUKNzw4EgibyOnIm0XXjYDsa0YaE7JkqZg=; b=Grl5S+d7x+3FlMwpQPBbXTOkHViHR04PlpZD6EfFhxYBCvNFIpA68k5fMlv/yqp6n2 QyD7NsnZOESWQSbSopuuTFjg4au2OPLa6fNGKidw9S+ZHEBtptAQqRP1OMN7A+TpAY14 MTQFC1ohVA712mF4N9KkBgmJk94ZqXVDCEeaY= 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=JSwFOW3yvrUKNzw4EgibyOnIm0XXjYDsa0YaE7JkqZg=; b=WQPSzg6GNZM6a+rUed0u99bYVRH7Mk16gVk+/U45nkiBYFG1loDUb4PbhlKcvz3xnc si5IGN7ZkK/GabSun65xu4jSOsHjqq+5gEyjBpB8JrGJfnHjAAlv+woQJt3V1jfi2fP2 VUbDhCwTB5aYWp42UxIjVi+vd+Oqj9/ekHTPwJ2thKHcmDHyWWYrHwYhqLG06QuNdeXx 2iYEgE8BWxDwnECRquk34elNSPwGl71ED6YZ889Vn5gNqhAQ9Okxi10pR9LkOoJP6Srb DPZ4M7iKpnQWDNoMkKbNUH0H19XNXrfzfeGpJYLGaD3RZclpapzCMVvEAqu0QqcAWIiC C3tw== X-Gm-Message-State: ANoB5pnWp6OkJ/TUqklLw7GAyNT2HyTshp+8XyTBogK5f+BndQFgI9gY eSXCdmu46MQuD313cCpTo0WyKPr1 X-Google-Smtp-Source: AA0mqf4PsrvcGOTTiX1YkxSXkiU5uLhTPxyPIhRuHXP8TrgZYxHg0L4gxIKEH8nnE7RP5ukfENSauQ== X-Received: by 2002:a17:903:22ca:b0:189:cca6:3971 with SMTP id y10-20020a17090322ca00b00189cca63971mr23193772plg.89.1671022860317; Wed, 14 Dec 2022 05:01:00 -0800 (PST) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a17:90a:2848:b0:219:2eb:a5dc with SMTP id p8-20020a17090a284800b0021902eba5dcls26261028pjf.0.-pod-canary-gmail; Wed, 14 Dec 2022 05:00:59 -0800 (PST) X-Received: by 2002:a17:902:c14a:b0:189:6d2f:4bc7 with SMTP id 10-20020a170902c14a00b001896d2f4bc7mr24757409plj.37.1671022859208; Wed, 14 Dec 2022 05:00:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1671022859; cv=none; d=google.com; s=arc-20160816; b=aPfu0F+qhrz1rD7i9oo3zAfLPjnjKukjwvNFiISlCytVIr9OIJCnC+8F+kA5CJFXoG 5UpoXt42GH4twwIC/VXq3mvrJIVNXQLcLla9XrxrZKaHbzlwmsuJpOafHhvHjmgRv2F/ 89Ig7ILXqR8cThmwO2yOdpHOZpPkSTLARBkw+VktzMApfqFPQrwEEOO2sk8w5wt+MRU7 NQq3+yvzOBBJZblIyaxufg0RNNkpKdVA8QelbkvSXf8RBXgqu51a6OO6sgnbiQDrjwEW BnfGitDdrM+ptKqywv6N9A+8HDtMX6gfDQJ5lSoBK+G8t4H9F6g+pcCBzExPWa5rbS2A BOng== 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=ykkoMPBFg25R5qn07gjEHjZhs49sxOTu6Me4c71olVs=; b=w8yUYfRyrmY7zXYFX6yz1ug8FqgV3QQs26Ejh+CS2U/sXxO4dtHAdGDoFybJkfAlTj IIBaeQiaD7NiaC0y3+pNQZIGhQG8XvL3sESHOrnSxz3Py9CG9/DdHnIEN/kYzO2a+rCu Lf2tHLStj30rfJlm6nnJCImyagVIdO5WdGtdTLrqo6QULnr7ay7pFC4SyQmzpTD5YBTo W8nrYnC61nlJL6TuCqJfz3JpsGkonJbo8275GoL/NYGgGRQoDv/aljoV6UGv/T7ssE4Z vf0IOeURn95BMCc7hEmA/4mnM0H2cxofAl5+DU8EqXPrRZ00gsLGIf5MEQOf+RRh2kGl OiaQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=Jq3ptjES; 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 z14-20020a170903018e00b00189bf5e03a6sor1487653plg.77.2022.12.14.05.00.59 for (Google Transport Security); Wed, 14 Dec 2022 05:00:59 -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:7b83:b0:189:b0e7:c5f0 with SMTP id w3-20020a1709027b8300b00189b0e7c5f0mr22677431pll.14.1671022858705; Wed, 14 Dec 2022 05:00:58 -0800 (PST) Received: from localhost.localdomain ([2405:201:c00a:a809:5e03:faf:846e:352d]) by smtp.gmail.com with ESMTPSA id ix17-20020a170902f81100b001895f7c8a71sm1838651plb.97.2022.12.14.05.00.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Dec 2022 05:00:58 -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: [PATCH v10 12/18] drm: exynos: dsi: Consolidate component and bridge Date: Wed, 14 Dec 2022 18:29:01 +0530 Message-Id: <20221214125907.376148-13-jagan@amarulasolutions.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221214125907.376148-1-jagan@amarulasolutions.com> References: <20221214125907.376148-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=Jq3ptjES; 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 --- 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 bb3d6a7fa84e..819131a36b96 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) @@ -282,12 +284,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; @@ -317,6 +326,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) @@ -1320,10 +1335,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; @@ -1597,9 +1613,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); @@ -1613,35 +1628,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; } @@ -1650,12 +1645,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); @@ -1729,10 +1726,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; @@ -1743,17 +1796,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 = { @@ -1761,6 +1814,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, }; @@ -1855,7 +1942,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; @@ -1946,24 +2035,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[] = {