From bbc68b65d9fbba7bb10cf89644e4d984f536c059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B6=9B?= Date: Wed, 15 Aug 2012 10:41:41 +0800 Subject: [PATCH 1/9] i2c: rk: only rk29/rk30 need idle lock --- drivers/i2c/busses/i2c-rk29.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/i2c/busses/i2c-rk29.c b/drivers/i2c/busses/i2c-rk29.c index 69af912074c8..4e5f1e136751 100755 --- a/drivers/i2c/busses/i2c-rk29.c +++ b/drivers/i2c/busses/i2c-rk29.c @@ -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); } From 7db28b5ce2007ca5440b4c03561f4493352671b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B6=9B?= Date: Thu, 16 Aug 2012 09:18:32 +0800 Subject: [PATCH 2/9] rk2928: sram: fix loop use Thumb instruction set --- arch/arm/mach-rk2928/include/mach/sram.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-rk2928/include/mach/sram.h b/arch/arm/mach-rk2928/include/mach/sram.h index eba76bccf64d..4dec061dfeca 100644 --- a/arch/arm/mach-rk2928/include/mach/sram.h +++ b/arch/arm/mach-rk2928/include/mach/sram.h @@ -4,7 +4,7 @@ #include #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 */ From c5066ca24849fdb2e6ea4095b276c7567c7291b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B6=9B?= Date: Thu, 16 Aug 2012 09:43:53 +0800 Subject: [PATCH 3/9] rk2928: add initial pm support --- arch/arm/mach-rk2928/pm.c | 453 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 453 insertions(+) diff --git a/arch/arm/mach-rk2928/pm.c b/arch/arm/mach-rk2928/pm.c index b8bcc0292339..0591da0f482f 100755 --- a/arch/arm/mach-rk2928/pm.c +++ b/arch/arm/mach-rk2928/pm.c @@ -14,13 +14,47 @@ #include #include +#include +#include #include #include #include +#include +#include + +#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); From 278d2a1ab231c04241452583bf3f55bc45202aac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B6=9B?= Date: Thu, 16 Aug 2012 11:51:17 +0800 Subject: [PATCH 4/9] gpio: rk2928: enable support rk30_gpiolib_pull_updown --- drivers/gpio/gpio-rk30.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-rk30.c b/drivers/gpio/gpio-rk30.c index 14417a33a4a9..911636cf49c1 100755 --- a/drivers/gpio/gpio-rk30.c +++ b/drivers/gpio/gpio-rk30.c @@ -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; From 475f235898a07dc0b8531d0277fbf2e947788177 Mon Sep 17 00:00:00 2001 From: zsq Date: Thu, 16 Aug 2012 14:43:06 +0800 Subject: [PATCH 5/9] fix no async bug --- drivers/video/rockchip/rga/rga_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/rockchip/rga/rga_drv.c b/drivers/video/rockchip/rga/rga_drv.c index 507751400069..734af2cbb802 100755 --- a/drivers/video/rockchip/rga/rga_drv.c +++ b/drivers/video/rockchip/rga/rga_drv.c @@ -356,7 +356,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; @@ -951,7 +951,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: From 28ef1d8c93c668c535145d9e94385335138247e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B6=9B?= Date: Thu, 16 Aug 2012 12:57:25 +0800 Subject: [PATCH 6/9] Input: rk29_keys: close debug print, open by 9ea1329 --- drivers/input/keyboard/rk29_keys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/keyboard/rk29_keys.c b/drivers/input/keyboard/rk29_keys.c index d184b51a1e0a..b5881d5b5e93 100755 --- a/drivers/input/keyboard/rk29_keys.c +++ b/drivers/input/keyboard/rk29_keys.c @@ -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 From 9e0aa7b6bbef569e756d42a15946cd2b3c445c50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B6=9B?= Date: Thu, 16 Aug 2012 15:55:57 +0800 Subject: [PATCH 7/9] rga: refactor rga_drv.c for support rk30/rk31/rk2928 --- drivers/video/rockchip/rga/rga_drv.c | 41 ++++++---------------------- 1 file changed, 8 insertions(+), 33 deletions(-) diff --git a/drivers/video/rockchip/rga/rga_drv.c b/drivers/video/rockchip/rga/rga_drv.c index 734af2cbb802..6bf2399a59b8 100755 --- a/drivers/video/rockchip/rga/rga_drv.c +++ b/drivers/video/rockchip/rga/rga_drv.c @@ -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) { @@ -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); @@ -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"); From 6ef0af5a9b983cc81192d2b04ea650e0e7cb9a1c Mon Sep 17 00:00:00 2001 From: zyc Date: Fri, 17 Aug 2012 10:31:42 +0800 Subject: [PATCH 8/9] camera : fix conflict when merge to rk30 --- drivers/media/video/rk30_camera_oneframe.c | 331 +++++++-------------- 1 file changed, 106 insertions(+), 225 deletions(-) diff --git a/drivers/media/video/rk30_camera_oneframe.c b/drivers/media/video/rk30_camera_oneframe.c index 23139426138d..b77d345e94ce 100755 --- a/drivers/media/video/rk30_camera_oneframe.c +++ b/drivers/media/video/rk30_camera_oneframe.c @@ -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); /* From c4915c3f0f1f4b5a84fa761b16cc7a9c9055f0a1 Mon Sep 17 00:00:00 2001 From: Zheng Yang Date: Fri, 17 Aug 2012 14:33:23 +0800 Subject: [PATCH 9/9] rk2929 acodec: for internal audio codec, mclk = 64*bclk = 256*lrclk. --- sound/soc/rk29/rk2928-card.c | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/sound/soc/rk29/rk2928-card.c b/sound/soc/rk29/rk2928-card.c index 8d08942bd86d..412460cb4cdf 100755 --- a/sound/soc/rk29/rk2928-card.c +++ b/sound/soc/rk29/rk2928-card.c @@ -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