diff --git a/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon b/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon index 9bce281314dfde..adbb9bce15a5d6 100644 --- a/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon +++ b/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon @@ -124,3 +124,27 @@ Contact: intel-xe@lists.freedesktop.org Description: RO. VRAM temperature in millidegree Celsius. Only supported for particular Intel Xe graphics platforms. + +What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon/fan1_input +Date: March 2025 +KernelVersion: 6.14 +Contact: intel-xe@lists.freedesktop.org +Description: RO. Fan 1 speed in RPM. + + Only supported for particular Intel Xe graphics platforms. + +What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon/fan2_input +Date: March 2025 +KernelVersion: 6.14 +Contact: intel-xe@lists.freedesktop.org +Description: RO. Fan 2 speed in RPM. + + Only supported for particular Intel Xe graphics platforms. + +What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon/fan3_input +Date: March 2025 +KernelVersion: 6.14 +Contact: intel-xe@lists.freedesktop.org +Description: RO. Fan 3 speed in RPM. + + Only supported for particular Intel Xe graphics platforms. diff --git a/Documentation/gpu/xe/index.rst b/Documentation/gpu/xe/index.rst index 92cfb25e64d327..b2369561f24e18 100644 --- a/Documentation/gpu/xe/index.rst +++ b/Documentation/gpu/xe/index.rst @@ -25,3 +25,4 @@ DG2, etc is provided to prototype the driver. xe_debugging xe_devcoredump xe-drm-usage-stats.rst + xe_configfs diff --git a/Documentation/gpu/xe/xe_configfs.rst b/Documentation/gpu/xe/xe_configfs.rst new file mode 100644 index 00000000000000..9b9d941eb20ed6 --- /dev/null +++ b/Documentation/gpu/xe/xe_configfs.rst @@ -0,0 +1,10 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +.. _xe_configfs: + +============ +Xe Configfs +============ + +.. kernel-doc:: drivers/gpu/drm/xe/xe_configfs.c + :doc: Xe Configfs diff --git a/Documentation/gpu/xe/xe_pcode.rst b/Documentation/gpu/xe/xe_pcode.rst index d2e22cc45061f3..5937ef3599b0e2 100644 --- a/Documentation/gpu/xe/xe_pcode.rst +++ b/Documentation/gpu/xe/xe_pcode.rst @@ -12,3 +12,10 @@ Internal API .. kernel-doc:: drivers/gpu/drm/xe/xe_pcode.c :internal: + +================== +Boot Survivability +================== + +.. kernel-doc:: drivers/gpu/drm/xe/xe_survivability_mode.c + :doc: Xe Boot Survivability diff --git a/MAINTAINERS b/MAINTAINERS index a05d21fad0f730..f024b5376cdecd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11918,13 +11918,10 @@ F: drivers/gpio/gpio-tangier.c F: drivers/gpio/gpio-tangier.h INTEL GVT-g DRIVERS (Intel GPU Virtualization) -M: Zhenyu Wang -M: Zhi Wang -L: intel-gvt-dev@lists.freedesktop.org -L: intel-gfx@lists.freedesktop.org -S: Supported +R: Zhenyu Wang +R: Zhi Wang +S: Odd Fixes W: https://github.com/intel/gvt-linux/wiki -T: git https://github.com/intel/gvt-linux.git F: drivers/gpu/drm/i915/gvt/ INTEL HID EVENT DRIVER diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index 0825851656a274..f0dad0c9ce3381 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -332,7 +332,7 @@ ivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t si return -EINVAL; ret = ivpu_rpm_get(vdev); - if (ret) + if (ret < 0) return ret; ivpu_pm_trigger_recovery(vdev, "debugfs"); @@ -383,7 +383,7 @@ static int dct_active_set(void *data, u64 active_percent) return -EINVAL; ret = ivpu_rpm_get(vdev); - if (ret) + if (ret < 0) return ret; if (active_percent) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 4fa73189502e1a..eff1d3ca075f5a 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2020-2024 Intel Corporation + * Copyright (C) 2020-2025 Intel Corporation */ #include @@ -164,7 +164,7 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f args->value = vdev->platform; break; case DRM_IVPU_PARAM_CORE_CLOCK_RATE: - args->value = ivpu_hw_ratio_to_freq(vdev, vdev->hw->pll.max_ratio); + args->value = ivpu_hw_dpu_max_freq_get(vdev); break; case DRM_IVPU_PARAM_NUM_CONTEXTS: args->value = ivpu_get_context_count(vdev); @@ -421,9 +421,9 @@ void ivpu_prepare_for_reset(struct ivpu_device *vdev) { ivpu_hw_irq_disable(vdev); disable_irq(vdev->irq); - cancel_work_sync(&vdev->irq_ipc_work); - cancel_work_sync(&vdev->irq_dct_work); - cancel_work_sync(&vdev->context_abort_work); + flush_work(&vdev->irq_ipc_work); + flush_work(&vdev->irq_dct_work); + flush_work(&vdev->context_abort_work); ivpu_ipc_disable(vdev); ivpu_mmu_disable(vdev); } diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 7a1bb92d8c8161..5e1d709c6a464d 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2020-2024 Intel Corporation + * Copyright (C) 2020-2025 Intel Corporation */ #include @@ -233,10 +233,20 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) fw->dvfs_mode = 0; fw->sched_mode = ivpu_fw_sched_mode_select(vdev, fw_hdr); - fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size; - fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size; ivpu_info(vdev, "Scheduler mode: %s\n", fw->sched_mode ? "HW" : "OS"); + if (fw_hdr->preemption_buffer_1_max_size) + fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_max_size; + else + fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size; + + if (fw_hdr->preemption_buffer_2_max_size) + fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_max_size; + else + fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size; + ivpu_dbg(vdev, FW_BOOT, "Preemption buffer sizes: primary %u, secondary %u\n", + fw->primary_preempt_buf_size, fw->secondary_preempt_buf_size); + if (fw_hdr->ro_section_start_address && !is_within_range(fw_hdr->ro_section_start_address, fw_hdr->ro_section_size, fw_hdr->image_load_address, @@ -566,7 +576,6 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params boot_params->magic = VPU_BOOT_PARAMS_MAGIC; boot_params->vpu_id = to_pci_dev(vdev->drm.dev)->bus->number; - boot_params->frequency = ivpu_hw_pll_freq_get(vdev); /* * This param is a debug firmware feature. It switches default clock diff --git a/drivers/accel/ivpu/ivpu_hw.h b/drivers/accel/ivpu/ivpu_hw.h index 16435f2756d024..d79668fe1609f6 100644 --- a/drivers/accel/ivpu/ivpu_hw.h +++ b/drivers/accel/ivpu/ivpu_hw.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2020-2024 Intel Corporation + * Copyright (C) 2020-2025 Intel Corporation */ #ifndef __IVPU_HW_H__ @@ -82,19 +82,19 @@ static inline u64 ivpu_hw_range_size(const struct ivpu_addr_range *range) return range->end - range->start; } -static inline u32 ivpu_hw_ratio_to_freq(struct ivpu_device *vdev, u32 ratio) +static inline u32 ivpu_hw_dpu_max_freq_get(struct ivpu_device *vdev) { - return ivpu_hw_btrs_ratio_to_freq(vdev, ratio); + return ivpu_hw_btrs_dpu_max_freq_get(vdev); } -static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev) +static inline u32 ivpu_hw_dpu_freq_get(struct ivpu_device *vdev) { - ivpu_hw_ip_irq_clear(vdev); + return ivpu_hw_btrs_dpu_freq_get(vdev); } -static inline u32 ivpu_hw_pll_freq_get(struct ivpu_device *vdev) +static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev) { - return ivpu_hw_btrs_pll_freq_get(vdev); + ivpu_hw_ip_irq_clear(vdev); } static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev) diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index 56c56012b980fd..b236c7234daabb 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -1,8 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2020-2024 Intel Corporation + * Copyright (C) 2020-2025 Intel Corporation */ +#include + #include "ivpu_drv.h" #include "ivpu_hw.h" #include "ivpu_hw_btrs.h" @@ -28,17 +30,13 @@ #define BTRS_LNL_ALL_IRQ_MASK ((u32)-1) -#define BTRS_MTL_WP_CONFIG_1_TILE_5_3_RATIO WP_CONFIG(MTL_CONFIG_1_TILE, MTL_PLL_RATIO_5_3) -#define BTRS_MTL_WP_CONFIG_1_TILE_4_3_RATIO WP_CONFIG(MTL_CONFIG_1_TILE, MTL_PLL_RATIO_4_3) -#define BTRS_MTL_WP_CONFIG_2_TILE_5_3_RATIO WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_5_3) -#define BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_4_3) -#define BTRS_MTL_WP_CONFIG_0_TILE_PLL_OFF WP_CONFIG(0, 0) #define PLL_CDYN_DEFAULT 0x80 #define PLL_EPP_DEFAULT 0x80 #define PLL_CONFIG_DEFAULT 0x0 -#define PLL_SIMULATION_FREQ 10000000 -#define PLL_REF_CLK_FREQ 50000000 +#define PLL_REF_CLK_FREQ 50000000ull +#define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ) + #define PLL_TIMEOUT_US (1500 * USEC_PER_MSEC) #define IDLE_TIMEOUT_US (5 * USEC_PER_MSEC) #define TIMEOUT_US (150 * USEC_PER_MSEC) @@ -62,6 +60,8 @@ #define DCT_ENABLE 0x1 #define DCT_DISABLE 0x0 +static u32 pll_ratio_to_dpu_freq(struct ivpu_device *vdev, u32 ratio); + int ivpu_hw_btrs_irqs_clear_with_0_mtl(struct ivpu_device *vdev) { REGB_WR32(VPU_HW_BTRS_MTL_INTERRUPT_STAT, BTRS_MTL_ALL_IRQ_MASK); @@ -156,7 +156,7 @@ static int info_init_mtl(struct ivpu_device *vdev) hw->tile_fuse = BTRS_MTL_TILE_FUSE_ENABLE_BOTH; hw->sku = BTRS_MTL_TILE_SKU_BOTH; - hw->config = BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO; + hw->config = WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_4_3); return 0; } @@ -334,8 +334,8 @@ int ivpu_hw_btrs_wp_drive(struct ivpu_device *vdev, bool enable) prepare_wp_request(vdev, &wp, enable); - ivpu_dbg(vdev, PM, "PLL workpoint request: %u Hz, config: 0x%x, epp: 0x%x, cdyn: 0x%x\n", - PLL_RATIO_TO_FREQ(wp.target), wp.cfg, wp.epp, wp.cdyn); + ivpu_dbg(vdev, PM, "PLL workpoint request: %lu MHz, config: 0x%x, epp: 0x%x, cdyn: 0x%x\n", + pll_ratio_to_dpu_freq(vdev, wp.target) / HZ_PER_MHZ, wp.cfg, wp.epp, wp.cdyn); ret = wp_request_send(vdev, &wp); if (ret) { @@ -573,6 +573,47 @@ int ivpu_hw_btrs_wait_for_idle(struct ivpu_device *vdev) return REGB_POLL_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, IDLE, 0x1, IDLE_TIMEOUT_US); } +static u32 pll_config_get_mtl(struct ivpu_device *vdev) +{ + return REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL); +} + +static u32 pll_config_get_lnl(struct ivpu_device *vdev) +{ + return REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ); +} + +static u32 pll_ratio_to_dpu_freq_mtl(u16 ratio) +{ + return (PLL_RATIO_TO_FREQ(ratio) * 2) / 3; +} + +static u32 pll_ratio_to_dpu_freq_lnl(u16 ratio) +{ + return PLL_RATIO_TO_FREQ(ratio) / 2; +} + +static u32 pll_ratio_to_dpu_freq(struct ivpu_device *vdev, u32 ratio) +{ + if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) + return pll_ratio_to_dpu_freq_mtl(ratio); + else + return pll_ratio_to_dpu_freq_lnl(ratio); +} + +u32 ivpu_hw_btrs_dpu_max_freq_get(struct ivpu_device *vdev) +{ + return pll_ratio_to_dpu_freq(vdev, vdev->hw->pll.max_ratio); +} + +u32 ivpu_hw_btrs_dpu_freq_get(struct ivpu_device *vdev) +{ + if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) + return pll_ratio_to_dpu_freq_mtl(pll_config_get_mtl(vdev)); + else + return pll_ratio_to_dpu_freq_lnl(pll_config_get_lnl(vdev)); +} + /* Handler for IRQs from Buttress core (irqB) */ bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq) { @@ -582,9 +623,12 @@ bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq) if (!status) return false; - if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, FREQ_CHANGE, status)) - ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x", - REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL)); + if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, FREQ_CHANGE, status)) { + u32 pll = pll_config_get_mtl(vdev); + + ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq, wp %08x, %lu MHz", + pll, pll_ratio_to_dpu_freq_mtl(pll) / HZ_PER_MHZ); + } if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, ATS_ERR, status)) { ivpu_err(vdev, "ATS_ERR irq 0x%016llx", REGB_RD64(VPU_HW_BTRS_MTL_ATS_ERR_LOG_0)); @@ -633,8 +677,12 @@ bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq) queue_work(system_wq, &vdev->irq_dct_work); } - if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, FREQ_CHANGE, status)) - ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x", REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ)); + if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, FREQ_CHANGE, status)) { + u32 pll = pll_config_get_lnl(vdev); + + ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq, wp %08x, %lu MHz", + pll, pll_ratio_to_dpu_freq_lnl(pll) / HZ_PER_MHZ); + } if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR, status)) { ivpu_err(vdev, "ATS_ERR LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n", @@ -717,60 +765,6 @@ void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 acti REGB_WR32(VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS, val); } -static u32 pll_ratio_to_freq_mtl(u32 ratio, u32 config) -{ - u32 pll_clock = PLL_REF_CLK_FREQ * ratio; - u32 cpu_clock; - - if ((config & 0xff) == MTL_PLL_RATIO_4_3) - cpu_clock = pll_clock * 2 / 4; - else - cpu_clock = pll_clock * 2 / 5; - - return cpu_clock; -} - -u32 ivpu_hw_btrs_ratio_to_freq(struct ivpu_device *vdev, u32 ratio) -{ - struct ivpu_hw_info *hw = vdev->hw; - - if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) - return pll_ratio_to_freq_mtl(ratio, hw->config); - else - return PLL_RATIO_TO_FREQ(ratio); -} - -static u32 pll_freq_get_mtl(struct ivpu_device *vdev) -{ - u32 pll_curr_ratio; - - pll_curr_ratio = REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL); - pll_curr_ratio &= VPU_HW_BTRS_MTL_CURRENT_PLL_RATIO_MASK; - - if (!ivpu_is_silicon(vdev)) - return PLL_SIMULATION_FREQ; - - return pll_ratio_to_freq_mtl(pll_curr_ratio, vdev->hw->config); -} - -static u32 pll_freq_get_lnl(struct ivpu_device *vdev) -{ - u32 pll_curr_ratio; - - pll_curr_ratio = REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ); - pll_curr_ratio &= VPU_HW_BTRS_LNL_PLL_FREQ_RATIO_MASK; - - return PLL_RATIO_TO_FREQ(pll_curr_ratio); -} - -u32 ivpu_hw_btrs_pll_freq_get(struct ivpu_device *vdev) -{ - if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) - return pll_freq_get_mtl(vdev); - else - return pll_freq_get_lnl(vdev); -} - u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev) { if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.h b/drivers/accel/ivpu/ivpu_hw_btrs.h index 1fd71b4d4ab01a..300f749971d4d6 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.h +++ b/drivers/accel/ivpu/ivpu_hw_btrs.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2020-2024 Intel Corporation + * Copyright (C) 2020-2025 Intel Corporation */ #ifndef __IVPU_HW_BTRS_H__ @@ -13,7 +13,6 @@ #define PLL_PROFILING_FREQ_DEFAULT 38400000 #define PLL_PROFILING_FREQ_HIGH 400000000 -#define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ) #define DCT_DEFAULT_ACTIVE_PERCENT 15u #define DCT_PERIOD_US 35300u @@ -32,12 +31,12 @@ int ivpu_hw_btrs_ip_reset(struct ivpu_device *vdev); void ivpu_hw_btrs_profiling_freq_reg_set_lnl(struct ivpu_device *vdev); void ivpu_hw_btrs_ats_print_lnl(struct ivpu_device *vdev); void ivpu_hw_btrs_clock_relinquish_disable_lnl(struct ivpu_device *vdev); +u32 ivpu_hw_btrs_dpu_max_freq_get(struct ivpu_device *vdev); +u32 ivpu_hw_btrs_dpu_freq_get(struct ivpu_device *vdev); bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq); bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq); int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable); void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 dct_percent); -u32 ivpu_hw_btrs_pll_freq_get(struct ivpu_device *vdev); -u32 ivpu_hw_btrs_ratio_to_freq(struct ivpu_device *vdev, u32 ratio); u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev); u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev); u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev); diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index 0e096fd9b95dd6..39f83225c1815a 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -302,7 +302,8 @@ ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req struct ivpu_ipc_consumer cons; int ret; - drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev)); + drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev) && + pm_runtime_enabled(vdev->drm.dev)); ivpu_ipc_consumer_add(vdev, &cons, channel, NULL); diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 004059e4f1e89d..863e3cd6ace51e 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -470,8 +470,8 @@ static void ivpu_job_destroy(struct ivpu_job *job) struct ivpu_device *vdev = job->vdev; u32 i; - ivpu_dbg(vdev, JOB, "Job destroyed: id %3u ctx %2d engine %d", - job->job_id, job->file_priv->ctx.id, job->engine_idx); + ivpu_dbg(vdev, JOB, "Job destroyed: id %3u ctx %2d cmdq_id %u engine %d", + job->job_id, job->file_priv->ctx.id, job->cmdq_id, job->engine_idx); for (i = 0; i < job->bo_count; i++) if (job->bos[i]) @@ -564,8 +564,8 @@ static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32 dma_fence_signal(job->done_fence); trace_job("done", job); - ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d engine %d status 0x%x\n", - job->job_id, job->file_priv->ctx.id, job->engine_idx, job_status); + ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d cmdq_id %u engine %d status 0x%x\n", + job->job_id, job->file_priv->ctx.id, job->cmdq_id, job->engine_idx, job_status); ivpu_job_destroy(job); ivpu_stop_job_timeout_detection(vdev); @@ -664,8 +664,8 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority, u32 cmdq_id) } trace_job("submit", job); - ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d engine %d prio %d addr 0x%llx next %d\n", - job->job_id, file_priv->ctx.id, job->engine_idx, cmdq->priority, + ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d cmdq_id %u engine %d prio %d addr 0x%llx next %d\n", + job->job_id, file_priv->ctx.id, cmdq->id, job->engine_idx, cmdq->priority, job->cmd_buf_vpu_addr, cmdq->jobq->header.tail); mutex_unlock(&file_priv->lock); @@ -777,7 +777,8 @@ static int ivpu_submit(struct drm_file *file, struct ivpu_file_priv *file_priv, goto err_free_handles; } - ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u buf_count %u\n", file_priv->ctx.id, buffer_count); + ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u cmdq_id %u buf_count %u\n", + file_priv->ctx.id, cmdq_id, buffer_count); job = ivpu_job_create(file_priv, engine, buffer_count); if (!job) { diff --git a/drivers/accel/ivpu/ivpu_ms.c b/drivers/accel/ivpu/ivpu_ms.c index ffe7b10f8a767b..2a043baf10ca17 100644 --- a/drivers/accel/ivpu/ivpu_ms.c +++ b/drivers/accel/ivpu/ivpu_ms.c @@ -4,6 +4,7 @@ */ #include +#include #include "ivpu_drv.h" #include "ivpu_gem.h" @@ -44,6 +45,10 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil args->sampling_period_ns < MS_MIN_SAMPLE_PERIOD_NS) return -EINVAL; + ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; + mutex_lock(&file_priv->ms_lock); if (get_instance_by_mask(file_priv, args->metric_group_mask)) { @@ -96,6 +101,8 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil kfree(ms); unlock: mutex_unlock(&file_priv->ms_lock); + + ivpu_rpm_put(vdev); return ret; } @@ -160,6 +167,10 @@ int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file * if (!args->metric_group_mask) return -EINVAL; + ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; + mutex_lock(&file_priv->ms_lock); ms = get_instance_by_mask(file_priv, args->metric_group_mask); @@ -187,6 +198,7 @@ int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file * unlock: mutex_unlock(&file_priv->ms_lock); + ivpu_rpm_put(vdev); return ret; } @@ -204,11 +216,17 @@ int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file { struct ivpu_file_priv *file_priv = file->driver_priv; struct drm_ivpu_metric_streamer_stop *args = data; + struct ivpu_device *vdev = file_priv->vdev; struct ivpu_ms_instance *ms; + int ret; if (!args->metric_group_mask) return -EINVAL; + ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; + mutex_lock(&file_priv->ms_lock); ms = get_instance_by_mask(file_priv, args->metric_group_mask); @@ -217,6 +235,7 @@ int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file mutex_unlock(&file_priv->ms_lock); + ivpu_rpm_put(vdev); return ms ? 0 : -EINVAL; } @@ -281,6 +300,9 @@ int ivpu_ms_get_info_ioctl(struct drm_device *dev, void *data, struct drm_file * void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv) { struct ivpu_ms_instance *ms, *tmp; + struct ivpu_device *vdev = file_priv->vdev; + + pm_runtime_get_sync(vdev->drm.dev); mutex_lock(&file_priv->ms_lock); @@ -293,6 +315,8 @@ void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv) free_instance(file_priv, ms); mutex_unlock(&file_priv->ms_lock); + + pm_runtime_put_autosuspend(vdev->drm.dev); } void ivpu_ms_cleanup_all(struct ivpu_device *vdev) diff --git a/drivers/accel/ivpu/ivpu_sysfs.c b/drivers/accel/ivpu/ivpu_sysfs.c index 97102feaf8ddca..268ab7744a8bbb 100644 --- a/drivers/accel/ivpu/ivpu_sysfs.c +++ b/drivers/accel/ivpu/ivpu_sysfs.c @@ -1,10 +1,12 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2024-2025 Intel Corporation */ #include #include +#include +#include #include "ivpu_drv.h" #include "ivpu_gem.h" @@ -90,10 +92,55 @@ sched_mode_show(struct device *dev, struct device_attribute *attr, char *buf) static DEVICE_ATTR_RO(sched_mode); +/** + * DOC: npu_max_frequency + * + * The npu_max_frequency shows maximum frequency in MHz of the NPU's data + * processing unit + */ +static ssize_t +npu_max_frequency_mhz_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct drm_device *drm = dev_get_drvdata(dev); + struct ivpu_device *vdev = to_ivpu_device(drm); + u32 freq = ivpu_hw_dpu_max_freq_get(vdev); + + return sysfs_emit(buf, "%lu\n", freq / HZ_PER_MHZ); +} + +static DEVICE_ATTR_RO(npu_max_frequency_mhz); + +/** + * DOC: npu_current_frequency_mhz + * + * The npu_current_frequency_mhz shows current frequency in MHz of the NPU's + * data processing unit + */ +static ssize_t +npu_current_frequency_mhz_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct drm_device *drm = dev_get_drvdata(dev); + struct ivpu_device *vdev = to_ivpu_device(drm); + u32 freq = 0; + + /* Read frequency only if device is active, otherwise frequency is 0 */ + if (pm_runtime_get_if_active(vdev->drm.dev) > 0) { + freq = ivpu_hw_dpu_freq_get(vdev); + + pm_runtime_put_autosuspend(vdev->drm.dev); + } + + return sysfs_emit(buf, "%lu\n", freq / HZ_PER_MHZ); +} + +static DEVICE_ATTR_RO(npu_current_frequency_mhz); + static struct attribute *ivpu_dev_attrs[] = { &dev_attr_npu_busy_time_us.attr, &dev_attr_npu_memory_utilization.attr, &dev_attr_sched_mode.attr, + &dev_attr_npu_max_frequency_mhz.attr, + &dev_attr_npu_current_frequency_mhz.attr, NULL, }; diff --git a/drivers/accel/ivpu/vpu_boot_api.h b/drivers/accel/ivpu/vpu_boot_api.h index 908e68ea1c39c2..218468bbbcadaf 100644 --- a/drivers/accel/ivpu/vpu_boot_api.h +++ b/drivers/accel/ivpu/vpu_boot_api.h @@ -26,7 +26,7 @@ * Minor version changes when API backward compatibility is preserved. * Resets to 0 if Major version is incremented. */ -#define VPU_BOOT_API_VER_MINOR 26 +#define VPU_BOOT_API_VER_MINOR 28 /* * API header changed (field names, documentation, formatting) but API itself has not been changed @@ -76,8 +76,15 @@ struct vpu_firmware_header { * submission queue size and device capabilities. */ u32 preemption_buffer_2_size; + /* + * Maximum preemption buffer size that the FW can use: no need for the host + * driver to allocate more space than that specified by these fields. + * A value of 0 means no declared limit. + */ + u32 preemption_buffer_1_max_size; + u32 preemption_buffer_2_max_size; /* Space reserved for future preemption-related fields. */ - u32 preemption_reserved[6]; + u32 preemption_reserved[4]; /* FW image read only section start address, 4KB aligned */ u64 ro_section_start_address; /* FW image read only section size, 4KB aligned */ @@ -134,7 +141,7 @@ enum vpu_trace_destination { /* * Processor bit shifts (for loggable HW components). */ -#define VPU_TRACE_PROC_BIT_ARM 0 +#define VPU_TRACE_PROC_BIT_RESERVED 0 #define VPU_TRACE_PROC_BIT_LRT 1 #define VPU_TRACE_PROC_BIT_LNN 2 #define VPU_TRACE_PROC_BIT_SHV_0 3 diff --git a/drivers/accel/ivpu/vpu_jsm_api.h b/drivers/accel/ivpu/vpu_jsm_api.h index 7215c144158cbd..4b6b2b3d2583a8 100644 --- a/drivers/accel/ivpu/vpu_jsm_api.h +++ b/drivers/accel/ivpu/vpu_jsm_api.h @@ -22,7 +22,7 @@ /* * Minor version changes when API backward compatibility is preserved. */ -#define VPU_JSM_API_VER_MINOR 25 +#define VPU_JSM_API_VER_MINOR 29 /* * API header changed (field names, documentation, formatting) but API itself has not been changed @@ -53,8 +53,7 @@ * Engine indexes. */ #define VPU_ENGINE_COMPUTE 0 -#define VPU_ENGINE_COPY 1 -#define VPU_ENGINE_NB 2 +#define VPU_ENGINE_NB 1 /* * VPU status values. @@ -126,11 +125,13 @@ enum { * When set, indicates that job queue uses native fences (as inline commands * in job queue). Such queues may also use legacy fences (as commands in batch buffers). * When cleared, indicates the job queue only uses legacy fences. - * NOTE: For queues using native fences, VPU expects that all jobs in the queue - * are immediately followed by an inline command object. This object is expected - * to be a fence signal command in most cases, but can also be a NOP in case the host - * does not need per-job fence signalling. Other inline commands objects can be - * inserted between "job and inline command" pairs. + * NOTES: + * 1. For queues using native fences, VPU expects that all jobs in the queue + * are immediately followed by an inline command object. This object is expected + * to be a fence signal command in most cases, but can also be a NOP in case the host + * does not need per-job fence signalling. Other inline commands objects can be + * inserted between "job and inline command" pairs. + * 2. Native fence queues are only supported on VPU 40xx onwards. */ VPU_JOB_QUEUE_FLAGS_USE_NATIVE_FENCE_MASK = (1 << 1U), @@ -275,6 +276,8 @@ struct vpu_inline_cmd { u64 value; /* User VA of the log buffer in which to add log entry on completion. */ u64 log_buffer_va; + /* NPU private data. */ + u64 npu_private_data; } fence; /* Other commands do not have a payload. */ /* Payload definition for future inline commands can be inserted here. */ @@ -791,12 +794,22 @@ struct vpu_jsm_metric_streamer_update { /** Metric group mask that identifies metric streamer instance. */ u64 metric_group_mask; /** - * Address and size of the buffer where the VPU will write metric data. If - * the buffer address is 0 or same as the currently used buffer the VPU will - * continue writing metric data to the current buffer. In this case the - * buffer size is ignored and the size of the current buffer is unchanged. - * If the address is non-zero and differs from the current buffer address the - * VPU will immediately switch data collection to the new buffer. + * Address and size of the buffer where the VPU will write metric data. + * This member dictates how the update operation should perform: + * 1. client needs information about the number of collected samples and the + * amount of data written to the current buffer + * 2. client wants to switch to a new buffer + * + * Case 1. is identified by the buffer address being 0 or the same as the + * currently used buffer address. In this case the buffer size is ignored and + * the size of the current buffer is unchanged. The VPU will return an update + * in the vpu_jsm_metric_streamer_done structure. The internal writing position + * into the buffer is not changed. + * + * Case 2. is identified by the address being non-zero and differs from the + * current buffer address. The VPU will immediately switch data collection to + * the new buffer. Then the VPU will return an update in the + * vpu_jsm_metric_streamer_done structure. */ u64 buffer_addr; u64 buffer_size; @@ -934,6 +947,7 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup { /* * Default quantum in 100ns units for scheduling across processes * within a priority band + * Minimum value supported by NPU is 1ms (10000 in 100ns units). */ u32 process_quantum[VPU_HWS_NUM_PRIORITY_BANDS]; /* @@ -946,8 +960,10 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup { * in situations when it's starved by the focus band. */ u32 normal_band_percentage; - /* Reserved */ - u32 reserved_0; + /* + * TDR timeout value in milliseconds. Default value of 0 meaning no timeout. + */ + u32 tdr_timeout; }; /* @@ -1024,7 +1040,10 @@ struct vpu_ipc_msg_payload_hws_set_context_sched_properties { s32 in_process_priority; /* Zero padding / Reserved */ u32 reserved_1; - /* Context quantum relative to other contexts of same priority in the same process */ + /* + * Context quantum relative to other contexts of same priority in the same process + * Minimum value supported by NPU is 1ms (10000 in 100ns units). + */ u64 context_quantum; /* Grace period when preempting context of the same priority within the same process */ u64 grace_period_same_priority; diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 773799cfd44308..14bed90d833676 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2178,7 +2178,7 @@ static bool ata_identify_page_supported(struct ata_device *dev, u8 page) * for drives which implement this ATA level or above. */ if (ata_id_major_version(dev->id) >= 10) - ata_dev_warn(dev, + ata_dev_notice(dev, "ATA Identify Device Log not supported\n"); dev->quirks |= ATA_QUIRK_NO_ID_DEV_LOG; return false; @@ -2249,7 +2249,7 @@ static void ata_dev_config_ncq_send_recv(struct ata_device *dev) unsigned int err_mask; if (!ata_log_supported(dev, ATA_LOG_NCQ_SEND_RECV)) { - ata_dev_warn(dev, "NCQ Send/Recv Log not supported\n"); + ata_dev_notice(dev, "NCQ Send/Recv Log not supported\n"); return; } err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV, @@ -2273,8 +2273,8 @@ static void ata_dev_config_ncq_non_data(struct ata_device *dev) unsigned int err_mask; if (!ata_log_supported(dev, ATA_LOG_NCQ_NON_DATA)) { - ata_dev_warn(dev, - "NCQ Non-Data Log not supported\n"); + ata_dev_notice(dev, + "NCQ Non-Data Log not supported\n"); return; } err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_NON_DATA, @@ -2937,14 +2937,14 @@ int ata_dev_configure(struct ata_device *dev) if (ata_id_is_cfa(id)) { /* CPRM may make this media unusable */ if (id[ATA_ID_CFA_KEY_MGMT] & 1) - ata_dev_warn(dev, + ata_dev_notice(dev, "supports DRM functions and may not be fully accessible\n"); snprintf(revbuf, 7, "CFA"); } else { snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); /* Warn the user if the device has TPM extensions */ if (ata_id_has_tpm(id)) - ata_dev_warn(dev, + ata_dev_notice(dev, "supports DRM functions and may not be fully accessible\n"); } @@ -3100,8 +3100,8 @@ int ata_dev_configure(struct ata_device *dev) } if ((dev->quirks & ATA_QUIRK_FIRMWARE_WARN) && print_info) { - ata_dev_warn(dev, "WARNING: device requires firmware update to be fully functional\n"); - ata_dev_warn(dev, " contact the vendor or visit http://ata.wiki.kernel.org\n"); + ata_dev_notice(dev, "WARNING: device requires firmware update to be fully functional\n"); + ata_dev_notice(dev, " contact the vendor or visit http://ata.wiki.kernel.org\n"); } return 0; diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index ef30445527a2d2..bcc26785175d39 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -53,6 +53,7 @@ struct intel_gtt_driver { * of the mmio register file, that's done in the generic code. */ void (*cleanup)(void); void (*write_entry)(dma_addr_t addr, unsigned int entry, unsigned int flags); + dma_addr_t (*read_entry)(unsigned int entry, bool *is_present, bool *is_local); /* Flags is a more or less chipset specific opaque value. * For chipsets that need to support old ums (non-gem) code, this * needs to be identical to the various supported agp memory types! */ @@ -336,6 +337,19 @@ static void i810_write_entry(dma_addr_t addr, unsigned int entry, writel_relaxed(addr | pte_flags, intel_private.gtt + entry); } +static dma_addr_t i810_read_entry(unsigned int entry, + bool *is_present, bool *is_local) +{ + u32 val; + + val = readl(intel_private.gtt + entry); + + *is_present = val & I810_PTE_VALID; + *is_local = val & I810_PTE_LOCAL; + + return val & ~0xfff; +} + static resource_size_t intel_gtt_stolen_size(void) { u16 gmch_ctrl; @@ -741,6 +755,19 @@ static void i830_write_entry(dma_addr_t addr, unsigned int entry, writel_relaxed(addr | pte_flags, intel_private.gtt + entry); } +static dma_addr_t i830_read_entry(unsigned int entry, + bool *is_present, bool *is_local) +{ + u32 val; + + val = readl(intel_private.gtt + entry); + + *is_present = val & I810_PTE_VALID; + *is_local = false; + + return val & ~0xfff; +} + bool intel_gmch_enable_gtt(void) { u8 __iomem *reg; @@ -878,6 +905,13 @@ void intel_gmch_gtt_insert_sg_entries(struct sg_table *st, } EXPORT_SYMBOL(intel_gmch_gtt_insert_sg_entries); +dma_addr_t intel_gmch_gtt_read_entry(unsigned int pg, + bool *is_present, bool *is_local) +{ + return intel_private.driver->read_entry(pg, is_present, is_local); +} +EXPORT_SYMBOL(intel_gmch_gtt_read_entry); + #if IS_ENABLED(CONFIG_AGP_INTEL) static void intel_gmch_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries, @@ -1126,6 +1160,19 @@ static void i965_write_entry(dma_addr_t addr, writel_relaxed(addr | pte_flags, intel_private.gtt + entry); } +static dma_addr_t i965_read_entry(unsigned int entry, + bool *is_present, bool *is_local) +{ + u64 val; + + val = readl(intel_private.gtt + entry); + + *is_present = val & I810_PTE_VALID; + *is_local = false; + + return ((val & 0xf0) << 28) | (val & ~0xfff); +} + static int i9xx_setup(void) { phys_addr_t reg_addr; @@ -1187,6 +1234,7 @@ static const struct intel_gtt_driver i81x_gtt_driver = { .cleanup = i810_cleanup, .check_flags = i830_check_flags, .write_entry = i810_write_entry, + .read_entry = i810_read_entry, }; static const struct intel_gtt_driver i8xx_gtt_driver = { .gen = 2, @@ -1194,6 +1242,7 @@ static const struct intel_gtt_driver i8xx_gtt_driver = { .setup = i830_setup, .cleanup = i830_cleanup, .write_entry = i830_write_entry, + .read_entry = i830_read_entry, .dma_mask_size = 32, .check_flags = i830_check_flags, .chipset_flush = i830_chipset_flush, @@ -1205,6 +1254,7 @@ static const struct intel_gtt_driver i915_gtt_driver = { .cleanup = i9xx_cleanup, /* i945 is the last gpu to need phys mem (for overlay and cursors). */ .write_entry = i830_write_entry, + .read_entry = i830_read_entry, .dma_mask_size = 32, .check_flags = i830_check_flags, .chipset_flush = i9xx_chipset_flush, @@ -1215,6 +1265,7 @@ static const struct intel_gtt_driver g33_gtt_driver = { .setup = i9xx_setup, .cleanup = i9xx_cleanup, .write_entry = i965_write_entry, + .read_entry = i965_read_entry, .dma_mask_size = 36, .check_flags = i830_check_flags, .chipset_flush = i9xx_chipset_flush, @@ -1225,6 +1276,7 @@ static const struct intel_gtt_driver pineview_gtt_driver = { .setup = i9xx_setup, .cleanup = i9xx_cleanup, .write_entry = i965_write_entry, + .read_entry = i965_read_entry, .dma_mask_size = 36, .check_flags = i830_check_flags, .chipset_flush = i9xx_chipset_flush, @@ -1235,6 +1287,7 @@ static const struct intel_gtt_driver i965_gtt_driver = { .setup = i9xx_setup, .cleanup = i9xx_cleanup, .write_entry = i965_write_entry, + .read_entry = i965_read_entry, .dma_mask_size = 36, .check_flags = i830_check_flags, .chipset_flush = i9xx_chipset_flush, @@ -1244,6 +1297,7 @@ static const struct intel_gtt_driver g4x_gtt_driver = { .setup = i9xx_setup, .cleanup = i9xx_cleanup, .write_entry = i965_write_entry, + .read_entry = i965_read_entry, .dma_mask_size = 36, .check_flags = i830_check_flags, .chipset_flush = i9xx_chipset_flush, @@ -1254,6 +1308,7 @@ static const struct intel_gtt_driver ironlake_gtt_driver = { .setup = i9xx_setup, .cleanup = i9xx_cleanup, .write_entry = i965_write_entry, + .read_entry = i965_read_entry, .dma_mask_size = 36, .check_flags = i830_check_flags, .chipset_flush = i9xx_chipset_flush, diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 2fa2c9135eac35..7eee3eb47a8ee8 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -392,7 +392,7 @@ static long udmabuf_create(struct miscdevice *device, if (!ubuf) return -ENOMEM; - pglimit = (size_limit_mb * 1024 * 1024) >> PAGE_SHIFT; + pglimit = ((u64)size_limit_mb * 1024 * 1024) >> PAGE_SHIFT; for (i = 0; i < head->count; i++) { pgoff_t subpgcnt; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 6d83ccfa42eeb0..2c04ae13384845 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -353,7 +353,6 @@ enum amdgpu_kiq_irq { AMDGPU_CP_KIQ_IRQ_DRIVER0 = 0, AMDGPU_CP_KIQ_IRQ_LAST }; -#define SRIOV_USEC_TIMEOUT 1200000 /* wait 12 * 100ms for SRIOV */ #define MAX_KIQ_REG_WAIT 5000 /* in usecs, 5ms */ #define MAX_KIQ_REG_BAILOUT_INTERVAL 5 /* in msecs, 5ms */ #define MAX_KIQ_REG_TRY 1000 diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index a30111d2c3ea0e..b34b915203f250 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3643,6 +3643,13 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev) adev, adev->ip_blocks[i].version->type)) continue; + /* Since we skip suspend for S0i3, we need to cancel the delayed + * idle work here as the suspend callback never gets called. + */ + if (adev->in_s0ix && + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX && + amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(10, 0, 0)) + cancel_delayed_work_sync(&adev->gfx.idle_work); /* skip suspend of gfx/mes and psp for S0ix * gfx is in gfxoff state, so on resume it will exit gfxoff just * like at runtime. PSP is also part of the always on hardware diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c index dc2713ec95a5bd..9e738fae2b74f1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -120,6 +120,8 @@ MODULE_FIRMWARE("amdgpu/vega20_ip_discovery.bin"); MODULE_FIRMWARE("amdgpu/raven_ip_discovery.bin"); MODULE_FIRMWARE("amdgpu/raven2_ip_discovery.bin"); MODULE_FIRMWARE("amdgpu/picasso_ip_discovery.bin"); +MODULE_FIRMWARE("amdgpu/arcturus_ip_discovery.bin"); +MODULE_FIRMWARE("amdgpu/aldebaran_ip_discovery.bin"); #define mmIP_DISCOVERY_VERSION 0x16A00 #define mmRCC_CONFIG_MEMSIZE 0xde3 diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index 9f627caedc3f61..667080cc9ae1c1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -75,11 +75,25 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, */ static int amdgpu_dma_buf_pin(struct dma_buf_attachment *attach) { - struct drm_gem_object *obj = attach->dmabuf->priv; - struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); + struct dma_buf *dmabuf = attach->dmabuf; + struct amdgpu_bo *bo = gem_to_amdgpu_bo(dmabuf->priv); + u32 domains = bo->preferred_domains; - /* pin buffer into GTT */ - return amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT); + dma_resv_assert_held(dmabuf->resv); + + /* + * Try pinning into VRAM to allow P2P with RDMA NICs without ODP + * support if all attachments can do P2P. If any attachment can't do + * P2P just pin into GTT instead. + */ + list_for_each_entry(attach, &dmabuf->attachments, node) + if (!attach->peer2peer) + domains &= ~AMDGPU_GEM_DOMAIN_VRAM; + + if (domains & AMDGPU_GEM_DOMAIN_VRAM) + bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; + + return amdgpu_bo_pin(bo, domains); } /** @@ -134,9 +148,6 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach, r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); if (r) return ERR_PTR(r); - - } else if (bo->tbo.resource->mem_type != TTM_PL_TT) { - return ERR_PTR(-EBUSY); } switch (bo->tbo.resource->mem_type) { @@ -184,7 +195,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach, struct sg_table *sgt, enum dma_data_direction dir) { - if (sgt->sgl->page_link) { + if (sg_page(sgt->sgl)) { dma_unmap_sgtable(attach->dev, sgt, dir, 0); sg_free_table(sgt); kfree(sgt); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 464625282872aa..ecb74ccf1d9081 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -699,12 +699,10 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid, uint32_t flush_type, bool all_hub, uint32_t inst) { - u32 usec_timeout = amdgpu_sriov_vf(adev) ? SRIOV_USEC_TIMEOUT : - adev->usec_timeout; struct amdgpu_ring *ring = &adev->gfx.kiq[inst].ring; struct amdgpu_kiq *kiq = &adev->gfx.kiq[inst]; unsigned int ndw; - int r; + int r, cnt = 0; uint32_t seq; /* @@ -761,10 +759,21 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid, amdgpu_ring_commit(ring); spin_unlock(&adev->gfx.kiq[inst].ring_lock); - if (amdgpu_fence_wait_polling(ring, seq, usec_timeout) < 1) { + + r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); + + might_sleep(); + while (r < 1 && cnt++ < MAX_KIQ_REG_TRY && + !amdgpu_reset_pending(adev->reset_domain)) { + msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); + r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); + } + + if (cnt > MAX_KIQ_REG_TRY) { dev_err(adev->dev, "timeout waiting for kiq fence\n"); r = -ETIME; - } + } else + r = 0; } error_unlock_reset: diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 80cd6f5273db3a..0b9987781f7622 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -163,8 +163,8 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain) * When GTT is just an alternative to VRAM make sure that we * only use it as fallback and still try to fill up VRAM first. */ - if (domain & abo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM && - !(adev->flags & AMD_IS_APU)) + if (abo->tbo.resource && !(adev->flags & AMD_IS_APU) && + domain & abo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) places[c].flags |= TTM_PL_FLAG_FALLBACK; c++; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c index 6da8994e0469af..2d7f82e98df92c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -24,6 +24,7 @@ #include #include +#include #include "amdgpu.h" #include "amdgpu_vm.h" @@ -907,6 +908,9 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev) struct ttm_resource_manager *man = &mgr->manager; int err; + man->cg = drmm_cgroup_register_region(adev_to_drm(adev), "vram", adev->gmc.real_vram_size); + if (IS_ERR(man->cg)) + return PTR_ERR(man->cg); ttm_resource_manager_init(man, &adev->mman.bdev, adev->gmc.real_vram_size); diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c index e65916ada23b32..ef9538fbbf5371 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c @@ -894,6 +894,10 @@ static void mes_v11_0_get_fw_version(struct amdgpu_device *adev) { int pipe; + /* return early if we have already fetched these */ + if (adev->mes.sched_version && adev->mes.kiq_version) + return; + /* get MES scheduler/KIQ versions */ mutex_lock(&adev->srbm_mutex); diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c index 183dd3346da576..e6ab617b9a4041 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c @@ -1392,17 +1392,20 @@ static int mes_v12_0_queue_init(struct amdgpu_device *adev, mes_v12_0_queue_init_register(ring); } - /* get MES scheduler/KIQ versions */ - mutex_lock(&adev->srbm_mutex); - soc21_grbm_select(adev, 3, pipe, 0, 0); + if (((pipe == AMDGPU_MES_SCHED_PIPE) && !adev->mes.sched_version) || + ((pipe == AMDGPU_MES_KIQ_PIPE) && !adev->mes.kiq_version)) { + /* get MES scheduler/KIQ versions */ + mutex_lock(&adev->srbm_mutex); + soc21_grbm_select(adev, 3, pipe, 0, 0); - if (pipe == AMDGPU_MES_SCHED_PIPE) - adev->mes.sched_version = RREG32_SOC15(GC, 0, regCP_MES_GP3_LO); - else if (pipe == AMDGPU_MES_KIQ_PIPE && adev->enable_mes_kiq) - adev->mes.kiq_version = RREG32_SOC15(GC, 0, regCP_MES_GP3_LO); + if (pipe == AMDGPU_MES_SCHED_PIPE) + adev->mes.sched_version = RREG32_SOC15(GC, 0, regCP_MES_GP3_LO); + else if (pipe == AMDGPU_MES_KIQ_PIPE && adev->enable_mes_kiq) + adev->mes.kiq_version = RREG32_SOC15(GC, 0, regCP_MES_GP3_LO); - soc21_grbm_select(adev, 0, 0, 0, 0); - mutex_unlock(&adev->srbm_mutex); + soc21_grbm_select(adev, 0, 0, 0, 0); + mutex_unlock(&adev->srbm_mutex); + } return 0; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index e477d7509646aa..9bbee484d57cc4 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -1983,9 +1983,6 @@ static void kfd_topology_set_capabilities(struct kfd_topology_device *dev) if (kfd_dbg_has_ttmps_always_setup(dev->gpu)) dev->node_props.debug_prop |= HSA_DBG_DISPATCH_INFO_ALWAYS_VALID; - if (dev->gpu->adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE) - dev->node_props.capability2 |= HSA_CAP2_PER_SDMA_QUEUE_RESET_SUPPORTED; - if (KFD_GC_VERSION(dev->gpu) < IP_VERSION(10, 0, 0)) { if (KFD_GC_VERSION(dev->gpu) == IP_VERSION(9, 4, 3) || KFD_GC_VERSION(dev->gpu) == IP_VERSION(9, 4, 4)) @@ -2001,7 +1998,11 @@ static void kfd_topology_set_capabilities(struct kfd_topology_device *dev) dev->node_props.capability |= HSA_CAP_TRAP_DEBUG_PRECISE_MEMORY_OPERATIONS_SUPPORTED; - dev->node_props.capability |= HSA_CAP_PER_QUEUE_RESET_SUPPORTED; + if (!amdgpu_sriov_vf(dev->gpu->adev)) + dev->node_props.capability |= HSA_CAP_PER_QUEUE_RESET_SUPPORTED; + + if (dev->gpu->adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE) + dev->node_props.capability2 |= HSA_CAP2_PER_SDMA_QUEUE_RESET_SUPPORTED; } else { dev->node_props.debug_prop |= HSA_DBG_WATCH_ADDR_MASK_LO_BIT_GFX10 | HSA_DBG_WATCH_ADDR_MASK_HI_BIT; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index d0d8ad5368c3f3..9fed4471405f89 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1722,6 +1722,13 @@ static const struct dmi_system_id dmi_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite mt645 G8 Mobile Thin Client"), }, }, + { + .callback = edp0_on_dp1_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 645 14 inch G11 Notebook PC"), + }, + }, { .callback = edp0_on_dp1_callback, .matches = { @@ -1729,6 +1736,20 @@ static const struct dmi_system_id dmi_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 665 16 inch G11 Notebook PC"), }, }, + { + .callback = edp0_on_dp1_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook 445 14 inch G11 Notebook PC"), + }, + }, + { + .callback = edp0_on_dp1_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook 465 16 inch G11 Notebook PC"), + }, + }, {} /* TODO: refactor this from a fixed table to a dynamic option */ }; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index 36a830a7440f10..e8bdd7f0c46079 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -113,6 +113,7 @@ bool amdgpu_dm_crtc_vrr_active(const struct dm_crtc_state *dm_state) * * Panel Replay and PSR SU * - Enable when: + * - VRR is disabled * - vblank counter is disabled * - entry is allowed: usermode demonstrates an adequate number of fast * commits) @@ -131,19 +132,20 @@ static void amdgpu_dm_crtc_set_panel_sr_feature( bool is_sr_active = (link->replay_settings.replay_allow_active || link->psr_settings.psr_allow_active); bool is_crc_window_active = false; + bool vrr_active = amdgpu_dm_crtc_vrr_active_irq(vblank_work->acrtc); #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY is_crc_window_active = amdgpu_dm_crc_window_is_activated(&vblank_work->acrtc->base); #endif - if (link->replay_settings.replay_feature_enabled && + if (link->replay_settings.replay_feature_enabled && !vrr_active && allow_sr_entry && !is_sr_active && !is_crc_window_active) { amdgpu_dm_replay_enable(vblank_work->stream, true); } else if (vblank_enabled) { if (link->psr_settings.psr_version < DC_PSR_VERSION_SU_1 && is_sr_active) amdgpu_dm_psr_disable(vblank_work->stream, false); - } else if (link->psr_settings.psr_feature_enabled && + } else if (link->psr_settings.psr_feature_enabled && !vrr_active && allow_sr_entry && !is_sr_active && !is_crc_window_active) { struct amdgpu_dm_connector *aconn = @@ -244,6 +246,8 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work) struct vblank_control_work *vblank_work = container_of(work, struct vblank_control_work, work); struct amdgpu_display_manager *dm = vblank_work->dm; + struct amdgpu_device *adev = drm_to_adev(dm->ddev); + int r; mutex_lock(&dm->dc_lock); @@ -271,8 +275,15 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work) vblank_work->acrtc->dm_irq_params.allow_sr_entry); } - if (dm->active_vblank_irq_count == 0) + if (dm->active_vblank_irq_count == 0) { + r = amdgpu_dpm_pause_power_profile(adev, true); + if (r) + dev_warn(adev->dev, "failed to set default power profile mode\n"); dc_allow_idle_optimizations(dm->dc, true); + r = amdgpu_dpm_pause_power_profile(adev, false); + if (r) + dev_warn(adev->dev, "failed to restore the power profile mode\n"); + } mutex_unlock(&dm->dc_lock); diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c index be54f0e696ce28..94e99e540691cf 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c @@ -86,6 +86,8 @@ static void dml21_init(const struct dc *in_dc, struct dml2_context **dml_ctx, co /* Store configuration options */ (*dml_ctx)->config = *config; + DC_FP_START(); + /*Initialize SOCBB and DCNIP params */ dml21_initialize_soc_bb_params(&(*dml_ctx)->v21.dml_init, config, in_dc); dml21_initialize_ip_params(&(*dml_ctx)->v21.dml_init, config, in_dc); @@ -96,6 +98,8 @@ static void dml21_init(const struct dc *in_dc, struct dml2_context **dml_ctx, co /*Initialize DML21 instance */ dml2_initialize_instance(&(*dml_ctx)->v21.dml_init); + + DC_FP_END(); } bool dml21_create(const struct dc *in_dc, struct dml2_context **dml_ctx, const struct dml2_configuration_options *config) @@ -283,11 +287,16 @@ bool dml21_validate(const struct dc *in_dc, struct dc_state *context, struct dml { bool out = false; + DC_FP_START(); + /* Use dml_validate_only for fast_validate path */ - if (fast_validate) { + if (fast_validate) out = dml21_check_mode_support(in_dc, context, dml_ctx); - } else + else out = dml21_mode_check_and_programming(in_dc, context, dml_ctx); + + DC_FP_END(); + return out; } @@ -426,8 +435,12 @@ void dml21_copy(struct dml2_context *dst_dml_ctx, dst_dml_ctx->v21.mode_programming.programming = dst_dml2_programming; + DC_FP_START(); + /* need to initialize copied instance for internal references to be correct */ dml2_initialize_instance(&dst_dml_ctx->v21.dml_init); + + DC_FP_END(); } bool dml21_create_copy(struct dml2_context **dst_dml_ctx, diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c index 939ee0708bd23b..f549a778f6f1a9 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c @@ -732,11 +732,16 @@ bool dml2_validate(const struct dc *in_dc, struct dc_state *context, struct dml2 return out; } + DC_FP_START(); + /* Use dml_validate_only for fast_validate path */ if (fast_validate) out = dml2_validate_only(context); else out = dml2_validate_and_build_resource(in_dc, context); + + DC_FP_END(); + return out; } @@ -779,11 +784,15 @@ static void dml2_init(const struct dc *in_dc, const struct dml2_configuration_op break; } + DC_FP_START(); + initialize_dml2_ip_params(*dml2, in_dc, &(*dml2)->v20.dml_core_ctx.ip); initialize_dml2_soc_bbox(*dml2, in_dc, &(*dml2)->v20.dml_core_ctx.soc); initialize_dml2_soc_states(*dml2, in_dc, &(*dml2)->v20.dml_core_ctx.soc, &(*dml2)->v20.dml_core_ctx.states); + + DC_FP_END(); } bool dml2_create(const struct dc *in_dc, const struct dml2_configuration_options *config, struct dml2_context **dml2) diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 2a9606118d8994..21dc956b5f35d4 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -429,6 +429,7 @@ struct amd_pm_funcs { int (*set_pp_table)(void *handle, const char *buf, size_t size); void (*debugfs_print_current_performance_level)(void *handle, struct seq_file *m); int (*switch_power_profile)(void *handle, enum PP_SMC_POWER_PROFILE type, bool en); + int (*pause_power_profile)(void *handle, bool pause); /* export to amdgpu */ struct amd_vce_state *(*get_vce_clock_state)(void *handle, u32 idx); int (*dispatch_tasks)(void *handle, enum amd_pp_task task_id, diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c index 81e9b443ca0adc..3533d43ed1e73d 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -349,6 +349,25 @@ int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev, return ret; } +int amdgpu_dpm_pause_power_profile(struct amdgpu_device *adev, + bool pause) +{ + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; + int ret = 0; + + if (amdgpu_sriov_vf(adev)) + return 0; + + if (pp_funcs && pp_funcs->pause_power_profile) { + mutex_lock(&adev->pm.mutex); + ret = pp_funcs->pause_power_profile( + adev->powerplay.pp_handle, pause); + mutex_unlock(&adev->pm.mutex); + } + + return ret; +} + int amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device *adev, uint32_t pstate) { diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h index f93d287dbf1376..4c0f7ad1481661 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h @@ -410,6 +410,8 @@ int amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device *adev, int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev, enum PP_SMC_POWER_PROFILE type, bool en); +int amdgpu_dpm_pause_power_profile(struct amdgpu_device *adev, + bool pause); int amdgpu_dpm_baco_reset(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 033c3229b555f0..46cce1d2aaf357 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -2398,7 +2398,11 @@ static int smu_switch_power_profile(void *handle, smu_power_profile_mode_get(smu, type); else smu_power_profile_mode_put(smu, type); - ret = smu_bump_power_profile_mode(smu, NULL, 0); + /* don't switch the active workload when paused */ + if (smu->pause_workload) + ret = 0; + else + ret = smu_bump_power_profile_mode(smu, NULL, 0); if (ret) { if (enable) smu_power_profile_mode_put(smu, type); @@ -2411,6 +2415,35 @@ static int smu_switch_power_profile(void *handle, return 0; } +static int smu_pause_power_profile(void *handle, + bool pause) +{ + struct smu_context *smu = handle; + struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); + u32 workload_mask = 1 << PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; + int ret; + + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) + return -EOPNOTSUPP; + + if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL && + smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) { + smu->pause_workload = pause; + + /* force to bootup default profile */ + if (smu->pause_workload && smu->ppt_funcs->set_power_profile_mode) + ret = smu->ppt_funcs->set_power_profile_mode(smu, + workload_mask, + NULL, + 0); + else + ret = smu_bump_power_profile_mode(smu, NULL, 0); + return ret; + } + + return 0; +} + static enum amd_dpm_forced_level smu_get_performance_level(void *handle) { struct smu_context *smu = handle; @@ -3733,6 +3766,7 @@ static const struct amd_pm_funcs swsmu_pm_funcs = { .get_pp_table = smu_sys_get_pp_table, .set_pp_table = smu_sys_set_pp_table, .switch_power_profile = smu_switch_power_profile, + .pause_power_profile = smu_pause_power_profile, /* export to amdgpu */ .dispatch_tasks = smu_handle_dpm_task, .load_firmware = smu_load_microcode, diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h index 3ba169639f5460..dd6d0e7aa2425d 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -558,6 +558,7 @@ struct smu_context { /* asic agnostic workload mask */ uint32_t workload_mask; + bool pause_workload; /* default/user workload preference */ uint32_t power_profile_mode; uint32_t workload_refcount[PP_SMC_POWER_PROFILE_COUNT]; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c index 78391d8f35a9cb..25fabf336a6401 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c @@ -1204,7 +1204,7 @@ int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu, uint32_t crystal_clock_freq = 2500; uint32_t tach_period; - if (speed == 0) + if (!speed || speed > UINT_MAX/8) return -EINVAL; /* * To prevent from possible overheat, some ASICs may have requirement diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c index 38431e8360e783..40a56f38ff8e0b 100644 --- a/drivers/gpu/drm/drm_gpusvm.c +++ b/drivers/gpu/drm/drm_gpusvm.c @@ -1454,6 +1454,11 @@ int drm_gpusvm_range_get_pages(struct drm_gpusvm *gpusvm, goto err_unmap; } + if (ctx->devmem_only) { + err = -EFAULT; + goto err_unmap; + } + addr = dma_map_page(gpusvm->drm->dev, page, 0, PAGE_SIZE << order, @@ -1765,6 +1770,8 @@ int drm_gpusvm_migrate_to_devmem(struct drm_gpusvm *gpusvm, goto err_finalize; /* Upon success bind devmem allocation to range and zdd */ + devmem_allocation->timeslice_expiration = get_jiffies_64() + + msecs_to_jiffies(ctx->timeslice_ms); zdd->devmem_allocation = devmem_allocation; /* Owns ref */ err_finalize: @@ -1985,6 +1992,13 @@ static int __drm_gpusvm_migrate_to_ram(struct vm_area_struct *vas, void *buf; int i, err = 0; + if (page) { + zdd = page->zone_device_data; + if (time_before64(get_jiffies_64(), + zdd->devmem_allocation->timeslice_expiration)) + return 0; + } + start = ALIGN_DOWN(fault_addr, size); end = ALIGN(fault_addr + 1, size); diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index ed05b131ed3abb..c8fc271b33b773 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -247,6 +247,7 @@ i915-y += \ display/intel_display_power_map.o \ display/intel_display_power_well.o \ display/intel_display_reset.o \ + display/intel_display_rpm.o \ display/intel_display_rps.o \ display/intel_display_snapshot.o \ display/intel_display_wa.o \ diff --git a/drivers/gpu/drm/i915/display/dvo_ch7017.c b/drivers/gpu/drm/i915/display/dvo_ch7017.c index 206818f9ad49e6..f10c0fb8d2c89c 100644 --- a/drivers/gpu/drm/i915/display/dvo_ch7017.c +++ b/drivers/gpu/drm/i915/display/dvo_ch7017.c @@ -25,6 +25,8 @@ * */ +#include + #include "intel_display_types.h" #include "intel_dvo_dev.h" diff --git a/drivers/gpu/drm/i915/display/dvo_ch7xxx.c b/drivers/gpu/drm/i915/display/dvo_ch7xxx.c index 10ab3cc73e5864..49f02aca818bb8 100644 --- a/drivers/gpu/drm/i915/display/dvo_ch7xxx.c +++ b/drivers/gpu/drm/i915/display/dvo_ch7xxx.c @@ -26,6 +26,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +#include + #include "intel_display_types.h" #include "intel_dvo_dev.h" diff --git a/drivers/gpu/drm/i915/display/dvo_ivch.c b/drivers/gpu/drm/i915/display/dvo_ivch.c index d9c3152d4338fb..0713b27094124b 100644 --- a/drivers/gpu/drm/i915/display/dvo_ivch.c +++ b/drivers/gpu/drm/i915/display/dvo_ivch.c @@ -29,6 +29,8 @@ * */ +#include + #include "intel_display_types.h" #include "intel_dvo_dev.h" diff --git a/drivers/gpu/drm/i915/display/dvo_ns2501.c b/drivers/gpu/drm/i915/display/dvo_ns2501.c index 92d32d6b5bceba..80b71bd6a83719 100644 --- a/drivers/gpu/drm/i915/display/dvo_ns2501.c +++ b/drivers/gpu/drm/i915/display/dvo_ns2501.c @@ -26,6 +26,8 @@ * */ +#include + #include "intel_display_types.h" #include "intel_dvo_dev.h" diff --git a/drivers/gpu/drm/i915/display/dvo_sil164.c b/drivers/gpu/drm/i915/display/dvo_sil164.c index b42c717085f316..017b617a8069e0 100644 --- a/drivers/gpu/drm/i915/display/dvo_sil164.c +++ b/drivers/gpu/drm/i915/display/dvo_sil164.c @@ -26,6 +26,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +#include + #include "intel_display_types.h" #include "intel_dvo_dev.h" diff --git a/drivers/gpu/drm/i915/display/dvo_tfp410.c b/drivers/gpu/drm/i915/display/dvo_tfp410.c index 28069943852679..ed560e3438db98 100644 --- a/drivers/gpu/drm/i915/display/dvo_tfp410.c +++ b/drivers/gpu/drm/i915/display/dvo_tfp410.c @@ -25,6 +25,8 @@ * */ +#include + #include "intel_display_types.h" #include "intel_dvo_dev.h" diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 55b9e9bfcc4d06..b39aae9165df61 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -519,7 +519,7 @@ static void intel_disable_dp(struct intel_atomic_state *state, { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - intel_dp->link_trained = false; + intel_dp->link.active = false; /* * Make sure the panel is off before trying to change the mode. diff --git a/drivers/gpu/drm/i915/display/hsw_ips.c b/drivers/gpu/drm/i915/display/hsw_ips.c index 674a0e5f085840..4307e2ed03d949 100644 --- a/drivers/gpu/drm/i915/display/hsw_ips.c +++ b/drivers/gpu/drm/i915/display/hsw_ips.c @@ -10,6 +10,7 @@ #include "i915_reg.h" #include "intel_color_regs.h" #include "intel_de.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_pcode.h" @@ -344,10 +345,9 @@ static int hsw_ips_debugfs_status_show(struct seq_file *m, void *unused) { struct intel_crtc *crtc = m->private; struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); seq_printf(m, "Enabled by kernel parameter: %s\n", str_yes_no(display->params.enable_ips)); @@ -361,7 +361,7 @@ static int hsw_ips_debugfs_status_show(struct seq_file *m, void *unused) seq_puts(m, "Currently: disabled\n"); } - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return 0; } diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 013295f66d56ec..5e8344fdfc28a3 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -630,84 +630,92 @@ vlv_primary_async_flip(struct intel_dsb *dsb, static void bdw_primary_enable_flip_done(struct intel_plane *plane) { + struct intel_display *display = to_intel_display(plane); struct drm_i915_private *i915 = to_i915(plane->base.dev); enum pipe pipe = plane->pipe; spin_lock_irq(&i915->irq_lock); - bdw_enable_pipe_irq(i915, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); + bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); spin_unlock_irq(&i915->irq_lock); } static void bdw_primary_disable_flip_done(struct intel_plane *plane) { + struct intel_display *display = to_intel_display(plane); struct drm_i915_private *i915 = to_i915(plane->base.dev); enum pipe pipe = plane->pipe; spin_lock_irq(&i915->irq_lock); - bdw_disable_pipe_irq(i915, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); + bdw_disable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); spin_unlock_irq(&i915->irq_lock); } static void ivb_primary_enable_flip_done(struct intel_plane *plane) { + struct intel_display *display = to_intel_display(plane); struct drm_i915_private *i915 = to_i915(plane->base.dev); spin_lock_irq(&i915->irq_lock); - ilk_enable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); + ilk_enable_display_irq(display, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); spin_unlock_irq(&i915->irq_lock); } static void ivb_primary_disable_flip_done(struct intel_plane *plane) { + struct intel_display *display = to_intel_display(plane); struct drm_i915_private *i915 = to_i915(plane->base.dev); spin_lock_irq(&i915->irq_lock); - ilk_disable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); + ilk_disable_display_irq(display, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); spin_unlock_irq(&i915->irq_lock); } static void ilk_primary_enable_flip_done(struct intel_plane *plane) { + struct intel_display *display = to_intel_display(plane); struct drm_i915_private *i915 = to_i915(plane->base.dev); spin_lock_irq(&i915->irq_lock); - ilk_enable_display_irq(i915, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); + ilk_enable_display_irq(display, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); spin_unlock_irq(&i915->irq_lock); } static void ilk_primary_disable_flip_done(struct intel_plane *plane) { + struct intel_display *display = to_intel_display(plane); struct drm_i915_private *i915 = to_i915(plane->base.dev); spin_lock_irq(&i915->irq_lock); - ilk_disable_display_irq(i915, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); + ilk_disable_display_irq(display, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); spin_unlock_irq(&i915->irq_lock); } static void vlv_primary_enable_flip_done(struct intel_plane *plane) { + struct intel_display *display = to_intel_display(plane); struct drm_i915_private *i915 = to_i915(plane->base.dev); enum pipe pipe = plane->pipe; spin_lock_irq(&i915->irq_lock); - i915_enable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); + i915_enable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); spin_unlock_irq(&i915->irq_lock); } static void vlv_primary_disable_flip_done(struct intel_plane *plane) { + struct intel_display *display = to_intel_display(plane); struct drm_i915_private *i915 = to_i915(plane->base.dev); enum pipe pipe = plane->pipe; spin_lock_irq(&i915->irq_lock); - i915_disable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); + i915_disable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); spin_unlock_irq(&i915->irq_lock); } diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 7c80e37c1c5f7f..40751f1547b76e 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -9,6 +9,7 @@ #include "i9xx_wm_regs.h" #include "intel_atomic.h" #include "intel_bo.h" +#include "intel_de.h" #include "intel_display.h" #include "intel_display_trace.h" #include "intel_fb.h" @@ -81,13 +82,14 @@ static const struct cxsr_latency cxsr_latency_table[] = { {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ }; -static const struct cxsr_latency *pnv_get_cxsr_latency(struct drm_i915_private *i915) +static const struct cxsr_latency *pnv_get_cxsr_latency(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); int i; for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { const struct cxsr_latency *latency = &cxsr_latency_table[i]; - bool is_desktop = !IS_MOBILE(i915); + bool is_desktop = !display->platform.mobile; if (is_desktop == latency->is_desktop && i915->is_ddr3 == latency->is_ddr3 && @@ -96,15 +98,16 @@ static const struct cxsr_latency *pnv_get_cxsr_latency(struct drm_i915_private * return latency; } - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Could not find CxSR latency for DDR%s, FSB %u kHz, MEM %u kHz\n", i915->is_ddr3 ? "3" : "2", i915->fsb_freq, i915->mem_freq); return NULL; } -static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable) +static void chv_set_memory_dvfs(struct intel_display *display, bool enable) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 val; vlv_punit_get(dev_priv); @@ -120,14 +123,15 @@ static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable) if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) & FORCE_DDR_FREQ_REQ_ACK) == 0, 3)) - drm_err(&dev_priv->drm, + drm_err(display->drm, "timed out waiting for Punit DDR DVFS request\n"); vlv_punit_put(dev_priv); } -static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable) +static void chv_set_memory_pm5(struct intel_display *display, bool enable) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 val; vlv_punit_get(dev_priv); @@ -145,53 +149,52 @@ static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable) #define FW_WM(value, plane) \ (((value) << DSPFW_ ## plane ## _SHIFT) & DSPFW_ ## plane ## _MASK) -static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) +static bool _intel_set_memory_cxsr(struct intel_display *display, bool enable) { - struct intel_display *display = &dev_priv->display; bool was_enabled; u32 val; - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - was_enabled = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; - intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0); - intel_uncore_posting_read(&dev_priv->uncore, FW_BLC_SELF_VLV); - } else if (IS_G4X(dev_priv) || IS_I965GM(dev_priv)) { - was_enabled = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF) & FW_BLC_SELF_EN; - intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0); - intel_uncore_posting_read(&dev_priv->uncore, FW_BLC_SELF); - } else if (IS_PINEVIEW(dev_priv)) { - val = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv)); + if (display->platform.valleyview || display->platform.cherryview) { + was_enabled = intel_de_read(display, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; + intel_de_write(display, FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0); + intel_de_posting_read(display, FW_BLC_SELF_VLV); + } else if (display->platform.g4x || display->platform.i965gm) { + was_enabled = intel_de_read(display, FW_BLC_SELF) & FW_BLC_SELF_EN; + intel_de_write(display, FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0); + intel_de_posting_read(display, FW_BLC_SELF); + } else if (display->platform.pineview) { + val = intel_de_read(display, DSPFW3(display)); was_enabled = val & PINEVIEW_SELF_REFRESH_EN; if (enable) val |= PINEVIEW_SELF_REFRESH_EN; else val &= ~PINEVIEW_SELF_REFRESH_EN; - intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), val); - intel_uncore_posting_read(&dev_priv->uncore, DSPFW3(dev_priv)); - } else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv)) { - was_enabled = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF) & FW_BLC_SELF_EN; + intel_de_write(display, DSPFW3(display), val); + intel_de_posting_read(display, DSPFW3(display)); + } else if (display->platform.i945g || display->platform.i945gm) { + was_enabled = intel_de_read(display, FW_BLC_SELF) & FW_BLC_SELF_EN; val = enable ? _MASKED_BIT_ENABLE(FW_BLC_SELF_EN) : _MASKED_BIT_DISABLE(FW_BLC_SELF_EN); - intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, val); - intel_uncore_posting_read(&dev_priv->uncore, FW_BLC_SELF); - } else if (IS_I915GM(dev_priv)) { + intel_de_write(display, FW_BLC_SELF, val); + intel_de_posting_read(display, FW_BLC_SELF); + } else if (display->platform.i915gm) { /* * FIXME can't find a bit like this for 915G, and * yet it does have the related watermark in * FW_BLC_SELF. What's going on? */ - was_enabled = intel_uncore_read(&dev_priv->uncore, INSTPM) & INSTPM_SELF_EN; + was_enabled = intel_de_read(display, INSTPM) & INSTPM_SELF_EN; val = enable ? _MASKED_BIT_ENABLE(INSTPM_SELF_EN) : _MASKED_BIT_DISABLE(INSTPM_SELF_EN); - intel_uncore_write(&dev_priv->uncore, INSTPM, val); - intel_uncore_posting_read(&dev_priv->uncore, INSTPM); + intel_de_write(display, INSTPM, val); + intel_de_posting_read(display, INSTPM); } else { return false; } trace_intel_memory_cxsr(display, was_enabled, enable); - drm_dbg_kms(&dev_priv->drm, "memory self-refresh is %s (was %s)\n", + drm_dbg_kms(display->drm, "memory self-refresh is %s (was %s)\n", str_enabled_disabled(enable), str_enabled_disabled(was_enabled)); @@ -200,7 +203,7 @@ static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enabl /** * intel_set_memory_cxsr - Configure CxSR state - * @dev_priv: i915 device + * @display: display device * @enable: Allow vs. disallow CxSR * * Allow or disallow the system to enter a special CxSR @@ -235,17 +238,17 @@ static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enabl * the hardware w.r.t. HPLL SR when writing to plane registers. * Disallowing just CxSR is sufficient. */ -bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) +bool intel_set_memory_cxsr(struct intel_display *display, bool enable) { bool ret; - mutex_lock(&dev_priv->display.wm.wm_mutex); - ret = _intel_set_memory_cxsr(dev_priv, enable); - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - dev_priv->display.wm.vlv.cxsr = enable; - else if (IS_G4X(dev_priv)) - dev_priv->display.wm.g4x.cxsr = enable; - mutex_unlock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); + ret = _intel_set_memory_cxsr(display, enable); + if (display->platform.valleyview || display->platform.cherryview) + display->wm.vlv.cxsr = enable; + else if (display->platform.g4x) + display->wm.g4x.cxsr = enable; + mutex_unlock(&display->wm.wm_mutex); return ret; } @@ -271,8 +274,8 @@ static const int pessimal_latency_ns = 5000; static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state; enum pipe pipe = crtc->pipe; int sprite0_start, sprite1_start; @@ -280,22 +283,20 @@ static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state) switch (pipe) { case PIPE_A: - dsparb = intel_uncore_read(&dev_priv->uncore, - DSPARB(dev_priv)); - dsparb2 = intel_uncore_read(&dev_priv->uncore, DSPARB2); + dsparb = intel_de_read(display, DSPARB(display)); + dsparb2 = intel_de_read(display, DSPARB2); sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 0, 0); sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 8, 4); break; case PIPE_B: - dsparb = intel_uncore_read(&dev_priv->uncore, - DSPARB(dev_priv)); - dsparb2 = intel_uncore_read(&dev_priv->uncore, DSPARB2); + dsparb = intel_de_read(display, DSPARB(display)); + dsparb2 = intel_de_read(display, DSPARB2); sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 16, 8); sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 24, 12); break; case PIPE_C: - dsparb2 = intel_uncore_read(&dev_priv->uncore, DSPARB2); - dsparb3 = intel_uncore_read(&dev_priv->uncore, DSPARB3); + dsparb2 = intel_de_read(display, DSPARB2); + dsparb3 = intel_de_read(display, DSPARB3); sprite0_start = VLV_FIFO_START(dsparb3, dsparb2, 0, 16); sprite1_start = VLV_FIFO_START(dsparb3, dsparb2, 8, 20); break; @@ -310,26 +311,26 @@ static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state) fifo_state->plane[PLANE_CURSOR] = 63; } -static int i9xx_get_fifo_size(struct drm_i915_private *dev_priv, +static int i9xx_get_fifo_size(struct intel_display *display, enum i9xx_plane_id i9xx_plane) { - u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB(dev_priv)); + u32 dsparb = intel_de_read(display, DSPARB(display)); int size; size = dsparb & 0x7f; if (i9xx_plane == PLANE_B) size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - size; - drm_dbg_kms(&dev_priv->drm, "FIFO size - (0x%08x) %c: %d\n", + drm_dbg_kms(display->drm, "FIFO size - (0x%08x) %c: %d\n", dsparb, plane_name(i9xx_plane), size); return size; } -static int i830_get_fifo_size(struct drm_i915_private *dev_priv, +static int i830_get_fifo_size(struct intel_display *display, enum i9xx_plane_id i9xx_plane) { - u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB(dev_priv)); + u32 dsparb = intel_de_read(display, DSPARB(display)); int size; size = dsparb & 0x1ff; @@ -337,22 +338,22 @@ static int i830_get_fifo_size(struct drm_i915_private *dev_priv, size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - size; size >>= 1; /* Convert to cachelines */ - drm_dbg_kms(&dev_priv->drm, "FIFO size - (0x%08x) %c: %d\n", + drm_dbg_kms(display->drm, "FIFO size - (0x%08x) %c: %d\n", dsparb, plane_name(i9xx_plane), size); return size; } -static int i845_get_fifo_size(struct drm_i915_private *dev_priv, +static int i845_get_fifo_size(struct intel_display *display, enum i9xx_plane_id i9xx_plane) { - u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB(dev_priv)); + u32 dsparb = intel_de_read(display, DSPARB(display)); int size; size = dsparb & 0x7f; size >>= 2; /* Convert to cachelines */ - drm_dbg_kms(&dev_priv->drm, "FIFO size - (0x%08x) %c: %d\n", + drm_dbg_kms(display->drm, "FIFO size - (0x%08x) %c: %d\n", dsparb, plane_name(i9xx_plane), size); return size; @@ -537,7 +538,7 @@ static unsigned int intel_wm_method2(unsigned int pixel_rate, /** * intel_calculate_wm - calculate watermark level - * @i915: the device + * @display: display device * @pixel_rate: pixel clock * @wm: chip FIFO params * @fifo_size: size of the FIFO buffer @@ -555,7 +556,7 @@ static unsigned int intel_wm_method2(unsigned int pixel_rate, * past the watermark point. If the FIFO drains completely, a FIFO underrun * will occur, and a display engine hang could result. */ -static unsigned int intel_calculate_wm(struct drm_i915_private *i915, +static unsigned int intel_calculate_wm(struct intel_display *display, int pixel_rate, const struct intel_watermark_params *wm, int fifo_size, int cpp, @@ -573,10 +574,10 @@ static unsigned int intel_calculate_wm(struct drm_i915_private *i915, latency_ns / 100); entries = DIV_ROUND_UP(entries, wm->cacheline_size) + wm->guard_size; - drm_dbg_kms(&i915->drm, "FIFO entries required for mode: %d\n", entries); + drm_dbg_kms(display->drm, "FIFO entries required for mode: %d\n", entries); wm_size = fifo_size - entries; - drm_dbg_kms(&i915->drm, "FIFO watermark level: %d\n", wm_size); + drm_dbg_kms(display->drm, "FIFO watermark level: %d\n", wm_size); /* Don't promote wm_size to unsigned... */ if (wm_size > wm->max_wm) @@ -626,11 +627,11 @@ static bool intel_crtc_active(struct intel_crtc *crtc) crtc->config->hw.adjusted_mode.crtc_clock; } -static struct intel_crtc *single_enabled_crtc(struct drm_i915_private *dev_priv) +static struct intel_crtc *single_enabled_crtc(struct intel_display *display) { struct intel_crtc *crtc, *enabled = NULL; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { if (intel_crtc_active(crtc)) { if (enabled) return NULL; @@ -641,21 +642,21 @@ static struct intel_crtc *single_enabled_crtc(struct drm_i915_private *dev_priv) return enabled; } -static void pnv_update_wm(struct drm_i915_private *dev_priv) +static void pnv_update_wm(struct intel_display *display) { struct intel_crtc *crtc; const struct cxsr_latency *latency; u32 reg; unsigned int wm; - latency = pnv_get_cxsr_latency(dev_priv); + latency = pnv_get_cxsr_latency(display); if (!latency) { - drm_dbg_kms(&dev_priv->drm, "Unknown FSB/MEM, disabling CxSR\n"); - intel_set_memory_cxsr(dev_priv, false); + drm_dbg_kms(display->drm, "Unknown FSB/MEM, disabling CxSR\n"); + intel_set_memory_cxsr(display, false); return; } - crtc = single_enabled_crtc(dev_priv); + crtc = single_enabled_crtc(display); if (crtc) { const struct drm_framebuffer *fb = crtc->base.primary->state->fb; @@ -663,47 +664,46 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv) int cpp = fb->format->cpp[0]; /* Display SR */ - wm = intel_calculate_wm(dev_priv, pixel_rate, + wm = intel_calculate_wm(display, pixel_rate, &pnv_display_wm, pnv_display_wm.fifo_size, cpp, latency->display_sr); - reg = intel_uncore_read(&dev_priv->uncore, DSPFW1(dev_priv)); + reg = intel_de_read(display, DSPFW1(display)); reg &= ~DSPFW_SR_MASK; reg |= FW_WM(wm, SR); - intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv), reg); - drm_dbg_kms(&dev_priv->drm, "DSPFW1 register is %x\n", reg); + intel_de_write(display, DSPFW1(display), reg); + drm_dbg_kms(display->drm, "DSPFW1 register is %x\n", reg); /* cursor SR */ - wm = intel_calculate_wm(dev_priv, pixel_rate, + wm = intel_calculate_wm(display, pixel_rate, &pnv_cursor_wm, pnv_display_wm.fifo_size, 4, latency->cursor_sr); - intel_uncore_rmw(&dev_priv->uncore, DSPFW3(dev_priv), - DSPFW_CURSOR_SR_MASK, - FW_WM(wm, CURSOR_SR)); + intel_de_rmw(display, DSPFW3(display), + DSPFW_CURSOR_SR_MASK, FW_WM(wm, CURSOR_SR)); /* Display HPLL off SR */ - wm = intel_calculate_wm(dev_priv, pixel_rate, + wm = intel_calculate_wm(display, pixel_rate, &pnv_display_hplloff_wm, pnv_display_hplloff_wm.fifo_size, cpp, latency->display_hpll_disable); - intel_uncore_rmw(&dev_priv->uncore, DSPFW3(dev_priv), - DSPFW_HPLL_SR_MASK, FW_WM(wm, HPLL_SR)); + intel_de_rmw(display, DSPFW3(display), + DSPFW_HPLL_SR_MASK, FW_WM(wm, HPLL_SR)); /* cursor HPLL off SR */ - wm = intel_calculate_wm(dev_priv, pixel_rate, + wm = intel_calculate_wm(display, pixel_rate, &pnv_cursor_hplloff_wm, pnv_display_hplloff_wm.fifo_size, 4, latency->cursor_hpll_disable); - reg = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv)); + reg = intel_de_read(display, DSPFW3(display)); reg &= ~DSPFW_HPLL_CURSOR_MASK; reg |= FW_WM(wm, HPLL_CURSOR); - intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), reg); - drm_dbg_kms(&dev_priv->drm, "DSPFW3 register is %x\n", reg); + intel_de_write(display, DSPFW3(display), reg); + drm_dbg_kms(display->drm, "DSPFW3 register is %x\n", reg); - intel_set_memory_cxsr(dev_priv, true); + intel_set_memory_cxsr(display, true); } else { - intel_set_memory_cxsr(dev_priv, false); + intel_set_memory_cxsr(display, false); } } @@ -794,53 +794,51 @@ static unsigned int g4x_tlb_miss_wa(int fifo_size, int width, int cpp) return max(0, tlb_miss); } -static void g4x_write_wm_values(struct drm_i915_private *dev_priv, +static void g4x_write_wm_values(struct intel_display *display, const struct g4x_wm_values *wm) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) trace_g4x_wm(intel_crtc_for_pipe(display, pipe), wm); - intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv), - FW_WM(wm->sr.plane, SR) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA)); - intel_uncore_write(&dev_priv->uncore, DSPFW2(dev_priv), - (wm->fbc_en ? DSPFW_FBC_SR_EN : 0) | - FW_WM(wm->sr.fbc, FBC_SR) | - FW_WM(wm->hpll.fbc, FBC_HPLL_SR) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEB) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA)); - intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), - (wm->hpll_en ? DSPFW_HPLL_SR_EN : 0) | - FW_WM(wm->sr.cursor, CURSOR_SR) | - FW_WM(wm->hpll.cursor, HPLL_CURSOR) | - FW_WM(wm->hpll.plane, HPLL_SR)); - - intel_uncore_posting_read(&dev_priv->uncore, DSPFW1(dev_priv)); + intel_de_write(display, DSPFW1(display), + FW_WM(wm->sr.plane, SR) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA)); + intel_de_write(display, DSPFW2(display), + (wm->fbc_en ? DSPFW_FBC_SR_EN : 0) | + FW_WM(wm->sr.fbc, FBC_SR) | + FW_WM(wm->hpll.fbc, FBC_HPLL_SR) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEB) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA)); + intel_de_write(display, DSPFW3(display), + (wm->hpll_en ? DSPFW_HPLL_SR_EN : 0) | + FW_WM(wm->sr.cursor, CURSOR_SR) | + FW_WM(wm->hpll.cursor, HPLL_CURSOR) | + FW_WM(wm->hpll.plane, HPLL_SR)); + + intel_de_posting_read(display, DSPFW1(display)); } #define FW_WM_VLV(value, plane) \ (((value) << DSPFW_ ## plane ## _SHIFT) & DSPFW_ ## plane ## _MASK_VLV) -static void vlv_write_wm_values(struct drm_i915_private *dev_priv, +static void vlv_write_wm_values(struct intel_display *display, const struct vlv_wm_values *wm) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { trace_vlv_wm(intel_crtc_for_pipe(display, pipe), wm); - intel_uncore_write(&dev_priv->uncore, VLV_DDL(pipe), - (wm->ddl[pipe].plane[PLANE_CURSOR] << DDL_CURSOR_SHIFT) | - (wm->ddl[pipe].plane[PLANE_SPRITE1] << DDL_SPRITE_SHIFT(1)) | - (wm->ddl[pipe].plane[PLANE_SPRITE0] << DDL_SPRITE_SHIFT(0)) | - (wm->ddl[pipe].plane[PLANE_PRIMARY] << DDL_PLANE_SHIFT)); + intel_de_write(display, VLV_DDL(pipe), + (wm->ddl[pipe].plane[PLANE_CURSOR] << DDL_CURSOR_SHIFT) | + (wm->ddl[pipe].plane[PLANE_SPRITE1] << DDL_SPRITE_SHIFT(1)) | + (wm->ddl[pipe].plane[PLANE_SPRITE0] << DDL_SPRITE_SHIFT(0)) | + (wm->ddl[pipe].plane[PLANE_PRIMARY] << DDL_PLANE_SHIFT)); } /* @@ -848,72 +846,72 @@ static void vlv_write_wm_values(struct drm_i915_private *dev_priv, * high order bits so that there are no out of bounds values * present in the registers during the reprogramming. */ - intel_uncore_write(&dev_priv->uncore, DSPHOWM, 0); - intel_uncore_write(&dev_priv->uncore, DSPHOWM1, 0); - intel_uncore_write(&dev_priv->uncore, DSPFW4, 0); - intel_uncore_write(&dev_priv->uncore, DSPFW5, 0); - intel_uncore_write(&dev_priv->uncore, DSPFW6, 0); - - intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv), - FW_WM(wm->sr.plane, SR) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) | - FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) | - FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA)); - intel_uncore_write(&dev_priv->uncore, DSPFW2(dev_priv), - FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE1], SPRITEB) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) | - FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA)); - intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), - FW_WM(wm->sr.cursor, CURSOR_SR)); - - if (IS_CHERRYVIEW(dev_priv)) { - intel_uncore_write(&dev_priv->uncore, DSPFW7_CHV, - FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE1], SPRITED) | - FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEC)); - intel_uncore_write(&dev_priv->uncore, DSPFW8_CHV, - FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_SPRITE1], SPRITEF) | - FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_SPRITE0], SPRITEE)); - intel_uncore_write(&dev_priv->uncore, DSPFW9_CHV, - FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_PRIMARY], PLANEC) | - FW_WM(wm->pipe[PIPE_C].plane[PLANE_CURSOR], CURSORC)); - intel_uncore_write(&dev_priv->uncore, DSPHOWM, - FW_WM(wm->sr.plane >> 9, SR_HI) | - FW_WM(wm->pipe[PIPE_C].plane[PLANE_SPRITE1] >> 8, SPRITEF_HI) | - FW_WM(wm->pipe[PIPE_C].plane[PLANE_SPRITE0] >> 8, SPRITEE_HI) | - FW_WM(wm->pipe[PIPE_C].plane[PLANE_PRIMARY] >> 8, PLANEC_HI) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE1] >> 8, SPRITED_HI) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0] >> 8, SPRITEC_HI) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY] >> 8, PLANEB_HI) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE1] >> 8, SPRITEB_HI) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0] >> 8, SPRITEA_HI) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY] >> 8, PLANEA_HI)); + intel_de_write(display, DSPHOWM, 0); + intel_de_write(display, DSPHOWM1, 0); + intel_de_write(display, DSPFW4, 0); + intel_de_write(display, DSPFW5, 0); + intel_de_write(display, DSPFW6, 0); + + intel_de_write(display, DSPFW1(display), + FW_WM(wm->sr.plane, SR) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) | + FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) | + FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA)); + intel_de_write(display, DSPFW2(display), + FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE1], SPRITEB) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) | + FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA)); + intel_de_write(display, DSPFW3(display), + FW_WM(wm->sr.cursor, CURSOR_SR)); + + if (display->platform.cherryview) { + intel_de_write(display, DSPFW7_CHV, + FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE1], SPRITED) | + FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEC)); + intel_de_write(display, DSPFW8_CHV, + FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_SPRITE1], SPRITEF) | + FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_SPRITE0], SPRITEE)); + intel_de_write(display, DSPFW9_CHV, + FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_PRIMARY], PLANEC) | + FW_WM(wm->pipe[PIPE_C].plane[PLANE_CURSOR], CURSORC)); + intel_de_write(display, DSPHOWM, + FW_WM(wm->sr.plane >> 9, SR_HI) | + FW_WM(wm->pipe[PIPE_C].plane[PLANE_SPRITE1] >> 8, SPRITEF_HI) | + FW_WM(wm->pipe[PIPE_C].plane[PLANE_SPRITE0] >> 8, SPRITEE_HI) | + FW_WM(wm->pipe[PIPE_C].plane[PLANE_PRIMARY] >> 8, PLANEC_HI) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE1] >> 8, SPRITED_HI) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0] >> 8, SPRITEC_HI) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY] >> 8, PLANEB_HI) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE1] >> 8, SPRITEB_HI) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0] >> 8, SPRITEA_HI) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY] >> 8, PLANEA_HI)); } else { - intel_uncore_write(&dev_priv->uncore, DSPFW7, - FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE1], SPRITED) | - FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEC)); - intel_uncore_write(&dev_priv->uncore, DSPHOWM, - FW_WM(wm->sr.plane >> 9, SR_HI) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE1] >> 8, SPRITED_HI) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0] >> 8, SPRITEC_HI) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY] >> 8, PLANEB_HI) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE1] >> 8, SPRITEB_HI) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0] >> 8, SPRITEA_HI) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY] >> 8, PLANEA_HI)); + intel_de_write(display, DSPFW7, + FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE1], SPRITED) | + FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEC)); + intel_de_write(display, DSPHOWM, + FW_WM(wm->sr.plane >> 9, SR_HI) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE1] >> 8, SPRITED_HI) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0] >> 8, SPRITEC_HI) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY] >> 8, PLANEB_HI) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE1] >> 8, SPRITEB_HI) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0] >> 8, SPRITEA_HI) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY] >> 8, PLANEA_HI)); } - intel_uncore_posting_read(&dev_priv->uncore, DSPFW1(dev_priv)); + intel_de_posting_read(display, DSPFW1(display)); } #undef FW_WM_VLV -static void g4x_setup_wm_latency(struct drm_i915_private *dev_priv) +static void g4x_setup_wm_latency(struct intel_display *display) { /* all latencies in usec */ - dev_priv->display.wm.pri_latency[G4X_WM_LEVEL_NORMAL] = 5; - dev_priv->display.wm.pri_latency[G4X_WM_LEVEL_SR] = 12; - dev_priv->display.wm.pri_latency[G4X_WM_LEVEL_HPLL] = 35; + display->wm.pri_latency[G4X_WM_LEVEL_NORMAL] = 5; + display->wm.pri_latency[G4X_WM_LEVEL_SR] = 12; + display->wm.pri_latency[G4X_WM_LEVEL_HPLL] = 35; - dev_priv->display.wm.num_levels = G4X_WM_LEVEL_HPLL + 1; + display->wm.num_levels = G4X_WM_LEVEL_HPLL + 1; } static int g4x_plane_fifo_size(enum plane_id plane_id, int level) @@ -962,11 +960,11 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, int level) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode; - unsigned int latency = dev_priv->display.wm.pri_latency[level] * 10; + unsigned int latency = display->wm.pri_latency[level] * 10; unsigned int pixel_rate, htotal, cpp, width, wm; if (latency == 0) @@ -1017,10 +1015,10 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state, static bool g4x_raw_plane_wm_set(struct intel_crtc_state *crtc_state, int level, enum plane_id plane_id, u16 value) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); bool dirty = false; - for (; level < dev_priv->display.wm.num_levels; level++) { + for (; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.g4x.raw[level]; dirty |= raw->plane[plane_id] != value; @@ -1033,13 +1031,13 @@ static bool g4x_raw_plane_wm_set(struct intel_crtc_state *crtc_state, static bool g4x_raw_fbc_wm_set(struct intel_crtc_state *crtc_state, int level, u16 value) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); bool dirty = false; /* NORMAL level doesn't have an FBC watermark */ level = max(level, G4X_WM_LEVEL_SR); - for (; level < dev_priv->display.wm.num_levels; level++) { + for (; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.g4x.raw[level]; dirty |= raw->fbc != value; @@ -1056,8 +1054,8 @@ static u32 ilk_compute_fbc_wm(const struct intel_crtc_state *crtc_state, static bool g4x_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); enum plane_id plane_id = plane->id; bool dirty = false; int level; @@ -1069,7 +1067,7 @@ static bool g4x_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, goto out; } - for (level = 0; level < dev_priv->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.g4x.raw[level]; int wm, max_wm; @@ -1109,7 +1107,7 @@ static bool g4x_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, out: if (dirty) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "%s watermarks: normal=%d, SR=%d, HPLL=%d\n", plane->base.name, crtc_state->wm.g4x.raw[G4X_WM_LEVEL_NORMAL].plane[plane_id], @@ -1117,7 +1115,7 @@ static bool g4x_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, crtc_state->wm.g4x.raw[G4X_WM_LEVEL_HPLL].plane[plane_id]); if (plane_id == PLANE_PRIMARY) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "FBC watermarks: SR=%d, HPLL=%d\n", crtc_state->wm.g4x.raw[G4X_WM_LEVEL_SR].fbc, crtc_state->wm.g4x.raw[G4X_WM_LEVEL_HPLL].fbc); @@ -1137,9 +1135,9 @@ static bool g4x_raw_plane_wm_is_valid(const struct intel_crtc_state *crtc_state, static bool g4x_raw_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state, int level) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); - if (level >= dev_priv->display.wm.num_levels) + if (level >= display->wm.num_levels) return false; return g4x_raw_plane_wm_is_valid(crtc_state, PLANE_PRIMARY, level) && @@ -1281,7 +1279,7 @@ static int g4x_compute_pipe_wm(struct intel_atomic_state *state, static int g4x_compute_intermediate_wm(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_crtc_state *old_crtc_state = @@ -1311,7 +1309,7 @@ static int g4x_compute_intermediate_wm(struct intel_atomic_state *state, max(optimal->wm.plane[plane_id], active->wm.plane[plane_id]); - drm_WARN_ON(&dev_priv->drm, intermediate->wm.plane[plane_id] > + drm_WARN_ON(display->drm, intermediate->wm.plane[plane_id] > g4x_plane_fifo_size(plane_id, G4X_WM_LEVEL_NORMAL)); } @@ -1329,23 +1327,23 @@ static int g4x_compute_intermediate_wm(struct intel_atomic_state *state, intermediate->hpll.fbc = max(optimal->hpll.fbc, active->hpll.fbc); - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, (intermediate->sr.plane > g4x_plane_fifo_size(PLANE_PRIMARY, G4X_WM_LEVEL_SR) || intermediate->sr.cursor > g4x_plane_fifo_size(PLANE_CURSOR, G4X_WM_LEVEL_SR)) && intermediate->cxsr); - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, (intermediate->sr.plane > g4x_plane_fifo_size(PLANE_PRIMARY, G4X_WM_LEVEL_HPLL) || intermediate->sr.cursor > g4x_plane_fifo_size(PLANE_CURSOR, G4X_WM_LEVEL_HPLL)) && intermediate->hpll_en); - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, intermediate->sr.fbc > g4x_fbc_fifo_size(1) && intermediate->fbc_en && intermediate->cxsr); - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, intermediate->hpll.fbc > g4x_fbc_fifo_size(2) && intermediate->fbc_en && intermediate->hpll_en); @@ -1376,7 +1374,7 @@ static int g4x_compute_watermarks(struct intel_atomic_state *state, return 0; } -static void g4x_merge_wm(struct drm_i915_private *dev_priv, +static void g4x_merge_wm(struct intel_display *display, struct g4x_wm_values *wm) { struct intel_crtc *crtc; @@ -1386,7 +1384,7 @@ static void g4x_merge_wm(struct drm_i915_private *dev_priv, wm->hpll_en = true; wm->fbc_en = true; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct g4x_wm_state *wm_state = &crtc->wm.active.g4x; if (!crtc->active) @@ -1408,7 +1406,7 @@ static void g4x_merge_wm(struct drm_i915_private *dev_priv, wm->fbc_en = false; } - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct g4x_wm_state *wm_state = &crtc->wm.active.g4x; enum pipe pipe = crtc->pipe; @@ -1420,23 +1418,23 @@ static void g4x_merge_wm(struct drm_i915_private *dev_priv, } } -static void g4x_program_watermarks(struct drm_i915_private *dev_priv) +static void g4x_program_watermarks(struct intel_display *display) { - struct g4x_wm_values *old_wm = &dev_priv->display.wm.g4x; + struct g4x_wm_values *old_wm = &display->wm.g4x; struct g4x_wm_values new_wm = {}; - g4x_merge_wm(dev_priv, &new_wm); + g4x_merge_wm(display, &new_wm); if (memcmp(old_wm, &new_wm, sizeof(new_wm)) == 0) return; if (is_disabling(old_wm->cxsr, new_wm.cxsr, true)) - _intel_set_memory_cxsr(dev_priv, false); + _intel_set_memory_cxsr(display, false); - g4x_write_wm_values(dev_priv, &new_wm); + g4x_write_wm_values(display, &new_wm); if (is_enabling(old_wm->cxsr, new_wm.cxsr, true)) - _intel_set_memory_cxsr(dev_priv, true); + _intel_set_memory_cxsr(display, true); *old_wm = new_wm; } @@ -1444,30 +1442,30 @@ static void g4x_program_watermarks(struct drm_i915_private *dev_priv) static void g4x_initial_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); crtc->wm.active.g4x = crtc_state->wm.g4x.intermediate; - g4x_program_watermarks(dev_priv); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + g4x_program_watermarks(display); + mutex_unlock(&display->wm.wm_mutex); } static void g4x_optimize_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); if (!crtc_state->wm.need_postvbl_update) return; - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); crtc->wm.active.g4x = crtc_state->wm.g4x.optimal; - g4x_program_watermarks(dev_priv); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + g4x_program_watermarks(display); + mutex_unlock(&display->wm.wm_mutex); } /* latency must be in 0.1us units. */ @@ -1486,18 +1484,18 @@ static unsigned int vlv_wm_method2(unsigned int pixel_rate, return ret; } -static void vlv_setup_wm_latency(struct drm_i915_private *dev_priv) +static void vlv_setup_wm_latency(struct intel_display *display) { /* all latencies in usec */ - dev_priv->display.wm.pri_latency[VLV_WM_LEVEL_PM2] = 3; + display->wm.pri_latency[VLV_WM_LEVEL_PM2] = 3; - dev_priv->display.wm.num_levels = VLV_WM_LEVEL_PM2 + 1; + display->wm.num_levels = VLV_WM_LEVEL_PM2 + 1; - if (IS_CHERRYVIEW(dev_priv)) { - dev_priv->display.wm.pri_latency[VLV_WM_LEVEL_PM5] = 12; - dev_priv->display.wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 33; + if (display->platform.cherryview) { + display->wm.pri_latency[VLV_WM_LEVEL_PM5] = 12; + display->wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 33; - dev_priv->display.wm.num_levels = VLV_WM_LEVEL_DDR_DVFS + 1; + display->wm.num_levels = VLV_WM_LEVEL_DDR_DVFS + 1; } } @@ -1505,13 +1503,13 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, int level) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode; unsigned int pixel_rate, htotal, cpp, width, wm; - if (dev_priv->display.wm.pri_latency[level] == 0) + if (display->wm.pri_latency[level] == 0) return USHRT_MAX; if (!intel_wm_plane_visible(crtc_state, plane_state)) @@ -1532,7 +1530,7 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state, wm = 63; } else { wm = vlv_wm_method2(pixel_rate, htotal, width, cpp, - dev_priv->display.wm.pri_latency[level] * 10); + display->wm.pri_latency[level] * 10); } return min_t(unsigned int, wm, USHRT_MAX); @@ -1546,8 +1544,8 @@ static bool vlv_need_sprite0_fifo_workaround(unsigned int active_planes) static int vlv_compute_fifo(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct g4x_pipe_wm *raw = &crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM2]; struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state; @@ -1616,11 +1614,11 @@ static int vlv_compute_fifo(struct intel_crtc_state *crtc_state) fifo_left -= plane_extra; } - drm_WARN_ON(&dev_priv->drm, active_planes != 0 && fifo_left != 0); + drm_WARN_ON(display->drm, active_planes != 0 && fifo_left != 0); /* give it all to the first plane if none are active */ if (active_planes == 0) { - drm_WARN_ON(&dev_priv->drm, fifo_left != fifo_size); + drm_WARN_ON(display->drm, fifo_left != fifo_size); fifo_state->plane[PLANE_PRIMARY] = fifo_left; } @@ -1631,9 +1629,9 @@ static int vlv_compute_fifo(struct intel_crtc_state *crtc_state) static void vlv_invalidate_wms(struct intel_crtc *crtc, struct vlv_wm_state *wm_state, int level) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); - for (; level < dev_priv->display.wm.num_levels; level++) { + for (; level < display->wm.num_levels; level++) { enum plane_id plane_id; for_each_plane_id_on_crtc(crtc, plane_id) @@ -1659,10 +1657,10 @@ static u16 vlv_invert_wm_value(u16 wm, u16 fifo_size) static bool vlv_raw_plane_wm_set(struct intel_crtc_state *crtc_state, int level, enum plane_id plane_id, u16 value) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); bool dirty = false; - for (; level < dev_priv->display.wm.num_levels; level++) { + for (; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.vlv.raw[level]; dirty |= raw->plane[plane_id] != value; @@ -1675,8 +1673,8 @@ static bool vlv_raw_plane_wm_set(struct intel_crtc_state *crtc_state, static bool vlv_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); enum plane_id plane_id = plane->id; int level; bool dirty = false; @@ -1686,7 +1684,7 @@ static bool vlv_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, goto out; } - for (level = 0; level < dev_priv->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.vlv.raw[level]; int wm = vlv_compute_wm_level(crtc_state, plane_state, level); int max_wm = plane_id == PLANE_CURSOR ? 63 : 511; @@ -1703,7 +1701,7 @@ static bool vlv_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, out: if (dirty) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "%s watermarks: PM2=%d, PM5=%d, DDR DVFS=%d\n", plane->base.name, crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM2].plane[plane_id], @@ -1734,8 +1732,8 @@ static bool vlv_raw_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state, static int _vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal; const struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state; @@ -1745,7 +1743,7 @@ static int _vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state) int level; /* initially allow all levels */ - wm_state->num_levels = dev_priv->display.wm.num_levels; + wm_state->num_levels = display->wm.num_levels; /* * Note that enabling cxsr with no primary/sprite planes * enabled can wedge the pipe. Hence we only allow cxsr @@ -1755,7 +1753,7 @@ static int _vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state) for (level = 0; level < wm_state->num_levels; level++) { const struct g4x_pipe_wm *raw = &crtc_state->wm.vlv.raw[level]; - const int sr_fifo_size = INTEL_NUM_PIPES(dev_priv) * 512 - 1; + const int sr_fifo_size = INTEL_NUM_PIPES(display) * 512 - 1; if (!vlv_raw_crtc_wm_is_valid(crtc_state, level)) break; @@ -1855,6 +1853,7 @@ static int vlv_compute_pipe_wm(struct intel_atomic_state *state, static void vlv_atomic_update_fifo(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_uncore *uncore = &dev_priv->uncore; const struct intel_crtc_state *crtc_state = @@ -1871,8 +1870,8 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state, sprite1_start = fifo_state->plane[PLANE_SPRITE0] + sprite0_start; fifo_size = fifo_state->plane[PLANE_SPRITE1] + sprite1_start; - drm_WARN_ON(&dev_priv->drm, fifo_state->plane[PLANE_CURSOR] != 63); - drm_WARN_ON(&dev_priv->drm, fifo_size != 511); + drm_WARN_ON(display->drm, fifo_state->plane[PLANE_CURSOR] != 63); + drm_WARN_ON(display->drm, fifo_size != 511); trace_vlv_fifo_size(crtc, sprite0_start, sprite1_start, fifo_size); @@ -1889,8 +1888,8 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state, switch (crtc->pipe) { case PIPE_A: - dsparb = intel_uncore_read_fw(uncore, DSPARB(dev_priv)); - dsparb2 = intel_uncore_read_fw(uncore, DSPARB2); + dsparb = intel_de_read_fw(display, DSPARB(display)); + dsparb2 = intel_de_read_fw(display, DSPARB2); dsparb &= ~(VLV_FIFO(SPRITEA, 0xff) | VLV_FIFO(SPRITEB, 0xff)); @@ -1902,12 +1901,12 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state, dsparb2 |= (VLV_FIFO(SPRITEA_HI, sprite0_start >> 8) | VLV_FIFO(SPRITEB_HI, sprite1_start >> 8)); - intel_uncore_write_fw(uncore, DSPARB(dev_priv), dsparb); - intel_uncore_write_fw(uncore, DSPARB2, dsparb2); + intel_de_write_fw(display, DSPARB(display), dsparb); + intel_de_write_fw(display, DSPARB2, dsparb2); break; case PIPE_B: - dsparb = intel_uncore_read_fw(uncore, DSPARB(dev_priv)); - dsparb2 = intel_uncore_read_fw(uncore, DSPARB2); + dsparb = intel_de_read_fw(display, DSPARB(display)); + dsparb2 = intel_de_read_fw(display, DSPARB2); dsparb &= ~(VLV_FIFO(SPRITEC, 0xff) | VLV_FIFO(SPRITED, 0xff)); @@ -1919,12 +1918,12 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state, dsparb2 |= (VLV_FIFO(SPRITEC_HI, sprite0_start >> 8) | VLV_FIFO(SPRITED_HI, sprite1_start >> 8)); - intel_uncore_write_fw(uncore, DSPARB(dev_priv), dsparb); - intel_uncore_write_fw(uncore, DSPARB2, dsparb2); + intel_de_write_fw(display, DSPARB(display), dsparb); + intel_de_write_fw(display, DSPARB2, dsparb2); break; case PIPE_C: - dsparb3 = intel_uncore_read_fw(uncore, DSPARB3); - dsparb2 = intel_uncore_read_fw(uncore, DSPARB2); + dsparb3 = intel_de_read_fw(display, DSPARB3); + dsparb2 = intel_de_read_fw(display, DSPARB2); dsparb3 &= ~(VLV_FIFO(SPRITEE, 0xff) | VLV_FIFO(SPRITEF, 0xff)); @@ -1936,14 +1935,14 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state, dsparb2 |= (VLV_FIFO(SPRITEE_HI, sprite0_start >> 8) | VLV_FIFO(SPRITEF_HI, sprite1_start >> 8)); - intel_uncore_write_fw(uncore, DSPARB3, dsparb3); - intel_uncore_write_fw(uncore, DSPARB2, dsparb2); + intel_de_write_fw(display, DSPARB3, dsparb3); + intel_de_write_fw(display, DSPARB2, dsparb2); break; default: break; } - intel_uncore_posting_read_fw(uncore, DSPARB(dev_priv)); + intel_de_read_fw(display, DSPARB(display)); spin_unlock(&uncore->lock); } @@ -2018,16 +2017,16 @@ static int vlv_compute_watermarks(struct intel_atomic_state *state, return 0; } -static void vlv_merge_wm(struct drm_i915_private *dev_priv, +static void vlv_merge_wm(struct intel_display *display, struct vlv_wm_values *wm) { struct intel_crtc *crtc; int num_active_pipes = 0; - wm->level = dev_priv->display.wm.num_levels - 1; + wm->level = display->wm.num_levels - 1; wm->cxsr = true; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct vlv_wm_state *wm_state = &crtc->wm.active.vlv; if (!crtc->active) @@ -2046,7 +2045,7 @@ static void vlv_merge_wm(struct drm_i915_private *dev_priv, if (num_active_pipes > 1) wm->level = VLV_WM_LEVEL_PM2; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct vlv_wm_state *wm_state = &crtc->wm.active.vlv; enum pipe pipe = crtc->pipe; @@ -2061,35 +2060,35 @@ static void vlv_merge_wm(struct drm_i915_private *dev_priv, } } -static void vlv_program_watermarks(struct drm_i915_private *dev_priv) +static void vlv_program_watermarks(struct intel_display *display) { - struct vlv_wm_values *old_wm = &dev_priv->display.wm.vlv; + struct vlv_wm_values *old_wm = &display->wm.vlv; struct vlv_wm_values new_wm = {}; - vlv_merge_wm(dev_priv, &new_wm); + vlv_merge_wm(display, &new_wm); if (memcmp(old_wm, &new_wm, sizeof(new_wm)) == 0) return; if (is_disabling(old_wm->level, new_wm.level, VLV_WM_LEVEL_DDR_DVFS)) - chv_set_memory_dvfs(dev_priv, false); + chv_set_memory_dvfs(display, false); if (is_disabling(old_wm->level, new_wm.level, VLV_WM_LEVEL_PM5)) - chv_set_memory_pm5(dev_priv, false); + chv_set_memory_pm5(display, false); if (is_disabling(old_wm->cxsr, new_wm.cxsr, true)) - _intel_set_memory_cxsr(dev_priv, false); + _intel_set_memory_cxsr(display, false); - vlv_write_wm_values(dev_priv, &new_wm); + vlv_write_wm_values(display, &new_wm); if (is_enabling(old_wm->cxsr, new_wm.cxsr, true)) - _intel_set_memory_cxsr(dev_priv, true); + _intel_set_memory_cxsr(display, true); if (is_enabling(old_wm->level, new_wm.level, VLV_WM_LEVEL_PM5)) - chv_set_memory_pm5(dev_priv, true); + chv_set_memory_pm5(display, true); if (is_enabling(old_wm->level, new_wm.level, VLV_WM_LEVEL_DDR_DVFS)) - chv_set_memory_dvfs(dev_priv, true); + chv_set_memory_dvfs(display, true); *old_wm = new_wm; } @@ -2097,33 +2096,33 @@ static void vlv_program_watermarks(struct drm_i915_private *dev_priv) static void vlv_initial_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); crtc->wm.active.vlv = crtc_state->wm.vlv.intermediate; - vlv_program_watermarks(dev_priv); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + vlv_program_watermarks(display); + mutex_unlock(&display->wm.wm_mutex); } static void vlv_optimize_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); if (!crtc_state->wm.need_postvbl_update) return; - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); crtc->wm.active.vlv = crtc_state->wm.vlv.optimal; - vlv_program_watermarks(dev_priv); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + vlv_program_watermarks(display); + mutex_unlock(&display->wm.wm_mutex); } -static void i965_update_wm(struct drm_i915_private *dev_priv) +static void i965_update_wm(struct intel_display *display) { struct intel_crtc *crtc; int srwm = 1; @@ -2131,7 +2130,7 @@ static void i965_update_wm(struct drm_i915_private *dev_priv) bool cxsr_enabled; /* Calc sr entries for one plane configs */ - crtc = single_enabled_crtc(dev_priv); + crtc = single_enabled_crtc(display); if (crtc) { /* self-refresh has much higher latency */ static const int sr_latency_ns = 12000; @@ -2152,7 +2151,7 @@ static void i965_update_wm(struct drm_i915_private *dev_priv) if (srwm < 0) srwm = 1; srwm &= 0x1ff; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "self-refresh entries: %d, wm: %d\n", entries, srwm); @@ -2167,7 +2166,7 @@ static void i965_update_wm(struct drm_i915_private *dev_priv) if (cursor_sr > i965_cursor_wm_info.max_wm) cursor_sr = i965_cursor_wm_info.max_wm; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "self-refresh watermark: display plane %d " "cursor %d\n", srwm, cursor_sr); @@ -2175,39 +2174,38 @@ static void i965_update_wm(struct drm_i915_private *dev_priv) } else { cxsr_enabled = false; /* Turn off self refresh if both pipes are enabled */ - intel_set_memory_cxsr(dev_priv, false); + intel_set_memory_cxsr(display, false); } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", srwm); /* 965 has limitations... */ - intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv), - FW_WM(srwm, SR) | - FW_WM(8, CURSORB) | - FW_WM(8, PLANEB) | - FW_WM(8, PLANEA)); - intel_uncore_write(&dev_priv->uncore, DSPFW2(dev_priv), - FW_WM(8, CURSORA) | - FW_WM(8, PLANEC_OLD)); + intel_de_write(display, DSPFW1(display), + FW_WM(srwm, SR) | + FW_WM(8, CURSORB) | + FW_WM(8, PLANEB) | + FW_WM(8, PLANEA)); + intel_de_write(display, DSPFW2(display), + FW_WM(8, CURSORA) | + FW_WM(8, PLANEC_OLD)); /* update cursor SR watermark */ - intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), - FW_WM(cursor_sr, CURSOR_SR)); + intel_de_write(display, DSPFW3(display), + FW_WM(cursor_sr, CURSOR_SR)); if (cxsr_enabled) - intel_set_memory_cxsr(dev_priv, true); + intel_set_memory_cxsr(display, true); } #undef FW_WM -static struct intel_crtc *intel_crtc_for_plane(struct drm_i915_private *i915, +static struct intel_crtc *intel_crtc_for_plane(struct intel_display *display, enum i9xx_plane_id i9xx_plane) { - struct intel_display *display = &i915->display; struct intel_plane *plane; - for_each_intel_plane(&i915->drm, plane) { + for_each_intel_plane(display->drm, plane) { if (plane->id == PLANE_PRIMARY && plane->i9xx_plane == i9xx_plane) return intel_crtc_for_pipe(display, plane->pipe); @@ -2216,7 +2214,7 @@ static struct intel_crtc *intel_crtc_for_plane(struct drm_i915_private *i915, return NULL; } -static void i9xx_update_wm(struct drm_i915_private *dev_priv) +static void i9xx_update_wm(struct intel_display *display) { const struct intel_watermark_params *wm_info; u32 fwater_lo; @@ -2226,29 +2224,29 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) int planea_wm, planeb_wm; struct intel_crtc *crtc; - if (IS_I945GM(dev_priv)) + if (display->platform.i945gm) wm_info = &i945_wm_info; - else if (DISPLAY_VER(dev_priv) != 2) + else if (DISPLAY_VER(display) != 2) wm_info = &i915_wm_info; else wm_info = &i830_a_wm_info; - if (DISPLAY_VER(dev_priv) == 2) - fifo_size = i830_get_fifo_size(dev_priv, PLANE_A); + if (DISPLAY_VER(display) == 2) + fifo_size = i830_get_fifo_size(display, PLANE_A); else - fifo_size = i9xx_get_fifo_size(dev_priv, PLANE_A); - crtc = intel_crtc_for_plane(dev_priv, PLANE_A); + fifo_size = i9xx_get_fifo_size(display, PLANE_A); + crtc = intel_crtc_for_plane(display, PLANE_A); if (intel_crtc_active(crtc)) { const struct drm_framebuffer *fb = crtc->base.primary->state->fb; int cpp; - if (DISPLAY_VER(dev_priv) == 2) + if (DISPLAY_VER(display) == 2) cpp = 4; else cpp = fb->format->cpp[0]; - planea_wm = intel_calculate_wm(dev_priv, crtc->config->pixel_rate, + planea_wm = intel_calculate_wm(display, crtc->config->pixel_rate, wm_info, fifo_size, cpp, pessimal_latency_ns); } else { @@ -2257,25 +2255,25 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) planea_wm = wm_info->max_wm; } - if (DISPLAY_VER(dev_priv) == 2) + if (DISPLAY_VER(display) == 2) wm_info = &i830_bc_wm_info; - if (DISPLAY_VER(dev_priv) == 2) - fifo_size = i830_get_fifo_size(dev_priv, PLANE_B); + if (DISPLAY_VER(display) == 2) + fifo_size = i830_get_fifo_size(display, PLANE_B); else - fifo_size = i9xx_get_fifo_size(dev_priv, PLANE_B); - crtc = intel_crtc_for_plane(dev_priv, PLANE_B); + fifo_size = i9xx_get_fifo_size(display, PLANE_B); + crtc = intel_crtc_for_plane(display, PLANE_B); if (intel_crtc_active(crtc)) { const struct drm_framebuffer *fb = crtc->base.primary->state->fb; int cpp; - if (DISPLAY_VER(dev_priv) == 2) + if (DISPLAY_VER(display) == 2) cpp = 4; else cpp = fb->format->cpp[0]; - planeb_wm = intel_calculate_wm(dev_priv, crtc->config->pixel_rate, + planeb_wm = intel_calculate_wm(display, crtc->config->pixel_rate, wm_info, fifo_size, cpp, pessimal_latency_ns); } else { @@ -2284,11 +2282,11 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) planeb_wm = wm_info->max_wm; } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); - crtc = single_enabled_crtc(dev_priv); - if (IS_I915GM(dev_priv) && crtc) { + crtc = single_enabled_crtc(display); + if (display->platform.i915gm && crtc) { struct drm_gem_object *obj; obj = intel_fb_bo(crtc->base.primary->state->fb); @@ -2304,10 +2302,10 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) cwm = 2; /* Play safe and disable self-refresh before adjusting watermarks. */ - intel_set_memory_cxsr(dev_priv, false); + intel_set_memory_cxsr(display, false); /* Calc sr entries for one plane configs */ - if (HAS_FW_BLC(dev_priv) && crtc) { + if (HAS_FW_BLC(display) && crtc) { /* self-refresh has much higher latency */ static const int sr_latency_ns = 6000; const struct drm_display_mode *pipe_mode = @@ -2320,7 +2318,7 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) int cpp; int entries; - if (IS_I915GM(dev_priv) || IS_I945GM(dev_priv)) + if (display->platform.i915gm || display->platform.i945gm) cpp = 4; else cpp = fb->format->cpp[0]; @@ -2328,20 +2326,20 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) entries = intel_wm_method2(pixel_rate, htotal, width, cpp, sr_latency_ns / 100); entries = DIV_ROUND_UP(entries, wm_info->cacheline_size); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "self-refresh entries: %d\n", entries); srwm = wm_info->fifo_size - entries; if (srwm < 0) srwm = 1; - if (IS_I945G(dev_priv) || IS_I945GM(dev_priv)) - intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, - FW_BLC_SELF_FIFO_MASK | (srwm & 0xff)); + if (display->platform.i945g || display->platform.i945gm) + intel_de_write(display, FW_BLC_SELF, + FW_BLC_SELF_FIFO_MASK | (srwm & 0xff)); else - intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, srwm & 0x3f); + intel_de_write(display, FW_BLC_SELF, srwm & 0x3f); } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", planea_wm, planeb_wm, cwm, srwm); @@ -2352,34 +2350,34 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) fwater_lo = fwater_lo | (1 << 24) | (1 << 8); fwater_hi = fwater_hi | (1 << 8); - intel_uncore_write(&dev_priv->uncore, FW_BLC, fwater_lo); - intel_uncore_write(&dev_priv->uncore, FW_BLC2, fwater_hi); + intel_de_write(display, FW_BLC, fwater_lo); + intel_de_write(display, FW_BLC2, fwater_hi); if (crtc) - intel_set_memory_cxsr(dev_priv, true); + intel_set_memory_cxsr(display, true); } -static void i845_update_wm(struct drm_i915_private *dev_priv) +static void i845_update_wm(struct intel_display *display) { struct intel_crtc *crtc; u32 fwater_lo; int planea_wm; - crtc = single_enabled_crtc(dev_priv); + crtc = single_enabled_crtc(display); if (crtc == NULL) return; - planea_wm = intel_calculate_wm(dev_priv, crtc->config->pixel_rate, + planea_wm = intel_calculate_wm(display, crtc->config->pixel_rate, &i845_wm_info, - i845_get_fifo_size(dev_priv, PLANE_A), + i845_get_fifo_size(display, PLANE_A), 4, pessimal_latency_ns); - fwater_lo = intel_uncore_read(&dev_priv->uncore, FW_BLC) & ~0xfff; + fwater_lo = intel_de_read(display, FW_BLC) & ~0xfff; fwater_lo |= (3<<8) | planea_wm; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Setting FIFO watermarks - A: %d\n", planea_wm); - intel_uncore_write(&dev_priv->uncore, FW_BLC, fwater_lo); + intel_de_write(display, FW_BLC, fwater_lo); } /* latency must be in 0.1us units. */ @@ -2534,24 +2532,24 @@ static u32 ilk_compute_fbc_wm(const struct intel_crtc_state *crtc_state, } static unsigned int -ilk_display_fifo_size(const struct drm_i915_private *dev_priv) +ilk_display_fifo_size(struct intel_display *display) { - if (DISPLAY_VER(dev_priv) >= 8) + if (DISPLAY_VER(display) >= 8) return 3072; - else if (DISPLAY_VER(dev_priv) >= 7) + else if (DISPLAY_VER(display) >= 7) return 768; else return 512; } static unsigned int -ilk_plane_wm_reg_max(const struct drm_i915_private *dev_priv, +ilk_plane_wm_reg_max(struct intel_display *display, int level, bool is_sprite) { - if (DISPLAY_VER(dev_priv) >= 8) + if (DISPLAY_VER(display) >= 8) /* BDW primary/sprite plane watermarks */ return level == 0 ? 255 : 2047; - else if (DISPLAY_VER(dev_priv) >= 7) + else if (DISPLAY_VER(display) >= 7) /* IVB/HSW primary/sprite plane watermarks */ return level == 0 ? 127 : 1023; else if (!is_sprite) @@ -2563,30 +2561,30 @@ ilk_plane_wm_reg_max(const struct drm_i915_private *dev_priv, } static unsigned int -ilk_cursor_wm_reg_max(const struct drm_i915_private *dev_priv, int level) +ilk_cursor_wm_reg_max(struct intel_display *display, int level) { - if (DISPLAY_VER(dev_priv) >= 7) + if (DISPLAY_VER(display) >= 7) return level == 0 ? 63 : 255; else return level == 0 ? 31 : 63; } -static unsigned int ilk_fbc_wm_reg_max(const struct drm_i915_private *dev_priv) +static unsigned int ilk_fbc_wm_reg_max(struct intel_display *display) { - if (DISPLAY_VER(dev_priv) >= 8) + if (DISPLAY_VER(display) >= 8) return 31; else return 15; } /* Calculate the maximum primary/sprite plane watermark */ -static unsigned int ilk_plane_wm_max(const struct drm_i915_private *dev_priv, +static unsigned int ilk_plane_wm_max(struct intel_display *display, int level, const struct intel_wm_config *config, enum intel_ddb_partitioning ddb_partitioning, bool is_sprite) { - unsigned int fifo_size = ilk_display_fifo_size(dev_priv); + unsigned int fifo_size = ilk_display_fifo_size(display); /* if sprites aren't enabled, sprites get nothing */ if (is_sprite && !config->sprites_enabled) @@ -2594,14 +2592,14 @@ static unsigned int ilk_plane_wm_max(const struct drm_i915_private *dev_priv, /* HSW allows LP1+ watermarks even with multiple pipes */ if (level == 0 || config->num_pipes_active > 1) { - fifo_size /= INTEL_NUM_PIPES(dev_priv); + fifo_size /= INTEL_NUM_PIPES(display); /* * For some reason the non self refresh * FIFO size is only half of the self * refresh FIFO size on ILK/SNB. */ - if (DISPLAY_VER(dev_priv) < 7) + if (DISPLAY_VER(display) < 7) fifo_size /= 2; } @@ -2617,11 +2615,11 @@ static unsigned int ilk_plane_wm_max(const struct drm_i915_private *dev_priv, } /* clamp to max that the registers can hold */ - return min(fifo_size, ilk_plane_wm_reg_max(dev_priv, level, is_sprite)); + return min(fifo_size, ilk_plane_wm_reg_max(display, level, is_sprite)); } /* Calculate the maximum cursor plane watermark */ -static unsigned int ilk_cursor_wm_max(const struct drm_i915_private *dev_priv, +static unsigned int ilk_cursor_wm_max(struct intel_display *display, int level, const struct intel_wm_config *config) { @@ -2630,32 +2628,32 @@ static unsigned int ilk_cursor_wm_max(const struct drm_i915_private *dev_priv, return 64; /* otherwise just report max that registers can hold */ - return ilk_cursor_wm_reg_max(dev_priv, level); + return ilk_cursor_wm_reg_max(display, level); } -static void ilk_compute_wm_maximums(const struct drm_i915_private *dev_priv, +static void ilk_compute_wm_maximums(struct intel_display *display, int level, const struct intel_wm_config *config, enum intel_ddb_partitioning ddb_partitioning, struct ilk_wm_maximums *max) { - max->pri = ilk_plane_wm_max(dev_priv, level, config, ddb_partitioning, false); - max->spr = ilk_plane_wm_max(dev_priv, level, config, ddb_partitioning, true); - max->cur = ilk_cursor_wm_max(dev_priv, level, config); - max->fbc = ilk_fbc_wm_reg_max(dev_priv); + max->pri = ilk_plane_wm_max(display, level, config, ddb_partitioning, false); + max->spr = ilk_plane_wm_max(display, level, config, ddb_partitioning, true); + max->cur = ilk_cursor_wm_max(display, level, config); + max->fbc = ilk_fbc_wm_reg_max(display); } -static void ilk_compute_wm_reg_maximums(const struct drm_i915_private *dev_priv, +static void ilk_compute_wm_reg_maximums(struct intel_display *display, int level, struct ilk_wm_maximums *max) { - max->pri = ilk_plane_wm_reg_max(dev_priv, level, false); - max->spr = ilk_plane_wm_reg_max(dev_priv, level, true); - max->cur = ilk_cursor_wm_reg_max(dev_priv, level); - max->fbc = ilk_fbc_wm_reg_max(dev_priv); + max->pri = ilk_plane_wm_reg_max(display, level, false); + max->spr = ilk_plane_wm_reg_max(display, level, true); + max->cur = ilk_cursor_wm_reg_max(display, level); + max->fbc = ilk_fbc_wm_reg_max(display); } -static bool ilk_validate_wm_level(struct drm_i915_private *i915, +static bool ilk_validate_wm_level(struct intel_display *display, int level, const struct ilk_wm_maximums *max, struct intel_wm_level *result) @@ -2679,15 +2677,15 @@ static bool ilk_validate_wm_level(struct drm_i915_private *i915, */ if (level == 0 && !result->enable) { if (result->pri_val > max->pri) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Primary WM%d too large %u (max %u)\n", level, result->pri_val, max->pri); if (result->spr_val > max->spr) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Sprite WM%d too large %u (max %u)\n", level, result->spr_val, max->spr); if (result->cur_val > max->cur) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Cursor WM%d too large %u (max %u)\n", level, result->cur_val, max->cur); @@ -2700,7 +2698,7 @@ static bool ilk_validate_wm_level(struct drm_i915_private *i915, return ret; } -static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, +static void ilk_compute_wm_level(struct intel_display *display, const struct intel_crtc *crtc, int level, struct intel_crtc_state *crtc_state, @@ -2709,9 +2707,9 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, const struct intel_plane_state *curstate, struct intel_wm_level *result) { - u16 pri_latency = dev_priv->display.wm.pri_latency[level]; - u16 spr_latency = dev_priv->display.wm.spr_latency[level]; - u16 cur_latency = dev_priv->display.wm.cur_latency[level]; + u16 pri_latency = display->wm.pri_latency[level]; + u16 spr_latency = display->wm.spr_latency[level]; + u16 cur_latency = display->wm.cur_latency[level]; /* WM1+ latency values stored in 0.5us units */ if (level > 0) { @@ -2735,11 +2733,12 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, result->enable = true; } -static void hsw_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) +static void hsw_read_wm_latency(struct intel_display *display, u16 wm[]) { + struct drm_i915_private *i915 = to_i915(display->drm); u64 sskpd; - i915->display.wm.num_levels = 5; + display->wm.num_levels = 5; sskpd = intel_uncore_read64(&i915->uncore, MCH_SSKPD); @@ -2752,11 +2751,12 @@ static void hsw_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) wm[4] = REG_FIELD_GET64(SSKPD_WM4_MASK_HSW, sskpd); } -static void snb_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) +static void snb_read_wm_latency(struct intel_display *display, u16 wm[]) { + struct drm_i915_private *i915 = to_i915(display->drm); u32 sskpd; - i915->display.wm.num_levels = 4; + display->wm.num_levels = 4; sskpd = intel_uncore_read(&i915->uncore, MCH_SSKPD); @@ -2766,11 +2766,12 @@ static void snb_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) wm[3] = REG_FIELD_GET(SSKPD_WM3_MASK_SNB, sskpd); } -static void ilk_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) +static void ilk_read_wm_latency(struct intel_display *display, u16 wm[]) { + struct drm_i915_private *i915 = to_i915(display->drm); u32 mltr; - i915->display.wm.num_levels = 3; + display->wm.num_levels = 3; mltr = intel_uncore_read(&i915->uncore, MLTR_ILK); @@ -2780,24 +2781,21 @@ static void ilk_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) wm[2] = REG_FIELD_GET(MLTR_WM2_MASK, mltr); } -static void intel_fixup_spr_wm_latency(struct drm_i915_private *dev_priv, - u16 wm[5]) +static void intel_fixup_spr_wm_latency(struct intel_display *display, u16 wm[5]) { /* ILK sprite LP0 latency is 1300 ns */ - if (DISPLAY_VER(dev_priv) == 5) + if (DISPLAY_VER(display) == 5) wm[0] = 13; } -static void intel_fixup_cur_wm_latency(struct drm_i915_private *dev_priv, - u16 wm[5]) +static void intel_fixup_cur_wm_latency(struct intel_display *display, u16 wm[5]) { /* ILK cursor LP0 latency is 1300 ns */ - if (DISPLAY_VER(dev_priv) == 5) + if (DISPLAY_VER(display) == 5) wm[0] = 13; } -static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv, - u16 wm[5], u16 min) +static bool ilk_increase_wm_latency(struct intel_display *display, u16 wm[5], u16 min) { int level; @@ -2805,13 +2803,13 @@ static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv, return false; wm[0] = max(wm[0], min); - for (level = 1; level < dev_priv->display.wm.num_levels; level++) + for (level = 1; level < display->wm.num_levels; level++) wm[level] = max_t(u16, wm[level], DIV_ROUND_UP(min, 5)); return true; } -static void snb_wm_latency_quirk(struct drm_i915_private *dev_priv) +static void snb_wm_latency_quirk(struct intel_display *display) { bool changed; @@ -2819,21 +2817,21 @@ static void snb_wm_latency_quirk(struct drm_i915_private *dev_priv) * The BIOS provided WM memory latency values are often * inadequate for high resolution displays. Adjust them. */ - changed = ilk_increase_wm_latency(dev_priv, dev_priv->display.wm.pri_latency, 12); - changed |= ilk_increase_wm_latency(dev_priv, dev_priv->display.wm.spr_latency, 12); - changed |= ilk_increase_wm_latency(dev_priv, dev_priv->display.wm.cur_latency, 12); + changed = ilk_increase_wm_latency(display, display->wm.pri_latency, 12); + changed |= ilk_increase_wm_latency(display, display->wm.spr_latency, 12); + changed |= ilk_increase_wm_latency(display, display->wm.cur_latency, 12); if (!changed) return; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "WM latency values increased to avoid potential underruns\n"); - intel_print_wm_latency(dev_priv, "Primary", dev_priv->display.wm.pri_latency); - intel_print_wm_latency(dev_priv, "Sprite", dev_priv->display.wm.spr_latency); - intel_print_wm_latency(dev_priv, "Cursor", dev_priv->display.wm.cur_latency); + intel_print_wm_latency(display, "Primary", display->wm.pri_latency); + intel_print_wm_latency(display, "Sprite", display->wm.spr_latency); + intel_print_wm_latency(display, "Cursor", display->wm.cur_latency); } -static void snb_wm_lp3_irq_quirk(struct drm_i915_private *dev_priv) +static void snb_wm_lp3_irq_quirk(struct intel_display *display) { /* * On some SNB machines (Thinkpad X220 Tablet at least) @@ -2846,50 +2844,50 @@ static void snb_wm_lp3_irq_quirk(struct drm_i915_private *dev_priv) * interrupts only. To play it safe we disable LP3 * watermarks entirely. */ - if (dev_priv->display.wm.pri_latency[3] == 0 && - dev_priv->display.wm.spr_latency[3] == 0 && - dev_priv->display.wm.cur_latency[3] == 0) + if (display->wm.pri_latency[3] == 0 && + display->wm.spr_latency[3] == 0 && + display->wm.cur_latency[3] == 0) return; - dev_priv->display.wm.pri_latency[3] = 0; - dev_priv->display.wm.spr_latency[3] = 0; - dev_priv->display.wm.cur_latency[3] = 0; + display->wm.pri_latency[3] = 0; + display->wm.spr_latency[3] = 0; + display->wm.cur_latency[3] = 0; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "LP3 watermarks disabled due to potential for lost interrupts\n"); - intel_print_wm_latency(dev_priv, "Primary", dev_priv->display.wm.pri_latency); - intel_print_wm_latency(dev_priv, "Sprite", dev_priv->display.wm.spr_latency); - intel_print_wm_latency(dev_priv, "Cursor", dev_priv->display.wm.cur_latency); + intel_print_wm_latency(display, "Primary", display->wm.pri_latency); + intel_print_wm_latency(display, "Sprite", display->wm.spr_latency); + intel_print_wm_latency(display, "Cursor", display->wm.cur_latency); } -static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv) +static void ilk_setup_wm_latency(struct intel_display *display) { - if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) - hsw_read_wm_latency(dev_priv, dev_priv->display.wm.pri_latency); - else if (DISPLAY_VER(dev_priv) >= 6) - snb_read_wm_latency(dev_priv, dev_priv->display.wm.pri_latency); + if (display->platform.broadwell || display->platform.haswell) + hsw_read_wm_latency(display, display->wm.pri_latency); + else if (DISPLAY_VER(display) >= 6) + snb_read_wm_latency(display, display->wm.pri_latency); else - ilk_read_wm_latency(dev_priv, dev_priv->display.wm.pri_latency); + ilk_read_wm_latency(display, display->wm.pri_latency); - memcpy(dev_priv->display.wm.spr_latency, dev_priv->display.wm.pri_latency, - sizeof(dev_priv->display.wm.pri_latency)); - memcpy(dev_priv->display.wm.cur_latency, dev_priv->display.wm.pri_latency, - sizeof(dev_priv->display.wm.pri_latency)); + memcpy(display->wm.spr_latency, display->wm.pri_latency, + sizeof(display->wm.pri_latency)); + memcpy(display->wm.cur_latency, display->wm.pri_latency, + sizeof(display->wm.pri_latency)); - intel_fixup_spr_wm_latency(dev_priv, dev_priv->display.wm.spr_latency); - intel_fixup_cur_wm_latency(dev_priv, dev_priv->display.wm.cur_latency); + intel_fixup_spr_wm_latency(display, display->wm.spr_latency); + intel_fixup_cur_wm_latency(display, display->wm.cur_latency); - intel_print_wm_latency(dev_priv, "Primary", dev_priv->display.wm.pri_latency); - intel_print_wm_latency(dev_priv, "Sprite", dev_priv->display.wm.spr_latency); - intel_print_wm_latency(dev_priv, "Cursor", dev_priv->display.wm.cur_latency); + intel_print_wm_latency(display, "Primary", display->wm.pri_latency); + intel_print_wm_latency(display, "Sprite", display->wm.spr_latency); + intel_print_wm_latency(display, "Cursor", display->wm.cur_latency); - if (DISPLAY_VER(dev_priv) == 6) { - snb_wm_latency_quirk(dev_priv); - snb_wm_lp3_irq_quirk(dev_priv); + if (DISPLAY_VER(display) == 6) { + snb_wm_latency_quirk(display); + snb_wm_lp3_irq_quirk(display); } } -static bool ilk_validate_pipe_wm(struct drm_i915_private *dev_priv, +static bool ilk_validate_pipe_wm(struct intel_display *display, struct intel_pipe_wm *pipe_wm) { /* LP0 watermark maximums depend on this pipe alone */ @@ -2901,11 +2899,11 @@ static bool ilk_validate_pipe_wm(struct drm_i915_private *dev_priv, struct ilk_wm_maximums max; /* LP0 watermarks always use 1/2 DDB partitioning */ - ilk_compute_wm_maximums(dev_priv, 0, &config, INTEL_DDB_PART_1_2, &max); + ilk_compute_wm_maximums(display, 0, &config, INTEL_DDB_PART_1_2, &max); /* At least LP0 must be valid */ - if (!ilk_validate_wm_level(dev_priv, 0, &max, &pipe_wm->wm[0])) { - drm_dbg_kms(&dev_priv->drm, "LP0 watermark invalid\n"); + if (!ilk_validate_wm_level(display, 0, &max, &pipe_wm->wm[0])) { + drm_dbg_kms(display->drm, "LP0 watermark invalid\n"); return false; } @@ -2916,7 +2914,7 @@ static bool ilk_validate_pipe_wm(struct drm_i915_private *dev_priv, static int ilk_compute_pipe_wm(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_pipe_wm *pipe_wm; @@ -2943,10 +2941,10 @@ static int ilk_compute_pipe_wm(struct intel_atomic_state *state, pipe_wm->sprites_enabled = crtc_state->active_planes & BIT(PLANE_SPRITE0); pipe_wm->sprites_scaled = crtc_state->scaled_planes & BIT(PLANE_SPRITE0); - usable_level = dev_priv->display.wm.num_levels - 1; + usable_level = display->wm.num_levels - 1; /* ILK/SNB: LP2+ watermarks only w/o sprites */ - if (DISPLAY_VER(dev_priv) < 7 && pipe_wm->sprites_enabled) + if (DISPLAY_VER(display) < 7 && pipe_wm->sprites_enabled) usable_level = 1; /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ @@ -2954,18 +2952,18 @@ static int ilk_compute_pipe_wm(struct intel_atomic_state *state, usable_level = 0; memset(&pipe_wm->wm, 0, sizeof(pipe_wm->wm)); - ilk_compute_wm_level(dev_priv, crtc, 0, crtc_state, + ilk_compute_wm_level(display, crtc, 0, crtc_state, pristate, sprstate, curstate, &pipe_wm->wm[0]); - if (!ilk_validate_pipe_wm(dev_priv, pipe_wm)) + if (!ilk_validate_pipe_wm(display, pipe_wm)) return -EINVAL; - ilk_compute_wm_reg_maximums(dev_priv, 1, &max); + ilk_compute_wm_reg_maximums(display, 1, &max); for (level = 1; level <= usable_level; level++) { struct intel_wm_level *wm = &pipe_wm->wm[level]; - ilk_compute_wm_level(dev_priv, crtc, level, crtc_state, + ilk_compute_wm_level(display, crtc, level, crtc_state, pristate, sprstate, curstate, wm); /* @@ -2973,7 +2971,7 @@ static int ilk_compute_pipe_wm(struct intel_atomic_state *state, * register maximums since such watermarks are * always invalid. */ - if (!ilk_validate_wm_level(dev_priv, level, &max, wm)) { + if (!ilk_validate_wm_level(display, level, &max, wm)) { memset(wm, 0, sizeof(*wm)); break; } @@ -2990,7 +2988,7 @@ static int ilk_compute_pipe_wm(struct intel_atomic_state *state, static int ilk_compute_intermediate_wm(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_crtc_state *old_crtc_state = @@ -3015,7 +3013,7 @@ static int ilk_compute_intermediate_wm(struct intel_atomic_state *state, intermediate->sprites_enabled |= active->sprites_enabled; intermediate->sprites_scaled |= active->sprites_scaled; - for (level = 0; level < dev_priv->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { struct intel_wm_level *intermediate_wm = &intermediate->wm[level]; const struct intel_wm_level *active_wm = &active->wm[level]; @@ -3036,7 +3034,7 @@ static int ilk_compute_intermediate_wm(struct intel_atomic_state *state, * there's no safe way to transition from the old state to * the new state, so we need to fail the atomic transaction. */ - if (!ilk_validate_pipe_wm(dev_priv, intermediate)) + if (!ilk_validate_pipe_wm(display, intermediate)) return -EINVAL; /* @@ -3068,7 +3066,7 @@ static int ilk_compute_watermarks(struct intel_atomic_state *state, /* * Merge the watermarks from all active pipes for a specific level. */ -static void ilk_merge_wm_level(struct drm_i915_private *dev_priv, +static void ilk_merge_wm_level(struct intel_display *display, int level, struct intel_wm_level *ret_wm) { @@ -3076,7 +3074,7 @@ static void ilk_merge_wm_level(struct drm_i915_private *dev_priv, ret_wm->enable = true; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct intel_pipe_wm *active = &crtc->wm.active.ilk; const struct intel_wm_level *wm = &active->wm[level]; @@ -3101,31 +3099,31 @@ static void ilk_merge_wm_level(struct drm_i915_private *dev_priv, /* * Merge all low power watermarks for all active pipes. */ -static void ilk_wm_merge(struct drm_i915_private *dev_priv, +static void ilk_wm_merge(struct intel_display *display, const struct intel_wm_config *config, const struct ilk_wm_maximums *max, struct intel_pipe_wm *merged) { - int level, num_levels = dev_priv->display.wm.num_levels; + int level, num_levels = display->wm.num_levels; int last_enabled_level = num_levels - 1; /* ILK/SNB/IVB: LP1+ watermarks only w/ single pipe */ - if ((DISPLAY_VER(dev_priv) < 7 || IS_IVYBRIDGE(dev_priv)) && + if ((DISPLAY_VER(display) < 7 || display->platform.ivybridge) && config->num_pipes_active > 1) last_enabled_level = 0; /* ILK: FBC WM must be disabled always */ - merged->fbc_wm_enabled = DISPLAY_VER(dev_priv) >= 6; + merged->fbc_wm_enabled = DISPLAY_VER(display) >= 6; /* merge each WM1+ level */ for (level = 1; level < num_levels; level++) { struct intel_wm_level *wm = &merged->wm[level]; - ilk_merge_wm_level(dev_priv, level, wm); + ilk_merge_wm_level(display, level, wm); if (level > last_enabled_level) wm->enable = false; - else if (!ilk_validate_wm_level(dev_priv, level, max, wm)) + else if (!ilk_validate_wm_level(display, level, max, wm)) /* make sure all following levels get disabled */ last_enabled_level = level - 1; @@ -3141,8 +3139,8 @@ static void ilk_wm_merge(struct drm_i915_private *dev_priv, } /* ILK: LP2+ must be disabled when FBC WM is disabled but FBC enabled */ - if (DISPLAY_VER(dev_priv) == 5 && HAS_FBC(dev_priv) && - dev_priv->display.params.enable_fbc && !merged->fbc_wm_enabled) { + if (DISPLAY_VER(display) == 5 && HAS_FBC(display) && + display->params.enable_fbc && !merged->fbc_wm_enabled) { for (level = 2; level < num_levels; level++) { struct intel_wm_level *wm = &merged->wm[level]; @@ -3158,16 +3156,16 @@ static int ilk_wm_lp_to_level(int wm_lp, const struct intel_pipe_wm *pipe_wm) } /* The value we need to program into the WM_LPx latency field */ -static unsigned int ilk_wm_lp_latency(struct drm_i915_private *dev_priv, +static unsigned int ilk_wm_lp_latency(struct intel_display *display, int level) { - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) + if (display->platform.haswell || display->platform.broadwell) return 2 * level; else - return dev_priv->display.wm.pri_latency[level]; + return display->wm.pri_latency[level]; } -static void ilk_compute_wm_results(struct drm_i915_private *dev_priv, +static void ilk_compute_wm_results(struct intel_display *display, const struct intel_pipe_wm *merged, enum intel_ddb_partitioning partitioning, struct ilk_wm_values *results) @@ -3191,14 +3189,14 @@ static void ilk_compute_wm_results(struct drm_i915_private *dev_priv, * disabled. Doing otherwise could cause underruns. */ results->wm_lp[wm_lp - 1] = - WM_LP_LATENCY(ilk_wm_lp_latency(dev_priv, level)) | + WM_LP_LATENCY(ilk_wm_lp_latency(display, level)) | WM_LP_PRIMARY(r->pri_val) | WM_LP_CURSOR(r->cur_val); if (r->enable) results->wm_lp[wm_lp - 1] |= WM_LP_ENABLE; - if (DISPLAY_VER(dev_priv) >= 8) + if (DISPLAY_VER(display) >= 8) results->wm_lp[wm_lp - 1] |= WM_LP_FBC_BDW(r->fbc_val); else results->wm_lp[wm_lp - 1] |= WM_LP_FBC_ILK(r->fbc_val); @@ -3209,19 +3207,19 @@ static void ilk_compute_wm_results(struct drm_i915_private *dev_priv, * Always set WM_LP_SPRITE_EN when spr_val != 0, even if the * level is disabled. Doing otherwise could cause underruns. */ - if (DISPLAY_VER(dev_priv) < 7 && r->spr_val) { - drm_WARN_ON(&dev_priv->drm, wm_lp != 1); + if (DISPLAY_VER(display) < 7 && r->spr_val) { + drm_WARN_ON(display->drm, wm_lp != 1); results->wm_lp_spr[wm_lp - 1] |= WM_LP_SPRITE_ENABLE; } } /* LP0 register values */ - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { enum pipe pipe = crtc->pipe; const struct intel_pipe_wm *pipe_wm = &crtc->wm.active.ilk; const struct intel_wm_level *r = &pipe_wm->wm[0]; - if (drm_WARN_ON(&dev_priv->drm, !r->enable)) + if (drm_WARN_ON(display->drm, !r->enable)) continue; results->wm_pipe[pipe] = @@ -3236,13 +3234,13 @@ static void ilk_compute_wm_results(struct drm_i915_private *dev_priv, * case both are at the same level. Prefer r1 in case they're the same. */ static struct intel_pipe_wm * -ilk_find_best_result(struct drm_i915_private *dev_priv, +ilk_find_best_result(struct intel_display *display, struct intel_pipe_wm *r1, struct intel_pipe_wm *r2) { int level, level1 = 0, level2 = 0; - for (level = 1; level < dev_priv->display.wm.num_levels; level++) { + for (level = 1; level < display->wm.num_levels; level++) { if (r1->wm[level].enable) level1 = level; if (r2->wm[level].enable) @@ -3268,7 +3266,7 @@ ilk_find_best_result(struct drm_i915_private *dev_priv, #define WM_DIRTY_FBC (1 << 24) #define WM_DIRTY_DDB (1 << 25) -static unsigned int ilk_compute_wm_dirty(struct drm_i915_private *dev_priv, +static unsigned int ilk_compute_wm_dirty(struct intel_display *display, const struct ilk_wm_values *old, const struct ilk_wm_values *new) { @@ -3276,7 +3274,7 @@ static unsigned int ilk_compute_wm_dirty(struct drm_i915_private *dev_priv, enum pipe pipe; int wm_lp; - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { if (old->wm_pipe[pipe] != new->wm_pipe[pipe]) { dirty |= WM_DIRTY_PIPE(pipe); /* Must disable LP1+ watermarks too */ @@ -3314,25 +3312,25 @@ static unsigned int ilk_compute_wm_dirty(struct drm_i915_private *dev_priv, return dirty; } -static bool _ilk_disable_lp_wm(struct drm_i915_private *dev_priv, +static bool _ilk_disable_lp_wm(struct intel_display *display, unsigned int dirty) { - struct ilk_wm_values *previous = &dev_priv->display.wm.hw; + struct ilk_wm_values *previous = &display->wm.hw; bool changed = false; if (dirty & WM_DIRTY_LP(3) && previous->wm_lp[2] & WM_LP_ENABLE) { previous->wm_lp[2] &= ~WM_LP_ENABLE; - intel_uncore_write(&dev_priv->uncore, WM3_LP_ILK, previous->wm_lp[2]); + intel_de_write(display, WM3_LP_ILK, previous->wm_lp[2]); changed = true; } if (dirty & WM_DIRTY_LP(2) && previous->wm_lp[1] & WM_LP_ENABLE) { previous->wm_lp[1] &= ~WM_LP_ENABLE; - intel_uncore_write(&dev_priv->uncore, WM2_LP_ILK, previous->wm_lp[1]); + intel_de_write(display, WM2_LP_ILK, previous->wm_lp[1]); changed = true; } if (dirty & WM_DIRTY_LP(1) && previous->wm_lp[0] & WM_LP_ENABLE) { previous->wm_lp[0] &= ~WM_LP_ENABLE; - intel_uncore_write(&dev_priv->uncore, WM1_LP_ILK, previous->wm_lp[0]); + intel_de_write(display, WM1_LP_ILK, previous->wm_lp[0]); changed = true; } @@ -3348,73 +3346,73 @@ static bool _ilk_disable_lp_wm(struct drm_i915_private *dev_priv, * The spec says we shouldn't write when we don't need, because every write * causes WMs to be re-evaluated, expending some power. */ -static void ilk_write_wm_values(struct drm_i915_private *dev_priv, +static void ilk_write_wm_values(struct intel_display *display, struct ilk_wm_values *results) { - struct ilk_wm_values *previous = &dev_priv->display.wm.hw; + struct ilk_wm_values *previous = &display->wm.hw; unsigned int dirty; - dirty = ilk_compute_wm_dirty(dev_priv, previous, results); + dirty = ilk_compute_wm_dirty(display, previous, results); if (!dirty) return; - _ilk_disable_lp_wm(dev_priv, dirty); + _ilk_disable_lp_wm(display, dirty); if (dirty & WM_DIRTY_PIPE(PIPE_A)) - intel_uncore_write(&dev_priv->uncore, WM0_PIPE_ILK(PIPE_A), results->wm_pipe[0]); + intel_de_write(display, WM0_PIPE_ILK(PIPE_A), results->wm_pipe[0]); if (dirty & WM_DIRTY_PIPE(PIPE_B)) - intel_uncore_write(&dev_priv->uncore, WM0_PIPE_ILK(PIPE_B), results->wm_pipe[1]); + intel_de_write(display, WM0_PIPE_ILK(PIPE_B), results->wm_pipe[1]); if (dirty & WM_DIRTY_PIPE(PIPE_C)) - intel_uncore_write(&dev_priv->uncore, WM0_PIPE_ILK(PIPE_C), results->wm_pipe[2]); + intel_de_write(display, WM0_PIPE_ILK(PIPE_C), results->wm_pipe[2]); if (dirty & WM_DIRTY_DDB) { - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) - intel_uncore_rmw(&dev_priv->uncore, WM_MISC, WM_MISC_DATA_PARTITION_5_6, - results->partitioning == INTEL_DDB_PART_1_2 ? 0 : - WM_MISC_DATA_PARTITION_5_6); + if (display->platform.haswell || display->platform.broadwell) + intel_de_rmw(display, WM_MISC, WM_MISC_DATA_PARTITION_5_6, + results->partitioning == INTEL_DDB_PART_1_2 ? 0 : + WM_MISC_DATA_PARTITION_5_6); else - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL2, DISP_DATA_PARTITION_5_6, - results->partitioning == INTEL_DDB_PART_1_2 ? 0 : - DISP_DATA_PARTITION_5_6); + intel_de_rmw(display, DISP_ARB_CTL2, DISP_DATA_PARTITION_5_6, + results->partitioning == INTEL_DDB_PART_1_2 ? 0 : + DISP_DATA_PARTITION_5_6); } if (dirty & WM_DIRTY_FBC) - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, DISP_FBC_WM_DIS, - results->enable_fbc_wm ? 0 : DISP_FBC_WM_DIS); + intel_de_rmw(display, DISP_ARB_CTL, DISP_FBC_WM_DIS, + results->enable_fbc_wm ? 0 : DISP_FBC_WM_DIS); if (dirty & WM_DIRTY_LP(1) && previous->wm_lp_spr[0] != results->wm_lp_spr[0]) - intel_uncore_write(&dev_priv->uncore, WM1S_LP_ILK, results->wm_lp_spr[0]); + intel_de_write(display, WM1S_LP_ILK, results->wm_lp_spr[0]); - if (DISPLAY_VER(dev_priv) >= 7) { + if (DISPLAY_VER(display) >= 7) { if (dirty & WM_DIRTY_LP(2) && previous->wm_lp_spr[1] != results->wm_lp_spr[1]) - intel_uncore_write(&dev_priv->uncore, WM2S_LP_IVB, results->wm_lp_spr[1]); + intel_de_write(display, WM2S_LP_IVB, results->wm_lp_spr[1]); if (dirty & WM_DIRTY_LP(3) && previous->wm_lp_spr[2] != results->wm_lp_spr[2]) - intel_uncore_write(&dev_priv->uncore, WM3S_LP_IVB, results->wm_lp_spr[2]); + intel_de_write(display, WM3S_LP_IVB, results->wm_lp_spr[2]); } if (dirty & WM_DIRTY_LP(1) && previous->wm_lp[0] != results->wm_lp[0]) - intel_uncore_write(&dev_priv->uncore, WM1_LP_ILK, results->wm_lp[0]); + intel_de_write(display, WM1_LP_ILK, results->wm_lp[0]); if (dirty & WM_DIRTY_LP(2) && previous->wm_lp[1] != results->wm_lp[1]) - intel_uncore_write(&dev_priv->uncore, WM2_LP_ILK, results->wm_lp[1]); + intel_de_write(display, WM2_LP_ILK, results->wm_lp[1]); if (dirty & WM_DIRTY_LP(3) && previous->wm_lp[2] != results->wm_lp[2]) - intel_uncore_write(&dev_priv->uncore, WM3_LP_ILK, results->wm_lp[2]); + intel_de_write(display, WM3_LP_ILK, results->wm_lp[2]); - dev_priv->display.wm.hw = *results; + display->wm.hw = *results; } -bool ilk_disable_cxsr(struct drm_i915_private *dev_priv) +bool ilk_disable_cxsr(struct intel_display *display) { - return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL); + return _ilk_disable_lp_wm(display, WM_DIRTY_LP_ALL); } -static void ilk_compute_wm_config(struct drm_i915_private *dev_priv, +static void ilk_compute_wm_config(struct intel_display *display, struct intel_wm_config *config) { struct intel_crtc *crtc; /* Compute the currently _active_ config */ - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct intel_pipe_wm *wm = &crtc->wm.active.ilk; if (!wm->pipe_enabled) @@ -3426,7 +3424,7 @@ static void ilk_compute_wm_config(struct drm_i915_private *dev_priv, } } -static void ilk_program_watermarks(struct drm_i915_private *dev_priv) +static void ilk_program_watermarks(struct intel_display *display) { struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; struct ilk_wm_maximums max; @@ -3434,18 +3432,18 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv) struct ilk_wm_values results = {}; enum intel_ddb_partitioning partitioning; - ilk_compute_wm_config(dev_priv, &config); + ilk_compute_wm_config(display, &config); - ilk_compute_wm_maximums(dev_priv, 1, &config, INTEL_DDB_PART_1_2, &max); - ilk_wm_merge(dev_priv, &config, &max, &lp_wm_1_2); + ilk_compute_wm_maximums(display, 1, &config, INTEL_DDB_PART_1_2, &max); + ilk_wm_merge(display, &config, &max, &lp_wm_1_2); /* 5/6 split only in single pipe config on IVB+ */ - if (DISPLAY_VER(dev_priv) >= 7 && + if (DISPLAY_VER(display) >= 7 && config.num_pipes_active == 1 && config.sprites_enabled) { - ilk_compute_wm_maximums(dev_priv, 1, &config, INTEL_DDB_PART_5_6, &max); - ilk_wm_merge(dev_priv, &config, &max, &lp_wm_5_6); + ilk_compute_wm_maximums(display, 1, &config, INTEL_DDB_PART_5_6, &max); + ilk_wm_merge(display, &config, &max, &lp_wm_5_6); - best_lp_wm = ilk_find_best_result(dev_priv, &lp_wm_1_2, &lp_wm_5_6); + best_lp_wm = ilk_find_best_result(display, &lp_wm_1_2, &lp_wm_5_6); } else { best_lp_wm = &lp_wm_1_2; } @@ -3453,50 +3451,49 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv) partitioning = (best_lp_wm == &lp_wm_1_2) ? INTEL_DDB_PART_1_2 : INTEL_DDB_PART_5_6; - ilk_compute_wm_results(dev_priv, best_lp_wm, partitioning, &results); + ilk_compute_wm_results(display, best_lp_wm, partitioning, &results); - ilk_write_wm_values(dev_priv, &results); + ilk_write_wm_values(display, &results); } static void ilk_initial_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); crtc->wm.active.ilk = crtc_state->wm.ilk.intermediate; - ilk_program_watermarks(dev_priv); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + ilk_program_watermarks(display); + mutex_unlock(&display->wm.wm_mutex); } static void ilk_optimize_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); if (!crtc_state->wm.need_postvbl_update) return; - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); crtc->wm.active.ilk = crtc_state->wm.ilk.optimal; - ilk_program_watermarks(dev_priv); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + ilk_program_watermarks(display); + mutex_unlock(&display->wm.wm_mutex); } static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct ilk_wm_values *hw = &dev_priv->display.wm.hw; + struct intel_display *display = to_intel_display(crtc); + struct ilk_wm_values *hw = &display->wm.hw; struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_pipe_wm *active = &crtc_state->wm.ilk.optimal; enum pipe pipe = crtc->pipe; - hw->wm_pipe[pipe] = intel_uncore_read(&dev_priv->uncore, WM0_PIPE_ILK(pipe)); + hw->wm_pipe[pipe] = intel_de_read(display, WM0_PIPE_ILK(pipe)); memset(active, 0, sizeof(*active)); @@ -3523,7 +3520,7 @@ static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc) * should be marked as enabled but zeroed, * which is what we'd compute them to. */ - for (level = 0; level < dev_priv->display.wm.num_levels; level++) + for (level = 0; level < display->wm.num_levels; level++) active->wm[level].enable = true; } @@ -3572,7 +3569,7 @@ static int ilk_sanitize_watermarks_add_affected(struct drm_atomic_state *state) * through the atomic check code to calculate new watermark values in the * state object. */ -void ilk_wm_sanitize(struct drm_i915_private *dev_priv) +void ilk_wm_sanitize(struct intel_display *display) { struct drm_atomic_state *state; struct intel_atomic_state *intel_state; @@ -3583,14 +3580,14 @@ void ilk_wm_sanitize(struct drm_i915_private *dev_priv) int i; /* Only supported on platforms that use atomic watermark design */ - if (!dev_priv->display.funcs.wm->optimize_watermarks) + if (!display->funcs.wm->optimize_watermarks) return; - if (drm_WARN_ON(&dev_priv->drm, DISPLAY_VER(dev_priv) >= 9)) + if (drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 9)) return; - state = drm_atomic_state_alloc(&dev_priv->drm); - if (drm_WARN_ON(&dev_priv->drm, !state)) + state = drm_atomic_state_alloc(display->drm); + if (drm_WARN_ON(display->drm, !state)) return; intel_state = to_intel_atomic_state(state); @@ -3606,14 +3603,14 @@ void ilk_wm_sanitize(struct drm_i915_private *dev_priv) * intermediate watermarks (since we don't trust the current * watermarks). */ - if (!HAS_GMCH(dev_priv)) + if (!HAS_GMCH(display)) intel_state->skip_intermediate_wm = true; ret = ilk_sanitize_watermarks_add_affected(state); if (ret) goto fail; - ret = intel_atomic_check(&dev_priv->drm, state); + ret = intel_atomic_check(display->drm, state); if (ret) goto fail; @@ -3643,7 +3640,7 @@ void ilk_wm_sanitize(struct drm_i915_private *dev_priv) * If this actually happens, we'll have to just leave the * BIOS-programmed watermarks untouched and hope for the best. */ - drm_WARN(&dev_priv->drm, ret, + drm_WARN(display->drm, ret, "Could not determine valid watermarks for inherited state\n"); drm_atomic_state_put(state); @@ -3657,18 +3654,18 @@ void ilk_wm_sanitize(struct drm_i915_private *dev_priv) #define _FW_WM_VLV(value, plane) \ (((value) & DSPFW_ ## plane ## _MASK_VLV) >> DSPFW_ ## plane ## _SHIFT) -static void g4x_read_wm_values(struct drm_i915_private *dev_priv, +static void g4x_read_wm_values(struct intel_display *display, struct g4x_wm_values *wm) { u32 tmp; - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1(dev_priv)); + tmp = intel_de_read(display, DSPFW1(display)); wm->sr.plane = _FW_WM(tmp, SR); wm->pipe[PIPE_B].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORB); wm->pipe[PIPE_B].plane[PLANE_PRIMARY] = _FW_WM(tmp, PLANEB); wm->pipe[PIPE_A].plane[PLANE_PRIMARY] = _FW_WM(tmp, PLANEA); - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2(dev_priv)); + tmp = intel_de_read(display, DSPFW2(display)); wm->fbc_en = tmp & DSPFW_FBC_SR_EN; wm->sr.fbc = _FW_WM(tmp, FBC_SR); wm->hpll.fbc = _FW_WM(tmp, FBC_HPLL_SR); @@ -3676,21 +3673,21 @@ static void g4x_read_wm_values(struct drm_i915_private *dev_priv, wm->pipe[PIPE_A].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORA); wm->pipe[PIPE_A].plane[PLANE_SPRITE0] = _FW_WM(tmp, SPRITEA); - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv)); + tmp = intel_de_read(display, DSPFW3(display)); wm->hpll_en = tmp & DSPFW_HPLL_SR_EN; wm->sr.cursor = _FW_WM(tmp, CURSOR_SR); wm->hpll.cursor = _FW_WM(tmp, HPLL_CURSOR); wm->hpll.plane = _FW_WM(tmp, HPLL_SR); } -static void vlv_read_wm_values(struct drm_i915_private *dev_priv, +static void vlv_read_wm_values(struct intel_display *display, struct vlv_wm_values *wm) { enum pipe pipe; u32 tmp; - for_each_pipe(dev_priv, pipe) { - tmp = intel_uncore_read(&dev_priv->uncore, VLV_DDL(pipe)); + for_each_pipe(display, pipe) { + tmp = intel_de_read(display, VLV_DDL(pipe)); wm->ddl[pipe].plane[PLANE_PRIMARY] = (tmp >> DDL_PLANE_SHIFT) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK); @@ -3702,34 +3699,34 @@ static void vlv_read_wm_values(struct drm_i915_private *dev_priv, (tmp >> DDL_SPRITE_SHIFT(1)) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK); } - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1(dev_priv)); + tmp = intel_de_read(display, DSPFW1(display)); wm->sr.plane = _FW_WM(tmp, SR); wm->pipe[PIPE_B].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORB); wm->pipe[PIPE_B].plane[PLANE_PRIMARY] = _FW_WM_VLV(tmp, PLANEB); wm->pipe[PIPE_A].plane[PLANE_PRIMARY] = _FW_WM_VLV(tmp, PLANEA); - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2(dev_priv)); + tmp = intel_de_read(display, DSPFW2(display)); wm->pipe[PIPE_A].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITEB); wm->pipe[PIPE_A].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORA); wm->pipe[PIPE_A].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEA); - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv)); + tmp = intel_de_read(display, DSPFW3(display)); wm->sr.cursor = _FW_WM(tmp, CURSOR_SR); - if (IS_CHERRYVIEW(dev_priv)) { - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW7_CHV); + if (display->platform.cherryview) { + tmp = intel_de_read(display, DSPFW7_CHV); wm->pipe[PIPE_B].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITED); wm->pipe[PIPE_B].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEC); - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW8_CHV); + tmp = intel_de_read(display, DSPFW8_CHV); wm->pipe[PIPE_C].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITEF); wm->pipe[PIPE_C].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEE); - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW9_CHV); + tmp = intel_de_read(display, DSPFW9_CHV); wm->pipe[PIPE_C].plane[PLANE_PRIMARY] = _FW_WM_VLV(tmp, PLANEC); wm->pipe[PIPE_C].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORC); - tmp = intel_uncore_read(&dev_priv->uncore, DSPHOWM); + tmp = intel_de_read(display, DSPHOWM); wm->sr.plane |= _FW_WM(tmp, SR_HI) << 9; wm->pipe[PIPE_C].plane[PLANE_SPRITE1] |= _FW_WM(tmp, SPRITEF_HI) << 8; wm->pipe[PIPE_C].plane[PLANE_SPRITE0] |= _FW_WM(tmp, SPRITEE_HI) << 8; @@ -3741,11 +3738,11 @@ static void vlv_read_wm_values(struct drm_i915_private *dev_priv, wm->pipe[PIPE_A].plane[PLANE_SPRITE0] |= _FW_WM(tmp, SPRITEA_HI) << 8; wm->pipe[PIPE_A].plane[PLANE_PRIMARY] |= _FW_WM(tmp, PLANEA_HI) << 8; } else { - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW7); + tmp = intel_de_read(display, DSPFW7); wm->pipe[PIPE_B].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITED); wm->pipe[PIPE_B].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEC); - tmp = intel_uncore_read(&dev_priv->uncore, DSPHOWM); + tmp = intel_de_read(display, DSPHOWM); wm->sr.plane |= _FW_WM(tmp, SR_HI) << 9; wm->pipe[PIPE_B].plane[PLANE_SPRITE1] |= _FW_WM(tmp, SPRITED_HI) << 8; wm->pipe[PIPE_B].plane[PLANE_SPRITE0] |= _FW_WM(tmp, SPRITEC_HI) << 8; @@ -3759,16 +3756,16 @@ static void vlv_read_wm_values(struct drm_i915_private *dev_priv, #undef _FW_WM #undef _FW_WM_VLV -static void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv) +static void g4x_wm_get_hw_state(struct intel_display *display) { - struct g4x_wm_values *wm = &dev_priv->display.wm.g4x; + struct g4x_wm_values *wm = &display->wm.g4x; struct intel_crtc *crtc; - g4x_read_wm_values(dev_priv, wm); + g4x_read_wm_values(display, wm); - wm->cxsr = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF) & FW_BLC_SELF_EN; + wm->cxsr = intel_de_read(display, FW_BLC_SELF) & FW_BLC_SELF_EN; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct g4x_wm_state *active = &crtc->wm.active.g4x; @@ -3833,7 +3830,7 @@ static void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv) crtc_state->wm.g4x.optimal = *active; crtc_state->wm.g4x.intermediate = *active; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Initial watermarks: pipe %c, plane=%d, cursor=%d, sprite=%d\n", pipe_name(pipe), wm->pipe[pipe].plane[PLANE_PRIMARY], @@ -3841,26 +3838,25 @@ static void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv) wm->pipe[pipe].plane[PLANE_SPRITE0]); } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Initial SR watermarks: plane=%d, cursor=%d fbc=%d\n", wm->sr.plane, wm->sr.cursor, wm->sr.fbc); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Initial HPLL watermarks: plane=%d, SR cursor=%d fbc=%d\n", wm->hpll.plane, wm->hpll.cursor, wm->hpll.fbc); - drm_dbg_kms(&dev_priv->drm, "Initial SR=%s HPLL=%s FBC=%s\n", + drm_dbg_kms(display->drm, "Initial SR=%s HPLL=%s FBC=%s\n", str_yes_no(wm->cxsr), str_yes_no(wm->hpll_en), str_yes_no(wm->fbc_en)); } -static void g4x_wm_sanitize(struct drm_i915_private *dev_priv) +static void g4x_wm_sanitize(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; struct intel_plane *plane; struct intel_crtc *crtc; - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); - for_each_intel_plane(&dev_priv->drm, plane) { + for_each_intel_plane(display->drm, plane) { struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe); struct intel_crtc_state *crtc_state = @@ -3873,7 +3869,7 @@ static void g4x_wm_sanitize(struct drm_i915_private *dev_priv) if (plane_state->uapi.visible) continue; - for (level = 0; level < dev_priv->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.g4x.raw[level]; @@ -3884,36 +3880,37 @@ static void g4x_wm_sanitize(struct drm_i915_private *dev_priv) } } - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); int ret; ret = _g4x_compute_pipe_wm(crtc_state); - drm_WARN_ON(&dev_priv->drm, ret); + drm_WARN_ON(display->drm, ret); crtc_state->wm.g4x.intermediate = crtc_state->wm.g4x.optimal; crtc->wm.active.g4x = crtc_state->wm.g4x.optimal; } - g4x_program_watermarks(dev_priv); + g4x_program_watermarks(display); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + mutex_unlock(&display->wm.wm_mutex); } -static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) +static void vlv_wm_get_hw_state(struct intel_display *display) { - struct vlv_wm_values *wm = &dev_priv->display.wm.vlv; + struct drm_i915_private *dev_priv = to_i915(display->drm); + struct vlv_wm_values *wm = &display->wm.vlv; struct intel_crtc *crtc; u32 val; - vlv_read_wm_values(dev_priv, wm); + vlv_read_wm_values(display, wm); - wm->cxsr = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; + wm->cxsr = intel_de_read(display, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; wm->level = VLV_WM_LEVEL_PM2; - if (IS_CHERRYVIEW(dev_priv)) { + if (display->platform.cherryview) { vlv_punit_get(dev_priv); val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM); @@ -3935,10 +3932,10 @@ static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) & FORCE_DDR_FREQ_REQ_ACK) == 0, 3)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Punit not acking DDR DVFS request, " "assuming DDR DVFS is disabled\n"); - dev_priv->display.wm.num_levels = VLV_WM_LEVEL_PM5 + 1; + display->wm.num_levels = VLV_WM_LEVEL_PM5 + 1; } else { val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2); if ((val & FORCE_DDR_HIGH_FREQ) == 0) @@ -3948,7 +3945,7 @@ static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) vlv_punit_put(dev_priv); } - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct vlv_wm_state *active = &crtc->wm.active.vlv; @@ -3988,7 +3985,7 @@ static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) crtc_state->wm.vlv.optimal = *active; crtc_state->wm.vlv.intermediate = *active; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Initial watermarks: pipe %c, plane=%d, cursor=%d, sprite0=%d, sprite1=%d\n", pipe_name(pipe), wm->pipe[pipe].plane[PLANE_PRIMARY], @@ -3997,20 +3994,19 @@ static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) wm->pipe[pipe].plane[PLANE_SPRITE1]); } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Initial watermarks: SR plane=%d, SR cursor=%d level=%d cxsr=%d\n", wm->sr.plane, wm->sr.cursor, wm->level, wm->cxsr); } -static void vlv_wm_sanitize(struct drm_i915_private *dev_priv) +static void vlv_wm_sanitize(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; struct intel_plane *plane; struct intel_crtc *crtc; - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); - for_each_intel_plane(&dev_priv->drm, plane) { + for_each_intel_plane(display->drm, plane) { struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe); struct intel_crtc_state *crtc_state = @@ -4023,7 +4019,7 @@ static void vlv_wm_sanitize(struct drm_i915_private *dev_priv) if (plane_state->uapi.visible) continue; - for (level = 0; level < dev_priv->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.vlv.raw[level]; @@ -4031,33 +4027,33 @@ static void vlv_wm_sanitize(struct drm_i915_private *dev_priv) } } - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); int ret; ret = _vlv_compute_pipe_wm(crtc_state); - drm_WARN_ON(&dev_priv->drm, ret); + drm_WARN_ON(display->drm, ret); crtc_state->wm.vlv.intermediate = crtc_state->wm.vlv.optimal; crtc->wm.active.vlv = crtc_state->wm.vlv.optimal; } - vlv_program_watermarks(dev_priv); + vlv_program_watermarks(display); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + mutex_unlock(&display->wm.wm_mutex); } /* * FIXME should probably kill this and improve * the real watermark readout/sanitation instead */ -static void ilk_init_lp_watermarks(struct drm_i915_private *dev_priv) +static void ilk_init_lp_watermarks(struct intel_display *display) { - intel_uncore_rmw(&dev_priv->uncore, WM3_LP_ILK, WM_LP_ENABLE, 0); - intel_uncore_rmw(&dev_priv->uncore, WM2_LP_ILK, WM_LP_ENABLE, 0); - intel_uncore_rmw(&dev_priv->uncore, WM1_LP_ILK, WM_LP_ENABLE, 0); + intel_de_rmw(display, WM3_LP_ILK, WM_LP_ENABLE, 0); + intel_de_rmw(display, WM2_LP_ILK, WM_LP_ENABLE, 0); + intel_de_rmw(display, WM1_LP_ILK, WM_LP_ENABLE, 0); /* * Don't touch WM_LP_SPRITE_ENABLE here. @@ -4065,37 +4061,37 @@ static void ilk_init_lp_watermarks(struct drm_i915_private *dev_priv) */ } -static void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv) +static void ilk_wm_get_hw_state(struct intel_display *display) { - struct ilk_wm_values *hw = &dev_priv->display.wm.hw; + struct ilk_wm_values *hw = &display->wm.hw; struct intel_crtc *crtc; - ilk_init_lp_watermarks(dev_priv); + ilk_init_lp_watermarks(display); - for_each_intel_crtc(&dev_priv->drm, crtc) + for_each_intel_crtc(display->drm, crtc) ilk_pipe_wm_get_hw_state(crtc); - hw->wm_lp[0] = intel_uncore_read(&dev_priv->uncore, WM1_LP_ILK); - hw->wm_lp[1] = intel_uncore_read(&dev_priv->uncore, WM2_LP_ILK); - hw->wm_lp[2] = intel_uncore_read(&dev_priv->uncore, WM3_LP_ILK); + hw->wm_lp[0] = intel_de_read(display, WM1_LP_ILK); + hw->wm_lp[1] = intel_de_read(display, WM2_LP_ILK); + hw->wm_lp[2] = intel_de_read(display, WM3_LP_ILK); - hw->wm_lp_spr[0] = intel_uncore_read(&dev_priv->uncore, WM1S_LP_ILK); - if (DISPLAY_VER(dev_priv) >= 7) { - hw->wm_lp_spr[1] = intel_uncore_read(&dev_priv->uncore, WM2S_LP_IVB); - hw->wm_lp_spr[2] = intel_uncore_read(&dev_priv->uncore, WM3S_LP_IVB); + hw->wm_lp_spr[0] = intel_de_read(display, WM1S_LP_ILK); + if (DISPLAY_VER(display) >= 7) { + hw->wm_lp_spr[1] = intel_de_read(display, WM2S_LP_IVB); + hw->wm_lp_spr[2] = intel_de_read(display, WM3S_LP_IVB); } - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) - hw->partitioning = (intel_uncore_read(&dev_priv->uncore, WM_MISC) & + if (display->platform.haswell || display->platform.broadwell) + hw->partitioning = (intel_de_read(display, WM_MISC) & WM_MISC_DATA_PARTITION_5_6) ? INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2; - else if (IS_IVYBRIDGE(dev_priv)) - hw->partitioning = (intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL2) & + else if (display->platform.ivybridge) + hw->partitioning = (intel_de_read(display, DISP_ARB_CTL2) & DISP_DATA_PARTITION_5_6) ? INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2; hw->enable_fbc_wm = - !(intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) & DISP_FBC_WM_DIS); + !(intel_de_read(display, DISP_ARB_CTL) & DISP_FBC_WM_DIS); } static const struct intel_wm_funcs ilk_wm_funcs = { @@ -4145,39 +4141,41 @@ static const struct intel_wm_funcs i845_wm_funcs = { static const struct intel_wm_funcs nop_funcs = { }; -void i9xx_wm_init(struct drm_i915_private *dev_priv) +void i9xx_wm_init(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + /* For FIFO watermark updates */ if (HAS_PCH_SPLIT(dev_priv)) { - ilk_setup_wm_latency(dev_priv); - dev_priv->display.funcs.wm = &ilk_wm_funcs; - } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - vlv_setup_wm_latency(dev_priv); - dev_priv->display.funcs.wm = &vlv_wm_funcs; - } else if (IS_G4X(dev_priv)) { - g4x_setup_wm_latency(dev_priv); - dev_priv->display.funcs.wm = &g4x_wm_funcs; - } else if (IS_PINEVIEW(dev_priv)) { - if (!pnv_get_cxsr_latency(dev_priv)) { - drm_info(&dev_priv->drm, "Unknown FSB/MEM, disabling CxSR\n"); + ilk_setup_wm_latency(display); + display->funcs.wm = &ilk_wm_funcs; + } else if (display->platform.valleyview || display->platform.cherryview) { + vlv_setup_wm_latency(display); + display->funcs.wm = &vlv_wm_funcs; + } else if (display->platform.g4x) { + g4x_setup_wm_latency(display); + display->funcs.wm = &g4x_wm_funcs; + } else if (display->platform.pineview) { + if (!pnv_get_cxsr_latency(display)) { + drm_info(display->drm, "Unknown FSB/MEM, disabling CxSR\n"); /* Disable CxSR and never update its watermark again */ - intel_set_memory_cxsr(dev_priv, false); - dev_priv->display.funcs.wm = &nop_funcs; + intel_set_memory_cxsr(display, false); + display->funcs.wm = &nop_funcs; } else { - dev_priv->display.funcs.wm = &pnv_wm_funcs; + display->funcs.wm = &pnv_wm_funcs; } - } else if (DISPLAY_VER(dev_priv) == 4) { - dev_priv->display.funcs.wm = &i965_wm_funcs; - } else if (DISPLAY_VER(dev_priv) == 3) { - dev_priv->display.funcs.wm = &i9xx_wm_funcs; - } else if (DISPLAY_VER(dev_priv) == 2) { - if (INTEL_NUM_PIPES(dev_priv) == 1) - dev_priv->display.funcs.wm = &i845_wm_funcs; + } else if (DISPLAY_VER(display) == 4) { + display->funcs.wm = &i965_wm_funcs; + } else if (DISPLAY_VER(display) == 3) { + display->funcs.wm = &i9xx_wm_funcs; + } else if (DISPLAY_VER(display) == 2) { + if (INTEL_NUM_PIPES(display) == 1) + display->funcs.wm = &i845_wm_funcs; else - dev_priv->display.funcs.wm = &i9xx_wm_funcs; + display->funcs.wm = &i9xx_wm_funcs; } else { - drm_err(&dev_priv->drm, + drm_err(display->drm, "unexpected fall-through in %s\n", __func__); - dev_priv->display.funcs.wm = &nop_funcs; + display->funcs.wm = &nop_funcs; } } diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.h b/drivers/gpu/drm/i915/display/i9xx_wm.h index 06ac37c6c94b5b..7bb363b2a75638 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.h +++ b/drivers/gpu/drm/i915/display/i9xx_wm.h @@ -8,28 +8,28 @@ #include -struct drm_i915_private; struct intel_crtc_state; +struct intel_display; struct intel_plane_state; #ifdef I915 -bool ilk_disable_cxsr(struct drm_i915_private *i915); -void ilk_wm_sanitize(struct drm_i915_private *i915); -bool intel_set_memory_cxsr(struct drm_i915_private *i915, bool enable); -void i9xx_wm_init(struct drm_i915_private *i915); +bool ilk_disable_cxsr(struct intel_display *display); +void ilk_wm_sanitize(struct intel_display *display); +bool intel_set_memory_cxsr(struct intel_display *display, bool enable); +void i9xx_wm_init(struct intel_display *display); #else -static inline bool ilk_disable_cxsr(struct drm_i915_private *i915) +static inline bool ilk_disable_cxsr(struct intel_display *display) { return false; } -static inline void ilk_wm_sanitize(struct drm_i915_private *i915) +static inline void ilk_wm_sanitize(struct intel_display *display) { } -static inline bool intel_set_memory_cxsr(struct drm_i915_private *i915, bool enable) +static inline bool intel_set_memory_cxsr(struct intel_display *display, bool enable) { return false; } -static inline void i9xx_wm_init(struct drm_i915_private *i915) +static inline void i9xx_wm_init(struct intel_display *display) { } #endif diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 402b7b2e182967..ca7033251e916b 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "i915_reg.h" @@ -1826,107 +1827,56 @@ static const struct mipi_dsi_host_ops gen11_dsi_host_ops = { .transfer = gen11_dsi_host_transfer, }; -#define ICL_PREPARE_CNT_MAX 0x7 -#define ICL_CLK_ZERO_CNT_MAX 0xf -#define ICL_TRAIL_CNT_MAX 0x7 -#define ICL_TCLK_PRE_CNT_MAX 0x3 -#define ICL_TCLK_POST_CNT_MAX 0x7 -#define ICL_HS_ZERO_CNT_MAX 0xf -#define ICL_EXIT_ZERO_CNT_MAX 0x7 - static void icl_dphy_param_init(struct intel_dsi *intel_dsi) { - struct intel_display *display = to_intel_display(&intel_dsi->base); struct intel_connector *connector = intel_dsi->attached_connector; struct mipi_config *mipi_config = connector->panel.vbt.dsi.config; u32 tlpx_ns; - u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; - u32 ths_prepare_ns, tclk_trail_ns; - u32 hs_zero_cnt; - u32 tclk_pre_cnt; + u32 tclk_prepare_esc_clk, tclk_zero_esc_clk, tclk_pre_esc_clk; + u32 ths_prepare_esc_clk, ths_zero_esc_clk, ths_exit_esc_clk; tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); - tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail); - ths_prepare_ns = max(mipi_config->ths_prepare, - mipi_config->tclk_prepare); - /* - * prepare cnt in escape clocks - * this field represents a hexadecimal value with a precision - * of 1.2 – i.e. the most significant bit is the integer - * and the least significant 2 bits are fraction bits. - * so, the field can represent a range of 0.25 to 1.75 + * The clock and data lane prepare timing parameters are in expressed in + * units of 1/4 escape clocks, and all the other timings parameters in + * escape clocks. */ - prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * 4, tlpx_ns); - if (prepare_cnt > ICL_PREPARE_CNT_MAX) { - drm_dbg_kms(display->drm, "prepare_cnt out of range (%d)\n", - prepare_cnt); - prepare_cnt = ICL_PREPARE_CNT_MAX; - } + tclk_prepare_esc_clk = DIV_ROUND_UP(mipi_config->tclk_prepare * 4, tlpx_ns); + tclk_prepare_esc_clk = min(tclk_prepare_esc_clk, 7); - /* clk zero count in escape clocks */ - clk_zero_cnt = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero - - ths_prepare_ns, tlpx_ns); - if (clk_zero_cnt > ICL_CLK_ZERO_CNT_MAX) { - drm_dbg_kms(display->drm, - "clk_zero_cnt out of range (%d)\n", clk_zero_cnt); - clk_zero_cnt = ICL_CLK_ZERO_CNT_MAX; - } + tclk_zero_esc_clk = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero - + mipi_config->tclk_prepare, tlpx_ns); + tclk_zero_esc_clk = min(tclk_zero_esc_clk, 15); - /* trail cnt in escape clocks*/ - trail_cnt = DIV_ROUND_UP(tclk_trail_ns, tlpx_ns); - if (trail_cnt > ICL_TRAIL_CNT_MAX) { - drm_dbg_kms(display->drm, "trail_cnt out of range (%d)\n", - trail_cnt); - trail_cnt = ICL_TRAIL_CNT_MAX; - } + tclk_pre_esc_clk = DIV_ROUND_UP(mipi_config->tclk_pre, tlpx_ns); + tclk_pre_esc_clk = min(tclk_pre_esc_clk, 3); - /* tclk pre count in escape clocks */ - tclk_pre_cnt = DIV_ROUND_UP(mipi_config->tclk_pre, tlpx_ns); - if (tclk_pre_cnt > ICL_TCLK_PRE_CNT_MAX) { - drm_dbg_kms(display->drm, - "tclk_pre_cnt out of range (%d)\n", tclk_pre_cnt); - tclk_pre_cnt = ICL_TCLK_PRE_CNT_MAX; - } + ths_prepare_esc_clk = DIV_ROUND_UP(mipi_config->ths_prepare * 4, tlpx_ns); + ths_prepare_esc_clk = min(ths_prepare_esc_clk, 7); - /* hs zero cnt in escape clocks */ - hs_zero_cnt = DIV_ROUND_UP(mipi_config->ths_prepare_hszero - - ths_prepare_ns, tlpx_ns); - if (hs_zero_cnt > ICL_HS_ZERO_CNT_MAX) { - drm_dbg_kms(display->drm, "hs_zero_cnt out of range (%d)\n", - hs_zero_cnt); - hs_zero_cnt = ICL_HS_ZERO_CNT_MAX; - } + ths_zero_esc_clk = DIV_ROUND_UP(mipi_config->ths_prepare_hszero - + mipi_config->ths_prepare, tlpx_ns); + ths_zero_esc_clk = min(ths_zero_esc_clk, 15); - /* hs exit zero cnt in escape clocks */ - exit_zero_cnt = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns); - if (exit_zero_cnt > ICL_EXIT_ZERO_CNT_MAX) { - drm_dbg_kms(display->drm, - "exit_zero_cnt out of range (%d)\n", - exit_zero_cnt); - exit_zero_cnt = ICL_EXIT_ZERO_CNT_MAX; - } + ths_exit_esc_clk = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns); + ths_exit_esc_clk = min(ths_exit_esc_clk, 7); /* clock lane dphy timings */ intel_dsi->dphy_reg = (CLK_PREPARE_OVERRIDE | - CLK_PREPARE(prepare_cnt) | + CLK_PREPARE(tclk_prepare_esc_clk) | CLK_ZERO_OVERRIDE | - CLK_ZERO(clk_zero_cnt) | + CLK_ZERO(tclk_zero_esc_clk) | CLK_PRE_OVERRIDE | - CLK_PRE(tclk_pre_cnt) | - CLK_TRAIL_OVERRIDE | - CLK_TRAIL(trail_cnt)); + CLK_PRE(tclk_pre_esc_clk)); /* data lanes dphy timings */ intel_dsi->dphy_data_lane_reg = (HS_PREPARE_OVERRIDE | - HS_PREPARE(prepare_cnt) | + HS_PREPARE(ths_prepare_esc_clk) | HS_ZERO_OVERRIDE | - HS_ZERO(hs_zero_cnt) | - HS_TRAIL_OVERRIDE | - HS_TRAIL(trail_cnt) | + HS_ZERO(ths_zero_esc_clk) | HS_EXIT_OVERRIDE | - HS_EXIT(exit_zero_cnt)); + HS_EXIT(ths_exit_esc_clk)); intel_dsi_log_params(intel_dsi); } diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index 03dc54c802d3b3..e83feca5c9c9b5 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -33,16 +33,17 @@ #include #include #include +#include -#include "i915_drv.h" #include "intel_atomic.h" #include "intel_cdclk.h" +#include "intel_display_core.h" #include "intel_display_types.h" #include "intel_dp_tunnel.h" +#include "intel_fb.h" #include "intel_global_state.h" #include "intel_hdcp.h" #include "intel_psr.h" -#include "intel_fb.h" #include "skl_universal_plane.h" /** @@ -59,17 +60,16 @@ int intel_digital_connector_atomic_get_property(struct drm_connector *connector, struct drm_property *property, u64 *val) { - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(connector->dev); const struct intel_digital_connector_state *intel_conn_state = to_intel_digital_connector_state(state); - if (property == dev_priv->display.properties.force_audio) + if (property == display->properties.force_audio) *val = intel_conn_state->force_audio; - else if (property == dev_priv->display.properties.broadcast_rgb) + else if (property == display->properties.broadcast_rgb) *val = intel_conn_state->broadcast_rgb; else { - drm_dbg_atomic(&dev_priv->drm, + drm_dbg_atomic(display->drm, "Unknown property [PROP:%d:%s]\n", property->base.id, property->name); return -EINVAL; @@ -92,22 +92,21 @@ int intel_digital_connector_atomic_set_property(struct drm_connector *connector, struct drm_property *property, u64 val) { - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(connector->dev); struct intel_digital_connector_state *intel_conn_state = to_intel_digital_connector_state(state); - if (property == dev_priv->display.properties.force_audio) { + if (property == display->properties.force_audio) { intel_conn_state->force_audio = val; return 0; } - if (property == dev_priv->display.properties.broadcast_rgb) { + if (property == display->properties.broadcast_rgb) { intel_conn_state->broadcast_rgb = val; return 0; } - drm_dbg_atomic(&dev_priv->drm, "Unknown property [PROP:%d:%s]\n", + drm_dbg_atomic(display->drm, "Unknown property [PROP:%d:%s]\n", property->base.id, property->name); return -EINVAL; } diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c index 178dc6c8de80c5..4f3fa966c5372f 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -16,6 +16,7 @@ #include "intel_backlight_regs.h" #include "intel_connector.h" #include "intel_de.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dp_aux_backlight.h" #include "intel_dsi_dcs_backlight.h" @@ -901,11 +902,9 @@ static int intel_backlight_device_get_brightness(struct backlight_device *bd) { struct intel_connector *connector = bl_get_data(bd); struct intel_display *display = to_intel_display(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); - intel_wakeref_t wakeref; int ret = 0; - with_intel_runtime_pm(&i915->runtime_pm, wakeref) { + with_intel_display_rpm(display) { u32 hw_level; drm_modeset_lock(&display->drm->mode_config.connection_mutex, NULL); diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index a8d08d7d82b3db..fabfcf2caa69e7 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -37,6 +37,7 @@ #include "i915_drv.h" #include "intel_display.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_gmbus.h" @@ -3115,7 +3116,6 @@ static const struct vbt_header *intel_bios_get_vbt(struct intel_display *display { struct drm_i915_private *i915 = to_i915(display->drm); const struct vbt_header *vbt = NULL; - intel_wakeref_t wakeref; vbt = firmware_get_vbt(display, sizep); @@ -3127,11 +3127,11 @@ static const struct vbt_header *intel_bios_get_vbt(struct intel_display *display * through MMIO or PCI mapping */ if (!vbt && IS_DGFX(i915)) - with_intel_runtime_pm(&i915->runtime_pm, wakeref) + with_intel_display_rpm(display) vbt = oprom_get_vbt(display, intel_rom_spi(i915), sizep, "SPI flash"); if (!vbt) - with_intel_runtime_pm(&i915->runtime_pm, wakeref) + with_intel_display_rpm(display) vbt = oprom_get_vbt(display, intel_rom_pci(i915), sizep, "PCI ROM"); return vbt; diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 048be287224774..a5dd2932b852d6 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -39,14 +39,15 @@ struct intel_qgv_info { u8 deinterleave; }; -static int dg1_mchbar_read_qgv_point_info(struct drm_i915_private *dev_priv, +static int dg1_mchbar_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { + struct drm_i915_private *i915 = to_i915(display->drm); u32 dclk_ratio, dclk_reference; u32 val; - val = intel_uncore_read(&dev_priv->uncore, SA_PERF_STATUS_0_0_0_MCHBAR_PC); + val = intel_uncore_read(&i915->uncore, SA_PERF_STATUS_0_0_0_MCHBAR_PC); dclk_ratio = REG_FIELD_GET(DG1_QCLK_RATIO_MASK, val); if (val & DG1_QCLK_REFERENCE) dclk_reference = 6; /* 6 * 16.666 MHz = 100 MHz */ @@ -54,18 +55,18 @@ static int dg1_mchbar_read_qgv_point_info(struct drm_i915_private *dev_priv, dclk_reference = 8; /* 8 * 16.666 MHz = 133 MHz */ sp->dclk = DIV_ROUND_UP((16667 * dclk_ratio * dclk_reference) + 500, 1000); - val = intel_uncore_read(&dev_priv->uncore, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU); + val = intel_uncore_read(&i915->uncore, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU); if (val & DG1_GEAR_TYPE) sp->dclk *= 2; if (sp->dclk == 0) return -EINVAL; - val = intel_uncore_read(&dev_priv->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR); + val = intel_uncore_read(&i915->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR); sp->t_rp = REG_FIELD_GET(DG1_DRAM_T_RP_MASK, val); sp->t_rdpre = REG_FIELD_GET(DG1_DRAM_T_RDPRE_MASK, val); - val = intel_uncore_read(&dev_priv->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH); + val = intel_uncore_read(&i915->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH); sp->t_rcd = REG_FIELD_GET(DG1_DRAM_T_RCD_MASK, val); sp->t_ras = REG_FIELD_GET(DG1_DRAM_T_RAS_MASK, val); @@ -74,22 +75,23 @@ static int dg1_mchbar_read_qgv_point_info(struct drm_i915_private *dev_priv, return 0; } -static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv, +static int icl_pcode_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { + struct drm_i915_private *i915 = to_i915(display->drm); u32 val = 0, val2 = 0; u16 dclk; int ret; - ret = snb_pcode_read(&dev_priv->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | + ret = snb_pcode_read(&i915->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point), &val, &val2); if (ret) return ret; dclk = val & 0xffff; - sp->dclk = DIV_ROUND_UP((16667 * dclk) + (DISPLAY_VER(dev_priv) >= 12 ? 500 : 0), + sp->dclk = DIV_ROUND_UP((16667 * dclk) + (DISPLAY_VER(display) >= 12 ? 500 : 0), 1000); sp->t_rp = (val & 0xff0000) >> 16; sp->t_rcd = (val & 0xff000000) >> 24; @@ -102,14 +104,15 @@ static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv, return 0; } -static int adls_pcode_read_psf_gv_point_info(struct drm_i915_private *dev_priv, - struct intel_psf_gv_point *points) +static int adls_pcode_read_psf_gv_point_info(struct intel_display *display, + struct intel_psf_gv_point *points) { + struct drm_i915_private *i915 = to_i915(display->drm); u32 val = 0; int ret; int i; - ret = snb_pcode_read(&dev_priv->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | + ret = snb_pcode_read(&i915->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, &val, NULL); if (ret) return ret; @@ -122,10 +125,10 @@ static int adls_pcode_read_psf_gv_point_info(struct drm_i915_private *dev_priv, return 0; } -static u16 icl_qgv_points_mask(struct drm_i915_private *i915) +static u16 icl_qgv_points_mask(struct intel_display *display) { - unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; - unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; + unsigned int num_psf_gv_points = display->bw.max[0].num_psf_gv_points; + unsigned int num_qgv_points = display->bw.max[0].num_qgv_points; u16 qgv_points = 0, psf_points = 0; /* @@ -142,49 +145,51 @@ static u16 icl_qgv_points_mask(struct drm_i915_private *i915) return ICL_PCODE_REQ_QGV_PT(qgv_points) | ADLS_PCODE_REQ_PSF_PT(psf_points); } -static bool is_sagv_enabled(struct drm_i915_private *i915, u16 points_mask) +static bool is_sagv_enabled(struct intel_display *display, u16 points_mask) { - return !is_power_of_2(~points_mask & icl_qgv_points_mask(i915) & + return !is_power_of_2(~points_mask & icl_qgv_points_mask(display) & ICL_PCODE_REQ_QGV_PT_MASK); } -int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv, +int icl_pcode_restrict_qgv_points(struct intel_display *display, u32 points_mask) { + struct drm_i915_private *i915 = to_i915(display->drm); int ret; - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) return 0; /* bspec says to keep retrying for at least 1 ms */ - ret = skl_pcode_request(&dev_priv->uncore, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG, + ret = skl_pcode_request(&i915->uncore, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG, points_mask, ICL_PCODE_REP_QGV_MASK | ADLS_PCODE_REP_PSF_MASK, ICL_PCODE_REP_QGV_SAFE | ADLS_PCODE_REP_PSF_SAFE, 1); if (ret < 0) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Failed to disable qgv points (0x%x) points: 0x%x\n", ret, points_mask); return ret; } - dev_priv->display.sagv.status = is_sagv_enabled(dev_priv, points_mask) ? + display->sagv.status = is_sagv_enabled(display, points_mask) ? I915_SAGV_ENABLED : I915_SAGV_DISABLED; return 0; } -static int mtl_read_qgv_point_info(struct drm_i915_private *dev_priv, +static int mtl_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { + struct drm_i915_private *i915 = to_i915(display->drm); u32 val, val2; u16 dclk; - val = intel_uncore_read(&dev_priv->uncore, + val = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_QGV_POINT_LOW(point)); - val2 = intel_uncore_read(&dev_priv->uncore, + val2 = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_QGV_POINT_HIGH(point)); dclk = REG_FIELD_GET(MTL_DCLK_MASK, val); sp->dclk = DIV_ROUND_CLOSEST(16667 * dclk, 1000); @@ -200,29 +205,30 @@ static int mtl_read_qgv_point_info(struct drm_i915_private *dev_priv, } static int -intel_read_qgv_point_info(struct drm_i915_private *dev_priv, +intel_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { - if (DISPLAY_VER(dev_priv) >= 14) - return mtl_read_qgv_point_info(dev_priv, sp, point); - else if (IS_DG1(dev_priv)) - return dg1_mchbar_read_qgv_point_info(dev_priv, sp, point); + if (DISPLAY_VER(display) >= 14) + return mtl_read_qgv_point_info(display, sp, point); + else if (display->platform.dg1) + return dg1_mchbar_read_qgv_point_info(display, sp, point); else - return icl_pcode_read_qgv_point_info(dev_priv, sp, point); + return icl_pcode_read_qgv_point_info(display, sp, point); } -static int icl_get_qgv_points(struct drm_i915_private *dev_priv, +static int icl_get_qgv_points(struct intel_display *display, struct intel_qgv_info *qi, bool is_y_tile) { - const struct dram_info *dram_info = &dev_priv->dram_info; + struct drm_i915_private *i915 = to_i915(display->drm); + const struct dram_info *dram_info = &i915->dram_info; int i, ret; qi->num_points = dram_info->num_qgv_points; qi->num_psf_points = dram_info->num_psf_gv_points; - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { switch (dram_info->type) { case INTEL_DRAM_DDR4: qi->t_bl = 4; @@ -244,13 +250,14 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv, qi->deinterleave = 4; break; case INTEL_DRAM_GDDR: + case INTEL_DRAM_GDDR_ECC: qi->channel_width = 32; break; default: MISSING_CASE(dram_info->type); return -EINVAL; } - } else if (DISPLAY_VER(dev_priv) >= 12) { + } else if (DISPLAY_VER(display) >= 12) { switch (dram_info->type) { case INTEL_DRAM_DDR4: qi->t_bl = is_y_tile ? 8 : 4; @@ -265,7 +272,7 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv, qi->deinterleave = is_y_tile ? 1 : 2; break; case INTEL_DRAM_LPDDR4: - if (IS_ROCKETLAKE(dev_priv)) { + if (display->platform.rocketlake) { qi->t_bl = 8; qi->max_numchannels = 4; qi->channel_width = 32; @@ -284,39 +291,39 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv, qi->max_numchannels = 1; break; } - } else if (DISPLAY_VER(dev_priv) == 11) { - qi->t_bl = dev_priv->dram_info.type == INTEL_DRAM_DDR4 ? 4 : 8; + } else if (DISPLAY_VER(display) == 11) { + qi->t_bl = dram_info->type == INTEL_DRAM_DDR4 ? 4 : 8; qi->max_numchannels = 1; } - if (drm_WARN_ON(&dev_priv->drm, + if (drm_WARN_ON(display->drm, qi->num_points > ARRAY_SIZE(qi->points))) qi->num_points = ARRAY_SIZE(qi->points); for (i = 0; i < qi->num_points; i++) { struct intel_qgv_point *sp = &qi->points[i]; - ret = intel_read_qgv_point_info(dev_priv, sp, i); + ret = intel_read_qgv_point_info(display, sp, i); if (ret) { - drm_dbg_kms(&dev_priv->drm, "Could not read QGV %d info\n", i); + drm_dbg_kms(display->drm, "Could not read QGV %d info\n", i); return ret; } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "QGV %d: DCLK=%d tRP=%d tRDPRE=%d tRAS=%d tRCD=%d tRC=%d\n", i, sp->dclk, sp->t_rp, sp->t_rdpre, sp->t_ras, sp->t_rcd, sp->t_rc); } if (qi->num_psf_points > 0) { - ret = adls_pcode_read_psf_gv_point_info(dev_priv, qi->psf_points); + ret = adls_pcode_read_psf_gv_point_info(display, qi->psf_points); if (ret) { - drm_err(&dev_priv->drm, "Failed to read PSF point data; PSF points will not be considered in bandwidth calculations.\n"); + drm_err(display->drm, "Failed to read PSF point data; PSF points will not be considered in bandwidth calculations.\n"); qi->num_psf_points = 0; } for (i = 0; i < qi->num_psf_points; i++) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "PSF GV %d: CLK=%d \n", i, qi->psf_points[i].clk); } @@ -398,20 +405,34 @@ static const struct intel_sa_info xe2_hpd_sa_info = { /* Other values not used by simplified algorithm */ }; -static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa) +static const struct intel_sa_info xe2_hpd_ecc_sa_info = { + .derating = 45, + .deprogbwlimit = 53, + /* Other values not used by simplified algorithm */ +}; + +static const struct intel_sa_info xe3lpd_sa_info = { + .deburst = 32, + .deprogbwlimit = 65, /* GB/s */ + .displayrtids = 256, + .derating = 10, +}; + +static int icl_get_bw_info(struct intel_display *display, const struct intel_sa_info *sa) { + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_qgv_info qi = {}; bool is_y_tile = true; /* assume y tile may be used */ - int num_channels = max_t(u8, 1, dev_priv->dram_info.num_channels); + int num_channels = max_t(u8, 1, i915->dram_info.num_channels); int ipqdepth, ipqdepthpch = 16; int dclk_max; int maxdebw; - int num_groups = ARRAY_SIZE(dev_priv->display.bw.max); + int num_groups = ARRAY_SIZE(display->bw.max); int i, ret; - ret = icl_get_qgv_points(dev_priv, &qi, is_y_tile); + ret = icl_get_qgv_points(display, &qi, is_y_tile); if (ret) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Failed to get memory subsystem information, ignoring bandwidth limits"); return ret; } @@ -422,7 +443,7 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel qi.deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2); for (i = 0; i < num_groups; i++) { - struct intel_bw_info *bi = &dev_priv->display.bw.max[i]; + struct intel_bw_info *bi = &display->bw.max[i]; int clpchgroup; int j; @@ -449,7 +470,7 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel bi->deratedbw[j] = min(maxdebw, bw * (100 - sa->derating) / 100); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "BW%d / QGV %d: num_planes=%d deratedbw=%u\n", i, j, bi->num_planes, bi->deratedbw[j]); } @@ -460,44 +481,45 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel * as it will fail and pointless anyway. */ if (qi.num_points == 1) - dev_priv->display.sagv.status = I915_SAGV_NOT_CONTROLLED; + display->sagv.status = I915_SAGV_NOT_CONTROLLED; else - dev_priv->display.sagv.status = I915_SAGV_ENABLED; + display->sagv.status = I915_SAGV_ENABLED; return 0; } -static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa) +static int tgl_get_bw_info(struct intel_display *display, const struct intel_sa_info *sa) { + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_qgv_info qi = {}; - const struct dram_info *dram_info = &dev_priv->dram_info; + const struct dram_info *dram_info = &i915->dram_info; bool is_y_tile = true; /* assume y tile may be used */ - int num_channels = max_t(u8, 1, dev_priv->dram_info.num_channels); + int num_channels = max_t(u8, 1, dram_info->num_channels); int ipqdepth, ipqdepthpch = 16; int dclk_max; int maxdebw, peakbw; int clperchgroup; - int num_groups = ARRAY_SIZE(dev_priv->display.bw.max); + int num_groups = ARRAY_SIZE(display->bw.max); int i, ret; - ret = icl_get_qgv_points(dev_priv, &qi, is_y_tile); + ret = icl_get_qgv_points(display, &qi, is_y_tile); if (ret) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Failed to get memory subsystem information, ignoring bandwidth limits"); return ret; } - if (DISPLAY_VER(dev_priv) < 14 && + if (DISPLAY_VER(display) < 14 && (dram_info->type == INTEL_DRAM_LPDDR4 || dram_info->type == INTEL_DRAM_LPDDR5)) num_channels *= 2; qi.deinterleave = qi.deinterleave ? : DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2); - if (num_channels < qi.max_numchannels && DISPLAY_VER(dev_priv) >= 12) + if (num_channels < qi.max_numchannels && DISPLAY_VER(display) >= 12) qi.deinterleave = max(DIV_ROUND_UP(qi.deinterleave, 2), 1); - if (DISPLAY_VER(dev_priv) >= 12 && num_channels > qi.max_numchannels) - drm_warn(&dev_priv->drm, "Number of channels exceeds max number of channels."); + if (DISPLAY_VER(display) >= 12 && num_channels > qi.max_numchannels) + drm_warn(display->drm, "Number of channels exceeds max number of channels."); if (qi.max_numchannels != 0) num_channels = min_t(u8, num_channels, qi.max_numchannels); @@ -514,7 +536,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel clperchgroup = 4 * DIV_ROUND_UP(8, num_channels) * qi.deinterleave; for (i = 0; i < num_groups; i++) { - struct intel_bw_info *bi = &dev_priv->display.bw.max[i]; + struct intel_bw_info *bi = &display->bw.max[i]; struct intel_bw_info *bi_next; int clpchgroup; int j; @@ -522,7 +544,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel clpchgroup = (sa->deburst * qi.deinterleave / num_channels) << i; if (i < num_groups - 1) { - bi_next = &dev_priv->display.bw.max[i + 1]; + bi_next = &display->bw.max[i + 1]; if (clpchgroup < clperchgroup) bi_next->num_planes = (ipqdepth - clpchgroup) / @@ -554,7 +576,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel num_channels * qi.channel_width, 8); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "BW%d / QGV %d: num_planes=%d deratedbw=%u peakbw: %u\n", i, j, bi->num_planes, bi->deratedbw[j], bi->peakbw[j]); @@ -565,7 +587,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel bi->psf_bw[j] = adl_calc_psf_bw(sp->clk); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "BW%d / PSF GV %d: num_planes=%d bw=%u\n", i, j, bi->num_planes, bi->psf_bw[j]); } @@ -577,17 +599,17 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel * as it will fail and pointless anyway. */ if (qi.num_points == 1) - dev_priv->display.sagv.status = I915_SAGV_NOT_CONTROLLED; + display->sagv.status = I915_SAGV_NOT_CONTROLLED; else - dev_priv->display.sagv.status = I915_SAGV_ENABLED; + display->sagv.status = I915_SAGV_ENABLED; return 0; } -static void dg2_get_bw_info(struct drm_i915_private *i915) +static void dg2_get_bw_info(struct intel_display *display) { - unsigned int deratedbw = IS_DG2_G11(i915) ? 38000 : 50000; - int num_groups = ARRAY_SIZE(i915->display.bw.max); + unsigned int deratedbw = display->platform.dg2_g11 ? 38000 : 50000; + int num_groups = ARRAY_SIZE(display->bw.max); int i; /* @@ -598,7 +620,7 @@ static void dg2_get_bw_info(struct drm_i915_private *i915) * whereas DG2-G11 platforms have 38 GB/s. */ for (i = 0; i < num_groups; i++) { - struct intel_bw_info *bi = &i915->display.bw.max[i]; + struct intel_bw_info *bi = &display->bw.max[i]; bi->num_planes = 1; /* Need only one dummy QGV point per group */ @@ -606,20 +628,21 @@ static void dg2_get_bw_info(struct drm_i915_private *i915) bi->deratedbw[0] = deratedbw; } - i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED; + display->sagv.status = I915_SAGV_NOT_CONTROLLED; } -static int xe2_hpd_get_bw_info(struct drm_i915_private *i915, +static int xe2_hpd_get_bw_info(struct intel_display *display, const struct intel_sa_info *sa) { + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_qgv_info qi = {}; int num_channels = i915->dram_info.num_channels; int peakbw, maxdebw; int ret, i; - ret = icl_get_qgv_points(i915, &qi, true); + ret = icl_get_qgv_points(display, &qi, true); if (ret) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Failed to get memory subsystem information, ignoring bandwidth limits"); return ret; } @@ -631,33 +654,33 @@ static int xe2_hpd_get_bw_info(struct drm_i915_private *i915, const struct intel_qgv_point *point = &qi.points[i]; int bw = num_channels * (qi.channel_width / 8) * point->dclk; - i915->display.bw.max[0].deratedbw[i] = + display->bw.max[0].deratedbw[i] = min(maxdebw, (100 - sa->derating) * bw / 100); - i915->display.bw.max[0].peakbw[i] = bw; + display->bw.max[0].peakbw[i] = bw; - drm_dbg_kms(&i915->drm, "QGV %d: deratedbw=%u peakbw: %u\n", - i, i915->display.bw.max[0].deratedbw[i], - i915->display.bw.max[0].peakbw[i]); + drm_dbg_kms(display->drm, "QGV %d: deratedbw=%u peakbw: %u\n", + i, display->bw.max[0].deratedbw[i], + display->bw.max[0].peakbw[i]); } /* Bandwidth does not depend on # of planes; set all groups the same */ - i915->display.bw.max[0].num_planes = 1; - i915->display.bw.max[0].num_qgv_points = qi.num_points; - for (i = 1; i < ARRAY_SIZE(i915->display.bw.max); i++) - memcpy(&i915->display.bw.max[i], &i915->display.bw.max[0], - sizeof(i915->display.bw.max[0])); + display->bw.max[0].num_planes = 1; + display->bw.max[0].num_qgv_points = qi.num_points; + for (i = 1; i < ARRAY_SIZE(display->bw.max); i++) + memcpy(&display->bw.max[i], &display->bw.max[0], + sizeof(display->bw.max[0])); /* * Xe2_HPD should always have exactly two QGV points representing * battery and plugged-in operation. */ - drm_WARN_ON(&i915->drm, qi.num_points != 2); - i915->display.sagv.status = I915_SAGV_ENABLED; + drm_WARN_ON(display->drm, qi.num_points != 2); + display->sagv.status = I915_SAGV_ENABLED; return 0; } -static unsigned int icl_max_bw_index(struct drm_i915_private *dev_priv, +static unsigned int icl_max_bw_index(struct intel_display *display, int num_planes, int qgv_point) { int i; @@ -667,9 +690,9 @@ static unsigned int icl_max_bw_index(struct drm_i915_private *dev_priv, */ num_planes = max(1, num_planes); - for (i = 0; i < ARRAY_SIZE(dev_priv->display.bw.max); i++) { + for (i = 0; i < ARRAY_SIZE(display->bw.max); i++) { const struct intel_bw_info *bi = - &dev_priv->display.bw.max[i]; + &display->bw.max[i]; /* * Pcode will not expose all QGV points when @@ -685,7 +708,7 @@ static unsigned int icl_max_bw_index(struct drm_i915_private *dev_priv, return UINT_MAX; } -static unsigned int tgl_max_bw_index(struct drm_i915_private *dev_priv, +static unsigned int tgl_max_bw_index(struct intel_display *display, int num_planes, int qgv_point) { int i; @@ -695,9 +718,9 @@ static unsigned int tgl_max_bw_index(struct drm_i915_private *dev_priv, */ num_planes = max(1, num_planes); - for (i = ARRAY_SIZE(dev_priv->display.bw.max) - 1; i >= 0; i--) { + for (i = ARRAY_SIZE(display->bw.max) - 1; i >= 0; i--) { const struct intel_bw_info *bi = - &dev_priv->display.bw.max[i]; + &display->bw.max[i]; /* * Pcode will not expose all QGV points when @@ -713,52 +736,59 @@ static unsigned int tgl_max_bw_index(struct drm_i915_private *dev_priv, return 0; } -static unsigned int adl_psf_bw(struct drm_i915_private *dev_priv, +static unsigned int adl_psf_bw(struct intel_display *display, int psf_gv_point) { const struct intel_bw_info *bi = - &dev_priv->display.bw.max[0]; + &display->bw.max[0]; return bi->psf_bw[psf_gv_point]; } -static unsigned int icl_qgv_bw(struct drm_i915_private *i915, +static unsigned int icl_qgv_bw(struct intel_display *display, int num_active_planes, int qgv_point) { unsigned int idx; - if (DISPLAY_VER(i915) >= 12) - idx = tgl_max_bw_index(i915, num_active_planes, qgv_point); + if (DISPLAY_VER(display) >= 12) + idx = tgl_max_bw_index(display, num_active_planes, qgv_point); else - idx = icl_max_bw_index(i915, num_active_planes, qgv_point); + idx = icl_max_bw_index(display, num_active_planes, qgv_point); - if (idx >= ARRAY_SIZE(i915->display.bw.max)) + if (idx >= ARRAY_SIZE(display->bw.max)) return 0; - return i915->display.bw.max[idx].deratedbw[qgv_point]; + return display->bw.max[idx].deratedbw[qgv_point]; } -void intel_bw_init_hw(struct drm_i915_private *dev_priv) +void intel_bw_init_hw(struct intel_display *display) { - if (!HAS_DISPLAY(dev_priv)) + const struct dram_info *dram_info = &to_i915(display->drm)->dram_info; + + if (!HAS_DISPLAY(display)) return; - if (DISPLAY_VERx100(dev_priv) >= 1401 && IS_DGFX(dev_priv)) - xe2_hpd_get_bw_info(dev_priv, &xe2_hpd_sa_info); - else if (DISPLAY_VER(dev_priv) >= 14) - tgl_get_bw_info(dev_priv, &mtl_sa_info); - else if (IS_DG2(dev_priv)) - dg2_get_bw_info(dev_priv); - else if (IS_ALDERLAKE_P(dev_priv)) - tgl_get_bw_info(dev_priv, &adlp_sa_info); - else if (IS_ALDERLAKE_S(dev_priv)) - tgl_get_bw_info(dev_priv, &adls_sa_info); - else if (IS_ROCKETLAKE(dev_priv)) - tgl_get_bw_info(dev_priv, &rkl_sa_info); - else if (DISPLAY_VER(dev_priv) == 12) - tgl_get_bw_info(dev_priv, &tgl_sa_info); - else if (DISPLAY_VER(dev_priv) == 11) - icl_get_bw_info(dev_priv, &icl_sa_info); + if (DISPLAY_VER(display) >= 30) + tgl_get_bw_info(display, &xe3lpd_sa_info); + else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx && + dram_info->type == INTEL_DRAM_GDDR_ECC) + xe2_hpd_get_bw_info(display, &xe2_hpd_ecc_sa_info); + else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx) + xe2_hpd_get_bw_info(display, &xe2_hpd_sa_info); + else if (DISPLAY_VER(display) >= 14) + tgl_get_bw_info(display, &mtl_sa_info); + else if (display->platform.dg2) + dg2_get_bw_info(display); + else if (display->platform.alderlake_p) + tgl_get_bw_info(display, &adlp_sa_info); + else if (display->platform.alderlake_s) + tgl_get_bw_info(display, &adls_sa_info); + else if (display->platform.rocketlake) + tgl_get_bw_info(display, &rkl_sa_info); + else if (DISPLAY_VER(display) == 12) + tgl_get_bw_info(display, &tgl_sa_info); + else if (DISPLAY_VER(display) == 11) + icl_get_bw_info(display, &icl_sa_info); } static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_state *crtc_state) @@ -772,8 +802,8 @@ static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_stat static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); unsigned int data_rate = 0; enum plane_id plane_id; @@ -787,7 +817,7 @@ static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_ data_rate += crtc_state->data_rate[plane_id]; - if (DISPLAY_VER(i915) < 11) + if (DISPLAY_VER(display) < 11) data_rate += crtc_state->data_rate_y[plane_id]; } @@ -795,39 +825,38 @@ static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_ } /* "Maximum Pipe Read Bandwidth" */ -static int intel_bw_crtc_min_cdclk(const struct intel_crtc_state *crtc_state) +static int intel_bw_crtc_min_cdclk(struct intel_display *display, + unsigned int data_rate) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - - if (DISPLAY_VER(i915) < 12) + if (DISPLAY_VER(display) < 12) return 0; - return DIV_ROUND_UP_ULL(mul_u32_u32(intel_bw_crtc_data_rate(crtc_state), 10), 512); + return DIV_ROUND_UP_ULL(mul_u32_u32(data_rate, 10), 512); } -static unsigned int intel_bw_num_active_planes(struct drm_i915_private *dev_priv, +static unsigned int intel_bw_num_active_planes(struct intel_display *display, const struct intel_bw_state *bw_state) { unsigned int num_active_planes = 0; enum pipe pipe; - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) num_active_planes += bw_state->num_active_planes[pipe]; return num_active_planes; } -static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv, +static unsigned int intel_bw_data_rate(struct intel_display *display, const struct intel_bw_state *bw_state) { + struct drm_i915_private *i915 = to_i915(display->drm); unsigned int data_rate = 0; enum pipe pipe; - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) data_rate += bw_state->data_rate[pipe]; - if (DISPLAY_VER(dev_priv) >= 13 && i915_vtd_active(dev_priv)) + if (DISPLAY_VER(display) >= 13 && i915_vtd_active(i915)) data_rate = DIV_ROUND_UP(data_rate * 105, 100); return data_rate; @@ -836,10 +865,10 @@ static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv, struct intel_bw_state * intel_atomic_get_old_bw_state(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_global_state *bw_state; - bw_state = intel_atomic_get_old_global_obj_state(state, &dev_priv->display.bw.obj); + bw_state = intel_atomic_get_old_global_obj_state(state, &display->bw.obj); return to_intel_bw_state(bw_state); } @@ -847,10 +876,10 @@ intel_atomic_get_old_bw_state(struct intel_atomic_state *state) struct intel_bw_state * intel_atomic_get_new_bw_state(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_global_state *bw_state; - bw_state = intel_atomic_get_new_global_obj_state(state, &dev_priv->display.bw.obj); + bw_state = intel_atomic_get_new_global_obj_state(state, &display->bw.obj); return to_intel_bw_state(bw_state); } @@ -858,27 +887,27 @@ intel_atomic_get_new_bw_state(struct intel_atomic_state *state) struct intel_bw_state * intel_atomic_get_bw_state(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_global_state *bw_state; - bw_state = intel_atomic_get_global_obj_state(state, &dev_priv->display.bw.obj); + bw_state = intel_atomic_get_global_obj_state(state, &display->bw.obj); if (IS_ERR(bw_state)) return ERR_CAST(bw_state); return to_intel_bw_state(bw_state); } -static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915, +static unsigned int icl_max_bw_qgv_point_mask(struct intel_display *display, int num_active_planes) { - unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; + unsigned int num_qgv_points = display->bw.max[0].num_qgv_points; unsigned int max_bw_point = 0; unsigned int max_bw = 0; int i; for (i = 0; i < num_qgv_points; i++) { unsigned int max_data_rate = - icl_qgv_bw(i915, num_active_planes, i); + icl_qgv_bw(display, num_active_planes, i); /* * We need to know which qgv point gives us @@ -897,23 +926,23 @@ static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915, return max_bw_point; } -static u16 icl_prepare_qgv_points_mask(struct drm_i915_private *i915, +static u16 icl_prepare_qgv_points_mask(struct intel_display *display, unsigned int qgv_points, unsigned int psf_points) { return ~(ICL_PCODE_REQ_QGV_PT(qgv_points) | - ADLS_PCODE_REQ_PSF_PT(psf_points)) & icl_qgv_points_mask(i915); + ADLS_PCODE_REQ_PSF_PT(psf_points)) & icl_qgv_points_mask(display); } -static unsigned int icl_max_bw_psf_gv_point_mask(struct drm_i915_private *i915) +static unsigned int icl_max_bw_psf_gv_point_mask(struct intel_display *display) { - unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; + unsigned int num_psf_gv_points = display->bw.max[0].num_psf_gv_points; unsigned int max_bw_point_mask = 0; unsigned int max_bw = 0; int i; for (i = 0; i < num_psf_gv_points; i++) { - unsigned int max_data_rate = adl_psf_bw(i915, i); + unsigned int max_data_rate = adl_psf_bw(display, i); if (max_data_rate > max_bw) { max_bw_point_mask = BIT(i); @@ -926,29 +955,29 @@ static unsigned int icl_max_bw_psf_gv_point_mask(struct drm_i915_private *i915) return max_bw_point_mask; } -static void icl_force_disable_sagv(struct drm_i915_private *i915, +static void icl_force_disable_sagv(struct intel_display *display, struct intel_bw_state *bw_state) { - unsigned int qgv_points = icl_max_bw_qgv_point_mask(i915, 0); - unsigned int psf_points = icl_max_bw_psf_gv_point_mask(i915); + unsigned int qgv_points = icl_max_bw_qgv_point_mask(display, 0); + unsigned int psf_points = icl_max_bw_psf_gv_point_mask(display); - bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(i915, + bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(display, qgv_points, psf_points); - drm_dbg_kms(&i915->drm, "Forcing SAGV disable: mask 0x%x\n", + drm_dbg_kms(display->drm, "Forcing SAGV disable: mask 0x%x\n", bw_state->qgv_points_mask); - icl_pcode_restrict_qgv_points(i915, bw_state->qgv_points_mask); + icl_pcode_restrict_qgv_points(display, bw_state->qgv_points_mask); } -static int mtl_find_qgv_points(struct drm_i915_private *i915, +static int mtl_find_qgv_points(struct intel_display *display, unsigned int data_rate, unsigned int num_active_planes, struct intel_bw_state *new_bw_state) { unsigned int best_rate = UINT_MAX; - unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; + unsigned int num_qgv_points = display->bw.max[0].num_qgv_points; unsigned int qgv_peak_bw = 0; int i; int ret; @@ -962,9 +991,9 @@ static int mtl_find_qgv_points(struct drm_i915_private *i915, * for qgv peak bw in PM Demand request. So assign UINT_MAX if SAGV is * not enabled. PM Demand code will clamp the value for the register */ - if (!intel_can_enable_sagv(i915, new_bw_state)) { + if (!intel_can_enable_sagv(display, new_bw_state)) { new_bw_state->qgv_point_peakbw = U16_MAX; - drm_dbg_kms(&i915->drm, "No SAGV, use UINT_MAX as peak bw."); + drm_dbg_kms(display->drm, "No SAGV, use UINT_MAX as peak bw."); return 0; } @@ -974,27 +1003,27 @@ static int mtl_find_qgv_points(struct drm_i915_private *i915, */ for (i = 0; i < num_qgv_points; i++) { unsigned int bw_index = - tgl_max_bw_index(i915, num_active_planes, i); + tgl_max_bw_index(display, num_active_planes, i); unsigned int max_data_rate; - if (bw_index >= ARRAY_SIZE(i915->display.bw.max)) + if (bw_index >= ARRAY_SIZE(display->bw.max)) continue; - max_data_rate = i915->display.bw.max[bw_index].deratedbw[i]; + max_data_rate = display->bw.max[bw_index].deratedbw[i]; if (max_data_rate < data_rate) continue; if (max_data_rate - data_rate < best_rate) { best_rate = max_data_rate - data_rate; - qgv_peak_bw = i915->display.bw.max[bw_index].peakbw[i]; + qgv_peak_bw = display->bw.max[bw_index].peakbw[i]; } - drm_dbg_kms(&i915->drm, "QGV point %d: max bw %d required %d qgv_peak_bw: %d\n", + drm_dbg_kms(display->drm, "QGV point %d: max bw %d required %d qgv_peak_bw: %d\n", i, max_data_rate, data_rate, qgv_peak_bw); } - drm_dbg_kms(&i915->drm, "Matching peaks QGV bw: %d for required data rate: %d\n", + drm_dbg_kms(display->drm, "Matching peaks QGV bw: %d for required data rate: %d\n", qgv_peak_bw, data_rate); /* @@ -1002,7 +1031,7 @@ static int mtl_find_qgv_points(struct drm_i915_private *i915, * satisfying the required data rate is found */ if (qgv_peak_bw == 0) { - drm_dbg_kms(&i915->drm, "No QGV points for bw %d for display configuration(%d active planes).\n", + drm_dbg_kms(display->drm, "No QGV points for bw %d for display configuration(%d active planes).\n", data_rate, num_active_planes); return -EINVAL; } @@ -1013,14 +1042,14 @@ static int mtl_find_qgv_points(struct drm_i915_private *i915, return 0; } -static int icl_find_qgv_points(struct drm_i915_private *i915, +static int icl_find_qgv_points(struct intel_display *display, unsigned int data_rate, unsigned int num_active_planes, const struct intel_bw_state *old_bw_state, struct intel_bw_state *new_bw_state) { - unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; - unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; + unsigned int num_psf_gv_points = display->bw.max[0].num_psf_gv_points; + unsigned int num_qgv_points = display->bw.max[0].num_qgv_points; u16 psf_points = 0; u16 qgv_points = 0; int i; @@ -1031,22 +1060,22 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, return ret; for (i = 0; i < num_qgv_points; i++) { - unsigned int max_data_rate = icl_qgv_bw(i915, + unsigned int max_data_rate = icl_qgv_bw(display, num_active_planes, i); if (max_data_rate >= data_rate) qgv_points |= BIT(i); - drm_dbg_kms(&i915->drm, "QGV point %d: max bw %d required %d\n", + drm_dbg_kms(display->drm, "QGV point %d: max bw %d required %d\n", i, max_data_rate, data_rate); } for (i = 0; i < num_psf_gv_points; i++) { - unsigned int max_data_rate = adl_psf_bw(i915, i); + unsigned int max_data_rate = adl_psf_bw(display, i); if (max_data_rate >= data_rate) psf_points |= BIT(i); - drm_dbg_kms(&i915->drm, "PSF GV point %d: max bw %d" + drm_dbg_kms(display->drm, "PSF GV point %d: max bw %d" " required %d\n", i, max_data_rate, data_rate); } @@ -1057,14 +1086,14 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, * reasons. */ if (qgv_points == 0) { - drm_dbg_kms(&i915->drm, "No QGV points provide sufficient memory" + drm_dbg_kms(display->drm, "No QGV points provide sufficient memory" " bandwidth %d for display configuration(%d active planes).\n", data_rate, num_active_planes); return -EINVAL; } if (num_psf_gv_points > 0 && psf_points == 0) { - drm_dbg_kms(&i915->drm, "No PSF GV points provide sufficient memory" + drm_dbg_kms(display->drm, "No PSF GV points provide sufficient memory" " bandwidth %d for display configuration(%d active planes).\n", data_rate, num_active_planes); return -EINVAL; @@ -1075,9 +1104,9 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, * we can't enable SAGV due to the increased memory latency it may * cause. */ - if (!intel_can_enable_sagv(i915, new_bw_state)) { - qgv_points = icl_max_bw_qgv_point_mask(i915, num_active_planes); - drm_dbg_kms(&i915->drm, "No SAGV, using single QGV point mask 0x%x\n", + if (!intel_can_enable_sagv(display, new_bw_state)) { + qgv_points = icl_max_bw_qgv_point_mask(display, num_active_planes); + drm_dbg_kms(display->drm, "No SAGV, using single QGV point mask 0x%x\n", qgv_points); } @@ -1085,7 +1114,7 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, * We store the ones which need to be masked as that is what PCode * actually accepts as a parameter. */ - new_bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(i915, + new_bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(display, qgv_points, psf_points); /* @@ -1101,80 +1130,90 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, return 0; } -static int intel_bw_check_qgv_points(struct drm_i915_private *i915, +static int intel_bw_check_qgv_points(struct intel_display *display, const struct intel_bw_state *old_bw_state, struct intel_bw_state *new_bw_state) { - unsigned int data_rate = intel_bw_data_rate(i915, new_bw_state); + unsigned int data_rate = intel_bw_data_rate(display, new_bw_state); unsigned int num_active_planes = - intel_bw_num_active_planes(i915, new_bw_state); + intel_bw_num_active_planes(display, new_bw_state); data_rate = DIV_ROUND_UP(data_rate, 1000); - if (DISPLAY_VER(i915) >= 14) - return mtl_find_qgv_points(i915, data_rate, num_active_planes, + if (DISPLAY_VER(display) >= 14) + return mtl_find_qgv_points(display, data_rate, num_active_planes, new_bw_state); else - return icl_find_qgv_points(i915, data_rate, num_active_planes, + return icl_find_qgv_points(display, data_rate, num_active_planes, old_bw_state, new_bw_state); } -static bool intel_bw_state_changed(struct drm_i915_private *i915, +static bool intel_dbuf_bw_changed(struct intel_display *display, + const struct intel_dbuf_bw *old_dbuf_bw, + const struct intel_dbuf_bw *new_dbuf_bw) +{ + enum dbuf_slice slice; + + for_each_dbuf_slice(display, slice) { + if (old_dbuf_bw->max_bw[slice] != new_dbuf_bw->max_bw[slice] || + old_dbuf_bw->active_planes[slice] != new_dbuf_bw->active_planes[slice]) + return true; + } + + return false; +} + +static bool intel_bw_state_changed(struct intel_display *display, const struct intel_bw_state *old_bw_state, const struct intel_bw_state *new_bw_state) { enum pipe pipe; - for_each_pipe(i915, pipe) { - const struct intel_dbuf_bw *old_crtc_bw = + for_each_pipe(display, pipe) { + const struct intel_dbuf_bw *old_dbuf_bw = &old_bw_state->dbuf_bw[pipe]; - const struct intel_dbuf_bw *new_crtc_bw = + const struct intel_dbuf_bw *new_dbuf_bw = &new_bw_state->dbuf_bw[pipe]; - enum dbuf_slice slice; - for_each_dbuf_slice(i915, slice) { - if (old_crtc_bw->max_bw[slice] != new_crtc_bw->max_bw[slice] || - old_crtc_bw->active_planes[slice] != new_crtc_bw->active_planes[slice]) - return true; - } + if (intel_dbuf_bw_changed(display, old_dbuf_bw, new_dbuf_bw)) + return true; - if (old_bw_state->min_cdclk[pipe] != new_bw_state->min_cdclk[pipe]) + if (intel_bw_crtc_min_cdclk(display, old_bw_state->data_rate[pipe]) != + intel_bw_crtc_min_cdclk(display, new_bw_state->data_rate[pipe])) return true; } return false; } -static void skl_plane_calc_dbuf_bw(struct intel_bw_state *bw_state, +static void skl_plane_calc_dbuf_bw(struct intel_dbuf_bw *dbuf_bw, struct intel_crtc *crtc, enum plane_id plane_id, const struct skl_ddb_entry *ddb, unsigned int data_rate) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - struct intel_dbuf_bw *crtc_bw = &bw_state->dbuf_bw[crtc->pipe]; - unsigned int dbuf_mask = skl_ddb_dbuf_slice_mask(i915, ddb); + struct intel_display *display = to_intel_display(crtc); + unsigned int dbuf_mask = skl_ddb_dbuf_slice_mask(display, ddb); enum dbuf_slice slice; /* * The arbiter can only really guarantee an * equal share of the total bw to each plane. */ - for_each_dbuf_slice_in_mask(i915, slice, dbuf_mask) { - crtc_bw->max_bw[slice] = max(crtc_bw->max_bw[slice], data_rate); - crtc_bw->active_planes[slice] |= BIT(plane_id); + for_each_dbuf_slice_in_mask(display, slice, dbuf_mask) { + dbuf_bw->max_bw[slice] = max(dbuf_bw->max_bw[slice], data_rate); + dbuf_bw->active_planes[slice] |= BIT(plane_id); } } -static void skl_crtc_calc_dbuf_bw(struct intel_bw_state *bw_state, +static void skl_crtc_calc_dbuf_bw(struct intel_dbuf_bw *dbuf_bw, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - struct intel_dbuf_bw *crtc_bw = &bw_state->dbuf_bw[crtc->pipe]; enum plane_id plane_id; - memset(crtc_bw, 0, sizeof(*crtc_bw)); + memset(dbuf_bw, 0, sizeof(*dbuf_bw)); if (!crtc_state->hw.active) return; @@ -1187,12 +1226,12 @@ static void skl_crtc_calc_dbuf_bw(struct intel_bw_state *bw_state, if (plane_id == PLANE_CURSOR) continue; - skl_plane_calc_dbuf_bw(bw_state, crtc, plane_id, + skl_plane_calc_dbuf_bw(dbuf_bw, crtc, plane_id, &crtc_state->wm.skl.plane_ddb[plane_id], crtc_state->data_rate[plane_id]); - if (DISPLAY_VER(i915) < 11) - skl_plane_calc_dbuf_bw(bw_state, crtc, plane_id, + if (DISPLAY_VER(display) < 11) + skl_plane_calc_dbuf_bw(dbuf_bw, crtc, plane_id, &crtc_state->wm.skl.plane_ddb_y[plane_id], crtc_state->data_rate[plane_id]); } @@ -1200,13 +1239,13 @@ static void skl_crtc_calc_dbuf_bw(struct intel_bw_state *bw_state, /* "Maximum Data Buffer Bandwidth" */ static int -intel_bw_dbuf_min_cdclk(struct drm_i915_private *i915, +intel_bw_dbuf_min_cdclk(struct intel_display *display, const struct intel_bw_state *bw_state) { unsigned int total_max_bw = 0; enum dbuf_slice slice; - for_each_dbuf_slice(i915, slice) { + for_each_dbuf_slice(display, slice) { int num_active_planes = 0; unsigned int max_bw = 0; enum pipe pipe; @@ -1215,11 +1254,11 @@ intel_bw_dbuf_min_cdclk(struct drm_i915_private *i915, * The arbiter can only really guarantee an * equal share of the total bw to each plane. */ - for_each_pipe(i915, pipe) { - const struct intel_dbuf_bw *crtc_bw = &bw_state->dbuf_bw[pipe]; + for_each_pipe(display, pipe) { + const struct intel_dbuf_bw *dbuf_bw = &bw_state->dbuf_bw[pipe]; - max_bw = max(crtc_bw->max_bw[slice], max_bw); - num_active_planes += hweight8(crtc_bw->active_planes[slice]); + max_bw = max(dbuf_bw->max_bw[slice], max_bw); + num_active_planes += hweight8(dbuf_bw->active_planes[slice]); } max_bw *= num_active_planes; @@ -1229,16 +1268,18 @@ intel_bw_dbuf_min_cdclk(struct drm_i915_private *i915, return DIV_ROUND_UP(total_max_bw, 64); } -int intel_bw_min_cdclk(struct drm_i915_private *i915, +int intel_bw_min_cdclk(struct intel_display *display, const struct intel_bw_state *bw_state) { enum pipe pipe; int min_cdclk; - min_cdclk = intel_bw_dbuf_min_cdclk(i915, bw_state); + min_cdclk = intel_bw_dbuf_min_cdclk(display, bw_state); - for_each_pipe(i915, pipe) - min_cdclk = max(min_cdclk, bw_state->min_cdclk[pipe]); + for_each_pipe(display, pipe) + min_cdclk = max(min_cdclk, + intel_bw_crtc_min_cdclk(display, + bw_state->data_rate[pipe])); return min_cdclk; } @@ -1246,42 +1287,49 @@ int intel_bw_min_cdclk(struct drm_i915_private *i915, int intel_bw_calc_min_cdclk(struct intel_atomic_state *state, bool *need_cdclk_calc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_bw_state *new_bw_state = NULL; const struct intel_bw_state *old_bw_state = NULL; const struct intel_cdclk_state *cdclk_state; - const struct intel_crtc_state *crtc_state; + const struct intel_crtc_state *old_crtc_state; + const struct intel_crtc_state *new_crtc_state; int old_min_cdclk, new_min_cdclk; struct intel_crtc *crtc; int i; - if (DISPLAY_VER(dev_priv) < 9) + if (DISPLAY_VER(display) < 9) return 0; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, + new_crtc_state, i) { + struct intel_dbuf_bw old_dbuf_bw, new_dbuf_bw; + + skl_crtc_calc_dbuf_bw(&old_dbuf_bw, old_crtc_state); + skl_crtc_calc_dbuf_bw(&new_dbuf_bw, new_crtc_state); + + if (!intel_dbuf_bw_changed(display, &old_dbuf_bw, &new_dbuf_bw)) + continue; + new_bw_state = intel_atomic_get_bw_state(state); if (IS_ERR(new_bw_state)) return PTR_ERR(new_bw_state); old_bw_state = intel_atomic_get_old_bw_state(state); - skl_crtc_calc_dbuf_bw(new_bw_state, crtc_state); - - new_bw_state->min_cdclk[crtc->pipe] = - intel_bw_crtc_min_cdclk(crtc_state); + new_bw_state->dbuf_bw[crtc->pipe] = new_dbuf_bw; } if (!old_bw_state) return 0; - if (intel_bw_state_changed(dev_priv, old_bw_state, new_bw_state)) { + if (intel_bw_state_changed(display, old_bw_state, new_bw_state)) { int ret = intel_atomic_lock_global_state(&new_bw_state->base); if (ret) return ret; } - old_min_cdclk = intel_bw_min_cdclk(dev_priv, old_bw_state); - new_min_cdclk = intel_bw_min_cdclk(dev_priv, new_bw_state); + old_min_cdclk = intel_bw_min_cdclk(display, old_bw_state); + new_min_cdclk = intel_bw_min_cdclk(display, new_bw_state); /* * No need to check against the cdclk state if @@ -1309,7 +1357,7 @@ int intel_bw_calc_min_cdclk(struct intel_atomic_state *state, if (new_min_cdclk <= cdclk_state->bw_min_cdclk) return 0; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "new bandwidth min cdclk (%d kHz) > old min cdclk (%d kHz)\n", new_min_cdclk, cdclk_state->bw_min_cdclk); *need_cdclk_calc = true; @@ -1319,7 +1367,7 @@ int intel_bw_calc_min_cdclk(struct intel_atomic_state *state, static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *changed) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; int i; @@ -1353,7 +1401,7 @@ static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *chan *changed = true; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] data rate %u num active planes %u\n", crtc->base.base.id, crtc->base.name, new_bw_state->data_rate[crtc->pipe], @@ -1363,16 +1411,103 @@ static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *chan return 0; } -int intel_bw_atomic_check(struct intel_atomic_state *state) +static int intel_bw_modeset_checks(struct intel_atomic_state *state) { + struct intel_display *display = to_intel_display(state); + const struct intel_bw_state *old_bw_state; + struct intel_bw_state *new_bw_state; + + if (DISPLAY_VER(display) < 9) + return 0; + + new_bw_state = intel_atomic_get_bw_state(state); + if (IS_ERR(new_bw_state)) + return PTR_ERR(new_bw_state); + + old_bw_state = intel_atomic_get_old_bw_state(state); + + new_bw_state->active_pipes = + intel_calc_active_pipes(state, old_bw_state->active_pipes); + + if (new_bw_state->active_pipes != old_bw_state->active_pipes) { + int ret; + + ret = intel_atomic_lock_global_state(&new_bw_state->base); + if (ret) + return ret; + } + + return 0; +} + +static int intel_bw_check_sagv_mask(struct intel_atomic_state *state) +{ + struct intel_display *display = to_intel_display(state); + const struct intel_crtc_state *old_crtc_state; + const struct intel_crtc_state *new_crtc_state; + const struct intel_bw_state *old_bw_state = NULL; + struct intel_bw_state *new_bw_state = NULL; + struct intel_crtc *crtc; + int ret, i; + + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, + new_crtc_state, i) { + if (intel_crtc_can_enable_sagv(old_crtc_state) == + intel_crtc_can_enable_sagv(new_crtc_state)) + continue; + + new_bw_state = intel_atomic_get_bw_state(state); + if (IS_ERR(new_bw_state)) + return PTR_ERR(new_bw_state); + + old_bw_state = intel_atomic_get_old_bw_state(state); + + if (intel_crtc_can_enable_sagv(new_crtc_state)) + new_bw_state->pipe_sagv_reject &= ~BIT(crtc->pipe); + else + new_bw_state->pipe_sagv_reject |= BIT(crtc->pipe); + } + + if (!new_bw_state) + return 0; + + if (intel_can_enable_sagv(display, new_bw_state) != + intel_can_enable_sagv(display, old_bw_state)) { + ret = intel_atomic_serialize_global_state(&new_bw_state->base); + if (ret) + return ret; + } else if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) { + ret = intel_atomic_lock_global_state(&new_bw_state->base); + if (ret) + return ret; + } + + return 0; +} + +int intel_bw_atomic_check(struct intel_atomic_state *state, bool any_ms) +{ + struct intel_display *display = to_intel_display(state); bool changed = false; - struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_bw_state *new_bw_state; const struct intel_bw_state *old_bw_state; int ret; + if (DISPLAY_VER(display) < 9) + return 0; + + if (any_ms) { + ret = intel_bw_modeset_checks(state); + if (ret) + return ret; + } + + ret = intel_bw_check_sagv_mask(state); + if (ret) + return ret; + /* FIXME earlier gens need some checks too */ - if (DISPLAY_VER(i915) < 11) + if (DISPLAY_VER(display) < 11) return 0; ret = intel_bw_check_data_rate(state, &changed); @@ -1383,9 +1518,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) new_bw_state = intel_atomic_get_new_bw_state(state); if (new_bw_state && - (intel_can_enable_sagv(i915, old_bw_state) != - intel_can_enable_sagv(i915, new_bw_state) || - new_bw_state->force_check_qgv)) + intel_can_enable_sagv(display, old_bw_state) != + intel_can_enable_sagv(display, new_bw_state)) changed = true; /* @@ -1395,28 +1529,25 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) if (!changed) return 0; - ret = intel_bw_check_qgv_points(i915, old_bw_state, new_bw_state); + ret = intel_bw_check_qgv_points(display, old_bw_state, new_bw_state); if (ret) return ret; - new_bw_state->force_check_qgv = false; - return 0; } static void intel_bw_crtc_update(struct intel_bw_state *bw_state, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); bw_state->data_rate[crtc->pipe] = intel_bw_crtc_data_rate(crtc_state); bw_state->num_active_planes[crtc->pipe] = intel_bw_crtc_num_active_planes(crtc_state); - bw_state->force_check_qgv = true; - drm_dbg_kms(&i915->drm, "pipe %c data rate %u num active planes %u\n", + drm_dbg_kms(display->drm, "pipe %c data rate %u num active planes %u\n", pipe_name(crtc->pipe), bw_state->data_rate[crtc->pipe], bw_state->num_active_planes[crtc->pipe]); @@ -1432,6 +1563,7 @@ void intel_bw_update_hw_state(struct intel_display *display) return; bw_state->active_pipes = 0; + bw_state->pipe_sagv_reject = 0; for_each_intel_crtc(display->drm, crtc) { const struct intel_crtc_state *crtc_state = @@ -1443,6 +1575,11 @@ void intel_bw_update_hw_state(struct intel_display *display) if (DISPLAY_VER(display) >= 11) intel_bw_crtc_update(bw_state, crtc_state); + + skl_crtc_calc_dbuf_bw(&bw_state->dbuf_bw[pipe], crtc_state); + + /* initially SAGV has been forced off */ + bw_state->pipe_sagv_reject |= BIT(pipe); } } @@ -1458,6 +1595,7 @@ void intel_bw_crtc_disable_noatomic(struct intel_crtc *crtc) bw_state->data_rate[pipe] = 0; bw_state->num_active_planes[pipe] = 0; + memset(&bw_state->dbuf_bw[pipe], 0, sizeof(bw_state->dbuf_bw[pipe])); } static struct intel_global_state * @@ -1483,9 +1621,8 @@ static const struct intel_global_state_funcs intel_bw_funcs = { .atomic_destroy_state = intel_bw_destroy_state, }; -int intel_bw_init(struct drm_i915_private *i915) +int intel_bw_init(struct intel_display *display) { - struct intel_display *display = &i915->display; struct intel_bw_state *state; state = kzalloc(sizeof(*state), GFP_KERNEL); @@ -1499,8 +1636,8 @@ int intel_bw_init(struct drm_i915_private *i915) * Limit this only if we have SAGV. And for Display version 14 onwards * sagv is handled though pmdemand requests */ - if (intel_has_sagv(i915) && IS_DISPLAY_VER(i915, 11, 13)) - icl_force_disable_sagv(i915, state); + if (intel_has_sagv(display) && IS_DISPLAY_VER(display, 11, 13)) + icl_force_disable_sagv(display, state); return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h index 3313e4eac4f00d..eb2cc883e9c1e3 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.h +++ b/drivers/gpu/drm/i915/display/intel_bw.h @@ -12,7 +12,6 @@ #include "intel_display_power.h" #include "intel_global_state.h" -struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; @@ -49,13 +48,6 @@ struct intel_bw_state { */ u16 qgv_points_mask; - /* - * Flag to force the QGV comparison in atomic check right after the - * hw state readout - */ - bool force_check_qgv; - - int min_cdclk[I915_MAX_PIPES]; unsigned int data_rate[I915_MAX_PIPES]; u8 num_active_planes[I915_MAX_PIPES]; }; @@ -72,14 +64,14 @@ intel_atomic_get_new_bw_state(struct intel_atomic_state *state); struct intel_bw_state * intel_atomic_get_bw_state(struct intel_atomic_state *state); -void intel_bw_init_hw(struct drm_i915_private *dev_priv); -int intel_bw_init(struct drm_i915_private *dev_priv); -int intel_bw_atomic_check(struct intel_atomic_state *state); -int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv, +void intel_bw_init_hw(struct intel_display *display); +int intel_bw_init(struct intel_display *display); +int intel_bw_atomic_check(struct intel_atomic_state *state, bool any_ms); +int icl_pcode_restrict_qgv_points(struct intel_display *display, u32 points_mask); int intel_bw_calc_min_cdclk(struct intel_atomic_state *state, bool *need_cdclk_calc); -int intel_bw_min_cdclk(struct drm_i915_private *i915, +int intel_bw_min_cdclk(struct intel_display *display, const struct intel_bw_state *bw_state); void intel_bw_update_hw_state(struct intel_display *display); void intel_bw_crtc_disable_noatomic(struct intel_crtc *crtc); diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 2a8749a0213e74..6830950aae3f23 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1972,9 +1972,7 @@ int intel_mdclk_cdclk_ratio(struct intel_display *display, static void xe2lpd_mdclk_cdclk_ratio_program(struct intel_display *display, const struct intel_cdclk_config *cdclk_config) { - struct drm_i915_private *i915 = to_i915(display->drm); - - intel_dbuf_mdclk_cdclk_ratio_update(i915, + intel_dbuf_mdclk_cdclk_ratio_update(display, intel_mdclk_cdclk_ratio(display, cdclk_config), cdclk_config->joined_mbus); } @@ -2808,7 +2806,6 @@ static int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_stat static int intel_compute_min_cdclk(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_cdclk_state *cdclk_state = intel_atomic_get_new_cdclk_state(state); const struct intel_bw_state *bw_state; @@ -2836,7 +2833,7 @@ static int intel_compute_min_cdclk(struct intel_atomic_state *state) bw_state = intel_atomic_get_new_bw_state(state); if (bw_state) { - min_cdclk = intel_bw_min_cdclk(dev_priv, bw_state); + min_cdclk = intel_bw_min_cdclk(display, bw_state); if (cdclk_state->bw_min_cdclk != min_cdclk) { int ret; @@ -3342,6 +3339,8 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) void intel_cdclk_update_hw_state(struct intel_display *display) { + const struct intel_bw_state *bw_state = + to_intel_bw_state(display->bw.obj.state); struct intel_cdclk_state *cdclk_state = to_intel_cdclk_state(display->cdclk.obj.state); struct intel_crtc *crtc; @@ -3359,6 +3358,8 @@ void intel_cdclk_update_hw_state(struct intel_display *display) cdclk_state->min_cdclk[pipe] = intel_crtc_compute_min_cdclk(crtc_state); cdclk_state->min_voltage_level[pipe] = crtc_state->min_voltage_level; } + + cdclk_state->bw_min_cdclk = intel_bw_min_cdclk(display, bw_state); } void intel_cdclk_crtc_disable_noatomic(struct intel_crtc *crtc) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index cfe14162231dbf..98dddf72c0eb97 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -22,7 +22,9 @@ * */ -#include "i915_drv.h" +#include + +#include "i915_utils.h" #include "i9xx_plane_regs.h" #include "intel_color.h" #include "intel_color_regs.h" @@ -405,14 +407,13 @@ static void icl_read_csc(struct intel_crtc_state *crtc_state) static bool ilk_limited_range(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct drm_i915_private *i915 = to_i915(display->drm); /* icl+ have dedicated output CSC */ if (DISPLAY_VER(display) >= 11) return false; /* pre-hsw have TRANSCONF_COLOR_RANGE_SELECT */ - if (DISPLAY_VER(display) < 7 || IS_IVYBRIDGE(i915)) + if (DISPLAY_VER(display) < 7 || display->platform.ivybridge) return false; return crtc_state->limited_color_range; @@ -516,7 +517,6 @@ static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state, static void ilk_assign_csc(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct drm_i915_private *i915 = to_i915(display->drm); bool limited_color_range = ilk_csc_limited_range(crtc_state); if (crtc_state->hw.ctm) { @@ -538,7 +538,7 @@ static void ilk_assign_csc(struct intel_crtc_state *crtc_state) * LUT is needed but CSC is not we need to load an * identity matrix. */ - drm_WARN_ON(display->drm, !IS_GEMINILAKE(i915)); + drm_WARN_ON(display->drm, !display->platform.geminilake); ilk_csc_copy(display, &crtc_state->csc, &ilk_csc_matrix_identity); } else { @@ -3983,12 +3983,10 @@ int intel_color_init(struct intel_display *display) void intel_color_init_hooks(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (HAS_GMCH(display)) { - if (IS_CHERRYVIEW(i915)) + if (display->platform.cherryview) display->funcs.color = &chv_color_funcs; - else if (IS_VALLEYVIEW(i915)) + else if (display->platform.valleyview) display->funcs.color = &vlv_color_funcs; else if (DISPLAY_VER(display) >= 4) display->funcs.color = &i965_color_funcs; @@ -4005,7 +4003,7 @@ void intel_color_init_hooks(struct intel_display *display) display->funcs.color = &skl_color_funcs; else if (DISPLAY_VER(display) == 8) display->funcs.color = &bdw_color_funcs; - else if (IS_HASWELL(i915)) + else if (display->platform.haswell) display->funcs.color = &hsw_color_funcs; else if (DISPLAY_VER(display) == 7) display->funcs.color = &ivb_color_funcs; diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c b/drivers/gpu/drm/i915/display/intel_combo_phy.c index 17eea244cc833f..f5cc38dbe55907 100644 --- a/drivers/gpu/drm/i915/display/intel_combo_phy.c +++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c @@ -3,6 +3,8 @@ * Copyright © 2018 Intel Corporation */ +#include + #include "i915_reg.h" #include "i915_utils.h" #include "intel_combo_phy.h" diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c index e42357bd9e809c..6c81c9f2fd09a7 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.c +++ b/drivers/gpu/drm/i915/display/intel_connector.c @@ -31,8 +31,10 @@ #include #include "i915_drv.h" +#include "i915_utils.h" #include "intel_backlight.h" #include "intel_connector.h" +#include "intel_display_core.h" #include "intel_display_debugfs.h" #include "intel_display_types.h" #include "intel_hdcp.h" @@ -154,13 +156,14 @@ void intel_connector_destroy(struct drm_connector *connector) int intel_connector_register(struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); + struct drm_i915_private *i915 = to_i915(connector->dev); int ret; ret = intel_backlight_device_register(intel_connector); if (ret) goto err; - if (i915_inject_probe_failure(to_i915(connector->dev))) { + if (i915_inject_probe_failure(i915)) { ret = -EFAULT; goto err_backlight; } @@ -204,10 +207,10 @@ bool intel_connector_get_hw_state(struct intel_connector *connector) enum pipe intel_connector_get_pipe(struct intel_connector *connector) { - struct drm_device *dev = connector->base.dev; + struct intel_display *display = to_intel_display(connector); - drm_WARN_ON(dev, - !drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + drm_WARN_ON(display->drm, + !drm_modeset_is_locked(&display->drm->mode_config.connection_mutex)); if (!connector->base.state->crtc) return INVALID_PIPE; @@ -264,20 +267,19 @@ static const struct drm_prop_enum_list force_audio_names[] = { void intel_attach_force_audio_property(struct drm_connector *connector) { - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(connector->dev); struct drm_property *prop; - prop = dev_priv->display.properties.force_audio; + prop = display->properties.force_audio; if (prop == NULL) { - prop = drm_property_create_enum(dev, 0, - "audio", - force_audio_names, - ARRAY_SIZE(force_audio_names)); + prop = drm_property_create_enum(display->drm, 0, + "audio", + force_audio_names, + ARRAY_SIZE(force_audio_names)); if (prop == NULL) return; - dev_priv->display.properties.force_audio = prop; + display->properties.force_audio = prop; } drm_object_attach_property(&connector->base, prop, 0); } @@ -291,20 +293,19 @@ static const struct drm_prop_enum_list broadcast_rgb_names[] = { void intel_attach_broadcast_rgb_property(struct drm_connector *connector) { - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(connector->dev); struct drm_property *prop; - prop = dev_priv->display.properties.broadcast_rgb; + prop = display->properties.broadcast_rgb; if (prop == NULL) { - prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, - "Broadcast RGB", - broadcast_rgb_names, - ARRAY_SIZE(broadcast_rgb_names)); + prop = drm_property_create_enum(display->drm, DRM_MODE_PROP_ENUM, + "Broadcast RGB", + broadcast_rgb_names, + ARRAY_SIZE(broadcast_rgb_names)); if (prop == NULL) return; - dev_priv->display.properties.broadcast_rgb = prop; + display->properties.broadcast_rgb = prop; } drm_object_attach_property(&connector->base, prop, 0); @@ -336,14 +337,14 @@ intel_attach_dp_colorspace_property(struct drm_connector *connector) void intel_attach_scaling_mode_property(struct drm_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->dev); + struct intel_display *display = to_intel_display(connector->dev); u32 scaling_modes; scaling_modes = BIT(DRM_MODE_SCALE_ASPECT) | BIT(DRM_MODE_SCALE_FULLSCREEN); /* On GMCH platforms borders are only possible on the LVDS port */ - if (!HAS_GMCH(i915) || connector->connector_type == DRM_MODE_CONNECTOR_LVDS) + if (!HAS_GMCH(display) || connector->connector_type == DRM_MODE_CONNECTOR_LVDS) scaling_modes |= BIT(DRM_MODE_SCALE_CENTER); drm_connector_attach_scaling_mode_property(connector, scaling_modes); diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index 76ffb3f8467c8e..cca22d2402e889 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.c +++ b/drivers/gpu/drm/i915/display/intel_crt.c @@ -532,8 +532,6 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) { struct intel_display *display = to_intel_display(connector->dev); struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector)); - struct drm_i915_private *dev_priv = to_i915(connector->dev); - bool reenable_hpd; u32 adpa; bool ret; u32 save_adpa; @@ -550,7 +548,7 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) * * Just disable HPD interrupts here to prevent this */ - reenable_hpd = intel_hpd_disable(dev_priv, crt->base.hpd_pin); + intel_hpd_block(&crt->base); save_adpa = adpa = intel_de_read(display, crt->adpa_reg); drm_dbg_kms(display->drm, @@ -577,8 +575,7 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) drm_dbg_kms(display->drm, "valleyview hotplug adpa=0x%x, result %d\n", adpa, ret); - if (reenable_hpd) - intel_hpd_enable(dev_priv, crt->base.hpd_pin); + intel_hpd_clear_and_unblock(&crt->base); return ret; } @@ -609,7 +606,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) for (i = 0; i < tries ; i++) { /* turn on the FORCE_DETECT */ - i915_hotplug_interrupt_update(dev_priv, + i915_hotplug_interrupt_update(display, CRT_HOTPLUG_FORCE_DETECT, CRT_HOTPLUG_FORCE_DETECT); /* wait for FORCE_DETECT to go off */ @@ -627,7 +624,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) intel_de_write(display, PORT_HOTPLUG_STAT(display), CRT_HOTPLUG_INT_STATUS); - i915_hotplug_interrupt_update(dev_priv, CRT_HOTPLUG_FORCE_DETECT, 0); + i915_hotplug_interrupt_update(display, CRT_HOTPLUG_FORCE_DETECT, 0); return ret; } @@ -880,7 +877,7 @@ intel_crt_detect(struct drm_connector *connector, wakeref = intel_display_power_get(display, encoder->power_domain); - if (I915_HAS_HOTPLUG(display)) { + if (HAS_HOTPLUG(display)) { /* We can not rely on the HPD pin always being correctly wired * up, for example many KVM do not pass it through, and so * only trust an assertion that the monitor is connected. @@ -904,7 +901,7 @@ intel_crt_detect(struct drm_connector *connector, * broken monitor (without edid) to work behind a broken kvm (that fails * to have the right resistors for HP detection) needs to fix this up. * For now just bail out. */ - if (I915_HAS_HOTPLUG(display)) { + if (HAS_HOTPLUG(display)) { status = connector_status_disconnected; goto out; } @@ -1084,7 +1081,7 @@ void intel_crt_init(struct intel_display *display) crt->base.power_domain = POWER_DOMAIN_PORT_CRT; - if (I915_HAS_HOTPLUG(display) && + if (HAS_HOTPLUG(display) && !dmi_check_system(intel_spurious_crt_detect)) { crt->base.hpd_pin = HPD_CRT; crt->base.hotplug = intel_encoder_hotplug; diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index 599ddce96371fb..0c7f9104699679 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -5,9 +5,10 @@ #include #include +#include -#include "i915_drv.h" #include "intel_crtc_state_dump.h" +#include "intel_display_core.h" #include "intel_display_types.h" #include "intel_hdmi.h" #include "intel_vblank.h" @@ -42,13 +43,13 @@ intel_dump_m_n_config(struct drm_printer *p, } static void -intel_dump_infoframe(struct drm_i915_private *i915, +intel_dump_infoframe(struct intel_display *display, const union hdmi_infoframe *frame) { if (!drm_debug_enabled(DRM_UT_KMS)) return; - hdmi_infoframe_log(KERN_DEBUG, i915->drm.dev, frame); + hdmi_infoframe_log(KERN_DEBUG, display->drm->dev, frame); } #define OUTPUT_TYPE(x) [INTEL_OUTPUT_ ## x] = #x @@ -136,7 +137,7 @@ static void intel_dump_plane_state(struct drm_printer *p, } static void -ilk_dump_csc(struct drm_i915_private *i915, +ilk_dump_csc(struct intel_display *display, struct drm_printer *p, const char *name, const struct intel_csc_matrix *csc) @@ -152,7 +153,7 @@ ilk_dump_csc(struct drm_i915_private *i915, csc->coeff[3 * i + 1], csc->coeff[3 * i + 2]); - if (DISPLAY_VER(i915) < 7) + if (DISPLAY_VER(display) < 7) return; drm_printf(p, "%s: post offsets: 0x%04x 0x%04x 0x%04x\n", name, @@ -178,7 +179,6 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, { struct intel_display *display = to_intel_display(pipe_config); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); const struct intel_plane_state *plane_state; struct intel_plane *plane; struct drm_printer p; @@ -188,7 +188,7 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, if (!drm_debug_enabled(DRM_UT_KMS)) return; - p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, NULL); + p = drm_dbg_printer(display->drm, DRM_UT_KMS, NULL); drm_printf(&p, "[CRTC:%d:%s] enable: %s [%s]\n", crtc->base.base.id, crtc->base.name, @@ -262,19 +262,19 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, drm_printf(&p, "GCP: 0x%x\n", pipe_config->infoframes.gcp); if (pipe_config->infoframes.enable & intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_AVI)) - intel_dump_infoframe(i915, &pipe_config->infoframes.avi); + intel_dump_infoframe(display, &pipe_config->infoframes.avi); if (pipe_config->infoframes.enable & intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_SPD)) - intel_dump_infoframe(i915, &pipe_config->infoframes.spd); + intel_dump_infoframe(display, &pipe_config->infoframes.spd); if (pipe_config->infoframes.enable & intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_VENDOR)) - intel_dump_infoframe(i915, &pipe_config->infoframes.hdmi); + intel_dump_infoframe(display, &pipe_config->infoframes.hdmi); if (pipe_config->infoframes.enable & intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_DRM)) - intel_dump_infoframe(i915, &pipe_config->infoframes.drm); + intel_dump_infoframe(display, &pipe_config->infoframes.drm); if (pipe_config->infoframes.enable & intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA)) - intel_dump_infoframe(i915, &pipe_config->infoframes.drm); + intel_dump_infoframe(display, &pipe_config->infoframes.drm); if (pipe_config->infoframes.enable & intel_hdmi_infoframe_enable(DP_SDP_VSC)) drm_dp_vsc_sdp_log(&p, &pipe_config->infoframes.vsc); @@ -294,8 +294,9 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, pipe_config->hw.adjusted_mode.crtc_vdisplay, pipe_config->framestart_delay, pipe_config->msa_timing_delay); - drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, flipline: %d, pipeline full: %d, guardband: %d vsync start: %d, vsync end: %d\n", + drm_printf(&p, "vrr: %s, fixed rr: %s, vmin: %d, vmax: %d, flipline: %d, pipeline full: %d, guardband: %d vsync start: %d, vsync end: %d\n", str_yes_no(pipe_config->vrr.enable), + str_yes_no(intel_vrr_is_fixed_rr(pipe_config)), pipe_config->vrr.vmin, pipe_config->vrr.vmax, pipe_config->vrr.flipline, pipe_config->vrr.pipeline_full, pipe_config->vrr.guardband, pipe_config->vrr.vsync_start, pipe_config->vrr.vsync_end); @@ -319,14 +320,14 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, drm_printf(&p, "linetime: %d, ips linetime: %d\n", pipe_config->linetime, pipe_config->ips_linetime); - if (DISPLAY_VER(i915) >= 9) + if (DISPLAY_VER(display) >= 9) drm_printf(&p, "num_scalers: %d, scaler_users: 0x%x, scaler_id: %d, scaling_filter: %d\n", crtc->num_scalers, pipe_config->scaler_state.scaler_users, pipe_config->scaler_state.scaler_id, pipe_config->hw.scaling_filter); - if (HAS_GMCH(i915)) + if (HAS_GMCH(display)) drm_printf(&p, "gmch pfit: control: 0x%08x, ratios: 0x%08x, lvds border: 0x%08x\n", pipe_config->gmch_pfit.control, pipe_config->gmch_pfit.pgm_ratios, @@ -343,7 +344,7 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, intel_dpll_dump_hw_state(display, &p, &pipe_config->dpll_hw_state); - if (IS_CHERRYVIEW(i915)) + if (display->platform.cherryview) drm_printf(&p, "cgm_mode: 0x%x gamma_mode: 0x%x gamma_enable: %d csc_enable: %d\n", pipe_config->cgm_mode, pipe_config->gamma_mode, pipe_config->gamma_enable, pipe_config->csc_enable); @@ -354,20 +355,20 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, drm_printf(&p, "pre csc lut: %s%d entries, post csc lut: %d entries\n", pipe_config->pre_csc_lut && pipe_config->pre_csc_lut == - i915->display.color.glk_linear_degamma_lut ? "(linear) " : "", + display->color.glk_linear_degamma_lut ? "(linear) " : "", pipe_config->pre_csc_lut ? drm_color_lut_size(pipe_config->pre_csc_lut) : 0, pipe_config->post_csc_lut ? drm_color_lut_size(pipe_config->post_csc_lut) : 0); - if (DISPLAY_VER(i915) >= 11) - ilk_dump_csc(i915, &p, "output csc", &pipe_config->output_csc); + if (DISPLAY_VER(display) >= 11) + ilk_dump_csc(display, &p, "output csc", &pipe_config->output_csc); - if (!HAS_GMCH(i915)) - ilk_dump_csc(i915, &p, "pipe csc", &pipe_config->csc); - else if (IS_CHERRYVIEW(i915)) + if (!HAS_GMCH(display)) + ilk_dump_csc(display, &p, "pipe csc", &pipe_config->csc); + else if (display->platform.cherryview) vlv_dump_csc(&p, "cgm csc", &pipe_config->csc); - else if (IS_VALLEYVIEW(i915)) + else if (display->platform.valleyview) vlv_dump_csc(&p, "wgc csc", &pipe_config->csc); intel_vdsc_state_dump(&p, 0, pipe_config); diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index f38c998935b977..b48ed5df7a9671 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -78,6 +78,7 @@ #include "intel_tc.h" #include "intel_vdsc.h" #include "intel_vdsc_regs.h" +#include "intel_vrr.h" #include "skl_scaler.h" #include "skl_universal_plane.h" @@ -106,14 +107,14 @@ static int intel_ddi_hdmi_level(struct intel_encoder *encoder, return level; } -static bool has_buf_trans_select(struct drm_i915_private *i915) +static bool has_buf_trans_select(struct intel_display *display) { - return DISPLAY_VER(i915) < 10 && !IS_BROXTON(i915); + return DISPLAY_VER(display) < 10 && !display->platform.broxton; } -static bool has_iboost(struct drm_i915_private *i915) +static bool has_iboost(struct intel_display *display) { - return DISPLAY_VER(i915) == 9 && !IS_BROXTON(i915); + return DISPLAY_VER(display) == 9 && !display->platform.broxton; } /* @@ -124,25 +125,25 @@ static bool has_iboost(struct drm_i915_private *i915) void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); u32 iboost_bit = 0; int i, n_entries; enum port port = encoder->port; const struct intel_ddi_buf_trans *trans; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return; /* If we're boosting the current, set bit 31 of trans1 */ - if (has_iboost(dev_priv) && + if (has_iboost(display) && intel_bios_dp_boost_level(encoder->devdata)) iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; for (i = 0; i < n_entries; i++) { - intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, i), + intel_de_write(display, DDI_BUF_TRANS_LO(port, i), trans->entries[i].hsw.trans1 | iboost_bit); - intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, i), + intel_de_write(display, DDI_BUF_TRANS_HI(port, i), trans->entries[i].hsw.trans2); } } @@ -155,7 +156,7 @@ void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder, static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); int level = intel_ddi_level(encoder, crtc_state, 0); u32 iboost_bit = 0; int n_entries; @@ -163,27 +164,25 @@ static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, const struct intel_ddi_buf_trans *trans; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return; /* If we're boosting the current, set bit 31 of trans1 */ - if (has_iboost(dev_priv) && + if (has_iboost(display) && intel_bios_hdmi_boost_level(encoder->devdata)) iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; /* Entry 9 is for HDMI: */ - intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, 9), + intel_de_write(display, DDI_BUF_TRANS_LO(port, 9), trans->entries[level].hsw.trans1 | iboost_bit); - intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, 9), + intel_de_write(display, DDI_BUF_TRANS_HI(port, 9), trans->entries[level].hsw.trans2); } static i915_reg_t intel_ddi_buf_status_reg(struct intel_display *display, enum port port) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (DISPLAY_VER(display) >= 14) - return XELPDP_PORT_BUF_CTL1(i915, port); + return XELPDP_PORT_BUF_CTL1(display, port); else return DDI_BUF_CTL(port); } @@ -346,7 +345,6 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); @@ -359,14 +357,14 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, if (dig_port->ddi_a_4_lanes) intel_dp->DP |= DDI_A_4_LANES; - if (DISPLAY_VER(i915) >= 14) { + if (DISPLAY_VER(display) >= 14) { if (intel_dp_is_uhbr(crtc_state)) intel_dp->DP |= DDI_BUF_PORT_DATA_40BIT; else intel_dp->DP |= DDI_BUF_PORT_DATA_10BIT; } - if (IS_ALDERLAKE_P(i915) && intel_encoder_is_tc(encoder)) { + if (display->platform.alderlake_p && intel_encoder_is_tc(encoder)) { intel_dp->DP |= ddi_buf_phy_link_rate(crtc_state->port_clock); if (!intel_tc_port_in_tbt_alt_mode(dig_port)) intel_dp->DP |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; @@ -379,8 +377,7 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, } } -static int icl_calc_tbt_pll_link(struct intel_display *display, - enum port port) +static int icl_calc_tbt_pll_link(struct intel_display *display, enum port port) { u32 val = intel_de_read(display, DDI_CLK_SEL(port)) & DDI_CLK_SEL_MASK; @@ -414,15 +411,14 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config) void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 temp; if (!intel_crtc_has_dp_encoder(crtc_state)) return; - drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)); + drm_WARN_ON(display->drm, transcoder_is_dsi(cpu_transcoder)); temp = DP_MSA_MISC_SYNC_CLOCK; @@ -445,7 +441,7 @@ void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state, } /* nonsense combination */ - drm_WARN_ON(&dev_priv->drm, crtc_state->limited_color_range && + drm_WARN_ON(display->drm, crtc_state->limited_color_range && crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB); if (crtc_state->limited_color_range) @@ -468,7 +464,7 @@ void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state, if (intel_dp_needs_vsc_sdp(crtc_state, conn_state)) temp |= DP_MSA_MISC_COLOR_VSC_SDP; - intel_de_write(dev_priv, TRANS_MSA_MISC(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_MSA_MISC(display, cpu_transcoder), temp); } @@ -507,8 +503,8 @@ static u32 intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum port port = encoder->port; @@ -516,7 +512,7 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */ temp = TRANS_DDI_FUNC_ENABLE; - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) temp |= TGL_TRANS_DDI_SELECT_PORT(port); else temp |= TRANS_DDI_SELECT_PORT(port); @@ -578,7 +574,7 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, temp |= TRANS_DDI_HDMI_SCRAMBLING; if (crtc_state->hdmi_high_tmds_clock_ratio) temp |= TRANS_DDI_HIGH_TMDS_CHAR_RATE; - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) temp |= TRANS_DDI_PORT_WIDTH(crtc_state->lane_count); } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) { temp |= TRANS_DDI_MODE_SELECT_FDI_OR_128B132B; @@ -591,11 +587,11 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, temp |= TRANS_DDI_MODE_SELECT_DP_MST; temp |= DDI_PORT_WIDTH(crtc_state->lane_count); - if (DISPLAY_VER(dev_priv) >= 12) { + if (DISPLAY_VER(display) >= 12) { enum transcoder master; master = crtc_state->mst_master_transcoder; - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, master == INVALID_TRANSCODER); temp |= TRANS_DDI_MST_TRANSPORT_SELECT(master); } @@ -604,7 +600,7 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, temp |= DDI_PORT_WIDTH(crtc_state->lane_count); } - if (IS_DISPLAY_VER(dev_priv, 8, 10) && + if (IS_DISPLAY_VER(display, 8, 10) && crtc_state->master_transcoder != INVALID_TRANSCODER) { u8 master_select = bdw_trans_port_sync_master_select(crtc_state->master_transcoder); @@ -619,11 +615,10 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, void intel_ddi_enable_transcoder_func(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - if (DISPLAY_VER(dev_priv) >= 11) { + if (DISPLAY_VER(display) >= 11) { enum transcoder master_transcoder = crtc_state->master_transcoder; u32 ctl2 = 0; @@ -635,12 +630,12 @@ void intel_ddi_enable_transcoder_func(struct intel_encoder *encoder, PORT_SYNC_MODE_MASTER_SELECT(master_select); } - intel_de_write(dev_priv, - TRANS_DDI_FUNC_CTL2(dev_priv, cpu_transcoder), + intel_de_write(display, + TRANS_DDI_FUNC_CTL2(display, cpu_transcoder), ctl2); } - intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder), intel_ddi_transcoder_func_reg_val_get(encoder, crtc_state)); } @@ -654,8 +649,7 @@ void intel_ddi_config_transcoder_func(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 ctl; @@ -663,7 +657,7 @@ intel_ddi_config_transcoder_func(struct intel_encoder *encoder, ctl = intel_ddi_transcoder_func_reg_val_get(encoder, crtc_state); ctl &= ~TRANS_DDI_FUNC_ENABLE; - intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder), ctl); } @@ -677,27 +671,26 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state { struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 ctl; - if (DISPLAY_VER(dev_priv) >= 11) - intel_de_write(dev_priv, - TRANS_DDI_FUNC_CTL2(dev_priv, cpu_transcoder), + if (DISPLAY_VER(display) >= 11) + intel_de_write(display, + TRANS_DDI_FUNC_CTL2(display, cpu_transcoder), 0); - ctl = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); + ctl = intel_de_read(display, + TRANS_DDI_FUNC_CTL(display, cpu_transcoder)); drm_WARN_ON(crtc->base.dev, ctl & TRANS_DDI_HDCP_SIGNALLING); ctl &= ~TRANS_DDI_FUNC_ENABLE; - if (IS_DISPLAY_VER(dev_priv, 8, 10)) + if (IS_DISPLAY_VER(display, 8, 10)) ctl &= ~(TRANS_DDI_PORT_SYNC_ENABLE | TRANS_DDI_PORT_SYNC_MASTER_SELECT_MASK); - if (DISPLAY_VER(dev_priv) >= 12) { + if (DISPLAY_VER(display) >= 12) { if (!intel_dp_mst_is_master_trans(crtc_state)) { ctl &= ~(TGL_TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK); @@ -706,7 +699,7 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state ctl &= ~(TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK); } - intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder), ctl); if (intel_dp_mst_is_slave_trans(crtc_state)) @@ -725,17 +718,15 @@ int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder, bool enable, u32 hdcp_mask) { struct intel_display *display = to_intel_display(intel_encoder); - struct drm_device *dev = intel_encoder->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); intel_wakeref_t wakeref; int ret = 0; wakeref = intel_display_power_get_if_enabled(display, intel_encoder->power_domain); - if (drm_WARN_ON(dev, !wakeref)) + if (drm_WARN_ON(display->drm, !wakeref)) return -ENXIO; - intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder), + intel_de_rmw(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder), hdcp_mask, enable ? hdcp_mask : 0); intel_display_power_put(display, intel_encoder->power_domain, wakeref); return ret; @@ -744,7 +735,6 @@ int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder, bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) { struct intel_display *display = to_intel_display(intel_connector); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder = intel_attached_encoder(intel_connector); int type = intel_connector->base.connector_type; enum port port = encoder->port; @@ -765,12 +755,12 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) goto out; } - if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) + if (HAS_TRANSCODER(display, TRANSCODER_EDP) && port == PORT_A) cpu_transcoder = TRANSCODER_EDP; else cpu_transcoder = (enum transcoder) pipe; - ddi_mode = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)) & + ddi_mode = intel_de_read(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder)) & TRANS_DDI_MODE_SELECT_MASK; if (ddi_mode == TRANS_DDI_MODE_SELECT_HDMI || @@ -804,7 +794,6 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, u8 *pipe_mask, bool *is_dp_mst) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(display->drm); enum port port = encoder->port; intel_wakeref_t wakeref; enum pipe p; @@ -819,13 +808,13 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, if (!wakeref) return; - tmp = intel_de_read(dev_priv, DDI_BUF_CTL(port)); + tmp = intel_de_read(display, DDI_BUF_CTL(port)); if (!(tmp & DDI_BUF_CTL_ENABLE)) goto out; - if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) { - tmp = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_EDP)); + if (HAS_TRANSCODER(display, TRANSCODER_EDP) && port == PORT_A) { + tmp = intel_de_read(display, + TRANS_DDI_FUNC_CTL(display, TRANSCODER_EDP)); switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { default: @@ -846,7 +835,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, goto out; } - for_each_pipe(dev_priv, p) { + for_each_pipe(display, p) { enum transcoder cpu_transcoder = (enum transcoder)p; u32 port_mask, ddi_select, ddi_mode; intel_wakeref_t trans_wakeref; @@ -856,7 +845,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, if (!trans_wakeref) continue; - if (DISPLAY_VER(dev_priv) >= 12) { + if (DISPLAY_VER(display) >= 12) { port_mask = TGL_TRANS_DDI_PORT_MASK; ddi_select = TGL_TRANS_DDI_SELECT_PORT(port); } else { @@ -864,8 +853,8 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, ddi_select = TRANS_DDI_SELECT_PORT(port); } - tmp = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); + tmp = intel_de_read(display, + TRANS_DDI_FUNC_CTL(display, cpu_transcoder)); intel_display_power_put(display, POWER_DOMAIN_TRANSCODER(cpu_transcoder), trans_wakeref); @@ -883,12 +872,12 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, } if (!*pipe_mask) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "No pipe for [ENCODER:%d:%s] found\n", encoder->base.base.id, encoder->base.name); if (!mst_pipe_mask && dp128b132b_pipe_mask) { - struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); /* * If we don't have 8b/10b MST, but have more than one @@ -901,12 +890,12 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, * can assume it's SST. */ if (hweight8(dp128b132b_pipe_mask) > 1 || - intel_dp_mst_encoder_active_links(dig_port)) + intel_dp_mst_active_streams(intel_dp)) mst_pipe_mask = dp128b132b_pipe_mask; } if (!mst_pipe_mask && hweight8(*pipe_mask) > 1) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Multiple pipes for [ENCODER:%d:%s] (pipe_mask %02x)\n", encoder->base.base.id, encoder->base.name, *pipe_mask); @@ -914,7 +903,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, } if (mst_pipe_mask && mst_pipe_mask != *pipe_mask) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Conflicting MST and non-MST state for [ENCODER:%d:%s] (pipe masks: all %02x, MST %02x, 128b/132b %02x)\n", encoder->base.base.id, encoder->base.name, *pipe_mask, mst_pipe_mask, dp128b132b_pipe_mask); @@ -922,12 +911,12 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, *is_dp_mst = mst_pipe_mask; out: - if (*pipe_mask && (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))) { - tmp = intel_de_read(dev_priv, BXT_PHY_CTL(port)); + if (*pipe_mask && (display->platform.geminilake || display->platform.broxton)) { + tmp = intel_de_read(display, BXT_PHY_CTL(port)); if ((tmp & (BXT_PHY_CMNLANE_POWERDOWN_ACK | BXT_PHY_LANE_POWERDOWN_ACK | BXT_PHY_LANE_ENABLED)) != BXT_PHY_LANE_ENABLED) - drm_err(&dev_priv->drm, + drm_err(display->drm, "[ENCODER:%d:%s] enabled but PHY powered down? (PHY_CTL %08x)\n", encoder->base.base.id, encoder->base.name, tmp); } @@ -1041,8 +1030,7 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder, void intel_ddi_enable_transcoder_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum phy phy = intel_encoder_to_phy(encoder); u32 val; @@ -1050,53 +1038,53 @@ void intel_ddi_enable_transcoder_clock(struct intel_encoder *encoder, if (cpu_transcoder == TRANSCODER_EDP) return; - if (DISPLAY_VER(dev_priv) >= 13) + if (DISPLAY_VER(display) >= 13) val = TGL_TRANS_CLK_SEL_PORT(phy); - else if (DISPLAY_VER(dev_priv) >= 12) + else if (DISPLAY_VER(display) >= 12) val = TGL_TRANS_CLK_SEL_PORT(encoder->port); else val = TRANS_CLK_SEL_PORT(encoder->port); - intel_de_write(dev_priv, TRANS_CLK_SEL(cpu_transcoder), val); + intel_de_write(display, TRANS_CLK_SEL(cpu_transcoder), val); } void intel_ddi_disable_transcoder_clock(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 val; if (cpu_transcoder == TRANSCODER_EDP) return; - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) val = TGL_TRANS_CLK_SEL_DISABLED; else val = TRANS_CLK_SEL_DISABLED; - intel_de_write(dev_priv, TRANS_CLK_SEL(cpu_transcoder), val); + intel_de_write(display, TRANS_CLK_SEL(cpu_transcoder), val); } -static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv, +static void _skl_ddi_set_iboost(struct intel_display *display, enum port port, u8 iboost) { u32 tmp; - tmp = intel_de_read(dev_priv, DISPIO_CR_TX_BMU_CR0); + tmp = intel_de_read(display, DISPIO_CR_TX_BMU_CR0); tmp &= ~(BALANCE_LEG_MASK(port) | BALANCE_LEG_DISABLE(port)); if (iboost) tmp |= iboost << BALANCE_LEG_SHIFT(port); else tmp |= BALANCE_LEG_DISABLE(port); - intel_de_write(dev_priv, DISPIO_CR_TX_BMU_CR0, tmp); + intel_de_write(display, DISPIO_CR_TX_BMU_CR0, tmp); } static void skl_ddi_set_iboost(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, int level) { + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u8 iboost; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) @@ -1109,7 +1097,7 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, int n_entries; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return; iboost = trans->entries[level].hsw.i_boost; @@ -1117,28 +1105,28 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, /* Make sure that the requested I_boost is valid */ if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) { - drm_err(&dev_priv->drm, "Invalid I_boost value %u\n", iboost); + drm_err(display->drm, "Invalid I_boost value %u\n", iboost); return; } - _skl_ddi_set_iboost(dev_priv, encoder->port, iboost); + _skl_ddi_set_iboost(display, encoder->port, iboost); if (encoder->port == PORT_A && dig_port->max_lanes == 4) - _skl_ddi_set_iboost(dev_priv, PORT_E, iboost); + _skl_ddi_set_iboost(display, PORT_E, iboost); } static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(intel_dp); struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); int n_entries; encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON(&dev_priv->drm, n_entries < 1)) + if (drm_WARN_ON(display->drm, n_entries < 1)) n_entries = 1; - if (drm_WARN_ON(&dev_priv->drm, + if (drm_WARN_ON(display->drm, n_entries > ARRAY_SIZE(index_to_dp_signal_levels))) n_entries = ARRAY_SIZE(index_to_dp_signal_levels); @@ -1171,14 +1159,14 @@ static u32 icl_combo_phy_loadgen_select(const struct intel_crtc_state *crtc_stat static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_ddi_buf_trans *trans; enum phy phy = intel_encoder_to_phy(encoder); int n_entries, ln; u32 val; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) { @@ -1186,25 +1174,25 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, val = EDP4K2K_MODE_OVRD_EN | EDP4K2K_MODE_OVRD_OPTIMIZED; intel_dp->hobl_active = is_hobl_buf_trans(trans); - intel_de_rmw(dev_priv, ICL_PORT_CL_DW10(phy), val, + intel_de_rmw(display, ICL_PORT_CL_DW10(phy), val, intel_dp->hobl_active ? val : 0); } /* Set PORT_TX_DW5 */ - val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); + val = intel_de_read(display, ICL_PORT_TX_DW5_LN(0, phy)); val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK | COEFF_POLARITY | CURSOR_PROGRAM | TAP2_DISABLE | TAP3_DISABLE); val |= SCALING_MODE_SEL(0x2); val |= RTERM_SELECT(0x6); val |= TAP3_DISABLE; - intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); + intel_de_write(display, ICL_PORT_TX_DW5_GRP(phy), val); /* Program PORT_TX_DW2 */ for (ln = 0; ln < 4; ln++) { int level = intel_ddi_level(encoder, crtc_state, ln); - intel_de_rmw(dev_priv, ICL_PORT_TX_DW2_LN(ln, phy), + intel_de_rmw(display, ICL_PORT_TX_DW2_LN(ln, phy), SWING_SEL_UPPER_MASK | SWING_SEL_LOWER_MASK | RCOMP_SCALAR_MASK, SWING_SEL_UPPER(trans->entries[level].icl.dw2_swing_sel) | SWING_SEL_LOWER(trans->entries[level].icl.dw2_swing_sel) | @@ -1216,7 +1204,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, for (ln = 0; ln < 4; ln++) { int level = intel_ddi_level(encoder, crtc_state, ln); - intel_de_rmw(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy), + intel_de_rmw(display, ICL_PORT_TX_DW4_LN(ln, phy), POST_CURSOR_1_MASK | POST_CURSOR_2_MASK | CURSOR_COEFF_MASK, POST_CURSOR_1(trans->entries[level].icl.dw4_post_cursor_1) | POST_CURSOR_2(trans->entries[level].icl.dw4_post_cursor_2) | @@ -1227,7 +1215,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, for (ln = 0; ln < 4; ln++) { int level = intel_ddi_level(encoder, crtc_state, ln); - intel_de_rmw(dev_priv, ICL_PORT_TX_DW7_LN(ln, phy), + intel_de_rmw(display, ICL_PORT_TX_DW7_LN(ln, phy), N_SCALAR_MASK, N_SCALAR(trans->entries[level].icl.dw7_n_scalar)); } @@ -1236,7 +1224,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); u32 val; int ln; @@ -1246,12 +1234,12 @@ static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, * set PORT_PCS_DW1 cmnkeeper_enable to 1b, * else clear to 0b. */ - val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN(0, phy)); + val = intel_de_read(display, ICL_PORT_PCS_DW1_LN(0, phy)); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) val &= ~COMMON_KEEPER_EN; else val |= COMMON_KEEPER_EN; - intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy), val); + intel_de_write(display, ICL_PORT_PCS_DW1_GRP(phy), val); /* 2. Program loadgen select */ /* @@ -1261,33 +1249,33 @@ static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0) */ for (ln = 0; ln < 4; ln++) { - intel_de_rmw(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy), + intel_de_rmw(display, ICL_PORT_TX_DW4_LN(ln, phy), LOADGEN_SELECT, icl_combo_phy_loadgen_select(crtc_state, ln)); } /* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */ - intel_de_rmw(dev_priv, ICL_PORT_CL_DW5(phy), + intel_de_rmw(display, ICL_PORT_CL_DW5(phy), 0, SUS_CLOCK_CONFIG); /* 4. Clear training enable to change swing values */ - val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); + val = intel_de_read(display, ICL_PORT_TX_DW5_LN(0, phy)); val &= ~TX_TRAINING_EN; - intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); + intel_de_write(display, ICL_PORT_TX_DW5_GRP(phy), val); /* 5. Program swing and de-emphasis */ icl_ddi_combo_vswing_program(encoder, crtc_state); /* 6. Set training enable to trigger update */ - val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); + val = intel_de_read(display, ICL_PORT_TX_DW5_LN(0, phy)); val |= TX_TRAINING_EN; - intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); + intel_de_write(display, ICL_PORT_TX_DW5_GRP(phy), val); } static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum tc_port tc_port = intel_encoder_to_tc(encoder); const struct intel_ddi_buf_trans *trans; int n_entries, ln; @@ -1296,13 +1284,13 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, return; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return; for (ln = 0; ln < 2; ln++) { - intel_de_rmw(dev_priv, MG_TX1_LINK_PARAMS(ln, tc_port), + intel_de_rmw(display, MG_TX1_LINK_PARAMS(ln, tc_port), CRI_USE_FS32, 0); - intel_de_rmw(dev_priv, MG_TX2_LINK_PARAMS(ln, tc_port), + intel_de_rmw(display, MG_TX2_LINK_PARAMS(ln, tc_port), CRI_USE_FS32, 0); } @@ -1312,13 +1300,13 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, level = intel_ddi_level(encoder, crtc_state, 2*ln+0); - intel_de_rmw(dev_priv, MG_TX1_SWINGCTRL(ln, tc_port), + intel_de_rmw(display, MG_TX1_SWINGCTRL(ln, tc_port), CRI_TXDEEMPH_OVERRIDE_17_12_MASK, CRI_TXDEEMPH_OVERRIDE_17_12(trans->entries[level].mg.cri_txdeemph_override_17_12)); level = intel_ddi_level(encoder, crtc_state, 2*ln+1); - intel_de_rmw(dev_priv, MG_TX2_SWINGCTRL(ln, tc_port), + intel_de_rmw(display, MG_TX2_SWINGCTRL(ln, tc_port), CRI_TXDEEMPH_OVERRIDE_17_12_MASK, CRI_TXDEEMPH_OVERRIDE_17_12(trans->entries[level].mg.cri_txdeemph_override_17_12)); } @@ -1329,7 +1317,7 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, level = intel_ddi_level(encoder, crtc_state, 2*ln+0); - intel_de_rmw(dev_priv, MG_TX1_DRVCTRL(ln, tc_port), + intel_de_rmw(display, MG_TX1_DRVCTRL(ln, tc_port), CRI_TXDEEMPH_OVERRIDE_11_6_MASK | CRI_TXDEEMPH_OVERRIDE_5_0_MASK, CRI_TXDEEMPH_OVERRIDE_11_6(trans->entries[level].mg.cri_txdeemph_override_11_6) | @@ -1338,7 +1326,7 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, level = intel_ddi_level(encoder, crtc_state, 2*ln+1); - intel_de_rmw(dev_priv, MG_TX2_DRVCTRL(ln, tc_port), + intel_de_rmw(display, MG_TX2_DRVCTRL(ln, tc_port), CRI_TXDEEMPH_OVERRIDE_11_6_MASK | CRI_TXDEEMPH_OVERRIDE_5_0_MASK, CRI_TXDEEMPH_OVERRIDE_11_6(trans->entries[level].mg.cri_txdeemph_override_11_6) | @@ -1354,21 +1342,21 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, * values from table for which TX1 and TX2 enabled. */ for (ln = 0; ln < 2; ln++) { - intel_de_rmw(dev_priv, MG_CLKHUB(ln, tc_port), + intel_de_rmw(display, MG_CLKHUB(ln, tc_port), CFG_LOW_RATE_LKREN_EN, crtc_state->port_clock < 300000 ? CFG_LOW_RATE_LKREN_EN : 0); } /* Program the MG_TX_DCC based on the link frequency */ for (ln = 0; ln < 2; ln++) { - intel_de_rmw(dev_priv, MG_TX1_DCC(ln, tc_port), + intel_de_rmw(display, MG_TX1_DCC(ln, tc_port), CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK | CFG_AMI_CK_DIV_OVERRIDE_EN, crtc_state->port_clock > 500000 ? CFG_AMI_CK_DIV_OVERRIDE_VAL(1) | CFG_AMI_CK_DIV_OVERRIDE_EN : 0); - intel_de_rmw(dev_priv, MG_TX2_DCC(ln, tc_port), + intel_de_rmw(display, MG_TX2_DCC(ln, tc_port), CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK | CFG_AMI_CK_DIV_OVERRIDE_EN, crtc_state->port_clock > 500000 ? @@ -1378,9 +1366,9 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, /* Program MG_TX_PISO_READLOAD with values from vswing table */ for (ln = 0; ln < 2; ln++) { - intel_de_rmw(dev_priv, MG_TX1_PISO_READLOAD(ln, tc_port), + intel_de_rmw(display, MG_TX1_PISO_READLOAD(ln, tc_port), 0, CRI_CALCINIT); - intel_de_rmw(dev_priv, MG_TX2_PISO_READLOAD(ln, tc_port), + intel_de_rmw(display, MG_TX2_PISO_READLOAD(ln, tc_port), 0, CRI_CALCINIT); } } @@ -1490,12 +1478,12 @@ int intel_ddi_level(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, int lane) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_ddi_buf_trans *trans; int level, n_entries; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&i915->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return 0; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) @@ -1504,7 +1492,7 @@ int intel_ddi_level(struct intel_encoder *encoder, level = intel_ddi_dp_level(enc_to_intel_dp(encoder), crtc_state, lane); - if (drm_WARN_ON_ONCE(&i915->drm, level >= n_entries)) + if (drm_WARN_ON_ONCE(display->drm, level >= n_entries)) level = n_entries - 1; return level; @@ -1514,13 +1502,13 @@ static void hsw_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); int level = intel_ddi_level(encoder, crtc_state, 0); enum port port = encoder->port; u32 signal_levels; - if (has_iboost(dev_priv)) + if (has_iboost(display)) skl_ddi_set_iboost(encoder, crtc_state, level); /* HDMI ignores the rest */ @@ -1529,46 +1517,46 @@ hsw_set_signal_levels(struct intel_encoder *encoder, signal_levels = DDI_BUF_TRANS_SELECT(level); - drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n", + drm_dbg_kms(display->drm, "Using signal levels %08x\n", signal_levels); intel_dp->DP &= ~DDI_BUF_EMP_MASK; intel_dp->DP |= signal_levels; - intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); - intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); + intel_de_write(display, DDI_BUF_CTL(port), intel_dp->DP); + intel_de_posting_read(display, DDI_BUF_CTL(port)); } -static void _icl_ddi_enable_clock(struct drm_i915_private *i915, i915_reg_t reg, +static void _icl_ddi_enable_clock(struct intel_display *display, i915_reg_t reg, u32 clk_sel_mask, u32 clk_sel, u32 clk_off) { - mutex_lock(&i915->display.dpll.lock); + mutex_lock(&display->dpll.lock); - intel_de_rmw(i915, reg, clk_sel_mask, clk_sel); + intel_de_rmw(display, reg, clk_sel_mask, clk_sel); /* * "This step and the step before must be * done with separate register writes." */ - intel_de_rmw(i915, reg, clk_off, 0); + intel_de_rmw(display, reg, clk_off, 0); - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); } -static void _icl_ddi_disable_clock(struct drm_i915_private *i915, i915_reg_t reg, +static void _icl_ddi_disable_clock(struct intel_display *display, i915_reg_t reg, u32 clk_off) { - mutex_lock(&i915->display.dpll.lock); + mutex_lock(&display->dpll.lock); - intel_de_rmw(i915, reg, 0, clk_off); + intel_de_rmw(display, reg, 0, clk_off); - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); } -static bool _icl_ddi_is_clock_enabled(struct drm_i915_private *i915, i915_reg_t reg, +static bool _icl_ddi_is_clock_enabled(struct intel_display *display, i915_reg_t reg, u32 clk_off) { - return !(intel_de_read(i915, reg) & clk_off); + return !(intel_de_read(display, reg) & clk_off); } static struct intel_shared_dpll * @@ -1585,14 +1573,14 @@ _icl_ddi_get_pll(struct intel_display *display, i915_reg_t reg, static void adls_ddi_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum phy phy = intel_encoder_to_phy(encoder); - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; - _icl_ddi_enable_clock(i915, ADLS_DPCLKA_CFGCR(phy), + _icl_ddi_enable_clock(display, ADLS_DPCLKA_CFGCR(phy), ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy), pll->info->id << ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy), ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); @@ -1600,19 +1588,19 @@ static void adls_ddi_enable_clock(struct intel_encoder *encoder, static void adls_ddi_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - _icl_ddi_disable_clock(i915, ADLS_DPCLKA_CFGCR(phy), + _icl_ddi_disable_clock(display, ADLS_DPCLKA_CFGCR(phy), ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } static bool adls_ddi_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_is_clock_enabled(i915, ADLS_DPCLKA_CFGCR(phy), + return _icl_ddi_is_clock_enabled(display, ADLS_DPCLKA_CFGCR(phy), ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } @@ -1629,14 +1617,14 @@ static struct intel_shared_dpll *adls_ddi_get_pll(struct intel_encoder *encoder) static void rkl_ddi_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum phy phy = intel_encoder_to_phy(encoder); - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; - _icl_ddi_enable_clock(i915, ICL_DPCLKA_CFGCR0, + _icl_ddi_enable_clock(display, ICL_DPCLKA_CFGCR0, RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), RKL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy), RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); @@ -1644,19 +1632,19 @@ static void rkl_ddi_enable_clock(struct intel_encoder *encoder, static void rkl_ddi_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - _icl_ddi_disable_clock(i915, ICL_DPCLKA_CFGCR0, + _icl_ddi_disable_clock(display, ICL_DPCLKA_CFGCR0, RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } static bool rkl_ddi_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_is_clock_enabled(i915, ICL_DPCLKA_CFGCR0, + return _icl_ddi_is_clock_enabled(display, ICL_DPCLKA_CFGCR0, RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } @@ -1673,23 +1661,23 @@ static struct intel_shared_dpll *rkl_ddi_get_pll(struct intel_encoder *encoder) static void dg1_ddi_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum phy phy = intel_encoder_to_phy(encoder); - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; /* * If we fail this, something went very wrong: first 2 PLLs should be * used by first 2 phys and last 2 PLLs by last phys */ - if (drm_WARN_ON(&i915->drm, + if (drm_WARN_ON(display->drm, (pll->info->id < DPLL_ID_DG1_DPLL2 && phy >= PHY_C) || (pll->info->id >= DPLL_ID_DG1_DPLL2 && phy < PHY_C))) return; - _icl_ddi_enable_clock(i915, DG1_DPCLKA_CFGCR0(phy), + _icl_ddi_enable_clock(display, DG1_DPCLKA_CFGCR0(phy), DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), DG1_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy), DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); @@ -1697,19 +1685,19 @@ static void dg1_ddi_enable_clock(struct intel_encoder *encoder, static void dg1_ddi_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - _icl_ddi_disable_clock(i915, DG1_DPCLKA_CFGCR0(phy), + _icl_ddi_disable_clock(display, DG1_DPCLKA_CFGCR0(phy), DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } static bool dg1_ddi_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_is_clock_enabled(i915, DG1_DPCLKA_CFGCR0(phy), + return _icl_ddi_is_clock_enabled(display, DG1_DPCLKA_CFGCR0(phy), DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } @@ -1739,14 +1727,14 @@ static struct intel_shared_dpll *dg1_ddi_get_pll(struct intel_encoder *encoder) static void icl_ddi_combo_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum phy phy = intel_encoder_to_phy(encoder); - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; - _icl_ddi_enable_clock(i915, ICL_DPCLKA_CFGCR0, + _icl_ddi_enable_clock(display, ICL_DPCLKA_CFGCR0, ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy), ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); @@ -1754,19 +1742,19 @@ static void icl_ddi_combo_enable_clock(struct intel_encoder *encoder, static void icl_ddi_combo_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - _icl_ddi_disable_clock(i915, ICL_DPCLKA_CFGCR0, + _icl_ddi_disable_clock(display, ICL_DPCLKA_CFGCR0, ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } static bool icl_ddi_combo_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_is_clock_enabled(i915, ICL_DPCLKA_CFGCR0, + return _icl_ddi_is_clock_enabled(display, ICL_DPCLKA_CFGCR0, ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } @@ -1783,39 +1771,39 @@ struct intel_shared_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder) static void jsl_ddi_tc_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum port port = encoder->port; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; /* * "For DDIC and DDID, program DDI_CLK_SEL to map the MG clock to the port. * MG does not exist, but the programming is required to ungate DDIC and DDID." */ - intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_MG); + intel_de_write(display, DDI_CLK_SEL(port), DDI_CLK_SEL_MG); icl_ddi_combo_enable_clock(encoder, crtc_state); } static void jsl_ddi_tc_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; icl_ddi_combo_disable_clock(encoder); - intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); + intel_de_write(display, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); } static bool jsl_ddi_tc_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; u32 tmp; - tmp = intel_de_read(i915, DDI_CLK_SEL(port)); + tmp = intel_de_read(display, DDI_CLK_SEL(port)); if ((tmp & DDI_CLK_SEL_MASK) == DDI_CLK_SEL_NONE) return false; @@ -1826,54 +1814,54 @@ static bool jsl_ddi_tc_is_clock_enabled(struct intel_encoder *encoder) static void icl_ddi_tc_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum tc_port tc_port = intel_encoder_to_tc(encoder); enum port port = encoder->port; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; - intel_de_write(i915, DDI_CLK_SEL(port), + intel_de_write(display, DDI_CLK_SEL(port), icl_pll_to_ddi_clk_sel(encoder, crtc_state)); - mutex_lock(&i915->display.dpll.lock); + mutex_lock(&display->dpll.lock); - intel_de_rmw(i915, ICL_DPCLKA_CFGCR0, + intel_de_rmw(display, ICL_DPCLKA_CFGCR0, ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port), 0); - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); } static void icl_ddi_tc_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum tc_port tc_port = intel_encoder_to_tc(encoder); enum port port = encoder->port; - mutex_lock(&i915->display.dpll.lock); + mutex_lock(&display->dpll.lock); - intel_de_rmw(i915, ICL_DPCLKA_CFGCR0, + intel_de_rmw(display, ICL_DPCLKA_CFGCR0, 0, ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port)); - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); - intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); + intel_de_write(display, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); } static bool icl_ddi_tc_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum tc_port tc_port = intel_encoder_to_tc(encoder); enum port port = encoder->port; u32 tmp; - tmp = intel_de_read(i915, DDI_CLK_SEL(port)); + tmp = intel_de_read(display, DDI_CLK_SEL(port)); if ((tmp & DDI_CLK_SEL_MASK) == DDI_CLK_SEL_NONE) return false; - tmp = intel_de_read(i915, ICL_DPCLKA_CFGCR0); + tmp = intel_de_read(display, ICL_DPCLKA_CFGCR0); return !(tmp & ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port)); } @@ -1934,47 +1922,47 @@ static struct intel_shared_dpll *bxt_ddi_get_pll(struct intel_encoder *encoder) static void skl_ddi_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum port port = encoder->port; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; - mutex_lock(&i915->display.dpll.lock); + mutex_lock(&display->dpll.lock); - intel_de_rmw(i915, DPLL_CTRL2, + intel_de_rmw(display, DPLL_CTRL2, DPLL_CTRL2_DDI_CLK_OFF(port) | DPLL_CTRL2_DDI_CLK_SEL_MASK(port), DPLL_CTRL2_DDI_CLK_SEL(pll->info->id, port) | DPLL_CTRL2_DDI_SEL_OVERRIDE(port)); - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); } static void skl_ddi_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; - mutex_lock(&i915->display.dpll.lock); + mutex_lock(&display->dpll.lock); - intel_de_rmw(i915, DPLL_CTRL2, + intel_de_rmw(display, DPLL_CTRL2, 0, DPLL_CTRL2_DDI_CLK_OFF(port)); - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); } static bool skl_ddi_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; /* * FIXME Not sure if the override affects both * the PLL selection and the CLK_OFF bit. */ - return !(intel_de_read(i915, DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_OFF(port)); + return !(intel_de_read(display, DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_OFF(port)); } static struct intel_shared_dpll *skl_ddi_get_pll(struct intel_encoder *encoder) @@ -2002,30 +1990,30 @@ static struct intel_shared_dpll *skl_ddi_get_pll(struct intel_encoder *encoder) void hsw_ddi_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum port port = encoder->port; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; - intel_de_write(i915, PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll)); + intel_de_write(display, PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll)); } void hsw_ddi_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; - intel_de_write(i915, PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); + intel_de_write(display, PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); } bool hsw_ddi_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; - return intel_de_read(i915, PORT_CLK_SEL(port)) != PORT_CLK_SEL_NONE; + return intel_de_read(display, PORT_CLK_SEL(port)) != PORT_CLK_SEL_NONE; } static struct intel_shared_dpll *hsw_ddi_get_pll(struct intel_encoder *encoder) @@ -2081,7 +2069,7 @@ void intel_ddi_disable_clock(struct intel_encoder *encoder) void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); u32 port_mask; bool ddi_clk_needed; @@ -2101,7 +2089,7 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) * In the unlikely case that BIOS enables DP in MST mode, just * warn since our MST HW readout is incomplete. */ - if (drm_WARN_ON(&i915->drm, is_mst)) + if (drm_WARN_ON(display->drm, is_mst)) return; } @@ -2116,11 +2104,11 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) * Sanity check that we haven't incorrectly registered another * encoder using any of the ports of this DSI encoder. */ - for_each_intel_encoder(&i915->drm, other_encoder) { + for_each_intel_encoder(display->drm, other_encoder) { if (other_encoder == encoder) continue; - if (drm_WARN_ON(&i915->drm, + if (drm_WARN_ON(display->drm, port_mask & BIT(other_encoder->port))) return; } @@ -2135,7 +2123,7 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) !encoder->is_clock_enabled(encoder)) return; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] is disabled/in DSI mode with an ungated DDI clock, gate it\n", encoder->base.base.id, encoder->base.name); @@ -2255,10 +2243,10 @@ tgl_dp_tp_transcoder(const struct intel_crtc_state *crtc_state) i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - if (DISPLAY_VER(dev_priv) >= 12) - return TGL_DP_TP_CTL(dev_priv, + if (DISPLAY_VER(display) >= 12) + return TGL_DP_TP_CTL(display, tgl_dp_tp_transcoder(crtc_state)); else return DP_TP_CTL(encoder->port); @@ -2267,10 +2255,10 @@ i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder, static i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - if (DISPLAY_VER(dev_priv) >= 12) - return TGL_DP_TP_STATUS(dev_priv, + if (DISPLAY_VER(display) >= 12) + return TGL_DP_TP_STATUS(display, tgl_dp_tp_transcoder(crtc_state)); else return DP_TP_STATUS(encoder->port); @@ -2445,14 +2433,14 @@ static void intel_ddi_enable_fec(struct intel_encoder *encoder, static void intel_ddi_disable_fec(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); if (!crtc_state->fec_enable) return; - intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), + intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state), DP_TP_CTL_FEC_ENABLE, 0); - intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); + intel_de_posting_read(display, dp_tp_ctl_reg(encoder, crtc_state)); } static void intel_ddi_power_up_lanes(struct intel_encoder *encoder, @@ -2474,11 +2462,11 @@ static void intel_ddi_power_up_lanes(struct intel_encoder *encoder, * Splitter enable for eDP MSO is limited to certain pipes, on certain * platforms. */ -static u8 intel_ddi_splitter_pipe_mask(struct drm_i915_private *i915) +static u8 intel_ddi_splitter_pipe_mask(struct intel_display *display) { - if (DISPLAY_VER(i915) > 20) + if (DISPLAY_VER(display) > 20) return ~0; - else if (IS_ALDERLAKE_P(i915)) + else if (display->platform.alderlake_p) return BIT(PIPE_A) | BIT(PIPE_B); else return BIT(PIPE_A); @@ -2487,28 +2475,28 @@ static u8 intel_ddi_splitter_pipe_mask(struct drm_i915_private *i915) static void intel_ddi_mso_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { + struct intel_display *display = to_intel_display(pipe_config); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; u32 dss1; - if (!HAS_MSO(i915)) + if (!HAS_MSO(display)) return; - dss1 = intel_de_read(i915, ICL_PIPE_DSS_CTL1(pipe)); + dss1 = intel_de_read(display, ICL_PIPE_DSS_CTL1(pipe)); pipe_config->splitter.enable = dss1 & SPLITTER_ENABLE; if (!pipe_config->splitter.enable) return; - if (drm_WARN_ON(&i915->drm, !(intel_ddi_splitter_pipe_mask(i915) & BIT(pipe)))) { + if (drm_WARN_ON(display->drm, !(intel_ddi_splitter_pipe_mask(display) & BIT(pipe)))) { pipe_config->splitter.enable = false; return; } switch (dss1 & SPLITTER_CONFIGURATION_MASK) { default: - drm_WARN(&i915->drm, true, + drm_WARN(display->drm, true, "Invalid splitter configuration, dss1=0x%08x\n", dss1); fallthrough; case SPLITTER_CONFIGURATION_2_SEGMENT: @@ -2524,12 +2512,12 @@ static void intel_ddi_mso_get_config(struct intel_encoder *encoder, static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; u32 dss1 = 0; - if (!HAS_MSO(i915)) + if (!HAS_MSO(display)) return; if (crtc_state->splitter.enable) { @@ -2541,7 +2529,7 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state) dss1 |= SPLITTER_CONFIGURATION_4_SEGMENT; } - intel_de_rmw(i915, ICL_PIPE_DSS_CTL1(pipe), + intel_de_rmw(display, ICL_PIPE_DSS_CTL1(pipe), SPLITTER_ENABLE | SPLITTER_CONFIGURATION_MASK | OVERLAP_PIXELS_MASK, dss1); } @@ -2549,27 +2537,27 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state) static void mtl_ddi_enable_d2d(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; i915_reg_t reg; u32 set_bits, wait_bits; - if (DISPLAY_VER(dev_priv) < 14) + if (DISPLAY_VER(display) < 14) return; - if (DISPLAY_VER(dev_priv) >= 20) { + if (DISPLAY_VER(display) >= 20) { reg = DDI_BUF_CTL(port); set_bits = XE2LPD_DDI_BUF_D2D_LINK_ENABLE; wait_bits = XE2LPD_DDI_BUF_D2D_LINK_STATE; } else { - reg = XELPDP_PORT_BUF_CTL1(dev_priv, port); + reg = XELPDP_PORT_BUF_CTL1(display, port); set_bits = XELPDP_PORT_BUF_D2D_LINK_ENABLE; wait_bits = XELPDP_PORT_BUF_D2D_LINK_STATE; } - intel_de_rmw(dev_priv, reg, 0, set_bits); - if (wait_for_us(intel_de_read(dev_priv, reg) & wait_bits, 100)) { - drm_err(&dev_priv->drm, "Timeout waiting for D2D Link enable for DDI/PORT_BUF_CTL %c\n", + intel_de_rmw(display, reg, 0, set_bits); + if (wait_for_us(intel_de_read(display, reg) & wait_bits, 100)) { + drm_err(display->drm, "Timeout waiting for D2D Link enable for DDI/PORT_BUF_CTL %c\n", port_name(port)); } } @@ -2599,13 +2587,13 @@ static void mtl_port_buf_ctl_program(struct intel_encoder *encoder, static void mtl_port_buf_ctl_io_selection(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); u32 val; val = intel_tc_port_in_tbt_alt_mode(dig_port) ? XELPDP_PORT_BUF_IO_SELECT_TBT : 0; - intel_de_rmw(i915, XELPDP_PORT_BUF_CTL1(i915, encoder->port), + intel_de_rmw(display, XELPDP_PORT_BUF_CTL1(display, encoder->port), XELPDP_PORT_BUF_IO_SELECT_TBT, val); } @@ -2734,7 +2722,6 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); int ret; @@ -2778,7 +2765,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, /* 5. If IO power is controlled through PWR_WELL_CTL, Enable IO Power */ if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { - drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); + drm_WARN_ON(display->drm, dig_port->ddi_io_wakeref); dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); } @@ -2882,16 +2869,15 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); - if (DISPLAY_VER(dev_priv) < 11) - drm_WARN_ON(&dev_priv->drm, + if (DISPLAY_VER(display) < 11) + drm_WARN_ON(display->drm, is_mst && (port == PORT_A || port == PORT_E)); else - drm_WARN_ON(&dev_priv->drm, is_mst && port == PORT_A); + drm_WARN_ON(display->drm, is_mst && port == PORT_A); intel_dp_set_link_params(intel_dp, crtc_state->port_clock, @@ -2908,14 +2894,14 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, intel_ddi_enable_clock(encoder, crtc_state); if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { - drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); + drm_WARN_ON(display->drm, dig_port->ddi_io_wakeref); dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); } icl_program_mg_dp_mode(dig_port, crtc_state); - if (has_buf_trans_select(dev_priv)) + if (has_buf_trans_select(display)) hsw_prepare_dp_ddi_buffers(encoder, crtc_state); encoder->set_signal_levels(encoder, crtc_state); @@ -2931,7 +2917,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, crtc_state); intel_dp_sink_set_fec_ready(intel_dp, crtc_state, true); intel_dp_start_link_train(state, intel_dp, crtc_state); - if ((port != PORT_A || DISPLAY_VER(dev_priv) >= 9) && + if ((port != PORT_A || DISPLAY_VER(display) >= 9) && !is_trans_port_sync_mode(crtc_state)) intel_dp_stop_link_train(intel_dp, crtc_state); @@ -2979,12 +2965,11 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_hdmi *intel_hdmi = &dig_port->hdmi; - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); intel_ddi_enable_clock(encoder, crtc_state); - drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); + drm_WARN_ON(display->drm, dig_port->ddi_io_wakeref); dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); @@ -3022,10 +3007,9 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - drm_WARN_ON(&dev_priv->drm, crtc_state->has_pch_encoder); + drm_WARN_ON(display->drm, crtc_state->has_pch_encoder); intel_set_cpu_fifo_underrun_reporting(display, pipe, true); @@ -3050,27 +3034,27 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state, static void mtl_ddi_disable_d2d(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; i915_reg_t reg; u32 clr_bits, wait_bits; - if (DISPLAY_VER(dev_priv) < 14) + if (DISPLAY_VER(display) < 14) return; - if (DISPLAY_VER(dev_priv) >= 20) { + if (DISPLAY_VER(display) >= 20) { reg = DDI_BUF_CTL(port); clr_bits = XE2LPD_DDI_BUF_D2D_LINK_ENABLE; wait_bits = XE2LPD_DDI_BUF_D2D_LINK_STATE; } else { - reg = XELPDP_PORT_BUF_CTL1(dev_priv, port); + reg = XELPDP_PORT_BUF_CTL1(display, port); clr_bits = XELPDP_PORT_BUF_D2D_LINK_ENABLE; wait_bits = XELPDP_PORT_BUF_D2D_LINK_STATE; } - intel_de_rmw(dev_priv, reg, clr_bits, 0); - if (wait_for_us(!(intel_de_read(dev_priv, reg) & wait_bits), 100)) - drm_err(&dev_priv->drm, "Timeout waiting for D2D Link disable for DDI/PORT_BUF_CTL %c\n", + intel_de_rmw(display, reg, clr_bits, 0); + if (wait_for_us(!(intel_de_read(display, reg) & wait_bits), 100)) + drm_err(display->drm, "Timeout waiting for D2D Link disable for DDI/PORT_BUF_CTL %c\n", port_name(port)); } @@ -3089,10 +3073,9 @@ static void intel_ddi_buf_disable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; - intel_de_rmw(dev_priv, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0); + intel_de_rmw(display, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0); if (DISPLAY_VER(display) >= 14) intel_wait_ddi_buf_idle(display, port); @@ -3100,7 +3083,7 @@ static void intel_ddi_buf_disable(struct intel_encoder *encoder, mtl_ddi_disable_d2d(encoder); if (intel_crtc_has_dp_encoder(crtc_state)) { - intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), + intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state), DP_TP_CTL_ENABLE, 0); } @@ -3118,7 +3101,6 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, const struct drm_connector_state *old_conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_dp *intel_dp = &dig_port->dp; intel_wakeref_t wakeref; @@ -3135,12 +3117,12 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, */ intel_dp_set_power(intel_dp, DP_SET_POWER_D3); - if (DISPLAY_VER(dev_priv) >= 12) { + if (DISPLAY_VER(display) >= 12) { if (is_mst || intel_dp_is_uhbr(old_crtc_state)) { enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; - intel_de_rmw(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder), + intel_de_rmw(display, + TRANS_DDI_FUNC_CTL(display, cpu_transcoder), TGL_TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK, 0); } @@ -3160,7 +3142,7 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, * Configure Transcoder Clock select to direct no clock to the * transcoder" */ - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) intel_ddi_disable_transcoder_clock(old_crtc_state); intel_pps_vdd_on(intel_dp); @@ -3176,8 +3158,8 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, intel_ddi_disable_clock(encoder); /* De-select Thunderbolt */ - if (DISPLAY_VER(dev_priv) >= 14) - intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(dev_priv, encoder->port), + if (DISPLAY_VER(display) >= 14) + intel_de_rmw(display, XELPDP_PORT_BUF_CTL1(display, encoder->port), XELPDP_PORT_BUF_IO_SELECT_TBT, 0); } @@ -3187,7 +3169,6 @@ static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state, const struct drm_connector_state *old_conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_hdmi *intel_hdmi = &dig_port->hdmi; intel_wakeref_t wakeref; @@ -3195,12 +3176,12 @@ static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state, dig_port->set_infoframes(encoder, false, old_crtc_state, old_conn_state); - if (DISPLAY_VER(dev_priv) < 12) + if (DISPLAY_VER(display) < 12) intel_ddi_disable_transcoder_clock(old_crtc_state); intel_ddi_buf_disable(encoder, old_crtc_state); - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) intel_ddi_disable_transcoder_clock(old_crtc_state); wakeref = fetch_and_zero(&dig_port->ddi_io_wakeref); @@ -3220,7 +3201,6 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state, const struct drm_connector_state *old_conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_crtc *pipe_crtc; bool is_hdmi = intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI); @@ -3249,6 +3229,8 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state, drm_dp_dpcd_poll_act_handled(&intel_dp->aux, 0); } + intel_vrr_transcoder_disable(old_crtc_state); + intel_ddi_disable_transcoder_func(old_crtc_state); for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { @@ -3257,7 +3239,7 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state, intel_dsc_disable(old_pipe_crtc_state); - if (DISPLAY_VER(dev_priv) >= 9) + if (DISPLAY_VER(display) >= 9) skl_scaler_disable(old_pipe_crtc_state); else ilk_pfit_disable(old_pipe_crtc_state); @@ -3359,12 +3341,12 @@ static void intel_ddi_enable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); enum port port = encoder->port; - if (port == PORT_A && DISPLAY_VER(dev_priv) < 9) + if (port == PORT_A && DISPLAY_VER(display) < 9) intel_dp_stop_link_train(intel_dp, crtc_state); drm_connector_update_privacy_screen(conn_state); @@ -3401,7 +3383,6 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, const struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct drm_connector *connector = conn_state->connector; enum port port = encoder->port; @@ -3410,11 +3391,11 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, if (!intel_hdmi_handle_sink_scrambling(encoder, connector, crtc_state->hdmi_high_tmds_clock_ratio, crtc_state->hdmi_scrambling)) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Failed to configure sink scrambling/TMDS bit clock ratio\n", connector->base.id, connector->name); - if (has_buf_trans_select(dev_priv)) + if (has_buf_trans_select(display)) hsw_prepare_hdmi_ddi_buffers(encoder, crtc_state); /* e. Enable D2D Link for C10/C20 Phy */ @@ -3423,7 +3404,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, encoder->set_signal_levels(encoder, crtc_state); /* Display WA #1143: skl,kbl,cfl */ - if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) { + if (DISPLAY_VER(display) == 9 && !display->platform.broxton) { /* * For some reason these chicken bits have been * stuffed into a transcoder register, event though @@ -3433,7 +3414,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, i915_reg_t reg = gen9_chicken_trans_reg_by_port(display, port); u32 val; - val = intel_de_read(dev_priv, reg); + val = intel_de_read(display, reg); if (port == PORT_E) val |= DDIE_TRAINING_OVERRIDE_ENABLE | @@ -3442,8 +3423,8 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, val |= DDI_TRAINING_OVERRIDE_ENABLE | DDI_TRAINING_OVERRIDE_VALUE; - intel_de_write(dev_priv, reg, val); - intel_de_posting_read(dev_priv, reg); + intel_de_write(display, reg, val); + intel_de_posting_read(display, reg); udelay(1); @@ -3454,7 +3435,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, val &= ~(DDI_TRAINING_OVERRIDE_ENABLE | DDI_TRAINING_OVERRIDE_VALUE); - intel_de_write(dev_priv, reg, val); + intel_de_write(display, reg, val); } intel_ddi_power_up_lanes(encoder, crtc_state); @@ -3475,7 +3456,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, if (dig_port->ddi_a_4_lanes) buf_ctl |= DDI_A_4_LANES; - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { u32 port_buf = 0; port_buf |= XELPDP_PORT_WIDTH(crtc_state->lane_count); @@ -3483,15 +3464,15 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, if (dig_port->lane_reversal) port_buf |= XELPDP_PORT_REVERSAL; - intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(dev_priv, port), + intel_de_rmw(display, XELPDP_PORT_BUF_CTL1(display, port), XELPDP_PORT_WIDTH_MASK | XELPDP_PORT_REVERSAL, port_buf); buf_ctl |= DDI_PORT_WIDTH(crtc_state->lane_count); - if (DISPLAY_VER(dev_priv) >= 20) + if (DISPLAY_VER(display) >= 20) buf_ctl |= XE2LPD_DDI_BUF_D2D_LINK_ENABLE; - } else if (IS_ALDERLAKE_P(dev_priv) && intel_encoder_is_tc(encoder)) { - drm_WARN_ON(&dev_priv->drm, !intel_tc_port_in_legacy_mode(dig_port)); + } else if (display->platform.alderlake_p && intel_encoder_is_tc(encoder)) { + drm_WARN_ON(display->drm, !intel_tc_port_in_legacy_mode(dig_port)); buf_ctl |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; } @@ -3522,6 +3503,8 @@ static void intel_ddi_enable(struct intel_atomic_state *state, intel_ddi_enable_transcoder_func(encoder, crtc_state); + intel_vrr_transcoder_enable(crtc_state); + /* Enable/Disable DP2.0 SDP split config before transcoder */ intel_audio_sdp_split_update(crtc_state); @@ -3567,7 +3550,7 @@ static void intel_ddi_disable_dp(struct intel_atomic_state *state, struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - intel_dp->link_trained = false; + intel_dp->link.active = false; intel_psr_disable(intel_dp, old_crtc_state); intel_edp_backlight_off(old_conn_state); @@ -3584,12 +3567,12 @@ static void intel_ddi_disable_hdmi(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct drm_connector *connector = old_conn_state->connector; if (!intel_hdmi_handle_sink_scrambling(encoder, connector, false, false)) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Failed to reset sink scrambling/TMDS bit clock ratio\n", connector->base.id, connector->name); } @@ -3653,16 +3636,16 @@ void intel_ddi_update_active_dpll(struct intel_atomic_state *state, struct intel_encoder *encoder, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_crtc *pipe_crtc; /* FIXME: Add MTL pll_mgr */ - if (DISPLAY_VER(i915) >= 14 || !intel_encoder_is_tc(encoder)) + if (DISPLAY_VER(display) >= 14 || !intel_encoder_is_tc(encoder)) return; - for_each_intel_crtc_in_pipe_mask(&i915->drm, pipe_crtc, + for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc, intel_crtc_joined_pipe_mask(crtc_state)) intel_update_active_dpll(state, pipe_crtc, encoder); } @@ -3678,7 +3661,7 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_tc_port = intel_encoder_is_tc(encoder); @@ -3697,7 +3680,7 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, * Type-C ports. Skip this step for TBT. */ intel_tc_port_set_fia_lane_count(dig_port, crtc_state->lane_count); - else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + else if (display->platform.geminilake || display->platform.broxton) bxt_dpio_phy_set_lane_optim_mask(encoder, crtc_state->lane_lat_optim_mask); } @@ -3765,10 +3748,9 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, struct intel_display *display = to_intel_display(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &dig_port->base; - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 dp_tp_ctl; - dp_tp_ctl = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); + dp_tp_ctl = intel_de_read(display, dp_tp_ctl_reg(encoder, crtc_state)); drm_WARN_ON(display->drm, dp_tp_ctl & DP_TP_CTL_ENABLE); @@ -3781,10 +3763,10 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, if (crtc_state->enhanced_framing) dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; } - intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); - intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); + intel_de_write(display, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); + intel_de_posting_read(display, dp_tp_ctl_reg(encoder, crtc_state)); - if (IS_ALDERLAKE_P(dev_priv) && + if (display->platform.alderlake_p && (intel_tc_port_in_dp_alt_mode(dig_port) || intel_tc_port_in_legacy_mode(dig_port))) adlp_tbt_to_dp_alt_switch_wa(encoder); @@ -3796,11 +3778,11 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, u8 dp_train_pat) { + struct intel_display *display = to_intel_display(intel_dp); struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 temp; - temp = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); + temp = intel_de_read(display, dp_tp_ctl_reg(encoder, crtc_state)); temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; switch (intel_dp_training_pattern_symbol(dp_train_pat)) { @@ -3821,17 +3803,17 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp, break; } - intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), temp); + intel_de_write(display, dp_tp_ctl_reg(encoder, crtc_state), temp); } static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(intel_dp); struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; - intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), + intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state), DP_TP_CTL_LINK_TRAIN_MASK, DP_TP_CTL_LINK_TRAIN_IDLE); /* @@ -3841,28 +3823,26 @@ static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp, * In this case there is requirement to wait for a minimum number of * idle patterns to be sent. */ - if (port == PORT_A && DISPLAY_VER(dev_priv) < 12) + if (port == PORT_A && DISPLAY_VER(display) < 12) return; - if (intel_de_wait_for_set(dev_priv, + if (intel_de_wait_for_set(display, dp_tp_status_reg(encoder, crtc_state), DP_TP_STATUS_IDLE_DONE, 2)) - drm_err(&dev_priv->drm, + drm_err(display->drm, "Timed out waiting for DP idle patterns\n"); } -static bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv, +static bool intel_ddi_is_audio_enabled(struct intel_display *display, enum transcoder cpu_transcoder) { - struct intel_display *display = &dev_priv->display; - if (cpu_transcoder == TRANSCODER_EDP) return false; if (!intel_display_power_is_enabled(display, POWER_DOMAIN_AUDIO_MMIO)) return false; - return intel_de_read(dev_priv, HSW_AUD_PIN_ELD_CP_VLD) & + return intel_de_read(display, HSW_AUD_PIN_ELD_CP_VLD) & AUDIO_OUTPUT_ENABLE(cpu_transcoder); } @@ -3892,34 +3872,34 @@ static int icl_ddi_min_voltage_level(const struct intel_crtc_state *crtc_state) void intel_ddi_compute_min_voltage_level(struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) crtc_state->min_voltage_level = icl_ddi_min_voltage_level(crtc_state); - else if (DISPLAY_VER(dev_priv) >= 12) + else if (DISPLAY_VER(display) >= 12) crtc_state->min_voltage_level = tgl_ddi_min_voltage_level(crtc_state); - else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) + else if (display->platform.jasperlake || display->platform.elkhartlake) crtc_state->min_voltage_level = jsl_ddi_min_voltage_level(crtc_state); - else if (DISPLAY_VER(dev_priv) >= 11) + else if (DISPLAY_VER(display) >= 11) crtc_state->min_voltage_level = icl_ddi_min_voltage_level(crtc_state); } -static enum transcoder bdw_transcoder_master_readout(struct drm_i915_private *dev_priv, +static enum transcoder bdw_transcoder_master_readout(struct intel_display *display, enum transcoder cpu_transcoder) { u32 master_select; - if (DISPLAY_VER(dev_priv) >= 11) { - u32 ctl2 = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL2(dev_priv, cpu_transcoder)); + if (DISPLAY_VER(display) >= 11) { + u32 ctl2 = intel_de_read(display, + TRANS_DDI_FUNC_CTL2(display, cpu_transcoder)); if ((ctl2 & PORT_SYNC_MODE_ENABLE) == 0) return INVALID_TRANSCODER; master_select = REG_FIELD_GET(PORT_SYNC_MODE_MASTER_SELECT_MASK, ctl2); } else { - u32 ctl = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); + u32 ctl = intel_de_read(display, + TRANS_DDI_FUNC_CTL(display, cpu_transcoder)); if ((ctl & TRANS_DDI_PORT_SYNC_ENABLE) == 0) return INVALID_TRANSCODER; @@ -3936,15 +3916,14 @@ static enum transcoder bdw_transcoder_master_readout(struct drm_i915_private *de static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); u32 transcoders = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C) | BIT(TRANSCODER_D); enum transcoder cpu_transcoder; crtc_state->master_transcoder = - bdw_transcoder_master_readout(dev_priv, crtc_state->cpu_transcoder); + bdw_transcoder_master_readout(display, crtc_state->cpu_transcoder); - for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) { + for_each_cpu_transcoder_masked(display, cpu_transcoder, transcoders) { enum intel_display_power_domain power_domain; intel_wakeref_t trans_wakeref; @@ -3955,14 +3934,14 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state) if (!trans_wakeref) continue; - if (bdw_transcoder_master_readout(dev_priv, cpu_transcoder) == + if (bdw_transcoder_master_readout(display, cpu_transcoder) == crtc_state->cpu_transcoder) crtc_state->sync_mode_slaves_mask |= BIT(cpu_transcoder); intel_display_power_put(display, power_domain, trans_wakeref); } - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, crtc_state->master_transcoder != INVALID_TRANSCODER && crtc_state->sync_mode_slaves_mask); } @@ -4085,11 +4064,10 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; u32 ddi_func_ctl, ddi_mode, flags = 0; - ddi_func_ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); + ddi_func_ctl = intel_de_read(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder)); if (ddi_func_ctl & TRANS_DDI_PHSYNC) flags |= DRM_MODE_FLAG_PHSYNC; else @@ -4131,13 +4109,13 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, } else if (ddi_mode == TRANS_DDI_MODE_SELECT_DP_MST) { intel_ddi_read_func_ctl_dp_mst(encoder, pipe_config, ddi_func_ctl); } else if (ddi_mode == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B && HAS_DP20(display)) { - struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); /* * If this is true, we know we're being called from mst stream * encoder's ->get_config(). */ - if (intel_dp_mst_encoder_active_links(dig_port)) + if (intel_dp_mst_active_streams(intel_dp)) intel_ddi_read_func_ctl_dp_mst(encoder, pipe_config, ddi_func_ctl); else intel_ddi_read_func_ctl_dp_sst(encoder, pipe_config, ddi_func_ctl); @@ -4152,11 +4130,11 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, static void intel_ddi_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; /* XXX: DSI transcoder paranoia */ - if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder))) + if (drm_WARN_ON(display->drm, transcoder_is_dsi(cpu_transcoder))) return; intel_ddi_read_func_ctl(encoder, pipe_config); @@ -4164,14 +4142,14 @@ static void intel_ddi_get_config(struct intel_encoder *encoder, intel_ddi_mso_get_config(encoder, pipe_config); pipe_config->has_audio = - intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder); + intel_ddi_is_audio_enabled(display, cpu_transcoder); if (encoder->type == INTEL_OUTPUT_EDP) intel_edp_fixup_vbt_bpp(encoder, pipe_config->pipe_bpp); ddi_dotclock_get(pipe_config); - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) pipe_config->lane_lat_optim_mask = bxt_dpio_phy_get_lane_lat_optim_mask(encoder); @@ -4192,7 +4170,7 @@ static void intel_ddi_get_config(struct intel_encoder *encoder, HDMI_INFOFRAME_TYPE_DRM, &pipe_config->infoframes.drm); - if (DISPLAY_VER(dev_priv) >= 8) + if (DISPLAY_VER(display) >= 8) bdw_get_trans_port_sync_config(pipe_config); intel_psr_get_config(encoder, pipe_config); @@ -4285,10 +4263,10 @@ static enum icl_port_dpll_id icl_ddi_tc_port_pll_type(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return ICL_PORT_DPLL_DEFAULT; if (icl_ddi_tc_pll_is_tbt(pll)) @@ -4382,11 +4360,11 @@ static void intel_ddi_sync_state(struct intel_encoder *encoder, static bool intel_ddi_initial_fastset_check(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); bool fastset = true; if (intel_encoder_is_tc(encoder)) { - drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Forcing full modeset to compute TC port DPLLs\n", + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] Forcing full modeset to compute TC port DPLLs\n", encoder->base.base.id, encoder->base.name); crtc_state->uapi.mode_changed = true; fastset = false; @@ -4421,12 +4399,12 @@ static int intel_ddi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; int ret; - if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) + if (HAS_TRANSCODER(display, TRANSCODER_EDP) && port == PORT_A) pipe_config->cpu_transcoder = TRANSCODER_EDP; if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) { @@ -4441,13 +4419,13 @@ static int intel_ddi_compute_config(struct intel_encoder *encoder, if (ret) return ret; - if (IS_HASWELL(dev_priv) && crtc->pipe == PIPE_A && + if (display->platform.haswell && crtc->pipe == PIPE_A && pipe_config->cpu_transcoder == TRANSCODER_EDP) pipe_config->pch_pfit.force_thru = pipe_config->pch_pfit.enabled || pipe_config->crc_enabled; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) pipe_config->lane_lat_optim_mask = bxt_dpio_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); @@ -4498,9 +4476,9 @@ static u8 intel_ddi_port_sync_transcoders(const struct intel_crtc_state *ref_crtc_state, int tile_group_id) { + struct intel_display *display = to_intel_display(ref_crtc_state); struct drm_connector *connector; const struct drm_connector_state *conn_state; - struct drm_i915_private *dev_priv = to_i915(ref_crtc_state->uapi.crtc->dev); struct intel_atomic_state *state = to_intel_atomic_state(ref_crtc_state->uapi.state); u8 transcoders = 0; @@ -4510,7 +4488,7 @@ intel_ddi_port_sync_transcoders(const struct intel_crtc_state *ref_crtc_state, * We don't enable port sync on BDW due to missing w/as and * due to not having adjusted the modeset sequence appropriately. */ - if (DISPLAY_VER(dev_priv) < 9) + if (DISPLAY_VER(display) < 9) return 0; if (!intel_crtc_has_type(ref_crtc_state, INTEL_OUTPUT_DP)) @@ -4542,11 +4520,11 @@ static int intel_ddi_compute_config_late(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct drm_connector *connector = conn_state->connector; u8 port_sync_transcoders = 0; - drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] [CRTC:%d:%s]\n", + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] [CRTC:%d:%s]\n", encoder->base.base.id, encoder->base.name, crtc_state->uapi.crtc->base.id, crtc_state->uapi.crtc->name); @@ -4618,7 +4596,7 @@ static const struct drm_encoder_funcs intel_ddi_funcs = { static int intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); struct intel_connector *connector; enum port port = dig_port->base.port; @@ -4627,7 +4605,7 @@ static int intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) return -ENOMEM; dig_port->dp.output_reg = DDI_BUF_CTL(port); - if (DISPLAY_VER(i915) >= 14) + if (DISPLAY_VER(display) >= 14) dig_port->dp.prepare_link_retrain = mtl_ddi_prepare_link_retrain; else dig_port->dp.prepare_link_retrain = intel_ddi_prepare_link_retrain; @@ -4643,15 +4621,14 @@ static int intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) } if (dig_port->base.type == INTEL_OUTPUT_EDP) { - struct drm_device *dev = dig_port->base.base.dev; struct drm_privacy_screen *privacy_screen; - privacy_screen = drm_privacy_screen_get(dev->dev, NULL); + privacy_screen = drm_privacy_screen_get(display->drm->dev, NULL); if (!IS_ERR(privacy_screen)) { drm_connector_attach_privacy_screen_provider(&connector->base, privacy_screen); } else if (PTR_ERR(privacy_screen) != -ENODEV) { - drm_warn(dev, "Error getting privacy-screen\n"); + drm_warn(display->drm, "Error getting privacy-screen\n"); } } @@ -4662,7 +4639,6 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, struct drm_modeset_acquire_ctx *ctx) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder); struct intel_connector *connector = hdmi->attached_connector; struct i2c_adapter *ddc = connector->base.ddc; @@ -4675,7 +4651,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, if (connector->base.status != connector_status_connected) return 0; - ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, + ret = drm_modeset_lock(&display->drm->mode_config.connection_mutex, ctx); if (ret) return ret; @@ -4692,7 +4668,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, crtc_state = to_intel_crtc_state(crtc->base.state); - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)); if (!crtc_state->hw.active) @@ -4708,7 +4684,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, ret = drm_scdc_readb(ddc, SCDC_TMDS_CONFIG, &config); if (ret < 0) { - drm_err(&dev_priv->drm, "[CONNECTOR:%d:%s] Failed to read TMDS config: %d\n", + drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to read TMDS config: %d\n", connector->base.base.id, connector->base.name, ret); return 0; } @@ -4733,11 +4709,11 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, static void intel_ddi_link_check(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); /* TODO: Move checking the HDMI link state here as well. */ - drm_WARN_ON(&i915->drm, !dig_port->dp.attached_connector); + drm_WARN_ON(display->drm, !dig_port->dp.attached_connector); intel_dp_link_check(encoder); } @@ -4800,26 +4776,26 @@ intel_ddi_hotplug(struct intel_encoder *encoder, static bool lpt_digital_port_connected(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - u32 bit = dev_priv->display.hotplug.pch_hpd[encoder->hpd_pin]; + struct intel_display *display = to_intel_display(encoder); + u32 bit = display->hotplug.pch_hpd[encoder->hpd_pin]; - return intel_de_read(dev_priv, SDEISR) & bit; + return intel_de_read(display, SDEISR) & bit; } static bool hsw_digital_port_connected(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - u32 bit = dev_priv->display.hotplug.hpd[encoder->hpd_pin]; + struct intel_display *display = to_intel_display(encoder); + u32 bit = display->hotplug.hpd[encoder->hpd_pin]; - return intel_de_read(dev_priv, DEISR) & bit; + return intel_de_read(display, DEISR) & bit; } static bool bdw_digital_port_connected(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - u32 bit = dev_priv->display.hotplug.hpd[encoder->hpd_pin]; + struct intel_display *display = to_intel_display(encoder); + u32 bit = display->hotplug.hpd[encoder->hpd_pin]; - return intel_de_read(dev_priv, GEN8_DE_PORT_ISR) & bit; + return intel_de_read(display, GEN8_DE_PORT_ISR) & bit; } static int intel_ddi_init_hdmi_connector(struct intel_digital_port *dig_port) @@ -4848,7 +4824,7 @@ static int intel_ddi_init_hdmi_connector(struct intel_digital_port *dig_port) static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port) { - struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); if (dig_port->base.port != PORT_A) return false; @@ -4859,7 +4835,7 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port) /* Broxton/Geminilake: Bspec says that DDI_A_4_LANES is the only * supported configuration */ - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) return true; return false; @@ -4868,15 +4844,15 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port) static int intel_ddi_max_lanes(struct intel_digital_port *dig_port) { - struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); enum port port = dig_port->base.port; int max_lanes = 4; - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) return max_lanes; if (port == PORT_A || port == PORT_E) { - if (intel_de_read(dev_priv, DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) + if (intel_de_read(display, DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) max_lanes = port == PORT_A ? 4 : 0; else /* Both A and E share 2 lanes */ @@ -4889,7 +4865,7 @@ intel_ddi_max_lanes(struct intel_digital_port *dig_port) * so we use the proper lane count for our calculations. */ if (intel_ddi_a_force_4_lanes(dig_port)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Forcing DDI_A_4_LANES for port A\n"); dig_port->ddi_a_4_lanes = true; max_lanes = 4; @@ -4898,8 +4874,7 @@ intel_ddi_max_lanes(struct intel_digital_port *dig_port) return max_lanes; } -static enum hpd_pin xelpd_hpd_pin(struct drm_i915_private *dev_priv, - enum port port) +static enum hpd_pin xelpd_hpd_pin(struct intel_display *display, enum port port) { if (port >= PORT_D_XELPD) return HPD_PORT_D + port - PORT_D_XELPD; @@ -4909,8 +4884,7 @@ static enum hpd_pin xelpd_hpd_pin(struct drm_i915_private *dev_priv, return HPD_PORT_A + port - PORT_A; } -static enum hpd_pin dg1_hpd_pin(struct drm_i915_private *dev_priv, - enum port port) +static enum hpd_pin dg1_hpd_pin(struct intel_display *display, enum port port) { if (port >= PORT_TC1) return HPD_PORT_C + port - PORT_TC1; @@ -4918,8 +4892,7 @@ static enum hpd_pin dg1_hpd_pin(struct drm_i915_private *dev_priv, return HPD_PORT_A + port - PORT_A; } -static enum hpd_pin tgl_hpd_pin(struct drm_i915_private *dev_priv, - enum port port) +static enum hpd_pin tgl_hpd_pin(struct intel_display *display, enum port port) { if (port >= PORT_TC1) return HPD_PORT_TC1 + port - PORT_TC1; @@ -4927,11 +4900,12 @@ static enum hpd_pin tgl_hpd_pin(struct drm_i915_private *dev_priv, return HPD_PORT_A + port - PORT_A; } -static enum hpd_pin rkl_hpd_pin(struct drm_i915_private *dev_priv, - enum port port) +static enum hpd_pin rkl_hpd_pin(struct intel_display *display, enum port port) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + if (HAS_PCH_TGP(dev_priv)) - return tgl_hpd_pin(dev_priv, port); + return tgl_hpd_pin(display, port); if (port >= PORT_TC1) return HPD_PORT_C + port - PORT_TC1; @@ -4939,8 +4913,7 @@ static enum hpd_pin rkl_hpd_pin(struct drm_i915_private *dev_priv, return HPD_PORT_A + port - PORT_A; } -static enum hpd_pin icl_hpd_pin(struct drm_i915_private *dev_priv, - enum port port) +static enum hpd_pin icl_hpd_pin(struct intel_display *display, enum port port) { if (port >= PORT_C) return HPD_PORT_TC1 + port - PORT_C; @@ -4948,31 +4921,34 @@ static enum hpd_pin icl_hpd_pin(struct drm_i915_private *dev_priv, return HPD_PORT_A + port - PORT_A; } -static enum hpd_pin ehl_hpd_pin(struct drm_i915_private *dev_priv, - enum port port) +static enum hpd_pin ehl_hpd_pin(struct intel_display *display, enum port port) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + if (port == PORT_D) return HPD_PORT_A; if (HAS_PCH_TGP(dev_priv)) - return icl_hpd_pin(dev_priv, port); + return icl_hpd_pin(display, port); return HPD_PORT_A + port - PORT_A; } -static enum hpd_pin skl_hpd_pin(struct drm_i915_private *dev_priv, enum port port) +static enum hpd_pin skl_hpd_pin(struct intel_display *display, enum port port) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + if (HAS_PCH_TGP(dev_priv)) - return icl_hpd_pin(dev_priv, port); + return icl_hpd_pin(display, port); return HPD_PORT_A + port - PORT_A; } -static bool intel_ddi_is_tc(struct drm_i915_private *i915, enum port port) +static bool intel_ddi_is_tc(struct intel_display *display, enum port port) { - if (DISPLAY_VER(i915) >= 12) + if (DISPLAY_VER(display) >= 12) return port >= PORT_TC1; - else if (DISPLAY_VER(i915) >= 11) + else if (DISPLAY_VER(display) >= 11) return port >= PORT_C; else return false; @@ -5015,21 +4991,21 @@ static void intel_ddi_tc_encoder_shutdown_complete(struct intel_encoder *encoder #define port_tc_name(port) ((port) - PORT_TC1 + '1') #define tc_port_name(tc_port) ((tc_port) - TC_PORT_1 + '1') -static bool port_strap_detected(struct drm_i915_private *i915, enum port port) +static bool port_strap_detected(struct intel_display *display, enum port port) { /* straps not used on skl+ */ - if (DISPLAY_VER(i915) >= 9) + if (DISPLAY_VER(display) >= 9) return true; switch (port) { case PORT_A: - return intel_de_read(i915, DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED; + return intel_de_read(display, DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED; case PORT_B: - return intel_de_read(i915, SFUSE_STRAP) & SFUSE_STRAP_DDIB_DETECTED; + return intel_de_read(display, SFUSE_STRAP) & SFUSE_STRAP_DDIB_DETECTED; case PORT_C: - return intel_de_read(i915, SFUSE_STRAP) & SFUSE_STRAP_DDIC_DETECTED; + return intel_de_read(display, SFUSE_STRAP) & SFUSE_STRAP_DDIC_DETECTED; case PORT_D: - return intel_de_read(i915, SFUSE_STRAP) & SFUSE_STRAP_DDID_DETECTED; + return intel_de_read(display, SFUSE_STRAP) & SFUSE_STRAP_DDID_DETECTED; case PORT_E: return true; /* no strap for DDI-E */ default: @@ -5043,18 +5019,18 @@ static bool need_aux_ch(struct intel_encoder *encoder, bool init_dp) return init_dp || intel_encoder_is_tc(encoder); } -static bool assert_has_icl_dsi(struct drm_i915_private *i915) +static bool assert_has_icl_dsi(struct intel_display *display) { - return !drm_WARN(&i915->drm, !IS_ALDERLAKE_P(i915) && - !IS_TIGERLAKE(i915) && DISPLAY_VER(i915) != 11, + return !drm_WARN(display->drm, !display->platform.alderlake_p && + !display->platform.tigerlake && DISPLAY_VER(display) != 11, "Platform does not support DSI\n"); } -static bool port_in_use(struct drm_i915_private *i915, enum port port) +static bool port_in_use(struct intel_display *display, enum port port) { struct intel_encoder *encoder; - for_each_intel_encoder(&i915->drm, encoder) { + for_each_intel_encoder(display->drm, encoder) { /* FIXME what about second port for dual link DSI? */ if (encoder->port == port) return true; @@ -5066,7 +5042,6 @@ static bool port_in_use(struct drm_i915_private *i915, enum port port) void intel_ddi_init(struct intel_display *display, const struct intel_bios_encoder_data *devdata) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_digital_port *dig_port; struct intel_encoder *encoder; bool init_hdmi, init_dp; @@ -5078,8 +5053,8 @@ void intel_ddi_init(struct intel_display *display, if (port == PORT_NONE) return; - if (!port_strap_detected(dev_priv, port)) { - drm_dbg_kms(&dev_priv->drm, + if (!port_strap_detected(display, port)) { + drm_dbg_kms(display->drm, "Port %c strap not detected\n", port_name(port)); return; } @@ -5087,15 +5062,15 @@ void intel_ddi_init(struct intel_display *display, if (!assert_port_valid(display, port)) return; - if (port_in_use(dev_priv, port)) { - drm_dbg_kms(&dev_priv->drm, + if (port_in_use(display, port)) { + drm_dbg_kms(display->drm, "Port %c already claimed\n", port_name(port)); return; } if (intel_bios_encoder_supports_dsi(devdata)) { /* BXT/GLK handled elsewhere, for now at least */ - if (!assert_has_icl_dsi(dev_priv)) + if (!assert_has_icl_dsi(display)) return; icl_dsi_init(display, devdata); @@ -5111,7 +5086,7 @@ void intel_ddi_init(struct intel_display *display, * outputs. */ if (intel_hti_uses_phy(display, phy)) { - drm_dbg_kms(&dev_priv->drm, "PORT %c / PHY %c reserved by HTI\n", + drm_dbg_kms(display->drm, "PORT %c / PHY %c reserved by HTI\n", port_name(port), phy_name(phy)); return; } @@ -5128,20 +5103,20 @@ void intel_ddi_init(struct intel_display *display, */ init_dp = true; init_hdmi = false; - drm_dbg_kms(&dev_priv->drm, "VBT says port %c has lspcon\n", + drm_dbg_kms(display->drm, "VBT says port %c has lspcon\n", port_name(port)); } if (!init_dp && !init_hdmi) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "VBT says port %c is not DVI/HDMI/DP compatible, respect it\n", port_name(port)); return; } if (intel_phy_is_snps(display, phy) && - dev_priv->display.snps.phy_failed_calibration & BIT(phy)) { - drm_dbg_kms(&dev_priv->drm, + display->snps.phy_failed_calibration & BIT(phy)) { + drm_dbg_kms(display->drm, "SNPS PHY %c failed to calibrate, proceeding anyway\n", phy_name(phy)); } @@ -5155,26 +5130,26 @@ void intel_ddi_init(struct intel_display *display, encoder = &dig_port->base; encoder->devdata = devdata; - if (DISPLAY_VER(dev_priv) >= 13 && port >= PORT_D_XELPD) { - drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, + if (DISPLAY_VER(display) >= 13 && port >= PORT_D_XELPD) { + drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, "DDI %c/PHY %c", port_name(port - PORT_D_XELPD + PORT_D), phy_name(phy)); - } else if (DISPLAY_VER(dev_priv) >= 12) { + } else if (DISPLAY_VER(display) >= 12) { enum tc_port tc_port = intel_port_to_tc(display, port); - drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, + drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, "DDI %s%c/PHY %s%c", port >= PORT_TC1 ? "TC" : "", port >= PORT_TC1 ? port_tc_name(port) : port_name(port), tc_port != TC_PORT_NONE ? "TC" : "", tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); - } else if (DISPLAY_VER(dev_priv) >= 11) { + } else if (DISPLAY_VER(display) >= 11) { enum tc_port tc_port = intel_port_to_tc(display, port); - drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, + drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, "DDI %c%s/PHY %s%c", port_name(port), @@ -5182,7 +5157,7 @@ void intel_ddi_init(struct intel_display *display, tc_port != TC_PORT_NONE ? "TC" : "", tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); } else { - drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, + drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, "DDI %c/PHY %c", port_name(port), phy_name(phy)); } @@ -5218,32 +5193,32 @@ void intel_ddi_init(struct intel_display *display, encoder->cloneable = 0; encoder->pipe_mask = ~0; - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { encoder->enable_clock = intel_mtl_pll_enable; encoder->disable_clock = intel_mtl_pll_disable; encoder->port_pll_type = intel_mtl_port_pll_type; encoder->get_config = mtl_ddi_get_config; - } else if (IS_DG2(dev_priv)) { + } else if (display->platform.dg2) { encoder->enable_clock = intel_mpllb_enable; encoder->disable_clock = intel_mpllb_disable; encoder->get_config = dg2_ddi_get_config; - } else if (IS_ALDERLAKE_S(dev_priv)) { + } else if (display->platform.alderlake_s) { encoder->enable_clock = adls_ddi_enable_clock; encoder->disable_clock = adls_ddi_disable_clock; encoder->is_clock_enabled = adls_ddi_is_clock_enabled; encoder->get_config = adls_ddi_get_config; - } else if (IS_ROCKETLAKE(dev_priv)) { + } else if (display->platform.rocketlake) { encoder->enable_clock = rkl_ddi_enable_clock; encoder->disable_clock = rkl_ddi_disable_clock; encoder->is_clock_enabled = rkl_ddi_is_clock_enabled; encoder->get_config = rkl_ddi_get_config; - } else if (IS_DG1(dev_priv)) { + } else if (display->platform.dg1) { encoder->enable_clock = dg1_ddi_enable_clock; encoder->disable_clock = dg1_ddi_disable_clock; encoder->is_clock_enabled = dg1_ddi_is_clock_enabled; encoder->get_config = dg1_ddi_get_config; - } else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) { - if (intel_ddi_is_tc(dev_priv, port)) { + } else if (display->platform.jasperlake || display->platform.elkhartlake) { + if (intel_ddi_is_tc(display, port)) { encoder->enable_clock = jsl_ddi_tc_enable_clock; encoder->disable_clock = jsl_ddi_tc_disable_clock; encoder->is_clock_enabled = jsl_ddi_tc_is_clock_enabled; @@ -5255,8 +5230,8 @@ void intel_ddi_init(struct intel_display *display, encoder->is_clock_enabled = icl_ddi_combo_is_clock_enabled; encoder->get_config = icl_ddi_combo_get_config; } - } else if (DISPLAY_VER(dev_priv) >= 11) { - if (intel_ddi_is_tc(dev_priv, port)) { + } else if (DISPLAY_VER(display) >= 11) { + if (intel_ddi_is_tc(display, port)) { encoder->enable_clock = icl_ddi_tc_enable_clock; encoder->disable_clock = icl_ddi_tc_disable_clock; encoder->is_clock_enabled = icl_ddi_tc_is_clock_enabled; @@ -5268,36 +5243,36 @@ void intel_ddi_init(struct intel_display *display, encoder->is_clock_enabled = icl_ddi_combo_is_clock_enabled; encoder->get_config = icl_ddi_combo_get_config; } - } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + } else if (display->platform.geminilake || display->platform.broxton) { /* BXT/GLK have fixed PLL->port mapping */ encoder->get_config = bxt_ddi_get_config; - } else if (DISPLAY_VER(dev_priv) == 9) { + } else if (DISPLAY_VER(display) == 9) { encoder->enable_clock = skl_ddi_enable_clock; encoder->disable_clock = skl_ddi_disable_clock; encoder->is_clock_enabled = skl_ddi_is_clock_enabled; encoder->get_config = skl_ddi_get_config; - } else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) { + } else if (display->platform.broadwell || display->platform.haswell) { encoder->enable_clock = hsw_ddi_enable_clock; encoder->disable_clock = hsw_ddi_disable_clock; encoder->is_clock_enabled = hsw_ddi_is_clock_enabled; encoder->get_config = hsw_ddi_get_config; } - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { encoder->set_signal_levels = intel_cx0_phy_set_signal_levels; - } else if (IS_DG2(dev_priv)) { + } else if (display->platform.dg2) { encoder->set_signal_levels = intel_snps_phy_set_signal_levels; - } else if (DISPLAY_VER(dev_priv) >= 12) { + } else if (DISPLAY_VER(display) >= 12) { if (intel_encoder_is_combo(encoder)) encoder->set_signal_levels = icl_combo_phy_set_signal_levels; else encoder->set_signal_levels = tgl_dkl_phy_set_signal_levels; - } else if (DISPLAY_VER(dev_priv) >= 11) { + } else if (DISPLAY_VER(display) >= 11) { if (intel_encoder_is_combo(encoder)) encoder->set_signal_levels = icl_combo_phy_set_signal_levels; else encoder->set_signal_levels = icl_mg_phy_set_signal_levels; - } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + } else if (display->platform.geminilake || display->platform.broxton) { encoder->set_signal_levels = bxt_dpio_phy_set_signal_levels; } else { encoder->set_signal_levels = hsw_set_signal_levels; @@ -5305,29 +5280,29 @@ void intel_ddi_init(struct intel_display *display, intel_ddi_buf_trans_init(encoder); - if (DISPLAY_VER(dev_priv) >= 13) - encoder->hpd_pin = xelpd_hpd_pin(dev_priv, port); - else if (IS_DG1(dev_priv)) - encoder->hpd_pin = dg1_hpd_pin(dev_priv, port); - else if (IS_ROCKETLAKE(dev_priv)) - encoder->hpd_pin = rkl_hpd_pin(dev_priv, port); - else if (DISPLAY_VER(dev_priv) >= 12) - encoder->hpd_pin = tgl_hpd_pin(dev_priv, port); - else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) - encoder->hpd_pin = ehl_hpd_pin(dev_priv, port); - else if (DISPLAY_VER(dev_priv) == 11) - encoder->hpd_pin = icl_hpd_pin(dev_priv, port); - else if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) - encoder->hpd_pin = skl_hpd_pin(dev_priv, port); + if (DISPLAY_VER(display) >= 13) + encoder->hpd_pin = xelpd_hpd_pin(display, port); + else if (display->platform.dg1) + encoder->hpd_pin = dg1_hpd_pin(display, port); + else if (display->platform.rocketlake) + encoder->hpd_pin = rkl_hpd_pin(display, port); + else if (DISPLAY_VER(display) >= 12) + encoder->hpd_pin = tgl_hpd_pin(display, port); + else if (display->platform.jasperlake || display->platform.elkhartlake) + encoder->hpd_pin = ehl_hpd_pin(display, port); + else if (DISPLAY_VER(display) == 11) + encoder->hpd_pin = icl_hpd_pin(display, port); + else if (DISPLAY_VER(display) == 9 && !display->platform.broxton) + encoder->hpd_pin = skl_hpd_pin(display, port); else encoder->hpd_pin = intel_hpd_pin_default(port); - ddi_buf_ctl = intel_de_read(dev_priv, DDI_BUF_CTL(port)); + ddi_buf_ctl = intel_de_read(display, DDI_BUF_CTL(port)); dig_port->lane_reversal = intel_bios_encoder_lane_reversal(devdata) || ddi_buf_ctl & DDI_BUF_PORT_REVERSAL; - dig_port->ddi_a_4_lanes = DISPLAY_VER(dev_priv) < 11 && ddi_buf_ctl & DDI_A_4_LANES; + dig_port->ddi_a_4_lanes = DISPLAY_VER(display) < 11 && ddi_buf_ctl & DDI_A_4_LANES; dig_port->dp.output_reg = INVALID_MMIO_REG; dig_port->max_lanes = intel_ddi_max_lanes(dig_port); @@ -5346,7 +5321,7 @@ void intel_ddi_init(struct intel_display *display, if (!is_legacy && init_hdmi) { is_legacy = !init_dp; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "VBT says port %c is non-legacy TC and has HDMI (with DP: %s), assume it's %s\n", port_name(port), str_yes_no(init_dp), @@ -5363,24 +5338,24 @@ void intel_ddi_init(struct intel_display *display, goto err; } - drm_WARN_ON(&dev_priv->drm, port > PORT_I); + drm_WARN_ON(display->drm, port > PORT_I); dig_port->ddi_io_power_domain = intel_display_power_ddi_io_domain(display, port); - if (DISPLAY_VER(dev_priv) >= 11) { + if (DISPLAY_VER(display) >= 11) { if (intel_encoder_is_tc(encoder)) dig_port->connected = intel_tc_port_connected; else dig_port->connected = lpt_digital_port_connected; - } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + } else if (display->platform.geminilake || display->platform.broxton) { dig_port->connected = bdw_digital_port_connected; - } else if (DISPLAY_VER(dev_priv) == 9) { + } else if (DISPLAY_VER(display) == 9) { dig_port->connected = lpt_digital_port_connected; - } else if (IS_BROADWELL(dev_priv)) { + } else if (display->platform.broadwell) { if (port == PORT_A) dig_port->connected = bdw_digital_port_connected; else dig_port->connected = lpt_digital_port_connected; - } else if (IS_HASWELL(dev_priv)) { + } else if (display->platform.haswell) { if (port == PORT_A) dig_port->connected = hsw_digital_port_connected; else @@ -5396,7 +5371,7 @@ void intel_ddi_init(struct intel_display *display, dig_port->hpd_pulse = intel_dp_hpd_pulse; if (dig_port->dp.mso_link_count) - encoder->pipe_mask = intel_ddi_splitter_pipe_mask(dev_priv); + encoder->pipe_mask = intel_ddi_splitter_pipe_mask(display); } /* diff --git a/drivers/gpu/drm/i915/display/intel_de.h b/drivers/gpu/drm/i915/display/intel_de.h index b7399e9d11ccd6..655467a6ba87f5 100644 --- a/drivers/gpu/drm/i915/display/intel_de.h +++ b/drivers/gpu/drm/i915/display/intel_de.h @@ -181,20 +181,18 @@ intel_de_wait_custom(struct intel_display *display, i915_reg_t reg, } static inline int -__intel_de_wait_for_set(struct intel_display *display, i915_reg_t reg, - u32 mask, unsigned int timeout) +intel_de_wait_for_set(struct intel_display *display, i915_reg_t reg, + u32 mask, unsigned int timeout) { return intel_de_wait(display, reg, mask, mask, timeout); } -#define intel_de_wait_for_set(p,...) __intel_de_wait_for_set(__to_intel_display(p), __VA_ARGS__) static inline int -__intel_de_wait_for_clear(struct intel_display *display, i915_reg_t reg, - u32 mask, unsigned int timeout) +intel_de_wait_for_clear(struct intel_display *display, i915_reg_t reg, + u32 mask, unsigned int timeout) { return intel_de_wait(display, reg, mask, 0, timeout); } -#define intel_de_wait_for_clear(p,...) __intel_de_wait_for_clear(__to_intel_display(p), __VA_ARGS__) /* * Unlocked mmio-accessors, think carefully before using these. @@ -205,7 +203,7 @@ __intel_de_wait_for_clear(struct intel_display *display, i915_reg_t reg, * a more localised lock guarding all access to that bank of registers. */ static inline u32 -__intel_de_read_fw(struct intel_display *display, i915_reg_t reg) +intel_de_read_fw(struct intel_display *display, i915_reg_t reg) { u32 val; @@ -214,15 +212,13 @@ __intel_de_read_fw(struct intel_display *display, i915_reg_t reg) return val; } -#define intel_de_read_fw(p,...) __intel_de_read_fw(__to_intel_display(p), __VA_ARGS__) static inline void -__intel_de_write_fw(struct intel_display *display, i915_reg_t reg, u32 val) +intel_de_write_fw(struct intel_display *display, i915_reg_t reg, u32 val) { trace_i915_reg_rw(true, reg, val, sizeof(val), true); intel_uncore_write_fw(__to_uncore(display), reg, val); } -#define intel_de_write_fw(p,...) __intel_de_write_fw(__to_intel_display(p), __VA_ARGS__) static inline u32 intel_de_read_notrace(struct intel_display *display, i915_reg_t reg) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3afb85fe8536df..db524d01e574d6 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -73,6 +73,7 @@ #include "intel_de.h" #include "intel_display_driver.h" #include "intel_display_power.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dmc.h" #include "intel_dp.h" @@ -663,7 +664,6 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, struct intel_plane *plane) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane_state *plane_state = @@ -696,7 +696,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, * wait-for-vblank between disabling the plane and the pipe. */ if (HAS_GMCH(display) && - intel_set_memory_cxsr(dev_priv, false)) + intel_set_memory_cxsr(display, false)) intel_plane_initial_vblank_wait(crtc); /* @@ -968,7 +968,9 @@ static bool vrr_params_changed(const struct intel_crtc_state *old_crtc_state, old_crtc_state->vrr.vmin != new_crtc_state->vrr.vmin || old_crtc_state->vrr.vmax != new_crtc_state->vrr.vmax || old_crtc_state->vrr.guardband != new_crtc_state->vrr.guardband || - old_crtc_state->vrr.pipeline_full != new_crtc_state->vrr.pipeline_full; + old_crtc_state->vrr.pipeline_full != new_crtc_state->vrr.pipeline_full || + old_crtc_state->vrr.vsync_start != new_crtc_state->vrr.vsync_start || + old_crtc_state->vrr.vsync_end != new_crtc_state->vrr.vsync_end; } static bool cmrr_params_changed(const struct intel_crtc_state *old_crtc_state, @@ -1048,12 +1050,10 @@ static void intel_post_plane_update(struct intel_atomic_state *state, intel_atomic_get_new_crtc_state(state, crtc); enum pipe pipe = crtc->pipe; - intel_psr_post_plane_update(state, crtc); - intel_frontbuffer_flip(dev_priv, new_crtc_state->fb_bits); if (new_crtc_state->update_wm_post && new_crtc_state->hw.active) - intel_update_watermarks(dev_priv); + intel_update_watermarks(display); intel_fbc_post_update(state, crtc); @@ -1078,6 +1078,8 @@ static void intel_post_plane_update(struct intel_atomic_state *state, if (audio_enabling(old_crtc_state, new_crtc_state)) intel_encoders_audio_enable(state, crtc); + + intel_psr_post_plane_update(state, crtc); } static void intel_post_plane_update_after_readout(struct intel_atomic_state *state, @@ -1166,13 +1168,14 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(state->base.dev); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); enum pipe pipe = crtc->pipe; + intel_psr_pre_plane_update(state, crtc); + if (intel_crtc_vrr_disabling(state, crtc)) { intel_vrr_disable(old_crtc_state); intel_crtc_update_active_timings(old_crtc_state, false); @@ -1183,8 +1186,6 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, intel_drrs_deactivate(old_crtc_state); - intel_psr_pre_plane_update(state, crtc); - if (hsw_ips_pre_update(state, crtc)) intel_crtc_wait_for_next_vblank(crtc); @@ -1220,7 +1221,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, * wait-for-vblank between disabling the plane and the pipe. */ if (HAS_GMCH(display) && old_crtc_state->hw.active && - new_crtc_state->disable_cxsr && intel_set_memory_cxsr(dev_priv, false)) + new_crtc_state->disable_cxsr && intel_set_memory_cxsr(display, false)) intel_crtc_wait_for_next_vblank(crtc); /* @@ -1231,7 +1232,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, * WaCxSRDisabledForSpriteScaling:ivb */ if (!HAS_GMCH(display) && old_crtc_state->hw.active && - new_crtc_state->disable_cxsr && ilk_disable_cxsr(dev_priv)) + new_crtc_state->disable_cxsr && ilk_disable_cxsr(display)) intel_crtc_wait_for_next_vblank(crtc); /* @@ -1255,7 +1256,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, */ if (!intel_initial_watermarks(state, crtc)) if (new_crtc_state->update_wm_pre) - intel_update_watermarks(dev_priv); + intel_update_watermarks(display); } /* @@ -1660,13 +1661,8 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, intel_encoders_pre_pll_enable(state, crtc); - for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) { - const struct intel_crtc_state *pipe_crtc_state = - intel_atomic_get_new_crtc_state(state, pipe_crtc); - - if (pipe_crtc_state->shared_dpll) - intel_enable_shared_dpll(pipe_crtc_state); - } + if (new_crtc_state->shared_dpll) + intel_enable_shared_dpll(new_crtc_state); intel_encoders_pre_enable(state, crtc); @@ -1777,8 +1773,6 @@ static void ilk_crtc_disable(struct intel_atomic_state *state, intel_set_cpu_fifo_underrun_reporting(display, pipe, true); intel_set_pch_fifo_underrun_reporting(display, pipe, true); - - intel_disable_shared_dpll(old_crtc_state); } static void hsw_crtc_disable(struct intel_atomic_state *state, @@ -1797,12 +1791,7 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, intel_encoders_disable(state, crtc); intel_encoders_post_disable(state, crtc); - for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { - const struct intel_crtc_state *old_pipe_crtc_state = - intel_atomic_get_old_crtc_state(state, pipe_crtc); - - intel_disable_shared_dpll(old_pipe_crtc_state); - } + intel_disable_shared_dpll(old_crtc_state); intel_encoders_post_pll_disable(state, crtc); @@ -2081,7 +2070,6 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; if (drm_WARN_ON(display->drm, crtc->active)) @@ -2105,7 +2093,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, intel_color_modeset(new_crtc_state); if (!intel_initial_watermarks(state, crtc)) - intel_update_watermarks(dev_priv); + intel_update_watermarks(display); intel_enable_transcoder(new_crtc_state); intel_crtc_vblank_on(new_crtc_state); @@ -2121,7 +2109,6 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); enum pipe pipe = crtc->pipe; @@ -2145,9 +2132,9 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI)) { if (display->platform.cherryview) - chv_disable_pll(dev_priv, pipe); + chv_disable_pll(display, pipe); else if (display->platform.valleyview) - vlv_disable_pll(dev_priv, pipe); + vlv_disable_pll(display, pipe); else i9xx_disable_pll(old_crtc_state); } @@ -2158,7 +2145,7 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, intel_set_cpu_fifo_underrun_reporting(display, pipe, false); if (!display->funcs.wm->initial_watermarks) - intel_update_watermarks(dev_priv); + intel_update_watermarks(display); /* clock the pipe down to 640x480@60 to potentially save power */ if (display->platform.i830) @@ -2341,7 +2328,6 @@ static int intel_crtc_compute_pipe_src(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); intel_joiner_compute_pipe_src(crtc_state); @@ -2360,7 +2346,7 @@ static int intel_crtc_compute_pipe_src(struct intel_crtc_state *crtc_state) } if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) && - intel_is_dual_link_lvds(i915)) { + intel_is_dual_link_lvds(display)) { drm_dbg_kms(display->drm, "[CRTC:%d:%s] Odd pipe source width not supported with dual link LVDS\n", crtc->base.base.id, crtc->base.name); @@ -2637,6 +2623,15 @@ void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc, PIPE_LINK_N2(display, transcoder)); } +static bool +transcoder_has_vrr(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + + return HAS_VRR(display) && !transcoder_is_dsi(cpu_transcoder); +} + static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); @@ -2701,6 +2696,15 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta HSYNC_START(adjusted_mode->crtc_hsync_start - 1) | HSYNC_END(adjusted_mode->crtc_hsync_end - 1)); + /* + * For platforms that always use VRR Timing Generator, the VTOTAL.Vtotal + * bits are not required. Since the support for these bits is going to + * be deprecated in upcoming platforms, avoid writing these bits for the + * platforms that do not use legacy Timing Generator. + */ + if (intel_vrr_always_use_vrr_tg(display)) + crtc_vtotal = 1; + intel_de_write(display, TRANS_VTOTAL(display, cpu_transcoder), VACTIVE(crtc_vdisplay - 1) | VTOTAL(crtc_vtotal - 1)); @@ -2761,6 +2765,15 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc intel_de_write(display, TRANS_VBLANK(display, cpu_transcoder), VBLANK_START(crtc_vblank_start - 1) | VBLANK_END(crtc_vblank_end - 1)); + /* + * For platforms that always use VRR Timing Generator, the VTOTAL.Vtotal + * bits are not required. Since the support for these bits is going to + * be deprecated in upcoming platforms, avoid writing these bits for the + * platforms that do not use legacy Timing Generator. + */ + if (intel_vrr_always_use_vrr_tg(display)) + crtc_vtotal = 1; + /* * The double buffer latch point for TRANS_VTOTAL * is the transcoder's undelayed vblank. @@ -2768,6 +2781,9 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc intel_de_write(display, TRANS_VTOTAL(display, cpu_transcoder), VACTIVE(crtc_vdisplay - 1) | VTOTAL(crtc_vtotal - 1)); + + intel_vrr_set_fixed_rr_timings(crtc_state); + intel_vrr_transcoder_enable(crtc_state); } static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state) @@ -3833,7 +3849,6 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, struct intel_display_power_domain_set *power_domain_set) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder; enum port port; u32 tmp; @@ -3855,7 +3870,7 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, * registers/MIPI[BXT]. We can break out here early, since we * need the same DSI PLL to be enabled for both DSI ports. */ - if (!bxt_dsi_pll_is_enabled(dev_priv)) + if (!bxt_dsi_pll_is_enabled(display)) break; /* XXX: this works for video mode only */ @@ -3918,7 +3933,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, DISPLAY_VER(display) >= 11) intel_get_transcoder_timings(crtc, pipe_config); - if (HAS_VRR(display) && !transcoder_is_dsi(pipe_config->cpu_transcoder)) + if (transcoder_has_vrr(pipe_config)) intel_vrr_get_config(pipe_config); intel_get_pipe_src_size(crtc, pipe_config); @@ -4145,8 +4160,6 @@ static u16 hsw_ips_linetime_wm(const struct intel_crtc_state *crtc_state, static u16 skl_linetime_wm(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode; int linetime_wm; @@ -4159,7 +4172,7 @@ static u16 skl_linetime_wm(const struct intel_crtc_state *crtc_state) /* Display WA #1135: BXT:ALL GLK:ALL */ if ((display->platform.geminilake || display->platform.broxton) && - skl_watermark_ipc_enabled(dev_priv)) + skl_watermark_ipc_enabled(display)) linetime_wm /= 2; return min(linetime_wm, 0x1ff); @@ -5385,8 +5398,6 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_I(vrr.vmin); PIPE_CONF_CHECK_I(vrr.vmax); PIPE_CONF_CHECK_I(vrr.flipline); - PIPE_CONF_CHECK_I(vrr.pipeline_full); - PIPE_CONF_CHECK_I(vrr.guardband); PIPE_CONF_CHECK_I(vrr.vsync_start); PIPE_CONF_CHECK_I(vrr.vsync_end); PIPE_CONF_CHECK_LLI(cmrr.cmrr_m); @@ -5394,6 +5405,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_BOOL(cmrr.enable); } + if (!fastset || intel_vrr_always_use_vrr_tg(display)) { + PIPE_CONF_CHECK_I(vrr.pipeline_full); + PIPE_CONF_CHECK_I(vrr.guardband); + } + #undef PIPE_CONF_CHECK_X #undef PIPE_CONF_CHECK_I #undef PIPE_CONF_CHECK_LLI @@ -6427,7 +6443,7 @@ int intel_atomic_check(struct drm_device *dev, if (ret) goto fail; - ret = intel_bw_atomic_check(state); + ret = intel_bw_atomic_check(state, any_ms); if (ret) goto fail; @@ -7229,7 +7245,7 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, static void intel_atomic_commit_tail(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(display->drm); + struct drm_i915_private __maybe_unused *dev_priv = to_i915(display->drm); struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {}; @@ -7443,7 +7459,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * toggling overhead at and above 60 FPS. */ intel_display_power_put_async_delay(display, POWER_DOMAIN_DC_OFF, wakeref, 17); - intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); + intel_display_rpm_put(display, state->wakeref); /* * Defer the cleanup of the old state to a separate worker to not @@ -7515,10 +7531,9 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, { struct intel_display *display = to_intel_display(dev); struct intel_atomic_state *state = to_intel_atomic_state(_state); - struct drm_i915_private *dev_priv = to_i915(dev); int ret = 0; - state->wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + state->wakeref = intel_display_rpm_get(display); /* * The intel_legacy_cursor_update() fast path takes care @@ -7552,7 +7567,7 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, if (ret) { drm_dbg_atomic(display->drm, "Preparing state failed with %i\n", ret); - intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); + intel_display_rpm_put(display, state->wakeref); return ret; } @@ -7562,7 +7577,7 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, if (ret) { drm_atomic_helper_unprepare_planes(dev, &state->base); - intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); + intel_display_rpm_put(display, state->wakeref); return ret; } @@ -7670,7 +7685,7 @@ void intel_setup_outputs(struct intel_display *display) intel_bios_for_each_encoder(display, intel_ddi_init); if (display->platform.geminilake || display->platform.broxton) - vlv_dsi_init(dev_priv); + vlv_dsi_init(display); } else if (HAS_PCH_SPLIT(dev_priv)) { int found; @@ -7679,7 +7694,7 @@ void intel_setup_outputs(struct intel_display *display) * to prevent the registration of both eDP and LVDS and the * incorrect sharing of the PPS. */ - intel_lvds_init(dev_priv); + intel_lvds_init(display); intel_crt_init(display); dpd_is_edp = intel_dp_is_port_edp(display, PORT_D); @@ -7754,15 +7769,15 @@ void intel_setup_outputs(struct intel_display *display) g4x_hdmi_init(display, CHV_HDMID, PORT_D); } - vlv_dsi_init(dev_priv); + vlv_dsi_init(display); } else if (display->platform.pineview) { - intel_lvds_init(dev_priv); + intel_lvds_init(display); intel_crt_init(display); } else if (IS_DISPLAY_VER(display, 3, 4)) { bool found = false; if (display->platform.mobile) - intel_lvds_init(dev_priv); + intel_lvds_init(display); intel_crt_init(display); @@ -7804,10 +7819,10 @@ void intel_setup_outputs(struct intel_display *display) intel_tv_init(display); } else if (DISPLAY_VER(display) == 2) { if (display->platform.i85x) - intel_lvds_init(dev_priv); + intel_lvds_init(display); intel_crt_init(display); - intel_dvo_init(dev_priv); + intel_dvo_init(display); } for_each_intel_encoder(display->drm, encoder) { @@ -7817,7 +7832,7 @@ void intel_setup_outputs(struct intel_display *display) intel_encoder_possible_clones(encoder); } - intel_init_pch_refclk(dev_priv); + intel_init_pch_refclk(display); drm_helper_move_panel_connectors_to_head(display->drm); } @@ -8081,6 +8096,9 @@ int intel_initial_commit(struct intel_display *display) goto out; } + if (!crtc_state->hw.active) + crtc_state->inherited = false; + if (crtc_state->hw.active) { struct intel_encoder *encoder; diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index eeb7ae3eaea878..eb6d6f2d0f7576 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -80,7 +80,7 @@ struct intel_display_funcs { /* functions used for watermark calcs for display. */ struct intel_wm_funcs { /* update_wm is for legacy wm management */ - void (*update_wm)(struct drm_i915_private *dev_priv); + void (*update_wm)(struct intel_display *display); int (*compute_watermarks)(struct intel_atomic_state *state, struct intel_crtc *crtc); void (*initial_watermarks)(struct intel_atomic_state *state, @@ -90,8 +90,8 @@ struct intel_wm_funcs { void (*optimize_watermarks)(struct intel_atomic_state *state, struct intel_crtc *crtc); int (*compute_global_watermarks)(struct intel_atomic_state *state); - void (*get_hw_state)(struct drm_i915_private *i915); - void (*sanitize)(struct drm_i915_private *i915); + void (*get_hw_state)(struct intel_display *display); + void (*sanitize)(struct intel_display *display); }; struct intel_audio_state { @@ -160,6 +160,7 @@ struct intel_hotplug { struct { unsigned long last_jiffies; int count; + int blocked_count; enum { HPD_ENABLED = 0, HPD_DISABLED = 1, @@ -170,8 +171,8 @@ struct intel_hotplug { u32 retry_bits; struct delayed_work reenable_work; - u32 long_port_mask; - u32 short_port_mask; + u32 long_hpd_pin_mask; + u32 short_hpd_pin_mask; struct work_struct dig_port_work; struct work_struct poll_init_work; diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index fdedf65bee5332..4c208fdb91375c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -24,6 +24,7 @@ #include "intel_display_debugfs_params.h" #include "intel_display_power.h" #include "intel_display_power_well.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dmc.h" #include "intel_dp.h" @@ -52,8 +53,11 @@ static struct intel_display *node_to_intel_display(struct drm_info_node *node) static int intel_display_caps(struct seq_file *m, void *data) { struct intel_display *display = node_to_intel_display(m->private); + struct drm_i915_private *i915 = to_i915(display->drm); struct drm_printer p = drm_seq_file_printer(m); + drm_printf(&p, "PCH type: %d\n", INTEL_PCH_TYPE(i915)); + intel_display_device_info_print(DISPLAY_INFO(display), DISPLAY_RUNTIME_INFO(display), &p); intel_display_params_dump(&display->params, display->drm->driver->name, &p); @@ -580,13 +584,12 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc) static int i915_display_info(struct seq_file *m, void *unused) { struct intel_display *display = node_to_intel_display(m->private); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc; struct drm_connector *connector; struct drm_connector_list_iter conn_iter; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get(display); drm_modeset_lock_all(display->drm); @@ -605,18 +608,7 @@ static int i915_display_info(struct seq_file *m, void *unused) drm_modeset_unlock_all(display->drm); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); - - return 0; -} - -static int i915_display_capabilities(struct seq_file *m, void *unused) -{ - struct intel_display *display = node_to_intel_display(m->private); - struct drm_printer p = drm_seq_file_printer(m); - - intel_display_device_info_print(DISPLAY_INFO(display), - DISPLAY_RUNTIME_INFO(display), &p); + intel_display_rpm_put(display, wakeref); return 0; } @@ -690,14 +682,11 @@ static bool intel_lpsp_power_well_enabled(struct intel_display *display, enum i915_power_well_id power_well_id) { - struct drm_i915_private *i915 = to_i915(display->drm); - intel_wakeref_t wakeref; bool is_enabled; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); - is_enabled = intel_display_power_well_is_enabled(display, - power_well_id); - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + with_intel_display_rpm(display) + is_enabled = intel_display_power_well_is_enabled(display, + power_well_id); return is_enabled; } @@ -820,7 +809,6 @@ static const struct drm_info_list intel_display_debugfs_list[] = { {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, {"i915_power_domain_info", i915_power_domain_info, 0}, {"i915_display_info", i915_display_info, 0}, - {"i915_display_capabilities", i915_display_capabilities, 0}, {"i915_shared_dplls_info", i915_shared_dplls_info, 0}, {"i915_dp_mst_info", i915_dp_mst_info, 0}, {"i915_ddb_info", i915_ddb_info, 0}, @@ -829,7 +817,6 @@ static const struct drm_info_list intel_display_debugfs_list[] = { void intel_display_debugfs_register(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct drm_minor *minor = display->drm->primary; debugfs_create_file("i915_fifo_underrun_reset", 0644, minor->debugfs_root, @@ -844,10 +831,10 @@ void intel_display_debugfs_register(struct intel_display *display) intel_dmc_debugfs_register(display); intel_dp_test_debugfs_register(display); intel_fbc_debugfs_register(display); - intel_hpd_debugfs_register(i915); + intel_hpd_debugfs_register(display); intel_opregion_debugfs_register(display); intel_psr_debugfs_register(display); - intel_wm_debugfs_register(i915); + intel_wm_debugfs_register(display); intel_display_debugfs_params(display); } diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index 717286981687a2..368b0d3417c26f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -143,9 +143,11 @@ struct intel_display_platforms { #define HAS_4TILE(__display) ((__display)->platform.dg2 || DISPLAY_VER(__display) >= 14) #define HAS_ASYNC_FLIPS(__display) (DISPLAY_VER(__display) >= 5) +#define HAS_AS_SDP(__display) (DISPLAY_VER(__display) >= 13) #define HAS_BIGJOINER(__display) (DISPLAY_VER(__display) >= 11 && HAS_DSC(__display)) #define HAS_CDCLK_CRAWL(__display) (DISPLAY_INFO(__display)->has_cdclk_crawl) #define HAS_CDCLK_SQUASH(__display) (DISPLAY_INFO(__display)->has_cdclk_squash) +#define HAS_CMRR(__display) (DISPLAY_VER(__display) >= 20) #define HAS_CMTG(__display) (!(__display)->platform.dg2 && DISPLAY_VER(__display) >= 13) #define HAS_CUR_FBC(__display) (!HAS_GMCH(__display) && IS_DISPLAY_VER(__display, 7, 13)) #define HAS_D12_PLANE_MINIMIZATION(__display) ((__display)->platform.rocketlake || (__display)->platform.alderlake_s) @@ -156,9 +158,9 @@ struct intel_display_platforms { #define HAS_DMC_WAKELOCK(__display) (DISPLAY_VER(__display) >= 20) #define HAS_DOUBLE_BUFFERED_M_N(__display) (DISPLAY_VER(__display) >= 9 || (__display)->platform.broadwell) #define HAS_DOUBLE_WIDE(__display) (DISPLAY_VER(__display) < 4) -#define HAS_DP_MST(__display) (DISPLAY_INFO(__display)->has_dp_mst) #define HAS_DP20(__display) ((__display)->platform.dg2 || DISPLAY_VER(__display) >= 14) #define HAS_DPT(__display) (DISPLAY_VER(__display) >= 13) +#define HAS_DP_MST(__display) (DISPLAY_INFO(__display)->has_dp_mst) #define HAS_DSB(__display) (DISPLAY_INFO(__display)->has_dsb) #define HAS_DSC(__display) (DISPLAY_RUNTIME_INFO(__display)->has_dsc) #define HAS_DSC_MST(__display) (DISPLAY_VER(__display) >= 12 && HAS_DSC(__display)) @@ -166,9 +168,10 @@ struct intel_display_platforms { #define HAS_FBC_DIRTY_RECT(__display) (DISPLAY_VER(__display) >= 30) #define HAS_FPGA_DBG_UNCLAIMED(__display) (DISPLAY_INFO(__display)->has_fpga_dbg) #define HAS_FW_BLC(__display) (DISPLAY_VER(__display) >= 3) -#define HAS_GMBUS_IRQ(__display) (DISPLAY_VER(__display) >= 4) #define HAS_GMBUS_BURST_READ(__display) (DISPLAY_VER(__display) >= 10 || (__display)->platform.kabylake) +#define HAS_GMBUS_IRQ(__display) (DISPLAY_VER(__display) >= 4) #define HAS_GMCH(__display) (DISPLAY_INFO(__display)->has_gmch) +#define HAS_HOTPLUG(__display) (DISPLAY_INFO(__display)->has_hotplug) #define HAS_HW_SAGV_WM(__display) (DISPLAY_VER(__display) >= 13 && !(__display)->platform.dgfx) #define HAS_IPC(__display) (DISPLAY_INFO(__display)->has_ipc) #define HAS_IPS(__display) ((__display)->platform.haswell_ult || (__display)->platform.broadwell) @@ -189,10 +192,7 @@ struct intel_display_platforms { ((__display)->platform.dgfx && DISPLAY_VER(__display) == 14)) && \ HAS_DSC(__display)) #define HAS_VRR(__display) (DISPLAY_VER(__display) >= 11) -#define HAS_AS_SDP(__display) (DISPLAY_VER(__display) >= 13) -#define HAS_CMRR(__display) (DISPLAY_VER(__display) >= 20) #define INTEL_NUM_PIPES(__display) (hweight8(DISPLAY_RUNTIME_INFO(__display)->pipe_mask)) -#define I915_HAS_HOTPLUG(__display) (DISPLAY_INFO(__display)->has_hotplug) #define OVERLAY_NEEDS_PHYSICAL(__display) (DISPLAY_INFO(__display)->overlay_needs_physical) #define SUPPORTS_TV(__display) (DISPLAY_INFO(__display)->supports_tv) diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 31740a677dd807..efee8925987e56 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -82,7 +82,6 @@ bool intel_display_driver_probe_defer(struct pci_dev *pdev) void intel_display_driver_init_hw(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_cdclk_state *cdclk_state; if (!HAS_DISPLAY(display)) @@ -94,7 +93,7 @@ void intel_display_driver_init_hw(struct intel_display *display) intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK"); cdclk_state->logical = cdclk_state->actual = display->cdclk.hw; - intel_display_wa_apply(i915); + intel_display_wa_apply(display); } static const struct drm_mode_config_funcs intel_mode_funcs = { @@ -181,8 +180,6 @@ static void intel_plane_possible_crtcs_init(struct intel_display *display) void intel_display_driver_early_probe(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (!HAS_DISPLAY(display)) return; @@ -193,12 +190,12 @@ void intel_display_driver_early_probe(struct intel_display *display) mutex_init(&display->pps.mutex); mutex_init(&display->hdcp.hdcp_mutex); - intel_display_irq_init(i915); + intel_display_irq_init(display); intel_dkl_phy_init(display); intel_color_init_hooks(display); intel_init_cdclk_hooks(display); intel_audio_hooks_init(display); - intel_dpll_init_clock_hook(i915); + intel_dpll_init_clock_hook(display); intel_init_display_hooks(display); intel_fdi_init_hook(display); intel_dmc_wl_init(display); @@ -255,11 +252,11 @@ int intel_display_driver_probe_noirq(struct intel_display *display) if (ret) goto cleanup_vga_client_pw_domain_dmc; - ret = intel_dbuf_init(i915); + ret = intel_dbuf_init(display); if (ret) goto cleanup_vga_client_pw_domain_dmc; - ret = intel_bw_init(i915); + ret = intel_bw_init(display); if (ret) goto cleanup_vga_client_pw_domain_dmc; @@ -315,11 +312,9 @@ static void set_display_access(struct intel_display *display, */ void intel_display_driver_enable_user_access(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - set_display_access(display, true, NULL); - intel_hpd_enable_detection_work(i915); + intel_hpd_enable_detection_work(display); } /** @@ -341,9 +336,7 @@ void intel_display_driver_enable_user_access(struct intel_display *display) */ void intel_display_driver_disable_user_access(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - intel_hpd_disable_detection_work(i915); + intel_hpd_disable_detection_work(display); set_display_access(display, false, current); } @@ -429,7 +422,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display) if (!HAS_DISPLAY(display)) return 0; - intel_wm_init(i915); + intel_wm_init(display); intel_panel_sanitize_ssc(display); @@ -483,7 +476,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display) * since the watermark calculation done here will use pstate->fb. */ if (!HAS_GMCH(display)) - ilk_wm_sanitize(i915); + ilk_wm_sanitize(display); return 0; @@ -498,7 +491,6 @@ int intel_display_driver_probe_nogem(struct intel_display *display) /* part #3: call after gem init */ int intel_display_driver_probe(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); int ret; if (!HAS_DISPLAY(display)) @@ -524,9 +516,9 @@ int intel_display_driver_probe(struct intel_display *display) intel_overlay_setup(display); /* Only enable hotplug handling once the fbdev is fully set up. */ - intel_hpd_init(i915); + intel_hpd_init(display); - skl_watermark_ipc_init(i915); + skl_watermark_ipc_init(display); return 0; } @@ -558,7 +550,7 @@ void intel_display_driver_register(struct intel_display *display) * fbdev->async_cookie. */ drm_kms_helper_poll_init(display->drm); - intel_hpd_poll_disable(i915); + intel_hpd_poll_disable(display); intel_fbdev_setup(i915); @@ -600,7 +592,7 @@ void intel_display_driver_remove_noirq(struct intel_display *display) * Due to the hpd irq storm handling the hotplug work can re-arm the * poll handlers. Hence disable polling after hpd handling is shut down. */ - intel_hpd_poll_fini(i915); + intel_hpd_poll_fini(display); intel_unregister_dsm_handler(); @@ -733,7 +725,6 @@ __intel_display_driver_resume(struct intel_display *display, void intel_display_driver_resume(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct drm_atomic_state *state = display->restore.modeset_state; struct drm_modeset_acquire_ctx ctx; int ret; @@ -761,7 +752,7 @@ void intel_display_driver_resume(struct intel_display *display) if (!ret) ret = __intel_display_driver_resume(display, state, &ctx); - skl_watermark_ipc_update(i915); + skl_watermark_ipc_update(display); drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index aa23bb81780534..d2a35e3630b1d6 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -14,6 +14,7 @@ #include "intel_crtc.h" #include "intel_de.h" #include "intel_display_irq.h" +#include "intel_display_rpm.h" #include "intel_display_trace.h" #include "intel_display_types.h" #include "intel_dmc_wl.h" @@ -115,9 +116,8 @@ static void intel_pipe_fault_irq_handler(struct intel_display *display, } static void -intel_handle_vblank(struct drm_i915_private *dev_priv, enum pipe pipe) +intel_handle_vblank(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); drm_crtc_handle_vblank(&crtc->base); @@ -125,59 +125,59 @@ intel_handle_vblank(struct drm_i915_private *dev_priv, enum pipe pipe) /** * ilk_update_display_irq - update DEIMR - * @dev_priv: driver private + * @display: display device * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */ -void ilk_update_display_irq(struct drm_i915_private *dev_priv, +void ilk_update_display_irq(struct intel_display *display, u32 interrupt_mask, u32 enabled_irq_mask) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 new_val; lockdep_assert_held(&dev_priv->irq_lock); - drm_WARN_ON(&dev_priv->drm, enabled_irq_mask & ~interrupt_mask); + drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask); new_val = dev_priv->irq_mask; new_val &= ~interrupt_mask; new_val |= (~enabled_irq_mask & interrupt_mask); if (new_val != dev_priv->irq_mask && - !drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) { + !drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv))) { dev_priv->irq_mask = new_val; intel_de_write(display, DEIMR, dev_priv->irq_mask); intel_de_posting_read(display, DEIMR); } } -void ilk_enable_display_irq(struct drm_i915_private *i915, u32 bits) +void ilk_enable_display_irq(struct intel_display *display, u32 bits) { - ilk_update_display_irq(i915, bits, bits); + ilk_update_display_irq(display, bits, bits); } -void ilk_disable_display_irq(struct drm_i915_private *i915, u32 bits) +void ilk_disable_display_irq(struct intel_display *display, u32 bits) { - ilk_update_display_irq(i915, bits, 0); + ilk_update_display_irq(display, bits, 0); } /** * bdw_update_port_irq - update DE port interrupt - * @dev_priv: driver private + * @display: display device * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */ -void bdw_update_port_irq(struct drm_i915_private *dev_priv, +void bdw_update_port_irq(struct intel_display *display, u32 interrupt_mask, u32 enabled_irq_mask) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 new_val; u32 old_val; lockdep_assert_held(&dev_priv->irq_lock); - drm_WARN_ON(&dev_priv->drm, enabled_irq_mask & ~interrupt_mask); + drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask); - if (drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) + if (drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv))) return; old_val = intel_de_read(display, GEN8_DE_PORT_IMR); @@ -194,83 +194,83 @@ void bdw_update_port_irq(struct drm_i915_private *dev_priv, /** * bdw_update_pipe_irq - update DE pipe interrupt - * @dev_priv: driver private + * @display: display device * @pipe: pipe whose interrupt to update * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */ -static void bdw_update_pipe_irq(struct drm_i915_private *dev_priv, +static void bdw_update_pipe_irq(struct intel_display *display, enum pipe pipe, u32 interrupt_mask, u32 enabled_irq_mask) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 new_val; lockdep_assert_held(&dev_priv->irq_lock); - drm_WARN_ON(&dev_priv->drm, enabled_irq_mask & ~interrupt_mask); + drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask); - if (drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) + if (drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv))) return; - new_val = dev_priv->display.irq.de_irq_mask[pipe]; + new_val = display->irq.de_irq_mask[pipe]; new_val &= ~interrupt_mask; new_val |= (~enabled_irq_mask & interrupt_mask); - if (new_val != dev_priv->display.irq.de_irq_mask[pipe]) { - dev_priv->display.irq.de_irq_mask[pipe] = new_val; + if (new_val != display->irq.de_irq_mask[pipe]) { + display->irq.de_irq_mask[pipe] = new_val; intel_de_write(display, GEN8_DE_PIPE_IMR(pipe), display->irq.de_irq_mask[pipe]); intel_de_posting_read(display, GEN8_DE_PIPE_IMR(pipe)); } } -void bdw_enable_pipe_irq(struct drm_i915_private *i915, +void bdw_enable_pipe_irq(struct intel_display *display, enum pipe pipe, u32 bits) { - bdw_update_pipe_irq(i915, pipe, bits, bits); + bdw_update_pipe_irq(display, pipe, bits, bits); } -void bdw_disable_pipe_irq(struct drm_i915_private *i915, +void bdw_disable_pipe_irq(struct intel_display *display, enum pipe pipe, u32 bits) { - bdw_update_pipe_irq(i915, pipe, bits, 0); + bdw_update_pipe_irq(display, pipe, bits, 0); } /** * ibx_display_interrupt_update - update SDEIMR - * @dev_priv: driver private + * @display: display device * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */ -void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, +void ibx_display_interrupt_update(struct intel_display *display, u32 interrupt_mask, u32 enabled_irq_mask) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 sdeimr = intel_de_read(display, SDEIMR); sdeimr &= ~interrupt_mask; sdeimr |= (~enabled_irq_mask & interrupt_mask); - drm_WARN_ON(&dev_priv->drm, enabled_irq_mask & ~interrupt_mask); + drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask); lockdep_assert_held(&dev_priv->irq_lock); - if (drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) + if (drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv))) return; intel_de_write(display, SDEIMR, sdeimr); intel_de_posting_read(display, SDEIMR); } -void ibx_enable_display_interrupt(struct drm_i915_private *i915, u32 bits) +void ibx_enable_display_interrupt(struct intel_display *display, u32 bits) { - ibx_display_interrupt_update(i915, bits, bits); + ibx_display_interrupt_update(display, bits, bits); } -void ibx_disable_display_interrupt(struct drm_i915_private *i915, u32 bits) +void ibx_disable_display_interrupt(struct intel_display *display, u32 bits) { - ibx_display_interrupt_update(i915, bits, 0); + ibx_display_interrupt_update(display, bits, 0); } u32 i915_pipestat_enable_mask(struct intel_display *display, @@ -318,48 +318,48 @@ u32 i915_pipestat_enable_mask(struct intel_display *display, return enable_mask; } -void i915_enable_pipestat(struct drm_i915_private *dev_priv, +void i915_enable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask) { - struct intel_display *display = &dev_priv->display; - i915_reg_t reg = PIPESTAT(dev_priv, pipe); + struct drm_i915_private *dev_priv = to_i915(display->drm); + i915_reg_t reg = PIPESTAT(display, pipe); u32 enable_mask; - drm_WARN_ONCE(&dev_priv->drm, status_mask & ~PIPESTAT_INT_STATUS_MASK, + drm_WARN_ONCE(display->drm, status_mask & ~PIPESTAT_INT_STATUS_MASK, "pipe %c: status_mask=0x%x\n", pipe_name(pipe), status_mask); lockdep_assert_held(&dev_priv->irq_lock); - drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv)); + drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv)); - if ((dev_priv->display.irq.pipestat_irq_mask[pipe] & status_mask) == status_mask) + if ((display->irq.pipestat_irq_mask[pipe] & status_mask) == status_mask) return; - dev_priv->display.irq.pipestat_irq_mask[pipe] |= status_mask; + display->irq.pipestat_irq_mask[pipe] |= status_mask; enable_mask = i915_pipestat_enable_mask(display, pipe); intel_de_write(display, reg, enable_mask | status_mask); intel_de_posting_read(display, reg); } -void i915_disable_pipestat(struct drm_i915_private *dev_priv, +void i915_disable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask) { - struct intel_display *display = &dev_priv->display; - i915_reg_t reg = PIPESTAT(dev_priv, pipe); + struct drm_i915_private *dev_priv = to_i915(display->drm); + i915_reg_t reg = PIPESTAT(display, pipe); u32 enable_mask; - drm_WARN_ONCE(&dev_priv->drm, status_mask & ~PIPESTAT_INT_STATUS_MASK, + drm_WARN_ONCE(display->drm, status_mask & ~PIPESTAT_INT_STATUS_MASK, "pipe %c: status_mask=0x%x\n", pipe_name(pipe), status_mask); lockdep_assert_held(&dev_priv->irq_lock); - drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv)); + drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv)); - if ((dev_priv->display.irq.pipestat_irq_mask[pipe] & status_mask) == 0) + if ((display->irq.pipestat_irq_mask[pipe] & status_mask) == 0) return; - dev_priv->display.irq.pipestat_irq_mask[pipe] &= ~status_mask; + display->irq.pipestat_irq_mask[pipe] &= ~status_mask; enable_mask = i915_pipestat_enable_mask(display, pipe); intel_de_write(display, reg, enable_mask | status_mask); @@ -368,24 +368,22 @@ void i915_disable_pipestat(struct drm_i915_private *dev_priv, static bool i915_has_legacy_blc_interrupt(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - if (IS_I85X(i915)) + if (display->platform.i85x) return true; - if (IS_PINEVIEW(i915)) + if (display->platform.pineview) return true; - return IS_DISPLAY_VER(display, 3, 4) && IS_MOBILE(i915); + return IS_DISPLAY_VER(display, 3, 4) && display->platform.mobile; } /** * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion - * @dev_priv: i915 device private + * @display: display device */ -void i915_enable_asle_pipestat(struct drm_i915_private *dev_priv) +void i915_enable_asle_pipestat(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); if (!intel_opregion_asle_present(display)) return; @@ -395,22 +393,21 @@ void i915_enable_asle_pipestat(struct drm_i915_private *dev_priv) spin_lock_irq(&dev_priv->irq_lock); - i915_enable_pipestat(dev_priv, PIPE_B, PIPE_LEGACY_BLC_EVENT_STATUS); - if (DISPLAY_VER(dev_priv) >= 4) - i915_enable_pipestat(dev_priv, PIPE_A, + i915_enable_pipestat(display, PIPE_B, PIPE_LEGACY_BLC_EVENT_STATUS); + if (DISPLAY_VER(display) >= 4) + i915_enable_pipestat(display, PIPE_A, PIPE_LEGACY_BLC_EVENT_STATUS); spin_unlock_irq(&dev_priv->irq_lock); } #if IS_ENABLED(CONFIG_DEBUG_FS) -static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, +static void display_pipe_crc_irq_handler(struct intel_display *display, enum pipe pipe, u32 crc0, u32 crc1, u32 crc2, u32 crc3, u32 crc4) { - struct intel_display *display = &dev_priv->display; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc; u32 crcs[5] = { crc0, crc1, crc2, crc3, crc4 }; @@ -427,7 +424,7 @@ static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, * don't trust that one either. */ if (pipe_crc->skipped <= 0 || - (DISPLAY_VER(dev_priv) >= 8 && pipe_crc->skipped == 1)) { + (DISPLAY_VER(display) >= 8 && pipe_crc->skipped == 1)) { pipe_crc->skipped++; spin_unlock(&pipe_crc->lock); return; @@ -440,20 +437,19 @@ static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, } #else static inline void -display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, +display_pipe_crc_irq_handler(struct intel_display *display, enum pipe pipe, u32 crc0, u32 crc1, u32 crc2, u32 crc3, u32 crc4) {} #endif -static void flip_done_handler(struct drm_i915_private *i915, +static void flip_done_handler(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &i915->display; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); - spin_lock(&i915->drm.event_lock); + spin_lock(&display->drm->event_lock); if (crtc->flip_done_event) { trace_intel_crtc_flip_done(crtc); @@ -461,25 +457,21 @@ static void flip_done_handler(struct drm_i915_private *i915, crtc->flip_done_event = NULL; } - spin_unlock(&i915->drm.event_lock); + spin_unlock(&display->drm->event_lock); } -static void hsw_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, +static void hsw_pipe_crc_irq_handler(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; - - display_pipe_crc_irq_handler(dev_priv, pipe, + display_pipe_crc_irq_handler(display, pipe, intel_de_read(display, PIPE_CRC_RES_HSW(pipe)), 0, 0, 0, 0); } -static void ivb_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, +static void ivb_pipe_crc_irq_handler(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; - - display_pipe_crc_irq_handler(dev_priv, pipe, + display_pipe_crc_irq_handler(display, pipe, intel_de_read(display, PIPE_CRC_RES_1_IVB(pipe)), intel_de_read(display, PIPE_CRC_RES_2_IVB(pipe)), intel_de_read(display, PIPE_CRC_RES_3_IVB(pipe)), @@ -487,58 +479,56 @@ static void ivb_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, intel_de_read(display, PIPE_CRC_RES_5_IVB(pipe))); } -static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, +static void i9xx_pipe_crc_irq_handler(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; u32 res1, res2; - if (DISPLAY_VER(dev_priv) >= 3) - res1 = intel_de_read(display, PIPE_CRC_RES_RES1_I915(dev_priv, pipe)); + if (DISPLAY_VER(display) >= 3) + res1 = intel_de_read(display, PIPE_CRC_RES_RES1_I915(display, pipe)); else res1 = 0; - if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) - res2 = intel_de_read(display, PIPE_CRC_RES_RES2_G4X(dev_priv, pipe)); + if (DISPLAY_VER(display) >= 5 || display->platform.g4x) + res2 = intel_de_read(display, PIPE_CRC_RES_RES2_G4X(display, pipe)); else res2 = 0; - display_pipe_crc_irq_handler(dev_priv, pipe, - intel_de_read(display, PIPE_CRC_RES_RED(dev_priv, pipe)), - intel_de_read(display, PIPE_CRC_RES_GREEN(dev_priv, pipe)), - intel_de_read(display, PIPE_CRC_RES_BLUE(dev_priv, pipe)), + display_pipe_crc_irq_handler(display, pipe, + intel_de_read(display, PIPE_CRC_RES_RED(display, pipe)), + intel_de_read(display, PIPE_CRC_RES_GREEN(display, pipe)), + intel_de_read(display, PIPE_CRC_RES_BLUE(display, pipe)), res1, res2); } -static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv) +static void i9xx_pipestat_irq_reset(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { intel_de_write(display, - PIPESTAT(dev_priv, pipe), + PIPESTAT(display, pipe), PIPESTAT_INT_STATUS_MASK | PIPE_FIFO_UNDERRUN_STATUS); - dev_priv->display.irq.pipestat_irq_mask[pipe] = 0; + display->irq.pipestat_irq_mask[pipe] = 0; } } -void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, +void i9xx_pipestat_irq_ack(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe; spin_lock(&dev_priv->irq_lock); - if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && - !dev_priv->display.irq.vlv_display_irqs_enabled) { + if ((display->platform.valleyview || display->platform.cherryview) && + !display->irq.vlv_display_irqs_enabled) { spin_unlock(&dev_priv->irq_lock); return; } - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { i915_reg_t reg; u32 status_mask, enable_mask, iir_bit = 0; @@ -566,12 +556,12 @@ void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, break; } if (iir & iir_bit) - status_mask |= dev_priv->display.irq.pipestat_irq_mask[pipe]; + status_mask |= display->irq.pipestat_irq_mask[pipe]; if (!status_mask) continue; - reg = PIPESTAT(dev_priv, pipe); + reg = PIPESTAT(display, pipe); pipe_stats[pipe] = intel_de_read(display, reg) & status_mask; enable_mask = i915_pipestat_enable_mask(display, pipe); @@ -592,22 +582,21 @@ void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, spin_unlock(&dev_priv->irq_lock); } -void i915_pipestat_irq_handler(struct drm_i915_private *dev_priv, +void i915_pipestat_irq_handler(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { - struct intel_display *display = &dev_priv->display; bool blc_event = false; enum pipe pipe; - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) blc_event = true; if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) - i9xx_pipe_crc_irq_handler(dev_priv, pipe); + i9xx_pipe_crc_irq_handler(display, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) intel_cpu_fifo_underrun_irq_handler(display, pipe); @@ -617,22 +606,21 @@ void i915_pipestat_irq_handler(struct drm_i915_private *dev_priv, intel_opregion_asle_intr(display); } -void i965_pipestat_irq_handler(struct drm_i915_private *dev_priv, +void i965_pipestat_irq_handler(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { - struct intel_display *display = &dev_priv->display; bool blc_event = false; enum pipe pipe; - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) blc_event = true; if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) - i9xx_pipe_crc_irq_handler(dev_priv, pipe); + i9xx_pipe_crc_irq_handler(display, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) intel_cpu_fifo_underrun_irq_handler(display, pipe); @@ -645,21 +633,20 @@ void i965_pipestat_irq_handler(struct drm_i915_private *dev_priv, intel_gmbus_irq_handler(display); } -void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv, +void valleyview_pipestat_irq_handler(struct intel_display *display, u32 pipe_stats[I915_MAX_PIPES]) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV) - flip_done_handler(dev_priv, pipe); + flip_done_handler(display, pipe); if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) - i9xx_pipe_crc_irq_handler(dev_priv, pipe); + i9xx_pipe_crc_irq_handler(display, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) intel_cpu_fifo_underrun_irq_handler(display, pipe); @@ -669,18 +656,17 @@ void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv, intel_gmbus_irq_handler(display); } -static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) +static void ibx_irq_handler(struct intel_display *display, u32 pch_iir) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK; - ibx_hpd_irq_handler(dev_priv, hotplug_trigger); + ibx_hpd_irq_handler(display, hotplug_trigger); if (pch_iir & SDE_AUDIO_POWER_MASK) { int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK) >> SDE_AUDIO_POWER_SHIFT); - drm_dbg(&dev_priv->drm, "PCH audio power change on port %d\n", + drm_dbg(display->drm, "PCH audio power change on port %d\n", port_name(port)); } @@ -691,26 +677,26 @@ static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) intel_gmbus_irq_handler(display); if (pch_iir & SDE_AUDIO_HDCP_MASK) - drm_dbg(&dev_priv->drm, "PCH HDCP audio interrupt\n"); + drm_dbg(display->drm, "PCH HDCP audio interrupt\n"); if (pch_iir & SDE_AUDIO_TRANS_MASK) - drm_dbg(&dev_priv->drm, "PCH transcoder audio interrupt\n"); + drm_dbg(display->drm, "PCH transcoder audio interrupt\n"); if (pch_iir & SDE_POISON) - drm_err(&dev_priv->drm, "PCH poison interrupt\n"); + drm_err(display->drm, "PCH poison interrupt\n"); if (pch_iir & SDE_FDI_MASK) { - for_each_pipe(dev_priv, pipe) - drm_dbg(&dev_priv->drm, " pipe %c FDI IIR: 0x%08x\n", + for_each_pipe(display, pipe) + drm_dbg(display->drm, " pipe %c FDI IIR: 0x%08x\n", pipe_name(pipe), intel_de_read(display, FDI_RX_IIR(pipe))); } if (pch_iir & (SDE_TRANSB_CRC_DONE | SDE_TRANSA_CRC_DONE)) - drm_dbg(&dev_priv->drm, "PCH transcoder CRC done interrupt\n"); + drm_dbg(display->drm, "PCH transcoder CRC done interrupt\n"); if (pch_iir & (SDE_TRANSB_CRC_ERR | SDE_TRANSA_CRC_ERR)) - drm_dbg(&dev_priv->drm, + drm_dbg(display->drm, "PCH transcoder CRC error interrupt\n"); if (pch_iir & SDE_TRANSA_FIFO_UNDER) @@ -753,14 +739,13 @@ static const struct pipe_fault_handler ivb_pipe_fault_handlers[] = { {} }; -static void ivb_err_int_handler(struct drm_i915_private *dev_priv) +static void ivb_err_int_handler(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; u32 err_int = intel_de_read(display, GEN7_ERR_INT); enum pipe pipe; if (err_int & ERR_INT_POISON) - drm_err(&dev_priv->drm, "Poison interrupt\n"); + drm_err(display->drm, "Poison interrupt\n"); if (err_int & ERR_INT_INVALID_GTT_PTE) drm_err_ratelimited(display->drm, "Invalid GTT PTE\n"); @@ -768,17 +753,17 @@ static void ivb_err_int_handler(struct drm_i915_private *dev_priv) if (err_int & ERR_INT_INVALID_PTE_DATA) drm_err_ratelimited(display->drm, "Invalid PTE data\n"); - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { u32 fault_errors; if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) intel_cpu_fifo_underrun_irq_handler(display, pipe); if (err_int & ERR_INT_PIPE_CRC_DONE(pipe)) { - if (IS_IVYBRIDGE(dev_priv)) - ivb_pipe_crc_irq_handler(dev_priv, pipe); + if (display->platform.ivybridge) + ivb_pipe_crc_irq_handler(display, pipe); else - hsw_pipe_crc_irq_handler(dev_priv, pipe); + hsw_pipe_crc_irq_handler(display, pipe); } fault_errors = err_int & ivb_err_int_pipe_fault_mask(pipe); @@ -790,34 +775,32 @@ static void ivb_err_int_handler(struct drm_i915_private *dev_priv) intel_de_write(display, GEN7_ERR_INT, err_int); } -static void cpt_serr_int_handler(struct drm_i915_private *dev_priv) +static void cpt_serr_int_handler(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; u32 serr_int = intel_de_read(display, SERR_INT); enum pipe pipe; if (serr_int & SERR_INT_POISON) - drm_err(&dev_priv->drm, "PCH poison interrupt\n"); + drm_err(display->drm, "PCH poison interrupt\n"); - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) if (serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pipe)) intel_pch_fifo_underrun_irq_handler(display, pipe); intel_de_write(display, SERR_INT, serr_int); } -static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) +static void cpt_irq_handler(struct intel_display *display, u32 pch_iir) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT; - ibx_hpd_irq_handler(dev_priv, hotplug_trigger); + ibx_hpd_irq_handler(display, hotplug_trigger); if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) { int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >> SDE_AUDIO_POWER_SHIFT_CPT); - drm_dbg(&dev_priv->drm, "PCH audio power change on port %c\n", + drm_dbg(display->drm, "PCH audio power change on port %c\n", port_name(port)); } @@ -828,20 +811,20 @@ static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) intel_gmbus_irq_handler(display); if (pch_iir & SDE_AUDIO_CP_REQ_CPT) - drm_dbg(&dev_priv->drm, "Audio CP request interrupt\n"); + drm_dbg(display->drm, "Audio CP request interrupt\n"); if (pch_iir & SDE_AUDIO_CP_CHG_CPT) - drm_dbg(&dev_priv->drm, "Audio CP change interrupt\n"); + drm_dbg(display->drm, "Audio CP change interrupt\n"); if (pch_iir & SDE_FDI_MASK_CPT) { - for_each_pipe(dev_priv, pipe) - drm_dbg(&dev_priv->drm, " pipe %c FDI IIR: 0x%08x\n", + for_each_pipe(display, pipe) + drm_dbg(display->drm, " pipe %c FDI IIR: 0x%08x\n", pipe_name(pipe), intel_de_read(display, FDI_RX_IIR(pipe))); } if (pch_iir & SDE_ERROR_CPT) - cpt_serr_int_handler(dev_priv); + cpt_serr_int_handler(display); } static u32 ilk_gtt_fault_pipe_fault_mask(enum pipe pipe) @@ -894,14 +877,14 @@ static void ilk_gtt_fault_irq_handler(struct intel_display *display) } } -void ilk_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) +void ilk_display_irq_handler(struct intel_display *display, u32 de_iir) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe; u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG; if (hotplug_trigger) - ilk_hpd_irq_handler(dev_priv, hotplug_trigger); + ilk_hpd_irq_handler(display, hotplug_trigger); if (de_iir & DE_AUX_CHANNEL_A) intel_dp_aux_irq_handler(display); @@ -910,23 +893,23 @@ void ilk_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) intel_opregion_asle_intr(display); if (de_iir & DE_POISON) - drm_err(&dev_priv->drm, "Poison interrupt\n"); + drm_err(display->drm, "Poison interrupt\n"); if (de_iir & DE_GTT_FAULT) ilk_gtt_fault_irq_handler(display); - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { if (de_iir & DE_PIPE_VBLANK(pipe)) - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); if (de_iir & DE_PLANE_FLIP_DONE(pipe)) - flip_done_handler(dev_priv, pipe); + flip_done_handler(display, pipe); if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe)) intel_cpu_fifo_underrun_irq_handler(display, pipe); if (de_iir & DE_PIPE_CRC_DONE(pipe)) - i9xx_pipe_crc_irq_handler(dev_priv, pipe); + i9xx_pipe_crc_irq_handler(display, pipe); } /* check event from PCH */ @@ -934,34 +917,34 @@ void ilk_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) u32 pch_iir = intel_de_read(display, SDEIIR); if (HAS_PCH_CPT(dev_priv)) - cpt_irq_handler(dev_priv, pch_iir); + cpt_irq_handler(display, pch_iir); else - ibx_irq_handler(dev_priv, pch_iir); + ibx_irq_handler(display, pch_iir); /* should clear PCH hotplug event before clear CPU irq */ intel_de_write(display, SDEIIR, pch_iir); } - if (DISPLAY_VER(dev_priv) == 5 && de_iir & DE_PCU_EVENT) + if (DISPLAY_VER(display) == 5 && de_iir & DE_PCU_EVENT) gen5_rps_irq_handler(&to_gt(dev_priv)->rps); } -void ivb_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) +void ivb_display_irq_handler(struct intel_display *display, u32 de_iir) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe; u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG_IVB; if (hotplug_trigger) - ilk_hpd_irq_handler(dev_priv, hotplug_trigger); + ilk_hpd_irq_handler(display, hotplug_trigger); if (de_iir & DE_ERR_INT_IVB) - ivb_err_int_handler(dev_priv); + ivb_err_int_handler(display); if (de_iir & DE_EDP_PSR_INT_HSW) { struct intel_encoder *encoder; - for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) { + for_each_intel_encoder_with_psr(display->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); u32 psr_iir; @@ -977,35 +960,35 @@ void ivb_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) if (de_iir & DE_GSE_IVB) intel_opregion_asle_intr(display); - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { if (de_iir & DE_PIPE_VBLANK_IVB(pipe)) - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe)) - flip_done_handler(dev_priv, pipe); + flip_done_handler(display, pipe); } /* check event from PCH */ if (!HAS_PCH_NOP(dev_priv) && (de_iir & DE_PCH_EVENT_IVB)) { u32 pch_iir = intel_de_read(display, SDEIIR); - cpt_irq_handler(dev_priv, pch_iir); + cpt_irq_handler(display, pch_iir); /* clear PCH hotplug event before clear CPU irq */ intel_de_write(display, SDEIIR, pch_iir); } } -static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv) +static u32 gen8_de_port_aux_mask(struct intel_display *display) { u32 mask; - if (DISPLAY_VER(dev_priv) >= 20) + if (DISPLAY_VER(display) >= 20) return 0; - else if (DISPLAY_VER(dev_priv) >= 14) + else if (DISPLAY_VER(display) >= 14) return TGL_DE_PORT_AUX_DDIA | TGL_DE_PORT_AUX_DDIB; - else if (DISPLAY_VER(dev_priv) >= 13) + else if (DISPLAY_VER(display) >= 13) return TGL_DE_PORT_AUX_DDIA | TGL_DE_PORT_AUX_DDIB | TGL_DE_PORT_AUX_DDIC | @@ -1015,7 +998,7 @@ static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv) TGL_DE_PORT_AUX_USBC2 | TGL_DE_PORT_AUX_USBC3 | TGL_DE_PORT_AUX_USBC4; - else if (DISPLAY_VER(dev_priv) >= 12) + else if (DISPLAY_VER(display) >= 12) return TGL_DE_PORT_AUX_DDIA | TGL_DE_PORT_AUX_DDIB | TGL_DE_PORT_AUX_DDIC | @@ -1027,12 +1010,12 @@ static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv) TGL_DE_PORT_AUX_USBC6; mask = GEN8_AUX_CHANNEL_A; - if (DISPLAY_VER(dev_priv) >= 9) + if (DISPLAY_VER(display) >= 9) mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | GEN9_AUX_CHANNEL_D; - if (DISPLAY_VER(dev_priv) == 11) { + if (DISPLAY_VER(display) == 11) { mask |= ICL_AUX_CHANNEL_F; mask |= ICL_AUX_CHANNEL_E; } @@ -1040,10 +1023,8 @@ static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv) return mask; } -static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv) +static u32 gen8_de_pipe_fault_mask(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; - if (DISPLAY_VER(display) >= 14) return MTL_PIPEDMC_ATS_FAULT | MTL_PLANE_ATS_FAULT | @@ -1195,15 +1176,14 @@ gen8_pipe_fault_handlers(struct intel_display *display) return bdw_pipe_fault_handlers; } -static void intel_pmdemand_irq_handler(struct drm_i915_private *dev_priv) +static void intel_pmdemand_irq_handler(struct intel_display *display) { - wake_up_all(&dev_priv->display.pmdemand.waitqueue); + wake_up_all(&display->pmdemand.waitqueue); } static void -gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) +gen8_de_misc_irq_handler(struct intel_display *display, u32 iir) { - struct intel_display *display = &dev_priv->display; bool found = false; if (HAS_DBUF_OVERLAP_DETECTION(display)) { @@ -1213,20 +1193,20 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) } } - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { if (iir & (XELPDP_PMDEMAND_RSP | XELPDP_PMDEMAND_RSPTOUT_ERR)) { if (iir & XELPDP_PMDEMAND_RSPTOUT_ERR) - drm_dbg(&dev_priv->drm, + drm_dbg(display->drm, "Error waiting for Punit PM Demand Response\n"); - intel_pmdemand_irq_handler(dev_priv); + intel_pmdemand_irq_handler(display); found = true; } if (iir & XELPDP_RM_TIMEOUT) { u32 val = intel_de_read(display, RM_TIMEOUT_REG_CAPTURE); - drm_warn(&dev_priv->drm, "Register Access Timeout = 0x%x\n", val); + drm_warn(display->drm, "Register Access Timeout = 0x%x\n", val); found = true; } } else if (iir & GEN8_DE_MISC_GSE) { @@ -1239,12 +1219,12 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) u32 psr_iir; i915_reg_t iir_reg; - for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) { + for_each_intel_encoder_with_psr(display->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - if (DISPLAY_VER(dev_priv) >= 12) - iir_reg = TRANS_PSR_IIR(dev_priv, - intel_dp->psr.transcoder); + if (DISPLAY_VER(display) >= 12) + iir_reg = TRANS_PSR_IIR(display, + intel_dp->psr.transcoder); else iir_reg = EDP_PSR_IIR; @@ -1256,19 +1236,18 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) intel_psr_irq_handler(intel_dp, psr_iir); /* prior GEN12 only have one EDP PSR */ - if (DISPLAY_VER(dev_priv) < 12) + if (DISPLAY_VER(display) < 12) break; } } if (!found) - drm_err(&dev_priv->drm, "Unexpected DE Misc interrupt: 0x%08x\n", iir); + drm_err(display->drm, "Unexpected DE Misc interrupt: 0x%08x\n", iir); } -static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, +static void gen11_dsi_te_interrupt_handler(struct intel_display *display, u32 te_trigger) { - struct intel_display *display = &dev_priv->display; enum pipe pipe = INVALID_PIPE; enum transcoder dsi_trans; enum port port; @@ -1278,7 +1257,7 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, * Incase of dual link, TE comes from DSI_1 * this is to check if dual link is enabled */ - val = intel_de_read(display, TRANS_DDI_FUNC_CTL2(dev_priv, TRANSCODER_DSI_0)); + val = intel_de_read(display, TRANS_DDI_FUNC_CTL2(display, TRANSCODER_DSI_0)); val &= PORT_SYNC_MODE_ENABLE; /* @@ -1294,12 +1273,12 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, val = val & OP_MODE_MASK; if (val != CMD_MODE_NO_GATE && val != CMD_MODE_TE_GATE) { - drm_err(&dev_priv->drm, "DSI trancoder not configured in command mode\n"); + drm_err(display->drm, "DSI trancoder not configured in command mode\n"); return; } /* Get PIPE for handling VBLANK event */ - val = intel_de_read(display, TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans)); + val = intel_de_read(display, TRANS_DDI_FUNC_CTL(display, dsi_trans)); switch (val & TRANS_DDI_EDP_INPUT_MASK) { case TRANS_DDI_EDP_INPUT_A_ON: pipe = PIPE_A; @@ -1311,28 +1290,28 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, pipe = PIPE_C; break; default: - drm_err(&dev_priv->drm, "Invalid PIPE\n"); + drm_err(display->drm, "Invalid PIPE\n"); return; } - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); /* clear TE in dsi IIR */ port = (te_trigger & DSI1_TE) ? PORT_B : PORT_A; intel_de_rmw(display, DSI_INTR_IDENT_REG(port), 0, 0); } -static u32 gen8_de_pipe_flip_done_mask(struct drm_i915_private *i915) +static u32 gen8_de_pipe_flip_done_mask(struct intel_display *display) { - if (DISPLAY_VER(i915) >= 9) + if (DISPLAY_VER(display) >= 9) return GEN9_PIPE_PLANE1_FLIP_DONE; else return GEN8_PIPE_PRIMARY_FLIP_DONE; } -static void gen8_read_and_ack_pch_irqs(struct drm_i915_private *i915, u32 *pch_iir, u32 *pica_iir) +static void gen8_read_and_ack_pch_irqs(struct intel_display *display, u32 *pch_iir, u32 *pica_iir) { - struct intel_display *display = &i915->display; + struct drm_i915_private *i915 = to_i915(display->drm); u32 pica_ier = 0; *pica_iir = 0; @@ -1346,7 +1325,7 @@ static void gen8_read_and_ack_pch_irqs(struct drm_i915_private *i915, u32 *pch_i * their flags both in the PICA and SDE IIR. */ if (*pch_iir & SDE_PICAINTERRUPT) { - drm_WARN_ON(&i915->drm, INTEL_PCH_TYPE(i915) < PCH_MTL); + drm_WARN_ON(display->drm, INTEL_PCH_TYPE(i915) < PCH_MTL); pica_ier = intel_de_rmw(display, PICAINTERRUPT_IER, ~0, 0); *pica_iir = intel_de_read(display, PICAINTERRUPT_IIR); @@ -1359,32 +1338,32 @@ static void gen8_read_and_ack_pch_irqs(struct drm_i915_private *i915, u32 *pch_i intel_de_write(display, PICAINTERRUPT_IER, pica_ier); } -void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) +void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 iir; enum pipe pipe; - drm_WARN_ON_ONCE(&dev_priv->drm, !HAS_DISPLAY(dev_priv)); + drm_WARN_ON_ONCE(display->drm, !HAS_DISPLAY(display)); if (master_ctl & GEN8_DE_MISC_IRQ) { iir = intel_de_read(display, GEN8_DE_MISC_IIR); if (iir) { intel_de_write(display, GEN8_DE_MISC_IIR, iir); - gen8_de_misc_irq_handler(dev_priv, iir); + gen8_de_misc_irq_handler(display, iir); } else { - drm_err_ratelimited(&dev_priv->drm, + drm_err_ratelimited(display->drm, "The master control interrupt lied (DE MISC)!\n"); } } - if (DISPLAY_VER(dev_priv) >= 11 && (master_ctl & GEN11_DE_HPD_IRQ)) { + if (DISPLAY_VER(display) >= 11 && (master_ctl & GEN11_DE_HPD_IRQ)) { iir = intel_de_read(display, GEN11_DE_HPD_IIR); if (iir) { intel_de_write(display, GEN11_DE_HPD_IIR, iir); - gen11_hpd_irq_handler(dev_priv, iir); + gen11_hpd_irq_handler(display, iir); } else { - drm_err_ratelimited(&dev_priv->drm, + drm_err_ratelimited(display->drm, "The master control interrupt lied, (DE HPD)!\n"); } } @@ -1396,52 +1375,52 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) intel_de_write(display, GEN8_DE_PORT_IIR, iir); - if (iir & gen8_de_port_aux_mask(dev_priv)) { + if (iir & gen8_de_port_aux_mask(display)) { intel_dp_aux_irq_handler(display); found = true; } - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { u32 hotplug_trigger = iir & BXT_DE_PORT_HOTPLUG_MASK; if (hotplug_trigger) { - bxt_hpd_irq_handler(dev_priv, hotplug_trigger); + bxt_hpd_irq_handler(display, hotplug_trigger); found = true; } - } else if (IS_BROADWELL(dev_priv)) { + } else if (display->platform.broadwell) { u32 hotplug_trigger = iir & BDW_DE_PORT_HOTPLUG_MASK; if (hotplug_trigger) { - ilk_hpd_irq_handler(dev_priv, hotplug_trigger); + ilk_hpd_irq_handler(display, hotplug_trigger); found = true; } } - if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) && + if ((display->platform.geminilake || display->platform.broxton) && (iir & BXT_DE_PORT_GMBUS)) { intel_gmbus_irq_handler(display); found = true; } - if (DISPLAY_VER(dev_priv) >= 11) { + if (DISPLAY_VER(display) >= 11) { u32 te_trigger = iir & (DSI0_TE | DSI1_TE); if (te_trigger) { - gen11_dsi_te_interrupt_handler(dev_priv, te_trigger); + gen11_dsi_te_interrupt_handler(display, te_trigger); found = true; } } if (!found) - drm_err_ratelimited(&dev_priv->drm, + drm_err_ratelimited(display->drm, "Unexpected DE Port interrupt\n"); } else { - drm_err_ratelimited(&dev_priv->drm, + drm_err_ratelimited(display->drm, "The master control interrupt lied (DE PORT)!\n"); } } - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { u32 fault_errors; if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe))) @@ -1449,7 +1428,7 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) iir = intel_de_read(display, GEN8_DE_PIPE_IIR(pipe)); if (!iir) { - drm_err_ratelimited(&dev_priv->drm, + drm_err_ratelimited(display->drm, "The master control interrupt lied (DE PIPE)!\n"); continue; } @@ -1457,29 +1436,29 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) intel_de_write(display, GEN8_DE_PIPE_IIR(pipe), iir); if (iir & GEN8_PIPE_VBLANK) - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); - if (iir & gen8_de_pipe_flip_done_mask(dev_priv)) - flip_done_handler(dev_priv, pipe); + if (iir & gen8_de_pipe_flip_done_mask(display)) + flip_done_handler(display, pipe); - if (HAS_DSB(dev_priv)) { + if (HAS_DSB(display)) { if (iir & GEN12_DSB_INT(INTEL_DSB_0)) - intel_dsb_irq_handler(&dev_priv->display, pipe, INTEL_DSB_0); + intel_dsb_irq_handler(display, pipe, INTEL_DSB_0); if (iir & GEN12_DSB_INT(INTEL_DSB_1)) - intel_dsb_irq_handler(&dev_priv->display, pipe, INTEL_DSB_1); + intel_dsb_irq_handler(display, pipe, INTEL_DSB_1); if (iir & GEN12_DSB_INT(INTEL_DSB_2)) - intel_dsb_irq_handler(&dev_priv->display, pipe, INTEL_DSB_2); + intel_dsb_irq_handler(display, pipe, INTEL_DSB_2); } if (iir & GEN8_PIPE_CDCLK_CRC_DONE) - hsw_pipe_crc_irq_handler(dev_priv, pipe); + hsw_pipe_crc_irq_handler(display, pipe); if (iir & GEN8_PIPE_FIFO_UNDERRUN) intel_cpu_fifo_underrun_irq_handler(display, pipe); - fault_errors = iir & gen8_de_pipe_fault_mask(dev_priv); + fault_errors = iir & gen8_de_pipe_fault_mask(display); if (fault_errors) intel_pipe_fault_irq_handler(display, gen8_pipe_fault_handlers(display), @@ -1495,31 +1474,30 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) * scheme also closed the SDE interrupt handling race we've seen * on older pch-split platforms. But this needs testing. */ - gen8_read_and_ack_pch_irqs(dev_priv, &iir, &pica_iir); + gen8_read_and_ack_pch_irqs(display, &iir, &pica_iir); if (iir) { if (pica_iir) - xelpdp_pica_irq_handler(dev_priv, pica_iir); + xelpdp_pica_irq_handler(display, pica_iir); if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) - icp_irq_handler(dev_priv, iir); + icp_irq_handler(display, iir); else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT) - spt_irq_handler(dev_priv, iir); + spt_irq_handler(display, iir); else - cpt_irq_handler(dev_priv, iir); + cpt_irq_handler(display, iir); } else { /* * Like on previous PCH there seems to be something * fishy going on with forwarding PCH interrupts. */ - drm_dbg(&dev_priv->drm, + drm_dbg(display->drm, "The master control interrupt lied (SDE)!\n"); } } } -u32 gen11_gu_misc_irq_ack(struct drm_i915_private *i915, const u32 master_ctl) +u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl) { - struct intel_display *display = &i915->display; u32 iir; if (!(master_ctl & GEN11_GU_MISC_IRQ)) @@ -1532,20 +1510,17 @@ u32 gen11_gu_misc_irq_ack(struct drm_i915_private *i915, const u32 master_ctl) return iir; } -void gen11_gu_misc_irq_handler(struct drm_i915_private *i915, const u32 iir) +void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir) { - struct intel_display *display = &i915->display; - if (iir & GEN11_GU_MISC_GSE) intel_opregion_asle_intr(display); } -void gen11_display_irq_handler(struct drm_i915_private *i915) +void gen11_display_irq_handler(struct intel_display *display) { - struct intel_display *display = &i915->display; u32 disp_ctl; - disable_rpm_wakeref_asserts(&i915->runtime_pm); + intel_display_rpm_assert_block(display); /* * GEN11_DISPLAY_INT_CTL has same format as GEN8_MASTER_IRQ * for the display related bits. @@ -1553,16 +1528,15 @@ void gen11_display_irq_handler(struct drm_i915_private *i915) disp_ctl = intel_de_read(display, GEN11_DISPLAY_INT_CTL); intel_de_write(display, GEN11_DISPLAY_INT_CTL, 0); - gen8_de_irq_handler(i915, disp_ctl); + gen8_de_irq_handler(display, disp_ctl); intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); - enable_rpm_wakeref_asserts(&i915->runtime_pm); + intel_display_rpm_assert_unblock(display); } -static void i915gm_irq_cstate_wa_enable(struct drm_i915_private *i915) +static void i915gm_irq_cstate_wa_enable(struct intel_display *display) { - struct intel_display *display = &i915->display; - lockdep_assert_held(&i915->drm.vblank_time_lock); + lockdep_assert_held(&display->drm->vblank_time_lock); /* * Vblank/CRC interrupts fail to wake the device up from C2+. @@ -1570,41 +1544,41 @@ static void i915gm_irq_cstate_wa_enable(struct drm_i915_private *i915) * the problem. There is a small power cost so we do this * only when vblank/CRC interrupts are actually enabled. */ - if (i915->display.irq.vblank_enabled++ == 0) + if (display->irq.vblank_enabled++ == 0) intel_de_write(display, SCPD0, _MASKED_BIT_ENABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); } -static void i915gm_irq_cstate_wa_disable(struct drm_i915_private *i915) +static void i915gm_irq_cstate_wa_disable(struct intel_display *display) { - struct intel_display *display = &i915->display; - lockdep_assert_held(&i915->drm.vblank_time_lock); + lockdep_assert_held(&display->drm->vblank_time_lock); - if (--i915->display.irq.vblank_enabled == 0) + if (--display->irq.vblank_enabled == 0) intel_de_write(display, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); } -void i915gm_irq_cstate_wa(struct drm_i915_private *i915, bool enable) +void i915gm_irq_cstate_wa(struct intel_display *display, bool enable) { - spin_lock_irq(&i915->drm.vblank_time_lock); + spin_lock_irq(&display->drm->vblank_time_lock); if (enable) - i915gm_irq_cstate_wa_enable(i915); + i915gm_irq_cstate_wa_enable(display); else - i915gm_irq_cstate_wa_disable(i915); + i915gm_irq_cstate_wa_disable(display); - spin_unlock_irq(&i915->drm.vblank_time_lock); + spin_unlock_irq(&display->drm->vblank_time_lock); } int i8xx_enable_vblank(struct drm_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc->dev); struct drm_i915_private *dev_priv = to_i915(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_STATUS); + i915_enable_pipestat(display, pipe, PIPE_VBLANK_INTERRUPT_STATUS); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); return 0; @@ -1612,41 +1586,43 @@ int i8xx_enable_vblank(struct drm_crtc *crtc) void i8xx_disable_vblank(struct drm_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc->dev); struct drm_i915_private *dev_priv = to_i915(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_STATUS); + i915_disable_pipestat(display, pipe, PIPE_VBLANK_INTERRUPT_STATUS); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } int i915gm_enable_vblank(struct drm_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(crtc->dev); + struct intel_display *display = to_intel_display(crtc->dev); - i915gm_irq_cstate_wa_enable(i915); + i915gm_irq_cstate_wa_enable(display); return i8xx_enable_vblank(crtc); } void i915gm_disable_vblank(struct drm_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(crtc->dev); + struct intel_display *display = to_intel_display(crtc->dev); i8xx_disable_vblank(crtc); - i915gm_irq_cstate_wa_disable(i915); + i915gm_irq_cstate_wa_disable(display); } int i965_enable_vblank(struct drm_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc->dev); struct drm_i915_private *dev_priv = to_i915(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_enable_pipestat(dev_priv, pipe, + i915_enable_pipestat(display, pipe, PIPE_START_VBLANK_INTERRUPT_STATUS); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); @@ -1655,32 +1631,34 @@ int i965_enable_vblank(struct drm_crtc *crtc) void i965_disable_vblank(struct drm_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc->dev); struct drm_i915_private *dev_priv = to_i915(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_disable_pipestat(dev_priv, pipe, + i915_disable_pipestat(display, pipe, PIPE_START_VBLANK_INTERRUPT_STATUS); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } int ilk_enable_vblank(struct drm_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc->dev); struct drm_i915_private *dev_priv = to_i915(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; - u32 bit = DISPLAY_VER(dev_priv) >= 7 ? + u32 bit = DISPLAY_VER(display) >= 7 ? DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe); spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - ilk_enable_display_irq(dev_priv, bit); + ilk_enable_display_irq(display, bit); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); /* Even though there is no DMC, frame counter can get stuck when * PSR is active as no frames are generated. */ - if (HAS_PSR(dev_priv)) + if (HAS_PSR(display)) drm_crtc_vblank_restore(crtc); return 0; @@ -1688,14 +1666,15 @@ int ilk_enable_vblank(struct drm_crtc *crtc) void ilk_disable_vblank(struct drm_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc->dev); struct drm_i915_private *dev_priv = to_i915(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; - u32 bit = DISPLAY_VER(dev_priv) >= 7 ? + u32 bit = DISPLAY_VER(display) >= 7 ? DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe); spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - ilk_disable_display_irq(dev_priv, bit); + ilk_disable_display_irq(display, bit); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } @@ -1753,13 +1732,13 @@ int bdw_enable_vblank(struct drm_crtc *_crtc) schedule_work(&display->irq.vblank_dc_work); spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK); + bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_VBLANK); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); /* Even if there is no DMC, frame counter can get stuck when * PSR is active as no frames are generated, so check only for PSR. */ - if (HAS_PSR(dev_priv)) + if (HAS_PSR(display)) drm_crtc_vblank_restore(&crtc->base); return 0; @@ -1777,7 +1756,7 @@ void bdw_disable_vblank(struct drm_crtc *_crtc) return; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK); + bdw_disable_pipe_irq(display, pipe, GEN8_PIPE_VBLANK); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); if (crtc->block_dc_for_vblank && --display->irq.vblank_wa_num_pipes == 0) @@ -1892,11 +1871,11 @@ void vlv_display_error_irq_handler(struct intel_display *display, vlv_page_table_error_irq_handler(display, dpinvgtt); } -static void _vlv_display_irq_reset(struct drm_i915_private *dev_priv) +static void _vlv_display_irq_reset(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) intel_de_write(display, DPINVGTT, DPINVGTT_STATUS_MASK_CHV); else intel_de_write(display, DPINVGTT, DPINVGTT_STATUS_MASK_VLV); @@ -1904,31 +1883,29 @@ static void _vlv_display_irq_reset(struct drm_i915_private *dev_priv) gen2_error_reset(to_intel_uncore(display->drm), VLV_ERROR_REGS); - i915_hotplug_interrupt_update_locked(dev_priv, 0xffffffff, 0); - intel_de_rmw(display, PORT_HOTPLUG_STAT(dev_priv), 0, 0); + i915_hotplug_interrupt_update_locked(display, 0xffffffff, 0); + intel_de_rmw(display, PORT_HOTPLUG_STAT(display), 0, 0); - i9xx_pipestat_irq_reset(dev_priv); + i9xx_pipestat_irq_reset(display); intel_display_irq_regs_reset(display, VLV_IRQ_REGS); dev_priv->irq_mask = ~0u; } -void vlv_display_irq_reset(struct drm_i915_private *dev_priv) +void vlv_display_irq_reset(struct intel_display *display) { - if (dev_priv->display.irq.vlv_display_irqs_enabled) - _vlv_display_irq_reset(dev_priv); + if (display->irq.vlv_display_irqs_enabled) + _vlv_display_irq_reset(display); } -void i9xx_display_irq_reset(struct drm_i915_private *i915) +void i9xx_display_irq_reset(struct intel_display *display) { - struct intel_display *display = &i915->display; - - if (I915_HAS_HOTPLUG(i915)) { - i915_hotplug_interrupt_update(i915, 0xffffffff, 0); - intel_de_rmw(display, PORT_HOTPLUG_STAT(i915), 0, 0); + if (HAS_HOTPLUG(display)) { + i915_hotplug_interrupt_update(display, 0xffffffff, 0); + intel_de_rmw(display, PORT_HOTPLUG_STAT(display), 0, 0); } - i9xx_pipestat_irq_reset(i915); + i9xx_pipestat_irq_reset(display); } static u32 vlv_error_mask(void) @@ -1937,17 +1914,17 @@ static u32 vlv_error_mask(void) return VLV_ERROR_PAGE_TABLE; } -void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) +void vlv_display_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 pipestat_mask; u32 enable_mask; enum pipe pipe; - if (!dev_priv->display.irq.vlv_display_irqs_enabled) + if (!display->irq.vlv_display_irqs_enabled) return; - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) intel_de_write(display, DPINVGTT, DPINVGTT_STATUS_MASK_CHV | DPINVGTT_EN_MASK_CHV); @@ -1961,9 +1938,9 @@ void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) pipestat_mask = PIPE_CRC_DONE_INTERRUPT_STATUS; - i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); - for_each_pipe(dev_priv, pipe) - i915_enable_pipestat(dev_priv, pipe, pipestat_mask); + i915_enable_pipestat(display, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); + for_each_pipe(display, pipe) + i915_enable_pipestat(display, pipe, pipestat_mask); enable_mask = I915_DISPLAY_PORT_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | @@ -1972,29 +1949,28 @@ void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) I915_LPE_PIPE_B_INTERRUPT | I915_MASTER_ERROR_INTERRUPT; - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) enable_mask |= I915_DISPLAY_PIPE_C_EVENT_INTERRUPT | I915_LPE_PIPE_C_INTERRUPT; - drm_WARN_ON(&dev_priv->drm, dev_priv->irq_mask != ~0u); + drm_WARN_ON(display->drm, dev_priv->irq_mask != ~0u); dev_priv->irq_mask = ~enable_mask; intel_display_irq_regs_init(display, VLV_IRQ_REGS, dev_priv->irq_mask, enable_mask); } -void gen8_display_irq_reset(struct drm_i915_private *dev_priv) +void gen8_display_irq_reset(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; intel_de_write(display, EDP_PSR_IMR, 0xffffffff); intel_de_write(display, EDP_PSR_IIR, 0xffffffff); - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) if (intel_display_power_is_enabled(display, POWER_DOMAIN_PIPE(pipe))) intel_display_irq_regs_reset(display, GEN8_DE_PIPE_IRQ_REGS(pipe)); @@ -2003,22 +1979,22 @@ void gen8_display_irq_reset(struct drm_i915_private *dev_priv) intel_display_irq_regs_reset(display, GEN8_DE_MISC_IRQ_REGS); } -void gen11_display_irq_reset(struct drm_i915_private *dev_priv) +void gen11_display_irq_reset(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe; u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C) | BIT(TRANSCODER_D); - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; intel_de_write(display, GEN11_DISPLAY_INT_CTL, 0); - if (DISPLAY_VER(dev_priv) >= 12) { + if (DISPLAY_VER(display) >= 12) { enum transcoder trans; - for_each_cpu_transcoder_masked(dev_priv, trans, trans_mask) { + for_each_cpu_transcoder_masked(display, trans, trans_mask) { enum intel_display_power_domain domain; domain = POWER_DOMAIN_TRANSCODER(trans); @@ -2026,10 +2002,10 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) continue; intel_de_write(display, - TRANS_PSR_IMR(dev_priv, trans), + TRANS_PSR_IMR(display, trans), 0xffffffff); intel_de_write(display, - TRANS_PSR_IIR(dev_priv, trans), + TRANS_PSR_IIR(display, trans), 0xffffffff); } } else { @@ -2037,7 +2013,7 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) intel_de_write(display, EDP_PSR_IIR, 0xffffffff); } - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) if (intel_display_power_is_enabled(display, POWER_DOMAIN_PIPE(pipe))) intel_display_irq_regs_reset(display, GEN8_DE_PIPE_IRQ_REGS(pipe)); @@ -2045,7 +2021,7 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) intel_display_irq_regs_reset(display, GEN8_DE_PORT_IRQ_REGS); intel_display_irq_regs_reset(display, GEN8_DE_MISC_IRQ_REGS); - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) intel_display_irq_regs_reset(display, PICAINTERRUPT_IRQ_REGS); else intel_display_irq_regs_reset(display, GEN11_DE_HPD_IRQ_REGS); @@ -2054,12 +2030,12 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) intel_display_irq_regs_reset(display, SDE_IRQ_REGS); } -void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, +void gen8_irq_power_well_post_enable(struct intel_display *display, u8 pipe_mask) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN | - gen8_de_pipe_flip_done_mask(dev_priv); + gen8_de_pipe_flip_done_mask(display); enum pipe pipe; spin_lock_irq(&dev_priv->irq_lock); @@ -2069,18 +2045,18 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, return; } - for_each_pipe_masked(dev_priv, pipe, pipe_mask) + for_each_pipe_masked(display, pipe, pipe_mask) intel_display_irq_regs_init(display, GEN8_DE_PIPE_IRQ_REGS(pipe), - dev_priv->display.irq.de_irq_mask[pipe], - ~dev_priv->display.irq.de_irq_mask[pipe] | extra_ier); + display->irq.de_irq_mask[pipe], + ~display->irq.de_irq_mask[pipe] | extra_ier); spin_unlock_irq(&dev_priv->irq_lock); } -void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, +void gen8_irq_power_well_pre_disable(struct intel_display *display, u8 pipe_mask) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe; spin_lock_irq(&dev_priv->irq_lock); @@ -2090,7 +2066,7 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, return; } - for_each_pipe_masked(dev_priv, pipe, pipe_mask) + for_each_pipe_masked(display, pipe, pipe_mask) intel_display_irq_regs_reset(display, GEN8_DE_PIPE_IRQ_REGS(pipe)); spin_unlock_irq(&dev_priv->irq_lock); @@ -2110,9 +2086,9 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, * to avoid races with the irq handler, assuming we have MSI. Shared legacy * interrupts could still race. */ -static void ibx_irq_postinstall(struct drm_i915_private *dev_priv) +static void ibx_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 mask; if (HAS_PCH_NOP(dev_priv)) @@ -2128,40 +2104,45 @@ static void ibx_irq_postinstall(struct drm_i915_private *dev_priv) intel_display_irq_regs_init(display, SDE_IRQ_REGS, ~mask, 0xffffffff); } -void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv) +void valleyview_enable_display_irqs(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + lockdep_assert_held(&dev_priv->irq_lock); - if (dev_priv->display.irq.vlv_display_irqs_enabled) + if (display->irq.vlv_display_irqs_enabled) return; - dev_priv->display.irq.vlv_display_irqs_enabled = true; + display->irq.vlv_display_irqs_enabled = true; if (intel_irqs_enabled(dev_priv)) { - _vlv_display_irq_reset(dev_priv); - vlv_display_irq_postinstall(dev_priv); + _vlv_display_irq_reset(display); + vlv_display_irq_postinstall(display); } } -void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv) +void valleyview_disable_display_irqs(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + lockdep_assert_held(&dev_priv->irq_lock); - if (!dev_priv->display.irq.vlv_display_irqs_enabled) + if (!display->irq.vlv_display_irqs_enabled) return; - dev_priv->display.irq.vlv_display_irqs_enabled = false; + display->irq.vlv_display_irqs_enabled = false; if (intel_irqs_enabled(dev_priv)) - _vlv_display_irq_reset(dev_priv); + _vlv_display_irq_reset(display); } -void ilk_de_irq_postinstall(struct drm_i915_private *i915) +void ilk_de_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &i915->display; + struct drm_i915_private *i915 = to_i915(display->drm); + u32 display_mask, extra_mask; - if (DISPLAY_VER(i915) >= 7) { + if (DISPLAY_VER(display) >= 7) { display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | DE_PCH_EVENT_IVB | DE_AUX_CHANNEL_A_IVB); extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | @@ -2182,59 +2163,59 @@ void ilk_de_irq_postinstall(struct drm_i915_private *i915) DE_DP_A_HOTPLUG); } - if (IS_HASWELL(i915)) { + if (display->platform.haswell) { intel_display_irq_regs_assert_irr_is_zero(display, EDP_PSR_IIR); display_mask |= DE_EDP_PSR_INT_HSW; } - if (IS_IRONLAKE_M(i915)) + if (display->platform.ironlake && display->platform.mobile) extra_mask |= DE_PCU_EVENT; i915->irq_mask = ~display_mask; - ibx_irq_postinstall(i915); + ibx_irq_postinstall(display); intel_display_irq_regs_init(display, DE_IRQ_REGS, i915->irq_mask, display_mask | extra_mask); } -static void mtp_irq_postinstall(struct drm_i915_private *i915); -static void icp_irq_postinstall(struct drm_i915_private *i915); +static void mtp_irq_postinstall(struct intel_display *display); +static void icp_irq_postinstall(struct intel_display *display); -void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) +void gen8_de_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); - u32 de_pipe_masked = gen8_de_pipe_fault_mask(dev_priv) | + u32 de_pipe_masked = gen8_de_pipe_fault_mask(display) | GEN8_PIPE_CDCLK_CRC_DONE; u32 de_pipe_enables; - u32 de_port_masked = gen8_de_port_aux_mask(dev_priv); + u32 de_port_masked = gen8_de_port_aux_mask(display); u32 de_port_enables; u32 de_misc_masked = GEN8_DE_EDP_PSR; u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C) | BIT(TRANSCODER_D); enum pipe pipe; - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; - if (DISPLAY_VER(dev_priv) >= 14) - mtp_irq_postinstall(dev_priv); + if (DISPLAY_VER(display) >= 14) + mtp_irq_postinstall(display); else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) - icp_irq_postinstall(dev_priv); + icp_irq_postinstall(display); else if (HAS_PCH_SPLIT(dev_priv)) - ibx_irq_postinstall(dev_priv); + ibx_irq_postinstall(display); - if (DISPLAY_VER(dev_priv) < 11) + if (DISPLAY_VER(display) < 11) de_misc_masked |= GEN8_DE_MISC_GSE; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) de_port_masked |= BXT_DE_PORT_GMBUS; - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { de_misc_masked |= XELPDP_PMDEMAND_RSPTOUT_ERR | XELPDP_PMDEMAND_RSP | XELPDP_RM_TIMEOUT; - } else if (DISPLAY_VER(dev_priv) >= 11) { + } else if (DISPLAY_VER(display) >= 11) { enum port port; if (intel_bios_is_dsi_present(display, &port)) @@ -2244,25 +2225,25 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) if (HAS_DBUF_OVERLAP_DETECTION(display)) de_misc_masked |= XE2LPD_DBUF_OVERLAP_DETECTED; - if (HAS_DSB(dev_priv)) + if (HAS_DSB(display)) de_pipe_masked |= GEN12_DSB_INT(INTEL_DSB_0) | GEN12_DSB_INT(INTEL_DSB_1) | GEN12_DSB_INT(INTEL_DSB_2); de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN | - gen8_de_pipe_flip_done_mask(dev_priv); + gen8_de_pipe_flip_done_mask(display); de_port_enables = de_port_masked; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) de_port_enables |= BXT_DE_PORT_HOTPLUG_MASK; - else if (IS_BROADWELL(dev_priv)) + else if (display->platform.broadwell) de_port_enables |= BDW_DE_PORT_HOTPLUG_MASK; - if (DISPLAY_VER(dev_priv) >= 12) { + if (DISPLAY_VER(display) >= 12) { enum transcoder trans; - for_each_cpu_transcoder_masked(dev_priv, trans, trans_mask) { + for_each_cpu_transcoder_masked(display, trans, trans_mask) { enum intel_display_power_domain domain; domain = POWER_DOMAIN_TRANSCODER(trans); @@ -2270,19 +2251,19 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) continue; intel_display_irq_regs_assert_irr_is_zero(display, - TRANS_PSR_IIR(dev_priv, trans)); + TRANS_PSR_IIR(display, trans)); } } else { intel_display_irq_regs_assert_irr_is_zero(display, EDP_PSR_IIR); } - for_each_pipe(dev_priv, pipe) { - dev_priv->display.irq.de_irq_mask[pipe] = ~de_pipe_masked; + for_each_pipe(display, pipe) { + display->irq.de_irq_mask[pipe] = ~de_pipe_masked; if (intel_display_power_is_enabled(display, POWER_DOMAIN_PIPE(pipe))) intel_display_irq_regs_init(display, GEN8_DE_PIPE_IRQ_REGS(pipe), - dev_priv->display.irq.de_irq_mask[pipe], + display->irq.de_irq_mask[pipe], de_pipe_enables); } @@ -2291,7 +2272,7 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) intel_display_irq_regs_init(display, GEN8_DE_MISC_IRQ_REGS, ~de_misc_masked, de_misc_masked); - if (IS_DISPLAY_VER(dev_priv, 11, 13)) { + if (IS_DISPLAY_VER(display, 11, 13)) { u32 de_hpd_masked = 0; u32 de_hpd_enables = GEN11_DE_TC_HOTPLUG_MASK | GEN11_DE_TBT_HOTPLUG_MASK; @@ -2301,9 +2282,8 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) } } -static void mtp_irq_postinstall(struct drm_i915_private *i915) +static void mtp_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &i915->display; u32 sde_mask = SDE_GMBUS_ICP | SDE_PICAINTERRUPT; u32 de_hpd_mask = XELPDP_AUX_TC_MASK; u32 de_hpd_enables = de_hpd_mask | XELPDP_DP_ALT_HOTPLUG_MASK | @@ -2315,43 +2295,37 @@ static void mtp_irq_postinstall(struct drm_i915_private *i915) intel_display_irq_regs_init(display, SDE_IRQ_REGS, ~sde_mask, 0xffffffff); } -static void icp_irq_postinstall(struct drm_i915_private *dev_priv) +static void icp_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; u32 mask = SDE_GMBUS_ICP; intel_display_irq_regs_init(display, SDE_IRQ_REGS, ~mask, 0xffffffff); } -void gen11_de_irq_postinstall(struct drm_i915_private *dev_priv) +void gen11_de_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; - - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; - gen8_de_irq_postinstall(dev_priv); + gen8_de_irq_postinstall(display); intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); } -void dg1_de_irq_postinstall(struct drm_i915_private *i915) +void dg1_de_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &i915->display; - - if (!HAS_DISPLAY(i915)) + if (!HAS_DISPLAY(display)) return; - gen8_de_irq_postinstall(i915); + gen8_de_irq_postinstall(display); intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); } -void intel_display_irq_init(struct drm_i915_private *i915) +void intel_display_irq_init(struct intel_display *display) { - i915->drm.vblank_disable_immediate = true; + display->drm->vblank_disable_immediate = true; - intel_hotplug_irq_init(i915); + intel_hotplug_irq_init(display); - INIT_WORK(&i915->display.irq.vblank_dc_work, - intel_display_vblank_dc_work); + INIT_WORK(&display->irq.vblank_dc_work, intel_display_vblank_dc_work); } diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index d9867cd0a220d0..f72727768351e6 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -12,28 +12,27 @@ enum pipe; struct drm_crtc; -struct drm_i915_private; struct intel_display; -void valleyview_enable_display_irqs(struct drm_i915_private *i915); -void valleyview_disable_display_irqs(struct drm_i915_private *i915); +void valleyview_enable_display_irqs(struct intel_display *display); +void valleyview_disable_display_irqs(struct intel_display *display); -void ilk_update_display_irq(struct drm_i915_private *i915, +void ilk_update_display_irq(struct intel_display *display, u32 interrupt_mask, u32 enabled_irq_mask); -void ilk_enable_display_irq(struct drm_i915_private *i915, u32 bits); -void ilk_disable_display_irq(struct drm_i915_private *i915, u32 bits); +void ilk_enable_display_irq(struct intel_display *display, u32 bits); +void ilk_disable_display_irq(struct intel_display *display, u32 bits); -void bdw_update_port_irq(struct drm_i915_private *i915, u32 interrupt_mask, u32 enabled_irq_mask); -void bdw_enable_pipe_irq(struct drm_i915_private *i915, enum pipe pipe, u32 bits); -void bdw_disable_pipe_irq(struct drm_i915_private *i915, enum pipe pipe, u32 bits); +void bdw_update_port_irq(struct intel_display *display, u32 interrupt_mask, u32 enabled_irq_mask); +void bdw_enable_pipe_irq(struct intel_display *display, enum pipe pipe, u32 bits); +void bdw_disable_pipe_irq(struct intel_display *display, enum pipe pipe, u32 bits); -void ibx_display_interrupt_update(struct drm_i915_private *i915, +void ibx_display_interrupt_update(struct intel_display *display, u32 interrupt_mask, u32 enabled_irq_mask); -void ibx_enable_display_interrupt(struct drm_i915_private *i915, u32 bits); -void ibx_disable_display_interrupt(struct drm_i915_private *i915, u32 bits); +void ibx_enable_display_interrupt(struct intel_display *display, u32 bits); +void ibx_disable_display_interrupt(struct intel_display *display, u32 bits); -void gen8_irq_power_well_post_enable(struct drm_i915_private *i915, u8 pipe_mask); -void gen8_irq_power_well_pre_disable(struct drm_i915_private *i915, u8 pipe_mask); +void gen8_irq_power_well_post_enable(struct intel_display *display, u8 pipe_mask); +void gen8_irq_power_well_pre_disable(struct intel_display *display, u8 pipe_mask); int i8xx_enable_vblank(struct drm_crtc *crtc); int i915gm_enable_vblank(struct drm_crtc *crtc); @@ -46,41 +45,41 @@ void i965_disable_vblank(struct drm_crtc *crtc); void ilk_disable_vblank(struct drm_crtc *crtc); void bdw_disable_vblank(struct drm_crtc *crtc); -void ivb_display_irq_handler(struct drm_i915_private *i915, u32 de_iir); -void ilk_display_irq_handler(struct drm_i915_private *i915, u32 de_iir); -void gen8_de_irq_handler(struct drm_i915_private *i915, u32 master_ctl); -void gen11_display_irq_handler(struct drm_i915_private *i915); +void ivb_display_irq_handler(struct intel_display *display, u32 de_iir); +void ilk_display_irq_handler(struct intel_display *display, u32 de_iir); +void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl); +void gen11_display_irq_handler(struct intel_display *display); -u32 gen11_gu_misc_irq_ack(struct drm_i915_private *i915, const u32 master_ctl); -void gen11_gu_misc_irq_handler(struct drm_i915_private *i915, const u32 iir); +u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl); +void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir); -void i9xx_display_irq_reset(struct drm_i915_private *i915); -void vlv_display_irq_reset(struct drm_i915_private *i915); -void gen8_display_irq_reset(struct drm_i915_private *i915); -void gen11_display_irq_reset(struct drm_i915_private *i915); +void i9xx_display_irq_reset(struct intel_display *display); +void vlv_display_irq_reset(struct intel_display *display); +void gen8_display_irq_reset(struct intel_display *display); +void gen11_display_irq_reset(struct intel_display *display); -void vlv_display_irq_postinstall(struct drm_i915_private *i915); -void ilk_de_irq_postinstall(struct drm_i915_private *i915); -void gen8_de_irq_postinstall(struct drm_i915_private *i915); -void gen11_de_irq_postinstall(struct drm_i915_private *i915); -void dg1_de_irq_postinstall(struct drm_i915_private *i915); +void vlv_display_irq_postinstall(struct intel_display *display); +void ilk_de_irq_postinstall(struct intel_display *display); +void gen8_de_irq_postinstall(struct intel_display *display); +void gen11_de_irq_postinstall(struct intel_display *display); +void dg1_de_irq_postinstall(struct intel_display *display); u32 i915_pipestat_enable_mask(struct intel_display *display, enum pipe pipe); -void i915_enable_pipestat(struct drm_i915_private *i915, enum pipe pipe, u32 status_mask); -void i915_disable_pipestat(struct drm_i915_private *i915, enum pipe pipe, u32 status_mask); -void i915_enable_asle_pipestat(struct drm_i915_private *i915); +void i915_enable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask); +void i915_disable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask); +void i915_enable_asle_pipestat(struct intel_display *display); -void i9xx_pipestat_irq_ack(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); +void i9xx_pipestat_irq_ack(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); -void i915_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); -void i965_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); -void valleyview_pipestat_irq_handler(struct drm_i915_private *i915, u32 pipe_stats[I915_MAX_PIPES]); +void i915_pipestat_irq_handler(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); +void i965_pipestat_irq_handler(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); +void valleyview_pipestat_irq_handler(struct intel_display *display, u32 pipe_stats[I915_MAX_PIPES]); void vlv_display_error_irq_ack(struct intel_display *display, u32 *eir, u32 *dpinvgtt); void vlv_display_error_irq_handler(struct intel_display *display, u32 eir, u32 dpinvgtt); -void intel_display_irq_init(struct drm_i915_private *i915); +void intel_display_irq_init(struct intel_display *display); -void i915gm_irq_cstate_wa(struct drm_i915_private *i915, bool enable); +void i915gm_irq_cstate_wa(struct intel_display *display, bool enable); #endif /* __INTEL_DISPLAY_IRQ_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index f7171e6932dc33..c78315eb44facf 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -16,6 +16,7 @@ #include "intel_display_power.h" #include "intel_display_power_map.h" #include "intel_display_power_well.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dmc.h" #include "intel_mchbar_regs.h" @@ -204,7 +205,7 @@ static bool __intel_display_power_is_enabled(struct intel_display *display, struct i915_power_well *power_well; bool is_enabled; - if (pm_runtime_suspended(display->drm->dev)) + if (intel_display_rpm_suspended(display)) return false; is_enabled = true; @@ -455,7 +456,6 @@ static bool intel_display_power_grab_async_put_ref(struct intel_display *display, enum intel_display_power_domain domain) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct intel_power_domain_mask async_put_mask; bool ret = false; @@ -473,8 +473,8 @@ intel_display_power_grab_async_put_ref(struct intel_display *display, goto out_verify; cancel_async_put_work(power_domains, false); - intel_runtime_pm_put_raw(&dev_priv->runtime_pm, - fetch_and_zero(&power_domains->async_put_wakeref)); + intel_display_rpm_put_raw(display, + fetch_and_zero(&power_domains->async_put_wakeref)); out_verify: verify_async_put_domains_state(power_domains); @@ -512,9 +512,10 @@ __intel_display_power_get_domain(struct intel_display *display, intel_wakeref_t intel_display_power_get(struct intel_display *display, enum intel_display_power_domain domain) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; - intel_wakeref_t wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + struct ref_tracker *wakeref; + + wakeref = intel_display_rpm_get(display); mutex_lock(&power_domains->lock); __intel_display_power_get_domain(display, domain); @@ -539,12 +540,11 @@ intel_wakeref_t intel_display_power_get_if_enabled(struct intel_display *display, enum intel_display_power_domain domain) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; bool is_enabled; - wakeref = intel_runtime_pm_get_if_in_use(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get_if_in_use(display); if (!wakeref) return NULL; @@ -560,7 +560,7 @@ intel_display_power_get_if_enabled(struct intel_display *display, mutex_unlock(&power_domains->lock); if (!is_enabled) { - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); wakeref = NULL; } @@ -623,12 +623,10 @@ release_async_put_domains(struct i915_power_domains *power_domains, struct intel_display *display = container_of(power_domains, struct intel_display, power.domains); - struct drm_i915_private *dev_priv = to_i915(display->drm); - struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; enum intel_display_power_domain domain; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; - wakeref = intel_runtime_pm_get_noresume(rpm); + wakeref = intel_display_rpm_get_noresume(display); for_each_power_domain(domain, mask) { /* Clear before put, so put's sanity check is happy. */ @@ -636,7 +634,7 @@ release_async_put_domains(struct i915_power_domains *power_domains, __intel_display_power_put_domain(display, domain); } - intel_runtime_pm_put(rpm, wakeref); + intel_display_rpm_put(display, wakeref); } static void @@ -644,11 +642,10 @@ intel_display_power_put_async_work(struct work_struct *work) { struct intel_display *display = container_of(work, struct intel_display, power.domains.async_put_work.work); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; - struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; - intel_wakeref_t new_work_wakeref = intel_runtime_pm_get_raw(rpm); - intel_wakeref_t old_work_wakeref = NULL; + struct ref_tracker *new_work_wakeref, *old_work_wakeref = NULL; + + new_work_wakeref = intel_display_rpm_get_raw(display); mutex_lock(&power_domains->lock); @@ -688,9 +685,9 @@ intel_display_power_put_async_work(struct work_struct *work) mutex_unlock(&power_domains->lock); if (old_work_wakeref) - intel_runtime_pm_put_raw(rpm, old_work_wakeref); + intel_display_rpm_put_raw(display, old_work_wakeref); if (new_work_wakeref) - intel_runtime_pm_put_raw(rpm, new_work_wakeref); + intel_display_rpm_put_raw(display, new_work_wakeref); } /** @@ -711,10 +708,10 @@ void __intel_display_power_put_async(struct intel_display *display, intel_wakeref_t wakeref, int delay_ms) { - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; - struct intel_runtime_pm *rpm = &i915->runtime_pm; - intel_wakeref_t work_wakeref = intel_runtime_pm_get_raw(rpm); + struct ref_tracker *work_wakeref; + + work_wakeref = intel_display_rpm_get_raw(display); delay_ms = delay_ms >= 0 ? delay_ms : 100; @@ -746,9 +743,9 @@ void __intel_display_power_put_async(struct intel_display *display, mutex_unlock(&power_domains->lock); if (work_wakeref) - intel_runtime_pm_put_raw(rpm, work_wakeref); + intel_display_rpm_put_raw(display, work_wakeref); - intel_runtime_pm_put(rpm, wakeref); + intel_display_rpm_put(display, wakeref); } /** @@ -765,7 +762,6 @@ void __intel_display_power_put_async(struct intel_display *display, */ void intel_display_power_flush_work(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct intel_power_domain_mask async_put_mask; intel_wakeref_t work_wakeref; @@ -786,7 +782,7 @@ void intel_display_power_flush_work(struct intel_display *display) mutex_unlock(&power_domains->lock); if (work_wakeref) - intel_runtime_pm_put_raw(&i915->runtime_pm, work_wakeref); + intel_display_rpm_put_raw(display, work_wakeref); } /** @@ -824,10 +820,8 @@ void intel_display_power_put(struct intel_display *display, enum intel_display_power_domain domain, intel_wakeref_t wakeref) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - __intel_display_power_put(display, domain); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); } #else /** @@ -846,10 +840,8 @@ void intel_display_power_put(struct intel_display *display, void intel_display_power_put_unchecked(struct intel_display *display, enum intel_display_power_domain domain) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - __intel_display_power_put(display, domain); - intel_runtime_pm_put_unchecked(&dev_priv->runtime_pm); + intel_display_rpm_put_unchecked(display); } #endif @@ -1381,18 +1373,18 @@ static void hsw_enable_pc8(struct intel_display *display) intel_de_rmw(display, SOUTH_DSPCLK_GATE_D, PCH_LP_PARTITION_LEVEL_DISABLE, 0); - lpt_disable_clkout_dp(dev_priv); + lpt_disable_clkout_dp(display); hsw_disable_lcpll(display, true, true); } static void hsw_disable_pc8(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); + struct drm_i915_private __maybe_unused *dev_priv = to_i915(display->drm); drm_dbg_kms(display->drm, "Disabling package C8+\n"); hsw_restore_lcpll(display); - intel_init_pch_refclk(dev_priv); + intel_init_pch_refclk(display); /* Many display registers don't survive PC8+ */ #ifdef I915 /* FIXME */ @@ -1979,7 +1971,6 @@ void intel_power_domains_init_hw(struct intel_display *display, bool resume) */ void intel_power_domains_driver_remove(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); intel_wakeref_t wakeref __maybe_unused = fetch_and_zero(&display->power.domains.init_wakeref); @@ -1993,7 +1984,7 @@ void intel_power_domains_driver_remove(struct intel_display *display) intel_power_domains_verify_state(display); /* Keep the power well enabled, but cancel its rpm wakeref. */ - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); } /** diff --git a/drivers/gpu/drm/i915/display/intel_display_power_map.c b/drivers/gpu/drm/i915/display/intel_display_power_map.c index e80e1fd611ca16..ab1163744bc595 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_map.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_map.c @@ -1696,6 +1696,7 @@ I915_DECL_PW_DOMAINS(xe3lpd_pwdoms_dc_off, XE3LPD_PW_C_POWER_DOMAINS, XE3LPD_PW_D_POWER_DOMAINS, POWER_DOMAIN_AUDIO_MMIO, + POWER_DOMAIN_AUDIO_PLAYBACK, POWER_DOMAIN_INIT); static const struct i915_power_well_desc xe3lpd_power_wells_dcoff[] = { diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index 8ec87ffd87d26f..b9b4359751cc3a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -13,6 +13,7 @@ #include "intel_de.h" #include "intel_display_irq.h" #include "intel_display_power_well.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dkl_phy.h" #include "intel_dkl_phy_regs.h" @@ -186,22 +187,18 @@ int intel_power_well_refcount(struct i915_power_well *power_well) static void hsw_power_well_post_enable(struct intel_display *display, u8 irq_pipe_mask, bool has_vga) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (has_vga) intel_vga_reset_io_mem(display); if (irq_pipe_mask) - gen8_irq_power_well_post_enable(dev_priv, irq_pipe_mask); + gen8_irq_power_well_post_enable(display, irq_pipe_mask); } static void hsw_power_well_pre_disable(struct intel_display *display, u8 irq_pipe_mask) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (irq_pipe_mask) - gen8_irq_power_well_pre_disable(dev_priv, irq_pipe_mask); + gen8_irq_power_well_pre_disable(display, irq_pipe_mask); } #define ICL_AUX_PW_TO_PHY(pw_idx) \ @@ -752,8 +749,9 @@ void gen9_sanitize_dc_state(struct intel_display *display) void gen9_set_dc_state(struct intel_display *display, u32 state) { struct i915_power_domains *power_domains = &display->power.domains; - u32 val; + bool dc6_was_enabled, enable_dc6; u32 mask; + u32 val; if (!HAS_DISPLAY(display)) return; @@ -772,11 +770,19 @@ void gen9_set_dc_state(struct intel_display *display, u32 state) drm_err(display->drm, "DC state mismatch (0x%x -> 0x%x)\n", power_domains->dc_state, val & mask); + enable_dc6 = state & DC_STATE_EN_UPTO_DC6; + dc6_was_enabled = val & DC_STATE_EN_UPTO_DC6; + if (!dc6_was_enabled && enable_dc6) + intel_dmc_update_dc6_allowed_count(display, true); + val &= ~mask; val |= state; gen9_write_dc_state(display, val); + if (!enable_dc6 && dc6_was_enabled) + intel_dmc_update_dc6_allowed_count(display, false); + power_domains->dc_state = val & mask; } @@ -816,7 +822,8 @@ static void assert_can_enable_dc5(struct intel_display *display) (intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_UPTO_DC5), "DC5 already programmed to be enabled.\n"); - assert_rpm_wakelock_held(&dev_priv->runtime_pm); + + assert_display_rpm_held(display); assert_dmc_loaded(display); } @@ -1226,7 +1233,7 @@ static void vlv_display_power_well_init(struct intel_display *display) vlv_init_display_clock_gating(display); spin_lock_irq(&dev_priv->irq_lock); - valleyview_enable_display_irqs(dev_priv); + valleyview_enable_display_irqs(display); spin_unlock_irq(&dev_priv->irq_lock); /* @@ -1236,8 +1243,8 @@ static void vlv_display_power_well_init(struct intel_display *display) if (display->power.domains.initializing) return; - intel_hpd_init(dev_priv); - intel_hpd_poll_disable(dev_priv); + intel_hpd_init(display); + intel_hpd_poll_disable(display); /* Re-enable the ADPA, if we have one */ for_each_intel_encoder(display->drm, encoder) { @@ -1255,7 +1262,7 @@ static void vlv_display_power_well_deinit(struct intel_display *display) struct drm_i915_private *dev_priv = to_i915(display->drm); spin_lock_irq(&dev_priv->irq_lock); - valleyview_disable_display_irqs(dev_priv); + valleyview_disable_display_irqs(display); spin_unlock_irq(&dev_priv->irq_lock); /* make sure we're done processing display irqs */ @@ -1265,7 +1272,7 @@ static void vlv_display_power_well_deinit(struct intel_display *display) /* Prevent us from re-enabling polling on accident in late suspend */ if (!display->drm->dev->power.is_suspended) - intel_hpd_poll_enable(dev_priv); + intel_hpd_poll_enable(display); } static void vlv_display_power_well_enable(struct intel_display *display, diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.c b/drivers/gpu/drm/i915/display/intel_display_reset.c index 1f2798404f2c94..1dbd3e841df337 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.c +++ b/drivers/gpu/drm/i915/display/intel_display_reset.c @@ -107,14 +107,14 @@ void intel_display_reset_finish(struct intel_display *display, bool test_only) intel_display_driver_init_hw(display); intel_clock_gating_init(i915); intel_cx0_pll_power_save_wa(display); - intel_hpd_init(i915); + intel_hpd_init(display); ret = __intel_display_driver_resume(display, state, ctx); if (ret) drm_err(display->drm, "Restoring old state failed with %i\n", ret); - intel_hpd_poll_disable(i915); + intel_hpd_poll_disable(display); } drm_atomic_state_put(state); diff --git a/drivers/gpu/drm/i915/display/intel_display_rpm.c b/drivers/gpu/drm/i915/display/intel_display_rpm.c new file mode 100644 index 00000000000000..48da67dd013618 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_display_rpm.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2025 Intel Corporation */ + +#include "i915_drv.h" +#include "intel_display_rpm.h" +#include "intel_runtime_pm.h" + +static struct intel_runtime_pm *display_to_rpm(struct intel_display *display) +{ + struct drm_i915_private *i915 = to_i915(display->drm); + + return &i915->runtime_pm; +} + +struct ref_tracker *intel_display_rpm_get_raw(struct intel_display *display) +{ + return intel_runtime_pm_get_raw(display_to_rpm(display)); +} + +void intel_display_rpm_put_raw(struct intel_display *display, struct ref_tracker *wakeref) +{ + intel_runtime_pm_put_raw(display_to_rpm(display), wakeref); +} + +struct ref_tracker *intel_display_rpm_get(struct intel_display *display) +{ + return intel_runtime_pm_get(display_to_rpm(display)); +} + +struct ref_tracker *intel_display_rpm_get_if_in_use(struct intel_display *display) +{ + return intel_runtime_pm_get_if_in_use(display_to_rpm(display)); +} + +struct ref_tracker *intel_display_rpm_get_noresume(struct intel_display *display) +{ + return intel_runtime_pm_get_noresume(display_to_rpm(display)); +} + +void intel_display_rpm_put(struct intel_display *display, struct ref_tracker *wakeref) +{ + intel_runtime_pm_put(display_to_rpm(display), wakeref); +} + +void intel_display_rpm_put_unchecked(struct intel_display *display) +{ + intel_runtime_pm_put_unchecked(display_to_rpm(display)); +} + +bool intel_display_rpm_suspended(struct intel_display *display) +{ + return intel_runtime_pm_suspended(display_to_rpm(display)); +} + +void assert_display_rpm_held(struct intel_display *display) +{ + assert_rpm_wakelock_held(display_to_rpm(display)); +} + +void intel_display_rpm_assert_block(struct intel_display *display) +{ + disable_rpm_wakeref_asserts(display_to_rpm(display)); +} + +void intel_display_rpm_assert_unblock(struct intel_display *display) +{ + enable_rpm_wakeref_asserts(display_to_rpm(display)); +} diff --git a/drivers/gpu/drm/i915/display/intel_display_rpm.h b/drivers/gpu/drm/i915/display/intel_display_rpm.h new file mode 100644 index 00000000000000..6ef48515f84bbd --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_display_rpm.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __INTEL_DISPLAY_RPM__ +#define __INTEL_DISPLAY_RPM__ + +#include + +struct intel_display; +struct ref_tracker; + +struct ref_tracker *intel_display_rpm_get(struct intel_display *display); +void intel_display_rpm_put(struct intel_display *display, struct ref_tracker *wakeref); + +#define __with_intel_display_rpm(__display, __wakeref) \ + for (struct ref_tracker *(__wakeref) = intel_display_rpm_get(__display); (__wakeref); \ + intel_display_rpm_put((__display), (__wakeref)), (__wakeref) = NULL) + +#define with_intel_display_rpm(__display) \ + __with_intel_display_rpm((__display), __UNIQUE_ID(wakeref)) + +/* Only for special cases. */ +bool intel_display_rpm_suspended(struct intel_display *display); + +void assert_display_rpm_held(struct intel_display *display); +void intel_display_rpm_assert_block(struct intel_display *display); +void intel_display_rpm_assert_unblock(struct intel_display *display); + +/* Only for display power implementation. */ +struct ref_tracker *intel_display_rpm_get_raw(struct intel_display *display); +void intel_display_rpm_put_raw(struct intel_display *display, struct ref_tracker *wakeref); + +struct ref_tracker *intel_display_rpm_get_if_in_use(struct intel_display *display); +struct ref_tracker *intel_display_rpm_get_noresume(struct intel_display *display); +void intel_display_rpm_put_unchecked(struct intel_display *display); + +#endif /* __INTEL_DISPLAY_RPM__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 99a6fd2900b9c6..94468a9d2e0d3a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -581,7 +581,7 @@ struct dpll { struct intel_atomic_state { struct drm_atomic_state base; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; struct __intel_global_objs_state *global_objs; int num_global_objs; @@ -1620,7 +1620,7 @@ struct intel_psr { bool sink_support; bool source_support; bool enabled; - bool paused; + int pause_counter; enum pipe pipe; enum transcoder transcoder; bool active; @@ -1658,7 +1658,6 @@ struct intel_dp { int link_rate; u8 lane_count; u8 sink_count; - bool link_trained; bool needs_modeset_retry; bool use_max_params; u8 dpcd[DP_RECEIVER_CAP_SIZE]; @@ -1683,6 +1682,7 @@ struct intel_dp { int common_rates[DP_MAX_SUPPORTED_RATES]; struct { /* TODO: move the rest of link specific fields to here */ + bool active; /* common rate,lane_count configs in bw order */ int num_configs; #define INTEL_DP_MAX_LANE_COUNT 4 @@ -1739,7 +1739,7 @@ struct intel_dp { struct { struct intel_dp_mst_encoder *stream_encoders[I915_MAX_PIPES]; struct drm_dp_mst_topology_mgr mgr; - int active_links; + int active_streams; } mst; u32 (*get_aux_clock_divider)(struct intel_dp *dp, int index); diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.c b/drivers/gpu/drm/i915/display/intel_display_wa.c index e5a8022db664b0..da429c33291426 100644 --- a/drivers/gpu/drm/i915/display/intel_display_wa.c +++ b/drivers/gpu/drm/i915/display/intel_display_wa.c @@ -3,38 +3,38 @@ * Copyright © 2023 Intel Corporation */ -#include "i915_drv.h" #include "i915_reg.h" #include "intel_de.h" +#include "intel_display_core.h" #include "intel_display_wa.h" -static void gen11_display_wa_apply(struct drm_i915_private *i915) +static void gen11_display_wa_apply(struct intel_display *display) { /* Wa_14010594013 */ - intel_de_rmw(i915, GEN8_CHICKEN_DCPR_1, 0, ICL_DELAY_PMRSP); + intel_de_rmw(display, GEN8_CHICKEN_DCPR_1, 0, ICL_DELAY_PMRSP); } -static void xe_d_display_wa_apply(struct drm_i915_private *i915) +static void xe_d_display_wa_apply(struct intel_display *display) { /* Wa_14013723622 */ - intel_de_rmw(i915, CLKREQ_POLICY, CLKREQ_POLICY_MEM_UP_OVRD, 0); + intel_de_rmw(display, CLKREQ_POLICY, CLKREQ_POLICY_MEM_UP_OVRD, 0); } -static void adlp_display_wa_apply(struct drm_i915_private *i915) +static void adlp_display_wa_apply(struct intel_display *display) { /* Wa_22011091694:adlp */ - intel_de_rmw(i915, GEN9_CLKGATE_DIS_5, 0, DPCE_GATING_DIS); + intel_de_rmw(display, GEN9_CLKGATE_DIS_5, 0, DPCE_GATING_DIS); /* Bspec/49189 Initialize Sequence */ - intel_de_rmw(i915, GEN8_CHICKEN_DCPR_1, DDI_CLOCK_REG_ACCESS, 0); + intel_de_rmw(display, GEN8_CHICKEN_DCPR_1, DDI_CLOCK_REG_ACCESS, 0); } -void intel_display_wa_apply(struct drm_i915_private *i915) +void intel_display_wa_apply(struct intel_display *display) { - if (IS_ALDERLAKE_P(i915)) - adlp_display_wa_apply(i915); - else if (DISPLAY_VER(i915) == 12) - xe_d_display_wa_apply(i915); - else if (DISPLAY_VER(i915) == 11) - gen11_display_wa_apply(i915); + if (display->platform.alderlake_p) + adlp_display_wa_apply(display); + else if (DISPLAY_VER(display) == 12) + xe_d_display_wa_apply(display); + else if (DISPLAY_VER(display) == 11) + gen11_display_wa_apply(display); } diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.h b/drivers/gpu/drm/i915/display/intel_display_wa.h index be644ab6ae0061..babd9d16603d33 100644 --- a/drivers/gpu/drm/i915/display/intel_display_wa.h +++ b/drivers/gpu/drm/i915/display/intel_display_wa.h @@ -8,14 +8,17 @@ #include -struct drm_i915_private; +struct intel_display; -void intel_display_wa_apply(struct drm_i915_private *i915); +void intel_display_wa_apply(struct intel_display *display); #ifdef I915 -static inline bool intel_display_needs_wa_16023588340(struct drm_i915_private *i915) { return false; } +static inline bool intel_display_needs_wa_16023588340(struct intel_display *display) +{ + return false; +} #else -bool intel_display_needs_wa_16023588340(struct drm_i915_private *i915); +bool intel_display_needs_wa_16023588340(struct intel_display *display); #endif #endif diff --git a/drivers/gpu/drm/i915/display/intel_dkl_phy.c b/drivers/gpu/drm/i915/display/intel_dkl_phy.c index 0813fb9b5823ff..dad7192132ad92 100644 --- a/drivers/gpu/drm/i915/display/intel_dkl_phy.c +++ b/drivers/gpu/drm/i915/display/intel_dkl_phy.c @@ -4,6 +4,7 @@ */ #include +#include #include "intel_de.h" #include "intel_display.h" diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index fa6944e55d9558..98f80a6c63e80c 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -28,6 +28,8 @@ #include "i915_drv.h" #include "i915_reg.h" #include "intel_de.h" +#include "intel_display_rpm.h" +#include "intel_display_power_well.h" #include "intel_dmc.h" #include "intel_dmc_regs.h" #include "intel_step.h" @@ -57,6 +59,10 @@ struct intel_dmc { const char *fw_path; u32 max_fw_size; /* bytes */ u32 version; + struct { + u32 dc5_start; + u32 count; + } dc6_allowed; struct dmc_fw_info { u32 mmio_count; i915_reg_t mmioaddr[20]; @@ -595,7 +601,7 @@ void intel_dmc_load_program(struct intel_display *display) disable_all_event_handlers(display); - assert_rpm_wakelock_held(&i915->runtime_pm); + assert_display_rpm_held(display); preempt_disable(); @@ -1232,18 +1238,57 @@ void intel_dmc_snapshot_print(const struct intel_dmc_snapshot *snapshot, struct DMC_VERSION_MINOR(snapshot->version)); } +void intel_dmc_update_dc6_allowed_count(struct intel_display *display, + bool start_tracking) +{ + struct intel_dmc *dmc = display_to_dmc(display); + u32 dc5_cur_count; + + if (DISPLAY_VER(dmc->display) < 14) + return; + + dc5_cur_count = intel_de_read(dmc->display, DG1_DMC_DEBUG_DC5_COUNT); + + if (!start_tracking) + dmc->dc6_allowed.count += dc5_cur_count - dmc->dc6_allowed.dc5_start; + + dmc->dc6_allowed.dc5_start = dc5_cur_count; +} + +static bool intel_dmc_get_dc6_allowed_count(struct intel_display *display, u32 *count) +{ + struct i915_power_domains *power_domains = &display->power.domains; + struct intel_dmc *dmc = display_to_dmc(display); + bool dc6_enabled; + + if (DISPLAY_VER(display) < 14) + return false; + + mutex_lock(&power_domains->lock); + dc6_enabled = intel_de_read(display, DC_STATE_EN) & + DC_STATE_EN_UPTO_DC6; + if (dc6_enabled) + intel_dmc_update_dc6_allowed_count(display, false); + + *count = dmc->dc6_allowed.count; + mutex_unlock(&power_domains->lock); + + return true; +} + static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) { struct intel_display *display = m->private; struct drm_i915_private *i915 = to_i915(display->drm); struct intel_dmc *dmc = display_to_dmc(display); - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; i915_reg_t dc5_reg, dc6_reg = INVALID_MMIO_REG; + u32 dc6_allowed_count; if (!HAS_DMC(display)) return -ENODEV; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); seq_printf(m, "DMC initialized: %s\n", str_yes_no(dmc)); seq_printf(m, "fw loaded: %s\n", @@ -1287,7 +1332,11 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) } seq_printf(m, "DC3 -> DC5 count: %d\n", intel_de_read(display, dc5_reg)); - if (i915_mmio_reg_valid(dc6_reg)) + + if (intel_dmc_get_dc6_allowed_count(display, &dc6_allowed_count)) + seq_printf(m, "DC5 -> DC6 allowed count: %d\n", + dc6_allowed_count); + else if (i915_mmio_reg_valid(dc6_reg)) seq_printf(m, "DC5 -> DC6 count: %d\n", intel_de_read(display, dc6_reg)); @@ -1299,7 +1348,7 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) intel_de_read(display, DMC_SSP_BASE)); seq_printf(m, "htp: 0x%08x\n", intel_de_read(display, DMC_HTP_SKL)); - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h index 44cecef98e7363..c78426eb4cd5a0 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.h +++ b/drivers/gpu/drm/i915/display/intel_dmc.h @@ -26,6 +26,7 @@ void intel_dmc_debugfs_register(struct intel_display *display); struct intel_dmc_snapshot *intel_dmc_snapshot_capture(struct intel_display *display); void intel_dmc_snapshot_print(const struct intel_dmc_snapshot *snapshot, struct drm_printer *p); +void intel_dmc_update_dc6_allowed_count(struct intel_display *display, bool start_tracking); void assert_dmc_loaded(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index a236b5fc7a3d7b..aeb14a5455fd1d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -62,6 +62,7 @@ #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dp.h" #include "intel_dp_aux.h" @@ -87,7 +88,6 @@ #include "intel_pfit.h" #include "intel_pps.h" #include "intel_psr.h" -#include "intel_runtime_pm.h" #include "intel_quirks.h" #include "intel_tc.h" #include "intel_vdsc.h" @@ -172,10 +172,28 @@ int intel_dp_link_symbol_clock(int rate) static int max_dprx_rate(struct intel_dp *intel_dp) { + struct intel_display *display = to_intel_display(intel_dp); + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + int max_rate; + if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp)) - return drm_dp_tunnel_max_dprx_rate(intel_dp->tunnel); + max_rate = drm_dp_tunnel_max_dprx_rate(intel_dp->tunnel); + else + max_rate = drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]); + + /* + * Some broken eDP sinks illegally declare support for + * HBR3 without TPS4, and are unable to produce a stable + * output. Reject HBR3 when TPS4 is not available. + */ + if (max_rate >= 810000 && !drm_dp_tps4_supported(intel_dp->dpcd)) { + drm_dbg_kms(display->drm, + "[ENCODER:%d:%s] Rejecting HBR3 due to missing TPS4 support\n", + encoder->base.base.id, encoder->base.name); + max_rate = 540000; + } - return drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]); + return max_rate; } static int max_dprx_lane_count(struct intel_dp *intel_dp) @@ -3204,7 +3222,7 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp, int link_rate, int lane_count) { memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set)); - intel_dp->link_trained = false; + intel_dp->link.active = false; intel_dp->needs_modeset_retry = false; intel_dp->link_rate = link_rate; intel_dp->lane_count = lane_count; @@ -3568,7 +3586,7 @@ void intel_dp_sync_state(struct intel_encoder *encoder, if (crtc_state) { intel_dp_reset_link_params(intel_dp); intel_dp_set_link_params(intel_dp, crtc_state->port_clock, crtc_state->lane_count); - intel_dp->link_trained = true; + intel_dp->link.active = true; } } @@ -4170,6 +4188,9 @@ static void intel_edp_mso_init(struct intel_dp *intel_dp) static void intel_edp_set_sink_rates(struct intel_dp *intel_dp) { + struct intel_display *display = to_intel_display(intel_dp); + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + intel_dp->num_sink_rates = 0; if (intel_dp->edp_dpcd[0] >= DP_EDP_14) { @@ -4180,10 +4201,7 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp) sink_rates, sizeof(sink_rates)); for (i = 0; i < ARRAY_SIZE(sink_rates); i++) { - int val = le16_to_cpu(sink_rates[i]); - - if (val == 0) - break; + int rate; /* Value read multiplied by 200kHz gives the per-lane * link rate in kHz. The source rates are, however, @@ -4191,7 +4209,24 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp) * back to symbols is * (val * 200kHz)*(8/10 ch. encoding)*(1/8 bit to Byte) */ - intel_dp->sink_rates[i] = (val * 200) / 10; + rate = le16_to_cpu(sink_rates[i]) * 200 / 10; + + if (rate == 0) + break; + + /* + * Some broken eDP sinks illegally declare support for + * HBR3 without TPS4, and are unable to produce a stable + * output. Reject HBR3 when TPS4 is not available. + */ + if (rate >= 810000 && !drm_dp_tps4_supported(intel_dp->dpcd)) { + drm_dbg_kms(display->drm, + "[ENCODER:%d:%s] Rejecting HBR3 due to missing TPS4 support\n", + encoder->base.base.id, encoder->base.name); + break; + } + + intel_dp->sink_rates[i] = rate; } intel_dp->num_sink_rates = i; } @@ -4969,8 +5004,6 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) bool link_ok = true; bool reprobe_needed = false; - drm_WARN_ON_ONCE(display->drm, intel_dp->mst.active_links < 0); - for (;;) { u8 esi[4] = {}; u8 ack[4] = {}; @@ -4985,7 +5018,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) drm_dbg_kms(display->drm, "DPRX ESI: %4ph\n", esi); - if (intel_dp->mst.active_links > 0 && link_ok && + if (intel_dp_mst_active_streams(intel_dp) > 0 && link_ok && esi[3] & LINK_STATUS_CHANGED) { if (!intel_dp_mst_link_status(intel_dp)) link_ok = false; @@ -5046,7 +5079,7 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp) { u8 link_status[DP_LINK_STATUS_SIZE]; - if (!intel_dp->link_trained) + if (!intel_dp->link.active) return false; /* @@ -6117,7 +6150,7 @@ static void intel_dp_oob_hotplug_event(struct drm_connector *connector, spin_unlock_irq(&i915->irq_lock); if (need_work) - intel_hpd_schedule_detection(i915); + intel_hpd_schedule_detection(display); } static const struct drm_connector_funcs intel_dp_connector_funcs = { @@ -6144,13 +6177,12 @@ enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd) { struct intel_display *display = to_intel_display(dig_port); - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_dp *intel_dp = &dig_port->dp; u8 dpcd[DP_RECEIVER_CAP_SIZE]; if (dig_port->base.type == INTEL_OUTPUT_EDP && (long_hpd || - intel_runtime_pm_suspended(&i915->runtime_pm) || + intel_display_rpm_suspended(display) || !intel_pps_have_panel_power_or_vdd(intel_dp))) { /* * vdd off can generate a long/short pulse on eDP which @@ -6326,7 +6358,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, * eDP and LVDS bail out early in this case to prevent interfering * with an already powered-on LVDS power sequencer. */ - if (intel_get_lvds_encoder(dev_priv)) { + if (intel_get_lvds_encoder(display)) { drm_WARN_ON(display->drm, !(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv))); drm_info(display->drm, diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c index ec27bbd70bcf01..0496061203fbfe 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c @@ -247,7 +247,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, u32 aux_clock_divider; enum intel_display_power_domain aux_domain; intel_wakeref_t aux_wakeref; - intel_wakeref_t pps_wakeref; + intel_wakeref_t pps_wakeref = NULL; int i, ret, recv_bytes; int try, clock = 0; u32 status; @@ -272,7 +272,20 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, aux_domain = intel_aux_power_domain(dig_port); aux_wakeref = intel_display_power_get(display, aux_domain); - pps_wakeref = intel_pps_lock(intel_dp); + + /* + * The PPS state needs to be locked for: + * - eDP on all platforms, since AUX transfers on eDP need VDD power + * (either forced or via panel power) which depends on the PPS + * state. + * - non-eDP on platforms where the PPS is a pipe instance (VLV/CHV), + * since changing the PPS state (via a parallel modeset for + * instance) may interfere with the AUX transfers on a non-eDP + * output as well. + */ + if (intel_dp_is_edp(intel_dp) || + display->platform.valleyview || display->platform.cherryview) + pps_wakeref = intel_pps_lock(intel_dp); /* * We will be called with VDD already enabled for dpcd/edid/oui reads. @@ -430,7 +443,9 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, if (vdd) intel_pps_vdd_off_unlocked(intel_dp, false); - intel_pps_unlock(intel_dp, pps_wakeref); + if (pps_wakeref) + intel_pps_unlock(intel_dp, pps_wakeref); + intel_display_power_put_async(display, aux_domain, aux_wakeref); out_unlock: intel_digital_port_unlock(encoder); diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 2966f5b3939220..a479b63112eab3 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -56,6 +56,8 @@ lt_dbg(_intel_dp, _dp_phy, "Sink disconnected: " _format, ## __VA_ARGS__); \ } while (0) +#define MAX_SEQ_TRAIN_FAILURES 2 + static void intel_dp_reset_lttpr_common_caps(struct intel_dp *intel_dp) { memset(intel_dp->lttpr_common_caps, 0, sizeof(intel_dp->lttpr_common_caps)); @@ -164,7 +166,7 @@ static int intel_dp_init_lttpr_phys(struct intel_dp *intel_dp, const u8 dpcd[DP_ * resetting its internal state when the mode is changed from * non-transparent to transparent. */ - if (intel_dp->link_trained) { + if (intel_dp->link.active) { if (lttpr_count < 0 || intel_dp_lttpr_transparent_mode_enabled(intel_dp)) goto out_reset_lttpr_count; @@ -711,8 +713,21 @@ void intel_dp_link_training_set_mode(struct intel_dp *intel_dp, int link_rate, b static void intel_dp_update_downspread_ctrl(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + /* + * Currently, we set the MSA ignore bit based on vrr.in_range. + * We can't really read that out during driver load since we don't have + * the connector information read in yet. So if we do end up doing a + * modeset during initial_commit() we'll clear the MSA ignore bit. + * GOP likely wouldn't have set this bit so after the initial commit, + * if there are no modesets and we enable VRR mode seamlessly + * (without a full modeset), the MSA ignore bit might never get set. + * + * #TODO: Implement readout of vrr.in_range. + * We need fastset support for setting the MSA ignore bit in DPCD, + * especially on the first real commit when clearing the inherited flag. + */ intel_dp_link_training_set_mode(intel_dp, - crtc_state->port_clock, crtc_state->vrr.flipline); + crtc_state->port_clock, crtc_state->vrr.in_range); } void intel_dp_link_training_set_bw(struct intel_dp *intel_dp, @@ -1110,7 +1125,10 @@ intel_dp_128b132b_intra_hop(struct intel_dp *intel_dp, void intel_dp_stop_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { - intel_dp->link_trained = true; + struct intel_display *display = to_intel_display(intel_dp); + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + + intel_dp->link.active = true; intel_dp_disable_dpcd_training_pattern(intel_dp, DP_PHY_DPRX); intel_dp_program_link_training_pattern(intel_dp, crtc_state, DP_PHY_DPRX, @@ -1120,6 +1138,15 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp, wait_for(intel_dp_128b132b_intra_hop(intel_dp, crtc_state) == 0, 500)) { lt_dbg(intel_dp, DP_PHY_DPRX, "128b/132b intra-hop not clearing\n"); } + + intel_hpd_unblock(encoder); + + if (!display->hotplug.ignore_long_hpd && + intel_dp->link.seq_train_failures < MAX_SEQ_TRAIN_FAILURES) { + int delay_ms = intel_dp->link.seq_train_failures ? 0 : 2000; + + intel_encoder_link_check_queue_work(encoder, delay_ms); + } } static bool @@ -1602,7 +1629,11 @@ void intel_dp_start_link_train(struct intel_atomic_state *state, * non-transparent mode. During an earlier LTTPR detection this * could've been prevented by an active link. */ - int lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp); + int lttpr_count; + + intel_hpd_block(encoder); + + lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp); if (lttpr_count < 0) /* Still continue with enabling the port and link training. */ @@ -1620,7 +1651,6 @@ void intel_dp_start_link_train(struct intel_atomic_state *state, lt_dbg(intel_dp, DP_PHY_DPRX, "Forcing link training failure\n"); } else if (passed) { intel_dp->link.seq_train_failures = 0; - intel_encoder_link_check_queue_work(encoder, 2000); return; } @@ -1643,10 +1673,8 @@ void intel_dp_start_link_train(struct intel_atomic_state *state, return; } - if (intel_dp->link.seq_train_failures < 2) { - intel_encoder_link_check_queue_work(encoder, 0); + if (intel_dp->link.seq_train_failures < MAX_SEQ_TRAIN_FAILURES) return; - } if (intel_dp_schedule_fallback_link_training(state, intel_dp, crtc_state)) return; @@ -1693,7 +1721,7 @@ static int i915_dp_force_link_rate_show(struct seq_file *m, void *data) if (err) return err; - if (intel_dp->link_trained) + if (intel_dp->link.active) current_rate = intel_dp->link_rate; force_rate = intel_dp->link.force_rate; @@ -1791,7 +1819,7 @@ static int i915_dp_force_lane_count_show(struct seq_file *m, void *data) if (err) return err; - if (intel_dp->link_trained) + if (intel_dp->link.active) current_lane_count = intel_dp->lane_count; force_lane_count = intel_dp->link.force_lane_count; diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 02f95108c63799..4c15dcb103aa2e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -52,6 +52,7 @@ #include "intel_pfit.h" #include "intel_psr.h" #include "intel_vdsc.h" +#include "intel_vrr.h" #include "skl_scaler.h" /* @@ -104,6 +105,34 @@ static struct intel_dp *to_primary_dp(struct intel_encoder *encoder) return &dig_port->dp; } +int intel_dp_mst_active_streams(struct intel_dp *intel_dp) +{ + return intel_dp->mst.active_streams; +} + +static bool intel_dp_mst_dec_active_streams(struct intel_dp *intel_dp) +{ + struct intel_display *display = to_intel_display(intel_dp); + + drm_dbg_kms(display->drm, "active MST streams %d -> %d\n", + intel_dp->mst.active_streams, intel_dp->mst.active_streams - 1); + + if (drm_WARN_ON(display->drm, intel_dp->mst.active_streams == 0)) + return true; + + return --intel_dp->mst.active_streams == 0; +} + +static bool intel_dp_mst_inc_active_streams(struct intel_dp *intel_dp) +{ + struct intel_display *display = to_intel_display(intel_dp); + + drm_dbg_kms(display->drm, "active MST streams %d -> %d\n", + intel_dp->mst.active_streams, intel_dp->mst.active_streams + 1); + + return intel_dp->mst.active_streams++ == 0; +} + static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state, bool dsc) { @@ -710,6 +739,8 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, pipe_config->lane_lat_optim_mask = bxt_dpio_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); + intel_vrr_compute_config(pipe_config, conn_state); + intel_dp_audio_compute_config(encoder, pipe_config, conn_state); intel_ddi_compute_min_voltage_level(pipe_config); @@ -997,11 +1028,8 @@ static void mst_stream_disable(struct intel_atomic_state *state, to_intel_connector(old_conn_state->connector); enum transcoder trans = old_crtc_state->cpu_transcoder; - drm_dbg_kms(display->drm, "active links %d\n", - intel_dp->mst.active_links); - - if (intel_dp->mst.active_links == 1) - intel_dp->link_trained = false; + if (intel_dp_mst_active_streams(intel_dp) == 1) + intel_dp->link.active = false; intel_hdcp_disable(intel_mst->connector); @@ -1034,8 +1062,8 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, bool last_mst_stream; int i; - intel_dp->mst.active_links--; - last_mst_stream = intel_dp->mst.active_links == 0; + last_mst_stream = intel_dp_mst_dec_active_streams(intel_dp); + drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 12 && last_mst_stream && !intel_dp_mst_is_master_trans(old_crtc_state)); @@ -1062,6 +1090,8 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, drm_dp_remove_payload_part2(&intel_dp->mst.mgr, new_mst_state, old_payload, new_payload); + intel_vrr_transcoder_disable(old_crtc_state); + intel_ddi_disable_transcoder_func(old_crtc_state); for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { @@ -1104,8 +1134,6 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, primary_encoder->post_disable(state, primary_encoder, old_crtc_state, NULL); - drm_dbg_kms(display->drm, "active links %d\n", - intel_dp->mst.active_links); } static void mst_stream_post_pll_disable(struct intel_atomic_state *state, @@ -1116,7 +1144,7 @@ static void mst_stream_post_pll_disable(struct intel_atomic_state *state, struct intel_encoder *primary_encoder = to_primary_encoder(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); - if (intel_dp->mst.active_links == 0 && + if (intel_dp_mst_active_streams(intel_dp) == 0 && primary_encoder->post_pll_disable) primary_encoder->post_pll_disable(state, primary_encoder, old_crtc_state, old_conn_state); } @@ -1129,7 +1157,7 @@ static void mst_stream_pre_pll_enable(struct intel_atomic_state *state, struct intel_encoder *primary_encoder = to_primary_encoder(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); - if (intel_dp->mst.active_links == 0) + if (intel_dp_mst_active_streams(intel_dp) == 0) primary_encoder->pre_pll_enable(state, primary_encoder, pipe_config, NULL); else @@ -1189,13 +1217,11 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state, */ connector->encoder = encoder; intel_mst->connector = connector; - first_mst_stream = intel_dp->mst.active_links == 0; + + first_mst_stream = intel_dp_mst_inc_active_streams(intel_dp); drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 12 && first_mst_stream && !intel_dp_mst_is_master_trans(pipe_config)); - drm_dbg_kms(display->drm, "active links %d\n", - intel_dp->mst.active_links); - if (first_mst_stream) intel_dp_set_power(intel_dp, DP_SET_POWER_D0); @@ -1210,8 +1236,6 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state, intel_mst_reprobe_topology(intel_dp, pipe_config); } - intel_dp->mst.active_links++; - ret = drm_dp_add_payload_part1(&intel_dp->mst.mgr, mst_state, drm_atomic_get_mst_payload_state(mst_state, connector->mst.port)); if (ret < 0) @@ -1279,7 +1303,7 @@ static void mst_stream_enable(struct intel_atomic_state *state, struct drm_dp_mst_topology_state *mst_state = drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst.mgr); enum transcoder trans = pipe_config->cpu_transcoder; - bool first_mst_stream = intel_dp->mst.active_links == 1; + bool first_mst_stream = intel_dp_mst_active_streams(intel_dp) == 1; struct intel_crtc *pipe_crtc; int ret, i, min_hblank; @@ -1323,14 +1347,13 @@ static void mst_stream_enable(struct intel_atomic_state *state, intel_ddi_enable_transcoder_func(encoder, pipe_config); + intel_vrr_transcoder_enable(pipe_config); + intel_ddi_clear_act_sent(encoder, pipe_config); intel_de_rmw(display, TRANS_DDI_FUNC_CTL(display, trans), 0, TRANS_DDI_DP_VC_PAYLOAD_ALLOC); - drm_dbg_kms(display->drm, "active links %d\n", - intel_dp->mst.active_links); - intel_ddi_wait_for_act_sent(encoder, pipe_config); drm_dp_check_act_status(&intel_dp->mst.mgr); @@ -1869,12 +1892,6 @@ mst_stream_encoders_create(struct intel_digital_port *dig_port) return true; } -int -intel_dp_mst_encoder_active_links(struct intel_digital_port *dig_port) -{ - return dig_port->dp.mst.active_links; -} - int intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id) { @@ -2101,7 +2118,7 @@ void intel_dp_mst_prepare_probe(struct intel_dp *intel_dp) u8 rate_select; u8 link_bw; - if (intel_dp->link_trained) + if (intel_dp->link.active) return; if (intel_mst_probed_link_params_valid(intel_dp, link_rate, lane_count)) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h b/drivers/gpu/drm/i915/display/intel_dp_mst.h index c1bbfeb02ca9e7..ab09b487c6bb5e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h @@ -18,7 +18,7 @@ struct intel_link_bw_limits; int intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_id); void intel_dp_mst_encoder_cleanup(struct intel_digital_port *dig_port); -int intel_dp_mst_encoder_active_links(struct intel_digital_port *dig_port); +int intel_dp_mst_active_streams(struct intel_dp *intel_dp); bool intel_dp_mst_is_master_trans(const struct intel_crtc_state *crtc_state); bool intel_dp_mst_is_slave_trans(const struct intel_crtc_state *crtc_state); bool intel_dp_mst_source_support(struct intel_dp *intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 08a30e5aafcee0..0481b1365b8521 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -373,14 +373,15 @@ int chv_calc_dpll_params(int refclk, struct dpll *clock) static int i9xx_pll_refclk(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; if ((hw_state->dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) - return i915->display.vbt.lvds_ssc_freq; + return display->vbt.lvds_ssc_freq; else if (HAS_PCH_SPLIT(i915)) return 120000; - else if (DISPLAY_VER(i915) != 2) + else if (DISPLAY_VER(display) != 2) return 96000; else return 48000; @@ -389,27 +390,27 @@ static int i9xx_pll_refclk(const struct intel_crtc_state *crtc_state) void i9xx_dpll_get_hw_state(struct intel_crtc *crtc, struct intel_dpll_hw_state *dpll_hw_state) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct i9xx_dpll_hw_state *hw_state = &dpll_hw_state->i9xx; - if (DISPLAY_VER(dev_priv) >= 4) { + if (DISPLAY_VER(display) >= 4) { u32 tmp; /* No way to read it out on pipes B and C */ - if (IS_CHERRYVIEW(dev_priv) && crtc->pipe != PIPE_A) - tmp = dev_priv->display.state.chv_dpll_md[crtc->pipe]; + if (display->platform.cherryview && crtc->pipe != PIPE_A) + tmp = display->state.chv_dpll_md[crtc->pipe]; else - tmp = intel_de_read(dev_priv, - DPLL_MD(dev_priv, crtc->pipe)); + tmp = intel_de_read(display, + DPLL_MD(display, crtc->pipe)); hw_state->dpll_md = tmp; } - hw_state->dpll = intel_de_read(dev_priv, DPLL(dev_priv, crtc->pipe)); + hw_state->dpll = intel_de_read(display, DPLL(display, crtc->pipe)); - if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) { - hw_state->fp0 = intel_de_read(dev_priv, FP0(crtc->pipe)); - hw_state->fp1 = intel_de_read(dev_priv, FP1(crtc->pipe)); + if (!display->platform.valleyview && !display->platform.cherryview) { + hw_state->fp0 = intel_de_read(display, FP0(crtc->pipe)); + hw_state->fp1 = intel_de_read(display, FP1(crtc->pipe)); } else { /* Mask out read-only status bits. */ hw_state->dpll &= ~(DPLL_LOCK_VLV | @@ -421,8 +422,8 @@ void i9xx_dpll_get_hw_state(struct intel_crtc *crtc, /* Returns the clock of the currently programmed mode of the given pipe. */ void i9xx_crtc_clock_get(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; u32 dpll = hw_state->dpll; u32 fp; @@ -436,7 +437,7 @@ void i9xx_crtc_clock_get(struct intel_crtc_state *crtc_state) fp = hw_state->fp1; clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; - if (IS_PINEVIEW(dev_priv)) { + if (display->platform.pineview) { clock.n = ffs((fp & FP_N_PINEVIEW_DIV_MASK) >> FP_N_DIV_SHIFT) - 1; clock.m2 = (fp & FP_M2_PINEVIEW_DIV_MASK) >> FP_M2_DIV_SHIFT; } else { @@ -444,8 +445,8 @@ void i9xx_crtc_clock_get(struct intel_crtc_state *crtc_state) clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; } - if (DISPLAY_VER(dev_priv) != 2) { - if (IS_PINEVIEW(dev_priv)) + if (DISPLAY_VER(display) != 2) { + if (display->platform.pineview) clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW) >> DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW); else @@ -462,23 +463,23 @@ void i9xx_crtc_clock_get(struct intel_crtc_state *crtc_state) 7 : 14; break; default: - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Unknown DPLL mode %08x in programmed " "mode\n", (int)(dpll & DPLL_MODE_MASK)); return; } - if (IS_PINEVIEW(dev_priv)) + if (display->platform.pineview) port_clock = pnv_calc_dpll_params(refclk, &clock); else port_clock = i9xx_calc_dpll_params(refclk, &clock); } else { enum pipe lvds_pipe; - if (IS_I85X(dev_priv) && - intel_lvds_port_enabled(dev_priv, LVDS, &lvds_pipe) && + if (display->platform.i85x && + intel_lvds_port_enabled(display, LVDS, &lvds_pipe) && lvds_pipe == crtc->pipe) { - u32 lvds = intel_de_read(dev_priv, LVDS); + u32 lvds = intel_de_read(display, LVDS); clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> DPLL_FPA01_P1_POST_DIV_SHIFT); @@ -577,7 +578,7 @@ void chv_crtc_clock_get(struct intel_crtc_state *crtc_state) * Returns whether the given set of divisors are valid for a given refclk with * the given connectors. */ -static bool intel_pll_is_valid(struct drm_i915_private *dev_priv, +static bool intel_pll_is_valid(struct intel_display *display, const struct intel_limit *limit, const struct dpll *clock) { @@ -590,14 +591,14 @@ static bool intel_pll_is_valid(struct drm_i915_private *dev_priv, if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) return false; - if (!IS_PINEVIEW(dev_priv) && - !IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) && - !IS_BROXTON(dev_priv) && !IS_GEMINILAKE(dev_priv)) + if (!display->platform.pineview && + !display->platform.valleyview && !display->platform.cherryview && + !display->platform.broxton && !display->platform.geminilake) if (clock->m1 <= clock->m2) return false; - if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) && - !IS_BROXTON(dev_priv) && !IS_GEMINILAKE(dev_priv)) { + if (!display->platform.valleyview && !display->platform.cherryview && + !display->platform.broxton && !display->platform.geminilake) { if (clock->p < limit->p.min || limit->p.max < clock->p) return false; if (clock->m < limit->m.min || limit->m.max < clock->m) @@ -620,7 +621,7 @@ i9xx_select_p2_div(const struct intel_limit *limit, const struct intel_crtc_state *crtc_state, int target) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { /* @@ -628,7 +629,7 @@ i9xx_select_p2_div(const struct intel_limit *limit, * We haven't figured out how to reliably set up different * single/dual channel state, if we even can. */ - if (intel_is_dual_link_lvds(dev_priv)) + if (intel_is_dual_link_lvds(display)) return limit->p2.p2_fast; else return limit->p2.p2_slow; @@ -656,7 +657,7 @@ i9xx_find_best_dpll(const struct intel_limit *limit, const struct dpll *match_clock, struct dpll *best_clock) { - struct drm_device *dev = crtc_state->uapi.crtc->dev; + struct intel_display *display = to_intel_display(crtc_state); struct dpll clock; int err = target; @@ -677,7 +678,7 @@ i9xx_find_best_dpll(const struct intel_limit *limit, int this_err; i9xx_calc_dpll_params(refclk, &clock); - if (!intel_pll_is_valid(to_i915(dev), + if (!intel_pll_is_valid(display, limit, &clock)) continue; @@ -714,7 +715,7 @@ pnv_find_best_dpll(const struct intel_limit *limit, const struct dpll *match_clock, struct dpll *best_clock) { - struct drm_device *dev = crtc_state->uapi.crtc->dev; + struct intel_display *display = to_intel_display(crtc_state); struct dpll clock; int err = target; @@ -733,7 +734,7 @@ pnv_find_best_dpll(const struct intel_limit *limit, int this_err; pnv_calc_dpll_params(refclk, &clock); - if (!intel_pll_is_valid(to_i915(dev), + if (!intel_pll_is_valid(display, limit, &clock)) continue; @@ -770,7 +771,7 @@ g4x_find_best_dpll(const struct intel_limit *limit, const struct dpll *match_clock, struct dpll *best_clock) { - struct drm_device *dev = crtc_state->uapi.crtc->dev; + struct intel_display *display = to_intel_display(crtc_state); struct dpll clock; int max_n; bool found = false; @@ -794,7 +795,7 @@ g4x_find_best_dpll(const struct intel_limit *limit, int this_err; i9xx_calc_dpll_params(refclk, &clock); - if (!intel_pll_is_valid(to_i915(dev), + if (!intel_pll_is_valid(display, limit, &clock)) continue; @@ -817,7 +818,7 @@ g4x_find_best_dpll(const struct intel_limit *limit, * Check if the calculated PLL configuration is more optimal compared to the * best configuration and error found so far. Return the calculated error. */ -static bool vlv_PLL_is_optimal(struct drm_device *dev, int target_freq, +static bool vlv_PLL_is_optimal(struct intel_display *display, int target_freq, const struct dpll *calculated_clock, const struct dpll *best_clock, unsigned int best_error_ppm, @@ -827,13 +828,13 @@ static bool vlv_PLL_is_optimal(struct drm_device *dev, int target_freq, * For CHV ignore the error and consider only the P value. * Prefer a bigger P value based on HW requirements. */ - if (IS_CHERRYVIEW(to_i915(dev))) { + if (display->platform.cherryview) { *error_ppm = 0; return calculated_clock->p > best_clock->p; } - if (drm_WARN_ON_ONCE(dev, !target_freq)) + if (drm_WARN_ON_ONCE(display->drm, !target_freq)) return false; *error_ppm = div_u64(1000000ULL * @@ -864,8 +865,7 @@ vlv_find_best_dpll(const struct intel_limit *limit, const struct dpll *match_clock, struct dpll *best_clock) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_device *dev = crtc->base.dev; + struct intel_display *display = to_intel_display(crtc_state); struct dpll clock; unsigned int bestppm = 1000000; /* min update 19.2 MHz */ @@ -889,12 +889,12 @@ vlv_find_best_dpll(const struct intel_limit *limit, vlv_calc_dpll_params(refclk, &clock); - if (!intel_pll_is_valid(to_i915(dev), + if (!intel_pll_is_valid(display, limit, &clock)) continue; - if (!vlv_PLL_is_optimal(dev, target, + if (!vlv_PLL_is_optimal(display, target, &clock, best_clock, bestppm, &ppm)) @@ -922,8 +922,7 @@ chv_find_best_dpll(const struct intel_limit *limit, const struct dpll *match_clock, struct dpll *best_clock) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_device *dev = crtc->base.dev; + struct intel_display *display = to_intel_display(crtc_state); unsigned int best_error_ppm; struct dpll clock; u64 m2; @@ -958,10 +957,10 @@ chv_find_best_dpll(const struct intel_limit *limit, chv_calc_dpll_params(refclk, &clock); - if (!intel_pll_is_valid(to_i915(dev), limit, &clock)) + if (!intel_pll_is_valid(display, limit, &clock)) continue; - if (!vlv_PLL_is_optimal(dev, target, &clock, best_clock, + if (!vlv_PLL_is_optimal(display, target, &clock, best_clock, best_error_ppm, &error_ppm)) continue; @@ -1005,8 +1004,6 @@ static u32 i9xx_dpll(const struct intel_crtc_state *crtc_state, const struct dpll *reduced_clock) { struct intel_display *display = to_intel_display(crtc_state); - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 dpll; dpll = DPLL_VCO_ENABLE | DPLL_VGA_MODE_DIS; @@ -1016,8 +1013,8 @@ static u32 i9xx_dpll(const struct intel_crtc_state *crtc_state, else dpll |= DPLLB_MODE_DAC_SERIAL; - if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) || - IS_G33(dev_priv) || IS_PINEVIEW(dev_priv)) { + if (display->platform.i945g || display->platform.i945gm || + display->platform.g33 || display->platform.pineview) { dpll |= (crtc_state->pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; } @@ -1030,10 +1027,10 @@ static u32 i9xx_dpll(const struct intel_crtc_state *crtc_state, dpll |= DPLL_SDVO_HIGH_SPEED; /* compute bitmask from p1 value */ - if (IS_G4X(dev_priv)) { + if (display->platform.g4x) { dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; dpll |= (1 << (reduced_clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; - } else if (IS_PINEVIEW(dev_priv)) { + } else if (display->platform.pineview) { dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW; WARN_ON(reduced_clock->p1 != clock->p1); } else { @@ -1057,7 +1054,7 @@ static u32 i9xx_dpll(const struct intel_crtc_state *crtc_state, } WARN_ON(reduced_clock->p2 != clock->p2); - if (DISPLAY_VER(dev_priv) >= 4) + if (DISPLAY_VER(display) >= 4) dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); if (crtc_state->sdvo_tv_clock) @@ -1075,11 +1072,10 @@ static void i9xx_compute_dpll(struct intel_crtc_state *crtc_state, const struct dpll *clock, const struct dpll *reduced_clock) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; - if (IS_PINEVIEW(dev_priv)) { + if (display->platform.pineview) { hw_state->fp0 = pnv_dpll_compute_fp(clock); hw_state->fp1 = pnv_dpll_compute_fp(reduced_clock); } else { @@ -1089,7 +1085,7 @@ static void i9xx_compute_dpll(struct intel_crtc_state *crtc_state, hw_state->dpll = i9xx_dpll(crtc_state, clock, reduced_clock); - if (DISPLAY_VER(dev_priv) >= 4) + if (DISPLAY_VER(display) >= 4) hw_state->dpll_md = i965_dpll_md(crtc_state); } @@ -1098,8 +1094,6 @@ static u32 i8xx_dpll(const struct intel_crtc_state *crtc_state, const struct dpll *reduced_clock) { struct intel_display *display = to_intel_display(crtc_state); - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 dpll; dpll = DPLL_VCO_ENABLE | DPLL_VGA_MODE_DIS; @@ -1129,7 +1123,7 @@ static u32 i8xx_dpll(const struct intel_crtc_state *crtc_state, * both DPLLS. The spec says we should disable the DVO 2X clock * when not needed, but this seems to work fine in practice. */ - if (IS_I830(dev_priv) || + if (display->platform.i830 || intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DVO)) dpll |= DPLL_DVO_2X_MODE; @@ -1157,14 +1151,14 @@ static void i8xx_compute_dpll(struct intel_crtc_state *crtc_state, static int hsw_crtc_compute_clock(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_encoder *encoder = intel_get_crtc_new_encoder(state, crtc_state); int ret; - if (DISPLAY_VER(dev_priv) < 11 && + if (DISPLAY_VER(display) < 11 && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) return 0; @@ -1186,13 +1180,13 @@ static int hsw_crtc_compute_clock(struct intel_atomic_state *state, static int hsw_crtc_get_shared_dpll(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_encoder *encoder = intel_get_crtc_new_encoder(state, crtc_state); - if (DISPLAY_VER(dev_priv) < 11 && + if (DISPLAY_VER(display) < 11 && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) return 0; @@ -1245,8 +1239,8 @@ static int ilk_fb_cb_factor(const struct intel_crtc_state *crtc_state) struct drm_i915_private *i915 = to_i915(crtc->base.dev); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) && - ((intel_panel_use_ssc(display) && i915->display.vbt.lvds_ssc_freq == 100000) || - (HAS_PCH_IBX(i915) && intel_is_dual_link_lvds(i915)))) + ((intel_panel_use_ssc(display) && display->vbt.lvds_ssc_freq == 100000) || + (HAS_PCH_IBX(i915) && intel_is_dual_link_lvds(display)))) return 25; if (crtc_state->sdvo_tv_clock) @@ -1276,8 +1270,6 @@ static u32 ilk_dpll(const struct intel_crtc_state *crtc_state, const struct dpll *reduced_clock) { struct intel_display *display = to_intel_display(crtc_state); - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 dpll; dpll = DPLL_VCO_ENABLE; @@ -1311,7 +1303,7 @@ static u32 ilk_dpll(const struct intel_crtc_state *crtc_state, * clear if it''s a win or loss power wise. No point in doing * this on ILK at all since it has a fixed DPLL<->pipe mapping. */ - if (INTEL_NUM_PIPES(dev_priv) == 3 && + if (INTEL_NUM_PIPES(display) == 3 && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) dpll |= DPLL_SDVO_HIGH_SPEED; @@ -1362,7 +1354,6 @@ static int ilk_crtc_compute_clock(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; @@ -1375,13 +1366,13 @@ static int ilk_crtc_compute_clock(struct intel_atomic_state *state, if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(display)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "using SSC reference clock of %d kHz\n", - dev_priv->display.vbt.lvds_ssc_freq); - refclk = dev_priv->display.vbt.lvds_ssc_freq; + display->vbt.lvds_ssc_freq); + refclk = display->vbt.lvds_ssc_freq; } - if (intel_is_dual_link_lvds(dev_priv)) { + if (intel_is_dual_link_lvds(display)) { if (refclk == 100000) limit = &ilk_limits_dual_lvds_100m; else @@ -1539,7 +1530,6 @@ static int g4x_crtc_compute_clock(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; @@ -1547,13 +1537,13 @@ static int g4x_crtc_compute_clock(struct intel_atomic_state *state, if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(display)) { - refclk = dev_priv->display.vbt.lvds_ssc_freq; - drm_dbg_kms(&dev_priv->drm, + refclk = display->vbt.lvds_ssc_freq; + drm_dbg_kms(display->drm, "using SSC reference clock of %d kHz\n", refclk); } - if (intel_is_dual_link_lvds(dev_priv)) + if (intel_is_dual_link_lvds(display)) limit = &intel_limits_g4x_dual_channel_lvds; else limit = &intel_limits_g4x_single_channel_lvds; @@ -1589,7 +1579,6 @@ static int pnv_crtc_compute_clock(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; @@ -1597,8 +1586,8 @@ static int pnv_crtc_compute_clock(struct intel_atomic_state *state, if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(display)) { - refclk = dev_priv->display.vbt.lvds_ssc_freq; - drm_dbg_kms(&dev_priv->drm, + refclk = display->vbt.lvds_ssc_freq; + drm_dbg_kms(display->drm, "using SSC reference clock of %d kHz\n", refclk); } @@ -1628,7 +1617,6 @@ static int i9xx_crtc_compute_clock(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; @@ -1636,8 +1624,8 @@ static int i9xx_crtc_compute_clock(struct intel_atomic_state *state, if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(display)) { - refclk = dev_priv->display.vbt.lvds_ssc_freq; - drm_dbg_kms(&dev_priv->drm, + refclk = display->vbt.lvds_ssc_freq; + drm_dbg_kms(display->drm, "using SSC reference clock of %d kHz\n", refclk); } @@ -1669,7 +1657,6 @@ static int i8xx_crtc_compute_clock(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; @@ -1677,8 +1664,8 @@ static int i8xx_crtc_compute_clock(struct intel_atomic_state *state, if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(display)) { - refclk = dev_priv->display.vbt.lvds_ssc_freq; - drm_dbg_kms(&dev_priv->drm, + refclk = display->vbt.lvds_ssc_freq; + drm_dbg_kms(display->drm, "using SSC reference clock of %d kHz\n", refclk); } @@ -1751,12 +1738,12 @@ static const struct intel_dpll_funcs i8xx_dpll_funcs = { int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); int ret; - drm_WARN_ON(&i915->drm, !intel_crtc_needs_modeset(crtc_state)); + drm_WARN_ON(display->drm, !intel_crtc_needs_modeset(crtc_state)); memset(&crtc_state->dpll_hw_state, 0, sizeof(crtc_state->dpll_hw_state)); @@ -1764,9 +1751,9 @@ int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state, if (!crtc_state->hw.enable) return 0; - ret = i915->display.funcs.dpll->crtc_compute_clock(state, crtc); + ret = display->funcs.dpll->crtc_compute_clock(state, crtc); if (ret) { - drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] Couldn't calculate DPLL settings\n", + drm_dbg_kms(display->drm, "[CRTC:%d:%s] Couldn't calculate DPLL settings\n", crtc->base.base.id, crtc->base.name); return ret; } @@ -1777,23 +1764,23 @@ int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state, int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); int ret; - drm_WARN_ON(&i915->drm, !intel_crtc_needs_modeset(crtc_state)); - drm_WARN_ON(&i915->drm, !crtc_state->hw.enable && crtc_state->shared_dpll); + drm_WARN_ON(display->drm, !intel_crtc_needs_modeset(crtc_state)); + drm_WARN_ON(display->drm, !crtc_state->hw.enable && crtc_state->shared_dpll); if (!crtc_state->hw.enable || crtc_state->shared_dpll) return 0; - if (!i915->display.funcs.dpll->crtc_get_shared_dpll) + if (!display->funcs.dpll->crtc_get_shared_dpll) return 0; - ret = i915->display.funcs.dpll->crtc_get_shared_dpll(state, crtc); + ret = display->funcs.dpll->crtc_get_shared_dpll(state, crtc); if (ret) { - drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] Couldn't get a shared DPLL\n", + drm_dbg_kms(display->drm, "[CRTC:%d:%s] Couldn't get a shared DPLL\n", crtc->base.base.id, crtc->base.name); return ret; } @@ -1802,43 +1789,44 @@ int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state, } void -intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv) -{ - if (DISPLAY_VER(dev_priv) >= 14) - dev_priv->display.funcs.dpll = &mtl_dpll_funcs; - else if (IS_DG2(dev_priv)) - dev_priv->display.funcs.dpll = &dg2_dpll_funcs; - else if (DISPLAY_VER(dev_priv) >= 9 || HAS_DDI(dev_priv)) - dev_priv->display.funcs.dpll = &hsw_dpll_funcs; +intel_dpll_init_clock_hook(struct intel_display *display) +{ + struct drm_i915_private *dev_priv = to_i915(display->drm); + + if (DISPLAY_VER(display) >= 14) + display->funcs.dpll = &mtl_dpll_funcs; + else if (display->platform.dg2) + display->funcs.dpll = &dg2_dpll_funcs; + else if (DISPLAY_VER(display) >= 9 || HAS_DDI(display)) + display->funcs.dpll = &hsw_dpll_funcs; else if (HAS_PCH_SPLIT(dev_priv)) - dev_priv->display.funcs.dpll = &ilk_dpll_funcs; - else if (IS_CHERRYVIEW(dev_priv)) - dev_priv->display.funcs.dpll = &chv_dpll_funcs; - else if (IS_VALLEYVIEW(dev_priv)) - dev_priv->display.funcs.dpll = &vlv_dpll_funcs; - else if (IS_G4X(dev_priv)) - dev_priv->display.funcs.dpll = &g4x_dpll_funcs; - else if (IS_PINEVIEW(dev_priv)) - dev_priv->display.funcs.dpll = &pnv_dpll_funcs; - else if (DISPLAY_VER(dev_priv) != 2) - dev_priv->display.funcs.dpll = &i9xx_dpll_funcs; + display->funcs.dpll = &ilk_dpll_funcs; + else if (display->platform.cherryview) + display->funcs.dpll = &chv_dpll_funcs; + else if (display->platform.valleyview) + display->funcs.dpll = &vlv_dpll_funcs; + else if (display->platform.g4x) + display->funcs.dpll = &g4x_dpll_funcs; + else if (display->platform.pineview) + display->funcs.dpll = &pnv_dpll_funcs; + else if (DISPLAY_VER(display) != 2) + display->funcs.dpll = &i9xx_dpll_funcs; else - dev_priv->display.funcs.dpll = &i8xx_dpll_funcs; + display->funcs.dpll = &i8xx_dpll_funcs; } -static bool i9xx_has_pps(struct drm_i915_private *dev_priv) +static bool i9xx_has_pps(struct intel_display *display) { - if (IS_I830(dev_priv)) + if (display->platform.i830) return false; - return IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv); + return display->platform.pineview || display->platform.mobile; } void i9xx_enable_pll(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; enum pipe pipe = crtc->pipe; int i; @@ -1846,27 +1834,27 @@ void i9xx_enable_pll(const struct intel_crtc_state *crtc_state) assert_transcoder_disabled(display, crtc_state->cpu_transcoder); /* PLL is protected by panel, make sure we can write it */ - if (i9xx_has_pps(dev_priv)) + if (i9xx_has_pps(display)) assert_pps_unlocked(display, pipe); - intel_de_write(dev_priv, FP0(pipe), hw_state->fp0); - intel_de_write(dev_priv, FP1(pipe), hw_state->fp1); + intel_de_write(display, FP0(pipe), hw_state->fp0); + intel_de_write(display, FP1(pipe), hw_state->fp1); /* * Apparently we need to have VGA mode enabled prior to changing * the P1/P2 dividers. Otherwise the DPLL will keep using the old * dividers, even though the register value does change. */ - intel_de_write(dev_priv, DPLL(dev_priv, pipe), + intel_de_write(display, DPLL(display, pipe), hw_state->dpll & ~DPLL_VGA_MODE_DIS); - intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll); + intel_de_write(display, DPLL(display, pipe), hw_state->dpll); /* Wait for the clocks to stabilize. */ - intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe)); + intel_de_posting_read(display, DPLL(display, pipe)); udelay(150); - if (DISPLAY_VER(dev_priv) >= 4) { - intel_de_write(dev_priv, DPLL_MD(dev_priv, pipe), + if (DISPLAY_VER(display) >= 4) { + intel_de_write(display, DPLL_MD(display, pipe), hw_state->dpll_md); } else { /* The pixel multiplier can only be updated once the @@ -1874,20 +1862,21 @@ void i9xx_enable_pll(const struct intel_crtc_state *crtc_state) * * So write it again. */ - intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll); + intel_de_write(display, DPLL(display, pipe), hw_state->dpll); } /* We do this three times for luck */ for (i = 0; i < 3; i++) { - intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll); - intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe)); + intel_de_write(display, DPLL(display, pipe), hw_state->dpll); + intel_de_posting_read(display, DPLL(display, pipe)); udelay(150); /* wait for warmup */ } } -static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, +static void vlv_pllb_recal_opamp(struct intel_display *display, enum dpio_phy phy, enum dpio_channel ch) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 tmp; /* @@ -1916,6 +1905,7 @@ static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct dpll *clock = &crtc_state->dpll; @@ -1930,7 +1920,7 @@ static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state) /* PLL B needs special handling */ if (pipe == PIPE_B) - vlv_pllb_recal_opamp(dev_priv, phy, ch); + vlv_pllb_recal_opamp(display, phy, ch); /* Set up Tx target for periodic Rcomp update */ vlv_dpio_write(dev_priv, phy, VLV_PCS_DW17_BCAST, 0x0100000f); @@ -2003,24 +1993,23 @@ static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state) static void _vlv_enable_pll(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; enum pipe pipe = crtc->pipe; - intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll); - intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe)); + intel_de_write(display, DPLL(display, pipe), hw_state->dpll); + intel_de_posting_read(display, DPLL(display, pipe)); udelay(150); - if (intel_de_wait_for_set(dev_priv, DPLL(dev_priv, pipe), DPLL_LOCK_VLV, 1)) - drm_err(&dev_priv->drm, "DPLL %d failed to lock\n", pipe); + if (intel_de_wait_for_set(display, DPLL(display, pipe), DPLL_LOCK_VLV, 1)) + drm_err(display->drm, "DPLL %d failed to lock\n", pipe); } void vlv_enable_pll(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; enum pipe pipe = crtc->pipe; @@ -2030,7 +2019,7 @@ void vlv_enable_pll(const struct intel_crtc_state *crtc_state) assert_pps_unlocked(display, pipe); /* Enable Refclk */ - intel_de_write(dev_priv, DPLL(dev_priv, pipe), + intel_de_write(display, DPLL(display, pipe), hw_state->dpll & ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV)); if (hw_state->dpll & DPLL_VCO_ENABLE) { @@ -2038,8 +2027,8 @@ void vlv_enable_pll(const struct intel_crtc_state *crtc_state) _vlv_enable_pll(crtc_state); } - intel_de_write(dev_priv, DPLL_MD(dev_priv, pipe), hw_state->dpll_md); - intel_de_posting_read(dev_priv, DPLL_MD(dev_priv, pipe)); + intel_de_write(display, DPLL_MD(display, pipe), hw_state->dpll_md); + intel_de_posting_read(display, DPLL_MD(display, pipe)); } static void chv_prepare_pll(const struct intel_crtc_state *crtc_state) @@ -2133,6 +2122,7 @@ static void chv_prepare_pll(const struct intel_crtc_state *crtc_state) static void _chv_enable_pll(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; @@ -2156,18 +2146,17 @@ static void _chv_enable_pll(const struct intel_crtc_state *crtc_state) udelay(1); /* Enable PLL */ - intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll); + intel_de_write(display, DPLL(display, pipe), hw_state->dpll); /* Check PLL is locked */ - if (intel_de_wait_for_set(dev_priv, DPLL(dev_priv, pipe), DPLL_LOCK_VLV, 1)) - drm_err(&dev_priv->drm, "PLL %d failed to lock\n", pipe); + if (intel_de_wait_for_set(display, DPLL(display, pipe), DPLL_LOCK_VLV, 1)) + drm_err(display->drm, "PLL %d failed to lock\n", pipe); } void chv_enable_pll(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; enum pipe pipe = crtc->pipe; @@ -2177,7 +2166,7 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state) assert_pps_unlocked(display, pipe); /* Enable Refclk and SSC */ - intel_de_write(dev_priv, DPLL(dev_priv, pipe), + intel_de_write(display, DPLL(display, pipe), hw_state->dpll & ~DPLL_VCO_ENABLE); if (hw_state->dpll & DPLL_VCO_ENABLE) { @@ -2192,29 +2181,29 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state) * DPLLCMD is AWOL. Use chicken bits to propagate * the value from DPLLBMD to either pipe B or C. */ - intel_de_write(dev_priv, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe)); - intel_de_write(dev_priv, DPLL_MD(dev_priv, PIPE_B), + intel_de_write(display, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe)); + intel_de_write(display, DPLL_MD(display, PIPE_B), hw_state->dpll_md); - intel_de_write(dev_priv, CBR4_VLV, 0); - dev_priv->display.state.chv_dpll_md[pipe] = hw_state->dpll_md; + intel_de_write(display, CBR4_VLV, 0); + display->state.chv_dpll_md[pipe] = hw_state->dpll_md; /* * DPLLB VGA mode also seems to cause problems. * We should always have it disabled. */ - drm_WARN_ON(&dev_priv->drm, - (intel_de_read(dev_priv, DPLL(dev_priv, PIPE_B)) & + drm_WARN_ON(display->drm, + (intel_de_read(display, DPLL(display, PIPE_B)) & DPLL_VGA_MODE_DIS) == 0); } else { - intel_de_write(dev_priv, DPLL_MD(dev_priv, pipe), + intel_de_write(display, DPLL_MD(display, pipe), hw_state->dpll_md); - intel_de_posting_read(dev_priv, DPLL_MD(dev_priv, pipe)); + intel_de_posting_read(display, DPLL_MD(display, pipe)); } } /** * vlv_force_pll_on - forcibly enable just the PLL - * @dev_priv: i915 private structure + * @display: display device * @pipe: pipe PLL to enable * @dpll: PLL configuration * @@ -2222,10 +2211,9 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state) * in cases where we need the PLL enabled even when @pipe is not going to * be enabled. */ -int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, +int vlv_force_pll_on(struct intel_display *display, enum pipe pipe, const struct dpll *dpll) { - struct intel_display *display = &dev_priv->display; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); struct intel_crtc_state *crtc_state; @@ -2238,7 +2226,7 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, crtc_state->dpll = *dpll; crtc_state->output_types = BIT(INTEL_OUTPUT_EDP); - if (IS_CHERRYVIEW(dev_priv)) { + if (display->platform.cherryview) { chv_compute_dpll(crtc_state); chv_enable_pll(crtc_state); } else { @@ -2251,9 +2239,8 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, return 0; } -void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) +void vlv_disable_pll(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; u32 val; /* Make sure the pipe isn't still relying on us */ @@ -2268,9 +2255,9 @@ void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) intel_de_posting_read(display, DPLL(display, pipe)); } -void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) +void chv_disable_pll(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); enum dpio_channel ch = vlv_pipe_to_channel(pipe); enum dpio_phy phy = vlv_pipe_to_phy(pipe); u32 val; @@ -2316,18 +2303,18 @@ void i9xx_disable_pll(const struct intel_crtc_state *crtc_state) /** * vlv_force_pll_off - forcibly disable just the PLL - * @dev_priv: i915 private structure + * @display: display device * @pipe: pipe PLL to disable * * Disable the PLL for @pipe. To be used in cases where we need * the PLL enabled even when @pipe is not going to be enabled. */ -void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe) +void vlv_force_pll_off(struct intel_display *display, enum pipe pipe) { - if (IS_CHERRYVIEW(dev_priv)) - chv_disable_pll(dev_priv, pipe); + if (display->platform.cherryview) + chv_disable_pll(display, pipe); else - vlv_disable_pll(dev_priv, pipe); + vlv_disable_pll(display, pipe); } /* Only for pre-ILK configs */ diff --git a/drivers/gpu/drm/i915/display/intel_dpll.h b/drivers/gpu/drm/i915/display/intel_dpll.h index 21d06cbd2ce75b..280e90a57c8751 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.h +++ b/drivers/gpu/drm/i915/display/intel_dpll.h @@ -8,16 +8,15 @@ #include +enum pipe; struct dpll; -struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; struct intel_display; struct intel_dpll_hw_state; -enum pipe; -void intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv); +void intel_dpll_init_clock_hook(struct intel_display *display); int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state, struct intel_crtc *crtc); int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state, @@ -29,14 +28,14 @@ void i9xx_dpll_get_hw_state(struct intel_crtc *crtc, void vlv_compute_dpll(struct intel_crtc_state *crtc_state); void chv_compute_dpll(struct intel_crtc_state *crtc_state); -int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, +int vlv_force_pll_on(struct intel_display *display, enum pipe pipe, const struct dpll *dpll); -void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe); +void vlv_force_pll_off(struct intel_display *display, enum pipe pipe); void chv_enable_pll(const struct intel_crtc_state *crtc_state); -void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe); +void chv_disable_pll(struct intel_display *display, enum pipe pipe); void vlv_enable_pll(const struct intel_crtc_state *crtc_state); -void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe); +void vlv_disable_pll(struct intel_display *display, enum pipe pipe); void i9xx_enable_pll(const struct intel_crtc_state *crtc_state); void i9xx_disable_pll(const struct intel_crtc_state *crtc_state); bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index c825a507b90513..84df41086a892e 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -257,7 +257,7 @@ void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state) struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_shared_dpll *pll = crtc_state->shared_dpll; - unsigned int pipe_mask = BIT(crtc->pipe); + unsigned int pipe_mask = intel_crtc_joined_pipe_mask(crtc_state); unsigned int old_mask; if (drm_WARN_ON(display->drm, !pll)) @@ -303,7 +303,7 @@ void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state) struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_shared_dpll *pll = crtc_state->shared_dpll; - unsigned int pipe_mask = BIT(crtc->pipe); + unsigned int pipe_mask = intel_crtc_joined_pipe_mask(crtc_state); /* PCH only available on ILK+ */ if (DISPLAY_VER(display) < 5) @@ -715,7 +715,6 @@ static void hsw_ddi_spll_enable(struct intel_display *display, static void hsw_ddi_wrpll_disable(struct intel_display *display, struct intel_shared_dpll *pll) { - struct drm_i915_private *i915 = to_i915(display->drm); const enum intel_dpll_id id = pll->info->id; intel_de_rmw(display, WRPLL_CTL(id), WRPLL_PLL_ENABLE, 0); @@ -726,13 +725,12 @@ static void hsw_ddi_wrpll_disable(struct intel_display *display, * that depend on it have been shut down. */ if (display->dpll.pch_ssc_use & BIT(id)) - intel_init_pch_refclk(i915); + intel_init_pch_refclk(display); } static void hsw_ddi_spll_disable(struct intel_display *display, struct intel_shared_dpll *pll) { - struct drm_i915_private *i915 = to_i915(display->drm); enum intel_dpll_id id = pll->info->id; intel_de_rmw(display, SPLL_CTL, SPLL_PLL_ENABLE, 0); @@ -743,7 +741,7 @@ static void hsw_ddi_spll_disable(struct intel_display *display, * that depend on it have been shut down. */ if (display->dpll.pch_ssc_use & BIT(id)) - intel_init_pch_refclk(i915); + intel_init_pch_refclk(display); } static bool hsw_ddi_wrpll_get_hw_state(struct intel_display *display, @@ -2606,10 +2604,8 @@ ehl_combo_pll_div_frac_wa_needed(struct intel_display *display) { return ((display->platform.elkhartlake && IS_DISPLAY_STEP(display, STEP_B0, STEP_FOREVER)) || - display->platform.tigerlake || - display->platform.alderlake_s || - display->platform.alderlake_p) && - display->dpll.ref_clks.nssc == 38400; + DISPLAY_VER(display) >= 12) && + display->dpll.ref_clks.nssc == 38400; } struct icl_combo_pll_params { diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index 0d8ebe38226ea1..43bd97e4f58989 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -9,6 +9,7 @@ #include "gt/gen8_ppgtt.h" #include "i915_drv.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dpt.h" #include "intel_fb.h" @@ -127,7 +128,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, struct drm_i915_private *i915 = vm->i915; struct intel_display *display = &i915->display; struct i915_dpt *dpt = i915_vm_to_dpt(vm); - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; struct i915_vma *vma; void __iomem *iomem; struct i915_gem_ww_ctx ww; @@ -137,7 +138,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, if (i915_gem_object_is_stolen(dpt->obj)) pin_flags |= PIN_MAPPABLE; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); atomic_inc(&display->restore.pending_fb_pin); for_i915_gem_ww(&ww, err, true) { @@ -169,7 +170,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, dpt->obj->mm.dirty = true; atomic_dec(&display->restore.pending_fb_pin); - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return err ? ERR_PTR(err) : vma; } diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 9fc4003d15794a..72fe390c5af22a 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -11,6 +11,7 @@ #include "i915_reg.h" #include "intel_crtc.h" #include "intel_de.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dsb.h" #include "intel_dsb_buffer.h" @@ -142,10 +143,10 @@ static int dsb_vtotal(struct intel_atomic_state *state, static int dsb_dewake_scanline_start(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *crtc_state = intel_pre_commit_crtc_state(state, crtc); - struct drm_i915_private *i915 = to_i915(state->base.dev); - unsigned int latency = skl_watermark_max_latency(i915, 0); + unsigned int latency = skl_watermark_max_latency(display, 0); return intel_mode_vdisplay(&crtc_state->hw.adjusted_mode) - intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, latency); @@ -795,22 +796,22 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state, enum intel_dsb_id dsb_id, unsigned int max_cmds) { - struct drm_i915_private *i915 = to_i915(state->base.dev); - intel_wakeref_t wakeref; + struct intel_display *display = to_intel_display(state); + struct ref_tracker *wakeref; struct intel_dsb *dsb; unsigned int size; - if (!HAS_DSB(i915)) + if (!HAS_DSB(display)) return NULL; - if (!i915->display.params.enable_dsb) + if (!display->params.enable_dsb) return NULL; dsb = kzalloc(sizeof(*dsb), GFP_KERNEL); if (!dsb) goto out; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); /* ~1 qword per instruction, full cachelines */ size = ALIGN(max_cmds * 8, CACHELINE_BYTES); @@ -818,7 +819,7 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state, if (!intel_dsb_buffer_create(crtc, &dsb->dsb_buf, size)) goto out_put_rpm; - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); dsb->id = dsb_id; dsb->crtc = crtc; @@ -831,10 +832,10 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state, return dsb; out_put_rpm: - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); kfree(dsb); out: - drm_info_once(&i915->drm, + drm_info_once(display->drm, "[CRTC:%d:%s] DSB %d queue setup failed, will fallback to MMIO for display HW programming\n", crtc->base.base.id, crtc->base.name, dsb_id); diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c index 0494432453101d..b3c453bf7d5c19 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c @@ -24,9 +24,10 @@ */ #include +#include #include