mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-17 16:16:42 +07:00
gpu: ipu-v3: allocate ipuv3_channels as needed
Most of the 64 IPUv3 DMA channels are never used, some of them (channels 16, 30, 32, 34-39, and 53-63) are even marked as reserved. Allocate the channel control structure only when a channel is actually requested, replace the fixed size array with a list, and remove the unused enabled and busy fields from the ipuv3_channel structure. Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
This commit is contained in:
parent
e1e9733cd3
commit
93adc8b570
@ -274,15 +274,22 @@ struct ipuv3_channel *ipu_idmac_get(struct ipu_soc *ipu, unsigned num)
|
|||||||
|
|
||||||
mutex_lock(&ipu->channel_lock);
|
mutex_lock(&ipu->channel_lock);
|
||||||
|
|
||||||
channel = &ipu->channel[num];
|
list_for_each_entry(channel, &ipu->channels, list) {
|
||||||
|
if (channel->num == num) {
|
||||||
|
channel = ERR_PTR(-EBUSY);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (channel->busy) {
|
channel = kzalloc(sizeof(*channel), GFP_KERNEL);
|
||||||
channel = ERR_PTR(-EBUSY);
|
if (!channel) {
|
||||||
|
channel = ERR_PTR(-ENOMEM);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->busy = true;
|
|
||||||
channel->num = num;
|
channel->num = num;
|
||||||
|
channel->ipu = ipu;
|
||||||
|
list_add(&channel->list, &ipu->channels);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&ipu->channel_lock);
|
mutex_unlock(&ipu->channel_lock);
|
||||||
@ -299,7 +306,8 @@ void ipu_idmac_put(struct ipuv3_channel *channel)
|
|||||||
|
|
||||||
mutex_lock(&ipu->channel_lock);
|
mutex_lock(&ipu->channel_lock);
|
||||||
|
|
||||||
channel->busy = false;
|
list_del(&channel->list);
|
||||||
|
kfree(channel);
|
||||||
|
|
||||||
mutex_unlock(&ipu->channel_lock);
|
mutex_unlock(&ipu->channel_lock);
|
||||||
}
|
}
|
||||||
@ -1376,7 +1384,7 @@ static int ipu_probe(struct platform_device *pdev)
|
|||||||
struct ipu_soc *ipu;
|
struct ipu_soc *ipu;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
unsigned long ipu_base;
|
unsigned long ipu_base;
|
||||||
int i, ret, irq_sync, irq_err;
|
int ret, irq_sync, irq_err;
|
||||||
const struct ipu_devtype *devtype;
|
const struct ipu_devtype *devtype;
|
||||||
|
|
||||||
devtype = of_device_get_match_data(&pdev->dev);
|
devtype = of_device_get_match_data(&pdev->dev);
|
||||||
@ -1409,13 +1417,12 @@ static int ipu_probe(struct platform_device *pdev)
|
|||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 64; i++)
|
|
||||||
ipu->channel[i].ipu = ipu;
|
|
||||||
ipu->devtype = devtype;
|
ipu->devtype = devtype;
|
||||||
ipu->ipu_type = devtype->type;
|
ipu->ipu_type = devtype->type;
|
||||||
|
|
||||||
spin_lock_init(&ipu->lock);
|
spin_lock_init(&ipu->lock);
|
||||||
mutex_init(&ipu->channel_lock);
|
mutex_init(&ipu->channel_lock);
|
||||||
|
INIT_LIST_HEAD(&ipu->channels);
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "cm_reg: 0x%08lx\n",
|
dev_dbg(&pdev->dev, "cm_reg: 0x%08lx\n",
|
||||||
ipu_base + devtype->cm_ofs);
|
ipu_base + devtype->cm_ofs);
|
||||||
|
@ -157,11 +157,8 @@ enum ipu_modules {
|
|||||||
|
|
||||||
struct ipuv3_channel {
|
struct ipuv3_channel {
|
||||||
unsigned int num;
|
unsigned int num;
|
||||||
|
|
||||||
bool enabled;
|
|
||||||
bool busy;
|
|
||||||
|
|
||||||
struct ipu_soc *ipu;
|
struct ipu_soc *ipu;
|
||||||
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ipu_cpmem;
|
struct ipu_cpmem;
|
||||||
@ -184,6 +181,7 @@ struct ipu_soc {
|
|||||||
enum ipuv3_type ipu_type;
|
enum ipuv3_type ipu_type;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct mutex channel_lock;
|
struct mutex channel_lock;
|
||||||
|
struct list_head channels;
|
||||||
|
|
||||||
void __iomem *cm_reg;
|
void __iomem *cm_reg;
|
||||||
void __iomem *idmac_reg;
|
void __iomem *idmac_reg;
|
||||||
@ -193,8 +191,6 @@ struct ipu_soc {
|
|||||||
|
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
|
|
||||||
struct ipuv3_channel channel[64];
|
|
||||||
|
|
||||||
int irq_sync;
|
int irq_sync;
|
||||||
int irq_err;
|
int irq_err;
|
||||||
struct irq_domain *domain;
|
struct irq_domain *domain;
|
||||||
|
Loading…
Reference in New Issue
Block a user