mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
rknpu: add fake platform device to rknpu device
The device 'fake_dev' under rknpu_dev is registered by rknpu_drv, which is a virtual platform device. The rknpu partial sync should use a platform device without iommu, so to use rknpu_dev->fake_dev. Change-Id: I33f1b05d308063f235d31044f8e562755c1217f4 Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com> Signed-off-by: Felix Zeng <felix.zeng@rock-chips.com>
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
struct rknpu_config {
|
||||
__u32 bw_priority_base;
|
||||
__u32 bw_priority_length;
|
||||
__u64 dma_mask;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -52,6 +53,7 @@ struct rknpu_config {
|
||||
struct rknpu_device {
|
||||
void __iomem *base;
|
||||
struct device *dev;
|
||||
struct device *fake_dev;
|
||||
struct drm_device *drm_dev;
|
||||
atomic_t sequence;
|
||||
spinlock_t lock;
|
||||
|
||||
@@ -49,6 +49,7 @@ MODULE_PARM_DESC(bypass_irq_handler,
|
||||
static const struct rknpu_config rk356x_rknpu_config = {
|
||||
.bw_priority_base = 0xfe180008,
|
||||
.bw_priority_length = 0x10,
|
||||
.dma_mask = DMA_BIT_MASK(32),
|
||||
};
|
||||
|
||||
/* driver probe and init */
|
||||
@@ -247,6 +248,42 @@ static bool rknpu_is_iommu_enable(struct device *dev)
|
||||
return true;
|
||||
}
|
||||
|
||||
static int drm_fake_dev_register(struct rknpu_device *rknpu_dev)
|
||||
{
|
||||
const struct platform_device_info rknpu_dev_info = {
|
||||
.name = "rknpu_dev",
|
||||
.id = PLATFORM_DEVID_AUTO,
|
||||
.dma_mask = rknpu_dev->config->dma_mask,
|
||||
};
|
||||
struct platform_device *pdev = NULL;
|
||||
int ret = -EINVAL;
|
||||
|
||||
pdev = platform_device_register_full(&rknpu_dev_info);
|
||||
if (pdev) {
|
||||
ret = of_dma_configure(&pdev->dev, NULL, true);
|
||||
if (ret) {
|
||||
platform_device_unregister(pdev);
|
||||
pdev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
rknpu_dev->fake_dev = pdev ? &pdev->dev : NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void drm_fake_dev_unregister(struct rknpu_device *rknpu_dev)
|
||||
{
|
||||
struct platform_device *pdev = NULL;
|
||||
|
||||
if (!rknpu_dev->fake_dev)
|
||||
return;
|
||||
|
||||
pdev = to_platform_device(rknpu_dev->fake_dev);
|
||||
|
||||
platform_device_unregister(pdev);
|
||||
}
|
||||
|
||||
static int rknpu_drm_probe(struct rknpu_device *rknpu_dev)
|
||||
{
|
||||
struct device *dev = rknpu_dev->dev;
|
||||
@@ -265,6 +302,8 @@ static int rknpu_drm_probe(struct rknpu_device *rknpu_dev)
|
||||
drm_dev->dev_private = rknpu_dev;
|
||||
rknpu_dev->drm_dev = drm_dev;
|
||||
|
||||
drm_fake_dev_register(rknpu_dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_drm:
|
||||
@@ -281,7 +320,10 @@ static void rknpu_drm_remove(struct rknpu_device *rknpu_dev)
|
||||
{
|
||||
struct drm_device *drm_dev = rknpu_dev->drm_dev;
|
||||
|
||||
drm_fake_dev_unregister(rknpu_dev);
|
||||
|
||||
drm_dev_unregister(drm_dev);
|
||||
|
||||
#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE
|
||||
drm_dev_put(drm_dev);
|
||||
#else
|
||||
|
||||
@@ -935,6 +935,11 @@ int rknpu_gem_sync_ioctl(struct drm_device *dev, void *data,
|
||||
DMA_FROM_DEVICE);
|
||||
}
|
||||
} else {
|
||||
struct drm_device *drm = rknpu_obj->base.dev;
|
||||
struct rknpu_device *rknpu_dev = drm->dev_private;
|
||||
|
||||
WARN_ON(!rknpu_dev->fake_dev);
|
||||
|
||||
length = args->size;
|
||||
offset = args->offset;
|
||||
|
||||
@@ -951,15 +956,14 @@ int rknpu_gem_sync_ioctl(struct drm_device *dev, void *data,
|
||||
|
||||
if (args->flags & RKNPU_MEM_SYNC_TO_DEVICE) {
|
||||
dma_sync_single_range_for_device(
|
||||
dev->dev, sg_dma_addr, sg_offset, size,
|
||||
DMA_TO_DEVICE);
|
||||
rknpu_dev->fake_dev, sg_dma_addr,
|
||||
sg_offset, size, DMA_TO_DEVICE);
|
||||
}
|
||||
|
||||
if (args->flags & RKNPU_MEM_SYNC_FROM_DEVICE) {
|
||||
dma_sync_single_range_for_cpu(dev->dev,
|
||||
sg_dma_addr,
|
||||
sg_offset, size,
|
||||
DMA_FROM_DEVICE);
|
||||
dma_sync_single_range_for_cpu(
|
||||
rknpu_dev->fake_dev, sg_dma_addr,
|
||||
sg_offset, size, DMA_FROM_DEVICE);
|
||||
}
|
||||
|
||||
offset += size;
|
||||
|
||||
Reference in New Issue
Block a user