sh_mobile_meram: Rename operations to cache_[alloc|free|update]
The MERAM operations meram_register, meram_unregister and meram_update handle LCDC cache. In preparation for "raw" MERAM allocation, rename them to more appropriate names. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
Родитель
6fcdbc0c3a
Коммит
4a23717721
|
@ -1104,7 +1104,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
|
||||||
/* Compute frame buffer base address and pitch for each channel. */
|
/* Compute frame buffer base address and pitch for each channel. */
|
||||||
for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
|
for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
|
||||||
int pixelformat;
|
int pixelformat;
|
||||||
void *meram;
|
void *cache;
|
||||||
|
|
||||||
ch = &priv->ch[k];
|
ch = &priv->ch[k];
|
||||||
if (!ch->enabled)
|
if (!ch->enabled)
|
||||||
|
@ -1119,12 +1119,10 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
|
||||||
ch->cfg->meram_cfg == NULL)
|
ch->cfg->meram_cfg == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* we need to de-init configured ICBs before we can
|
/* Free the allocated MERAM cache. */
|
||||||
* re-initialize them.
|
if (ch->cache) {
|
||||||
*/
|
mdev->ops->cache_free(mdev, ch->cache);
|
||||||
if (ch->meram) {
|
ch->cache = NULL;
|
||||||
mdev->ops->meram_unregister(mdev, ch->meram);
|
|
||||||
ch->meram = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ch->format->fourcc) {
|
switch (ch->format->fourcc) {
|
||||||
|
@ -1146,14 +1144,14 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
meram = mdev->ops->meram_register(mdev, ch->cfg->meram_cfg,
|
cache = mdev->ops->cache_alloc(mdev, ch->cfg->meram_cfg,
|
||||||
ch->pitch, ch->yres, pixelformat,
|
ch->pitch, ch->yres, pixelformat,
|
||||||
&ch->line_size);
|
&ch->line_size);
|
||||||
if (!IS_ERR(meram)) {
|
if (!IS_ERR(cache)) {
|
||||||
mdev->ops->meram_update(mdev, meram,
|
mdev->ops->cache_update(mdev, cache,
|
||||||
ch->base_addr_y, ch->base_addr_c,
|
ch->base_addr_y, ch->base_addr_c,
|
||||||
&ch->base_addr_y, &ch->base_addr_c);
|
&ch->base_addr_y, &ch->base_addr_c);
|
||||||
ch->meram = meram;
|
ch->cache = cache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1223,12 +1221,12 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
|
||||||
|
|
||||||
sh_mobile_lcdc_display_off(ch);
|
sh_mobile_lcdc_display_off(ch);
|
||||||
|
|
||||||
/* disable the meram */
|
/* Free the MERAM cache. */
|
||||||
if (ch->meram) {
|
if (ch->cache) {
|
||||||
struct sh_mobile_meram_info *mdev;
|
struct sh_mobile_meram_info *mdev;
|
||||||
mdev = priv->meram_dev;
|
mdev = priv->meram_dev;
|
||||||
mdev->ops->meram_unregister(mdev, ch->meram);
|
mdev->ops->cache_free(mdev, ch->cache);
|
||||||
ch->meram = 0;
|
ch->cache = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1839,11 +1837,11 @@ static int sh_mobile_lcdc_pan(struct fb_var_screeninfo *var,
|
||||||
base_addr_c += var->xoffset;
|
base_addr_c += var->xoffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch->meram) {
|
if (ch->cache) {
|
||||||
struct sh_mobile_meram_info *mdev;
|
struct sh_mobile_meram_info *mdev;
|
||||||
|
|
||||||
mdev = priv->meram_dev;
|
mdev = priv->meram_dev;
|
||||||
mdev->ops->meram_update(mdev, ch->meram,
|
mdev->ops->cache_update(mdev, ch->cache,
|
||||||
base_addr_y, base_addr_c,
|
base_addr_y, base_addr_c,
|
||||||
&base_addr_y, &base_addr_c);
|
&base_addr_y, &base_addr_c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ struct sh_mobile_lcdc_chan {
|
||||||
unsigned long *reg_offs;
|
unsigned long *reg_offs;
|
||||||
unsigned long ldmt1r_value;
|
unsigned long ldmt1r_value;
|
||||||
unsigned long enabled; /* ME and SE in LDCNT2R */
|
unsigned long enabled; /* ME and SE in LDCNT2R */
|
||||||
void *meram;
|
void *cache;
|
||||||
|
|
||||||
struct mutex open_lock; /* protects the use counter */
|
struct mutex open_lock; /* protects the use counter */
|
||||||
int use_count;
|
int use_count;
|
||||||
|
|
|
@ -194,13 +194,13 @@ static inline unsigned long meram_read_reg(void __iomem *base, unsigned int off)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Allocation
|
* LCDC cache planes allocation, init, cleanup and free
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Allocate ICBs and MERAM for a plane. */
|
/* Allocate ICBs and MERAM for a plane. */
|
||||||
static int __meram_alloc(struct sh_mobile_meram_priv *priv,
|
static int meram_plane_alloc(struct sh_mobile_meram_priv *priv,
|
||||||
struct sh_mobile_meram_fb_plane *plane,
|
struct sh_mobile_meram_fb_plane *plane,
|
||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
unsigned long mem;
|
unsigned long mem;
|
||||||
unsigned long idx;
|
unsigned long idx;
|
||||||
|
@ -229,8 +229,8 @@ static int __meram_alloc(struct sh_mobile_meram_priv *priv,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free ICBs and MERAM for a plane. */
|
/* Free ICBs and MERAM for a plane. */
|
||||||
static void __meram_free(struct sh_mobile_meram_priv *priv,
|
static void meram_plane_free(struct sh_mobile_meram_priv *priv,
|
||||||
struct sh_mobile_meram_fb_plane *plane)
|
struct sh_mobile_meram_fb_plane *plane)
|
||||||
{
|
{
|
||||||
gen_pool_free(priv->pool, priv->meram + plane->marker->offset,
|
gen_pool_free(priv->pool, priv->meram + plane->marker->offset,
|
||||||
plane->marker->size * 1024);
|
plane->marker->size * 1024);
|
||||||
|
@ -248,62 +248,6 @@ static int is_nvcolor(int cspace)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate memory for the ICBs and mark them as used. */
|
|
||||||
static struct sh_mobile_meram_fb_cache *
|
|
||||||
meram_alloc(struct sh_mobile_meram_priv *priv,
|
|
||||||
const struct sh_mobile_meram_cfg *cfg,
|
|
||||||
int pixelformat)
|
|
||||||
{
|
|
||||||
struct sh_mobile_meram_fb_cache *cache;
|
|
||||||
unsigned int nplanes = is_nvcolor(pixelformat) ? 2 : 1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (cfg->icb[0].meram_size == 0)
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
|
|
||||||
if (nplanes == 2 && cfg->icb[1].meram_size == 0)
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
|
|
||||||
cache = kzalloc(sizeof(*cache), GFP_KERNEL);
|
|
||||||
if (cache == NULL)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
|
|
||||||
cache->nplanes = nplanes;
|
|
||||||
|
|
||||||
ret = __meram_alloc(priv, &cache->planes[0], cfg->icb[0].meram_size);
|
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
cache->planes[0].marker->current_reg = 1;
|
|
||||||
cache->planes[0].marker->pixelformat = pixelformat;
|
|
||||||
|
|
||||||
if (cache->nplanes == 1)
|
|
||||||
return cache;
|
|
||||||
|
|
||||||
ret = __meram_alloc(priv, &cache->planes[1], cfg->icb[1].meram_size);
|
|
||||||
if (ret < 0) {
|
|
||||||
__meram_free(priv, &cache->planes[0]);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cache;
|
|
||||||
|
|
||||||
error:
|
|
||||||
kfree(cache);
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unmark the specified ICB as used. */
|
|
||||||
static void meram_free(struct sh_mobile_meram_priv *priv,
|
|
||||||
struct sh_mobile_meram_fb_cache *cache)
|
|
||||||
{
|
|
||||||
__meram_free(priv, &cache->planes[0]);
|
|
||||||
if (cache->nplanes == 2)
|
|
||||||
__meram_free(priv, &cache->planes[1]);
|
|
||||||
|
|
||||||
kfree(cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the next address to fetch. */
|
/* Set the next address to fetch. */
|
||||||
static void meram_set_next_addr(struct sh_mobile_meram_priv *priv,
|
static void meram_set_next_addr(struct sh_mobile_meram_priv *priv,
|
||||||
struct sh_mobile_meram_fb_cache *cache,
|
struct sh_mobile_meram_fb_cache *cache,
|
||||||
|
@ -355,10 +299,10 @@ meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata,
|
||||||
(((x) * (y) + (MERAM_LINE_WIDTH - 1)) & ~(MERAM_LINE_WIDTH - 1))
|
(((x) * (y) + (MERAM_LINE_WIDTH - 1)) & ~(MERAM_LINE_WIDTH - 1))
|
||||||
|
|
||||||
/* Initialize MERAM. */
|
/* Initialize MERAM. */
|
||||||
static int meram_init(struct sh_mobile_meram_priv *priv,
|
static int meram_plane_init(struct sh_mobile_meram_priv *priv,
|
||||||
struct sh_mobile_meram_fb_plane *plane,
|
struct sh_mobile_meram_fb_plane *plane,
|
||||||
unsigned int xres, unsigned int yres,
|
unsigned int xres, unsigned int yres,
|
||||||
unsigned int *out_pitch)
|
unsigned int *out_pitch)
|
||||||
{
|
{
|
||||||
struct sh_mobile_meram_icb *marker = plane->marker;
|
struct sh_mobile_meram_icb *marker = plane->marker;
|
||||||
unsigned long total_byte_count = MERAM_CALC_BYTECOUNT(xres, yres);
|
unsigned long total_byte_count = MERAM_CALC_BYTECOUNT(xres, yres);
|
||||||
|
@ -427,8 +371,8 @@ static int meram_init(struct sh_mobile_meram_priv *priv,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void meram_deinit(struct sh_mobile_meram_priv *priv,
|
static void meram_plane_cleanup(struct sh_mobile_meram_priv *priv,
|
||||||
struct sh_mobile_meram_fb_plane *plane)
|
struct sh_mobile_meram_fb_plane *plane)
|
||||||
{
|
{
|
||||||
/* disable ICB */
|
/* disable ICB */
|
||||||
meram_write_icb(priv->base, plane->cache->index, MExxCTL,
|
meram_write_icb(priv->base, plane->cache->index, MExxCTL,
|
||||||
|
@ -441,18 +385,60 @@ static void meram_deinit(struct sh_mobile_meram_priv *priv,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Registration/unregistration
|
* LCDC cache operations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
|
/* Allocate memory for the ICBs and mark them as used. */
|
||||||
const struct sh_mobile_meram_cfg *cfg,
|
static struct sh_mobile_meram_fb_cache *
|
||||||
unsigned int xres, unsigned int yres,
|
meram_cache_alloc(struct sh_mobile_meram_priv *priv,
|
||||||
unsigned int pixelformat,
|
const struct sh_mobile_meram_cfg *cfg,
|
||||||
unsigned int *pitch)
|
int pixelformat)
|
||||||
|
{
|
||||||
|
unsigned int nplanes = is_nvcolor(pixelformat) ? 2 : 1;
|
||||||
|
struct sh_mobile_meram_fb_cache *cache;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
cache = kzalloc(sizeof(*cache), GFP_KERNEL);
|
||||||
|
if (cache == NULL)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
cache->nplanes = nplanes;
|
||||||
|
|
||||||
|
ret = meram_plane_alloc(priv, &cache->planes[0],
|
||||||
|
cfg->icb[0].meram_size);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
cache->planes[0].marker->current_reg = 1;
|
||||||
|
cache->planes[0].marker->pixelformat = pixelformat;
|
||||||
|
|
||||||
|
if (cache->nplanes == 1)
|
||||||
|
return cache;
|
||||||
|
|
||||||
|
ret = meram_plane_alloc(priv, &cache->planes[1],
|
||||||
|
cfg->icb[1].meram_size);
|
||||||
|
if (ret < 0) {
|
||||||
|
meram_plane_free(priv, &cache->planes[0]);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache;
|
||||||
|
|
||||||
|
error:
|
||||||
|
kfree(cache);
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *sh_mobile_cache_alloc(struct sh_mobile_meram_info *pdata,
|
||||||
|
const struct sh_mobile_meram_cfg *cfg,
|
||||||
|
unsigned int xres, unsigned int yres,
|
||||||
|
unsigned int pixelformat,
|
||||||
|
unsigned int *pitch)
|
||||||
{
|
{
|
||||||
struct sh_mobile_meram_fb_cache *cache;
|
struct sh_mobile_meram_fb_cache *cache;
|
||||||
struct sh_mobile_meram_priv *priv = pdata->priv;
|
struct sh_mobile_meram_priv *priv = pdata->priv;
|
||||||
struct platform_device *pdev = pdata->pdev;
|
struct platform_device *pdev = pdata->pdev;
|
||||||
|
unsigned int nplanes = is_nvcolor(pixelformat) ? 2 : 1;
|
||||||
unsigned int out_pitch;
|
unsigned int out_pitch;
|
||||||
|
|
||||||
if (pixelformat != SH_MOBILE_MERAM_PF_NV &&
|
if (pixelformat != SH_MOBILE_MERAM_PF_NV &&
|
||||||
|
@ -469,10 +455,16 @@ static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cfg->icb[0].meram_size == 0)
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
if (nplanes == 2 && cfg->icb[1].meram_size == 0)
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
mutex_lock(&priv->lock);
|
mutex_lock(&priv->lock);
|
||||||
|
|
||||||
/* We now register the ICBs and allocate the MERAM regions. */
|
/* We now register the ICBs and allocate the MERAM regions. */
|
||||||
cache = meram_alloc(priv, cfg, pixelformat);
|
cache = meram_cache_alloc(priv, cfg, pixelformat);
|
||||||
if (IS_ERR(cache)) {
|
if (IS_ERR(cache)) {
|
||||||
dev_err(&pdev->dev, "MERAM allocation failed (%ld).",
|
dev_err(&pdev->dev, "MERAM allocation failed (%ld).",
|
||||||
PTR_ERR(cache));
|
PTR_ERR(cache));
|
||||||
|
@ -480,14 +472,14 @@ static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize MERAM */
|
/* initialize MERAM */
|
||||||
meram_init(priv, &cache->planes[0], xres, yres, &out_pitch);
|
meram_plane_init(priv, &cache->planes[0], xres, yres, &out_pitch);
|
||||||
*pitch = out_pitch;
|
*pitch = out_pitch;
|
||||||
if (pixelformat == SH_MOBILE_MERAM_PF_NV)
|
if (pixelformat == SH_MOBILE_MERAM_PF_NV)
|
||||||
meram_init(priv, &cache->planes[1], xres, (yres + 1) / 2,
|
meram_plane_init(priv, &cache->planes[1],
|
||||||
&out_pitch);
|
xres, (yres + 1) / 2, &out_pitch);
|
||||||
else if (pixelformat == SH_MOBILE_MERAM_PF_NV24)
|
else if (pixelformat == SH_MOBILE_MERAM_PF_NV24)
|
||||||
meram_init(priv, &cache->planes[1], 2 * xres, (yres + 1) / 2,
|
meram_plane_init(priv, &cache->planes[1],
|
||||||
&out_pitch);
|
2 * xres, (yres + 1) / 2, &out_pitch);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
mutex_unlock(&priv->lock);
|
mutex_unlock(&priv->lock);
|
||||||
|
@ -495,25 +487,29 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sh_mobile_meram_unregister(struct sh_mobile_meram_info *pdata, void *data)
|
sh_mobile_cache_free(struct sh_mobile_meram_info *pdata, void *data)
|
||||||
{
|
{
|
||||||
struct sh_mobile_meram_fb_cache *cache = data;
|
struct sh_mobile_meram_fb_cache *cache = data;
|
||||||
struct sh_mobile_meram_priv *priv = pdata->priv;
|
struct sh_mobile_meram_priv *priv = pdata->priv;
|
||||||
|
|
||||||
mutex_lock(&priv->lock);
|
mutex_lock(&priv->lock);
|
||||||
|
|
||||||
/* deinit & free */
|
/* Cleanup and free. */
|
||||||
meram_deinit(priv, &cache->planes[0]);
|
meram_plane_cleanup(priv, &cache->planes[0]);
|
||||||
if (cache->nplanes == 2)
|
meram_plane_free(priv, &cache->planes[0]);
|
||||||
meram_deinit(priv, &cache->planes[1]);
|
|
||||||
|
|
||||||
meram_free(priv, cache);
|
if (cache->nplanes == 2) {
|
||||||
|
meram_plane_cleanup(priv, &cache->planes[1]);
|
||||||
|
meram_plane_free(priv, &cache->planes[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(cache);
|
||||||
|
|
||||||
mutex_unlock(&priv->lock);
|
mutex_unlock(&priv->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sh_mobile_meram_update(struct sh_mobile_meram_info *pdata, void *data,
|
sh_mobile_cache_update(struct sh_mobile_meram_info *pdata, void *data,
|
||||||
unsigned long base_addr_y, unsigned long base_addr_c,
|
unsigned long base_addr_y, unsigned long base_addr_c,
|
||||||
unsigned long *icb_addr_y, unsigned long *icb_addr_c)
|
unsigned long *icb_addr_y, unsigned long *icb_addr_c)
|
||||||
{
|
{
|
||||||
|
@ -530,9 +526,9 @@ sh_mobile_meram_update(struct sh_mobile_meram_info *pdata, void *data,
|
||||||
|
|
||||||
static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
|
static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
.meram_register = sh_mobile_meram_register,
|
.cache_alloc = sh_mobile_cache_alloc,
|
||||||
.meram_unregister = sh_mobile_meram_unregister,
|
.cache_free = sh_mobile_cache_free,
|
||||||
.meram_update = sh_mobile_meram_update,
|
.cache_update = sh_mobile_cache_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -41,19 +41,14 @@ struct sh_mobile_meram_cfg {
|
||||||
struct module;
|
struct module;
|
||||||
struct sh_mobile_meram_ops {
|
struct sh_mobile_meram_ops {
|
||||||
struct module *module;
|
struct module *module;
|
||||||
/* register usage of meram */
|
|
||||||
void *(*meram_register)(struct sh_mobile_meram_info *meram_dev,
|
|
||||||
const struct sh_mobile_meram_cfg *cfg,
|
|
||||||
unsigned int xres, unsigned int yres,
|
|
||||||
unsigned int pixelformat,
|
|
||||||
unsigned int *pitch);
|
|
||||||
|
|
||||||
/* unregister usage of meram */
|
/* LCDC cache management */
|
||||||
void (*meram_unregister)(struct sh_mobile_meram_info *meram_dev,
|
void *(*cache_alloc)(struct sh_mobile_meram_info *meram_dev,
|
||||||
void *data);
|
const struct sh_mobile_meram_cfg *cfg,
|
||||||
|
unsigned int xres, unsigned int yres,
|
||||||
/* update meram settings */
|
unsigned int pixelformat, unsigned int *pitch);
|
||||||
void (*meram_update)(struct sh_mobile_meram_info *meram_dev, void *data,
|
void (*cache_free)(struct sh_mobile_meram_info *meram_dev, void *data);
|
||||||
|
void (*cache_update)(struct sh_mobile_meram_info *meram_dev, void *data,
|
||||||
unsigned long base_addr_y,
|
unsigned long base_addr_y,
|
||||||
unsigned long base_addr_c,
|
unsigned long base_addr_c,
|
||||||
unsigned long *icb_addr_y,
|
unsigned long *icb_addr_y,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче