Unverified Commit 4b09c073 authored by Jernej Skrabec's avatar Jernej Skrabec Committed by Maxime Ripard
Browse files

drm/sun4i: Rework DE2 register defines



Most, if not all, registers found in DE2 still exists in DE3. However,
units are on different base addresses.

To prepare for addition of DE3 support, registers macros are reworked so
they take base address as parameter.

Signed-off-by: default avatarJernej Skrabec <jernej.skrabec@siol.net>
[rebased]
Signed-off-by: default avatarIcenowy Zheng <icenowy@aosc.io>
Signed-off-by: default avatarMaxime Ripard <maxime.ripard@bootlin.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181104182705.18047-10-jernej.skrabec@siol.net
parent fb3ef542
Loading
Loading
Loading
Loading
+9 −5
Original line number Original line Diff line number Diff line
@@ -368,6 +368,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
	struct sun8i_mixer *mixer;
	struct sun8i_mixer *mixer;
	struct resource *res;
	struct resource *res;
	void __iomem *regs;
	void __iomem *regs;
	unsigned int base;
	int plane_cnt;
	int plane_cnt;
	int i, ret;
	int i, ret;


@@ -456,6 +457,8 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,


	list_add_tail(&mixer->engine.list, &drv->engine_list);
	list_add_tail(&mixer->engine.list, &drv->engine_list);


	base = sun8i_blender_base(mixer);

	/* Reset the registers */
	/* Reset the registers */
	for (i = 0x0; i < 0x20000; i += 4)
	for (i = 0x0; i < 0x20000; i += 4)
		regmap_write(mixer->engine.regs, i, 0);
		regmap_write(mixer->engine.regs, i, 0);
@@ -465,24 +468,25 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
		     SUN8I_MIXER_GLOBAL_CTL_RT_EN);
		     SUN8I_MIXER_GLOBAL_CTL_RT_EN);


	/* Set background color to black */
	/* Set background color to black */
	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR,
	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base),
		     SUN8I_MIXER_BLEND_COLOR_BLACK);
		     SUN8I_MIXER_BLEND_COLOR_BLACK);


	/*
	/*
	 * Set fill color of bottom plane to black. Generally not needed
	 * Set fill color of bottom plane to black. Generally not needed
	 * except when VI plane is at bottom (zpos = 0) and enabled.
	 * except when VI plane is at bottom (zpos = 0) and enabled.
	 */
	 */
	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL,
	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
		     SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
		     SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(0),
	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0),
		     SUN8I_MIXER_BLEND_COLOR_BLACK);
		     SUN8I_MIXER_BLEND_COLOR_BLACK);


	plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num;
	plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num;
	for (i = 0; i < plane_cnt; i++)
	for (i = 0; i < plane_cnt; i++)
		regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_MODE(i),
		regmap_write(mixer->engine.regs,
			     SUN8I_MIXER_BLEND_MODE(base, i),
			     SUN8I_MIXER_BLEND_MODE_DEF);
			     SUN8I_MIXER_BLEND_MODE_DEF);


	regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL,
	regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
			   SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0);
			   SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0);


	return 0;
	return 0;
+30 −14
Original line number Original line Diff line number Diff line
@@ -29,20 +29,24 @@


#define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE		BIT(0)
#define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE		BIT(0)


#define SUN8I_MIXER_BLEND_PIPE_CTL		0x1000
#define DE2_BLD_BASE				0x1000
#define SUN8I_MIXER_BLEND_ATTR_FCOLOR(x)	(0x1004 + 0x10 * (x) + 0x0)
#define DE2_CH_BASE				0x2000
#define SUN8I_MIXER_BLEND_ATTR_INSIZE(x)	(0x1004 + 0x10 * (x) + 0x4)
#define DE2_CH_SIZE				0x1000
#define SUN8I_MIXER_BLEND_ATTR_COORD(x)		(0x1004 + 0x10 * (x) + 0x8)

