Skip to content

Commit

Permalink
Merge branch 'bdw-fixes' into backlight-rework
Browse files Browse the repository at this point in the history
Merge the bdw changes into the backlight rework branch so that we can
adapt the new code for bdw, too.  This is a bit a mess, but doing this
another way would have delayed the merging of the backlight
refactoring. Mea culpa.

As discussed with Jani on irc only do bdw-specific callbacks for the
set/get methods and bake in the only other special-case into the pch
enable function.

Conflicts:
	drivers/gpu/drm/i915/intel_panel.c

v2: Don't enable the PWM too early for bdw (Jani).

v3: Create new bdw_ functions for setup and enable - the rules change
sufficiently imo with the switch from controlling the pwm from the cpu
to controlling it completel from the pch to warrant this.

v4: Rip out unused pipe variable in bdw_enable_backlight (0-day
builder).

Tested-by: Ben Widawsky <ben@bwidawsk.net> (on bdw)
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Daniel Vetter committed Nov 15, 2013
2 parents 565ee38 + 596cc11 commit 96ab4c7
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 34 deletions.
11 changes: 8 additions & 3 deletions drivers/gpu/drm/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -1329,7 +1329,7 @@ static u32 edid_get_quirks(struct edid *edid)
}

#define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay)
#define MODE_REFRESH_DIFF(m,r) (abs((m)->vrefresh - target_refresh))
#define MODE_REFRESH_DIFF(c,t) (abs((c) - (t)))

/**
* edid_fixup_preferred - set preferred modes based on quirk list
Expand All @@ -1344,6 +1344,7 @@ static void edid_fixup_preferred(struct drm_connector *connector,
{
struct drm_display_mode *t, *cur_mode, *preferred_mode;
int target_refresh = 0;
int cur_vrefresh, preferred_vrefresh;

if (list_empty(&connector->probed_modes))
return;
Expand All @@ -1366,10 +1367,14 @@ static void edid_fixup_preferred(struct drm_connector *connector,
if (MODE_SIZE(cur_mode) > MODE_SIZE(preferred_mode))
preferred_mode = cur_mode;

cur_vrefresh = cur_mode->vrefresh ?
cur_mode->vrefresh : drm_mode_vrefresh(cur_mode);
preferred_vrefresh = preferred_mode->vrefresh ?
preferred_mode->vrefresh : drm_mode_vrefresh(preferred_mode);
/* At a given size, try to get closest to target refresh */
if ((MODE_SIZE(cur_mode) == MODE_SIZE(preferred_mode)) &&
MODE_REFRESH_DIFF(cur_mode, target_refresh) <
MODE_REFRESH_DIFF(preferred_mode, target_refresh)) {
MODE_REFRESH_DIFF(cur_vrefresh, target_refresh) <
MODE_REFRESH_DIFF(preferred_vrefresh, target_refresh)) {
preferred_mode = cur_mode;
}
}
Expand Down
7 changes: 6 additions & 1 deletion drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1755,8 +1755,13 @@ struct drm_i915_file_private {
#define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile)
#define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \
((dev)->pdev->device & 0xFF00) == 0x0C00)
#define IS_ULT(dev) (IS_HASWELL(dev) && \
#define IS_BDW_ULT(dev) (IS_BROADWELL(dev) && \
(((dev)->pdev->device & 0xf) == 0x2 || \
((dev)->pdev->device & 0xf) == 0x6 || \
((dev)->pdev->device & 0xf) == 0xe))
#define IS_HSW_ULT(dev) (IS_HASWELL(dev) && \
((dev)->pdev->device & 0xFF00) == 0x0A00)
#define IS_ULT(dev) (IS_HSW_ULT(dev) || IS_BDW_ULT(dev))
#define IS_HSW_GT3(dev) (IS_HASWELL(dev) && \
((dev)->pdev->device & 0x00F0) == 0x0020)
#define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary)
Expand Down
9 changes: 7 additions & 2 deletions drivers/gpu/drm/i915/i915_gem_gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,8 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
kfree(ppgtt->gen8_pt_dma_addr[i]);
}

