static void disp_aal_set_interrupt(int enabled) { #ifdef CONFIG_MTK_AAL_SUPPORT if (enabled) { if (DISP_REG_GET(DISP_AAL_EN) == 0) { AAL_DBG("[WARNING] DISP_AAL_EN not enabled!"); } /* Enable output frame end interrupt */ DISP_CPU_REG_SET(DISP_AAL_INTEN, 0x2); AAL_DBG("Interrupt enabled"); } else { if (g_aal_dirty_frame_retrieved) { DISP_CPU_REG_SET(DISP_AAL_INTEN, 0x0); AAL_DBG("Interrupt disabled"); } else { /* Dirty histogram was not retrieved */ /* Only if the dirty hist was retrieved, interrupt can be disabled. Continue interrupt until AALService can get the latest histogram. */ } } #else AAL_ERR("AAL driver is not enabled"); #endif }
static int disp_aal_wait_hist(unsigned long timeout) { int ret = 0; AAL_DBG("disp_aal_wait_hist: available = %d", g_aal_hist_available); if (!g_aal_hist_available) { ret = wait_event_interruptible(g_aal_hist_wq, (g_aal_hist_available != 0)); AAL_DBG("disp_aal_wait_hist: waken up, ret = %d", ret); } else { /* If g_aal_hist_available is already set, means AALService was delayed */ } return ret; }
static int aal_config(DISP_MODULE_ENUM module, disp_ddp_path_config *pConfig, void *cmdq) { if (pConfig->dst_dirty) { int width, height; width = pConfig->dst_w; height = pConfig->dst_h; DISP_REG_SET(cmdq, DISP_AAL_SIZE, (width << 16) | height); DISP_REG_MASK(cmdq, DISP_AAL_CFG, 0x0, 0x1); /* Disable relay mode */ disp_aal_init(module, width, height, cmdq); DISP_REG_MASK(cmdq, DISP_AAL_EN, 0x1, 0x1); AAL_DBG("AAL_CFG = 0x%x, AAL_SIZE = 0x%x(%d, %d)", DISP_REG_GET(DISP_AAL_CFG), DISP_REG_GET(DISP_AAL_SIZE), width, height); } if (pConfig->ovl_dirty || pConfig->rdma_dirty) { disp_aal_notify_frame_dirty(); } return 0; }
int disp_aal_set_param(DISP_AAL_PARAM __user *param, void *cmdq) { int ret = -EFAULT; int backlight_value = 0; /* Not need to protect g_aal_param, since only AALService can set AAL parameters. */ if (copy_from_user(&g_aal_param, param, sizeof(DISP_AAL_PARAM)) == 0) { ret = disp_aal_write_param_to_reg(cmdq, &g_aal_param); backlight_value = g_aal_param.FinalBacklight; } if (g_aal_backlight_notified == 0) backlight_value = 0; if (ret == 0) { ret |= disp_pwm_set_backlight_cmdq(DISP_PWM0, backlight_value, cmdq); } AAL_DBG("disp_aal_set_param(CABC = %d, DRE[0,8] = %d,%d): ret = %d", g_aal_param.cabc_fltgain_force, g_aal_param.DREGainFltStatus[0], g_aal_param.DREGainFltStatus[8], ret); backlight_brightness_set(backlight_value); disp_aal_trigger_refresh(); return ret; }
int disp_aal_write_init_regs(void *cmdq) { int ret = -EFAULT; if (g_aal_is_init_regs_valid) { DISP_AAL_INITREG *init_regs = &g_aal_init_regs; int i, j; int *gain; DISP_REG_MASK(cmdq, DISP_AAL_DRE_MAPPING_00, (init_regs->dre_map_bypass << 4), 1 << 4); gain = init_regs->cabc_gainlmt; j = 0; for (i = 0; i <= 10; i++) { DISP_REG_SET(cmdq, DISP_AAL_CABC_GAINLMT_TBL(i), CABC_GAINLMT(gain[j], gain[j + 1], gain[j + 2])); j += 3; } AAL_DBG("disp_aal_write_init_regs: done"); ret = 0; } return ret; }
static int disp_aal_set_init_reg(DISP_AAL_INITREG __user *user_regs, void *cmdq) { int ret = -EFAULT; DISP_AAL_INITREG *init_regs; init_regs = (DISP_AAL_INITREG*)kmalloc(sizeof(DISP_AAL_INITREG), GFP_KERNEL); if (init_regs == NULL) { AAL_ERR("disp_aal_set_init_reg: insufficient memory"); return -EFAULT; } ret = copy_from_user(init_regs, user_regs, sizeof(DISP_AAL_INITREG)); if (ret == 0) { int i, j; int *gain; DISP_REG_MASK(cmdq, DISP_AAL_DRE_MAPPING_00, (init_regs->dre_map_bypass << 4), 1 << 4); gain = init_regs->cabc_gainlmt; j = 0; for (i = 0; i <= 10; i++) { DISP_REG_SET(cmdq, DISP_AAL_CABC_GAINLMT_TBL(i), CABC_GAINLMT(gain[j], gain[j + 1], gain[j + 2])); j += 3; } } else { AAL_ERR("disp_aal_set_init_reg: copy_from_user() failed"); } AAL_DBG("disp_aal_set_init_reg: %d", ret); kfree(init_regs); return ret; }
void disp_aal_on_end_of_frame(void) { unsigned int intsta; int i; unsigned long flags; intsta = DISP_REG_GET(DISP_AAL_INTSTA); AAL_DBG("disp_aal_on_end_of_frame: intsta: 0x%x", intsta); if (intsta & 0x2) { /* End of frame */ if (spin_trylock_irqsave(&g_aal_hist_lock, flags)) { DISP_CPU_REG_SET(DISP_AAL_INTSTA, (intsta & ~0x3)); for (i = 0; i < AAL_HIST_BIN; i++) { g_aal_hist.maxHist[i] = DISP_REG_GET(DISP_AAL_STATUS_00 + (i << 2)); } g_aal_hist_available = 1; /* Allow to disable interrupt */ g_aal_dirty_frame_retrieved = 1; spin_unlock_irqrestore(&g_aal_hist_lock, flags); wake_up_interruptible(&g_aal_hist_wq); } else { /* * Histogram was not be retrieved, but it's OK. * Another interrupt will come until histogram available * See: disp_aal_set_interrupt() */ } } }
int aal_bypass(DISP_MODULE_ENUM module, int bypass) { int relay = 0; if (bypass) relay = 1; DISP_REG_MASK(NULL, DISP_AAL_CFG, relay, 0x1); AAL_DBG("aal_bypass(bypass = %d)", bypass); return 0; }
static void disp_aal_notify_frame_dirty(void) { #ifdef MTK_AAL_SUPPORT unsigned long flags; AAL_DBG("disp_aal_notify_frame_dirty()"); spin_lock_irqsave(&g_aal_hist_lock, flags); /* Interrupt can be disabled until dirty histogram is retrieved */ g_aal_dirty_frame_retrieved = 0; spin_unlock_irqrestore(&g_aal_hist_lock, flags); disp_aal_set_interrupt(1); #endif }
void disp_aal_on_end_of_frame(void) { #ifdef CONFIG_MTK_AAL_SUPPORT unsigned int intsta; int i; unsigned long flags; intsta = DISP_REG_GET(DISP_AAL_INTSTA); AAL_DBG("disp_aal_on_end_of_frame: intsta: 0x%x", intsta); if (intsta & 0x2) { /* End of frame */ if (spin_trylock_irqsave(&g_aal_hist_lock, flags)) { DISP_CPU_REG_SET(DISP_AAL_INTSTA, (intsta & ~0x3)); for (i = 0; i < AAL_HIST_BIN; i++) { g_aal_hist.maxHist[i] = DISP_REG_GET(DISP_AAL_STATUS_00 + (i << 2)); } g_aal_hist_available = 1; /* Allow to disable interrupt */ g_aal_dirty_frame_retrieved = 1; spin_unlock_irqrestore(&g_aal_hist_lock, flags); if (!g_aal_is_init_regs_valid) { /* * AAL service is not running, not need per-frame wakeup. * We stop interrupt until next frame dirty. */ disp_aal_set_interrupt(0); } wake_up_interruptible(&g_aal_hist_wq); } else { /* * Histogram was not be retrieved, but it's OK. * Another interrupt will come until histogram available * See: disp_aal_set_interrupt() */ } } #else /* * We will not wake up AAL unless signals */ #endif }
static int disp_aal_copy_hist_to_user(DISP_AAL_HIST __user *hist) { unsigned long flags; int ret = -EFAULT; /* We assume only one thread will call this function */ spin_lock_irqsave(&g_aal_hist_lock, flags); memcpy(&g_aal_hist_db, &g_aal_hist, sizeof(DISP_AAL_HIST)); g_aal_hist_available = 0; spin_unlock_irqrestore(&g_aal_hist_lock, flags); if (copy_to_user(hist, &g_aal_hist_db, sizeof(DISP_AAL_HIST)) == 0) { ret = 0; } AAL_DBG("disp_aal_copy_hist_to_user: %d", ret); return ret; }
static int disp_aal_set_init_reg(DISP_AAL_INITREG __user *user_regs, void *cmdq) { int ret = -EFAULT; #ifdef CONFIG_MTK_AAL_SUPPORT DISP_AAL_INITREG *init_regs; init_regs = &g_aal_init_regs; ret = copy_from_user(init_regs, user_regs, sizeof(DISP_AAL_INITREG)); if (ret == 0) { g_aal_is_init_regs_valid = 1; ret = disp_aal_write_init_regs(cmdq); } else { AAL_ERR("disp_aal_set_init_reg: copy_from_user() failed"); } AAL_DBG("disp_aal_set_init_reg: %d", ret); #else AAL_ERR("disp_aal_set_init_reg: AAL not supported"); #endif return ret; }
static int aal_clock_off(DISP_MODULE_ENUM module, void *cmq_handle) { AAL_DBG("aal_clock_off"); disable_clock(MT_CG_DISP0_DISP_AAL, "aal"); return 0; }
static int aal_clock_on(DISP_MODULE_ENUM module, void *cmq_handle) { enable_clock(MT_CG_DISP0_DISP_AAL, "aal"); AAL_DBG("aal_clock_on CG 0x%x", DISP_REG_GET(DISP_REG_CONFIG_MMSYS_CG_CON0)); return 0; }