mirror of
https://github.com/torvalds/linux.git
synced 2024-11-19 18:41:48 +00:00
i915, amdgpu, omapdrm, docs and mst fix
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJb7fpHAAoJEAx081l5xIa+750P/1b/w3g7nZFbcXpDhomBVQJH qbxAsGdxwerZsYBnp4aSa4CEy4BWVJqGEqvBlvoSTqrdXZoP4ViQotFHgQ8efpnj DluZrKHzNrSXPAZYJqGJ6nY5QiFDdYdlj303+h4pt+3Ndc7fDXwM2kTECQASfGxZ lqrCN9wwmYlXdAiaP0GDrk4iPFuF3s4S34R0TuAEuigr8usYbUky6cjd/GbANTVB ovvrgkNCz13EBBCqoWdA4S6h1/yJPzXxE6lG9w4nhbVtXupxkk6ZRwAxT+M6A8P6 uGrqKQweAgfKPKWcLVEKJpGQwJ+zsbn1jqchjWLNKbcPdub9kLW7c+0SFQw4+Evm YMU9pS8DatM8jZ6fVv1Lwc7P3+Fue4zdNQ3Izw8+IiDbbdbb5bT3rUSKXU2qPl8o tDygle1R4k7jazOwK+htNX02MpQjHGDAKrkM188m6Wq8QPraqfjxbp26dP1Geh+h DPVQ833gIMKxXZIfo5BUaS8JK1gCYvgtDDSJd3twn5MBEuV94upXB6Zix6AkISmd pfjWv4OFh1wk0EraHfp50BlJ51BS8Tgfp565dC1NaBFqxulGaLLx9pxbiW9+lvQw fiQoC4KjkxCqpR3gHAF5WRrzUKwEIUyv/+qiVJJO7kkl0Jwf8I5rFVM1jeux1PAX UGjXLcYx+qMkF0/ItjWH =JYkZ -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2018-11-16' of git://anongit.freedesktop.org/drm/drm Pull drm fixes from Dave Airlie: "Live from Vancouver, SoC maintainer talk, this weeks drm fixes pull for rc3: omapdrm: - regression fixes for the reordering bridge stuff that went into rc1 i915: - incorrect EU count fix - HPD storm fix - MST fix - relocation fix for gen4/5 amdgpu: - huge page handling fix - IH ring setup - XGMI aperture setup - watermark setup fix misc: - docs and MST fix" * tag 'drm-fixes-2018-11-16' of git://anongit.freedesktop.org/drm/drm: (23 commits) drm/i915: Account for scale factor when calculating initial phase drm/i915: Clean up skl_program_scaler() drm/i915: Move programming plane scaler to its own function. drm/i915/icl: Drop spurious register read from icl_dbuf_slices_update drm/i915: fix broadwell EU computation drm/amdgpu: fix huge page handling on Vega10 drm/amd/pp: Fix truncated clock value when set watermark drm/amdgpu: fix bug with IH ring setup drm/meson: venc: dmt mode must use encp drm/amdgpu: set system aperture to cover whole FB region drm/i915: Fix hpd handling for pins with two encoders drm/i915/execlists: Force write serialisation into context image vs execution drm/i915/icl: Fix power well 2 wrt. DC-off toggling order drm/i915: Fix NULL deref when re-enabling HPD IRQs on systems with MST drm/i915: Fix possible race in intel_dp_add_mst_connector() drm/i915/ringbuffer: Delay after EMIT_INVALIDATE for gen4/gen5 drm/omap: dsi: Fix missing of_platform_depopulate() drm/omap: Move DISPC runtime PM handling to omapdrm drm/omap: dsi: Ensure the device is active during probe drm/omap: hdmi4: Ensure the device is active during bind ...
This commit is contained in:
commit
4efd34602f
@ -209,11 +209,61 @@ static int __init omapdss_init_fbdev(void)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static inline int omapdss_init_fbdev(void)
|
static const char * const omapdss_compat_names[] __initconst = {
|
||||||
|
"ti,omap2-dss",
|
||||||
|
"ti,omap3-dss",
|
||||||
|
"ti,omap4-dss",
|
||||||
|
"ti,omap5-dss",
|
||||||
|
"ti,dra7-dss",
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct device_node * __init omapdss_find_dss_of_node(void)
|
||||||
{
|
{
|
||||||
return 0;
|
struct device_node *node;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(omapdss_compat_names); ++i) {
|
||||||
|
node = of_find_compatible_node(NULL, NULL,
|
||||||
|
omapdss_compat_names[i]);
|
||||||
|
if (node)
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __init omapdss_init_of(void)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
struct device_node *node;
|
||||||
|
struct platform_device *pdev;
|
||||||
|
|
||||||
|
/* only create dss helper devices if dss is enabled in the .dts */
|
||||||
|
|
||||||
|
node = omapdss_find_dss_of_node();
|
||||||
|
if (!node)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!of_device_is_available(node))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pdev = of_find_device_by_node(node);
|
||||||
|
|
||||||
|
if (!pdev) {
|
||||||
|
pr_err("Unable to find DSS platform device\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = of_platform_populate(node, NULL, NULL, &pdev->dev);
|
||||||
|
if (r) {
|
||||||
|
pr_err("Unable to populate DSS submodule devices\n");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return omapdss_init_fbdev();
|
||||||
|
}
|
||||||
|
omap_device_initcall(omapdss_init_of);
|
||||||
#endif /* CONFIG_FB_OMAP2 */
|
#endif /* CONFIG_FB_OMAP2 */
|
||||||
|
|
||||||
static void dispc_disable_outputs(void)
|
static void dispc_disable_outputs(void)
|
||||||
@ -361,58 +411,3 @@ int omap_dss_reset(struct omap_hwmod *oh)
|
|||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char * const omapdss_compat_names[] __initconst = {
|
|
||||||
"ti,omap2-dss",
|
|
||||||
"ti,omap3-dss",
|
|
||||||
"ti,omap4-dss",
|
|
||||||
"ti,omap5-dss",
|
|
||||||
"ti,dra7-dss",
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct device_node * __init omapdss_find_dss_of_node(void)
|
|
||||||
{
|
|
||||||
struct device_node *node;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(omapdss_compat_names); ++i) {
|
|
||||||
node = of_find_compatible_node(NULL, NULL,
|
|
||||||
omapdss_compat_names[i]);
|
|
||||||
if (node)
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init omapdss_init_of(void)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
struct device_node *node;
|
|
||||||
struct platform_device *pdev;
|
|
||||||
|
|
||||||
/* only create dss helper devices if dss is enabled in the .dts */
|
|
||||||
|
|
||||||
node = omapdss_find_dss_of_node();
|
|
||||||
if (!node)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!of_device_is_available(node))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pdev = of_find_device_by_node(node);
|
|
||||||
|
|
||||||
if (!pdev) {
|
|
||||||
pr_err("Unable to find DSS platform device\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = of_platform_populate(node, NULL, NULL, &pdev->dev);
|
|
||||||
if (r) {
|
|
||||||
pr_err("Unable to populate DSS submodule devices\n");
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return omapdss_init_fbdev();
|
|
||||||
}
|
|
||||||
omap_device_initcall(omapdss_init_of);
|
|
||||||
|
@ -1632,13 +1632,6 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First check if the entry is already handled */
|
|
||||||
if (cursor.pfn < frag_start) {
|
|
||||||
cursor.entry->huge = true;
|
|
||||||
amdgpu_vm_pt_next(adev, &cursor);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If it isn't already handled it can't be a huge page */
|
/* If it isn't already handled it can't be a huge page */
|
||||||
if (cursor.entry->huge) {
|
if (cursor.entry->huge) {
|
||||||
/* Add the entry to the relocated list to update it. */
|
/* Add the entry to the relocated list to update it. */
|
||||||
@ -1701,8 +1694,17 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
|
|||||||
}
|
}
|
||||||
} while (frag_start < entry_end);
|
} while (frag_start < entry_end);
|
||||||
|
|
||||||
if (frag >= shift)
|
if (amdgpu_vm_pt_descendant(adev, &cursor)) {
|
||||||
|
/* Mark all child entries as huge */
|
||||||
|
while (cursor.pfn < frag_start) {
|
||||||
|
cursor.entry->huge = true;
|
||||||
|
amdgpu_vm_pt_next(adev, &cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (frag >= shift) {
|
||||||
|
/* or just move on to the next on the same level. */
|
||||||
amdgpu_vm_pt_next(adev, &cursor);
|
amdgpu_vm_pt_next(adev, &cursor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -72,7 +72,7 @@ static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||||||
|
|
||||||
/* Program the system aperture low logical page number. */
|
/* Program the system aperture low logical page number. */
|
||||||
WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,
|
WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,
|
||||||
min(adev->gmc.vram_start, adev->gmc.agp_start) >> 18);
|
min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18);
|
||||||
|
|
||||||
if (adev->asic_type == CHIP_RAVEN && adev->rev_id >= 0x8)
|
if (adev->asic_type == CHIP_RAVEN && adev->rev_id >= 0x8)
|
||||||
/*
|
/*
|
||||||
@ -82,11 +82,11 @@ static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||||||
* to get rid of the VM fault and hardware hang.
|
* to get rid of the VM fault and hardware hang.
|
||||||
*/
|
*/
|
||||||
WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||||
max((adev->gmc.vram_end >> 18) + 0x1,
|
max((adev->gmc.fb_end >> 18) + 0x1,
|
||||||
adev->gmc.agp_end >> 18));
|
adev->gmc.agp_end >> 18));
|
||||||
else
|
else
|
||||||
WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||||
max(adev->gmc.vram_end, adev->gmc.agp_end) >> 18);
|
max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
|
||||||
|
|
||||||
/* Set default page address. */
|
/* Set default page address. */
|
||||||
value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start
|
value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start
|
||||||
|
@ -90,7 +90,7 @@ static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||||||
|
|
||||||
/* Program the system aperture low logical page number. */
|
/* Program the system aperture low logical page number. */
|
||||||
WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,
|
WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,
|
||||||
min(adev->gmc.vram_start, adev->gmc.agp_start) >> 18);
|
min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18);
|
||||||
|
|
||||||
if (adev->asic_type == CHIP_RAVEN && adev->rev_id >= 0x8)
|
if (adev->asic_type == CHIP_RAVEN && adev->rev_id >= 0x8)
|
||||||
/*
|
/*
|
||||||
@ -100,11 +100,11 @@ static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||||||
* to get rid of the VM fault and hardware hang.
|
* to get rid of the VM fault and hardware hang.
|
||||||
*/
|
*/
|
||||||
WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||||
max((adev->gmc.vram_end >> 18) + 0x1,
|
max((adev->gmc.fb_end >> 18) + 0x1,
|
||||||
adev->gmc.agp_end >> 18));
|
adev->gmc.agp_end >> 18));
|
||||||
else
|
else
|
||||||
WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||||
max(adev->gmc.vram_end, adev->gmc.agp_end) >> 18);
|
max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
|
||||||
|
|
||||||
/* Set default page address. */
|
/* Set default page address. */
|
||||||
value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start +
|
value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start +
|
||||||
|
@ -129,7 +129,7 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
|
|||||||
else
|
else
|
||||||
wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
|
wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
|
||||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
|
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
|
||||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
|
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFFFF);
|
||||||
|
|
||||||
/* set rptr, wptr to 0 */
|
/* set rptr, wptr to 0 */
|
||||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
|
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
|
||||||
|
@ -713,20 +713,20 @@ int smu_set_watermarks_for_clocks_ranges(void *wt_table,
|
|||||||
for (i = 0; i < wm_with_clock_ranges->num_wm_dmif_sets; i++) {
|
for (i = 0; i < wm_with_clock_ranges->num_wm_dmif_sets; i++) {
|
||||||
table->WatermarkRow[1][i].MinClock =
|
table->WatermarkRow[1][i].MinClock =
|
||||||
cpu_to_le16((uint16_t)
|
cpu_to_le16((uint16_t)
|
||||||
(wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz) /
|
(wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz /
|
||||||
1000);
|
1000));
|
||||||
table->WatermarkRow[1][i].MaxClock =
|
table->WatermarkRow[1][i].MaxClock =
|
||||||
cpu_to_le16((uint16_t)
|
cpu_to_le16((uint16_t)
|
||||||
(wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz) /
|
(wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz /
|
||||||
1000);
|
1000));
|
||||||
table->WatermarkRow[1][i].MinUclk =
|
table->WatermarkRow[1][i].MinUclk =
|
||||||
cpu_to_le16((uint16_t)
|
cpu_to_le16((uint16_t)
|
||||||
(wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz) /
|
(wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz /
|
||||||
1000);
|
1000));
|
||||||
table->WatermarkRow[1][i].MaxUclk =
|
table->WatermarkRow[1][i].MaxUclk =
|
||||||
cpu_to_le16((uint16_t)
|
cpu_to_le16((uint16_t)
|
||||||
(wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz) /
|
(wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz /
|
||||||
1000);
|
1000));
|
||||||
table->WatermarkRow[1][i].WmSetting = (uint8_t)
|
table->WatermarkRow[1][i].WmSetting = (uint8_t)
|
||||||
wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id;
|
wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id;
|
||||||
}
|
}
|
||||||
@ -734,20 +734,20 @@ int smu_set_watermarks_for_clocks_ranges(void *wt_table,
|
|||||||
for (i = 0; i < wm_with_clock_ranges->num_wm_mcif_sets; i++) {
|
for (i = 0; i < wm_with_clock_ranges->num_wm_mcif_sets; i++) {
|
||||||
table->WatermarkRow[0][i].MinClock =
|
table->WatermarkRow[0][i].MinClock =
|
||||||
cpu_to_le16((uint16_t)
|
cpu_to_le16((uint16_t)
|
||||||
(wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz) /
|
(wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz /
|
||||||
1000);
|
1000));
|
||||||
table->WatermarkRow[0][i].MaxClock =
|
table->WatermarkRow[0][i].MaxClock =
|
||||||
cpu_to_le16((uint16_t)
|
cpu_to_le16((uint16_t)
|
||||||
(wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz) /
|
(wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz /
|
||||||
1000);
|
1000));
|
||||||
table->WatermarkRow[0][i].MinUclk =
|
table->WatermarkRow[0][i].MinUclk =
|
||||||
cpu_to_le16((uint16_t)
|
cpu_to_le16((uint16_t)
|
||||||
(wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz) /
|
(wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz /
|
||||||
1000);
|
1000));
|
||||||
table->WatermarkRow[0][i].MaxUclk =
|
table->WatermarkRow[0][i].MaxUclk =
|
||||||
cpu_to_le16((uint16_t)
|
cpu_to_le16((uint16_t)
|
||||||
(wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz) /
|
(wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz /
|
||||||
1000);
|
1000));
|
||||||
table->WatermarkRow[0][i].WmSetting = (uint8_t)
|
table->WatermarkRow[0][i].WmSetting = (uint8_t)
|
||||||
wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id;
|
wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id;
|
||||||
}
|
}
|
||||||
|
@ -1275,6 +1275,9 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_
|
|||||||
mutex_lock(&mgr->lock);
|
mutex_lock(&mgr->lock);
|
||||||
mstb = mgr->mst_primary;
|
mstb = mgr->mst_primary;
|
||||||
|
|
||||||
|
if (!mstb)
|
||||||
|
goto out;
|
||||||
|
|
||||||
for (i = 0; i < lct - 1; i++) {
|
for (i = 0; i < lct - 1; i++) {
|
||||||
int shift = (i % 2) ? 0 : 4;
|
int shift = (i % 2) ? 0 : 4;
|
||||||
int port_num = (rad[i / 2] >> shift) & 0xf;
|
int port_num = (rad[i / 2] >> shift) & 0xf;
|
||||||
|
@ -97,9 +97,9 @@ EXPORT_SYMBOL(drm_mode_legacy_fb_format);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_driver_legacy_fb_format - compute drm fourcc code from legacy description
|
* drm_driver_legacy_fb_format - compute drm fourcc code from legacy description
|
||||||
|
* @dev: DRM device
|
||||||
* @bpp: bits per pixels
|
* @bpp: bits per pixels
|
||||||
* @depth: bit depth per pixel
|
* @depth: bit depth per pixel
|
||||||
* @native: use host native byte order
|
|
||||||
*
|
*
|
||||||
* Computes a drm fourcc pixel format code for the given @bpp/@depth values.
|
* Computes a drm fourcc pixel format code for the given @bpp/@depth values.
|
||||||
* Unlike drm_mode_legacy_fb_format() this looks at the drivers mode_config,
|
* Unlike drm_mode_legacy_fb_format() this looks at the drivers mode_config,
|
||||||
|
@ -474,7 +474,7 @@ static void broadwell_sseu_info_init(struct drm_i915_private *dev_priv)
|
|||||||
u8 eu_disabled_mask;
|
u8 eu_disabled_mask;
|
||||||
u32 n_disabled;
|
u32 n_disabled;
|
||||||
|
|
||||||
if (!(sseu->subslice_mask[ss] & BIT(ss)))
|
if (!(sseu->subslice_mask[s] & BIT(ss)))
|
||||||
/* skip disabled subslice */
|
/* skip disabled subslice */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -4850,8 +4850,31 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
|
|||||||
* chroma samples for both of the luma samples, and thus we don't
|
* chroma samples for both of the luma samples, and thus we don't
|
||||||
* actually get the expected MPEG2 chroma siting convention :(
|
* actually get the expected MPEG2 chroma siting convention :(
|
||||||
* The same behaviour is observed on pre-SKL platforms as well.
|
* The same behaviour is observed on pre-SKL platforms as well.
|
||||||
|
*
|
||||||
|
* Theory behind the formula (note that we ignore sub-pixel
|
||||||
|
* source coordinates):
|
||||||
|
* s = source sample position
|
||||||
|
* d = destination sample position
|
||||||
|
*
|
||||||
|
* Downscaling 4:1:
|
||||||
|
* -0.5
|
||||||
|
* | 0.0
|
||||||
|
* | | 1.5 (initial phase)
|
||||||
|
* | | |
|
||||||
|
* v v v
|
||||||
|
* | s | s | s | s |
|
||||||
|
* | d |
|
||||||
|
*
|
||||||
|
* Upscaling 1:4:
|
||||||
|
* -0.5
|
||||||
|
* | -0.375 (initial phase)
|
||||||
|
* | | 0.0
|
||||||
|
* | | |
|
||||||
|
* v v v
|
||||||
|
* | s |
|
||||||
|
* | d | d | d | d |
|
||||||
*/
|
*/
|
||||||
u16 skl_scaler_calc_phase(int sub, bool chroma_cosited)
|
u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_cosited)
|
||||||
{
|
{
|
||||||
int phase = -0x8000;
|
int phase = -0x8000;
|
||||||
u16 trip = 0;
|
u16 trip = 0;
|
||||||
@ -4859,6 +4882,15 @@ u16 skl_scaler_calc_phase(int sub, bool chroma_cosited)
|
|||||||
if (chroma_cosited)
|
if (chroma_cosited)
|
||||||
phase += (sub - 1) * 0x8000 / sub;
|
phase += (sub - 1) * 0x8000 / sub;
|
||||||
|
|
||||||
|
phase += scale / (2 * sub);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hardware initial phase limited to [-0.5:1.5].
|
||||||
|
* Since the max hardware scale factor is 3.0, we
|
||||||
|
* should never actually excdeed 1.0 here.
|
||||||
|
*/
|
||||||
|
WARN_ON(phase < -0x8000 || phase > 0x18000);
|
||||||
|
|
||||||
if (phase < 0)
|
if (phase < 0)
|
||||||
phase = 0x10000 + phase;
|
phase = 0x10000 + phase;
|
||||||
else
|
else
|
||||||
@ -5067,13 +5099,20 @@ static void skylake_pfit_enable(struct intel_crtc *crtc)
|
|||||||
|
|
||||||
if (crtc->config->pch_pfit.enabled) {
|
if (crtc->config->pch_pfit.enabled) {
|
||||||
u16 uv_rgb_hphase, uv_rgb_vphase;
|
u16 uv_rgb_hphase, uv_rgb_vphase;
|
||||||
|
int pfit_w, pfit_h, hscale, vscale;
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
if (WARN_ON(crtc->config->scaler_state.scaler_id < 0))
|
if (WARN_ON(crtc->config->scaler_state.scaler_id < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uv_rgb_hphase = skl_scaler_calc_phase(1, false);
|
pfit_w = (crtc->config->pch_pfit.size >> 16) & 0xFFFF;
|
||||||
uv_rgb_vphase = skl_scaler_calc_phase(1, false);
|
pfit_h = crtc->config->pch_pfit.size & 0xFFFF;
|
||||||
|
|
||||||
|
hscale = (crtc->config->pipe_src_w << 16) / pfit_w;
|
||||||
|
vscale = (crtc->config->pipe_src_h << 16) / pfit_h;
|
||||||
|
|
||||||
|
uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
|
||||||
|
uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
|
||||||
|
|
||||||
id = scaler_state->scaler_id;
|
id = scaler_state->scaler_id;
|
||||||
I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN |
|
I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN |
|
||||||
|
@ -452,6 +452,10 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
|
|||||||
if (!intel_connector)
|
if (!intel_connector)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
intel_connector->get_hw_state = intel_dp_mst_get_hw_state;
|
||||||
|
intel_connector->mst_port = intel_dp;
|
||||||
|
intel_connector->port = port;
|
||||||
|
|
||||||
connector = &intel_connector->base;
|
connector = &intel_connector->base;
|
||||||
ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs,
|
ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs,
|
||||||
DRM_MODE_CONNECTOR_DisplayPort);
|
DRM_MODE_CONNECTOR_DisplayPort);
|
||||||
@ -462,10 +466,6 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
|
|||||||
|
|
||||||
drm_connector_helper_add(connector, &intel_dp_mst_connector_helper_funcs);
|
drm_connector_helper_add(connector, &intel_dp_mst_connector_helper_funcs);
|
||||||
|
|
||||||
intel_connector->get_hw_state = intel_dp_mst_get_hw_state;
|
|
||||||
intel_connector->mst_port = intel_dp;
|
|
||||||
intel_connector->port = port;
|
|
||||||
|
|
||||||
for_each_pipe(dev_priv, pipe) {
|
for_each_pipe(dev_priv, pipe) {
|
||||||
struct drm_encoder *enc =
|
struct drm_encoder *enc =
|
||||||
&intel_dp->mst_encoders[pipe]->base.base;
|
&intel_dp->mst_encoders[pipe]->base.base;
|
||||||
|
@ -1646,7 +1646,7 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
|
|||||||
void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
|
void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
|
||||||
struct intel_crtc_state *crtc_state);
|
struct intel_crtc_state *crtc_state);
|
||||||
|
|
||||||
u16 skl_scaler_calc_phase(int sub, bool chroma_center);
|
u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_center);
|
||||||
int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
|
int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
|
||||||
int skl_max_scale(const struct intel_crtc_state *crtc_state,
|
int skl_max_scale(const struct intel_crtc_state *crtc_state,
|
||||||
u32 pixel_format);
|
u32 pixel_format);
|
||||||
|
@ -228,7 +228,9 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
|
|||||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||||
struct intel_connector *intel_connector = to_intel_connector(connector);
|
struct intel_connector *intel_connector = to_intel_connector(connector);
|
||||||
|
|
||||||
if (intel_connector->encoder->hpd_pin == pin) {
|
/* Don't check MST ports, they don't have pins */
|
||||||
|
if (!intel_connector->mst_port &&
|
||||||
|
intel_connector->encoder->hpd_pin == pin) {
|
||||||
if (connector->polled != intel_connector->polled)
|
if (connector->polled != intel_connector->polled)
|
||||||
DRM_DEBUG_DRIVER("Reenabling HPD on connector %s\n",
|
DRM_DEBUG_DRIVER("Reenabling HPD on connector %s\n",
|
||||||
connector->name);
|
connector->name);
|
||||||
@ -395,37 +397,54 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
|
|||||||
struct intel_encoder *encoder;
|
struct intel_encoder *encoder;
|
||||||
bool storm_detected = false;
|
bool storm_detected = false;
|
||||||
bool queue_dig = false, queue_hp = false;
|
bool queue_dig = false, queue_hp = false;
|
||||||
|
u32 long_hpd_pulse_mask = 0;
|
||||||
|
u32 short_hpd_pulse_mask = 0;
|
||||||
|
enum hpd_pin pin;
|
||||||
|
|
||||||
if (!pin_mask)
|
if (!pin_mask)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
spin_lock(&dev_priv->irq_lock);
|
spin_lock(&dev_priv->irq_lock);
|
||||||
for_each_intel_encoder(&dev_priv->drm, encoder) {
|
|
||||||
enum hpd_pin pin = encoder->hpd_pin;
|
|
||||||
bool has_hpd_pulse = intel_encoder_has_hpd_pulse(encoder);
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine whether ->hpd_pulse() exists for each pin, and
|
||||||
|
* whether we have a short or a long pulse. This is needed
|
||||||
|
* as each pin may have up to two encoders (HDMI and DP) and
|
||||||
|
* only the one of them (DP) will have ->hpd_pulse().
|
||||||
|
*/
|
||||||
|
for_each_intel_encoder(&dev_priv->drm, encoder) {
|
||||||
|
bool has_hpd_pulse = intel_encoder_has_hpd_pulse(encoder);
|
||||||
|
enum port port = encoder->port;
|
||||||
|
bool long_hpd;
|
||||||
|
|
||||||
|
pin = encoder->hpd_pin;
|
||||||
if (!(BIT(pin) & pin_mask))
|
if (!(BIT(pin) & pin_mask))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (has_hpd_pulse) {
|
if (!has_hpd_pulse)
|
||||||
bool long_hpd = long_mask & BIT(pin);
|
continue;
|
||||||
enum port port = encoder->port;
|
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", port_name(port),
|
long_hpd = long_mask & BIT(pin);
|
||||||
long_hpd ? "long" : "short");
|
|
||||||
/*
|
DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", port_name(port),
|
||||||
* For long HPD pulses we want to have the digital queue happen,
|
long_hpd ? "long" : "short");
|
||||||
* but we still want HPD storm detection to function.
|
queue_dig = true;
|
||||||
*/
|
|
||||||
queue_dig = true;
|
if (long_hpd) {
|
||||||
if (long_hpd) {
|
long_hpd_pulse_mask |= BIT(pin);
|
||||||
dev_priv->hotplug.long_port_mask |= (1 << port);
|
dev_priv->hotplug.long_port_mask |= BIT(port);
|
||||||
} else {
|
} else {
|
||||||
/* for short HPD just trigger the digital queue */
|
short_hpd_pulse_mask |= BIT(pin);
|
||||||
dev_priv->hotplug.short_port_mask |= (1 << port);
|
dev_priv->hotplug.short_port_mask |= BIT(port);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now process each pin just once */
|
||||||
|
for_each_hpd_pin(pin) {
|
||||||
|
bool long_hpd;
|
||||||
|
|
||||||
|
if (!(BIT(pin) & pin_mask))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (dev_priv->hotplug.stats[pin].state == HPD_DISABLED) {
|
if (dev_priv->hotplug.stats[pin].state == HPD_DISABLED) {
|
||||||
/*
|
/*
|
||||||
@ -442,11 +461,22 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
|
|||||||
if (dev_priv->hotplug.stats[pin].state != HPD_ENABLED)
|
if (dev_priv->hotplug.stats[pin].state != HPD_ENABLED)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!has_hpd_pulse) {
|
/*
|
||||||
|
* Delegate to ->hpd_pulse() if one of the encoders for this
|
||||||
|
* pin has it, otherwise let the hotplug_work deal with this
|
||||||
|
* pin directly.
|
||||||
|
*/
|
||||||
|
if (((short_hpd_pulse_mask | long_hpd_pulse_mask) & BIT(pin))) {
|
||||||
|
long_hpd = long_hpd_pulse_mask & BIT(pin);
|
||||||
|
} else {
|
||||||
dev_priv->hotplug.event_bits |= BIT(pin);
|
dev_priv->hotplug.event_bits |= BIT(pin);
|
||||||
|
long_hpd = true;
|
||||||
queue_hp = true;
|
queue_hp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!long_hpd)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (intel_hpd_irq_storm_detect(dev_priv, pin)) {
|
if (intel_hpd_irq_storm_detect(dev_priv, pin)) {
|
||||||
dev_priv->hotplug.event_bits &= ~BIT(pin);
|
dev_priv->hotplug.event_bits &= ~BIT(pin);
|
||||||
storm_detected = true;
|
storm_detected = true;
|
||||||
|
@ -424,7 +424,8 @@ static u64 execlists_update_context(struct i915_request *rq)
|
|||||||
|
|
||||||
reg_state[CTX_RING_TAIL+1] = intel_ring_set_tail(rq->ring, rq->tail);
|
reg_state[CTX_RING_TAIL+1] = intel_ring_set_tail(rq->ring, rq->tail);
|
||||||
|
|
||||||
/* True 32b PPGTT with dynamic page allocation: update PDP
|
/*
|
||||||
|
* True 32b PPGTT with dynamic page allocation: update PDP
|
||||||
* registers and point the unallocated PDPs to scratch page.
|
* registers and point the unallocated PDPs to scratch page.
|
||||||
* PML4 is allocated during ppgtt init, so this is not needed
|
* PML4 is allocated during ppgtt init, so this is not needed
|
||||||
* in 48-bit mode.
|
* in 48-bit mode.
|
||||||
@ -432,6 +433,17 @@ static u64 execlists_update_context(struct i915_request *rq)
|
|||||||
if (ppgtt && !i915_vm_is_48bit(&ppgtt->vm))
|
if (ppgtt && !i915_vm_is_48bit(&ppgtt->vm))
|
||||||
execlists_update_context_pdps(ppgtt, reg_state);
|
execlists_update_context_pdps(ppgtt, reg_state);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure the context image is complete before we submit it to HW.
|
||||||
|
*
|
||||||
|
* Ostensibly, writes (including the WCB) should be flushed prior to
|
||||||
|
* an uncached write such as our mmio register access, the empirical
|
||||||
|
* evidence (esp. on Braswell) suggests that the WC write into memory
|
||||||
|
* may not be visible to the HW prior to the completion of the UC
|
||||||
|
* register write and that we may begin execution from the context
|
||||||
|
* before its image is complete leading to invalid PD chasing.
|
||||||
|
*/
|
||||||
|
wmb();
|
||||||
return ce->lrc_desc;
|
return ce->lrc_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +91,7 @@ static int
|
|||||||
gen4_render_ring_flush(struct i915_request *rq, u32 mode)
|
gen4_render_ring_flush(struct i915_request *rq, u32 mode)
|
||||||
{
|
{
|
||||||
u32 cmd, *cs;
|
u32 cmd, *cs;
|
||||||
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* read/write caches:
|
* read/write caches:
|
||||||
@ -127,12 +128,45 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode)
|
|||||||
cmd |= MI_INVALIDATE_ISP;
|
cmd |= MI_INVALIDATE_ISP;
|
||||||
}
|
}
|
||||||
|
|
||||||
cs = intel_ring_begin(rq, 2);
|
i = 2;
|
||||||
|
if (mode & EMIT_INVALIDATE)
|
||||||
|
i += 20;
|
||||||
|
|
||||||
|
cs = intel_ring_begin(rq, i);
|
||||||
if (IS_ERR(cs))
|
if (IS_ERR(cs))
|
||||||
return PTR_ERR(cs);
|
return PTR_ERR(cs);
|
||||||
|
|
||||||
*cs++ = cmd;
|
*cs++ = cmd;
|
||||||
*cs++ = MI_NOOP;
|
|
||||||
|
/*
|
||||||
|
* A random delay to let the CS invalidate take effect? Without this
|
||||||
|
* delay, the GPU relocation path fails as the CS does not see
|
||||||
|
* the updated contents. Just as important, if we apply the flushes
|
||||||
|
* to the EMIT_FLUSH branch (i.e. immediately after the relocation
|
||||||
|
* write and before the invalidate on the next batch), the relocations
|
||||||
|
* still fail. This implies that is a delay following invalidation
|
||||||
|
* that is required to reset the caches as opposed to a delay to
|
||||||
|
* ensure the memory is written.
|
||||||
|
*/
|
||||||
|
if (mode & EMIT_INVALIDATE) {
|
||||||
|
*cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
|
||||||
|
*cs++ = i915_ggtt_offset(rq->engine->scratch) |
|
||||||
|
PIPE_CONTROL_GLOBAL_GTT;
|
||||||
|
*cs++ = 0;
|
||||||
|
*cs++ = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 12; i++)
|
||||||
|
*cs++ = MI_FLUSH;
|
||||||
|
|
||||||
|
*cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
|
||||||
|
*cs++ = i915_ggtt_offset(rq->engine->scratch) |
|
||||||
|
PIPE_CONTROL_GLOBAL_GTT;
|
||||||
|
*cs++ = 0;
|
||||||
|
*cs++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*cs++ = cmd;
|
||||||
|
|
||||||
intel_ring_advance(rq, cs);
|
intel_ring_advance(rq, cs);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2748,6 +2748,12 @@ static const struct i915_power_well_desc icl_power_wells[] = {
|
|||||||
.hsw.has_fuses = true,
|
.hsw.has_fuses = true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "DC off",
|
||||||
|
.domains = ICL_DISPLAY_DC_OFF_POWER_DOMAINS,
|
||||||
|
.ops = &gen9_dc_off_power_well_ops,
|
||||||
|
.id = DISP_PW_ID_NONE,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "power well 2",
|
.name = "power well 2",
|
||||||
.domains = ICL_PW_2_POWER_DOMAINS,
|
.domains = ICL_PW_2_POWER_DOMAINS,
|
||||||
@ -2759,12 +2765,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
|
|||||||
.hsw.has_fuses = true,
|
.hsw.has_fuses = true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
.name = "DC off",
|
|
||||||
.domains = ICL_DISPLAY_DC_OFF_POWER_DOMAINS,
|
|
||||||
.ops = &gen9_dc_off_power_well_ops,
|
|
||||||
.id = DISP_PW_ID_NONE,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
.name = "power well 3",
|
.name = "power well 3",
|
||||||
.domains = ICL_PW_3_POWER_DOMAINS,
|
.domains = ICL_PW_3_POWER_DOMAINS,
|
||||||
@ -3176,8 +3176,7 @@ static u8 intel_dbuf_max_slices(struct drm_i915_private *dev_priv)
|
|||||||
void icl_dbuf_slices_update(struct drm_i915_private *dev_priv,
|
void icl_dbuf_slices_update(struct drm_i915_private *dev_priv,
|
||||||
u8 req_slices)
|
u8 req_slices)
|
||||||
{
|
{
|
||||||
u8 hw_enabled_slices = dev_priv->wm.skl_hw.ddb.enabled_slices;
|
const u8 hw_enabled_slices = dev_priv->wm.skl_hw.ddb.enabled_slices;
|
||||||
u32 val;
|
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
if (req_slices > intel_dbuf_max_slices(dev_priv)) {
|
if (req_slices > intel_dbuf_max_slices(dev_priv)) {
|
||||||
@ -3188,7 +3187,6 @@ void icl_dbuf_slices_update(struct drm_i915_private *dev_priv,
|
|||||||
if (req_slices == hw_enabled_slices || req_slices == 0)
|
if (req_slices == hw_enabled_slices || req_slices == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
val = I915_READ(DBUF_CTL_S2);
|
|
||||||
if (req_slices > hw_enabled_slices)
|
if (req_slices > hw_enabled_slices)
|
||||||
ret = intel_dbuf_slice_set(dev_priv, DBUF_CTL_S2, true);
|
ret = intel_dbuf_slice_set(dev_priv, DBUF_CTL_S2, true);
|
||||||
else
|
else
|
||||||
|
@ -302,13 +302,65 @@ skl_plane_max_stride(struct intel_plane *plane,
|
|||||||
return min(8192 * cpp, 32768);
|
return min(8192 * cpp, 32768);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
skl_program_scaler(struct intel_plane *plane,
|
||||||
|
const struct intel_crtc_state *crtc_state,
|
||||||
|
const struct intel_plane_state *plane_state)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||||
|
enum pipe pipe = plane->pipe;
|
||||||
|
int scaler_id = plane_state->scaler_id;
|
||||||
|
const struct intel_scaler *scaler =
|
||||||
|
&crtc_state->scaler_state.scalers[scaler_id];
|
||||||
|
int crtc_x = plane_state->base.dst.x1;
|
||||||
|
int crtc_y = plane_state->base.dst.y1;
|
||||||
|
uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
|
||||||
|
uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
|
||||||
|
u16 y_hphase, uv_rgb_hphase;
|
||||||
|
u16 y_vphase, uv_rgb_vphase;
|
||||||
|
int hscale, vscale;
|
||||||
|
|
||||||
|
hscale = drm_rect_calc_hscale(&plane_state->base.src,
|
||||||
|
&plane_state->base.dst,
|
||||||
|
0, INT_MAX);
|
||||||
|
vscale = drm_rect_calc_vscale(&plane_state->base.src,
|
||||||
|
&plane_state->base.dst,
|
||||||
|
0, INT_MAX);
|
||||||
|
|
||||||
|
/* TODO: handle sub-pixel coordinates */
|
||||||
|
if (plane_state->base.fb->format->format == DRM_FORMAT_NV12) {
|
||||||
|
y_hphase = skl_scaler_calc_phase(1, hscale, false);
|
||||||
|
y_vphase = skl_scaler_calc_phase(1, vscale, false);
|
||||||
|
|
||||||
|
/* MPEG2 chroma siting convention */
|
||||||
|
uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true);
|
||||||
|
uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false);
|
||||||
|
} else {
|
||||||
|
/* not used */
|
||||||
|
y_hphase = 0;
|
||||||
|
y_vphase = 0;
|
||||||
|
|
||||||
|
uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
|
||||||
|
uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
|
||||||
|
PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
|
||||||
|
I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
|
||||||
|
I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
|
||||||
|
PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
|
||||||
|
I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
|
||||||
|
PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
|
||||||
|
I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
|
||||||
|
I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
skl_update_plane(struct intel_plane *plane,
|
skl_update_plane(struct intel_plane *plane,
|
||||||
const struct intel_crtc_state *crtc_state,
|
const struct intel_crtc_state *crtc_state,
|
||||||
const struct intel_plane_state *plane_state)
|
const struct intel_plane_state *plane_state)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||||
const struct drm_framebuffer *fb = plane_state->base.fb;
|
|
||||||
enum plane_id plane_id = plane->id;
|
enum plane_id plane_id = plane->id;
|
||||||
enum pipe pipe = plane->pipe;
|
enum pipe pipe = plane->pipe;
|
||||||
u32 plane_ctl = plane_state->ctl;
|
u32 plane_ctl = plane_state->ctl;
|
||||||
@ -318,8 +370,6 @@ skl_update_plane(struct intel_plane *plane,
|
|||||||
u32 aux_stride = skl_plane_stride(plane_state, 1);
|
u32 aux_stride = skl_plane_stride(plane_state, 1);
|
||||||
int crtc_x = plane_state->base.dst.x1;
|
int crtc_x = plane_state->base.dst.x1;
|
||||||
int crtc_y = plane_state->base.dst.y1;
|
int crtc_y = plane_state->base.dst.y1;
|
||||||
uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
|
|
||||||
uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
|
|
||||||
uint32_t x = plane_state->color_plane[0].x;
|
uint32_t x = plane_state->color_plane[0].x;
|
||||||
uint32_t y = plane_state->color_plane[0].y;
|
uint32_t y = plane_state->color_plane[0].y;
|
||||||
uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
|
uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
|
||||||
@ -329,8 +379,6 @@ skl_update_plane(struct intel_plane *plane,
|
|||||||
/* Sizes are 0 based */
|
/* Sizes are 0 based */
|
||||||
src_w--;
|
src_w--;
|
||||||
src_h--;
|
src_h--;
|
||||||
crtc_w--;
|
|
||||||
crtc_h--;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
|
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
|
||||||
|
|
||||||
@ -353,41 +401,8 @@ skl_update_plane(struct intel_plane *plane,
|
|||||||
(plane_state->color_plane[1].y << 16) |
|
(plane_state->color_plane[1].y << 16) |
|
||||||
plane_state->color_plane[1].x);
|
plane_state->color_plane[1].x);
|
||||||
|
|
||||||
/* program plane scaler */
|
|
||||||
if (plane_state->scaler_id >= 0) {
|
if (plane_state->scaler_id >= 0) {
|
||||||
int scaler_id = plane_state->scaler_id;
|
skl_program_scaler(plane, crtc_state, plane_state);
|
||||||
const struct intel_scaler *scaler =
|
|
||||||
&crtc_state->scaler_state.scalers[scaler_id];
|
|
||||||
u16 y_hphase, uv_rgb_hphase;
|
|
||||||
u16 y_vphase, uv_rgb_vphase;
|
|
||||||
|
|
||||||
/* TODO: handle sub-pixel coordinates */
|
|
||||||
if (fb->format->format == DRM_FORMAT_NV12) {
|
|
||||||
y_hphase = skl_scaler_calc_phase(1, false);
|
|
||||||
y_vphase = skl_scaler_calc_phase(1, false);
|
|
||||||
|
|
||||||
/* MPEG2 chroma siting convention */
|
|
||||||
uv_rgb_hphase = skl_scaler_calc_phase(2, true);
|
|
||||||
uv_rgb_vphase = skl_scaler_calc_phase(2, false);
|
|
||||||
} else {
|
|
||||||
/* not used */
|
|
||||||
y_hphase = 0;
|
|
||||||
y_vphase = 0;
|
|
||||||
|
|
||||||
uv_rgb_hphase = skl_scaler_calc_phase(1, false);
|
|
||||||
uv_rgb_vphase = skl_scaler_calc_phase(1, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
|
|
||||||
PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode);
|
|
||||||
I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
|
|
||||||
I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
|
|
||||||
PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
|
|
||||||
I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
|
|
||||||
PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
|
|
||||||
I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
|
|
||||||
I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id),
|
|
||||||
((crtc_w + 1) << 16)|(crtc_h + 1));
|
|
||||||
|
|
||||||
I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
|
I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -854,6 +854,13 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
|
|||||||
unsigned int sof_lines;
|
unsigned int sof_lines;
|
||||||
unsigned int vsync_lines;
|
unsigned int vsync_lines;
|
||||||
|
|
||||||
|
/* Use VENCI for 480i and 576i and double HDMI pixels */
|
||||||
|
if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
|
||||||
|
hdmi_repeat = true;
|
||||||
|
use_enci = true;
|
||||||
|
venc_hdmi_latency = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (meson_venc_hdmi_supported_vic(vic)) {
|
if (meson_venc_hdmi_supported_vic(vic)) {
|
||||||
vmode = meson_venc_hdmi_get_vic_vmode(vic);
|
vmode = meson_venc_hdmi_get_vic_vmode(vic);
|
||||||
if (!vmode) {
|
if (!vmode) {
|
||||||
@ -865,13 +872,7 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
|
|||||||
} else {
|
} else {
|
||||||
meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt);
|
meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt);
|
||||||
vmode = &vmode_dmt;
|
vmode = &vmode_dmt;
|
||||||
}
|
use_enci = false;
|
||||||
|
|
||||||
/* Use VENCI for 480i and 576i and double HDMI pixels */
|
|
||||||
if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
|
|
||||||
hdmi_repeat = true;
|
|
||||||
use_enci = true;
|
|
||||||
venc_hdmi_latency = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
|
/* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
|
||||||
|
@ -5409,11 +5409,14 @@ static int dsi_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
/* DSI on OMAP3 doesn't have register DSI_GNQ, set number
|
/* DSI on OMAP3 doesn't have register DSI_GNQ, set number
|
||||||
* of data to 3 by default */
|
* of data to 3 by default */
|
||||||
if (dsi->data->quirks & DSI_QUIRK_GNQ)
|
if (dsi->data->quirks & DSI_QUIRK_GNQ) {
|
||||||
|
dsi_runtime_get(dsi);
|
||||||
/* NB_DATA_LANES */
|
/* NB_DATA_LANES */
|
||||||
dsi->num_lanes_supported = 1 + REG_GET(dsi, DSI_GNQ, 11, 9);
|
dsi->num_lanes_supported = 1 + REG_GET(dsi, DSI_GNQ, 11, 9);
|
||||||
else
|
dsi_runtime_put(dsi);
|
||||||
|
} else {
|
||||||
dsi->num_lanes_supported = 3;
|
dsi->num_lanes_supported = 3;
|
||||||
|
}
|
||||||
|
|
||||||
r = dsi_init_output(dsi);
|
r = dsi_init_output(dsi);
|
||||||
if (r)
|
if (r)
|
||||||
@ -5426,15 +5429,19 @@ static int dsi_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
r = of_platform_populate(dev->of_node, NULL, NULL, dev);
|
r = of_platform_populate(dev->of_node, NULL, NULL, dev);
|
||||||
if (r)
|
if (r) {
|
||||||
DSSERR("Failed to populate DSI child devices: %d\n", r);
|
DSSERR("Failed to populate DSI child devices: %d\n", r);
|
||||||
|
goto err_uninit_output;
|
||||||
|
}
|
||||||
|
|
||||||
r = component_add(&pdev->dev, &dsi_component_ops);
|
r = component_add(&pdev->dev, &dsi_component_ops);
|
||||||
if (r)
|
if (r)
|
||||||
goto err_uninit_output;
|
goto err_of_depopulate;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_of_depopulate:
|
||||||
|
of_platform_depopulate(dev);
|
||||||
err_uninit_output:
|
err_uninit_output:
|
||||||
dsi_uninit_output(dsi);
|
dsi_uninit_output(dsi);
|
||||||
err_pm_disable:
|
err_pm_disable:
|
||||||
@ -5470,19 +5477,12 @@ static int dsi_runtime_suspend(struct device *dev)
|
|||||||
/* wait for current handler to finish before turning the DSI off */
|
/* wait for current handler to finish before turning the DSI off */
|
||||||
synchronize_irq(dsi->irq);
|
synchronize_irq(dsi->irq);
|
||||||
|
|
||||||
dispc_runtime_put(dsi->dss->dispc);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsi_runtime_resume(struct device *dev)
|
static int dsi_runtime_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
struct dsi_data *dsi = dev_get_drvdata(dev);
|
struct dsi_data *dsi = dev_get_drvdata(dev);
|
||||||
int r;
|
|
||||||
|
|
||||||
r = dispc_runtime_get(dsi->dss->dispc);
|
|
||||||
if (r)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
dsi->is_enabled = true;
|
dsi->is_enabled = true;
|
||||||
/* ensure the irq handler sees the is_enabled value */
|
/* ensure the irq handler sees the is_enabled value */
|
||||||
|
@ -1484,16 +1484,23 @@ static int dss_probe(struct platform_device *pdev)
|
|||||||
dss);
|
dss);
|
||||||
|
|
||||||
/* Add all the child devices as components. */
|
/* Add all the child devices as components. */
|
||||||
|
r = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
|
||||||
|
if (r)
|
||||||
|
goto err_uninit_debugfs;
|
||||||
|
|
||||||
omapdss_gather_components(&pdev->dev);
|
omapdss_gather_components(&pdev->dev);
|
||||||
|
|
||||||
device_for_each_child(&pdev->dev, &match, dss_add_child_component);
|
device_for_each_child(&pdev->dev, &match, dss_add_child_component);
|
||||||
|
|
||||||
r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
|
r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
|
||||||
if (r)
|
if (r)
|
||||||
goto err_uninit_debugfs;
|
goto err_of_depopulate;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_of_depopulate:
|
||||||
|
of_platform_depopulate(&pdev->dev);
|
||||||
|
|
||||||
err_uninit_debugfs:
|
err_uninit_debugfs:
|
||||||
dss_debugfs_remove_file(dss->debugfs.clk);
|
dss_debugfs_remove_file(dss->debugfs.clk);
|
||||||
dss_debugfs_remove_file(dss->debugfs.dss);
|
dss_debugfs_remove_file(dss->debugfs.dss);
|
||||||
@ -1522,6 +1529,8 @@ static int dss_remove(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct dss_device *dss = platform_get_drvdata(pdev);
|
struct dss_device *dss = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
of_platform_depopulate(&pdev->dev);
|
||||||
|
|
||||||
component_master_del(&pdev->dev, &dss_component_ops);
|
component_master_del(&pdev->dev, &dss_component_ops);
|
||||||
|
|
||||||
dss_debugfs_remove_file(dss->debugfs.clk);
|
dss_debugfs_remove_file(dss->debugfs.clk);
|
||||||
|
@ -635,10 +635,14 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data)
|
|||||||
|
|
||||||
hdmi->dss = dss;
|
hdmi->dss = dss;
|
||||||
|
|
||||||
r = hdmi_pll_init(dss, hdmi->pdev, &hdmi->pll, &hdmi->wp);
|
r = hdmi_runtime_get(hdmi);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
r = hdmi_pll_init(dss, hdmi->pdev, &hdmi->pll, &hdmi->wp);
|
||||||
|
if (r)
|
||||||
|
goto err_runtime_put;
|
||||||
|
|
||||||
r = hdmi4_cec_init(hdmi->pdev, &hdmi->core, &hdmi->wp);
|
r = hdmi4_cec_init(hdmi->pdev, &hdmi->core, &hdmi->wp);
|
||||||
if (r)
|
if (r)
|
||||||
goto err_pll_uninit;
|
goto err_pll_uninit;
|
||||||
@ -652,12 +656,16 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data)
|
|||||||
hdmi->debugfs = dss_debugfs_create_file(dss, "hdmi", hdmi_dump_regs,
|
hdmi->debugfs = dss_debugfs_create_file(dss, "hdmi", hdmi_dump_regs,
|
||||||
hdmi);
|
hdmi);
|
||||||
|
|
||||||
|
hdmi_runtime_put(hdmi);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_cec_uninit:
|
err_cec_uninit:
|
||||||
hdmi4_cec_uninit(&hdmi->core);
|
hdmi4_cec_uninit(&hdmi->core);
|
||||||
err_pll_uninit:
|
err_pll_uninit:
|
||||||
hdmi_pll_uninit(&hdmi->pll);
|
hdmi_pll_uninit(&hdmi->pll);
|
||||||
|
err_runtime_put:
|
||||||
|
hdmi_runtime_put(hdmi);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -833,32 +841,6 @@ static int hdmi4_remove(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hdmi_runtime_suspend(struct device *dev)
|
|
||||||
{
|
|
||||||
struct omap_hdmi *hdmi = dev_get_drvdata(dev);
|
|
||||||
|
|
||||||
dispc_runtime_put(hdmi->dss->dispc);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hdmi_runtime_resume(struct device *dev)
|
|
||||||
{
|
|
||||||
struct omap_hdmi *hdmi = dev_get_drvdata(dev);
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = dispc_runtime_get(hdmi->dss->dispc);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct dev_pm_ops hdmi_pm_ops = {
|
|
||||||
.runtime_suspend = hdmi_runtime_suspend,
|
|
||||||
.runtime_resume = hdmi_runtime_resume,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct of_device_id hdmi_of_match[] = {
|
static const struct of_device_id hdmi_of_match[] = {
|
||||||
{ .compatible = "ti,omap4-hdmi", },
|
{ .compatible = "ti,omap4-hdmi", },
|
||||||
{},
|
{},
|
||||||
@ -869,7 +851,6 @@ struct platform_driver omapdss_hdmi4hw_driver = {
|
|||||||
.remove = hdmi4_remove,
|
.remove = hdmi4_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "omapdss_hdmi",
|
.name = "omapdss_hdmi",
|
||||||
.pm = &hdmi_pm_ops,
|
|
||||||
.of_match_table = hdmi_of_match,
|
.of_match_table = hdmi_of_match,
|
||||||
.suppress_bind_attrs = true,
|
.suppress_bind_attrs = true,
|
||||||
},
|
},
|
||||||
|
@ -825,32 +825,6 @@ static int hdmi5_remove(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hdmi_runtime_suspend(struct device *dev)
|
|
||||||
{
|
|
||||||
struct omap_hdmi *hdmi = dev_get_drvdata(dev);
|
|
||||||
|
|
||||||
dispc_runtime_put(hdmi->dss->dispc);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hdmi_runtime_resume(struct device *dev)
|
|
||||||
{
|
|
||||||
struct omap_hdmi *hdmi = dev_get_drvdata(dev);
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = dispc_runtime_get(hdmi->dss->dispc);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct dev_pm_ops hdmi_pm_ops = {
|
|
||||||
.runtime_suspend = hdmi_runtime_suspend,
|
|
||||||
.runtime_resume = hdmi_runtime_resume,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct of_device_id hdmi_of_match[] = {
|
static const struct of_device_id hdmi_of_match[] = {
|
||||||
{ .compatible = "ti,omap5-hdmi", },
|
{ .compatible = "ti,omap5-hdmi", },
|
||||||
{ .compatible = "ti,dra7-hdmi", },
|
{ .compatible = "ti,dra7-hdmi", },
|
||||||
@ -862,7 +836,6 @@ struct platform_driver omapdss_hdmi5hw_driver = {
|
|||||||
.remove = hdmi5_remove,
|
.remove = hdmi5_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "omapdss_hdmi5",
|
.name = "omapdss_hdmi5",
|
||||||
.pm = &hdmi_pm_ops,
|
|
||||||
.of_match_table = hdmi_of_match,
|
.of_match_table = hdmi_of_match,
|
||||||
.suppress_bind_attrs = true,
|
.suppress_bind_attrs = true,
|
||||||
},
|
},
|
||||||
|
@ -946,19 +946,12 @@ static int venc_runtime_suspend(struct device *dev)
|
|||||||
if (venc->tv_dac_clk)
|
if (venc->tv_dac_clk)
|
||||||
clk_disable_unprepare(venc->tv_dac_clk);
|
clk_disable_unprepare(venc->tv_dac_clk);
|
||||||
|
|
||||||
dispc_runtime_put(venc->dss->dispc);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int venc_runtime_resume(struct device *dev)
|
static int venc_runtime_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
struct venc_device *venc = dev_get_drvdata(dev);
|
struct venc_device *venc = dev_get_drvdata(dev);
|
||||||
int r;
|
|
||||||
|
|
||||||
r = dispc_runtime_get(venc->dss->dispc);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (venc->tv_dac_clk)
|
if (venc->tv_dac_clk)
|
||||||
clk_prepare_enable(venc->tv_dac_clk);
|
clk_prepare_enable(venc->tv_dac_clk);
|
||||||
|
@ -350,11 +350,14 @@ static void omap_crtc_arm_event(struct drm_crtc *crtc)
|
|||||||
static void omap_crtc_atomic_enable(struct drm_crtc *crtc,
|
static void omap_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||||
struct drm_crtc_state *old_state)
|
struct drm_crtc_state *old_state)
|
||||||
{
|
{
|
||||||
|
struct omap_drm_private *priv = crtc->dev->dev_private;
|
||||||
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
|
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DBG("%s", omap_crtc->name);
|
DBG("%s", omap_crtc->name);
|
||||||
|
|
||||||
|
priv->dispc_ops->runtime_get(priv->dispc);
|
||||||
|
|
||||||
spin_lock_irq(&crtc->dev->event_lock);
|
spin_lock_irq(&crtc->dev->event_lock);
|
||||||
drm_crtc_vblank_on(crtc);
|
drm_crtc_vblank_on(crtc);
|
||||||
ret = drm_crtc_vblank_get(crtc);
|
ret = drm_crtc_vblank_get(crtc);
|
||||||
@ -367,6 +370,7 @@ static void omap_crtc_atomic_enable(struct drm_crtc *crtc,
|
|||||||
static void omap_crtc_atomic_disable(struct drm_crtc *crtc,
|
static void omap_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||||
struct drm_crtc_state *old_state)
|
struct drm_crtc_state *old_state)
|
||||||
{
|
{
|
||||||
|
struct omap_drm_private *priv = crtc->dev->dev_private;
|
||||||
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
|
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
|
||||||
|
|
||||||
DBG("%s", omap_crtc->name);
|
DBG("%s", omap_crtc->name);
|
||||||
@ -379,6 +383,8 @@ static void omap_crtc_atomic_disable(struct drm_crtc *crtc,
|
|||||||
spin_unlock_irq(&crtc->dev->event_lock);
|
spin_unlock_irq(&crtc->dev->event_lock);
|
||||||
|
|
||||||
drm_crtc_vblank_off(crtc);
|
drm_crtc_vblank_off(crtc);
|
||||||
|
|
||||||
|
priv->dispc_ops->runtime_put(priv->dispc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc,
|
static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc,
|
||||||
|
Loading…
Reference in New Issue
Block a user