Skip to content

Commit 55d42f6

Browse files
Pratap Nirujogialexdeucher
authored andcommitted
drm/amd/amdgpu: Add helper functions for isp buffers
Accessing amdgpu internal data structures "struct amdgpu_device" and "struct amdgpu_bo" in ISP V4L2 driver to alloc/free GART buffers is not recommended. Add new amdgpu_isp helper functions that takes opaque params from ISP V4L2 driver and calls the amdgpu internal functions amdgpu_bo_create_isp_user() and amdgpu_bo_create_kernel() to alloc/free GART buffers. Reviewed-by: Mario Limonciello <[email protected]> Signed-off-by: Pratap Nirujogi <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent e36519f commit 55d42f6

File tree

4 files changed

+227
-10
lines changed

4 files changed

+227
-10
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_isp.c

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include "isp_v4_1_0.h"
3434
#include "isp_v4_1_1.h"
3535

36+
#define ISP_MC_ADDR_ALIGN (1024 * 32)
37+
3638
/**
3739
* isp_hw_init - start and test isp block
3840
*
@@ -141,6 +143,179 @@ static int isp_set_powergating_state(struct amdgpu_ip_block *ip_block,
141143
return 0;
142144
}
143145

146+
static int is_valid_isp_device(struct device *isp_parent, struct device *amdgpu_dev)
147+
{
148+
if (isp_parent != amdgpu_dev)
149+
return -EINVAL;
150+
151+
return 0;
152+
}
153+
154+
/**
155+
* isp_user_buffer_alloc - create user buffer object (BO) for isp
156+
*
157+
* @dev: isp device handle
158+
* @dmabuf: DMABUF handle for isp buffer allocated in system memory
159+
* @buf_obj: GPU buffer object handle to initialize
160+
* @buf_addr: GPU addr of the pinned BO to initialize
161+
*
162+
* Imports isp DMABUF to allocate and pin a user BO for isp internal use. It does
163+
* GART alloc to generate GPU addr for BO to make it accessible through the
164+
* GART aperture for ISP HW.
165+
*
166+
* This function is exported to allow the V4L2 isp device external to drm device
167+
* to create and access the isp user BO.
168+
*
169+
* Returns:
170+
* 0 on success, negative error code otherwise.
171+
*/
172+
int isp_user_buffer_alloc(struct device *dev, void *dmabuf,
173+
void **buf_obj, u64 *buf_addr)
174+
{
175+
struct platform_device *ispdev = to_platform_device(dev);
176+
const struct isp_platform_data *isp_pdata;
177+
struct amdgpu_device *adev;
178+
struct mfd_cell *mfd_cell;
179+
struct amdgpu_bo *bo;
180+
u64 gpu_addr;
181+
int ret;
182+
183+
if (WARN_ON(!ispdev))
184+
return -ENODEV;
185+
186+
if (WARN_ON(!buf_obj))
187+
return -EINVAL;
188+
189+
if (WARN_ON(!buf_addr))
190+
return -EINVAL;
191+
192+
mfd_cell = &ispdev->mfd_cell[0];
193+
if (!mfd_cell)
194+
return -ENODEV;
195+
196+
isp_pdata = mfd_cell->platform_data;
197+
adev = isp_pdata->adev;
198+
199+
ret = is_valid_isp_device(ispdev->dev.parent, adev->dev);
200+
if (ret)
201+
return ret;
202+
203+
ret = amdgpu_bo_create_isp_user(adev, dmabuf,
204+
AMDGPU_GEM_DOMAIN_GTT, &bo, &gpu_addr);
205+
if (ret) {
206+
drm_err(&adev->ddev, "failed to alloc gart user buffer (%d)", ret);
207+
return ret;
208+
}
209+
210+
*buf_obj = (void *)bo;
211+
*buf_addr = gpu_addr;
212+
213+
return 0;
214+
}
215+
EXPORT_SYMBOL(isp_user_buffer_alloc);
216+
217+
/**
218+
* isp_user_buffer_free - free isp user buffer object (BO)
219+
*
220+
* @buf_obj: amdgpu isp user BO to free
221+
*
222+
* unpin and unref BO for isp internal use.
223+
*
224+
* This function is exported to allow the V4L2 isp device
225+
* external to drm device to free the isp user BO.
226+
*/
227+
void isp_user_buffer_free(void *buf_obj)
228+
{
229+
amdgpu_bo_free_isp_user(buf_obj);
230+
}
231+
EXPORT_SYMBOL(isp_user_buffer_free);
232+
233+
/**
234+
* isp_kernel_buffer_alloc - create kernel buffer object (BO) for isp
235+
*
236+
* @dev: isp device handle
237+
* @size: size for the new BO
238+
* @buf_obj: GPU BO handle to initialize
239+
* @gpu_addr: GPU addr of the pinned BO
240+
* @cpu_addr: CPU address mapping of BO
241+
*
242+
* Allocates and pins a kernel BO for internal isp firmware use.
243+
*
244+
* This function is exported to allow the V4L2 isp device
245+
* external to drm device to create and access the kernel BO.
246+
*
247+
* Returns:
248+
* 0 on success, negative error code otherwise.
249+
*/
250+
int isp_kernel_buffer_alloc(struct device *dev, u64 size,
251+
void **buf_obj, u64 *gpu_addr, void **cpu_addr)
252+
{
253+
struct platform_device *ispdev = to_platform_device(dev);
254+
struct amdgpu_bo **bo = (struct amdgpu_bo **)buf_obj;
255+
const struct isp_platform_data *isp_pdata;
256+
struct amdgpu_device *adev;
257+
struct mfd_cell *mfd_cell;
258+
int ret;
259+
260+
if (WARN_ON(!ispdev))
261+
return -ENODEV;
262+
263+
if (WARN_ON(!buf_obj))
264+
return -EINVAL;
265+
266+
if (WARN_ON(!gpu_addr))
267+
return -EINVAL;
268+
269+
if (WARN_ON(!cpu_addr))
270+
return -EINVAL;
271+
272+
mfd_cell = &ispdev->mfd_cell[0];
273+
if (!mfd_cell)
274+
return -ENODEV;
275+
276+
isp_pdata = mfd_cell->platform_data;
277+
adev = isp_pdata->adev;
278+
279+
ret = is_valid_isp_device(ispdev->dev.parent, adev->dev);
280+
if (ret)
281+
return ret;
282+
283+
ret = amdgpu_bo_create_kernel(adev,
284+
size,
285+
ISP_MC_ADDR_ALIGN,
286+
AMDGPU_GEM_DOMAIN_GTT,
287+
bo,
288+
gpu_addr,
289+
cpu_addr);
290+
if (!cpu_addr || ret) {
291+
drm_err(&adev->ddev, "failed to alloc gart kernel buffer (%d)", ret);
292+
return ret;
293+
}
294+
295+
return 0;
296+
}
297+
EXPORT_SYMBOL(isp_kernel_buffer_alloc);
298+
299+
/**
300+
* isp_kernel_buffer_free - free isp kernel buffer object (BO)
301+
*
302+
* @buf_obj: amdgpu isp user BO to free
303+
* @gpu_addr: GPU addr of isp kernel BO
304+
* @cpu_addr: CPU addr of isp kernel BO
305+
*
306+
* unmaps and unpin a isp kernel BO.
307+
*
308+
* This function is exported to allow the V4L2 isp device
309+
* external to drm device to free the kernel BO.
310+
*/
311+
void isp_kernel_buffer_free(void **buf_obj, u64 *gpu_addr, void **cpu_addr)
312+
{
313+
struct amdgpu_bo **bo = (struct amdgpu_bo **)buf_obj;
314+
315+
amdgpu_bo_free_kernel(bo, gpu_addr, cpu_addr);
316+
}
317+
EXPORT_SYMBOL(isp_kernel_buffer_free);
318+
144319
static const struct amd_ip_funcs isp_ip_funcs = {
145320
.name = "isp_ip",
146321
.early_init = isp_early_init,

drivers/gpu/drm/amd/amdgpu/amdgpu_isp.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,13 @@
2828
#ifndef __AMDGPU_ISP_H__
2929
#define __AMDGPU_ISP_H__
3030

31+
#include <drm/amd/isp.h>
3132
#include <linux/pm_domain.h>
3233

3334
#define ISP_REGS_OFFSET_END 0x629A4
3435

3536
struct amdgpu_isp;
3637

37-
struct isp_platform_data {
38-
void *adev;
39-
u32 asic_type;
40-
resource_size_t base_rmmio_size;
41-
};
42-
4338
struct isp_funcs {
4439
int (*hw_init)(struct amdgpu_isp *isp);
4540
int (*hw_fini)(struct amdgpu_isp *isp);

drivers/gpu/drm/amd/amdgpu/amdgpu_object.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,6 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
352352

353353
return 0;
354354
}
355-
EXPORT_SYMBOL(amdgpu_bo_create_kernel);
356355

357356
/**
358357
* amdgpu_bo_create_isp_user - create user BO for isp
@@ -421,7 +420,6 @@ int amdgpu_bo_create_isp_user(struct amdgpu_device *adev,
421420

422421
return r;
423422
}
424-
EXPORT_SYMBOL(amdgpu_bo_create_isp_user);
425423

426424
/**
427425
* amdgpu_bo_create_kernel_at - create BO for kernel use at specific location
@@ -525,7 +523,6 @@ void amdgpu_bo_free_kernel(struct amdgpu_bo **bo, u64 *gpu_addr,
525523
if (cpu_addr)
526524
*cpu_addr = NULL;
527525
}
528-
EXPORT_SYMBOL(amdgpu_bo_free_kernel);
529526

530527
/**
531528
* amdgpu_bo_free_isp_user - free BO for isp use
@@ -548,7 +545,6 @@ void amdgpu_bo_free_isp_user(struct amdgpu_bo *bo)
548545
}
549546
amdgpu_bo_unref(&bo);
550547
}
551-
EXPORT_SYMBOL(amdgpu_bo_free_isp_user);
552548

553549
/* Validate bo size is bit bigger than the request domain */
554550
static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,

include/drm/amd/isp.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/* SPDX-License-Identifier: MIT */
2+
/*
3+
* Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.
4+
* All Rights Reserved.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a
7+
* copy of this software and associated documentation files (the
8+
* "Software"), to deal in the Software without restriction, including
9+
* without limitation the rights to use, copy, modify, merge, publish,
10+
* distribute, sub license, and/or sell copies of the Software, and to
11+
* permit persons to whom the Software is furnished to do so, subject to
12+
* the following conditions:
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17+
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18+
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
* USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
*
22+
* The above copyright notice and this permission notice (including the
23+
* next paragraph) shall be included in all copies or substantial portions
24+
* of the Software.
25+
*
26+
*/
27+
28+
#ifndef __ISP_H__
29+
#define __ISP_H__
30+
31+
#include <linux/types.h>
32+
33+
struct device;
34+
35+
struct isp_platform_data {
36+
void *adev;
37+
u32 asic_type;
38+
resource_size_t base_rmmio_size;
39+
};
40+
41+
int isp_user_buffer_alloc(struct device *dev, void *dmabuf,
42+
void **buf_obj, u64 *buf_addr);
43+
44+
void isp_user_buffer_free(void *buf_obj);
45+
46+
int isp_kernel_buffer_alloc(struct device *dev, u64 size,
47+
void **buf_obj, u64 *gpu_addr, void **cpu_addr);
48+
49+
void isp_kernel_buffer_free(void **buf_obj, u64 *gpu_addr, void **cpu_addr);
50+
51+
#endif

0 commit comments

Comments
 (0)