Merge "msm: jpeg: Support for decoder 1.0 driver"
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_common.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_common.h
index 88ec1ad..04af6b6 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_common.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_common.h
@@ -14,12 +14,13 @@
#define MSM_JPEG_COMMON_H
#ifdef MSM_JPEG_DEBUG
-#define JPEG_DBG(fmt, args...) printk(fmt, ##args)
+#define JPEG_DBG(fmt, args...) pr_info(fmt, ##args)
#else
#define JPEG_DBG(fmt, args...) do { } while (0)
#endif
#define JPEG_PR_ERR pr_err
+#define JPEG_DBG_HIGH pr_err
enum JPEG_MODE {
JPEG_MODE_DISABLE,
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_core.c
index 7905ff3..b67245c 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_core.c
@@ -17,122 +17,130 @@
#include "msm_jpeg_platform.h"
#include "msm_jpeg_common.h"
-static struct msm_jpeg_hw_pingpong fe_pingpong_buf;
-static struct msm_jpeg_hw_pingpong we_pingpong_buf;
-static int we_pingpong_index;
-static int reset_done_ack;
-static spinlock_t reset_lock;
-static wait_queue_head_t reset_wait;
-
-int msm_jpeg_core_reset(uint8_t op_mode, void *base, int size)
-{
+int msm_jpeg_core_reset(struct msm_jpeg_device *pgmn_dev, uint8_t op_mode,
+ void *base, int size) {
unsigned long flags;
int rc = 0;
int tm = 500; /*500ms*/
- memset(&fe_pingpong_buf, 0, sizeof(fe_pingpong_buf));
- fe_pingpong_buf.is_fe = 1;
- we_pingpong_index = 0;
- memset(&we_pingpong_buf, 0, sizeof(we_pingpong_buf));
- spin_lock_irqsave(&reset_lock, flags);
- reset_done_ack = 0;
+ JPEG_DBG("%s:%d] reset", __func__, __LINE__);
+ memset(&pgmn_dev->fe_pingpong_buf, 0,
+ sizeof(pgmn_dev->fe_pingpong_buf));
+ pgmn_dev->fe_pingpong_buf.is_fe = 1;
+ memset(&pgmn_dev->we_pingpong_buf, 0,
+ sizeof(pgmn_dev->we_pingpong_buf));
+ spin_lock_irqsave(&pgmn_dev->reset_lock, flags);
+ pgmn_dev->reset_done_ack = 0;
msm_jpeg_hw_reset(base, size);
- spin_unlock_irqrestore(&reset_lock, flags);
+ spin_unlock_irqrestore(&pgmn_dev->reset_lock, flags);
rc = wait_event_interruptible_timeout(
- reset_wait,
- reset_done_ack,
+ pgmn_dev->reset_wait,
+ pgmn_dev->reset_done_ack,
msecs_to_jiffies(tm));
- if (!reset_done_ack) {
+ if (!pgmn_dev->reset_done_ack) {
JPEG_DBG("%s: reset ACK failed %d", __func__, rc);
return -EBUSY;
}
JPEG_DBG("%s: reset_done_ack rc %d", __func__, rc);
- spin_lock_irqsave(&reset_lock, flags);
- reset_done_ack = 0;
- spin_unlock_irqrestore(&reset_lock, flags);
+ spin_lock_irqsave(&pgmn_dev->reset_lock, flags);
+ pgmn_dev->reset_done_ack = 0;
+ spin_unlock_irqrestore(&pgmn_dev->reset_lock, flags);
return 0;
}
-void msm_jpeg_core_release(int release_buf, int domain_num)
-{
+void msm_jpeg_core_release(struct msm_jpeg_device *pgmn_dev,
+ int domain_num) {
int i = 0;
for (i = 0; i < 2; i++) {
- if (we_pingpong_buf.buf_status[i] && release_buf)
- msm_jpeg_platform_p2v(we_pingpong_buf.buf[i].file,
- &we_pingpong_buf.buf[i].handle, domain_num);
- we_pingpong_buf.buf_status[i] = 0;
+ if (pgmn_dev->we_pingpong_buf.buf_status[i] &&
+ pgmn_dev->release_buf)
+ msm_jpeg_platform_p2v(pgmn_dev,
+ pgmn_dev->we_pingpong_buf.buf[i].file,
+ &pgmn_dev->we_pingpong_buf.buf[i].handle,
+ domain_num);
+ pgmn_dev->we_pingpong_buf.buf_status[i] = 0;
}
}
-void msm_jpeg_core_init(void)
+void msm_jpeg_core_init(struct msm_jpeg_device *pgmn_dev)
{
- init_waitqueue_head(&reset_wait);
- spin_lock_init(&reset_lock);
+ init_waitqueue_head(&pgmn_dev->reset_wait);
+ spin_lock_init(&pgmn_dev->reset_lock);
}
-int msm_jpeg_core_fe_start(void)
+int msm_jpeg_core_fe_start(struct msm_jpeg_device *pgmn_dev)
{
- msm_jpeg_hw_fe_start();
+ msm_jpeg_hw_fe_start(pgmn_dev->base);
return 0;
}
/* fetch engine */
-int msm_jpeg_core_fe_buf_update(struct msm_jpeg_core_buf *buf)
+int msm_jpeg_core_fe_buf_update(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_core_buf *buf)
{
+ if (0 == buf->cbcr_len)
+ buf->cbcr_buffer_addr = 0x0;
JPEG_DBG("%s:%d] 0x%08x %d 0x%08x %d\n", __func__, __LINE__,
(int) buf->y_buffer_addr, buf->y_len,
(int) buf->cbcr_buffer_addr, buf->cbcr_len);
- return msm_jpeg_hw_pingpong_update(&fe_pingpong_buf, buf);
+ return msm_jpeg_hw_pingpong_update(&pgmn_dev->fe_pingpong_buf, buf,
+ pgmn_dev->base);
}
-void *msm_jpeg_core_fe_pingpong_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_fe_pingpong_irq(int jpeg_irq_status,
+ struct msm_jpeg_device *pgmn_dev)
{
- return msm_jpeg_hw_pingpong_irq(&fe_pingpong_buf);
+ return msm_jpeg_hw_pingpong_irq(&pgmn_dev->fe_pingpong_buf);
}
/* write engine */
-int msm_jpeg_core_we_buf_update(struct msm_jpeg_core_buf *buf)
-{
+int msm_jpeg_core_we_buf_update(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_core_buf *buf) {
JPEG_DBG("%s:%d] 0x%08x 0x%08x %d\n", __func__, __LINE__,
(int) buf->y_buffer_addr, (int) buf->cbcr_buffer_addr,
buf->y_len);
- we_pingpong_buf.buf[0] = *buf;
- we_pingpong_buf.buf_status[0] = 1;
+ pgmn_dev->we_pingpong_buf.buf[0] = *buf;
+ pgmn_dev->we_pingpong_buf.buf_status[0] = 1;
msm_jpeg_hw_we_buffer_update(
- &we_pingpong_buf.buf[0], 0);
+ &pgmn_dev->we_pingpong_buf.buf[0], 0, pgmn_dev->base);
return 0;
}
-int msm_jpeg_core_we_buf_reset(struct msm_jpeg_hw_buf *buf)
+int msm_jpeg_core_we_buf_reset(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_hw_buf *buf)
{
int i = 0;
for (i = 0; i < 2; i++) {
- if (we_pingpong_buf.buf[i].y_buffer_addr
- == buf->y_buffer_addr)
- we_pingpong_buf.buf_status[i] = 0;
+ if (pgmn_dev->we_pingpong_buf.buf[i].y_buffer_addr
+ == buf->y_buffer_addr)
+ pgmn_dev->we_pingpong_buf.buf_status[i] = 0;
}
return 0;
}
-void *msm_jpeg_core_we_pingpong_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_we_pingpong_irq(int jpeg_irq_status,
+ struct msm_jpeg_device *pgmn_dev)
{
JPEG_DBG("%s:%d]\n", __func__, __LINE__);
- return msm_jpeg_hw_pingpong_irq(&we_pingpong_buf);
+ return msm_jpeg_hw_pingpong_irq(&pgmn_dev->we_pingpong_buf);
}
-void *msm_jpeg_core_framedone_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_framedone_irq(int jpeg_irq_status,
+ struct msm_jpeg_device *pgmn_dev)
{
struct msm_jpeg_hw_buf *buf_p;
JPEG_DBG("%s:%d]\n", __func__, __LINE__);
- buf_p = msm_jpeg_hw_pingpong_active_buffer(&we_pingpong_buf);
- if (buf_p) {
- buf_p->framedone_len = msm_jpeg_hw_encode_output_size();
+ buf_p = msm_jpeg_hw_pingpong_active_buffer(
+ &pgmn_dev->we_pingpong_buf);
+ if (buf_p && !pgmn_dev->decode_flag) {
+ buf_p->framedone_len =
+ msm_jpeg_hw_encode_output_size(pgmn_dev->base);
JPEG_DBG("%s:%d] framedone_len %d\n", __func__, __LINE__,
buf_p->framedone_len);
}
@@ -140,14 +148,16 @@
return buf_p;
}
-void *msm_jpeg_core_reset_ack_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_reset_ack_irq(int jpeg_irq_status,
+ struct msm_jpeg_device *pgmn_dev)
{
/* @todo return the status back to msm_jpeg_core_reset */
JPEG_DBG("%s:%d]\n", __func__, __LINE__);
return NULL;
}
-void *msm_jpeg_core_err_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_err_irq(int jpeg_irq_status,
+ struct msm_jpeg_device *pgmn_dev)
{
JPEG_PR_ERR("%s:%d]\n", __func__, jpeg_irq_status);
return NULL;
@@ -155,15 +165,32 @@
static int (*msm_jpeg_irq_handler) (int, void *, void *);
+void msm_jpeg_core_return_buffers(struct msm_jpeg_device *pgmn_dev,
+ int jpeg_irq_status)
+{
+ void *data = NULL;
+ data = msm_jpeg_core_fe_pingpong_irq(jpeg_irq_status,
+ pgmn_dev);
+ if (msm_jpeg_irq_handler)
+ msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_FE,
+ pgmn_dev, data);
+ data = msm_jpeg_core_we_pingpong_irq(jpeg_irq_status,
+ pgmn_dev);
+ if (msm_jpeg_irq_handler)
+ msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_WE,
+ pgmn_dev, data);
+}
+
irqreturn_t msm_jpeg_core_irq(int irq_num, void *context)
{
void *data = NULL;
unsigned long flags;
int jpeg_irq_status;
+ struct msm_jpeg_device *pgmn_dev = (struct msm_jpeg_device *)context;
JPEG_DBG("%s:%d] irq_num = %d\n", __func__, __LINE__, irq_num);
- jpeg_irq_status = msm_jpeg_hw_irq_get_status();
+ jpeg_irq_status = msm_jpeg_hw_irq_get_status(pgmn_dev->base);
JPEG_DBG("%s:%d] jpeg_irq_status = %0x\n", __func__, __LINE__,
jpeg_irq_status);
@@ -171,18 +198,26 @@
/*For reset and framedone IRQs, clear all bits*/
if (jpeg_irq_status & 0x10000000) {
msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
- JPEG_IRQ_CLEAR_ALL);
+ JPEG_IRQ_CLEAR_ALL, pgmn_dev->base);
} else if (jpeg_irq_status & 0x1) {
msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
- JPEG_IRQ_CLEAR_ALL);
+ JPEG_IRQ_CLEAR_ALL, pgmn_dev->base);
+ if (pgmn_dev->decode_flag)
+ msm_jpeg_decode_status(pgmn_dev->base);
} else {
msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
- jpeg_irq_status);
+ jpeg_irq_status, pgmn_dev->base);
}
if (msm_jpeg_hw_irq_is_frame_done(jpeg_irq_status)) {
+ /* send fe ping pong irq */
+ data = msm_jpeg_core_fe_pingpong_irq(jpeg_irq_status,
+ pgmn_dev);
+ if (msm_jpeg_irq_handler)
+ msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_FE,
+ context, data);
data = msm_jpeg_core_framedone_irq(jpeg_irq_status,
- context);
+ pgmn_dev);
if (msm_jpeg_irq_handler)
msm_jpeg_irq_handler(
MSM_JPEG_HW_MASK_COMP_FRAMEDONE,
@@ -190,11 +225,11 @@
}
if (msm_jpeg_hw_irq_is_reset_ack(jpeg_irq_status)) {
data = msm_jpeg_core_reset_ack_irq(jpeg_irq_status,
- context);
- spin_lock_irqsave(&reset_lock, flags);
- reset_done_ack = 1;
- spin_unlock_irqrestore(&reset_lock, flags);
- wake_up(&reset_wait);
+ pgmn_dev);
+ spin_lock_irqsave(&pgmn_dev->reset_lock, flags);
+ pgmn_dev->reset_done_ack = 1;
+ spin_unlock_irqrestore(&pgmn_dev->reset_lock, flags);
+ wake_up(&pgmn_dev->reset_wait);
if (msm_jpeg_irq_handler)
msm_jpeg_irq_handler(
MSM_JPEG_HW_MASK_COMP_RESET_ACK,
@@ -203,7 +238,10 @@
/* Unexpected/unintended HW interrupt */
if (msm_jpeg_hw_irq_is_err(jpeg_irq_status)) {
- data = msm_jpeg_core_err_irq(jpeg_irq_status, context);
+ if (pgmn_dev->decode_flag)
+ msm_jpeg_decode_status(pgmn_dev->base);
+ msm_jpeg_core_return_buffers(pgmn_dev, jpeg_irq_status);
+ data = msm_jpeg_core_err_irq(jpeg_irq_status, pgmn_dev);
if (msm_jpeg_irq_handler)
msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_ERR,
context, data);
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_core.h
index b5c725c..212eaff 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_core.h
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include "msm_jpeg_hw.h"
+#include "msm_jpeg_sync.h"
#define msm_jpeg_core_buf msm_jpeg_hw_buf
@@ -23,13 +24,17 @@
void msm_jpeg_core_irq_install(int (*irq_handler) (int, void *, void *));
void msm_jpeg_core_irq_remove(void);
-int msm_jpeg_core_fe_buf_update(struct msm_jpeg_core_buf *buf);
-int msm_jpeg_core_we_buf_update(struct msm_jpeg_core_buf *buf);
-int msm_jpeg_core_we_buf_reset(struct msm_jpeg_hw_buf *buf);
+int msm_jpeg_core_fe_buf_update(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_core_buf *buf);
+int msm_jpeg_core_we_buf_update(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_core_buf *buf);
+int msm_jpeg_core_we_buf_reset(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_hw_buf *buf);
-int msm_jpeg_core_reset(uint8_t op_mode, void *base, int size);
-int msm_jpeg_core_fe_start(void);
+int msm_jpeg_core_reset(struct msm_jpeg_device *pgmn_dev, uint8_t op_mode,
+ void *base, int size);
+int msm_jpeg_core_fe_start(struct msm_jpeg_device *);
-void msm_jpeg_core_release(int, int);
-void msm_jpeg_core_init(void);
+void msm_jpeg_core_release(struct msm_jpeg_device *, int);
+void msm_jpeg_core_init(struct msm_jpeg_device *);
#endif /* MSM_JPEG_CORE_H */
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c
index 45a9a38..0662f54 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c
@@ -31,9 +31,7 @@
#include "msm_jpeg_common.h"
#define MSM_JPEG_NAME "jpeg"
-#define MSM_JPEGE1_NAME "jpege1"
-#define MSM_JPEGD_NAME "jpegd"
-
+#define DEV_NAME_LEN 10
static int msm_jpeg_open(struct inode *inode, struct file *filp)
{
@@ -146,7 +144,7 @@
int rc = -1;
struct device *dev;
struct msm_jpeg_device *msm_jpeg_device_p;
- char devname[10];
+ char devname[DEV_NAME_LEN];
msm_jpeg_device_p = kzalloc(sizeof(struct msm_jpeg_device), GFP_ATOMIC);
if (!msm_jpeg_device_p) {
@@ -158,7 +156,7 @@
if (pdev->dev.of_node)
of_property_read_u32((&pdev->dev)->of_node, "cell-index",
- &pdev->id);
+ &pdev->id);
snprintf(devname, sizeof(devname), "%s%d", MSM_JPEG_NAME, pdev->id);
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c
index 0bfb6a8..e311e4c 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c
@@ -17,11 +17,8 @@
#include <linux/io.h>
-static void *jpeg_region_base;
-static uint32_t jpeg_region_size;
-
int msm_jpeg_hw_pingpong_update(struct msm_jpeg_hw_pingpong *pingpong_hw,
- struct msm_jpeg_hw_buf *buf)
+ struct msm_jpeg_hw_buf *buf, void *base)
{
int buf_free_index = -1;
@@ -41,11 +38,13 @@
if (pingpong_hw->is_fe) {
/* it is fe */
msm_jpeg_hw_fe_buffer_update(
- &pingpong_hw->buf[buf_free_index], buf_free_index);
+ &pingpong_hw->buf[buf_free_index], buf_free_index,
+ base);
} else {
/* it is we */
msm_jpeg_hw_we_buffer_update(
- &pingpong_hw->buf[buf_free_index], buf_free_index);
+ &pingpong_hw->buf[buf_free_index], buf_free_index,
+ base);
}
return 0;
}
@@ -81,12 +80,10 @@
JPEG_IRQ_STATUS_BMSK, {0} },
};
-int msm_jpeg_hw_irq_get_status(void)
+int msm_jpeg_hw_irq_get_status(void *base)
{
uint32_t n_irq_status = 0;
- rmb();
- n_irq_status = msm_jpeg_hw_read(&hw_cmd_irq_get_status[0]);
- rmb();
+ n_irq_status = msm_jpeg_hw_read(&hw_cmd_irq_get_status[0], base);
return n_irq_status;
}
@@ -97,11 +94,12 @@
JPEG_ENCODE_OUTPUT_SIZE_STATUS_BMSK, {0} } ,
};
-long msm_jpeg_hw_encode_output_size(void)
+long msm_jpeg_hw_encode_output_size(void *base)
{
uint32_t encode_output_size = 0;
- encode_output_size = msm_jpeg_hw_read(&hw_cmd_encode_output_size[0]);
+ encode_output_size = msm_jpeg_hw_read(&hw_cmd_encode_output_size[0],
+ base);
return encode_output_size;
}
@@ -112,12 +110,12 @@
JPEG_IRQ_CLEAR_BMSK, {JPEG_IRQ_CLEAR_ALL} },
};
-void msm_jpeg_hw_irq_clear(uint32_t mask, uint32_t data)
+void msm_jpeg_hw_irq_clear(uint32_t mask, uint32_t data, void *base)
{
JPEG_DBG("%s:%d] mask %0x data %0x", __func__, __LINE__, mask, data);
hw_cmd_irq_clear[0].mask = mask;
hw_cmd_irq_clear[0].data = data;
- msm_jpeg_hw_write(&hw_cmd_irq_clear[0]);
+ msm_jpeg_hw_write(&hw_cmd_irq_clear[0], base);
}
struct msm_jpeg_hw_cmd hw_cmd_fe_ping_update[] = {
@@ -137,26 +135,26 @@
};
void msm_jpeg_hw_fe_buffer_update(struct msm_jpeg_hw_buf *p_input,
- uint8_t pingpong_index)
+ uint8_t pingpong_index, void *base)
{
struct msm_jpeg_hw_cmd *hw_cmd_p;
if (pingpong_index == 0) {
hw_cmd_p = &hw_cmd_fe_ping_update[0];
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
hw_cmd_p->data = p_input->y_buffer_addr;
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
hw_cmd_p->data = p_input->cbcr_buffer_addr;
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
}
@@ -169,9 +167,9 @@
JPEG_CMD_BMSK, {JPEG_OFFLINE_CMD_START} },
};
-void msm_jpeg_hw_fe_start(void)
+void msm_jpeg_hw_fe_start(void *base)
{
- msm_jpeg_hw_write(&hw_cmd_fe_start[0]);
+ msm_jpeg_hw_write(&hw_cmd_fe_start[0], base);
return;
}
@@ -180,20 +178,46 @@
/* type, repeat n times, offset, mask, data or pdata */
{MSM_JPEG_HW_CMD_TYPE_WRITE, 1, JPEG_PLN0_WR_PNTR_ADDR,
JPEG_PLN0_WR_PNTR_BMSK, {0} },
+ {MSM_JPEG_HW_CMD_TYPE_WRITE, 1, JPEG_PLN1_WR_PNTR_ADDR,
+ JPEG_PLN0_WR_PNTR_BMSK, {0} },
+ {MSM_JPEG_HW_CMD_TYPE_WRITE, 1, JPEG_PLN2_WR_PNTR_ADDR,
+ JPEG_PLN0_WR_PNTR_BMSK, {0} },
};
+void msm_jpeg_decode_status(void *base)
+{
+ uint32_t data;
+ data = readl_relaxed(base + JPEG_DECODE_MCUS_DECODED_STATUS);
+ JPEG_DBG_HIGH("Decode MCUs decode status %u", data);
+ data = readl_relaxed(base + JPEG_DECODE_BITS_CONSUMED_STATUS);
+ JPEG_DBG_HIGH("Decode bits consumed status %u", data);
+ data = readl_relaxed(base + JPEG_DECODE_PRED_Y_STATE);
+ JPEG_DBG_HIGH("Decode prediction Y state %u", data);
+ data = readl_relaxed(base + JPEG_DECODE_PRED_C_STATE);
+ JPEG_DBG_HIGH("Decode prediction C state %u", data);
+ data = readl_relaxed(base + JPEG_DECODE_RSM_STATE);
+ JPEG_DBG_HIGH("Decode prediction RSM state %u", data);
+}
+
+
void msm_jpeg_hw_we_buffer_update(struct msm_jpeg_hw_buf *p_input,
- uint8_t pingpong_index)
+ uint8_t pingpong_index, void *base)
{
struct msm_jpeg_hw_cmd *hw_cmd_p;
if (pingpong_index == 0) {
hw_cmd_p = &hw_cmd_we_ping_update[0];
hw_cmd_p->data = p_input->y_buffer_addr;
- JPEG_PR_ERR("%s Output buffer address is %x\n", __func__,
- p_input->y_buffer_addr);
- msm_jpeg_hw_write(hw_cmd_p++);
-
+ JPEG_PR_ERR("%s Output pln0 buffer address is %x\n", __func__,
+ p_input->y_buffer_addr);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
+ hw_cmd_p->data = p_input->cbcr_buffer_addr;
+ JPEG_PR_ERR("%s Output pln1 buffer address is %x\n", __func__,
+ p_input->cbcr_buffer_addr);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
+ JPEG_PR_ERR("%s Output pln2 buffer address is %x\n", __func__,
+ p_input->pln2_addr);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
}
return;
}
@@ -210,31 +234,26 @@
JPEG_RESET_CMD_RMSK, {JPEG_RESET_DEFAULT} },
};
-void msm_jpeg_hw_init(void *base, int size)
-{
- jpeg_region_base = base;
- jpeg_region_size = size;
-}
-
void msm_jpeg_hw_reset(void *base, int size)
{
struct msm_jpeg_hw_cmd *hw_cmd_p;
hw_cmd_p = &hw_cmd_reset[0];
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
- msm_jpeg_hw_write(hw_cmd_p);
+ msm_jpeg_hw_write(hw_cmd_p, base);
wmb();
return;
}
-uint32_t msm_jpeg_hw_read(struct msm_jpeg_hw_cmd *hw_cmd_p)
+uint32_t msm_jpeg_hw_read(struct msm_jpeg_hw_cmd *hw_cmd_p,
+ void *jpeg_region_base)
{
uint32_t *paddr;
uint32_t data;
@@ -247,7 +266,8 @@
return data;
}
-void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *hw_cmd_p)
+void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *hw_cmd_p,
+ void *jpeg_region_base)
{
uint32_t *paddr;
uint32_t old_data, new_data;
@@ -266,17 +286,18 @@
writel_relaxed(new_data, paddr);
}
-int msm_jpeg_hw_wait(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us)
+int msm_jpeg_hw_wait(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us,
+ void *base)
{
int tm = hw_cmd_p->n;
uint32_t data;
uint32_t wait_data = hw_cmd_p->data & hw_cmd_p->mask;
- data = msm_jpeg_hw_read(hw_cmd_p);
+ data = msm_jpeg_hw_read(hw_cmd_p, base);
if (data != wait_data) {
while (tm) {
udelay(m_us);
- data = msm_jpeg_hw_read(hw_cmd_p);
+ data = msm_jpeg_hw_read(hw_cmd_p, base);
if (data == wait_data)
break;
tm--;
@@ -295,41 +316,42 @@
}
}
-int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_cmds)
+int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_cmds,
+ uint32_t max_size, void *base)
{
int is_copy_to_user = -1;
uint32_t data;
while (m_cmds--) {
- if (hw_cmd_p->offset > jpeg_region_size) {
+ if (hw_cmd_p->offset > max_size) {
JPEG_PR_ERR("%s:%d] %d exceed hw region %d\n", __func__,
- __LINE__, hw_cmd_p->offset, jpeg_region_size);
+ __LINE__, hw_cmd_p->offset, max_size);
return -EFAULT;
}
switch (hw_cmd_p->type) {
case MSM_JPEG_HW_CMD_TYPE_READ:
- hw_cmd_p->data = msm_jpeg_hw_read(hw_cmd_p);
+ hw_cmd_p->data = msm_jpeg_hw_read(hw_cmd_p, base);
is_copy_to_user = 1;
break;
case MSM_JPEG_HW_CMD_TYPE_WRITE:
- msm_jpeg_hw_write(hw_cmd_p);
+ msm_jpeg_hw_write(hw_cmd_p, base);
break;
case MSM_JPEG_HW_CMD_TYPE_WRITE_OR:
- data = msm_jpeg_hw_read(hw_cmd_p);
+ data = msm_jpeg_hw_read(hw_cmd_p, base);
hw_cmd_p->data = (hw_cmd_p->data & hw_cmd_p->mask) |
data;
- msm_jpeg_hw_write(hw_cmd_p);
+ msm_jpeg_hw_write(hw_cmd_p, base);
break;
case MSM_JPEG_HW_CMD_TYPE_UWAIT:
- msm_jpeg_hw_wait(hw_cmd_p, 1);
+ msm_jpeg_hw_wait(hw_cmd_p, 1, base);
break;
case MSM_JPEG_HW_CMD_TYPE_MWAIT:
- msm_jpeg_hw_wait(hw_cmd_p, 1000);
+ msm_jpeg_hw_wait(hw_cmd_p, 1000, base);
break;
case MSM_JPEG_HW_CMD_TYPE_UDELAY:
@@ -350,15 +372,14 @@
return is_copy_to_user;
}
-void msm_jpeg_io_dump(int size)
+void msm_jpeg_io_dump(void *base, int size)
{
char line_str[128], *p_str;
- void __iomem *addr = jpeg_region_base;
+ void __iomem *addr = (void __iomem *)base;
int i;
u32 *p = (u32 *) addr;
u32 data;
- JPEG_PR_ERR("%s: %p %d reg_size %d\n", __func__, addr, size,
- jpeg_region_size);
+ JPEG_DBG_HIGH("%s:%d] %p %d", __func__, __LINE__, addr, size);
line_str[0] = '\0';
p_str = line_str;
for (i = 0; i < size/4; i++) {
@@ -370,11 +391,12 @@
snprintf(p_str, 12, "%08x ", data);
p_str += 9;
if ((i + 1) % 4 == 0) {
- JPEG_PR_ERR("%s\n", line_str);
+ JPEG_DBG_HIGH("%s\n", line_str);
line_str[0] = '\0';
p_str = line_str;
}
}
if (line_str[0] != '\0')
- JPEG_PR_ERR("%s\n", line_str);
+ JPEG_DBG_HIGH("%s\n", line_str);
}
+
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h
index 73a0e27..e90b941 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h
@@ -28,6 +28,8 @@
uint32_t cbcr_len;
uint32_t num_of_mcu_rows;
struct ion_handle *handle;
+ uint32_t pln2_addr;
+ uint32_t pln2_offset;
};
struct msm_jpeg_hw_pingpong {
@@ -38,14 +40,14 @@
};
int msm_jpeg_hw_pingpong_update(struct msm_jpeg_hw_pingpong *pingpong_hw,
- struct msm_jpeg_hw_buf *buf);
+ struct msm_jpeg_hw_buf *buf, void *);
void *msm_jpeg_hw_pingpong_irq(struct msm_jpeg_hw_pingpong *pingpong_hw);
void *msm_jpeg_hw_pingpong_active_buffer(struct msm_jpeg_hw_pingpong
*pingpong_hw);
-void msm_jpeg_hw_irq_clear(uint32_t, uint32_t);
-int msm_jpeg_hw_irq_get_status(void);
-long msm_jpeg_hw_encode_output_size(void);
+void msm_jpeg_hw_irq_clear(uint32_t, uint32_t, void *);
+int msm_jpeg_hw_irq_get_status(void *);
+long msm_jpeg_hw_encode_output_size(void *);
#define MSM_JPEG_HW_MASK_COMP_FRAMEDONE \
MSM_JPEG_HW_IRQ_STATUS_FRAMEDONE_MASK
#define MSM_JPEG_HW_MASK_COMP_FE \
@@ -56,13 +58,14 @@
#define MSM_JPEG_HW_MASK_COMP_RESET_ACK \
MSM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK
#define MSM_JPEG_HW_MASK_COMP_ERR \
- (MSM_JPEG_HW_IRQ_STATUS_FE_RTOVF_MASK | \
- MSM_JPEG_HW_IRQ_STATUS_FE_VFE_OVERFLOW_MASK | \
- MSM_JPEG_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_MASK | \
- MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_MASK | \
- MSM_JPEG_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_MASK | \
- MSM_JPEG_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_MASK | \
- MSM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK | \
+ (MSM_JPEG_HW_IRQ_STATUS_DCD_UNESCAPED_FF | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_HUFFMAN_ERROR | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_COEFFICIENT_ERR | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_BIT_STUFF | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_SCAN_UNDERFLOW | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM_SEQ | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_RSM | \
MSM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK)
#define msm_jpeg_hw_irq_is_frame_done(jpeg_irq_status) \
@@ -77,25 +80,26 @@
(jpeg_irq_status & MSM_JPEG_HW_MASK_COMP_ERR)
void msm_jpeg_hw_fe_buffer_update(struct msm_jpeg_hw_buf *p_input,
- uint8_t pingpong_index);
+ uint8_t pingpong_index, void *);
void msm_jpeg_hw_we_buffer_update(struct msm_jpeg_hw_buf *p_input,
- uint8_t pingpong_index);
+ uint8_t pingpong_index, void *);
void msm_jpeg_hw_we_buffer_cfg(uint8_t is_realtime);
-void msm_jpeg_hw_fe_start(void);
+void msm_jpeg_hw_fe_start(void *);
void msm_jpeg_hw_clk_cfg(void);
void msm_jpeg_hw_reset(void *base, int size);
void msm_jpeg_hw_irq_cfg(void);
-void msm_jpeg_hw_init(void *base, int size);
-uint32_t msm_jpeg_hw_read(struct msm_jpeg_hw_cmd *hw_cmd_p);
-void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *hw_cmd_p);
-int msm_jpeg_hw_wait(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us);
-void msm_jpeg_hw_delay(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us);
-int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_cmds);
+uint32_t msm_jpeg_hw_read(struct msm_jpeg_hw_cmd *, void *);
+void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *, void *);
+int msm_jpeg_hw_wait(struct msm_jpeg_hw_cmd *, int, void *);
+void msm_jpeg_hw_delay(struct msm_jpeg_hw_cmd *, int);
+int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *, int ,
+ uint32_t , void *);
void msm_jpeg_hw_region_dump(int size);
-void msm_jpeg_io_dump(int size);
+void msm_jpeg_io_dump(void *base, int size);
+void msm_jpeg_decode_status(void *base);
#endif /* MSM_JPEG_HW_H */
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
index ae64c32..928d59e 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
@@ -37,30 +37,25 @@
#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_PINGPONG_MASK 0x00000020
#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_PINGPONG_SHIFT 0x00000005
-#define MSM_JPEG_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_MASK 0x00000040
-#define MSM_JPEG_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_SHIFT 0x00000006
-
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_MASK 0x00000080
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_SHIFT 0x00000007
-
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_MASK 0x00000100
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_SHIFT 0x00000008
-
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_MASK 0x00000200
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_SHIFT 0x00000009
-
#define MSM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK 0x10000000
#define MSM_JPEG_HW_IRQ_STATUS_RESET_ACK_SHIFT 0x0000000a
#define MSM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK 0x00000800
#define MSM_JPEG_HW_IRQ_STATUS_BUS_ERROR_SHIFT 0x0000000b
-#define MSM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK 0x00001000
-#define MSM_JPEG_HW_IRQ_STATUS_VIOLATION_SHIFT 0x0000000c
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_UNESCAPED_FF (0x1<<19)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_HUFFMAN_ERROR (0x1<<20)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_COEFFICIENT_ERR (0x1<<21)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_BIT_STUFF (0x1<<22)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_SCAN_UNDERFLOW (0x1<<23)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM (0x1<<24)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM_SEQ (0x1<<25)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_RSM (0x1<<26)
+#define MSM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK (0x1<<29)
#define JPEG_OFFLINE_CMD_START 0x00000001
-#define JPEG_RESET_DEFAULT 0x00000003 /* cfff? */
+#define JPEG_RESET_DEFAULT 0x00020000
#define JPEG_IRQ_DISABLE_ALL 0x00000000
#define JPEG_IRQ_CLEAR_ALL 0xFFFFFFFF
@@ -87,6 +82,9 @@
#define JPEG_PLN1_WR_PNTR_ADDR (JPEG_REG_BASE + 0x000000D0)
#define JPEG_PLN1_WR_PNTR_BMSK 0xFFFFFFFF
+#define JPEG_PLN2_WR_PNTR_ADDR (JPEG_REG_BASE + 0x000000D4)
+#define JPEG_PLN2_WR_PNTR_BMSK 0xFFFFFFFF
+
#define JPEG_IRQ_MASK_ADDR (JPEG_REG_BASE + 0x00000018)
#define JPEG_IRQ_MASK_BMSK 0xFFFFFFFF
#define JPEG_IRQ_ALLSOURCES_ENABLE 0xFFFFFFFF
@@ -103,6 +101,11 @@
#define JPEG_ENCODE_OUTPUT_SIZE_STATUS_ADDR (JPEG_REG_BASE + 0x00000180)
#define JPEG_ENCODE_OUTPUT_SIZE_STATUS_BMSK 0x1FFFFFFF
+#define JPEG_DECODE_MCUS_DECODED_STATUS (JPEG_REG_BASE + 0x00000258)
+#define JPEG_DECODE_BITS_CONSUMED_STATUS (JPEG_REG_BASE + 0x0000025C)
+#define JPEG_DECODE_PRED_Y_STATE (JPEG_REG_BASE + 0x00000260)
+#define JPEG_DECODE_PRED_C_STATE (JPEG_REG_BASE + 0x00000264)
+#define JPEG_DECODE_RSM_STATE (JPEG_REG_BASE + 0x00000268)
#define VBIF_BASE_ADDRESS 0xFDA60000
#define VBIF_REGION_SIZE 0xC30
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
index 981c56c..0370f63 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
@@ -26,36 +26,32 @@
#include "msm_jpeg_common.h"
#include "msm_jpeg_hw.h"
-/* AXI rate in KHz */
-struct ion_client *jpeg_client;
-static void *jpeg_vbif;
-
-void msm_jpeg_platform_p2v(struct file *file,
- struct ion_handle **ionhandle, int domain_num)
+void msm_jpeg_platform_p2v(struct msm_jpeg_device *pgmn_dev, struct file *file,
+ struct ion_handle **ionhandle, int domain_num)
{
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- ion_unmap_iommu(jpeg_client, *ionhandle, domain_num, 0);
- ion_free(jpeg_client, *ionhandle);
+ ion_unmap_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0);
+ ion_free(pgmn_dev->jpeg_client, *ionhandle);
*ionhandle = NULL;
#elif CONFIG_ANDROID_PMEM
put_pmem_file(file);
#endif
}
-uint32_t msm_jpeg_platform_v2p(int fd, uint32_t len, struct file **file_p,
- struct ion_handle **ionhandle, int domain_num)
-{
+uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd,
+ uint32_t len, struct file **file_p, struct ion_handle **ionhandle,
+ int domain_num) {
unsigned long paddr;
unsigned long size;
int rc;
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- *ionhandle = ion_import_dma_buf(jpeg_client, fd);
+ *ionhandle = ion_import_dma_buf(pgmn_dev->jpeg_client, fd);
if (IS_ERR_OR_NULL(*ionhandle))
return 0;
- rc = ion_map_iommu(jpeg_client, *ionhandle, domain_num, 0,
- SZ_4K, 0, &paddr, (unsigned long *)&size, UNCACHED, 0);
- JPEG_DBG("%s:%d] addr 0x%x size %ld", __func__, __LINE__,
+ rc = ion_map_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0,
+ SZ_4K, 0, &paddr, (unsigned long *)&size, UNCACHED,
+0); JPEG_DBG("%s:%d] addr 0x%x size %ld", __func__, __LINE__,
(uint32_t)paddr, size);
#elif CONFIG_ANDROID_PMEM
@@ -81,7 +77,7 @@
return paddr;
error1:
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- ion_free(jpeg_client, *ionhandle);
+ ion_free(pgmn_dev->jpeg_client, *ionhandle);
#endif
return 0;
}
@@ -149,10 +145,10 @@
}
jpeg_irq = jpeg_irq_res->start;
JPEG_DBG("%s base address: 0x%x, jpeg irq number: %d\n", __func__,
- jpeg_mem->start, jpeg_irq);
+ jpeg_mem->start, jpeg_irq);
jpeg_io = request_mem_region(jpeg_mem->start,
- resource_size(jpeg_mem), pdev->name);
+ resource_size(jpeg_mem), pdev->name);
if (!jpeg_io) {
JPEG_PR_ERR("%s: region already claimed\n", __func__);
return -EBUSY;
@@ -165,14 +161,14 @@
goto fail1;
}
- jpeg_vbif = ioremap(VBIF_BASE_ADDRESS, VBIF_REGION_SIZE);
- if (!jpeg_vbif) {
+ pgmn_dev->jpeg_vbif = ioremap(VBIF_BASE_ADDRESS, VBIF_REGION_SIZE);
+ if (!pgmn_dev->jpeg_vbif) {
rc = -ENOMEM;
JPEG_PR_ERR("%s:%d] ioremap failed\n", __func__, __LINE__);
goto fail1;
}
JPEG_DBG("%s:%d] jpeg_vbif 0x%x", __func__, __LINE__,
- (uint32_t)jpeg_vbif);
+ (uint32_t)pgmn_dev->jpeg_vbif);
pgmn_dev->jpeg_fs = regulator_get(&pgmn_dev->pdev->dev, "vdd");
rc = regulator_enable(pgmn_dev->jpeg_fs);
@@ -202,9 +198,8 @@
(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
}
#endif
- set_vbif_params(jpeg_vbif);
+ set_vbif_params(pgmn_dev->jpeg_vbif);
- msm_jpeg_hw_init(jpeg_base, resource_size(jpeg_mem));
rc = request_irq(jpeg_irq, handler, IRQF_TRIGGER_RISING, "jpeg",
context);
if (rc) {
@@ -218,7 +213,7 @@
*irq = jpeg_irq;
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- jpeg_client = msm_ion_client_create(-1, "camera/jpeg");
+ pgmn_dev->jpeg_client = msm_ion_client_create(-1, "camera/jpeg");
#endif
JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
@@ -276,11 +271,11 @@
regulator_disable(pgmn_dev->jpeg_fs);
pgmn_dev->jpeg_fs = NULL;
}
- iounmap(jpeg_vbif);
+ iounmap(pgmn_dev->jpeg_vbif);
iounmap(base);
release_mem_region(mem->start, resource_size(mem));
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- ion_client_destroy(jpeg_client);
+ ion_client_destroy(pgmn_dev->jpeg_client);
#endif
JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
return result;
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h
index 8a37cef..cd80d2e 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h
@@ -18,12 +18,13 @@
#include <linux/ion.h>
#include <linux/iommu.h>
#include <mach/iommu.h>
+#include "msm_jpeg_sync.h"
-
-void msm_jpeg_platform_p2v(struct file *file,
- struct ion_handle **ionhandle, int domain_num);
-uint32_t msm_jpeg_platform_v2p(int fd, uint32_t len, struct file **file,
- struct ion_handle **ionhandle, int domain_num);
+void msm_jpeg_platform_p2v(struct msm_jpeg_device *pgmn_dev, struct file *file,
+ struct ion_handle **ionhandle, int domain_num);
+uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd,
+ uint32_t len, struct file **file, struct ion_handle **ionhandle,
+ int domain_num);
int msm_jpeg_platform_clk_enable(void);
int msm_jpeg_platform_clk_disable(void);
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
index 6ac4a5e..a0aaf03 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
@@ -22,7 +22,9 @@
#include "msm_jpeg_platform.h"
#include "msm_jpeg_common.h"
-static int release_buf;
+#define JPEG_REG_SIZE 0x308
+#define JPEG_DEV_CNT 3
+#define JPEG_DEC_ID 2
inline void msm_jpeg_q_init(char const *name, struct msm_jpeg_q *q_p)
{
@@ -143,15 +145,15 @@
return 0;
}
-inline void msm_jpeg_outbuf_q_cleanup(struct msm_jpeg_q *q_p,
- int domain_num)
+inline void msm_jpeg_outbuf_q_cleanup(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_q *q_p, int domain_num)
{
struct msm_jpeg_core_buf *buf_p;
JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
do {
buf_p = msm_jpeg_q_out(q_p);
if (buf_p) {
- msm_jpeg_platform_p2v(buf_p->file,
+ msm_jpeg_platform_p2v(pgmn_dev, buf_p->file,
&buf_p->handle, domain_num);
JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
kfree(buf_p);
@@ -289,10 +291,10 @@
if (buf_out) {
JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
(int) buf_out->y_buffer_addr, buf_out->y_len);
- rc = msm_jpeg_core_we_buf_update(buf_out);
+ rc = msm_jpeg_core_we_buf_update(pgmn_dev, buf_out);
kfree(buf_out);
} else {
- msm_jpeg_core_we_buf_reset(buf_in);
+ msm_jpeg_core_we_buf_reset(pgmn_dev, buf_in);
JPEG_DBG("%s:%d] no output buffer\n", __func__, __LINE__);
rc = -2;
}
@@ -320,7 +322,7 @@
}
buf_cmd = buf_p->vbuf;
- msm_jpeg_platform_p2v(buf_p->file, &buf_p->handle,
+ msm_jpeg_platform_p2v(pgmn_dev, buf_p->file, &buf_p->handle,
pgmn_dev->domain_num);
kfree(buf_p);
@@ -347,6 +349,7 @@
{
struct msm_jpeg_buf buf_cmd;
struct msm_jpeg_core_buf *buf_p;
+ memset(&buf_cmd, 0x0, sizeof(struct msm_jpeg_buf));
JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_jpeg_buf))) {
@@ -364,7 +367,7 @@
__func__, __LINE__, (int) buf_cmd.vaddr, buf_cmd.y_len,
buf_cmd.fd);
- buf_p->y_buffer_addr = msm_jpeg_platform_v2p(buf_cmd.fd,
+ buf_p->y_buffer_addr = msm_jpeg_platform_v2p(pgmn_dev, buf_cmd.fd,
buf_cmd.y_len, &buf_p->file, &buf_p->handle,
pgmn_dev->domain_num);
if (!buf_p->y_buffer_addr) {
@@ -372,9 +375,18 @@
kfree(buf_p);
return -EFAULT;
}
- JPEG_DBG("%s:%d]After v2p y_address =0x%08x, handle = %p\n",
- __func__, __LINE__, buf_p->y_buffer_addr, buf_p->handle);
+
+ if (buf_cmd.cbcr_len)
+ buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr +
+ buf_cmd.y_len;
+ else
+ buf_p->cbcr_buffer_addr = 0x0;
+
+ JPEG_DBG("%s:%d] After v2p pln0_addr =0x%x,pln0_len %d pl1_len %d",
+ __func__, __LINE__, buf_p->y_buffer_addr,
+ buf_cmd.y_len, buf_cmd.cbcr_len);
buf_p->y_len = buf_cmd.y_len;
+ buf_p->cbcr_len = buf_cmd.cbcr_len;
buf_p->vbuf = buf_cmd;
msm_jpeg_q_in(&pgmn_dev->output_buf_q, buf_p);
@@ -403,9 +415,9 @@
buf_out = msm_jpeg_q_out(&pgmn_dev->input_buf_q);
if (buf_out) {
- rc = msm_jpeg_core_fe_buf_update(buf_out);
+ rc = msm_jpeg_core_fe_buf_update(pgmn_dev, buf_out);
kfree(buf_out);
- msm_jpeg_core_fe_start();
+ msm_jpeg_core_fe_start(pgmn_dev);
} else {
JPEG_DBG("%s:%d] no input buffer\n", __func__, __LINE__);
rc = -EFAULT;
@@ -433,8 +445,8 @@
}
buf_cmd = buf_p->vbuf;
- msm_jpeg_platform_p2v(buf_p->file, &buf_p->handle,
- pgmn_dev->domain_num);
+ msm_jpeg_platform_p2v(pgmn_dev, buf_p->file, &buf_p->handle,
+ pgmn_dev->domain_num);
kfree(buf_p);
JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
@@ -460,6 +472,7 @@
{
struct msm_jpeg_core_buf *buf_p;
struct msm_jpeg_buf buf_cmd;
+ memset(&buf_cmd, 0x0, sizeof(struct msm_jpeg_buf));
if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_jpeg_buf))) {
JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
@@ -475,20 +488,26 @@
JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
(int) buf_cmd.vaddr, buf_cmd.y_len);
- buf_p->y_buffer_addr = msm_jpeg_platform_v2p(buf_cmd.fd,
+ buf_p->y_buffer_addr = msm_jpeg_platform_v2p(pgmn_dev, buf_cmd.fd,
buf_cmd.y_len + buf_cmd.cbcr_len, &buf_p->file,
&buf_p->handle, pgmn_dev->domain_num) + buf_cmd.offset
+ buf_cmd.y_off;
buf_p->y_len = buf_cmd.y_len;
- buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr + buf_cmd.y_len
- + buf_cmd.cbcr_off;
buf_p->cbcr_len = buf_cmd.cbcr_len;
buf_p->num_of_mcu_rows = buf_cmd.num_of_mcu_rows;
+ buf_p->y_len = buf_cmd.y_len;
+ buf_p->cbcr_len = buf_cmd.cbcr_len;
+ if (buf_cmd.cbcr_len)
+ buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr + buf_cmd.y_len
+ + buf_cmd.cbcr_off;
+ else
+ buf_p->cbcr_buffer_addr = 0x0;
+
JPEG_DBG("%s: y_addr=%x, y_len=%x, cbcr_addr=%x, cbcr_len=%x, fd =%d\n",
__func__, buf_p->y_buffer_addr, buf_p->y_len,
buf_p->cbcr_buffer_addr, buf_p->cbcr_len, buf_cmd.fd);
- if (!buf_p->y_buffer_addr || !buf_p->cbcr_buffer_addr) {
+ if (!buf_p->y_buffer_addr) {
JPEG_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
kfree(buf_p);
return -EFAULT;
@@ -559,13 +578,15 @@
JPEG_DBG("%s:%d] platform resources - mem %p, base %p, irq %d\n",
__func__, __LINE__,
pgmn_dev->mem, pgmn_dev->base, pgmn_dev->irq);
+ pgmn_dev->res_size = resource_size(pgmn_dev->mem);
msm_jpeg_q_cleanup(&pgmn_dev->evt_q);
msm_jpeg_q_cleanup(&pgmn_dev->output_rtn_q);
- msm_jpeg_outbuf_q_cleanup(&pgmn_dev->output_buf_q,
- pgmn_dev->domain_num); msm_jpeg_q_cleanup(&pgmn_dev->input_rtn_q);
+ msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->output_buf_q,
+ pgmn_dev->domain_num);
+ msm_jpeg_q_cleanup(&pgmn_dev->input_rtn_q);
msm_jpeg_q_cleanup(&pgmn_dev->input_buf_q);
- msm_jpeg_core_init();
+ msm_jpeg_core_init(pgmn_dev);
JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
return rc;
@@ -583,13 +604,14 @@
pgmn_dev->open_count--;
mutex_unlock(&pgmn_dev->lock);
- msm_jpeg_core_release(release_buf, pgmn_dev->domain_num);
+ msm_jpeg_core_release(pgmn_dev, pgmn_dev->domain_num);
msm_jpeg_q_cleanup(&pgmn_dev->evt_q);
msm_jpeg_q_cleanup(&pgmn_dev->output_rtn_q);
- msm_jpeg_outbuf_q_cleanup(&pgmn_dev->output_buf_q,
- pgmn_dev->domain_num);
+ msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->output_buf_q,
+ pgmn_dev->domain_num);
msm_jpeg_q_cleanup(&pgmn_dev->input_rtn_q);
- msm_jpeg_outbuf_q_cleanup(&pgmn_dev->input_buf_q, pgmn_dev->domain_num);
+ msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->input_buf_q,
+ pgmn_dev->domain_num);
JPEG_DBG("%s:%d]\n", __func__, __LINE__);
if (pgmn_dev->open_count)
@@ -598,6 +620,7 @@
msm_jpeg_platform_release(pgmn_dev->mem, pgmn_dev->base,
pgmn_dev->irq, pgmn_dev);
+ JPEG_DBG("%s:%d]\n", __func__, __LINE__);
return 0;
}
@@ -612,7 +635,8 @@
return -EFAULT;
}
- is_copy_to_user = msm_jpeg_hw_exec_cmds(&hw_cmd, 1);
+ is_copy_to_user = msm_jpeg_hw_exec_cmds(&hw_cmd, 1,
+ pgmn_dev->res_size, pgmn_dev->base);
JPEG_DBG("%s:%d] type %d, n %d, offset %d, mask %x, data %x,pdata %x\n",
__func__, __LINE__, hw_cmd.type, hw_cmd.n, hw_cmd.offset,
hw_cmd.mask, hw_cmd.data, (int) hw_cmd.pdata);
@@ -657,7 +681,8 @@
hw_cmd_p = (struct msm_jpeg_hw_cmd *) &(hw_cmds_p->hw_cmd);
- is_copy_to_user = msm_jpeg_hw_exec_cmds(hw_cmd_p, m);
+ is_copy_to_user = msm_jpeg_hw_exec_cmds(hw_cmd_p, m,
+ pgmn_dev->res_size, pgmn_dev->base);
if (is_copy_to_user >= 0) {
if (copy_to_user(arg, hw_cmds_p, len)) {
@@ -678,12 +703,12 @@
JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
- release_buf = 1;
+ pgmn_dev->release_buf = 1;
for (i = 0; i < 2; i++) {
buf_out = msm_jpeg_q_out(&pgmn_dev->input_buf_q);
if (buf_out) {
- msm_jpeg_core_fe_buf_update(buf_out);
+ msm_jpeg_core_fe_buf_update(pgmn_dev, buf_out);
kfree(buf_out);
} else {
JPEG_DBG("%s:%d] no input buffer\n", __func__,
@@ -696,8 +721,8 @@
buf_out_free[i] = msm_jpeg_q_out(&pgmn_dev->output_buf_q);
if (buf_out_free[i]) {
- msm_jpeg_core_we_buf_update(buf_out_free[i]);
- release_buf = 0;
+ msm_jpeg_core_we_buf_update(pgmn_dev, buf_out_free[i]);
+ pgmn_dev->release_buf = 0;
} else {
JPEG_DBG("%s:%d] no output buffer\n",
__func__, __LINE__);
@@ -708,6 +733,7 @@
for (i = 0; i < 2; i++)
kfree(buf_out_free[i]);
+ msm_jpeg_io_dump(pgmn_dev->base, JPEG_REG_SIZE);
rc = msm_jpeg_ioctl_hw_cmds(pgmn_dev, arg);
JPEG_DBG("%s:%d]\n", __func__, __LINE__);
return rc;
@@ -727,7 +753,7 @@
pgmn_dev->op_mode = ctrl_cmd.type;
- rc = msm_jpeg_core_reset(pgmn_dev->op_mode, pgmn_dev->base,
+ rc = msm_jpeg_core_reset(pgmn_dev, pgmn_dev->op_mode, pgmn_dev->base,
resource_size(pgmn_dev->mem));
return rc;
}
@@ -736,7 +762,7 @@
unsigned long arg)
{
JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
- msm_jpeg_io_dump(arg);
+ msm_jpeg_io_dump(pgmn_dev->base, JPEG_REG_SIZE);
return 0;
}
@@ -836,9 +862,10 @@
int __msm_jpeg_init(struct msm_jpeg_device *pgmn_dev)
{
- int rc = 0, i = 0;
+ int rc = 0, i = 0, j = 0;
int idx = 0;
- char *iommu_name[3] = {"jpeg_enc0", "jpeg_enc1", "jpeg_dec"};
+ char *iommu_name[JPEG_DEV_CNT] = {"jpeg_enc0", "jpeg_enc1",
+ "jpeg_dec"};
mutex_init(&pgmn_dev->lock);
@@ -847,6 +874,7 @@
idx = pgmn_dev->pdev->id;
pgmn_dev->idx = idx;
pgmn_dev->iommu_cnt = 1;
+ pgmn_dev->decode_flag = (idx == JPEG_DEC_ID);
msm_jpeg_q_init("evt_q", &pgmn_dev->evt_q);
msm_jpeg_q_init("output_rtn_q", &pgmn_dev->output_rtn_q);
@@ -855,21 +883,23 @@
msm_jpeg_q_init("input_buf_q", &pgmn_dev->input_buf_q);
#ifdef CONFIG_MSM_IOMMU
-/*get device context for IOMMU*/
+ j = (pgmn_dev->iommu_cnt <= 1) ? idx : 0;
+ /*get device context for IOMMU*/
for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
- pgmn_dev->iommu_ctx_arr[i] = msm_iommu_get_ctx(iommu_name[i]);
- JPEG_DBG("%s:%d] name %s", __func__, __LINE__, iommu_name[i]);
+ pgmn_dev->iommu_ctx_arr[i] = msm_iommu_get_ctx(iommu_name[j]);
+ JPEG_DBG("%s:%d] name %s", __func__, __LINE__, iommu_name[j]);
JPEG_DBG("%s:%d] ctx 0x%x", __func__, __LINE__,
- (uint32_t)pgmn_dev->iommu_ctx_arr[i]);
+ (uint32_t)pgmn_dev->iommu_ctx_arr[i]);
if (!pgmn_dev->iommu_ctx_arr[i]) {
JPEG_PR_ERR("%s: No iommu fw context found\n",
__func__);
goto error;
}
+ j++;
}
pgmn_dev->domain_num = camera_register_domain();
JPEG_DBG("%s:%d] dom_num 0x%x", __func__, __LINE__,
- pgmn_dev->domain_num);
+ pgmn_dev->domain_num);
if (pgmn_dev->domain_num < 0) {
JPEG_PR_ERR("%s: could not register domain\n", __func__);
goto error;
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h
index 1d82060..1ac4838 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h
@@ -21,7 +21,7 @@
#include <linux/platform_device.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
-#include "msm_jpeg_core.h"
+#include "msm_jpeg_hw.h"
#define JPEG_7X 0x1
#define JPEG_8X60 (0x1 << 1)
@@ -88,6 +88,17 @@
struct iommu_domain *domain;
struct device *iommu_ctx_arr[3];
int iommu_cnt;
+ int decode_flag;
+ struct ion_client *jpeg_client;
+ void *jpeg_vbif;
+ int release_buf;
+ struct msm_jpeg_hw_pingpong fe_pingpong_buf;
+ struct msm_jpeg_hw_pingpong we_pingpong_buf;
+ int we_pingpong_index;
+ int reset_done_ack;
+ spinlock_t reset_lock;
+ wait_queue_head_t reset_wait;
+ uint32_t res_size;
};
int __msm_jpeg_open(struct msm_jpeg_device *pgmn_dev);
diff --git a/include/media/msm_jpeg.h b/include/media/msm_jpeg.h
index 11c3247..56829f1 100644
--- a/include/media/msm_jpeg.h
+++ b/include/media/msm_jpeg.h
@@ -85,6 +85,8 @@
uint32_t num_of_mcu_rows;
uint32_t offset;
+ uint32_t pln2_off;
+ uint32_t pln2_len;
};
#define MSM_JPEG_HW_CMD_TYPE_READ 0