__free_pages(ppgtt->gen8_pt_pages, ppgtt->num_pt_pages << PAGE_SHIFT);
__free_pages(ppgtt->pd_pages, ppgtt->num_pd_pages << PAGE_SHIFT);
__free_pages(ppgtt->gen8_pt_pages, get_order(ppgtt->num_pt_pages << PAGE_SHIFT));
__free_pages(ppgtt->pd_pages, get_order(ppgtt->num_pd_pages << PAGE_SHIFT));
}

/**
Expand Down Expand Up @@ -1239,6 +1239,11 @@ static inline unsigned int gen8_get_total_gtt_size(u16 bdw_gmch_ctl)
bdw_gmch_ctl &= BDW_GMCH_GGMS_MASK;
if (bdw_gmch_ctl)
bdw_gmch_ctl = 1 << bdw_gmch_ctl;
if (bdw_gmch_ctl > 4) {
WARN_ON(!i915_preliminary_hw_support);
return 4<<20;
}

return bdw_gmch_ctl << 20;
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/intel_opregion.c
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,9 @@ int intel_opregion_setup(struct drm_device *dev)
return -ENOTSUPP;
}

#ifdef CONFIG_ACPI
INIT_WORK(&opregion->asle_work, asle_work);
#endif

base = acpi_os_ioremap(asls, OPREGION_SIZE);
if (!base)
Expand Down
81 changes: 80 additions & 1 deletion drivers/gpu/drm/i915/intel_panel.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,14 @@ static u32 intel_panel_compute_brightness(struct intel_connector *connector,
return val;
}

static u32 bdw_get_backlight(struct intel_connector *connector)
{
struct drm_device *dev = connector->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;

return I915_READ(BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
}

static u32 pch_get_backlight(struct intel_connector *connector)
{
struct drm_device *dev = connector->base.dev;
Expand Down Expand Up @@ -414,6 +422,14 @@ static u32 intel_panel_get_backlight(struct intel_connector *connector)
return val;
}

static void bdw_set_backlight(struct intel_connector *connector, u32 level)
{
struct drm_device *dev = connector->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
I915_WRITE(BLC_PWM_PCH_CTL2, val | level);
}

static void pch_set_backlight(struct intel_connector *connector, u32 level)
{
struct drm_device *dev = connector->base.dev;
Expand Down Expand Up @@ -585,6 +601,38 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
}

static void bdw_enable_backlight(struct intel_connector *connector)
{
struct drm_device *dev = connector->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_panel *panel = &connector->panel;
u32 pch_ctl1, pch_ctl2;

pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
DRM_DEBUG_KMS("pch backlight already enabled\n");
pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
}

pch_ctl2 = panel->backlight.max << 16;
I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);

pch_ctl1 = 0;
if (panel->backlight.active_low_pwm)
pch_ctl1 |= BLM_PCH_POLARITY;

/* BDW always uses the pch pwm controls. */
pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;

I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
POSTING_READ(BLC_PWM_PCH_CTL1);
I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);

/* This won't stick until the above enable. */
intel_panel_actually_set_backlight(connector, panel->backlight.level);
}

