[media] coda: dynamic IRAM setup for encoder
authorPhilipp Zabel <p.zabel@pengutronix.de>
Fri, 21 Jun 2013 06:55:28 +0000 (03:55 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Fri, 26 Jul 2013 15:14:05 +0000 (12:14 -0300)
This sets up IRAM areas used as temporary memory for the different
hardware units depending on the frame size.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Kamil Debski <k.debski@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
drivers/media/platform/coda.c
drivers/media/platform/coda.h

index ef3bb8bc3b6a0b48cc6ed1c0fe018097c4c69949..f6d790af5a2dd489ece195413fe660efdbba7e31 100644 (file)
@@ -160,6 +160,18 @@ struct coda_params {
        u32                     slice_max_mb;
 };
 
+struct coda_iram_info {
+       u32             axi_sram_use;
+       phys_addr_t     buf_bit_use;
+       phys_addr_t     buf_ip_ac_dc_use;
+       phys_addr_t     buf_dbk_y_use;
+       phys_addr_t     buf_dbk_c_use;
+       phys_addr_t     buf_ovl_use;
+       phys_addr_t     buf_btp_use;
+       phys_addr_t     search_ram_paddr;
+       int             search_ram_size;
+};
+
 struct coda_ctx {
        struct coda_dev                 *dev;
        struct list_head                list;
@@ -182,6 +194,7 @@ struct coda_ctx {
        struct coda_aux_buf             internal_frames[CODA_MAX_FRAMEBUFFERS];
        int                             num_internal_frames;
        int                             idx;
+       struct coda_iram_info           iram_info;
 };
 
 static const u8 coda_filler_nal[14] = { 0x00, 0x00, 0x00, 0x01, 0x0c, 0xff,
@@ -800,6 +813,10 @@ static void coda_device_run(void *m2m_priv)
                                CODA7_REG_BIT_AXI_SRAM_USE);
        }
 
+       if (dev->devtype->product != CODA_DX6)
+               coda_write(dev, ctx->iram_info.axi_sram_use,
+                               CODA7_REG_BIT_AXI_SRAM_USE);
+
        /* 1 second timeout in case CODA locks up */
        schedule_delayed_work(&dev->timeout, HZ);
 
@@ -1035,6 +1052,110 @@ static int coda_h264_padding(int size, char *p)
        return nal_size;
 }
 
+static void coda_setup_iram(struct coda_ctx *ctx)
+{
+       struct coda_iram_info *iram_info = &ctx->iram_info;
+       struct coda_dev *dev = ctx->dev;
+       int ipacdc_size;
+       int bitram_size;
+       int dbk_size;
+       int mb_width;
+       int me_size;
+       int size;
+
+       memset(iram_info, 0, sizeof(*iram_info));
+       size = dev->iram_size;
+
+       if (dev->devtype->product == CODA_DX6)
+               return;
+
+       if (ctx->inst_type == CODA_INST_ENCODER) {
+               struct coda_q_data *q_data_src;
+
+               q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+               mb_width = DIV_ROUND_UP(q_data_src->width, 16);
+
+               /* Prioritize in case IRAM is too small for everything */
+               me_size = round_up(round_up(q_data_src->width, 16) * 36 + 2048,
+                                  1024);
+               iram_info->search_ram_size = me_size;
+               if (size >= iram_info->search_ram_size) {
+                       if (dev->devtype->product == CODA_7541)
+                               iram_info->axi_sram_use |= CODA7_USE_HOST_ME_ENABLE;
+                       iram_info->search_ram_paddr = dev->iram_paddr;
+                       size -= iram_info->search_ram_size;
+               } else {
+                       pr_err("IRAM is smaller than the search ram size\n");
+                       goto out;
+               }
+
+               /* Only H.264BP and H.263P3 are considered */
+               dbk_size = round_up(128 * mb_width, 1024);
+               if (size >= dbk_size) {
+                       iram_info->axi_sram_use |= CODA7_USE_HOST_DBK_ENABLE;
+                       iram_info->buf_dbk_y_use = dev->iram_paddr +
+                                                  iram_info->search_ram_size;
+                       iram_info->buf_dbk_c_use = iram_info->buf_dbk_y_use +
+                                                  dbk_size / 2;
+                       size -= dbk_size;
+               } else {
+                       goto out;
+               }
+
+               bitram_size = round_up(128 * mb_width, 1024);
+               if (size >= bitram_size) {
+                       iram_info->axi_sram_use |= CODA7_USE_HOST_BIT_ENABLE;
+                       iram_info->buf_bit_use = iram_info->buf_dbk_c_use +
+                                                dbk_size / 2;
+                       size -= bitram_size;
+               } else {
+                       goto out;
+               }
+
+               ipacdc_size = round_up(128 * mb_width, 1024);
+               if (size >= ipacdc_size) {
+                       iram_info->axi_sram_use |= CODA7_USE_HOST_IP_ENABLE;
+                       iram_info->buf_ip_ac_dc_use = iram_info->buf_bit_use +
+                                                     bitram_size;
+                       size -= ipacdc_size;
+               }
+
+               /* OVL disabled for encoder */
+       }
+
+out:
+       switch (dev->devtype->product) {
+       case CODA_DX6:
+               break;
+       case CODA_7541:
+               /* i.MX53 uses secondary AXI for IRAM access */
+               if (iram_info->axi_sram_use & CODA7_USE_HOST_BIT_ENABLE)
+                       iram_info->axi_sram_use |= CODA7_USE_BIT_ENABLE;
+               if (iram_info->axi_sram_use & CODA7_USE_HOST_IP_ENABLE)
+                       iram_info->axi_sram_use |= CODA7_USE_IP_ENABLE;
+               if (iram_info->axi_sram_use & CODA7_USE_HOST_DBK_ENABLE)
+                       iram_info->axi_sram_use |= CODA7_USE_DBK_ENABLE;
+               if (iram_info->axi_sram_use & CODA7_USE_HOST_OVL_ENABLE)
+                       iram_info->axi_sram_use |= CODA7_USE_OVL_ENABLE;
+               if (iram_info->axi_sram_use & CODA7_USE_HOST_ME_ENABLE)
+                       iram_info->axi_sram_use |= CODA7_USE_ME_ENABLE;
+       }
+
+       if (!(iram_info->axi_sram_use & CODA7_USE_HOST_IP_ENABLE))
+               v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+                        "IRAM smaller than needed\n");
+
+       if (dev->devtype->product == CODA_7541) {
+               /* TODO - Enabling these causes picture errors on CODA7541 */
+               if (ctx->inst_type == CODA_INST_ENCODER) {
+                       iram_info->axi_sram_use &= ~(CODA7_USE_HOST_IP_ENABLE |
+                                                    CODA7_USE_HOST_DBK_ENABLE |
+                                                    CODA7_USE_IP_ENABLE |
+                                                    CODA7_USE_DBK_ENABLE);
+               }
+       }
+}
+
 static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf,
                              int header_code, u8 *header, int *size)
 {
@@ -1207,6 +1328,8 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
        }
        coda_write(dev, value, CODA_CMD_ENC_SEQ_OPTION);
 