#define SUN8I_MIXER_BLEND_ROUTE			0x1080
#define SUN8I_MIXER_BLEND_PIPE_CTL(base)	((base) + 0)
#define SUN8I_MIXER_BLEND_PREMULTIPLY		0x1084
#define SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, x)	((base) + 0x4 + 0x10 * (x))
#define SUN8I_MIXER_BLEND_BKCOLOR		0x1088
#define SUN8I_MIXER_BLEND_ATTR_INSIZE(base, x)	((base) + 0x8 + 0x10 * (x))
#define SUN8I_MIXER_BLEND_OUTSIZE		0x108c
#define SUN8I_MIXER_BLEND_ATTR_COORD(base, x)	((base) + 0xc + 0x10 * (x))
#define SUN8I_MIXER_BLEND_MODE(x)		(0x1090 + 0x04 * (x))
#define SUN8I_MIXER_BLEND_ROUTE(base)		((base) + 0x80)
#define SUN8I_MIXER_BLEND_CK_CTL		0x10b0
#define SUN8I_MIXER_BLEND_PREMULTIPLY(base)	((base) + 0x84)
#define SUN8I_MIXER_BLEND_CK_CFG		0x10b4
#define SUN8I_MIXER_BLEND_BKCOLOR(base)		((base) + 0x88)
#define SUN8I_MIXER_BLEND_CK_MAX(x)		(0x10c0 + 0x04 * (x))
#define SUN8I_MIXER_BLEND_OUTSIZE(base)		((base) + 0x8c)
#define SUN8I_MIXER_BLEND_CK_MIN(x)		(0x10e0 + 0x04 * (x))
#define SUN8I_MIXER_BLEND_MODE(base, x)		((base) + 0x90 + 0x04 * (x))
#define SUN8I_MIXER_BLEND_OUTCTL		0x10fc
#define SUN8I_MIXER_BLEND_CK_CTL(base)		((base) + 0xb0)
#define SUN8I_MIXER_BLEND_CK_CFG(base)		((base) + 0xb4)
#define SUN8I_MIXER_BLEND_CK_MAX(base, x)	((base) + 0xc0 + 0x04 * (x))
#define SUN8I_MIXER_BLEND_CK_MIN(base, x)	((base) + 0xe0 + 0x04 * (x))
#define SUN8I_MIXER_BLEND_OUTCTL(base)		((base) + 0xfc)


#define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK	GENMASK(12, 8)
#define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK	GENMASK(12, 8)
#define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)	BIT(8 + pipe)
#define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)	BIT(8 + pipe)
@@ -153,5 +157,17 @@ engine_to_sun8i_mixer(struct sunxi_engine *engine)
	return container_of(engine, struct sun8i_mixer, engine);
	return container_of(engine, struct sun8i_mixer, engine);
}
}


static inline u32
sun8i_blender_base(struct sun8i_mixer *mixer)
{
	return DE2_BLD_BASE;
}

static inline u32
sun8i_channel_base(struct sun8i_mixer *mixer, int channel)
{
	return DE2_CH_BASE + channel * DE2_CH_SIZE;
}

const struct de2_fmt_info *sun8i_mixer_format_info(u32 format);
const struct de2_fmt_info *sun8i_mixer_format_info(u32 format);
#endif /* _SUN8I_MIXER_H_ */
#endif /* _SUN8I_MIXER_H_ */
+30 −17
Original line number Original line Diff line number Diff line
@@ -30,7 +30,10 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
				  int overlay, bool enable, unsigned int zpos,
				  int overlay, bool enable, unsigned int zpos,
				  unsigned int old_zpos)
				  unsigned int old_zpos)
{
{
	u32 val;
	u32 val, bld_base, ch_base;

	bld_base = sun8i_blender_base(mixer);
	ch_base = sun8i_channel_base(mixer, channel);


	DRM_DEBUG_DRIVER("%sabling channel %d overlay %d\n",
	DRM_DEBUG_DRIVER("%sabling channel %d overlay %d\n",
			 enable ? "En" : "Dis", channel, overlay);
			 enable ? "En" : "Dis", channel, overlay);
@@ -41,17 +44,17 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
		val = 0;
		val = 0;


	regmap_update_bits(mixer->engine.regs,
	regmap_update_bits(mixer->engine.regs,
			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay),
			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val);
			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val);


	if (!enable || zpos != old_zpos) {
	if (!enable || zpos != old_zpos) {
		regmap_update_bits(mixer->engine.regs,
		regmap_update_bits(mixer->engine.regs,
				   SUN8I_MIXER_BLEND_PIPE_CTL,
				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
				   SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
				   SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
				   0);
				   0);


		regmap_update_bits(mixer->engine.regs,
		regmap_update_bits(mixer->engine.regs,
				   SUN8I_MIXER_BLEND_ROUTE,
				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
				   0);
				   0);
	}
	}
@@ -60,12 +63,13 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
		val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
		val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);


		regmap_update_bits(mixer->engine.regs,
		regmap_update_bits(mixer->engine.regs,
				   SUN8I_MIXER_BLEND_PIPE_CTL, val, val);
				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
				   val, val);


		val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
		val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);


		regmap_update_bits(mixer->engine.regs,
		regmap_update_bits(mixer->engine.regs,
				   SUN8I_MIXER_BLEND_ROUTE,
				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
				   val);
				   val);
	}
	}
