From nobody Wed Feb 11 05:41:41 2026 Received: from out-187.mta0.migadu.com (out-187.mta0.migadu.com [91.218.175.187]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A5BB04D5AA for ; Sun, 19 May 2024 16:54:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.187 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137660; cv=none; b=do8qdkmQNBxH8CsAAMGNWQ7uHSwRycpfq6/kf7HL9hgtEmNRXRBKS9FqrGS5lLUTck/iuGuUGFLGi2XGvI52cJyoNf4pbeaFptcUHwUwVPG8+Tjex6nFBPTmiIAsr/AGlL1z6sXOHDPdIsiB/gLchDwfdbCoksJH5DpD6Pd6AC8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137660; c=relaxed/simple; bh=KAZWXjSYnci4BObhDy2HkSBCKA1IgWkN/tPI5FVl+No=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cUMjF1/Pa07Lj1sm0FZQ8mw7P+GIa2tHFczTHMvLytFzonnHp/nJaz3jt5qmP+tvgohSR+tMMLV01skkdpFCIFdX0pBYk9OO9PT1MDgrxvKV72YIxlfVCRjPPFyFRkVW7BPUOW1qPqCwOmWsBD4J7h+HqPRe/Ilv1OMoXrcD1EI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=mg4FV1ap; arc=none smtp.client-ip=91.218.175.187 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="mg4FV1ap" X-Envelope-To: l.stach@pengutronix.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1716137656; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7ExoUU6tg2//RjoBtky2xb+vLzbkleyPn1j+Bsv6Tuk=; b=mg4FV1apy8t47+hpavdd5Q1kazzq+igCK6S05akf/Cm4t66MAFlaTLF8ShzwLgJQQJ0m5V gdEBmfhafgCBset/I+ASIghJVZfD0POgwx5f3iR7SQ8zUhDSMjiDozb85Xy/WRFDLECTZW LWvjnlPEJ0LrGWhhNBRccgRRK24hBoY= X-Envelope-To: linux+etnaviv@armlinux.org.uk X-Envelope-To: christian.gmeiner@gmail.com X-Envelope-To: linux-kernel@vger.kernel.org X-Envelope-To: etnaviv@lists.freedesktop.org X-Envelope-To: dri-devel@lists.freedesktop.org X-Envelope-To: sui.jingfeng@linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Sui Jingfeng To: Lucas Stach Cc: Russell King , Christian Gmeiner , linux-kernel@vger.kernel.org, etnaviv@lists.freedesktop.org, dri-devel@lists.freedesktop.org, Sui Jingfeng Subject: [etnaviv-next v14 1/8] drm/etnaviv: Add a dedicated helper function to get various clocks Date: Mon, 20 May 2024 00:53:14 +0800 Message-Id: <20240519165321.2123356-2-sui.jingfeng@linux.dev> In-Reply-To: <20240519165321.2123356-1-sui.jingfeng@linux.dev> References: <20240519165321.2123356-1-sui.jingfeng@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Because the current implementation is DT-based, this only works when the host platform has the DT support. The problem is that some host platforms does not provide DT-based clocks drivers, as a result, the driver rage quit. PLL hardwares are typically provided by the host platform, which is part of the entire clock tree. The PLL hardware provide clock pulse to the GPU core, but it's not belong to the GPU corei itself. PLL registers can be manipulated directly by the device driver. Hence, it may need dedicated clock driver. Add a the etnaviv_gpu_clk_get() function to group similar code blocks, which make it easier to call this function on the platform where it works. Signed-off-by: Sui Jingfeng Tested-by: Christian Gmeiner --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 53 ++++++++++++++++----------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnavi= v/etnaviv_gpu.c index d84d73c197fc..e0c36f564fa6 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1605,6 +1605,35 @@ static irqreturn_t irq_handler(int irq, void *data) return ret; } =20 +static int etnaviv_gpu_clk_get(struct etnaviv_gpu *gpu) +{ + struct device *dev =3D gpu->dev; + + gpu->clk_reg =3D devm_clk_get_optional(dev, "reg"); + DBG("clk_reg: %p", gpu->clk_reg); + if (IS_ERR(gpu->clk_reg)) + return PTR_ERR(gpu->clk_reg); + + gpu->clk_bus =3D devm_clk_get_optional(dev, "bus"); + DBG("clk_bus: %p", gpu->clk_bus); + if (IS_ERR(gpu->clk_bus)) + return PTR_ERR(gpu->clk_bus); + + gpu->clk_core =3D devm_clk_get(dev, "core"); + DBG("clk_core: %p", gpu->clk_core); + if (IS_ERR(gpu->clk_core)) + return PTR_ERR(gpu->clk_core); + gpu->base_rate_core =3D clk_get_rate(gpu->clk_core); + + gpu->clk_shader =3D devm_clk_get_optional(dev, "shader"); + DBG("clk_shader: %p", gpu->clk_shader); + if (IS_ERR(gpu->clk_shader)) + return PTR_ERR(gpu->clk_shader); + gpu->base_rate_shader =3D clk_get_rate(gpu->clk_shader); + + return 0; +} + static int etnaviv_gpu_clk_enable(struct etnaviv_gpu *gpu) { int ret; @@ -1880,27 +1909,9 @@ static int etnaviv_gpu_platform_probe(struct platfor= m_device *pdev) } =20 /* Get Clocks: */ - gpu->clk_reg =3D devm_clk_get_optional(&pdev->dev, "reg"); - DBG("clk_reg: %p", gpu->clk_reg); - if (IS_ERR(gpu->clk_reg)) - return PTR_ERR(gpu->clk_reg); - - gpu->clk_bus =3D devm_clk_get_optional(&pdev->dev, "bus"); - DBG("clk_bus: %p", gpu->clk_bus); - if (IS_ERR(gpu->clk_bus)) - return PTR_ERR(gpu->clk_bus); - - gpu->clk_core =3D devm_clk_get(&pdev->dev, "core"); - DBG("clk_core: %p", gpu->clk_core); - if (IS_ERR(gpu->clk_core)) - return PTR_ERR(gpu->clk_core); - gpu->base_rate_core =3D clk_get_rate(gpu->clk_core); - - gpu->clk_shader =3D devm_clk_get_optional(&pdev->dev, "shader"); - DBG("clk_shader: %p", gpu->clk_shader); - if (IS_ERR(gpu->clk_shader)) - return PTR_ERR(gpu->clk_shader); - gpu->base_rate_shader =3D clk_get_rate(gpu->clk_shader); + err =3D etnaviv_gpu_clk_get(gpu); + if (err) + return err; =20 /* TODO: figure out max mapped size */ dev_set_drvdata(dev, gpu); --=20 2.34.1 From nobody Wed Feb 11 05:41:41 2026 Received: from out-178.mta0.migadu.com (out-178.mta0.migadu.com [91.218.175.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 54D384D59E for ; Sun, 19 May 2024 16:54:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137684; cv=none; b=R59XRfsKrLbXQOVxVWj/rxmXLV/ffba4ReNmslTS5TmfAJO9utsGEGxD9XmUBuj7Sf/bG32wlhIkMoBdI2eqdXWMGC+3jiM4cAVcnb3ZaUOrSs4CEvbjlni9gW1cHh8tSsOuuzLZqYu1zgXi6qdkGgp8fKkLpffCNYRbJjghMng= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137684; c=relaxed/simple; bh=wR1Emg5c1AEbhI0Kq+IKHKxn5JDqxreiWkqApwdFmSA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=CdLlLkGYECi1KWRt64oP8rtGz8FTlbrXolw2eEiB5QzBcGm/HN/kuUegbt3Y43p5lTb5TftHv/U0gGRG9e0Uyh+oxm/AqQlgD54g3NSHkN8EkgJLvCxh7G4LiIuryZO37nHHAlh2xrWg6k8EpX8GNZuDZAS6l0d9wp3J+l1BFdo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=VbX3EKrj; arc=none smtp.client-ip=91.218.175.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="VbX3EKrj" X-Envelope-To: l.stach@pengutronix.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1716137680; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0YtsLv1p6v4P1MxchPcntfjjhkynHWMpb0L7dfEcquM=; b=VbX3EKrjaOG7ZwnS1SiavbEPVj/M3ojTFP9zSfpO1gt39s+/LE9xIJvPB6g7AZEWoQ3xb/ Qm4nYdqPISQJe00FXgyOPRHTYacBeU3tMhtdwpnjbUINSzYnfEzdXGUvzxuc854urpRaPZ vJ+rb2k3DRJUnik1wC/2ld4+HZjLFjc= X-Envelope-To: linux+etnaviv@armlinux.org.uk X-Envelope-To: christian.gmeiner@gmail.com X-Envelope-To: linux-kernel@vger.kernel.org X-Envelope-To: etnaviv@lists.freedesktop.org X-Envelope-To: dri-devel@lists.freedesktop.org X-Envelope-To: sui.jingfeng@linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Sui Jingfeng To: Lucas Stach Cc: Russell King , Christian Gmeiner , linux-kernel@vger.kernel.org, etnaviv@lists.freedesktop.org, dri-devel@lists.freedesktop.org, Sui Jingfeng Subject: [etnaviv-next v14 2/8] drm/etnaviv: Add constructor and destructor for the etnaviv_drm_private structure Date: Mon, 20 May 2024 00:53:15 +0800 Message-Id: <20240519165321.2123356-3-sui.jingfeng@linux.dev> In-Reply-To: <20240519165321.2123356-1-sui.jingfeng@linux.dev> References: <20240519165321.2123356-1-sui.jingfeng@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Because there are a lot of data members in the struct etnaviv_drm_private, which are intended to be shared by all GPU cores. It can be lengthy and daunting on error handling, the 'gem_lock' of struct etnaviv_drm_private just be forgeten to destroy on driver leave. Switch to use the dedicated helpers introduced, etnaviv_bind() and etnaviv_unbind() gets simplified. Another potential benefit is that we could put the struct drm_device into struct etnaviv_drm_private in the future, which made them share the same life time. Signed-off-by: Sui Jingfeng Tested-by: Christian Gmeiner --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 72 +++++++++++++++++---------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnavi= v/etnaviv_drv.c index 6500f3999c5f..22c78bc944c4 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -41,6 +41,45 @@ static struct device_node *etnaviv_of_first_available_no= de(void) return NULL; } =20 +static struct etnaviv_drm_private *etnaviv_alloc_private(struct device *de= v) +{ + struct etnaviv_drm_private *priv; + + priv =3D kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return ERR_PTR(-ENOMEM); + + xa_init_flags(&priv->active_contexts, XA_FLAGS_ALLOC); + + mutex_init(&priv->gem_lock); + INIT_LIST_HEAD(&priv->gem_list); + priv->num_gpus =3D 0; + priv->shm_gfp_mask =3D GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN; + + priv->cmdbuf_suballoc =3D etnaviv_cmdbuf_suballoc_new(dev); + if (IS_ERR(priv->cmdbuf_suballoc)) { + kfree(priv); + dev_err(dev, "Failed to create cmdbuf suballocator\n"); + return ERR_PTR(-ENOMEM); + } + + return priv; +} + +static void etnaviv_free_private(struct etnaviv_drm_private *priv) +{ + if (!priv) + return; + + mutex_destroy(&priv->gem_lock); + + etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc); + + xa_destroy(&priv->active_contexts); + + kfree(priv); +} + static void load_gpu(struct drm_device *dev) { struct etnaviv_drm_private *priv =3D dev->dev_private; @@ -521,35 +560,21 @@ static int etnaviv_bind(struct device *dev) if (IS_ERR(drm)) return PTR_ERR(drm); =20 - priv =3D kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(dev, "failed to allocate private data\n"); - ret =3D -ENOMEM; + priv =3D etnaviv_alloc_private(dev); + if (IS_ERR(priv)) { + ret =3D PTR_ERR(priv); goto out_put; } + drm->dev_private =3D priv; =20 dma_set_max_seg_size(dev, SZ_2G); =20 - xa_init_flags(&priv->active_contexts, XA_FLAGS_ALLOC); - - mutex_init(&priv->gem_lock); - INIT_LIST_HEAD(&priv->gem_list); - priv->num_gpus =3D 0; - priv->shm_gfp_mask =3D GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN; - - priv->cmdbuf_suballoc =3D etnaviv_cmdbuf_suballoc_new(drm->dev); - if (IS_ERR(priv->cmdbuf_suballoc)) { - dev_err(drm->dev, "Failed to create cmdbuf suballocator\n"); - ret =3D PTR_ERR(priv->cmdbuf_suballoc); - goto out_free_priv; - } - dev_set_drvdata(dev, drm); =20 ret =3D component_bind_all(dev, drm); if (ret < 0) - goto out_destroy_suballoc; + goto out_free_priv; =20 load_gpu(drm); =20 @@ -561,10 +586,8 @@ static int etnaviv_bind(struct device *dev) =20 out_unbind: component_unbind_all(dev, drm); -out_destroy_suballoc: - etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc); out_free_priv: - kfree(priv); + etnaviv_free_private(priv); out_put: drm_dev_put(drm); =20 @@ -580,12 +603,9 @@ static void etnaviv_unbind(struct device *dev) =20 component_unbind_all(dev, drm); =20 - etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc); - - xa_destroy(&priv->active_contexts); + etnaviv_free_private(priv); =20 drm->dev_private =3D NULL; - kfree(priv); =20 drm_dev_put(drm); } --=20 2.34.1 From nobody Wed Feb 11 05:41:41 2026 Received: from out-180.mta0.migadu.com (out-180.mta0.migadu.com [91.218.175.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B5055029B for ; Sun, 19 May 2024 16:54:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137697; cv=none; b=BcDSbyRJ0l9EbuARZzkOXn2Vh1UrNuK+zs/jhAd9HYbEhwqeS8swZ1nnK/VHkqGJ1nrh0neJj8bfemH9eA4shf4Yn335Kx8iQL61zmGKjVHJ08NoO9kNVOgNRaI+fMjlbcjoeqz78dTI0vGWiv8lYUMJQPjWvdQxs6aqfdol2zc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137697; c=relaxed/simple; bh=4goH//CjiHV5XvHFG0rMLcn1PCdbbTf2Udhx5eMCgrU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fuH/zA4j9yRnxZ/MVUO5oKO/NiF+QCb1I9feg4e/xjS2CEuJTgdvme2kgOh9b8KWC8Lmf11QF6B36IxgvcRPn9e5q/MzeN+rKc59/TbV00hgh/Vnl0AbXrkhiYNQW9gw9/MNiHmOAqkBow9GynsnmHiT60XvXBwvdrxIIilB0aU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=FZ0O73IC; arc=none smtp.client-ip=91.218.175.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="FZ0O73IC" X-Envelope-To: l.stach@pengutronix.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1716137693; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KrrrUAMvLGSMTDh1k6FGYebCnWRlfKpEJuCQOvt4lG0=; b=FZ0O73ICs+SYi6csaJNZ9pvooDQrgDy5pufCjf6szXgt5YlAwdygBvDcA9INZJ+NMdJyxz gdSpP6Z4mD5/m4m2OQZuCUug/RlvpiudtGlH+vOsTKwwgE0pX79o5sV4OGvdWEOmniw5Xc jXKOzhL75nSQMn9nDLZAv7L+zgIwIss= X-Envelope-To: linux+etnaviv@armlinux.org.uk X-Envelope-To: christian.gmeiner@gmail.com X-Envelope-To: linux-kernel@vger.kernel.org X-Envelope-To: etnaviv@lists.freedesktop.org X-Envelope-To: dri-devel@lists.freedesktop.org X-Envelope-To: sui.jingfeng@linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Sui Jingfeng To: Lucas Stach Cc: Russell King , Christian Gmeiner , linux-kernel@vger.kernel.org, etnaviv@lists.freedesktop.org, dri-devel@lists.freedesktop.org, Sui Jingfeng Subject: [etnaviv-next v14 3/8] drm/etnaviv: Embed struct drm_device into struct etnaviv_drm_private Date: Mon, 20 May 2024 00:53:16 +0800 Message-Id: <20240519165321.2123356-4-sui.jingfeng@linux.dev> In-Reply-To: <20240519165321.2123356-1-sui.jingfeng@linux.dev> References: <20240519165321.2123356-1-sui.jingfeng@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Both the instance of struct drm_device and the instance of struct etnaviv_drm_private are intended to be shared by all GPU cores, both have only one instance created across drm/etnaviv driver. After embedded in, the whole structure can be allocated with devm_drm_dev_alloc(). And the DRM device created is automatically put on driver detach, so we don't need to call drm_dev_put() explicitly on driver leave. It's also eliminate the need to use the .dev_private member, which is deprecated according to the drm document. We can also use container_of() to retrieve pointer for the containing structure. Signed-off-by: Sui Jingfeng Tested-by: Christian Gmeiner --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 65 ++++++++------------ drivers/gpu/drm/etnaviv/etnaviv_drv.h | 7 +++ drivers/gpu/drm/etnaviv/etnaviv_gem.c | 6 +- drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 2 +- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 6 +- drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 4 +- 6 files changed, 40 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnavi= v/etnaviv_drv.c index 22c78bc944c4..e3eb31ba9a2b 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -41,14 +41,9 @@ static struct device_node *etnaviv_of_first_available_no= de(void) return NULL; } =20 -static struct etnaviv_drm_private *etnaviv_alloc_private(struct device *de= v) +static int etnaviv_private_init(struct device *dev, + struct etnaviv_drm_private *priv) { - struct etnaviv_drm_private *priv; - - priv =3D kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return ERR_PTR(-ENOMEM); - xa_init_flags(&priv->active_contexts, XA_FLAGS_ALLOC); =20 mutex_init(&priv->gem_lock); @@ -58,15 +53,14 @@ static struct etnaviv_drm_private *etnaviv_alloc_privat= e(struct device *dev) =20 priv->cmdbuf_suballoc =3D etnaviv_cmdbuf_suballoc_new(dev); if (IS_ERR(priv->cmdbuf_suballoc)) { - kfree(priv); dev_err(dev, "Failed to create cmdbuf suballocator\n"); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } =20 - return priv; + return 0; } =20 -static void etnaviv_free_private(struct etnaviv_drm_private *priv) +static void etnaviv_private_fini(struct etnaviv_drm_private *priv) { if (!priv) return; @@ -76,13 +70,11 @@ static void etnaviv_free_private(struct etnaviv_drm_pri= vate *priv) etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc); =20 xa_destroy(&priv->active_contexts); - - kfree(priv); } =20 static void load_gpu(struct drm_device *dev) { - struct etnaviv_drm_private *priv =3D dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(dev); unsigned int i; =20 for (i =3D 0; i < ETNA_MAX_PIPES; i++) { @@ -100,7 +92,7 @@ static void load_gpu(struct drm_device *dev) =20 static int etnaviv_open(struct drm_device *dev, struct drm_file *file) { - struct etnaviv_drm_private *priv =3D dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(dev); struct etnaviv_file_private *ctx; int ret, i; =20 @@ -143,7 +135,7 @@ static int etnaviv_open(struct drm_device *dev, struct = drm_file *file) =20 static void etnaviv_postclose(struct drm_device *dev, struct drm_file *fil= e) { - struct etnaviv_drm_private *priv =3D dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(dev); struct etnaviv_file_private *ctx =3D file->driver_priv; unsigned int i; =20 @@ -168,7 +160,7 @@ static void etnaviv_postclose(struct drm_device *dev, s= truct drm_file *file) #ifdef CONFIG_DEBUG_FS static int etnaviv_gem_show(struct drm_device *dev, struct seq_file *m) { - struct etnaviv_drm_private *priv =3D dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(dev); =20 etnaviv_gem_describe_objects(priv, m); =20 @@ -262,7 +254,7 @@ static int show_each_gpu(struct seq_file *m, void *arg) { struct drm_info_node *node =3D (struct drm_info_node *) m->private; struct drm_device *dev =3D node->minor->dev; - struct etnaviv_drm_private *priv =3D dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(dev); struct etnaviv_gpu *gpu; int (*show)(struct etnaviv_gpu *gpu, struct seq_file *m) =3D node->info_ent->data; @@ -305,7 +297,7 @@ static void etnaviv_debugfs_init(struct drm_minor *mino= r) static int etnaviv_ioctl_get_param(struct drm_device *dev, void *data, struct drm_file *file) { - struct etnaviv_drm_private *priv =3D dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(dev); struct drm_etnaviv_param *args =3D data; struct etnaviv_gpu *gpu; =20 @@ -398,7 +390,7 @@ static int etnaviv_ioctl_wait_fence(struct drm_device *= dev, void *data, struct drm_file *file) { struct drm_etnaviv_wait_fence *args =3D data; - struct etnaviv_drm_private *priv =3D dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(dev); struct drm_etnaviv_timespec *timeout =3D &args->timeout; struct etnaviv_gpu *gpu; =20 @@ -446,7 +438,7 @@ static int etnaviv_ioctl_gem_userptr(struct drm_device = *dev, void *data, static int etnaviv_ioctl_gem_wait(struct drm_device *dev, void *data, struct drm_file *file) { - struct etnaviv_drm_private *priv =3D dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(dev); struct drm_etnaviv_gem_wait *args =3D data; struct drm_etnaviv_timespec *timeout =3D &args->timeout; struct drm_gem_object *obj; @@ -480,7 +472,7 @@ static int etnaviv_ioctl_gem_wait(struct drm_device *de= v, void *data, static int etnaviv_ioctl_pm_query_dom(struct drm_device *dev, void *data, struct drm_file *file) { - struct etnaviv_drm_private *priv =3D dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(dev); struct drm_etnaviv_pm_domain *args =3D data; struct etnaviv_gpu *gpu; =20 @@ -497,7 +489,7 @@ static int etnaviv_ioctl_pm_query_dom(struct drm_device= *dev, void *data, static int etnaviv_ioctl_pm_query_sig(struct drm_device *dev, void *data, struct drm_file *file) { - struct etnaviv_drm_private *priv =3D dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(dev); struct drm_etnaviv_pm_signal *args =3D data; struct etnaviv_gpu *gpu; =20 @@ -556,17 +548,14 @@ static int etnaviv_bind(struct device *dev) struct drm_device *drm; int ret; =20 - drm =3D drm_dev_alloc(&etnaviv_drm_driver, dev); - if (IS_ERR(drm)) - return PTR_ERR(drm); + priv =3D devm_drm_dev_alloc(dev, &etnaviv_drm_driver, + struct etnaviv_drm_private, drm); + if (IS_ERR(priv)) + return PTR_ERR(priv); =20 - priv =3D etnaviv_alloc_private(dev); - if (IS_ERR(priv)) { - ret =3D PTR_ERR(priv); - goto out_put; - } + etnaviv_private_init(dev, priv); =20 - drm->dev_private =3D priv; + drm =3D &priv->drm; =20 dma_set_max_seg_size(dev, SZ_2G); =20 @@ -587,9 +576,7 @@ static int etnaviv_bind(struct device *dev) out_unbind: component_unbind_all(dev, drm); out_free_priv: - etnaviv_free_private(priv); -out_put: - drm_dev_put(drm); + etnaviv_private_fini(priv); =20 return ret; } @@ -597,17 +584,13 @@ static int etnaviv_bind(struct device *dev) static void etnaviv_unbind(struct device *dev) { struct drm_device *drm =3D dev_get_drvdata(dev); - struct etnaviv_drm_private *priv =3D drm->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(drm); =20 drm_dev_unregister(drm); =20 component_unbind_all(dev, drm); =20 - etnaviv_free_private(priv); - - drm->dev_private =3D NULL; - - drm_dev_put(drm); + etnaviv_private_fini(priv); } =20 static const struct component_master_ops etnaviv_master_ops =3D { diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnavi= v/etnaviv_drv.h index b3eb1662e90c..1f9b50b5a6aa 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -35,6 +35,7 @@ struct etnaviv_file_private { }; =20 struct etnaviv_drm_private { + struct drm_device drm; int num_gpus; struct etnaviv_gpu *gpu[ETNA_MAX_PIPES]; gfp_t shm_gfp_mask; @@ -50,6 +51,12 @@ struct etnaviv_drm_private { struct list_head gem_list; }; =20 +static inline struct etnaviv_drm_private * +to_etnaviv_priv(struct drm_device *ddev) +{ + return container_of(ddev, struct etnaviv_drm_private, drm); +} + int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, struct drm_file *file); =20 diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnavi= v/etnaviv_gem.c index 71a6d2b1c80f..aa95a5e98374 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -486,7 +486,7 @@ static const struct etnaviv_gem_ops etnaviv_gem_shmem_o= ps =3D { void etnaviv_gem_free_object(struct drm_gem_object *obj) { struct etnaviv_gem_object *etnaviv_obj =3D to_etnaviv_bo(obj); - struct etnaviv_drm_private *priv =3D obj->dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(obj->dev); struct etnaviv_vram_mapping *mapping, *tmp; =20 /* object should not be active */ @@ -517,7 +517,7 @@ void etnaviv_gem_free_object(struct drm_gem_object *obj) =20 void etnaviv_gem_obj_add(struct drm_device *dev, struct drm_gem_object *ob= j) { - struct etnaviv_drm_private *priv =3D dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(dev); struct etnaviv_gem_object *etnaviv_obj =3D to_etnaviv_bo(obj); =20 mutex_lock(&priv->gem_lock); @@ -584,7 +584,7 @@ static int etnaviv_gem_new_impl(struct drm_device *dev,= u32 flags, int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file, u32 size, u32 flags, u32 *handle) { - struct etnaviv_drm_private *priv =3D dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(dev); struct drm_gem_object *obj =3D NULL; int ret; =20 diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm= /etnaviv/etnaviv_gem_submit.c index 3d0f8d182506..6b40a39fb8cd 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c @@ -413,7 +413,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, vo= id *data, struct drm_file *file) { struct etnaviv_file_private *ctx =3D file->driver_priv; - struct etnaviv_drm_private *priv =3D dev->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(dev); struct drm_etnaviv_gem_submit *args =3D data; struct drm_etnaviv_gem_submit_reloc *relocs; struct drm_etnaviv_gem_submit_pmr *pmrs; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnavi= v/etnaviv_gpu.c index e0c36f564fa6..02d7efdc82c0 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -38,7 +38,7 @@ static const struct platform_device_id gpu_ids[] =3D { =20 int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value) { - struct etnaviv_drm_private *priv =3D gpu->drm->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(gpu->drm); =20 switch (param) { case ETNAVIV_PARAM_GPU_MODEL: @@ -789,7 +789,7 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu) =20 int etnaviv_gpu_init(struct etnaviv_gpu *gpu) { - struct etnaviv_drm_private *priv =3D gpu->drm->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(gpu->drm); dma_addr_t cmdbuf_paddr; int ret, i; =20 @@ -1779,7 +1779,7 @@ static int etnaviv_gpu_bind(struct device *dev, struc= t device *master, void *data) { struct drm_device *drm =3D data; - struct etnaviv_drm_private *priv =3D drm->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(drm); struct etnaviv_gpu *gpu =3D dev_get_drvdata(dev); int ret; =20 diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnavi= v/etnaviv_mmu.c index 1661d589bf3e..c38272868328 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -490,7 +490,7 @@ void etnaviv_iommu_dump(struct etnaviv_iommu_context *c= ontext, void *buf) int etnaviv_iommu_global_init(struct etnaviv_gpu *gpu) { enum etnaviv_iommu_version version =3D ETNAVIV_IOMMU_V1; - struct etnaviv_drm_private *priv =3D gpu->drm->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(gpu->drm); struct etnaviv_iommu_global *global; struct device *dev =3D gpu->drm->dev; =20 @@ -550,7 +550,7 @@ int etnaviv_iommu_global_init(struct etnaviv_gpu *gpu) =20 void etnaviv_iommu_global_fini(struct etnaviv_gpu *gpu) { - struct etnaviv_drm_private *priv =3D gpu->drm->dev_private; + struct etnaviv_drm_private *priv =3D to_etnaviv_priv(gpu->drm); struct etnaviv_iommu_global *global =3D priv->mmu_global; =20 if (!global) --=20 2.34.1 From nobody Wed Feb 11 05:41:41 2026 Received: from out-184.mta0.migadu.com (out-184.mta0.migadu.com [91.218.175.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 64EB6495E5 for ; Sun, 19 May 2024 16:55:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.184 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137714; cv=none; b=t0qXgpm3rVtO/YY+y0OXON7820IdH1braHWvcM2/yFOGat0pbKH+Jpn3nO3FqVG5dA/xDRUmHlZk6JqqeeJLAyUIeG0o4UUu2PDFHeieRkyvdJM+DPjNxg6cJHn98M0g7qg2POK0RJHcs3B1FqLv3jlVsmnmFTDY2PGkc2SWfPw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137714; c=relaxed/simple; bh=HLEE5CycAUBUUmCccedhfrJ12xykardYssIwYKvg69Y=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=G/YP/ib8WUv3SDTv0lQIL7LsCEdkRLLgyrpyx6ywqObimDt1jVgafFNE6FI7ZKIW5YgYXTvdBOnOk5pBjMWUfEFLZ3apwkBIhcp9b0YKyG7JC7mtS8piQ6LYHsFaoj9934ZftCHaQMPg1RoAI+7FGhMg+mf6vHFgPt8DGws7350= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=bBlT1H7D; arc=none smtp.client-ip=91.218.175.184 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="bBlT1H7D" X-Envelope-To: l.stach@pengutronix.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1716137710; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pwKICKst0L9yhry2NDoovnT+HCNlgrmcR3qE1GjmJec=; b=bBlT1H7DxARNi8JC9kBvYsbaGoD0hxSggt0J/XuuMtKkhgwS8p7//uKxzrGvH8wGWkeKGm e1iyhK+QtBKAFoftw8vneZwgTuHBhhMNXMCe7HXugnF78CplZLZB0hYyEUpZP+8fbVIgP0 GMgT57Wf5lN9/+RCOkQBCZN8fKtJ1Do= X-Envelope-To: linux+etnaviv@armlinux.org.uk X-Envelope-To: christian.gmeiner@gmail.com X-Envelope-To: linux-kernel@vger.kernel.org X-Envelope-To: etnaviv@lists.freedesktop.org X-Envelope-To: dri-devel@lists.freedesktop.org X-Envelope-To: sui.jingfeng@linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Sui Jingfeng To: Lucas Stach Cc: Russell King , Christian Gmeiner , linux-kernel@vger.kernel.org, etnaviv@lists.freedesktop.org, dri-devel@lists.freedesktop.org, Sui Jingfeng Subject: [etnaviv-next v14 4/8] drm/etnaviv: Fix wrong cache property being used for vmap() Date: Mon, 20 May 2024 00:53:17 +0800 Message-Id: <20240519165321.2123356-5-sui.jingfeng@linux.dev> In-Reply-To: <20240519165321.2123356-1-sui.jingfeng@linux.dev> References: <20240519165321.2123356-1-sui.jingfeng@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" In the etnaviv_gem_vmap_impl() function, the driver vmap whatever buffers with Write-Combine page property. This is unreasonable, as some platforms are cached coherent. And cached buffers should be mapped with cached page property. Fixes: a0a5ab3e99b8 ("drm/etnaviv: call correct function when trying to vma= p a DMABUF") Signed-off-by: Sui Jingfeng Tested-by: Christian Gmeiner --- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnavi= v/etnaviv_gem.c index aa95a5e98374..eed98bb9e446 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -342,6 +342,7 @@ void *etnaviv_gem_vmap(struct drm_gem_object *obj) static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj) { struct page **pages; + pgprot_t prot; =20 lockdep_assert_held(&obj->lock); =20 @@ -349,8 +350,19 @@ static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_= object *obj) if (IS_ERR(pages)) return NULL; =20 - return vmap(pages, obj->base.size >> PAGE_SHIFT, - VM_MAP, pgprot_writecombine(PAGE_KERNEL)); + switch (obj->flags) { + case ETNA_BO_CACHED: + prot =3D PAGE_KERNEL; + break; + case ETNA_BO_UNCACHED: + prot =3D pgprot_noncached(PAGE_KERNEL); + break; + case ETNA_BO_WC: + default: + prot =3D pgprot_writecombine(PAGE_KERNEL); + } + + return vmap(pages, obj->base.size >> PAGE_SHIFT, VM_MAP, prot); } =20 static inline enum dma_data_direction etnaviv_op_to_dma_dir(u32 op) --=20 2.34.1 From nobody Wed Feb 11 05:41:41 2026 Received: from out-171.mta0.migadu.com (out-171.mta0.migadu.com [91.218.175.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEEBC1DFCB for ; Sun, 19 May 2024 16:55:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137737; cv=none; b=M1crnlUKMkvS9ijNgJ7e0XailwYGCJaW7O6kBQJR7c0JUatBendWhT6yMO89rFuVu7uMGS7kzIpnQ/WyeJXDqfoKFelB5WViRJPU7Q9VPps3gIUq34m6SHFZTYk5Ltm2WDRm1itsdDA+1F7K/K32XxEXo8tEfvWtpktOz1l1g2Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137737; c=relaxed/simple; bh=2tOtaCRxRph0PTMDHLzelUUn+onpkPRFXw3ZipPu0ZE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=hZb1NwItOOBpR3MFVyjX/tEu+UfcVghPeOPguSc5g2vsWWSe+wlyK1ueRzs4JEf1TzUK6MhBn//F4T1IJooMs52IYOadk2KND5q8T72XO+7Ed3M+xNG5mFfhplli+jEEA4Ip6bFtmng86bkbGuzHL93yyN3pKrYL93o7GR8slhg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=OKowqIjP; arc=none smtp.client-ip=91.218.175.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="OKowqIjP" X-Envelope-To: l.stach@pengutronix.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1716137734; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tJoc0KMwzsmIaav0VlUAEml/vTeXcEP0ggNixh3RBXA=; b=OKowqIjPtjotymtjYZy07VzQRnpNqCA8o/6QsYXk+fkQ8Aff1w7nxIkroJYKrny+HzJlNB v4+yKyxxwgNPfbOlcD4PLpPUJwB2S2UAGDGxaDwFFaBjeySfQz/tnhdI39MqGvl7wRqWxW JTQx+S+Qmxg7Hz7h6L3eTppRXyRB2M0= X-Envelope-To: linux+etnaviv@armlinux.org.uk X-Envelope-To: christian.gmeiner@gmail.com X-Envelope-To: linux-kernel@vger.kernel.org X-Envelope-To: etnaviv@lists.freedesktop.org X-Envelope-To: dri-devel@lists.freedesktop.org X-Envelope-To: sui.jingfeng@linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Sui Jingfeng To: Lucas Stach Cc: Russell King , Christian Gmeiner , linux-kernel@vger.kernel.org, etnaviv@lists.freedesktop.org, dri-devel@lists.freedesktop.org, Sui Jingfeng Subject: [etnaviv-next v14 5/8] drm/etnaviv: Add support for cached coherent caching mode Date: Mon, 20 May 2024 00:53:18 +0800 Message-Id: <20240519165321.2123356-6-sui.jingfeng@linux.dev> In-Reply-To: <20240519165321.2123356-1-sui.jingfeng@linux.dev> References: <20240519165321.2123356-1-sui.jingfeng@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Many modern CPUs and/or platforms choose to define their peripheral devices as cached coherent by default, to be specific, the PCH is capable of snooping CPU's cache. When hit the peripheral devices will access data directly from CPU's cache. This means that device drivers do not need to maintain the coherency issue between a processor and peripheral I/O for the cached buffers. Hence, it dosen't need us to sync manually on the software side, which is useful to avoid some overheads, especially for userspace, but userspace is not known yet. Probe the hardware maintained cached coherent support of the host platform with the dev_is_dma_coherent() function, and store the result in struct etnaviv_drm_private. As this is a platform implementation-defined hardware feature and again is meant to be shared by all GPU cores. And expose it via etnaviv parameter mechanism to let userspace know. Please note that write-combine mapping out of scope of the discussion and therefore is not being addressed. Signed-off-by: Sui Jingfeng Tested-by: Christian Gmeiner --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 3 +++ drivers/gpu/drm/etnaviv/etnaviv_drv.h | 9 +++++++++ drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 4 ++++ include/uapi/drm/etnaviv_drm.h | 1 + 4 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnavi= v/etnaviv_drv.c index e3eb31ba9a2b..986fd68b489a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -5,6 +5,7 @@ =20 #include #include +#include #include #include #include @@ -57,6 +58,8 @@ static int etnaviv_private_init(struct device *dev, return -ENOMEM; } =20 + priv->cached_coherent =3D dev_is_dma_coherent(dev); + return 0; } =20 diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnavi= v/etnaviv_drv.h index 1f9b50b5a6aa..4b59fdb457b7 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -46,6 +46,15 @@ struct etnaviv_drm_private { struct xarray active_contexts; u32 next_context_id; =20 + /* + * If true, the cached mapping is consistent for all CPU cores and + * peripheral bus masters in the system. It means that both of the + * CPU and GPU will see the same data if the buffer being accessed + * is cached. And the coherency is guaranteed by the host platform + * specific hardwares. + */ + bool cached_coherent; + /* list of GEM objects: */ struct mutex gem_lock; struct list_head gem_list; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnavi= v/etnaviv_gpu.c index 02d7efdc82c0..aa15682f94db 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -164,6 +164,10 @@ int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32= param, u64 *value) *value =3D gpu->identity.eco_id; break; =20 + case ETNAVIV_PARAM_CACHED_COHERENT: + *value =3D priv->cached_coherent; + break; + default: DBG("%s: invalid param: %u", dev_name(gpu->dev), param); return -EINVAL; diff --git a/include/uapi/drm/etnaviv_drm.h b/include/uapi/drm/etnaviv_drm.h index af024d90453d..61eaa8cd0f5e 100644 --- a/include/uapi/drm/etnaviv_drm.h +++ b/include/uapi/drm/etnaviv_drm.h @@ -77,6 +77,7 @@ struct drm_etnaviv_timespec { #define ETNAVIV_PARAM_GPU_PRODUCT_ID 0x1c #define ETNAVIV_PARAM_GPU_CUSTOMER_ID 0x1d #define ETNAVIV_PARAM_GPU_ECO_ID 0x1e +#define ETNAVIV_PARAM_CACHED_COHERENT 0x1f =20 #define ETNA_MAX_PIPES 4 =20 --=20 2.34.1 From nobody Wed Feb 11 05:41:41 2026 Received: from out-174.mta0.migadu.com (out-174.mta0.migadu.com [91.218.175.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 34AA24F5EC for ; Sun, 19 May 2024 16:55:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137747; cv=none; b=lHb6apiqp0TlJSBSKp+Y6/ew1ep2n29AYHNhAfx0/ux6ftrM1agMXmYFR6zJ7JLFCaG2sUTRFtrjNdB92BBkGO2E+MkOHsiPa+92Jm5CgooXjZHI4DBYD3Za6YzKMUmfXTg4XpHBLbCI+mqHsRQs2RkTt/4MF5izXrCzPqZTDYs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137747; c=relaxed/simple; bh=hm59Au1r1mM30f5gqdiuaWkIu4F5pPhFgp+s8SKe0+I=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=iRBs4+eHB2XAkd/cHSx7WR9UPkXlFWbk1qIHVEtz4u6O7Wv68zTf3+i+TLIUpy4eOPzvgtfN53Pb2tXjJXhb+BrvBsZ8GeM3CNhnpciD2dgfDAyyLD4MJ3M+UNKS6abmROYOI/KT+W79Z1zlkxfDEgKD8jjCoOzLQkpbRpg1qI0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=cVpdhXYz; arc=none smtp.client-ip=91.218.175.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="cVpdhXYz" X-Envelope-To: l.stach@pengutronix.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1716137744; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EFYuWykwL1U4iv85dPQQK/TFC0Vjyb1IATiwN/iE76Q=; b=cVpdhXYzbGvg9D3LY2MmiBLKPrGIEy/mf3TWS3BAPUz9HMPI8ILszrEsLY5Rp0HacuSaIn bMdWGQWdg7IWkfT/5oziJ+hhzycV7sQjLFC1obPYqGaHf0h543ME/N7rVVQ7dBbP5D0rEV IM1M9zkwbTWclhbIqGujBrA8psHb7xA= X-Envelope-To: linux+etnaviv@armlinux.org.uk X-Envelope-To: christian.gmeiner@gmail.com X-Envelope-To: linux-kernel@vger.kernel.org X-Envelope-To: etnaviv@lists.freedesktop.org X-Envelope-To: dri-devel@lists.freedesktop.org X-Envelope-To: sui.jingfeng@linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Sui Jingfeng To: Lucas Stach Cc: Russell King , Christian Gmeiner , linux-kernel@vger.kernel.org, etnaviv@lists.freedesktop.org, dri-devel@lists.freedesktop.org, Sui Jingfeng Subject: [etnaviv-next v14 6/8] drm/etnaviv: Replace the '&pdev->dev' with 'dev' Date: Mon, 20 May 2024 00:53:19 +0800 Message-Id: <20240519165321.2123356-7-sui.jingfeng@linux.dev> In-Reply-To: <20240519165321.2123356-1-sui.jingfeng@linux.dev> References: <20240519165321.2123356-1-sui.jingfeng@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" In the etnaviv_pdev_probe(), etnaviv_gpu_platform_probe() function, the value of '&pdev->dev' has been cached to the 'dev' local auto variable. But part of callers use 'dev' as argument, while the rest use '&pdev->dev'. To keep it consistent, use 'dev' uniformly. Signed-off-by: Sui Jingfeng Tested-by: Christian Gmeiner --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 10 +++++----- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnavi= v/etnaviv_drv.c index 986fd68b489a..863faac2ea19 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -614,7 +614,7 @@ static int etnaviv_pdev_probe(struct platform_device *p= dev) if (!of_device_is_available(core_node)) continue; =20 - drm_of_component_match_add(&pdev->dev, &match, + drm_of_component_match_add(dev, &match, component_compare_of, core_node); } } else { @@ -637,9 +637,9 @@ static int etnaviv_pdev_probe(struct platform_device *p= dev) * bit to make sure we are allocating the command buffers and * TLBs in the lower 4 GiB address space. */ - if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(40)) || - dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) { - dev_dbg(&pdev->dev, "No suitable DMA available\n"); + if (dma_set_mask(dev, DMA_BIT_MASK(40)) || + dma_set_coherent_mask(dev, DMA_BIT_MASK(32))) { + dev_dbg(dev, "No suitable DMA available\n"); return -ENODEV; } =20 @@ -650,7 +650,7 @@ static int etnaviv_pdev_probe(struct platform_device *p= dev) */ first_node =3D etnaviv_of_first_available_node(); if (first_node) { - of_dma_configure(&pdev->dev, first_node, true); + of_dma_configure(dev, first_node, true); of_node_put(first_node); } =20 diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnavi= v/etnaviv_gpu.c index aa15682f94db..3a14e187388a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1891,7 +1891,7 @@ static int etnaviv_gpu_platform_probe(struct platform= _device *pdev) if (!gpu) return -ENOMEM; =20 - gpu->dev =3D &pdev->dev; + gpu->dev =3D dev; mutex_init(&gpu->lock); mutex_init(&gpu->sched_lock); =20 @@ -1905,8 +1905,8 @@ static int etnaviv_gpu_platform_probe(struct platform= _device *pdev) if (gpu->irq < 0) return gpu->irq; =20 - err =3D devm_request_irq(&pdev->dev, gpu->irq, irq_handler, 0, - dev_name(gpu->dev), gpu); + err =3D devm_request_irq(dev, gpu->irq, irq_handler, 0, + dev_name(dev), gpu); if (err) { dev_err(dev, "failed to request IRQ%u: %d\n", gpu->irq, err); return err; @@ -1925,13 +1925,13 @@ static int etnaviv_gpu_platform_probe(struct platfo= rm_device *pdev) * autosuspend delay is rather arbitary: no measurements have * yet been performed to determine an appropriate value. */ - pm_runtime_use_autosuspend(gpu->dev); - pm_runtime_set_autosuspend_delay(gpu->dev, 200); - pm_runtime_enable(gpu->dev); + pm_runtime_use_autosuspend(dev); + pm_runtime_set_autosuspend_delay(dev, 200); + pm_runtime_enable(dev); =20 - err =3D component_add(&pdev->dev, &gpu_ops); + err =3D component_add(dev, &gpu_ops); if (err < 0) { - dev_err(&pdev->dev, "failed to register component: %d\n", err); + dev_err(dev, "failed to register component: %d\n", err); return err; } =20 --=20 2.34.1 From nobody Wed Feb 11 05:41:41 2026 Received: from out-171.mta0.migadu.com (out-171.mta0.migadu.com [91.218.175.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E013C8FF for ; Sun, 19 May 2024 16:56:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137775; cv=none; b=Fo4J2RNJ70VgzPit6yPyd/wwdRQJzgfs1tyQ7ClIsCKpgBm+TVd1MqJKFnKmytSOLdtFuRSHw8lEATcuP7oa6wZqv3INHiUH8C+hv6MIB1HxOD67Uozc0S83ijIVUZpcVp/ha4vSezaRJtljbKTnX4p0L6zmT3QH0hwuUZPcBTA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137775; c=relaxed/simple; bh=1zWonPgi6S+7f5hKM3YQ0+36A4RjI7I06WXNNdsJEsU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Vm6PDC3SbOE0rt1CUtZtNnf55QUQs3Ss0v3RodVcaRtIZ4r1HJ2gM07RgIZEdo4FNCM/VxVOeKsAL3Nki0Vro8z4w6c79lpe2P6bWJIt3etOzZ3UbDTk71a5ZUTV+LYZJMrSwNHmffA5CRndDlT3Kfc5hV5zXzvWl3aQBCwoob4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=OvtOrBIa; arc=none smtp.client-ip=91.218.175.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="OvtOrBIa" X-Envelope-To: l.stach@pengutronix.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1716137770; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GXBVcpMLvTTn2V6PI5Jk17nPGWaXsqbtzsGA2rLsFpo=; b=OvtOrBIapWAMCIxGKinBz4phnHIumhUQ6rpUPbfYbaPfpTipfVP2gtdc8F7jN1baR5EnZs dcEPVXVSARixMmx0rzJtLIoxC4JvhwPtroE198OXOZ2i1dlQDdEJRCcx0M8gobnaYW8R53 OJhi0aMJ+0kLK8evqB3w0ww7anyU38s= X-Envelope-To: linux+etnaviv@armlinux.org.uk X-Envelope-To: christian.gmeiner@gmail.com X-Envelope-To: linux-kernel@vger.kernel.org X-Envelope-To: etnaviv@lists.freedesktop.org X-Envelope-To: dri-devel@lists.freedesktop.org X-Envelope-To: sui.jingfeng@linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Sui Jingfeng To: Lucas Stach Cc: Russell King , Christian Gmeiner , linux-kernel@vger.kernel.org, etnaviv@lists.freedesktop.org, dri-devel@lists.freedesktop.org, Sui Jingfeng Subject: [etnaviv-next v14 7/8] drm/etnaviv: Allow creating subdevices and pass platform specific data Date: Mon, 20 May 2024 00:53:20 +0800 Message-Id: <20240519165321.2123356-8-sui.jingfeng@linux.dev> In-Reply-To: <20240519165321.2123356-1-sui.jingfeng@linux.dev> References: <20240519165321.2123356-1-sui.jingfeng@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Because some hardware are too complex to be managed by a monolithic driver, a split of the functionality into child devices can helps to achieve better modularity. We will use this function to create subdevice as a repensentation of a single hardware ip block, so that the same modular approach that works for ARM-SoC can also works for PCIe cards. Signed-off-by: Sui Jingfeng Tested-by: Christian Gmeiner --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 33 +++++++++++++++++++++++---- drivers/gpu/drm/etnaviv/etnaviv_drv.h | 9 ++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnavi= v/etnaviv_drv.c index 863faac2ea19..dc3556aad134 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -670,16 +670,36 @@ static struct platform_driver etnaviv_platform_driver= =3D { }, }; =20 -static int etnaviv_create_platform_device(const char *name, - struct platform_device **ppdev) +int etnaviv_create_platform_device(struct device *parent, + const char *name, int id, + struct resource *pres, + void *data, + struct platform_device **ppdev) { struct platform_device *pdev; int ret; =20 - pdev =3D platform_device_alloc(name, PLATFORM_DEVID_NONE); + pdev =3D platform_device_alloc(name, id); if (!pdev) return -ENOMEM; =20 + pdev->dev.parent =3D parent; + + if (pres) { + ret =3D platform_device_add_resources(pdev, pres, 1); + if (ret) { + platform_device_put(pdev); + return ret; + } + } + + if (data) { + void *pdata =3D kmalloc(sizeof(void *), GFP_KERNEL); + + *(void **)pdata =3D data; + pdev->dev.platform_data =3D pdata; + } + ret =3D platform_device_add(pdev); if (ret) { platform_device_put(pdev); @@ -691,7 +711,7 @@ static int etnaviv_create_platform_device(const char *n= ame, return 0; } =20 -static void etnaviv_destroy_platform_device(struct platform_device **ppdev) +void etnaviv_destroy_platform_device(struct platform_device **ppdev) { struct platform_device *pdev =3D *ppdev; =20 @@ -728,7 +748,10 @@ static int __init etnaviv_init(void) if (np) { of_node_put(np); =20 - ret =3D etnaviv_create_platform_device("etnaviv", &etnaviv_drm); + ret =3D etnaviv_create_platform_device(NULL, "etnaviv", + PLATFORM_DEVID_NONE, + NULL, NULL, + &etnaviv_drm); if (ret) goto unregister_platform_driver; } diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnavi= v/etnaviv_drv.h index 4b59fdb457b7..4612843ff9f6 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -98,6 +99,14 @@ bool etnaviv_cmd_validate_one(struct etnaviv_gpu *gpu, u32 *stream, unsigned int size, struct drm_etnaviv_gem_submit_reloc *relocs, unsigned int reloc_size); =20 +int etnaviv_create_platform_device(struct device *parent, + const char *name, int id, + struct resource *pres, + void *data, + struct platform_device **ppdev); + +void etnaviv_destroy_platform_device(struct platform_device **ppdev); + #ifdef CONFIG_DEBUG_FS void etnaviv_gem_describe_objects(struct etnaviv_drm_private *priv, struct seq_file *m); --=20 2.34.1 From nobody Wed Feb 11 05:41:41 2026 Received: from out-185.mta0.migadu.com (out-185.mta0.migadu.com [91.218.175.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A35AE45979 for ; Sun, 19 May 2024 16:56:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137784; cv=none; b=YH9M3W4ZvMbQWfGMEBFRJDfqOQ0TIXFtpMbkiyYKSDHfQzSUiI3BRTaqRBhMbZ4nRoX9KxezyTEIe5al9SYVBQiO/Rd3YS749c6FttNVxWqXRyBw8mtq45GL27FG0z7A9J4CInTPiWYljOQfM1HPQze++n5Kc9FOrAkqR1taqU0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716137784; c=relaxed/simple; bh=k8kBfwr/tS4NEVIrA6MHQ1PbVNWQJaoN3iq9wpGQQ2Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NqnBbaVXA9Szg3DmOnQYC7/d0rEm5J1Em5POIUyol+c9pFs3jBYDpaAcEq1SCwyOU8Taz4lE1gbm3kUPcGw3Kv7El/QX3zjqyvw0CSr3S0xHTTtJJnX0jHrjpiBpKKL1Zuhut6p2zF3zljjgw+ATp9tx5ZUGDNwYbrn2J0JgLow= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=T6oBLJen; arc=none smtp.client-ip=91.218.175.185 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="T6oBLJen" X-Envelope-To: l.stach@pengutronix.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1716137780; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lv5jd6YpkxTgUWKKDJB7a8iSYY106QolNH90JNd3E68=; b=T6oBLJen2ATEOekueDtdB73oWxqXFf5EZl9koIGBL+W74DmXuZw+lDsSDG9KLHYJktRSpZ 5Tn3BJYgPfM8/Q6xVQVE3dRJop+PqnZ3v646/cb+GYObD5wc32uMNwl75UckGGWJFnmle0 oxTv7rDGEbyuXSO9sudc5PrPo4rG2uA= X-Envelope-To: linux+etnaviv@armlinux.org.uk X-Envelope-To: christian.gmeiner@gmail.com X-Envelope-To: linux-kernel@vger.kernel.org X-Envelope-To: etnaviv@lists.freedesktop.org X-Envelope-To: dri-devel@lists.freedesktop.org X-Envelope-To: sui.jingfeng@linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Sui Jingfeng To: Lucas Stach Cc: Russell King , Christian Gmeiner , linux-kernel@vger.kernel.org, etnaviv@lists.freedesktop.org, dri-devel@lists.freedesktop.org, Sui Jingfeng Subject: [etnaviv-next v14 8/8] drm/etnaviv: Add support for vivante GPU cores attached via PCIe device Date: Mon, 20 May 2024 00:53:21 +0800 Message-Id: <20240519165321.2123356-9-sui.jingfeng@linux.dev> In-Reply-To: <20240519165321.2123356-1-sui.jingfeng@linux.dev> References: <20240519165321.2123356-1-sui.jingfeng@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Previouly, the component framework is being used to bind multiple platform GPU devices to a virtual master. The virtual master is manually created by the driver, and is also a platform device. This is fine and works well for various SoCs, yet there some hardware venders integrate Vivante GPU cores into PCIe card and the driver lacks the support for PCIe devices. Create virtual platform devices as a representation for each GPU IP core, the manually created platform devices are functional as subcomponent, and all of them are child of the PCIe master device. The master is real for PCIe devices, as the PCIe device has already been created by the time the etnaviv.ko is loaded. Hence, bind all of the virtual child to the real master, this design reflects the hardware layout perfectly and is extensible. Signed-off-by: Sui Jingfeng Tested-by: Christian Gmeiner --- drivers/gpu/drm/etnaviv/Kconfig | 9 ++ drivers/gpu/drm/etnaviv/Makefile | 2 + drivers/gpu/drm/etnaviv/etnaviv_drv.c | 12 +- drivers/gpu/drm/etnaviv/etnaviv_drv.h | 2 + drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 75 ++++++++-- drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 4 + drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c | 161 ++++++++++++++++++++++ drivers/gpu/drm/etnaviv/etnaviv_pci_drv.h | 44 ++++++ 8 files changed, 293 insertions(+), 16 deletions(-) create mode 100644 drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c create mode 100644 drivers/gpu/drm/etnaviv/etnaviv_pci_drv.h diff --git a/drivers/gpu/drm/etnaviv/Kconfig b/drivers/gpu/drm/etnaviv/Kcon= fig index faa7fc68b009..7cb44f72d512 100644 --- a/drivers/gpu/drm/etnaviv/Kconfig +++ b/drivers/gpu/drm/etnaviv/Kconfig @@ -15,6 +15,15 @@ config DRM_ETNAVIV help DRM driver for Vivante GPUs. =20 +config DRM_ETNAVIV_PCI_DRIVER + bool "enable ETNAVIV PCI driver support" + depends on DRM_ETNAVIV + depends on PCI + default n + help + Compile in support for Vivante GPUs attached via PCIe card. + Say Y if you have such hardwares. + config DRM_ETNAVIV_THERMAL bool "enable ETNAVIV thermal throttling" depends on DRM_ETNAVIV diff --git a/drivers/gpu/drm/etnaviv/Makefile b/drivers/gpu/drm/etnaviv/Mak= efile index 46e5ffad69a6..6829e1ebf2db 100644 --- a/drivers/gpu/drm/etnaviv/Makefile +++ b/drivers/gpu/drm/etnaviv/Makefile @@ -16,4 +16,6 @@ etnaviv-y :=3D \ etnaviv_perfmon.o \ etnaviv_sched.o =20 +etnaviv-$(CONFIG_DRM_ETNAVIV_PCI_DRIVER) +=3D etnaviv_pci_drv.o + obj-$(CONFIG_DRM_ETNAVIV) +=3D etnaviv.o diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnavi= v/etnaviv_drv.c index dc3556aad134..90ee60b00c24 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -24,6 +24,7 @@ #include "etnaviv_gpu.h" #include "etnaviv_gem.h" #include "etnaviv_mmu.h" +#include "etnaviv_pci_drv.h" #include "etnaviv_perfmon.h" =20 /* @@ -568,6 +569,10 @@ static int etnaviv_bind(struct device *dev) if (ret < 0) goto out_free_priv; =20 + ret =3D etnaviv_register_irq_handler(dev, priv); + if (ret) + goto out_unbind; + load_gpu(drm); =20 ret =3D drm_dev_register(drm, 0); @@ -596,7 +601,7 @@ static void etnaviv_unbind(struct device *dev) etnaviv_private_fini(priv); } =20 -static const struct component_master_ops etnaviv_master_ops =3D { +const struct component_master_ops etnaviv_master_ops =3D { .bind =3D etnaviv_bind, .unbind =3D etnaviv_unbind, }; @@ -740,6 +745,10 @@ static int __init etnaviv_init(void) if (ret !=3D 0) goto unregister_gpu_driver; =20 + ret =3D etnaviv_register_pci_driver(); + if (ret) + goto unregister_platform_driver; + /* * If the DT contains at least one available GPU device, instantiate * the DRM platform device. @@ -769,6 +778,7 @@ module_init(etnaviv_init); static void __exit etnaviv_exit(void) { etnaviv_destroy_platform_device(&etnaviv_drm); + etnaviv_unregister_pci_driver(); platform_driver_unregister(&etnaviv_platform_driver); platform_driver_unregister(&etnaviv_gpu_driver); } diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnavi= v/etnaviv_drv.h index 4612843ff9f6..6db26d384cbe 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -27,6 +27,8 @@ struct etnaviv_gem_object; struct etnaviv_gem_submit; struct etnaviv_iommu_global; =20 +extern const struct component_master_ops etnaviv_master_ops; + #define ETNAVIV_SOFTPIN_START_ADDRESS SZ_4M /* must be >=3D SUBALLOC_SIZE = */ =20 struct etnaviv_file_private { diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnavi= v/etnaviv_gpu.c index 3a14e187388a..2b5955693fbb 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,7 @@ =20 static const struct platform_device_id gpu_ids[] =3D { { .name =3D "etnaviv-gpu,2d" }, + { .name =3D "etnaviv-gpu,3d" }, { }, }; =20 @@ -1543,14 +1545,22 @@ static void dump_mmu_fault(struct etnaviv_gpu *gpu) =20 static irqreturn_t irq_handler(int irq, void *data) { - struct etnaviv_gpu *gpu =3D data; + struct etnaviv_drm_private *priv =3D data; irqreturn_t ret =3D IRQ_NONE; + int i; =20 - u32 intr =3D gpu_read(gpu, VIVS_HI_INTR_ACKNOWLEDGE); - - if (intr !=3D 0) { + for (i =3D 0; i < priv->num_gpus; i++) { + struct etnaviv_gpu *gpu =3D priv->gpu[i]; + u32 intr; int event; =20 + if (!gpu) + continue; + + intr =3D gpu_read(gpu, VIVS_HI_INTR_ACKNOWLEDGE); + if (!intr) + continue; + pm_runtime_mark_last_busy(gpu->dev); =20 dev_dbg(gpu->dev, "intr 0x%08x\n", intr); @@ -1881,10 +1891,44 @@ static const struct of_device_id etnaviv_gpu_match[= ] =3D { }; MODULE_DEVICE_TABLE(of, etnaviv_gpu_match); =20 +/* + * dev point to the master. For platform device, it is virtual. + * For PCI(e) device, it is real. + */ +int etnaviv_register_irq_handler(struct device *dev, + struct etnaviv_drm_private *priv) +{ + bool is_pci =3D dev_is_pci(dev); + int ret =3D 0; + + if (is_pci) { + struct pci_dev *pdev =3D to_pci_dev(dev); + + ret =3D request_irq(pdev->irq, irq_handler, IRQF_SHARED, + dev_name(dev), priv); + } else { + int i; + + for (i =3D 0; i < priv->num_gpus; i++) { + struct etnaviv_gpu *gpu =3D priv->gpu[i]; + + ret =3D devm_request_irq(gpu->dev, gpu->irq, irq_handler, + 0, dev_name(dev), priv); + if (ret) { + dev_err(dev, "failed to request IRQ handler: %d\n", ret); + break; + } + } + } + + return ret; +} + static int etnaviv_gpu_platform_probe(struct platform_device *pdev) { struct device *dev =3D &pdev->dev; struct etnaviv_gpu *gpu; + bool is_pci; int err; =20 gpu =3D devm_kzalloc(dev, sizeof(*gpu), GFP_KERNEL); @@ -1900,22 +1944,23 @@ static int etnaviv_gpu_platform_probe(struct platfo= rm_device *pdev) if (IS_ERR(gpu->mmio)) return PTR_ERR(gpu->mmio); =20 + is_pci =3D dev->parent ? dev_is_pci(dev->parent) : false; + /* Get Interrupt: */ - gpu->irq =3D platform_get_irq(pdev, 0); + if (is_pci) + gpu->irq =3D to_pci_dev(dev->parent)->irq; + else + gpu->irq =3D platform_get_irq(pdev, 0); + if (gpu->irq < 0) return gpu->irq; =20 - err =3D devm_request_irq(dev, gpu->irq, irq_handler, 0, - dev_name(dev), gpu); - if (err) { - dev_err(dev, "failed to request IRQ%u: %d\n", gpu->irq, err); - return err; - } - /* Get Clocks: */ - err =3D etnaviv_gpu_clk_get(gpu); - if (err) - return err; + if (!is_pci) { + err =3D etnaviv_gpu_clk_get(gpu); + if (err) + return err; + } =20 /* TODO: figure out max mapped size */ dev_set_drvdata(dev, gpu); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnavi= v/etnaviv_gpu.h index 197e0037732e..78222f62725f 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h @@ -196,6 +196,10 @@ static inline u32 gpu_read_power(struct etnaviv_gpu *g= pu, u32 reg) int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value); =20 int etnaviv_gpu_init(struct etnaviv_gpu *gpu); + +int etnaviv_register_irq_handler(struct device *dev, + struct etnaviv_drm_private *priv); + bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu); =20 #ifdef CONFIG_DEBUG_FS diff --git a/drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c b/drivers/gpu/drm/et= naviv/etnaviv_pci_drv.c new file mode 100644 index 000000000000..9d505bfead1f --- /dev/null +++ b/drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include + +#include "etnaviv_drv.h" +#include "etnaviv_pci_drv.h" + +static const struct etnaviv_pci_gpu_data +gccore_platform_data[GCCORE_PCI_CHIP_ID_LAST] =3D { + { + .chip_id =3D GCCORE_PCI_CHIP_ID_UNKNOWN, + }, + { + .chip_id =3D JM9100, + .num_core =3D 1, + .num_vram =3D 2, + .vram_bars =3D {0, 2}, + .mmio_bar =3D 1, + .ip_block =3D {{0, 0x00900000, 0x00010000, "etnaviv-gpu,3d"},}, + .has_dedicated_vram =3D true, + .market_name =3D "JingJia Micro JM9100", + }, + { + .chip_id =3D JD9230P, + .num_core =3D 2, + .num_vram =3D 2, + .vram_bars =3D {0, 2}, + .mmio_bar =3D 1, + .ip_block =3D {{0, 0x00900000, 0x00010000, "etnaviv-gpu,3d"}, + {1, 0x00910000, 0x00010000, "etnaviv-gpu,3d"},}, + .has_dedicated_vram =3D true, + .market_name =3D "JingJia Micro JD9230P", + }, + { + .chip_id =3D GP102, + .num_core =3D 2, + .num_vram =3D 1, + .vram_bars =3D {0,}, + .mmio_bar =3D 2, + .ip_block =3D {{0, 0x00040000, 0x00010000, "etnaviv-gpu,3d"}, + {0, 0x000C0000, 0x00010000, "etnaviv-gpu,2d"},}, + .has_dedicated_vram =3D true, + .market_name =3D "LingJiu GP102", + }, +}; + +static const struct etnaviv_pci_gpu_data * +etnaviv_pci_get_platform_data(const struct pci_device_id *entity) +{ + enum etnaviv_pci_chip_id chip_id =3D entity->driver_data; + + if (chip_id =3D=3D GCCORE_PCI_CHIP_ID_UNKNOWN || + chip_id >=3D GCCORE_PCI_CHIP_ID_LAST) + return NULL; + + return &gccore_platform_data[chip_id]; +} + +static int etnaviv_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + const struct etnaviv_pci_gpu_data *pdata; + struct device *dev =3D &pdev->dev; + struct component_match *matches =3D NULL; + unsigned int i; + unsigned int num_core; + int ret; + + ret =3D pcim_enable_device(pdev); + if (ret) + return ret; + + pci_set_master(pdev); + + ret =3D dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (ret) + return ret; + + pdata =3D etnaviv_pci_get_platform_data(ent); + if (!pdata) + return -ENODEV; + + num_core =3D pdata->num_core; + + dev_info(dev, "%s has %u GPU cores\n", pdata->market_name, num_core); + + for (i =3D 0; i < num_core; i++) { + const struct vivante_gc_ip_block *pblock =3D &pdata->ip_block[i]; + struct platform_device *virtual_child; + resource_size_t start; + struct resource res; + + start =3D pci_resource_start(pdev, pdata->mmio_bar); + memset(&res, 0, sizeof(res)); + res.flags =3D IORESOURCE_MEM; + res.name =3D "register"; + res.start =3D start + pblock->offset; + res.end =3D start + pblock->offset + pblock->size - 1; + + ret =3D etnaviv_create_platform_device(dev, + pblock->compatible, + pblock->id, + &res, + (void *)pdata, + &virtual_child); + if (ret) + return ret; + + component_match_add(dev, &matches, component_compare_dev, + &virtual_child->dev); + } + + return component_master_add_with_match(dev, &etnaviv_master_ops, matches); +} + +static int platform_device_remove_callback(struct device *dev, void *data) +{ + struct platform_device *pdev =3D to_platform_device(dev); + + etnaviv_destroy_platform_device(&pdev); + + return 0; +} + +static void etnaviv_pci_remove(struct pci_dev *pdev) +{ + struct device *dev =3D &pdev->dev; + + component_master_del(dev, &etnaviv_master_ops); + + device_for_each_child(dev, NULL, platform_device_remove_callback); + + pci_clear_master(pdev); +} + +static const struct pci_device_id etnaviv_pci_id_list[] =3D { + {0x0731, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, JM9100}, + {0x0731, 0x9230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, JD9230P}, + {0x0709, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GP102}, + { } +}; + +static struct pci_driver etnaviv_pci_driver =3D { + .name =3D "etnaviv", + .id_table =3D etnaviv_pci_id_list, + .probe =3D etnaviv_pci_probe, + .remove =3D etnaviv_pci_remove, +}; + +int etnaviv_register_pci_driver(void) +{ + return pci_register_driver(&etnaviv_pci_driver); +} + +void etnaviv_unregister_pci_driver(void) +{ + pci_unregister_driver(&etnaviv_pci_driver); +} + +MODULE_DEVICE_TABLE(pci, etnaviv_pci_id_list); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_pci_drv.h b/drivers/gpu/drm/et= naviv/etnaviv_pci_drv.h new file mode 100644 index 000000000000..6782481a0c0b --- /dev/null +++ b/drivers/gpu/drm/etnaviv/etnaviv_pci_drv.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ETNAVIV_PCI_DRV_H__ +#define __ETNAVIV_PCI_DRV_H__ + +#ifdef CONFIG_DRM_ETNAVIV_PCI_DRIVER + +enum etnaviv_pci_chip_id { + GCCORE_PCI_CHIP_ID_UNKNOWN =3D 0, + JM9100 =3D 1, + JD9230P =3D 2, + GP102 =3D 3, + GCCORE_PCI_CHIP_ID_LAST, +}; + +struct vivante_gc_ip_block { + u32 id; + u32 offset; + u32 size; + char compatible[20]; +}; + +struct etnaviv_pci_gpu_data { + enum etnaviv_pci_chip_id chip_id; + u32 num_core; + u32 num_vram; + u32 vram_bars[2]; + u32 mmio_bar; + struct vivante_gc_ip_block ip_block[ETNA_MAX_PIPES]; + bool has_dedicated_vram; + char market_name[24]; +}; + +int etnaviv_register_pci_driver(void); +void etnaviv_unregister_pci_driver(void); + +#else + +static inline int etnaviv_register_pci_driver(void) { return 0; } +static inline void etnaviv_unregister_pci_driver(void) { } + +#endif + +#endif --=20 2.34.1