static void pch_enable_backlight(struct intel_connector *connector)
{
struct drm_device *dev = connector->base.dev;
Expand Down Expand Up @@ -626,6 +674,7 @@ static void pch_enable_backlight(struct intel_connector *connector)
pch_ctl1 = 0;
if (panel->backlight.active_low_pwm)
pch_ctl1 |= BLM_PCH_POLARITY;

I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
POSTING_READ(BLC_PWM_PCH_CTL1);
I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
Expand Down Expand Up @@ -869,6 +918,30 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
* XXX: Query mode clock or hardware clock and program PWM modulation frequency
* appropriately when it's 0. Use VBT and/or sane defaults.
*/
static int bdw_setup_backlight(struct intel_connector *connector)
{
struct drm_device *dev = connector->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_panel *panel = &connector->panel;
u32 pch_ctl1, pch_ctl2, val;

pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;

pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
panel->backlight.max = pch_ctl2 >> 16;
if (!panel->backlight.max)
return -ENODEV;

val = bdw_get_backlight(connector);
panel->backlight.level = intel_panel_compute_brightness(connector, val);

panel->backlight.enabled = (pch_ctl1 & BLM_PCH_PWM_ENABLE) &&
panel->backlight.level != 0;

return 0;
}

static int pch_setup_backlight(struct intel_connector *connector)
{
struct drm_device *dev = connector->base.dev;
Expand Down Expand Up @@ -1036,7 +1109,13 @@ void intel_panel_init_backlight_funcs(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;

if (HAS_PCH_SPLIT(dev)) {
if (IS_BROADWELL(dev)) {
dev_priv->display.setup_backlight = bdw_setup_backlight;
dev_priv->display.enable_backlight = bdw_enable_backlight;
dev_priv->display.disable_backlight = pch_disable_backlight;
dev_priv->display.set_backlight = bdw_set_backlight;
dev_priv->display.get_backlight = bdw_get_backlight;
} else if (HAS_PCH_SPLIT(dev)) {
dev_priv->display.setup_backlight = pch_setup_backlight;
dev_priv->display.enable_backlight = pch_enable_backlight;
dev_priv->display.disable_backlight = pch_disable_backlight;
Expand Down
18 changes: 17 additions & 1 deletion drivers/gpu/drm/i915/intel_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -5684,6 +5684,7 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable)
{
struct drm_i915_private *dev_priv = dev->dev_private;
bool is_enabled, enable_requested;
unsigned long irqflags;
uint32_t tmp;

tmp = I915_READ(HSW_PWR_WELL_DRIVER);
Expand All @@ -5701,9 +5702,24 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable)
HSW_PWR_WELL_STATE_ENABLED), 20))
DRM_ERROR("Timeout enabling power well\n");
}

