/* dsr lock and power island lock should be hold before calling this function */ int psb_dpst_diet_save(struct drm_device *dev) { struct drm_psb_private *dev_priv = NULL; struct dpst_ie_histogram_control ie_hist_cont_reg; uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL; uint32_t iebdr_reg = HISTOGRAM_BIN_DATA; int dpst3_bin_count = 32; u32 i; if (!dev) return 0; dev_priv = psb_priv(dev); if (!dev_priv || !dev_priv->psb_dpst_state) return 0; ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); ie_hist_cont_reg.bin_reg_func_select = 1; ie_hist_cont_reg.bin_reg_index = 0; PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); for (i = 0; i <= dpst3_bin_count; i++) diet_saved[i] = PSB_RVDC32(iebdr_reg); dpst_print("diet saved\n"); diet_saved[0] = 0x200; return 0; }
/* SH TODO This doesn't work yet. */ int psb_diet_enable(struct drm_device *dev, void *data) { struct drm_psb_private *dev_priv = psb_priv(dev); struct mdfld_dsi_config *dsi_config = NULL; struct mdfld_dsi_hw_context *ctx = NULL; uint32_t *arg = data; struct dpst_ie_histogram_control ie_hist_cont_reg; u32 i; int dpst3_bin_threshold_count = 1; int dpst_hsv_multiplier = 2; uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL; uint32_t iebdr_reg = HISTOGRAM_BIN_DATA; int dpst3_bin_count = 32; if (!dev_priv) return 0; dsi_config = dev_priv->dsi_configs[0]; if (!dsi_config) return 0; ctx = &dsi_config->dsi_hw_context; if (!ospm_power_using_hw_begin (OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) return 0; mdfld_dsi_dsr_forbid(dsi_config); if (data) { ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); ie_hist_cont_reg.bin_reg_func_select = dpst3_bin_threshold_count; ie_hist_cont_reg.bin_reg_index = 0; PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); for (i = 0; i < dpst3_bin_count; i++) PSB_WVDC32(arg[i], iebdr_reg); ctx->aimg_enhance_bin = PSB_RVDC32(iebdr_reg); ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); ie_hist_cont_reg.ie_mode_table_enabled = 1; ie_hist_cont_reg.alt_enhancement_mode = dpst_hsv_multiplier; PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); ctx->histogram_logic_ctrl = ie_hist_cont_reg.data; } else { ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); ie_hist_cont_reg.ie_mode_table_enabled = 0; PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); ctx->histogram_logic_ctrl = ie_hist_cont_reg.data; } mdfld_dsi_dsr_allow(dsi_config); ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); return 0; }
static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) { struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private; uint32_t pipestat; int wake = 0; int vsync_a = 0; int vsync_b = 0; static int pipe_a_on = 0; static int pipe_b_on = 0; int trigger_2d_blit = 0; pipestat = PSB_RVDC32(PSB_PIPEASTAT); if (pipestat & (1<<31)) { printk("buffer underrun 0x%x\n",underrun++); PSB_WVDC32(1<<31 | 1<<15, PSB_PIPEASTAT); } if ((!drm_psb_disable_vsync) && (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)) { atomic_inc(&dev->vbl_received); wake = 1; PSB_WVDC32(_PSB_VBLANK_INTERRUPT_ENABLE | _PSB_VBLANK_CLEAR, PSB_PIPEASTAT); } if ((!drm_psb_disable_vsync) && (vdc_stat & _PSB_VSYNC_PIPEB_FLAG)) { atomic_inc(&dev->vbl_received2); wake = 1; PSB_WVDC32(_PSB_VBLANK_INTERRUPT_ENABLE | _PSB_VBLANK_CLEAR, PSB_PIPEBSTAT); } if (vdc_stat & _PSB_HOTPLUG_INTERRUPT_FLAG) { // Clear 2nd status register spin_lock(&dev_priv->irqmask_lock); uint32_t hotplugstat = PSB_RVDC32(PORT_HOTPLUG_STATUS_REG); PSB_WVDC32(hotplugstat, PORT_HOTPLUG_STATUS_REG); spin_unlock(&dev_priv->irqmask_lock); hotplug_env = '1'; wake_up_interruptible(&hotplug_queue); } PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R); (void)PSB_RVDC32(PSB_INT_IDENTITY_R); DRM_READMEMORYBARRIER(); if (wake) { DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); } }
static int psb_hist_status(struct drm_device *dev, void *data) { struct drm_psb_private *dev_priv = psb_priv(dev); struct drm_psb_hist_status_arg *hist_status = data; uint32_t *arg = hist_status->buf; struct mdfld_dsi_config *dsi_config = NULL; u32 iedbr_reg_data = 0; struct dpst_ie_histogram_control ie_hist_cont_reg; u32 i; int dpst3_bin_threshold_count = 0; uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL; uint32_t iebdr_reg = HISTOGRAM_BIN_DATA; uint32_t segvalue_max_22_bit = 0x3fffff; uint32_t iedbr_busy_bit = 0x80000000; int dpst3_bin_count = 32; if (!dev_priv) return 0; dsi_config = dev_priv->dsi_configs[0]; if (!dsi_config) return 0; if (!ospm_power_using_hw_begin (OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { return 0; } mdfld_dsi_dsr_forbid(dsi_config); ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); ie_hist_cont_reg.bin_reg_func_select = dpst3_bin_threshold_count; ie_hist_cont_reg.bin_reg_index = 0; PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); for (i = 0; i < dpst3_bin_count; i++) { iedbr_reg_data = PSB_RVDC32(iebdr_reg); if (!(iedbr_reg_data & iedbr_busy_bit)) { arg[i] = iedbr_reg_data & segvalue_max_22_bit; } else { i = 0; ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); ie_hist_cont_reg.bin_reg_index = 0; PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); } } mdfld_dsi_dsr_allow(dsi_config); ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); return 0; }
void psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) { if ((dev_priv->pipestat[pipe] & mask) != mask) { u32 reg = psb_pipestat(pipe); u32 writeVal = PSB_RVDC32(reg); dev_priv->pipestat[pipe] |= mask; /* Enable the interrupt, clear any pending status */ writeVal |= (mask | (mask >> 16)); PSB_WVDC32(writeVal, reg); (void) PSB_RVDC32(reg); }
static int psb_hist_status(struct drm_device *dev, void *data) { struct drm_psb_private *dev_priv = psb_priv(dev); struct drm_psb_hist_status_arg *hist_status = data; uint32_t * arg = hist_status->buf; struct mdfld_dsi_config *dsi_config = NULL; u32 iedbr_reg_data = 0; struct dpst_ie_histogram_control ie_hist_cont_reg; u32 i; int dpst3_bin_threshold_count = 0; uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL; uint32_t iebdr_reg = HISTOGRAM_BIN_DATA; uint32_t segvalue_max_22_bit = 0x3fffff; uint32_t iedbr_busy_bit = 0x80000000; int dpst3_bin_count = 32; //Different DPST Algs has different Values? if (!dev_priv) return 0; dsi_config = dev_priv->dsi_configs[0]; if (!dsi_config) return 0; /* * FIXME: We need to force the Display to * turn on but on TNG OSPM how we can force PIPEA to do it? */ if (power_island_get(OSPM_DISPLAY_A)) { ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); ie_hist_cont_reg.bin_reg_func_select = dpst3_bin_threshold_count; ie_hist_cont_reg.bin_reg_index = 0; PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); for (i = 0; i < dpst3_bin_count; i++) { iedbr_reg_data = PSB_RVDC32(iebdr_reg); if (!(iedbr_reg_data & iedbr_busy_bit)) { arg[i] = iedbr_reg_data & segvalue_max_22_bit; } else { i = 0; ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); ie_hist_cont_reg.bin_reg_index = 0; PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); } } power_island_put(OSPM_DISPLAY_A); } return 0; }
void psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) { if ((dev_priv->pipestat[pipe] & mask) != mask) { u32 reg = psb_pipestat(pipe); dev_priv->pipestat[pipe] |= mask; /* Enable the interrupt, clear any pending status */ if (ospm_power_using_hw_begin (OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) { u32 writeVal = PSB_RVDC32(reg); writeVal |= (mask | (mask >> 16)); PSB_WVDC32(writeVal, reg); (void)PSB_RVDC32(reg); ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); } }
void psb_irq_postinstall(struct drm_device *dev) { struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private; unsigned long irqflags; spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); PSB_WSGX32(dev_priv->sgx2_irq_mask, PSB_CR_EVENT_HOST_ENABLE2); PSB_WSGX32(dev_priv->sgx_irq_mask, PSB_CR_EVENT_HOST_ENABLE); (void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE); /****MSVDX IRQ Setup...*****/ /* Enable Mtx Interupt to host */ { unsigned long enables = 0; PSB_DEBUG_GENERAL("Setting up MSVDX IRQs.....\n"); REGIO_WRITE_FIELD_LITE(enables, MSVDX_INTERRUPT_STATUS, CR_MTX_IRQ, 1); PSB_WMSVDX32(enables, MSVDX_HOST_INTERRUPT_ENABLE); } dev_priv->irq_enabled = 1; uint32_t hotplug_stat = PSB_RVDC32(PORT_HOTPLUG_ENABLE_REG); PSB_WVDC32(hotplug_stat | SDVOB_HOTPLUG_DETECT_ENABLE, PORT_HOTPLUG_ENABLE_REG); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); }
int psb_update_guard(struct drm_device *dev, void *data) { struct drm_psb_private *dev_priv = psb_priv(dev); struct dpst_guardband *input = (struct dpst_guardband *)data; struct mdfld_dsi_config *dsi_config = NULL; struct mdfld_dsi_hw_context *ctx = NULL; struct dpst_guardband reg_data; if (!dev_priv) return 0; dsi_config = dev_priv->dsi_configs[0]; if (!dsi_config) return 0; ctx = &dsi_config->dsi_hw_context; if (!ospm_power_using_hw_begin (OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) return 0; mdfld_dsi_dsr_forbid(dsi_config); reg_data.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL); reg_data.guardband = input->guardband; reg_data.guardband_interrupt_delay = input->guardband_interrupt_delay; PSB_WVDC32(reg_data.data, HISTOGRAM_INT_CONTROL); ctx->histogram_intr_ctrl = reg_data.data; mdfld_dsi_dsr_allow(dsi_config); ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); return 0; }
void psb_irq_uninstall(struct drm_device *dev) { struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private; unsigned long irqflags; spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); dev_priv->sgx_irq_mask = 0x00000000; dev_priv->sgx2_irq_mask = 0x00000000; dev_priv->vdc_irq_mask = 0x00000000; PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R); PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); PSB_WSGX32(dev_priv->sgx_irq_mask, PSB_CR_EVENT_HOST_ENABLE); PSB_WSGX32(dev_priv->sgx2_irq_mask, PSB_CR_EVENT_HOST_ENABLE2); wmb(); PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R); PSB_WSGX32(PSB_RSGX32(PSB_CR_EVENT_STATUS), PSB_CR_EVENT_HOST_CLEAR); PSB_WSGX32(PSB_RSGX32(PSB_CR_EVENT_STATUS2), PSB_CR_EVENT_HOST_CLEAR2); /****MSVDX IRQ Setup...*****/ /* Clear interrupt enabled flag */ PSB_WMSVDX32(0, MSVDX_HOST_INTERRUPT_ENABLE); dev_priv->irq_enabled = 0; spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); }
irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *)arg; struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private; uint32_t vdc_stat; uint32_t sgx_stat; uint32_t sgx_stat2; uint32_t msvdx_stat; int handled = 0; spin_lock(&dev_priv->irqmask_lock); vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R); sgx_stat = PSB_RSGX32(PSB_CR_EVENT_STATUS); sgx_stat2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2); msvdx_stat = PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS); sgx_stat2 &= dev_priv->sgx2_irq_mask; sgx_stat &= dev_priv->sgx_irq_mask; PSB_WSGX32(sgx_stat2, PSB_CR_EVENT_HOST_CLEAR2); PSB_WSGX32(sgx_stat, PSB_CR_EVENT_HOST_CLEAR); (void)PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR); vdc_stat &= dev_priv->vdc_irq_mask; spin_unlock(&dev_priv->irqmask_lock); if (msvdx_stat) { psb_msvdx_interrupt(dev, msvdx_stat); handled = 1; } if (vdc_stat) { #ifdef PSB_DETEAR if(psb_blit_info.cmd_ready) { psb_blit_info.cmd_ready = 0; psb_blit_2d_reg_write(dev_priv, psb_blit_info.cmdbuf); /* to resume the blocked psb_cmdbuf_2d() */ set_bit(0, &psb_blit_info.vdc_bit); } #endif /* PSB_DETEAR */ /* MSVDX IRQ status is part of vdc_irq_mask */ psb_vdc_interrupt(dev, vdc_stat); handled = 1; } if (sgx_stat || sgx_stat2) { psb_sgx_interrupt(dev, sgx_stat, sgx_stat2); handled = 1; } if (!handled) { return IRQ_NONE; } return IRQ_HANDLED; }
static int get_data(void *data) { struct intel_i2c_chan *chan = data; struct drm_psb_private *dev_priv = chan->drm_dev->dev_private; uint32_t val; val = PSB_RVDC32(chan->reg); return ((val & GPIO_DATA_VAL_IN) != 0); }
static void set_clock(void *data, int state_high) { struct intel_i2c_chan *chan = data; struct drm_psb_private *dev_priv = chan->drm_dev->dev_private; uint32_t reserved = 0, clock_bits; /* On most chips, these bits must be preserved in software. */ reserved = PSB_RVDC32(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | GPIO_CLOCK_PULLUP_DISABLE); if (state_high) clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK; else clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | GPIO_CLOCK_VAL_MASK; PSB_WVDC32(reserved | clock_bits, chan->reg); udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ }
int psb_dpst_mode(struct drm_device *dev, void *data) { struct drm_psb_private *dev_priv = psb_priv(dev); struct mdfld_dsi_config *dsi_config = NULL; uint32_t * arg = data; uint32_t x = 0; uint32_t y = 0; uint32_t reg; if (!dev_priv) return 0; dsi_config = dev_priv->dsi_configs[0]; if (!dsi_config) return 0; if (!power_island_get(OSPM_DISPLAY_A)) return 0; reg = PSB_RVDC32(PIPEASRC); power_island_put(OSPM_DISPLAY_A); /* horizontal is the left 16 bits */ x = reg >> 16; /* vertical is the right 16 bits */ y = reg & 0x0000ffff; /* the values are the image size minus one */ x += 1; y += 1; *arg = (x << 16) | y; if (x*y <= 1280*800) dpst_hist_fake = dpst_hist_720p; else if (x*y <= 1920*1200) dpst_hist_fake = dpst_hist_1080p; else dpst_hist_fake = dpst_hist_25x16; return 0; }
int psb_dpst_mode(struct drm_device *dev, void *data) { struct drm_psb_private *dev_priv = psb_priv(dev); struct mdfld_dsi_config *dsi_config = NULL; uint32_t *arg = data; uint32_t x = 0; uint32_t y = 0; uint32_t reg; if (!dev_priv) return 0; dsi_config = dev_priv->dsi_configs[0]; if (!dsi_config) return 0; mdfld_dsi_dsr_forbid(dsi_config); if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) return 0; reg = PSB_RVDC32(PIPEASRC); ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); mdfld_dsi_dsr_allow(dsi_config); /* horizontal is the left 16 bits */ x = reg >> 16; /* vertical is the right 16 bits */ y = reg & 0x0000ffff; /* the values are the image size minus one */ x += 1; y += 1; *arg = (x << 16) | y; return 0; }
int psb_update_guard(struct drm_device *dev, void *data) { struct drm_psb_private *dev_priv = psb_priv(dev); struct dpst_guardband *input = (struct dpst_guardband *)data; struct mdfld_dsi_config *dsi_config = NULL; struct mdfld_dsi_hw_context *ctx = NULL; struct dpst_guardband reg_data; if (!dev_priv) return 0; dsi_config = dev_priv->dsi_configs[0]; if (!dsi_config) return 0; ctx = &dsi_config->dsi_hw_context; /* * FIXME: We need to force the Display to * turn on but on TNG OSPM how we can force PIPEA to do it? */ if (!power_island_get(OSPM_DISPLAY_A)) { return 0; } reg_data.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL); reg_data.guardband = input->guardband; reg_data.guardband_interrupt_delay = input->guardband_interrupt_delay; /* printk(KERN_ALERT "guardband = %u\ninterrupt delay = %u\n", reg_data.guardband, reg_data.guardband_interrupt_delay); */ PSB_WVDC32(reg_data.data, HISTOGRAM_INT_CONTROL); ctx->histogram_intr_ctrl = reg_data.data; dpst_print("guardband 0x%x\n", reg_data.data); power_island_put(OSPM_DISPLAY_A); return 0; }
/** * mdfld_save_cursor_overlay_registers - save cursor overlay info * @dev: our device * * Save the cursor and overlay register state */ static int mdfld_save_cursor_overlay_registers(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; /* Save cursor regs */ dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR); dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE); dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS); dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR); dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE); dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS); dev_priv->saveDSPCCURSOR_CTRL = PSB_RVDC32(CURCCNTR); dev_priv->saveDSPCCURSOR_BASE = PSB_RVDC32(CURCBASE); dev_priv->saveDSPCCURSOR_POS = PSB_RVDC32(CURCPOS); /* HW overlay */ dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD); dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0); dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1); dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2); dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3); dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4); dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5); dev_priv->saveOV_OVADD_C = PSB_RVDC32(OV_OVADD + OV_C_OFFSET); dev_priv->saveOV_OGAMC0_C = PSB_RVDC32(OV_OGAMC0 + OV_C_OFFSET); dev_priv->saveOV_OGAMC1_C = PSB_RVDC32(OV_OGAMC1 + OV_C_OFFSET); dev_priv->saveOV_OGAMC2_C = PSB_RVDC32(OV_OGAMC2 + OV_C_OFFSET); dev_priv->saveOV_OGAMC3_C = PSB_RVDC32(OV_OGAMC3 + OV_C_OFFSET); dev_priv->saveOV_OGAMC4_C = PSB_RVDC32(OV_OGAMC4 + OV_C_OFFSET); dev_priv->saveOV_OGAMC5_C = PSB_RVDC32(OV_OGAMC5 + OV_C_OFFSET); return 0; }
/* dsr lock and power island lock should be hold before calling this function */ int psb_dpst_diet_restore(struct drm_device *dev) { struct drm_psb_private *dev_priv = NULL; struct mdfld_dsi_config *dsi_config = NULL; struct mdfld_dsi_hw_context *ctx = NULL; struct dpst_ie_histogram_control ie_hist_cont_reg; u32 i; uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL; uint32_t iebdr_reg = HISTOGRAM_BIN_DATA; int dpst3_bin_count = 32; u32 temp =0; if (!dev) return 0; dev_priv = psb_priv(dev); if (!dev_priv || !dev_priv->psb_dpst_state) return 0; dsi_config = dev_priv->dsi_configs[0]; if (!dsi_config) return 0; ctx = &dsi_config->dsi_hw_context; PSB_WVDC32(ctx->histogram_intr_ctrl, HISTOGRAM_INT_CONTROL); ie_hist_cont_reg.data = ctx->histogram_logic_ctrl; dpst_print("hist_ctl: 0x%x\n", ie_hist_cont_reg.data); ie_hist_cont_reg.bin_reg_func_select = 1; ie_hist_cont_reg.bin_reg_index = 0; ie_hist_cont_reg.ie_histogram_enable = 1; ie_hist_cont_reg.ie_mode_table_enabled = 1; ie_hist_cont_reg.ie_pipe_assignment = 0; #ifdef HSV ie_hist_cont_reg.histogram_mode_select = 1;//HSV ie_hist_cont_reg.alt_enhancement_mode = 2;//dpst_hsv_multiplier; #else ie_hist_cont_reg.histogram_mode_select = 0;//YUV ie_hist_cont_reg.alt_enhancement_mode = 1; //additive #endif PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); if (drm_psb_debug & PSB_D_DPST) { printk("before restore: "); for (i = 0; i <= dpst3_bin_count; i++) { printk(" 0x%x ", PSB_RVDC32(iebdr_reg)); } printk("\n"); } for (i = 0; i <= dpst3_bin_count; i++) { PSB_WVDC32(diet_saved[i], iebdr_reg); } ctx->aimg_enhance_bin = PSB_RVDC32(iebdr_reg); ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); temp = ie_hist_cont_reg.data; temp|=(1<<27); temp&=~0x7f; ie_hist_cont_reg.data = temp; PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); ctx->histogram_logic_ctrl = ie_hist_cont_reg.data; return 0; }
IMG_BOOL MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo, unsigned long uiAddr) { int dspbase = (psDevInfo->ui32MainPipe == 0 ? DSPABASE : DSPBBASE); int dspsurf = (psDevInfo->ui32MainPipe == 0 ? DSPASURF : DSPBSURF); struct drm_device * dev = psDevInfo->psDrmDevice; struct drm_psb_private *dev_priv = (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private; MRSTLFB_SWAPCHAIN *psCurrentSwapChain = psDevInfo->psCurrentSwapChain; struct mdfld_dsi_config *dsi_config; struct mdfld_dsi_hw_context *ctx; unsigned int tmp; if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false)) { if (IS_MRST(dev)) { MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr); } else if (IS_MDFLD(dev)) { if (psCurrentSwapChain != NULL) { if (psCurrentSwapChain->ui32SwapChainPropertyFlag & PVRSRV_SWAPCHAIN_ATTACHED_PLANE_A) { dspsurf = DSPASURF; tmp = PSB_RVDC32(DSPACNTR); if (!(tmp & DISPLAY_PLANE_ENABLE)) PSB_WVDC32(tmp | DISPLAY_PLANE_ENABLE, DSPACNTR); MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr); dsi_config = dev_priv->dsi_configs[0]; if (dsi_config) { ctx = &dsi_config->dsi_hw_context; ctx->dspsurf = uiAddr; } if (mdfld_dsi_dsr_update_panel_fb(dsi_config)) { ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); return IMG_FALSE; } } #if defined(CONFIG_MDFD_DUAL_MIPI) if (psCurrentSwapChain->ui32SwapChainPropertyFlag & PVRSRV_SWAPCHAIN_ATTACHED_PLANE_C) { dspsurf = DSPCSURF; tmp = PSB_RVDC32(DSPACNTR + 0x2000); if (!(tmp & DISPLAY_PLANE_ENABLE)) PSB_WVDC32(tmp | DISPLAY_PLANE_ENABLE, DSPACNTR + 0x2000); MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr); dsi_config = dev_priv->dsi_configs[1]; if (dsi_config) { ctx = &dsi_config->dsi_hw_context; ctx->dspsurf = uiAddr; } if (mdfld_dsi_dsr_update_panel_fb(dsi_config)) { ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); return IMG_FALSE; } } #endif #ifdef CONFIG_SUPPORT_HDMI /* To avoid Plane B still fetches data from original frame * buffer. */ if (psCurrentSwapChain->ui32SwapChainPropertyFlag & PVRSRV_SWAPCHAIN_ATTACHED_PLANE_B) { dspsurf = DSPBSURF; tmp = PSB_RVDC32(DSPACNTR + 0x1000); if (!(tmp & DISPLAY_PLANE_ENABLE)) PSB_WVDC32(tmp | DISPLAY_PLANE_ENABLE, DSPACNTR + 0x1000); MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr); } #endif } else { printk(KERN_WARNING "Current Swapchain is null, no attached plane info\ available, omit address update\n"); if (drm_psb_debug & PSB_D_GENERAL) dump_stack(); } } else { MRSTLFBVSyncWriteReg(psDevInfo, dspbase, uiAddr); } ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); }
// SH START DIET int psb_diet_enable(struct drm_device *dev, void *data) { struct drm_psb_private *dev_priv = psb_priv(dev); struct mdfld_dsi_config *dsi_config = NULL; struct mdfld_dsi_hw_context *ctx = NULL; uint32_t * arg = data; struct dpst_ie_histogram_control ie_hist_cont_reg; u32 i; uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL; uint32_t iebdr_reg = HISTOGRAM_BIN_DATA; int dpst3_bin_count = 32; u32 temp =0; if (!dev_priv) return 0; if(dev_priv->early_suspended) return 0; dsi_config = dev_priv->dsi_configs[0]; if (!dsi_config) return 0; ctx = &dsi_config->dsi_hw_context; mutex_lock(&dpst_mutex); if (power_island_get(OSPM_DISPLAY_A)) { mdfld_dsi_dsr_forbid(dsi_config); if (data) { ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); dpst_print("hist_ctl: 0x%x\n", ie_hist_cont_reg.data); ie_hist_cont_reg.bin_reg_func_select = 1; ie_hist_cont_reg.bin_reg_index = 0; ie_hist_cont_reg.ie_histogram_enable = 1; ie_hist_cont_reg.ie_mode_table_enabled = 1; ie_hist_cont_reg.ie_pipe_assignment = 0; #ifdef HSV ie_hist_cont_reg.histogram_mode_select = 1;//HSV ie_hist_cont_reg.alt_enhancement_mode = 2;//dpst_hsv_multiplier; #else ie_hist_cont_reg.histogram_mode_select = 0;//YUV ie_hist_cont_reg.alt_enhancement_mode = 1; //additive #endif PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); if (drm_psb_debug & PSB_D_DPST) { printk("previous corr: "); for (i = 0; i <= dpst3_bin_count; i++) { printk(" 0x%x ", PSB_RVDC32(iebdr_reg)); } printk("\n"); } PSB_WVDC32(0x200, iebdr_reg); for (i = 1; i <= dpst3_bin_count; i++) { PSB_WVDC32(arg[i], iebdr_reg); } ctx->aimg_enhance_bin = PSB_RVDC32(iebdr_reg); ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); temp = ie_hist_cont_reg.data; temp|=(1<<27); temp&=~0x7f; ie_hist_cont_reg.data = temp; PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); ctx->histogram_logic_ctrl = ie_hist_cont_reg.data; } else { ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); ie_hist_cont_reg.ie_mode_table_enabled = 0; PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); ctx->histogram_logic_ctrl = ie_hist_cont_reg.data; } mdfld_dsi_dsr_allow(dsi_config); power_island_put(OSPM_DISPLAY_A); } mutex_unlock(&dpst_mutex); return 0; }
int psb_hist_enable(struct drm_device *dev, void *data) { u32 irqCtrl = 0; struct drm_psb_private *dev_priv = psb_priv(dev); struct dpst_guardband guardband_reg; struct dpst_ie_histogram_control ie_hist_cont_reg; struct mdfld_dsi_hw_context *ctx = NULL; uint32_t *enable = data; struct mdfld_dsi_config *dsi_config = NULL; if (!dev_priv) return 0; dsi_config = dev_priv->dsi_configs[0]; if (!dsi_config) return 0; ctx = &dsi_config->dsi_hw_context; if (!ospm_power_using_hw_begin (OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { return 0; } mdfld_dsi_dsr_forbid(dsi_config); if (*enable == 1) { ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); ie_hist_cont_reg.ie_pipe_assignment = 0; ie_hist_cont_reg.histogram_mode_select = DPST_YUV_LUMA_MODE; ie_hist_cont_reg.ie_histogram_enable = 1; PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL); ctx->histogram_logic_ctrl = ie_hist_cont_reg.data; guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL); guardband_reg.interrupt_enable = 1; guardband_reg.interrupt_status = 1; PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL); ctx->histogram_intr_ctrl = guardband_reg.data; irqCtrl = PSB_RVDC32(PIPEASTAT); ctx->pipestat = (irqCtrl | PIPE_DPST_EVENT_ENABLE); PSB_WVDC32(ctx->pipestat, PIPEASTAT); } else { guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL); guardband_reg.interrupt_enable = 0; guardband_reg.interrupt_status = 1; PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL); ctx->histogram_intr_ctrl = guardband_reg.data; ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); ie_hist_cont_reg.ie_histogram_enable = 0; PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL); ctx->histogram_logic_ctrl = ie_hist_cont_reg.data; irqCtrl = PSB_RVDC32(PIPEASTAT); irqCtrl &= ~PIPE_DPST_EVENT_ENABLE; PSB_WVDC32(irqCtrl, PIPEASTAT); ctx->pipestat = irqCtrl; dpst_disable_post_process(g_dev); } mdfld_dsi_dsr_allow(dsi_config); ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); return 0; }
static int psb_hist_status(struct drm_device *dev, void *data) { struct drm_psb_private *dev_priv = psb_priv(dev); struct drm_psb_hist_status_arg *hist_status = data; uint32_t * arg = hist_status->buf; struct mdfld_dsi_config *dsi_config = NULL; u32 iedbr_reg_data = 0; struct dpst_ie_histogram_control ie_hist_cont_reg; u32 i; uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL; uint32_t iebdr_reg = HISTOGRAM_BIN_DATA; uint32_t segvalue_max_22_bit = 0x3fffff; uint32_t iedbr_busy_bit = 0x80000000; int dpst3_bin_count = 32; //Different DPST Algs has different Values? if (!dev_priv) return 0; dsi_config = dev_priv->dsi_configs[0]; if (!dsi_config) return 0; /* Use a fake hist status to avoid enhancement is adapted to black * content during suspend, while make content too bright on resume. */ if(dev_priv->early_suspended) { memcpy(arg, dpst_hist_fake, 32*sizeof(uint32_t)); return 0; } mutex_lock(&dpst_mutex); /* * FIXME: We need to force the Display to * turn on but on TNG OSPM how we can force PIPEA to do it? */ if (power_island_get(OSPM_DISPLAY_A)) { mdfld_dsi_dsr_forbid(dsi_config); ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); dpst_print("hist_ctl: 0x%x\n", ie_hist_cont_reg.data); ie_hist_cont_reg.bin_reg_func_select = 0; ie_hist_cont_reg.bin_reg_index = 0; ie_hist_cont_reg.ie_histogram_enable = 1; ie_hist_cont_reg.ie_mode_table_enabled = 1; ie_hist_cont_reg.ie_pipe_assignment = 0; #ifdef HSV ie_hist_cont_reg.histogram_mode_select = 1;//HSV ie_hist_cont_reg.alt_enhancement_mode = 2;//dpst_hsv_multiplier; #else ie_hist_cont_reg.histogram_mode_select = 0;//YUV ie_hist_cont_reg.alt_enhancement_mode = 1; //additive #endif PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); dpst_print("hist static: \n"); for (i = 0; i < dpst3_bin_count; i++) { iedbr_reg_data = PSB_RVDC32(iebdr_reg); if (!(iedbr_reg_data & iedbr_busy_bit)) { arg[i] = iedbr_reg_data & segvalue_max_22_bit; dpst_print("hist_ctl 0x%d 0x%x\n", 0x3ff & PSB_RVDC32(blm_hist_ctl), arg[i]); } else { i = -1; ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl); ie_hist_cont_reg.bin_reg_index = 0; PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl); } } mdfld_dsi_dsr_allow(dsi_config); power_island_put(OSPM_DISPLAY_A); } mutex_unlock(&dpst_mutex); return 0; }
/* IOCTL - moved to standard calls for Kernel Integration */ int psb_hist_enable(struct drm_device *dev, void *data) { struct drm_psb_private *dev_priv = psb_priv(dev); struct dpst_guardband guardband_reg; struct dpst_ie_histogram_control ie_hist_cont_reg; struct mdfld_dsi_hw_context *ctx = NULL; uint32_t * enable = data; struct mdfld_dsi_config *dsi_config = NULL; if (!dev_priv) return 0; dsi_config = dev_priv->dsi_configs[0]; if(!dsi_config) return 0; ctx = &dsi_config->dsi_hw_context; mutex_lock(&dpst_mutex); /* * FIXME: We need to force the Display to * turn on but on TNG OSPM how we can force PIPEA to do it? */ if (power_island_get(OSPM_DISPLAY_A)) { mdfld_dsi_dsr_forbid(dsi_config); if (*enable == 1) { ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); ie_hist_cont_reg.ie_pipe_assignment = 0; ie_hist_cont_reg.bin_reg_func_select = 1; ie_hist_cont_reg.bin_reg_index = 0; ie_hist_cont_reg.ie_histogram_enable = 1; ie_hist_cont_reg.ie_mode_table_enabled = 1; #ifdef HSV ie_hist_cont_reg.histogram_mode_select = 1;//HSV ie_hist_cont_reg.alt_enhancement_mode = 2;//dpst_hsv_multiplier; #else ie_hist_cont_reg.histogram_mode_select = 0;//YUV ie_hist_cont_reg.alt_enhancement_mode = 1; //additive #endif PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL); ctx->histogram_logic_ctrl = ie_hist_cont_reg.data; dpst_print("hist_ctl 0x%x\n", ie_hist_cont_reg.data); guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL); guardband_reg.interrupt_enable = 1; guardband_reg.interrupt_status = 1; PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL); ctx->histogram_intr_ctrl = guardband_reg.data; dpst_print("guardband 0x%x\n", guardband_reg.data); /* Wait for two vblanks */ } else { guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL); guardband_reg.interrupt_enable = 0; guardband_reg.interrupt_status = 1; PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL); ctx->histogram_intr_ctrl = guardband_reg.data; dpst_print("guardband 0x%x\n", guardband_reg.data); ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); ie_hist_cont_reg.ie_histogram_enable = 0; PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL); ctx->histogram_logic_ctrl = ie_hist_cont_reg.data; dpst_print("disabled: hist_ctl 0x%x\n", ie_hist_cont_reg.data); dpst_disable_post_process(g_dev); } mdfld_dsi_dsr_allow(dsi_config); power_island_put(OSPM_DISPLAY_A); } mutex_unlock(&dpst_mutex); return 0; }
/** * mdfld_save_display_registers - save registers for pipe * @dev: our device * @pipe: pipe to save * * Save the pipe state of the device before we power it off. Keep everything * we need to put it back again */ static int mdfld_save_display_registers(struct drm_device *dev, int pipe) { struct drm_psb_private *dev_priv = dev->dev_private; int i; /* register */ u32 dpll_reg = MRST_DPLL_A; u32 fp_reg = MRST_FPA0; u32 pipeconf_reg = PIPEACONF; u32 htot_reg = HTOTAL_A; u32 hblank_reg = HBLANK_A; u32 hsync_reg = HSYNC_A; u32 vtot_reg = VTOTAL_A; u32 vblank_reg = VBLANK_A; u32 vsync_reg = VSYNC_A; u32 pipesrc_reg = PIPEASRC; u32 dspstride_reg = DSPASTRIDE; u32 dsplinoff_reg = DSPALINOFF; u32 dsptileoff_reg = DSPATILEOFF; u32 dspsize_reg = DSPASIZE; u32 dsppos_reg = DSPAPOS; u32 dspsurf_reg = DSPASURF; u32 mipi_reg = MIPI; u32 dspcntr_reg = DSPACNTR; u32 dspstatus_reg = PIPEASTAT; u32 palette_reg = PALETTE_A; /* pointer to values */ u32 *dpll_val = &dev_priv->saveDPLL_A; u32 *fp_val = &dev_priv->saveFPA0; u32 *pipeconf_val = &dev_priv->savePIPEACONF; u32 *htot_val = &dev_priv->saveHTOTAL_A; u32 *hblank_val = &dev_priv->saveHBLANK_A; u32 *hsync_val = &dev_priv->saveHSYNC_A; u32 *vtot_val = &dev_priv->saveVTOTAL_A; u32 *vblank_val = &dev_priv->saveVBLANK_A; u32 *vsync_val = &dev_priv->saveVSYNC_A; u32 *pipesrc_val = &dev_priv->savePIPEASRC; u32 *dspstride_val = &dev_priv->saveDSPASTRIDE; u32 *dsplinoff_val = &dev_priv->saveDSPALINOFF; u32 *dsptileoff_val = &dev_priv->saveDSPATILEOFF; u32 *dspsize_val = &dev_priv->saveDSPASIZE; u32 *dsppos_val = &dev_priv->saveDSPAPOS; u32 *dspsurf_val = &dev_priv->saveDSPASURF; u32 *mipi_val = &dev_priv->saveMIPI; u32 *dspcntr_val = &dev_priv->saveDSPACNTR; u32 *dspstatus_val = &dev_priv->saveDSPASTATUS; u32 *palette_val = dev_priv->save_palette_a; switch (pipe) { case 0: break; case 1: /* register */ dpll_reg = MDFLD_DPLL_B; fp_reg = MDFLD_DPLL_DIV0; pipeconf_reg = PIPEBCONF; htot_reg = HTOTAL_B; hblank_reg = HBLANK_B; hsync_reg = HSYNC_B; vtot_reg = VTOTAL_B; vblank_reg = VBLANK_B; vsync_reg = VSYNC_B; pipesrc_reg = PIPEBSRC; dspstride_reg = DSPBSTRIDE; dsplinoff_reg = DSPBLINOFF; dsptileoff_reg = DSPBTILEOFF; dspsize_reg = DSPBSIZE; dsppos_reg = DSPBPOS; dspsurf_reg = DSPBSURF; dspcntr_reg = DSPBCNTR; dspstatus_reg = PIPEBSTAT; palette_reg = PALETTE_B; /* values */ dpll_val = &dev_priv->saveDPLL_B; fp_val = &dev_priv->saveFPB0; pipeconf_val = &dev_priv->savePIPEBCONF; htot_val = &dev_priv->saveHTOTAL_B; hblank_val = &dev_priv->saveHBLANK_B; hsync_val = &dev_priv->saveHSYNC_B; vtot_val = &dev_priv->saveVTOTAL_B; vblank_val = &dev_priv->saveVBLANK_B; vsync_val = &dev_priv->saveVSYNC_B; pipesrc_val = &dev_priv->savePIPEBSRC; dspstride_val = &dev_priv->saveDSPBSTRIDE; dsplinoff_val = &dev_priv->saveDSPBLINOFF; dsptileoff_val = &dev_priv->saveDSPBTILEOFF; dspsize_val = &dev_priv->saveDSPBSIZE; dsppos_val = &dev_priv->saveDSPBPOS; dspsurf_val = &dev_priv->saveDSPBSURF; dspcntr_val = &dev_priv->saveDSPBCNTR; dspstatus_val = &dev_priv->saveDSPBSTATUS; palette_val = dev_priv->save_palette_b; break; case 2: /* register */ pipeconf_reg = PIPECCONF; htot_reg = HTOTAL_C; hblank_reg = HBLANK_C; hsync_reg = HSYNC_C; vtot_reg = VTOTAL_C; vblank_reg = VBLANK_C; vsync_reg = VSYNC_C; pipesrc_reg = PIPECSRC; dspstride_reg = DSPCSTRIDE; dsplinoff_reg = DSPCLINOFF; dsptileoff_reg = DSPCTILEOFF; dspsize_reg = DSPCSIZE; dsppos_reg = DSPCPOS; dspsurf_reg = DSPCSURF; mipi_reg = MIPI_C; dspcntr_reg = DSPCCNTR; dspstatus_reg = PIPECSTAT; palette_reg = PALETTE_C; /* pointer to values */ pipeconf_val = &dev_priv->savePIPECCONF; htot_val = &dev_priv->saveHTOTAL_C; hblank_val = &dev_priv->saveHBLANK_C; hsync_val = &dev_priv->saveHSYNC_C; vtot_val = &dev_priv->saveVTOTAL_C; vblank_val = &dev_priv->saveVBLANK_C; vsync_val = &dev_priv->saveVSYNC_C; pipesrc_val = &dev_priv->savePIPECSRC; dspstride_val = &dev_priv->saveDSPCSTRIDE; dsplinoff_val = &dev_priv->saveDSPCLINOFF; dsptileoff_val = &dev_priv->saveDSPCTILEOFF; dspsize_val = &dev_priv->saveDSPCSIZE; dsppos_val = &dev_priv->saveDSPCPOS; dspsurf_val = &dev_priv->saveDSPCSURF; mipi_val = &dev_priv->saveMIPI_C; dspcntr_val = &dev_priv->saveDSPCCNTR; dspstatus_val = &dev_priv->saveDSPCSTATUS; palette_val = dev_priv->save_palette_c; break; default: DRM_ERROR("%s, invalid pipe number.\n", __func__); return -EINVAL; } /* Pipe & plane A info */ *dpll_val = PSB_RVDC32(dpll_reg); *fp_val = PSB_RVDC32(fp_reg); *pipeconf_val = PSB_RVDC32(pipeconf_reg); *htot_val = PSB_RVDC32(htot_reg); *hblank_val = PSB_RVDC32(hblank_reg); *hsync_val = PSB_RVDC32(hsync_reg); *vtot_val = PSB_RVDC32(vtot_reg); *vblank_val = PSB_RVDC32(vblank_reg); *vsync_val = PSB_RVDC32(vsync_reg); *pipesrc_val = PSB_RVDC32(pipesrc_reg); *dspstride_val = PSB_RVDC32(dspstride_reg); *dsplinoff_val = PSB_RVDC32(dsplinoff_reg); *dsptileoff_val = PSB_RVDC32(dsptileoff_reg); *dspsize_val = PSB_RVDC32(dspsize_reg); *dsppos_val = PSB_RVDC32(dsppos_reg); *dspsurf_val = PSB_RVDC32(dspsurf_reg); *dspcntr_val = PSB_RVDC32(dspcntr_reg); *dspstatus_val = PSB_RVDC32(dspstatus_reg); /*save palette (gamma) */ for (i = 0; i < 256; i++) palette_val[i] = PSB_RVDC32(palette_reg + (i<<2)); if (pipe == 1) { dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL); dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS); dev_priv->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL); dev_priv->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL); return 0; } *mipi_val = PSB_RVDC32(mipi_reg); return 0; }
/* * mdfld_save_display_registers * * Description: We are going to suspend so save current display * register state. * * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio */ static int mdfld_save_display_registers(struct drm_device *dev, int pipenum) { struct drm_psb_private *dev_priv = dev->dev_private; struct medfield_state *regs = &dev_priv->regs.mdfld; struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum]; const struct psb_offset *map = &dev_priv->regmap[pipenum]; int i; u32 *mipi_val; /* register */ u32 mipi_reg = MIPI; switch (pipenum) { case 0: mipi_val = ®s->saveMIPI; break; case 1: mipi_val = ®s->saveMIPI; break; case 2: /* register */ mipi_reg = MIPI_C; /* pointer to values */ mipi_val = ®s->saveMIPI_C; break; default: DRM_ERROR("%s, invalid pipe number.\n", __func__); return -EINVAL; } /* Pipe & plane A info */ pipe->dpll = PSB_RVDC32(map->dpll); pipe->fp0 = PSB_RVDC32(map->fp0); pipe->conf = PSB_RVDC32(map->conf); pipe->htotal = PSB_RVDC32(map->htotal); pipe->hblank = PSB_RVDC32(map->hblank); pipe->hsync = PSB_RVDC32(map->hsync); pipe->vtotal = PSB_RVDC32(map->vtotal); pipe->vblank = PSB_RVDC32(map->vblank); pipe->vsync = PSB_RVDC32(map->vsync); pipe->src = PSB_RVDC32(map->src); pipe->stride = PSB_RVDC32(map->stride); pipe->linoff = PSB_RVDC32(map->linoff); pipe->tileoff = PSB_RVDC32(map->tileoff); pipe->size = PSB_RVDC32(map->size); pipe->pos = PSB_RVDC32(map->pos); pipe->surf = PSB_RVDC32(map->surf); pipe->cntr = PSB_RVDC32(map->cntr); pipe->status = PSB_RVDC32(map->status); /*save palette (gamma) */ for (i = 0; i < 256; i++) pipe->palette[i] = PSB_RVDC32(map->palette + (i << 2)); if (pipenum == 1) { regs->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL); regs->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS); regs->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL); regs->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL); return 0; } *mipi_val = PSB_RVDC32(mipi_reg); return 0; }
/* * mdfld_restore_display_registers * * Description: We are going to resume so restore display register state. * * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio */ static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) { /* To get panel out of ULPS mode. */ u32 temp = 0; u32 device_ready_reg = DEVICE_READY_REG; struct drm_psb_private *dev_priv = dev->dev_private; struct mdfld_dsi_config *dsi_config = NULL; struct medfield_state *regs = &dev_priv->regs.mdfld; struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum]; const struct psb_offset *map = &dev_priv->regmap[pipenum]; u32 i; u32 dpll; u32 timeout = 0; /* register */ u32 mipi_reg = MIPI; /* values */ u32 dpll_val = pipe->dpll; u32 mipi_val = regs->saveMIPI; switch (pipenum) { case 0: dpll_val &= ~DPLL_VCO_ENABLE; dsi_config = dev_priv->dsi_configs[0]; break; case 1: dpll_val &= ~DPLL_VCO_ENABLE; break; case 2: mipi_reg = MIPI_C; mipi_val = regs->saveMIPI_C; dsi_config = dev_priv->dsi_configs[1]; break; default: DRM_ERROR("%s, invalid pipe number.\n", __func__); return -EINVAL; } /*make sure VGA plane is off. it initializes to on after reset!*/ PSB_WVDC32(0x80000000, VGACNTRL); if (pipenum == 1) { PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, map->dpll); PSB_RVDC32(map->dpll); PSB_WVDC32(pipe->fp0, map->fp0); } else { dpll = PSB_RVDC32(map->dpll); if (!(dpll & DPLL_VCO_ENABLE)) { /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */ if (dpll & MDFLD_PWR_GATE_EN) { dpll &= ~MDFLD_PWR_GATE_EN; PSB_WVDC32(dpll, map->dpll); /* FIXME_MDFLD PO - change 500 to 1 after PO */ udelay(500); } PSB_WVDC32(pipe->fp0, map->fp0); PSB_WVDC32(dpll_val, map->dpll); /* FIXME_MDFLD PO - change 500 to 1 after PO */ udelay(500); dpll_val |= DPLL_VCO_ENABLE; PSB_WVDC32(dpll_val, map->dpll); PSB_RVDC32(map->dpll); /* wait for DSI PLL to lock */ while (timeout < 20000 && !(PSB_RVDC32(map->conf) & PIPECONF_DSIPLL_LOCK)) { udelay(150); timeout++; } if (timeout == 20000) { DRM_ERROR("%s, can't lock DSIPLL.\n", __func__); return -EINVAL; } } } /* Restore mode */ PSB_WVDC32(pipe->htotal, map->htotal); PSB_WVDC32(pipe->hblank, map->hblank); PSB_WVDC32(pipe->hsync, map->hsync); PSB_WVDC32(pipe->vtotal, map->vtotal); PSB_WVDC32(pipe->vblank, map->vblank); PSB_WVDC32(pipe->vsync, map->vsync); PSB_WVDC32(pipe->src, map->src); PSB_WVDC32(pipe->status, map->status); /*set up the plane*/ PSB_WVDC32(pipe->stride, map->stride); PSB_WVDC32(pipe->linoff, map->linoff); PSB_WVDC32(pipe->tileoff, map->tileoff); PSB_WVDC32(pipe->size, map->size); PSB_WVDC32(pipe->pos, map->pos); PSB_WVDC32(pipe->surf, map->surf); if (pipenum == 1) { /* restore palette (gamma) */ /*DRM_UDELAY(50000); */ for (i = 0; i < 256; i++) PSB_WVDC32(pipe->palette[i], map->palette + (i << 2)); PSB_WVDC32(regs->savePFIT_CONTROL, PFIT_CONTROL); PSB_WVDC32(regs->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS); /*TODO: resume HDMI port */ /*TODO: resume pipe*/ /*enable the plane*/ PSB_WVDC32(pipe->cntr & ~DISPLAY_PLANE_ENABLE, map->cntr); return 0; } /*set up pipe related registers*/ PSB_WVDC32(mipi_val, mipi_reg); /*setup MIPI adapter + MIPI IP registers*/ if (dsi_config) mdfld_dsi_controller_init(dsi_config, pipenum); if (in_atomic() || in_interrupt()) mdelay(20); else msleep(20); /*enable the plane*/ PSB_WVDC32(pipe->cntr, map->cntr); if (in_atomic() || in_interrupt()) mdelay(20); else msleep(20); /* LP Hold Release */ temp = REG_READ(mipi_reg); temp |= LP_OUTPUT_HOLD_RELEASE; REG_WRITE(mipi_reg, temp); mdelay(1); /* Set DSI host to exit from Utra Low Power State */ temp = REG_READ(device_ready_reg); temp &= ~ULPS_MASK; temp |= 0x3; temp |= EXIT_ULPS_DEV_READY; REG_WRITE(device_ready_reg, temp); mdelay(1); temp = REG_READ(device_ready_reg); temp &= ~ULPS_MASK; temp |= EXITING_ULPS; REG_WRITE(device_ready_reg, temp); mdelay(1); /*enable the pipe*/ PSB_WVDC32(pipe->conf, map->conf); /* restore palette (gamma) */ /*DRM_UDELAY(50000); */ for (i = 0; i < 256; i++) PSB_WVDC32(pipe->palette[i], map->palette + (i << 2)); return 0; }
/* IOCTL - moved to standard calls for Kernel Integration */ int psb_hist_enable(struct drm_device *dev, void *data) { u32 irqCtrl = 0; struct drm_psb_private *dev_priv = psb_priv(dev); struct dpst_guardband guardband_reg; struct dpst_ie_histogram_control ie_hist_cont_reg; struct mdfld_dsi_hw_context *ctx = NULL; uint32_t * enable = data; struct mdfld_dsi_config *dsi_config = NULL; if (!dev_priv) return 0; dsi_config = dev_priv->dsi_configs[0]; if(!dsi_config) return 0; ctx = &dsi_config->dsi_hw_context; /* * FIXME: We need to force the Display to * turn on but on TNG OSPM how we can force PIPEA to do it? */ if (power_island_get(OSPM_DISPLAY_A)) { if (*enable == 1) { ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); ie_hist_cont_reg.ie_pipe_assignment = 0; ie_hist_cont_reg.histogram_mode_select = DPST_YUV_LUMA_MODE; ie_hist_cont_reg.ie_histogram_enable = 1; PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL); ctx->histogram_logic_ctrl = ie_hist_cont_reg.data; guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL); guardband_reg.interrupt_enable = 1; guardband_reg.interrupt_status = 1; PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL); ctx->histogram_intr_ctrl = guardband_reg.data; irqCtrl = PSB_RVDC32(PIPEASTAT); ctx->pipestat = (irqCtrl | PIPE_DPST_EVENT_ENABLE); PSB_WVDC32(ctx->pipestat, PIPEASTAT); /* Wait for two vblanks */ } else { guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL); guardband_reg.interrupt_enable = 0; guardband_reg.interrupt_status = 1; PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL); ctx->histogram_intr_ctrl = guardband_reg.data; ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); ie_hist_cont_reg.ie_histogram_enable = 0; PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL); ctx->histogram_logic_ctrl = ie_hist_cont_reg.data; irqCtrl = PSB_RVDC32(PIPEASTAT); irqCtrl &= ~PIPE_DPST_EVENT_ENABLE; PSB_WVDC32(irqCtrl, PIPEASTAT); ctx->pipestat = irqCtrl; dpst_disable_post_process(g_dev); } power_island_put(OSPM_DISPLAY_A); } return 0; }
/* * mdfld_restore_display_registers - restore the state of a pipe * @dev: our device * @pipe: the pipe to restore * * Restore the state of a pipe to that which was saved by the register save * functions. */ static int mdfld_restore_display_registers(struct drm_device *dev, int pipe) { /* To get panel out of ULPS mode */ struct drm_psb_private *dev_priv = dev->dev_private; struct mdfld_dsi_config *dsi_config = NULL; u32 i = 0; u32 dpll = 0; u32 timeout = 0; u32 reg_offset = 0; /* register */ u32 dpll_reg = MRST_DPLL_A; u32 fp_reg = MRST_FPA0; u32 pipeconf_reg = PIPEACONF; u32 htot_reg = HTOTAL_A; u32 hblank_reg = HBLANK_A; u32 hsync_reg = HSYNC_A; u32 vtot_reg = VTOTAL_A; u32 vblank_reg = VBLANK_A; u32 vsync_reg = VSYNC_A; u32 pipesrc_reg = PIPEASRC; u32 dspstride_reg = DSPASTRIDE; u32 dsplinoff_reg = DSPALINOFF; u32 dsptileoff_reg = DSPATILEOFF; u32 dspsize_reg = DSPASIZE; u32 dsppos_reg = DSPAPOS; u32 dspsurf_reg = DSPASURF; u32 dspstatus_reg = PIPEASTAT; u32 mipi_reg = MIPI; u32 dspcntr_reg = DSPACNTR; u32 palette_reg = PALETTE_A; /* values */ u32 dpll_val = dev_priv->saveDPLL_A & ~DPLL_VCO_ENABLE; u32 fp_val = dev_priv->saveFPA0; u32 pipeconf_val = dev_priv->savePIPEACONF; u32 htot_val = dev_priv->saveHTOTAL_A; u32 hblank_val = dev_priv->saveHBLANK_A; u32 hsync_val = dev_priv->saveHSYNC_A; u32 vtot_val = dev_priv->saveVTOTAL_A; u32 vblank_val = dev_priv->saveVBLANK_A; u32 vsync_val = dev_priv->saveVSYNC_A; u32 pipesrc_val = dev_priv->savePIPEASRC; u32 dspstride_val = dev_priv->saveDSPASTRIDE; u32 dsplinoff_val = dev_priv->saveDSPALINOFF; u32 dsptileoff_val = dev_priv->saveDSPATILEOFF; u32 dspsize_val = dev_priv->saveDSPASIZE; u32 dsppos_val = dev_priv->saveDSPAPOS; u32 dspsurf_val = dev_priv->saveDSPASURF; u32 dspstatus_val = dev_priv->saveDSPASTATUS; u32 mipi_val = dev_priv->saveMIPI; u32 dspcntr_val = dev_priv->saveDSPACNTR; u32 *palette_val = dev_priv->save_palette_a; switch (pipe) { case 0: dsi_config = dev_priv->dsi_configs[0]; break; case 1: /* register */ dpll_reg = MDFLD_DPLL_B; fp_reg = MDFLD_DPLL_DIV0; pipeconf_reg = PIPEBCONF; htot_reg = HTOTAL_B; hblank_reg = HBLANK_B; hsync_reg = HSYNC_B; vtot_reg = VTOTAL_B; vblank_reg = VBLANK_B; vsync_reg = VSYNC_B; pipesrc_reg = PIPEBSRC; dspstride_reg = DSPBSTRIDE; dsplinoff_reg = DSPBLINOFF; dsptileoff_reg = DSPBTILEOFF; dspsize_reg = DSPBSIZE; dsppos_reg = DSPBPOS; dspsurf_reg = DSPBSURF; dspcntr_reg = DSPBCNTR; palette_reg = PALETTE_B; dspstatus_reg = PIPEBSTAT; /* values */ dpll_val = dev_priv->saveDPLL_B & ~DPLL_VCO_ENABLE; fp_val = dev_priv->saveFPB0; pipeconf_val = dev_priv->savePIPEBCONF; htot_val = dev_priv->saveHTOTAL_B; hblank_val = dev_priv->saveHBLANK_B; hsync_val = dev_priv->saveHSYNC_B; vtot_val = dev_priv->saveVTOTAL_B; vblank_val = dev_priv->saveVBLANK_B; vsync_val = dev_priv->saveVSYNC_B; pipesrc_val = dev_priv->savePIPEBSRC; dspstride_val = dev_priv->saveDSPBSTRIDE; dsplinoff_val = dev_priv->saveDSPBLINOFF; dsptileoff_val = dev_priv->saveDSPBTILEOFF; dspsize_val = dev_priv->saveDSPBSIZE; dsppos_val = dev_priv->saveDSPBPOS; dspsurf_val = dev_priv->saveDSPBSURF; dspcntr_val = dev_priv->saveDSPBCNTR; dspstatus_val = dev_priv->saveDSPBSTATUS; palette_val = dev_priv->save_palette_b; break; case 2: reg_offset = MIPIC_REG_OFFSET; /* register */ pipeconf_reg = PIPECCONF; htot_reg = HTOTAL_C; hblank_reg = HBLANK_C; hsync_reg = HSYNC_C; vtot_reg = VTOTAL_C; vblank_reg = VBLANK_C; vsync_reg = VSYNC_C; pipesrc_reg = PIPECSRC; dspstride_reg = DSPCSTRIDE; dsplinoff_reg = DSPCLINOFF; dsptileoff_reg = DSPCTILEOFF; dspsize_reg = DSPCSIZE; dsppos_reg = DSPCPOS; dspsurf_reg = DSPCSURF; mipi_reg = MIPI_C; dspcntr_reg = DSPCCNTR; palette_reg = PALETTE_C; dspstatus_reg = PIPECSTAT; /* values */ pipeconf_val = dev_priv->savePIPECCONF; htot_val = dev_priv->saveHTOTAL_C; hblank_val = dev_priv->saveHBLANK_C; hsync_val = dev_priv->saveHSYNC_C; vtot_val = dev_priv->saveVTOTAL_C; vblank_val = dev_priv->saveVBLANK_C; vsync_val = dev_priv->saveVSYNC_C; pipesrc_val = dev_priv->savePIPECSRC; dspstride_val = dev_priv->saveDSPCSTRIDE; dsplinoff_val = dev_priv->saveDSPCLINOFF; dsptileoff_val = dev_priv->saveDSPCTILEOFF; dspsize_val = dev_priv->saveDSPCSIZE; dsppos_val = dev_priv->saveDSPCPOS; dspsurf_val = dev_priv->saveDSPCSURF; dspstatus_val = dev_priv->saveDSPCSTATUS; mipi_val = dev_priv->saveMIPI_C; dspcntr_val = dev_priv->saveDSPCCNTR; palette_val = dev_priv->save_palette_c; dsi_config = dev_priv->dsi_configs[1]; break; default: DRM_ERROR("%s, invalid pipe number.\n", __func__); return -EINVAL; } /* Make sure VGA plane is off. it initializes to on after reset!*/ PSB_WVDC32(0x80000000, VGACNTRL); if (pipe == 1) { PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg); PSB_RVDC32(dpll_reg); PSB_WVDC32(fp_val, fp_reg); } else { dpll = PSB_RVDC32(dpll_reg); if (!(dpll & DPLL_VCO_ENABLE)) { /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */ if (dpll & MDFLD_PWR_GATE_EN) { dpll &= ~MDFLD_PWR_GATE_EN; PSB_WVDC32(dpll, dpll_reg); udelay(500); /* FIXME: 1 ? */ } PSB_WVDC32(fp_val, fp_reg); PSB_WVDC32(dpll_val, dpll_reg); /* FIXME_MDFLD PO - change 500 to 1 after PO */ udelay(500); dpll_val |= DPLL_VCO_ENABLE; PSB_WVDC32(dpll_val, dpll_reg); PSB_RVDC32(dpll_reg); /* wait for DSI PLL to lock */ while ((timeout < 20000) && !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) { udelay(150); timeout++; } if (timeout == 20000) { DRM_ERROR("%s, can't lock DSIPLL.\n", __func__); return -EINVAL; } } } /* Restore mode */ PSB_WVDC32(htot_val, htot_reg); PSB_WVDC32(hblank_val, hblank_reg); PSB_WVDC32(hsync_val, hsync_reg); PSB_WVDC32(vtot_val, vtot_reg); PSB_WVDC32(vblank_val, vblank_reg); PSB_WVDC32(vsync_val, vsync_reg); PSB_WVDC32(pipesrc_val, pipesrc_reg); PSB_WVDC32(dspstatus_val, dspstatus_reg); /* Set up the plane */ PSB_WVDC32(dspstride_val, dspstride_reg); PSB_WVDC32(dsplinoff_val, dsplinoff_reg); PSB_WVDC32(dsptileoff_val, dsptileoff_reg); PSB_WVDC32(dspsize_val, dspsize_reg); PSB_WVDC32(dsppos_val, dsppos_reg); PSB_WVDC32(dspsurf_val, dspsurf_reg); if (pipe == 1) { PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL); PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS); PSB_WVDC32(dev_priv->saveHDMIPHYMISCCTL, HDMIPHYMISCCTL); PSB_WVDC32(dev_priv->saveHDMIB_CONTROL, HDMIB_CONTROL); } else { /* Set up pipe related registers */ PSB_WVDC32(mipi_val, mipi_reg); /* Setup MIPI adapter + MIPI IP registers */ mdfld_dsi_controller_init(dsi_config, pipe); msleep(20); } /* Enable the plane */ PSB_WVDC32(dspcntr_val, dspcntr_reg); msleep(20); /* Enable the pipe */ PSB_WVDC32(pipeconf_val, pipeconf_reg); for (i = 0; i < 256; i++) PSB_WVDC32(palette_val[i], palette_reg + (i<<2)); if (pipe == 1) return 0; if (!mdfld_panel_dpi(dev)) mdfld_enable_te(dev, pipe); return 0; }