From 5cd2c5c50354549fb1eae510af3b39dbd3884818 Mon Sep 17 00:00:00 2001 From: Topi Pohjolainen Date: Fri, 27 Apr 2012 17:24:27 +0300 Subject: [PATCH] staging: topaz: add support for bias table Part of hw video driver update from UMG. Signed-off-by: Topi Pohjolainen --- drivers/staging/mrst/imgv/pnw_topaz.c | 39 +++++++++++++++++++++ drivers/staging/mrst/imgv/pnw_topaz.h | 8 +++++ drivers/staging/mrst/imgv/pnw_topazinit.c | 57 +++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) diff --git a/drivers/staging/mrst/imgv/pnw_topaz.c b/drivers/staging/mrst/imgv/pnw_topaz.c index 6e7ea19..9d8db4f 100644 --- a/drivers/staging/mrst/imgv/pnw_topaz.c +++ b/drivers/staging/mrst/imgv/pnw_topaz.c @@ -421,6 +421,37 @@ int pnw_topaz_kick_null_cmd(struct drm_psb_private *dev_priv, return 0; } +static void pnw_topaz_save_bias_table(struct pnw_topaz_private *topaz_priv, + const void *cmd, int byte_size, int core) +{ + PSB_DEBUG_GENERAL("TOPAZ: Save BIAS table(size %d) for core %d\n", + byte_size, core); + + if (byte_size > PNW_TOPAZ_BIAS_TABLE_MAX_SIZE) { + DRM_ERROR("Invalid BIAS table size %d!\n", byte_size); + return; + } + + if (core > (topaz_priv->topaz_num_cores - 1)) { + DRM_ERROR("Invalid core id %d\n", core); + return; + } + + if (topaz_priv->topaz_bias_table[core] == NULL) { + topaz_priv->topaz_bias_table[core] = + kmalloc(PNW_TOPAZ_BIAS_TABLE_MAX_SIZE, + GFP_KERNEL); + if (NULL == topaz_priv->topaz_bias_table[core]) { + DRM_ERROR("Run out of memory!\n"); + return; + } + } + + memcpy(topaz_priv->topaz_bias_table[core], + cmd, byte_size); + return; +} + static int pnw_topaz_send(struct drm_device *dev, void *cmd, unsigned long cmd_size, uint32_t sync_seq) @@ -480,6 +511,14 @@ pnw_topaz_send(struct drm_device *dev, void *cmd, p_command = (uint32_t *)(command); p_command++; cur_cmd_size = *p_command; + + if ((drm_topaz_pmpolicy != PSB_PMPOLICY_NOPM) && + (!PNW_IS_JPEG_ENC(topaz_priv->topaz_cur_codec))) + pnw_topaz_save_bias_table(topaz_priv, + (const void *)command, + (cur_cmd_size * 2 + 2) * 4, + cur_cmd_header->core); + p_command++; PSB_DEBUG_GENERAL("TOPAZ: Start to write" " %d Registers\n", cur_cmd_size); diff --git a/drivers/staging/mrst/imgv/pnw_topaz.h b/drivers/staging/mrst/imgv/pnw_topaz.h index 3a7e1ae..fdf0640 100644 --- a/drivers/staging/mrst/imgv/pnw_topaz.h +++ b/drivers/staging/mrst/imgv/pnw_topaz.h @@ -30,8 +30,15 @@ /*Must be equal to IMG_CODEC_NUM*/ #define PNW_TOPAZ_CODEC_NUM_MAX (11) +#define PNW_TOPAZ_BIAS_TABLE_MAX_SIZE (2 * 1024) //#define TOPAZ_PDUMP +#define PNW_IS_H264_ENC(codec) \ + (codec == IMG_CODEC_H264_VBR || \ + codec == IMG_CODEC_H264_VCM || \ + codec == IMG_CODEC_H264_CBR || \ + codec == IMG_CODEC_H264_NO_RC) + #define PNW_IS_JPEG_ENC(codec) \ (codec == IMG_CODEC_JPEG) @@ -79,6 +86,7 @@ struct pnw_topaz_private { uint32_t topaz_cur_codec; uint32_t cur_mtx_data_size[MAX_TOPAZ_CORES]; int topaz_needs_reset; + void *topaz_bias_table[MAX_TOPAZ_CORES]; /* *topaz command queue diff --git a/drivers/staging/mrst/imgv/pnw_topazinit.c b/drivers/staging/mrst/imgv/pnw_topazinit.c index cb596f2..802eba8 100644 --- a/drivers/staging/mrst/imgv/pnw_topazinit.c +++ b/drivers/staging/mrst/imgv/pnw_topazinit.c @@ -486,6 +486,8 @@ int pnw_topaz_uninit(struct drm_device *dev) /* release mtx data memory save space */ if (topaz_priv->topaz_mtx_data_mem[n]) ttm_bo_unref(&topaz_priv->topaz_mtx_data_mem[n]); + + kfree(topaz_priv->topaz_bias_table[n]); } /* # release firmware storage */ for (n = 0; n < IMG_CODEC_NUM * 2; ++n) { @@ -1420,6 +1422,50 @@ void pnw_topaz_mmu_flushcache(struct drm_psb_private *dev_priv) psb_gl3_global_invalidation(dev_priv->dev); } + +static void pnw_topaz_restore_bias_table(struct drm_psb_private *dev_priv, + int core) +{ + struct pnw_topaz_private *topaz_priv = dev_priv->topaz_private; + u32 *p_command; + unsigned int reg_cnt, reg_off, reg_val; + int cur_cmd_size; + + if (core >= MAX_TOPAZ_CORES || + topaz_priv->topaz_bias_table[core] == NULL) { + /* + * If VEC D0i3 isn't enabled, the bias table won't be saved + * in initialization. No need to restore. + */ + return; + } + + p_command = (u32 *)(topaz_priv->topaz_bias_table[core]); + p_command++; + cur_cmd_size = *p_command; + p_command++; + + PSB_DEBUG_GENERAL("TOPAZ: Restore BIAS table(size %d) for core %c\n", + cur_cmd_size, + core); + for (reg_cnt = 0; reg_cnt < cur_cmd_size; reg_cnt++) { + reg_off = *p_command; + p_command++; + reg_val = *p_command; + p_command++; + + if (reg_off > TOPAZSC_REG_OFF_MAX) + DRM_ERROR("TOPAZ: Ignore write (0x%08x)" + " to register 0x%08x\n", + reg_val, reg_off); + else + MM_WRITE32(0, reg_off, reg_val); + } + + return; +} + + int pnw_topaz_restore_mtx_state(struct drm_device *dev) { struct drm_psb_private *dev_priv = @@ -1634,6 +1680,17 @@ int pnw_topaz_restore_mtx_state(struct drm_device *dev) } + if (!PNW_IS_JPEG_ENC(topaz_priv->topaz_cur_codec)) { + for (core_id = topaz_priv->topaz_num_cores - 1; + core_id >= 0; core_id--) { + /*MPEG4/H263 only use core 0*/ + if (!PNW_IS_H264_ENC(topaz_priv->topaz_cur_codec) + && core_id > 0) + continue; + pnw_topaz_restore_bias_table(dev_priv, core_id); + } + } + PSB_DEBUG_GENERAL("TOPAZ: send NULL command to test firmware\n"); topaz_priv->topaz_mtx_saved = 0; return 0; -- 2.7.4