static int vlv_allow_gt_wake(struct drm_i915_private *dev_priv, bool allow) { u32 val; int err = 0; val = I915_READ(VLV_GTLC_WAKE_CTRL); val &= ~VLV_GTLC_ALLOWWAKEREQ; if (allow) val |= VLV_GTLC_ALLOWWAKEREQ; I915_WRITE(VLV_GTLC_WAKE_CTRL, val); POSTING_READ(VLV_GTLC_WAKE_CTRL); #define COND (!!(I915_READ(VLV_GTLC_PW_STATUS) & VLV_GTLC_ALLOWWAKEACK) == \ allow) err = wait_for(COND, 1); if (err) DRM_ERROR("timeout disabling GT waking\n"); return err; #undef COND }
static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv) { u32 fbc_ctl; /* Disable compression */ fbc_ctl = I915_READ(FBC_CONTROL); if ((fbc_ctl & FBC_CTL_EN) == 0) return; fbc_ctl &= ~FBC_CTL_EN; I915_WRITE(FBC_CONTROL, fbc_ctl); /* Wait for compressing bit to clear */ if (intel_wait_for_register(dev_priv, FBC_STATUS, FBC_STAT_COMPRESSING, 0, 10)) { DRM_DEBUG_KMS("FBC idle timed out\n"); return; } }
static void set_clock(void *data, int state_high) { struct intel_i2c_chan *chan = data; struct drm_device *dev = chan->drm_dev; struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; u32 reserved = 0, clock_bits; /* On most chips, these bits must be preserved in software. */ if (!IS_I830(dev) && !IS_845G(dev)) reserved = I915_READ(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; I915_WRITE(chan->reg, reserved | clock_bits); udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ }
static int dsi_vc_send_short(struct intel_dsi *intel_dsi, int channel, u8 data_type, u16 data) { struct drm_encoder *encoder = &intel_dsi->base.base; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); enum pipe pipe = intel_crtc->pipe; u32 ctrl_reg; u32 ctrl; u32 mask; DRM_DEBUG_KMS("channel %d, data_type %d, data %04x\n", channel, data_type, data); if (intel_dsi->hs) { ctrl_reg = MIPI_HS_GEN_CTRL(pipe); mask = HS_CTRL_FIFO_FULL; } else { ctrl_reg = MIPI_LP_GEN_CTRL(pipe); mask = LP_CTRL_FIFO_FULL; } if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == 0, 50)) { DRM_ERROR("Timeout waiting for HS/LP CTRL FIFO !full\n"); print_stat(intel_dsi); } /* * Note: This function is also used for long packets, with length passed * as data, since SHORT_PACKET_PARAM_SHIFT == * LONG_PACKET_WORD_COUNT_SHIFT. */ ctrl = data << SHORT_PACKET_PARAM_SHIFT | channel << VIRTUAL_CHANNEL_SHIFT | data_type << DATA_TYPE_SHIFT; I915_WRITE(ctrl_reg, ctrl); return 0; }
static void intel_disable_transcoder(struct drm_i915_private *dev_priv, enum pipe pipe) { int reg; u32 val; /* FDI relies on the transcoder */ assert_fdi_tx_disabled(dev_priv, pipe); assert_fdi_rx_disabled(dev_priv, pipe); /* Ports must be off as well */ assert_pch_ports_disabled(dev_priv, pipe); reg = TRANSCONF(pipe); val = I915_READ(reg); val &= ~TRANS_ENABLE; I915_WRITE(reg, val); /* wait for PCH transcoder off, transcoder state */ if (wait_for((I915_READ(reg) & TRANS_STATE_ENABLE) == 0, 50)) fprintf(stderr, "failed to disable transcoder\n"); }
static void i915_restore_palette(struct drm_device *dev, enum i915_pipe pipe) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long reg = (pipe == PIPE_A ? _PALETTE_A : _PALETTE_B); u32 *array; int i; if (!i915_pipe_enabled(dev, pipe)) return; if (HAS_PCH_SPLIT(dev)) reg = (pipe == PIPE_A) ? _LGC_PALETTE_A : _LGC_PALETTE_B; if (pipe == PIPE_A) array = dev_priv->save_palette_a; else array = dev_priv->save_palette_b; for (i = 0; i < 256; i++) I915_WRITE(reg + (i << 2), array[i]); }
static void set_data(void *data, int state_high) { struct intel_i2c_chan *chan = data; struct drm_device *dev = chan->drm_dev; struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; u32 reserved = 0, data_bits; if (!IS_I830(dev) && !IS_845G(dev)) reserved = I915_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | GPIO_CLOCK_PULLUP_DISABLE); if (state_high) data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK; else data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | GPIO_DATA_VAL_MASK; I915_WRITE(chan->reg, reserved | data_bits); udelay(I2C_RISEFALL_TIME); }
static void set_dsi_timings(struct drm_encoder *encoder, const struct drm_display_mode *mode) { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); int pipe = intel_crtc->pipe; unsigned int bpp = intel_crtc->config.pipe_bpp; unsigned int lane_count = intel_dsi->lane_count; u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp; hactive = mode->hdisplay; hfp = mode->hsync_start - mode->hdisplay; hsync = mode->hsync_end - mode->hsync_start; hbp = mode->htotal - mode->hsync_end; vfp = mode->vsync_start - mode->vdisplay; vsync = mode->vsync_end - mode->vsync_start; vbp = mode->vtotal - mode->vsync_end; /* horizontal values are in terms of high speed byte clock */ hactive = txbyteclkhs(hactive, bpp, lane_count, intel_dsi->burst_mode_ratio); hfp = txbyteclkhs(hfp, bpp, lane_count, intel_dsi->burst_mode_ratio); hsync = txbyteclkhs(hsync, bpp, lane_count, intel_dsi->burst_mode_ratio); hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio); I915_WRITE(MIPI_HACTIVE_AREA_COUNT(pipe), hactive); I915_WRITE(MIPI_HFP_COUNT(pipe), hfp); /* meaningful for video mode non-burst sync pulse mode only, can be zero * for non-burst sync events and burst modes */ I915_WRITE(MIPI_HSYNC_PADDING_COUNT(pipe), hsync); I915_WRITE(MIPI_HBP_COUNT(pipe), hbp); /* vertical values are in terms of lines */ I915_WRITE(MIPI_VFP_COUNT(pipe), vfp); I915_WRITE(MIPI_VSYNC_PADDING_COUNT(pipe), vsync); I915_WRITE(MIPI_VBP_COUNT(pipe), vbp); }
static int dsi_vc_send_long(struct intel_dsi *intel_dsi, int channel, u8 data_type, const u8 *data, int len) { struct drm_encoder *encoder = &intel_dsi->base.base; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); enum pipe pipe = intel_crtc->pipe; u32 data_reg; int i, j, n; u32 mask; DRM_DEBUG_KMS("channel %d, data_type %d, len %04x\n", channel, data_type, len); if (intel_dsi->hs) { data_reg = MIPI_HS_GEN_DATA(pipe); mask = HS_DATA_FIFO_FULL; } else { data_reg = MIPI_LP_GEN_DATA(pipe); mask = LP_DATA_FIFO_FULL; } if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == 0, 50)) DRM_ERROR("Timeout waiting for HS/LP DATA FIFO !full\n"); for (i = 0; i < len; i += n) { u32 val = 0; n = min_t(int, len - i, 4); for (j = 0; j < n; j++) val |= *data++ << 8 * j; I915_WRITE(data_reg, val); /* XXX: check for data fifo full, once that is set, write 4 * dwords, then wait for not set, then continue. */ } return dsi_vc_send_short(intel_dsi, channel, data_type, len); }
/** * huc_fw_xfer() - DMA's the firmware * @huc_fw: the firmware descriptor * @vma: the firmware image (bound into the GGTT) * * Transfer the firmware image to RAM for execution by the microcontroller. * * Return: 0 on success, non-zero on failure */ static int huc_fw_xfer(struct intel_uc_fw *huc_fw, struct i915_vma *vma) { struct intel_huc *huc = container_of(huc_fw, struct intel_huc, fw); struct drm_i915_private *dev_priv = huc_to_i915(huc); unsigned long offset = 0; u32 size; int ret; GEM_BUG_ON(huc_fw->type != INTEL_UC_FW_TYPE_HUC); intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); /* Set the source address for the uCode */ offset = intel_guc_ggtt_offset(&dev_priv->guc, vma) + huc_fw->header_offset; I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset)); I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF); /* Hardware doesn't look at destination address for HuC. Set it to 0, * but still program the correct address space. */ I915_WRITE(DMA_ADDR_1_LOW, 0); I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM); size = huc_fw->header_size + huc_fw->ucode_size; I915_WRITE(DMA_COPY_SIZE, size); /* Start the DMA */ I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(HUC_UKERNEL | START_DMA)); /* Wait for DMA to finish */ ret = intel_wait_for_register_fw(dev_priv, DMA_CTRL, START_DMA, 0, 100); DRM_DEBUG_DRIVER("HuC DMA transfer wait over with ret %d\n", ret); /* Disable the bits once DMA is over */ I915_WRITE(DMA_CTRL, _MASKED_BIT_DISABLE(HUC_UKERNEL)); intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); return ret; }
void bxt_dsi_pll_disable(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 val; DRM_DEBUG_KMS("\n"); val = I915_READ(BXT_DSI_PLL_ENABLE); val &= ~BXT_DSI_PLL_DO_ENABLE; I915_WRITE(BXT_DSI_PLL_ENABLE, val); /* * PLL lock should deassert within 200us. * Wait up to 1ms before timing out. */ if (intel_wait_for_register(dev_priv, BXT_DSI_PLL_ENABLE, BXT_DSI_PLL_LOCKED, 0, 1)) DRM_ERROR("Timeout waiting for PLL lock deassertion\n"); }
static void i8xx_fbc_disable(struct drm_i915_private *dev_priv) { u32 fbc_ctl; dev_priv->fbc.enabled = false; /* Disable compression */ fbc_ctl = I915_READ(FBC_CONTROL); if ((fbc_ctl & FBC_CTL_EN) == 0) return; fbc_ctl &= ~FBC_CTL_EN; I915_WRITE(FBC_CONTROL, fbc_ctl); /* Wait for compressing bit to clear */ if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10)) { DRM_DEBUG_KMS("FBC idle timed out\n"); return; } DRM_DEBUG_KMS("disabled FBC\n"); }
/* On Haswell, DDI port buffers must be programmed with correct values * in advance. The buffer values are different for FDI and DP modes, * but the HDMI/DVI fields are shared among those. So we program the DDI * in either FDI or DP modes only, as HDMI connections will work with both * of those */ void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, bool use_fdi_mode) { struct drm_i915_private *dev_priv = dev->dev_private; u32 reg; int i; const u32 *ddi_translations = ((use_fdi_mode) ? hsw_ddi_translations_fdi : hsw_ddi_translations_dp); DRM_DEBUG_DRIVER("Initializing DDI buffers for port %c in %s mode\n", port_name(port), use_fdi_mode ? "FDI" : "DP"); WARN((use_fdi_mode && (port != PORT_E)), "Programming port %c in FDI mode, this probably will not work.\n", port_name(port)); for (i=0, reg=DDI_BUF_TRANS(port); i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { I915_WRITE(reg, ddi_translations[i]); reg += 4; } }
static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { enum dpio_phy phy; WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC && power_well->data != PUNIT_POWER_WELL_DPIO_CMN_D); if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) { phy = DPIO_PHY0; assert_pll_disabled(dev_priv, PIPE_A); assert_pll_disabled(dev_priv, PIPE_B); } else { phy = DPIO_PHY1; assert_pll_disabled(dev_priv, PIPE_C); } I915_WRITE(DISPLAY_PHY_CONTROL, I915_READ(DISPLAY_PHY_CONTROL) & ~PHY_COM_LANE_RESET_DEASSERT(phy)); vlv_set_power_well(dev_priv, power_well, false); }
static void intel_dsi_post_disable(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); u32 val; DRM_DEBUG_KMS("\n"); intel_dsi_disable(encoder); intel_dsi_clear_device_ready(encoder); val = I915_READ(DSPCLK_GATE_D); val &= ~DPOUNIT_CLOCK_GATE_DISABLE; I915_WRITE(DSPCLK_GATE_D, val); if (intel_dsi->dev.dev_ops->disable_panel_power) intel_dsi->dev.dev_ops->disable_panel_power(&intel_dsi->dev); msleep(intel_dsi->panel_off_delay); msleep(intel_dsi->panel_pwr_cycle_delay); }
static void intel_dsi_disable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int pipe = intel_crtc->pipe; u32 temp; DRM_DEBUG_KMS("\n"); if (is_vid_mode(intel_dsi)) { wait_for_dsi_fifo_empty(intel_dsi); /* de-assert ip_tg_enable signal */ temp = I915_READ(MIPI_PORT_CTRL(pipe)); I915_WRITE(MIPI_PORT_CTRL(pipe), temp & ~DPI_ENABLE); POSTING_READ(MIPI_PORT_CTRL(pipe)); msleep(2); } /* Panel commands can be sent when clock is in LP11 */ I915_WRITE(MIPI_DEVICE_READY(pipe), 0x0); temp = I915_READ(MIPI_CTRL(pipe)); temp &= ~ESCAPE_CLOCK_DIVIDER_MASK; I915_WRITE(MIPI_CTRL(pipe), temp | intel_dsi->escape_clk_div << ESCAPE_CLOCK_DIVIDER_SHIFT); I915_WRITE(MIPI_EOT_DISABLE(pipe), CLOCKSTOP); temp = I915_READ(MIPI_DSI_FUNC_PRG(pipe)); temp &= ~VID_MODE_FORMAT_MASK; I915_WRITE(MIPI_DSI_FUNC_PRG(pipe), temp); I915_WRITE(MIPI_DEVICE_READY(pipe), 0x1); /* if disable packets are sent before sending shutdown packet then in * some next enable sequence send turn on packet error is observed */ if (intel_dsi->dev.dev_ops->disable) intel_dsi->dev.dev_ops->disable(&intel_dsi->dev); wait_for_dsi_fifo_empty(intel_dsi); }
static void vlv_undo_pipe_scramble_reset(struct drm_i915_private *dev_priv, enum pipe pipe) { uint32_t tmp = I915_READ(PORT_DFT2_G4X); switch (pipe) { case PIPE_A: tmp &= ~PIPE_A_SCRAMBLE_RESET; break; case PIPE_B: tmp &= ~PIPE_B_SCRAMBLE_RESET; break; case PIPE_C: tmp &= ~PIPE_C_SCRAMBLE_RESET; break; default: return; } if (!(tmp & PIPE_SCRAMBLE_RESET_MASK)) tmp &= ~DC_BALANCE_RESET_VLV; I915_WRITE(PORT_DFT2_G4X, tmp); }
void intel_ddi_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); int port = intel_hdmi->ddi_port; u32 temp; temp = I915_READ(DDI_BUF_CTL(port)); if (mode != DRM_MODE_DPMS_ON) { temp &= ~DDI_BUF_CTL_ENABLE; } else { temp |= DDI_BUF_CTL_ENABLE; } /* Enable DDI_BUF_CTL. In HDMI/DVI mode, the port width, * and swing/emphasis values are ignored so nothing special needs * to be done besides enabling the port. */ I915_WRITE(DDI_BUF_CTL(port), temp); }
int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool force_on) { u32 val; int err; #define COND (I915_READ(VLV_GTLC_SURVIVABILITY_REG) & VLV_GFX_CLK_STATUS_BIT) val = I915_READ(VLV_GTLC_SURVIVABILITY_REG); val &= ~VLV_GFX_CLK_FORCE_ON_BIT; if (force_on) val |= VLV_GFX_CLK_FORCE_ON_BIT; I915_WRITE(VLV_GTLC_SURVIVABILITY_REG, val); if (!force_on) return 0; err = wait_for(COND, 20); if (err) DRM_ERROR("timeout waiting for GFX clock force-on (%08x)\n", I915_READ(VLV_GTLC_SURVIVABILITY_REG)); return err; #undef COND }
static int gmbus_xfer_read(struct drm_i915_private *dev_priv, struct iic_msg *msg, u32 gmbus1_index) { int reg_offset = dev_priv->gpio_mmio_base; u16 len = msg->len; u8 *buf = msg->buf; I915_WRITE(GMBUS1 + reg_offset, gmbus1_index | GMBUS_CYCLE_WAIT | (len << GMBUS_BYTE_COUNT_SHIFT) | (msg->slave << (GMBUS_SLAVE_ADDR_SHIFT - 1)) | GMBUS_SLAVE_READ | GMBUS_SW_RDY); while (len) { int ret; u32 val, loop = 0; u32 gmbus2; ret = wait_for((gmbus2 = I915_READ(GMBUS2 + reg_offset)) & (GMBUS_SATOER | GMBUS_HW_RDY), 50); if (ret) return -ETIMEDOUT; if (gmbus2 & GMBUS_SATOER) return -ENXIO; val = I915_READ(GMBUS3 + reg_offset); do { *buf++ = val & 0xff; val >>= 8; } while (--len && ++loop < 4); } return 0; }
static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_output *intel_output = to_intel_output(connector); struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; u32 temp, bit; temp = I915_READ(PORT_HOTPLUG_EN); I915_WRITE(PORT_HOTPLUG_EN, temp | HDMIB_HOTPLUG_INT_EN | HDMIC_HOTPLUG_INT_EN | HDMID_HOTPLUG_INT_EN); POSTING_READ(PORT_HOTPLUG_EN); switch (hdmi_priv->sdvox_reg) { case SDVOB: bit = HDMIB_HOTPLUG_INT_STATUS; break; case SDVOC: bit = HDMIC_HOTPLUG_INT_STATUS; break; default: return connector_status_unknown; } if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) { intel_hdmi_sink_detect(connector); return connector_status_connected; } else return connector_status_disconnected; }
int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int channel, u8 *reqdata, int reqlen, u8 *buf, int buflen) { struct drm_encoder *encoder = &intel_dsi->base.base; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); enum pipe pipe = intel_crtc->pipe; u32 mask; int ret; /* * XXX: should issue multiple read requests and reads if request is * longer than MIPI_MAX_RETURN_PKT_SIZE */ I915_WRITE(MIPI_INTR_STAT(pipe), GEN_READ_DATA_AVAIL); ret = dsi_vc_generic_send_read_request(intel_dsi, channel, reqdata, reqlen); if (ret) return ret; mask = GEN_READ_DATA_AVAIL; if (wait_for((I915_READ(MIPI_INTR_STAT(pipe)) & mask) == mask, 50)) DRM_ERROR("Timeout waiting for read data.\n"); ret = dsi_read_data_return(intel_dsi, buf, buflen); if (ret < 0) return ret; if (ret != buflen) return -EIO; return 0; }
/** * intel_disable_pipe - disable a pipe, asserting requirements * @dev_priv: i915 private structure * @pipe: pipe to disable * * Disable @pipe, making sure that various hardware specific requirements * are met, if applicable, e.g. plane disabled, panel fitter off, etc. * * @pipe should be %PIPE_A or %PIPE_B. * * Will wait until the pipe has shut down before returning. */ static void intel_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) { int reg; u32 val; /* * Make sure planes won't keep trying to pump pixels to us, * or we might hang the display. */ assert_planes_disabled(dev_priv, pipe); /* Don't disable pipe A or pipe A PLLs if needed */ if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) return; reg = PIPECONF(pipe); val = I915_READ(reg); if ((val & PIPECONF_ENABLE) == 0) return; I915_WRITE(reg, val & ~PIPECONF_ENABLE); intel_wait_for_pipe_off(dev_priv->dev, pipe); }
/* * Transfer the firmware image to RAM for execution by the microcontroller. * * Architecturally, the DMA engine is bidirectional, and can potentially even * transfer between GTT locations. This functionality is left out of the API * for now as there is no need for it. */ static int guc_xfer_ucode(struct intel_guc *guc, struct i915_vma *vma) { struct drm_i915_private *dev_priv = guc_to_i915(guc); struct intel_uc_fw *guc_fw = &guc->fw; unsigned long offset; u32 status; int ret; /* * The header plus uCode will be copied to WOPCM via DMA, excluding any * other components */ I915_WRITE(DMA_COPY_SIZE, guc_fw->header_size + guc_fw->ucode_size); /* Set the source address for the new blob */ offset = guc_ggtt_offset(vma) + guc_fw->header_offset; I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset)); I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF); /* * Set the DMA destination. Current uCode expects the code to be * loaded at 8k; locations below this are used for the stack. */ I915_WRITE(DMA_ADDR_1_LOW, 0x2000); I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM); /* Finally start the DMA */ I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE | START_DMA)); /* Wait for DMA to finish */ ret = __intel_wait_for_register_fw(dev_priv, DMA_CTRL, START_DMA, 0, 2, 100, &status); DRM_DEBUG_DRIVER("GuC DMA status %#x\n", status); return ret; }
/* This function forces a CFB recompression through the nuke operation. */ static void intel_fbc_recompress(struct drm_i915_private *dev_priv) { I915_WRITE(MSG_FBC_REND_STATE, FBC_REND_NUKE); POSTING_READ(MSG_FBC_REND_STATE); }
static void ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, uint32_t x, uint32_t y, uint32_t src_w, uint32_t src_h) { struct drm_device *dev = plane->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_plane *intel_plane = to_intel_plane(plane); int pipe = intel_plane->pipe; u32 sprctl, sprscale = 0; int pixel_size; sprctl = I915_READ(SPRCTL(pipe)); /* Mask out pixel format bits in case we change it */ sprctl &= ~SPRITE_PIXFORMAT_MASK; sprctl &= ~SPRITE_RGB_ORDER_RGBX; sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK; switch (fb->pixel_format) { case DRM_FORMAT_XBGR8888: sprctl |= SPRITE_FORMAT_RGBX888; pixel_size = 4; break; case DRM_FORMAT_XRGB8888: sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; pixel_size = 4; break; case DRM_FORMAT_YUYV: sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; pixel_size = 2; break; case DRM_FORMAT_YVYU: sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; pixel_size = 2; break; case DRM_FORMAT_UYVY: sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; pixel_size = 2; break; case DRM_FORMAT_VYUY: sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; pixel_size = 2; break; default: DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n"); sprctl |= DVS_FORMAT_RGBX888; pixel_size = 4; break; } if (obj->tiling_mode != I915_TILING_NONE) sprctl |= SPRITE_TILED; /* must disable */ sprctl |= SPRITE_TRICKLE_FEED_DISABLE; sprctl |= SPRITE_ENABLE; /* Sizes are 0 based */ src_w--; src_h--; crtc_w--; crtc_h--; intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); /* * IVB workaround: must disable low power watermarks for at least * one frame before enabling scaling. LP watermarks can be re-enabled * when scaling is disabled. */ if (crtc_w != src_w || crtc_h != src_h) { if (!dev_priv->sprite_scaling_enabled) { dev_priv->sprite_scaling_enabled = true; intel_update_watermarks(dev); intel_wait_for_vblank(dev, pipe); } sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; } else { if (dev_priv->sprite_scaling_enabled) { dev_priv->sprite_scaling_enabled = false; /* potentially re-enable LP watermarks */ intel_update_watermarks(dev); } } I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); if (obj->tiling_mode != I915_TILING_NONE) { I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x); } else { unsigned long offset; offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); I915_WRITE(SPRLINOFF(pipe), offset); } I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); I915_WRITE(SPRSCALE(pipe), sprscale); I915_WRITE(SPRCTL(pipe), sprctl); I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset); POSTING_READ(SPRSURF(pipe)); }
static void ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, uint32_t x, uint32_t y, uint32_t src_w, uint32_t src_h) { struct drm_device *dev = plane->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_plane *intel_plane = to_intel_plane(plane); int pipe = intel_plane->pipe, pixel_size; u32 dvscntr, dvsscale; dvscntr = I915_READ(DVSCNTR(pipe)); /* Mask out pixel format bits in case we change it */ dvscntr &= ~DVS_PIXFORMAT_MASK; dvscntr &= ~DVS_RGB_ORDER_XBGR; dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; switch (fb->pixel_format) { case DRM_FORMAT_XBGR8888: dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; pixel_size = 4; break; case DRM_FORMAT_XRGB8888: dvscntr |= DVS_FORMAT_RGBX888; pixel_size = 4; break; case DRM_FORMAT_YUYV: dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV; pixel_size = 2; break; case DRM_FORMAT_YVYU: dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU; pixel_size = 2; break; case DRM_FORMAT_UYVY: dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY; pixel_size = 2; break; case DRM_FORMAT_VYUY: dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY; pixel_size = 2; break; default: DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n"); dvscntr |= DVS_FORMAT_RGBX888; pixel_size = 4; break; } if (obj->tiling_mode != I915_TILING_NONE) dvscntr |= DVS_TILED; if (IS_GEN6(dev)) dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ dvscntr |= DVS_ENABLE; /* Sizes are 0 based */ src_w--; src_h--; crtc_w--; crtc_h--; intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); dvsscale = 0; if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x); if (obj->tiling_mode != I915_TILING_NONE) { I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x); } else { unsigned long offset; offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); I915_WRITE(DVSLINOFF(pipe), offset); } I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); I915_WRITE(DVSSCALE(pipe), dvsscale); I915_WRITE(DVSCNTR(pipe), dvscntr); I915_MODIFY_DISPBASE(DVSSURF(pipe), obj->gtt_offset); POSTING_READ(DVSSURF(pipe)); }
static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *dev_priv) { struct vlv_s0ix_state *s = &dev_priv->vlv_s0ix_state; u32 val; int i; /* GAM 0x4000-0x4770 */ I915_WRITE(GEN7_WR_WATERMARK, s->wr_watermark); I915_WRITE(GEN7_GFX_PRIO_CTRL, s->gfx_prio_ctrl); I915_WRITE(ARB_MODE, s->arb_mode | (0xffff << 16)); I915_WRITE(GEN7_GFX_PEND_TLB0, s->gfx_pend_tlb0); I915_WRITE(GEN7_GFX_PEND_TLB1, s->gfx_pend_tlb1); for (i = 0; i < ARRAY_SIZE(s->lra_limits); i++) I915_WRITE(GEN7_LRA_LIMITS(i), s->lra_limits[i]); I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->media_max_req_count); I915_WRITE(GEN7_GFX_MAX_REQ_COUNT, s->gfx_max_req_count); I915_WRITE(RENDER_HWS_PGA_GEN7, s->render_hwsp); I915_WRITE(GAM_ECOCHK, s->ecochk); I915_WRITE(BSD_HWS_PGA_GEN7, s->bsd_hwsp); I915_WRITE(BLT_HWS_PGA_GEN7, s->blt_hwsp); I915_WRITE(GEN7_TLB_RD_ADDR, s->tlb_rd_addr); /* MBC 0x9024-0x91D0, 0x8500 */ I915_WRITE(VLV_G3DCTL, s->g3dctl); I915_WRITE(VLV_GSCKGCTL, s->gsckgctl); I915_WRITE(GEN6_MBCTL, s->mbctl); /* GCP 0x9400-0x9424, 0x8100-0x810C */ I915_WRITE(GEN6_UCGCTL1, s->ucgctl1); I915_WRITE(GEN6_UCGCTL3, s->ucgctl3); I915_WRITE(GEN6_RCGCTL1, s->rcgctl1); I915_WRITE(GEN6_RCGCTL2, s->rcgctl2); I915_WRITE(GEN6_RSTCTL, s->rstctl); I915_WRITE(GEN7_MISCCPCTL, s->misccpctl); /* GPM 0xA000-0xAA84, 0x8000-0x80FC */ I915_WRITE(GEN6_GFXPAUSE, s->gfxpause); I915_WRITE(GEN6_RPDEUHWTC, s->rpdeuhwtc); I915_WRITE(GEN6_RPDEUC, s->rpdeuc); I915_WRITE(ECOBUS, s->ecobus); I915_WRITE(VLV_PWRDWNUPCTL, s->pwrdwnupctl); I915_WRITE(GEN6_RP_DOWN_TIMEOUT,s->rp_down_timeout); I915_WRITE(GEN6_RPDEUCSW, s->rp_deucsw); I915_WRITE(GEN6_RCUBMABDTMR, s->rcubmabdtmr); I915_WRITE(VLV_RCEDATA, s->rcedata); I915_WRITE(VLV_SPAREG2H, s->spare2gh); /* Display CZ domain, 0x4400C-0x4402C, 0x4F000-0x4F11F */ I915_WRITE(GTIMR, s->gt_imr); I915_WRITE(GTIER, s->gt_ier); I915_WRITE(GEN6_PMIMR, s->pm_imr); I915_WRITE(GEN6_PMIER, s->pm_ier); for (i = 0; i < ARRAY_SIZE(s->gt_scratch); i++) I915_WRITE(GEN7_GT_SCRATCH(i), s->gt_scratch[i]); /* GT SA CZ domain, 0x100000-0x138124 */ I915_WRITE(TILECTL, s->tilectl); I915_WRITE(GTFIFOCTL, s->gt_fifoctl); /* * Preserve the GT allow wake and GFX force clock bit, they are not * be restored, as they are used to control the s0ix suspend/resume * sequence by the caller. */ val = I915_READ(VLV_GTLC_WAKE_CTRL); val &= VLV_GTLC_ALLOWWAKEREQ; val |= s->gtlc_wake_ctrl & ~VLV_GTLC_ALLOWWAKEREQ; I915_WRITE(VLV_GTLC_WAKE_CTRL, val); val = I915_READ(VLV_GTLC_SURVIVABILITY_REG); val &= VLV_GFX_CLK_FORCE_ON_BIT; val |= s->gtlc_survive & ~VLV_GFX_CLK_FORCE_ON_BIT; I915_WRITE(VLV_GTLC_SURVIVABILITY_REG, val); I915_WRITE(VLV_PMWGICZ, s->pmwgicz); /* Gunit-Display CZ domain, 0x182028-0x1821CF */ I915_WRITE(VLV_GU_CTL0, s->gu_ctl0); I915_WRITE(VLV_GU_CTL1, s->gu_ctl1); I915_WRITE(VLV_PCBR, s->pcbr); I915_WRITE(VLV_GUNIT_CLOCK_GATE2, s->clock_gate_dis2); }
static void skl_set_power_well(struct drm_i915_private *dev_priv, struct i915_power_well *power_well, bool enable) { uint32_t tmp, fuse_status; uint32_t req_mask, state_mask; bool is_enabled, enable_requested, check_fuse_status = false; tmp = I915_READ(HSW_PWR_WELL_DRIVER); fuse_status = I915_READ(SKL_FUSE_STATUS); switch (power_well->data) { case SKL_DISP_PW_1: if (wait_for((I915_READ(SKL_FUSE_STATUS) & SKL_FUSE_PG0_DIST_STATUS), 1)) { DRM_ERROR("PG0 not enabled\n"); return; } break; case SKL_DISP_PW_2: if (!(fuse_status & SKL_FUSE_PG1_DIST_STATUS)) { DRM_ERROR("PG1 in disabled state\n"); return; } break; case SKL_DISP_PW_DDI_A_E: case SKL_DISP_PW_DDI_B: case SKL_DISP_PW_DDI_C: case SKL_DISP_PW_DDI_D: case SKL_DISP_PW_MISC_IO: break; default: WARN(1, "Unknown power well %lu\n", power_well->data); return; } req_mask = SKL_POWER_WELL_REQ(power_well->data); enable_requested = tmp & req_mask; state_mask = SKL_POWER_WELL_STATE(power_well->data); is_enabled = tmp & state_mask; if (enable) { if (!enable_requested) { I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask); } if (!is_enabled) { DRM_DEBUG_KMS("Enabling %s\n", power_well->name); if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) & state_mask), 1)) DRM_ERROR("%s enable timeout\n", power_well->name); check_fuse_status = true; } } else { if (enable_requested) { I915_WRITE(HSW_PWR_WELL_DRIVER, tmp & ~req_mask); POSTING_READ(HSW_PWR_WELL_DRIVER); DRM_DEBUG_KMS("Disabling %s\n", power_well->name); } } if (check_fuse_status) { if (power_well->data == SKL_DISP_PW_1) { if (wait_for((I915_READ(SKL_FUSE_STATUS) & SKL_FUSE_PG1_DIST_STATUS), 1)) DRM_ERROR("PG1 distributing status timeout\n"); } else if (power_well->data == SKL_DISP_PW_2) { if (wait_for((I915_READ(SKL_FUSE_STATUS) & SKL_FUSE_PG2_DIST_STATUS), 1)) DRM_ERROR("PG2 distributing status timeout\n"); } } if (enable && !is_enabled) skl_power_well_post_enable(dev_priv, power_well); }
void intel_i2c_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; I915_WRITE(dev_priv->gpio_mmio_base + GMBUS0, 0); }