host1x_emu: Adding API dispatch functionality

Adding dynamic APi dispatch functionality in host1x-fence
modue. This CL exports new host1x wrapper API, which can
be called by client kernel modules. The wrapper API dispatch
call to either Host1x module or Host1x-EMU depending if the
host1x-emu driver registered its interface during its probe.

Bug 5064819

Change-Id: I49445cdce7c3795a2c94fde9d0871da393993554
Signed-off-by: amitabhd <amitabhd@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3306857
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Leslin Varghese <lvarghese@nvidia.com>
Reviewed-by: Raghavendra Vishnu Kumar <rvk@nvidia.com>
This commit is contained in:
amitabhd
2025-02-20 11:05:00 +00:00
committed by Jon Hunter
parent 1e83ec96df
commit 2cc3c99c6e
10 changed files with 764 additions and 8 deletions

View File

@@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: GPL-2.0-only
*/
#ifndef __HOST1X_DISPATCH_H
#define __HOST1X_DISPATCH_H
#include <linux/host1x-dispatch_api.h>
// fence.c
#define host1x_fence_create wrap_host1x_fence_create
#define host1x_fence_extract wrap_host1x_fence_extract
#define host1x_fence_cancel wrap_host1x_fence_cancel
#define host1x_syncpt_fence_scan wrap_host1x_syncpt_fence_scan
// Syncpt.c
#define host1x_get_dma_mask wrap_host1x_get_dma_mask
#define host1x_syncpt_get wrap_host1x_syncpt_get
#define host1x_syncpt_get_by_id wrap_host1x_syncpt_get_by_id
#define host1x_syncpt_get_by_id_noref wrap_host1x_syncpt_get_by_id_noref
#define host1x_syncpt_read wrap_host1x_syncpt_read
#define host1x_syncpt_read_min wrap_host1x_syncpt_read_min
#define host1x_syncpt_read_max wrap_host1x_syncpt_read_max
#define host1x_syncpt_incr wrap_host1x_syncpt_incr
#define host1x_syncpt_incr_max wrap_host1x_syncpt_incr_max
#define host1x_syncpt_alloc wrap_host1x_syncpt_alloc
#define host1x_syncpt_put wrap_host1x_syncpt_put
#define host1x_syncpt_id wrap_host1x_syncpt_id
#define host1x_syncpt_wait_ts wrap_host1x_syncpt_wait_ts
#define host1x_syncpt_wait wrap_host1x_syncpt_wait
#define host1x_fence_get_node wrap_host1x_fence_get_node
//nvhost.h
#define host1x_writel wrap_host1x_writel
#define nvhost_get_default_device wrap_nvhost_get_default_device
#define nvhost_get_host1x wrap_nvhost_get_host1x
#define nvhost_client_device_get_resources wrap_nvhost_client_device_get_resources
#define nvhost_client_device_init wrap_nvhost_client_device_init
#define nvhost_client_device_release wrap_nvhost_client_device_release
#define nvhost_get_syncpt_host_managed wrap_nvhost_get_syncpt_host_managed
#define nvhost_get_syncpt_client_managed wrap_nvhost_get_syncpt_client_managed
#define nvhost_get_syncpt_gpu_managed wrap_nvhost_get_syncpt_gpu_managed
#define nvhost_syncpt_put_ref_ext wrap_nvhost_syncpt_put_ref_ext
#define nvhost_syncpt_is_valid_pt_ext wrap_nvhost_syncpt_is_valid_pt_ext
#define nvhost_syncpt_is_expired_ext wrap_nvhost_syncpt_is_expired_ext
#define nvhost_syncpt_set_min_update wrap_nvhost_syncpt_set_min_update
#define nvhost_syncpt_read_ext_check wrap_nvhost_syncpt_read_ext_check
#define nvhost_syncpt_read_maxval wrap_nvhost_syncpt_read_maxval
#define nvhost_syncpt_incr_max_ext wrap_nvhost_syncpt_incr_max_ext
#define nvhost_syncpt_unit_interface_get_byte_offset_ext wrap_nvhost_syncpt_unit_interface_get_byte_offset_ext
#define nvhost_syncpt_unit_interface_get_byte_offset wrap_nvhost_syncpt_unit_interface_get_byte_offset
#define nvhost_syncpt_unit_interface_get_aperture wrap_nvhost_syncpt_unit_interface_get_aperture
#define nvhost_syncpt_unit_interface_init wrap_nvhost_syncpt_unit_interface_init
#define nvhost_syncpt_unit_interface_deinit wrap_nvhost_syncpt_unit_interface_deinit
#define nvhost_syncpt_address wrap_nvhost_syncpt_address
#define nvhost_intr_register_notifier wrap_nvhost_intr_register_notifier
#define nvhost_module_init wrap_nvhost_module_init
#define nvhost_module_deinit wrap_nvhost_module_deinit
#define nvhost_module_reset wrap_nvhost_module_reset
#define nvhost_module_busy wrap_nvhost_module_busy
#define nvhost_module_idle wrap_nvhost_module_idle
#define nvhost_module_idle_mult wrap_nvhost_module_idle_mult
#endif /*__HOST1X_DISPATCH_H */

