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;
/* 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);
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... */
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();
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__);
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;
}
#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.
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) {
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;
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,
#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,
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 */
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 */
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;
}
}
- 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);
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)