@@ -77,12 +81,16 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
{
{
	struct drm_plane_state *state = plane->state;
	struct drm_plane_state *state = plane->state;
	u32 src_w, src_h, dst_w, dst_h;
	u32 src_w, src_h, dst_w, dst_h;
	u32 bld_base, ch_base;
	u32 outsize, insize;
	u32 outsize, insize;
	u32 hphase, vphase;
	u32 hphase, vphase;


	DRM_DEBUG_DRIVER("Updating UI channel %d overlay %d\n",
	DRM_DEBUG_DRIVER("Updating UI channel %d overlay %d\n",
			 channel, overlay);
			 channel, overlay);


	bld_base = sun8i_blender_base(mixer);
	ch_base = sun8i_channel_base(mixer, channel);

	src_w = drm_rect_width(&state->src) >> 16;
	src_w = drm_rect_width(&state->src) >> 16;
	src_h = drm_rect_height(&state->src) >> 16;
	src_h = drm_rect_height(&state->src) >> 16;
	dst_w = drm_rect_width(&state->dst);
	dst_w = drm_rect_width(&state->dst);
@@ -103,8 +111,8 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
		regmap_write(mixer->engine.regs,
		regmap_write(mixer->engine.regs,
			     SUN8I_MIXER_GLOBAL_SIZE,
			     SUN8I_MIXER_GLOBAL_SIZE,
			     outsize);
			     outsize);
		regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_OUTSIZE,
		regmap_write(mixer->engine.regs,
			     outsize);
			     SUN8I_MIXER_BLEND_OUTSIZE(bld_base), outsize);


		if (state->crtc)
		if (state->crtc)
			interlaced = state->crtc->state->adjusted_mode.flags
			interlaced = state->crtc->state->adjusted_mode.flags
@@ -116,7 +124,7 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
			val = 0;
			val = 0;


		regmap_update_bits(mixer->engine.regs,
		regmap_update_bits(mixer->engine.regs,
				   SUN8I_MIXER_BLEND_OUTCTL,
				   SUN8I_MIXER_BLEND_OUTCTL(bld_base),
				   SUN8I_MIXER_BLEND_OUTCTL_INTERLACED,
				   SUN8I_MIXER_BLEND_OUTCTL_INTERLACED,
				   val);
				   val);


@@ -129,10 +137,10 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
			 state->src.x1 >> 16, state->src.y1 >> 16);
			 state->src.x1 >> 16, state->src.y1 >> 16);
	DRM_DEBUG_DRIVER("Layer source size W: %d H: %d\n", src_w, src_h);
	DRM_DEBUG_DRIVER("Layer source size W: %d H: %d\n", src_w, src_h);
	regmap_write(mixer->engine.regs,
	regmap_write(mixer->engine.regs,
		     SUN8I_MIXER_CHAN_UI_LAYER_SIZE(channel, overlay),
		     SUN8I_MIXER_CHAN_UI_LAYER_SIZE(ch_base, overlay),
		     insize);
		     insize);
	regmap_write(mixer->engine.regs,
	regmap_write(mixer->engine.regs,
		     SUN8I_MIXER_CHAN_UI_OVL_SIZE(channel),
		     SUN8I_MIXER_CHAN_UI_OVL_SIZE(ch_base),
		     insize);
		     insize);


	if (insize != outsize || hphase || vphase) {
	if (insize != outsize || hphase || vphase) {
@@ -156,10 +164,10 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
			 state->dst.x1, state->dst.y1);
			 state->dst.x1, state->dst.y1);
	DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h);
	DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h);
	regmap_write(mixer->engine.regs,
	regmap_write(mixer->engine.regs,
		     SUN8I_MIXER_BLEND_ATTR_COORD(zpos),
		     SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos),
		     SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1));
		     SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1));
	regmap_write(mixer->engine.regs,
	regmap_write(mixer->engine.regs,
		     SUN8I_MIXER_BLEND_ATTR_INSIZE(zpos),
		     SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos),
		     outsize);
		     outsize);


	return 0;
	return 0;
