Skip to content

Commit

Permalink
gpu: ipu-v3: pre: add tiled prefetch support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Lucas Stach authored and Philipp Zabel committed Dec 19, 2017
1 parent 7294408 commit 2f64a55
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
29 changes: 26 additions & 3 deletions drivers/gpu/ipu-v3/ipu-pre.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/ipu-v3/ipu-prg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/ipu-v3/ipu-prv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 2f64a55

Please sign in to comment.