summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tegra
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/tegra')
-rw-r--r--drivers/gpu/drm/tegra/dpaux.c39
-rw-r--r--drivers/gpu/drm/tegra/drm.c12
-rw-r--r--drivers/gpu/drm/tegra/gem.c25
3 files changed, 36 insertions, 40 deletions
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index d6b55e3e3716..07b26972f487 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -56,15 +56,14 @@ static inline struct tegra_dpaux *work_to_dpaux(struct work_struct *work)
return container_of(work, struct tegra_dpaux, work);
}
-static inline unsigned long tegra_dpaux_readl(struct tegra_dpaux *dpaux,
- unsigned long offset)
+static inline u32 tegra_dpaux_readl(struct tegra_dpaux *dpaux,
+ unsigned long offset)
{
return readl(dpaux->regs + (offset << 2));
}
static inline void tegra_dpaux_writel(struct tegra_dpaux *dpaux,
- unsigned long value,
- unsigned long offset)
+ u32 value, unsigned long offset)
{
writel(value, dpaux->regs + (offset << 2));
}
@@ -72,34 +71,32 @@ static inline void tegra_dpaux_writel(struct tegra_dpaux *dpaux,
static void tegra_dpaux_write_fifo(struct tegra_dpaux *dpaux, const u8 *buffer,
size_t size)
{
- unsigned long offset = DPAUX_DP_AUXDATA_WRITE(0);
size_t i, j;
- for (i = 0; i < size; i += 4) {
- size_t num = min_t(size_t, size - i, 4);
- unsigned long value = 0;
+ for (i = 0; i < DIV_ROUND_UP(size, 4); i++) {
+ size_t num = min_t(size_t, size - i * 4, 4);
+ u32 value = 0;
for (j = 0; j < num; j++)
- value |= buffer[i + j] << (j * 8);
+ value |= buffer[i * 4 + j] << (j * 8);
- tegra_dpaux_writel(dpaux, value, offset++);
+ tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXDATA_WRITE(i));
}
}
static void tegra_dpaux_read_fifo(struct tegra_dpaux *dpaux, u8 *buffer,
size_t size)
{
- unsigned long offset = DPAUX_DP_AUXDATA_READ(0);
size_t i, j;
- for (i = 0; i < size; i += 4) {
- size_t num = min_t(size_t, size - i, 4);
- unsigned long value;
+ for (i = 0; i < DIV_ROUND_UP(size, 4); i++) {
+ size_t num = min_t(size_t, size - i * 4, 4);
+ u32 value;
- value = tegra_dpaux_readl(dpaux, offset++);
+ value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXDATA_READ(i));
for (j = 0; j < num; j++)
- buffer[i + j] = value >> (j * 8);
+ buffer[i * 4 + j] = value >> (j * 8);
}
}
@@ -250,7 +247,7 @@ static irqreturn_t tegra_dpaux_irq(int irq, void *data)
{
struct tegra_dpaux *dpaux = data;
irqreturn_t ret = IRQ_HANDLED;
- unsigned long value;
+ u32 value;
/* clear interrupts */
value = tegra_dpaux_readl(dpaux, DPAUX_INTR_AUX);
@@ -273,7 +270,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
{
struct tegra_dpaux *dpaux;
struct resource *regs;
- unsigned long value;
+ u32 value;
int err;
dpaux = devm_kzalloc(&pdev->dev, sizeof(*dpaux), GFP_KERNEL);
@@ -465,7 +462,7 @@ int tegra_dpaux_detach(struct tegra_dpaux *dpaux)
enum drm_connector_status tegra_dpaux_detect(struct tegra_dpaux *dpaux)
{
- unsigned long value;
+ u32 value;
value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXSTAT);
@@ -477,7 +474,7 @@ enum drm_connector_status tegra_dpaux_detect(struct tegra_dpaux *dpaux)
int tegra_dpaux_enable(struct tegra_dpaux *dpaux)
{
- unsigned long value;
+ u32 value;
value = DPAUX_HYBRID_PADCTL_AUX_CMH(2) |
DPAUX_HYBRID_PADCTL_AUX_DRVZ(4) |
@@ -495,7 +492,7 @@ int tegra_dpaux_enable(struct tegra_dpaux *dpaux)
int tegra_dpaux_disable(struct tegra_dpaux *dpaux)
{
- unsigned long value;
+ u32 value;
value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
value |= DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index bfad15a913a0..427f50c6803c 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -124,14 +124,22 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
return -ENOMEM;
if (iommu_present(&platform_bus_type)) {
+ struct iommu_domain_geometry *geometry;
+ u64 start, end;
+
tegra->domain = iommu_domain_alloc(&platform_bus_type);
if (!tegra->domain) {
err = -ENOMEM;
goto free;
}
- DRM_DEBUG("IOMMU context initialized\n");
- drm_mm_init(&tegra->mm, 0, SZ_2G);
+ geometry = &tegra->domain->geometry;
+ start = geometry->aperture_start;
+ end = geometry->aperture_end;
+
+ DRM_DEBUG("IOMMU context initialized (aperture: %#llx-%#llx)\n",
+ start, end);
+ drm_mm_init(&tegra->mm, start, end - start + 1);
}
mutex_init(&tegra->clients_lock);
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 1217272a51f2..01e16e146bfe 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -189,7 +189,6 @@ static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo)
static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
{
struct scatterlist *s;
- struct sg_table *sgt;
unsigned int i;
bo->pages = drm_gem_get_pages(&bo->gem);
@@ -198,36 +197,28 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
bo->num_pages = bo->gem.size >> PAGE_SHIFT;
- sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages);
- if (IS_ERR(sgt))
+ bo->sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages);
+ if (IS_ERR(bo->sgt))
goto put_pages;
/*
- * Fake up the SG table so that dma_map_sg() can be used to flush the
- * pages associated with it. Note that this relies on the fact that
- * the DMA API doesn't hook into IOMMU on Tegra, therefore mapping is
- * only cache maintenance.
+ * Fake up the SG table so that dma_sync_sg_for_device() can be used
+ * to flush the pages associated with it.
*
* TODO: Replace this by drm_clflash_sg() once it can be implemented
* without relying on symbols that are not exported.
*/
- for_each_sg(sgt->sgl, s, sgt->nents, i)
+ for_each_sg(bo->sgt->sgl, s, bo->sgt->nents, i)
sg_dma_address(s) = sg_phys(s);
- if (dma_map_sg(drm->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE) == 0)
- goto release_sgt;
-
- bo->sgt = sgt;
+ dma_sync_sg_for_device(drm->dev, bo->sgt->sgl, bo->sgt->nents,
+ DMA_TO_DEVICE);
return 0;
-release_sgt:
- sg_free_table(sgt);
- kfree(sgt);
- sgt = ERR_PTR(-ENOMEM);
put_pages:
drm_gem_put_pages(&bo->gem, bo->pages, false, false);
- return PTR_ERR(sgt);
+ return PTR_ERR(bo->sgt);
}
static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo)