diff options
-rw-r--r-- | ARM-OMAP4-Fix-crashes.patch | 46 | ||||
-rw-r--r-- | arm-revert-mmc-omap_hsmmc-Use-dma_request_chan-for-reque.patch | 100 | ||||
-rw-r--r-- | arm64-mm-Fix-memmap-to-be-initialized-for-the-entire-section.patch | 93 | ||||
-rw-r--r-- | bcm283x-vc4-fixes.patch | 308 | ||||
-rw-r--r-- | config-arm-generic | 4 | ||||
-rw-r--r-- | config-armv7-generic | 8 | ||||
-rw-r--r-- | drm_i915_skl_Backport_watermark_fixes_for_4.8.y.patch | 1247 | ||||
-rw-r--r-- | kernel.spec | 20 | ||||
-rw-r--r-- | sources | 2 |
9 files changed, 262 insertions, 1566 deletions
diff --git a/ARM-OMAP4-Fix-crashes.patch b/ARM-OMAP4-Fix-crashes.patch new file mode 100644 index 000000000..5a4a257e1 --- /dev/null +++ b/ARM-OMAP4-Fix-crashes.patch @@ -0,0 +1,46 @@ +From patchwork Wed Oct 26 15:17:01 2016 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [3/5] ARM: OMAP4+: Fix bad fallthrough for cpuidle +From: Tony Lindgren <tony@atomide.com> +X-Patchwork-Id: 9397501 +Message-Id: <20161026151703.24730-4-tony@atomide.com> +To: linux-omap@vger.kernel.org +Cc: Nishanth Menon <nm@ti.com>, Dmitry Lifshitz <lifshitz@compulab.co.il>, + Dave Gerlach <d-gerlach@ti.com>, + Enric Balletbo Serra <eballetbo@gmail.com>, + "Dr . H . Nikolaus Schaller" <hns@goldelico.com>, + Pau Pajuel <ppajuel@gmail.com>, Grazvydas Ignotas <notasas@gmail.com>, + Benoit Cousson <bcousson@baylibre.com>, + Santosh Shilimkar <ssantosh@kernel.org>, + Javier Martinez Canillas <javier@dowhile0.org>, + Robert Nelson <robertcnelson@gmail.com>, + Marek Belisko <marek@goldelico.com>, linux-arm-kernel@lists.infradead.org +Date: Wed, 26 Oct 2016 08:17:01 -0700 + +We don't want to fall through to a bunch of errors for retention +if PM_OMAP4_CPU_OSWR_DISABLE is not configured for a SoC. + +Fixes: 6099dd37c669 ("ARM: OMAP5 / DRA7: Enable CPU RET on suspend") +Signed-off-by: Tony Lindgren <tony@atomide.com> +--- + arch/arm/mach-omap2/omap-mpuss-lowpower.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c +--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c ++++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c +@@ -244,10 +244,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) + save_state = 1; + break; + case PWRDM_POWER_RET: +- if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE)) { ++ if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE)) + save_state = 0; +- break; +- } ++ break; + default: + /* + * CPUx CSWR is invalid hardware state. Also CPUx OSWR diff --git a/arm-revert-mmc-omap_hsmmc-Use-dma_request_chan-for-reque.patch b/arm-revert-mmc-omap_hsmmc-Use-dma_request_chan-for-reque.patch new file mode 100644 index 000000000..b55dec0cb --- /dev/null +++ b/arm-revert-mmc-omap_hsmmc-Use-dma_request_chan-for-reque.patch @@ -0,0 +1,100 @@ +From bb3e08008c0e48fd4f51a0f0957eecae61a24d69 Mon Sep 17 00:00:00 2001 +From: Peter Robinson <pbrobinson@gmail.com> +Date: Tue, 1 Nov 2016 09:35:30 +0000 +Subject: [PATCH] Revert "mmc: omap_hsmmc: Use dma_request_chan() for + requesting DMA channel" + +This reverts commit 81eef6ca92014845d40e3f1310e42b7010303acc. +--- + drivers/mmc/host/omap_hsmmc.c | 50 ++++++++++++++++++++++++++++++++++--------- + 1 file changed, 40 insertions(+), 10 deletions(-) + +diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c +index 24ebc9a..3563321 100644 +--- a/drivers/mmc/host/omap_hsmmc.c ++++ b/drivers/mmc/host/omap_hsmmc.c +@@ -32,6 +32,7 @@ + #include <linux/of_irq.h> + #include <linux/of_gpio.h> + #include <linux/of_device.h> ++#include <linux/omap-dmaengine.h> + #include <linux/mmc/host.h> + #include <linux/mmc/core.h> + #include <linux/mmc/mmc.h> +@@ -1992,6 +1993,8 @@ static int omap_hsmmc_probe(struct platform_device *pdev) + struct resource *res; + int ret, irq; + const struct of_device_id *match; ++ dma_cap_mask_t mask; ++ unsigned tx_req, rx_req; + const struct omap_mmc_of_data *data; + void __iomem *base; + +@@ -2121,17 +2124,44 @@ static int omap_hsmmc_probe(struct platform_device *pdev) + + omap_hsmmc_conf_bus_power(host); + +- host->rx_chan = dma_request_chan(&pdev->dev, "rx"); +- if (IS_ERR(host->rx_chan)) { +- dev_err(mmc_dev(host->mmc), "RX DMA channel request failed\n"); +- ret = PTR_ERR(host->rx_chan); ++ if (!pdev->dev.of_node) { ++ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); ++ if (!res) { ++ dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n"); ++ ret = -ENXIO; ++ goto err_irq; ++ } ++ tx_req = res->start; ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); ++ if (!res) { ++ dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n"); ++ ret = -ENXIO; ++ goto err_irq; ++ } ++ rx_req = res->start; ++ } ++ ++ dma_cap_zero(mask); ++ dma_cap_set(DMA_SLAVE, mask); ++ ++ host->rx_chan = ++ dma_request_slave_channel_compat(mask, omap_dma_filter_fn, ++ &rx_req, &pdev->dev, "rx"); ++ ++ if (!host->rx_chan) { ++ dev_err(mmc_dev(host->mmc), "unable to obtain RX DMA engine channel\n"); ++ ret = -ENXIO; + goto err_irq; + } + +- host->tx_chan = dma_request_chan(&pdev->dev, "tx"); +- if (IS_ERR(host->tx_chan)) { +- dev_err(mmc_dev(host->mmc), "TX DMA channel request failed\n"); +- ret = PTR_ERR(host->tx_chan); ++ host->tx_chan = ++ dma_request_slave_channel_compat(mask, omap_dma_filter_fn, ++ &tx_req, &pdev->dev, "tx"); ++ ++ if (!host->tx_chan) { ++ dev_err(mmc_dev(host->mmc), "unable to obtain TX DMA engine channel\n"); ++ ret = -ENXIO; + goto err_irq; + } + +@@ -2189,9 +2219,9 @@ err_slot_name: + mmc_remove_host(mmc); + err_irq: + device_init_wakeup(&pdev->dev, false); +- if (!IS_ERR_OR_NULL(host->tx_chan)) ++ if (host->tx_chan) + dma_release_channel(host->tx_chan); +- if (!IS_ERR_OR_NULL(host->rx_chan)) ++ if (host->rx_chan) + dma_release_channel(host->rx_chan); + pm_runtime_dont_use_autosuspend(host->dev); + pm_runtime_put_sync(host->dev); +-- +2.9.3 + diff --git a/arm64-mm-Fix-memmap-to-be-initialized-for-the-entire-section.patch b/arm64-mm-Fix-memmap-to-be-initialized-for-the-entire-section.patch new file mode 100644 index 000000000..eaf809d53 --- /dev/null +++ b/arm64-mm-Fix-memmap-to-be-initialized-for-the-entire-section.patch @@ -0,0 +1,93 @@ +From patchwork Thu Oct 6 09:52:07 2016 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: arm64: mm: Fix memmap to be initialized for the entire section +From: Robert Richter <rrichter@cavium.com> +X-Patchwork-Id: 9364537 +Message-Id: <1475747527-32387-1-git-send-email-rrichter@cavium.com> +To: Catalin Marinas <catalin.marinas@arm.com>, Will Deacon + <will.deacon@arm.com> +Cc: Mark Rutland <mark.rutland@arm.com>, linux-efi@vger.kernel.org, + David Daney <david.daney@cavium.com>, + Ard Biesheuvel <ard.biesheuvel@linaro.org>, + linux-kernel@vger.kernel.org, Robert Richter <rrichter@cavium.com>, + Hanjun Guo <hanjun.guo@linaro.org>, linux-arm-kernel@lists.infradead.org +Date: Thu, 6 Oct 2016 11:52:07 +0200 + +There is a memory setup problem on ThunderX systems with certain +memory configurations. The symptom is + + kernel BUG at mm/page_alloc.c:1848! + +This happens for some configs with 64k page size enabled. The bug +triggers for page zones with some pages in the zone not assigned to +this particular zone. In my case some pages that are marked as nomap +were not reassigned to the new zone of node 1, so those are still +assigned to node 0. + +The reason for the mis-configuration is a change in pfn_valid() which +reports pages marked nomap as invalid: + + 68709f45385a arm64: only consider memblocks with NOMAP cleared for linear mapping + +This causes pages marked as nomap being no long reassigned to the new +zone in memmap_init_zone() by calling __init_single_pfn(). + +Fixing this by restoring the old behavior of pfn_valid() to use +memblock_is_memory(). Also changing users of pfn_valid() in arm64 code +to use memblock_is_map_memory() where necessary. This only affects +code in ioremap.c. The code in mmu.c still can use the new version of +pfn_valid(). + +Should be marked stable v4.5.. + +Signed-off-by: Robert Richter <rrichter@cavium.com> +--- + arch/arm64/mm/init.c | 2 +- + arch/arm64/mm/ioremap.c | 5 +++-- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c +index bbb7ee76e319..25b8659c2a9f 100644 +--- a/arch/arm64/mm/init.c ++++ b/arch/arm64/mm/init.c +@@ -147,7 +147,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) + #ifdef CONFIG_HAVE_ARCH_PFN_VALID + int pfn_valid(unsigned long pfn) + { +- return memblock_is_map_memory(pfn << PAGE_SHIFT); ++ return memblock_is_memory(pfn << PAGE_SHIFT); + } + EXPORT_SYMBOL(pfn_valid); + #endif +diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c +index 01e88c8bcab0..c17c220b0c48 100644 +--- a/arch/arm64/mm/ioremap.c ++++ b/arch/arm64/mm/ioremap.c +@@ -21,6 +21,7 @@ + */ + + #include <linux/export.h> ++#include <linux/memblock.h> + #include <linux/mm.h> + #include <linux/vmalloc.h> + #include <linux/io.h> +@@ -55,7 +56,7 @@ static void __iomem *__ioremap_caller(phys_addr_t phys_addr, size_t size, + /* + * Don't allow RAM to be mapped. + */ +- if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr)))) ++ if (WARN_ON(memblock_is_map_memory(phys_addr))) + return NULL; + + area = get_vm_area_caller(size, VM_IOREMAP, caller); +@@ -96,7 +97,7 @@ EXPORT_SYMBOL(__iounmap); + void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size) + { + /* For normal memory we already have a cacheable mapping. */ +- if (pfn_valid(__phys_to_pfn(phys_addr))) ++ if (memblock_is_map_memory(phys_addr)) + return (void __iomem *)__phys_to_virt(phys_addr); + + return __ioremap_caller(phys_addr, size, __pgprot(PROT_NORMAL), diff --git a/bcm283x-vc4-fixes.patch b/bcm283x-vc4-fixes.patch index 4d496ec4d..3f77b7485 100644 --- a/bcm283x-vc4-fixes.patch +++ b/bcm283x-vc4-fixes.patch @@ -133,237 +133,6 @@ index 160942a..9ecd6ff 100644 -- 2.9.3 -From 107d3188b3723840deddaa5efeffcaf167e462f2 Mon Sep 17 00:00:00 2001 -From: Eric Anholt <eric@anholt.net> -Date: Wed, 28 Sep 2016 08:42:42 -0700 -Subject: [PATCH 3/4] drm/vc4: Fix races when the CS reads from render targets. - -With the introduction of bin/render pipelining, the previous job may -not be completed when we start binning the next one. If the previous -job wrote our VBO, IB, or CS textures, then the binning stage might -get stale or uninitialized results. - -Fixes the major rendering failure in glmark2 -b terrain. - -Signed-off-by: Eric Anholt <eric@anholt.net> -Fixes: ca26d28bbaa3 ("drm/vc4: improve throughput by pipelining binning and rendering jobs") -Cc: stable@vger.kernel.org ---- - drivers/gpu/drm/vc4/vc4_drv.h | 19 ++++++++++++++++++- - drivers/gpu/drm/vc4/vc4_gem.c | 13 +++++++++++++ - drivers/gpu/drm/vc4/vc4_render_cl.c | 21 +++++++++++++++++---- - drivers/gpu/drm/vc4/vc4_validate.c | 17 ++++++++++++++--- - 4 files changed, 62 insertions(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h -index 428e249..f696b75 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -122,9 +122,16 @@ to_vc4_dev(struct drm_device *dev) - struct vc4_bo { - struct drm_gem_cma_object base; - -- /* seqno of the last job to render to this BO. */ -+ /* seqno of the last job to render using this BO. */ - uint64_t seqno; - -+ /* seqno of the last job to use the RCL to write to this BO. -+ * -+ * Note that this doesn't include binner overflow memory -+ * writes. -+ */ -+ uint64_t write_seqno; -+ - /* List entry for the BO's position in either - * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list - */ -@@ -216,6 +223,9 @@ struct vc4_exec_info { - /* Sequence number for this bin/render job. */ - uint64_t seqno; - -+ /* Latest write_seqno of any BO that binning depends on. */ -+ uint64_t bin_dep_seqno; -+ - /* Last current addresses the hardware was processing when the - * hangcheck timer checked on us. - */ -@@ -230,6 +240,13 @@ struct vc4_exec_info { - struct drm_gem_cma_object **bo; - uint32_t bo_count; - -+ /* List of BOs that are being written by the RCL. Other than -+ * the binner temporary storage, this is all the BOs written -+ * by the job. -+ */ -+ struct drm_gem_cma_object *rcl_write_bo[4]; -+ uint32_t rcl_write_bo_count; -+ - /* Pointers for our position in vc4->job_list */ - struct list_head head; - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index b262c5c..ae1609e 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -471,6 +471,11 @@ vc4_update_bo_seqnos(struct vc4_exec_info *exec, uint64_t seqno) - list_for_each_entry(bo, &exec->unref_list, unref_head) { - bo->seqno = seqno; - } -+ -+ for (i = 0; i < exec->rcl_write_bo_count; i++) { -+ bo = to_vc4_bo(&exec->rcl_write_bo[i]->base); -+ bo->write_seqno = seqno; -+ } - } - - /* Queues a struct vc4_exec_info for execution. If no job is -@@ -673,6 +678,14 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) - goto fail; - - ret = vc4_validate_shader_recs(dev, exec); -+ if (ret) -+ goto fail; -+ -+ /* Block waiting on any previous rendering into the CS's VBO, -+ * IB, or textures, so that pixels are actually written by the -+ * time we try to read them. -+ */ -+ ret = vc4_wait_for_seqno(dev, exec->bin_dep_seqno, ~0ull, true); - - fail: - drm_free_large(temp); -diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c -index 0f12418..08886a3 100644 ---- a/drivers/gpu/drm/vc4/vc4_render_cl.c -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -45,6 +45,8 @@ struct vc4_rcl_setup { - - struct drm_gem_cma_object *rcl; - u32 next_offset; -+ -+ u32 next_write_bo_index; - }; - - static inline void rcl_u8(struct vc4_rcl_setup *setup, u8 val) -@@ -407,6 +409,8 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec, - if (!*obj) - return -EINVAL; - -+ exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; -+ - if (surf->offset & 0xf) { - DRM_ERROR("MSAA write must be 16b aligned.\n"); - return -EINVAL; -@@ -417,7 +421,8 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec, - - static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, - struct drm_gem_cma_object **obj, -- struct drm_vc4_submit_rcl_surface *surf) -+ struct drm_vc4_submit_rcl_surface *surf, -+ bool is_write) - { - uint8_t tiling = VC4_GET_FIELD(surf->bits, - VC4_LOADSTORE_TILE_BUFFER_TILING); -@@ -440,6 +445,9 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, - if (!*obj) - return -EINVAL; - -+ if (is_write) -+ exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; -+ - if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { - if (surf == &exec->args->zs_write) { - DRM_ERROR("general zs write may not be a full-res.\n"); -@@ -542,6 +550,8 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec, - if (!*obj) - return -EINVAL; - -+ exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; -+ - if (tiling > VC4_TILING_FORMAT_LT) { - DRM_ERROR("Bad tiling format\n"); - return -EINVAL; -@@ -599,15 +609,18 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) - if (ret) - return ret; - -- ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read); -+ ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read, -+ false); - if (ret) - return ret; - -- ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read); -+ ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read, -+ false); - if (ret) - return ret; - -- ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write); -+ ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write, -+ true); - if (ret) - return ret; - -diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c -index 9ce1d0a..26503e3 100644 ---- a/drivers/gpu/drm/vc4/vc4_validate.c -+++ b/drivers/gpu/drm/vc4/vc4_validate.c -@@ -267,6 +267,9 @@ validate_indexed_prim_list(VALIDATE_ARGS) - if (!ib) - return -EINVAL; - -+ exec->bin_dep_seqno = max(exec->bin_dep_seqno, -+ to_vc4_bo(&ib->base)->write_seqno); -+ - if (offset > ib->base.size || - (ib->base.size - offset) / index_size < length) { - DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n", -@@ -555,8 +558,7 @@ static bool - reloc_tex(struct vc4_exec_info *exec, - void *uniform_data_u, - struct vc4_texture_sample_info *sample, -- uint32_t texture_handle_index) -- -+ uint32_t texture_handle_index, bool is_cs) - { - struct drm_gem_cma_object *tex; - uint32_t p0 = *(uint32_t *)(uniform_data_u + sample->p_offset[0]); -@@ -714,6 +716,11 @@ reloc_tex(struct vc4_exec_info *exec, - - *validated_p0 = tex->paddr + p0; - -+ if (is_cs) { -+ exec->bin_dep_seqno = max(exec->bin_dep_seqno, -+ to_vc4_bo(&tex->base)->write_seqno); -+ } -+ - return true; - fail: - DRM_INFO("Texture p0 at %d: 0x%08x\n", sample->p_offset[0], p0); -@@ -835,7 +842,8 @@ validate_gl_shader_rec(struct drm_device *dev, - if (!reloc_tex(exec, - uniform_data_u, - &validated_shader->texture_samples[tex], -- texture_handles_u[tex])) { -+ texture_handles_u[tex], -+ i == 2)) { - return -EINVAL; - } - } -@@ -867,6 +875,9 @@ validate_gl_shader_rec(struct drm_device *dev, - uint32_t stride = *(uint8_t *)(pkt_u + o + 5); - uint32_t max_index; - -+ exec->bin_dep_seqno = max(exec->bin_dep_seqno, -+ to_vc4_bo(&vbo->base)->write_seqno); -+ - if (state->addr & 0x8) - stride |= (*(uint32_t *)(pkt_u + 100 + i * 4)) & ~0xff; - --- -2.9.3 - From f379f5432e4b74e3d1d894ce2fefbe1b8a3c24fd Mon Sep 17 00:00:00 2001 From: Eric Anholt <eric@anholt.net> Date: Wed, 28 Sep 2016 19:20:44 -0700 @@ -868,83 +637,6 @@ index 400615b..c6420b3 100644 -- cgit v0.12 -From 67615c588a059b731df9d019edc3c561d8006ec9 Mon Sep 17 00:00:00 2001 -From: Eric Anholt <eric@anholt.net> -Date: Wed, 1 Jun 2016 12:05:36 -0700 -Subject: clk: bcm2835: Skip PLLC clocks when deciding on a new clock parent - -If the firmware had set up a clock to source from PLLC, go along with -it. But if we're looking for a new parent, we don't want to switch it -to PLLC because the firmware will force PLLC (and thus the AXI bus -clock) to different frequencies during over-temp/under-voltage, -without notification to Linux. - -On my system, this moves the Linux-enabled HDMI state machine and DSI1 -escape clock over to plld_per from pllc_per. EMMC still ends up on -pllc_per, because the firmware had set it up to use that. - -Signed-off-by: Eric Anholt <eric@anholt.net> -Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks") -Acked-by: Martin Sperl <kernel@martin.sperl.org> -Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> ---- - drivers/clk/bcm/clk-bcm2835.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c -index c6420b3..e8a9646a 100644 ---- a/drivers/clk/bcm/clk-bcm2835.c -+++ b/drivers/clk/bcm/clk-bcm2835.c -@@ -1009,16 +1009,28 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw, - return 0; - } - -+static bool -+bcm2835_clk_is_pllc(struct clk_hw *hw) -+{ -+ if (!hw) -+ return false; -+ -+ return strncmp(clk_hw_get_name(hw), "pllc", 4) == 0; -+} -+ - static int bcm2835_clock_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) - { - struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); - struct clk_hw *parent, *best_parent = NULL; -+ bool current_parent_is_pllc; - unsigned long rate, best_rate = 0; - unsigned long prate, best_prate = 0; - size_t i; - u32 div; - -+ current_parent_is_pllc = bcm2835_clk_is_pllc(clk_hw_get_parent(hw)); -+ - /* - * Select parent clock that results in the closest but lower rate - */ -@@ -1026,6 +1038,17 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw, - parent = clk_hw_get_parent_by_index(hw, i); - if (!parent) - continue; -+ -+ /* -+ * Don't choose a PLLC-derived clock as our parent -+ * unless it had been manually set that way. PLLC's -+ * frequency gets adjusted by the firmware due to -+ * over-temp or under-voltage conditions, without -+ * prior notification to our clock consumer. -+ */ -+ if (bcm2835_clk_is_pllc(parent) && !current_parent_is_pllc) -+ continue; -+ - prate = clk_hw_get_rate(parent); - div = bcm2835_clock_choose_div(hw, req->rate, prate, true); - rate = bcm2835_clock_rate_from_divisor(clock, prate, div); --- -cgit v0.12 - From 30772942cc1095c3129eecfa182e2c568e566b9d Mon Sep 17 00:00:00 2001 From: Dan Carpenter <dan.carpenter@oracle.com> Date: Thu, 13 Oct 2016 11:54:31 +0300 diff --git a/config-arm-generic b/config-arm-generic index 7a88c2d02..a851da49f 100644 --- a/config-arm-generic +++ b/config-arm-generic @@ -95,12 +95,12 @@ CONFIG_EDAC_LEGACY_SYSFS=y # Regulators CONFIG_REGULATOR=y -CONFIG_RFKILL_REGULATOR=m +CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_VIRTUAL_CONSUMER=m CONFIG_REGULATOR_USERSPACE_CONSUMER=m -CONFIG_REGULATOR_GPIO=m CONFIG_REGULATOR_PWM=m +CONFIG_RFKILL_REGULATOR=m # ARM VExpress CONFIG_ARCH_VEXPRESS=y diff --git a/config-armv7-generic b/config-armv7-generic index f36ed38b0..90d3ecd8a 100644 --- a/config-armv7-generic +++ b/config-armv7-generic @@ -210,10 +210,10 @@ CONFIG_GPIO_PCF857X=m CONFIG_TOUCHSCREEN_SUN4I=m CONFIG_MFD_AXP20X=y CONFIG_MFD_AXP20X_I2C=y -CONFIG_MFD_AXP20X_RSB=m +CONFIG_MFD_AXP20X_RSB=y CONFIG_AXP20X_POWER=m CONFIG_INPUT_AXP20X_PEK=m -CONFIG_REGULATOR_AXP20X=m +CONFIG_REGULATOR_AXP20X=y CONFIG_AXP288_FUEL_GAUGE=m CONFIG_AXP288_ADC=m CONFIG_EXTCON_AXP288=m @@ -228,14 +228,14 @@ CONFIG_RTC_DRV_SUN6I=m CONFIG_MTD_NAND_SUNXI=m CONFIG_SERIO_SUN4I_PS2=m CONFIG_KEYBOARD_SUN4I_LRADC=m -CONFIG_PWM_SUN4I=m +CONFIG_PWM_SUN4I=y CONFIG_CAN_SUN4I=m CONFIG_USB_MUSB_SUNXI=m CONFIG_CRYPTO_DEV_SUN4I_SS=m CONFIG_SND_SUN4I_CODEC=m CONFIG_SND_SUN4I_SPDIF=m CONFIG_SND_SUN4I_I2S=m -CONFIG_SUNXI_RSB=m +CONFIG_SUNXI_RSB=y CONFIG_NVMEM_SUNXI_SID=m # Exynos diff --git a/drm_i915_skl_Backport_watermark_fixes_for_4.8.y.patch b/drm_i915_skl_Backport_watermark_fixes_for_4.8.y.patch deleted file mode 100644 index cf2a7dfef..000000000 --- a/drm_i915_skl_Backport_watermark_fixes_for_4.8.y.patch +++ /dev/null @@ -1,1247 +0,0 @@ -From: Lyude <lyude@redhat.com> -To: kernel@lists.fedoraproject.org -Subject: [PATCH 0/5] drm/i915/skl: Backport watermark fixes for 4.8.y -Date: Thu, 27 Oct 2016 10:49:34 -0400 - -Hey! Hans de Geode requested that I also send this patch series to you guys. -These are the fixes for most (maybe even all) of the issues with display -flickering that users have been seeing on Skylake systems. They've already been -submitted for inclusion in 4.8.y. - - Original message - -Now that these have finally made it into 4.9, it's time to finally backport -these fixes. Skylake has been a mess in multi-monitor setups for a while now -because up until recently we've been updating the watermarks on Skylake just -like we would for previous generations of Intel GPUs. This means updating -attributes for each plane, and then only after they've been updated writing -their new watermark values. - -The problem with this approach is Skylake has double buffered watermark -registers that are flipped at the same time as the rest of the plane registers. -This means that the original approach will leave planes active with new -attributes but without the required watermark programming that would ensure the -display pipe reads enough data from each plane. As a result, pipes start to -underrun and the user's displays starts to flicker heavily. Usually in response -to plugging in new monitors, or moving cursors from one screen to another -(which triggers a plane and watermark update). - -Additionally, issues were found with the original code for configuring ddb, -display data buffer, allocations between display planes on Skylake. On Skylake -all planes have space allocated to them in the ddb, and the hardware requires -that these allocations never overlap at any point in time. Because ddb -allocations were not updated alongside plane attributes despite also being -double buffered registers armed by plane updates, planes were likely to get -stuck momentarily with ddb allocations that overlapped one another. This would -also lead to pipe underruns and display flickering. - -The new approach fixes this problem by making sure that on Skylake, attributes -for display planes are always updated at the same time as the watermarks, and -pipes are updated in an order that ensures their ddb allocations don't -overlap at any point between plane updates. This ensures the display pipes are -always programmed correctly, and dramatically reduces the chance of display -flickering. - -(note: my e-mail has changed since these patches were upstreamed, and I updated -the e-mails in these patches to reflect this. if this is wrong I will be happy -to update and resend the patches). - -Lyude (4): - drm/i915/skl: Update plane watermarks atomically during plane updates - drm/i915: Move CRTC updating in atomic_commit into it's own hook - drm/i915/skl: Update DDB values atomically with wms/plane attrs - drm/i915/skl: Don't try to update plane watermarks if they haven't - changed - -Paulo Zanoni (1): - drm/i915/gen9: only add the planes actually affected by ddb changes - - drivers/gpu/drm/i915/i915_drv.h | 2 + - drivers/gpu/drm/i915/intel_display.c | 189 +++++++++++++++++++----- - drivers/gpu/drm/i915/intel_drv.h | 12 ++ - drivers/gpu/drm/i915/intel_pm.c | 271 ++++++++++++++--------------------- - drivers/gpu/drm/i915/intel_sprite.c | 14 ++ - 5 files changed, 289 insertions(+), 199 deletions(-) - --- -2.7.4 -_______________________________________________ -kernel mailing list -- kernel@lists.fedoraproject.org -To unsubscribe send an email to kernel-leave@lists.fedoraproject.org - -From: Lyude <lyude@redhat.com> -To: kernel@lists.fedoraproject.org -Subject: [PATCH 1/5] drm/i915/skl: Update plane watermarks atomically - during plane updates -Date: Thu, 27 Oct 2016 10:49:35 -0400 - -commit c145d3be1c313184be71d2629fd575561b7e38d4 upstream - -Thanks to Ville for suggesting this as a potential solution to pipe -underruns on Skylake. - -On Skylake all of the registers for configuring planes, including the -registers for configuring their watermarks, are double buffered. New -values written to them won't take effect until said registers are -"armed", which is done by writing to the PLANE_SURF (or in the case of -cursor planes, the CURBASE register) register. - -With this in mind, up until now we've been updating watermarks on skl -like this: - - non-modeset { - - calculate (during atomic check phase) - - finish_atomic_commit: - - intel_pre_plane_update: - - intel_update_watermarks() - - {vblank happens; new watermarks + old plane values => underrun } - - drm_atomic_helper_commit_planes_on_crtc: - - start vblank evasion - - write new plane registers - - end vblank evasion - } - - or - - modeset { - - calculate (during atomic check phase) - - finish_atomic_commit: - - crtc_enable: - - intel_update_watermarks() - - {vblank happens; new watermarks + old plane values => underrun } - - drm_atomic_helper_commit_planes_on_crtc: - - start vblank evasion - - write new plane registers - - end vblank evasion - } - -Now we update watermarks atomically like this: - - non-modeset { - - calculate (during atomic check phase) - - finish_atomic_commit: - - intel_pre_plane_update: - - intel_update_watermarks() (wm values aren't written yet) - - drm_atomic_helper_commit_planes_on_crtc: - - start vblank evasion - - write new plane registers - - write new wm values - - end vblank evasion - } - - modeset { - - calculate (during atomic check phase) - - finish_atomic_commit: - - crtc_enable: - - intel_update_watermarks() (actual wm values aren't written - yet) - - drm_atomic_helper_commit_planes_on_crtc: - - start vblank evasion - - write new plane registers - - write new wm values - - end vblank evasion - } - -So this patch moves all of the watermark writes into the right place; -inside of the vblank evasion where we update all of the registers for -each plane. While this patch doesn't fix everything, it does allow us to -update the watermark values in the way the hardware expects us to. - -Changes since original patch series: - - Remove mutex_lock/mutex_unlock since they don't do anything and we're - not touching global state - - Move skl_write_cursor_wm/skl_write_plane_wm functions into - intel_pm.c, make externally visible - - Add skl_write_plane_wm calls to skl_update_plane - - Fix conditional for for loop in skl_write_plane_wm (level < max_level - should be level <= max_level) - - Make diagram in commit more accurate to what's actually happening - - Add Fixes: - -Changes since v1: - - Use IS_GEN9() instead of IS_SKYLAKE() since these fixes apply to more - then just Skylake - - Update description to make it clear this patch doesn't fix everything - - Check if pipes were actually changed before writing watermarks - -Changes since v2: - - Write PIPE_WM_LINETIME during vblank evasion - -Changes since v3: - - Rebase against new SAGV patch changes - -Changes since v4: - - Add a parameter to choose what skl_wm_values struct to use when - writing new plane watermarks - -Changes since v5: - - Remove cursor ddb entry write in skl_write_cursor_wm(), defer until - patch 6 - - Write WM_LINETIME in intel_begin_crtc_commit() - -Changes since v6: - - Remove redundant dirty_pipes check in skl_write_plane_wm (we check - this in all places where we call this function, and it was supposed - to have been removed earlier anyway) - - In i9xx_update_cursor(), use dev_priv->info.gen >= 9 instead of - IS_GEN9(dev_priv). We do this everywhere else and I'd imagine this - needs to be done for gen10 as well - -Changes since v7: - - Fix rebase fail (unused variable obj) - - Make struct skl_wm_values *wm const - - Fix indenting - - Use INTEL_GEN() instead of dev_priv->info.gen - -Changes since v8: - - Don't forget calls to skl_write_plane_wm() when disabling planes - - Use INTEL_GEN(), not INTEL_INFO()->gen in intel_begin_crtc_commit() - -Fixes: 2d41c0b59afc ("drm/i915/skl: SKL Watermark Computation") -Signed-off-by: Lyude <lyude@redhat.com> -Reviewed-by: Matt Roper <matthew.d.roper@intel.com> -Cc: stable@vger.kernel.org -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Daniel Vetter <daniel.vetter@intel.com> -Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com> -Cc: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> -Link: http://patchwork.freedesktop.org/patch/msgid/1471884608-10671-1-git-send-email-cpaul@redhat.com -Link: http://patchwork.freedesktop.org/patch/msgid/1471884608-10671-1-git-send-email-cpaul@redhat.com ---- - drivers/gpu/drm/i915/intel_display.c | 21 +++++++++++++-- - drivers/gpu/drm/i915/intel_drv.h | 5 ++++ - drivers/gpu/drm/i915/intel_pm.c | 50 ++++++++++++++++++++++++------------ - drivers/gpu/drm/i915/intel_sprite.c | 6 +++++ - 4 files changed, 64 insertions(+), 18 deletions(-) - -diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c -index 175595f..1ae587f 100644 ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -2980,6 +2980,7 @@ static void skylake_update_primary_plane(struct drm_plane *plane, - struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); - struct drm_framebuffer *fb = plane_state->base.fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); -+ const struct skl_wm_values *wm = &dev_priv->wm.skl_results; - int pipe = intel_crtc->pipe; - u32 plane_ctl, stride_div, stride; - u32 tile_height, plane_offset, plane_size; -@@ -3031,6 +3032,9 @@ static void skylake_update_primary_plane(struct drm_plane *plane, - intel_crtc->adjusted_x = x_offset; - intel_crtc->adjusted_y = y_offset; - -+ if (wm->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) -+ skl_write_plane_wm(intel_crtc, wm, 0); -+ - I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl); - I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset); - I915_WRITE(PLANE_SIZE(pipe, 0), plane_size); -@@ -3061,7 +3065,10 @@ static void skylake_disable_primary_plane(struct drm_plane *primary, - { - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = to_i915(dev); -- int pipe = to_intel_crtc(crtc)->pipe; -+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -+ int pipe = intel_crtc->pipe; -+ -+ skl_write_plane_wm(intel_crtc, &dev_priv->wm.skl_results, 0); - - I915_WRITE(PLANE_CTL(pipe, 0), 0); - I915_WRITE(PLANE_SURF(pipe, 0), 0); -@@ -10306,9 +10313,13 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base, - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -+ const struct skl_wm_values *wm = &dev_priv->wm.skl_results; - int pipe = intel_crtc->pipe; - uint32_t cntl = 0; - -+ if (INTEL_GEN(dev_priv) >= 9 && wm->dirty_pipes & drm_crtc_mask(crtc)) -+ skl_write_cursor_wm(intel_crtc, wm); -+ - if (plane_state && plane_state->visible) { - cntl = MCURSOR_GAMMA_ENABLE; - switch (plane_state->base.crtc_w) { -@@ -14221,10 +14232,12 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) - { - struct drm_device *dev = crtc->dev; -+ struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_crtc_state *old_intel_state = - to_intel_crtc_state(old_crtc_state); - bool modeset = needs_modeset(crtc->state); -+ enum pipe pipe = intel_crtc->pipe; - - /* Perform vblank evasion around commit operation */ - intel_pipe_update_start(intel_crtc); -@@ -14239,8 +14252,12 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc, - - if (to_intel_crtc_state(crtc->state)->update_pipe) - intel_update_pipe_config(intel_crtc, old_intel_state); -- else if (INTEL_INFO(dev)->gen >= 9) -+ else if (INTEL_GEN(dev_priv) >= 9) { - skl_detach_scalers(intel_crtc); -+ -+ I915_WRITE(PIPE_WM_LINETIME(pipe), -+ dev_priv->wm.skl_hw.wm_linetime[pipe]); -+ } - } - - static void intel_finish_crtc_commit(struct drm_crtc *crtc, -diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h -index ff399b9..58a8152 100644 ---- a/drivers/gpu/drm/i915/intel_drv.h -+++ b/drivers/gpu/drm/i915/intel_drv.h -@@ -1719,6 +1719,11 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, - bool skl_can_enable_sagv(struct drm_atomic_state *state); - int skl_enable_sagv(struct drm_i915_private *dev_priv); - int skl_disable_sagv(struct drm_i915_private *dev_priv); -+void skl_write_cursor_wm(struct intel_crtc *intel_crtc, -+ const struct skl_wm_values *wm); -+void skl_write_plane_wm(struct intel_crtc *intel_crtc, -+ const struct skl_wm_values *wm, -+ int plane); - uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config); - bool ilk_disable_lp_wm(struct drm_device *dev); - int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6); -diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c -index 2d24813..29bed77 100644 ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -3828,6 +3828,39 @@ static void skl_ddb_entry_write(struct drm_i915_private *dev_priv, - I915_WRITE(reg, 0); - } - -+void skl_write_plane_wm(struct intel_crtc *intel_crtc, -+ const struct skl_wm_values *wm, -+ int plane) -+{ -+ struct drm_crtc *crtc = &intel_crtc->base; -+ struct drm_device *dev = crtc->dev; -+ struct drm_i915_private *dev_priv = to_i915(dev); -+ int level, max_level = ilk_wm_max_level(dev); -+ enum pipe pipe = intel_crtc->pipe; -+ -+ for (level = 0; level <= max_level; level++) { -+ I915_WRITE(PLANE_WM(pipe, plane, level), -+ wm->plane[pipe][plane][level]); -+ } -+ I915_WRITE(PLANE_WM_TRANS(pipe, plane), wm->plane_trans[pipe][plane]); -+} -+ -+void skl_write_cursor_wm(struct intel_crtc *intel_crtc, -+ const struct skl_wm_values *wm) -+{ -+ struct drm_crtc *crtc = &intel_crtc->base; -+ struct drm_device *dev = crtc->dev; -+ struct drm_i915_private *dev_priv = to_i915(dev); -+ int level, max_level = ilk_wm_max_level(dev); -+ enum pipe pipe = intel_crtc->pipe; -+ -+ for (level = 0; level <= max_level; level++) { -+ I915_WRITE(CUR_WM(pipe, level), -+ wm->plane[pipe][PLANE_CURSOR][level]); -+ } -+ I915_WRITE(CUR_WM_TRANS(pipe), wm->plane_trans[pipe][PLANE_CURSOR]); -+} -+ - static void skl_write_wm_values(struct drm_i915_private *dev_priv, - const struct skl_wm_values *new) - { -@@ -3835,7 +3868,7 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv, - struct intel_crtc *crtc; - - for_each_intel_crtc(dev, crtc) { -- int i, level, max_level = ilk_wm_max_level(dev); -+ int i; - enum pipe pipe = crtc->pipe; - - if ((new->dirty_pipes & drm_crtc_mask(&crtc->base)) == 0) -@@ -3843,21 +3876,6 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv, - if (!crtc->active) - continue; - -- I915_WRITE(PIPE_WM_LINETIME(pipe), new->wm_linetime[pipe]); -- -- for (level = 0; level <= max_level; level++) { -- for (i = 0; i < intel_num_planes(crtc); i++) -- I915_WRITE(PLANE_WM(pipe, i, level), -- new->plane[pipe][i][level]); -- I915_WRITE(CUR_WM(pipe, level), -- new->plane[pipe][PLANE_CURSOR][level]); -- } -- for (i = 0; i < intel_num_planes(crtc); i++) -- I915_WRITE(PLANE_WM_TRANS(pipe, i), -- new->plane_trans[pipe][i]); -- I915_WRITE(CUR_WM_TRANS(pipe), -- new->plane_trans[pipe][PLANE_CURSOR]); -- - for (i = 0; i < intel_num_planes(crtc); i++) { - skl_ddb_entry_write(dev_priv, - PLANE_BUF_CFG(pipe, i), -diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c -index 7c08e4f..d8bfff1 100644 ---- a/drivers/gpu/drm/i915/intel_sprite.c -+++ b/drivers/gpu/drm/i915/intel_sprite.c -@@ -203,6 +203,9 @@ skl_update_plane(struct drm_plane *drm_plane, - struct intel_plane *intel_plane = to_intel_plane(drm_plane); - struct drm_framebuffer *fb = plane_state->base.fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); -+ const struct skl_wm_values *wm = &dev_priv->wm.skl_results; -+ struct drm_crtc *crtc = crtc_state->base.crtc; -+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - const int pipe = intel_plane->pipe; - const int plane = intel_plane->plane + 1; - u32 plane_ctl, stride_div, stride; -@@ -238,6 +241,9 @@ skl_update_plane(struct drm_plane *drm_plane, - crtc_w--; - crtc_h--; - -+ if (wm->dirty_pipes & drm_crtc_mask(crtc)) -+ skl_write_plane_wm(intel_crtc, wm, plane); -+ - if (key->flags) { - I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value); - I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value); --- -2.7.4 -_______________________________________________ -kernel mailing list -- kernel@lists.fedoraproject.org -To unsubscribe send an email to kernel-leave@lists.fedoraproject.org - -From: Lyude <lyude@redhat.com> -To: kernel@lists.fedoraproject.org -Subject: [PATCH 2/5] drm/i915: Move CRTC updating in atomic_commit into - it's own hook -Date: Thu, 27 Oct 2016 10:49:36 -0400 - -commit 896e5bb022bce64e29ce2e1b2fc2a7476d311a15 upstream - -Since we have to write ddb allocations at the same time as we do other -plane updates, we're going to need to be able to control the order in -which we execute modesets on each pipe. The easiest way to do this is to -just factor this section of intel_atomic_commit_tail() -(intel_atomic_commit() for stable branches) into it's own function, and -add an appropriate display function hook for it. - -Based off of Matt Rope's suggestions - -Changes since v1: - - Drop pipe_config->base.active check in intel_update_crtcs() since we - check that before calling the function - -Signed-off-by: Lyude <cpaul@redhat.com> -Reviewed-by: Matt Roper <matthew.d.roper@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Daniel Vetter <daniel.vetter@intel.com> -Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com> -Cc: Hans de Goede <hdegoede@redhat.com> - -Signed-off-by: Lyude <lyude@redhat.com> -Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> -Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-1-git-send-email-cpaul@redhat.com ---- - drivers/gpu/drm/i915/i915_drv.h | 2 + - drivers/gpu/drm/i915/intel_display.c | 74 +++++++++++++++++++++++++----------- - 2 files changed, 54 insertions(+), 22 deletions(-) - -diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h -index f68c789..ad75dbd 100644 ---- a/drivers/gpu/drm/i915/i915_drv.h -+++ b/drivers/gpu/drm/i915/i915_drv.h -@@ -631,6 +631,8 @@ struct drm_i915_display_funcs { - struct intel_crtc_state *crtc_state); - void (*crtc_enable)(struct drm_crtc *crtc); - void (*crtc_disable)(struct drm_crtc *crtc); -+ void (*update_crtcs)(struct drm_atomic_state *state, -+ unsigned int *crtc_vblank_mask); - void (*audio_codec_enable)(struct drm_connector *connector, - struct intel_encoder *encoder, - const struct drm_display_mode *adjusted_mode); -diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c -index 1ae587f..e2c46eb 100644 ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -13682,6 +13682,52 @@ static bool needs_vblank_wait(struct intel_crtc_state *crtc_state) - return false; - } - -+static void intel_update_crtc(struct drm_crtc *crtc, -+ struct drm_atomic_state *state, -+ struct drm_crtc_state *old_crtc_state, -+ unsigned int *crtc_vblank_mask) -+{ -+ struct drm_device *dev = crtc->dev; -+ struct drm_i915_private *dev_priv = to_i915(dev); -+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -+ struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->state); -+ bool modeset = needs_modeset(crtc->state); -+ -+ if (modeset) { -+ update_scanline_offset(intel_crtc); -+ dev_priv->display.crtc_enable(crtc); -+ } else { -+ intel_pre_plane_update(to_intel_crtc_state(old_crtc_state)); -+ } -+ -+ if (drm_atomic_get_existing_plane_state(state, crtc->primary)) { -+ intel_fbc_enable( -+ intel_crtc, pipe_config, -+ to_intel_plane_state(crtc->primary->state)); -+ } -+ -+ drm_atomic_helper_commit_planes_on_crtc(old_crtc_state); -+ -+ if (needs_vblank_wait(pipe_config)) -+ *crtc_vblank_mask |= drm_crtc_mask(crtc); -+} -+ -+static void intel_update_crtcs(struct drm_atomic_state *state, -+ unsigned int *crtc_vblank_mask) -+{ -+ struct drm_crtc *crtc; -+ struct drm_crtc_state *old_crtc_state; -+ int i; -+ -+ for_each_crtc_in_state(state, crtc, old_crtc_state, i) { -+ if (!crtc->state->active) -+ continue; -+ -+ intel_update_crtc(crtc, state, old_crtc_state, -+ crtc_vblank_mask); -+ } -+} -+ - static void intel_atomic_commit_tail(struct drm_atomic_state *state) - { - struct drm_device *dev = state->dev; -@@ -13780,17 +13826,9 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) - intel_modeset_verify_disabled(dev); - } - -- /* Now enable the clocks, plane, pipe, and connectors that we set up. */ -+ /* Complete the events for pipes that have now been disabled */ - for_each_crtc_in_state(state, crtc, old_crtc_state, i) { -- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - bool modeset = needs_modeset(crtc->state); -- struct intel_crtc_state *pipe_config = -- to_intel_crtc_state(crtc->state); -- -- if (modeset && crtc->state->active) { -- update_scanline_offset(to_intel_crtc(crtc)); -- dev_priv->display.crtc_enable(crtc); -- } - - /* Complete events for now disable pipes here. */ - if (modeset && !crtc->state->active && crtc->state->event) { -@@ -13800,21 +13838,11 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) - - crtc->state->event = NULL; - } -- -- if (!modeset) -- intel_pre_plane_update(to_intel_crtc_state(old_crtc_state)); -- -- if (crtc->state->active && -- drm_atomic_get_existing_plane_state(state, crtc->primary)) -- intel_fbc_enable(intel_crtc, pipe_config, to_intel_plane_state(crtc->primary->state)); -- -- if (crtc->state->active) -- drm_atomic_helper_commit_planes_on_crtc(old_crtc_state); -- -- if (pipe_config->base.active && needs_vblank_wait(pipe_config)) -- crtc_vblank_mask |= 1 << i; - } - -+ /* Now enable the clocks, plane, pipe, and connectors that we set up. */ -+ dev_priv->display.update_crtcs(state, &crtc_vblank_mask); -+ - /* FIXME: We should call drm_atomic_helper_commit_hw_done() here - * already, but still need the state for the delayed optimization. To - * fix this: -@@ -15275,6 +15303,8 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) - dev_priv->display.crtc_disable = i9xx_crtc_disable; - } - -+ dev_priv->display.update_crtcs = intel_update_crtcs; -+ - /* Returns the core display clock speed */ - if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) - dev_priv->display.get_display_clock_speed = --- -2.7.4 -_______________________________________________ -kernel mailing list -- kernel@lists.fedoraproject.org -To unsubscribe send an email to kernel-leave@lists.fedoraproject.org - -From: Lyude <lyude@redhat.com> -To: kernel@lists.fedoraproject.org -Subject: [PATCH 3/5] drm/i915/skl: Update DDB values atomically with - wms/plane attrs -Date: Thu, 27 Oct 2016 10:49:37 -0400 - -commit 27082493e9c6371b05370a619ab9d2877c5f4726 upstream - -Now that we can hook into update_crtcs and control the order in which we -update CRTCs at each modeset, we can finish the final step of fixing -Skylake's watermark handling by performing DDB updates at the same time -as plane updates and watermark updates. - -The first major change in this patch is skl_update_crtcs(), which -handles ensuring that we order each CRTC update in our atomic commits -properly so that they honor the DDB flush order. - -The second major change in this patch is the order in which we flush the -pipes. While the previous order may have worked, it can't be used in -this approach since it no longer will do the right thing. For example, -using the old ddb flush order: - -We have pipes A, B, and C enabled, and we're disabling C. Initial ddb -allocation looks like this: - -| A | B |xxxxxxx| - -Since we're performing the ddb updates after performing any CRTC -disablements in intel_atomic_commit_tail(), the space to the right of -pipe B is unallocated. - -1. Flush pipes with new allocation contained into old space. None - apply, so we skip this -2. Flush pipes having their allocation reduced, but overlapping with a - previous allocation. None apply, so we also skip this -3. Flush pipes that got more space allocated. This applies to A and B, - giving us the following update order: A, B - -This is wrong, since updating pipe A first will cause it to overlap with -B and potentially burst into flames. Our new order (see the code -comments for details) would update the pipes in the proper order: B, A. - -As well, we calculate the order for each DDB update during the check -phase, and reference it later in the commit phase when we hit -skl_update_crtcs(). - -This long overdue patch fixes the rest of the underruns on Skylake. - -Changes since v1: - - Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm() -Changes since v2: - - Use the method for updating CRTCs that Ville suggested - - In skl_update_wm(), only copy the watermarks for the crtc that was - passed to us -Changes since v3: - - Small comment fix in skl_ddb_allocation_overlaps() -Changes since v4: - - Remove the second loop in intel_update_crtcs() and use Ville's - suggestion for updating the ddb allocations in the right order - - Get rid of the second loop and just use the ddb state as it updates - to determine what order to update everything in (thanks for the - suggestion Ville) - - Simplify skl_ddb_allocation_overlaps() - - Split actual overlap checking into it's own helper - -Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration") -Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation") -[omitting CC for stable, since this patch will need to be changed for -such backports first] - -Testcase: kms_cursor_legacy -Testcase: plane-all-modeset-transition -Signed-off-by: Lyude <lyude@redhat.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Daniel Vetter <daniel.vetter@intel.com> -Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com> -Cc: Hans de Goede <hdegoede@redhat.com> -Cc: Matt Roper <matthew.d.roper@intel.com> -Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> -Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-2-git-send-email-cpaul@redhat.com ---- - drivers/gpu/drm/i915/intel_display.c | 93 +++++++++++++--- - drivers/gpu/drm/i915/intel_drv.h | 7 ++ - drivers/gpu/drm/i915/intel_pm.c | 200 ++++++++--------------------------- - 3 files changed, 132 insertions(+), 168 deletions(-) - -diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c -index e2c46eb..8086e62 100644 ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -12967,16 +12967,23 @@ static void verify_wm_state(struct drm_crtc *crtc, - hw_entry->start, hw_entry->end); - } - -- /* cursor */ -- hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR]; -- sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR]; -- -- if (!skl_ddb_entry_equal(hw_entry, sw_entry)) { -- DRM_ERROR("mismatch in DDB state pipe %c cursor " -- "(expected (%u,%u), found (%u,%u))\n", -- pipe_name(pipe), -- sw_entry->start, sw_entry->end, -- hw_entry->start, hw_entry->end); -+ /* -+ * cursor -+ * If the cursor plane isn't active, we may not have updated it's ddb -+ * allocation. In that case since the ddb allocation will be updated -+ * once the plane becomes visible, we can skip this check -+ */ -+ if (intel_crtc->cursor_addr) { -+ hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR]; -+ sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR]; -+ -+ if (!skl_ddb_entry_equal(hw_entry, sw_entry)) { -+ DRM_ERROR("mismatch in DDB state pipe %c cursor " -+ "(expected (%u,%u), found (%u,%u))\n", -+ pipe_name(pipe), -+ sw_entry->start, sw_entry->end, -+ hw_entry->start, hw_entry->end); -+ } - } - } - -@@ -13728,6 +13735,65 @@ static void intel_update_crtcs(struct drm_atomic_state *state, - } - } - -+static void skl_update_crtcs(struct drm_atomic_state *state, -+ unsigned int *crtc_vblank_mask) -+{ -+ struct drm_device *dev = state->dev; -+ struct drm_i915_private *dev_priv = to_i915(dev); -+ struct intel_atomic_state *intel_state = to_intel_atomic_state(state); -+ struct drm_crtc *crtc; -+ struct drm_crtc_state *old_crtc_state; -+ struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; -+ struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; -+ unsigned int updated = 0; -+ bool progress; -+ enum pipe pipe; -+ -+ /* -+ * Whenever the number of active pipes changes, we need to make sure we -+ * update the pipes in the right order so that their ddb allocations -+ * never overlap with eachother inbetween CRTC updates. Otherwise we'll -+ * cause pipe underruns and other bad stuff. -+ */ -+ do { -+ int i; -+ progress = false; -+ -+ for_each_crtc_in_state(state, crtc, old_crtc_state, i) { -+ bool vbl_wait = false; -+ unsigned int cmask = drm_crtc_mask(crtc); -+ pipe = to_intel_crtc(crtc)->pipe; -+ -+ if (updated & cmask || !crtc->state->active) -+ continue; -+ if (skl_ddb_allocation_overlaps(state, cur_ddb, new_ddb, -+ pipe)) -+ continue; -+ -+ updated |= cmask; -+ -+ /* -+ * If this is an already active pipe, it's DDB changed, -+ * and this isn't the last pipe that needs updating -+ * then we need to wait for a vblank to pass for the -+ * new ddb allocation to take effect. -+ */ -+ if (!skl_ddb_allocation_equals(cur_ddb, new_ddb, pipe) && -+ !crtc->state->active_changed && -+ intel_state->wm_results.dirty_pipes != updated) -+ vbl_wait = true; -+ -+ intel_update_crtc(crtc, state, old_crtc_state, -+ crtc_vblank_mask); -+ -+ if (vbl_wait) -+ intel_wait_for_vblank(dev, pipe); -+ -+ progress = true; -+ } -+ } while (progress); -+} -+ - static void intel_atomic_commit_tail(struct drm_atomic_state *state) - { - struct drm_device *dev = state->dev; -@@ -15303,8 +15369,6 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) - dev_priv->display.crtc_disable = i9xx_crtc_disable; - } - -- dev_priv->display.update_crtcs = intel_update_crtcs; -- - /* Returns the core display clock speed */ - if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) - dev_priv->display.get_display_clock_speed = -@@ -15394,6 +15458,11 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) - skl_modeset_calc_cdclk; - } - -+ if (dev_priv->info.gen >= 9) -+ dev_priv->display.update_crtcs = skl_update_crtcs; -+ else -+ dev_priv->display.update_crtcs = intel_update_crtcs; -+ - switch (INTEL_INFO(dev_priv)->gen) { - case 2: - dev_priv->display.queue_flip = intel_gen2_queue_flip; -diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h -index 58a8152..83674c6 100644 ---- a/drivers/gpu/drm/i915/intel_drv.h -+++ b/drivers/gpu/drm/i915/intel_drv.h -@@ -1719,6 +1719,13 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, - bool skl_can_enable_sagv(struct drm_atomic_state *state); - int skl_enable_sagv(struct drm_i915_private *dev_priv); - int skl_disable_sagv(struct drm_i915_private *dev_priv); -+bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old, -+ const struct skl_ddb_allocation *new, -+ enum pipe pipe); -+bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state, -+ const struct skl_ddb_allocation *old, -+ const struct skl_ddb_allocation *new, -+ enum pipe pipe); - void skl_write_cursor_wm(struct intel_crtc *intel_crtc, - const struct skl_wm_values *wm); - void skl_write_plane_wm(struct intel_crtc *intel_crtc, -diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c -index 29bed77..a0c5c4e 100644 ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -3843,6 +3843,11 @@ void skl_write_plane_wm(struct intel_crtc *intel_crtc, - wm->plane[pipe][plane][level]); - } - I915_WRITE(PLANE_WM_TRANS(pipe, plane), wm->plane_trans[pipe][plane]); -+ -+ skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane), -+ &wm->ddb.plane[pipe][plane]); -+ skl_ddb_entry_write(dev_priv, PLANE_NV12_BUF_CFG(pipe, plane), -+ &wm->ddb.y_plane[pipe][plane]); - } - - void skl_write_cursor_wm(struct intel_crtc *intel_crtc, -@@ -3859,170 +3864,46 @@ void skl_write_cursor_wm(struct intel_crtc *intel_crtc, - wm->plane[pipe][PLANE_CURSOR][level]); - } - I915_WRITE(CUR_WM_TRANS(pipe), wm->plane_trans[pipe][PLANE_CURSOR]); --} -- --static void skl_write_wm_values(struct drm_i915_private *dev_priv, -- const struct skl_wm_values *new) --{ -- struct drm_device *dev = &dev_priv->drm; -- struct intel_crtc *crtc; -- -- for_each_intel_crtc(dev, crtc) { -- int i; -- enum pipe pipe = crtc->pipe; -- -- if ((new->dirty_pipes & drm_crtc_mask(&crtc->base)) == 0) -- continue; -- if (!crtc->active) -- continue; -- -- for (i = 0; i < intel_num_planes(crtc); i++) { -- skl_ddb_entry_write(dev_priv, -- PLANE_BUF_CFG(pipe, i), -- &new->ddb.plane[pipe][i]); -- skl_ddb_entry_write(dev_priv, -- PLANE_NV12_BUF_CFG(pipe, i), -- &new->ddb.y_plane[pipe][i]); -- } - -- skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), -- &new->ddb.plane[pipe][PLANE_CURSOR]); -- } -+ skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), -+ &wm->ddb.plane[pipe][PLANE_CURSOR]); - } - --/* -- * When setting up a new DDB allocation arrangement, we need to correctly -- * sequence the times at which the new allocations for the pipes are taken into -- * account or we'll have pipes fetching from space previously allocated to -- * another pipe. -- * -- * Roughly the sequence looks like: -- * 1. re-allocate the pipe(s) with the allocation being reduced and not -- * overlapping with a previous light-up pipe (another way to put it is: -- * pipes with their new allocation strickly included into their old ones). -- * 2. re-allocate the other pipes that get their allocation reduced -- * 3. allocate the pipes having their allocation increased -- * -- * Steps 1. and 2. are here to take care of the following case: -- * - Initially DDB looks like this: -- * | B | C | -- * - enable pipe A. -- * - pipe B has a reduced DDB allocation that overlaps with the old pipe C -- * allocation -- * | A | B | C | -- * -- * We need to sequence the re-allocation: C, B, A (and not B, C, A). -- */ -- --static void --skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, int pass) -+bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old, -+ const struct skl_ddb_allocation *new, -+ enum pipe pipe) - { -- int plane; -- -- DRM_DEBUG_KMS("flush pipe %c (pass %d)\n", pipe_name(pipe), pass); -- -- for_each_plane(dev_priv, pipe, plane) { -- I915_WRITE(PLANE_SURF(pipe, plane), -- I915_READ(PLANE_SURF(pipe, plane))); -- } -- I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe))); -+ return new->pipe[pipe].start == old->pipe[pipe].start && -+ new->pipe[pipe].end == old->pipe[pipe].end; - } - --static bool --skl_ddb_allocation_included(const struct skl_ddb_allocation *old, -- const struct skl_ddb_allocation *new, -- enum pipe pipe) -+static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a, -+ const struct skl_ddb_entry *b) - { -- uint16_t old_size, new_size; -- -- old_size = skl_ddb_entry_size(&old->pipe[pipe]); -- new_size = skl_ddb_entry_size(&new->pipe[pipe]); -- -- return old_size != new_size && -- new->pipe[pipe].start >= old->pipe[pipe].start && -- new->pipe[pipe].end <= old->pipe[pipe].end; -+ return a->start < b->end && b->start < a->end; - } - --static void skl_flush_wm_values(struct drm_i915_private *dev_priv, -- struct skl_wm_values *new_values) -+bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state, -+ const struct skl_ddb_allocation *old, -+ const struct skl_ddb_allocation *new, -+ enum pipe pipe) - { -- struct drm_device *dev = &dev_priv->drm; -- struct skl_ddb_allocation *cur_ddb, *new_ddb; -- bool reallocated[I915_MAX_PIPES] = {}; -- struct intel_crtc *crtc; -- enum pipe pipe; -- -- new_ddb = &new_values->ddb; -- cur_ddb = &dev_priv->wm.skl_hw.ddb; -- -- /* -- * First pass: flush the pipes with the new allocation contained into -- * the old space. -- * -- * We'll wait for the vblank on those pipes to ensure we can safely -- * re-allocate the freed space without this pipe fetching from it. -- */ -- for_each_intel_crtc(dev, crtc) { -- if (!crtc->active) -- continue; -- -- pipe = crtc->pipe; -- -- if (!skl_ddb_allocation_included(cur_ddb, new_ddb, pipe)) -- continue; -- -- skl_wm_flush_pipe(dev_priv, pipe, 1); -- intel_wait_for_vblank(dev, pipe); -- -- reallocated[pipe] = true; -- } -- -- -- /* -- * Second pass: flush the pipes that are having their allocation -- * reduced, but overlapping with a previous allocation. -- * -- * Here as well we need to wait for the vblank to make sure the freed -- * space is not used anymore. -- */ -- for_each_intel_crtc(dev, crtc) { -- if (!crtc->active) -- continue; -+ struct drm_device *dev = state->dev; -+ struct intel_crtc *intel_crtc; -+ enum pipe otherp; - -- pipe = crtc->pipe; -+ for_each_intel_crtc(dev, intel_crtc) { -+ otherp = intel_crtc->pipe; - -- if (reallocated[pipe]) -+ if (otherp == pipe) - continue; - -- if (skl_ddb_entry_size(&new_ddb->pipe[pipe]) < -- skl_ddb_entry_size(&cur_ddb->pipe[pipe])) { -- skl_wm_flush_pipe(dev_priv, pipe, 2); -- intel_wait_for_vblank(dev, pipe); -- reallocated[pipe] = true; -- } -+ if (skl_ddb_entries_overlap(&new->pipe[pipe], -+ &old->pipe[otherp])) -+ return true; - } - -- /* -- * Third pass: flush the pipes that got more space allocated. -- * -- * We don't need to actively wait for the update here, next vblank -- * will just get more DDB space with the correct WM values. -- */ -- for_each_intel_crtc(dev, crtc) { -- if (!crtc->active) -- continue; -- -- pipe = crtc->pipe; -- -- /* -- * At this point, only the pipes more space than before are -- * left to re-allocate. -- */ -- if (reallocated[pipe]) -- continue; -- -- skl_wm_flush_pipe(dev_priv, pipe, 3); -- } -+ return false; - } - - static int skl_update_pipe_wm(struct drm_crtc_state *cstate, -@@ -4224,7 +4105,7 @@ static void skl_update_wm(struct drm_crtc *crtc) - struct skl_wm_values *hw_vals = &dev_priv->wm.skl_hw; - struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); - struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal; -- int pipe; -+ enum pipe pipe = intel_crtc->pipe; - - if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0) - return; -@@ -4233,15 +4114,22 @@ static void skl_update_wm(struct drm_crtc *crtc) - - mutex_lock(&dev_priv->wm.wm_mutex); - -- skl_write_wm_values(dev_priv, results); -- skl_flush_wm_values(dev_priv, results); -- - /* -- * Store the new configuration (but only for the pipes that have -- * changed; the other values weren't recomputed). -+ * If this pipe isn't active already, we're going to be enabling it -+ * very soon. Since it's safe to update a pipe's ddb allocation while -+ * the pipe's shut off, just do so here. Already active pipes will have -+ * their watermarks updated once we update their planes. - */ -- for_each_pipe_masked(dev_priv, pipe, results->dirty_pipes) -- skl_copy_wm_for_pipe(hw_vals, results, pipe); -+ if (crtc->state->active_changed) { -+ int plane; -+ -+ for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) -+ skl_write_plane_wm(intel_crtc, results, plane); -+ -+ skl_write_cursor_wm(intel_crtc, results); -+ } -+ -+ skl_copy_wm_for_pipe(hw_vals, results, pipe); - - mutex_unlock(&dev_priv->wm.wm_mutex); - } --- -2.7.4 -_______________________________________________ -kernel mailing list -- kernel@lists.fedoraproject.org -To unsubscribe send an email to kernel-leave@lists.fedoraproject.org - -From: Lyude <lyude@redhat.com> -To: kernel@lists.fedoraproject.org -Subject: [PATCH 4/5] drm/i915/skl: Don't try to update plane watermarks if - they haven't changed -Date: Thu, 27 Oct 2016 10:49:38 -0400 - -commit ccebc23b57c313229526dc76383ce82f5e0b9001 upstream - -i915 sometimes needs to disable planes in the middle of an atomic -commit, and then reenable them later in the same commit. Because of -this, we can't make the assumption that the state of the plane actually -changed. Since the state of the plane hasn't actually changed, neither -have it's watermarks. And if the watermarks hasn't changed then we -haven't populated skl_results with anything, which means we'll end up -zeroing out a plane's watermarks in the middle of the atomic commit -without restoring them later. - -Simple reproduction recipe: - - Get a SKL laptop, launch any kind of X session - - Get two extra monitors - - Keep hotplugging both displays (so that the display configuration - jumps from 1 active pipe to 3 active pipes and back) - - Eventually underrun - -Changes since v1: - - Fix incorrect use of "it's" -Changes since v2: - - Add reproduction recipe - -Signed-off-by: Lyude <lyude@redhat.com> -Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> -Fixes: 62e0fb880123 ("drm/i915/skl: Update plane watermarks atomically during plane updates") -Testcase: kms_plane -Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> -Link: http://patchwork.freedesktop.org/patch/msgid/1472488288-27280-1-git-send-email-cpaul@redhat.com -Cc: drm-intel-fixes@lists.freedesktop.org ---- - drivers/gpu/drm/i915/intel_display.c | 7 ++++++- - drivers/gpu/drm/i915/intel_sprite.c | 8 ++++++++ - 2 files changed, 14 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c -index 8086e62..85d161a 100644 ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -3068,7 +3068,12 @@ static void skylake_disable_primary_plane(struct drm_plane *primary, - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - -- skl_write_plane_wm(intel_crtc, &dev_priv->wm.skl_results, 0); -+ /* -+ * We only populate skl_results on watermark updates, and if the -+ * plane's visiblity isn't actually changing neither is its watermarks. -+ */ -+ if (!to_intel_plane_state(crtc->primary->state)->visible) -+ skl_write_plane_wm(intel_crtc, &dev_priv->wm.skl_results, 0); - - I915_WRITE(PLANE_CTL(pipe, 0), 0); - I915_WRITE(PLANE_SURF(pipe, 0), 0); -diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c -index d8bfff1..4178849 100644 ---- a/drivers/gpu/drm/i915/intel_sprite.c -+++ b/drivers/gpu/drm/i915/intel_sprite.c -@@ -314,6 +314,14 @@ skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) - const int pipe = intel_plane->pipe; - const int plane = intel_plane->plane + 1; - -+ /* -+ * We only populate skl_results on watermark updates, and if the -+ * plane's visiblity isn't actually changing neither is its watermarks. -+ */ -+ if (!to_intel_plane_state(dplane->state)->visible) -+ skl_write_plane_wm(to_intel_crtc(crtc), -+ &dev_priv->wm.skl_results, plane); -+ - I915_WRITE(PLANE_CTL(pipe, plane), 0); - - I915_WRITE(PLANE_SURF(pipe, plane), 0); --- -2.7.4 -_______________________________________________ -kernel mailing list -- kernel@lists.fedoraproject.org -To unsubscribe send an email to kernel-leave@lists.fedoraproject.org - -From: Lyude <lyude@redhat.com> -To: kernel@lists.fedoraproject.org -Subject: [PATCH 5/5] drm/i915/gen9: only add the planes actually affected - by ddb changes -Date: Thu, 27 Oct 2016 10:49:39 -0400 - -From: Paulo Zanoni <paulo.r.zanoni@intel.com> - -commit be5c571b2ff3a164d2e14ccc100cb5b2b3d3fb7c upstream - -We were previously adding all the planes owned by the CRTC even when -the ddb partitioning didn't change for them. As a consequence, a lot -of functions were being called when we were just moving the cursor -around the screen, such as skylake_update_primary_plane(). - -This was causing flickering on the primary plane when moving the -cursor. I'm not 100% sure which operation caused the flickering, but -we were writing to a lot of registers, so it could be any of these -writes. With this patch, just moving the mouse won't add the primary -plane to the commit since it won't trigger a change in DDB -partitioning. - -v2: Use skl_ddb_entry_equal() (Lyude). -v3: Change Reported-and-bisected-by: to Reported-by: for checkpatch - -Fixes: 05a76d3d6ad1 ("drm/i915/skl: Ensure pipes with changed wms get added to the state") -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97888 -Cc: Mike Lothian <mike@fireburn.co.uk> -Cc: stable@vger.kernel.org -Reported-by: Mike Lothian <mike@fireburn.co.uk> -Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> -Signed-off-by: Lyude <lyude@redhat.com> -Link: http://patchwork.freedesktop.org/patch/msgid/1475177808-29955-1-git-send-email-paulo.r.zanoni@intel.com -(cherry picked from commit 7f60e200e254cd53ad1bd74a56bdd23e813ac4b7) -Signed-off-by: Jani Nikula <jani.nikula@intel.com> ---- - drivers/gpu/drm/i915/intel_pm.c | 37 ++++++++++++++++++++++++++++++++++++- - 1 file changed, 36 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c -index a0c5c4e..5f763f4 100644 ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -3940,6 +3940,41 @@ pipes_modified(struct drm_atomic_state *state) - return ret; - } - -+int -+skl_ddb_add_affected_planes(struct intel_crtc_state *cstate) -+{ -+ struct drm_atomic_state *state = cstate->base.state; -+ struct drm_device *dev = state->dev; -+ struct drm_crtc *crtc = cstate->base.crtc; -+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -+ struct drm_i915_private *dev_priv = to_i915(dev); -+ struct intel_atomic_state *intel_state = to_intel_atomic_state(state); -+ struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; -+ struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; -+ struct drm_plane_state *plane_state; -+ struct drm_plane *plane; -+ enum pipe pipe = intel_crtc->pipe; -+ int id; -+ -+ WARN_ON(!drm_atomic_get_existing_crtc_state(state, crtc)); -+ -+ drm_for_each_plane_mask(plane, dev, crtc->state->plane_mask) { -+ id = skl_wm_plane_id(to_intel_plane(plane)); -+ -+ if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][id], -+ &new_ddb->plane[pipe][id]) && -+ skl_ddb_entry_equal(&cur_ddb->y_plane[pipe][id], -+ &new_ddb->y_plane[pipe][id])) -+ continue; -+ -+ plane_state = drm_atomic_get_plane_state(state, plane); -+ if (IS_ERR(plane_state)) -+ return PTR_ERR(plane_state); -+ } -+ -+ return 0; -+} -+ - static int - skl_compute_ddb(struct drm_atomic_state *state) - { -@@ -4004,7 +4039,7 @@ skl_compute_ddb(struct drm_atomic_state *state) - if (ret) - return ret; - -- ret = drm_atomic_add_affected_planes(state, &intel_crtc->base); -+ ret = skl_ddb_add_affected_planes(cstate); - if (ret) - return ret; - } --- -2.7.4 -_______________________________________________ -kernel mailing list -- kernel@lists.fedoraproject.org -To unsubscribe send an email to kernel-leave@lists.fedoraproject.org - diff --git a/kernel.spec b/kernel.spec index d963c3080..aa2c935f2 100644 --- a/kernel.spec +++ b/kernel.spec @@ -58,7 +58,7 @@ Summary: The Linux kernel %define stable_rc 0 # Do we have a -stable update to apply? -%define stable_update 5 +%define stable_update 6 # Set rpm version accordingly %if 0%{?stable_update} %define stablerev %{stable_update} @@ -530,6 +530,14 @@ Patch425: arm64-pcie-quirks.patch # http://www.spinics.net/lists/linux-tegra/msg26029.html Patch426: usb-phy-tegra-Add-38.4MHz-clock-table-entry.patch +# Fix OMAP4 (pandaboard) +Patch427: arm-revert-mmc-omap_hsmmc-Use-dma_request_chan-for-reque.patch +Patch428: ARM-OMAP4-Fix-crashes.patch + +# Not particularly happy we don't yet have a proper upstream resolution this is the right direction +# https://www.spinics.net/lists/arm-kernel/msg535191.html +Patch429: arm64-mm-Fix-memmap-to-be-initialized-for-the-entire-section.patch + # http://patchwork.ozlabs.org/patch/587554/ Patch430: ARM-tegra-usb-no-reset.patch @@ -643,9 +651,6 @@ Patch849: 0001-iio-Use-event-header-from-kernel-tree.patch # CVE-2016-9083 CVE-2016-9084 rhbz 1389258 1389259 1389285 Patch850: v3-vfio-pci-Fix-integer-overflows-bitmask-check.patch -# Skylake i915 fixes from 4.9 -Patch851: drm_i915_skl_Backport_watermark_fixes_for_4.8.y.patch - #rhbz 1325354 Patch852: 0001-HID-input-ignore-System-Control-application-usages-i.patch @@ -2188,6 +2193,13 @@ fi # # %changelog +* Tue Nov 1 2016 Peter Robinson <pbrobinson@fedoraproject.org> 4.8.6-300 +- Linux v4.8.6 +- Add revert to fix omap4 mmc (panda) +- Other minor omap4 fixes +- Adjust config for some AllWinner devices that don't like modular bits +- Add patch for aarch64 memory regions + * Sat Oct 29 2016 Peter Robinson <pbrobinson@fedoraproject.org> - Minor VC4 bug fix @@ -1,3 +1,3 @@ c1af0afbd3df35c1ccdc7a5118cd2d07 linux-4.8.tar.xz 0dad03f586e835d538d3e0d2cbdb9a28 perf-man-4.8.tar.gz -3b00c3fcfbe05e3cb7702e8db6fee28b patch-4.8.5.xz +666753363fd69ac2c1a94f4349a7197e patch-4.8.6.xz |