void decon_reg_set_clkval(u32 clkdiv) { u32 val; decon_write_mask(VIDCON0, ~0, VIDCON0_CLKVALUP); val = (clkdiv >= 1) ? VIDCON0_CLKVAL_F(clkdiv - 1) : 0; decon_write_mask(VIDCON0, val, VIDCON0_CLKVAL_F_MASK); }
void decon_reg_set_vidout(enum s3c_fb_psr_mode mode, u32 en) { if (mode == S3C_FB_MIPI_COMMAND_MODE) decon_write_mask(VIDOUTCON0, VIDOUTCON0_I80IF_F, VIDOUTCON0_IF_MASK); else decon_write_mask(VIDOUTCON0, VIDOUTCON0_RGBIF_F, VIDOUTCON0_IF_MASK); decon_write_mask(VIDOUTCON0, en ? ~0 : 0, VIDOUTCON0_LCD_ON_F); }
void decon_reg_set_rgb_order(enum decon_rgb_order order) { u32 val = VIDCON2_RGB_ORDER_O_RGB; switch (order) { case DECON_RGB: val = VIDCON2_RGB_ORDER_O_RGB; break; case DECON_GBR: val = VIDCON2_RGB_ORDER_O_GBR; break; case DECON_BRG: val = VIDCON2_RGB_ORDER_O_BRG; break; case DECON_BGR: val = VIDCON2_RGB_ORDER_O_BGR; break; case DECON_RBG: val = VIDCON2_RGB_ORDER_O_RBG; break; case DECON_GRB: val = VIDCON2_RGB_ORDER_O_GRB; break; } decon_write_mask(VIDCON2, val, VIDCON2_RGB_ORDER_O_MASK); }
void decon_reg_set_winmap(u32 idx, u32 color, u32 en) { u32 val = en ? WINxMAP_MAP : 0; val |= WINxMAP_MAP_COLOUR(color); decon_write_mask(WINxMAP(idx), val, WINxMAP_MAP | WINxMAP_MAP_COLOUR_MASK); }
irqreturn_t decon_int_irq_handler(int irq, void *dev_data) { struct decon_device *decon = dev_data; u32 irq_sts_reg; ktime_t timestamp; u32 fifo_level; timestamp = ktime_get(); spin_lock(&decon->slock); if ((decon->state == DECON_STATE_OFF) || (decon->state == DECON_STATE_LPD)) { goto irq_end; } irq_sts_reg = decon_read(decon->id, VIDINTCON1); if (irq_sts_reg & VIDINTCON1_INT_FRAME) { /* VSYNC interrupt, accept it */ decon_write_mask(decon->id, VIDINTCON1, ~0, VIDINTCON1_INT_FRAME); decon->vsync_info.timestamp = timestamp; wake_up_interruptible_all(&decon->vsync_info.wait); } if (irq_sts_reg & VIDINTCON1_INT_FIFO) { /* TODO: false underrun check only for EVT0. This will be removed in EVT1 */ fifo_level = FRAMEFIFO_FIFO0_VALID_SIZE_GET(decon_read(decon->id, FRAMEFIFO_REG7)); decon->underrun_stat.fifo_level = fifo_level; decon->underrun_stat.prev_overlap_cnt = decon->prev_overlap_cnt; decon->underrun_stat.cur_overlap_cnt = decon->cur_overlap_cnt; decon->underrun_stat.chmap = decon_read(0, WINCHMAP0); decon->underrun_stat.aclk = decon->res.aclk->rate; decon->underrun_stat.mif_pll = decon->res.mif_pll->rate; decon_int_get_enabled_win(decon); decon_oneshot_underrun_log(decon); decon_write_mask(decon->id, VIDINTCON1, ~0, VIDINTCON1_INT_FIFO); /* TODO: underrun function */ /* s3c_fb_log_fifo_underflow_locked(decon, timestamp); */ } if (irq_sts_reg & VIDINTCON1_INT_I80) { decon_write_mask(decon->id, VIDINTCON1, ~0, VIDINTCON1_INT_I80); } irq_end: spin_unlock(&decon->slock); return IRQ_HANDLED; }
/* enable(unmask) / disable(mask) hw trigger */ void decon_reg_set_trigger(enum decon_trig_mode trig, enum decon_set_trig en) { u32 val = (en == DECON_TRIG_ENABLE) ? ~0 : 0; u32 reg_id = TRIGCON_HWTRIGMASK_I80_RGB; if (trig == DECON_SW_TRIG) reg_id = TRIGCON_SWTRIGCMD_I80_RGB; decon_write_mask(TRIGCON, val, reg_id); }
/* set DECON's interrupt. It depends on mode(video mode or command mode) */ void decon_reg_set_int(struct decon_psr_info *psr, u32 en) { u32 val; val = VIDINTCON0_INT_ENABLE | VIDINTCON0_FIFOLEVEL_EMPTY | VIDINTCON0_INT_FIFO | VIDINTCON0_FIFOSEL_MAIN_EN; val |= VIDINTCON0_INT_FRAME | VIDINTCON0_FRAMESEL0_VSYNC; if (psr->psr_mode == S3C_FB_MIPI_COMMAND_MODE) val |= VIDINTCON0_INT_I80_EN; if (en) { if (psr->psr_mode == S3C_FB_MIPI_COMMAND_MODE) decon_write_mask(VIDINTCON1, ~0, VIDINTCON1_INT_I80); decon_write_mask(VIDINTCON0, val, ~0); } else { decon_write_mask(VIDINTCON0, 0, VIDINTCON0_INT_ENABLE); } }
irqreturn_t decon_ext_dsi_irq_handler(int irq, void *dev_data) { struct decon_device *decon = dev_data; ktime_t timestamp = ktime_get(); u32 irq_sts_reg; u32 wb_irq_sts_reg; spin_lock(&decon->slock); irq_sts_reg = decon_read(decon->id, VIDINTCON1); wb_irq_sts_reg = decon_read(decon->id, VIDINTCON3); if (irq_sts_reg & VIDINTCON1_INT_FRAME) { /* VSYNC interrupt, accept it */ decon_write_mask(decon->id, VIDINTCON1, ~0, VIDINTCON1_INT_FRAME); decon->vsync_info.timestamp = timestamp; wake_up_interruptible_all(&decon->vsync_info.wait); } if (irq_sts_reg & VIDINTCON1_INT_FIFO) { decon_err("DECON-ext FIFO underrun\n"); decon_write_mask(decon->id, VIDINTCON1, ~0, VIDINTCON1_INT_FIFO); } if (irq_sts_reg & VIDINTCON1_INT_I80) { decon_write_mask(decon->id, VIDINTCON1, ~0, VIDINTCON1_INT_I80); wake_up_interruptible_all(&decon->wait_frmdone); } #if 0 if (wb_irq_sts_reg & VIDINTCON3_WB_FRAME_DONE) { decon_dbg("write-back frame done\n"); DISP_SS_EVENT_LOG(DISP_EVT_WB_FRAME_DONE, &decon->sd, ktime_set(0, 0)); decon_write_mask(decon->id, VIDINTCON3, ~0, VIDINTCON3_WB_FRAME_DONE); atomic_set(&decon->wb_done, STATE_DONE); wake_up_interruptible_all(&decon->wait_frmdone); decon_reg_per_frame_off(decon->id); decon_reg_update_standalone(decon->id); decon_reg_wb_swtrigger(decon->id); decon_reg_wait_stop_status_timeout(decon->id, 20 * 1000); } #endif spin_unlock(&decon->slock); return IRQ_HANDLED; }
void decon_reg_configure_trigger(enum decon_trig_mode mode) { u32 val, mask; mask = TRIGCON_SWTRIGEN_I80_RGB | TRIGCON_HWTRIGEN_I80_RGB | TRIGCON_HWTRIGMASK_I80_RGB | TRIGCON_TRIGEN_PER_I80_RGB_F | TRIGCON_TRIGEN_I80_RGB_F; val = TRIGCON_TRIGEN_PER_I80_RGB_F | TRIGCON_TRIGEN_I80_RGB_F; if (mode == DECON_SW_TRIG) val |= TRIGCON_SWTRIGEN_I80_RGB; else val |= TRIGCON_HWTRIGEN_I80_RGB; decon_write_mask(TRIGCON, val, mask); }
void decon_reg_set_fixvclk(enum decon_hold_scheme mode) { u32 val = VIDCON1_VCLK_HOLD; switch (mode) { case DECON_VCLK_HOLD: val = VIDCON1_VCLK_HOLD; break; case DECON_VCLK_RUNNING: val = VIDCON1_VCLK_RUN; break; case DECON_VCLK_RUN_VDEN_DISABLE: val = VIDCON1_VCLK_RUN_VDEN_DISABLE; break; } decon_write_mask(VIDCON1, val, VIDCON1_VCLK_MASK); }
void decon_reg_direct_on_off(u32 en) { u32 val = en ? ~0 : 0; decon_write_mask(VIDCON0, val, VIDCON0_ENVID_F | VIDCON0_ENVID); }
void decon_reg_set_crc(u32 en) { u32 val = en ? ~0 : 0; decon_write_mask(CRCCTRL, val, CRCCTRL_CRCCLKEN | CRCCTRL_CRCEN); }
/* enable each window */ void decon_reg_activate_window(u32 index) { decon_write_mask(WINCON(index), ~0, WINCONx_ENWIN); decon_reg_update_standalone(); }
/* prohibit shadow update during writing something to SFR */ void decon_reg_shadow_protect_win(u32 idx, u32 protect) { u32 val = protect ? ~0 : 0; decon_write_mask(SHADOWCON, val, SHADOWCON_WINx_PROTECT(idx)); }
void decon_reg_per_frame_off(void) { decon_write_mask(VIDCON0, 0, VIDCON0_ENVID_F); }
void decon_reg_set_freerun_mode(u32 en) { decon_write_mask(VIDCON0, en ? ~0 : 0, VIDCON0_VLCKFREE); }
void decon_reg_update_standalone(void) { decon_write_mask(DECON_UPDATE, ~0, DECON_UPDATE_STANDALONE_F); }
void decon_reg_set_clkgate_mode(u32 en) { u32 val = en ? ~0 : 0; decon_write_mask(DECON_CMU, val, DECON_CMU_ALL_CLKGATE_ENABLE); }