Merge tag 'drm/tegra/for-4.14-rc1' of git://anongit.freedesktop.org/tegra/linux into drm-next
drm/tegra: Changes for v4.14-rc1 This contains a couple of fixes and improvements for host1x, with some preparatory work for Tegra186 support. The remainder is cleanup and minor bugfixes for Tegra DRM along with enhancements to debuggability. There have also been some enhancements to the kernel interfaces for host1x job submissions and support for mmap'ing PRIME buffers directly, all of which get the interfaces very close to ready for serious work. * tag 'drm/tegra/for-4.14-rc1' of git://anongit.freedesktop.org/tegra/linux: (21 commits) drm/tegra: Prevent BOs from being freed during job submission drm/tegra: gem: Implement mmap() for PRIME buffers drm/tegra: Support render node drm/tegra: sor: Trace register accesses drm/tegra: dpaux: Trace register accesses drm/tegra: dsi: Trace register accesses drm/tegra: hdmi: Trace register accesses drm/tegra: dc: Trace register accesses drm/tegra: sor: Use unsigned int for register offsets drm/tegra: hdmi: Use unsigned int for register offsets drm/tegra: dsi: Use unsigned int for register offsets drm/tegra: dpaux: Use unsigned int for register offsets drm/tegra: dc: Use unsigned int for register offsets drm/tegra: Fix NULL deref in debugfs/iova drm/tegra: switch to drm_*_get(), drm_*_put() helpers drm/tegra: Set MODULE_FIRMWARE for the VIC drm/tegra: Add CONFIG_OF dependency gpu: host1x: Support sub-devices recursively gpu: host1x: fix error return code in host1x_probe() gpu: host1x: Fix bitshift/mask multipliers ...
This commit is contained in:
@@ -44,9 +44,12 @@ struct host1x_subdev {
|
||||
* @np: device node
|
||||
*/
|
||||
static int host1x_subdev_add(struct host1x_device *device,
|
||||
struct host1x_driver *driver,
|
||||
struct device_node *np)
|
||||
{
|
||||
struct host1x_subdev *subdev;
|
||||
struct device_node *child;
|
||||
int err;
|
||||
|
||||
subdev = kzalloc(sizeof(*subdev), GFP_KERNEL);
|
||||
if (!subdev)
|
||||
@@ -59,6 +62,19 @@ static int host1x_subdev_add(struct host1x_device *device,
|
||||
list_add_tail(&subdev->list, &device->subdevs);
|
||||
mutex_unlock(&device->subdevs_lock);
|
||||
|
||||
/* recursively add children */
|
||||
for_each_child_of_node(np, child) {
|
||||
if (of_match_node(driver->subdevs, child) &&
|
||||
of_device_is_available(child)) {
|
||||
err = host1x_subdev_add(device, driver, child);
|
||||
if (err < 0) {
|
||||
/* XXX cleanup? */
|
||||
of_node_put(child);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -87,7 +103,7 @@ static int host1x_device_parse_dt(struct host1x_device *device,
|
||||
for_each_child_of_node(device->dev.parent->of_node, np) {
|
||||
if (of_match_node(driver->subdevs, np) &&
|
||||
of_device_is_available(np)) {
|
||||
err = host1x_subdev_add(device, np);
|
||||
err = host1x_subdev_add(device, driver, np);
|
||||
if (err < 0) {
|
||||
of_node_put(np);
|
||||
return err;
|
||||
|
@@ -134,8 +134,8 @@ static int host1x_probe(struct platform_device *pdev)
|
||||
|
||||
syncpt_irq = platform_get_irq(pdev, 0);
|
||||
if (syncpt_irq < 0) {
|
||||
dev_err(&pdev->dev, "failed to get IRQ\n");
|
||||
return -ENXIO;
|
||||
dev_err(&pdev->dev, "failed to get IRQ: %d\n", syncpt_irq);
|
||||
return syncpt_irq;
|
||||
}
|
||||
|
||||
host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
|
||||
|
@@ -33,10 +33,10 @@ static void host1x_intr_syncpt_handle(struct host1x_syncpt *syncpt)
|
||||
unsigned int id = syncpt->id;
|
||||
struct host1x *host = syncpt->host;
|
||||
|
||||
host1x_sync_writel(host, BIT_MASK(id),
|
||||
HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(BIT_WORD(id)));
|
||||
host1x_sync_writel(host, BIT_MASK(id),
|
||||
HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(BIT_WORD(id)));
|
||||
host1x_sync_writel(host, BIT(id % 32),
|
||||
HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(id / 32));
|
||||
host1x_sync_writel(host, BIT(id % 32),
|
||||
HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(id / 32));
|
||||
|
||||
schedule_work(&syncpt->intr.work);
|
||||
}
|
||||
@@ -50,9 +50,9 @@ static irqreturn_t syncpt_thresh_isr(int irq, void *dev_id)
|
||||
for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); i++) {
|
||||
reg = host1x_sync_readl(host,
|
||||
HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i));
|
||||
for_each_set_bit(id, ®, BITS_PER_LONG) {
|
||||
for_each_set_bit(id, ®, 32) {
|
||||
struct host1x_syncpt *syncpt =
|
||||
host->syncpt + (i * BITS_PER_LONG + id);
|
||||
host->syncpt + (i * 32 + id);
|
||||
host1x_intr_syncpt_handle(syncpt);
|
||||
}
|
||||
}
|
||||
@@ -117,17 +117,17 @@ static void _host1x_intr_set_syncpt_threshold(struct host1x *host,
|
||||
static void _host1x_intr_enable_syncpt_intr(struct host1x *host,
|
||||
unsigned int id)
|
||||
{
|
||||
host1x_sync_writel(host, BIT_MASK(id),
|
||||
HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(BIT_WORD(id)));
|
||||
host1x_sync_writel(host, BIT(id % 32),
|
||||
HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(id / 32));
|
||||
}
|
||||
|
||||
static void _host1x_intr_disable_syncpt_intr(struct host1x *host,
|
||||
unsigned int id)
|
||||
{
|
||||
host1x_sync_writel(host, BIT_MASK(id),
|
||||
HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(BIT_WORD(id)));
|
||||
host1x_sync_writel(host, BIT_MASK(id),
|
||||
HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(BIT_WORD(id)));
|
||||
host1x_sync_writel(host, BIT(id % 32),
|
||||
HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(id / 32));
|
||||
host1x_sync_writel(host, BIT(id % 32),
|
||||
HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(id / 32));
|
||||
}
|
||||
|
||||
static int _host1x_free_syncpt_irq(struct host1x *host)
|
||||
|
@@ -89,7 +89,7 @@ static int syncpt_cpu_incr(struct host1x_syncpt *sp)
|
||||
host1x_syncpt_idle(sp))
|
||||
return -EINVAL;
|
||||
|
||||
host1x_sync_writel(host, BIT_MASK(sp->id),
|
||||
host1x_sync_writel(host, BIT(sp->id % 32),
|
||||
HOST1X_SYNC_SYNCPT_CPU_INCR(reg_offset));
|
||||
wmb();
|
||||
|
||||
|
@@ -197,10 +197,6 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
|
||||
}
|
||||
|
||||
phys_addr = host1x_bo_pin(reloc->target.bo, &sgt);
|
||||
if (!phys_addr) {
|
||||
err = -EINVAL;
|
||||
goto unpin;
|
||||
}
|
||||
|
||||
job->addr_phys[job->num_unpins] = phys_addr;
|
||||
job->unpins[job->num_unpins].bo = reloc->target.bo;
|
||||
@@ -225,10 +221,6 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
|
||||
}
|
||||
|
||||
phys_addr = host1x_bo_pin(g->bo, &sgt);
|
||||
if (!phys_addr) {
|
||||
err = -EINVAL;
|
||||
goto unpin;
|
||||
}
|
||||
|
||||
if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) {
|
||||
for_each_sg(sgt->sgl, sg, sgt->nents, j)
|
||||
|
Reference in New Issue
Block a user