psb_video: remove MSVDX firmware uploading from driver for PNW D0
authorBinglin Chen <binglin.chen@intel.com>
Thu, 22 Dec 2011 19:41:11 +0000 (11:41 -0800)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Tue, 3 Jul 2012 09:29:16 +0000 (12:29 +0300)
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 <binglin.chen@intel.com>
Signed-off-by: Daniel Charles <daniel.charles@intel.com>
Acked-by: Pauli Nieminen <pauli.nieminen@linux.intel.com>
Acked-by: Sean V Kelley <sean.v.kelley@intel.com>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
drivers/staging/mrst/imgv/psb_msvdx.c
drivers/staging/mrst/imgv/psb_msvdx.h
drivers/staging/mrst/imgv/psb_msvdxinit.c

index 0fcc248..f9e2376 100644 (file)
@@ -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;
 }
 
index 9e63dba..ef3d987 100644 (file)
@@ -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.
index 64b8276..cfdf08a 100644 (file)
@@ -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)