@@ -170,7 +178,9 @@ static int sun8i_ui_layer_update_formats(struct sun8i_mixer *mixer, int channel,
{
{
	struct drm_plane_state *state = plane->state;
	struct drm_plane_state *state = plane->state;
	const struct de2_fmt_info *fmt_info;
	const struct de2_fmt_info *fmt_info;
	u32 val;
	u32 val, ch_base;

	ch_base = sun8i_channel_base(mixer, channel);


	fmt_info = sun8i_mixer_format_info(state->fb->format->format);
	fmt_info = sun8i_mixer_format_info(state->fb->format->format);
	if (!fmt_info || !fmt_info->rgb) {
	if (!fmt_info || !fmt_info->rgb) {
@@ -180,7 +190,7 @@ static int sun8i_ui_layer_update_formats(struct sun8i_mixer *mixer, int channel,


	val = fmt_info->de2_fmt << SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_OFFSET;
	val = fmt_info->de2_fmt << SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_OFFSET;
	regmap_update_bits(mixer->engine.regs,
	regmap_update_bits(mixer->engine.regs,
			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay),
			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK, val);
			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK, val);


	return 0;
	return 0;
@@ -193,8 +203,11 @@ static int sun8i_ui_layer_update_buffer(struct sun8i_mixer *mixer, int channel,
	struct drm_framebuffer *fb = state->fb;
	struct drm_framebuffer *fb = state->fb;
	struct drm_gem_cma_object *gem;
	struct drm_gem_cma_object *gem;
	dma_addr_t paddr;
	dma_addr_t paddr;
	u32 ch_base;
	int bpp;
	int bpp;


	ch_base = sun8i_channel_base(mixer, channel);

	/* Get the physical address of the buffer in memory */
	/* Get the physical address of the buffer in memory */
	gem = drm_fb_cma_get_gem_obj(fb, 0);
	gem = drm_fb_cma_get_gem_obj(fb, 0);


@@ -211,13 +224,13 @@ static int sun8i_ui_layer_update_buffer(struct sun8i_mixer *mixer, int channel,
	/* Set the line width */
	/* Set the line width */
	DRM_DEBUG_DRIVER("Layer line width: %d bytes\n", fb->pitches[0]);
	DRM_DEBUG_DRIVER("Layer line width: %d bytes\n", fb->pitches[0]);
	regmap_write(mixer->engine.regs,
	regmap_write(mixer->engine.regs,
		     SUN8I_MIXER_CHAN_UI_LAYER_PITCH(channel, overlay),
		     SUN8I_MIXER_CHAN_UI_LAYER_PITCH(ch_base, overlay),
		     fb->pitches[0]);
		     fb->pitches[0]);


	DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr);
	DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr);


	regmap_write(mixer->engine.regs,
	regmap_write(mixer->engine.regs,
		     SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(channel, overlay),
		     SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(ch_base, overlay),
		     lower_32_bits(paddr));
		     lower_32_bits(paddr));


	return 0;
	return 0;
+20 −17
Original line number Original line Diff line number Diff line
@@ -18,23 +18,26 @@


#include <drm/drm_plane.h>
#include <drm/drm_plane.h>


#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch, layer) \
#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR(base, layer) \
			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x0)
			((base) + 0x20 * (layer) + 0x0)
#define SUN8I_MIXER_CHAN_UI_LAYER_SIZE(ch, layer) \
#define SUN8I_MIXER_CHAN_UI_LAYER_SIZE(base, layer) \
			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x4)
			((base) + 0x20 * (layer) + 0x4)
#define SUN8I_MIXER_CHAN_UI_LAYER_COORD(ch, layer) \
#define SUN8I_MIXER_CHAN_UI_LAYER_COORD(base, layer) \
			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x8)
			((base) + 0x20 * (layer) + 0x8)
#define SUN8I_MIXER_CHAN_UI_LAYER_PITCH(ch, layer) \
#define SUN8I_MIXER_CHAN_UI_LAYER_PITCH(base, layer) \
			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0xc)
			((base) + 0x20 * (layer) + 0xc)
#define SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(ch, layer) \
#define SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(base, layer) \
			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x10)
			((base) + 0x20 * (layer) + 0x10)
