835 lines
20 KiB
C
835 lines
20 KiB
C
|
|
#include "sys_config.h"
|
||
|
|
#include "tx_platform.h"
|
||
|
|
#include "list.h"
|
||
|
|
#include "dev.h"
|
||
|
|
#include "typesdef.h"
|
||
|
|
#include "lib/video/dvp/cmos_sensor/csi.h"
|
||
|
|
#include "dev/csi/hgdvp.h"
|
||
|
|
#include "devid.h"
|
||
|
|
#include "osal/irq.h"
|
||
|
|
#include "osal/string.h"
|
||
|
|
#include "dev/jpg/hgjpg.h"
|
||
|
|
#include "lib/video/dvp/jpeg/jpg.h"
|
||
|
|
#include "hal/jpeg.h"
|
||
|
|
#include "osal/task.h"
|
||
|
|
#include "osal/sleep.h"
|
||
|
|
|
||
|
|
//调用外部接口
|
||
|
|
void driver_timer_add(int32_t (*func)(void *arg,uint32_t kick_time), void *arg);
|
||
|
|
|
||
|
|
struct hgjpg_hw
|
||
|
|
{
|
||
|
|
__IO uint32 CSR0;
|
||
|
|
__IO uint32 CSR1;
|
||
|
|
__IO uint32 CSR2;
|
||
|
|
__IO uint32 CSR3;
|
||
|
|
__IO uint32 DMA_CON;
|
||
|
|
__IO uint32 DMA_CON1;
|
||
|
|
__IO uint32 DMA_STA;
|
||
|
|
__IO uint32 DMA_TADR0;
|
||
|
|
__IO uint32 DMA_TADR1;
|
||
|
|
__IO uint32 DMA_DLEN;
|
||
|
|
__IO uint32 DMA_DHT_ADR;
|
||
|
|
__IO uint32 DMA_DADR;
|
||
|
|
__IO uint32 DMA_DTO;
|
||
|
|
__IO uint32 DMA_SF_YADR;
|
||
|
|
__IO uint32 DMA_SF_UADR;
|
||
|
|
__IO uint32 DMA_SF_VADR;
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
struct hgjpg_table_hw
|
||
|
|
{
|
||
|
|
__IO uint32 DQT[32];
|
||
|
|
};
|
||
|
|
|
||
|
|
struct hgjpg_huff_hw
|
||
|
|
{
|
||
|
|
__IO uint32_t HUFF[192];
|
||
|
|
};
|
||
|
|
|
||
|
|
struct jpg_device *p_jpg_global[JPG_NUM];
|
||
|
|
volatile uint8_t jpg_ready[JPG_NUM];
|
||
|
|
|
||
|
|
|
||
|
|
volatile uint8_t jpg_oe_enable[JPG_NUM];
|
||
|
|
volatile uint8_t jpg_oe_used[JPG_NUM];
|
||
|
|
volatile uint8_t jpg_oe_ok[JPG_NUM];
|
||
|
|
|
||
|
|
extern volatile uint8 isp_ov_err;
|
||
|
|
|
||
|
|
|
||
|
|
jpg_irq_hdl jpgirq_vector_table[JPG_NUM][JPG_IRQ_NUM];
|
||
|
|
void * jpgirq_dev_table[JPG_NUM][JPG_IRQ_NUM];
|
||
|
|
|
||
|
|
void irq_jpg_enable(struct hgjpg_hw *p_jpg,uint8 mode,uint8 irq){
|
||
|
|
if(mode){
|
||
|
|
p_jpg->DMA_CON |= BIT(irq+13);
|
||
|
|
}else{
|
||
|
|
p_jpg->DMA_CON &= ~BIT(irq+13);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
extern volatile uint8_t vpp_oe;
|
||
|
|
void JPG_IRQHandler_action(void *p_jpg)
|
||
|
|
{
|
||
|
|
uint32 jpgr = 0;
|
||
|
|
uint32 sta = 0;
|
||
|
|
uint8_t jpg_err = 0;
|
||
|
|
uint8 dec_err = 0;
|
||
|
|
uint32 arg = 0;
|
||
|
|
uint32 arg2 = 0;
|
||
|
|
int8_t loop;
|
||
|
|
struct hgjpg *jpg_hw;// = (struct hgjpg*)p_jpg;
|
||
|
|
struct hgjpg_hw *hw;// = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
jpgr = *(volatile uint32_t*)0x40005200; //fix jpg reg error bug,imp
|
||
|
|
uint8_t src_from;
|
||
|
|
if(p_jpg_global[0]){
|
||
|
|
jpg_hw = (struct hgjpg*)p_jpg_global[0];
|
||
|
|
hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
sta = (hw->DMA_STA & ((hw->DMA_CON >> 13) &0x01f));
|
||
|
|
src_from = (hw->DMA_CON& 0xE0)>>5;
|
||
|
|
for(loop = JPG_IRQ_NUM-1;loop >= 0;loop--) {
|
||
|
|
if(sta&BIT(loop)){
|
||
|
|
if(jpg_hw->opened)
|
||
|
|
{
|
||
|
|
if(loop == DONE_IRQ){
|
||
|
|
//_os_printf("--(%d)",SCHED->BW_STA_CNT);
|
||
|
|
jpg_hw->addr_count = 0;
|
||
|
|
arg = hw->DMA_DLEN;
|
||
|
|
if(jpg_hw->deal_time != ((hw->DMA_STA>>16)&0xff)){
|
||
|
|
arg2 = 1;
|
||
|
|
}
|
||
|
|
jpg_hw->deal_time = 0;
|
||
|
|
}
|
||
|
|
else if(loop == JPG_BUF_ERR){
|
||
|
|
_os_printf(KERN_INFO"hw->DMA_STA0:%x\r\n",hw->DMA_STA);
|
||
|
|
jpg_hw->addr_count = 0;
|
||
|
|
arg = hw->DMA_DLEN;
|
||
|
|
jpg_hw->deal_time = 0;
|
||
|
|
}else if(loop == JPG_OUTBUF_FULL){
|
||
|
|
jpg_hw->deal_time++;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(isp_ov_err && (jpg_hw->decode== 0 && (src_from == 0 || src_from == 1 || src_from == 3))){
|
||
|
|
if(loop == DONE_IRQ){
|
||
|
|
jpgirq_vector_table[0][JPG_BUF_ERR] (loop,(uint32)jpgirq_dev_table[0][JPG_BUF_ERR],arg,arg2);
|
||
|
|
jpg_err = 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//如果有错,就不再继续执行其他的中断
|
||
|
|
if(jpg_err==0 && jpgirq_vector_table[0][loop] != NULL)
|
||
|
|
jpgirq_vector_table[0][loop] (loop,(uint32)jpgirq_dev_table[0][loop],arg,arg2);
|
||
|
|
|
||
|
|
if(loop == JPG_BUF_ERR)
|
||
|
|
{
|
||
|
|
jpg_err = 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
hw->DMA_STA = BIT(loop);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if(p_jpg_global[1]){
|
||
|
|
jpg_hw = (struct hgjpg*)p_jpg_global[1];
|
||
|
|
hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
sta = (hw->DMA_STA & ((hw->DMA_CON >> 13) &0x1f));
|
||
|
|
src_from = (hw->DMA_CON& 0xE0)>>5;
|
||
|
|
for(loop = JPG_IRQ_NUM-1;loop >= 0;loop--) {
|
||
|
|
if(sta&BIT(loop)){
|
||
|
|
if(jpg_hw->opened || jpg_hw->decode)
|
||
|
|
{
|
||
|
|
if(loop == DONE_IRQ){
|
||
|
|
jpg_hw->addr_count = 0;
|
||
|
|
arg = hw->DMA_DLEN;
|
||
|
|
if(jpg_hw->deal_time != ((hw->DMA_STA>>16)&0xff)){
|
||
|
|
arg2 = 1;
|
||
|
|
}
|
||
|
|
jpg_hw->deal_time = 0;
|
||
|
|
jpg_hw->decode = 0;
|
||
|
|
}
|
||
|
|
else if(loop == JPG_BUF_ERR){
|
||
|
|
_os_printf(KERN_INFO"hw->DMA_STA1:%x\r\n",hw->DMA_STA);
|
||
|
|
jpg_hw->addr_count = 0;
|
||
|
|
arg = hw->DMA_DLEN;
|
||
|
|
jpg_hw->deal_time = 0;
|
||
|
|
jpg_hw->decode = 0;
|
||
|
|
if(hw->DMA_STA & BIT(8)){
|
||
|
|
dec_err = 1;
|
||
|
|
}
|
||
|
|
}else if(loop == JPG_OUTBUF_FULL){
|
||
|
|
jpg_hw->deal_time++;
|
||
|
|
}
|
||
|
|
if(isp_ov_err && (jpg_hw->decode== 0 && (src_from == 0 || src_from == 1 || src_from == 3))){
|
||
|
|
if(loop == DONE_IRQ){
|
||
|
|
jpgirq_vector_table[1][JPG_BUF_ERR] (loop,(uint32)jpgirq_dev_table[1][JPG_BUF_ERR],arg,arg2);
|
||
|
|
jpg_err = 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if(jpgirq_vector_table[1][loop] != NULL)
|
||
|
|
jpgirq_vector_table[1][loop] (loop,(uint32)jpgirq_dev_table[1][loop],arg,arg2);
|
||
|
|
|
||
|
|
|
||
|
|
if(dec_err == 1){
|
||
|
|
jpg_hw->decode = 0;
|
||
|
|
hw->DMA_CON |= BIT(12); //复位
|
||
|
|
__NOP();__NOP();__NOP();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
hw->DMA_STA = BIT(loop);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
int32 hgjpg_set_len(struct jpg_device *p_jpg,uint32 buflen,uint32 head_reserver){
|
||
|
|
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||
|
|
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
hw->DMA_CON |= ((buflen - head_reserver)<<16);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
void jpg_table_init(struct hgjpg_hw *p_jpg,struct hgjpg_table_hw* p_jpg_dqt,struct hgjpg_huff_hw *p_jpg_huff,uint32 table_index){
|
||
|
|
uint32 itk = 0;
|
||
|
|
uint32 *ptable;
|
||
|
|
ptable = (uint32*)quality_tab[table_index];
|
||
|
|
for(itk = 0;itk <32;itk++){
|
||
|
|
p_jpg_dqt->DQT[itk] = ptable[itk];
|
||
|
|
}
|
||
|
|
#if 0
|
||
|
|
uint16 *huftbl;
|
||
|
|
huftbl = (uint16_t*)htable;
|
||
|
|
for(itk = 0;itk <384;itk=itk+2){
|
||
|
|
p_jpg_huff->HUFF[itk/2] = (uint32)huftbl[itk]|(uint32)huftbl[itk+1]<<12;
|
||
|
|
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
p_jpg->DMA_DHT_ADR = (uint32)dhtable;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void jpg_huff_init(struct hgjpg* jpg)
|
||
|
|
{
|
||
|
|
struct hgjpg_huff_hw *p_jpg_huff = (struct hgjpg_huff_hw *)jpg->huf_hw;
|
||
|
|
uint32 itk = 0;
|
||
|
|
uint16 *huftbl;
|
||
|
|
huftbl = (uint16_t*)htable;
|
||
|
|
for(itk = 0;itk <384;itk=itk+2)
|
||
|
|
{
|
||
|
|
p_jpg_huff->HUFF[itk/2] = (uint32)huftbl[itk]|(uint32)huftbl[itk+1]<<12;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void jpg_csr_encode_config(struct hgjpg_hw *p_jpg,uint32 image_h,uint32 image_w){
|
||
|
|
p_jpg->CSR1 = (image_h<<16)|BIT(2)|BIT(8);
|
||
|
|
if((image_h%16) != 0)
|
||
|
|
image_h = ((image_h/16)+1)*16;
|
||
|
|
p_jpg->CSR2 = ((image_h * image_w) /256)-1;
|
||
|
|
p_jpg->CSR3 = (image_w<<16)|(image_w/16 - 1);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int32 hgjpg_open(struct jpg_device *p_jpg){
|
||
|
|
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||
|
|
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
uint8 jpg_chose;
|
||
|
|
|
||
|
|
//fix psram read data lock bug
|
||
|
|
//burst enable 0
|
||
|
|
//1ms
|
||
|
|
//burst enable 1
|
||
|
|
if(hw == (void *)MJPEG0_BASE){
|
||
|
|
jpg_chose = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(hw == (void *)MJPEG1_BASE){
|
||
|
|
jpg_chose = 1;
|
||
|
|
//hw->CSR1 = 0;
|
||
|
|
uint32_t jpgr = *(volatile uint32_t*)0x40005200; //fix jpg reg error bug,imp
|
||
|
|
(void)jpgr;
|
||
|
|
}
|
||
|
|
|
||
|
|
//SCHED->BW_STA_CYCLE = 60000000;
|
||
|
|
//SCHED->CTRL_CON |=BIT(1);
|
||
|
|
//open之前先将pending清除(预防之前pengding有残留)
|
||
|
|
hw->DMA_STA = hw->DMA_STA;
|
||
|
|
jpg_hw->decode = 0;
|
||
|
|
jpg_hw->opened = 1;
|
||
|
|
jpg_ready[jpg_chose] = 1;
|
||
|
|
hw->DMA_CON |= BIT(0); //enable jpg
|
||
|
|
hw->DMA_CON1 |= BIT(5);
|
||
|
|
//hw->CSR0 = 1;
|
||
|
|
irq_enable(jpg_hw->irq_num);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int32_t hgjpg_timer_close(void *arg,uint32_t kick_time)
|
||
|
|
{
|
||
|
|
struct hgjpg *jpg_hw = (struct hgjpg*)arg;
|
||
|
|
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
int32_t ret = 1;
|
||
|
|
//代表jpg已经完成
|
||
|
|
if(!(hw->DMA_STA&(0x7<<25)))
|
||
|
|
{
|
||
|
|
ret = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
//超时也要退出
|
||
|
|
if(os_jiffies() - kick_time > 1000)
|
||
|
|
{
|
||
|
|
ret = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
//关闭jpg
|
||
|
|
if(!ret)
|
||
|
|
{
|
||
|
|
uint8_t jpg_chose = 0;
|
||
|
|
uint32_t flag;
|
||
|
|
flag = disable_irq();
|
||
|
|
hw->DMA_CON &= ~(7<<5);
|
||
|
|
hw->DMA_CON |= (SOFT_DATA <<5);
|
||
|
|
if(hw == (void *)MJPEG0_BASE){
|
||
|
|
jpg_chose = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(hw == (void *)MJPEG1_BASE){
|
||
|
|
jpg_chose = 1;
|
||
|
|
}
|
||
|
|
enable_irq(flag);
|
||
|
|
|
||
|
|
|
||
|
|
flag = disable_irq();
|
||
|
|
hw->DMA_CON &= ~BIT(0); //disable jpg
|
||
|
|
hw->DMA_STA = hw->DMA_STA;
|
||
|
|
if(hw == (void *)MJPEG0_BASE){
|
||
|
|
jpg_chose = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(hw == (void *)MJPEG1_BASE){
|
||
|
|
jpg_chose = 1;
|
||
|
|
hw->CSR1 = 0;
|
||
|
|
uint32_t jpgr = *(volatile uint32_t*)0x40005200; //fix jpg reg error bug,imp
|
||
|
|
(void)jpgr;
|
||
|
|
}
|
||
|
|
jpg_ready[jpg_chose] = 0;
|
||
|
|
enable_irq(flag);
|
||
|
|
jpg_hw->opened = 0;
|
||
|
|
jpg_hw->decode = 0;
|
||
|
|
jpg_hw->addr_count = 0;
|
||
|
|
jpg_hw->jpg_run = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
int32 hgjpg_close(struct jpg_device *p_jpg){
|
||
|
|
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||
|
|
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
uint8_t jpg_chose = 0;
|
||
|
|
uint32_t flag;
|
||
|
|
uint32_t in_disable_irq(void);
|
||
|
|
if(!(__in_interrupt() || in_disable_irq()))
|
||
|
|
{
|
||
|
|
//在线程,jpg的close启动timer去操作
|
||
|
|
driver_timer_add(hgjpg_timer_close,(void*)jpg_hw);
|
||
|
|
}
|
||
|
|
//在中断,则直接去关闭
|
||
|
|
else
|
||
|
|
{
|
||
|
|
hw->DMA_CON &= ~(7<<5);
|
||
|
|
hw->DMA_CON |= (SOFT_DATA <<5);
|
||
|
|
if(hw == (void *)MJPEG0_BASE){
|
||
|
|
jpg_chose = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(hw == (void *)MJPEG1_BASE){
|
||
|
|
jpg_chose = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
flag = disable_irq();
|
||
|
|
hw->DMA_CON &= ~BIT(0); //disable jpg
|
||
|
|
hw->DMA_STA = hw->DMA_STA;
|
||
|
|
if(hw == (void *)MJPEG0_BASE){
|
||
|
|
jpg_chose = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(hw == (void *)MJPEG1_BASE){
|
||
|
|
jpg_chose = 1;
|
||
|
|
//hw->CSR1 = 0;
|
||
|
|
uint32_t jpgr = *(volatile uint32_t*)0x40005200; //fix jpg reg error bug,imp
|
||
|
|
(void)jpgr;
|
||
|
|
}
|
||
|
|
jpg_ready[jpg_chose] = 0;
|
||
|
|
enable_irq(flag);
|
||
|
|
jpg_hw->opened = 0;
|
||
|
|
jpg_hw->decode = 0;
|
||
|
|
jpg_hw->addr_count = 0;
|
||
|
|
jpg_hw->jpg_run = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int32 hgjpg_suspend(struct dev_obj *obj){
|
||
|
|
struct hgjpg *jpg_hw = (struct hgjpg*)obj;
|
||
|
|
struct hgjpg_hw *hw;
|
||
|
|
struct hgjpg_hw *hw_cfg;
|
||
|
|
jpg_hw->cfg_backup = (uint32 *)os_malloc(sizeof(struct hgjpg_hw));
|
||
|
|
//memcpy((uint8 *)p_jpg->cfg_backup,(uint8 *)jpg_hw->hw,sizeof(struct hgjpg_hw));
|
||
|
|
hw_cfg = (struct hgjpg_hw*)jpg_hw->cfg_backup;
|
||
|
|
hw = (struct hgjpg_hw*)jpg_hw->hw;
|
||
|
|
hw_cfg->CSR0 = hw->CSR0;
|
||
|
|
hw_cfg->CSR1 = hw->CSR1;
|
||
|
|
hw_cfg->CSR2 = hw->CSR2;
|
||
|
|
hw_cfg->CSR3 = hw->CSR3;
|
||
|
|
hw_cfg->DMA_CON1= hw->DMA_CON1;
|
||
|
|
hw_cfg->DMA_STA = hw->DMA_STA;
|
||
|
|
hw_cfg->DMA_DHT_ADR = hw->DMA_DHT_ADR;
|
||
|
|
hw_cfg->DMA_DADR= hw->DMA_DADR;
|
||
|
|
hw_cfg->DMA_DTO = hw->DMA_DTO;
|
||
|
|
hw_cfg->DMA_SF_YADR = hw->DMA_SF_YADR;
|
||
|
|
hw_cfg->DMA_SF_UADR = hw->DMA_SF_UADR;
|
||
|
|
hw_cfg->DMA_SF_VADR = hw->DMA_SF_VADR;
|
||
|
|
hw_cfg->DMA_TADR0 = hw->DMA_TADR0;
|
||
|
|
hw_cfg->DMA_TADR1 = hw->DMA_TADR1;
|
||
|
|
hw_cfg->DMA_DLEN = hw->DMA_DLEN;
|
||
|
|
hw_cfg->DMA_CON = hw->DMA_CON;
|
||
|
|
irq_disable(jpg_hw->irq_num);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int32 hgjpg_resume(struct dev_obj *obj){
|
||
|
|
uint32 jpgr = 0;
|
||
|
|
struct hgjpg *jpg_hw = (struct hgjpg*)obj;
|
||
|
|
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
struct hgjpg_hw *hw_cfg;
|
||
|
|
struct hgjpg_table_hw *thw = (struct hgjpg_table_hw *)jpg_hw->thw;
|
||
|
|
struct hgjpg_huff_hw *hufhw = (struct hgjpg_huff_hw *)jpg_hw->huf_hw;
|
||
|
|
//memcpy((uint8 *)jpg_hw->hw,(uint8 *)p_jpg->cfg_backup,sizeof(struct hgjpg_hw));
|
||
|
|
|
||
|
|
|
||
|
|
// SCHED->BW_STA_CYCLE = SYS_CLK;
|
||
|
|
SYSCTRL->CPU1_CON1 &= ~BIT(17);
|
||
|
|
// SCHED->CTRL_CON |=BIT(1);
|
||
|
|
SYSCTRL->SYS_CON8 |= BIT(8); //960M enable
|
||
|
|
SYSCTRL->SYS_CON14 &= ~(7<<29);
|
||
|
|
SYSCTRL->SYS_CON14 |= (6<<29); //mjpeg_pll2x_divnp5 div 3
|
||
|
|
SYSCTRL->SYS_CON14 |= BIT(28); //mjpeg_pll2x_divnp5 en
|
||
|
|
SYSCTRL->CLK_CON6 &= ~(3<<30);
|
||
|
|
SYSCTRL->CLK_CON6 |= (1<<30); //select mjpeg_pll2x_divnp5
|
||
|
|
SYSCTRL->CLK_CON6 &= (~(7<<0)); //mjpeg 1div
|
||
|
|
SYSCTRL->CPU1_CON0 |= BIT(0);
|
||
|
|
SYSCTRL->CLK_CON3 |= BIT(14); //mjpg0 clk en
|
||
|
|
SYSCTRL->CLK_CON4 |= BIT(0); //mjpg1 clk en
|
||
|
|
SYSCTRL->SYS_CON7 &= ~BIT(10);
|
||
|
|
SYSCTRL->SYS_CON7 |= BIT(10); //JPG0
|
||
|
|
SYSCTRL->SYS_CON7 &= ~BIT(20);
|
||
|
|
SYSCTRL->SYS_CON7 |= BIT(20); //JPG1
|
||
|
|
jpgr = *(volatile uint32_t*)0x40005200; //fix jpg reg error bug,imp
|
||
|
|
|
||
|
|
|
||
|
|
hw_cfg = (struct hgjpg_hw*)jpg_hw->cfg_backup;
|
||
|
|
jpg_table_init(hw,thw,hufhw,0x01);
|
||
|
|
hw->CSR0 = hw_cfg->CSR0;
|
||
|
|
hw->CSR1 = hw_cfg->CSR1;
|
||
|
|
hw->CSR2 = hw_cfg->CSR2;
|
||
|
|
hw->CSR3 = hw_cfg->CSR3;
|
||
|
|
hw->DMA_CON1= hw_cfg->DMA_CON1;
|
||
|
|
hw->DMA_STA = hw_cfg->DMA_STA;
|
||
|
|
hw->DMA_DHT_ADR = hw_cfg->DMA_DHT_ADR;
|
||
|
|
hw->DMA_DADR= hw_cfg->DMA_DADR;
|
||
|
|
hw->DMA_DTO = hw_cfg->DMA_DTO;
|
||
|
|
hw->DMA_SF_YADR = hw_cfg->DMA_SF_YADR;
|
||
|
|
hw->DMA_SF_UADR = hw_cfg->DMA_SF_UADR;
|
||
|
|
hw->DMA_SF_VADR = hw_cfg->DMA_SF_VADR;
|
||
|
|
hw->DMA_TADR0 = hw_cfg->DMA_TADR0;
|
||
|
|
hw->DMA_TADR1 = hw_cfg->DMA_TADR1;
|
||
|
|
hw->DMA_DLEN = hw_cfg->DMA_DLEN;
|
||
|
|
hw->DMA_CON = hw_cfg->DMA_CON;
|
||
|
|
jpgr = *(volatile uint32_t*)0x40005200;
|
||
|
|
irq_enable(jpg_hw->irq_num);
|
||
|
|
os_free(jpg_hw->cfg_backup);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int32 hgjpg_init(struct jpg_device *p_jpg,uint32 table_index,uint32 qt){
|
||
|
|
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||
|
|
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
struct hgjpg_table_hw *thw = (struct hgjpg_table_hw *)jpg_hw->thw;
|
||
|
|
struct hgjpg_huff_hw *hufhw = (struct hgjpg_huff_hw *)jpg_hw->huf_hw;
|
||
|
|
hw->DMA_CON |= BIT(12); //复位
|
||
|
|
__NOP();__NOP();__NOP();
|
||
|
|
SYSCTRL->CLK_CON3 |= BIT(14);
|
||
|
|
SYSCTRL->SYS_CON0 |= BIT(2); //
|
||
|
|
jpg_table_init(hw,thw,hufhw,table_index);
|
||
|
|
hw->DMA_CON = (qt<<1);
|
||
|
|
jpg_hw->addr_count = 0;
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int32 hgjpg_set_addr(struct jpg_device *p_jpg,uint32 param,uint32 buflen){
|
||
|
|
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||
|
|
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
uint8 jpg_chose;
|
||
|
|
if(hw == (void *)MJPEG0_BASE){
|
||
|
|
jpg_chose = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(hw == (void *)MJPEG1_BASE){
|
||
|
|
jpg_chose = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(jpg_hw->jpg_run == 0){
|
||
|
|
//printf("#################hw:%X\n",hw);
|
||
|
|
//os_printf("jpg_hw->addr_count:%d\n",jpg_hw->addr_count);
|
||
|
|
//os_printf("jpg_ready[jpg_chose]:%d\t%d\n",jpg_ready[jpg_chose],jpg_chose);
|
||
|
|
//os_printf("jpg_chose:%d\n",jpg_chose);
|
||
|
|
jpg_hw->jpg_run = 1;
|
||
|
|
jpg_hw->set_buf_len = 1;
|
||
|
|
|
||
|
|
}
|
||
|
|
if(jpg_hw->addr_count%2){
|
||
|
|
hw->DMA_TADR1 = param;
|
||
|
|
}else{
|
||
|
|
if(jpg_ready[jpg_chose]){
|
||
|
|
|
||
|
|
hw->DMA_TADR0 = param;
|
||
|
|
//hw->DMA_CON1 &= ~BIT(5);
|
||
|
|
hw->DMA_CON1 |= BIT(5);
|
||
|
|
jpg_ready[jpg_chose] = 0;
|
||
|
|
}else{
|
||
|
|
hw->DMA_TADR0 = param;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if(jpg_hw->set_buf_len){
|
||
|
|
hw->DMA_CON |= ((buflen/4-1)<<20);
|
||
|
|
jpg_hw->set_buf_len = 0;
|
||
|
|
}
|
||
|
|
jpg_hw->addr_count++;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
//decode to scaler
|
||
|
|
int32 hgjpg_decode(struct jpg_device *p_jpg,uint32 photo,uint32_t len){
|
||
|
|
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||
|
|
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
if(hw->DMA_CON & BIT(0)){
|
||
|
|
hw->DMA_CON &= ~BIT(0);
|
||
|
|
}
|
||
|
|
hw->DMA_CON &= ~(7<<5);
|
||
|
|
hw->DMA_CON |= BIT(12); //复位
|
||
|
|
__NOP();__NOP();__NOP();
|
||
|
|
//hw->DMA_CON &= ~BIT(12);
|
||
|
|
hw->CSR1 = BIT(3)|BIT(8);
|
||
|
|
hw->DMA_DADR = photo;
|
||
|
|
jpg_hw->decode = 1;
|
||
|
|
|
||
|
|
if (len % 4) {
|
||
|
|
len = len + 4;
|
||
|
|
}
|
||
|
|
|
||
|
|
//寄存器检查仅仅支持1M以下
|
||
|
|
if(len != 0 && len < 0x100000){
|
||
|
|
hw->DMA_DLEN = len; //需要word对齐
|
||
|
|
hw->DMA_CON1 |= BIT(1);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
hw->DMA_CON1 &= ~BIT(1);
|
||
|
|
}
|
||
|
|
hw->DMA_CON &= ~(0xf<<1);
|
||
|
|
hw->DMA_CON |= BIT(4);
|
||
|
|
hw->DMA_CON |= BIT(0);
|
||
|
|
irq_enable(jpg_hw->irq_num);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int32 hgjpg_ioctl(struct jpg_device *p_jpg,uint32 cmd,uint32 param1,uint32 param2){
|
||
|
|
int32 ret_val = RET_OK;
|
||
|
|
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||
|
|
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
struct hgjpg_table_hw *thw = (struct hgjpg_table_hw *)jpg_hw->thw;
|
||
|
|
uint8 jpg_chose;
|
||
|
|
uint32* dqt;
|
||
|
|
uint32 itk;
|
||
|
|
|
||
|
|
if(hw == (void *)MJPEG0_BASE){
|
||
|
|
jpg_chose = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(hw == (void *)MJPEG1_BASE){
|
||
|
|
jpg_chose = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
switch(cmd){
|
||
|
|
case JPG_IOCTL_CMD_IS_ONLINE:
|
||
|
|
return jpg_hw->opened;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_SET_ADR:
|
||
|
|
hgjpg_set_addr(p_jpg,param1,param2);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_SET_QT:
|
||
|
|
hw->DMA_CON &= ~(0xf<<1);
|
||
|
|
hw->DMA_CON |= (param1<<1);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_SET_SIZE:
|
||
|
|
jpg_csr_encode_config(hw,param1,param2);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_UPDATE_QT:
|
||
|
|
dqt = (uint32*)param1;
|
||
|
|
for(itk = 0;itk <32;itk++){
|
||
|
|
thw->DQT[itk] = dqt[itk];
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_DECODE_TAG:
|
||
|
|
if(param1){
|
||
|
|
hw->DMA_CON |= BIT(8);
|
||
|
|
}else{
|
||
|
|
hw->DMA_CON &= ~BIT(8);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
/*
|
||
|
|
case JPG_IOCTL_CMD_OPEN_DBG:
|
||
|
|
if(param1){
|
||
|
|
hw->DMA_CON |= BIT(10);
|
||
|
|
}else{
|
||
|
|
hw->DMA_CON &= ~BIT(10);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
*/
|
||
|
|
case JPG_IOCTL_CMD_SOFT_FRAME_START:
|
||
|
|
hw->DMA_CON |= BIT(10);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_SOFT_KICK:
|
||
|
|
hw->DMA_CON |= BIT(9);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_SET_SRC_FROM:
|
||
|
|
hw->DMA_CON &= ~(7<<5);
|
||
|
|
hw->DMA_CON |= (param1 <<5);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_HW_CHK:
|
||
|
|
if(param1){
|
||
|
|
hw->DMA_CON |= BIT(11);
|
||
|
|
}else{
|
||
|
|
hw->DMA_CON &= ~BIT(11);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_IS_IDLE:
|
||
|
|
if(hw->DMA_STA&(0x7<<25)){
|
||
|
|
ret_val = 0;
|
||
|
|
}else{
|
||
|
|
ret_val = 1;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case JPG_IOCTL_CMD_BUFF_INIT:
|
||
|
|
if(param1 == 1){
|
||
|
|
hw->DMA_CON1 |= BIT(5);
|
||
|
|
}else{
|
||
|
|
hw->DMA_CON1 &= ~BIT(5);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case JPG_IOCTL_CMD_VSYNC_DLY:
|
||
|
|
if(param1 == 1){
|
||
|
|
hw->DMA_CON1 |= BIT(4);
|
||
|
|
}else{
|
||
|
|
hw->DMA_CON1 &= ~BIT(4);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case JPG_IOCTL_CMD_SET_SOFT_Y:
|
||
|
|
hw->DMA_SF_YADR = param1;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_SET_SOFT_UV:
|
||
|
|
hw->DMA_SF_UADR = param1;
|
||
|
|
hw->DMA_SF_VADR = param2;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_TIMEOUT_CNT:
|
||
|
|
hw->DMA_DTO = param1;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_TIMEOUT_EN:
|
||
|
|
hw->DMA_CON1 |= BIT(3);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_DECAUTO_RUN_EN:
|
||
|
|
hw->DMA_CON1 |= BIT(2);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_DEC_LEN_CFG_EN:
|
||
|
|
//SET this bit ,may set the dlen len reg, otherwise while auto dec until finish or timeout err happen
|
||
|
|
if(param1){
|
||
|
|
hw->DMA_CON1 |= BIT(1);
|
||
|
|
}else{
|
||
|
|
hw->DMA_CON1 &= ~BIT(1);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case JPG_IOCTL_CMD_DEC_FLUSH_EN:
|
||
|
|
//set this bit,dec while run ,but not set data to memory,just check dec right or false
|
||
|
|
if(param1){
|
||
|
|
hw->DMA_CON1 |= BIT(0);
|
||
|
|
}else{
|
||
|
|
hw->DMA_CON1 &= ~BIT(0);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_CODEC_RESET:
|
||
|
|
hw->DMA_CON |= BIT(12);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_SET_DLEN:
|
||
|
|
hw->DMA_DLEN = param1;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_SET_READY:
|
||
|
|
jpg_ready[jpg_chose] = 1;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case JPG_IOCTL_CMD_SET_OE_SELECT:
|
||
|
|
if(param1 == 1){
|
||
|
|
jpg_oe_enable[jpg_chose] = 1;
|
||
|
|
jpg_oe_used[jpg_chose] = param2;
|
||
|
|
}else{
|
||
|
|
jpg_oe_enable[jpg_chose] = 0;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case JPG_IOCTL_CMD_SET_OE:
|
||
|
|
jpg_oe_ok[jpg_chose] = param1;
|
||
|
|
break;
|
||
|
|
case JPG_IOCTL_CMD_GET_OE:
|
||
|
|
if(jpg_oe_enable[jpg_chose] == 1){
|
||
|
|
if(jpg_oe_ok[jpg_chose] == jpg_oe_used[jpg_chose]){
|
||
|
|
ret_val = 1;
|
||
|
|
}else{
|
||
|
|
ret_val = 0;
|
||
|
|
}
|
||
|
|
}else{
|
||
|
|
ret_val = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
ret_val = -ENOTSUPP;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
return ret_val;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int32 jpgirq_register(struct jpg_device *p_jpg, jpg_irq_hdl isr,uint32 irq_flag, uint32 irq_data)
|
||
|
|
{
|
||
|
|
uint8 jpg_chose;
|
||
|
|
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||
|
|
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
uint32 irq_num = 0;
|
||
|
|
if(hw == (void *)MJPEG0_BASE){
|
||
|
|
jpg_chose = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(hw == (void *)MJPEG1_BASE){
|
||
|
|
jpg_chose = 1;
|
||
|
|
}
|
||
|
|
p_jpg_global[jpg_chose] = p_jpg;
|
||
|
|
request_irq(MJPEG01_IRQn, JPG_IRQHandler_action, NULL);
|
||
|
|
if(irq_flag == JPG_IRQ_FLAG_JPG_DONE ){
|
||
|
|
irq_num = DONE_IRQ;
|
||
|
|
}else if(irq_flag == JPG_IRQ_FLAG_JPG_BUF_FULL ){
|
||
|
|
irq_num = JPG_OUTBUF_FULL;
|
||
|
|
}else if(irq_flag == JPG_IRQ_FLAG_ERROR ){
|
||
|
|
irq_num = JPG_BUF_ERR;
|
||
|
|
}else if(irq_flag == JPG_IRQ_FLAG_PIXEL_DONE ){
|
||
|
|
irq_num = JPG_PIXEL_DONE;
|
||
|
|
}else if(irq_flag == JPG_IRQ_FLAG_TIME_OUT){
|
||
|
|
irq_num = JPG_TIME_OUT;
|
||
|
|
}
|
||
|
|
irq_jpg_enable(hw, 1, irq_num);
|
||
|
|
|
||
|
|
jpgirq_vector_table[jpg_chose][irq_num] = isr;
|
||
|
|
jpgirq_dev_table[jpg_chose][irq_num] = (void *)irq_data;
|
||
|
|
hw->DMA_STA |= BIT(irq_num);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int32 jpgirq_unregister(struct jpg_device *p_jpg,uint32 irq_flag){
|
||
|
|
uint8 jpg_chose;
|
||
|
|
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||
|
|
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||
|
|
uint32 irq_num = 0;
|
||
|
|
if(hw == (void *)MJPEG0_BASE){
|
||
|
|
jpg_chose = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(hw == (void *)MJPEG1_BASE){
|
||
|
|
jpg_chose = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(irq_flag == JPG_IRQ_FLAG_JPG_DONE ){
|
||
|
|
irq_num = DONE_IRQ;
|
||
|
|
}else if(irq_flag == JPG_IRQ_FLAG_JPG_BUF_FULL ){
|
||
|
|
irq_num = JPG_OUTBUF_FULL;
|
||
|
|
}else if(irq_flag == JPG_IRQ_FLAG_ERROR ){
|
||
|
|
irq_num = JPG_BUF_ERR;
|
||
|
|
}else if(irq_flag == JPG_IRQ_FLAG_PIXEL_DONE ){
|
||
|
|
irq_num = JPG_PIXEL_DONE;
|
||
|
|
}else if(irq_flag == JPG_IRQ_FLAG_TIME_OUT){
|
||
|
|
irq_num = JPG_TIME_OUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
irq_jpg_enable(hw, 0, irq_num);
|
||
|
|
jpgirq_vector_table[jpg_chose][irq_num] = NULL;
|
||
|
|
jpgirq_dev_table[jpg_chose][irq_num] = NULL;
|
||
|
|
hw->DMA_STA |= BIT(irq_num);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static const struct jpeg_hal_ops jpeg_ops = {
|
||
|
|
.open = hgjpg_open,
|
||
|
|
.close = hgjpg_close,
|
||
|
|
.init = hgjpg_init,
|
||
|
|
.decode = hgjpg_decode,
|
||
|
|
.ioctl = hgjpg_ioctl,
|
||
|
|
.request_irq = jpgirq_register,
|
||
|
|
.release_irq = jpgirq_unregister,
|
||
|
|
#ifdef CONFIG_SLEEP
|
||
|
|
.ops.suspend = hgjpg_suspend,
|
||
|
|
.ops.resume = hgjpg_resume,
|
||
|
|
#endif
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
void hgjpg_attach(uint32 dev_id, struct hgjpg *jpg)
|
||
|
|
{
|
||
|
|
jpg->dev.dev.ops = (const struct devobj_ops *)&jpeg_ops;
|
||
|
|
irq_disable(jpg->irq_num);
|
||
|
|
dev_register(dev_id, (struct dev_obj *)jpg);
|
||
|
|
jpg_huff_init(jpg);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|