static void msvdx_get_mtx_control_from_dash(struct drm_psb_private *dev_priv)
{
	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
	int count = 0;
	uint32_t reg_val = 0;

	REGIO_WRITE_FIELD(reg_val, MSVDX_MTX_DEBUG, MTX_DBG_IS_SLAVE, 1);
	REGIO_WRITE_FIELD(reg_val, MSVDX_MTX_DEBUG, MTX_DBG_GPIO_IN, 0x02);
	PSB_WMSVDX32(reg_val, MSVDX_MTX_DEBUG_OFFSET);

	do {
		reg_val = PSB_RMSVDX32(MSVDX_MTX_DEBUG_OFFSET);
		count++;
	} while (((reg_val & 0x18) != 0) && count < 50000);

	if (count >= 50000)
		PSB_DEBUG_GENERAL("MAVDX: timeout in get_mtx_control_from_dash\n");

	/* Save the access control register...*/
	msvdx_priv->psb_dash_access_ctrl = PSB_RMSVDX32(MTX_RAM_ACCESS_CONTROL_OFFSET);
}
static void tng__JPEG_set_ent_dec(context_JPEG_p ctx) {
    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
    uint32_t reg_value;

    psb_cmdbuf_reg_start_block(cmdbuf, 0);
    reg_value = 0;
    REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL, ENTDEC_FE_MODE, 0 );
    psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL ), reg_value);
    psb_cmdbuf_reg_end_block(cmdbuf);

    psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET( MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL ));
    reg_value = 0;
    REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_MODE, 0);
    psb_cmdbuf_rendec_write(cmdbuf, reg_value);
    psb_cmdbuf_rendec_end(cmdbuf);

}
static void msvdx_upload_fw(struct drm_psb_private *dev_priv,
			  uint32_t address, const unsigned int words, int fw_sel)
{
	uint32_t reg_val = 0;
	uint32_t cmd;
	uint32_t uCountReg, offset, mmu_ptd;
	uint32_t size = (words * 4); /* byte count */
	uint32_t dma_channel = 0; /* Setup a Simple DMA for Ch0 */
	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;

	PSB_DEBUG_GENERAL("MSVDX: Upload firmware by DMA\n");
	msvdx_get_mtx_control_from_dash(dev_priv);

	/* dma transfers to/from the mtx have to be 32-bit aligned and in multiples of 32 bits */
	PSB_WMSVDX32(address, MTX_SYSC_CDMAA_OFFSET);

	REGIO_WRITE_FIELD_LITE(reg_val, MTX_SYSC_CDMAC, BURSTSIZE,	4); /* burst size in multiples of 64 bits (allowed values are 2 or 4) */
	REGIO_WRITE_FIELD_LITE(reg_val, MTX_SYSC_CDMAC, RNW, 0);	/* false means write to mtx mem, true means read from mtx mem */
	REGIO_WRITE_FIELD_LITE(reg_val, MTX_SYSC_CDMAC, ENABLE,	1);				/* begin transfer */
	REGIO_WRITE_FIELD_LITE(reg_val, MTX_SYSC_CDMAC, LENGTH,	words);		/* This specifies the transfer size of the DMA operation in terms of 32-bit words */
	PSB_WMSVDX32(reg_val, MTX_SYSC_CDMAC_OFFSET);

	/* toggle channel 0 usage between mtx and other msvdx peripherals */
	{
		reg_val = PSB_RMSVDX32(MSVDX_CONTROL_OFFSET);
		REGIO_WRITE_FIELD(reg_val, MSVDX_CONTROL, DMAC_CH0_SELECT,  0);
		PSB_WMSVDX32(reg_val, MSVDX_CONTROL_OFFSET);
	}


	/* Clear the DMAC Stats */
	PSB_WMSVDX32(0 , DMAC_DMAC_IRQ_STAT_OFFSET + dma_channel);

	offset = msvdx_priv->fw->offset;

	if (fw_sel)
		offset += ((msvdx_priv->mtx_mem_size + 8192) & ~0xfff);

	/* use bank 0 */
	cmd = 0;
	PSB_WMSVDX32(cmd, MSVDX_MMU_BANK_INDEX_OFFSET);

	/* Write PTD to mmu base 0*/
	mmu_ptd = psb_get_default_pd_addr(dev_priv->mmu);
	PSB_WMSVDX32(mmu_ptd, MSVDX_MMU_DIR_LIST_BASE_OFFSET + 0);

	/* Invalidate */
	reg_val = PSB_RMSVDX32(MSVDX_MMU_CONTROL0_OFFSET);
	reg_val &= ~0xf;
	REGIO_WRITE_FIELD(reg_val, MSVDX_MMU_CONTROL0, MMU_INVALDC, 1);
	PSB_WMSVDX32(reg_val, MSVDX_MMU_CONTROL0_OFFSET);

	PSB_WMSVDX32(offset, DMAC_DMAC_SETUP_OFFSET + dma_channel);

	/* Only use a single dma - assert that this is valid */
	if ((size / 4) >= (1 << 15)) {
		DRM_ERROR("psb: DMA size beyond limited, aboart firmware uploading\n");
		return;
	}

	uCountReg = PSB_DMAC_VALUE_COUNT(PSB_DMAC_BSWAP_NO_SWAP,
					 0,  /* 32 bits */
					 PSB_DMAC_DIR_MEM_TO_PERIPH,
					 0,
					 (size / 4));
	/* Set the number of bytes to dma*/
	PSB_WMSVDX32(uCountReg, DMAC_DMAC_COUNT_OFFSET + dma_channel);

	cmd = PSB_DMAC_VALUE_PERIPH_PARAM(PSB_DMAC_ACC_DEL_0, PSB_DMAC_INCR_OFF, PSB_DMAC_BURST_2);
	PSB_WMSVDX32(cmd, DMAC_DMAC_PERIPH_OFFSET + dma_channel);

	/* Set destination port for dma */
	cmd = 0;
	REGIO_WRITE_FIELD(cmd, DMAC_DMAC_PERIPHERAL_ADDR, ADDR, MTX_SYSC_CDMAT_OFFSET);
	PSB_WMSVDX32(cmd, DMAC_DMAC_PERIPHERAL_ADDR_OFFSET + dma_channel);


	/* Finally, rewrite the count register with the enable bit set*/
	PSB_WMSVDX32(uCountReg | DMAC_DMAC_COUNT_EN_MASK, DMAC_DMAC_COUNT_OFFSET + dma_channel);

	/* Wait for all to be done */
	if (psb_wait_for_register(dev_priv,
				  DMAC_DMAC_IRQ_STAT_OFFSET + dma_channel,
				  DMAC_DMAC_IRQ_STAT_TRANSFER_FIN_MASK,
				  DMAC_DMAC_IRQ_STAT_TRANSFER_FIN_MASK,
				  2000000, 5)) {
		psb_setup_fw_dump(dev_priv, dma_channel);
		msvdx_release_mtx_control_from_dash(dev_priv);
		return;
	}

	/* Assert that the MTX DMA port is all done aswell */
	if (psb_wait_for_register(dev_priv,
			MTX_SYSC_CDMAS0_OFFSET,
			1, 1, 2000000, 5)) {
		msvdx_release_mtx_control_from_dash(dev_priv);
		return;
	}

	msvdx_release_mtx_control_from_dash(dev_priv);

	PSB_DEBUG_GENERAL("MSVDX: Upload done\n");
}
static void tng__JPEG_set_register(context_JPEG_p ctx, VASliceParameterBufferJPEGBaseline *slice_param) {
    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
    uint32_t reg_value;
    const uint32_t num_MCUs = ctx->MCU_width * ctx->MCU_height;
    const uint32_t num_MCUs_dec = slice_param->restart_interval ? min(slice_param->restart_interval, num_MCUs) :  num_MCUs;

    psb_cmdbuf_reg_start_block(cmdbuf, 0);
    // CR_VEC_JPEG_FE_COMPONENTS
    reg_value = 0;
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_COMPONENTS, MAX_V, ctx->max_scalingV);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_COMPONENTS, MAX_H, ctx->max_scalingH);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_COMPONENTS, FE_COMPONENTS,
                           slice_param->num_components);
    psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_COMPONENTS ), reg_value);

    // CR_VEC_JPEG_FE_HEIGHT
    reg_value = 0;
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_HEIGHT, FE_HEIGHT_MINUS1,
                           ctx->coded_picture_height - 1);
    psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_HEIGHT ), reg_value);

    // CR_VEC_JPEG_FE_RESTART_POS
    reg_value = 0;
    psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_RESTART_POS), reg_value);

    // CR_VEC_JPEG_FE_WIDTH
    reg_value = 0;
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_WIDTH, FE_WIDTH_MINUS1,
                           ctx->coded_picture_width - 1 );
    psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_WIDTH), reg_value);

    // CR_VEC_JPEG_FE_ENTROPY_CODING
    reg_value = 0;
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, NUM_MCUS_LESS1, num_MCUs_dec - 1);

    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TA3,
                           slice_param->components[3].ac_table_selector);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TD3,
                           slice_param->components[3].dc_table_selector);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TA2,
                           slice_param->components[2].ac_table_selector);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TD2,
                           slice_param->components[2].dc_table_selector);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TA1,
                           slice_param->components[1].ac_table_selector);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TD1,
                           slice_param->components[1].dc_table_selector );
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TA0,
                           slice_param->components[0].ac_table_selector);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TD0,
                           slice_param->components[0].dc_table_selector);

    psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING ), reg_value);

    // CR_VEC_JPEG_FE_SCALING
    reg_value = 0;
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_V3,
                           ctx->pic_params->components[3].v_sampling_factor);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_H3,
                           ctx->pic_params->components[3].h_sampling_factor );
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_V2,
                           ctx->pic_params->components[2].v_sampling_factor);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_H2,
                           ctx->pic_params->components[2].h_sampling_factor );
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_V1,
                           ctx->pic_params->components[1].v_sampling_factor );
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_H1,
                           ctx->pic_params->components[1].h_sampling_factor );
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_V0,
                           ctx->pic_params->components[0].v_sampling_factor );
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_H0,
                           ctx->pic_params->components[0].h_sampling_factor );

    psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING ), reg_value);
    psb_cmdbuf_reg_end_block(cmdbuf);

    psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET( MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_HEIGHT ));
    // CR_VEC_JPEG_BE_HEIGHT
    reg_value = 0;
    REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_HEIGHT, BE_HEIGHT_MINUS1,
                      ctx->coded_picture_height - 1);
    psb_cmdbuf_rendec_write(cmdbuf, reg_value);

    // CR_VEC_JPEG_BE_WIDTH
    reg_value = 0;
    REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_WIDTH, BE_WIDTH_MINUS1, ctx->coded_picture_width - 1);
    psb_cmdbuf_rendec_write(cmdbuf, reg_value);

    // CR_VEC_JPEG_BE_QUANTISATION
    reg_value = 0;
    REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_QUANTISATION, TQ3,
                      ctx->pic_params->components[3].quantiser_table_selector);
    REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_QUANTISATION, TQ2,
                      ctx->pic_params->components[2].quantiser_table_selector);
    REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_QUANTISATION, TQ1,
                      ctx->pic_params->components[1].quantiser_table_selector);
    REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_QUANTISATION, TQ0,
                      ctx->pic_params->components[0].quantiser_table_selector );
    psb_cmdbuf_rendec_write(cmdbuf, reg_value);

    // CR_VEC_JPEG_BE_CONTROL
    reg_value = 0;
    REGIO_WRITE_FIELD( reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_CONTROL, RGB, 0 );
    psb_cmdbuf_rendec_write(cmdbuf, reg_value);

    psb_cmdbuf_rendec_end(cmdbuf);
}