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

Commit 4a237177 authored by Laurent Pinchart's avatar Laurent Pinchart
Browse files

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: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
parent 6fcdbc0c
Loading
Loading
Loading
Loading
+15 −17
Original line number Diff line number Diff line
@@ -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. */
	for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
		int pixelformat;
		void *meram;
		void *cache;

		ch = &priv->ch[k];
		if (!ch->enabled)
@@ -1119,12 +1119,10 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
		    ch->cfg->meram_cfg == NULL)
			continue;

		/* we need to de-init configured ICBs before we can
		 * re-initialize them.
		 */
		if (ch->meram) {
			mdev->ops->meram_unregister(mdev, ch->meram);
			ch->meram = NULL;
		/* Free the allocated MERAM cache. */
		if (ch->cache) {
			mdev->ops->cache_free(mdev, ch->cache);
			ch->cache = NULL;
		}

		switch (ch->format->fourcc) {
@@ -1146,14 +1144,14 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
			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->line_size);
		if (!IS_ERR(meram)) {
			mdev->ops->meram_update(mdev, meram,
		if (!IS_ERR(cache)) {
			mdev->ops->cache_update(mdev, cache,
					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);

		/* disable the meram */
		if (ch->meram) {
		/* Free the MERAM cache. */
		if (ch->cache) {
			struct sh_mobile_meram_info *mdev;
			mdev = priv->meram_dev;
			mdev->ops->meram_unregister(mdev, ch->meram);
			ch->meram = 0;
			mdev->ops->cache_free(mdev, ch->cache);
			ch->cache = 0;
		}

	}
@@ -1839,11 +1837,11 @@ static int sh_mobile_lcdc_pan(struct fb_var_screeninfo *var,
			base_addr_c += var->xoffset;
	}

	if (ch->meram) {
	if (ch->cache) {
		struct sh_mobile_meram_info *mdev;

		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);
	}
+1 −1
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ struct sh_mobile_lcdc_chan {
	unsigned long *reg_offs;
	unsigned long ldmt1r_value;
	unsigned long enabled; /* ME and SE in LDCNT2R */
	void *meram;
	void *cache;

	struct mutex open_lock;		/* protects the use counter */
	int use_count;
+86 −90
Original line number Diff line number Diff line
@@ -194,11 +194,11 @@ 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. */
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,
			     size_t size)
{
@@ -229,7 +229,7 @@ static int __meram_alloc(struct sh_mobile_meram_priv *priv,
}

/* 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)
{
	gen_pool_free(priv->pool, priv->meram + plane->marker->offset,
@@ -248,62 +248,6 @@ static int is_nvcolor(int cspace)
	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. */
static void meram_set_next_addr(struct sh_mobile_meram_priv *priv,
				struct sh_mobile_meram_fb_cache *cache,
@@ -355,7 +299,7 @@ meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata,
	(((x) * (y) + (MERAM_LINE_WIDTH - 1)) & ~(MERAM_LINE_WIDTH - 1))

/* 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,
			    unsigned int xres, unsigned int yres,
			    unsigned int *out_pitch)
@@ -427,7 +371,7 @@ static int meram_init(struct sh_mobile_meram_priv *priv,
	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)
{
	/* disable ICB */
@@ -441,10 +385,51 @@ 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. */
static struct sh_mobile_meram_fb_cache *
meram_cache_alloc(struct sh_mobile_meram_priv *priv,
		  const struct sh_mobile_meram_cfg *cfg,
		  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,
@@ -453,6 +438,7 @@ static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
	struct sh_mobile_meram_fb_cache *cache;
	struct sh_mobile_meram_priv *priv = pdata->priv;
	struct platform_device *pdev = pdata->pdev;
	unsigned int nplanes = is_nvcolor(pixelformat) ? 2 : 1;
	unsigned int out_pitch;

	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);
	}

	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);

	/* 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)) {
		dev_err(&pdev->dev, "MERAM allocation failed (%ld).",
			PTR_ERR(cache));
@@ -480,14 +472,14 @@ static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
	}

	/* 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;
	if (pixelformat == SH_MOBILE_MERAM_PF_NV)
		meram_init(priv, &cache->planes[1], xres, (yres + 1) / 2,
			&out_pitch);
		meram_plane_init(priv, &cache->planes[1],
				 xres, (yres + 1) / 2, &out_pitch);
	else if (pixelformat == SH_MOBILE_MERAM_PF_NV24)
		meram_init(priv, &cache->planes[1], 2 * xres, (yres + 1) / 2,
			&out_pitch);
		meram_plane_init(priv, &cache->planes[1],
				 2 * xres, (yres + 1) / 2, &out_pitch);

err:
	mutex_unlock(&priv->lock);
@@ -495,25 +487,29 @@ static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
}

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_priv *priv = pdata->priv;

	mutex_lock(&priv->lock);

	/* deinit & free */
	meram_deinit(priv, &cache->planes[0]);
	if (cache->nplanes == 2)
		meram_deinit(priv, &cache->planes[1]);
	/* Cleanup and free. */
	meram_plane_cleanup(priv, &cache->planes[0]);
	meram_plane_free(priv, &cache->planes[0]);

	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);
}

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 *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 = {
	.module			= THIS_MODULE,
	.meram_register		= sh_mobile_meram_register,
	.meram_unregister	= sh_mobile_meram_unregister,
	.meram_update		= sh_mobile_meram_update,
	.cache_alloc		= sh_mobile_cache_alloc,
	.cache_free		= sh_mobile_cache_free,
	.cache_update		= sh_mobile_cache_update,
};

/* -----------------------------------------------------------------------------
+8 −13
Original line number Diff line number Diff line
@@ -41,19 +41,14 @@ struct sh_mobile_meram_cfg {
struct module;
struct sh_mobile_meram_ops {
	struct module	*module;
	/* register usage of meram */
	void *(*meram_register)(struct sh_mobile_meram_info *meram_dev,

	/* LCDC cache management */
	void *(*cache_alloc)(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 */
	void (*meram_unregister)(struct sh_mobile_meram_info *meram_dev,
				 void *data);

	/* update meram settings */
	void (*meram_update)(struct sh_mobile_meram_info *meram_dev, void *data,
			     unsigned int pixelformat, unsigned int *pitch);
	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_c,
			     unsigned long *icb_addr_y,