From nobody Tue Feb 10 16:44:04 2026 Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CC7EA253938; Fri, 6 Jun 2025 06:29:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749191348; cv=none; b=lUJoKyA+i2dDN4dreqBmu/LBrat+RLB5oK+gEzMIKTYDgl48krmWYzB66VXTsYGdrbN31UcXpGk2DxILCsQD5coSa5K981NaYkA09g5Jx4/v4TxM7WxnCq4NAnbTmEMv6B9Eu8N8UNRWOWmKE0LmWfs0IHcE7eul1vN/Y4RuqA8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749191348; c=relaxed/simple; bh=spCVFQM0RS8RX5HT/4i0I/ZaBCGQIczl+NtnKVG+l2k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LOnhh+AuRTI6gVoG1ULW7xiT7Bj2HQiDHBiq7geEJwTkUUoDYoTGzIbaRrlOkPgC0heqdf2i4JwMqAlIHQPO8ugb/8E6iElehw6k0G6vuTvdsmW1HHshLSsdQ4c3mAVHqo7DFWfwP7pi6mUMh0WFGBK50aQHoyf46cOVZV3u2bU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tomeuvizoso.net; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.218.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tomeuvizoso.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-adb5fd85996so339697366b.2; Thu, 05 Jun 2025 23:29:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749191345; x=1749796145; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4hhddfXDfku9i7J1TvbwOFygxBDLs6NnmsiXqGK3WQo=; b=AtJsJVcVC8t0n8WvnHGxblrdaZlPYMMIm4CK9PrZEH2haHhO7lA8BfNaqvnPxPfVMH 6/jjDu7m0ZR+iYy/Vlxyw6BQt2kEHIbTA50ghKwKpG+botiSOuemLBEXxi5dcPOfI4BE CGl8cORGAxqGyVggmW1zVlOrrLyZSJIcxjKtWjwfc/HsYNzxs2KUbh53iNBLWT9WE9wB W5ZcjcBbIhb2gxbH1AEL+TjbtWxA5HBfRmAEm0NKLMM5bxZ1higjIBwCI88N4v+J+PZY QzG8T4Fk/MKvEWzxHt2JqK0pF4+bYw9do4jx3MZ3e/e/03qj0ziMEvsLNN/IpcfIyf3u xjsA== X-Forwarded-Encrypted: i=1; AJvYcCUfGFAP8IvO1r9uprybB5VkGD1yT94nhVAyp4OmnxQFVGa3QFP8fnZo2MWGrrdXdSl6hQGgOqw8YL/w2Jvz@vger.kernel.org, AJvYcCVSvi/qKda9AdgJhv3nJy0rBBoolBhz+25rQ9ZWhZaSgOfnTiQiZOC+pXtWS9uBoOXT25bayu02RtDCW5Q=@vger.kernel.org, AJvYcCWjcEKgicaVDWeDQNFWf5+Bz1SsdOjPzyfnI3Vq43uhi/lCHLN0N7544kHagET+FFNsSC5qhNYSYS0=@vger.kernel.org X-Gm-Message-State: AOJu0YxWi249gIQLz67+EOVyzdmf5sq4TGJCT7y2BhDBKFYbwTrFfJOc ad8kQtTBKHiVRiaTQQUm2XfkU0CHbKaGAj9e9qE5d88sOwQKj0TGrN2o X-Gm-Gg: ASbGnctAbI43OJnvQNqpWkcIHf0Em1zgzDx31XP6nXQRW10pkDWDBFzyNr4MLyxf1OW BKmY65gtd8QvU+ZXfiBgjCl39eiOM4i2kM6F60ESxups5yhToX8MiMa/EYWsvFvwJmTwj9YAcjt 9iedbTi7QuPIrJgXGwAHlfaJ2FzJdnLXgDM+rXXjRiG5YR0egCcfQ/KomS7lf3WIB1T8Z+wWupP tEhTgC33fQ3YFCfx0WMB49sepwtwtRE1Fx/ghqMYIk0+jR3RdeCoKnLkS/V9th9nRHbQlw/jxeS /ETg69N7kC2k/2etoqMfmp1uj/+HCn+80nUUFFW7K0nSZLTkly1iGAOrYwMMxk9ORKtC1z5HWUR oEjlXAPF3up/9r53HoI/4 X-Google-Smtp-Source: AGHT+IF0kxEjRZKTJ5Isl9wd00bAvRzmf0g2DA8yKPRdTtooV62OfCm5lLjAbaXv/OYSPuoOw9Ifiw== X-Received: by 2002:a17:907:fdca:b0:ad2:549b:4c8d with SMTP id a640c23a62f3a-ade1aa46a4bmr190952566b.51.1749191344875; Thu, 05 Jun 2025 23:29:04 -0700 (PDT) Received: from [10.42.0.1] (cst-prg-46-162.cust.vodafone.cz. [46.135.46.162]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ade1d754653sm67989966b.20.2025.06.05.23.29.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Jun 2025 23:29:04 -0700 (PDT) From: Tomeu Vizoso Date: Fri, 06 Jun 2025 08:28:25 +0200 Subject: [PATCH v7 05/10] accel/rocket: Add IOCTLs for synchronizing memory accesses Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250606-6-10-rocket-v7-5-dc16cfe6fe4e@tomeuvizoso.net> References: <20250606-6-10-rocket-v7-0-dc16cfe6fe4e@tomeuvizoso.net> In-Reply-To: <20250606-6-10-rocket-v7-0-dc16cfe6fe4e@tomeuvizoso.net> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Oded Gabbay , Jonathan Corbet , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Sebastian Reichel , Nicolas Frattaroli , Kever Yang , Robin Murphy , Daniel Stone , Da Xue , Jeff Hugo Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org, linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org, Tomeu Vizoso , Jeff Hugo X-Mailer: b4 0.14.2 The NPU cores have their own access to the memory bus, and this isn't cache coherent with the CPUs. Add IOCTLs so userspace can mark when the caches need to be flushed, and also when a writer job needs to be waited for before the buffer can be accessed from the CPU. Initially based on the same IOCTLs from the Etnaviv driver. v2: - Don't break UABI by reordering the IOCTL IDs (Jeff Hugo) v3: - Check that padding fields in IOCTLs are zero (Jeff Hugo) v6: - Fix conversion logic to make sure we use DMA_BIDIRECTIONAL when needed (Lucas Stach) Signed-off-by: Tomeu Vizoso Reviewed-by: Jeff Hugo --- drivers/accel/rocket/rocket_drv.c | 2 + drivers/accel/rocket/rocket_gem.c | 82 +++++++++++++++++++++++++++++++++++= ++++ drivers/accel/rocket/rocket_gem.h | 5 +++ include/uapi/drm/rocket_accel.h | 37 ++++++++++++++++++ 4 files changed, 126 insertions(+) diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocke= t_drv.c index 4ab78193c186dfcfc3e323f16c588e85e6a8a334..eb9284ee2511f730afe6a532225= c2706ce0e2822 100644 --- a/drivers/accel/rocket/rocket_drv.c +++ b/drivers/accel/rocket/rocket_drv.c @@ -62,6 +62,8 @@ static const struct drm_ioctl_desc rocket_drm_driver_ioct= ls[] =3D { =20 ROCKET_IOCTL(CREATE_BO, create_bo), ROCKET_IOCTL(SUBMIT, submit), + ROCKET_IOCTL(PREP_BO, prep_bo), + ROCKET_IOCTL(FINI_BO, fini_bo), }; =20 DEFINE_DRM_ACCEL_FOPS(rocket_accel_driver_fops); diff --git a/drivers/accel/rocket/rocket_gem.c b/drivers/accel/rocket/rocke= t_gem.c index 61b7f970a6885aa13784daa1222611a02aa10dee..07024b6e71bf544dc7f00b008b9= afb74b0c4e802 100644 --- a/drivers/accel/rocket/rocket_gem.c +++ b/drivers/accel/rocket/rocket_gem.c @@ -113,3 +113,85 @@ int rocket_ioctl_create_bo(struct drm_device *dev, voi= d *data, struct drm_file * =20 return ret; } + +static inline enum dma_data_direction rocket_op_to_dma_dir(u32 op) +{ + op &=3D ROCKET_PREP_READ | ROCKET_PREP_WRITE; + + if (op =3D=3D ROCKET_PREP_READ) + return DMA_FROM_DEVICE; + else if (op =3D=3D ROCKET_PREP_WRITE) + return DMA_TO_DEVICE; + else + return DMA_BIDIRECTIONAL; +} + +int rocket_ioctl_prep_bo(struct drm_device *dev, void *data, struct drm_fi= le *file) +{ + struct drm_rocket_prep_bo *args =3D data; + unsigned long timeout =3D drm_timeout_abs_to_jiffies(args->timeout_ns); + struct rocket_device *rdev =3D to_rocket_device(dev); + struct drm_gem_object *gem_obj; + struct drm_gem_shmem_object *shmem_obj; + bool write =3D !!(args->op & ROCKET_PREP_WRITE); + long ret =3D 0; + + if (args->op & ~(ROCKET_PREP_READ | ROCKET_PREP_WRITE)) + return -EINVAL; + + gem_obj =3D drm_gem_object_lookup(file, args->handle); + if (!gem_obj) + return -ENOENT; + + ret =3D dma_resv_wait_timeout(gem_obj->resv, dma_resv_usage_rw(write), + true, timeout); + if (!ret) + ret =3D timeout ? -ETIMEDOUT : -EBUSY; + + shmem_obj =3D &to_rocket_bo(gem_obj)->base; + + for (unsigned int core =3D 1; core < rdev->num_cores; core++) { + dma_sync_sgtable_for_cpu(rdev->cores[core].dev, shmem_obj->sgt, + rocket_op_to_dma_dir(args->op)); + } + + to_rocket_bo(gem_obj)->last_cpu_prep_op =3D args->op; + + drm_gem_object_put(gem_obj); + + return ret; +} + +int rocket_ioctl_fini_bo(struct drm_device *dev, void *data, struct drm_fi= le *file) +{ + struct rocket_device *rdev =3D to_rocket_device(dev); + struct drm_rocket_fini_bo *args =3D data; + struct drm_gem_shmem_object *shmem_obj; + struct rocket_gem_object *rkt_obj; + struct drm_gem_object *gem_obj; + + if (args->reserved !=3D 0) { + drm_dbg(dev, "Reserved field in drm_rocket_fini_bo struct should be 0.\n= "); + return -EINVAL; + } + + gem_obj =3D drm_gem_object_lookup(file, args->handle); + if (!gem_obj) + return -ENOENT; + + rkt_obj =3D to_rocket_bo(gem_obj); + shmem_obj =3D &rkt_obj->base; + + WARN_ON(rkt_obj->last_cpu_prep_op =3D=3D 0); + + for (unsigned int core =3D 1; core < rdev->num_cores; core++) { + dma_sync_sgtable_for_device(rdev->cores[core].dev, shmem_obj->sgt, + rocket_op_to_dma_dir(rkt_obj->last_cpu_prep_op)); + } + + rkt_obj->last_cpu_prep_op =3D 0; + + drm_gem_object_put(gem_obj); + + return 0; +} diff --git a/drivers/accel/rocket/rocket_gem.h b/drivers/accel/rocket/rocke= t_gem.h index e8a4d6213fd80419be2ec8af04583a67fb1a4b75..a52a63cd78339a6150b99592ab5= f94feeeb51fde 100644 --- a/drivers/accel/rocket/rocket_gem.h +++ b/drivers/accel/rocket/rocket_gem.h @@ -12,12 +12,17 @@ struct rocket_gem_object { struct iommu_domain *domain; size_t size; u32 offset; + u32 last_cpu_prep_op; }; =20 struct drm_gem_object *rocket_gem_create_object(struct drm_device *dev, si= ze_t size); =20 int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_= file *file); =20 +int rocket_ioctl_prep_bo(struct drm_device *dev, void *data, struct drm_fi= le *file); + +int rocket_ioctl_fini_bo(struct drm_device *dev, void *data, struct drm_fi= le *file); + static inline struct rocket_gem_object *to_rocket_bo(struct drm_gem_object *obj) { diff --git a/include/uapi/drm/rocket_accel.h b/include/uapi/drm/rocket_acce= l.h index cb1b5934c201160e7650aabd1b3a2b1c77b1fd7b..b5c80dd767be56e9720b51e4a82= 617a425a881a1 100644 --- a/include/uapi/drm/rocket_accel.h +++ b/include/uapi/drm/rocket_accel.h @@ -13,9 +13,13 @@ extern "C" { =20 #define DRM_ROCKET_CREATE_BO 0x00 #define DRM_ROCKET_SUBMIT 0x01 +#define DRM_ROCKET_PREP_BO 0x02 +#define DRM_ROCKET_FINI_BO 0x03 =20 #define DRM_IOCTL_ROCKET_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_ROCKET= _CREATE_BO, struct drm_rocket_create_bo) #define DRM_IOCTL_ROCKET_SUBMIT DRM_IOW(DRM_COMMAND_BASE + DRM_ROCKET_SU= BMIT, struct drm_rocket_submit) +#define DRM_IOCTL_ROCKET_PREP_BO DRM_IOW(DRM_COMMAND_BASE + DRM_ROCKET_PR= EP_BO, struct drm_rocket_prep_bo) +#define DRM_IOCTL_ROCKET_FINI_BO DRM_IOW(DRM_COMMAND_BASE + DRM_ROCKET_FI= NI_BO, struct drm_rocket_fini_bo) =20 /** * struct drm_rocket_create_bo - ioctl argument for creating Rocket BOs. @@ -39,6 +43,39 @@ struct drm_rocket_create_bo { __u64 offset; }; =20 +#define ROCKET_PREP_READ 0x01 +#define ROCKET_PREP_WRITE 0x02 + +/** + * struct drm_rocket_prep_bo - ioctl argument for starting CPU ownership o= f the BO. + * + * Takes care of waiting for any NPU jobs that might still use the NPU and= performs cache + * synchronization. + */ +struct drm_rocket_prep_bo { + /** Input: GEM handle of the buffer object. */ + __u32 handle; + + /** Input: mask of ROCKET_PREP_x, direction of the access. */ + __u32 op; + + /** Input: Amount of time to wait for NPU jobs. */ + __s64 timeout_ns; +}; + +/** + * struct drm_rocket_fini_bo - ioctl argument for finishing CPU ownership = of the BO. + * + * Synchronize caches for NPU access. + */ +struct drm_rocket_fini_bo { + /** Input: GEM handle of the buffer object. */ + __u32 handle; + + /** Reserved, must be zero. */ + __u32 reserved; +}; + /** * struct drm_rocket_task - A task to be run on the NPU * --=20 2.49.0