mirror of https://gitee.com/openkylin/linux.git
drm/omap: fix TILER on OMAP5
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>
This commit is contained in:
parent
2dab0bab6b
commit
7cb0d6c17b
|
@ -153,6 +153,10 @@ struct refill_engine {
|
||||||
struct list_head idle_node;
|
struct list_head idle_node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dmm_platform_data {
|
||||||
|
uint32_t cpu_cache_flags;
|
||||||
|
};
|
||||||
|
|
||||||
struct dmm {
|
struct dmm {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
|
@ -183,6 +187,8 @@ struct dmm {
|
||||||
|
|
||||||
/* allocation list and lock */
|
/* allocation list and lock */
|
||||||
struct list_head alloc_head;
|
struct list_head alloc_head;
|
||||||
|
|
||||||
|
const struct dmm_platform_data *plat_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,6 +39,10 @@
|
||||||
static struct tcm *containers[TILFMT_NFORMATS];
|
static struct tcm *containers[TILFMT_NFORMATS];
|
||||||
static struct dmm *omap_dmm;
|
static struct dmm *omap_dmm;
|
||||||
|
|
||||||
|
#if defined(CONFIG_OF)
|
||||||
|
static const struct of_device_id dmm_of_match[];
|
||||||
|
#endif
|
||||||
|
|
||||||
/* global spinlock for protecting lists */
|
/* global spinlock for protecting lists */
|
||||||
static DEFINE_SPINLOCK(list_lock);
|
static DEFINE_SPINLOCK(list_lock);
|
||||||
|
|
||||||
|
@ -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;
|
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)
|
bool dmm_is_available(void)
|
||||||
{
|
{
|
||||||
return omap_dmm ? true : false;
|
return omap_dmm ? true : false;
|
||||||
|
@ -592,6 +601,18 @@ static int omap_dmm_probe(struct platform_device *dev)
|
||||||
|
|
||||||
init_waitqueue_head(&omap_dmm->engine_queue);
|
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 */
|
/* lookup hwmod data - base address and irq */
|
||||||
mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
||||||
if (!mem) {
|
if (!mem) {
|
||||||
|
@ -972,9 +993,23 @@ static const struct dev_pm_ops omap_dmm_pm_ops = {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_OF)
|
#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[] = {
|
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
|
#endif
|
||||||
|
|
|
@ -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_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);
|
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);
|
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);
|
bool dmm_is_available(void);
|
||||||
|
|
||||||
extern struct platform_driver omap_dmm_driver;
|
extern struct platform_driver omap_dmm_driver;
|
||||||
|
|
|
@ -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
|
/* currently don't allow cached buffers.. there is some caching
|
||||||
* stuff that needs to be handled better
|
* stuff that needs to be handled better
|
||||||
*/
|
*/
|
||||||
flags &= ~(OMAP_BO_CACHED|OMAP_BO_UNCACHED);
|
flags &= ~(OMAP_BO_CACHED|OMAP_BO_WC|OMAP_BO_UNCACHED);
|
||||||
flags |= OMAP_BO_WC;
|
flags |= tiler_get_cpu_cache_flags();
|
||||||
|
|
||||||
/* align dimensions to slot boundaries... */
|
/* align dimensions to slot boundaries... */
|
||||||
tiler_align(gem2fmt(flags),
|
tiler_align(gem2fmt(flags),
|
||||||
|
|
Loading…
Reference in New Issue