View File

@@ -0,0 +1,150 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: GPL-2.0-only
*/
#ifndef __HOST1X_DISPATCH_API_H
#define __HOST1X_DISPATCH_API_H
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/dma-fence.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/timekeeping.h>
#define HOST1X_SYNCPT_CLIENT_MANAGED (1 << 0)
#define HOST1X_SYNCPT_HAS_BASE (1 << 1)
#define HOST1X_SYNCPT_GPU (1 << 2)
#define HOST1X_GLOBAL_TO_LOCAL_SYNCPOINT(global_syncpoint_id) \
(global_syncpoint_id & 0xFFFFFF)
#define HOST1X_INSTANCE_NUM_FROM_GLOBAL_SYNCPOINT(global_syncpoint_id) \
((global_syncpoint_id & 0xFF000000) >> 24)
#define HOST1X_LOCAL_TO_GLOBAL_SYNCPOINT(local_syncpoint_id, instance) \
((instance << 24) | (local_syncpoint_id))
#define HOST1X_EMU_EXPORT_CALL(...) wrap_ ## __VA_ARGS__
struct host1x;
struct host1x_syncpt;
// fence.c
struct dma_fence* wrap_host1x_fence_create(struct host1x_syncpt *sp,
u32 threshold,
bool timeout);
int wrap_host1x_fence_extract(struct dma_fence *dfence, u32 *id, u32 *threshold);
void wrap_host1x_fence_cancel(struct dma_fence *dfence);
void wrap_host1x_syncpt_fence_scan(struct host1x_syncpt *sp);
// Syncpt.c
u64 wrap_host1x_get_dma_mask(struct host1x *host1x);
struct host1x_syncpt* wrap_host1x_syncpt_get(
struct host1x_syncpt *sp);
struct host1x_syncpt* wrap_host1x_syncpt_get_by_id(
struct host1x *host, unsigned int id);
struct host1x_syncpt* wrap_host1x_syncpt_get_by_id_noref(struct host1x *host, unsigned int id);
u32 wrap_host1x_syncpt_read(struct host1x_syncpt *sp);
u32 wrap_host1x_syncpt_read_min(struct host1x_syncpt *sp);
u32 wrap_host1x_syncpt_read_max(struct host1x_syncpt *sp);
int wrap_host1x_syncpt_incr(struct host1x_syncpt *sp);
u32 wrap_host1x_syncpt_incr_max(struct host1x_syncpt *sp, u32 incrs);
struct host1x_syncpt* wrap_host1x_syncpt_alloc(struct host1x *host,
unsigned long flags,
const char *name);
void wrap_host1x_syncpt_put(struct host1x_syncpt *sp);
u32 wrap_host1x_syncpt_id(struct host1x_syncpt *sp);
int wrap_host1x_syncpt_wait_ts(struct host1x_syncpt *sp,
u32 thresh, long timeout, u32 *value, ktime_t *ts);
int wrap_host1x_syncpt_wait(struct host1x_syncpt *sp,
u32 thresh, long timeout, u32 *value);
int wrap_host1x_fence_get_node(struct dma_fence *fence);
//nvhost.h
void wrap_host1x_writel(struct platform_device *pdev, u32 r, u32 v);
struct platform_device* wrap_nvhost_get_default_device(void);
struct host1x* wrap_nvhost_get_host1x(struct platform_device *pdev);
int wrap_nvhost_client_device_get_resources(struct platform_device *pdev);
int wrap_nvhost_client_device_init(struct platform_device *pdev);
int wrap_nvhost_client_device_release(struct platform_device *pdev);
u32 wrap_nvhost_get_syncpt_host_managed(struct platform_device *pdev,
u32 param, const char *syncpt_name);
u32 wrap_nvhost_get_syncpt_client_managed(struct platform_device *pdev,
const char *syncpt_name);
u32 wrap_nvhost_get_syncpt_gpu_managed(struct platform_device *pdev,
const char *syncpt_name);
void wrap_nvhost_syncpt_put_ref_ext(struct platform_device *pdev, u32 id);
bool wrap_nvhost_syncpt_is_valid_pt_ext(struct platform_device *pdev, u32 id);
int wrap_nvhost_syncpt_is_expired_ext(struct platform_device *pdev, u32 id,
u32 thresh);
void wrap_nvhost_syncpt_set_min_update(struct platform_device *pdev, u32 id, u32 val);
int wrap_nvhost_syncpt_read_ext_check(struct platform_device *pdev, u32 id, u32 *val);
u32 wrap_nvhost_syncpt_read_maxval(struct platform_device *pdev, u32 id);
u32 wrap_nvhost_syncpt_incr_max_ext(struct platform_device *pdev, u32 id, u32 incrs);
u32 wrap_nvhost_syncpt_unit_interface_get_byte_offset_ext(struct platform_device *pdev,
u32 syncpt_id);
u32 wrap_nvhost_syncpt_unit_interface_get_byte_offset(u32 syncpt_id);
int wrap_nvhost_syncpt_unit_interface_get_aperture(struct platform_device *pdev,
u64 *base, size_t *size);
int wrap_nvhost_syncpt_unit_interface_init(struct platform_device *pdev);
void wrap_nvhost_syncpt_unit_interface_deinit(struct platform_device *pdev);
dma_addr_t wrap_nvhost_syncpt_address(struct platform_device *pdev, u32 id);
int wrap_nvhost_intr_register_notifier(struct platform_device *pdev,
u32 id, u32 thresh,
void (*callback)(void *data),
void *private_data);
int wrap_nvhost_module_init(struct platform_device *pdev);
void wrap_nvhost_module_deinit(struct platform_device *pdev);
void wrap_nvhost_module_reset(struct platform_device *pdev, bool reboot);
int wrap_nvhost_module_busy(struct platform_device *dev);
inline void wrap_nvhost_module_idle(struct platform_device *pdev);
void wrap_nvhost_module_idle_mult(struct platform_device *pdev, int refs);
#endif /*__HOST1X_DISPATCH_API_H */

