Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 239921ec authored by Laurent Pinchart's avatar Laurent Pinchart
Browse files

sh_mobile_meram: Add direct MERAM allocation API



The API can be used to allocate and free MERAM blocks directly, without
going through ICBs.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
parent 6e729b41
Loading
Loading
Loading
Loading
+37 −4
Original line number Diff line number Diff line
@@ -194,6 +194,21 @@ static inline unsigned long meram_read_reg(void __iomem *base, unsigned int off)
	return ioread32(base + off);
}

/* -----------------------------------------------------------------------------
 * MERAM allocation and free
 */

static unsigned long meram_alloc(struct sh_mobile_meram_priv *priv, size_t size)
{
	return gen_pool_alloc(priv->pool, size);
}

static void meram_free(struct sh_mobile_meram_priv *priv, unsigned long mem,
		       size_t size)
{
	gen_pool_free(priv->pool, mem, size);
}

/* -----------------------------------------------------------------------------
 * LCDC cache planes allocation, init, cleanup and free
 */
@@ -216,7 +231,7 @@ static int meram_plane_alloc(struct sh_mobile_meram_priv *priv,
		return -ENOMEM;
	plane->marker = &priv->icbs[idx];

	mem = gen_pool_alloc(priv->pool, size * 1024);
	mem = meram_alloc(priv, size * 1024);
	if (mem == 0)
		return -ENOMEM;

@@ -233,7 +248,7 @@ static int meram_plane_alloc(struct sh_mobile_meram_priv *priv,
static void meram_plane_free(struct sh_mobile_meram_priv *priv,
			     struct sh_mobile_meram_fb_plane *plane)
{
	gen_pool_free(priv->pool, priv->meram + plane->marker->offset,
	meram_free(priv, priv->meram + plane->marker->offset,
		   plane->marker->size * 1024);

	__clear_bit(plane->marker->index, &priv->used_icb);
@@ -386,9 +401,27 @@ static void meram_plane_cleanup(struct sh_mobile_meram_priv *priv,
}

/* -----------------------------------------------------------------------------
 * LCDC cache operations
 * MERAM operations
 */

unsigned long sh_mobile_meram_alloc(struct sh_mobile_meram_info *pdata,
				    size_t size)
{
	struct sh_mobile_meram_priv *priv = pdata->priv;

	return meram_alloc(priv, size);
}
EXPORT_SYMBOL_GPL(sh_mobile_meram_alloc);

void sh_mobile_meram_free(struct sh_mobile_meram_info *pdata, unsigned long mem,
			  size_t size)
{
	struct sh_mobile_meram_priv *priv = pdata->priv;

	meram_free(priv, mem, size);
}
EXPORT_SYMBOL_GPL(sh_mobile_meram_free);

/* Allocate memory for the ICBs and mark them as used. */
static struct sh_mobile_meram_fb_cache *
meram_cache_alloc(struct sh_mobile_meram_priv *priv,
+16 −0
Original line number Diff line number Diff line
@@ -38,6 +38,10 @@ struct sh_mobile_meram_cfg {

#if defined(CONFIG_FB_SH_MOBILE_MERAM) || \
    defined(CONFIG_FB_SH_MOBILE_MERAM_MODULE)
unsigned long sh_mobile_meram_alloc(struct sh_mobile_meram_info *meram_dev,
				    size_t size);
void sh_mobile_meram_free(struct sh_mobile_meram_info *meram_dev,
			  unsigned long mem, size_t size);
void *sh_mobile_meram_cache_alloc(struct sh_mobile_meram_info *dev,
				  const struct sh_mobile_meram_cfg *cfg,
				  unsigned int xres, unsigned int yres,
@@ -50,6 +54,18 @@ void sh_mobile_meram_cache_update(struct sh_mobile_meram_info *dev, void *data,
				  unsigned long *icb_addr_y,
				  unsigned long *icb_addr_c);
#else
static inline unsigned long
sh_mobile_meram_alloc(struct sh_mobile_meram_info *meram_dev, size_t size)
{
	return 0;
}

static inline void
sh_mobile_meram_free(struct sh_mobile_meram_info *meram_dev,
		     unsigned long mem, size_t size)
{
}

static inline void *
sh_mobile_meram_cache_alloc(struct sh_mobile_meram_info *dev,
			    const struct sh_mobile_meram_cfg *cfg,