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; enum pipe pipe = intel_dsi->port; u32 data_reg, ctrl_reg, ctrl; int i, j, n; u32 mask = 0; 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); ctrl_reg = MIPI_HS_GEN_CTRL(pipe); mask |= HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY; } else { data_reg = MIPI_LP_GEN_DATA(pipe); ctrl_reg = MIPI_LP_GEN_CTRL(pipe); mask |= LP_CTRL_FIFO_EMPTY | LP_DATA_FIFO_EMPTY; } if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 50)) DRM_ERROR("Timeout waiting for FIFO to be Empty\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. */ } ctrl = len << LONG_PACKET_WORD_COUNT_SHIFT; ctrl |= channel << VIRTUAL_CHANNEL_SHIFT; ctrl |= data_type << DATA_TYPE_SHIFT; I915_WRITE(ctrl_reg, ctrl); return 0; }
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; }