View File

@@ -0,0 +1,75 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: GPL-2.0-only
*/
#ifndef __HOST1X_DISPATCH_TYPE_H
#define __HOST1X_DISPATCH_TYPE_H
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/dma-fence.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/timekeeping.h>
struct host1x;
struct host1x_syncpt;
struct host1x_interface_ops {
//host1x.h Interface
struct dma_fence* (*host1x_fence_create)(struct host1x_syncpt *sp, u32 threshold,bool timeout);
int (*host1x_fence_extract)(struct dma_fence *fence, u32 *id, u32 *threshold);
void (*host1x_fence_cancel)(struct dma_fence *fence);
int (*host1x_fence_get_node)(struct dma_fence *fence);
u64 (*host1x_get_dma_mask)(struct host1x *host1x);
struct host1x_syncpt* (*host1x_syncpt_get)(struct host1x_syncpt *sp);
struct host1x_syncpt* (*host1x_syncpt_get_by_id)(struct host1x *host, u32 id);
struct host1x_syncpt* (*host1x_syncpt_get_by_id_noref)(struct host1x *host, u32 id);
u32 (*host1x_syncpt_read)(struct host1x_syncpt *sp);
u32 (*host1x_syncpt_read_min)(struct host1x_syncpt *sp);
u32 (*host1x_syncpt_read_max)(struct host1x_syncpt *sp);
int (*host1x_syncpt_incr)(struct host1x_syncpt *sp);
u32 (*host1x_syncpt_incr_max)(struct host1x_syncpt *sp, u32 incrs);
struct host1x_syncpt* (*host1x_syncpt_alloc)(struct host1x *host, unsigned long flags, const char *name);
void (*host1x_syncpt_put)(struct host1x_syncpt *sp);
u32 (*host1x_syncpt_id)(struct host1x_syncpt *sp);
int (*host1x_syncpt_wait_ts)(struct host1x_syncpt *sp, u32 thresh, long timeout, u32 *value, ktime_t *ts);
int (*host1x_syncpt_wait)(struct host1x_syncpt *sp, u32 thresh, long timeout,u32 *value);
//nvhost.h Interface
void (*host1x_writel)(struct platform_device *pdev, u32 r, u32 v);
struct platform_device* (*nvhost_get_default_device)(void);
struct host1x* (*nvhost_get_host1x)(struct platform_device *pdev);
int (*nvhost_client_device_get_resources)(struct platform_device *pdev);
int (*nvhost_client_device_init)(struct platform_device *pdev);
int (*nvhost_client_device_release)(struct platform_device *pdev);
u32 (*nvhost_get_syncpt_host_managed)(struct platform_device *pdev, u32 param, const char *syncpt_name);
u32 (*nvhost_get_syncpt_client_managed)(struct platform_device *pdev,const char *syncpt_name);
u32 (*nvhost_get_syncpt_gpu_managed)(struct platform_device *pdev,const char *syncpt_name);
void (*nvhost_syncpt_put_ref_ext)(struct platform_device *pdev, u32 id);
bool (*nvhost_syncpt_is_valid_pt_ext)(struct platform_device *pdev, u32 id);
int (*nvhost_syncpt_is_expired_ext)(struct platform_device *pdev, u32 id, u32 thresh);
void (*nvhost_syncpt_set_min_update)(struct platform_device *pdev, u32 id, u32 val);
int (*nvhost_syncpt_read_ext_check)(struct platform_device *pdev, u32 id, u32 *val);
u32 (*nvhost_syncpt_read_maxval)(struct platform_device *pdev, u32 id);
u32 (*nvhost_syncpt_incr_max_ext)(struct platform_device *pdev, u32 id, u32 incrs);
u32 (*nvhost_syncpt_unit_interface_get_byte_offset_ext)(struct platform_device *pdev,u32 syncpt_id);
u32 (*nvhost_syncpt_unit_interface_get_byte_offset)(u32 syncpt_id);
int (*nvhost_syncpt_unit_interface_get_aperture)(struct platform_device *pdev, u64 *base, size_t *size);
int (*nvhost_syncpt_unit_interface_init)(struct platform_device *pdev);
void (*nvhost_syncpt_unit_interface_deinit)(struct platform_device *pdev);
dma_addr_t (*nvhost_syncpt_address)(struct platform_device *pdev, u32 id);
int (*nvhost_intr_register_notifier)(struct platform_device *pdev,u32 id, u32 thresh,void (*callback)(void *data),void *private_data);
int (*nvhost_module_init)(struct platform_device *pdev);
void (*nvhost_module_deinit)(struct platform_device *pdev);
void (*nvhost_module_reset)(struct platform_device *pdev, bool reboot);
int (*nvhost_module_busy)(struct platform_device *dev);
void (*nvhost_module_idle)(struct platform_device *pdev);
void (*nvhost_module_idle_mult)(struct platform_device *pdev, int refs);
};
bool host1x_wrapper_register_interface(struct host1x_interface_ops *host1x_hw_ops);
#endif /*__HOST1X_DISPATCH_API_H */