if (IS_BROADWELL(dev)) {
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_B),
dev_priv->de_irq_mask[PIPE_B]);
I915_WRITE(GEN8_DE_PIPE_IER(PIPE_B),
~dev_priv->de_irq_mask[PIPE_B] |
GEN8_PIPE_VBLANK);
I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_C),
dev_priv->de_irq_mask[PIPE_C]);
I915_WRITE(GEN8_DE_PIPE_IER(PIPE_C),
~dev_priv->de_irq_mask[PIPE_C] |
GEN8_PIPE_VBLANK);
POSTING_READ(GEN8_DE_PIPE_IER(PIPE_C));
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
}
} else {
if (enable_requested) {
unsigned long irqflags;
enum pipe p;

I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/intel_ringbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,7 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring)
} else if (IS_GEN6(ring->dev)) {
mmio = RING_HWS_PGA_GEN6(ring->mmio_base);
} else {
/* XXX: gen8 returns to sanity */
mmio = RING_HWS_PGA(ring->mmio_base);
}

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/intel_uncore.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,7 @@ static int gen6_do_reset(struct drm_device *dev)
int intel_gpu_reset(struct drm_device *dev)
{
switch (INTEL_INFO(dev)->gen) {
case 8:
case 7:
case 6: return gen6_do_reset(dev);
case 5: return ironlake_do_reset(dev);
Expand Down
30 changes: 13 additions & 17 deletions drivers/gpu/drm/ttm/ttm_bo_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
int retval = VM_FAULT_NOPAGE;
struct ttm_mem_type_manager *man =
&bdev->man[bo->mem.mem_type];
struct vm_area_struct cvma;

/*
* Work around locking order reversal in fault / nopfn
Expand Down Expand Up @@ -164,26 +165,21 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
}

/*
* Strictly, we're not allowed to modify vma->vm_page_prot here,
* since the mmap_sem is only held in read mode. However, we
* modify only the caching bits of vma->vm_page_prot and
* consider those bits protected by
* the bo->mutex, as we should be the only writers.
* There shouldn't really be any readers of these bits except
* within vm_insert_mixed()? fork?
*
* TODO: Add a list of vmas to the bo, and change the
* vma->vm_page_prot when the object changes caching policy, with
* the correct locks held.
* Make a local vma copy to modify the page_prot member
* and vm_flags if necessary. The vma parameter is protected
* by mmap_sem in write mode.
*/
cvma = *vma;
cvma.vm_page_prot = vm_get_page_prot(cvma.vm_flags);

if (bo->mem.bus.is_iomem) {
vma->vm_page_prot = ttm_io_prot(bo->mem.placement,
vma->vm_page_prot);
cvma.vm_page_prot = ttm_io_prot(bo->mem.placement,
cvma.vm_page_prot);
} else {
ttm = bo->ttm;
vma->vm_page_prot = (bo->mem.placement & TTM_PL_FLAG_CACHED) ?
vm_get_page_prot(vma->vm_flags) :
ttm_io_prot(bo->mem.placement, vma->vm_page_prot);
if (!(bo->mem.placement & TTM_PL_FLAG_CACHED))
cvma.vm_page_prot = ttm_io_prot(bo->mem.placement,
cvma.vm_page_prot);

/* Allocate all page at once, most common usage */
if (ttm->bdev->driver->ttm_tt_populate(ttm)) {
Expand All @@ -210,7 +206,7 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
pfn = page_to_pfn(page);
}

ret = vm_insert_mixed(vma, address, pfn);
ret = vm_insert_mixed(&cvma, address, pfn);
/*
* Somebody beat us to this PTE or prefaulting to
* an already populated PTE, or prefaulting error.
Expand Down
7 changes: 6 additions & 1 deletion drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,12 +453,13 @@ static void vmw_get_initial_size(struct vmw_private *dev_priv)
*/
static int vmw_dma_select_mode(struct vmw_private *dev_priv)
{
const struct dma_map_ops *dma_ops = get_dma_ops(dev_priv->dev->dev);
static const char *names[vmw_dma_map_max] = {
[vmw_dma_phys] = "Using physical TTM page addresses.",
[vmw_dma_alloc_coherent] = "Using coherent TTM pages.",
[vmw_dma_map_populate] = "Keeping DMA mappings.",
[vmw_dma_map_bind] = "Giving up DMA mappings early."};
#ifdef CONFIG_X86
const struct dma_map_ops *dma_ops = get_dma_ops(dev_priv->dev->dev);

#ifdef CONFIG_INTEL_IOMMU
if (intel_iommu_enabled) {
Expand Down Expand Up @@ -500,6 +501,10 @@ static int vmw_dma_select_mode(struct vmw_private *dev_priv)
return -EINVAL;
#endif

#else /* CONFIG_X86 */
dev_priv->map_mode = vmw_dma_map_populate;
#endif /* CONFIG_X86 */

DRM_INFO("DMA map mode: %s\n", names[dev_priv->map_mode]);

return 0;
Expand Down
7 changes: 5 additions & 2 deletions drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ static void vmw_gmr_free_descriptors(struct device *dev, dma_addr_t desc_dma,
}

page_virtual = kmap_atomic(page);
desc_dma = page_virtual[desc_per_page].ppn << PAGE_SHIFT;
desc_dma = (dma_addr_t)
le32_to_cpu(page_virtual[desc_per_page].ppn) <<
PAGE_SHIFT;
kunmap_atomic(page_virtual);

__free_page(page);
Expand Down Expand Up @@ -217,7 +219,8 @@ static int vmw_gmr_build_descriptors(struct device *dev,
desc_dma = 0;
list_for_each_entry_reverse(page, desc_pages, lru) {
page_virtual = kmap_atomic(page);
page_virtual[desc_per_page].ppn = desc_dma >> PAGE_SHIFT;
page_virtual[desc_per_page].ppn = cpu_to_le32
(desc_dma >> PAGE_SHIFT);
kunmap_atomic(page_virtual);
desc_dma = dma_map_page(dev, page, 0, PAGE_SIZE,
DMA_TO_DEVICE);
Expand Down
Loading

0 comments on commit 96ab4c7

Please sign in to comment.