mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-11 05:17:10 +09:00
camera: rockchip: camsys_drv: Another solution of isp reset failure for rk3326.
Reset on too high isp_clk rate will result in bus dead, so we reduce the isp_clk before reset and then restore after reset. Change-Id: I9e426564f0eb9f900fd5012def1e105d7d697394 Signed-off-by: Zhong Yichong <zyc@rock-chips.com>
This commit is contained in:
@@ -202,9 +202,14 @@
|
||||
1) fix isp soft reset failure for rk3326.
|
||||
reset on too high aclk rate will result in bus dead, so we reduce the aclk
|
||||
before reset and then recover it after reset.
|
||||
*v0.0x28.1:
|
||||
1) another reasonable solution of isp soft reset failure for rk3326.
|
||||
reset on too high isp_clk rate will result in bus dead.
|
||||
The signoff isp_clk rate is 350M, and the recommended rate
|
||||
on reset from IC is NOT greater than 300M.
|
||||
*/
|
||||
|
||||
#define CAMSYS_DRIVER_VERSION KERNEL_VERSION(0, 0x27, 0)
|
||||
#define CAMSYS_DRIVER_VERSION KERNEL_VERSION(0, 0x28, 1)
|
||||
|
||||
#define CAMSYS_PLATFORM_DRV_NAME "RockChip-CamSys"
|
||||
#define CAMSYS_PLATFORM_MARVIN_NAME "Platform_MarvinDev"
|
||||
|
||||
@@ -158,10 +158,11 @@ fail:
|
||||
|
||||
#define VI_IRCL 0x0014
|
||||
/**
|
||||
* reset on too high aclk rate will result in bus dead,
|
||||
* and 200M is a maximum safe value from experiment.
|
||||
* reset on too high isp_clk rate will result in bus dead.
|
||||
* The signoff isp_clk rate is 350M, and the recommended rate
|
||||
* on reset from IC is NOT greater than 300M.
|
||||
*/
|
||||
#define SAFETY_RESET_ACLK_RATE_LIMIT 200000000
|
||||
#define SAFETY_RESET_ISPCLK_RATE_LIMIT 300000000
|
||||
int camsys_rk3326_cfg
|
||||
(
|
||||
camsys_dev_t *camsys_dev,
|
||||
@@ -200,25 +201,27 @@ int camsys_rk3326_cfg
|
||||
}
|
||||
|
||||
case Isp_SoftRst: {/* ddl@rock-chips.com: v0.d.0 */
|
||||
camsys_mrv_clk_t *clk = (camsys_mrv_clk_t *)camsys_dev->clk;
|
||||
long old_aclk_rate = clk_get_rate(clk->aclk_isp);
|
||||
unsigned long reset;
|
||||
|
||||
reset = (unsigned long)cfg_para;
|
||||
|
||||
if (reset == 1) {
|
||||
/* limit the aclk to 200M before isp reset operation */
|
||||
if (old_aclk_rate > SAFETY_RESET_ACLK_RATE_LIMIT)
|
||||
clk_set_rate(clk->aclk_isp,
|
||||
SAFETY_RESET_ACLK_RATE_LIMIT);
|
||||
camsys_mrv_clk_t *clk =
|
||||
(camsys_mrv_clk_t *)camsys_dev->clk;
|
||||
long old_ispclk_rate = clk_get_rate(clk->isp);
|
||||
|
||||
/* check the isp_clk before isp reset operation */
|
||||
if (old_ispclk_rate > SAFETY_RESET_ISPCLK_RATE_LIMIT)
|
||||
clk_set_rate(clk->isp,
|
||||
SAFETY_RESET_ISPCLK_RATE_LIMIT);
|
||||
__raw_writel(0x80, (void *)(camsys_dev->rk_isp_base +
|
||||
VI_IRCL));
|
||||
} else {
|
||||
usleep_range(100, 200);
|
||||
__raw_writel(0x00, (void *)(camsys_dev->rk_isp_base +
|
||||
VI_IRCL));
|
||||
/* recover the old aclk after reset */
|
||||
if (old_aclk_rate != SAFETY_RESET_ACLK_RATE_LIMIT)
|
||||
clk_set_rate(clk->aclk_isp, old_aclk_rate);
|
||||
/* restore the old ispclk after reset */
|
||||
if (old_ispclk_rate != SAFETY_RESET_ISPCLK_RATE_LIMIT)
|
||||
clk_set_rate(clk->isp, old_ispclk_rate);
|
||||
}
|
||||
camsys_trace(2, "Isp self soft rst: %ld", reset);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user