#define SUN8I_MIXER_CHAN_UI_LAYER_BOT_LADDR(ch, layer) \
#define SUN8I_MIXER_CHAN_UI_LAYER_BOT_LADDR(base, layer) \
			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x14)
			((base) + 0x20 * (layer) + 0x14)
#define SUN8I_MIXER_CHAN_UI_LAYER_FCOLOR(ch, layer) \
#define SUN8I_MIXER_CHAN_UI_LAYER_FCOLOR(base, layer) \
			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x18)
			((base) + 0x20 * (layer) + 0x18)
#define SUN8I_MIXER_CHAN_UI_TOP_HADDR(ch)	(0x2000 + 0x1000 * (ch) + 0x80)
#define SUN8I_MIXER_CHAN_UI_TOP_HADDR(base) \
#define SUN8I_MIXER_CHAN_UI_BOT_HADDR(ch)	(0x2000 + 0x1000 * (ch) + 0x84)
			((base) + 0x80)
#define SUN8I_MIXER_CHAN_UI_OVL_SIZE(ch)	(0x2000 + 0x1000 * (ch) + 0x88)
#define SUN8I_MIXER_CHAN_UI_BOT_HADDR(base) \
			((base) + 0x84)
#define SUN8I_MIXER_CHAN_UI_OVL_SIZE(base) \
			((base) + 0x88)


#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN		BIT(0)
#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN		BIT(0)
#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_MASK	GENMASK(2, 1)
#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_MASK	GENMASK(2, 1)
+25 −16
Original line number Original line Diff line number Diff line
@@ -10,6 +10,7 @@
 */
 */


#include "sun8i_ui_scaler.h"
#include "sun8i_ui_scaler.h"
#include "sun8i_vi_scaler.h"


static const u32 lan2coefftab16[240] = {
static const u32 lan2coefftab16[240] = {
	0x00004000, 0x00033ffe, 0x00063efc, 0x000a3bfb,
	0x00004000, 0x00033ffe, 0x00063efc, 0x000a3bfb,
@@ -88,6 +89,14 @@ static const u32 lan2coefftab16[240] = {
	0x0b1c1603, 0x0d1c1502, 0x0e1d1401, 0x0f1d1301,
	0x0b1c1603, 0x0d1c1502, 0x0e1d1401, 0x0f1d1301,
};
};


static u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int channel)
{
	int vi_num = mixer->cfg->vi_num;

	return DE2_VI_SCALER_UNIT_BASE + DE2_VI_SCALER_UNIT_SIZE * vi_num +
	       DE2_UI_SCALER_UNIT_SIZE * (channel - vi_num);
}

static int sun8i_ui_scaler_coef_index(unsigned int step)
static int sun8i_ui_scaler_coef_index(unsigned int step)
{
{
	unsigned int scale, int_part, float_part;
	unsigned int scale, int_part, float_part;
@@ -114,33 +123,35 @@ static int sun8i_ui_scaler_coef_index(unsigned int step)


void sun8i_ui_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable)
void sun8i_ui_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable)
{
{
	int vi_cnt = mixer->cfg->vi_num;
	u32 val, base;
	u32 val;


	if (WARN_ON(layer < vi_cnt))
	if (WARN_ON(layer < mixer->cfg->vi_num))
		return;
		return;


	base = sun8i_ui_scaler_base(mixer, layer);

	if (enable)
	if (enable)
		val = SUN8I_SCALER_GSU_CTRL_EN |
		val = SUN8I_SCALER_GSU_CTRL_EN |
		      SUN8I_SCALER_GSU_CTRL_COEFF_RDY;
		      SUN8I_SCALER_GSU_CTRL_COEFF_RDY;
	else
	else
		val = 0;
		val = 0;


	regmap_write(mixer->engine.regs,
	regmap_write(mixer->engine.regs, SUN8I_SCALER_GSU_CTRL(base), val);
		     SUN8I_SCALER_GSU_CTRL(vi_cnt, layer - vi_cnt), val);
}
}


