[COMMON] media: mfc: parse the NAL_Q size
authorAyoung Sim <a.sim@samsung.com>
Tue, 24 Jul 2018 07:25:56 +0000 (16:25 +0900)
committerhskang <hs1218.kang@samsung.com>
Sun, 9 Sep 2018 21:39:04 +0000 (06:39 +0900)
Because NAL_Q structure size is differenct by F/W,
we parse this dependency from device tree.

Change-Id: I23ddcd3fcdae6b80ffe80ea372cf81965b47de85
Signed-off-by: Ayoung Sim <a.sim@samsung.com>
drivers/media/platform/exynos/mfc/mfc.c
drivers/media/platform/exynos/mfc/mfc_data_struct.h
drivers/media/platform/exynos/mfc/mfc_nal_q.c
drivers/media/platform/exynos/mfc/mfc_watchdog.c

index 88b76973706ef3400be825eeae9bc382f45fe926..b50bec31a21b3eb60b229271414005938d2e4a05 100644 (file)
@@ -980,6 +980,10 @@ static void __mfc_parse_dt(struct device_node *np, struct mfc_dev *mfc)
        of_property_read_u32(np, "axid_mask", &pdata->axid_mask);
        of_property_read_u32(np, "mfc_fault_num", &pdata->mfc_fault_num);
 
+       /* NAL-Q size */
+       of_property_read_u32(np, "nal_q_entry_size", &pdata->nal_q_entry_size);
+       of_property_read_u32(np, "nal_q_dump_size", &pdata->nal_q_dump_size);
+
        /* Features */
        of_property_read_u32_array(np, "nal_q", &pdata->nal_q.support, 2);
        of_property_read_u32_array(np, "skype", &pdata->skype.support, 2);
