1
0
Fork 0

gpu: ipu-v3: pre: add tiled prefetch support

This configures the TPR unit, using the DRM format modifier. For now only
the single buffer modifiers are supported, as split buffer needs more
configuration for the required cropping.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
[p.zabel@pengutronix.de: rebased after ERR009624 workaround]
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
hifive-unleashed-5.1
Lucas Stach 2017-11-10 17:09:58 +01:00 committed by Philipp Zabel
parent 7294408973
commit 2f64a55443
3 changed files with 29 additions and 6 deletions

View File

@ -49,6 +49,10 @@
#define IPU_PRE_TPR_CTRL 0x070
#define IPU_PRE_TPR_CTRL_TILE_FORMAT(v) ((v & 0xff) << 0)
#define IPU_PRE_TPR_CTRL_TILE_FORMAT_MASK 0xff
#define IPU_PRE_TPR_CTRL_TILE_FORMAT_16_BIT (1 << 0)
#define IPU_PRE_TPR_CTRL_TILE_FORMAT_SPLIT_BUF (1 << 4)
#define IPU_PRE_TPR_CTRL_TILE_FORMAT_SINGLE_BUF (1 << 5)
#define IPU_PRE_TPR_CTRL_TILE_FORMAT_SUPER_TILED (1 << 6)
#define IPU_PRE_PREFETCH_ENG_CTRL 0x080
#define IPU_PRE_PREF_ENG_CTRL_PREFETCH_EN (1 << 0)
@ -147,7 +151,7 @@ int ipu_pre_get(struct ipu_pre *pre)
val = IPU_PRE_CTRL_HANDSHAKE_ABORT_SKIP_EN |
IPU_PRE_CTRL_HANDSHAKE_EN |
IPU_PRE_CTRL_TPR_REST_SEL |
IPU_PRE_CTRL_BLOCK_16 | IPU_PRE_CTRL_SDW_UPDATE;
IPU_PRE_CTRL_SDW_UPDATE;
writel(val, pre->regs + IPU_PRE_CTRL);
pre->in_use = true;
@ -163,14 +167,17 @@ void ipu_pre_put(struct ipu_pre *pre)
void ipu_pre_configure(struct ipu_pre *pre, unsigned int width,
unsigned int height, unsigned int stride, u32 format,
unsigned int bufaddr)
uint64_t modifier, unsigned int bufaddr)
{
const struct drm_format_info *info = drm_format_info(format);
u32 active_bpp = info->cpp[0] >> 1;
u32 val;
/* calculate safe window for ctrl register updates */
pre->safe_window_end = height - 2;
if (modifier == DRM_FORMAT_MOD_LINEAR)
pre->safe_window_end = height - 2;
else
pre->safe_window_end = DIV_ROUND_UP(height, 4) - 1;
writel(bufaddr, pre->regs + IPU_PRE_CUR_BUF);
writel(bufaddr, pre->regs + IPU_PRE_NEXT_BUF);
@ -203,9 +210,25 @@ void ipu_pre_configure(struct ipu_pre *pre, unsigned int width,
writel(pre->buffer_paddr, pre->regs + IPU_PRE_STORE_ENG_ADDR);
val = readl(pre->regs + IPU_PRE_TPR_CTRL);
val &= ~IPU_PRE_TPR_CTRL_TILE_FORMAT_MASK;
if (modifier != DRM_FORMAT_MOD_LINEAR) {
/* only support single buffer formats for now */
val |= IPU_PRE_TPR_CTRL_TILE_FORMAT_SINGLE_BUF;
if (modifier == DRM_FORMAT_MOD_VIVANTE_SUPER_TILED)
val |= IPU_PRE_TPR_CTRL_TILE_FORMAT_SUPER_TILED;
if (info->cpp[0] == 2)
val |= IPU_PRE_TPR_CTRL_TILE_FORMAT_16_BIT;
}
writel(val, pre->regs + IPU_PRE_TPR_CTRL);
val = readl(pre->regs + IPU_PRE_CTRL);
val |= IPU_PRE_CTRL_EN_REPEAT | IPU_PRE_CTRL_ENABLE |
IPU_PRE_CTRL_SDW_UPDATE;
if (modifier == DRM_FORMAT_MOD_LINEAR)
val &= ~IPU_PRE_CTRL_BLOCK_EN;
else
val |= IPU_PRE_CTRL_BLOCK_EN;
writel(val, pre->regs + IPU_PRE_CTRL);
}

View File

@ -287,7 +287,7 @@ int ipu_prg_channel_configure(struct ipuv3_channel *ipu_chan,
return ret;
ipu_pre_configure(prg->pres[chan->used_pre],
width, height, stride, format, *eba);
width, height, stride, format, 0, *eba);
pm_runtime_get_sync(prg->dev);

View File

@ -269,8 +269,8 @@ int ipu_pre_get(struct ipu_pre *pre);
void ipu_pre_put(struct ipu_pre *pre);
u32 ipu_pre_get_baddr(struct ipu_pre *pre);
void ipu_pre_configure(struct ipu_pre *pre, unsigned int width,
unsigned int height,
unsigned int stride, u32 format, unsigned int bufaddr);
unsigned int height, unsigned int stride, u32 format,
uint64_t modifier, unsigned int bufaddr);
void ipu_pre_update(struct ipu_pre *pre, unsigned int bufaddr);
struct ipu_prg *ipu_prg_lookup_by_phandle(struct device *dev, const char *name,