mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
drm-misc-next for 6.11:
UAPI Changes: - New monochrome TV mode variant Cross-subsystem Changes: - dma heaps: Change slightly the allocation hook prototype Core Changes: Driver Changes: - ivpu: various improvements over firmware handling, clocks, power management, scheduling and logging. - mgag200: Add BMC output, enable polling - panfrost: Enable MT8188 support - tidss: drm_panic support - zynqmp_dp: IRQ cleanups, debugfs DP compliance testing API - bridge: - sii902x: state validation improvements - panel: - edp: Drop legacy panel compatibles - simple-bridge: Switch to devm_drm_bridge_add -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRcEzekXsqa64kGDp7j7w1vZxhRxQUCZnPhvwAKCRDj7w1vZxhR xZPbAP9+43f9IIXMscOBvs1+bQRXCsu5Fp4zG9jTwC/XdXMKDwD/VlAVMKKCGQSC T+2/igKmeJQF674/rPIqKDd7UyRpBQY= =c8ky -----END PGP SIGNATURE----- Merge tag 'drm-misc-next-2024-06-20' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next drm-misc-next for 6.11: UAPI Changes: - New monochrome TV mode variant Cross-subsystem Changes: - dma heaps: Change slightly the allocation hook prototype Core Changes: Driver Changes: - ivpu: various improvements over firmware handling, clocks, power management, scheduling and logging. - mgag200: Add BMC output, enable polling - panfrost: Enable MT8188 support - tidss: drm_panic support - zynqmp_dp: IRQ cleanups, debugfs DP compliance testing API - bridge: - sii902x: state validation improvements - panel: - edp: Drop legacy panel compatibles - simple-bridge: Switch to devm_drm_bridge_add Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <mripard@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240620-heretic-honored-macaque-b40f8a@houat
This commit is contained in:
commit
ab3d847962
@ -31,13 +31,9 @@ properties:
|
||||
# AUO B116XAK01 eDP TFT LCD panel
|
||||
- auo,b116xa01
|
||||
# AU Optronics Corporation 13.3" FHD (1920x1080) color TFT-LCD panel
|
||||
- auo,b133han05
|
||||
# AU Optronics Corporation 13.3" FHD (1920x1080) color TFT-LCD panel
|
||||
- auo,b133htn01
|
||||
# AU Optronics Corporation 13.3" WXGA (1366x768) TFT LCD panel
|
||||
- auo,b133xtn01
|
||||
# AU Optronics Corporation 14.0" FHD (1920x1080) color TFT-LCD panel
|
||||
- auo,b140han06
|
||||
# BOE OPTOELECTRONICS TECHNOLOGY 10.1" WXGA TFT LCD panel
|
||||
- boe,nv101wxmn51
|
||||
# BOE NV133FHM-N61 13.3" FHD (1920x1080) TFT LCD Panel
|
||||
@ -56,8 +52,6 @@ properties:
|
||||
- innolux,n125hce-gn1
|
||||
# Innolux P120ZDG-BF1 12.02 inch eDP 2K display panel
|
||||
- innolux,p120zdg-bf1
|
||||
# InfoVision Optoelectronics M133NWF4 R0 13.3" FHD (1920x1080) TFT LCD panel
|
||||
- ivo,m133nwf4-r0
|
||||
# King & Display KD116N21-30NV-A010 eDP TFT LCD panel
|
||||
- kingdisplay,kd116n21-30nv-a010
|
||||
# LG LP079QX1-SP0V 7.9" (1536x2048 pixels) TFT LCD panel
|
||||
@ -78,10 +72,6 @@ properties:
|
||||
- sharp,ld-d5116z01b
|
||||
# Sharp 12.3" (2400x1600 pixels) TFT LCD panel
|
||||
- sharp,lq123p1jx31
|
||||
# Sharp 14" (1920x1080 pixels) TFT LCD panel
|
||||
- sharp,lq140m1jw46
|
||||
# Starry 12.2" (1920x1200 pixels) TFT LCD panel
|
||||
- starry,kr122ea0sra
|
||||
|
||||
backlight: true
|
||||
ddc-i2c-bus: true
|
||||
|
@ -34,6 +34,7 @@ properties:
|
||||
- const: arm,mali-valhall-jm # Mali Valhall GPU model/revision is fully discoverable
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt8188-mali
|
||||
- mediatek,mt8192-mali
|
||||
- const: arm,mali-valhall-jm # Mali Valhall GPU model/revision is fully discoverable
|
||||
|
||||
@ -195,7 +196,9 @@ allOf:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: mediatek,mt8183b-mali
|
||||
enum:
|
||||
- mediatek,mt8183b-mali
|
||||
- mediatek,mt8188-mali
|
||||
then:
|
||||
properties:
|
||||
power-domains:
|
||||
|
@ -7196,6 +7196,7 @@ L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
F: Documentation/gpu/vkms.rst
|
||||
F: drivers/gpu/drm/ci/xfails/vkms*
|
||||
F: drivers/gpu/drm/vkms/
|
||||
|
||||
DRM DRIVER FOR VIRTUALBOX VIRTUAL GPU
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
@ -381,6 +381,39 @@ static const struct file_operations ivpu_resume_engine_fops = {
|
||||
.write = ivpu_resume_engine_fn,
|
||||
};
|
||||
|
||||
static int dct_active_get(void *data, u64 *active_percent)
|
||||
{
|
||||
struct ivpu_device *vdev = data;
|
||||
|
||||
*active_percent = vdev->pm->dct_active_percent;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dct_active_set(void *data, u64 active_percent)
|
||||
{
|
||||
struct ivpu_device *vdev = data;
|
||||
int ret;
|
||||
|
||||
if (active_percent > 100)
|
||||
return -EINVAL;
|
||||
|
||||
ret = ivpu_rpm_get(vdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (active_percent)
|
||||
ret = ivpu_pm_dct_enable(vdev, active_percent);
|
||||
else
|
||||
ret = ivpu_pm_dct_disable(vdev);
|
||||
|
||||
ivpu_rpm_put(vdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(ivpu_dct_fops, dct_active_get, dct_active_set, "%llu\n");
|
||||
|
||||
void ivpu_debugfs_init(struct ivpu_device *vdev)
|
||||
{
|
||||
struct dentry *debugfs_root = vdev->drm.debugfs_root;
|
||||
@ -409,7 +442,9 @@ void ivpu_debugfs_init(struct ivpu_device *vdev)
|
||||
debugfs_create_file("resume_engine", 0200, debugfs_root, vdev,
|
||||
&ivpu_resume_engine_fops);
|
||||
|
||||
if (ivpu_hw_ip_gen(vdev) >= IVPU_HW_IP_40XX)
|
||||
if (ivpu_hw_ip_gen(vdev) >= IVPU_HW_IP_40XX) {
|
||||
debugfs_create_file("fw_profiling_freq_drive", 0200,
|
||||
debugfs_root, vdev, &fw_profiling_freq_fops);
|
||||
debugfs_create_file("dct", 0644, debugfs_root, vdev, &ivpu_dct_fops);
|
||||
}
|
||||
}
|
||||
|
@ -58,11 +58,11 @@ module_param_named(sched_mode, ivpu_sched_mode, int, 0444);
|
||||
MODULE_PARM_DESC(sched_mode, "Scheduler mode: 0 - Default scheduler, 1 - Force HW scheduler");
|
||||
|
||||
bool ivpu_disable_mmu_cont_pages;
|
||||
module_param_named(disable_mmu_cont_pages, ivpu_disable_mmu_cont_pages, bool, 0644);
|
||||
module_param_named(disable_mmu_cont_pages, ivpu_disable_mmu_cont_pages, bool, 0444);
|
||||
MODULE_PARM_DESC(disable_mmu_cont_pages, "Disable MMU contiguous pages optimization");
|
||||
|
||||
bool ivpu_force_snoop;
|
||||
module_param_named(force_snoop, ivpu_force_snoop, bool, 0644);
|
||||
module_param_named(force_snoop, ivpu_force_snoop, bool, 0444);
|
||||
MODULE_PARM_DESC(force_snoop, "Force snooping for NPU host memory access");
|
||||
|
||||
struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv)
|
||||
@ -391,8 +391,13 @@ int ivpu_boot(struct ivpu_device *vdev)
|
||||
ivpu_hw_irq_enable(vdev);
|
||||
ivpu_ipc_enable(vdev);
|
||||
|
||||
if (ivpu_fw_is_cold_boot(vdev))
|
||||
if (ivpu_fw_is_cold_boot(vdev)) {
|
||||
ret = ivpu_pm_dct_init(vdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ivpu_hw_sched_init(vdev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -446,6 +451,26 @@ static const struct drm_driver driver = {
|
||||
.minor = DRM_IVPU_DRIVER_MINOR,
|
||||
};
|
||||
|
||||
static void ivpu_context_abort_invalid(struct ivpu_device *vdev)
|
||||
{
|
||||
struct ivpu_file_priv *file_priv;
|
||||
unsigned long ctx_id;
|
||||
|
||||
mutex_lock(&vdev->context_list_lock);
|
||||
|
||||
xa_for_each(&vdev->context_xa, ctx_id, file_priv) {
|
||||
if (!file_priv->has_mmu_faults || file_priv->aborted)
|
||||
continue;
|
||||
|
||||
mutex_lock(&file_priv->lock);
|
||||
ivpu_context_abort_locked(file_priv);
|
||||
file_priv->aborted = true;
|
||||
mutex_unlock(&file_priv->lock);
|
||||
}
|
||||
|
||||
mutex_unlock(&vdev->context_list_lock);
|
||||
}
|
||||
|
||||
static irqreturn_t ivpu_irq_thread_handler(int irq, void *arg)
|
||||
{
|
||||
struct ivpu_device *vdev = arg;
|
||||
@ -459,6 +484,12 @@ static irqreturn_t ivpu_irq_thread_handler(int irq, void *arg)
|
||||
case IVPU_HW_IRQ_SRC_IPC:
|
||||
ivpu_ipc_irq_thread_handler(vdev);
|
||||
break;
|
||||
case IVPU_HW_IRQ_SRC_MMU_EVTQ:
|
||||
ivpu_context_abort_invalid(vdev);
|
||||
break;
|
||||
case IVPU_HW_IRQ_SRC_DCT:
|
||||
ivpu_pm_dct_irq_thread_handler(vdev);
|
||||
break;
|
||||
default:
|
||||
ivpu_err_ratelimited(vdev, "Unknown IRQ source: %u\n", irq_src);
|
||||
break;
|
||||
@ -664,14 +695,14 @@ static void ivpu_bo_unbind_all_user_contexts(struct ivpu_device *vdev)
|
||||
|
||||
static void ivpu_dev_fini(struct ivpu_device *vdev)
|
||||
{
|
||||
ivpu_jobs_abort_all(vdev);
|
||||
ivpu_pm_cancel_recovery(vdev);
|
||||
ivpu_pm_disable(vdev);
|
||||
ivpu_prepare_for_reset(vdev);
|
||||
ivpu_shutdown(vdev);
|
||||
|
||||
ivpu_ms_cleanup_all(vdev);
|
||||
ivpu_jobs_abort_all(vdev);
|
||||
ivpu_job_done_consumer_fini(vdev);
|
||||
ivpu_pm_cancel_recovery(vdev);
|
||||
ivpu_bo_unbind_all_user_contexts(vdev);
|
||||
|
||||
ivpu_ipc_fini(vdev);
|
||||
|
@ -32,6 +32,8 @@
|
||||
#define IVPU_HW_IP_50XX 50
|
||||
#define IVPU_HW_IP_60XX 60
|
||||
|
||||
#define IVPU_HW_IP_REV_LNL_B0 4
|
||||
|
||||
#define IVPU_HW_BTRS_MTL 1
|
||||
#define IVPU_HW_BTRS_LNL 2
|
||||
|
||||
@ -102,6 +104,7 @@ struct ivpu_wa_table {
|
||||
bool interrupt_clear_with_0;
|
||||
bool disable_clock_relinquish;
|
||||
bool disable_d0i3_msg;
|
||||
bool wp0_during_power_up;
|
||||
};
|
||||
|
||||
struct ivpu_hw_info;
|
||||
@ -147,7 +150,6 @@ struct ivpu_device {
|
||||
int boot;
|
||||
int jsm;
|
||||
int tdr;
|
||||
int reschedule_suspend;
|
||||
int autosuspend;
|
||||
int d0i3_entry_msg;
|
||||
} timeout;
|
||||
@ -168,6 +170,7 @@ struct ivpu_file_priv {
|
||||
struct ivpu_bo *ms_info_bo;
|
||||
bool has_mmu_faults;
|
||||
bool bound;
|
||||
bool aborted;
|
||||
};
|
||||
|
||||
extern int ivpu_dbg_mask;
|
||||
@ -184,6 +187,7 @@ extern bool ivpu_force_snoop;
|
||||
#define IVPU_TEST_MODE_D0I3_MSG_ENABLE BIT(5)
|
||||
#define IVPU_TEST_MODE_PREEMPTION_DISABLE BIT(6)
|
||||
#define IVPU_TEST_MODE_HWS_EXTRA_EVENTS BIT(7)
|
||||
#define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8)
|
||||
extern int ivpu_test_mode;
|
||||
|
||||
struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv);
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/firmware.h>
|
||||
@ -123,6 +123,14 @@ ivpu_fw_check_api_ver_lt(struct ivpu_device *vdev, const struct vpu_firmware_hea
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_within_range(u64 addr, size_t size, u64 range_start, size_t range_size)
|
||||
{
|
||||
if (addr < range_start || addr + size > range_start + range_size)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ivpu_fw_parse(struct ivpu_device *vdev)
|
||||
{
|
||||
struct ivpu_fw_info *fw = vdev->fw;
|
||||
@ -205,10 +213,24 @@ static int ivpu_fw_parse(struct ivpu_device *vdev)
|
||||
fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size;
|
||||
fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_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,
|
||||
fw_hdr->image_size)) {
|
||||
ivpu_err(vdev, "Invalid read-only section: start address 0x%llx, size %u\n",
|
||||
fw_hdr->ro_section_start_address, fw_hdr->ro_section_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fw->read_only_addr = fw_hdr->ro_section_start_address;
|
||||
fw->read_only_size = fw_hdr->ro_section_size;
|
||||
|
||||
ivpu_dbg(vdev, FW_BOOT, "Size: file %lu image %u runtime %u shavenn %u\n",
|
||||
fw->file->size, fw->image_size, fw->runtime_size, fw->shave_nn_size);
|
||||
ivpu_dbg(vdev, FW_BOOT, "Address: runtime 0x%llx, load 0x%llx, entry point 0x%llx\n",
|
||||
fw->runtime_addr, image_load_addr, fw->entry_point);
|
||||
ivpu_dbg(vdev, FW_BOOT, "Read-only section: address 0x%llx, size %u\n",
|
||||
fw->read_only_addr, fw->read_only_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -270,6 +292,13 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = ivpu_mmu_context_set_pages_ro(vdev, &vdev->gctx, fw->read_only_addr,
|
||||
fw->read_only_size);
|
||||
if (ret) {
|
||||
ivpu_err(vdev, "Failed to set firmware image read-only\n");
|
||||
goto err_free_fw_mem;
|
||||
}
|
||||
|
||||
fw->mem_log_crit = ivpu_bo_create_global(vdev, IVPU_FW_CRITICAL_BUFFER_SIZE,
|
||||
DRM_IVPU_BO_CACHED | DRM_IVPU_BO_MAPPABLE);
|
||||
if (!fw->mem_log_crit) {
|
||||
|
@ -30,6 +30,8 @@ struct ivpu_fw_info {
|
||||
u32 dvfs_mode;
|
||||
u32 primary_preempt_buf_size;
|
||||
u32 secondary_preempt_buf_size;
|
||||
u64 read_only_addr;
|
||||
u32 read_only_size;
|
||||
};
|
||||
|
||||
int ivpu_fw_init(struct ivpu_device *vdev);
|
||||
|
@ -61,37 +61,48 @@ static void wa_init(struct ivpu_device *vdev)
|
||||
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
|
||||
vdev->wa.interrupt_clear_with_0 = ivpu_hw_btrs_irqs_clear_with_0_mtl(vdev);
|
||||
|
||||
if (ivpu_device_id(vdev) == PCI_DEVICE_ID_LNL)
|
||||
if (ivpu_device_id(vdev) == PCI_DEVICE_ID_LNL &&
|
||||
ivpu_revision(vdev) < IVPU_HW_IP_REV_LNL_B0)
|
||||
vdev->wa.disable_clock_relinquish = true;
|
||||
|
||||
if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
|
||||
vdev->wa.wp0_during_power_up = true;
|
||||
|
||||
IVPU_PRINT_WA(punit_disabled);
|
||||
IVPU_PRINT_WA(clear_runtime_mem);
|
||||
IVPU_PRINT_WA(interrupt_clear_with_0);
|
||||
IVPU_PRINT_WA(disable_clock_relinquish);
|
||||
IVPU_PRINT_WA(wp0_during_power_up);
|
||||
}
|
||||
|
||||
static void timeouts_init(struct ivpu_device *vdev)
|
||||
{
|
||||
if (ivpu_is_fpga(vdev)) {
|
||||
if (ivpu_test_mode & IVPU_TEST_MODE_DISABLE_TIMEOUTS) {
|
||||
vdev->timeout.boot = -1;
|
||||
vdev->timeout.jsm = -1;
|
||||
vdev->timeout.tdr = -1;
|
||||
vdev->timeout.autosuspend = -1;
|
||||
vdev->timeout.d0i3_entry_msg = -1;
|
||||
} else if (ivpu_is_fpga(vdev)) {
|
||||
vdev->timeout.boot = 100000;
|
||||
vdev->timeout.jsm = 50000;
|
||||
vdev->timeout.tdr = 2000000;
|
||||
vdev->timeout.reschedule_suspend = 1000;
|
||||
vdev->timeout.autosuspend = -1;
|
||||
vdev->timeout.d0i3_entry_msg = 500;
|
||||
} else if (ivpu_is_simics(vdev)) {
|
||||
vdev->timeout.boot = 50;
|
||||
vdev->timeout.jsm = 500;
|
||||
vdev->timeout.tdr = 10000;
|
||||
vdev->timeout.reschedule_suspend = 10;
|
||||
vdev->timeout.autosuspend = -1;
|
||||
vdev->timeout.d0i3_entry_msg = 100;
|
||||
} else {
|
||||
vdev->timeout.boot = 1000;
|
||||
vdev->timeout.jsm = 500;
|
||||
vdev->timeout.tdr = 2000;
|
||||
vdev->timeout.reschedule_suspend = 10;
|
||||
vdev->timeout.autosuspend = 10;
|
||||
if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
|
||||
vdev->timeout.autosuspend = 10;
|
||||
else
|
||||
vdev->timeout.autosuspend = 100;
|
||||
vdev->timeout.d0i3_entry_msg = 5;
|
||||
}
|
||||
}
|
||||
@ -125,6 +136,13 @@ int ivpu_hw_power_up(struct ivpu_device *vdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (IVPU_WA(wp0_during_power_up)) {
|
||||
/* WP requests may fail when powering down, so issue WP 0 here */
|
||||
ret = wp_disable(vdev);
|
||||
if (ret)
|
||||
ivpu_warn(vdev, "Failed to disable workpoint: %d\n", ret);
|
||||
}
|
||||
|
||||
ret = ivpu_hw_btrs_d0i3_disable(vdev);
|
||||
if (ret)
|
||||
ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2020 - 2024 Intel Corporation
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __IVPU_HW_H__
|
||||
@ -15,6 +15,8 @@
|
||||
#define IVPU_HW_IRQ_FIFO_LENGTH 1024
|
||||
|
||||
#define IVPU_HW_IRQ_SRC_IPC 1
|
||||
#define IVPU_HW_IRQ_SRC_MMU_EVTQ 2
|
||||
#define IVPU_HW_IRQ_SRC_DCT 3
|
||||
|
||||
struct ivpu_addr_range {
|
||||
resource_size_t start;
|
||||
|
@ -504,6 +504,8 @@ static int ip_reset_lnl(struct ivpu_device *vdev)
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
ivpu_hw_btrs_clock_relinquish_disable_lnl(vdev);
|
||||
|
||||
ret = REGB_POLL_FLD(VPU_HW_BTRS_LNL_IP_RESET, TRIGGER, 0, TIMEOUT_US);
|
||||
if (ret) {
|
||||
ivpu_err(vdev, "Wait for *_TRIGGER timed out\n");
|
||||
@ -641,8 +643,11 @@ bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq)
|
||||
if (!status)
|
||||
return false;
|
||||
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, SURV_ERR, status))
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, SURV_ERR, status)) {
|
||||
ivpu_dbg(vdev, IRQ, "Survivability IRQ\n");
|
||||
if (!kfifo_put(&vdev->hw->irq.fifo, IVPU_HW_IRQ_SRC_DCT))
|
||||
ivpu_err_ratelimited(vdev, "IRQ FIFO full\n");
|
||||
}
|
||||
|
||||
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));
|
||||
@ -692,21 +697,40 @@ bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void dct_drive_40xx(struct ivpu_device *vdev, u32 dct_val)
|
||||
int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable)
|
||||
{
|
||||
u32 val = REGB_RD32(VPU_HW_BTRS_LNL_PCODE_MAILBOX);
|
||||
u32 val = REGB_RD32(VPU_HW_BTRS_LNL_PCODE_MAILBOX_SHADOW);
|
||||
u32 cmd = REG_GET_FLD(VPU_HW_BTRS_LNL_PCODE_MAILBOX_SHADOW, CMD, val);
|
||||
u32 param1 = REG_GET_FLD(VPU_HW_BTRS_LNL_PCODE_MAILBOX_SHADOW, PARAM1, val);
|
||||
|
||||
val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_PCODE_MAILBOX, CMD, DCT_REQ, val);
|
||||
val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_PCODE_MAILBOX, PARAM1,
|
||||
dct_val ? DCT_ENABLE : DCT_DISABLE, val);
|
||||
val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_PCODE_MAILBOX, PARAM2, dct_val, val);
|
||||
if (cmd != DCT_REQ) {
|
||||
ivpu_err_ratelimited(vdev, "Unsupported PCODE command: 0x%x\n", cmd);
|
||||
return -EBADR;
|
||||
}
|
||||
|
||||
REGB_WR32(VPU_HW_BTRS_LNL_PCODE_MAILBOX, val);
|
||||
switch (param1) {
|
||||
case DCT_ENABLE:
|
||||
*enable = true;
|
||||
return 0;
|
||||
case DCT_DISABLE:
|
||||
*enable = false;
|
||||
return 0;
|
||||
default:
|
||||
ivpu_err_ratelimited(vdev, "Invalid PARAM1 value: %u\n", param1);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void ivpu_hw_btrs_dct_drive(struct ivpu_device *vdev, u32 dct_val)
|
||||
void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 active_percent)
|
||||
{
|
||||
return dct_drive_40xx(vdev, dct_val);
|
||||
u32 val = 0;
|
||||
u32 cmd = enable ? DCT_ENABLE : DCT_DISABLE;
|
||||
|
||||
val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS, CMD, DCT_REQ, val);
|
||||
val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS, PARAM1, cmd, val);
|
||||
val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS, PARAM2, active_percent, val);
|
||||
|
||||
REGB_WR32(VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS, val);
|
||||
}
|
||||
|
||||
static u32 pll_ratio_to_freq_mtl(u32 ratio, u32 config)
|
||||
|
@ -15,6 +15,9 @@
|
||||
#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
|
||||
|
||||
int ivpu_hw_btrs_info_init(struct ivpu_device *vdev);
|
||||
void ivpu_hw_btrs_freq_ratios_init(struct ivpu_device *vdev);
|
||||
int ivpu_hw_btrs_irqs_clear_with_0_mtl(struct ivpu_device *vdev);
|
||||
@ -31,7 +34,8 @@ void ivpu_hw_btrs_ats_print_lnl(struct ivpu_device *vdev);
|
||||
void ivpu_hw_btrs_clock_relinquish_disable_lnl(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);
|
||||
void ivpu_hw_btrs_dct_drive(struct ivpu_device *vdev, u32 dct_val);
|
||||
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);
|
||||
|
@ -44,11 +44,11 @@
|
||||
#define VPU_HW_BTRS_LNL_IMR_ERR_CFI1_HIGH 0x0000005cu
|
||||
#define VPU_HW_BTRS_LNL_IMR_ERR_CFI1_CLEAR 0x00000060u
|
||||
|
||||
#define VPU_HW_BTRS_LNL_PCODE_MAILBOX 0x00000070u
|
||||
#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_CMD_MASK GENMASK(7, 0)
|
||||
#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_PARAM1_MASK GENMASK(15, 8)
|
||||
#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_PARAM2_MASK GENMASK(23, 16)
|
||||
#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_PARAM3_MASK GENMASK(31, 24)
|
||||
#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS 0x00000070u
|
||||
#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS_CMD_MASK GENMASK(7, 0)
|
||||
#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS_PARAM1_MASK GENMASK(15, 8)
|
||||
#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS_PARAM2_MASK GENMASK(23, 16)
|
||||
#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS_PARAM3_MASK GENMASK(31, 24)
|
||||
|
||||
#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_SHADOW 0x00000074u
|
||||
#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_SHADOW_CMD_MASK GENMASK(7, 0)
|
||||
|
@ -210,8 +210,7 @@ void ivpu_ipc_consumer_del(struct ivpu_device *vdev, struct ivpu_ipc_consumer *c
|
||||
ivpu_ipc_tx_release(vdev, cons->tx_vpu_addr);
|
||||
}
|
||||
|
||||
static int
|
||||
ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct vpu_jsm_msg *req)
|
||||
int ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct vpu_jsm_msg *req)
|
||||
{
|
||||
struct ivpu_ipc_info *ipc = vdev->ipc;
|
||||
int ret;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __IVPU_IPC_H__
|
||||
@ -96,6 +96,8 @@ void ivpu_ipc_consumer_add(struct ivpu_device *vdev, struct ivpu_ipc_consumer *c
|
||||
u32 channel, ivpu_ipc_rx_callback_t callback);
|
||||
void ivpu_ipc_consumer_del(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons);
|
||||
|
||||
int ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
|
||||
struct vpu_jsm_msg *req);
|
||||
int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
|
||||
struct ivpu_ipc_hdr *ipc_buf, struct vpu_jsm_msg *jsm_msg,
|
||||
unsigned long timeout_ms);
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <drm/drm_file.h>
|
||||
@ -312,6 +312,33 @@ void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev)
|
||||
mutex_unlock(&vdev->context_list_lock);
|
||||
}
|
||||
|
||||
static void ivpu_cmdq_fini_all(struct ivpu_file_priv *file_priv)
|
||||
{
|
||||
u16 engine;
|
||||
u8 priority;
|
||||
|
||||
for (engine = 0; engine < IVPU_NUM_ENGINES; engine++) {
|
||||
for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) {
|
||||
int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority);
|
||||
|
||||
if (file_priv->cmdq[cmdq_idx])
|
||||
ivpu_cmdq_fini(file_priv, file_priv->cmdq[cmdq_idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv)
|
||||
{
|
||||
struct ivpu_device *vdev = file_priv->vdev;
|
||||
|
||||
lockdep_assert_held(&file_priv->lock);
|
||||
|
||||
ivpu_cmdq_fini_all(file_priv);
|
||||
|
||||
if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_OS)
|
||||
ivpu_jsm_context_release(vdev, file_priv->ctx.id);
|
||||
}
|
||||
|
||||
static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job)
|
||||
{
|
||||
struct ivpu_device *vdev = job->vdev;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __IVPU_JOB_H__
|
||||
@ -57,6 +57,8 @@ struct ivpu_job {
|
||||
|
||||
int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
|
||||
|
||||
void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv);
|
||||
|
||||
void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv);
|
||||
void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev);
|
||||
|
||||
|
@ -103,14 +103,10 @@ int ivpu_jsm_register_db(struct ivpu_device *vdev, u32 ctx_id, u32 db_id,
|
||||
|
||||
ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_REGISTER_DB_DONE, &resp,
|
||||
VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
|
||||
if (ret) {
|
||||
ivpu_err_ratelimited(vdev, "Failed to register doorbell %d: %d\n", db_id, ret);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
ivpu_err_ratelimited(vdev, "Failed to register doorbell %u: %d\n", db_id, ret);
|
||||
|
||||
ivpu_dbg(vdev, JSM, "Doorbell %d registered to context %d\n", db_id, ctx_id);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ivpu_jsm_unregister_db(struct ivpu_device *vdev, u32 db_id)
|
||||
@ -123,14 +119,10 @@ int ivpu_jsm_unregister_db(struct ivpu_device *vdev, u32 db_id)
|
||||
|
||||
ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_UNREGISTER_DB_DONE, &resp,
|
||||
VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
|
||||
if (ret) {
|
||||
ivpu_warn_ratelimited(vdev, "Failed to unregister doorbell %d: %d\n", db_id, ret);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
ivpu_warn_ratelimited(vdev, "Failed to unregister doorbell %u: %d\n", db_id, ret);
|
||||
|
||||
ivpu_dbg(vdev, JSM, "Doorbell %d unregistered\n", db_id);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ivpu_jsm_get_heartbeat(struct ivpu_device *vdev, u32 engine, u64 *heartbeat)
|
||||
@ -255,11 +247,16 @@ int ivpu_jsm_context_release(struct ivpu_device *vdev, u32 host_ssid)
|
||||
{
|
||||
struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_SSID_RELEASE };
|
||||
struct vpu_jsm_msg resp;
|
||||
int ret;
|
||||
|
||||
req.payload.ssid_release.host_ssid = host_ssid;
|
||||
|
||||
return ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_SSID_RELEASE_DONE, &resp,
|
||||
VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
|
||||
ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_SSID_RELEASE_DONE, &resp,
|
||||
VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
|
||||
if (ret)
|
||||
ivpu_warn_ratelimited(vdev, "Failed to release context: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ivpu_jsm_pwr_d0i3_enter(struct ivpu_device *vdev)
|
||||
@ -538,3 +535,26 @@ int ivpu_jsm_metric_streamer_info(struct ivpu_device *vdev, u64 metric_group_mas
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ivpu_jsm_dct_enable(struct ivpu_device *vdev, u32 active_us, u32 inactive_us)
|
||||
{
|
||||
struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_DCT_ENABLE };
|
||||
struct vpu_jsm_msg resp;
|
||||
|
||||
req.payload.pwr_dct_control.dct_active_us = active_us;
|
||||
req.payload.pwr_dct_control.dct_inactive_us = inactive_us;
|
||||
|
||||
return ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_DCT_ENABLE_DONE,
|
||||
&resp, VPU_IPC_CHAN_ASYNC_CMD,
|
||||
vdev->timeout.jsm);
|
||||
}
|
||||
|
||||
int ivpu_jsm_dct_disable(struct ivpu_device *vdev)
|
||||
{
|
||||
struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_DCT_DISABLE };
|
||||
struct vpu_jsm_msg resp;
|
||||
|
||||
return ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_DCT_DISABLE_DONE,
|
||||
&resp, VPU_IPC_CHAN_ASYNC_CMD,
|
||||
vdev->timeout.jsm);
|
||||
}
|
||||
|
@ -41,4 +41,6 @@ int ivpu_jsm_metric_streamer_update(struct ivpu_device *vdev, u64 metric_group_m
|
||||
u64 buffer_addr, u64 buffer_size, u64 *bytes_written);
|
||||
int ivpu_jsm_metric_streamer_info(struct ivpu_device *vdev, u64 metric_group_mask, u64 buffer_addr,
|
||||
u64 buffer_size, u32 *sample_size, u64 *info_size);
|
||||
int ivpu_jsm_dct_enable(struct ivpu_device *vdev, u32 active_us, u32 inactive_us);
|
||||
int ivpu_jsm_dct_disable(struct ivpu_device *vdev);
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/circ_buf.h>
|
||||
@ -878,8 +878,9 @@ static void ivpu_mmu_dump_event(struct ivpu_device *vdev, u32 *event)
|
||||
u64 in_addr = ((u64)event[5]) << 32 | event[4];
|
||||
u32 sid = event[1];
|
||||
|
||||
ivpu_err(vdev, "MMU EVTQ: 0x%x (%s) SSID: %d SID: %d, e[2] %08x, e[3] %08x, in addr: 0x%llx, fetch addr: 0x%llx\n",
|
||||
op, ivpu_mmu_event_to_str(op), ssid, sid, event[2], event[3], in_addr, fetch_addr);
|
||||
ivpu_err_ratelimited(vdev, "MMU EVTQ: 0x%x (%s) SSID: %d SID: %d, e[2] %08x, e[3] %08x, in addr: 0x%llx, fetch addr: 0x%llx\n",
|
||||
op, ivpu_mmu_event_to_str(op), ssid, sid,
|
||||
event[2], event[3], in_addr, fetch_addr);
|
||||
}
|
||||
|
||||
static u32 *ivpu_mmu_get_event(struct ivpu_device *vdev)
|
||||
@ -915,6 +916,9 @@ void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev)
|
||||
ivpu_mmu_user_context_mark_invalid(vdev, ssid);
|
||||
REGV_WR32(IVPU_MMU_REG_EVTQ_CONS_SEC, vdev->mmu->evtq.cons);
|
||||
}
|
||||
|
||||
if (!kfifo_put(&vdev->hw->irq.fifo, IVPU_HW_IRQ_SRC_MMU_EVTQ))
|
||||
ivpu_err_ratelimited(vdev, "IRQ FIFO full\n");
|
||||
}
|
||||
|
||||
void ivpu_mmu_evtq_dump(struct ivpu_device *vdev)
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define IVPU_MMU_ENTRY_FLAG_CONT BIT(52)
|
||||
#define IVPU_MMU_ENTRY_FLAG_NG BIT(11)
|
||||
#define IVPU_MMU_ENTRY_FLAG_AF BIT(10)
|
||||
#define IVPU_MMU_ENTRY_FLAG_RO BIT(7)
|
||||
#define IVPU_MMU_ENTRY_FLAG_USER BIT(6)
|
||||
#define IVPU_MMU_ENTRY_FLAG_LLC_COHERENT BIT(2)
|
||||
#define IVPU_MMU_ENTRY_FLAG_TYPE_PAGE BIT(1)
|
||||
@ -319,6 +320,91 @@ ivpu_mmu_context_map_pages(struct ivpu_device *vdev, struct ivpu_mmu_context *ct
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ivpu_mmu_context_set_page_ro(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
|
||||
u64 vpu_addr)
|
||||
{
|
||||
int pgd_idx = FIELD_GET(IVPU_MMU_PGD_INDEX_MASK, vpu_addr);
|
||||
int pud_idx = FIELD_GET(IVPU_MMU_PUD_INDEX_MASK, vpu_addr);
|
||||
int pmd_idx = FIELD_GET(IVPU_MMU_PMD_INDEX_MASK, vpu_addr);
|
||||
int pte_idx = FIELD_GET(IVPU_MMU_PTE_INDEX_MASK, vpu_addr);
|
||||
|
||||
ctx->pgtable.pte_ptrs[pgd_idx][pud_idx][pmd_idx][pte_idx] |= IVPU_MMU_ENTRY_FLAG_RO;
|
||||
}
|
||||
|
||||
static void ivpu_mmu_context_split_page(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
|
||||
u64 vpu_addr)
|
||||
{
|
||||
int pgd_idx = FIELD_GET(IVPU_MMU_PGD_INDEX_MASK, vpu_addr);
|
||||
int pud_idx = FIELD_GET(IVPU_MMU_PUD_INDEX_MASK, vpu_addr);
|
||||
int pmd_idx = FIELD_GET(IVPU_MMU_PMD_INDEX_MASK, vpu_addr);
|
||||
int pte_idx = FIELD_GET(IVPU_MMU_PTE_INDEX_MASK, vpu_addr);
|
||||
|
||||
ctx->pgtable.pte_ptrs[pgd_idx][pud_idx][pmd_idx][pte_idx] &= ~IVPU_MMU_ENTRY_FLAG_CONT;
|
||||
}
|
||||
|
||||
static void ivpu_mmu_context_split_64k_page(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
|
||||
u64 vpu_addr)
|
||||
{
|
||||
u64 start = ALIGN_DOWN(vpu_addr, IVPU_MMU_CONT_PAGES_SIZE);
|
||||
u64 end = ALIGN(vpu_addr, IVPU_MMU_CONT_PAGES_SIZE);
|
||||
u64 offset = 0;
|
||||
|
||||
ivpu_dbg(vdev, MMU_MAP, "Split 64K page ctx: %u vpu_addr: 0x%llx\n", ctx->id, vpu_addr);
|
||||
|
||||
while (start + offset < end) {
|
||||
ivpu_mmu_context_split_page(vdev, ctx, start + offset);
|
||||
offset += IVPU_MMU_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ivpu_mmu_context_set_pages_ro(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u64 vpu_addr,
|
||||
size_t size)
|
||||
{
|
||||
u64 end = vpu_addr + size;
|
||||
size_t size_left = size;
|
||||
int ret;
|
||||
|
||||
if (size == 0)
|
||||
return 0;
|
||||
|
||||
if (drm_WARN_ON(&vdev->drm, !IS_ALIGNED(vpu_addr | size, IVPU_MMU_PAGE_SIZE)))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
|
||||
ivpu_dbg(vdev, MMU_MAP, "Set read-only pages ctx: %u vpu_addr: 0x%llx size: %lu\n",
|
||||
ctx->id, vpu_addr, size);
|
||||
|
||||
if (!ivpu_disable_mmu_cont_pages) {
|
||||
/* Split 64K contiguous page at the beginning if needed */
|
||||
if (!IS_ALIGNED(vpu_addr, IVPU_MMU_CONT_PAGES_SIZE))
|
||||
ivpu_mmu_context_split_64k_page(vdev, ctx, vpu_addr);
|
||||
|
||||
/* Split 64K contiguous page at the end if needed */
|
||||
if (!IS_ALIGNED(vpu_addr + size, IVPU_MMU_CONT_PAGES_SIZE))
|
||||
ivpu_mmu_context_split_64k_page(vdev, ctx, vpu_addr + size);
|
||||
}
|
||||
|
||||
while (size_left) {
|
||||
if (vpu_addr < end)
|
||||
ivpu_mmu_context_set_page_ro(vdev, ctx, vpu_addr);
|
||||
|
||||
vpu_addr += IVPU_MMU_PAGE_SIZE;
|
||||
size_left -= IVPU_MMU_PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* Ensure page table modifications are flushed from wc buffers to memory */
|
||||
wmb();
|
||||
|
||||
mutex_unlock(&ctx->lock);
|
||||
ret = ivpu_mmu_invalidate_tlb(vdev, ctx->id);
|
||||
if (ret)
|
||||
ivpu_err(vdev, "Failed to invalidate TLB for ctx %u: %d\n", ctx->id, ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ivpu_mmu_context_unmap_pages(struct ivpu_mmu_context *ctx, u64 vpu_addr, size_t size)
|
||||
{
|
||||
while (size) {
|
||||
|
@ -46,5 +46,7 @@ int ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *
|
||||
u64 vpu_addr, struct sg_table *sgt, bool llc_coherent);
|
||||
void ivpu_mmu_context_unmap_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
|
||||
u64 vpu_addr, struct sg_table *sgt);
|
||||
int ivpu_mmu_context_set_pages_ro(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
|
||||
u64 vpu_addr, size_t size);
|
||||
|
||||
#endif /* __IVPU_MMU_CONTEXT_H__ */
|
||||
|
@ -237,33 +237,30 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm = dev_get_drvdata(dev);
|
||||
struct ivpu_device *vdev = to_ivpu_device(drm);
|
||||
bool hw_is_idle = true;
|
||||
int ret;
|
||||
int ret, ret_d0i3;
|
||||
bool is_idle;
|
||||
|
||||
drm_WARN_ON(&vdev->drm, !xa_empty(&vdev->submitted_jobs_xa));
|
||||
drm_WARN_ON(&vdev->drm, work_pending(&vdev->pm->recovery_work));
|
||||
|
||||
ivpu_dbg(vdev, PM, "Runtime suspend..\n");
|
||||
|
||||
if (!ivpu_hw_is_idle(vdev) && vdev->pm->suspend_reschedule_counter) {
|
||||
ivpu_dbg(vdev, PM, "Failed to enter idle, rescheduling suspend, retries left %d\n",
|
||||
vdev->pm->suspend_reschedule_counter);
|
||||
pm_schedule_suspend(dev, vdev->timeout.reschedule_suspend);
|
||||
vdev->pm->suspend_reschedule_counter--;
|
||||
return -EAGAIN;
|
||||
}
|
||||
ivpu_mmu_disable(vdev);
|
||||
|
||||
if (!vdev->pm->suspend_reschedule_counter)
|
||||
hw_is_idle = false;
|
||||
else if (ivpu_jsm_pwr_d0i3_enter(vdev))
|
||||
hw_is_idle = false;
|
||||
is_idle = ivpu_hw_is_idle(vdev) || vdev->pm->dct_active_percent;
|
||||
if (!is_idle)
|
||||
ivpu_err(vdev, "NPU is not idle before autosuspend\n");
|
||||
|
||||
ret_d0i3 = ivpu_jsm_pwr_d0i3_enter(vdev);
|
||||
if (ret_d0i3)
|
||||
ivpu_err(vdev, "Failed to prepare for d0i3: %d\n", ret_d0i3);
|
||||
|
||||
ret = ivpu_suspend(vdev);
|
||||
if (ret)
|
||||
ivpu_err(vdev, "Failed to suspend NPU: %d\n", ret);
|
||||
|
||||
if (!hw_is_idle) {
|
||||
ivpu_err(vdev, "NPU failed to enter idle, force suspended.\n");
|
||||
if (!is_idle || ret_d0i3) {
|
||||
ivpu_err(vdev, "Forcing cold boot due to previous errors\n");
|
||||
atomic_inc(&vdev->pm->reset_counter);
|
||||
ivpu_fw_log_dump(vdev);
|
||||
ivpu_pm_prepare_cold_boot(vdev);
|
||||
@ -271,8 +268,6 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev)
|
||||
ivpu_pm_prepare_warm_boot(vdev);
|
||||
}
|
||||
|
||||
vdev->pm->suspend_reschedule_counter = PM_RESCHEDULE_LIMIT;
|
||||
|
||||
ivpu_dbg(vdev, PM, "Runtime suspend done.\n");
|
||||
|
||||
return 0;
|
||||
@ -300,17 +295,6 @@ int ivpu_rpm_get(struct ivpu_device *vdev)
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(vdev->drm.dev);
|
||||
if (!drm_WARN_ON(&vdev->drm, ret < 0))
|
||||
vdev->pm->suspend_reschedule_counter = PM_RESCHEDULE_LIMIT;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ivpu_rpm_get_if_active(struct ivpu_device *vdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_if_in_use(vdev->drm.dev);
|
||||
drm_WARN_ON(&vdev->drm, ret < 0);
|
||||
|
||||
return ret;
|
||||
@ -365,7 +349,6 @@ void ivpu_pm_init(struct ivpu_device *vdev)
|
||||
int delay;
|
||||
|
||||
pm->vdev = vdev;
|
||||
pm->suspend_reschedule_counter = PM_RESCHEDULE_LIMIT;
|
||||
|
||||
init_rwsem(&pm->reset_lock);
|
||||
atomic_set(&pm->reset_pending, 0);
|
||||
@ -406,3 +389,68 @@ void ivpu_pm_disable(struct ivpu_device *vdev)
|
||||
pm_runtime_get_noresume(vdev->drm.dev);
|
||||
pm_runtime_forbid(vdev->drm.dev);
|
||||
}
|
||||
|
||||
int ivpu_pm_dct_init(struct ivpu_device *vdev)
|
||||
{
|
||||
if (vdev->pm->dct_active_percent)
|
||||
return ivpu_pm_dct_enable(vdev, vdev->pm->dct_active_percent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ivpu_pm_dct_enable(struct ivpu_device *vdev, u8 active_percent)
|
||||
{
|
||||
u32 active_us, inactive_us;
|
||||
int ret;
|
||||
|
||||
if (active_percent == 0 || active_percent > 100)
|
||||
return -EINVAL;
|
||||
|
||||
active_us = (DCT_PERIOD_US * active_percent) / 100;
|
||||
inactive_us = DCT_PERIOD_US - active_us;
|
||||
|
||||
ret = ivpu_jsm_dct_enable(vdev, active_us, inactive_us);
|
||||
if (ret) {
|
||||
ivpu_err_ratelimited(vdev, "Filed to enable DCT: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vdev->pm->dct_active_percent = active_percent;
|
||||
|
||||
ivpu_dbg(vdev, PM, "DCT set to %u%% (D0: %uus, D0i2: %uus)\n",
|
||||
active_percent, active_us, inactive_us);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ivpu_pm_dct_disable(struct ivpu_device *vdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ivpu_jsm_dct_disable(vdev);
|
||||
if (ret) {
|
||||
ivpu_err_ratelimited(vdev, "Filed to disable DCT: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vdev->pm->dct_active_percent = 0;
|
||||
|
||||
ivpu_dbg(vdev, PM, "DCT disabled\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ivpu_pm_dct_irq_thread_handler(struct ivpu_device *vdev)
|
||||
{
|
||||
bool enable;
|
||||
int ret;
|
||||
|
||||
if (ivpu_hw_btrs_dct_get_request(vdev, &enable))
|
||||
return;
|
||||
|
||||
if (vdev->pm->dct_active_percent)
|
||||
ret = ivpu_pm_dct_enable(vdev, DCT_DEFAULT_ACTIVE_PERCENT);
|
||||
else
|
||||
ret = ivpu_pm_dct_disable(vdev);
|
||||
|
||||
if (!ret)
|
||||
ivpu_hw_btrs_dct_set_status(vdev, enable, vdev->pm->dct_active_percent);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __IVPU_PM_H__
|
||||
@ -19,7 +19,7 @@ struct ivpu_pm_info {
|
||||
atomic_t reset_counter;
|
||||
atomic_t reset_pending;
|
||||
bool is_warmboot;
|
||||
u32 suspend_reschedule_counter;
|
||||
u8 dct_active_percent;
|
||||
};
|
||||
|
||||
void ivpu_pm_init(struct ivpu_device *vdev);
|
||||
@ -36,11 +36,15 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev);
|
||||
void ivpu_pm_reset_done_cb(struct pci_dev *pdev);
|
||||
|
||||
int __must_check ivpu_rpm_get(struct ivpu_device *vdev);
|
||||
int __must_check ivpu_rpm_get_if_active(struct ivpu_device *vdev);
|
||||
void ivpu_rpm_put(struct ivpu_device *vdev);
|
||||
|
||||
void ivpu_pm_trigger_recovery(struct ivpu_device *vdev, const char *reason);
|
||||
void ivpu_start_job_timeout_detection(struct ivpu_device *vdev);
|
||||
void ivpu_stop_job_timeout_detection(struct ivpu_device *vdev);
|
||||
|
||||
int ivpu_pm_dct_init(struct ivpu_device *vdev);
|
||||
int ivpu_pm_dct_enable(struct ivpu_device *vdev, u8 active_percent);
|
||||
int ivpu_pm_dct_disable(struct ivpu_device *vdev);
|
||||
void ivpu_pm_dct_irq_thread_handler(struct ivpu_device *vdev);
|
||||
|
||||
#endif /* __IVPU_PM_H__ */
|
||||
|
@ -27,7 +27,7 @@
|
||||
* Minor version changes when API backward compatibility is preserved.
|
||||
* Resets to 0 if Major version is incremented.
|
||||
*/
|
||||
#define VPU_BOOT_API_VER_MINOR 22
|
||||
#define VPU_BOOT_API_VER_MINOR 24
|
||||
|
||||
/*
|
||||
* API header changed (field names, documentation, formatting) but API itself has not been changed
|
||||
@ -80,6 +80,11 @@ struct vpu_firmware_header {
|
||||
u32 preemption_buffer_2_size;
|
||||
/* Space reserved for future preemption-related fields. */
|
||||
u32 preemption_reserved[6];
|
||||
/* FW image read only section start address, 4KB aligned */
|
||||
u64 ro_section_start_address;
|
||||
/* FW image read only section size, 4KB aligned */
|
||||
u32 ro_section_size;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -333,7 +338,14 @@ struct vpu_boot_params {
|
||||
* The KMD is required to update this value on every VPU reset.
|
||||
*/
|
||||
u64 system_time_us;
|
||||
u32 pad4[18];
|
||||
u32 pad4[2];
|
||||
/*
|
||||
* The delta between device monotonic time and the current value of the
|
||||
* HW timestamp register, in ticks. Written by the firmware during boot.
|
||||
* Can be used by the KMD to calculate device time.
|
||||
*/
|
||||
u64 device_time_delta_ticks;
|
||||
u32 pad7[14];
|
||||
/* Warm boot information: 0x400 - 0x43F */
|
||||
u32 warm_boot_sections_count;
|
||||
u32 warm_boot_start_address_reference;
|
||||
|
@ -274,8 +274,8 @@ static const struct dma_buf_ops cma_heap_buf_ops = {
|
||||
|
||||
static struct dma_buf *cma_heap_allocate(struct dma_heap *heap,
|
||||
unsigned long len,
|
||||
unsigned long fd_flags,
|
||||
unsigned long heap_flags)
|
||||
u32 fd_flags,
|
||||
u64 heap_flags)
|
||||
{
|
||||
struct cma_heap *cma_heap = dma_heap_get_drvdata(heap);
|
||||
struct cma_heap_buffer *buffer;
|
||||
|
@ -333,8 +333,8 @@ static struct page *alloc_largest_available(unsigned long size,
|
||||
|
||||
static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
|
||||
unsigned long len,
|
||||
unsigned long fd_flags,
|
||||
unsigned long heap_flags)
|
||||
u32 fd_flags,
|
||||
u64 heap_flags)
|
||||
{
|
||||
struct system_heap_buffer *buffer;
|
||||
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
|
||||
|
@ -107,7 +107,7 @@ config DRM_KMS_HELPER
|
||||
|
||||
config DRM_PANIC
|
||||
bool "Display a user-friendly message when a kernel panic occurs"
|
||||
depends on DRM && !FRAMEBUFFER_CONSOLE
|
||||
depends on DRM && !(FRAMEBUFFER_CONSOLE && VT_CONSOLE)
|
||||
select DRM_KMS_HELPER
|
||||
select FONT_SUPPORT
|
||||
help
|
||||
|
@ -163,6 +163,14 @@
|
||||
|
||||
#define SII902X_AUDIO_PORT_INDEX 3
|
||||
|
||||
/*
|
||||
* The maximum resolution supported by the HDMI bridge is 1080p@60Hz
|
||||
* and 1920x1200 requiring a pixel clock of 165MHz and the minimum
|
||||
* resolution supported is 480p@60Hz requiring a pixel clock of 25MHz
|
||||
*/
|
||||
#define SII902X_MIN_PIXEL_CLOCK_KHZ 25000
|
||||
#define SII902X_MAX_PIXEL_CLOCK_KHZ 165000
|
||||
|
||||
struct sii902x {
|
||||
struct i2c_client *i2c;
|
||||
struct regmap *regmap;
|
||||
@ -310,20 +318,12 @@ static int sii902x_get_modes(struct drm_connector *connector)
|
||||
return num;
|
||||
}
|
||||
|
||||
static enum drm_mode_status sii902x_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
/* TODO: check mode */
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
static const struct drm_connector_helper_funcs sii902x_connector_helper_funcs = {
|
||||
.get_modes = sii902x_get_modes,
|
||||
.mode_valid = sii902x_mode_valid,
|
||||
};
|
||||
|
||||
static void sii902x_bridge_disable(struct drm_bridge *bridge)
|
||||
static void sii902x_bridge_atomic_disable(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_bridge_state)
|
||||
{
|
||||
struct sii902x *sii902x = bridge_to_sii902x(bridge);
|
||||
|
||||
@ -336,7 +336,8 @@ static void sii902x_bridge_disable(struct drm_bridge *bridge)
|
||||
mutex_unlock(&sii902x->mutex);
|
||||
}
|
||||
|
||||
static void sii902x_bridge_enable(struct drm_bridge *bridge)
|
||||
static void sii902x_bridge_atomic_enable(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_bridge_state)
|
||||
{
|
||||
struct sii902x *sii902x = bridge_to_sii902x(bridge);
|
||||
|
||||
@ -495,6 +496,10 @@ static int sii902x_bridge_atomic_check(struct drm_bridge *bridge,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
if (crtc_state->mode.clock < SII902X_MIN_PIXEL_CLOCK_KHZ ||
|
||||
crtc_state->mode.clock > SII902X_MAX_PIXEL_CLOCK_KHZ)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* There might be flags negotiation supported in future but
|
||||
* set the bus flags in atomic_check statically for now.
|
||||
@ -504,11 +509,25 @@ static int sii902x_bridge_atomic_check(struct drm_bridge *bridge,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
sii902x_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
if (mode->clock < SII902X_MIN_PIXEL_CLOCK_KHZ)
|
||||
return MODE_CLOCK_LOW;
|
||||
|
||||
if (mode->clock > SII902X_MAX_PIXEL_CLOCK_KHZ)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs sii902x_bridge_funcs = {
|
||||
.attach = sii902x_bridge_attach,
|
||||
.mode_set = sii902x_bridge_mode_set,
|
||||
.disable = sii902x_bridge_disable,
|
||||
.enable = sii902x_bridge_enable,
|
||||
.atomic_disable = sii902x_bridge_atomic_disable,
|
||||
.atomic_enable = sii902x_bridge_atomic_enable,
|
||||
.detect = sii902x_bridge_detect,
|
||||
.edid_read = sii902x_bridge_edid_read,
|
||||
.atomic_reset = drm_atomic_helper_bridge_reset,
|
||||
@ -516,6 +535,7 @@ static const struct drm_bridge_funcs sii902x_bridge_funcs = {
|
||||
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
|
||||
.atomic_get_input_bus_fmts = sii902x_bridge_atomic_get_input_bus_fmts,
|
||||
.atomic_check = sii902x_bridge_atomic_check,
|
||||
.mode_valid = sii902x_bridge_mode_valid,
|
||||
};
|
||||
|
||||
static int sii902x_mute(struct sii902x *sii902x, bool mute)
|
||||
|
@ -170,7 +170,6 @@ static int simple_bridge_probe(struct platform_device *pdev)
|
||||
sbridge = devm_kzalloc(&pdev->dev, sizeof(*sbridge), GFP_KERNEL);
|
||||
if (!sbridge)
|
||||
return -ENOMEM;
|
||||
platform_set_drvdata(pdev, sbridge);
|
||||
|
||||
sbridge->info = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
@ -208,16 +207,7 @@ static int simple_bridge_probe(struct platform_device *pdev)
|
||||
sbridge->bridge.of_node = pdev->dev.of_node;
|
||||
sbridge->bridge.timings = sbridge->info->timings;
|
||||
|
||||
drm_bridge_add(&sbridge->bridge);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void simple_bridge_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct simple_bridge *sbridge = platform_get_drvdata(pdev);
|
||||
|
||||
drm_bridge_remove(&sbridge->bridge);
|
||||
return devm_drm_bridge_add(&pdev->dev, &sbridge->bridge);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -294,7 +284,6 @@ MODULE_DEVICE_TABLE(of, simple_bridge_match);
|
||||
|
||||
static struct platform_driver simple_bridge_driver = {
|
||||
.probe = simple_bridge_probe,
|
||||
.remove_new = simple_bridge_remove,
|
||||
.driver = {
|
||||
.name = "simple-bridge",
|
||||
.of_match_table = simple_bridge_match,
|
||||
|
@ -160,7 +160,6 @@ fi
|
||||
|
||||
mkdir -p artifacts/install/lib
|
||||
mv install/* artifacts/install/.
|
||||
rm -rf artifacts/install/modules
|
||||
ln -s common artifacts/install/ci-common
|
||||
cp .config artifacts/${CI_JOB_NAME}_config
|
||||
|
||||
|
@ -123,6 +123,7 @@ stages:
|
||||
- msm
|
||||
- rockchip
|
||||
- virtio-gpu
|
||||
- software-driver
|
||||
|
||||
# YAML anchors for rule conditions
|
||||
# --------------------------------
|
||||
|
@ -30,10 +30,10 @@ case "$DRIVER_NAME" in
|
||||
export IGT_FORCE_DRIVER="panfrost"
|
||||
fi
|
||||
;;
|
||||
amdgpu)
|
||||
amdgpu|vkms)
|
||||
# Cannot use HWCI_KERNEL_MODULES as at that point we don't have the module in /lib
|
||||
mv /install/modules/lib/modules/* /lib/modules/.
|
||||
modprobe amdgpu
|
||||
mv /install/modules/lib/modules/* /lib/modules/. || true
|
||||
modprobe --first-time $DRIVER_NAME
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -4,7 +4,7 @@ variables:
|
||||
DEBIAN_BASE_TAG: "${CONTAINER_TAG}"
|
||||
|
||||
DEBIAN_X86_64_BUILD_IMAGE_PATH: "debian/x86_64_build"
|
||||
DEBIAN_BUILD_TAG: "2023-10-08-config"
|
||||
DEBIAN_BUILD_TAG: "2024-06-10-vkms"
|
||||
|
||||
KERNEL_ROOTFS_TAG: "2023-10-06-amd"
|
||||
|
||||
|
@ -338,7 +338,7 @@ meson:g12b:
|
||||
RUNNER_TAG: mesa-ci-x86-64-lava-meson-g12b-a311d-khadas-vim3
|
||||
|
||||
virtio_gpu:none:
|
||||
stage: virtio-gpu
|
||||
stage: software-driver
|
||||
variables:
|
||||
CROSVM_GALLIUM_DRIVER: llvmpipe
|
||||
DRIVER_NAME: virtio_gpu
|
||||
@ -358,3 +358,25 @@ virtio_gpu:none:
|
||||
- debian/x86_64_test-gl
|
||||
- testing:x86_64
|
||||
- igt:x86_64
|
||||
|
||||
vkms:none:
|
||||
stage: software-driver
|
||||
variables:
|
||||
DRIVER_NAME: vkms
|
||||
GPU_VERSION: none
|
||||
extends:
|
||||
- .test-gl
|
||||
- .test-rules
|
||||
tags:
|
||||
- kvm
|
||||
script:
|
||||
- ln -sf $CI_PROJECT_DIR/install /install
|
||||
- mv install/bzImage /lava-files/bzImage
|
||||
- mkdir -p /lib/modules
|
||||
- mkdir -p $CI_PROJECT_DIR/results
|
||||
- ln -sf $CI_PROJECT_DIR/results /results
|
||||
- ./install/crosvm-runner.sh ./install/igt_runner.sh
|
||||
needs:
|
||||
- debian/x86_64_test-gl
|
||||
- testing:x86_64
|
||||
- igt:x86_64
|
||||
|
@ -24,6 +24,7 @@ CONFIG_DRM=y
|
||||
CONFIG_DRM_PANEL_SIMPLE=y
|
||||
CONFIG_PWM_CROS_EC=y
|
||||
CONFIG_BACKLIGHT_PWM=y
|
||||
CONFIG_DRM_VKMS=m
|
||||
|
||||
# Strip out some stuff we don't need for graphics testing, to reduce
|
||||
# the build.
|
||||
|
@ -4,7 +4,6 @@ device_reset@unbind-cold-reset-rebind,Fail
|
||||
device_reset@unbind-reset-rebind,Fail
|
||||
dumb_buffer@invalid-bpp,Fail
|
||||
kms_3d,Fail
|
||||
kms_addfb_basic@addfb25-bad-modifier,Fail
|
||||
kms_cursor_legacy@forked-move,Fail
|
||||
kms_cursor_legacy@single-bo,Fail
|
||||
kms_cursor_legacy@torture-bo,Fail
|
||||
|
@ -4,6 +4,5 @@ device_reset@unbind-cold-reset-rebind,Fail
|
||||
device_reset@unbind-reset-rebind,Fail
|
||||
dumb_buffer@invalid-bpp,Fail
|
||||
kms_3d,Fail
|
||||
kms_addfb_basic@addfb25-bad-modifier,Fail
|
||||
kms_lease@lease-uevent,Fail
|
||||
tools_test@tools_test,Fail
|
||||
|
57
drivers/gpu/drm/ci/xfails/vkms-none-fails.txt
Normal file
57
drivers/gpu/drm/ci/xfails/vkms-none-fails.txt
Normal file
@ -0,0 +1,57 @@
|
||||
core_hotunplug@hotrebind,Fail
|
||||
core_hotunplug@hotrebind-lateclose,Fail
|
||||
core_hotunplug@hotreplug,Fail
|
||||
core_hotunplug@hotreplug-lateclose,Fail
|
||||
core_hotunplug@hotunbind-rebind,Fail
|
||||
core_hotunplug@hotunplug-rescan,Fail
|
||||
core_hotunplug@unbind-rebind,Fail
|
||||
core_hotunplug@unplug-rescan,Fail
|
||||
device_reset@cold-reset-bound,Fail
|
||||
device_reset@reset-bound,Fail
|
||||
device_reset@unbind-cold-reset-rebind,Fail
|
||||
device_reset@unbind-reset-rebind,Fail
|
||||
dumb_buffer@invalid-bpp,Fail
|
||||
kms_content_protection@atomic,Crash
|
||||
kms_content_protection@atomic-dpms,Crash
|
||||
kms_content_protection@content-type-change,Crash
|
||||
kms_content_protection@lic-type-0,Crash
|
||||
kms_content_protection@lic-type-1,Crash
|
||||
kms_content_protection@srm,Crash
|
||||
kms_content_protection@type1,Crash
|
||||
kms_content_protection@uevent,Crash
|
||||
kms_cursor_crc@cursor-rapid-movement-128x128,Fail
|
||||
kms_cursor_crc@cursor-rapid-movement-128x42,Fail
|
||||
kms_cursor_crc@cursor-rapid-movement-256x256,Fail
|
||||
kms_cursor_crc@cursor-rapid-movement-256x85,Fail
|
||||
kms_cursor_crc@cursor-rapid-movement-32x10,Fail
|
||||
kms_cursor_crc@cursor-rapid-movement-32x32,Fail
|
||||
kms_cursor_crc@cursor-rapid-movement-512x170,Fail
|
||||
kms_cursor_crc@cursor-rapid-movement-512x512,Fail
|
||||
kms_cursor_crc@cursor-rapid-movement-64x21,Fail
|
||||
kms_cursor_crc@cursor-rapid-movement-64x64,Fail
|
||||
kms_cursor_legacy@basic-flip-before-cursor-atomic,Fail
|
||||
kms_cursor_legacy@basic-flip-before-cursor-legacy,Fail
|
||||
kms_cursor_legacy@cursor-vs-flip-atomic,Fail
|
||||
kms_cursor_legacy@cursor-vs-flip-legacy,Fail
|
||||
kms_cursor_legacy@cursor-vs-flip-toggle,Fail
|
||||
kms_cursor_legacy@cursor-vs-flip-varying-size,Fail
|
||||
kms_cursor_legacy@flip-vs-cursor-atomic,Fail
|
||||
kms_cursor_legacy@flip-vs-cursor-crc-atomic,Fail
|
||||
kms_cursor_legacy@flip-vs-cursor-crc-legacy,Fail
|
||||
kms_cursor_legacy@flip-vs-cursor-legacy,Fail
|
||||
kms_flip@flip-vs-modeset-vs-hang,Fail
|
||||
kms_flip@flip-vs-panning-vs-hang,Fail
|
||||
kms_flip@flip-vs-suspend,Timeout
|
||||
kms_flip@flip-vs-suspend-interruptible,Timeout
|
||||
kms_flip@plain-flip-fb-recreate,Fail
|
||||
kms_lease@lease-uevent,Fail
|
||||
kms_pipe_crc_basic@nonblocking-crc,Fail
|
||||
kms_pipe_crc_basic@nonblocking-crc-frame-sequence,Fail
|
||||
kms_writeback@writeback-check-output,Fail
|
||||
kms_writeback@writeback-check-output-XRGB2101010,Fail
|
||||
kms_writeback@writeback-fb-id,Fail
|
||||
kms_writeback@writeback-fb-id-XRGB2101010,Fail
|
||||
kms_writeback@writeback-invalid-parameters,Fail
|
||||
kms_writeback@writeback-pixel-formats,Fail
|
||||
perf@i915-ref-count,Fail
|
||||
tools_test@tools_test,Fail
|
69
drivers/gpu/drm/ci/xfails/vkms-none-flakes.txt
Normal file
69
drivers/gpu/drm/ci/xfails/vkms-none-flakes.txt
Normal file
@ -0,0 +1,69 @@
|
||||
# Board Name: vkms
|
||||
# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
|
||||
# Failure Rate: 50
|
||||
# IGT Version: 1.28-g0df7b9b97
|
||||
# Linux Version: 6.9.0-rc7
|
||||
kms_cursor_legacy@long-nonblocking-modeset-vs-cursor-atomic
|
||||
|
||||
# Board Name: vkms
|
||||
# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
|
||||
# Failure Rate: 50
|
||||
# IGT Version: 1.28-g0df7b9b97
|
||||
# Linux Version: 6.9.0-rc7
|
||||
kms_flip@basic-flip-vs-wf_vblank
|
||||
|
||||
# Board Name: vkms
|
||||
# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
|
||||
# Failure Rate: 50
|
||||
# IGT Version: 1.28-g0df7b9b97
|
||||
# Linux Version: 6.9.0-rc7
|
||||
kms_flip@flip-vs-expired-vblank-interruptible
|
||||
|
||||
# Board Name: vkms
|
||||
# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
|
||||
# Failure Rate: 50
|
||||
# IGT Version: 1.28-g0df7b9b97
|
||||
# Linux Version: 6.9.0-rc7
|
||||
kms_flip@flip-vs-wf_vblank-interruptible
|
||||
|
||||
# Board Name: vkms
|
||||
# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
|
||||
# Failure Rate: 50
|
||||
# IGT Version: 1.28-g0df7b9b97
|
||||
# Linux Version: 6.9.0-rc7
|
||||
kms_flip@plain-flip-fb-recreate-interruptible
|
||||
|
||||
# Board Name: vkms
|
||||
# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
|
||||
# Failure Rate: 50
|
||||
# IGT Version: 1.28-g0df7b9b97
|
||||
# Linux Version: 6.9.0-rc7
|
||||
kms_flip@plain-flip-ts-check
|
||||
|
||||
# Board Name: vkms
|
||||
# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
|
||||
# Failure Rate: 50
|
||||
# IGT Version: 1.28-g0df7b9b97
|
||||
# Linux Version: 6.9.0-rc7
|
||||
kms_flip@plain-flip-ts-check-interruptible
|
||||
|
||||
# Board Name: vkms
|
||||
# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
|
||||
# Failure Rate: 50
|
||||
# IGT Version: 1.28-g0df7b9b97
|
||||
# Linux Version: 6.9.0-rc7
|
||||
kms_flip@flip-vs-absolute-wf_vblank
|
||||
|
||||
# Board Name: vkms
|
||||
# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
|
||||
# Failure Rate: 50
|
||||
# IGT Version: 1.28-g0df7b9b97
|
||||
# Linux Version: 6.9.0-rc7
|
||||
kms_flip@flip-vs-absolute-wf_vblank-interruptible
|
||||
|
||||
# Board Name: vkms
|
||||
# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
|
||||
# Failure Rate: 50
|
||||
# IGT Version: 1.28-g0df7b9b97
|
||||
# Linux Version: 6.9.0-rc7
|
||||
kms_flip@flip-vs-blocking-wf-vblank
|
119
drivers/gpu/drm/ci/xfails/vkms-none-skips.txt
Normal file
119
drivers/gpu/drm/ci/xfails/vkms-none-skips.txt
Normal file
@ -0,0 +1,119 @@
|
||||
# keeps printing vkms_vblank_simulate: vblank timer overrun and never ends
|
||||
kms_invalid_mode@int-max-clock
|
||||
|
||||
# Kernel panic
|
||||
kms_cursor_crc@cursor-rapid-movement-32x10
|
||||
# Oops: 0000 [#1] PREEMPT SMP NOPTI
|
||||
# CPU: 0 PID: 2635 Comm: kworker/u8:13 Not tainted 6.9.0-rc7-g40935263a1fd #1
|
||||
# Hardware name: ChromiumOS crosvm, BIOS 0
|
||||
# Workqueue: vkms_composer vkms_composer_worker [vkms]
|
||||
# RIP: 0010:compose_active_planes+0x1c7/0x4e0 [vkms]
|
||||
# Code: c9 0f 84 6a 01 00 00 8b 42 30 2b 42 28 41 39 c5 0f 8c 6f 01 00 00 49 83 c7 01 49 39 df 74 3b 4b 8b 34 fc 48 8b 96 48 01 00 00 <8b> 42 78 89 c1 83 e1 0a a8 20 74 b1 45 89 f5 41 f7 d5 44 03 6a 34
|
||||
# RSP: 0018:ffffbb4700c17d58 EFLAGS: 00010246
|
||||
# RAX: 0000000000000400 RBX: 0000000000000002 RCX: 0000000000000002
|
||||
# RDX: 0000000000000000 RSI: ffffa2ad0788c000 RDI: 00000000fff479a8
|
||||
# RBP: 0000000000000004 R08: 0000000000000000 R09: 0000000000000000
|
||||
# R10: ffffa2ad0bb14000 R11: 0000000000000000 R12: ffffa2ad03e21700
|
||||
# R13: 0000000000000003 R14: 0000000000000004 R15: 0000000000000000
|
||||
# FS: 0000000000000000(0000) GS:ffffa2ad2bc00000(0000) knlGS:0000000000000000
|
||||
# CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
# CR2: 0000000000000078 CR3: 000000010bd30000 CR4: 0000000000350ef0
|
||||
# Call Trace:
|
||||
# <TASK>
|
||||
# ? __die+0x1e/0x60
|
||||
# ? page_fault_oops+0x17b/0x490
|
||||
# ? exc_page_fault+0x6d/0x230
|
||||
# ? asm_exc_page_fault+0x26/0x30
|
||||
# ? compose_active_planes+0x1c7/0x4e0 [vkms]
|
||||
# ? compose_active_planes+0x2a3/0x4e0 [vkms]
|
||||
# ? srso_return_thunk+0x5/0x5f
|
||||
# vkms_composer_worker+0x205/0x240 [vkms]
|
||||
# process_one_work+0x1f4/0x6b0
|
||||
# ? lock_is_held_type+0x9e/0x110
|
||||
# worker_thread+0x17e/0x350
|
||||
# ? __pfx_worker_thread+0x10/0x10
|
||||
# kthread+0xce/0x100
|
||||
# ? __pfx_kthread+0x10/0x10
|
||||
# ret_from_fork+0x2f/0x50
|
||||
# ? __pfx_kthread+0x10/0x10
|
||||
# ret_from_fork_asm+0x1a/0x30
|
||||
# </TASK>
|
||||
# Modules linked in: vkms
|
||||
# CR2: 0000000000000078
|
||||
# ---[ end trace 0000000000000000 ]---
|
||||
# RIP: 0010:compose_active_planes+0x1c7/0x4e0 [vkms]
|
||||
# Code: c9 0f 84 6a 01 00 00 8b 42 30 2b 42 28 41 39 c5 0f 8c 6f 01 00 00 49 83 c7 01 49 39 df 74 3b 4b 8b 34 fc 48 8b 96 48 01 00 00 <8b> 42 78 89 c1 83 e1 0a a8 20 74 b1 45 89 f5 41 f7 d5 44 03 6a 34
|
||||
# RSP: 0018:ffffbb4700c17d58 EFLAGS: 00010246
|
||||
# RAX: 0000000000000400 RBX: 0000000000000002 RCX: 0000000000000002
|
||||
# RDX: 0000000000000000 RSI: ffffa2ad0788c000 RDI: 00000000fff479a8
|
||||
# RBP: 0000000000000004 R08: 0000000000000000 R09: 0000000000000000
|
||||
# R10: ffffa2ad0bb14000 R11: 0000000000000000 R12: ffffa2ad03e21700
|
||||
# R13: 0000000000000003 R14: 0000000000000004 R15: 0000000000000000
|
||||
# FS: 0000000000000000(0000) GS:ffffa2ad2bc00000(0000) knlGS:0000000000000000
|
||||
# CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
|
||||
kms_cursor_crc@cursor-rapid-movement-256x85
|
||||
# [drm:drm_crtc_add_crc_entry] *ERROR* Overflow of CRC buffer, userspace reads too slow.
|
||||
# Oops: 0000 [#1] PREEMPT SMP NOPTI
|
||||
# CPU: 1 PID: 10 Comm: kworker/u8:0 Not tainted 6.9.0-rc7-g646381cde463 #1
|
||||
# Hardware name: ChromiumOS crosvm, BIOS 0
|
||||
# Workqueue: vkms_composer vkms_composer_worker [vkms]
|
||||
# RIP: 0010:compose_active_planes+0x1c7/0x4e0 [vkms]
|
||||
# Code: c9 0f 84 6a 01 00 00 8b 42 30 2b 42 28 41 39 c5 0f 8c 6f 01 00 00 49 83 c7 01 49 39 df 74 3b 4b 8b 34 fc 48 8b 96 48 01 00 00 <8b> 42 78 89 c1 83 e1 0a a8 20 74 b1 45 89 f5 41 f7 d5 44 03 6a 34
|
||||
# RSP: 0018:ffffa7e980057d58 EFLAGS: 00010246
|
||||
# RAX: 0000000000000400 RBX: 0000000000000002 RCX: 0000000000000002
|
||||
# RDX: 0000000000000000 RSI: ffff977987aa5c00 RDI: 000000001b43a85f
|
||||
# RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
|
||||
# R10: ffff977981bf0000 R11: 0000000000000000 R12: ffff977989622590
|
||||
# R13: 0000000000000000 R14: 0000000000000001 R15: 0000000000000000
|
||||
# FS: 0000000000000000(0000) GS:ffff9779abd00000(0000) knlGS:0000000000000000
|
||||
# CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
# CR2: 0000000000000078 CR3: 0000000109b38000 CR4: 0000000000350ef0
|
||||
# Call Trace:
|
||||
# <TASK>
|
||||
# ? __die+0x1e/0x60
|
||||
# ? page_fault_oops+0x17b/0x490
|
||||
# ? exc_page_fault+0x6d/0x230
|
||||
# ? asm_exc_page_fault+0x26/0x30
|
||||
# ? compose_active_planes+0x1c7/0x4e0 [vkms]
|
||||
# ? compose_active_planes+0x2a3/0x4e0 [vkms]
|
||||
# ? srso_return_thunk+0x5/0x5f
|
||||
# vkms_composer_worker+0x205/0x240 [vkms]
|
||||
# process_one_work+0x1f4/0x6b0
|
||||
# ? lock_is_held_type+0x9e/0x110
|
||||
# worker_thread+0x17e/0x350
|
||||
# ? __pfx_worker_thread+0x10/0x10
|
||||
# kthread+0xce/0x100
|
||||
# ? __pfx_kthread+0x10/0x10
|
||||
# ret_from_fork+0x2f/0x50
|
||||
# ? __pfx_kthread+0x10/0x10
|
||||
# ret_from_fork_asm+0x1a/0x30
|
||||
# </TASK>
|
||||
# Modules linked in: vkms
|
||||
# CR2: 0000000000000078
|
||||
# ---[ end trace 0000000000000000 ]---
|
||||
# RIP: 0010:compose_active_planes+0x1c7/0x4e0 [vkms]
|
||||
# Code: c9 0f 84 6a 01 00 00 8b 42 30 2b 42 28 41 39 c5 0f 8c 6f 01 00 00 49 83 c7 01 49 39 df 74 3b 4b 8b 34 fc 48 8b 96 48 01 00 00 <8b> 42 78 89 c1 83 e1 0a a8 20 74 b1 45 89 f5 41 f7 d5 44 03 6a 34
|
||||
# RSP: 0018:ffffa7e980057d58 EFLAGS: 00010246
|
||||
# RAX: 0000000000000400 RBX: 0000000000000002 RCX: 0000000000000002
|
||||
# RDX: 0000000000000000 RSI: ffff977987aa5c00 RDI: 000000001b43a85f
|
||||
# RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
|
||||
# R10: ffff977981bf0000 R11: 0000000000000000 R12: ffff977989622590
|
||||
# R13: 0000000000000000 R14: 0000000000000001 R15: 0000000000000000
|
||||
# FS: 0000000000000000(0000) GS:ffff9779abd00000(0000) knlGS:0000000000000000
|
||||
# CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
# CR2: 0000000000000078 CR3: 0000000109b38000 CR4: 0000000000350ef0
|
||||
|
||||
# Skip driver specific tests
|
||||
^amdgpu.*
|
||||
msm_.*
|
||||
nouveau_.*
|
||||
panfrost_.*
|
||||
^v3d.*
|
||||
^vc4.*
|
||||
^vmwgfx*
|
||||
|
||||
# Skip intel specific tests
|
||||
gem_.*
|
||||
i915_.*
|
||||
xe_.*
|
@ -1087,6 +1087,7 @@ static const struct drm_prop_enum_list drm_tv_mode_enum_list[] = {
|
||||
{ DRM_MODE_TV_MODE_PAL_M, "PAL-M" },
|
||||
{ DRM_MODE_TV_MODE_PAL_N, "PAL-N" },
|
||||
{ DRM_MODE_TV_MODE_SECAM, "SECAM" },
|
||||
{ DRM_MODE_TV_MODE_MONOCHROME, "Mono" },
|
||||
};
|
||||
DRM_ENUM_NAME_FN(drm_get_tv_mode_name, drm_tv_mode_enum_list)
|
||||
|
||||
@ -1858,6 +1859,12 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);
|
||||
* TV Mode is CCIR System B (aka 625-lines) together with
|
||||
* the SECAM Color Encoding.
|
||||
*
|
||||
* Mono:
|
||||
*
|
||||
* Use timings appropriate to the DRM mode, including
|
||||
* equalizing pulses for a 525-line or 625-line mode,
|
||||
* with no pedestal or color encoding.
|
||||
*
|
||||
* Drivers can set up this property by calling
|
||||
* drm_mode_create_tv_properties().
|
||||
*/
|
||||
|
@ -531,7 +531,8 @@ static int fill_analog_mode(struct drm_device *dev,
|
||||
* @interlace: whether to compute an interlaced mode
|
||||
*
|
||||
* This function creates a struct drm_display_mode instance suited for
|
||||
* an analog TV output, for one of the usual analog TV mode.
|
||||
* an analog TV output, for one of the usual analog TV modes. Where
|
||||
* this is DRM_MODE_TV_MODE_MONOCHROME, a 625-line mode will be created.
|
||||
*
|
||||
* Note that @hdisplay is larger than the usual constraints for the PAL
|
||||
* and NTSC timings, and we'll choose to ignore most timings constraints
|
||||
@ -569,6 +570,8 @@ struct drm_display_mode *drm_analog_tv_mode(struct drm_device *dev,
|
||||
case DRM_MODE_TV_MODE_PAL_N:
|
||||
fallthrough;
|
||||
case DRM_MODE_TV_MODE_SECAM:
|
||||
fallthrough;
|
||||
case DRM_MODE_TV_MODE_MONOCHROME:
|
||||
analog = DRM_MODE_ANALOG_PAL;
|
||||
break;
|
||||
|
||||
|
@ -1259,8 +1259,9 @@ int drm_connector_helper_tv_get_modes(struct drm_connector *connector)
|
||||
for (i = 0; i < tv_mode_property->num_values; i++)
|
||||
supported_tv_modes |= BIT(tv_mode_property->values[i]);
|
||||
|
||||
if ((supported_tv_modes & ntsc_modes) &&
|
||||
(supported_tv_modes & pal_modes)) {
|
||||
if (((supported_tv_modes & ntsc_modes) &&
|
||||
(supported_tv_modes & pal_modes)) ||
|
||||
(supported_tv_modes & BIT(DRM_MODE_TV_MODE_MONOCHROME))) {
|
||||
uint64_t default_mode;
|
||||
|
||||
if (drm_object_property_get_default_value(&connector->base,
|
||||
|
@ -11,6 +11,7 @@ mgag200-y := \
|
||||
mgag200_g200ew3.o \
|
||||
mgag200_g200se.o \
|
||||
mgag200_g200wb.o \
|
||||
mgag200_mode.o
|
||||
mgag200_mode.o \
|
||||
mgag200_vga.o
|
||||
|
||||
obj-$(CONFIG_DRM_MGAG200) += mgag200.o
|
||||
|
@ -2,8 +2,18 @@
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_managed.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "mgag200_drv.h"
|
||||
|
||||
static struct mgag200_bmc_connector *to_mgag200_bmc_connector(struct drm_connector *connector)
|
||||
{
|
||||
return container_of(connector, struct mgag200_bmc_connector, base);
|
||||
}
|
||||
|
||||
void mgag200_bmc_disable_vidrst(struct mga_device *mdev)
|
||||
{
|
||||
u8 tmp;
|
||||
@ -97,3 +107,100 @@ void mgag200_bmc_enable_vidrst(struct mga_device *mdev)
|
||||
tmp &= ~0x10;
|
||||
WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
|
||||
}
|
||||
|
||||
static const struct drm_encoder_funcs mgag200_bmc_encoder_funcs = {
|
||||
.destroy = drm_encoder_cleanup,
|
||||
};
|
||||
|
||||
static int mgag200_bmc_connector_helper_detect_ctx(struct drm_connector *connector,
|
||||
struct drm_modeset_acquire_ctx *ctx,
|
||||
bool force)
|
||||
{
|
||||
struct mgag200_bmc_connector *bmc_connector = to_mgag200_bmc_connector(connector);
|
||||
struct drm_connector *physical_connector = bmc_connector->physical_connector;
|
||||
|
||||
/*
|
||||
* Most user-space compositors cannot handle more than one connected
|
||||
* connector per CRTC. Hence, we only mark the BMC as connected if the
|
||||
* physical connector is disconnected. If the physical connector's status
|
||||
* is connected or unknown, the BMC remains disconnected. This has no
|
||||
* effect on the output of the BMC.
|
||||
*
|
||||
* FIXME: Remove this logic once user-space compositors can handle more
|
||||
* than one connector per CRTC. The BMC should always be connected.
|
||||
*/
|
||||
|
||||
if (physical_connector && physical_connector->status == connector_status_disconnected)
|
||||
return connector_status_connected;
|
||||
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
static int mgag200_bmc_connector_helper_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct mga_device *mdev = to_mga_device(dev);
|
||||
const struct mgag200_device_info *minfo = mdev->info;
|
||||
|
||||
return drm_add_modes_noedid(connector, minfo->max_hdisplay, minfo->max_vdisplay);
|
||||
}
|
||||
|
||||
static const struct drm_connector_helper_funcs mgag200_bmc_connector_helper_funcs = {
|
||||
.get_modes = mgag200_bmc_connector_helper_get_modes,
|
||||
.detect_ctx = mgag200_bmc_connector_helper_detect_ctx,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs mgag200_bmc_connector_funcs = {
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = drm_connector_cleanup,
|
||||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
};
|
||||
|
||||
static int mgag200_bmc_connector_init(struct drm_device *dev,
|
||||
struct mgag200_bmc_connector *bmc_connector,
|
||||
struct drm_connector *physical_connector)
|
||||
{
|
||||
struct drm_connector *connector = &bmc_connector->base;
|
||||
int ret;
|
||||
|
||||
ret = drm_connector_init(dev, connector, &mgag200_bmc_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VIRTUAL);
|
||||
if (ret)
|
||||
return ret;
|
||||
drm_connector_helper_add(connector, &mgag200_bmc_connector_helper_funcs);
|
||||
|
||||
bmc_connector->physical_connector = physical_connector;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mgag200_bmc_output_init(struct mga_device *mdev, struct drm_connector *physical_connector)
|
||||
{
|
||||
struct drm_device *dev = &mdev->base;
|
||||
struct drm_crtc *crtc = &mdev->crtc;
|
||||
struct drm_encoder *encoder;
|
||||
struct mgag200_bmc_connector *bmc_connector;
|
||||
struct drm_connector *connector;
|
||||
int ret;
|
||||
|
||||
encoder = &mdev->output.bmc.encoder;
|
||||
ret = drm_encoder_init(dev, encoder, &mgag200_bmc_encoder_funcs,
|
||||
DRM_MODE_ENCODER_VIRTUAL, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
encoder->possible_crtcs = drm_crtc_mask(crtc);
|
||||
|
||||
bmc_connector = &mdev->output.bmc.bmc_connector;
|
||||
ret = mgag200_bmc_connector_init(dev, bmc_connector, physical_connector);
|
||||
if (ret)
|
||||
return ret;
|
||||
connector = &bmc_connector->base;
|
||||
|
||||
ret = drm_connector_attach_encoder(connector, encoder);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -186,6 +186,11 @@ static inline struct mgag200_crtc_state *to_mgag200_crtc_state(struct drm_crtc_s
|
||||
return container_of(base, struct mgag200_crtc_state, base);
|
||||
}
|
||||
|
||||
struct mgag200_bmc_connector {
|
||||
struct drm_connector base;
|
||||
struct drm_connector *physical_connector;
|
||||
};
|
||||
|
||||
enum mga_type {
|
||||
G200_PCI,
|
||||
G200_AGP,
|
||||
@ -283,8 +288,16 @@ struct mga_device {
|
||||
|
||||
struct drm_plane primary_plane;
|
||||
struct drm_crtc crtc;
|
||||
struct drm_encoder encoder;
|
||||
struct drm_connector connector;
|
||||
struct {
|
||||
struct {
|
||||
struct drm_encoder encoder;
|
||||
struct drm_connector connector;
|
||||
} vga;
|
||||
struct {
|
||||
struct drm_encoder encoder;
|
||||
struct mgag200_bmc_connector bmc_connector;
|
||||
} bmc;
|
||||
} output;
|
||||
};
|
||||
|
||||
static inline struct mga_device *to_mga_device(struct drm_device *dev)
|
||||
@ -417,27 +430,18 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_st
|
||||
.atomic_duplicate_state = mgag200_crtc_atomic_duplicate_state, \
|
||||
.atomic_destroy_state = mgag200_crtc_atomic_destroy_state
|
||||
|
||||
#define MGAG200_DAC_ENCODER_FUNCS \
|
||||
.destroy = drm_encoder_cleanup
|
||||
|
||||
#define MGAG200_VGA_CONNECTOR_HELPER_FUNCS \
|
||||
.get_modes = drm_connector_helper_get_modes
|
||||
|
||||
#define MGAG200_VGA_CONNECTOR_FUNCS \
|
||||
.reset = drm_atomic_helper_connector_reset, \
|
||||
.fill_modes = drm_helper_probe_single_connector_modes, \
|
||||
.destroy = drm_connector_cleanup, \
|
||||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, \
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state
|
||||
|
||||
void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mode *mode);
|
||||
void mgag200_set_format_regs(struct mga_device *mdev, const struct drm_format_info *format);
|
||||
void mgag200_enable_display(struct mga_device *mdev);
|
||||
void mgag200_init_registers(struct mga_device *mdev);
|
||||
int mgag200_mode_config_init(struct mga_device *mdev, resource_size_t vram_available);
|
||||
|
||||
/* mgag200_vga.c */
|
||||
int mgag200_vga_output_init(struct mga_device *mdev);
|
||||
|
||||
/* mgag200_bmc.c */
|
||||
void mgag200_bmc_disable_vidrst(struct mga_device *mdev);
|
||||
void mgag200_bmc_enable_vidrst(struct mga_device *mdev);
|
||||
int mgag200_bmc_output_init(struct mga_device *mdev, struct drm_connector *physical_connector);
|
||||
|
||||
#endif /* __MGAG200_DRV_H__ */
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "mgag200_ddc.h"
|
||||
#include "mgag200_drv.h"
|
||||
|
||||
static int mgag200_g200_init_pci_options(struct pci_dev *pdev)
|
||||
@ -184,26 +183,11 @@ static const struct drm_crtc_funcs mgag200_g200_crtc_funcs = {
|
||||
MGAG200_CRTC_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_encoder_funcs mgag200_g200_dac_encoder_funcs = {
|
||||
MGAG200_DAC_ENCODER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs mgag200_g200_vga_connector_helper_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs mgag200_g200_vga_connector_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_FUNCS,
|
||||
};
|
||||
|
||||
static int mgag200_g200_pipeline_init(struct mga_device *mdev)
|
||||
{
|
||||
struct drm_device *dev = &mdev->base;
|
||||
struct drm_plane *primary_plane = &mdev->primary_plane;
|
||||
struct drm_crtc *crtc = &mdev->crtc;
|
||||
struct drm_encoder *encoder = &mdev->encoder;
|
||||
struct drm_connector *connector = &mdev->connector;
|
||||
struct i2c_adapter *ddc;
|
||||
int ret;
|
||||
|
||||
ret = drm_universal_plane_init(dev, primary_plane, 0,
|
||||
@ -231,35 +215,9 @@ static int mgag200_g200_pipeline_init(struct mga_device *mdev)
|
||||
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
|
||||
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
|
||||
|
||||
encoder->possible_crtcs = drm_crtc_mask(crtc);
|
||||
ret = drm_encoder_init(dev, encoder, &mgag200_g200_dac_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
|
||||
ret = mgag200_vga_output_init(mdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ddc = mgag200_ddc_create(mdev);
|
||||
if (IS_ERR(ddc)) {
|
||||
ret = PTR_ERR(ddc);
|
||||
drm_err(dev, "failed to add DDC bus: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drm_connector_init_with_ddc(dev, connector,
|
||||
&mgag200_g200_vga_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VGA, ddc);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
drm_connector_helper_add(connector, &mgag200_g200_vga_connector_helper_funcs);
|
||||
|
||||
ret = drm_connector_attach_encoder(connector, encoder);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -443,6 +401,7 @@ struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct
|
||||
return ERR_PTR(ret);
|
||||
|
||||
drm_mode_config_reset(dev);
|
||||
drm_kms_helper_poll_init(dev);
|
||||
|
||||
return mdev;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "mgag200_ddc.h"
|
||||
#include "mgag200_drv.h"
|
||||
|
||||
void mgag200_g200eh_init_registers(struct mga_device *mdev)
|
||||
@ -183,26 +182,11 @@ static const struct drm_crtc_funcs mgag200_g200eh_crtc_funcs = {
|
||||
MGAG200_CRTC_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_encoder_funcs mgag200_g200eh_dac_encoder_funcs = {
|
||||
MGAG200_DAC_ENCODER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs mgag200_g200eh_vga_connector_helper_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs mgag200_g200eh_vga_connector_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_FUNCS,
|
||||
};
|
||||
|
||||
static int mgag200_g200eh_pipeline_init(struct mga_device *mdev)
|
||||
{
|
||||
struct drm_device *dev = &mdev->base;
|
||||
struct drm_plane *primary_plane = &mdev->primary_plane;
|
||||
struct drm_crtc *crtc = &mdev->crtc;
|
||||
struct drm_encoder *encoder = &mdev->encoder;
|
||||
struct drm_connector *connector = &mdev->connector;
|
||||
struct i2c_adapter *ddc;
|
||||
int ret;
|
||||
|
||||
ret = drm_universal_plane_init(dev, primary_plane, 0,
|
||||
@ -230,35 +214,13 @@ static int mgag200_g200eh_pipeline_init(struct mga_device *mdev)
|
||||
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
|
||||
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
|
||||
|
||||
encoder->possible_crtcs = drm_crtc_mask(crtc);
|
||||
ret = drm_encoder_init(dev, encoder, &mgag200_g200eh_dac_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
|
||||
ret = mgag200_vga_output_init(mdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ddc = mgag200_ddc_create(mdev);
|
||||
if (IS_ERR(ddc)) {
|
||||
ret = PTR_ERR(ddc);
|
||||
drm_err(dev, "failed to add DDC bus: %d\n", ret);
|
||||
ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drm_connector_init_with_ddc(dev, connector,
|
||||
&mgag200_g200eh_vga_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VGA, ddc);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
drm_connector_helper_add(connector, &mgag200_g200eh_vga_connector_helper_funcs);
|
||||
|
||||
ret = drm_connector_attach_encoder(connector, encoder);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -315,6 +277,7 @@ struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const stru
|
||||
return ERR_PTR(ret);
|
||||
|
||||
drm_mode_config_reset(dev);
|
||||
drm_kms_helper_poll_init(dev);
|
||||
|
||||
return mdev;
|
||||
}
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "mgag200_ddc.h"
|
||||
#include "mgag200_drv.h"
|
||||
|
||||
/*
|
||||
@ -87,26 +86,11 @@ static const struct drm_crtc_funcs mgag200_g200eh3_crtc_funcs = {
|
||||
MGAG200_CRTC_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_encoder_funcs mgag200_g200eh3_dac_encoder_funcs = {
|
||||
MGAG200_DAC_ENCODER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs mgag200_g200eh3_vga_connector_helper_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs mgag200_g200eh3_vga_connector_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_FUNCS,
|
||||
};
|
||||
|
||||
static int mgag200_g200eh3_pipeline_init(struct mga_device *mdev)
|
||||
{
|
||||
struct drm_device *dev = &mdev->base;
|
||||
struct drm_plane *primary_plane = &mdev->primary_plane;
|
||||
struct drm_crtc *crtc = &mdev->crtc;
|
||||
struct drm_encoder *encoder = &mdev->encoder;
|
||||
struct drm_connector *connector = &mdev->connector;
|
||||
struct i2c_adapter *ddc;
|
||||
int ret;
|
||||
|
||||
ret = drm_universal_plane_init(dev, primary_plane, 0,
|
||||
@ -134,35 +118,13 @@ static int mgag200_g200eh3_pipeline_init(struct mga_device *mdev)
|
||||
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
|
||||
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
|
||||
|
||||
encoder->possible_crtcs = drm_crtc_mask(crtc);
|
||||
ret = drm_encoder_init(dev, encoder, &mgag200_g200eh3_dac_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
|
||||
ret = mgag200_vga_output_init(mdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ddc = mgag200_ddc_create(mdev);
|
||||
if (IS_ERR(ddc)) {
|
||||
ret = PTR_ERR(ddc);
|
||||
drm_err(dev, "failed to add DDC bus: %d\n", ret);
|
||||
ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drm_connector_init_with_ddc(dev, connector,
|
||||
&mgag200_g200eh3_vga_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VGA, ddc);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
drm_connector_helper_add(connector, &mgag200_g200eh3_vga_connector_helper_funcs);
|
||||
|
||||
ret = drm_connector_attach_encoder(connector, encoder);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -220,6 +182,7 @@ struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev,
|
||||
return ERR_PTR(ret);
|
||||
|
||||
drm_mode_config_reset(dev);
|
||||
drm_kms_helper_poll_init(dev);
|
||||
|
||||
return mdev;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "mgag200_ddc.h"
|
||||
#include "mgag200_drv.h"
|
||||
|
||||
static void mgag200_g200er_init_registers(struct mga_device *mdev)
|
||||
@ -226,26 +225,11 @@ static const struct drm_crtc_funcs mgag200_g200er_crtc_funcs = {
|
||||
MGAG200_CRTC_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_encoder_funcs mgag200_g200er_dac_encoder_funcs = {
|
||||
MGAG200_DAC_ENCODER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs mgag200_g200er_vga_connector_helper_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs mgag200_g200er_vga_connector_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_FUNCS,
|
||||
};
|
||||
|
||||
static int mgag200_g200er_pipeline_init(struct mga_device *mdev)
|
||||
{
|
||||
struct drm_device *dev = &mdev->base;
|
||||
struct drm_plane *primary_plane = &mdev->primary_plane;
|
||||
struct drm_crtc *crtc = &mdev->crtc;
|
||||
struct drm_encoder *encoder = &mdev->encoder;
|
||||
struct drm_connector *connector = &mdev->connector;
|
||||
struct i2c_adapter *ddc;
|
||||
int ret;
|
||||
|
||||
ret = drm_universal_plane_init(dev, primary_plane, 0,
|
||||
@ -273,35 +257,13 @@ static int mgag200_g200er_pipeline_init(struct mga_device *mdev)
|
||||
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
|
||||
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
|
||||
|
||||
encoder->possible_crtcs = drm_crtc_mask(crtc);
|
||||
ret = drm_encoder_init(dev, encoder, &mgag200_g200er_dac_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
|
||||
ret = mgag200_vga_output_init(mdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ddc = mgag200_ddc_create(mdev);
|
||||
if (IS_ERR(ddc)) {
|
||||
ret = PTR_ERR(ddc);
|
||||
drm_err(dev, "failed to add DDC bus: %d\n", ret);
|
||||
ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drm_connector_init_with_ddc(dev, connector,
|
||||
&mgag200_g200er_vga_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VGA, ddc);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
drm_connector_helper_add(connector, &mgag200_g200er_vga_connector_helper_funcs);
|
||||
|
||||
ret = drm_connector_attach_encoder(connector, encoder);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -354,6 +316,7 @@ struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const stru
|
||||
return ERR_PTR(ret);
|
||||
|
||||
drm_mode_config_reset(dev);
|
||||
drm_kms_helper_poll_init(dev);
|
||||
|
||||
return mdev;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "mgag200_ddc.h"
|
||||
#include "mgag200_drv.h"
|
||||
|
||||
static void mgag200_g200ev_init_registers(struct mga_device *mdev)
|
||||
@ -227,26 +226,11 @@ static const struct drm_crtc_funcs mgag200_g200ev_crtc_funcs = {
|
||||
MGAG200_CRTC_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_encoder_funcs mgag200_g200ev_dac_encoder_funcs = {
|
||||
MGAG200_DAC_ENCODER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs mgag200_g200ev_vga_connector_helper_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs mgag200_g200ev_vga_connector_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_FUNCS,
|
||||
};
|
||||
|
||||
static int mgag200_g200ev_pipeline_init(struct mga_device *mdev)
|
||||
{
|
||||
struct drm_device *dev = &mdev->base;
|
||||
struct drm_plane *primary_plane = &mdev->primary_plane;
|
||||
struct drm_crtc *crtc = &mdev->crtc;
|
||||
struct drm_encoder *encoder = &mdev->encoder;
|
||||
struct drm_connector *connector = &mdev->connector;
|
||||
struct i2c_adapter *ddc;
|
||||
int ret;
|
||||
|
||||
ret = drm_universal_plane_init(dev, primary_plane, 0,
|
||||
@ -274,35 +258,13 @@ static int mgag200_g200ev_pipeline_init(struct mga_device *mdev)
|
||||
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
|
||||
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
|
||||
|
||||
encoder->possible_crtcs = drm_crtc_mask(crtc);
|
||||
ret = drm_encoder_init(dev, encoder, &mgag200_g200ev_dac_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
|
||||
ret = mgag200_vga_output_init(mdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ddc = mgag200_ddc_create(mdev);
|
||||
if (IS_ERR(ddc)) {
|
||||
ret = PTR_ERR(ddc);
|
||||
drm_err(dev, "failed to add DDC bus: %d\n", ret);
|
||||
ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drm_connector_init_with_ddc(dev, connector,
|
||||
&mgag200_g200ev_vga_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VGA, ddc);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
drm_connector_helper_add(connector, &mgag200_g200ev_vga_connector_helper_funcs);
|
||||
|
||||
ret = drm_connector_attach_encoder(connector, encoder);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -359,6 +321,7 @@ struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const stru
|
||||
return ERR_PTR(ret);
|
||||
|
||||
drm_mode_config_reset(dev);
|
||||
drm_kms_helper_poll_init(dev);
|
||||
|
||||
return mdev;
|
||||
}
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "mgag200_ddc.h"
|
||||
#include "mgag200_drv.h"
|
||||
|
||||
static void mgag200_g200ew3_init_registers(struct mga_device *mdev)
|
||||
@ -96,26 +95,11 @@ static const struct drm_crtc_funcs mgag200_g200ew3_crtc_funcs = {
|
||||
MGAG200_CRTC_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_encoder_funcs mgag200_g200ew3_dac_encoder_funcs = {
|
||||
MGAG200_DAC_ENCODER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs mgag200_g200ew3_vga_connector_helper_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs mgag200_g200ew3_vga_connector_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_FUNCS,
|
||||
};
|
||||
|
||||
static int mgag200_g200ew3_pipeline_init(struct mga_device *mdev)
|
||||
{
|
||||
struct drm_device *dev = &mdev->base;
|
||||
struct drm_plane *primary_plane = &mdev->primary_plane;
|
||||
struct drm_crtc *crtc = &mdev->crtc;
|
||||
struct drm_encoder *encoder = &mdev->encoder;
|
||||
struct drm_connector *connector = &mdev->connector;
|
||||
struct i2c_adapter *ddc;
|
||||
int ret;
|
||||
|
||||
ret = drm_universal_plane_init(dev, primary_plane, 0,
|
||||
@ -143,35 +127,13 @@ static int mgag200_g200ew3_pipeline_init(struct mga_device *mdev)
|
||||
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
|
||||
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
|
||||
|
||||
encoder->possible_crtcs = drm_crtc_mask(crtc);
|
||||
ret = drm_encoder_init(dev, encoder, &mgag200_g200ew3_dac_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
|
||||
ret = mgag200_vga_output_init(mdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ddc = mgag200_ddc_create(mdev);
|
||||
if (IS_ERR(ddc)) {
|
||||
ret = PTR_ERR(ddc);
|
||||
drm_err(dev, "failed to add DDC bus: %d\n", ret);
|
||||
ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drm_connector_init_with_ddc(dev, connector,
|
||||
&mgag200_g200ew3_vga_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VGA, ddc);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
drm_connector_helper_add(connector, &mgag200_g200ew3_vga_connector_helper_funcs);
|
||||
|
||||
ret = drm_connector_attach_encoder(connector, encoder);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -240,6 +202,7 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev,
|
||||
return ERR_PTR(ret);
|
||||
|
||||
drm_mode_config_reset(dev);
|
||||
drm_kms_helper_poll_init(dev);
|
||||
|
||||
return mdev;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "mgag200_ddc.h"
|
||||
#include "mgag200_drv.h"
|
||||
|
||||
static int mgag200_g200se_init_pci_options(struct pci_dev *pdev)
|
||||
@ -358,26 +357,11 @@ static const struct drm_crtc_funcs mgag200_g200se_crtc_funcs = {
|
||||
MGAG200_CRTC_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_encoder_funcs mgag200_g200se_dac_encoder_funcs = {
|
||||
MGAG200_DAC_ENCODER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs mgag200_g200se_vga_connector_helper_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs mgag200_g200se_vga_connector_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_FUNCS,
|
||||
};
|
||||
|
||||
static int mgag200_g200se_pipeline_init(struct mga_device *mdev)
|
||||
{
|
||||
struct drm_device *dev = &mdev->base;
|
||||
struct drm_plane *primary_plane = &mdev->primary_plane;
|
||||
struct drm_crtc *crtc = &mdev->crtc;
|
||||
struct drm_encoder *encoder = &mdev->encoder;
|
||||
struct drm_connector *connector = &mdev->connector;
|
||||
struct i2c_adapter *ddc;
|
||||
int ret;
|
||||
|
||||
ret = drm_universal_plane_init(dev, primary_plane, 0,
|
||||
@ -405,35 +389,13 @@ static int mgag200_g200se_pipeline_init(struct mga_device *mdev)
|
||||
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
|
||||
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
|
||||
|
||||
encoder->possible_crtcs = drm_crtc_mask(crtc);
|
||||
ret = drm_encoder_init(dev, encoder, &mgag200_g200se_dac_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
|
||||
ret = mgag200_vga_output_init(mdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ddc = mgag200_ddc_create(mdev);
|
||||
if (IS_ERR(ddc)) {
|
||||
ret = PTR_ERR(ddc);
|
||||
drm_err(dev, "failed to add DDC bus: %d\n", ret);
|
||||
ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drm_connector_init_with_ddc(dev, connector,
|
||||
&mgag200_g200se_vga_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VGA, ddc);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
drm_connector_helper_add(connector, &mgag200_g200se_vga_connector_helper_funcs);
|
||||
|
||||
ret = drm_connector_attach_encoder(connector, encoder);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -559,6 +521,7 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru
|
||||
return ERR_PTR(ret);
|
||||
|
||||
drm_mode_config_reset(dev);
|
||||
drm_kms_helper_poll_init(dev);
|
||||
|
||||
return mdev;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "mgag200_ddc.h"
|
||||
#include "mgag200_drv.h"
|
||||
|
||||
void mgag200_g200wb_init_registers(struct mga_device *mdev)
|
||||
@ -230,26 +229,11 @@ static const struct drm_crtc_funcs mgag200_g200wb_crtc_funcs = {
|
||||
MGAG200_CRTC_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_encoder_funcs mgag200_g200wb_dac_encoder_funcs = {
|
||||
MGAG200_DAC_ENCODER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs mgag200_g200wb_vga_connector_helper_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs mgag200_g200wb_vga_connector_funcs = {
|
||||
MGAG200_VGA_CONNECTOR_FUNCS,
|
||||
};
|
||||
|
||||
static int mgag200_g200wb_pipeline_init(struct mga_device *mdev)
|
||||
{
|
||||
struct drm_device *dev = &mdev->base;
|
||||
struct drm_plane *primary_plane = &mdev->primary_plane;
|
||||
struct drm_crtc *crtc = &mdev->crtc;
|
||||
struct drm_encoder *encoder = &mdev->encoder;
|
||||
struct drm_connector *connector = &mdev->connector;
|
||||
struct i2c_adapter *ddc;
|
||||
int ret;
|
||||
|
||||
ret = drm_universal_plane_init(dev, primary_plane, 0,
|
||||
@ -277,35 +261,13 @@ static int mgag200_g200wb_pipeline_init(struct mga_device *mdev)
|
||||
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
|
||||
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
|
||||
|
||||
encoder->possible_crtcs = drm_crtc_mask(crtc);
|
||||
ret = drm_encoder_init(dev, encoder, &mgag200_g200wb_dac_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
|
||||
ret = mgag200_vga_output_init(mdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ddc = mgag200_ddc_create(mdev);
|
||||
if (IS_ERR(ddc)) {
|
||||
ret = PTR_ERR(ddc);
|
||||
drm_err(dev, "failed to add DDC bus: %d\n", ret);
|
||||
ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drm_connector_init_with_ddc(dev, connector,
|
||||
&mgag200_g200wb_vga_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VGA, ddc);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
drm_connector_helper_add(connector, &mgag200_g200wb_vga_connector_helper_funcs);
|
||||
|
||||
ret = drm_connector_attach_encoder(connector, encoder);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -364,6 +326,7 @@ struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const stru
|
||||
return ERR_PTR(ret);
|
||||
|
||||
drm_mode_config_reset(dev);
|
||||
drm_kms_helper_poll_init(dev);
|
||||
|
||||
return mdev;
|
||||
}
|
||||
|
72
drivers/gpu/drm/mgag200/mgag200_vga.c
Normal file
72
drivers/gpu/drm/mgag200/mgag200_vga.c
Normal file
@ -0,0 +1,72 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_modeset_helper_vtables.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "mgag200_ddc.h"
|
||||
#include "mgag200_drv.h"
|
||||
|
||||
static const struct drm_encoder_funcs mgag200_dac_encoder_funcs = {
|
||||
.destroy = drm_encoder_cleanup
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs mgag200_vga_connector_helper_funcs = {
|
||||
.get_modes = drm_connector_helper_get_modes,
|
||||
.detect_ctx = drm_connector_helper_detect_from_ddc
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs mgag200_vga_connector_funcs = {
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = drm_connector_cleanup,
|
||||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state
|
||||
};
|
||||
|
||||
int mgag200_vga_output_init(struct mga_device *mdev)
|
||||
{
|
||||
struct drm_device *dev = &mdev->base;
|
||||
struct drm_crtc *crtc = &mdev->crtc;
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_connector *connector;
|
||||
struct i2c_adapter *ddc;
|
||||
int ret;
|
||||
|
||||
encoder = &mdev->output.vga.encoder;
|
||||
ret = drm_encoder_init(dev, encoder, &mgag200_dac_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
encoder->possible_crtcs = drm_crtc_mask(crtc);
|
||||
|
||||
ddc = mgag200_ddc_create(mdev);
|
||||
if (IS_ERR(ddc)) {
|
||||
ret = PTR_ERR(ddc);
|
||||
drm_err(dev, "failed to add DDC bus: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
connector = &mdev->output.vga.connector;
|
||||
ret = drm_connector_init_with_ddc(dev, connector,
|
||||
&mgag200_vga_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VGA, ddc);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
drm_connector_helper_add(connector, &mgag200_vga_connector_helper_funcs);
|
||||
|
||||
connector->polled = DRM_CONNECTOR_POLL_CONNECT |
|
||||
DRM_CONNECTOR_POLL_DISCONNECT;
|
||||
|
||||
ret = drm_connector_attach_encoder(connector, encoder);
|
||||
if (ret) {
|
||||
drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -898,7 +898,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict,
|
||||
* Without this the operation can timeout and we'll fallback to a
|
||||
* software copy, which might take several minutes to finish.
|
||||
*/
|
||||
nouveau_fence_wait(fence, false, false);
|
||||
nouveau_fence_wait(fence, false);
|
||||
ret = ttm_bo_move_accel_cleanup(bo, &fence->base, evict, false,
|
||||
new_reg);
|
||||
nouveau_fence_unref(&fence);
|
||||
|
@ -72,7 +72,7 @@ nouveau_channel_idle(struct nouveau_channel *chan)
|
||||
|
||||
ret = nouveau_fence_new(&fence, chan);
|
||||
if (!ret) {
|
||||
ret = nouveau_fence_wait(fence, false, false);
|
||||
ret = nouveau_fence_wait(fence, false);
|
||||
nouveau_fence_unref(&fence);
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ static void nouveau_dmem_page_free(struct page *page)
|
||||
static void nouveau_dmem_fence_done(struct nouveau_fence **fence)
|
||||
{
|
||||
if (fence) {
|
||||
nouveau_fence_wait(*fence, true, false);
|
||||
nouveau_fence_wait(*fence, false);
|
||||
nouveau_fence_unref(fence);
|
||||
} else {
|
||||
/*
|
||||
|
@ -188,7 +188,7 @@ nouveau_exec_job_timeout(struct nouveau_job *job)
|
||||
return DRM_GPU_SCHED_STAT_NOMINAL;
|
||||
}
|
||||
|
||||
static struct nouveau_job_ops nouveau_exec_job_ops = {
|
||||
static const struct nouveau_job_ops nouveau_exec_job_ops = {
|
||||
.submit = nouveau_exec_job_submit,
|
||||
.armed_submit = nouveau_exec_job_armed_submit,
|
||||
.run = nouveau_exec_job_run,
|
||||
|
@ -311,39 +311,11 @@ nouveau_fence_wait_legacy(struct dma_fence *f, bool intr, long wait)
|
||||
return timeout - t;
|
||||
}
|
||||
|
||||
static int
|
||||
nouveau_fence_wait_busy(struct nouveau_fence *fence, bool intr)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
while (!nouveau_fence_done(fence)) {
|
||||
if (time_after_eq(jiffies, fence->timeout)) {
|
||||
ret = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
__set_current_state(intr ?
|
||||
TASK_INTERRUPTIBLE :
|
||||
TASK_UNINTERRUPTIBLE);
|
||||
|
||||
if (intr && signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__set_current_state(TASK_RUNNING);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_fence_wait(struct nouveau_fence *fence, bool lazy, bool intr)
|
||||
nouveau_fence_wait(struct nouveau_fence *fence, bool intr)
|
||||
{
|
||||
long ret;
|
||||
|
||||
if (!lazy)
|
||||
return nouveau_fence_wait_busy(fence, intr);
|
||||
|
||||
ret = dma_fence_wait_timeout(&fence->base, intr, 15 * HZ);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -23,7 +23,7 @@ void nouveau_fence_unref(struct nouveau_fence **);
|
||||
|
||||
int nouveau_fence_emit(struct nouveau_fence *);
|
||||
bool nouveau_fence_done(struct nouveau_fence *);
|
||||
int nouveau_fence_wait(struct nouveau_fence *, bool lazy, bool intr);
|
||||
int nouveau_fence_wait(struct nouveau_fence *, bool intr);
|
||||
int nouveau_fence_sync(struct nouveau_bo *, struct nouveau_channel *, bool exclusive, bool intr);
|
||||
|
||||
struct nouveau_fence_chan {
|
||||
|
@ -928,7 +928,7 @@ revalidate:
|
||||
}
|
||||
|
||||
if (sync) {
|
||||
if (!(ret = nouveau_fence_wait(fence, false, false))) {
|
||||
if (!(ret = nouveau_fence_wait(fence, false))) {
|
||||
if ((ret = dma_fence_get_status(&fence->base)) == 1)
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ struct nouveau_job_args {
|
||||
u32 count;
|
||||
} out_sync;
|
||||
|
||||
struct nouveau_job_ops *ops;
|
||||
const struct nouveau_job_ops *ops;
|
||||
};
|
||||
|
||||
struct nouveau_job {
|
||||
@ -73,7 +73,7 @@ struct nouveau_job {
|
||||
u32 count;
|
||||
} out_sync;
|
||||
|
||||
struct nouveau_job_ops {
|
||||
const struct nouveau_job_ops {
|
||||
/* If .submit() returns without any error, it is guaranteed that
|
||||
* armed_submit() is called.
|
||||
*/
|
||||
|
@ -1534,7 +1534,7 @@ nouveau_uvmm_bind_job_cleanup(struct nouveau_job *job)
|
||||
nouveau_uvmm_bind_job_put(bind_job);
|
||||
}
|
||||
|
||||
static struct nouveau_job_ops nouveau_bind_job_ops = {
|
||||
static const struct nouveau_job_ops nouveau_bind_job_ops = {
|
||||
.submit = nouveau_uvmm_bind_job_submit,
|
||||
.armed_submit = nouveau_uvmm_bind_job_armed_submit,
|
||||
.run = nouveau_uvmm_bind_job_run,
|
||||
|
@ -1045,33 +1045,6 @@ static const struct panel_desc auo_b116xak01 = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct drm_display_mode auo_b133han05_mode = {
|
||||
.clock = 142600,
|
||||
.hdisplay = 1920,
|
||||
.hsync_start = 1920 + 58,
|
||||
.hsync_end = 1920 + 58 + 42,
|
||||
.htotal = 1920 + 58 + 42 + 60,
|
||||
.vdisplay = 1080,
|
||||
.vsync_start = 1080 + 3,
|
||||
.vsync_end = 1080 + 3 + 5,
|
||||
.vtotal = 1080 + 3 + 5 + 54,
|
||||
};
|
||||
|
||||
static const struct panel_desc auo_b133han05 = {
|
||||
.modes = &auo_b133han05_mode,
|
||||
.num_modes = 1,
|
||||
.bpc = 8,
|
||||
.size = {
|
||||
.width = 293,
|
||||
.height = 165,
|
||||
},
|
||||
.delay = {
|
||||
.hpd_reliable = 100,
|
||||
.enable = 20,
|
||||
.unprepare = 50,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct drm_display_mode auo_b133htn01_mode = {
|
||||
.clock = 150660,
|
||||
.hdisplay = 1920,
|
||||
@ -1121,33 +1094,6 @@ static const struct panel_desc auo_b133xtn01 = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct drm_display_mode auo_b140han06_mode = {
|
||||
.clock = 141000,
|
||||
.hdisplay = 1920,
|
||||
.hsync_start = 1920 + 16,
|
||||
.hsync_end = 1920 + 16 + 16,
|
||||
.htotal = 1920 + 16 + 16 + 152,
|
||||
.vdisplay = 1080,
|
||||
.vsync_start = 1080 + 3,
|
||||
.vsync_end = 1080 + 3 + 14,
|
||||
.vtotal = 1080 + 3 + 14 + 19,
|
||||
};
|
||||
|
||||
static const struct panel_desc auo_b140han06 = {
|
||||
.modes = &auo_b140han06_mode,
|
||||
.num_modes = 1,
|
||||
.bpc = 8,
|
||||
.size = {
|
||||
.width = 309,
|
||||
.height = 174,
|
||||
},
|
||||
.delay = {
|
||||
.hpd_reliable = 100,
|
||||
.enable = 20,
|
||||
.unprepare = 50,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct drm_display_mode boe_nv101wxmn51_modes[] = {
|
||||
{
|
||||
.clock = 71900,
|
||||
@ -1414,33 +1360,6 @@ static const struct panel_desc innolux_p120zdg_bf1 = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct drm_display_mode ivo_m133nwf4_r0_mode = {
|
||||
.clock = 138778,
|
||||
.hdisplay = 1920,
|
||||
.hsync_start = 1920 + 24,
|
||||
.hsync_end = 1920 + 24 + 48,
|
||||
.htotal = 1920 + 24 + 48 + 88,
|
||||
.vdisplay = 1080,
|
||||
.vsync_start = 1080 + 3,
|
||||
.vsync_end = 1080 + 3 + 12,
|
||||
.vtotal = 1080 + 3 + 12 + 17,
|
||||
.flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
|
||||
};
|
||||
|
||||
static const struct panel_desc ivo_m133nwf4_r0 = {
|
||||
.modes = &ivo_m133nwf4_r0_mode,
|
||||
.num_modes = 1,
|
||||
.bpc = 8,
|
||||
.size = {
|
||||
.width = 294,
|
||||
.height = 165,
|
||||
},
|
||||
.delay = {
|
||||
.hpd_absent = 200,
|
||||
.unprepare = 500,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct drm_display_mode kingdisplay_kd116n21_30nv_a010_mode = {
|
||||
.clock = 81000,
|
||||
.hdisplay = 1366,
|
||||
@ -1689,97 +1608,39 @@ static const struct panel_desc sharp_lq123p1jx31 = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct drm_display_mode sharp_lq140m1jw46_mode[] = {
|
||||
{
|
||||
.clock = 346500,
|
||||
.hdisplay = 1920,
|
||||
.hsync_start = 1920 + 48,
|
||||
.hsync_end = 1920 + 48 + 32,
|
||||
.htotal = 1920 + 48 + 32 + 80,
|
||||
.vdisplay = 1080,
|
||||
.vsync_start = 1080 + 3,
|
||||
.vsync_end = 1080 + 3 + 5,
|
||||
.vtotal = 1080 + 3 + 5 + 69,
|
||||
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
|
||||
}, {
|
||||
.clock = 144370,
|
||||
.hdisplay = 1920,
|
||||
.hsync_start = 1920 + 48,
|
||||
.hsync_end = 1920 + 48 + 32,
|
||||
.htotal = 1920 + 48 + 32 + 80,
|
||||
.vdisplay = 1080,
|
||||
.vsync_start = 1080 + 3,
|
||||
.vsync_end = 1080 + 3 + 5,
|
||||
.vtotal = 1080 + 3 + 5 + 69,
|
||||
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct panel_desc sharp_lq140m1jw46 = {
|
||||
.modes = sharp_lq140m1jw46_mode,
|
||||
.num_modes = ARRAY_SIZE(sharp_lq140m1jw46_mode),
|
||||
.bpc = 8,
|
||||
.size = {
|
||||
.width = 309,
|
||||
.height = 174,
|
||||
},
|
||||
.delay = {
|
||||
.hpd_absent = 80,
|
||||
.enable = 50,
|
||||
.unprepare = 500,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct drm_display_mode starry_kr122ea0sra_mode = {
|
||||
.clock = 147000,
|
||||
.hdisplay = 1920,
|
||||
.hsync_start = 1920 + 16,
|
||||
.hsync_end = 1920 + 16 + 16,
|
||||
.htotal = 1920 + 16 + 16 + 32,
|
||||
.vdisplay = 1200,
|
||||
.vsync_start = 1200 + 15,
|
||||
.vsync_end = 1200 + 15 + 2,
|
||||
.vtotal = 1200 + 15 + 2 + 18,
|
||||
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
|
||||
};
|
||||
|
||||
static const struct panel_desc starry_kr122ea0sra = {
|
||||
.modes = &starry_kr122ea0sra_mode,
|
||||
.num_modes = 1,
|
||||
.size = {
|
||||
.width = 263,
|
||||
.height = 164,
|
||||
},
|
||||
.delay = {
|
||||
/* TODO: should be hpd-absent and no-hpd should be set? */
|
||||
.hpd_reliable = 10 + 200,
|
||||
.enable = 50,
|
||||
.unprepare = 10 + 500,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct of_device_id platform_of_match[] = {
|
||||
{
|
||||
/* Must be first */
|
||||
.compatible = "edp-panel",
|
||||
}, {
|
||||
},
|
||||
/*
|
||||
* Do not add panels to the list below unless they cannot be handled by
|
||||
* the generic edp-panel compatible.
|
||||
*
|
||||
* The only two valid reasons are:
|
||||
* - Because of the panel issues (e.g. broken EDID or broken
|
||||
* identification).
|
||||
* - Because the eDP drivers didn't wire up the AUX bus properly.
|
||||
* NOTE that, though this is a marginally valid reason,
|
||||
* some justification needs to be made for why the platform can't
|
||||
* wire up the AUX bus properly.
|
||||
*
|
||||
* In all other cases the platform should use the aux-bus and declare
|
||||
* the panel using the 'edp-panel' compatible as a device on the AUX
|
||||
* bus.
|
||||
*/
|
||||
{
|
||||
.compatible = "auo,b101ean01",
|
||||
.data = &auo_b101ean01,
|
||||
}, {
|
||||
.compatible = "auo,b116xa01",
|
||||
.data = &auo_b116xak01,
|
||||
}, {
|
||||
.compatible = "auo,b133han05",
|
||||
.data = &auo_b133han05,
|
||||
}, {
|
||||
.compatible = "auo,b133htn01",
|
||||
.data = &auo_b133htn01,
|
||||
}, {
|
||||
.compatible = "auo,b133xtn01",
|
||||
.data = &auo_b133xtn01,
|
||||
}, {
|
||||
.compatible = "auo,b140han06",
|
||||
.data = &auo_b140han06,
|
||||
}, {
|
||||
.compatible = "boe,nv101wxmn51",
|
||||
.data = &boe_nv101wxmn51,
|
||||
@ -1807,9 +1668,6 @@ static const struct of_device_id platform_of_match[] = {
|
||||
}, {
|
||||
.compatible = "innolux,p120zdg-bf1",
|
||||
.data = &innolux_p120zdg_bf1,
|
||||
}, {
|
||||
.compatible = "ivo,m133nwf4-r0",
|
||||
.data = &ivo_m133nwf4_r0,
|
||||
}, {
|
||||
.compatible = "kingdisplay,kd116n21-30nv-a010",
|
||||
.data = &kingdisplay_kd116n21_30nv_a010,
|
||||
@ -1840,12 +1698,6 @@ static const struct of_device_id platform_of_match[] = {
|
||||
}, {
|
||||
.compatible = "sharp,lq123p1jx31",
|
||||
.data = &sharp_lq123p1jx31,
|
||||
}, {
|
||||
.compatible = "sharp,lq140m1jw46",
|
||||
.data = &sharp_lq140m1jw46,
|
||||
}, {
|
||||
.compatible = "starry,kr122ea0sra",
|
||||
.data = &starry_kr122ea0sra,
|
||||
}, {
|
||||
/* sentinel */
|
||||
}
|
||||
@ -1897,6 +1749,12 @@ static const struct panel_delay delay_200_500_e80_d50 = {
|
||||
.disable = 50,
|
||||
};
|
||||
|
||||
static const struct panel_delay delay_80_500_e50 = {
|
||||
.hpd_absent = 80,
|
||||
.unprepare = 500,
|
||||
.enable = 50,
|
||||
};
|
||||
|
||||
static const struct panel_delay delay_100_500_e200 = {
|
||||
.hpd_absent = 100,
|
||||
.unprepare = 500,
|
||||
@ -2105,7 +1963,7 @@ static const struct edp_panel_entry edp_panels[] = {
|
||||
EDP_PANEL_ENTRY('S', 'D', 'C', 0x416d, &delay_100_500_e200, "ATNA45AF01"),
|
||||
|
||||
EDP_PANEL_ENTRY('S', 'H', 'P', 0x1511, &delay_200_500_e50, "LQ140M1JW48"),
|
||||
EDP_PANEL_ENTRY('S', 'H', 'P', 0x1523, &sharp_lq140m1jw46.delay, "LQ140M1JW46"),
|
||||
EDP_PANEL_ENTRY('S', 'H', 'P', 0x1523, &delay_80_500_e50, "LQ140M1JW46"),
|
||||
EDP_PANEL_ENTRY('S', 'H', 'P', 0x153a, &delay_200_500_e50, "LQ140T1JH01"),
|
||||
EDP_PANEL_ENTRY('S', 'H', 'P', 0x154c, &delay_200_500_p2e100, "LQ116M1JW10"),
|
||||
|
||||
|
@ -777,6 +777,15 @@ static const struct panfrost_compatible mediatek_mt8186_data = {
|
||||
.pm_features = BIT(GPU_PM_CLK_DIS) | BIT(GPU_PM_VREG_OFF),
|
||||
};
|
||||
|
||||
/* MT8188 uses the same power domains and power supplies as MT8183 */
|
||||
static const struct panfrost_compatible mediatek_mt8188_data = {
|
||||
.num_supplies = ARRAY_SIZE(mediatek_mt8183_b_supplies) - 1,
|
||||
.supply_names = mediatek_mt8183_b_supplies,
|
||||
.num_pm_domains = ARRAY_SIZE(mediatek_mt8183_pm_domains),
|
||||
.pm_domain_names = mediatek_mt8183_pm_domains,
|
||||
.pm_features = BIT(GPU_PM_CLK_DIS) | BIT(GPU_PM_VREG_OFF),
|
||||
};
|
||||
|
||||
static const char * const mediatek_mt8192_supplies[] = { "mali", NULL };
|
||||
static const char * const mediatek_mt8192_pm_domains[] = { "core0", "core1", "core2",
|
||||
"core3", "core4" };
|
||||
@ -808,6 +817,7 @@ static const struct of_device_id dt_match[] = {
|
||||
{ .compatible = "mediatek,mt8183-mali", .data = &mediatek_mt8183_data },
|
||||
{ .compatible = "mediatek,mt8183b-mali", .data = &mediatek_mt8183_b_data },
|
||||
{ .compatible = "mediatek,mt8186-mali", .data = &mediatek_mt8186_data },
|
||||
{ .compatible = "mediatek,mt8188-mali", .data = &mediatek_mt8188_data },
|
||||
{ .compatible = "mediatek,mt8192-mali", .data = &mediatek_mt8192_data },
|
||||
{}
|
||||
};
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_blend.h>
|
||||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_fb_dma_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_framebuffer.h>
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
@ -166,6 +167,14 @@ static const struct drm_plane_helper_funcs tidss_plane_helper_funcs = {
|
||||
.atomic_disable = tidss_plane_atomic_disable,
|
||||
};
|
||||
|
||||
static const struct drm_plane_helper_funcs tidss_primary_plane_helper_funcs = {
|
||||
.atomic_check = tidss_plane_atomic_check,
|
||||
.atomic_update = tidss_plane_atomic_update,
|
||||
.atomic_enable = tidss_plane_atomic_enable,
|
||||
.atomic_disable = tidss_plane_atomic_disable,
|
||||
.get_scanout_buffer = drm_fb_dma_get_scanout_buffer,
|
||||
};
|
||||
|
||||
static const struct drm_plane_funcs tidss_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
@ -211,7 +220,10 @@ struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
drm_plane_helper_add(&tplane->plane, &tidss_plane_helper_funcs);
|
||||
if (type == DRM_PLANE_TYPE_PRIMARY)
|
||||
drm_plane_helper_add(&tplane->plane, &tidss_primary_plane_helper_funcs);
|
||||
else
|
||||
drm_plane_helper_add(&tplane->plane, &tidss_plane_helper_funcs);
|
||||
|
||||
drm_plane_create_zpos_property(&tplane->plane, tidss->num_planes, 0,
|
||||
num_planes - 1);
|
||||
|
@ -256,10 +256,10 @@ struct zynqmp_dp_link_config {
|
||||
* @fmt: format identifier string
|
||||
*/
|
||||
struct zynqmp_dp_mode {
|
||||
const char *fmt;
|
||||
int pclock;
|
||||
u8 bw_code;
|
||||
u8 lane_cnt;
|
||||
int pclock;
|
||||
const char *fmt;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -296,27 +296,27 @@ struct zynqmp_dp_config {
|
||||
* @train_set: set of training data
|
||||
*/
|
||||
struct zynqmp_dp {
|
||||
struct drm_dp_aux aux;
|
||||
struct drm_bridge bridge;
|
||||
struct work_struct hpd_work;
|
||||
|
||||
struct drm_bridge *next_bridge;
|
||||
struct device *dev;
|
||||
struct zynqmp_dpsub *dpsub;
|
||||
void __iomem *iomem;
|
||||
struct reset_control *reset;
|
||||
int irq;
|
||||
|
||||
struct drm_bridge bridge;
|
||||
struct drm_bridge *next_bridge;
|
||||
|
||||
struct zynqmp_dp_config config;
|
||||
struct drm_dp_aux aux;
|
||||
struct phy *phy[ZYNQMP_DP_MAX_LANES];
|
||||
u8 num_lanes;
|
||||
struct delayed_work hpd_work;
|
||||
|
||||
enum drm_connector_status status;
|
||||
int irq;
|
||||
bool enabled;
|
||||
|
||||
u8 dpcd[DP_RECEIVER_CAP_SIZE];
|
||||
struct zynqmp_dp_link_config link_config;
|
||||
struct zynqmp_dp_mode mode;
|
||||
struct zynqmp_dp_link_config link_config;
|
||||
struct zynqmp_dp_config config;
|
||||
u8 dpcd[DP_RECEIVER_CAP_SIZE];
|
||||
u8 train_set[ZYNQMP_DP_MAX_LANES];
|
||||
u8 num_lanes;
|
||||
};
|
||||
|
||||
static inline struct zynqmp_dp *bridge_to_dp(struct drm_bridge *bridge)
|
||||
@ -1482,7 +1482,7 @@ static void zynqmp_dp_bridge_atomic_disable(struct drm_bridge *bridge,
|
||||
struct zynqmp_dp *dp = bridge_to_dp(bridge);
|
||||
|
||||
dp->enabled = false;
|
||||
cancel_delayed_work(&dp->hpd_work);
|
||||
cancel_work(&dp->hpd_work);
|
||||
zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 0);
|
||||
drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
|
||||
zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN,
|
||||
@ -1648,8 +1648,7 @@ void zynqmp_dp_disable_vblank(struct zynqmp_dp *dp)
|
||||
|
||||
static void zynqmp_dp_hpd_work_func(struct work_struct *work)
|
||||
{
|
||||
struct zynqmp_dp *dp = container_of(work, struct zynqmp_dp,
|
||||
hpd_work.work);
|
||||
struct zynqmp_dp *dp = container_of(work, struct zynqmp_dp, hpd_work);
|
||||
enum drm_connector_status status;
|
||||
|
||||
status = zynqmp_dp_bridge_detect(&dp->bridge);
|
||||
@ -1685,7 +1684,7 @@ static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data)
|
||||
zynqmp_dpsub_drm_handle_vblank(dp->dpsub);
|
||||
|
||||
if (status & ZYNQMP_DP_INT_HPD_EVENT)
|
||||
schedule_delayed_work(&dp->hpd_work, 0);
|
||||
schedule_work(&dp->hpd_work);
|
||||
|
||||
if (status & ZYNQMP_DP_INT_HPD_IRQ) {
|
||||
int ret;
|
||||
@ -1727,7 +1726,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub)
|
||||
dp->dpsub = dpsub;
|
||||
dp->status = connector_status_disconnected;
|
||||
|
||||
INIT_DELAYED_WORK(&dp->hpd_work, zynqmp_dp_hpd_work_func);
|
||||
INIT_WORK(&dp->hpd_work, zynqmp_dp_hpd_work_func);
|
||||
|
||||
/* Acquire all resources (IOMEM, IRQ and PHYs). */
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dp");
|
||||
@ -1832,7 +1831,7 @@ void zynqmp_dp_remove(struct zynqmp_dpsub *dpsub)
|
||||
zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_ALL);
|
||||
disable_irq(dp->irq);
|
||||
|
||||
cancel_delayed_work_sync(&dp->hpd_work);
|
||||
cancel_work_sync(&dp->hpd_work);
|
||||
|
||||
zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 0);
|
||||
zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, 0xffffffff);
|
||||
|
@ -269,6 +269,7 @@ static int zynqmp_dpsub_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
err_disp:
|
||||
drm_bridge_remove(dpsub->bridge);
|
||||
zynqmp_disp_remove(dpsub);
|
||||
err_dp:
|
||||
zynqmp_dp_remove(dpsub);
|
||||
|
@ -120,9 +120,13 @@ static void zynqmp_dpsub_plane_atomic_update(struct drm_plane *plane,
|
||||
zynqmp_disp_blend_set_global_alpha(dpsub->disp, true,
|
||||
plane->state->alpha >> 8);
|
||||
|
||||
/* Enable or re-enable the plane if the format has changed. */
|
||||
if (format_changed)
|
||||
zynqmp_disp_layer_enable(layer);
|
||||
/*
|
||||
* Unconditionally enable the layer, as it may have been disabled
|
||||
* previously either explicitly to reconfigure layer format, or
|
||||
* implicitly after DPSUB reset during display mode change. DRM
|
||||
* framework calls this callback for enabled planes only.
|
||||
*/
|
||||
zynqmp_disp_layer_enable(layer);
|
||||
}
|
||||
|
||||
static const struct drm_plane_helper_funcs zynqmp_dpsub_plane_helper_funcs = {
|
||||
@ -433,23 +437,28 @@ static int zynqmp_dpsub_kms_init(struct zynqmp_dpsub *dpsub)
|
||||
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
|
||||
if (ret) {
|
||||
dev_err(dpsub->dev, "failed to attach bridge to encoder\n");
|
||||
return ret;
|
||||
goto err_encoder;
|
||||
}
|
||||
|
||||
/* Create the connector for the chain of bridges. */
|
||||
connector = drm_bridge_connector_init(&dpsub->drm->dev, encoder);
|
||||
if (IS_ERR(connector)) {
|
||||
dev_err(dpsub->dev, "failed to created connector\n");
|
||||
return PTR_ERR(connector);
|
||||
ret = PTR_ERR(connector);
|
||||
goto err_encoder;
|
||||
}
|
||||
|
||||
ret = drm_connector_attach_encoder(connector, encoder);
|
||||
if (ret < 0) {
|
||||
dev_err(dpsub->dev, "failed to attach connector to encoder\n");
|
||||
return ret;
|
||||
goto err_encoder;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_encoder:
|
||||
drm_encoder_cleanup(encoder);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void zynqmp_dpsub_drm_release(struct drm_device *drm, void *res)
|
||||
@ -529,5 +538,6 @@ void zynqmp_dpsub_drm_cleanup(struct zynqmp_dpsub *dpsub)
|
||||
|
||||
drm_dev_unregister(drm);
|
||||
drm_atomic_helper_shutdown(drm);
|
||||
drm_encoder_cleanup(&dpsub->drm->encoder);
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
}
|
||||
|
@ -201,6 +201,13 @@ enum drm_connector_tv_mode {
|
||||
*/
|
||||
DRM_MODE_TV_MODE_SECAM,
|
||||
|
||||
/**
|
||||
* @DRM_MODE_TV_MODE_MONOCHROME: Use timings appropriate to
|
||||
* the DRM mode, including equalizing pulses for a 525-line
|
||||
* or 625-line mode, with no pedestal or color encoding.
|
||||
*/
|
||||
DRM_MODE_TV_MODE_MONOCHROME,
|
||||
|
||||
/**
|
||||
* @DRM_MODE_TV_MODE_MAX: Number of analog TV output modes.
|
||||
*
|
||||
@ -929,6 +936,67 @@ struct drm_connector_hdmi_infoframe {
|
||||
bool set;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct drm_connector_hdmi_state - HDMI state container
|
||||
*/
|
||||
struct drm_connector_hdmi_state {
|
||||
/**
|
||||
* @broadcast_rgb: Connector property to pass the
|
||||
* Broadcast RGB selection value.
|
||||
*/
|
||||
enum drm_hdmi_broadcast_rgb broadcast_rgb;
|
||||
|
||||
/**
|
||||
* @infoframes: HDMI Infoframes matching that state
|
||||
*/
|
||||
struct {
|
||||
/**
|
||||
* @avi: AVI Infoframes structure matching our
|
||||
* state.
|
||||
*/
|
||||
struct drm_connector_hdmi_infoframe avi;
|
||||
|
||||
/**
|
||||
* @hdr_drm: DRM (Dynamic Range and Mastering)
|
||||
* Infoframes structure matching our state.
|
||||
*/
|
||||
struct drm_connector_hdmi_infoframe hdr_drm;
|
||||
|
||||
/**
|
||||
* @spd: SPD Infoframes structure matching our
|
||||
* state.
|
||||
*/
|
||||
struct drm_connector_hdmi_infoframe spd;
|
||||
|
||||
/**
|
||||
* @vendor: HDMI Vendor Infoframes structure
|
||||
* matching our state.
|
||||
*/
|
||||
struct drm_connector_hdmi_infoframe hdmi;
|
||||
} infoframes;
|
||||
|
||||
/**
|
||||
* @is_limited_range: Is the output supposed to use a limited
|
||||
* RGB Quantization Range or not?
|
||||
*/
|
||||
bool is_limited_range;
|
||||
|
||||
/**
|
||||
* @output_bpc: Bits per color channel to output.
|
||||
*/
|
||||
unsigned int output_bpc;
|
||||
|
||||
/**
|
||||
* @output_format: Pixel format to output in.
|
||||
*/
|
||||
enum hdmi_colorspace output_format;
|
||||
|
||||
/**
|
||||
* @tmds_char_rate: TMDS Character Rate, in Hz.
|
||||
*/
|
||||
unsigned long long tmds_char_rate;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_connector_state - mutable connector state
|
||||
*/
|
||||
@ -1078,63 +1146,7 @@ struct drm_connector_state {
|
||||
* @hdmi: HDMI-related variable and properties. Filled by
|
||||
* @drm_atomic_helper_connector_hdmi_check().
|
||||
*/
|
||||
struct {
|
||||
/**
|
||||
* @broadcast_rgb: Connector property to pass the
|
||||
* Broadcast RGB selection value.
|
||||
*/
|
||||
enum drm_hdmi_broadcast_rgb broadcast_rgb;
|
||||
|
||||
/**
|
||||
* @infoframes: HDMI Infoframes matching that state
|
||||
*/
|
||||
struct {
|
||||
/**
|
||||
* @avi: AVI Infoframes structure matching our
|
||||
* state.
|
||||
*/
|
||||
struct drm_connector_hdmi_infoframe avi;
|
||||
|
||||
/**
|
||||
* @hdr_drm: DRM (Dynamic Range and Mastering)
|
||||
* Infoframes structure matching our state.
|
||||
*/
|
||||
struct drm_connector_hdmi_infoframe hdr_drm;
|
||||
|
||||
/**
|
||||
* @spd: SPD Infoframes structure matching our
|
||||
* state.
|
||||
*/
|
||||
struct drm_connector_hdmi_infoframe spd;
|
||||
|
||||
/**
|
||||
* @vendor: HDMI Vendor Infoframes structure
|
||||
* matching our state.
|
||||
*/
|
||||
struct drm_connector_hdmi_infoframe hdmi;
|
||||
} infoframes;
|
||||
|
||||
/**
|
||||
* @is_limited_range: Is the output supposed to use a limited
|
||||
* RGB Quantization Range or not?
|
||||
*/
|
||||
bool is_limited_range;
|
||||
|
||||
/**
|
||||
* @output_bpc: Bits per color channel to output.
|
||||
*/
|
||||
unsigned int output_bpc;
|
||||
|
||||
/**
|
||||
* @output_format: Pixel format to output in.
|
||||
*/
|
||||
enum hdmi_colorspace output_format;
|
||||
|
||||
/**
|
||||
* @tmds_char_rate: TMDS Character Rate, in Hz.
|
||||
*/
|
||||
unsigned long long tmds_char_rate;
|
||||
} hdmi;
|
||||
struct drm_connector_hdmi_state hdmi;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1656,6 +1668,51 @@ struct drm_cmdline_mode {
|
||||
bool tv_mode_specified;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct drm_connector_hdmi - DRM Connector HDMI-related structure
|
||||
*/
|
||||
struct drm_connector_hdmi {
|
||||
#define DRM_CONNECTOR_HDMI_VENDOR_LEN 8
|
||||
/**
|
||||
* @vendor: HDMI Controller Vendor Name
|
||||
*/
|
||||
unsigned char vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] __nonstring;
|
||||
|
||||
#define DRM_CONNECTOR_HDMI_PRODUCT_LEN 16
|
||||
/**
|
||||
* @product: HDMI Controller Product Name
|
||||
*/
|
||||
unsigned char product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] __nonstring;
|
||||
|
||||
/**
|
||||
* @supported_formats: Bitmask of @hdmi_colorspace
|
||||
* supported by the controller.
|
||||
*/
|
||||
unsigned long supported_formats;
|
||||
|
||||
/**
|
||||
* @funcs: HDMI connector Control Functions
|
||||
*/
|
||||
const struct drm_connector_hdmi_funcs *funcs;
|
||||
|
||||
/**
|
||||
* @infoframes: Current Infoframes output by the connector
|
||||
*/
|
||||
struct {
|
||||
/**
|
||||
* @lock: Mutex protecting against concurrent access to
|
||||
* the infoframes, most notably between KMS and ALSA.
|
||||
*/
|
||||
struct mutex lock;
|
||||
|
||||
/**
|
||||
* @audio: Current Audio Infoframes structure. Protected
|
||||
* by @lock.
|
||||
*/
|
||||
struct drm_connector_hdmi_infoframe audio;
|
||||
} infoframes;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_connector - central DRM connector control structure
|
||||
*
|
||||
@ -2068,47 +2125,7 @@ struct drm_connector {
|
||||
/**
|
||||
* @hdmi: HDMI-related variable and properties.
|
||||
*/
|
||||
struct {
|
||||
#define DRM_CONNECTOR_HDMI_VENDOR_LEN 8
|
||||
/**
|
||||
* @vendor: HDMI Controller Vendor Name
|
||||
*/
|
||||
unsigned char vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] __nonstring;
|
||||
|
||||
#define DRM_CONNECTOR_HDMI_PRODUCT_LEN 16
|
||||
/**
|
||||
* @product: HDMI Controller Product Name
|
||||
*/
|
||||
unsigned char product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] __nonstring;
|
||||
|
||||
/**
|
||||
* @supported_formats: Bitmask of @hdmi_colorspace
|
||||
* supported by the controller.
|
||||
*/
|
||||
unsigned long supported_formats;
|
||||
|
||||
/**
|
||||
* @funcs: HDMI connector Control Functions
|
||||
*/
|
||||
const struct drm_connector_hdmi_funcs *funcs;
|
||||
|
||||
/**
|
||||
* @infoframes: Current Infoframes output by the connector
|
||||
*/
|
||||
struct {
|
||||
/**
|
||||
* @lock: Mutex protecting against concurrent access to
|
||||
* the infoframes, most notably between KMS and ALSA.
|
||||
*/
|
||||
struct mutex lock;
|
||||
|
||||
/**
|
||||
* @audio: Current Audio Infoframes structure. Protected
|
||||
* by @lock.
|
||||
*/
|
||||
struct drm_connector_hdmi_infoframe audio;
|
||||
} infoframes;
|
||||
} hdmi;
|
||||
struct drm_connector_hdmi hdmi;
|
||||
};
|
||||
|
||||
#define obj_to_connector(x) container_of(x, struct drm_connector, base)
|
||||
|
@ -23,8 +23,8 @@ struct dma_heap;
|
||||
struct dma_heap_ops {
|
||||
struct dma_buf *(*allocate)(struct dma_heap *heap,
|
||||
unsigned long len,
|
||||
unsigned long fd_flags,
|
||||
unsigned long heap_flags);
|
||||
u32 fd_flags,
|
||||
u64 heap_flags);
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user