void sun8i_ui_scaler_setup(struct sun8i_mixer *mixer, int layer,
void sun8i_ui_scaler_setup(struct sun8i_mixer *mixer, int layer,
			   u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
			   u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
			   u32 hscale, u32 vscale, u32 hphase, u32 vphase)
			   u32 hscale, u32 vscale, u32 hphase, u32 vphase)
{
{
	int vi_cnt = mixer->cfg->vi_num;
	u32 insize, outsize;
	u32 insize, outsize;
	int i, offset;
	int i, offset;
	u32 base;


	if (WARN_ON(layer < vi_cnt))
	if (WARN_ON(layer < mixer->cfg->vi_num))
		return;
		return;


	base = sun8i_ui_scaler_base(mixer, layer);

	hphase <<= SUN8I_UI_SCALER_PHASE_FRAC - 16;
	hphase <<= SUN8I_UI_SCALER_PHASE_FRAC - 16;
	vphase <<= SUN8I_UI_SCALER_PHASE_FRAC - 16;
	vphase <<= SUN8I_UI_SCALER_PHASE_FRAC - 16;
	hscale <<= SUN8I_UI_SCALER_SCALE_FRAC - 16;
	hscale <<= SUN8I_UI_SCALER_SCALE_FRAC - 16;
@@ -149,24 +160,22 @@ void sun8i_ui_scaler_setup(struct sun8i_mixer *mixer, int layer,
	insize = SUN8I_UI_SCALER_SIZE(src_w, src_h);
	insize = SUN8I_UI_SCALER_SIZE(src_w, src_h);
	outsize = SUN8I_UI_SCALER_SIZE(dst_w, dst_h);
	outsize = SUN8I_UI_SCALER_SIZE(dst_w, dst_h);


	layer -= vi_cnt;

	regmap_write(mixer->engine.regs,
	regmap_write(mixer->engine.regs,
		     SUN8I_SCALER_GSU_OUTSIZE(vi_cnt, layer), outsize);
		     SUN8I_SCALER_GSU_OUTSIZE(base), outsize);
	regmap_write(mixer->engine.regs,
	regmap_write(mixer->engine.regs,
		     SUN8I_SCALER_GSU_INSIZE(vi_cnt, layer), insize);
		     SUN8I_SCALER_GSU_INSIZE(base), insize);
	regmap_write(mixer->engine.regs,
	regmap_write(mixer->engine.regs,
		     SUN8I_SCALER_GSU_HSTEP(vi_cnt, layer), hscale);
		     SUN8I_SCALER_GSU_HSTEP(base), hscale);
	regmap_write(mixer->engine.regs,
	regmap_write(mixer->engine.regs,
		     SUN8I_SCALER_GSU_VSTEP(vi_cnt, layer), vscale);
		     SUN8I_SCALER_GSU_VSTEP(base), vscale);
	regmap_write(mixer->engine.regs,
	regmap_write(mixer->engine.regs,
		     SUN8I_SCALER_GSU_HPHASE(vi_cnt, layer), hphase);
		     SUN8I_SCALER_GSU_HPHASE(base), hphase);
	regmap_write(mixer->engine.regs,
	regmap_write(mixer->engine.regs,
		     SUN8I_SCALER_GSU_VPHASE(vi_cnt, layer), vphase);
		     SUN8I_SCALER_GSU_VPHASE(base), vphase);
	offset = sun8i_ui_scaler_coef_index(hscale) *
	offset = sun8i_ui_scaler_coef_index(hscale) *
			SUN8I_UI_SCALER_COEFF_COUNT;
			SUN8I_UI_SCALER_COEFF_COUNT;
	for (i = 0; i < SUN8I_UI_SCALER_COEFF_COUNT; i++)
	for (i = 0; i < SUN8I_UI_SCALER_COEFF_COUNT; i++)
		regmap_write(mixer->engine.regs,
		regmap_write(mixer->engine.regs,
			     SUN8I_SCALER_GSU_HCOEFF(vi_cnt, layer, i),
			     SUN8I_SCALER_GSU_HCOEFF(base, i),
			     lan2coefftab16[offset + i]);
			     lan2coefftab16[offset + i]);
}
}
Loading