Rev 6937 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6937 | Rev 7144 | ||
---|---|---|---|
Line 232... | Line 232... | ||
232 | 232 | ||
233 | mutex_lock(&dev_priv->sb_lock); |
233 | mutex_lock(&dev_priv->sb_lock); |
234 | if (!gtable[gpio].init) { |
234 | if (!gtable[gpio].init) { |
235 | /* program the function */ |
235 | /* program the function */ |
236 | /* FIXME: remove constant below */ |
236 | /* FIXME: remove constant below */ |
- | 237 | vlv_iosf_sb_write(dev_priv, IOSF_PORT_GPIO_NC, function, |
|
237 | vlv_gpio_nc_write(dev_priv, function, 0x2000CC00); |
238 | 0x2000CC00); |
238 | gtable[gpio].init = 1; |
239 | gtable[gpio].init = 1; |
Line 239... | Line 240... | ||
239 | } |
240 | } |
Line 240... | Line 241... | ||
240 | 241 | ||
241 | val = 0x4 | action; |
242 | val = 0x4 | action; |
242 | 243 | ||
Line 243... | Line 244... | ||
243 | /* pull up/down */ |
244 | /* pull up/down */ |
244 | vlv_gpio_nc_write(dev_priv, pad, val); |
245 | vlv_iosf_sb_write(dev_priv, IOSF_PORT_GPIO_NC, pad, val); |
245 | mutex_unlock(&dev_priv->sb_lock); |
246 | mutex_unlock(&dev_priv->sb_lock); |
Line -... | Line 247... | ||
- | 247 | ||
- | 248 | out: |
|
- | 249 | return data; |
|
- | 250 | } |
|
- | 251 | ||
246 | 252 | static const u8 *mipi_exec_i2c_skip(struct intel_dsi *intel_dsi, const u8 *data) |
|
247 | out: |
253 | { |
248 | return data; |
254 | return data + *(data + 6) + 7; |
249 | } |
- | |
250 | 255 | } |
|
251 | typedef const u8 * (*fn_mipi_elem_exec)(struct intel_dsi *intel_dsi, |
256 | |
252 | const u8 *data); |
257 | typedef const u8 * (*fn_mipi_elem_exec)(struct intel_dsi *intel_dsi, |
253 | static const fn_mipi_elem_exec exec_elem[] = { |
258 | const u8 *data); |
254 | NULL, /* reserved */ |
259 | static const fn_mipi_elem_exec exec_elem[] = { |
Line 255... | Line 260... | ||
255 | mipi_exec_send_packet, |
260 | [MIPI_SEQ_ELEM_SEND_PKT] = mipi_exec_send_packet, |
256 | mipi_exec_delay, |
261 | [MIPI_SEQ_ELEM_DELAY] = mipi_exec_delay, |
257 | mipi_exec_gpio, |
262 | [MIPI_SEQ_ELEM_GPIO] = mipi_exec_gpio, |
258 | NULL, /* status read; later */ |
263 | [MIPI_SEQ_ELEM_I2C] = mipi_exec_i2c_skip, |
259 | }; |
264 | }; |
Line 260... | Line 265... | ||
260 | 265 | ||
261 | /* |
- | |
262 | * MIPI Sequence from VBT #53 parsing logic |
266 | /* |
263 | * We have already separated each seqence during bios parsing |
267 | * MIPI Sequence from VBT #53 parsing logic |
264 | * Following is generic execution function for any sequence |
268 | * We have already separated each seqence during bios parsing |
265 | */ |
269 | * Following is generic execution function for any sequence |
266 | 270 | */ |
|
- | 271 | ||
- | 272 | static const char * const seq_name[] = { |
|
- | 273 | [MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET", |
|
- | 274 | [MIPI_SEQ_INIT_OTP] = "MIPI_SEQ_INIT_OTP", |
|
- | 275 | [MIPI_SEQ_DISPLAY_ON] = "MIPI_SEQ_DISPLAY_ON", |
|
- | 276 | [MIPI_SEQ_DISPLAY_OFF] = "MIPI_SEQ_DISPLAY_OFF", |
|
267 | static const char * const seq_name[] = { |
277 | [MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET", |
Line -... | Line 278... | ||
- | 278 | [MIPI_SEQ_BACKLIGHT_ON] = "MIPI_SEQ_BACKLIGHT_ON", |
|
- | 279 | [MIPI_SEQ_BACKLIGHT_OFF] = "MIPI_SEQ_BACKLIGHT_OFF", |
|
- | 280 | [MIPI_SEQ_TEAR_ON] = "MIPI_SEQ_TEAR_ON", |
|
- | 281 | [MIPI_SEQ_TEAR_OFF] = "MIPI_SEQ_TEAR_OFF", |
|
- | 282 | [MIPI_SEQ_POWER_ON] = "MIPI_SEQ_POWER_ON", |
|
- | 283 | [MIPI_SEQ_POWER_OFF] = "MIPI_SEQ_POWER_OFF", |
|
- | 284 | }; |
|
- | 285 | ||
268 | "UNDEFINED", |
286 | static const char *sequence_name(enum mipi_seq seq_id) |
269 | "MIPI_SEQ_ASSERT_RESET", |
287 | { |
- | 288 | if (seq_id < ARRAY_SIZE(seq_name) && seq_name[seq_id]) |
|
- | 289 | return seq_name[seq_id]; |
|
- | 290 | else |
|
- | 291 | return "(unknown)"; |
|
270 | "MIPI_SEQ_INIT_OTP", |
292 | } |
271 | "MIPI_SEQ_DISPLAY_ON", |
- | |
Line 272... | Line 293... | ||
272 | "MIPI_SEQ_DISPLAY_OFF", |
293 | |
273 | "MIPI_SEQ_DEASSERT_RESET" |
294 | static void generic_exec_sequence(struct drm_panel *panel, enum mipi_seq seq_id) |
Line 274... | Line -... | ||
274 | }; |
- | |
275 | - | ||
276 | static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) |
295 | { |
277 | { |
296 | struct vbt_panel *vbt_panel = to_vbt_panel(panel); |
278 | fn_mipi_elem_exec mipi_elem_exec; |
- | |
279 | int index; |
297 | struct intel_dsi *intel_dsi = vbt_panel->intel_dsi; |
280 | - | ||
281 | if (!data) |
- | |
282 | return; |
298 | struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); |
283 | - | ||
284 | DRM_DEBUG_DRIVER("Starting MIPI sequence - %s\n", seq_name[*data]); |
- | |
285 | 299 | const u8 *data; |
|
286 | /* go to the first element of the sequence */ |
300 | fn_mipi_elem_exec mipi_elem_exec; |
Line -... | Line 301... | ||
- | 301 | ||
- | 302 | if (WARN_ON(seq_id >= ARRAY_SIZE(dev_priv->vbt.dsi.sequence))) |
|
- | 303 | return; |
|
- | 304 | ||
- | 305 | data = dev_priv->vbt.dsi.sequence[seq_id]; |
|
287 | data++; |
306 | if (!data) { |
288 | 307 | DRM_DEBUG_KMS("MIPI sequence %d - %s not available\n", |
|
Line 289... | Line 308... | ||
289 | /* parse each byte till we reach end of sequence byte - 0x00 */ |
308 | seq_id, sequence_name(seq_id)); |
290 | while (1) { |
309 | return; |
- | 310 | } |
|
Line 291... | Line 311... | ||
291 | index = *data; |
311 | |
292 | mipi_elem_exec = exec_elem[index]; |
312 | WARN_ON(*data != seq_id); |
293 | if (!mipi_elem_exec) { |
313 | |
294 | DRM_ERROR("Unsupported MIPI element, skipping sequence execution\n"); |
- | |
295 | return; |
314 | DRM_DEBUG_KMS("Starting MIPI sequence %d - %s\n", |
296 | } |
315 | seq_id, sequence_name(seq_id)); |
297 | 316 | ||
- | 317 | /* Skip Sequence Byte. */ |
|
- | 318 | data++; |
|
- | 319 | ||
- | 320 | /* Skip Size of Sequence. */ |
|
- | 321 | if (dev_priv->vbt.dsi.seq_version >= 3) |
|
- | 322 | data += 4; |
|
- | 323 | ||
- | 324 | while (1) { |
|
- | 325 | u8 operation_byte = *data++; |
|
- | 326 | u8 operation_size = 0; |
|
- | 327 | ||
- | 328 | if (operation_byte == MIPI_SEQ_ELEM_END) |
|
- | 329 | break; |
|
- | 330 | ||
- | 331 | if (operation_byte < ARRAY_SIZE(exec_elem)) |
|
- | 332 | mipi_elem_exec = exec_elem[operation_byte]; |
|
- | 333 | else |
|
- | 334 | mipi_elem_exec = NULL; |
|
- | 335 | ||
- | 336 | /* Size of Operation. */ |
|
- | 337 | if (dev_priv->vbt.dsi.seq_version >= 3) |
|
- | 338 | operation_size = *data++; |
|
- | 339 | ||
298 | /* goto element payload */ |
340 | if (mipi_elem_exec) { |
299 | data++; |
341 | data = mipi_elem_exec(intel_dsi, data); |
Line 300... | Line 342... | ||
300 | 342 | } else if (operation_size) { |
|
301 | /* execute the element specific rotines */ |
343 | /* We have size, skip. */ |
302 | data = mipi_elem_exec(intel_dsi, data); |
- | |
303 | - | ||
304 | /* |
- | |
305 | * After processing the element, data should point to |
- | |
306 | * next element or end of sequence |
- | |
307 | * check if have we reached end of sequence |
- | |
308 | */ |
- | |
309 | if (*data == 0x00) |
344 | DRM_DEBUG_KMS("Unsupported MIPI operation byte %u\n", |
310 | break; |
- | |
311 | } |
- | |
312 | } |
345 | operation_byte); |
Line 313... | Line 346... | ||
313 | 346 | data += operation_size; |
|
314 | static int vbt_panel_prepare(struct drm_panel *panel) |
347 | } else { |
Line 315... | Line 348... | ||
315 | { |
348 | /* No size, can't skip without parsing. */ |
316 | struct vbt_panel *vbt_panel = to_vbt_panel(panel); |
349 | DRM_ERROR("Unsupported MIPI operation byte %u\n", |
317 | struct intel_dsi *intel_dsi = vbt_panel->intel_dsi; |
- | |
318 | struct drm_device *dev = intel_dsi->base.base.dev; |
- | |
319 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
320 | const u8 *sequence; |
- | |
321 | - | ||
322 | sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_ASSERT_RESET]; |
- | |
323 | generic_exec_sequence(intel_dsi, sequence); |
- | |
324 | 350 | operation_byte); |
|
Line 325... | Line 351... | ||
325 | sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP]; |
351 | return; |
326 | generic_exec_sequence(intel_dsi, sequence); |
352 | } |
Line 327... | Line 353... | ||
327 | 353 | } |
|
328 | return 0; |
354 | } |
329 | } |
- | |
330 | - | ||
331 | static int vbt_panel_unprepare(struct drm_panel *panel) |
- | |
332 | { |
- | |
333 | struct vbt_panel *vbt_panel = to_vbt_panel(panel); |
- | |
334 | struct intel_dsi *intel_dsi = vbt_panel->intel_dsi; |
- | |
335 | struct drm_device *dev = intel_dsi->base.base.dev; |
- | |
336 | struct drm_i915_private *dev_priv = dev->dev_private; |
355 | |
Line 337... | Line 356... | ||
337 | const u8 *sequence; |
356 | static int vbt_panel_prepare(struct drm_panel *panel) |
338 | 357 | { |
|
Line 339... | Line 358... | ||
339 | sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]; |
358 | generic_exec_sequence(panel, MIPI_SEQ_ASSERT_RESET); |
340 | generic_exec_sequence(intel_dsi, sequence); |
359 | generic_exec_sequence(panel, MIPI_SEQ_INIT_OTP); |
341 | - | ||
342 | return 0; |
- | |
343 | } |
- | |
344 | - | ||
345 | static int vbt_panel_enable(struct drm_panel *panel) |
- | |
346 | { |
- | |
347 | struct vbt_panel *vbt_panel = to_vbt_panel(panel); |
- | |
348 | struct intel_dsi *intel_dsi = vbt_panel->intel_dsi; |
360 | |
Line 349... | Line 361... | ||
349 | struct drm_device *dev = intel_dsi->base.base.dev; |
361 | return 0; |
350 | struct drm_i915_private *dev_priv = dev->dev_private; |
362 | } |
Line 351... | Line 363... | ||
351 | const u8 *sequence; |
363 | |
Line 426... | Line 438... | ||
426 | intel_dsi->lane_count = mipi_config->lane_cnt + 1; |
438 | intel_dsi->lane_count = mipi_config->lane_cnt + 1; |
427 | intel_dsi->pixel_format = mipi_config->videomode_color_format << 7; |
439 | intel_dsi->pixel_format = mipi_config->videomode_color_format << 7; |
428 | intel_dsi->dual_link = mipi_config->dual_link; |
440 | intel_dsi->dual_link = mipi_config->dual_link; |
429 | intel_dsi->pixel_overlap = mipi_config->pixel_overlap; |
441 | intel_dsi->pixel_overlap = mipi_config->pixel_overlap; |
Line 430... | Line -... | ||
430 | - | ||
431 | if (intel_dsi->pixel_format == VID_MODE_FORMAT_RGB666) |
- | |
432 | bits_per_pixel = 18; |
442 | |
433 | else if (intel_dsi->pixel_format == VID_MODE_FORMAT_RGB565) |
- | |
Line 434... | Line 443... | ||
434 | bits_per_pixel = 16; |
443 | bits_per_pixel = dsi_pixel_format_bpp(intel_dsi->pixel_format); |
435 | 444 | ||
436 | intel_dsi->operation_mode = mipi_config->is_cmd_mode; |
445 | intel_dsi->operation_mode = mipi_config->is_cmd_mode; |
437 | intel_dsi->video_mode_format = mipi_config->video_transfer_mode; |
446 | intel_dsi->video_mode_format = mipi_config->video_transfer_mode; |
Line 683... | Line 692... | ||
683 | intel_dsi->panel_off_delay = pps->panel_off_delay / 10; |
692 | intel_dsi->panel_off_delay = pps->panel_off_delay / 10; |
684 | intel_dsi->panel_pwr_cycle_delay = pps->panel_power_cycle_delay / 10; |
693 | intel_dsi->panel_pwr_cycle_delay = pps->panel_power_cycle_delay / 10; |
Line 685... | Line 694... | ||
685 | 694 | ||
686 | /* This is cheating a bit with the cleanup. */ |
695 | /* This is cheating a bit with the cleanup. */ |
- | 696 | vbt_panel = kzalloc(sizeof(*vbt_panel), GFP_KERNEL); |
|
- | 697 | if (!vbt_panel) |
|
Line 687... | Line 698... | ||
687 | vbt_panel = kzalloc(sizeof(*vbt_panel), GFP_KERNEL); |
698 | return NULL; |
688 | 699 | ||
689 | vbt_panel->intel_dsi = intel_dsi; |
700 | vbt_panel->intel_dsi = intel_dsi; |
690 | drm_panel_init(&vbt_panel->panel); |
701 | drm_panel_init(&vbt_panel->panel); |