From 6bf306d37dfc095296287a0ad12ef49864b4c5eb Mon Sep 17 00:00:00 2001 From: Binglin Chen Date: Thu, 22 Dec 2011 11:41:11 -0800 Subject: [PATCH] psb_video: remove MSVDX firmware uploading from driver for PNW D0 For PNW C0 and older steppings, MSVDX(Video Decoder) firmware is uploaded by driver. In PNW D0 silicon, MSVDX uploading is done by PUNIT so video driver needs to remove firmware uploading functionality and add adaption codes to work with PUNIT on firmware uploading, verification, and MTX initialization. Signed-off-by: Binglin Chen Signed-off-by: Daniel Charles Acked-by: Pauli Nieminen Acked-by: Sean V Kelley Signed-off-by: Kirill A. Shutemov --- drivers/staging/mrst/imgv/psb_msvdx.c | 48 ++++++------- drivers/staging/mrst/imgv/psb_msvdx.h | 51 ++++++++++++++ drivers/staging/mrst/imgv/psb_msvdxinit.c | 109 +++++++----------------------- 3 files changed, 98 insertions(+), 110 deletions(-) diff --git a/drivers/staging/mrst/imgv/psb_msvdx.c b/drivers/staging/mrst/imgv/psb_msvdx.c index 0fcc248..f9e2376 100644 --- a/drivers/staging/mrst/imgv/psb_msvdx.c +++ b/drivers/staging/mrst/imgv/psb_msvdx.c @@ -381,12 +381,7 @@ static int psb_submit_video_cmdbuf(struct drm_device *dev, if (msvdx_priv->msvdx_needs_reset) { spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags); - PSB_DEBUG_GENERAL("MSVDX: will reset msvdx\n"); - if (psb_msvdx_reset(dev_priv)) { - ret = -EBUSY; - DRM_ERROR("MSVDX: Reset failed\n"); - return ret; - } + msvdx_priv->msvdx_needs_reset = 0; msvdx_priv->msvdx_busy = 0; @@ -639,8 +634,6 @@ int psb_mtx_send(struct drm_psb_private *dev_priv, const void *msg) /* Make sure clocks are enabled before we kick */ PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE); - PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE); - /* signal an interrupt to let the mtx know there is a new message */ /* PSB_WMSVDX32(1, MSVDX_MTX_KICKI); */ PSB_WMSVDX32(1, MSVDX_MTX_KICK); @@ -1092,7 +1085,7 @@ done: goto loop; } /* we get a frame/slice done, try to save some power*/ - if (drm_msvdx_pmpolicy != PSB_PMPOLICY_NOPM) + if (drm_msvdx_pmpolicy == PSB_PMPOLICY_POWERDOWN) schedule_delayed_work(&dev_priv->scheduler.msvdx_suspend_wq, 0); DRM_MEMORYBARRIER(); /* TBD check this... */ @@ -1123,28 +1116,19 @@ IMG_BOOL psb_msvdx_interrupt(IMG_VOID *pvData) msvdx_stat = PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS); - if (msvdx_stat & MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_MASK) { - /*Ideally we should we should never get to this */ - PSB_DEBUG_IRQ("MSVDX:MMU Fault:0x%x\n", msvdx_stat); - - /* Pause MMU */ - PSB_WMSVDX32(MSVDX_MMU_CONTROL0_CR_MMU_PAUSE_MASK, - MSVDX_MMU_CONTROL0); - DRM_WRITEMEMORYBARRIER(); - - /* Clear this interupt bit only */ - PSB_WMSVDX32(MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_MASK, - MSVDX_INTERRUPT_CLEAR); - PSB_RMSVDX32(MSVDX_INTERRUPT_CLEAR); - DRM_READMEMORYBARRIER(); + /* driver only needs to handle mtx irq + * For MMU fault irq, there's always a HW PANIC generated + * if HW/FW is totally hang, the lockup function will handle + * the reseting when firmware is loaded w/o the driver + */ - msvdx_priv->msvdx_needs_reset = 1; - } else if (msvdx_stat & MSVDX_INTERRUPT_STATUS_CR_MTX_IRQ_MASK) { + if (msvdx_stat & MSVDX_INTERRUPT_STATUS_CR_MTX_IRQ_MASK) { PSB_DEBUG_IRQ ("MSVDX: msvdx_stat: 0x%x(MTX)\n", msvdx_stat); - /* Clear all interupt bits */ - PSB_WMSVDX32(0xffff, MSVDX_INTERRUPT_CLEAR); + /* Clear this interupt bit */ + PSB_WMSVDX32(MSVDX_INTERRUPT_STATUS_CR_MTX_IRQ_MASK, + MSVDX_INTERRUPT_CLEAR); PSB_RMSVDX32(MSVDX_INTERRUPT_CLEAR); DRM_READMEMORYBARRIER(); @@ -1205,6 +1189,13 @@ int psb_check_msvdx_idle(struct drm_device *dev) PSB_DEBUG_PM("MSVDX: psb_check_msvdx_idle returns busy\n"); return -EBUSY; } + + PSB_DEBUG_MSVDX("SIGNATURE is %x\n", + PSB_RMSVDX32(MSVDX_COMMS_SIGNATURE)); + + if (!(PSB_RMSVDX32(MSVDX_COMMS_FW_STATUS) & + MSVDX_FW_STATUS_HW_IDLE)) + return -EBUSY; /* if (msvdx_priv->msvdx_hw_busy) { PSB_DEBUG_PM("MSVDX: %s, HW is busy\n", __func__); @@ -1435,6 +1426,9 @@ int psb_msvdx_save_context(struct drm_device *dev) msvdx_priv->vec_local_mem_saved = 1; + PSB_WMSVDX32(0, MSVDX_MTX_ENABLE); + psb_msvdx_reset(dev_priv); + PSB_WMSVDX32(0, MSVDX_MAN_CLK_ENABLE); return 0; } diff --git a/drivers/staging/mrst/imgv/psb_msvdx.h b/drivers/staging/mrst/imgv/psb_msvdx.h index 9e63dba..ef3d987 100644 --- a/drivers/staging/mrst/imgv/psb_msvdx.h +++ b/drivers/staging/mrst/imgv/psb_msvdx.h @@ -614,6 +614,57 @@ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK) #define VEC_LOCAL_MEM_BYTE_SIZE (4 * 1024) #define VEC_LOCAL_MEM_OFFSET 0x2000 +/* 1311 RENDEC init msg */ +#define FW_DEVA_INIT_SIZE 16 +#define FW_DEVA_INIT_ID 0x80 + +/* FW_DEVA_INIT RENDEC_ADDR0 */ +#define FW_DEVA_INIT_RENDEC_ADDR0_START_BIT 0 +#define FW_DEVA_INIT_RENDEC_ADDR0_END_BIT 31 +#define FW_DEVA_INIT_RENDEC_ADDR0_ALIGNMENT 4 +#define FW_DEVA_INIT_RENDEC_ADDR0_TYPE IMG_UINT32 +#define FW_DEVA_INIT_RENDEC_ADDR0_MASK 0xFFFFFFFF +#define FW_DEVA_INIT_RENDEC_ADDR0_LSBMASK 0xFFFFFFFF +#define FW_DEVA_INIT_RENDEC_ADDR0_OFFSET 0x0004 +#define FW_DEVA_INIT_RENDEC_ADDR0_SHIFT 0 +#define FW_DEVA_INIT_RENDEC_ADDR0_SIGNED_FIELD IMG_FALSE + +/* FW_DEVA_INIT RENDEC_ADDR1 */ +#define FW_DEVA_INIT_RENDEC_ADDR1_START_BIT 0 +#define FW_DEVA_INIT_RENDEC_ADDR1_END_BIT 31 +#define FW_DEVA_INIT_RENDEC_ADDR1_ALIGNMENT 4 +#define FW_DEVA_INIT_RENDEC_ADDR1_TYPE IMG_UINT32 +#define FW_DEVA_INIT_RENDEC_ADDR1_MASK 0xFFFFFFFF +#define FW_DEVA_INIT_RENDEC_ADDR1_LSBMASK 0xFFFFFFFF +#define FW_DEVA_INIT_RENDEC_ADDR1_OFFSET 0x0008 +#define FW_DEVA_INIT_RENDEC_ADDR1_SHIFT 0 +#define FW_DEVA_INIT_RENDEC_ADDR1_SIGNED_FIELD IMG_FALSE + +/* FW_DEVA_INIT RENDEC_SIZE1 */ +#define FW_DEVA_INIT_RENDEC_SIZE1_START_BIT 16 +#define FW_DEVA_INIT_RENDEC_SIZE1_END_BIT 31 +#define FW_DEVA_INIT_RENDEC_SIZE1_ALIGNMENT 2 +#define FW_DEVA_INIT_RENDEC_SIZE1_TYPE IMG_UINT16 +#define FW_DEVA_INIT_RENDEC_SIZE1_MASK 0xFFFF +#define FW_DEVA_INIT_RENDEC_SIZE1_LSBMASK 0xFFFF +#define FW_DEVA_INIT_RENDEC_SIZE1_OFFSET 0x000E +#define FW_DEVA_INIT_RENDEC_SIZE1_SHIFT 0 +#define FW_DEVA_INIT_RENDEC_SIZE1_SIGNED_FIELD IMG_FALSE + +/* FW_DEVA_INIT RENDEC_SIZE0 */ +#define FW_DEVA_INIT_RENDEC_SIZE0_START_BIT 0 +#define FW_DEVA_INIT_RENDEC_SIZE0_END_BIT 15 +#define FW_DEVA_INIT_RENDEC_SIZE0_ALIGNMENT 2 +#define FW_DEVA_INIT_RENDEC_SIZE0_TYPE IMG_UINT16 +#define FW_DEVA_INIT_RENDEC_SIZE0_MASK 0xFFFF +#define FW_DEVA_INIT_RENDEC_SIZE0_LSBMASK 0xFFFF +#define FW_DEVA_INIT_RENDEC_SIZE0_OFFSET 0x000C +#define FW_DEVA_INIT_RENDEC_SIZE0_SHIFT 0 +#define FW_DEVA_INIT_RENDEC_SIZE0_SIGNED_FIELD IMG_FALSE + + + + /* This type defines the framework specified message ids */ enum { /* ! Sent by the DXVA driver on the host to the mtx firmware. diff --git a/drivers/staging/mrst/imgv/psb_msvdxinit.c b/drivers/staging/mrst/imgv/psb_msvdxinit.c index 64b8276..cfdf08a 100644 --- a/drivers/staging/mrst/imgv/psb_msvdxinit.c +++ b/drivers/staging/mrst/imgv/psb_msvdxinit.c @@ -511,15 +511,12 @@ int psb_setup_fw(struct drm_device *dev) const struct firmware *raw = NULL; struct msvdx_private *msvdx_priv = dev_priv->msvdx_private; int ec_firmware = 0, ret = 0; + uint32_t init_msg[FW_DEVA_INIT_SIZE]; /* todo : Assert the clock is on - if not turn it on to upload code */ PSB_DEBUG_GENERAL("MSVDX: psb_setup_fw\n"); PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE); - /* Reset MTX */ - PSB_WMSVDX32(MSVDX_MTX_SOFT_RESET_MTX_RESET_MASK, - MSVDX_MTX_SOFT_RESET); - /* Initialses Communication controll area to 0 */ /* if (psb_rev_id >= POULSBO_D1) { @@ -537,20 +534,8 @@ int psb_setup_fw(struct drm_device *dev) PSB_WMSVDX32(FIRMWAREID, MSVDX_COMMS_FIRMWARE_ID); - PSB_WMSVDX32(0, MSVDX_COMMS_ERROR_TRIG); - PSB_WMSVDX32(199, MSVDX_MTX_SYSC_TIMERDIV); /* MTX_SYSC_TIMERDIV */ PSB_WMSVDX32(0, MSVDX_EXT_FW_ERROR_STATE); /* EXT_FW_ERROR_STATE */ - PSB_WMSVDX32(0, MSVDX_COMMS_MSG_COUNTER); - PSB_WMSVDX32(0, MSVDX_COMMS_SIGNATURE); - PSB_WMSVDX32(0, MSVDX_COMMS_TO_HOST_RD_INDEX); - PSB_WMSVDX32(0, MSVDX_COMMS_TO_HOST_WRT_INDEX); - PSB_WMSVDX32(0, MSVDX_COMMS_TO_MTX_RD_INDEX); - PSB_WMSVDX32(0, MSVDX_COMMS_TO_MTX_WRT_INDEX); - PSB_WMSVDX32(0, MSVDX_COMMS_FW_STATUS); - PSB_WMSVDX32(DSIABLE_IDLE_GPIO_SIG | DSIABLE_Auto_CLOCK_GATING | RETURN_VDEB_DATA_IN_COMPLETION | DSIABLE_FW_WDT, - MSVDX_COMMS_OFFSET_FLAGS); - PSB_WMSVDX32(0, MSVDX_COMMS_SIGNATURE); /* read register bank size */ { uint32_t bank_size, reg; @@ -632,17 +617,7 @@ int psb_setup_fw(struct drm_device *dev) PSB_DEBUG_GENERAL("MSVDX: First 4 bytes of data: 0x%x\n", *data_ptr); - PSB_DEBUG_GENERAL("MSVDX: Uploading firmware\n"); -#if UPLOAD_FW_BY_DMA - psb_upload_fw(dev_priv, 0, msvdx_priv->mtx_mem_size / 4, ec_firmware); -#else - psb_upload_fw(dev_priv, MTX_CORE_CODE_MEM, ram_bank_size, - PC_START_ADDRESS - MTX_CODE_BASE, fw->text_size, - text_ptr); - psb_upload_fw(dev_priv, MTX_CORE_DATA_MEM, ram_bank_size, - fw->data_location - MTX_DATA_BASE, fw->data_size, - data_ptr); -#endif + PSB_DEBUG_GENERAL("MSVDX: Firmware uploaded\n"); #if 0 /* todo : Verify code upload possibly only in debug */ ret = psb_verify_fw(dev_priv, ram_bank_size, @@ -666,11 +641,6 @@ int psb_setup_fw(struct drm_device *dev) #else (void)psb_verify_fw; #endif - /* -- Set starting PC address */ - psb_write_mtx_core_reg(dev_priv, MTX_PC, PC_START_ADDRESS); - - /* -- Turn on the thread */ - PSB_WMSVDX32(MSVDX_MTX_ENABLE_MTX_ENABLE_MASK, MSVDX_MTX_ENABLE); /* Wait for the signature value to be written back */ ret = psb_wait_for_register(dev_priv, MSVDX_COMMS_SIGNATURE, @@ -684,6 +654,28 @@ int psb_setup_fw(struct drm_device *dev) PSB_DEBUG_GENERAL("MSVDX: MTX Initial indications OK\n"); PSB_DEBUG_GENERAL("MSVDX: MSVDX_COMMS_AREA_ADDR = %08x\n", MSVDX_COMMS_AREA_ADDR); + /* send INIT cmd for RENDEC init */ + PSB_WMSVDX32(DSIABLE_IDLE_GPIO_SIG, MSVDX_COMMS_OFFSET_FLAGS); + /* + * at this stage, FW is uplaoded successfully, can send rendec + * init message + */ + + MEMIO_WRITE_FIELD(init_msg, FWRK_GENMSG_SIZE, + FW_DEVA_INIT_SIZE); + MEMIO_WRITE_FIELD(init_msg, FWRK_GENMSG_ID, + FW_DEVA_INIT_ID); + + MEMIO_WRITE_FIELD(init_msg, FW_DEVA_INIT_RENDEC_ADDR0, + msvdx_priv->base_addr0); + MEMIO_WRITE_FIELD(init_msg, FW_DEVA_INIT_RENDEC_ADDR1, + msvdx_priv->base_addr1); + MEMIO_WRITE_FIELD(init_msg, FW_DEVA_INIT_RENDEC_SIZE0, + RENDEC_A_SIZE / (4*1024)); + MEMIO_WRITE_FIELD(init_msg, FW_DEVA_INIT_RENDEC_SIZE1, + RENDEC_B_SIZE / (4*1024)); + psb_mtx_send(dev_priv, init_msg); + #if 0 /* Send test message */ @@ -1080,8 +1072,6 @@ int psb_msvdx_init(struct drm_device *dev) PSB_WMSVDX32(8200, REGISTER(MSVDX_CORE, CR_BE_MSVDX_WDT_COMPAREMATCH)); PSB_WMSVDX32(reg_val, REGISTER(MSVDX_CORE, CR_BE_MSVDX_WDT_CONTROL)); */ - /* Enable MMU by removing all bypass bits */ - PSB_WMSVDX32(0, MSVDX_MMU_CONTROL0); /* move firmware loading to the place receiving first command buffer */ @@ -1135,16 +1125,6 @@ int psb_msvdx_init(struct drm_device *dev) PSB_DEBUG_GENERAL("MSVDX: RENDEC A: %08x RENDEC B: %08x\n", msvdx_priv->base_addr0, msvdx_priv->base_addr1); - PSB_WMSVDX32(msvdx_priv->base_addr0, MSVDX_RENDEC_BASE_ADDR0); - PSB_WMSVDX32(msvdx_priv->base_addr1, MSVDX_RENDEC_BASE_ADDR1); - - cmd = 0; - REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_BUFFER_SIZE, - RENDEC_BUFFER_SIZE0, RENDEC_A_SIZE / 4096); - REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_BUFFER_SIZE, - RENDEC_BUFFER_SIZE1, RENDEC_B_SIZE / 4096); - PSB_WMSVDX32(cmd, MSVDX_RENDEC_BUFFER_SIZE); - if (!msvdx_priv->fw) { uint32_t core_rev; @@ -1169,41 +1149,14 @@ int psb_msvdx_init(struct drm_device *dev) } } - cmd = 0; - REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL1, - RENDEC_DECODE_START_SIZE, 0); - REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL1, - RENDEC_BURST_SIZE_W, 1); - REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL1, - RENDEC_BURST_SIZE_R, 1); - REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL1, - RENDEC_EXTERNAL_MEMORY, 1); - PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTROL1); - - cmd = 0x00101010; - PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT0); - PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT1); - PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT2); - PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT3); - PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT4); - PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT5); - - cmd = 0; - REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL0, RENDEC_INITIALISE, - 1); - PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTROL0); - /* PSB_WMSVDX32(clk_enable_minimal, MSVDX_MAN_CLK_ENABLE); */ PSB_DEBUG_INIT("MSVDX:defer firmware loading to the" " place when receiving user space commands\n"); msvdx_priv->msvdx_fw_loaded = 0; /* need to load firware */ - PSB_WMSVDX32(820, MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH); - PSB_WMSVDX32(8200, MSVDX_CORE_CR_BE_MSVDX_WDT_COMPAREMATCH); - - PSB_WMSVDX32(820, MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH); - PSB_WMSVDX32(8200, MSVDX_CORE_CR_BE_MSVDX_WDT_COMPAREMATCH); + PSB_WMSVDX32(0x334, MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH); + PSB_WMSVDX32(0x2008, MSVDX_CORE_CR_BE_MSVDX_WDT_COMPAREMATCH); psb_msvdx_clearirq(dev); psb_msvdx_enableirq(dev); @@ -1211,16 +1164,6 @@ int psb_msvdx_init(struct drm_device *dev) PSB_DEBUG_INIT("MSDVX:old clock gating disable = 0x%08x\n", PSB_RVDC32(PSB_MSVDX_CLOCKGATING)); - { - cmd = 0; - cmd = PSB_RMSVDX32(MSVDX_VEC_SHIFTREG_CONTROL); /* VEC_SHIFTREG_CONTROL */ - REGIO_WRITE_FIELD(cmd, - VEC_SHIFTREG_CONTROL, - SR_MASTER_SELECT, - 1); /* Host */ - PSB_WMSVDX32(cmd, MSVDX_VEC_SHIFTREG_CONTROL); - } - #if 0 ret = psb_setup_fw(dev); if (ret) -- 2.7.4