index 3618747d04da84b8d52a3580d9bc790940eba8c0..a685de59a689d9ef833b9b51a5f8317280d40ed9 100644 (file)
@@ -446,6 +446,9 @@ struct mfc_platdata {
        struct mfc_qos *qos_table;
        struct mfc_qos_boost *qos_boost_table;
 #endif
+       /* NAL-Q size */
+       unsigned int nal_q_entry_size;
+       unsigned int nal_q_dump_size;
        /* Features */
        struct mfc_feature nal_q;
        struct mfc_feature skype;
@@ -474,18 +477,10 @@ struct mfc_platdata {
 };
 
 /************************ NAL_Q data structure ************************/
-#define NAL_Q_IN_ENTRY_SIZE            512
-#define NAL_Q_OUT_ENTRY_SIZE           512
+#define NAL_Q_ENTRY_SIZE_FOR_HDR10     512
 
-#define NAL_Q_IN_DEC_STR_SIZE          112
-#define NAL_Q_IN_ENC_STR_SIZE          324
-#define NAL_Q_OUT_DEC_STR_SIZE         376
-#define NAL_Q_OUT_ENC_STR_SIZE         64
-#define NAL_Q_DUMP_MAX_STR_SIZE                376
-
-/* 512*128(max instance 32 * slot 4) = 64 kbytes */
-#define NAL_Q_IN_QUEUE_SIZE            128
-#define NAL_Q_OUT_QUEUE_SIZE           128
+/* slot 4 * max instance 32 = 128 */
+#define NAL_Q_QUEUE_SIZE               128
 
 typedef struct __DecoderInputStr {
        int StartCode; /* = 0xAAAAAAAA; Decoder input structure marker */
@@ -508,7 +503,6 @@ typedef struct __DecoderInputStr {
        int Frame2BitStrideSize[2];
        unsigned int ScratchBufAddr;
        int ScratchBufSize;
-       char reserved[NAL_Q_IN_ENTRY_SIZE - NAL_Q_IN_DEC_STR_SIZE];
 } DecoderInputStr; /* 28*4 = 112 bytes */
 
 typedef struct __EncoderInputStr {
@@ -555,7 +549,6 @@ typedef struct __EncoderInputStr {
        int WeightUpper;
        int RcMode;
        int St2094_40sei[30];
-       char reserved[NAL_Q_IN_ENTRY_SIZE - NAL_Q_IN_ENC_STR_SIZE];
 } EncoderInputStr; /* 81*4 = 324 bytes */
 
 typedef struct __DecoderOutputStr {
@@ -620,7 +613,6 @@ typedef struct __DecoderOutputStr {
        int FirstPlaneDpbSize;
        int SecondPlaneDpbSize;
        int St2094_40sei[30];
-       char reserved[NAL_Q_OUT_ENTRY_SIZE - NAL_Q_OUT_DEC_STR_SIZE];
 } DecoderOutputStr; /* 94*4 =  376 bytes */
 
 typedef struct __EncoderOutputStr {
@@ -638,7 +630,6 @@ typedef struct __EncoderOutputStr {
        unsigned int ReconLumaDpbAddr;
        unsigned int ReconChromaDpbAddr;
        int EncCnt;
-       char reserved[NAL_Q_OUT_ENTRY_SIZE - NAL_Q_OUT_ENC_STR_SIZE];
 } EncoderOutputStr; /* 16*4 = 64 bytes */
 
 /**
@@ -650,33 +641,19 @@ typedef enum _nal_queue_state {
        NAL_Q_STATE_STOPPED, /* when mfc_nal_q_stop() is called */
 } nal_queue_state;
 
-typedef struct _nal_in_queue {
-       union {
-               DecoderInputStr dec;
-               EncoderInputStr enc;
-       } entry[NAL_Q_IN_QUEUE_SIZE];
-} nal_in_queue;
-
-typedef struct _nal_out_queue {
-       union {
-               DecoderOutputStr dec;
-               EncoderOutputStr enc;
-       } entry[NAL_Q_OUT_QUEUE_SIZE];
-} nal_out_queue;
-
 struct _nal_queue_handle;
 typedef struct _nal_queue_in_handle {
        struct _nal_queue_handle *nal_q_handle;
        struct mfc_special_buf in_buf;
        unsigned int in_exe_count;
-       nal_in_queue *nal_q_in_addr;
+       void *nal_q_in_addr;
 } nal_queue_in_handle;
 
 typedef struct _nal_queue_out_handle {
        struct _nal_queue_handle *nal_q_handle;
        struct mfc_special_buf out_buf;
        unsigned int out_exe_count;
-       nal_out_queue *nal_q_out_addr;
+       void *nal_q_out_addr;
        int nal_q_ctx;
 } nal_queue_out_handle;
 
index c88be065e21692351076c1938764035b9cc71b26..07ce22d128e93959f512ac14f6f5ab3d512f2c76 100644 (file)
@@ -211,13 +211,19 @@ static nal_queue_in_handle* __mfc_nal_q_create_in_q(struct mfc_dev *dev,
 
        nal_q_in_handle->nal_q_handle = nal_q_handle;
        nal_q_in_handle->in_buf.buftype = MFCBUF_NORMAL;
-       nal_q_in_handle->in_buf.size = NAL_Q_IN_ENTRY_SIZE * (NAL_Q_IN_QUEUE_SIZE + 2);
+       /*
+        * Total nal_q buf size = entry size * num slot * max instance
+        * ex) entry size is 512 byte
+        *     512 byte * 4 slot * 32 instance = 64KB
+        * Plus 1 is needed for margin, because F/W exceeds sometimes.
+        */
+       nal_q_in_handle->in_buf.size = dev->pdata->nal_q_entry_size * (NAL_Q_QUEUE_SIZE + 1);
        if (mfc_mem_ion_alloc(dev, &nal_q_in_handle->in_buf)) {
                mfc_err_dev("[NALQ] failed to get memory\n");
                kfree(nal_q_in_handle);
                return NULL;
        }
-       nal_q_in_handle->nal_q_in_addr = (nal_in_queue *)nal_q_in_handle->in_buf.vaddr;
+       nal_q_in_handle->nal_q_in_addr = nal_q_in_handle->in_buf.vaddr;
 
        mfc_debug_leave();
 
@@ -239,13 +245,19 @@ static nal_queue_out_handle* __mfc_nal_q_create_out_q(struct mfc_dev *dev,
 
        nal_q_out_handle->nal_q_handle = nal_q_handle;
        nal_q_out_handle->out_buf.buftype = MFCBUF_NORMAL;
-       nal_q_out_handle->out_buf.size = NAL_Q_OUT_ENTRY_SIZE * (NAL_Q_OUT_QUEUE_SIZE + 2);
+       /*
+        * Total nal_q buf size = entry size * num slot * max instance
+        * ex) entry size is 512 byte
+        *     512 byte * 4 slot * 32 instance = 64KB
+        * Plus 1 is needed for margin, because F/W exceeds sometimes.
+        */
+       nal_q_out_handle->out_buf.size = dev->pdata->nal_q_entry_size * (NAL_Q_QUEUE_SIZE + 1);
        if (mfc_mem_ion_alloc(dev, &nal_q_out_handle->out_buf)) {
                mfc_err_dev("[NALQ] failed to get memory\n");
                kfree(nal_q_out_handle);
                return NULL;
        }
-       nal_q_out_handle->nal_q_out_addr = (nal_out_queue *)nal_q_out_handle->out_buf.vaddr;
+       nal_q_out_handle->nal_q_out_addr = nal_q_out_handle->out_buf.vaddr;
 
        mfc_debug_leave();
 
@@ -412,7 +424,7 @@ void mfc_nal_q_start(struct mfc_dev *dev, nal_queue_handle *nal_q_handle)
 
        addr = nal_q_handle->nal_q_in_handle->in_buf.daddr;
 
-       mfc_update_nal_queue_input(dev, addr, NAL_Q_IN_ENTRY_SIZE * NAL_Q_IN_QUEUE_SIZE);
+       mfc_update_nal_queue_input(dev, addr, dev->pdata->nal_q_entry_size * NAL_Q_QUEUE_SIZE);
 
        mfc_debug(2, "[NALQ] MFC_REG_NAL_QUEUE_INPUT_ADDR=0x%x\n",
                mfc_get_nal_q_input_addr());
@@ -421,7 +433,7 @@ void mfc_nal_q_start(struct mfc_dev *dev, nal_queue_handle *nal_q_handle)
 
        addr = nal_q_handle->nal_q_out_handle->out_buf.daddr;
 
-       mfc_update_nal_queue_output(dev, addr, NAL_Q_OUT_ENTRY_SIZE * NAL_Q_OUT_QUEUE_SIZE);
+       mfc_update_nal_queue_output(dev, addr, dev->pdata->nal_q_entry_size * NAL_Q_QUEUE_SIZE);
 
        mfc_debug(2, "[NALQ] MFC_REG_NAL_QUEUE_OUTPUT_ADDR=0x%x\n",
                mfc_get_nal_q_output_addr());
@@ -559,6 +571,11 @@ static void __mfc_nal_q_get_hdr_plus_info(struct mfc_ctx *ctx, DecoderOutputStr
        int num_win, num_distribution;
        int i, j;
 
+       if (dev->pdata->nal_q_entry_size < NAL_Q_ENTRY_SIZE_FOR_HDR10) {
+               mfc_err_dev("[NALQ][HDR+] insufficient NAL-Q entry size\n");
+               return;
+       }
+
        sei_meta->valid = 1;
 
        /* iru_t_t35 */
@@ -651,6 +668,11 @@ static void __mfc_nal_q_set_hdr_plus_info(struct mfc_ctx *ctx, EncoderInputStr *
        int num_win, num_distribution;
        int i, j;
 
+       if (dev->pdata->nal_q_entry_size < NAL_Q_ENTRY_SIZE_FOR_HDR10) {
+               mfc_err_dev("[NALQ][HDR+] insufficient NAL-Q entry size\n");
+               return;
+       }
+
        pInStr->HevcNalControl &= ~(sei_meta->valid << 6);
        pInStr->HevcNalControl |= ((sei_meta->valid & 0x1) << 6);
 
@@ -1837,7 +1859,7 @@ int mfc_nal_q_enqueue_in_buf(struct mfc_dev *dev, struct mfc_ctx *ctx,
        unsigned int input_count = 0;
        unsigned int input_exe_count = 0;
        int input_diff = 0;
-       unsigned int index = 0;
+       unsigned int index = 0, offset = 0;
        EncoderInputStr *pStr = NULL;
        int ret = 0;
 
@@ -1863,26 +1885,27 @@ int mfc_nal_q_enqueue_in_buf(struct mfc_dev *dev, struct mfc_ctx *ctx,
 
        /*
         * meaning of the variable input_diff
-        * 0:                           number of available slots = NAL_Q_IN_QUEUE_SIZE
-        * 1:                           number of available slots = NAL_Q_IN_QUEUE_SIZE - 1
+        * 0:                           number of available slots = NAL_Q_QUEUE_SIZE
+        * 1:                           number of available slots = NAL_Q_QUEUE_SIZE - 1
         * ...
-        * NAL_Q_IN_QUEUE_SIZE-1:       number of available slots = 1
-        * NAL_Q_IN_QUEUE_SIZE:         number of available slots = 0
+        * NAL_Q_QUEUE_SIZE-1:          number of available slots = 1
+        * NAL_Q_QUEUE_SIZE:            number of available slots = 0
         */
 
        mfc_debug(2, "[NALQ] input_diff = %d(in: %d, exe: %d)\n",
                        input_diff, input_count, input_exe_count);
 
-       if ((input_diff < 0) || (input_diff >= NAL_Q_IN_QUEUE_SIZE)) {
+       if ((input_diff < 0) || (input_diff >= NAL_Q_QUEUE_SIZE)) {
                mfc_err_dev("[NALQ] No available input slot(%d)\n", input_diff);
                spin_unlock_irqrestore(&nal_q_in_handle->nal_q_handle->lock, flags);
                return -EINVAL;
        }
 
-       index = input_count % NAL_Q_IN_QUEUE_SIZE;
-       pStr = &(nal_q_in_handle->nal_q_in_addr->entry[index].enc);
+       index = input_count % NAL_Q_QUEUE_SIZE;
+       offset = dev->pdata->nal_q_entry_size * index;
+       pStr = (EncoderInputStr *)(nal_q_in_handle->nal_q_in_addr + offset);
 
-       memset(pStr, 0, NAL_Q_IN_ENTRY_SIZE);
+       memset(pStr, 0, dev->pdata->nal_q_entry_size);
 
        if (ctx->type == MFCINST_ENCODER)
                ret = __mfc_nal_q_run_in_buf_enc(ctx, pStr);
@@ -1900,7 +1923,7 @@ int mfc_nal_q_enqueue_in_buf(struct mfc_dev *dev, struct mfc_ctx *ctx,
                                ctx->type == MFCINST_ENCODER ? "ENC" : "DEC", dev->curr_ctx,
                                input_diff, input_count, input_exe_count);
                print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4,
-                               (int *)pStr, NAL_Q_DUMP_MAX_STR_SIZE, false);
+                               (int *)pStr, dev->pdata->nal_q_dump_size, false);
                printk("...\n");
        }
        input_count++;
@@ -1931,12 +1954,11 @@ EncoderOutputStr *mfc_nal_q_dequeue_out_buf(struct mfc_dev *dev,
        unsigned long flags;
        unsigned int output_count = 0;
        unsigned int output_exe_count = 0;
+       int input_diff = 0;
        int output_diff = 0;
-       unsigned int index = 0;
+       unsigned int index = 0, offset = 0;
        EncoderOutputStr *pStr = NULL;
 
-       int input_diff = 0;
-
        mfc_debug_enter();
 
        if (!nal_q_out_handle || !nal_q_out_handle->nal_q_out_addr) {
@@ -1955,20 +1977,21 @@ EncoderOutputStr *mfc_nal_q_dequeue_out_buf(struct mfc_dev *dev,
         * 0:                           number of output slots = 0
         * 1:                           number of output slots = 1
         * ...
-        * NAL_Q_OUT_QUEUE_SIZE-1:      number of output slots = NAL_Q_OUT_QUEUE_SIZE - 1
-        * NAL_Q_OUT_QUEUE_SIZE:        number of output slots = NAL_Q_OUT_QUEUE_SIZE
+        * NAL_Q_QUEUE_SIZE-1:          number of output slots = NAL_Q_QUEUE_SIZE - 1
+        * NAL_Q_QUEUE_SIZE:            number of output slots = NAL_Q_QUEUE_SIZE
         */
 
        mfc_debug(2, "[NALQ] output_diff = %d(out: %d, exe: %d)\n",
                        output_diff, output_count, output_exe_count);
-       if ((output_diff <= 0) || (output_diff > NAL_Q_OUT_QUEUE_SIZE)) {
+       if ((output_diff <= 0) || (output_diff > NAL_Q_QUEUE_SIZE)) {
                spin_unlock_irqrestore(&nal_q_out_handle->nal_q_handle->lock, flags);
                mfc_debug(2, "[NALQ] No available output slot(%d)\n", output_diff);
                return pStr;
        }
 
-       index = output_exe_count % NAL_Q_OUT_QUEUE_SIZE;
-       pStr = &(nal_q_out_handle->nal_q_out_addr->entry[index].enc);
+       index = output_exe_count % NAL_Q_QUEUE_SIZE;
+       offset = dev->pdata->nal_q_entry_size * index;
+       pStr = (EncoderOutputStr *)(nal_q_out_handle->nal_q_out_addr + offset);
 
        nal_q_out_handle->nal_q_ctx = __mfc_nal_q_find_ctx(dev, pStr);
        if (nal_q_out_handle->nal_q_ctx < 0) {
@@ -1984,7 +2007,7 @@ EncoderOutputStr *mfc_nal_q_dequeue_out_buf(struct mfc_dev *dev,
                                nal_q_out_handle->nal_q_ctx,
                                output_diff, output_count, output_exe_count);
                print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4,
-                               (int *)pStr, NAL_Q_DUMP_MAX_STR_SIZE, false);
+                               (int *)pStr, dev->pdata->nal_q_dump_size, false);
                printk("...\n");
        }
        nal_q_out_handle->out_exe_count++;
index 7bd48b433bfab1720552ae76d01f6d5683c5720f..96bc08af3d92fd2be020741931a631b63a2365a1 100644 (file)
@@ -145,12 +145,15 @@ static void __mfc_save_logging_sfr(struct mfc_dev *dev)
 static int __mfc_get_curr_ctx(struct mfc_dev *dev)
 {
        nal_queue_handle *nal_q_handle = dev->nal_q_handle;
-       int index;
+       unsigned int index, offset;
+       DecoderInputStr *pStr;
 
        if (nal_q_handle) {
                if (nal_q_handle->nal_q_state == NAL_Q_STATE_STARTED) {
-                       index = nal_q_handle->nal_q_in_handle->in_exe_count % NAL_Q_IN_QUEUE_SIZE;
-                       return nal_q_handle->nal_q_in_handle->nal_q_in_addr->entry[index].dec.InstanceId;
+                       index = nal_q_handle->nal_q_in_handle->in_exe_count % NAL_Q_QUEUE_SIZE;
+                       offset = dev->pdata->nal_q_entry_size * index;
+                       pStr = (DecoderInputStr *)(nal_q_handle->nal_q_in_handle->nal_q_in_addr + offset);
+                       return pStr->InstanceId;
                }
        }