+       coda_setup_iram(ctx);
+
        if (dst_fourcc == V4L2_PIX_FMT_H264) {
                value  = (FMO_SLICE_SAVE_BUF_SIZE << 7);
                value |= (0 & CODA_FMOPARAM_TYPE_MASK) << CODA_FMOPARAM_TYPE_OFFSET;
@@ -1214,8 +1337,10 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
                if (dev->devtype->product == CODA_DX6) {
                        coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO);
                } else {
-                       coda_write(dev, dev->iram_paddr, CODA7_CMD_ENC_SEQ_SEARCH_BASE);
-                       coda_write(dev, 48 * 1024, CODA7_CMD_ENC_SEQ_SEARCH_SIZE);
+                       coda_write(dev, ctx->iram_info.search_ram_paddr,
+                                       CODA7_CMD_ENC_SEQ_SEARCH_BASE);
+                       coda_write(dev, ctx->iram_info.search_ram_size,
+                                       CODA7_CMD_ENC_SEQ_SEARCH_SIZE);
                }
        }
 
@@ -1240,12 +1365,16 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
        coda_write(dev, ctx->num_internal_frames, CODA_CMD_SET_FRAME_BUF_NUM);
        coda_write(dev, round_up(q_data_src->width, 8), CODA_CMD_SET_FRAME_BUF_STRIDE);
        if (dev->devtype->product != CODA_DX6) {
-               coda_write(dev, round_up(q_data_src->width, 8), CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE);
-               coda_write(dev, dev->iram_paddr + 48 * 1024, CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR);
-               coda_write(dev, dev->iram_paddr + 53 * 1024, CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR);
-               coda_write(dev, dev->iram_paddr + 58 * 1024, CODA7_CMD_SET_FRAME_AXI_BIT_ADDR);
-               coda_write(dev, dev->iram_paddr + 68 * 1024, CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR);
-               coda_write(dev, 0x0, CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
+               coda_write(dev, ctx->iram_info.buf_bit_use,
+                               CODA7_CMD_SET_FRAME_AXI_BIT_ADDR);
+               coda_write(dev, ctx->iram_info.buf_ip_ac_dc_use,
+                               CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR);
+               coda_write(dev, ctx->iram_info.buf_dbk_y_use,
+                               CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR);
+               coda_write(dev, ctx->iram_info.buf_dbk_c_use,
+                               CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR);
+               coda_write(dev, ctx->iram_info.buf_ovl_use,
+                               CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
        }
        ret = coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF);
        if (ret < 0) {
index ace0bf0a3b9cb245a5399a55ae7acd2594eb1a1d..39c17c67be24f7483605f84c6c2ecadcf69976ac 100644 (file)
 #define CODA_REG_BIT_WR_PTR(x)                 (0x124 + 8 * (x))
 #define CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR   0x140
 #define CODA7_REG_BIT_AXI_SRAM_USE             0x140
-#define                CODA7_USE_BIT_ENABLE            (1 << 0)
+#define                CODA7_USE_HOST_ME_ENABLE        (1 << 11)
+#define                CODA7_USE_HOST_OVL_ENABLE       (1 << 10)
+#define                CODA7_USE_HOST_DBK_ENABLE       (1 << 9)
+#define                CODA7_USE_HOST_IP_ENABLE        (1 << 8)
 #define                CODA7_USE_HOST_BIT_ENABLE       (1 << 7)
 #define                CODA7_USE_ME_ENABLE             (1 << 4)
-#define                CODA7_USE_HOST_ME_ENABLE        (1 << 11)
+#define                CODA7_USE_OVL_ENABLE            (1 << 3)
+#define                CODA7_USE_DBK_ENABLE            (1 << 2)
+#define                CODA7_USE_IP_ENABLE             (1 << 1)
+#define                CODA7_USE_BIT_ENABLE            (1 << 0)
+
 #define CODA_REG_BIT_BUSY                      0x160
 #define                CODA_REG_BIT_BUSY_FLAG          1
 #define CODA_REG_BIT_RUN_COMMAND               0x164