Merge branch 'develop-3.0-rk2928' of ssh://10.10.10.29/rk/kernel into develop-3.0-rk2928

This commit is contained in:
gwl
2012-08-17 15:10:51 +08:00
8 changed files with 583 additions and 293 deletions

View File

@@ -4,7 +4,7 @@
#include <plat/sram.h>
#define SRAM_LOOPS_PER_USEC 24
#define SRAM_LOOP(loops) do { unsigned int i = (loops); if (i < 7) i = 7; barrier(); while (--i) barrier(); } while (0)
#define SRAM_LOOP(loops) do { unsigned int i = (loops); if (i < 7) i = 7; barrier(); asm volatile(".align 4; 1: subs %0, %0, #1; bne 1b;" : "+r" (i)); } while (0)
/* delay on slow mode */
#define sram_udelay(usecs) SRAM_LOOP((usecs)*SRAM_LOOPS_PER_USEC)
/* delay on deep slow mode */

View File

@@ -14,13 +14,47 @@
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/gic.h>
#include <mach/pmu.h>
#include <mach/board.h>
#include <mach/system.h>
#include <mach/sram.h>
#include <mach/gpio.h>
#include <mach/iomux.h>
#include <mach/cru.h>
#define cru_readl(offset) readl_relaxed(RK2928_CRU_BASE + offset)
#define cru_writel(v, offset) do { writel_relaxed(v, RK2928_CRU_BASE + offset); dsb(); } while (0)
#define grf_readl(offset) readl_relaxed(RK2928_GRF_BASE + offset)
#define grf_writel(v, offset) do { writel_relaxed(v, RK2928_GRF_BASE + offset); dsb(); } while (0)
#define gate_save_soc_clk(val, _save, cons, w_msk) \
do { \
(_save) = cru_readl(cons); \
cru_writel(((~(val) | (_save)) & (w_msk)) | ((w_msk) << 16), cons); \
} while (0)
void __sramfunc sram_printch(char byte)
{
#ifdef DEBUG_UART_BASE
u32 clk_gate2, clk_gate4, clk_gate8;
gate_save_soc_clk(0
| (1 << CLK_GATE_ACLK_PERIPH % 16)
| (1 << CLK_GATE_HCLK_PERIPH % 16)
| (1 << CLK_GATE_PCLK_PERIPH % 16)
, clk_gate2, CRU_CLKGATES_CON(2), 0
| (1 << ((CLK_GATE_ACLK_PERIPH % 16) + 16))
| (1 << ((CLK_GATE_HCLK_PERIPH % 16) + 16))
| (1 << ((CLK_GATE_PCLK_PERIPH % 16) + 16)));
gate_save_soc_clk((1 << CLK_GATE_ACLK_CPU_PERI % 16)
, clk_gate4, CRU_CLKGATES_CON(4),
(1 << ((CLK_GATE_ACLK_CPU_PERI % 16) + 16)));
gate_save_soc_clk((1 << ((CLK_GATE_PCLK_UART0 + CONFIG_RK_DEBUG_UART) % 16)),
clk_gate8, CRU_CLKGATES_CON(8),
(1 << (((CLK_GATE_PCLK_UART0 + CONFIG_RK_DEBUG_UART) % 16) + 16)));
sram_udelay(1);
writel_relaxed(byte, DEBUG_UART_BASE);
dsb();
@@ -28,8 +62,427 @@ void __sramfunc sram_printch(char byte)
while (!(readl_relaxed(DEBUG_UART_BASE + 0x14) & 0x40))
barrier();
cru_writel(0xffff0000 | clk_gate2, CRU_CLKGATES_CON(2));
cru_writel(0xffff0000 | clk_gate4, CRU_CLKGATES_CON(4));
cru_writel(0xffff0000 | clk_gate8, CRU_CLKGATES_CON(8));
if (byte == '\n')
sram_printch('\r');
#endif
}
__weak void __sramfunc ddr_suspend(void) {}
__weak void __sramfunc ddr_resume(void) {}
__weak uint32_t __sramfunc ddr_change_freq(uint32_t nMHz) { return nMHz; }
#ifdef CONFIG_DDR_TEST
static int ddr_debug=0;
module_param(ddr_debug, int, 0644);
static int inline calc_crc32(u32 addr, size_t len)
{
return crc32_le(~0, (const unsigned char *)addr, len);
}
static void ddr_testmode(void)
{
int32_t g_crc1, g_crc2;
uint32_t nMHz;
uint32_t n = 0;
uint32_t min,max;
extern char _stext[], _etext[];
if (ddr_debug == 1) {
max=500;
min=100;
for (;;) {
sram_printascii("\n change freq:");
g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
do
{
nMHz = min + random32();
nMHz %= max;
}while(nMHz < min);
sram_printhex(nMHz);
sram_printch(' ');
nMHz = ddr_change_freq(nMHz);
sram_printhex(n++);
sram_printch(' ');
g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
if (g_crc1!=g_crc2) {
sram_printascii("fail\n");
}
//ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
// sram_printascii("change freq success\n");
}
} else if(ddr_debug == 2) {
for (;;) {
sram_printch(' ');
sram_printch('9');
sram_printch('9');
sram_printch('9');
sram_printch(' ');
g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
nMHz = (random32()>>13);// 16.7s max
ddr_suspend();
sram_udelay(nMHz);
ddr_resume();
sram_printhex(nMHz);
sram_printch(' ');
sram_printhex(n++);
g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
if (g_crc1 != g_crc2) {
sram_printch(' ');
sram_printch('f');
sram_printch('a');
sram_printch('i');
sram_printch('l');
}
// ddr_print("check image crc32 fail!, count:%d\n", n++);
// sram_printascii("self refresh fail\n");
//else
//ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
// sram_printascii("self refresh success\n");
}
} else if (ddr_debug == 3) {
extern int memtester(void);
memtester();
}
else
{
ddr_change_freq(ddr_debug);
ddr_debug=0;
}
}
#else
static void ddr_testmode(void) {}
#endif
static noinline void rk2928_pm_dump_irq(void)
{
u32 irq_gpio = (readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + (IRQ_GPIO0 / 32) * 4) >> (IRQ_GPIO0 % 32)) & 0xF;
printk("wakeup irq: %08x %08x %08x\n",
readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + 4),
readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + 8),
readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + 12));
if (irq_gpio & 1)
printk("wakeup gpio0: %08x\n", readl_relaxed(RK2928_GPIO0_BASE + GPIO_INT_STATUS));
if (irq_gpio & 2)
printk("wakeup gpio1: %08x\n", readl_relaxed(RK2928_GPIO1_BASE + GPIO_INT_STATUS));
if (irq_gpio & 4)
printk("wakeup gpio2: %08x\n", readl_relaxed(RK2928_GPIO2_BASE + GPIO_INT_STATUS));
if (irq_gpio & 8)
printk("wakeup gpio3: %08x\n", readl_relaxed(RK2928_GPIO3_BASE + GPIO_INT_STATUS));
}
#define DUMP_GPIO_INTEN(ID) \
do { \
u32 en = readl_relaxed(RK2928_GPIO##ID##_BASE + GPIO_INTEN); \
if (en) { \
sram_printascii("GPIO" #ID "_INTEN: "); \
sram_printhex(en); \
sram_printch('\n'); \
} \
} while (0)
static noinline void rk2928_pm_dump_inten(void)
{
DUMP_GPIO_INTEN(0);
DUMP_GPIO_INTEN(1);
DUMP_GPIO_INTEN(2);
DUMP_GPIO_INTEN(3);
}
static void pm_pll_wait_lock(int pll_idx)
{
u32 pll_state[4] = { 1, 0, 2, 3 };
u32 bit = 0x10u << pll_state[pll_idx];
u32 delay = pll_idx == APLL_ID ? 24000000U : 2400000000U;
while (delay > 0) {
if (grf_readl(GRF_SOC_STATUS0) & bit)
break;
delay--;
}
if (delay == 0) {
//CRU_PRINTK_ERR("wait pll bit 0x%x time out!\n", bit);
sram_printch('p');
sram_printch('l');
sram_printch('l');
sram_printhex(pll_idx);
sram_printch('\n');
}
}
#define power_on_pll(id) \
cru_writel(PLL_PWR_DN_W_MSK|PLL_PWR_ON,PLL_CONS((id),3));\
pm_pll_wait_lock((id))
#define DDR_SAVE_SP(save_sp) do { save_sp = ddr_save_sp(((unsigned long)SRAM_DATA_END & (~7))); } while (0)
#define DDR_RESTORE_SP(save_sp) do { ddr_save_sp(save_sp); } while (0)
static unsigned long save_sp;
static noinline void interface_ctr_reg_pread(void)
{
u32 addr;
flush_cache_all();
outer_flush_all();
local_flush_tlb_all();
for (addr = (u32)SRAM_CODE_OFFSET; addr < (u32)SRAM_DATA_END; addr += PAGE_SIZE)
readl_relaxed(addr);
readl_relaxed(RK2928_GRF_BASE);
readl_relaxed(RK2928_DDR_PCTL_BASE);
readl_relaxed(RK2928_DDR_PHY_BASE);
// readl_relaxed(RK2928_I2C1_BASE);
}
__weak void board_gpio_suspend(void) {}
__weak void board_gpio_resume(void) {}
__weak void __sramfunc board_pmu_suspend(void) {}
__weak void __sramfunc board_pmu_resume(void) {}
__weak void __sramfunc rk30_suspend_voltage_set(unsigned int vol) {}
__weak void __sramfunc rk30_suspend_voltage_resume(unsigned int vol) {}
__weak void rk30_pwm_suspend_voltage_set(void) {}
__weak void rk30_pwm_resume_voltage_set(void) {}
__weak void __sramfunc rk30_pwm_logic_suspend_voltage(void) {}
__weak void __sramfunc rk30_pwm_logic_resume_voltage(void) {}
static void __sramfunc rk2928_sram_suspend(void)
{
u32 cru_clksel0_con;
u32 clkgt_regs[CRU_CLKGATES_CON_CNT];
int i;
sram_printch('5');
ddr_suspend();
sram_printch('6');
rk30_suspend_voltage_set(1000000);
rk30_pwm_logic_suspend_voltage();
sram_printch('7');
for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
clkgt_regs[i] = cru_readl(CRU_CLKGATES_CON(i));
}
gate_save_soc_clk(0
| (1 << CLK_GATE_CORE_PERIPH)
| (1 << CLK_GATE_DDRPHY_SRC)
| (1 << CLK_GATE_ACLK_CPU)
| (1 << CLK_GATE_HCLK_CPU)
| (1 << CLK_GATE_PCLK_CPU)
| (1 << CLK_GATE_ACLK_CORE)
, clkgt_regs[0], CRU_CLKGATES_CON(0), 0xffff);
if (!(clkgt_regs[8] & (0xf << (CLK_GATE_PCLK_GPIO0 % 16)))) {
gate_save_soc_clk(0
| (1 << CLK_GATE_PERIPH_SRC % 16)
| (1 << CLK_GATE_PCLK_PERIPH % 16)
, clkgt_regs[2], CRU_CLKGATES_CON(2), 0xffff);
} else {
gate_save_soc_clk(0, clkgt_regs[2], CRU_CLKGATES_CON(2), 0xffff);
}
gate_save_soc_clk(0
| (1 << CLK_GATE_ACLK_STRC_SYS % 16)
| (1 << CLK_GATE_ACLK_INTMEM % 16)
, clkgt_regs[4], CRU_CLKGATES_CON(4), 0xffff);
gate_save_soc_clk(0
| (1 << CLK_GATE_PCLK_GRF % 16)
| (1 << CLK_GATE_PCLK_DDRUPCTL % 16)
, clkgt_regs[5], CRU_CLKGATES_CON(5), 0xffff);
gate_save_soc_clk(0, clkgt_regs[7], CRU_CLKGATES_CON(7), 0xffff);
gate_save_soc_clk(0
| (1 << CLK_GATE_CLK_L2C % 16)
, clkgt_regs[9], CRU_CLKGATES_CON(9), 0x07ff);
board_pmu_suspend();
cru_clksel0_con = cru_readl(CRU_CLKSELS_CON(0));
cru_writel((0x1f << 16) | 0x1f, CRU_CLKSELS_CON(0));
dsb();
wfi();
cru_writel((0x1f << 16) | cru_clksel0_con, CRU_CLKSELS_CON(0));
board_pmu_resume();
for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
cru_writel(clkgt_regs[i] | 0xffff0000, CRU_CLKGATES_CON(i));
}
sram_printch('7');
rk30_pwm_logic_resume_voltage();
rk30_suspend_voltage_resume(1100000);
sram_printch('6');
ddr_resume();
sram_printch('5');
}
static void noinline rk2928_suspend(void)
{
DDR_SAVE_SP(save_sp);
rk2928_sram_suspend();
DDR_RESTORE_SP(save_sp);
}
static int rk2928_pm_enter(suspend_state_t state)
{
u32 i;
u32 clkgt_regs[CRU_CLKGATES_CON_CNT];
u32 clk_sel0, clk_sel1, clk_sel10;
u32 cru_mode_con;
// dump GPIO INTEN for debug
rk2928_pm_dump_inten();
sram_printch('0');
#ifdef CONFIG_DDR_TEST
// memory tester
if (ddr_debug != 0)
ddr_testmode();
#endif
sram_printch('1');
local_fiq_disable();
for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
clkgt_regs[i] = cru_readl(CRU_CLKGATES_CON(i));
}
gate_save_soc_clk(0
| (1 << CLK_GATE_CORE_PERIPH)
| (1 << CLK_GATE_DDRPHY_SRC)
| (1 << CLK_GATE_ACLK_CPU)
| (1 << CLK_GATE_HCLK_CPU)
| (1 << CLK_GATE_PCLK_CPU)
| (1 << CLK_GATE_ACLK_CORE)
, clkgt_regs[0], CRU_CLKGATES_CON(0), 0xffff);
gate_save_soc_clk(0, clkgt_regs[1], CRU_CLKGATES_CON(1), 0xffff);
gate_save_soc_clk(0
| (1 << CLK_GATE_PERIPH_SRC % 16)
| (1 << CLK_GATE_PCLK_PERIPH % 16)
| (1 << CLK_GATE_ACLK_PERIPH % 16)
, clkgt_regs[2], CRU_CLKGATES_CON(2), 0xffff);
gate_save_soc_clk(0, clkgt_regs[3], CRU_CLKGATES_CON(3), 0xff9f);
gate_save_soc_clk(0
| (1 << CLK_GATE_HCLK_PERI_AXI_MATRIX % 16)
| (1 << CLK_GATE_PCLK_PERI_AXI_MATRIX % 16)
| (1 << CLK_GATE_ACLK_CPU_PERI % 16)
| (1 << CLK_GATE_ACLK_PERI_AXI_MATRIX % 16)
| (1 << CLK_GATE_ACLK_STRC_SYS % 16)
| (1 << CLK_GATE_ACLK_INTMEM % 16)
, clkgt_regs[4], CRU_CLKGATES_CON(4), 0xffff);
gate_save_soc_clk(0
| (1 << CLK_GATE_PCLK_GRF % 16)
| (1 << CLK_GATE_PCLK_DDRUPCTL % 16)
, clkgt_regs[5], CRU_CLKGATES_CON(5), 0xffff);
gate_save_soc_clk(0, clkgt_regs[6], CRU_CLKGATES_CON(6), 0xffff);
gate_save_soc_clk(0
|(1 << CLK_GATE_PCLK_PWM01%16)
, clkgt_regs[7], CRU_CLKGATES_CON(7), 0xffff);
gate_save_soc_clk(0, clkgt_regs[8], CRU_CLKGATES_CON(8), 0x01ff);
gate_save_soc_clk(0
| (1 << CLK_GATE_CLK_L2C % 16)
| (1 << CLK_GATE_HCLK_PERI_ARBI % 16)
| (1 << CLK_GATE_ACLK_PERI_NIU % 16)
, clkgt_regs[9], CRU_CLKGATES_CON(9), 0x07ff);
sram_printch('2');
cru_mode_con = cru_readl(CRU_MODE_CON);
//cpll
cru_writel(PLL_MODE_SLOW(CPLL_ID), CRU_MODE_CON);
//gpll
clk_sel10 = cru_readl(CRU_CLKSELS_CON(10));
cru_writel(PLL_MODE_SLOW(GPLL_ID), CRU_MODE_CON);
cru_writel(PERI_SET_ACLK_DIV(1)
| PERI_SET_A2H_RATIO(RATIO_11)
| PERI_SET_A2P_RATIO(RATIO_11)
, CRU_CLKSELS_CON(10));
//apll
clk_sel0 = cru_readl(CRU_CLKSELS_CON(0));
clk_sel1 = cru_readl(CRU_CLKSELS_CON(1));
cru_writel(PLL_MODE_SLOW(APLL_ID), CRU_MODE_CON);
cru_writel(CLK_CORE_DIV(1) | ACLK_CPU_DIV(1), CRU_CLKSELS_CON(0));
cru_writel(CLK_CORE_PERI_DIV(1) | ACLK_CORE_DIV(1) | HCLK_CPU_DIV(1) | PCLK_CPU_DIV(1), CRU_CLKSELS_CON(1));
sram_printch('3');
rk30_pwm_suspend_voltage_set();
board_gpio_suspend();
interface_ctr_reg_pread();
sram_printch('4');
rk2928_suspend();
sram_printch('4');
board_gpio_resume();
rk30_pwm_resume_voltage_set();
sram_printch('3');
//apll
cru_writel(0xffff0000 | clk_sel1, CRU_CLKSELS_CON(1));
cru_writel(0xffff0000 | clk_sel0, CRU_CLKSELS_CON(0));
cru_writel((PLL_MODE_MSK(APLL_ID) << 16) | (PLL_MODE_MSK(APLL_ID) & cru_mode_con), CRU_MODE_CON);
//gpll
cru_writel(0xffff0000 | clk_sel10, CRU_CLKSELS_CON(10));
cru_writel(clk_sel10, CRU_CLKSELS_CON(10));
cru_writel((PLL_MODE_MSK(GPLL_ID) << 16) | (PLL_MODE_MSK(GPLL_ID) & cru_mode_con), CRU_MODE_CON);
//cpll
cru_writel((PLL_MODE_MSK(CPLL_ID) << 16) | (PLL_MODE_MSK(CPLL_ID) & cru_mode_con), CRU_MODE_CON);
sram_printch('2');
for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
cru_writel(clkgt_regs[i] | 0xffff0000, CRU_CLKGATES_CON(i));
}
local_fiq_enable();
sram_printch('1');
sram_printascii("0\n");
rk2928_pm_dump_irq();
return 0;
}
static int rk2928_pm_prepare(void)
{
/* disable entering idle by disable_hlt() */
disable_hlt();
return 0;
}
static void rk2928_pm_finish(void)
{
enable_hlt();
}
static struct platform_suspend_ops rk2928_pm_ops = {
.enter = rk2928_pm_enter,
.valid = suspend_valid_only_mem,
.prepare = rk2928_pm_prepare,
.finish = rk2928_pm_finish,
};
static int __init rk2928_pm_init(void)
{
suspend_set_ops(&rk2928_pm_ops);
#ifdef CONFIG_EARLYSUSPEND
pm_set_vt_switch(0); /* disable vt switch while suspend */
#endif
return 0;
}
__initcall(rk2928_pm_init);

