Skip to content

Commit

Permalink
drm/omap: fix TILER on OMAP5
Browse files Browse the repository at this point in the history
On OMAP5 it is not possible to use TILER buffer with CPU when caching or
write-combining is used. Doing so leads to errors from the memory
manager.

However, on OMAP4, write-combining works fine.

This patch adds platform specific data for the TILER, and a function
tiler_get_cpu_cache_flags() which can be used to get the caching mode to
be used.

Note that without write-combining the use of the TILER buffer with CPU
is unusably slow. It's still good to have it operational for testing
purposes.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
  • Loading branch information
Tomi Valkeinen committed Mar 24, 2015
1 parent 2dab0ba commit 7cb0d6c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 4 deletions.
6 changes: 6 additions & 0 deletions drivers/gpu/drm/omapdrm/omap_dmm_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ struct refill_engine {
struct list_head idle_node;
};

struct dmm_platform_data {
uint32_t cpu_cache_flags;
};

struct dmm {
struct device *dev;
void __iomem *base;
Expand Down Expand Up @@ -183,6 +187,8 @@ struct dmm {

/* allocation list and lock */
struct list_head alloc_head;

const struct dmm_platform_data *plat_data;
};

#endif
39 changes: 37 additions & 2 deletions drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
static struct tcm *containers[TILFMT_NFORMATS];
static struct dmm *omap_dmm;

#if defined(CONFIG_OF)
static const struct of_device_id dmm_of_match[];
#endif

/* global spinlock for protecting lists */
static DEFINE_SPINLOCK(list_lock);

Expand Down Expand Up @@ -529,6 +533,11 @@ size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h)
return round_up(geom[fmt].cpp * w, PAGE_SIZE) * h;
}

uint32_t tiler_get_cpu_cache_flags(void)
{
return omap_dmm->plat_data->cpu_cache_flags;
}

bool dmm_is_available(void)
{
return omap_dmm ? true : false;
Expand Down Expand Up @@ -592,6 +601,18 @@ static int omap_dmm_probe(struct platform_device *dev)

init_waitqueue_head(&omap_dmm->engine_queue);

if (dev->dev.of_node) {
const struct of_device_id *match;

match = of_match_node(dmm_of_match, dev->dev.of_node);
if (!match) {
dev_err(&dev->dev, "failed to find matching device node\n");
return -ENODEV;
}

omap_dmm->plat_data = match->data;
}

/* lookup hwmod data - base address and irq */
mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!mem) {
Expand Down Expand Up @@ -972,9 +993,23 @@ static const struct dev_pm_ops omap_dmm_pm_ops = {
#endif

#if defined(CONFIG_OF)
static const struct dmm_platform_data dmm_omap4_platform_data = {
.cpu_cache_flags = OMAP_BO_WC,
};

static const struct dmm_platform_data dmm_omap5_platform_data = {
.cpu_cache_flags = OMAP_BO_UNCACHED,
};

static const struct of_device_id dmm_of_match[] = {
{ .compatible = "ti,omap4-dmm", },
{ .compatible = "ti,omap5-dmm", },
{
.compatible = "ti,omap4-dmm",
.data = &dmm_omap4_platform_data,
},
{
.compatible = "ti,omap5-dmm",
.data = &dmm_omap5_platform_data,
},
{},
};
#endif
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/omapdrm/omap_dmm_tiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ uint32_t tiler_stride(enum tiler_fmt fmt, uint32_t orient);
size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h);
size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h);
void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h);
uint32_t tiler_get_cpu_cache_flags(void);
bool dmm_is_available(void);

extern struct platform_driver omap_dmm_driver;
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/omapdrm/omap_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1359,8 +1359,8 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
/* currently don't allow cached buffers.. there is some caching
* stuff that needs to be handled better
*/
flags &= ~(OMAP_BO_CACHED|OMAP_BO_UNCACHED);
flags |= OMAP_BO_WC;
flags &= ~(OMAP_BO_CACHED|OMAP_BO_WC|OMAP_BO_UNCACHED);
flags |= tiler_get_cpu_cache_flags();

/* align dimensions to slot boundaries... */
tiler_align(gem2fmt(flags),
Expand Down

0 comments on commit 7cb0d6c

Please sign in to comment.