void enable_HFPLL(struct drm_device *dev) { uint32_t pll_select = 0, ctrl_reg5 = 0; struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private; /* Enable HFPLL for command mode panel */ if (dev_priv->bUseHFPLL) { pll_select = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); ctrl_reg5 = intel_mid_msgbus_read32(CCK_PORT, FUSE_OVERRIDE_FREQ_CNTRL_REG5); pll_select &= ~(_DSI_MUX_SEL_CCK_DSI1 | _DSI_MUX_SEL_CCK_DSI0); intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, pll_select | _DSI_CCK_PLL_SELECT); ctrl_reg5 |= (1 << 7) | 0xF; if (get_panel_type(dev, 0) == SHARP_10x19_CMD) ctrl_reg5 = 0x1f87; intel_mid_msgbus_write32(CCK_PORT, FUSE_OVERRIDE_FREQ_CNTRL_REG5, ctrl_reg5); } }
void enable_HFPLL(struct drm_device *dev) { uint32_t pll_select = 0, ctrl_reg5 = 0; struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private; /* Enable HFPLL for B0 command mode panel */ if ((IS_TNG_B0(dev)) && (dev_priv->mipi_encoder_type == MDFLD_DSI_ENCODER_DBI)) { pll_select = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); ctrl_reg5 = intel_mid_msgbus_read32(CCK_PORT, FUSE_OVERRIDE_FREQ_CNTRL_REG5); pll_select &= ~(_DSI_MUX_SEL_CCK_DSI1 | _DSI_MUX_SEL_CCK_DSI0); intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, pll_select | _DSI_CCK_PLL_SELECT); ctrl_reg5 |= (1 << 7) | 0xF; intel_mid_msgbus_write32(CCK_PORT, FUSE_OVERRIDE_FREQ_CNTRL_REG5, ctrl_reg5); } }
void power_on_pipe(u32 msg_port, u32 msg_reg, u32 val_comp, u32 val_write) { u32 ret; int retry=0; ret = intel_mid_msgbus_read32(msg_port, msg_reg); if ((ret & val_comp) == 0) { DRM_ERROR("%s: pipe is already powered on\n", __func__); return; } else { intel_mid_msgbus_write32(msg_port, msg_reg, ret & val_write); ret = intel_mid_msgbus_read32(msg_port, msg_reg); while ((retry < 1000) && ((ret & val_comp) != 0)) { msleep(1); ret = intel_mid_msgbus_read32(msg_port, msg_reg); retry++; } if ((ret & val_comp) != 0) DRM_ERROR("%s: powering on pipe failed\n", __func__); if (msg_port == 0x4 && msg_reg == 0x3b) { DRM_ERROR("%s: skip powering up MIO AFE\n", __func__); } } }
void power_off_pipe(u32 msg_port, u32 msg_reg, u32 val, u32 val_comp) { u32 ret; int retry=0; ret = intel_mid_msgbus_read32(msg_port, msg_reg); intel_mid_msgbus_write32(msg_port, msg_reg, ret | val); ret = intel_mid_msgbus_read32(msg_port, msg_reg); if (((ret & val_comp) != val_comp) && (retry < 1000)) { retry++; ret = intel_mid_msgbus_read32(msg_port, msg_reg); } }
static int wait_for_nc_pmcmd_complete(int verify_mask, int status_mask, int state_type , int reg) { int pwr_sts; int count = 0; while (true) { pwr_sts = intel_mid_msgbus_read32(PUNIT_PORT, reg); pwr_sts = pwr_sts >> SSS_SHIFT; if (state_type == OSPM_ISLAND_DOWN || state_type == OSPM_ISLAND_SR) { if ((pwr_sts & status_mask) == (verify_mask & status_mask)) break; else udelay(10); } else if (state_type == OSPM_ISLAND_UP) { if ((~pwr_sts & status_mask) == (~verify_mask & status_mask)) break; else udelay(10); } count++; if (WARN_ONCE(count > 500000, "Timed out waiting for P-Unit")) return -EBUSY; } return 0; }
static int punit_read_reg_gfxsspm1(int attempts, int interval_us, u32 *p_reg_value) { int ui_count; *p_reg_value = 0; if(!p_reg_value) return -EINVAL; for (ui_count = 0; ; ui_count++) { *p_reg_value = intel_mid_msgbus_read32(PUNIT_PORT, GFX_SS_PM1); if(*p_reg_value) { #if defined(RGX_POW_MON_DEBUG) && RGX_POW_MON_DEBUG printk(KERN_ALERT "punit_read_reg_gfxsspm1: read reg value: %0x\n", *p_reg_value); #endif break; } if (ui_count >= attempts) return -EBUSY; udelay(interval_us); } return 0; }
bool disable_DSIPLL(struct drm_device * dev) { u32 val, guit_val; /* Disable PLL*/ intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, 0); val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); val &= ~_CLK_EN_MASK; intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, val); udelay(1); val &= ~DPLL_VCO_ENABLE; val |= _DSI_LDO_EN; intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, val); udelay(1); guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); if ((guit_val & _DSI_PLL_LOCK) == _DSI_PLL_LOCK ) { DRM_ERROR("DSI PLL fails to Unlock\n"); return false; } return true; }
/* This function checks north complex (NC) and * south complex (SC) device status in MRFLD. * returns TRUE if all NC and SC devices are in d0i3 * else FALSE. */ static bool mrfld_nc_sc_status_check(void) { int i; u32 val, nc_pwr_sts; struct pmu_ss_states cur_pmsss; bool nc_status, sc_status; /* assuming nc and sc are good */ nc_status = true; sc_status = true; /* Check south complex device status */ pmu_read_sss(&cur_pmsss); if (!(((cur_pmsss.pmu2_states[0] & S0IX_TARGET_SSS0_MASK) == S0IX_TARGET_SSS0) && ((cur_pmsss.pmu2_states[1] & S0IX_TARGET_SSS1_MASK) == S0IX_TARGET_SSS1) && ((cur_pmsss.pmu2_states[2] & S0IX_TARGET_SSS2_MASK) == S0IX_TARGET_SSS2) && ((cur_pmsss.pmu2_states[3] & S0IX_TARGET_SSS3_MASK) == (S0IX_TARGET_SSS3)))) { sc_status = false; pr_warn("SC device/devices not in d0i3!!\n"); } if (sc_status) { /* Check north complex status */ nc_pwr_sts = intel_mid_msgbus_read32(PUNIT_PORT, NC_PM_SSS); /* loop through the status to see if any of nc power island * is not in D0i3 state */ for (i = 0; i < mrfl_no_of_nc_devices; i++) { val = nc_pwr_sts & 3; if (val != 3) { nc_status = false; pr_warn("NC device/devices is not in D0i3!!\n"); break; } nc_pwr_sts >>= BITS_PER_LSS; } } return nc_status & sc_status; }
static int mrfld_nc_set_power_state(int islands, int state_type, int reg, int *change) { u32 pwr_sts = 0; u32 pwr_mask = 0; int i, lss, mask; int ret = 0; int status_mask = 0; *change = 0; pwr_sts = intel_mid_msgbus_read32(PUNIT_PORT, reg); pwr_mask = pwr_sts; for (i = 0; i < OSPM_MAX_POWER_ISLANDS; i++) { lss = islands & (0x1 << i); if (lss) { mask = D0I3_MASK << (BITS_PER_LSS * i); status_mask = status_mask | mask; if (state_type == OSPM_ISLAND_DOWN) pwr_mask |= mask; else if (state_type == OSPM_ISLAND_UP) pwr_mask &= ~mask; /* Soft reset case */ else if (state_type == OSPM_ISLAND_SR) { pwr_mask &= ~mask; mask = SR_MASK << (BITS_PER_LSS * i); pwr_mask |= mask; } } } if (pwr_mask != pwr_sts) { intel_mid_msgbus_write32(PUNIT_PORT, reg, pwr_mask); ret = wait_for_nc_pmcmd_complete(pwr_mask, status_mask, state_type, reg); if (!ret) *change = 1; if (nc_report_power_state) nc_report_power_state(pwr_mask, reg); } return ret; }
static int atomisp_save_iunit_reg(struct atomisp_device *isp) { struct pci_dev *dev = isp->pdev; dev_dbg(isp->dev, "%s\n", __func__); pci_read_config_word(dev, PCI_COMMAND, &isp->saved_regs.pcicmdsts); /* isp->saved_regs.ispmmadr is set from the atomisp_pci_probe() */ pci_read_config_dword(dev, PCI_MSI_CAPID, &isp->saved_regs.msicap); pci_read_config_dword(dev, PCI_MSI_ADDR, &isp->saved_regs.msi_addr); pci_read_config_word(dev, PCI_MSI_DATA, &isp->saved_regs.msi_data); pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &isp->saved_regs.intr); pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &isp->saved_regs.interrupt_control); if (IS_ISP2400) { pci_read_config_dword(dev, MRFLD_PCI_PMCS, &isp->saved_regs.pmcs); /* Ensure read/write combining is enabled. */ pci_read_config_dword(dev, PCI_I_CONTROL, &isp->saved_regs.i_control); isp->saved_regs.i_control |= MRFLD_PCI_I_CONTROL_ENABLE_READ_COMBINING | MRFLD_PCI_I_CONTROL_ENABLE_WRITE_COMBINING; pci_read_config_dword(dev, MRFLD_PCI_CSI_ACCESS_CTRL_VIOL, &isp->saved_regs.csi_access_viol); pci_read_config_dword(dev, MRFLD_PCI_CSI_RCOMP_CONTROL, &isp->saved_regs.csi_rcomp_config); pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, &isp->saved_regs.csi_afe_dly); pci_read_config_dword(dev, MRFLD_PCI_CSI_CONTROL, &isp->saved_regs.csi_control); pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_RCOMP_CONTROL, &isp->saved_regs.csi_afe_rcomp_config); pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_HS_CONTROL, &isp->saved_regs.csi_afe_hs_control); pci_read_config_dword(dev, MRFLD_PCI_CSI_DEADLINE_CONTROL, &isp->saved_regs.csi_deadline_control); } else { pci_read_config_dword(dev, MFLD_PCI_PMCS, &isp->saved_regs.pmcs); /* Ensure clock gating for ISPCLK, PERF and NOA monitoring. */ pci_read_config_dword(dev, MFLD_PCI_CG_DIS, &isp->saved_regs.cg_dis); isp->saved_regs.cg_dis &= ~(MFLD_PCI_CG_DIS_DISABLED_ISPCLK | MFLD_PCI_CG_DIS_DISABLED_PERF_MON | MFLD_PCI_CG_DIS_DISABLED_NOA_MON); /* Ensure read/write combining is enabled. */ pci_read_config_dword(dev, PCI_I_CONTROL, &isp->saved_regs.i_control); isp->saved_regs.i_control |= MFLD_PCI_I_CONTROL_ENABLE_READ_COMBINING | MFLD_PCI_I_CONTROL_ENABLE_WRITE_COMBINING; isp->saved_regs.csi_rcomp_config = intel_mid_msgbus_read32( MFLD_IUNITPHY_PORT, MFLD_CSI_RCOMP); isp->saved_regs.csi_afe_dly = intel_mid_msgbus_read32( MFLD_IUNITPHY_PORT, MFLD_CSI_AFE); /* Ensure mipi1 and mipi4 configurations are enabled */ isp->saved_regs.csi_control = intel_mid_msgbus_read32( MFLD_IUNITPHY_PORT, MFLD_CSI_CONTROL); isp->saved_regs.csi_control &= ~(MFLD_CSI_CONTROL_DIS_MIPI4_IF | MFLD_CSI_CONTROL_DIS_MIPI1_IF); isp->saved_regs.csi_control |= MFLD_CSI_CONTROL_EN_MIPI4_LANE | MFLD_CSI_CONTROL_EN_MIPI1_LANE; } return 0; }
static inline u32 read_soc_reg(unsigned int addr) { return intel_mid_msgbus_read32(PUNIT_PORT, addr); }
/** * Power off sequence for video mode MIPI panel. * NOTE: do NOT modify this function */ static int __dpi_panel_power_off(struct mdfld_dsi_config *dsi_config, struct panel_funcs *p_funcs) { u32 val = 0; u32 tmp = 0; struct mdfld_dsi_hw_registers *regs; struct mdfld_dsi_hw_context *ctx; struct drm_device *dev; struct drm_psb_private *dev_priv; int retry; int i; int err = 0; u32 guit_val = 0; u32 power_island = 0; int offset = 0; PSB_DEBUG_ENTRY("\n"); if (!dsi_config) return -EINVAL; regs = &dsi_config->regs; ctx = &dsi_config->dsi_hw_context; dev = dsi_config->dev; dev_priv = dev->dev_private; /* Don't reset brightness to 0.*/ ctx->lastbrightnesslevel = psb_brightness; tmp = REG_READ(regs->pipeconf_reg); /*save color_coef (chrome) */ for (i = 0; i < 6; i++) ctx->color_coef[i] = REG_READ(regs->color_coef_reg + (i<<2)); /* save palette (gamma) */ for (i = 0; i < 256; i++) ctx->palette[i] = REG_READ(regs->palette_reg + (i<<2)); /* * Couldn't disable the pipe until DRM_WAIT_ON signaled by last * vblank event when playing video, otherwise the last vblank event * will lost when pipe disabled before vblank interrupt coming * sometimes. */ /*Disable panel*/ val = ctx->dspcntr; REG_WRITE(regs->dspcntr_reg, (val & ~BIT31)); /*Disable overlay & cursor panel assigned to this pipe*/ REG_WRITE(regs->pipeconf_reg, (tmp | (0x000c0000))); /*Disable pipe*/ val = REG_READ(regs->pipeconf_reg); ctx->pipeconf = val; REG_WRITE(regs->pipeconf_reg, (val & ~BIT31)); /*wait for pipe disabling, pipe synchronization plus , only avaiable when timer generator is working*/ if (REG_READ(regs->mipi_reg) & BIT31) { retry = 100000; while (--retry && (REG_READ(regs->pipeconf_reg) & BIT30)) udelay(5); if (!retry) { DRM_ERROR("Failed to disable pipe\n"); err = -EAGAIN; goto power_off_err; } } /** * Different panel may have different ways to have * panel turned off. Support it! */ if (p_funcs && p_funcs->power_off) { if (p_funcs->power_off(dsi_config)) { DRM_ERROR("Failed to power off panel\n"); err = -EAGAIN; goto power_off_err; } } /*Disable MIPI port*/ REG_WRITE(regs->mipi_reg, (REG_READ(regs->mipi_reg) & ~BIT31)); /*clear Low power output hold*/ REG_WRITE(regs->mipi_reg, (REG_READ(regs->mipi_reg) & ~BIT16)); /*Disable DSI controller*/ REG_WRITE(regs->device_ready_reg, (ctx->device_ready & ~BIT0)); /*enter ULPS*/ __dpi_enter_ulps_locked(dsi_config, offset); if (is_dual_dsi(dev)) { offset = 0x1000; /*Disable MIPI port*/ REG_WRITE(regs->mipi_reg, (REG_READ(regs->mipi_reg) & ~BIT31)); /*clear Low power output hold*/ REG_WRITE(regs->mipi_reg, (REG_READ(regs->mipi_reg) & ~BIT16)); offset = 0x800; /*Disable DSI controller*/ REG_WRITE(regs->device_ready_reg, (ctx->device_ready & ~BIT0)); /*enter ULPS*/ __dpi_enter_ulps_locked(dsi_config, offset); offset = 0x0; } /* Disable DSI PLL */ intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, 0); guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, _DSI_LDO_EN); power_off_err: power_island = pipe_to_island(dsi_config->pipe); if (power_island & (OSPM_DISPLAY_A | OSPM_DISPLAY_C)) power_island |= OSPM_DISPLAY_MIO; if (is_dual_dsi(dev)) power_island |= OSPM_DISPLAY_C; if (!power_island_put(power_island)) return -EINVAL; return err; }
/** * Power on sequence for video mode MIPI panel. * NOTE: do NOT modify this function */ static int __dpi_panel_power_on(struct mdfld_dsi_config *dsi_config, struct panel_funcs *p_funcs) { u32 val = 0; struct mdfld_dsi_hw_registers *regs; struct mdfld_dsi_hw_context *ctx; struct drm_psb_private *dev_priv; struct drm_device *dev; int retry, reset_count = 10; int i; int err = 0; u32 guit_val = 0; u32 power_island = 0; int offset = 0; PSB_DEBUG_ENTRY("\n"); if (!dsi_config) return -EINVAL; regs = &dsi_config->regs; ctx = &dsi_config->dsi_hw_context; dev = dsi_config->dev; dev_priv = dev->dev_private; power_island = pipe_to_island(dsi_config->pipe); if (power_island & (OSPM_DISPLAY_A | OSPM_DISPLAY_C)) power_island |= OSPM_DISPLAY_MIO; if (is_dual_dsi(dev)) power_island |= OSPM_DISPLAY_C; if (!power_island_get(power_island)) return -EAGAIN; reset_recovery: --reset_count; /*HW-Reset*/ if (p_funcs && p_funcs->reset) p_funcs->reset(dsi_config); if (!is_dual_dsi(dev)) { /* Disable PLL*/ intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, 0); guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, _DSI_LDO_EN); /* Program PLL */ intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, ctx->fp); guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, ((guit_val & ~_P1_POST_DIV_MASK) | (ctx->dpll & _P1_POST_DIV_MASK))); ctx->dpll |= DPLL_VCO_ENABLE; ctx->dpll &= ~_DSI_LDO_EN; intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, ctx->dpll); } else { intel_mid_msgbus_write32(CCK_PORT, 0x68, 0x682); /* Disable PLL*/ intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, 0); guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, _DSI_LDO_EN); /* Program PLL */ intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, ctx->fp); guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, ((guit_val & ~_P1_POST_DIV_MASK) | (ctx->dpll & _P1_POST_DIV_MASK))); guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); ctx->dpll |= DPLL_VCO_ENABLE; ctx->dpll &= ~(_DSI_LDO_EN | _CLK_EN_CCK_DSI0 | _CLK_EN_CCK_DSI1 | _DSI_MUX_SEL_CCK_DSI1 | _DSI_MUX_SEL_CCK_DSI0); ctx->dpll |= _CLK_EN_PLL_DSI0 | _CLK_EN_PLL_DSI1; intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, ctx->dpll); } /* Wait for DSI PLL lock */ retry = 10000; guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); while (((guit_val & _DSI_PLL_LOCK) != _DSI_PLL_LOCK) && (--retry)) { udelay(3); guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); if (retry == 0) { DRM_ERROR("DSI PLL fails to lock\n"); err = -EAGAIN; goto power_on_err; } } /* * Wait for DSI PLL locked on pipe, and only need to poll status of pipe * A as both MIPI pipes share the same DSI PLL. */ if (dsi_config->pipe == 0) { retry = 20000; while (!(REG_READ(regs->pipeconf_reg) & PIPECONF_DSIPLL_LOCK) && --retry) udelay(150); if (!retry) { DRM_ERROR("PLL failed to lock on pipe\n"); err = -EAGAIN; goto power_on_err; } } __dpi_set_properties(dsi_config, PORT_A); /*Setup pipe timing*/ REG_WRITE(regs->htotal_reg, ctx->htotal); REG_WRITE(regs->hblank_reg, ctx->hblank); REG_WRITE(regs->hsync_reg, ctx->hsync); REG_WRITE(regs->vtotal_reg, ctx->vtotal); REG_WRITE(regs->vblank_reg, ctx->vblank); REG_WRITE(regs->vsync_reg, ctx->vsync); REG_WRITE(regs->pipesrc_reg, ctx->pipesrc); REG_WRITE(regs->dsppos_reg, ctx->dsppos); REG_WRITE(regs->dspstride_reg, ctx->dspstride); if (IS_ANN_A0(dev)) { /*reset registers*/ REG_WRITE(0x7002C, 0x000A0200); REG_WRITE(0x70508, 0x0c0c0c0c); REG_WRITE(0x70504, 0xffffffff); REG_WRITE(0x70500, 0xffffffff); DRM_DEBUG("LOADING: 0x70504 %#x\n", REG_READ(0x70504)); } /*Setup plane*/ REG_WRITE(regs->dspsize_reg, ctx->dspsize); REG_WRITE(regs->dspsurf_reg, ctx->dspsurf); REG_WRITE(regs->dsplinoff_reg, ctx->dsplinoff); REG_WRITE(regs->vgacntr_reg, ctx->vgacntr); /*restore color_coef (chrome) */ for (i = 0; i < 6; i++) REG_WRITE(regs->color_coef_reg + (i<<2), ctx->color_coef[i]); /* restore palette (gamma) */ for (i = 0; i < 256; i++) REG_WRITE(regs->palette_reg + (i<<2), ctx->palette[i]); /* restore dpst setting */ if (dev_priv->psb_dpst_state) { dpstmgr_reg_restore_locked(dev, dsi_config); psb_enable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); } if (__dpi_config_port(dsi_config, p_funcs, PORT_A) != 0) { if (!reset_count) { err = -EAGAIN; goto power_on_err; } DRM_ERROR("Failed to init dsi controller, reset it!\n"); goto reset_recovery; } if (is_dual_dsi(dev)) { __dpi_set_properties(dsi_config, PORT_C); __dpi_config_port(dsi_config, p_funcs, PORT_C); } /** * Different panel may have different ways to have * drvIC initialized. Support it! */ if (p_funcs && p_funcs->drv_ic_init) { if (p_funcs->drv_ic_init(dsi_config)) { if (!reset_count) { err = -EAGAIN; goto power_on_err; } DRM_ERROR("Failed to init dsi controller, reset it!\n"); goto reset_recovery; } } /*Enable MIPI Port A*/ offset = 0x0; REG_WRITE(regs->mipi_reg + offset, (ctx->mipi | BIT31)); REG_WRITE(regs->dpi_control_reg + offset, BIT1); if (is_dual_dsi(dev)) { /*Enable MIPI Port C*/ offset = 0x1000; REG_WRITE(regs->mipi_reg + offset, (ctx->mipi | BIT31)); offset = 0x800; REG_WRITE(regs->dpi_control_reg + offset, BIT1); } /** * Different panel may have different ways to have * panel turned on. Support it! */ if (p_funcs && p_funcs->power_on) if (p_funcs->power_on(dsi_config)) { DRM_ERROR("Failed to power on panel\n"); err = -EAGAIN; goto power_on_err; } /*Enable pipe*/ val = ctx->pipeconf; val &= ~0x000c0000; val |= BIT31; REG_WRITE(regs->pipeconf_reg, val); /*Wait for pipe enabling,when timing generator is wroking */ if (REG_READ(regs->mipi_reg) & BIT31) { retry = 10000; while (--retry && !(REG_READ(regs->pipeconf_reg) & BIT30)) udelay(3); if (!retry) { DRM_ERROR("Failed to enable pipe\n"); err = -EAGAIN; goto power_on_err; } } /*enable plane*/ val = ctx->dspcntr | BIT31; REG_WRITE(regs->dspcntr_reg, val); if (p_funcs && p_funcs->set_brightness) { if (p_funcs->set_brightness(dsi_config, ctx->lastbrightnesslevel)) DRM_ERROR("Failed to set panel brightness\n"); } else { DRM_ERROR("Failed to set panel brightness\n"); } if (p_funcs && p_funcs->drv_set_panel_mode) p_funcs->drv_set_panel_mode(dsi_config); psb_enable_vblank(dev, dsi_config->pipe); return err; power_on_err: power_island_put(power_island); return err; }
bool enable_DSIPLL(struct drm_device *dev) { DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private; struct mdfld_dsi_config *dsi_config = NULL; struct mdfld_dsi_hw_context *ctx = NULL; u32 guit_val = 0x0; u32 retry; if (!dev_priv) goto err_out; dsi_config = dev_priv->dsi_configs[0]; if (!dsi_config) goto err_out; ctx = &dsi_config->dsi_hw_context; if (IS_ANN(dev)) { int dspfreq; if ((get_panel_type(dev, 0) == JDI_7x12_CMD) || (get_panel_type(dev, 0) == JDI_7x12_VID)) dspfreq = DISPLAY_FREQ_FOR_200; else dspfreq = DISPLAY_FREQ_FOR_333; intel_mid_msgbus_write32(CCK_PORT, FUSE_OVERRIDE_FREQ_CNTRL_REG5, CKESC_GATE_EN | CKDP1X_GATE_EN | DISPLAY_FRE_EN | dspfreq); } /* Prepare DSI PLL register before enabling */ intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, 0); guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); guit_val &= ~(DPLL_VCO_ENABLE | _DSI_LDO_EN |_CLK_EN_MASK | _DSI_MUX_SEL_CCK_DSI0 | _DSI_MUX_SEL_CCK_DSI1); intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, guit_val); udelay(1); /* Program PLL */ /*first set up the dpll and fp variables * dpll - will contain the following information * - the clock source - DSI vs HFH vs LFH PLL * - what clocks should be running DSI0, DSI1 * - and the divisor. * */ intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, ctx->fp); guit_val &= ~_P1_POST_DIV_MASK; /*clear the divisor bit*/ /* the ctx->dpll contains the divisor that we need to use as well as which clocks * need to start up */ guit_val |= ctx->dpll; guit_val &= ~_DSI_LDO_EN; /* We want to clear the LDO enable when programming*/ guit_val |= DPLL_VCO_ENABLE; /* Enable the DSI PLL */ /* For the CD clock (clock used by Display controller), we need to set * the DSI_CCK_PLL_SELECT bit (bit 11). This should already be set. But * setting it just in case */ if (dev_priv->bUseHFPLL) guit_val |= _DSI_CCK_PLL_SELECT; intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, guit_val); /* Wait for DSI PLL lock */ retry = 10000; guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); while (((guit_val & _DSI_PLL_LOCK) != _DSI_PLL_LOCK) && (--retry)) { udelay(3); guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG); if (!retry%1000) DRM_ERROR("DSI PLL taking too long to lock" "- retry count=%d\n", 10000-retry); } if (retry == 0) { DRM_ERROR("DSI PLL fails to lock\n"); return false; } return true; err_out: return false; }
int vsp_init_fw(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; struct vsp_private *vsp_priv = dev_priv->vsp_private; int ret = 0; const struct firmware *raw; unsigned char *ptr, *ma_ptr; struct vsp_secure_boot_header *boot_header; struct vsp_multi_app_blob_data *ma_header; unsigned long imr_addr; int imr_size; unsigned char *imr_ptr; unsigned int vrl_header_size = 736; const unsigned long vsp_magic_num = 0x50535624; const int FW_NAME_LEN = 30; char fw_name[FW_NAME_LEN]; int name_ret; PSB_DEBUG_GENERAL("read firmware into buffer\n"); name_ret = snprintf(fw_name, FW_NAME_LEN, "vsp.bin.%04x.%04x", (int)spid.platform_family_id, (int)spid.hardware_id); if (name_ret > FW_NAME_LEN) { DRM_ERROR("failed to get fw name, ret %d vs expect %d\n", name_ret, FW_NAME_LEN); /* no way */ return -1; } /* try load with spid first */ ret = request_firmware(&raw, fw_name, &dev->pdev->dev); if (ret < 0 || raw == NULL) { VSP_DEBUG("failed to load fw: %s, try to load different fw\n", fw_name); /* read firmware img */ VSP_DEBUG("load vsp fw\n"); if (IS_ANN_A0(dev)) ret = request_firmware(&raw, FW_NAME_ANN, &dev->pdev->dev); else if (IS_TNG_B0(dev)) ret = request_firmware(&raw, FW_NAME_B0, &dev->pdev->dev); else { DRM_ERROR("VSP secure fw: bad platform\n"); raw = NULL; } } if (ret < 0 || raw == NULL) { DRM_ERROR("VSP: request_firmware failed: reason %d\n", ret); return -1; } if (raw->size < sizeof(struct vsp_secure_boot_header)) { DRM_ERROR("VSP: %s is not a correct firmware (size %d)\n", FW_NAME, raw->size); ret = -1; goto out; } ptr = (void *)raw->data; ma_ptr = (void *) raw->data + vrl_header_size; boot_header = (struct vsp_secure_boot_header *) (ptr + vrl_header_size); ma_header = (struct vsp_multi_app_blob_data *) (ma_ptr + boot_header->ma_header_offset); /* get firmware header */ memcpy(&vsp_priv->boot_header, boot_header, sizeof(vsp_priv->boot_header)); if (vsp_priv->boot_header.magic_number != VSP_SECURE_BOOT_MAGIC_NR) { DRM_ERROR("VSP: failed to load correct vsp firmware\n" "FW magic number is wrong %x (should be %x)\n", vsp_priv->boot_header.magic_number, VSP_SECURE_BOOT_MAGIC_NR); ret = -1; goto out; } /* read application firmware image data (for state-buffer size, etc) */ /* load the multi-app blob header */ memcpy(&vsp_priv->ma_header, ma_header, sizeof(vsp_priv->ma_header)); if (vsp_priv->ma_header.magic_number != VSP_MULTI_APP_MAGIC_NR) { DRM_ERROR("VSP: failed to load correct vsp firmware\n" "FW magic number is wrong %x (should be %x)\n", vsp_priv->ma_header.magic_number, VSP_MULTI_APP_MAGIC_NR); ret = -1; goto out; } VSP_DEBUG("firmware secure header:\n"); VSP_DEBUG("boot_header magic number %x\n", boot_header->magic_number); VSP_DEBUG("boot_text_offset %x\n", boot_header->boot_text_offset); VSP_DEBUG("boot_text_reg %x\n", boot_header->boot_text_reg); VSP_DEBUG("boot_icache_value %x\n", boot_header->boot_icache_value); VSP_DEBUG("boot_icache_reg %x\n", boot_header->boot_icache_reg); VSP_DEBUG("boot_pc_value %x\n", boot_header->boot_pc_value); VSP_DEBUG("boot_pc_reg %x\n", boot_header->boot_pc_reg); VSP_DEBUG("ma_header_offset %x\n", boot_header->ma_header_offset); VSP_DEBUG("ma_header_reg %x\n", boot_header->ma_header_reg); VSP_DEBUG("boot_start_value %x\n", boot_header->boot_start_value); VSP_DEBUG("boot_start_reg %x\n", boot_header->boot_start_reg); VSP_DEBUG("firmware ma_blob header:\n"); VSP_DEBUG("ma_header magic number %x\n", ma_header->magic_number); VSP_DEBUG("offset_from_start %x\n", ma_header->offset_from_start); VSP_DEBUG("imr_state_buffer_addr %x\n", ma_header->imr_state_buffer_addr); VSP_DEBUG("imr_state_buffer_size %x\n", ma_header->imr_state_buffer_size); VSP_DEBUG("apps_default_context_buffer_size %x\n", ma_header->apps_default_context_buffer_size); /* get imr 11 region start address and size */ imr_addr = intel_mid_msgbus_read32(PNW_IMR_MSG_PORT, TNG_IMR11L_MSG_REGADDR); imr_addr <<= 10; VSP_DEBUG("IMR11 base address %p\n", imr_addr); imr_size = raw->size; /* map imr 11 */ /* check if raw size is smaller than */ /* ioremap the region */ imr_ptr = ioremap(imr_addr, imr_size); if (!imr_ptr) { DRM_ERROR("failed to map imr_addr\n"); ret = -1; goto out; } /* copy the firmware to imr 11 */ memcpy(imr_ptr, ptr, raw->size); /* unmap the region */ iounmap(imr_ptr); #ifdef CONFIG_DX_SEP54 ret = sepapp_image_verify(imr_addr, imr_size, 15, vsp_magic_num); if (ret) { DRM_ERROR("failed to verify vsp firmware, ret %x\n", ret); ret = -1; goto out; } #endif vsp_priv->fw_loaded = VSP_FW_LOADED; vsp_priv->vsp_state = VSP_STATE_DOWN; vsp_priv->ctrl = (struct vsp_ctrl_reg *) (dev_priv->vsp_reg + VSP_CONFIG_REG_SDRAM_BASE + VSP_CONFIG_REG_START); out: release_firmware(raw); return ret; }