View File

@@ -318,10 +318,9 @@ static void rk30_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
spin_unlock_irqrestore(&bank->lock, flags);
}
static int rk30_gpiolib_pull_updown(struct gpio_chip *chip, unsigned offset, unsigned enable)
{
#if defined(CONFIG_ARCH_RK30)
#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928)
struct rk30_gpio_bank *bank = to_rk30_gpio_bank(chip);
unsigned long flags;
@@ -335,7 +334,6 @@ static int rk30_gpiolib_pull_updown(struct gpio_chip *chip, unsigned offset, uns
return 0;
}
static int rk30_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset)
{
return chip->base + offset;

View File

@@ -111,7 +111,9 @@ struct rk29_i2c_data {
#endif
};
#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK30)
static struct wake_lock idlelock; /* only for i2c0 */
#endif
static void rk29_set_ack(struct rk29_i2c_data *i2c)
{
@@ -558,8 +560,10 @@ static int rk29_i2c_xfer(struct i2c_adapter *adap,
i2c->udelay_time = RK29_UDELAY_TIME(i2c->scl_rate);
i2c->ack_timeout = RK29_I2C_ACK_TIMEOUT_COUNT * i2c->udelay_time;
#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK30)
if (adap->nr == 0)
wake_lock(&idlelock);
#endif
for (i = 0; i < num; i++)
{
@@ -572,8 +576,10 @@ static int rk29_i2c_xfer(struct i2c_adapter *adap,
}
}
#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK30)
if (adap->nr == 0)
wake_unlock(&idlelock);
#endif
/*
if( --retry && num < 0)
@@ -887,7 +893,9 @@ static struct platform_driver rk29_i2c_driver = {
static int __init rk29_i2c_adap_init(void)
{
#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK30)
wake_lock_init(&idlelock, WAKE_LOCK_IDLE, "i2c0");
#endif
return platform_driver_register(&rk29_i2c_driver);
}

View File

@@ -32,7 +32,7 @@
#define INVALID_ADVALUE 10
#if 1
#if 0
#define key_dbg(bdata, format, arg...) \
dev_printk(KERN_INFO , &bdata->input->dev , format , ## arg)
#else

View File

@@ -57,7 +57,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
printk(KERN_WARNING"rk_camera: " fmt , ## arg); } while (0)
#define RKCAMERA_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
#define RKCAMERA_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
#define RKCAMERA_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)
// CIF Reg Offset
#define CIF_CIF_CTRL 0x00
@@ -227,9 +227,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
*v0.x.b: specify the version is NOT sure stable.
*v0.x.c: 1. add cif reset when resolution changed to avoid of collecting data erro
2. irq process is splitted to two step.
*v0.x.e: fix bugs of early suspend when display_pd is closed.
*v0.x.e: fix bugs of early suspend when display_pd is closed.
*v0.x.f: fix calculate ipp memory size is enough or not in try_fmt function;
*v0.x.11: fix struct rk_camera_work may be reentrant
*/
#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 2, 0xe)
#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 2, 0x11)
/* limit to rk29 hardware capabilities */
#define RK_CAM_BUS_PARAM (SOCAM_MASTER |\
@@ -251,7 +253,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
#define RK_CAM_FRAME_INVAL_INIT 3
#define RK_CAM_FRAME_INVAL_DC 3 /* ddl@rock-chips.com : */
#define RK30_CAM_FRAME_MEASURE 5
extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
@@ -286,6 +287,8 @@ struct rk_camera_work
struct videobuf_buffer *vb;
struct rk_camera_dev *pcdev;
struct work_struct work;
struct list_head queue;
unsigned int index;
};
struct rk_camera_frmivalenum
{
@@ -356,6 +359,8 @@ struct rk_camera_dev
struct rk_camera_reg reginfo_suspend;
struct workqueue_struct *camera_wq;
struct rk_camera_work *camera_work;
struct list_head camera_work_queue;
spinlock_t camera_work_lock;
unsigned int camera_work_count;
struct rk_camera_timer fps_timer;
struct rk_camera_work camera_reinit_work;
@@ -405,6 +410,8 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
icd->current_fmt->host_fmt);
int bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
icd->current_fmt->host_fmt);
unsigned int i;
struct rk_camera_work *wk;
dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
@@ -432,19 +439,21 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
}
if (pcdev->camera_work == NULL) {
int wk_index = 0;
struct rk_camera_work *wk;
pcdev->camera_work = kmalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
if (pcdev->camera_work == NULL) {
RKCAMERA_TR("\n %s kmalloc fail\n", __FUNCTION__);
BUG();
}
for(;wk_index < *count;wk_index++){
wk = pcdev->camera_work+wk_index;
INIT_WORK(&wk->work, rk_camera_capture_process);
}
pcdev->camera_work_count = *count;
INIT_LIST_HEAD(&pcdev->camera_work_queue);
for (i=0; i<(*count); i++) {
wk->index = i;
list_add_tail(&wk->queue, &pcdev->camera_work_queue);
wk++;
}
pcdev->camera_work_count = (*count);
}
}
pcdev->video_vq = vq;
RKCAMERA_DG("%s..%d.. videobuf size:%d, vipmem_buf size:%d, count:%d \n",__FUNCTION__,__LINE__, *size,pcdev->vipmem_size, *count);
@@ -687,6 +696,9 @@ static void rk_camera_capture_process(struct work_struct *work)
do_ipp_err:
up(&pcdev->zoominfo.sem);
wake_up(&(camera_work->vb->done));
spin_lock_irqsave(&pcdev->camera_work_lock, flags);
list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
return;
}
static irqreturn_t rk_camera_irq(int irq, void *data)
@@ -739,7 +751,7 @@ static irqreturn_t rk_camera_irq(int irq, void *data)
if(!vb){
printk("no acticve buffer!!!\n");
goto RK_CAMERA_IRQ_END;
}
}
/* ddl@rock-chips.com : this vb may be deleted from queue */
if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
list_del_init(&vb->queue);
@@ -747,17 +759,10 @@ static irqreturn_t rk_camera_irq(int irq, void *data)
pcdev->active = NULL;
if (!list_empty(&pcdev->capture)) {
pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
if (pcdev->active && (pcdev->active->state == VIDEOBUF_QUEUED)) {
if (pcdev->active) {
WARN_ON(pcdev->active->state != VIDEOBUF_QUEUED);
rk_videobuf_capture(pcdev->active,pcdev);
}
else if(pcdev->active){
RKCAMERA_TR("%s : vb state is wrong ,del it \n",__FUNCTION__);
list_del_init(&(pcdev->active->queue));
pcdev->active->state = VIDEOBUF_NEEDS_INIT;
wake_up(&pcdev->active->done);
pcdev->active = NULL;
}
}
if (pcdev->active == NULL) {
RKCAMERA_DG("%s video_buf queue is empty!\n",__FUNCTION__);
@@ -769,10 +774,14 @@ static irqreturn_t rk_camera_irq(int irq, void *data)
vb->field_count++;
}
if (CAM_WORKQUEUE_IS_EN()) {
wk = pcdev->camera_work + vb->i;
wk->vb = vb;
wk->pcdev = pcdev;
queue_work(pcdev->camera_wq, &(wk->work));
if (!list_empty(&pcdev->camera_work_queue)) {
wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
list_del_init(&wk->queue);
INIT_WORK(&(wk->work), rk_camera_capture_process);
wk->vb = vb;
wk->pcdev = pcdev;
queue_work(pcdev->camera_wq, &(wk->work));
}
} else {
wake_up(&vb->done);
}
@@ -819,7 +828,7 @@ static void rk_videobuf_release(struct videobuf_queue *vq,
if (vb == pcdev->active) {
RKCAMERA_DG("%s Wait for this video buf(0x%x) write finished!\n ",__FUNCTION__,(unsigned int)vb);
interruptible_sleep_on_timeout(&vb->done, 100);
interruptible_sleep_on_timeout(&vb->done, msecs_to_jiffies(500));
flush_workqueue(pcdev->camera_wq);
RKCAMERA_DG("%s This video buf(0x%x) write finished, release now!!\n",__FUNCTION__,(unsigned int)vb);
}
@@ -921,7 +930,12 @@ static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
clk_disable(pcdev->hclk_cif);
clk_disable(pcdev->cif_clk_in);
clk_disable(pcdev->cif_clk_out);
clk_enable(pcdev->cif_clk_out);
clk_set_rate(pcdev->cif_clk_out,48*1000*1000);
clk_disable(pcdev->cif_clk_out);
clk_disable(pcdev->pd_cif);
return;
}
@@ -996,7 +1010,6 @@ static int rk_camera_add_device(struct soc_camera_device *icd)
pcdev->icd_frmival[0].icd = icd;
pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
}
RKCAMERA_TR("%s..%d.. \n",__FUNCTION__,__LINE__);
ebusy:
mutex_unlock(&camera_lock);
@@ -1043,6 +1056,7 @@ static void rk_camera_remove_device(struct soc_camera_device *icd)
kfree(pcdev->camera_work);
pcdev->camera_work = NULL;
pcdev->camera_work_count = 0;
INIT_LIST_HEAD(&pcdev->camera_work_queue);
}
rk_camera_deactivate(pcdev);
pcdev->active = NULL;
@@ -1206,33 +1220,33 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix
{
case V4L2_PIX_FMT_NV16:
cif_fmt_val &= ~YUV_OUTPUT_422;
cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
pcdev->pixfmt = host_pixfmt;
cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
pcdev->pixfmt = host_pixfmt;
break;
case V4L2_PIX_FMT_NV61:
cif_fmt_val &= ~YUV_OUTPUT_422;
cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
pcdev->pixfmt = host_pixfmt;
break;
case V4L2_PIX_FMT_NV61:
cif_fmt_val &= ~YUV_OUTPUT_422;
cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
pcdev->pixfmt = host_pixfmt;
break;
case V4L2_PIX_FMT_NV12:
cif_fmt_val |= YUV_OUTPUT_420;
cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
pcdev->pixfmt = host_pixfmt;
break;
case V4L2_PIX_FMT_NV21:
cif_fmt_val |= YUV_OUTPUT_420;
cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
pcdev->pixfmt = host_pixfmt;
break;
default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
cif_fmt_val |= YUV_OUTPUT_422;
break;
case V4L2_PIX_FMT_NV21:
cif_fmt_val |= YUV_OUTPUT_420;
cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
pcdev->pixfmt = host_pixfmt;
break;
default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
cif_fmt_val |= YUV_OUTPUT_422;
break;
}
switch (icd_code)
{
@@ -1278,13 +1292,11 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix
write_cif_reg(pcdev->base,CIF_CIF_FOR,cif_fmt_val); /* ddl@rock-chips.com: VIP capture mode and capture format must be set before FS register set */
// read_cif_reg(pcdev->base,CIF_CIF_INTSTAT); /* clear vip interrupte single */
write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) // it is one frame mode
{
BUG();
}
else{ // this is one frame mode
write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
BUG();
} else{ // this is one frame mode
cif_crop = (rect->left+ (rect->top<<16));
cif_fs = ((rect->width ) + (rect->height<<16));
}
@@ -1294,10 +1306,9 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix
write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
//MUST bypass scale
//MUST bypass scale
write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
//pcdev->host_width = rect->width;
// pcdev->host_height = rect->height;
RKCAMERA_DG("%s.. crop:0x%x fs:0x%x cif_fmt_val:0x%x CIF_CIF_FOR:0x%x\n",__FUNCTION__,cif_crop,cif_fs,cif_fmt_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
return;
}
@@ -1478,8 +1489,6 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
RKCAMERA_DG("ratio = %d ,host:%d*%d\n",ratio,pcdev->host_width,pcdev->host_height);
}
else{ // needn't crop ,just scaled by ipp
// pcdev->host_width = usr_w;
// pcdev->host_height = usr_h;
pcdev->host_width = mf.width;
pcdev->host_height = mf.height;
}
@@ -1604,7 +1613,8 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
bool is_capture = rk_camera_fmt_capturechk(f);
bool vipmem_is_overflow = false;
struct v4l2_mbus_framefmt mf;
int bytes_per_line_host;
usr_w = pix->width;
usr_h = pix->height;
RKCAMERA_DG("%s enter width:%d height:%d\n",__FUNCTION__,usr_w,usr_h);
@@ -1645,13 +1655,14 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
goto RK_CAMERA_TRY_FMT_END;
RKCAMERA_DG("%s mf.width:%d mf.height:%d\n",__FUNCTION__,mf.width,mf.height);
#ifdef CONFIG_VIDEO_RK29_WORK_IPP
if ((mf.width > usr_w) && (mf.height > usr_h)) {
if ((mf.width != usr_w) || (mf.height != usr_h)) {
bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt);
if (is_capture) {
vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height) > pcdev->vipmem_size);
vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
} else {
/* Assume preview buffer minimum is 4 */
vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height)*4 > pcdev->vipmem_size);
}
vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
}
if (vipmem_is_overflow == false) {
pix->width = usr_w;
pix->height = usr_h;
@@ -1660,26 +1671,14 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
pix->width = mf.width;
pix->height = mf.height;
}
} else if ((mf.width < usr_w) && (mf.height < usr_h)) {
if (((usr_w>>1) < mf.width) && ((usr_h>>1) < mf.height)) {
if (is_capture) {
vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height) > pcdev->vipmem_size);
} else {
vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height)*4 > pcdev->vipmem_size);
}
if (vipmem_is_overflow == false) {
pix->width = usr_w;
pix->height = usr_h;
} else {
RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);
pix->width = mf.width;
pix->height = mf.height;
}
} else {
RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
pix->width = mf.width;
pix->height = mf.height;
}
if ((mf.width < usr_w) || (mf.height < usr_h)) {
if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
pix->width = mf.width;
pix->height = mf.height;
}
}
}
#else
//need to change according to crop and scale capablicity
@@ -1819,12 +1818,7 @@ static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
//pcdev->reginfo_suspend.VipCrm = read_vip_reg(pcdev->base,RK29_VIP_CRM);
//tmp = pcdev->reginfo_suspend.cifFs>>16; /* ddl@rock-chips.com */
//tmp += pcdev->reginfo_suspend.cifCrop>>16;
//pcdev->reginfo_suspend.cifFs = (pcdev->reginfo_suspend.cifFs & 0xffff) | (tmp<<16);
pcdev->reginfo_suspend.Inval = Reg_Validate;
rk_camera_deactivate(pcdev);
@@ -1880,12 +1874,8 @@ rk_camera_resume_end:
static void rk_camera_reinit_work(struct work_struct *work)
{
struct v4l2_subdev *sd;
struct v4l2_mbus_framefmt mf;
const struct soc_camera_format_xlate *xlate;
int ret;
struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
struct rk_camera_dev *pcdev = camera_work->pcdev;
struct videobuf_buffer *tmp_vb;
struct soc_camera_link *tmp_soc_cam_link;
int index = 0;
unsigned long flags = 0;
@@ -1912,89 +1902,27 @@ static void rk_camera_reinit_work(struct work_struct *work)
RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
}
if(1/*pcdev->reinit_times++ >= 2*/)
{
pcdev->stop_cif = true;
write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
RKCAMERA_DG("the reinit times = %d\n",pcdev->reinit_times);
#if 0
while (!list_empty(&pcdev->capture)) {
tmp_vb = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
if (tmp_vb/* && (tmp_vb->state == VIDEOBUF_QUEUED)*/)
{
printk("wake up video buffer index = %d ,state = %d, !!!\n",tmp_vb->i,tmp_vb->state);
tmp_vb->state = VIDEOBUF_ERROR;
list_del_init(&(tmp_vb->queue));
wake_up(&tmp_vb->done);
}
}
#else
spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
for (index = 0; index < VIDEO_MAX_FRAME; index++) {
if (NULL == pcdev->video_vq->bufs[index])
continue;
if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED)
{
list_del_init(&pcdev->video_vq->bufs[index]->queue);
pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
wake_up_all(&pcdev->video_vq->bufs[index]->done);
printk("wake up video buffer index = %d !!!\n",index);
}
}
spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags);
pcdev->stop_cif = true;
write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
RKCAMERA_DG("the reinit times = %d\n",pcdev->reinit_times);
spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
for (index = 0; index < VIDEO_MAX_FRAME; index++) {
if (NULL == pcdev->video_vq->bufs[index])
continue;
#endif
RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
}/*else{ //the first time,just reinit sensor ,don't wake up vb
// rk_cif_poweroff(pcdev);
RKCAMERA_DG("first time to reinit\n");
// return;
if(IS_CIF0()){
// write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)|MASK_RST_CIF0|RQUEST_RST_CIF0 ));
// write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF0)) | MASK_RST_CIF0);
rk_camera_store_register(pcdev);
rk_camera_deactivate(pcdev);
pmu_set_idle_request(IDLE_REQ_VIO, true);
cru_set_soft_reset(SOFT_RST_CIF0, true);
udelay(50);
cru_set_soft_reset(SOFT_RST_CIF0, false);
pmu_set_idle_request(IDLE_REQ_VIO, false);
rk_camera_activate(pcdev,NULL);
rk_camera_restore_register(pcdev);
rk_videobuf_capture(pcdev->active,pcdev);
printk("clean cru register reset cif0 0x%x\n",read_cru_reg(CRU_CIF_RST_REG30));
if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED)
{
list_del_init(&pcdev->video_vq->bufs[index]->queue);
pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
wake_up_all(&pcdev->video_vq->bufs[index]->done);
printk("wake up video buffer index = %d !!!\n",index);
}
}
spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags);
}else{
// write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF1|RQUEST_RST_CIF1 | (read_cru_reg(CRU_CIF_RST_REG30)));
// write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF1)) | MASK_RST_CIF1);
rk_camera_store_register(pcdev);
rk_camera_deactivate(pcdev);
pmu_set_idle_request(IDLE_REQ_VIO, true);
cru_set_soft_reset(SOFT_RST_CIF1, true);
udelay(50);
cru_set_soft_reset(SOFT_RST_CIF1, false);
pmu_set_idle_request(IDLE_REQ_VIO, false);
rk_camera_activate(pcdev,NULL);
rk_camera_restore_register(pcdev);
rk_videobuf_capture(pcdev->active,pcdev);
}
tmp_soc_cam_link->power(pcdev->icd->pdev,0);
// rk_cif_poweron(pcdev);
tmp_soc_cam_link->power(pcdev->icd->pdev,1);
control = to_soc_camera_control(pcdev->icd);
sd = dev_get_drvdata(control);
ret = v4l2_subdev_call(sd,core, init, 1);
mf.width = pcdev->icd->user_width;
mf.height = pcdev->icd->user_height;
xlate = soc_camera_xlate_by_fourcc(pcdev->icd, pcdev->icd->current_fmt->host_fmt->fourcc);
mf.code = xlate->code;
ret |= v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
RKCAMERA_TR("first time Camera host haven't recevie data from sensor,Reinit sensor now! ret:0x%x\n",ret);
}*/
RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
}
static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
{
@@ -2117,11 +2045,6 @@ static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
pcdev->stop_cif = true;
spin_unlock_irqrestore(&pcdev->lock, flags);
// printk("flush work end!!!!!!!!!\n");
// mdelay(3*1000);
// write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);//frame1 has been ready to receive data,frame 2 is not used
// write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF); /* clear vip interrupte single */
// write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS,0); /* clear vip interrupte single */
flush_workqueue((pcdev->camera_wq));
RKCAMERA_DG("STREAM_OFF cancel timer and flush work:0x%x \n", ret);
}
@@ -2233,48 +2156,7 @@ static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct rk_camera_dev *pcdev = ici->priv;
#if 0
unsigned int cif_fs = 0,cif_crop = 0;
int work_index =0,stream_on = 0;
/* ddl@rock-chips.com : The largest resolution is 2047x1088, so larger resolution must be operated some times
(Assume operate times is 4),but resolution which ipp can operate ,it is width and height must be even. */
a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
a.c.width = pcdev->host_width*100/zoom_rate;
a.c.width &= ~0x03;
a.c.height = pcdev->host_height*100/zoom_rate;
a.c.height &= ~0x03;
a.c.left = (((pcdev->host_width - a.c.width)>>1) +pcdev->host_left)&(~0x01);
a.c.top = (((pcdev->host_height - a.c.height)>>1) + pcdev->host_top)&(~0x01);
stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
if (stream_on & ENABLE_CAPTURE)
write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE)));
if (CAM_IPPWORK_IS_EN() && (stream_on & ENABLE_CAPTURE)){
for(;work_index < pcdev->camera_work_count;work_index++)
flush_work(&((pcdev->camera_work + work_index)->work));
pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
}
//printk("host_left = %d , host_top = %d\n",pcdev->host_left,pcdev->host_top);
down(&pcdev->zoominfo.sem);
pcdev->zoominfo.a.c.height = a.c.height;
pcdev->zoominfo.a.c.width = a.c.width;
pcdev->zoominfo.a.c.top = 0;
pcdev->zoominfo.a.c.left = 0;
pcdev->zoominfo.vir_width = a.c.width;
up(&pcdev->zoominfo.sem);
cif_crop = a.c.left+ (a.c.top<<16);
cif_fs = a.c.width + ((a.c.height)<<16);
//cif do the crop , ipp do the scale
write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width);
write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
if (stream_on & ENABLE_CAPTURE)
write_cif_reg(pcdev->base,CIF_CIF_CTRL, stream_on);
#else
//change the crop and scale parameters
a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
a.c.width = pcdev->host_width*100/zoom_rate;
@@ -2290,8 +2172,6 @@ static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
pcdev->zoominfo.a.c.left = a.c.left;
pcdev->zoominfo.vir_width = pcdev->host_width;
up(&pcdev->zoominfo.sem);
#endif
RKCAMERA_DG("%s..zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n",__FUNCTION__, zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
return 0;
@@ -2446,7 +2326,6 @@ static int rk_camera_probe(struct platform_device *pdev)
pcdev->zoominfo.zoom_rate = 100;
pcdev->hostid = pdev->id;
/*config output clk*/ // must modify start
if(IS_CIF0()){
pcdev->pd_cif = clk_get(NULL, "pd_cif0");
@@ -2494,7 +2373,9 @@ static int rk_camera_probe(struct platform_device *pdev)
}
#endif
INIT_LIST_HEAD(&pcdev->capture);
INIT_LIST_HEAD(&pcdev->camera_work_queue);
spin_lock_init(&pcdev->lock);
spin_lock_init(&pcdev->camera_work_lock);
sema_init(&pcdev->zoominfo.sem,1);
/*

View File

@@ -60,21 +60,11 @@
#define RGA_MAJOR 255
#if 1
#if CONFIG_ARCH_RK2928
#define RK30_RGA_PHYS 0x1010C000
#define RK30_RGA_SIZE SZ_8K
#define RGA_RESET_TIMEOUT 1000
#elif CONFIG_ARCH_RK30
#define RK30_RGA_PHYS 0x10114000
#define RK30_RGA_SIZE SZ_8K
#define RGA_RESET_TIMEOUT 1000
#elif CONFIG_ARCH_RK31
#define RK30_RGA_PHYS 0x10114000
#define RK30_RGA_SIZE SZ_8K
#define RGA_RESET_TIMEOUT 1000
#endif
#if defined(CONFIG_ARCH_RK2928)
#define RK30_RGA_PHYS RK2928_RGA_PHYS
#define RK30_RGA_SIZE RK2928_RGA_SIZE
#endif
#define RGA_RESET_TIMEOUT 1000
/* Driver information */
#define DRIVER_DESC "RGA Device Driver"
@@ -136,7 +126,6 @@ static inline u32 rga_read(u32 r)
return __raw_readl(drvdata->rga_base + r);
}
#if 1//defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31)
static void rga_soft_reset(void)
{
u32 i;
@@ -157,7 +146,6 @@ static void rga_soft_reset(void)
if(i == RGA_RESET_TIMEOUT)
ERR("soft reset timeout.\n");
}
#endif
static void rga_dump(void)
{
@@ -356,7 +344,7 @@ static int rga_check_param(const struct rga_req *req)
return -EINVAL;
}
if (unlikely((req->dst.vir_w <= 0) || (req->dst.vir_w > 2048) || (req->dst.vir_h <= 0) || (req->dst.vir_h > 2048)))
if (unlikely((req->dst.vir_w <= 0) || (req->dst.vir_w > 4096) || (req->dst.vir_h <= 0) || (req->dst.vir_h > 2048)))
{
ERR("invalid destination resolution vir_w = %d, vir_h = %d\n", req->dst.vir_w, req->dst.vir_h);
return -EINVAL;
@@ -580,7 +568,7 @@ static void rga_try_set_reg(void)
udelay(1);
rga_copy_reg(reg, 0);
rga_reg_from_wait_to_run(reg);
rga_reg_from_wait_to_run(reg);
dmac_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[28]);
outer_flush_range(virt_to_phys(&rga_service.cmd_buff[0]),virt_to_phys(&rga_service.cmd_buff[28]));
@@ -606,6 +594,7 @@ static void rga_try_set_reg(void)
printk("%.8x %.8x %.8x %.8x\n", p[0 + i*4], p[1+i*4], p[2 + i*4], p[3 + i*4]);
}
#endif
/* master mode */
rga_write((0x1<<2)|(0x1<<3), RGA_SYS_CTRL);
@@ -951,7 +940,7 @@ static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg)
}
else
{
ret = rga_blit_sync(session, req);
ret = rga_blit_async(session, req);
}
break;
case RGA_FLUSH:
@@ -1039,7 +1028,6 @@ static irqreturn_t rga_irq_thread(int irq, void *dev_id)
rga_del_running_list();
rga_try_set_reg();
}
//printk("****** rga irq prc avil ******\n");
mutex_unlock(&rga_service.lock);
return IRQ_HANDLED;
@@ -1096,27 +1084,14 @@ static int __devinit rga_drv_probe(struct platform_device *pdev)
data->aclk_rga = clk_get(NULL, "aclk_rga");
data->hclk_rga = clk_get(NULL, "hclk_rga");
/* map the memory */
#if defined(CONFIG_ARCH_RK2928)
if (!request_mem_region(RK2928_RGA_PHYS, RK2928_RGA_SIZE, "rga_io"))
#elif defined(CONFIG_ARCH_RK30)
if (!request_mem_region(RK30_RGA_PHYS, RK30_RGA_SIZE, "rga_io"))
#elif defined(CONFIG_ARCH_RK31)
if (!request_mem_region(RK30_RGA_PHYS, RK30_RGA_SIZE, "rga_io"))
#endif
if (!request_mem_region(RK30_RGA_PHYS, RK30_RGA_SIZE, "rga_io"))
{
pr_info("failed to reserve rga HW regs\n");
return -EBUSY;
}
#if defined(CONFIG_ARCH_RK2928)
data->rga_base = (void*)ioremap_nocache(RK2928_RGA_PHYS, RK2928_RGA_SIZE);
#elif defined(CONFIG_ARCH_RK30)
data->rga_base = (void*)ioremap_nocache(RK30_RGA_PHYS, RK30_RGA_SIZE);
#elif defined(CONFIG_ARCH_RK31)
data->rga_base = (void*)ioremap_nocache(RK30_RGA_PHYS, RK30_RGA_SIZE);
#endif
data->rga_base = (void*)ioremap_nocache(RK30_RGA_PHYS, RK30_RGA_SIZE);
if (data->rga_base == NULL)
{
ERR("rga ioremap failed\n");

View File

@@ -55,35 +55,10 @@ static int rk2928_dai_hw_params(struct snd_pcm_substream *substream,
#endif
if (ret < 0)
return ret;
switch(params_rate(params)) {
case 8000:
case 16000:
case 24000:
case 32000:
case 48000:
case 96000:
pll_out = 12288000;
break;
case 11025:
case 22050:
case 44100:
case 88200:
pll_out = 11289600;
break;
case 176400:
pll_out = 11289600*2;
break;
case 192000:
pll_out = 12288000*2;
break;
default:
DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
return -EINVAL;
break;
}
DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
pll_out = 256 * params_rate(params);
#if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)
snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
#endif