diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/dma/pch_dma.c | 1 | ||||
| -rw-r--r-- | drivers/dma/pl330.c | 93 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_panel.c | 18 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 18 |
6 files changed, 114 insertions, 32 deletions
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index ce3dc3e9688c..0bbdea5059f3 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c | |||
| @@ -867,6 +867,7 @@ static int pch_dma_probe(struct pci_dev *pdev, | |||
| 867 | 867 | ||
| 868 | if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { | 868 | if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { |
| 869 | dev_err(&pdev->dev, "Cannot find proper base address\n"); | 869 | dev_err(&pdev->dev, "Cannot find proper base address\n"); |
| 870 | err = -ENODEV; | ||
| 870 | goto err_disable_pdev; | 871 | goto err_disable_pdev; |
| 871 | } | 872 | } |
| 872 | 873 | ||
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 593827b3fdd4..fa645d825009 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c | |||
| @@ -2505,6 +2505,10 @@ static dma_cookie_t pl330_tx_submit(struct dma_async_tx_descriptor *tx) | |||
| 2505 | /* Assign cookies to all nodes */ | 2505 | /* Assign cookies to all nodes */ |
| 2506 | while (!list_empty(&last->node)) { | 2506 | while (!list_empty(&last->node)) { |
| 2507 | desc = list_entry(last->node.next, struct dma_pl330_desc, node); | 2507 | desc = list_entry(last->node.next, struct dma_pl330_desc, node); |
| 2508 | if (pch->cyclic) { | ||
| 2509 | desc->txd.callback = last->txd.callback; | ||
| 2510 | desc->txd.callback_param = last->txd.callback_param; | ||
| 2511 | } | ||
| 2508 | 2512 | ||
| 2509 | dma_cookie_assign(&desc->txd); | 2513 | dma_cookie_assign(&desc->txd); |
| 2510 | 2514 | ||
| @@ -2688,45 +2692,82 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( | |||
| 2688 | size_t period_len, enum dma_transfer_direction direction, | 2692 | size_t period_len, enum dma_transfer_direction direction, |
| 2689 | unsigned long flags, void *context) | 2693 | unsigned long flags, void *context) |
| 2690 | { | 2694 | { |
| 2691 | struct dma_pl330_desc *desc; | 2695 | struct dma_pl330_desc *desc = NULL, *first = NULL; |
| 2692 | struct dma_pl330_chan *pch = to_pchan(chan); | 2696 | struct dma_pl330_chan *pch = to_pchan(chan); |
| 2697 | struct dma_pl330_dmac *pdmac = pch->dmac; | ||
| 2698 | unsigned int i; | ||
| 2693 | dma_addr_t dst; | 2699 | dma_addr_t dst; |
| 2694 | dma_addr_t src; | 2700 | dma_addr_t src; |
| 2695 | 2701 | ||
| 2696 | desc = pl330_get_desc(pch); | 2702 | if (len % period_len != 0) |
| 2697 | if (!desc) { | ||
| 2698 | dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n", | ||
| 2699 | __func__, __LINE__); | ||
| 2700 | return NULL; | 2703 | return NULL; |
| 2701 | } | ||
| 2702 | 2704 | ||
| 2703 | switch (direction) { | 2705 | if (!is_slave_direction(direction)) { |
| 2704 | case DMA_MEM_TO_DEV: | ||
| 2705 | desc->rqcfg.src_inc = 1; | ||
| 2706 | desc->rqcfg.dst_inc = 0; | ||
| 2707 | desc->req.rqtype = MEMTODEV; | ||
| 2708 | src = dma_addr; | ||
| 2709 | dst = pch->fifo_addr; | ||
| 2710 | break; | ||
| 2711 | case DMA_DEV_TO_MEM: | ||
| 2712 | desc->rqcfg.src_inc = 0; | ||
| 2713 | desc->rqcfg.dst_inc = 1; | ||
| 2714 | desc->req.rqtype = DEVTOMEM; | ||
| 2715 | src = pch->fifo_addr; | ||
| 2716 | dst = dma_addr; | ||
| 2717 | break; | ||
| 2718 | default: | ||
| 2719 | dev_err(pch->dmac->pif.dev, "%s:%d Invalid dma direction\n", | 2706 | dev_err(pch->dmac->pif.dev, "%s:%d Invalid dma direction\n", |
| 2720 | __func__, __LINE__); | 2707 | __func__, __LINE__); |
| 2721 | return NULL; | 2708 | return NULL; |
| 2722 | } | 2709 | } |
| 2723 | 2710 | ||
| 2724 | desc->rqcfg.brst_size = pch->burst_sz; | 2711 | for (i = 0; i < len / period_len; i++) { |
| 2725 | desc->rqcfg.brst_len = 1; | 2712 | desc = pl330_get_desc(pch); |
| 2713 | if (!desc) { | ||
| 2714 | dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n", | ||
| 2715 | __func__, __LINE__); | ||
| 2726 | 2716 | ||
| 2727 | pch->cyclic = true; | 2717 | if (!first) |
| 2718 | return NULL; | ||
| 2719 | |||
| 2720 | spin_lock_irqsave(&pdmac->pool_lock, flags); | ||
| 2721 | |||
| 2722 | while (!list_empty(&first->node)) { | ||
| 2723 | desc = list_entry(first->node.next, | ||
| 2724 | struct dma_pl330_desc, node); | ||
| 2725 | list_move_tail(&desc->node, &pdmac->desc_pool); | ||
| 2726 | } | ||
| 2727 | |||
| 2728 | list_move_tail(&first->node, &pdmac->desc_pool); | ||
| 2728 | 2729 | ||
| 2729 | fill_px(&desc->px, dst, src, period_len); | 2730 | spin_unlock_irqrestore(&pdmac->pool_lock, flags); |
| 2731 | |||
| 2732 | return NULL; | ||
| 2733 | } | ||
| 2734 | |||
| 2735 | switch (direction) { | ||
| 2736 | case DMA_MEM_TO_DEV: | ||
| 2737 | desc->rqcfg.src_inc = 1; | ||
| 2738 | desc->rqcfg.dst_inc = 0; | ||
| 2739 | desc->req.rqtype = MEMTODEV; | ||
| 2740 | src = dma_addr; | ||
| 2741 | dst = pch->fifo_addr; | ||
| 2742 | break; | ||
| 2743 | case DMA_DEV_TO_MEM: | ||
| 2744 | desc->rqcfg.src_inc = 0; | ||
| 2745 | desc->rqcfg.dst_inc = 1; | ||
| 2746 | desc->req.rqtype = DEVTOMEM; | ||
| 2747 | src = pch->fifo_addr; | ||
| 2748 | dst = dma_addr; | ||
| 2749 | break; | ||
| 2750 | default: | ||
| 2751 | break; | ||
| 2752 | } | ||
| 2753 | |||
| 2754 | desc->rqcfg.brst_size = pch->burst_sz; | ||
| 2755 | desc->rqcfg.brst_len = 1; | ||
| 2756 | fill_px(&desc->px, dst, src, period_len); | ||
| 2757 | |||
| 2758 | if (!first) | ||
| 2759 | first = desc; | ||
| 2760 | else | ||
| 2761 | list_add_tail(&desc->node, &first->node); | ||
| 2762 | |||
| 2763 | dma_addr += period_len; | ||
| 2764 | } | ||
| 2765 | |||
| 2766 | if (!desc) | ||
| 2767 | return NULL; | ||
| 2768 | |||
| 2769 | pch->cyclic = true; | ||
| 2770 | desc->txd.flags = flags; | ||
| 2730 | 2771 | ||
| 2731 | return &desc->txd; | 2772 | return &desc->txd; |
| 2732 | } | 2773 | } |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f2326fc60ac9..6f514297c483 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -1856,10 +1856,16 @@ | |||
| 1856 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) | 1856 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) |
| 1857 | 1857 | ||
| 1858 | #define PORT_HOTPLUG_STAT (dev_priv->info->display_mmio_offset + 0x61114) | 1858 | #define PORT_HOTPLUG_STAT (dev_priv->info->display_mmio_offset + 0x61114) |
| 1859 | /* HDMI/DP bits are gen4+ */ | 1859 | /* |
| 1860 | #define PORTB_HOTPLUG_LIVE_STATUS (1 << 29) | 1860 | * HDMI/DP bits are gen4+ |
| 1861 | * | ||
| 1862 | * WARNING: Bspec for hpd status bits on gen4 seems to be completely confused. | ||
| 1863 | * Please check the detailed lore in the commit message for for experimental | ||
| 1864 | * evidence. | ||
| 1865 | */ | ||
| 1866 | #define PORTD_HOTPLUG_LIVE_STATUS (1 << 29) | ||
| 1861 | #define PORTC_HOTPLUG_LIVE_STATUS (1 << 28) | 1867 | #define PORTC_HOTPLUG_LIVE_STATUS (1 << 28) |
| 1862 | #define PORTD_HOTPLUG_LIVE_STATUS (1 << 27) | 1868 | #define PORTB_HOTPLUG_LIVE_STATUS (1 << 27) |
| 1863 | #define PORTD_HOTPLUG_INT_STATUS (3 << 21) | 1869 | #define PORTD_HOTPLUG_INT_STATUS (3 << 21) |
| 1864 | #define PORTC_HOTPLUG_INT_STATUS (3 << 19) | 1870 | #define PORTC_HOTPLUG_INT_STATUS (3 << 19) |
| 1865 | #define PORTB_HOTPLUG_INT_STATUS (3 << 17) | 1871 | #define PORTB_HOTPLUG_INT_STATUS (3 << 17) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5fb305840db8..e38b45786653 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -8269,9 +8269,11 @@ check_crtc_state(struct drm_device *dev) | |||
| 8269 | 8269 | ||
| 8270 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | 8270 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
| 8271 | base.head) { | 8271 | base.head) { |
| 8272 | enum pipe pipe; | ||
| 8272 | if (encoder->base.crtc != &crtc->base) | 8273 | if (encoder->base.crtc != &crtc->base) |
| 8273 | continue; | 8274 | continue; |
| 8274 | if (encoder->get_config) | 8275 | if (encoder->get_config && |
| 8276 | encoder->get_hw_state(encoder, &pipe)) | ||
| 8275 | encoder->get_config(encoder, &pipe_config); | 8277 | encoder->get_config(encoder, &pipe_config); |
| 8276 | } | 8278 | } |
| 8277 | 8279 | ||
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 67e2c1f1c9a8..5950888ae1d0 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -497,8 +497,11 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max) | |||
| 497 | goto out; | 497 | goto out; |
| 498 | } | 498 | } |
| 499 | 499 | ||
| 500 | /* scale to hardware */ | 500 | /* scale to hardware, but be careful to not overflow */ |
| 501 | level = level * freq / max; | 501 | if (freq < max) |
| 502 | level = level * freq / max; | ||
| 503 | else | ||
| 504 | level = freq / max * level; | ||
| 502 | 505 | ||
| 503 | dev_priv->backlight.level = level; | 506 | dev_priv->backlight.level = level; |
| 504 | if (dev_priv->backlight.device) | 507 | if (dev_priv->backlight.device) |
| @@ -515,6 +518,17 @@ void intel_panel_disable_backlight(struct drm_device *dev) | |||
| 515 | struct drm_i915_private *dev_priv = dev->dev_private; | 518 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 516 | unsigned long flags; | 519 | unsigned long flags; |
| 517 | 520 | ||
| 521 | /* | ||
| 522 | * Do not disable backlight on the vgaswitcheroo path. When switching | ||
| 523 | * away from i915, the other client may depend on i915 to handle the | ||
| 524 | * backlight. This will leave the backlight on unnecessarily when | ||
| 525 | * another client is not activated. | ||
| 526 | */ | ||
| 527 | if (dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) { | ||
| 528 | DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n"); | ||
| 529 | return; | ||
| 530 | } | ||
| 531 | |||
| 518 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); | 532 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); |
| 519 | 533 | ||
| 520 | dev_priv->backlight.enabled = false; | 534 | dev_priv->backlight.enabled = false; |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index f895d1508df8..b0e4a0bd1313 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -5063,8 +5063,26 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) | |||
| 5063 | } | 5063 | } |
| 5064 | } else { | 5064 | } else { |
| 5065 | if (enable_requested) { | 5065 | if (enable_requested) { |
| 5066 | unsigned long irqflags; | ||
| 5067 | enum pipe p; | ||
| 5068 | |||
| 5066 | I915_WRITE(HSW_PWR_WELL_DRIVER, 0); | 5069 | I915_WRITE(HSW_PWR_WELL_DRIVER, 0); |
| 5070 | POSTING_READ(HSW_PWR_WELL_DRIVER); | ||
| 5067 | DRM_DEBUG_KMS("Requesting to disable the power well\n"); | 5071 | DRM_DEBUG_KMS("Requesting to disable the power well\n"); |
| 5072 | |||
| 5073 | /* | ||
| 5074 | * After this, the registers on the pipes that are part | ||
| 5075 | * of the power well will become zero, so we have to | ||
| 5076 | * adjust our counters according to that. | ||
| 5077 | * | ||
| 5078 | * FIXME: Should we do this in general in | ||
| 5079 | * drm_vblank_post_modeset? | ||
| 5080 | */ | ||
| 5081 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
| 5082 | for_each_pipe(p) | ||
| 5083 | if (p != PIPE_A) | ||
| 5084 | dev->last_vblank[p] = 0; | ||
| 5085 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
| 5068 | } | 5086 | } |
| 5069 | } | 5087 | } |
| 5070 | } | 5088 | } |
