[PATCHv3 2/2] i915/display/dp: SDP CRC16 for 128b132b link layer
Enable SDP error detection configuration, this will set CRC16 in 128b/132b link layer. For Display version 13 a hardware bit31 in register VIDEO_DIP_CTL is added to enable/disable SDP CRC applicable for DP2.0 only, but the default value of this bit will enable CRC16 in 128b/132b hence skipping this write. Corrective actions on SDP corruption is yet to be defined. v2: Moved the CRC enable to link training init(Jani N) v3: Moved crc enable to ddi pre enable Signed-off-by: Arun R Murthy --- .../gpu/drm/i915/display/intel_dp_link_training.c| 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 3d3efcf02011..7064e465423b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -1453,4 +1453,16 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp, if (!passed) intel_dp_schedule_fallback_link_training(intel_dp, crtc_state); + + /* DP v2.0 SCR on SDP CRC16 for 128b/132b Link Layer */ + if (intel_dp_is_uhbr(crtc_state) && passed) + drm_dp_dpcd_writeb(_dp->aux, + DP_SDP_ERROR_DETECTION_CONFIGURATION, + DP_SDP_CRC16_128B132B_EN); + /* +* VIDEO_DIP_CTL register bit 31 should be set to '0' to not +* disable SDP CRC. This is applicable for Display version 13. +* Default value of bit 31 is '0' hence discarding the write +*/ + /* TODO: Corrective actions on SDP corruption yet to be defined */ } -- 2.25.1
[PATCHv2 1/2] drm: Add SDP Error Detection Configuration Register
DP2.0 E11 defines a new register to facilitate SDP error detection by a 128B/132B capable DPRX device. v2: Update the macro name to reflect the DP spec(Harry) Signed-off-by: Arun R Murthy Reviewed-by: Harry Wentland --- include/drm/display/drm_dp.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index 632376c291db..358db4a9f167 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -692,6 +692,9 @@ # define DP_FEC_LANE_2_SELECT (2 << 4) # define DP_FEC_LANE_3_SELECT (3 << 4) +#define DP_SDP_ERROR_DETECTION_CONFIGURATION 0x121 /* DP 2.0 E11 */ +#define DP_SDP_CRC16_128B132B_EN BIT(0) + #define DP_AUX_FRAME_SYNC_VALUE0x15c /* eDP 1.4 */ # define DP_AUX_FRAME_SYNC_VALID (1 << 0) -- 2.25.1
[PATCHv3 0/2] DP2.0 SDP CRC16 for 128/132b link layer
*** BLURB HERE *** Arun R Murthy (2): drm: Add SDP Error Detection Configuration Register i915/display/dp: SDP CRC16 for 128b132b link layer .../gpu/drm/i915/display/intel_dp_link_training.c| 12 include/drm/display/drm_dp.h | 3 +++ 2 files changed, 15 insertions(+) -- 2.25.1
[PATCH v2 6/6] drm/i915/guc: More debug print updates - GuC logging
From: John Harrison Update a bunch more debug prints to use the new GT based scheme. Signed-off-by: John Harrison Reviewed-by: Michal Wajdeczko --- drivers/gpu/drm/i915/gt/intel_gt_print.h | 3 +++ drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 3 +-- drivers/gpu/drm/i915/gt/uc/intel_guc_print.h | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_print.h b/drivers/gpu/drm/i915/gt/intel_gt_print.h index 5d9da355ce242..55a336a9ff061 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_print.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_print.h @@ -28,6 +28,9 @@ #define gt_err_ratelimited(_gt, _fmt, ...) \ drm_err_ratelimited(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, ##__VA_ARGS__) +#define gt_notice_ratelimited(_gt, _fmt, ...) \ + dev_notice_ratelimited((_gt)->i915->drm.dev, "GT%u: " _fmt, (_gt)->info.id, ##__VA_ARGS__) + #define gt_probe_error(_gt, _fmt, ...) \ do { \ if (i915_error_injected()) \ diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c index c3792ddeec802..818e9e0e66a83 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c @@ -333,8 +333,7 @@ bool intel_guc_check_log_buf_overflow(struct intel_guc_log *log, log->stats[type].sampled_overflow += 16; } - dev_notice_ratelimited(guc_to_gt(log_to_guc(log))->i915->drm.dev, - "GuC log buffer overflow\n"); + guc_notice_ratelimited(log_to_guc(log), "log buffer overflow\n"); } return overflow; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_print.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_print.h index e75989d4ba067..2465d05638b40 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_print.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_print.h @@ -30,6 +30,9 @@ #define guc_err_ratelimited(_guc, _fmt, ...) \ guc_printk((_guc), err_ratelimited, _fmt, ##__VA_ARGS__) +#define guc_notice_ratelimited(_guc, _fmt, ...) \ + guc_printk((_guc), notice_ratelimited, _fmt, ##__VA_ARGS__) + #define guc_probe_error(_guc, _fmt, ...) \ guc_printk((_guc), probe_error, _fmt, ##__VA_ARGS__) -- 2.39.1
[PATCH v2 2/6] drm/i915/guc: More debug print updates - GSC firmware
From: John Harrison Update a bunch more debug prints to use the new GT based scheme. v2: Also change prints to use %pe for error values (MichalW). Signed-off-by: John Harrison Acked-by: Michal Wajdeczko --- drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 9 - drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 7 +++ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c index e73d4440c5e82..1d9fdfb112681 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c @@ -6,6 +6,7 @@ #include "gt/intel_engine_pm.h" #include "gt/intel_gpu_commands.h" #include "gt/intel_gt.h" +#include "gt/intel_gt_print.h" #include "gt/intel_ring.h" #include "intel_gsc_fw.h" @@ -88,9 +89,8 @@ static int gsc_fw_load(struct intel_gsc_uc *gsc) i915_request_put(rq); if (err) - drm_err(_uc_to_gt(gsc)->i915->drm, - "Request submission for GSC load failed (%d)\n", - err); + gt_err(gsc_uc_to_gt(gsc), "Request submission for GSC load failed %pe\n", + ERR_PTR(err)); return err; } @@ -200,8 +200,7 @@ int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc) /* FW is not fully operational until we enable SW proxy */ intel_uc_fw_change_status(gsc_fw, INTEL_UC_FIRMWARE_TRANSFERRED); - drm_info(>i915->drm, "Loaded GSC firmware %s\n", -gsc_fw->file_selected.path); + gt_info(gt, "Loaded GSC firmware %s\n", gsc_fw->file_selected.path); return 0; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c index fd21dbd2663be..8afd42cbded96 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c @@ -6,6 +6,7 @@ #include #include "gt/intel_gt.h" +#include "gt/intel_gt_print.h" #include "intel_gsc_uc.h" #include "intel_gsc_fw.h" #include "i915_drv.h" @@ -59,7 +60,6 @@ int intel_gsc_uc_init(struct intel_gsc_uc *gsc) { static struct lock_class_key gsc_lock; struct intel_gt *gt = gsc_uc_to_gt(gsc); - struct drm_i915_private *i915 = gt->i915; struct intel_engine_cs *engine = gt->engine[GSC0]; struct intel_context *ce; struct i915_vma *vma; @@ -81,8 +81,7 @@ int intel_gsc_uc_init(struct intel_gsc_uc *gsc) I915_GEM_HWS_GSC_ADDR, _lock, "gsc_context"); if (IS_ERR(ce)) { - drm_err(>i915->drm, - "failed to create GSC CS ctx for FW communication\n"); + gt_err(gt, "failed to create GSC CS ctx for FW communication\n"); err = PTR_ERR(ce); goto out_vma; } @@ -98,7 +97,7 @@ int intel_gsc_uc_init(struct intel_gsc_uc *gsc) out_fw: intel_uc_fw_fini(>fw); out: - i915_probe_error(i915, "failed with %d\n", err); + gt_probe_error(gt, "GSC init failed %pe\n", ERR_PTR(err)); return err; } -- 2.39.1
[PATCH v2 0/6] More drm_dbg to guc_dbg changes
From: John Harrison Update more print messages to the new scheme. v2: Also change all errors to %pe rather than %d (MichalW). Few other tweaks. Signed-off-by: John Harrison John Harrison (6): drm/i915/guc: More debug print updates - UC firmware drm/i915/guc: More debug print updates - GSC firmware drm/i915/guc: More debug print updates - GuC reg capture drm/i915/guc: More debug print updates - GuC selftests drm/i915/guc: More debug print updates - GuC SLPC drm/i915/guc: More debug print updates - GuC logging drivers/gpu/drm/i915/gt/intel_gt_print.h | 3 + drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 9 +- drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 7 +- .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 51 drivers/gpu/drm/i915/gt/uc/intel_guc_log.c| 3 +- drivers/gpu/drm/i915/gt/uc/intel_guc_print.h | 3 + drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c | 8 +- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 61 - drivers/gpu/drm/i915/gt/uc/intel_uc.c | 42 +++ drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 116 +- drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 42 --- .../drm/i915/gt/uc/selftest_guc_hangcheck.c | 23 ++-- .../drm/i915/gt/uc/selftest_guc_multi_lrc.c | 11 +- 13 files changed, 174 insertions(+), 205 deletions(-) -- 2.39.1
[PATCH v2 3/6] drm/i915/guc: More debug print updates - GuC reg capture
From: John Harrison Update a bunch more debug prints to use the new GT based scheme. v2: Upgrade the no node found message to a warning on the grounds of it being quite important if the error capture can't find any register state information. Signed-off-by: John Harrison Reviewed-by: Alan Previn --- .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 51 --- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c index fc3b994626a4f..101d44de729b1 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c @@ -15,6 +15,7 @@ #include "guc_capture_fwif.h" #include "intel_guc_capture.h" #include "intel_guc_fwif.h" +#include "intel_guc_print.h" #include "i915_drv.h" #include "i915_gpu_error.h" #include "i915_irq.h" @@ -353,7 +354,6 @@ guc_capture_alloc_steered_lists_xe_hpg(struct intel_guc *guc, u32 ipver) { struct intel_gt *gt = guc_to_gt(guc); - struct drm_i915_private *i915 = guc_to_gt(guc)->i915; struct sseu_dev_info *sseu; int slice, subslice, i, iter, num_steer_regs, num_tot_regs = 0; const struct __guc_mmio_reg_descr_group *list; @@ -402,7 +402,7 @@ guc_capture_alloc_steered_lists_xe_hpg(struct intel_guc *guc, } } - drm_dbg(>drm, "GuC-capture found %d-ext-regs.\n", num_tot_regs); + guc_dbg(guc, "capture found %d ext-regs.\n", num_tot_regs); guc->capture->extlists = extlists; } @@ -477,7 +477,6 @@ guc_capture_list_init(struct intel_guc *guc, u32 owner, u32 type, u32 classid, struct guc_mmio_reg *ptr, u16 num_entries) { u32 i = 0, j = 0; - struct drm_i915_private *i915 = guc_to_gt(guc)->i915; const struct __guc_mmio_reg_descr_group *reglists = guc->capture->reglists; struct __guc_mmio_reg_descr_group *extlists = guc->capture->extlists; const struct __guc_mmio_reg_descr_group *match; @@ -509,8 +508,7 @@ guc_capture_list_init(struct intel_guc *guc, u32 owner, u32 type, u32 classid, } } if (i < num_entries) - drm_dbg(>drm, "GuC-capture: Init reglist short %d out %d.\n", - (int)i, (int)num_entries); + guc_dbg(guc, "Got short capture reglist init: %d out %d.\n", i, num_entries); return 0; } @@ -540,12 +538,11 @@ guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid, size_t *size, bool is_purpose_est) { struct intel_guc_state_capture *gc = guc->capture; - struct drm_i915_private *i915 = guc_to_gt(guc)->i915; struct __guc_capture_ads_cache *cache = >ads_cache[owner][type][classid]; int num_regs; if (!gc->reglists) { - drm_warn(>drm, "GuC-capture: No reglist on this device\n"); + guc_warn(guc, "No capture reglist for this device\n"); return -ENODEV; } @@ -557,9 +554,9 @@ guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid, if (!is_purpose_est && owner == GUC_CAPTURE_LIST_INDEX_PF && !guc_capture_get_one_list(gc->reglists, owner, type, classid)) { if (type == GUC_CAPTURE_LIST_TYPE_GLOBAL) - drm_warn(>drm, "Missing GuC-Err-Cap reglist Global!\n"); + guc_warn(guc, "Missing capture reglist: global!\n"); else - drm_warn(>drm, "Missing GuC-Err-Cap reglist %s(%u):%s(%u)!\n", + guc_warn(guc, "Missing capture reglist: %s(%u):%s(%u)!\n", __stringify_type(type), type, __stringify_engclass(classid), classid); return -ENODATA; @@ -592,7 +589,6 @@ intel_guc_capture_getlist(struct intel_guc *guc, u32 owner, u32 type, u32 classi { struct intel_guc_state_capture *gc = guc->capture; struct __guc_capture_ads_cache *cache = >ads_cache[owner][type][classid]; - struct drm_i915_private *i915 = guc_to_gt(guc)->i915; struct guc_debug_capture_list *listnode; int ret, num_regs; u8 *caplist, *tmp; @@ -623,7 +619,7 @@ intel_guc_capture_getlist(struct intel_guc *guc, u32 owner, u32 type, u32 classi caplist = kzalloc(size, GFP_KERNEL); if (!caplist) { - drm_dbg(>drm, "GuC-capture: failed to alloc cached caplist"); + guc_dbg(guc, "Failed to alloc cached register capture list"); return -ENOMEM; } @@ -653,7 +649,6 @@ intel_guc_capture_getnullheader(struct intel_guc *guc, void **outptr, size_t *size) { struct intel_guc_state_capture *gc = guc->capture; - struct drm_i915_private *i915 = guc_to_gt(guc)->i915; int tmp
[PATCH v2 4/6] drm/i915/guc: More debug print updates - GuC selftests
From: John Harrison Update a bunch more debug prints to use the new GT based scheme. v2: Also change prints to use %pe for error values (MichalW). Fix a context leak on error due to a -- being too early. Use the correct header file for the debug macros. Signed-off-by: John Harrison --- drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 42 ++- .../drm/i915/gt/uc/selftest_guc_hangcheck.c | 23 +- .../drm/i915/gt/uc/selftest_guc_multi_lrc.c | 11 ++--- 3 files changed, 40 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c index e28518fe8b908..1fd760539f77b 100644 --- a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c +++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c @@ -3,6 +3,8 @@ * Copyright �� 2021 Intel Corporation */ +#include "gt/intel_gt_print.h" +#include "intel_guc_print.h" #include "selftests/igt_spinner.h" #include "selftests/intel_scheduler_helpers.h" @@ -65,7 +67,7 @@ static int intel_guc_scrub_ctbs(void *arg) ce = intel_context_create(engine); if (IS_ERR(ce)) { ret = PTR_ERR(ce); - drm_err(>i915->drm, "Failed to create context, %d: %d\n", i, ret); + gt_err(gt, "Failed to create context %d: %pe\n", i, ce); goto err; } @@ -86,7 +88,7 @@ static int intel_guc_scrub_ctbs(void *arg) if (IS_ERR(rq)) { ret = PTR_ERR(rq); - drm_err(>i915->drm, "Failed to create request, %d: %d\n", i, ret); + gt_err(gt, "Failed to create request %d: %pe\n", i, rq); goto err; } @@ -96,7 +98,7 @@ static int intel_guc_scrub_ctbs(void *arg) for (i = 0; i < 3; ++i) { ret = i915_request_wait(last[i], 0, HZ); if (ret < 0) { - drm_err(>i915->drm, "Last request failed to complete: %d\n", ret); + gt_err(gt, "Last request failed to complete: %pe\n", ERR_PTR(ret)); goto err; } i915_request_put(last[i]); @@ -113,7 +115,7 @@ static int intel_guc_scrub_ctbs(void *arg) /* GT will not idle if G2H are lost */ ret = intel_gt_wait_for_idle(gt, HZ); if (ret < 0) { - drm_err(>i915->drm, "GT failed to idle: %d\n", ret); + gt_err(gt, "GT failed to idle: %pe\n", ERR_PTR(ret)); goto err; } @@ -153,7 +155,7 @@ static int intel_guc_steal_guc_ids(void *arg) ce = kcalloc(GUC_MAX_CONTEXT_ID, sizeof(*ce), GFP_KERNEL); if (!ce) { - drm_err(>i915->drm, "Context array allocation failed\n"); + guc_err(guc, "Context array allocation failed\n"); return -ENOMEM; } @@ -166,25 +168,25 @@ static int intel_guc_steal_guc_ids(void *arg) ce[context_index] = intel_context_create(engine); if (IS_ERR(ce[context_index])) { ret = PTR_ERR(ce[context_index]); + guc_err(guc, "Failed to create context: %pe\n", ce[context_index]); ce[context_index] = NULL; - drm_err(>i915->drm, "Failed to create context: %d\n", ret); goto err_wakeref; } ret = igt_spinner_init(, engine->gt); if (ret) { - drm_err(>i915->drm, "Failed to create spinner: %d\n", ret); + guc_err(guc, "Failed to create spinner: %pe\n", ERR_PTR(ret)); goto err_contexts; } spin_rq = igt_spinner_create_request(, ce[context_index], MI_ARB_CHECK); if (IS_ERR(spin_rq)) { ret = PTR_ERR(spin_rq); - drm_err(>i915->drm, "Failed to create spinner request: %d\n", ret); + guc_err(guc, "Failed to create spinner request: %pe\n", spin_rq); goto err_contexts; } ret = request_add_spin(spin_rq, ); if (ret) { - drm_err(>i915->drm, "Failed to add Spinner request: %d\n", ret); + guc_err(guc, "Failed to add Spinner request: %pe\n", ERR_PTR(ret)); goto err_spin_rq; } @@ -192,9 +194,9 @@ static int intel_guc_steal_guc_ids(void *arg) while (ret != -EAGAIN) { ce[++context_index] = intel_context_create(engine); if (IS_ERR(ce[context_index])) { - ret = PTR_ERR(ce[context_index--]); - ce[context_index] = NULL; - drm_err(>i915->drm, "Failed to create context: %d\n", ret); + ret = PTR_ERR(ce[context_index]); + guc_err(guc, "Failed to create context: %pe\n", ce[context_index]); + ce[context_index--] = NULL; goto err_spin_rq;
[PATCH v2 5/6] drm/i915/guc: More debug print updates - GuC SLPC
From: John Harrison Update a bunch more debug prints to use the new GT based scheme. v2: Also change prints to use %pe for error values (MichalW). Signed-off-by: John Harrison Acked-by: Michal Wajdeczko --- drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c | 8 +-- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 61 - 2 files changed, 26 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c index b5855091cf6a9..23b287cefb943 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c @@ -6,6 +6,7 @@ #include #include "intel_guc_rc.h" +#include "intel_guc_print.h" #include "gt/intel_gt.h" #include "i915_drv.h" @@ -70,13 +71,12 @@ static int __guc_rc_control(struct intel_guc *guc, bool enable) ret = guc_action_control_gucrc(guc, enable); if (ret) { - i915_probe_error(guc_to_gt(guc)->i915, "Failed to %s GuC RC (%pe)\n", -str_enable_disable(enable), ERR_PTR(ret)); + guc_probe_error(guc, "Failed to %s RC (%pe)\n", + str_enable_disable(enable), ERR_PTR(ret)); return ret; } - drm_info(>i915->drm, "GuC RC: %s\n", -str_enabled_disabled(enable)); + guc_info(guc, "RC: %s\n", str_enabled_disabled(enable)); return 0; } diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c index 63464933cbceb..026d73855f36c 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -9,6 +9,7 @@ #include "i915_drv.h" #include "i915_reg.h" #include "intel_guc_slpc.h" +#include "intel_guc_print.h" #include "intel_mchbar_regs.h" #include "gt/intel_gt.h" #include "gt/intel_gt_regs.h" @@ -171,14 +172,12 @@ static int guc_action_slpc_query(struct intel_guc *guc, u32 offset) static int slpc_query_task_state(struct intel_guc_slpc *slpc) { struct intel_guc *guc = slpc_to_guc(slpc); - struct drm_i915_private *i915 = slpc_to_i915(slpc); u32 offset = intel_guc_ggtt_offset(guc, slpc->vma); int ret; ret = guc_action_slpc_query(guc, offset); if (unlikely(ret)) - i915_probe_error(i915, "Failed to query task state (%pe)\n", -ERR_PTR(ret)); + guc_probe_error(guc, "Failed to query task state: %pe\n", ERR_PTR(ret)); drm_clflush_virt_range(slpc->vaddr, SLPC_PAGE_SIZE_BYTES); @@ -188,15 +187,14 @@ static int slpc_query_task_state(struct intel_guc_slpc *slpc) static int slpc_set_param(struct intel_guc_slpc *slpc, u8 id, u32 value) { struct intel_guc *guc = slpc_to_guc(slpc); - struct drm_i915_private *i915 = slpc_to_i915(slpc); int ret; GEM_BUG_ON(id >= SLPC_MAX_PARAM); ret = guc_action_slpc_set_param(guc, id, value); if (ret) - i915_probe_error(i915, "Failed to set param %d to %u (%pe)\n", -id, value, ERR_PTR(ret)); + guc_probe_error(guc, "Failed to set param %d to %u: %pe\n", + id, value, ERR_PTR(ret)); return ret; } @@ -212,8 +210,8 @@ static int slpc_unset_param(struct intel_guc_slpc *slpc, u8 id) static int slpc_force_min_freq(struct intel_guc_slpc *slpc, u32 freq) { - struct drm_i915_private *i915 = slpc_to_i915(slpc); struct intel_guc *guc = slpc_to_guc(slpc); + struct drm_i915_private *i915 = slpc_to_i915(slpc); intel_wakeref_t wakeref; int ret = 0; @@ -236,9 +234,8 @@ static int slpc_force_min_freq(struct intel_guc_slpc *slpc, u32 freq) SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, freq); if (ret) - drm_notice(>drm, - "Failed to send set_param for min freq(%d): (%d)\n", - freq, ret); + guc_notice(guc, "Failed to send set_param for min freq(%d): %pe\n", + freq, ERR_PTR(ret)); } return ret; @@ -267,7 +264,6 @@ static void slpc_boost_work(struct work_struct *work) int intel_guc_slpc_init(struct intel_guc_slpc *slpc) { struct intel_guc *guc = slpc_to_guc(slpc); - struct drm_i915_private *i915 = slpc_to_i915(slpc); u32 size = PAGE_ALIGN(sizeof(struct slpc_shared_data)); int err; @@ -275,9 +271,7 @@ int intel_guc_slpc_init(struct intel_guc_slpc *slpc) err = intel_guc_allocate_and_map_vma(guc, size, >vma, (void **)>vaddr); if (unlikely(err)) { - i915_probe_error(i915, -"Failed to allocate SLPC struct (err=%pe)\n", -ERR_PTR(err)); +
[PATCH v2 1/6] drm/i915/guc: More debug print updates - UC firmware
From: John Harrison Update a bunch more debug prints to use the new GT based scheme. v2: Also change prints to use %pe for error values (MichalW). Signed-off-by: John Harrison --- drivers/gpu/drm/i915/gt/uc/intel_uc.c| 42 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 116 +++ 2 files changed, 73 insertions(+), 85 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c index de7f987cf6111..6648691bd6450 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c @@ -83,15 +83,15 @@ static int __intel_uc_reset_hw(struct intel_uc *uc) static void __confirm_options(struct intel_uc *uc) { - struct drm_i915_private *i915 = uc_to_gt(uc)->i915; + struct intel_gt *gt = uc_to_gt(uc); + struct drm_i915_private *i915 = gt->i915; - drm_dbg(>drm, - "enable_guc=%d (guc:%s submission:%s huc:%s slpc:%s)\n", - i915->params.enable_guc, - str_yes_no(intel_uc_wants_guc(uc)), - str_yes_no(intel_uc_wants_guc_submission(uc)), - str_yes_no(intel_uc_wants_huc(uc)), - str_yes_no(intel_uc_wants_guc_slpc(uc))); + gt_dbg(gt, "enable_guc=%d (guc:%s submission:%s huc:%s slpc:%s)\n", + i915->params.enable_guc, + str_yes_no(intel_uc_wants_guc(uc)), + str_yes_no(intel_uc_wants_guc_submission(uc)), + str_yes_no(intel_uc_wants_huc(uc)), + str_yes_no(intel_uc_wants_guc_slpc(uc))); if (i915->params.enable_guc == 0) { GEM_BUG_ON(intel_uc_wants_guc(uc)); @@ -102,26 +102,22 @@ static void __confirm_options(struct intel_uc *uc) } if (!intel_uc_supports_guc(uc)) - drm_info(>drm, -"Incompatible option enable_guc=%d - %s\n", -i915->params.enable_guc, "GuC is not supported!"); + gt_info(gt, "Incompatible option enable_guc=%d - %s\n", + i915->params.enable_guc, "GuC is not supported!"); if (i915->params.enable_guc & ENABLE_GUC_LOAD_HUC && !intel_uc_supports_huc(uc)) - drm_info(>drm, -"Incompatible option enable_guc=%d - %s\n", -i915->params.enable_guc, "HuC is not supported!"); + gt_info(gt, "Incompatible option enable_guc=%d - %s\n", + i915->params.enable_guc, "HuC is not supported!"); if (i915->params.enable_guc & ENABLE_GUC_SUBMISSION && !intel_uc_supports_guc_submission(uc)) - drm_info(>drm, -"Incompatible option enable_guc=%d - %s\n", -i915->params.enable_guc, "GuC submission is N/A"); + gt_info(gt, "Incompatible option enable_guc=%d - %s\n", + i915->params.enable_guc, "GuC submission is N/A"); if (i915->params.enable_guc & ~ENABLE_GUC_MASK) - drm_info(>drm, -"Incompatible option enable_guc=%d - %s\n", -i915->params.enable_guc, "undocumented flag"); + gt_info(gt, "Incompatible option enable_guc=%d - %s\n", + i915->params.enable_guc, "undocumented flag"); } void intel_uc_init_early(struct intel_uc *uc) @@ -549,10 +545,8 @@ static int __uc_init_hw(struct intel_uc *uc) intel_gsc_uc_load_start(>gsc); - gt_info(gt, "GuC submission %s\n", - str_enabled_disabled(intel_uc_uses_guc_submission(uc))); - gt_info(gt, "GuC SLPC %s\n", - str_enabled_disabled(intel_uc_uses_guc_slpc(uc))); + guc_info(guc, "submission %s\n", str_enabled_disabled(intel_uc_uses_guc_submission(uc))); + guc_info(guc, "SLPC %s\n", str_enabled_disabled(intel_uc_uses_guc_slpc(uc))); return 0; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c index 65672ff826054..264c952f777bb 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c @@ -11,6 +11,7 @@ #include #include "gem/i915_gem_lmem.h" +#include "gt/intel_gt_print.h" #include "intel_uc_fw.h" #include "intel_uc_fw_abi.h" #include "i915_drv.h" @@ -44,11 +45,10 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw, enum intel_uc_fw_status status) { uc_fw->__status = status; - drm_dbg(&__uc_fw_to_gt(uc_fw)->i915->drm, - "%s firmware -> %s\n", - intel_uc_fw_type_repr(uc_fw->type), - status == INTEL_UC_FIRMWARE_SELECTED ? - uc_fw->file_selected.path : intel_uc_fw_status_repr(status)); + gt_dbg(__uc_fw_to_gt(uc_fw), "%s firmware -> %s\n", + intel_uc_fw_type_repr(uc_fw->type), + status == INTEL_UC_FIRMWARE_SELECTED ? +
Re: [PATCH 1/2] backlight: hx8357: switch to using gpiod API
On Mon, Feb 06, 2023 at 11:35:32AM +, Daniel Thompson wrote: > On Tue, Jan 31, 2023 at 02:57:06PM -0800, Dmitry Torokhov wrote: > > Switch the driver from legacy gpio API that is deprecated to the newer > > gpiod API that respects line polarities described in ACPI/DT. > > > > This makes driver use standard property name for the reset gpio > > ("reset-gpios" vs "gpios-reset"), however there is a quirk in gpiolib > > to also recognize the legacy name and keep compatibility with older > > DTSes. > > > > Signed-off-by: Dmitry Torokhov > > --- > > > > All preparation gpiolib work to handle legacy names and polarity quirks > > has landed in mainline... > > > > drivers/video/backlight/hx8357.c | 82 ++-- > > 1 file changed, 37 insertions(+), 45 deletions(-) > > > > diff --git a/drivers/video/backlight/hx8357.c > > b/drivers/video/backlight/hx8357.c > > index 9b50bc96e00f..a93e14adb846 100644 > > --- a/drivers/video/backlight/hx8357.c > > +++ b/drivers/video/backlight/hx8357.c > > [snip] > > - if (of_find_property(spi->dev.of_node, "im-gpios", NULL)) { > > - lcd->use_im_pins = 1; > > - > > - for (i = 0; i < HX8357_NUM_IM_PINS; i++) { > > - lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node, > > - "im-gpios", i); > > - if (lcd->im_pins[i] == -EPROBE_DEFER) { > > - dev_info(>dev, "GPIO requested is not here > > yet, deferring the probe\n"); > > - return -EPROBE_DEFER; > > - } > > - if (!gpio_is_valid(lcd->im_pins[i])) { > > - dev_err(>dev, "Missing dt property: > > im-gpios\n"); > > - return -EINVAL; > > + gpiod_set_consumer_name(lcd->reset, "hx8357-reset"); > > + > > + for (i = 0; i < HX8357_NUM_IM_PINS; i++) { > > + lcd->im_pins[i] = devm_gpiod_get_index(>dev, > > + "im", i, GPIOD_OUT_LOW); > > + ret = PTR_ERR_OR_ZERO(lcd->im_pins[i]); > > + if (ret) { > > + if (ret == -ENOENT) { > > + if (i == 0) > > + break; > > + dev_err(>dev, "Missing im gpios[%d]\n", i); > > + ret = -EINVAL; > > + } if (ret == -EPROBE_DEFER) { I see I miss "else" here... > > + dev_info(>dev, "im gpio[%d] is not here > > yet, deferring the probe\n", > > +i); > > + } else { > > + dev_err(>dev, "failed to request im > > gpio[%d]: %d\n", > > + i, ret); > > } > > These last two clauses should be updated to return dev_err_probe(...) > instead. > > With that change: > Reviewed-by: Daniel Thompson So you want to actually suppress the deferral message unless debug printks are enabled? So you want this to read: if (ret) { if (ret == -ENOENT) { if (i == 0) break; dev_err(>dev, "Missing im gpios[%d]\n", i); return -EINVAL; } return dev_err_probe(>dev, ret, "failed to request im gpio[%d]\n", i); } Did I get it right? Thanks. -- Dmitry
Re: [Intel-gfx] [PATCH 2/3] drm/i915/guc: Clean up of register capture search
On 2/3/2023 23:29, Teres Alexis, Alan Previn wrote: I see you are inferring that a guc-id of zero can be valid. I am guessing that might have contributed to some lost captures? Thanks for catching this. I'm not inferring anything. I might be implying something, though. The patch description probably should have mentioned that change. I'll add something in. There is nothing special about id zero. The lower X many ids are reserved for multi-LRC use. So you won't see zero being allocated normally. But run a multi-LRC app/test and the first context allocated should be id zero. John. Reviewed-by: Alan Previn On Thu, 2023-02-02 at 17:10 -0800, john.c.harri...@intel.com wrote: From: John Harrison The comparison in the search for a matching register capture node was not the most readable. So remove two redundant terms and re-format to keep each term on a single line, and only one term per line. Signed-off-by: John Harrison --- drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c index 710999d7189ee..87b080dd6bead 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c @@ -1627,9 +1627,8 @@ void intel_guc_capture_get_matching_node(struct intel_gt *gt, list_for_each_entry_safe(n, ntmp, >capture->outlist, link) { if (n->eng_inst == GUC_ID_TO_ENGINE_INSTANCE(ee->engine->guc_id) && n->eng_class == GUC_ID_TO_ENGINE_CLASS(ee->engine->guc_id) && - n->guc_id && n->guc_id == ce->guc_id.id && - (n->lrca & CTX_GTT_ADDRESS_MASK) && (n->lrca & CTX_GTT_ADDRESS_MASK) == - (ce->lrc.lrca & CTX_GTT_ADDRESS_MASK)) { + n->guc_id == ce->guc_id.id && + (n->lrca & CTX_GTT_ADDRESS_MASK) == (ce->lrc.lrca & CTX_GTT_ADDRESS_MASK)) { list_del(>link); ee->guc_capture_node = n; ee->guc_capture = guc->capture;
Re: [Intel-gfx] [PATCH 3/6] drm/i915/guc: More debug print updates - GuC reg capture
On 2/4/2023 00:19, Teres Alexis, Alan Previn wrote: So i do have one request - but its a nit - for the following case, should it be a guc_warn instead of a guc_dbg? (last hunk in this patch) "No register capture node found for 0x%04X / 0x%08X\n", ce->guc_id.id, ce->lrc.lrca);" Did that get discussed in the original code review? I vaguely recall some reason for it not being a warning. But maybe I'm thinking of something else? Otherwise LGTM, Reviewed-by: Alan Previn On Thu, 2023-02-02 at 16:11 -0800, john.c.harri...@intel.com wrote: From: John Harrison Update a bunch more debug prints to use the new GT based scheme. Signed-off-by: John Harrison --- .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 51 --- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c index fc3b994626a4f..5f6e3594dda62 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c @@ -15,6 +15,7 @@ alan:snip
Re: [PATCH] drm/bridge: panel: Set orientation on panel_bridge connector
Hi, On Thu, Feb 2, 2023 at 4:45 PM Doug Anderson wrote: > > Hi, > > On Mon, Jan 23, 2023 at 8:05 AM Laurent Pinchart > wrote: > > > > Hi John, > > > > On Mon, Jan 23, 2023 at 12:16:45PM +, John Keeping wrote: > > > On Sun, Jan 22, 2023 at 05:01:27PM +0200, Laurent Pinchart wrote: > > > > On Sat, Jan 21, 2023 at 05:58:11PM +, John Keeping wrote: > > > > > On Sat, Jan 21, 2023 at 09:57:18AM +0100, Sam Ravnborg wrote: > > > > > > On Fri, Jan 20, 2023 at 01:44:38PM -0800, Doug Anderson wrote: > > > > > > > On Fri, Jan 20, 2023 at 3:43 AM John Keeping wrote: > > > > > > > > > > > > > > > > Commit 15b9ca1641f0 ("drm: Config orientation property if panel > > > > > > > > provides > > > > > > > > it") added a helper to set the panel panel orientation early > > > > > > > > but only > > > > > > > > connected this for drm_bridge_connector, which constructs a > > > > > > > > panel bridge > > > > > > > > with DRM_BRIDGE_ATTACH_NO_CONNECTOR and creates the connector > > > > > > > > itself. > > > > > > > > > > > > > > > > When the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag is not specified > > > > > > > > and the > > > > > > > > panel_bridge creates its own connector the orientation is not > > > > > > > > set unless > > > > > > > > the panel does it in .get_modes which is too late and leads to > > > > > > > > a warning > > > > > > > > splat from __drm_mode_object_add() because the device is already > > > > > > > > registered. > > > > > > > > > > > > > > > > Call the necessary function to set add the orientation property > > > > > > > > when the > > > > > > > > connector is created so that it is available before the device > > > > > > > > is > > > > > > > > registered. > > > > > > > > > > > > > > I have no huge objection to your patch and it looks OK to me. That > > > > > > > being said, my understanding is that: > > > > > > > > > > > > > > 1. DRM_BRIDGE_ATTACH_NO_CONNECTOR is "the future" and not using > > > > > > > the > > > > > > > flag is "deprecated". > > > > > > > > > > > > Correct. > > > > > > Could we take a look at how much is required to move the relevant > > > > > > driver > > > > > > to use DRM_BRIDGE_ATTACH_NO_CONNECTOR? > > > > > > > > > > > > If this is too much work now we may land this simple patch, but the > > > > > > preference is to move all drivers to the new bridge handling and > > > > > > thus > > > > > > asking display drivers to create the connector. > > > > > > > > I fully agree with Doug and Sam here. Let's see if we can keep the yak > > > > shaving minimal :-) > > > > > > > > > > What display driver are we dealing with here? > > > > > > > > > > This is dw-mipi-dsi-rockchip which uses the component path in > > > > > dw-mipi-dsi (and, in fact, is the only driver using that mode of > > > > > dw-mipi-dsi). > > > > > > > > > > I'm not familiar enough with DRM to say whether it's easy to convert > > > > > to > > > > > DRM_BRIDGE_ATTACH_NO_CONNECTOR - should dw-mipi-dsi-rockchip be moving > > > > > to use dw-mipi-dsi as a bridge driver or should dw_mipi_dsi_bind() > > > > > have > > > > > a drm_bridge_attach_flags argument? But I'm happy to test patches if > > > > > it > > > > > looks easy to convert to you :-) > > > > > > > > I'd go for the former (use dw_mipi_dsi_probe() and acquire the DSI > > > > bridge with of_drm_find_bridge() instead of using the component > > > > framework) if possible, but I don't know how intrusive that would be. > > > > > > I'm a bit confused about what's required since dw-mipi-dsi-rockchip > > > already uses dw_mipi_dsi_probe(), > > > > Indeed, my bad. > > > > > but I think moving away from the > > > component framework would be significant work as that's how the MIPI > > > subdriver fits in to the overall Rockchip display driver. > > > > It will be some work, yes. It however doesn't mean that the whole > > Rockchip display driver needs to move away from the component framework, > > it can be limited to the DSI encoder. It's not immediately clear to me > > why the DSI encoder uses the component framework in the first place, and > > if it would be difficult to move away from it. > > > > > Any changes / modernisation to the Rockchip MIPI driver look like it > > > will take more time than I have available to spend on this, so I'd > > > really like to see this patch land as it's a simple fix to an existing > > > working code path. > > > > So who volunteers for fixing it properly ? :-) > > > > I'll let Doug and Sam decide regarding mering this patch. > > This thread seems to have gone silent. > > I'm inclined to merge this patch (removing the "Fixes" tag) since it's > a one-line fix. While we want to encourage people to move to "the > future", it seems like it would be better to wait until someone is > trying to land something more intrusive than a 1-line fix before truly > forcing the issue. > > I'll plan to merge the patch to drm-misc-next early next week assuming > there are no objections. Pushed to drm-misc-next after removing the "Fixes" tag and also
Re: [PATCH v3 21/27] drm/msm/dpu: simplify dpu_plane_validate_src()
On 2/6/2023 4:27 PM, Dmitry Baryshkov wrote: On 07/02/2023 00:40, Abhinav Kumar wrote: On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote: Since the driver uses clipped src coordinates, there is no need to check against the fb coordinates. Remove corresponding checks and inline dpu_plane_validate_src(). Signed-off-by: Dmitry Baryshkov Can you please explain how the clipping in drm_atomic_helper_check_plane_state() can allow us to remove checking the fb co-ordinates? The clipping is done using the mode parameters. So lets say the FB being used is smaller than the source buffer by an incorrect usermode setting. Then the src sspp shall try to fetch the full image of src rectangle size from a FB which isnt that big leading to a fault. This case is checked by the drm_atomic_plane_check(). How does the clipping avoid such a case? clipping itself does not. However using clipped coordinates from plane_state->src ensures that they already were validated against the FB dimensions. I'll see if I can change the commit message to make it more obvious. Ah okay, yeah the commit text confused me a bit to look at the clipping code in drm_atomic_helper_check_plane_state(). Yes, please change it to point to the helper which addresses this. --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 30 --- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index ecf5402ab61a..0986e740b978 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -894,25 +894,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane, old_pstate->needs_dirtyfb); } -static bool dpu_plane_validate_src(struct drm_rect *src, - struct drm_rect *fb_rect, - uint32_t min_src_size) -{ - /* Ensure fb size is supported */ - if (drm_rect_width(fb_rect) > MAX_IMG_WIDTH || - drm_rect_height(fb_rect) > MAX_IMG_HEIGHT) - return false; - - /* Ensure src rect is above the minimum size */ - if (drm_rect_width(src) < min_src_size || - drm_rect_height(src) < min_src_size) - return false; - - /* Ensure src is fully encapsulated in fb */ - return drm_rect_intersect(fb_rect, src) && - drm_rect_equals(fb_rect, src); -} - static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu, const struct dpu_sspp_sub_blks *sblk, struct drm_rect src, const struct dpu_format *fmt) @@ -998,6 +979,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, fb_rect.x2 = new_plane_state->fb->width; fb_rect.y2 = new_plane_state->fb->height; + /* Ensure fb size is supported */ + if (drm_rect_width(_rect) > MAX_IMG_WIDTH || + drm_rect_height(_rect) > MAX_IMG_HEIGHT) { + DPU_DEBUG_PLANE(pdpu, "invalid framebuffer " DRM_RECT_FMT "\n", + DRM_RECT_ARG(_rect)); + return -E2BIG; + } + max_linewidth = pdpu->catalog->caps->max_linewidth; fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb)); @@ -1012,7 +1001,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, return -EINVAL; /* check src bounds */ - } else if (!dpu_plane_validate_src(_cfg->src_rect, _rect, min_src_size)) { + } else if (drm_rect_width(_cfg->src_rect) < min_src_size || + drm_rect_height(_cfg->src_rect) < min_src_size) { DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n", DRM_RECT_ARG(_cfg->src_rect)); return -E2BIG;
Re: [PATCH v2 02/17] drm/display/dp_mst: Handle old/new payload states in drm_dp_remove_payload()
On Wed, 2023-02-01 at 17:04 +0200, Imre Deak wrote: > > Yes, this patch should have no functional change, so please check what > would apply to other drivers as well. > > Could you also check Ville's comment about storing start_slot elsewhere > than the atomic state (leaving only time_slots there). I wonder if that > would work, at least it would simplify things I think. Ideally it'd be nice if we could have all this info in the atomic commit, but yeah - you're not the first person to find this a bit confusing. FWIW though, the way we store start_slot right now is intended to follow the same kind of behavior we have with atomic CRTC commit dependencies, I think I also made it that way so all of the state would be in a single place but there's no hard requirement for it. So if you guys think it'd be better design-wise to store this something else, I've got no strong feelings either way > > > For 0-2: > > > > Reviewed-by: Lyude Paul > > Thanks. > > > > > > > > > Cc: Lyude Paul > > > Cc: Ville Syrjälä > > > Cc: Ben Skeggs > > > Cc: Karol Herbst > > > Cc: Harry Wentland > > > Cc: Alex Deucher > > > Cc: Wayne Lin > > > Cc: sta...@vger.kernel.org # 6.1 > > > Cc: dri-devel@lists.freedesktop.org > > > Reviewed-by: Ville Syrjälä > > > Signed-off-by: Imre Deak > > > --- > > > .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 +- > > > drivers/gpu/drm/display/drm_dp_mst_topology.c | 26 ++- > > > drivers/gpu/drm/i915/display/intel_dp_mst.c | 4 ++- > > > drivers/gpu/drm/nouveau/dispnv50/disp.c | 2 +- > > > include/drm/display/drm_dp_mst_helper.h | 3 ++- > > > 5 files changed, 21 insertions(+), 16 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c > > > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c > > > index a50319fc42b11..180d3893b68da 100644 > > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c > > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c > > > @@ -208,7 +208,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( > > > if (enable) > > > drm_dp_add_payload_part1(mst_mgr, mst_state, payload); > > > else > > > - drm_dp_remove_payload(mst_mgr, mst_state, payload); > > > + drm_dp_remove_payload(mst_mgr, mst_state, payload, payload); > > > > > > /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or > > >* AUX message. The sequence is slot 1-63 allocated sequence for each > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c > > > index 847c10aa2098c..1990ff5dc7ddd 100644 > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c > > > @@ -3342,7 +3342,8 @@ EXPORT_SYMBOL(drm_dp_add_payload_part1); > > > * drm_dp_remove_payload() - Remove an MST payload > > > * @mgr: Manager to use. > > > * @mst_state: The MST atomic state > > > - * @payload: The payload to write > > > + * @old_payload: The payload with its old state > > > + * @new_payload: The payload to write > > > * > > > * Removes a payload from an MST topology if it was successfully > > > assigned a start slot. Also updates > > > * the starting time slots of all other payloads which would have been > > > shifted towards the start of > > > @@ -3350,36 +3351,37 @@ EXPORT_SYMBOL(drm_dp_add_payload_part1); > > > */ > > > void drm_dp_remove_payload(struct drm_dp_mst_topology_mgr *mgr, > > > struct drm_dp_mst_topology_state *mst_state, > > > -struct drm_dp_mst_atomic_payload *payload) > > > +const struct drm_dp_mst_atomic_payload *old_payload, > > > +struct drm_dp_mst_atomic_payload *new_payload) > > > { > > > struct drm_dp_mst_atomic_payload *pos; > > > bool send_remove = false; > > > > > > /* We failed to make the payload, so nothing to do */ > > > - if (payload->vc_start_slot == -1) > > > + if (new_payload->vc_start_slot == -1) > > > return; > > > > > > mutex_lock(>lock); > > > - send_remove = drm_dp_mst_port_downstream_of_branch(payload->port, > > > mgr->mst_primary); > > > + send_remove = drm_dp_mst_port_downstream_of_branch(new_payload->port, > > > mgr->mst_primary); > > > mutex_unlock(>lock); > > > > > > if (send_remove) > > > - drm_dp_destroy_payload_step1(mgr, mst_state, payload); > > > + drm_dp_destroy_payload_step1(mgr, mst_state, new_payload); > > > else > > > drm_dbg_kms(mgr->dev, "Payload for VCPI %d not in topology, not > > > sending remove\n", > > > - payload->vcpi); > > > + new_payload->vcpi); > > > > > > list_for_each_entry(pos, _state->payloads, next) { > > > - if (pos != payload && pos->vc_start_slot > > > > payload->vc_start_slot) > > > - pos->vc_start_slot -= payload->time_slots; > > > +
Re: [PATCH v3 21/27] drm/msm/dpu: simplify dpu_plane_validate_src()
On 07/02/2023 00:40, Abhinav Kumar wrote: On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote: Since the driver uses clipped src coordinates, there is no need to check against the fb coordinates. Remove corresponding checks and inline dpu_plane_validate_src(). Signed-off-by: Dmitry Baryshkov Can you please explain how the clipping in drm_atomic_helper_check_plane_state() can allow us to remove checking the fb co-ordinates? The clipping is done using the mode parameters. So lets say the FB being used is smaller than the source buffer by an incorrect usermode setting. Then the src sspp shall try to fetch the full image of src rectangle size from a FB which isnt that big leading to a fault. This case is checked by the drm_atomic_plane_check(). How does the clipping avoid such a case? clipping itself does not. However using clipped coordinates from plane_state->src ensures that they already were validated against the FB dimensions. I'll see if I can change the commit message to make it more obvious. --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 30 --- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index ecf5402ab61a..0986e740b978 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -894,25 +894,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane, old_pstate->needs_dirtyfb); } -static bool dpu_plane_validate_src(struct drm_rect *src, - struct drm_rect *fb_rect, - uint32_t min_src_size) -{ - /* Ensure fb size is supported */ - if (drm_rect_width(fb_rect) > MAX_IMG_WIDTH || - drm_rect_height(fb_rect) > MAX_IMG_HEIGHT) - return false; - - /* Ensure src rect is above the minimum size */ - if (drm_rect_width(src) < min_src_size || - drm_rect_height(src) < min_src_size) - return false; - - /* Ensure src is fully encapsulated in fb */ - return drm_rect_intersect(fb_rect, src) && - drm_rect_equals(fb_rect, src); -} - static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu, const struct dpu_sspp_sub_blks *sblk, struct drm_rect src, const struct dpu_format *fmt) @@ -998,6 +979,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, fb_rect.x2 = new_plane_state->fb->width; fb_rect.y2 = new_plane_state->fb->height; + /* Ensure fb size is supported */ + if (drm_rect_width(_rect) > MAX_IMG_WIDTH || + drm_rect_height(_rect) > MAX_IMG_HEIGHT) { + DPU_DEBUG_PLANE(pdpu, "invalid framebuffer " DRM_RECT_FMT "\n", + DRM_RECT_ARG(_rect)); + return -E2BIG; + } + max_linewidth = pdpu->catalog->caps->max_linewidth; fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb)); @@ -1012,7 +1001,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, return -EINVAL; /* check src bounds */ - } else if (!dpu_plane_validate_src(_cfg->src_rect, _rect, min_src_size)) { + } else if (drm_rect_width(_cfg->src_rect) < min_src_size || + drm_rect_height(_cfg->src_rect) < min_src_size) { DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n", DRM_RECT_ARG(_cfg->src_rect)); return -E2BIG; -- With best wishes Dmitry
Re: [PATCH v3 22/27] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote: Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the sspp-dependent? separate function dpu_plane_sspp_update_pipe(). This is one of preparational steps to add r_pipe support. Signed-off-by: Dmitry Baryshkov Just a couple of minor comments below but otherwise this split up lgtm --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 113 -- 1 file changed, 63 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 0986e740b978..f94e132733f3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -404,12 +404,13 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane, * _dpu_plane_set_ot_limit - set OT limit for the given plane * @plane:Pointer to drm plane * @pipe: Pointer to software pipe - * @crtc: Pointer to drm crtc * @pipe_cfg: Pointer to pipe configuration + * @frame_rate:CRTC's frame rate Can you please check the spacing here. There seems to be an extra tab before the CRTC's frame rate */ static void _dpu_plane_set_ot_limit(struct drm_plane *plane, struct dpu_sw_pipe *pipe, - struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg) + struct dpu_hw_sspp_cfg *pipe_cfg, + int frame_rate) { struct dpu_plane *pdpu = to_dpu_plane(plane); struct dpu_vbif_set_ot_params ot_params; @@ -421,7 +422,7 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane, ot_params.width = drm_rect_width(_cfg->src_rect); ot_params.height = drm_rect_height(_cfg->src_rect); ot_params.is_wfd = !pdpu->is_rt_pipe; - ot_params.frame_rate = drm_mode_vrefresh(>mode); + ot_params.frame_rate = frame_rate; ot_params.vbif_idx = VBIF_RT; ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl; ot_params.rd = true; @@ -457,26 +458,6 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane, dpu_vbif_set_qos_remap(dpu_kms, _params); } -static void _dpu_plane_set_scanout(struct drm_plane *plane, - struct dpu_plane_state *pstate, - struct drm_framebuffer *fb) -{ - struct dpu_plane *pdpu = to_dpu_plane(plane); - struct dpu_kms *kms = _dpu_plane_get_kms(>base); - struct msm_gem_address_space *aspace = kms->base.aspace; - struct dpu_hw_fmt_layout layout; - int ret; - - ret = dpu_format_populate_layout(aspace, fb, ); - if (ret) - DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret); - else if (pstate->pipe.sspp->ops.setup_sourceaddress) { - trace_dpu_plane_set_scanout(>pipe, - ); - pstate->pipe.sspp->ops.setup_sourceaddress(>pipe, ); - } -} - static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *pipe_hw, uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h, struct dpu_hw_scaler3_cfg *scale_cfg, @@ -1102,35 +1083,25 @@ void dpu_plane_set_error(struct drm_plane *plane, bool error) pdpu->is_error = error; } -static void dpu_plane_sspp_atomic_update(struct drm_plane *plane) +static void dpu_plane_sspp_update_pipe(struct drm_plane *plane, + struct dpu_sw_pipe *pipe, + struct dpu_hw_sspp_cfg *pipe_cfg, You can call this parameter sspp_cfg instead of pipe_cfg? + const struct dpu_format *fmt, + int frame_rate, + struct dpu_hw_fmt_layout *layout) { uint32_t src_flags; struct dpu_plane *pdpu = to_dpu_plane(plane); struct drm_plane_state *state = plane->state; struct dpu_plane_state *pstate = to_dpu_plane_state(state); - struct dpu_sw_pipe *pipe = >pipe; - struct drm_crtc *crtc = state->crtc; - struct drm_framebuffer *fb = state->fb; - bool is_rt_pipe; - const struct dpu_format *fmt = - to_dpu_format(msm_framebuffer_format(fb)); - struct dpu_hw_sspp_cfg *pipe_cfg = >pipe_cfg; - _dpu_plane_set_scanout(plane, pstate, fb); - - pstate->pending = true; - - is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT); - pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe); - pdpu->is_rt_pipe = is_rt_pipe; + if (layout && pipe->sspp->ops.setup_sourceaddress) { + trace_dpu_plane_set_scanout(pipe, layout); + pipe->sspp->ops.setup_sourceaddress(pipe, layout); + } _dpu_plane_set_qos_ctrl(plane, pipe, false, DPU_PLANE_QOS_PANIC_CTRL); - DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT -
Re: [PATCH v3 21/27] drm/msm/dpu: simplify dpu_plane_validate_src()
On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote: Since the driver uses clipped src coordinates, there is no need to check against the fb coordinates. Remove corresponding checks and inline dpu_plane_validate_src(). Signed-off-by: Dmitry Baryshkov Can you please explain how the clipping in drm_atomic_helper_check_plane_state() can allow us to remove checking the fb co-ordinates? The clipping is done using the mode parameters. So lets say the FB being used is smaller than the source buffer by an incorrect usermode setting. Then the src sspp shall try to fetch the full image of src rectangle size from a FB which isnt that big leading to a fault. How does the clipping avoid such a case? --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 30 --- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index ecf5402ab61a..0986e740b978 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -894,25 +894,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane, old_pstate->needs_dirtyfb); } -static bool dpu_plane_validate_src(struct drm_rect *src, - struct drm_rect *fb_rect, - uint32_t min_src_size) -{ - /* Ensure fb size is supported */ - if (drm_rect_width(fb_rect) > MAX_IMG_WIDTH || - drm_rect_height(fb_rect) > MAX_IMG_HEIGHT) - return false; - - /* Ensure src rect is above the minimum size */ - if (drm_rect_width(src) < min_src_size || - drm_rect_height(src) < min_src_size) - return false; - - /* Ensure src is fully encapsulated in fb */ - return drm_rect_intersect(fb_rect, src) && - drm_rect_equals(fb_rect, src); -} - static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu, const struct dpu_sspp_sub_blks *sblk, struct drm_rect src, const struct dpu_format *fmt) @@ -998,6 +979,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, fb_rect.x2 = new_plane_state->fb->width; fb_rect.y2 = new_plane_state->fb->height; + /* Ensure fb size is supported */ + if (drm_rect_width(_rect) > MAX_IMG_WIDTH || + drm_rect_height(_rect) > MAX_IMG_HEIGHT) { + DPU_DEBUG_PLANE(pdpu, "invalid framebuffer " DRM_RECT_FMT "\n", + DRM_RECT_ARG(_rect)); + return -E2BIG; + } + max_linewidth = pdpu->catalog->caps->max_linewidth; fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb)); @@ -1012,7 +1001,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, return -EINVAL; /* check src bounds */ - } else if (!dpu_plane_validate_src(_cfg->src_rect, _rect, min_src_size)) { + } else if (drm_rect_width(_cfg->src_rect) < min_src_size || + drm_rect_height(_cfg->src_rect) < min_src_size) { DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n", DRM_RECT_ARG(_cfg->src_rect)); return -E2BIG;
Re: [PATCH] [SUBMITTED 20210927] [RESEND^2] drm/amdgpu: fix enum odm_combine_mode mismatch
On Mon, Feb 6, 2023 at 2:36 PM Arnd Bergmann wrote: > > From: Arnd Bergmann > > A conversion from 'bool' to 'enum odm_combine_mode' was incomplete, > and gcc warns about this with many instances of > > display/dc/dml/dcn20/display_mode_vba_20.c:3899:44: warning: implicit > conversion from 'enum ' to 'enum > odm_combine_mode' [-Wenum-conversion] > 3899 | locals->ODMCombineEnablePerState[i][k] = false; > > Change the ones that we get a warning for, using the same numerical > values to leave the behavior unchanged. > > Fixes: 5fc11598166d ("drm/amd/display: expand dml structs") > Link: https://lore.kernel.org/all/20201026210039.3884312-3-a...@kernel.org/ > Link: https://lore.kernel.org/all/20210927100659.1431744-1-a...@kernel.org/ > Signed-off-by: Arnd Bergmann > --- > I sent this in 2020 and in 2021, but never got a reply and the warning > is still there. Applied. Sorry for the delay. Alex > --- > .../amd/display/dc/dml/dcn20/display_mode_vba_20.c | 8 > .../amd/display/dc/dml/dcn20/display_mode_vba_20v2.c | 10 +- > .../amd/display/dc/dml/dcn21/display_mode_vba_21.c | 12 ++-- > 3 files changed, 15 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c > b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c > index f34bc3c8da41..69c41e3e3ba2 100644 > --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c > +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c > @@ -3901,14 +3901,14 @@ void > dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l > > mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = > mode_lib->vba.PixelClock[k] / 2 > * (1 + > mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); > > - locals->ODMCombineEnablePerState[i][k] = > false; > + locals->ODMCombineEnablePerState[i][k] = > dm_odm_combine_mode_disabled; > mode_lib->vba.PlaneRequiredDISPCLK = > mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine; > if (mode_lib->vba.ODMCapability) { > if > (locals->PlaneRequiredDISPCLKWithoutODMCombine > > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) { > - > locals->ODMCombineEnablePerState[i][k] = true; > + > locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; > > mode_lib->vba.PlaneRequiredDISPCLK = > mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine; > } else if (locals->HActive[k] > > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) { > - > locals->ODMCombineEnablePerState[i][k] = true; > + > locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; > > mode_lib->vba.PlaneRequiredDISPCLK = > mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine; > } > } > @@ -3961,7 +3961,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct > display_mode_lib *mode_l > locals->RequiredDISPCLK[i][j] = 0.0; > locals->DISPCLK_DPPCLK_Support[i][j] = true; > for (k = 0; k <= > mode_lib->vba.NumberOfActivePlanes - 1; k++) { > - > locals->ODMCombineEnablePerState[i][k] = false; > + > locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled; > if (locals->SwathWidthYSingleDPP[k] > <= locals->MaximumSwathWidth[k]) { > locals->NoOfDPP[i][j][k] = 1; > > locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k] > diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c > b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c > index 366138df0fe2..f475a0ae946c 100644 > --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c > +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c > @@ -4012,17 +4012,17 @@ void > dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode > > mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = > mode_lib->vba.PixelClock[k] / 2 > * (1 + > mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); > > -
Re: [Intel-gfx] [PATCH] i915: fix memory leak with using debugfs_lookup()
On Thu, Feb 02, 2023 at 03:13:09PM +0100, Greg Kroah-Hartman wrote: > When calling debugfs_lookup() the result must have dput() called on it, > otherwise the memory will leak over time. To make things simpler, just > call debugfs_lookup_and_remove() instead which handles all of the logic > at once. > > Cc: Zhenyu Wang > Cc: Zhi Wang > Cc: Jani Nikula > Cc: Joonas Lahtinen > Cc: Rodrigo Vivi > Cc: Tvrtko Ursulin > Cc: David Airlie > Cc: Daniel Vetter > Cc: intel-gvt-...@lists.freedesktop.org > Cc: intel-...@lists.freedesktop.org > Cc: dri-devel@lists.freedesktop.org > Signed-off-by: Greg Kroah-Hartman Reviewed-by: Rodrigo Vivi Zhenyu or Zhi, could you please propagate this through your gvt branch? > --- > drivers/gpu/drm/i915/gvt/kvmgt.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c > b/drivers/gpu/drm/i915/gvt/kvmgt.c > index 8ae7039b3683..de675d799c7d 100644 > --- a/drivers/gpu/drm/i915/gvt/kvmgt.c > +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c > @@ -699,7 +699,7 @@ static void intel_vgpu_close_device(struct vfio_device > *vfio_dev) > > clear_bit(INTEL_VGPU_STATUS_ATTACHED, vgpu->status); > > - debugfs_remove(debugfs_lookup(KVMGT_DEBUGFS_FILENAME, vgpu->debugfs)); > + debugfs_lookup_and_remove(KVMGT_DEBUGFS_FILENAME, vgpu->debugfs); > > kvm_page_track_unregister_notifier(vgpu->vfio_device.kvm, > >track_node); > -- > 2.39.1 >
Re: [PATCH] drm/amd/amdgpu: add complete header search path
Applied. Thanks! On Fri, Feb 3, 2023 at 10:27 PM Randy Dunlap wrote: > > The path for the "mod_info_packet.h" header file is > incomplete, so add its location to the header search path > in the amdgpu Makefile. > > See on ARCH=alpha (275 times in one build). > > In file included from ../drivers/gpu/drm/amd/amdgpu/amdgpu.h:90, > from ../drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c:43: > ../drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.h:62:10: fatal > error: mod_info_packet.h: No such file or directory >62 | #include "mod_info_packet.h" > | ^~~ > compilation terminated. > > Fixes: 5b49da02ddbe ("drm/amd/display: Enable Freesync over PCon") > Signed-off-by: Randy Dunlap > Cc: Signed-off-by: Sung Joon Kim > Cc: Alex Deucher > Cc: Christian König > Cc: "Pan, Xinhui" > Cc: amd-...@lists.freedesktop.org > Cc: dri-devel@lists.freedesktop.org > --- > drivers/gpu/drm/amd/amdgpu/Makefile |1 + > 1 file changed, 1 insertion(+) > > diff -- a/drivers/gpu/drm/amd/amdgpu/Makefile > b/drivers/gpu/drm/amd/amdgpu/Makefile > --- a/drivers/gpu/drm/amd/amdgpu/Makefile > +++ b/drivers/gpu/drm/amd/amdgpu/Makefile > @@ -34,6 +34,7 @@ ccflags-y := -I$(FULL_AMD_PATH)/include/ > -I$(FULL_AMD_PATH)/acp/include \ > -I$(FULL_AMD_DISPLAY_PATH) \ > -I$(FULL_AMD_DISPLAY_PATH)/include \ > + -I$(FULL_AMD_DISPLAY_PATH)/modules/inc \ > -I$(FULL_AMD_DISPLAY_PATH)/dc \ > -I$(FULL_AMD_DISPLAY_PATH)/amdgpu_dm \ > -I$(FULL_AMD_PATH)/amdkfd
Re: [PATCH v2 2/8] dt-bindings: power: qcom,rpmpd: add RPMH_REGULATOR_LEVEL_LOW_SVS_L1
On 6.02.2023 15:57, Dmitry Baryshkov wrote: > Add define for another power saving state used on SM8350 for the GPU. > > Signed-off-by: Dmitry Baryshkov > --- Reviewed-by: Konrad Dybcio Konrad > include/dt-bindings/power/qcom-rpmpd.h | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/include/dt-bindings/power/qcom-rpmpd.h > b/include/dt-bindings/power/qcom-rpmpd.h > index 4a30d10e6b7d..1bf8e87ecd7e 100644 > --- a/include/dt-bindings/power/qcom-rpmpd.h > +++ b/include/dt-bindings/power/qcom-rpmpd.h > @@ -211,6 +211,7 @@ > #define RPMH_REGULATOR_LEVEL_MIN_SVS 48 > #define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56 > #define RPMH_REGULATOR_LEVEL_LOW_SVS 64 > +#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80 > #define RPMH_REGULATOR_LEVEL_SVS 128 > #define RPMH_REGULATOR_LEVEL_SVS_L0 144 > #define RPMH_REGULATOR_LEVEL_SVS_L1 192
[PATCH] backlight: qcom-wled: Add PMI8950 compatible
PMI8950 contains WLED of version 4. Add support for it to the driver. Signed-off-by: Luca Weiss --- While adding dt-bindings and dts in a previous series I forgot to add the compatible to the driver. Fix that now. --- drivers/video/backlight/qcom-wled.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c index 527210e85795..5f504883aca5 100644 --- a/drivers/video/backlight/qcom-wled.c +++ b/drivers/video/backlight/qcom-wled.c @@ -1731,6 +1731,7 @@ static int wled_remove(struct platform_device *pdev) static const struct of_device_id wled_match_table[] = { { .compatible = "qcom,pm8941-wled", .data = (void *)3 }, + { .compatible = "qcom,pmi8950-wled", .data = (void *)4 }, { .compatible = "qcom,pmi8994-wled", .data = (void *)4 }, { .compatible = "qcom,pmi8998-wled", .data = (void *)4 }, { .compatible = "qcom,pm660l-wled", .data = (void *)4 }, --- base-commit: 1b929c02afd37871d5afb9d498426f83432e71c2 change-id: 20221226-msm8953-6-2-wled-5f966bfa4db3 Best regards, -- Luca Weiss
[PATCH] drm: Rename headers to match DP2.1 spec
This patch changes the headers defined in drm_dp.h to match the DP 2.1 spec. Signed-off-by: Jasdeep Dhillon --- drivers/gpu/drm/tegra/dp.c | 2 +- include/drm/display/drm_dp.h | 13 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/tegra/dp.c b/drivers/gpu/drm/tegra/dp.c index 08fbd8f151a1..f33e468ece0a 100644 --- a/drivers/gpu/drm/tegra/dp.c +++ b/drivers/gpu/drm/tegra/dp.c @@ -499,7 +499,7 @@ static int drm_dp_link_apply_training(struct drm_dp_link *link) for (i = 0; i < lanes; i++) values[i / 2] |= DP_LANE_POST_CURSOR(i, pc[i]); - err = drm_dp_dpcd_write(aux, DP_TRAINING_LANE0_1_SET2, values, + err = drm_dp_dpcd_write(aux, DP_LINK_SQUARE_PATTERN, values, DIV_ROUND_UP(lanes, 2)); if (err < 0) { DRM_ERROR("failed to set post-cursor: %d\n", err); diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index ed10e6b6f99d..2093c1f8d8e0 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -641,12 +641,11 @@ # define DP_LINK_QUAL_PATTERN_CUSTOM0x40 # define DP_LINK_QUAL_PATTERN_SQUARE0x48 -#define DP_TRAINING_LANE0_1_SET2 0x10f -#define DP_TRAINING_LANE2_3_SET2 0x110 -# define DP_LANE02_POST_CURSOR2_SET_MASK(3 << 0) -# define DP_LANE02_MAX_POST_CURSOR2_REACHED (1 << 2) -# define DP_LANE13_POST_CURSOR2_SET_MASK(3 << 4) -# define DP_LANE13_MAX_POST_CURSOR2_REACHED (1 << 6) +#define DP_LINK_SQUARE_PATTERN 0x10f +#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX0x110 +# define DP_UHBR10_20_CAPABILITY (3 << 0) +# define DP_UHBR13_5_CAPABILITY(1 << 2) +# define DP_CABLE_TYPE (7 << 3) #define DP_MSTM_CTRL 0x111 /* 1.2 */ # define DP_MST_EN (1 << 0) @@ -1127,6 +1126,8 @@ # define DP_128B132B_TRAINING_AUX_RD_INTERVAL_32_MS 0x05 # define DP_128B132B_TRAINING_AUX_RD_INTERVAL_64_MS 0x06 +#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX 0x2217 /* 2.0 */ + #define DP_TEST_264BIT_CUSTOM_PATTERN_7_0 0x2230 #define DP_TEST_264BIT_CUSTOM_PATTERN_263_256 0x2250 -- 2.34.1
[PATCH] [SUBMITTED 20210927] [RESEND^2] drm/amdgpu: fix enum odm_combine_mode mismatch
From: Arnd Bergmann A conversion from 'bool' to 'enum odm_combine_mode' was incomplete, and gcc warns about this with many instances of display/dc/dml/dcn20/display_mode_vba_20.c:3899:44: warning: implicit conversion from 'enum ' to 'enum odm_combine_mode' [-Wenum-conversion] 3899 | locals->ODMCombineEnablePerState[i][k] = false; Change the ones that we get a warning for, using the same numerical values to leave the behavior unchanged. Fixes: 5fc11598166d ("drm/amd/display: expand dml structs") Link: https://lore.kernel.org/all/20201026210039.3884312-3-a...@kernel.org/ Link: https://lore.kernel.org/all/20210927100659.1431744-1-a...@kernel.org/ Signed-off-by: Arnd Bergmann --- I sent this in 2020 and in 2021, but never got a reply and the warning is still there. --- .../amd/display/dc/dml/dcn20/display_mode_vba_20.c | 8 .../amd/display/dc/dml/dcn20/display_mode_vba_20v2.c | 10 +- .../amd/display/dc/dml/dcn21/display_mode_vba_21.c | 12 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c index f34bc3c8da41..69c41e3e3ba2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c @@ -3901,14 +3901,14 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2 * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); - locals->ODMCombineEnablePerState[i][k] = false; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine; if (mode_lib->vba.ODMCapability) { if (locals->PlaneRequiredDISPCLKWithoutODMCombine > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) { - locals->ODMCombineEnablePerState[i][k] = true; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine; } else if (locals->HActive[k] > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) { - locals->ODMCombineEnablePerState[i][k] = true; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine; } } @@ -3961,7 +3961,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l locals->RequiredDISPCLK[i][j] = 0.0; locals->DISPCLK_DPPCLK_Support[i][j] = true; for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { - locals->ODMCombineEnablePerState[i][k] = false; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled; if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) { locals->NoOfDPP[i][j][k] = 1; locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k] diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c index 366138df0fe2..f475a0ae946c 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c @@ -4012,17 +4012,17 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2 * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); - locals->ODMCombineEnablePerState[i][k] = false; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled; mode_lib->vba.PlaneRequiredDISPCLK =
Re: [PATCH v3 20/27] drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote: Now as all accesses to pipe_cfg and pstate have been cleaned, re-add struct dpu_hw_pipe_cfg back to dpu_plane_state, so that dpu_plane_atomic_check() and dpu_plane_atomic_update() do not have a chance to disagree about src/dst rectangles (currently dpu_plane_atomic_check() uses unclipped rectangles, while dpu_plane_atomic_update() uses clipped rectangles calculated by drm_atomic_helper_check_plane_state()). The title of the patch should now say "add dpu_hw_sspp_cfg" I have a question on the commit text, why does it say "re-add" and not "add". dpu_hw_pipe_cfg/dpu_hw_sspp_cfg was not a part of dpu_plane_state even before and I dont recall it was removed in this series and then added back. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 64 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 2 + 2 files changed, 30 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 09a3fde1c910..ecf5402ab61a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -951,7 +951,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state); const struct drm_crtc_state *crtc_state = NULL; const struct dpu_format *fmt; - struct drm_rect src, dst, fb_rect = { 0 }; + struct dpu_hw_sspp_cfg *pipe_cfg = >pipe_cfg; + struct drm_rect fb_rect = { 0 }; uint32_t min_src_size, max_linewidth; unsigned int rotation; uint32_t supported_rotations; @@ -984,12 +985,15 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, return -EINVAL; } - src.x1 = new_plane_state->src_x >> 16; - src.y1 = new_plane_state->src_y >> 16; - src.x2 = src.x1 + (new_plane_state->src_w >> 16); - src.y2 = src.y1 + (new_plane_state->src_h >> 16); + pipe_cfg->src_rect = new_plane_state->src; - dst = drm_plane_state_dest(new_plane_state); + /* state->src is 16.16, src_rect is not */ + pipe_cfg->src_rect.x1 >>= 16; + pipe_cfg->src_rect.x2 >>= 16; + pipe_cfg->src_rect.y1 >>= 16; + pipe_cfg->src_rect.y2 >>= 16; + + pipe_cfg->dst_rect = new_plane_state->dst; fb_rect.x2 = new_plane_state->fb->width; fb_rect.y2 = new_plane_state->fb->height; @@ -1008,30 +1012,30 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, return -EINVAL; /* check src bounds */ - } else if (!dpu_plane_validate_src(, _rect, min_src_size)) { + } else if (!dpu_plane_validate_src(_cfg->src_rect, _rect, min_src_size)) { DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n", - DRM_RECT_ARG()); + DRM_RECT_ARG(_cfg->src_rect)); return -E2BIG; /* valid yuv image */ } else if (DPU_FORMAT_IS_YUV(fmt) && - (src.x1 & 0x1 || src.y1 & 0x1 || - drm_rect_width() & 0x1 || - drm_rect_height() & 0x1)) { + (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 || + drm_rect_width(_cfg->src_rect) & 0x1 || + drm_rect_height(_cfg->src_rect) & 0x1)) { DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n", - DRM_RECT_ARG()); + DRM_RECT_ARG(_cfg->src_rect)); return -EINVAL; /* min dst support */ - } else if (drm_rect_width() < 0x1 || drm_rect_height() < 0x1) { + } else if (drm_rect_width(_cfg->dst_rect) < 0x1 || drm_rect_height(_cfg->dst_rect) < 0x1) { DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n", - DRM_RECT_ARG()); + DRM_RECT_ARG(_cfg->dst_rect)); return -EINVAL; /* check decimated source width */ - } else if (drm_rect_width() > max_linewidth) { + } else if (drm_rect_width(_cfg->src_rect) > max_linewidth) { DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n", - DRM_RECT_ARG(), max_linewidth); + DRM_RECT_ARG(_cfg->src_rect), max_linewidth); return -E2BIG; } @@ -1045,7 +1049,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, if ((pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) && (rotation & DRM_MODE_ROTATE_90)) { - ret = dpu_plane_check_inline_rotation(pdpu, sblk, src, fmt); + ret = dpu_plane_check_inline_rotation(pdpu, sblk, pipe_cfg->src_rect, fmt); if (ret) return ret; } @@ -1120,9 +1124,7 @@
Re: [PATCH v2] drm/i915/huc: Add and use HuC oriented print macros
On 2/3/2023 12:59 AM, Michal Wajdeczko wrote: Like we did it for GuC, introduce some helper print macros for HuC to have unified format of messages that also include GT#. While around improve some messages and use %pe if possible. v2: update GSC/PXP timeout message Signed-off-by: Michal Wajdeczko Cc: John Harrison Cc: Daniele Ceraolo Spurio Reviewed-by: Daniele Ceraolo Spurio Daniele --- drivers/gpu/drm/i915/gt/uc/intel_huc.c | 44 ++ 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c index 410905da8e97..72884e21470b 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c @@ -6,6 +6,7 @@ #include #include "gt/intel_gt.h" +#include "gt/intel_gt_print.h" #include "intel_guc_reg.h" #include "intel_huc.h" #include "i915_drv.h" @@ -13,6 +14,15 @@ #include #include +#define huc_printk(_huc, _level, _fmt, ...) \ + gt_##_level(huc_to_gt(_huc), "HuC: " _fmt, ##__VA_ARGS__) +#define huc_err(_huc, _fmt, ...) huc_printk((_huc), err, _fmt, ##__VA_ARGS__) +#define huc_warn(_huc, _fmt, ...) huc_printk((_huc), warn, _fmt, ##__VA_ARGS__) +#define huc_notice(_huc, _fmt, ...)huc_printk((_huc), notice, _fmt, ##__VA_ARGS__) +#define huc_info(_huc, _fmt, ...) huc_printk((_huc), info, _fmt, ##__VA_ARGS__) +#define huc_dbg(_huc, _fmt, ...) huc_printk((_huc), dbg, _fmt, ##__VA_ARGS__) +#define huc_probe_error(_huc, _fmt, ...) huc_printk((_huc), probe_error, _fmt, ##__VA_ARGS__) + /** * DOC: HuC * @@ -107,11 +117,9 @@ static enum hrtimer_restart huc_delayed_load_timer_callback(struct hrtimer *hrti if (!intel_huc_is_authenticated(huc)) { if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_GSC) - drm_notice(_to_gt(huc)->i915->drm, - "timed out waiting for MEI GSC init to load HuC\n"); + huc_notice(huc, "timed out waiting for MEI GSC\n"); else if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_PXP) - drm_notice(_to_gt(huc)->i915->drm, - "timed out waiting for MEI PXP init to load HuC\n"); + huc_notice(huc, "timed out waiting for MEI PXP\n"); else MISSING_CASE(huc->delayed_load.status); @@ -174,8 +182,7 @@ static int gsc_notifier(struct notifier_block *nb, unsigned long action, void *d case BUS_NOTIFY_DRIVER_NOT_BOUND: /* mei driver fails to be bound */ case BUS_NOTIFY_UNBIND_DRIVER: /* mei driver about to be unbound */ - drm_info(_to_gt(huc)->i915->drm, -"mei driver not bound, disabling HuC load\n"); + huc_info(huc, "MEI driver not bound, disabling load\n"); gsc_init_error(huc); break; } @@ -193,8 +200,7 @@ void intel_huc_register_gsc_notifier(struct intel_huc *huc, struct bus_type *bus huc->delayed_load.nb.notifier_call = gsc_notifier; ret = bus_register_notifier(bus, >delayed_load.nb); if (ret) { - drm_err(_to_gt(huc)->i915->drm, - "failed to register GSC notifier\n"); + huc_err(huc, "failed to register GSC notifier %pe\n", ERR_PTR(ret)); huc->delayed_load.nb.notifier_call = NULL; gsc_init_error(huc); } @@ -306,29 +312,25 @@ static int check_huc_loading_mode(struct intel_huc *huc) GSC_LOADS_HUC; if (fw_needs_gsc != hw_uses_gsc) { - drm_err(>i915->drm, - "mismatch between HuC FW (%s) and HW (%s) load modes\n", - HUC_LOAD_MODE_STRING(fw_needs_gsc), - HUC_LOAD_MODE_STRING(hw_uses_gsc)); + huc_err(huc, "mismatch between FW (%s) and HW (%s) load modes\n", + HUC_LOAD_MODE_STRING(fw_needs_gsc), HUC_LOAD_MODE_STRING(hw_uses_gsc)); return -ENOEXEC; } /* make sure we can access the GSC via the mei driver if we need it */ if (!(IS_ENABLED(CONFIG_INTEL_MEI_PXP) && IS_ENABLED(CONFIG_INTEL_MEI_GSC)) && fw_needs_gsc) { - drm_info(>i915->drm, -"Can't load HuC due to missing MEI modules\n"); + huc_info(huc, "can't load due to missing MEI modules\n"); return -EIO; } - drm_dbg(>i915->drm, "GSC loads huc=%s\n", str_yes_no(fw_needs_gsc)); + huc_dbg(huc, "loaded by GSC = %s\n", str_yes_no(fw_needs_gsc)); return 0; } int intel_huc_init(struct intel_huc *huc) { - struct drm_i915_private *i915 = huc_to_gt(huc)->i915; int err; err = check_huc_loading_mode(huc); @@ -345,7 +347,7 @@ int intel_huc_init(struct intel_huc *huc) out:
Re: [PATCH] drm/i915/gt: Avoid redundant pointer validity check
On Tue, Feb 07, 2023 at 12:12:18AM +0530, Deepak R Varma wrote: > On Mon, Feb 06, 2023 at 10:33:13AM +, Matthew Auld wrote: > > On 06/02/2023 09:45, Tvrtko Ursulin wrote: > > > > > > Hi, > > > > > > Adding Matt & Thomas as potential candidates to review. > > > > > > Regards, > > > > > > Tvrtko > > > > > > On 03/02/2023 19:30, Deepak R Varma wrote: > > > > The macro definition of gen6_for_all_pdes() expands to a for loop such > > > > that it breaks when the page table is null. Hence there is no need to > > > > again test validity of the page table entry pointers in the pde list. > > > > This change is identified using itnull.cocci semantic patch. > > > > > > > > Signed-off-by: Deepak R Varma > > > > --- > > > > Please note: Proposed change is compile tested only. > > > > > > > > drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 5 ++--- > > > > 1 file changed, 2 insertions(+), 3 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c > > > > b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c > > > > index 5aaacc53fa4c..787b9e6d9f59 100644 > > > > --- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c > > > > +++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c > > > > @@ -258,8 +258,7 @@ static void gen6_ppgtt_free_pd(struct gen6_ppgtt > > > > *ppgtt) > > > > u32 pde; > > > > gen6_for_all_pdes(pt, pd, pde) > > > > - if (pt) > > > > - free_pt(>base.vm, pt); > > > > + free_pt(>base.vm, pt); > > > > } > > > > static void gen6_ppgtt_cleanup(struct i915_address_space *vm) > > > > @@ -304,7 +303,7 @@ static void pd_vma_unbind(struct > > > > i915_address_space *vm, > > > > /* Free all no longer used page tables */ > > > > gen6_for_all_pdes(pt, ppgtt->base.pd, pde) { > > > > - if (!pt || atomic_read(>used)) > > > > + if (atomic_read(>used)) > > > > Wow, I was really confused trying to remember how this all works. > > > > The gen6_for_all_pdes() does: > > > > (pt = i915_pt_entry(pd, iter), true) > > > > So NULL pt is expected, and does not 'break' here, since 'true' is always > > the value that decides whether to terminate the loop. So this patch would > > lead to NULL ptr deref, AFAICT. > > Hello Matt, > I understand it now. I was misreading the true as part of the function > argument. > Could you please also comment if the implementation of gen6_ppgtt_free_pd() in > the same file is safe? It doesn't appear to have an check on pt validity here. Please ignore the question. I understand it now. My apologies for inconvenience. The patch is invalid and can be dropped. deepak. > > Thank you, > deepak. > > > > > > > > > > > continue; > > > > free_pt(>base.vm, pt);
Re: [PATCH v3 19/27] drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly
On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote: Rework bandwidth/clock calculation functions to use mode directly rather than fetching it through the plane data. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 39 ++- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index ee261a591d45..09a3fde1c910 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -127,20 +127,19 @@ static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane) /** * _dpu_plane_calc_bw - calculate bandwidth required for a plane - * @plane: Pointer to drm plane. + * @catalog: Points to dpu catalog structure * @fmt: Pointer to source buffer format + * @mode: Pointer to drm display mode * @pipe_cfg: Pointer to pipe configuration * Result: Updates calculated bandwidth in the plane state. * BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest) * Prefill BW Equation: line src bytes * line_time */ -static void _dpu_plane_calc_bw(struct drm_plane *plane, +static u64 _dpu_plane_calc_bw(const struct dpu_mdss_cfg *catalog, const struct dpu_format *fmt, + const struct drm_display_mode *mode, struct dpu_hw_sspp_cfg *pipe_cfg) { - struct dpu_plane_state *pstate; - struct drm_display_mode *mode; - struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); int src_width, src_height, dst_height, fps; u64 plane_prefill_bw; u64 plane_bw; @@ -148,9 +147,6 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane, u64 scale_factor; int vbp, vpw, vfp; - pstate = to_dpu_plane_state(plane->state); - mode = >state->crtc->mode; - src_width = drm_rect_width(_cfg->src_rect); src_height = drm_rect_height(_cfg->src_rect); dst_height = drm_rect_height(_cfg->dst_rect); @@ -158,7 +154,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane, vbp = mode->vtotal - mode->vsync_end; vpw = mode->vsync_end - mode->vsync_start; vfp = mode->vsync_start - mode->vdisplay; - hw_latency_lines = dpu_kms->catalog->perf->min_prefill_lines; + hw_latency_lines = catalog->perf->min_prefill_lines; scale_factor = src_height > dst_height ? mult_frac(src_height, 1, dst_height) : 1; @@ -178,37 +174,36 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane, do_div(plane_prefill_bw, hw_latency_lines); - pstate->plane_fetch_bw = max(plane_bw, plane_prefill_bw); + return max(plane_bw, plane_prefill_bw); } /** * _dpu_plane_calc_clk - calculate clock required for a plane - * @plane: Pointer to drm plane. + * @mode: Pointer to drm display mode * @pipe_cfg: Pointer to pipe configuration * Result: Updates calculated clock in the plane state. * Clock equation: dst_w * v_total * fps * (src_h / dst_h) */ -static void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_sspp_cfg *pipe_cfg) +static u64 _dpu_plane_calc_clk(const struct drm_display_mode *mode, + struct dpu_hw_sspp_cfg *pipe_cfg) { - struct dpu_plane_state *pstate; - struct drm_display_mode *mode; int dst_width, src_height, dst_height, fps; - - pstate = to_dpu_plane_state(plane->state); - mode = >state->crtc->mode; + u64 plane_clk; src_height = drm_rect_height(_cfg->src_rect); dst_width = drm_rect_width(_cfg->dst_rect); dst_height = drm_rect_height(_cfg->dst_rect); fps = drm_mode_vrefresh(mode); - pstate->plane_clk = + plane_clk = dst_width * mode->vtotal * fps; if (src_height > dst_height) { - pstate->plane_clk *= src_height; - do_div(pstate->plane_clk, dst_height); + plane_clk *= src_height; + do_div(plane_clk, dst_height); } + + return plane_clk; } /** @@ -1219,9 +1214,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane) _dpu_plane_set_qos_remap(plane, pipe); } - _dpu_plane_calc_bw(plane, fmt, _cfg); + pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, >mode, _cfg); - _dpu_plane_calc_clk(plane, _cfg); + pstate->plane_clk = _dpu_plane_calc_clk(>mode, _cfg); } static void _dpu_plane_atomic_disable(struct drm_plane *plane)
Re: [PATCH] drm/shmem-helper: Fix locking for drm_gem_shmem_get_pages_sgt()
Hello Lina, On 2/5/23 13:51, Asahi Lina wrote: > Other functions touching shmem->sgt take the pages lock, so do that here > too. drm_gem_shmem_get_pages() & co take the same lock, so move to the > _locked() variants to avoid recursive locking. > > Discovered while auditing locking to write the Rust abstractions. > > Fixes: 2194a63a818d ("drm: Add library for shmem backed GEM objects") > Fixes: 4fa3d66f132b ("drm/shmem: Do dma_unmap_sg before purging pages") > Signed-off-by: Asahi Lina > --- Good catch. The patch looks good to me. Reviewed-by: Javier Martinez Canillas What about drm_gem_shmem_free() BTW, I believe that the helper should also grab the lock before unmap / free the sgtable? -- Best regards, Javier Martinez Canillas Core Platforms Red Hat
Re: [PATCH] drm/i915/gt: Avoid redundant pointer validity check
On Mon, Feb 06, 2023 at 10:33:13AM +, Matthew Auld wrote: > On 06/02/2023 09:45, Tvrtko Ursulin wrote: > > > > Hi, > > > > Adding Matt & Thomas as potential candidates to review. > > > > Regards, > > > > Tvrtko > > > > On 03/02/2023 19:30, Deepak R Varma wrote: > > > The macro definition of gen6_for_all_pdes() expands to a for loop such > > > that it breaks when the page table is null. Hence there is no need to > > > again test validity of the page table entry pointers in the pde list. > > > This change is identified using itnull.cocci semantic patch. > > > > > > Signed-off-by: Deepak R Varma > > > --- > > > Please note: Proposed change is compile tested only. > > > > > > drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 5 ++--- > > > 1 file changed, 2 insertions(+), 3 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c > > > b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c > > > index 5aaacc53fa4c..787b9e6d9f59 100644 > > > --- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c > > > +++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c > > > @@ -258,8 +258,7 @@ static void gen6_ppgtt_free_pd(struct gen6_ppgtt > > > *ppgtt) > > > u32 pde; > > > gen6_for_all_pdes(pt, pd, pde) > > > - if (pt) > > > - free_pt(>base.vm, pt); > > > + free_pt(>base.vm, pt); > > > } > > > static void gen6_ppgtt_cleanup(struct i915_address_space *vm) > > > @@ -304,7 +303,7 @@ static void pd_vma_unbind(struct > > > i915_address_space *vm, > > > /* Free all no longer used page tables */ > > > gen6_for_all_pdes(pt, ppgtt->base.pd, pde) { > > > - if (!pt || atomic_read(>used)) > > > + if (atomic_read(>used)) > > Wow, I was really confused trying to remember how this all works. > > The gen6_for_all_pdes() does: > > (pt = i915_pt_entry(pd, iter), true) > > So NULL pt is expected, and does not 'break' here, since 'true' is always > the value that decides whether to terminate the loop. So this patch would > lead to NULL ptr deref, AFAICT. Hello Matt, I understand it now. I was misreading the true as part of the function argument. Could you please also comment if the implementation of gen6_ppgtt_free_pd() in the same file is safe? It doesn't appear to have an check on pt validity here. Thank you, deepak. > > > > > > continue; > > > free_pt(>base.vm, pt);
Re: [Nouveau] [PATCH drm-next 05/14] drm/nouveau: new VM_BIND uapi interfaces
On 2/6/23 17:14, Christian König wrote: Concentrating this discussion on a very big misunderstanding first. Am 06.02.23 um 14:27 schrieb Danilo Krummrich: [SNIP] My understanding is that userspace is fully responsible on the parts of the GPU VA space it owns. This means that userspace needs to take care to *not* ask the kernel to modify mappings that are in use currently. This is a completely wrong assumption! Take a look at what games like Forza Horizzon are doing. Basically that game allocates a very big sparse area and fills it with pages from BOs while shaders are accessing it. And yes, as far as I know this is completely valid behavior. I also think this is valid behavior. That's not the problem I'm trying to describe. In this case userspace modifies the VA space *intentionally* while shaders are accessing it, because it knows that the shaders can deal with reading 0s. Just to have it all in place, the example I gave was: - two virtually contiguous buffers A and B - binding 1 mapped to A with BO offset 0 - binding 2 mapped to B with BO offset length(A) What I did not mention both A and B aren't sparse buffers in this example, although it probably doesn't matter too much. Since the conditions to do so are given, we merge binding 1 and binding 2 right at the time when binding 2 is requested. To do so a driver might unmap binding 1 for a very short period of time (e.g. to (re-)map the freshly merged binding with a different page size if possible). From userspace perspective buffer A is ready to use before applying binding 2 to buffer B, hence it would be illegal to touch binding 1 again when userspace asks the kernel to map binding 2 to buffer B. Besides that I think there is no point in merging between buffers anyway because we'd end up splitting such a merged mapping anyway later on when one of the two buffers is destroyed. Also, I think the same applies to sparse buffers as well, a mapping within A isn't expected to be re-mapped just because something is mapped to B. However, in this context I start wondering if re-mapping in the context of merge and split is allowed at all, even within the same sparse buffer (and even with a separate page table for sparse mappings as described in my last mail; shaders would never fault). So you need to be able to handle this case anyway and the approach with the regions won't help you at all preventing that. Regards, Christian.
[PATCH v2] drm/i915/pcode: Give the punit time to settle before fatally failing
From: Aravind Iddamsetty During module load the punit might still be busy with its booting routines. During this time we try to communicate with it but we fail because we don't receive any feedback from it and we return immediately with a -EINVAL fatal error. At this point the driver load is "dramatically" aborted. The following error message notifies us about it. i915 :4d:00.0: drm_WARN_ON_ONCE(timeout_base_ms > 3) It would be enough to wait a little in order to give the punit the chance to come up bright and shiny, ready to interact with the driver. Wait up 10 seconds for the punit to settle and complete any outstanding transactions upon module load. If it still fails try again with a longer timeout, 180s, 3 minutes. If it still fails then return -EPROBE_DEFER, in order to give the punit a second chance. Even if these timers might look long, we should consider that the punit, depending on the platforms, might need long times to complete its routines. Besides we want to try anything possible to move forward before deciding to abort the driver's load. The issue has been reported in: https://gitlab.freedesktop.org/drm/intel/-/issues/7814 The changes in this patch are valid only and uniquely during boot. The common transactions with the punit during the driver's normal operation are not affected. Signed-off-by: Aravind Iddamsetty Co-developed-by: Chris Wilson Signed-off-by: Chris Wilson Signed-off-by: Andi Shyti Cc: Rodrigo Vivi --- Hi, I'm proposing again the same patch as v1 with a hopefully more descriptive commit log in order to minimize the misunderstandings that we had during the v1 review. Thanks, Andi Changelog: == v1 -> v2: - write a more descriptive commit log. - add Chris SoB which was triggering a checkpatch error. drivers/gpu/drm/i915/intel_pcode.c | 35 ++ 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pcode.c b/drivers/gpu/drm/i915/intel_pcode.c index a234d9b4ed143..3db2ba439bb57 100644 --- a/drivers/gpu/drm/i915/intel_pcode.c +++ b/drivers/gpu/drm/i915/intel_pcode.c @@ -204,15 +204,42 @@ int skl_pcode_request(struct intel_uncore *uncore, u32 mbox, u32 request, #undef COND } +static int pcode_init_wait(struct intel_uncore *uncore, int timeout_ms) +{ + if (__intel_wait_for_register_fw(uncore, +GEN6_PCODE_MAILBOX, +GEN6_PCODE_READY, 0, +500, timeout_ms, +NULL)) + return -EPROBE_DEFER; + + return skl_pcode_request(uncore, +DG1_PCODE_STATUS, +DG1_UNCORE_GET_INIT_STATUS, +DG1_UNCORE_INIT_STATUS_COMPLETE, +DG1_UNCORE_INIT_STATUS_COMPLETE, timeout_ms); +} + int intel_pcode_init(struct intel_uncore *uncore) { + int err; + if (!IS_DGFX(uncore->i915)) return 0; - return skl_pcode_request(uncore, DG1_PCODE_STATUS, -DG1_UNCORE_GET_INIT_STATUS, -DG1_UNCORE_INIT_STATUS_COMPLETE, -DG1_UNCORE_INIT_STATUS_COMPLETE, 18); + /* +* Wait 10 seconds so that the punit to settle and complete +* any outstanding transactions upon module load +*/ + err = pcode_init_wait(uncore, 1); + + if (err) { + drm_notice(>i915->drm, + "Waiting for HW initialisation...\n"); + err = pcode_init_wait(uncore, 18); + } + + return err; } int snb_pcode_read_p(struct intel_uncore *uncore, u32 mbcmd, u32 p1, u32 p2, u32 *val) -- 2.39.1
Re: [PATCH 06/14] drm/msm/gpu: Use dev_pm_opp_set_rate for non-GMU GPUs
On 26.01.2023 16:16, Konrad Dybcio wrote: > Currently we only utilize the OPP table connected to the GPU for > getting (available) frequencies. We do however need to scale the > voltage rail(s) accordingly to ensure that we aren't trying to > run the GPU at 1GHz with a VDD_LOW vote, as that would result in > an otherwise inexplainable hang. > > Tell the OPP framework that we want to scale the "core" clock > and swap out the clk_set_rate to a dev_pm_opp_set_rate in > msm_devfreq_target() to enable usage of required-opps and by > extension proper voltage level/corner scaling. > > Signed-off-by: Konrad Dybcio > --- Welp, as-is, this breaks devfreq on GPUs with a GMU.. Will fix.. Konrad > drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 +++ > drivers/gpu/drm/msm/msm_gpu_devfreq.c | 2 +- > 2 files changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c > b/drivers/gpu/drm/msm/adreno/adreno_gpu.c > index 817599766329..c85ae3845a4e 100644 > --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c > +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c > @@ -1047,6 +1047,9 @@ int adreno_gpu_init(struct drm_device *drm, struct > platform_device *pdev, > const char *gpu_name; > u32 speedbin; > > + /* This can only be done here, or devm_pm_opp_set_supported_hw will > WARN_ON() */ > + devm_pm_opp_set_clkname(dev, "core"); > + > adreno_gpu->funcs = funcs; > adreno_gpu->info = adreno_info(config->rev); > adreno_gpu->gmem = adreno_gpu->info->gmem; > diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c > b/drivers/gpu/drm/msm/msm_gpu_devfreq.c > index e27dbf12b5e8..ea70c1c32d94 100644 > --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c > +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c > @@ -48,7 +48,7 @@ static int msm_devfreq_target(struct device *dev, unsigned > long *freq, > gpu->funcs->gpu_set_freq(gpu, opp, df->suspended); > mutex_unlock(>lock); > } else { > - clk_set_rate(gpu->core_clk, *freq); > + dev_pm_opp_set_rate(dev, *freq); > } > > dev_pm_opp_put(opp);
Re: [PATCH] drm/amdgpu: Fix potential race processing vm->freed
Am 06.02.23 um 19:21 schrieb Rob Clark: On Mon, Feb 6, 2023 at 8:05 AM Christian König wrote: Am 06.02.23 um 16:52 schrieb Rob Clark: On Mon, Feb 6, 2023 at 2:15 AM Christian König wrote: Am 03.02.23 um 19:10 schrieb Rob Clark: From: Rob Clark If userspace calls the AMDGPU_CS ioctl from multiple threads, because the vm is global to the drm_file, you can end up with multiple threads racing in amdgpu_vm_clear_freed(). So the freed list should be protected with the status_lock, similar to other vm lists. Well this is nonsense. To process the freed list the VM root PD lock must be held anyway. If we have a call path where this isn't true then we have a major bug at a different place here. I'm not super familiar w/ the amdgpu cs parser stuff, but the only thing that I'm seeing that protects things is the bo_list_mutex and it isn't clear to me that this is 1:1 with the vm (it looks like it is not). Do you have a backtrace? Take a look at the reservation object of vm->root.bo. This should always be locked first before doing *anything* in a CS. If that isn't the case we have a much worse problem. In this case, maybe an dma_resv_assert_held() would be a good idea? We should already have that. Which makes me really wonder what the heck is going on here. Christian. BR, -R (I cc'd you on the bug report, jfyi) I unfortunately only get a permission denied when I try to access that one. Regards, Christian. BR, -R Regards, Christian. Fixes: d38ceaf99ed0 ("drm/amdgpu: add core driver (v4)") Signed-off-by: Rob Clark --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 33 ++ 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index b9441ab457ea..aeed7bc1512f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1240,10 +1240,19 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, struct amdgpu_bo_va_mapping *mapping; uint64_t init_pte_value = 0; struct dma_fence *f = NULL; + struct list_head freed; int r; - while (!list_empty(>freed)) { - mapping = list_first_entry(>freed, + /* + * Move the contents of the VM's freed list to a local list + * that we can iterate without racing against other threads: + */ + spin_lock(>status_lock); + list_replace_init(>freed, ); + spin_unlock(>status_lock); + + while (!list_empty()) { + mapping = list_first_entry(, struct amdgpu_bo_va_mapping, list); list_del(>list); @@ -1258,6 +1267,15 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, amdgpu_vm_free_mapping(adev, vm, mapping, f); if (r) { dma_fence_put(f); + + /* + * Move any unprocessed mappings back to the freed + * list: + */ + spin_lock(>status_lock); + list_splice_tail(, >freed); + spin_unlock(>status_lock); + return r; } } @@ -1583,11 +1601,14 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, mapping->bo_va = NULL; trace_amdgpu_vm_bo_unmap(bo_va, mapping); - if (valid) + if (valid) { + spin_lock(>status_lock); list_add(>list, >freed); - else + spin_unlock(>status_lock); + } else { amdgpu_vm_free_mapping(adev, vm, mapping, bo_va->last_pt_update); + } return 0; } @@ -1671,7 +1692,9 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, tmp->last = eaddr; tmp->bo_va = NULL; + spin_lock(>status_lock); list_add(>list, >freed); + spin_unlock(>status_lock); trace_amdgpu_vm_bo_unmap(NULL, tmp); } @@ -1788,7 +1811,9 @@ void amdgpu_vm_bo_del(struct amdgpu_device *adev, amdgpu_vm_it_remove(mapping, >va); mapping->bo_va = NULL; trace_amdgpu_vm_bo_unmap(bo_va, mapping); + spin_lock(>status_lock); list_add(>list, >freed); + spin_unlock(>status_lock); } list_for_each_entry_safe(mapping, next, _va->invalids, list) { list_del(>list);
Re: [PATCH] drm/amdgpu: Fix potential race processing vm->freed
On Mon, Feb 6, 2023 at 8:05 AM Christian König wrote: > > Am 06.02.23 um 16:52 schrieb Rob Clark: > > On Mon, Feb 6, 2023 at 2:15 AM Christian König > > wrote: > >> Am 03.02.23 um 19:10 schrieb Rob Clark: > >>> From: Rob Clark > >>> > >>> If userspace calls the AMDGPU_CS ioctl from multiple threads, because > >>> the vm is global to the drm_file, you can end up with multiple threads > >>> racing in amdgpu_vm_clear_freed(). So the freed list should be > >>> protected with the status_lock, similar to other vm lists. > >> Well this is nonsense. To process the freed list the VM root PD lock > >> must be held anyway. > >> > >> If we have a call path where this isn't true then we have a major bug at > >> a different place here. > > I'm not super familiar w/ the amdgpu cs parser stuff, but the only > > thing that I'm seeing that protects things is the bo_list_mutex and it > > isn't clear to me that this is 1:1 with the vm (it looks like it is > > not). > > Do you have a backtrace? > > Take a look at the reservation object of vm->root.bo. This should always > be locked first before doing *anything* in a CS. > > If that isn't the case we have a much worse problem. In this case, maybe an dma_resv_assert_held() would be a good idea? BR, -R > > (I cc'd you on the bug report, jfyi) > > I unfortunately only get a permission denied when I try to access that one. > > Regards, > Christian. > > > > > BR, > > -R > > > >> Regards, > >> Christian. > >> > >>> Fixes: d38ceaf99ed0 ("drm/amdgpu: add core driver (v4)") > >>> Signed-off-by: Rob Clark > >>> --- > >>>drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 33 ++ > >>>1 file changed, 29 insertions(+), 4 deletions(-) > >>> > >>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > >>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > >>> index b9441ab457ea..aeed7bc1512f 100644 > >>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > >>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > >>> @@ -1240,10 +1240,19 @@ int amdgpu_vm_clear_freed(struct amdgpu_device > >>> *adev, > >>>struct amdgpu_bo_va_mapping *mapping; > >>>uint64_t init_pte_value = 0; > >>>struct dma_fence *f = NULL; > >>> + struct list_head freed; > >>>int r; > >>> > >>> - while (!list_empty(>freed)) { > >>> - mapping = list_first_entry(>freed, > >>> + /* > >>> + * Move the contents of the VM's freed list to a local list > >>> + * that we can iterate without racing against other threads: > >>> + */ > >>> + spin_lock(>status_lock); > >>> + list_replace_init(>freed, ); > >>> + spin_unlock(>status_lock); > >>> + > >>> + while (!list_empty()) { > >>> + mapping = list_first_entry(, > >>>struct amdgpu_bo_va_mapping, list); > >>>list_del(>list); > >>> > >>> @@ -1258,6 +1267,15 @@ int amdgpu_vm_clear_freed(struct amdgpu_device > >>> *adev, > >>>amdgpu_vm_free_mapping(adev, vm, mapping, f); > >>>if (r) { > >>>dma_fence_put(f); > >>> + > >>> + /* > >>> + * Move any unprocessed mappings back to the freed > >>> + * list: > >>> + */ > >>> + spin_lock(>status_lock); > >>> + list_splice_tail(, >freed); > >>> + spin_unlock(>status_lock); > >>> + > >>>return r; > >>>} > >>>} > >>> @@ -1583,11 +1601,14 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, > >>>mapping->bo_va = NULL; > >>>trace_amdgpu_vm_bo_unmap(bo_va, mapping); > >>> > >>> - if (valid) > >>> + if (valid) { > >>> + spin_lock(>status_lock); > >>>list_add(>list, >freed); > >>> - else > >>> + spin_unlock(>status_lock); > >>> + } else { > >>>amdgpu_vm_free_mapping(adev, vm, mapping, > >>> bo_va->last_pt_update); > >>> + } > >>> > >>>return 0; > >>>} > >>> @@ -1671,7 +1692,9 @@ int amdgpu_vm_bo_clear_mappings(struct > >>> amdgpu_device *adev, > >>>tmp->last = eaddr; > >>> > >>>tmp->bo_va = NULL; > >>> + spin_lock(>status_lock); > >>>list_add(>list, >freed); > >>> + spin_unlock(>status_lock); > >>>trace_amdgpu_vm_bo_unmap(NULL, tmp); > >>>} > >>> > >>> @@ -1788,7 +1811,9 @@ void amdgpu_vm_bo_del(struct amdgpu_device *adev, > >>>amdgpu_vm_it_remove(mapping, >va); > >>>mapping->bo_va = NULL; > >>>trace_amdgpu_vm_bo_unmap(bo_va, mapping); > >>> + spin_lock(>status_lock); > >>>list_add(>list, >freed); > >>> + spin_unlock(>status_lock); > >>>} > >>>list_for_each_entry_safe(mapping, next, _va->invalids, list) { > >>>
Re: [PATCH v7 1/6] drm/tidss: Remove Video Port to Output Port coupling
On 06/02/2023 19:34, Aradhya Bhatia wrote: On 06-Feb-23 18:35, Tomi Valkeinen wrote: On 05/02/2023 15:08, Aradhya Bhatia wrote: Hi Tomi, Thanks for the review! On 03-Feb-23 16:53, Tomi Valkeinen wrote: On 25/01/2023 13:35, Aradhya Bhatia wrote: Make DSS Video Ports agnostic of output bus types. DSS controllers have had a 1-to-1 coupling between its VPs and its output ports. This no longer stands true for the new AM625 DSS. This coupling, hence, has been removed by renaming the 'vp_bus_type' to 'output_port_bus_type' because the VPs are essentially agnostic of the bus type and it is the output ports which have a bus type. The AM625 DSS has 2 VPs but requires 3 output ports to support its Dual-Link OLDI video output coming from a single VP. Not a biggie, but this sentence is a bit odd here at the end. Shouldn't it be after the "...stands true for the new AM625 DSS."? Yes! It should be. Will make the edit. Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/tidss/tidss_dispc.c | 47 + drivers/gpu/drm/tidss/tidss_dispc.h | 21 +++-- drivers/gpu/drm/tidss/tidss_drv.h | 5 +-- drivers/gpu/drm/tidss/tidss_irq.h | 2 +- drivers/gpu/drm/tidss/tidss_kms.c | 12 5 files changed, 48 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c index 165365b515e1..c1c4faccbddc 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -61,7 +61,7 @@ const struct dispc_features dispc_k2g_feats = { .min_pclk_khz = 4375, .max_pclk_khz = { - [DISPC_VP_DPI] = 15, + [DISPC_PORT_DPI] = 15, }, /* @@ -96,7 +96,6 @@ const struct dispc_features dispc_k2g_feats = { .vp_name = { "vp1" }, .ovr_name = { "ovr1" }, .vpclk_name = { "vp1" }, - .vp_bus_type = { DISPC_VP_DPI }, .vp_feat = { .color = { .has_ctm = true, @@ -109,6 +108,9 @@ const struct dispc_features dispc_k2g_feats = { .vid_name = { "vid1" }, .vid_lite = { false }, .vid_order = { 0 }, + + .num_output_ports = 1, + .output_port_bus_type = { DISPC_PORT_DPI }, }; Just thinking out loud, as these will get more complex in the future, maybe we should finally group them with struct. E.g. we could define struct array for vps, like (just hacky example): struct { const char *name; const char *clkname; struct tidss_vp_feat feat; } vps[TIDSS_MAX_PORTS]; and then use them as: .vps = { { .name = "kala", .clkname = "kissa", .feat.color.has_ctm = true, }, { .name = "kala2", .clkname = "kissa2", .feat.color.has_ctm = false, }, }, Perhaps something to try in the future. Yes, agreed! Having that structure will tidy this up. I will keep this under future work. static const u16 tidss_am65x_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { @@ -140,8 +142,8 @@ static const u16 tidss_am65x_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { const struct dispc_features dispc_am65x_feats = { .max_pclk_khz = { - [DISPC_VP_DPI] = 165000, - [DISPC_VP_OLDI] = 165000, + [DISPC_PORT_DPI] = 165000, + [DISPC_PORT_OLDI] = 165000, }, .scaling = { @@ -171,7 +173,6 @@ const struct dispc_features dispc_am65x_feats = { .vp_name = { "vp1", "vp2" }, .ovr_name = { "ovr1", "ovr2" }, .vpclk_name = { "vp1", "vp2" }, - .vp_bus_type = { DISPC_VP_OLDI, DISPC_VP_DPI }, .vp_feat = { .color = { .has_ctm = true, @@ -185,6 +186,9 @@ const struct dispc_features dispc_am65x_feats = { .vid_name = { "vid", "vidl1" }, .vid_lite = { false, true, }, .vid_order = { 1, 0 }, + + .num_output_ports = 2, + .output_port_bus_type = { DISPC_PORT_OLDI, DISPC_PORT_DPI }, }; static const u16 tidss_j721e_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { @@ -229,8 +233,8 @@ static const u16 tidss_j721e_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { const struct dispc_features dispc_j721e_feats = { .max_pclk_khz = { - [DISPC_VP_DPI] = 17, - [DISPC_VP_INTERNAL] = 60, + [DISPC_PORT_DPI] = 17, + [DISPC_PORT_INTERNAL] = 60, }, .scaling = { @@ -260,9 +264,7 @@ const struct dispc_features dispc_j721e_feats = { .vp_name = { "vp1", "vp2", "vp3", "vp4" }, .ovr_name = { "ovr1", "ovr2", "ovr3", "ovr4" }, .vpclk_name = { "vp1", "vp2", "vp3", "vp4" }, - /* Currently hard coded VP routing (see dispc_initial_config()) */ - .vp_bus_type = { DISPC_VP_INTERNAL, DISPC_VP_DPI, - DISPC_VP_INTERNAL, DISPC_VP_DPI, }, + I think this line feed is extra. Okay! Will remove that from all SoC feat structs.
Re: [PATCH v7 4/6] drm/tidss: Add support to configure OLDI mode for am625-dss
On 06-Feb-23 19:12, Tomi Valkeinen wrote: > On 05/02/2023 15:42, Aradhya Bhatia wrote: >> Hi Tomi, >> >> On 03-Feb-23 20:42, Tomi Valkeinen wrote: >>> On 25/01/2023 13:35, Aradhya Bhatia wrote: The newer version of DSS (AM625-DSS) has 2 OLDI TXes at its disposal. These can be configured to support the following modes: 1. OLDI_SINGLE_LINK_SINGLE_MODE Single Output over OLDI 0. +--+ +-+ +---+ | | | | | | | CRTC +--->+ ENCODER +->| PANEL | | | | | | | +--+ +-+ +---+ 2. OLDI_SINGLE_LINK_CLONE_MODE Duplicate Output over OLDI 0 and 1. +--+ +-+ +---+ | | | | | | | CRTC +---+--->| ENCODER +->| PANEL | | | | | | | | +--+ | +-+ +---+ | | +-+ +---+ | | | | | +--->| ENCODER +->| PANEL | | | | | +-+ +---+ 3. OLDI_DUAL_LINK_MODE Combined Output over OLDI 0 and 1. +--+ +-+ +---+ | | | +->| | | CRTC +--->+ ENCODER | | PANEL | | | | +->| | +--+ +-+ +---+ Following the above pathways for different modes, 2 encoder/panel-bridge pipes get created for clone mode, and 1 pipe in cases of single link and dual link mode. Add support for confguring the OLDI modes using OF and LVDS DRM helper functions. Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/tidss/tidss_dispc.c | 24 ++- drivers/gpu/drm/tidss/tidss_dispc.h | 12 ++ drivers/gpu/drm/tidss/tidss_drv.h | 3 + drivers/gpu/drm/tidss/tidss_encoder.c | 4 +- drivers/gpu/drm/tidss/tidss_encoder.h | 3 +- drivers/gpu/drm/tidss/tidss_kms.c | 221 -- 6 files changed, 245 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c index b55ccbcaa67f..37a73e309330 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -88,6 +88,8 @@ const struct dispc_features dispc_k2g_feats = { .subrev = DISPC_K2G, + .has_oldi = false, + .common = "common", .common_regs = tidss_k2g_common_regs, @@ -166,6 +168,8 @@ const struct dispc_features dispc_am625_feats = { .subrev = DISPC_AM625, + .has_oldi = true, + .common = "common", .common_regs = tidss_am65x_common_regs, @@ -218,6 +222,8 @@ const struct dispc_features dispc_am65x_feats = { .subrev = DISPC_AM65X, + .has_oldi = true, + .common = "common", .common_regs = tidss_am65x_common_regs, @@ -309,6 +315,8 @@ const struct dispc_features dispc_j721e_feats = { .subrev = DISPC_J721E, + .has_oldi = false, + .common = "common_m", .common_regs = tidss_j721e_common_regs, @@ -361,6 +369,8 @@ struct dispc_device { struct dss_vp_data vp_data[TIDSS_MAX_VPS]; + enum dispc_oldi_modes oldi_mode; + u32 *fourccs; u32 num_fourccs; @@ -1963,6 +1973,12 @@ const u32 *dispc_plane_formats(struct dispc_device *dispc, unsigned int *len) return dispc->fourccs; } +void dispc_set_oldi_mode(struct dispc_device *dispc, + enum dispc_oldi_modes oldi_mode) +{ + dispc->oldi_mode = oldi_mode; +} + static s32 pixinc(int pixels, u8 ps) { if (pixels == 1) @@ -2647,7 +2663,7 @@ int dispc_runtime_resume(struct dispc_device *dispc) REG_GET(dispc, DSS_SYSSTATUS, 2, 2), REG_GET(dispc, DSS_SYSSTATUS, 3, 3)); - if (dispc->feat->subrev == DISPC_AM65X) + if (dispc->feat->has_oldi) dev_dbg(dispc->dev, "OLDI RESETDONE %d,%d,%d\n", REG_GET(dispc, DSS_SYSSTATUS, 5, 5), REG_GET(dispc, DSS_SYSSTATUS, 6, 6), @@ -2688,7 +2704,7 @@ static int dispc_iomap_resource(struct platform_device *pdev, const char *name, return 0; } -static int dispc_init_am65x_oldi_io_ctrl(struct device *dev, +static int dispc_init_am6xx_oldi_io_ctrl(struct device *dev, struct dispc_device *dispc) { dispc->oldi_io_ctrl = @@ -2827,8 +2843,8 @@ int
Re: [PATCH v7 1/6] drm/tidss: Remove Video Port to Output Port coupling
On 06-Feb-23 18:35, Tomi Valkeinen wrote: > On 05/02/2023 15:08, Aradhya Bhatia wrote: >> Hi Tomi, >> >> Thanks for the review! >> >> On 03-Feb-23 16:53, Tomi Valkeinen wrote: >>> On 25/01/2023 13:35, Aradhya Bhatia wrote: Make DSS Video Ports agnostic of output bus types. DSS controllers have had a 1-to-1 coupling between its VPs and its output ports. This no longer stands true for the new AM625 DSS. This coupling, hence, has been removed by renaming the 'vp_bus_type' to 'output_port_bus_type' because the VPs are essentially agnostic of the bus type and it is the output ports which have a bus type. The AM625 DSS has 2 VPs but requires 3 output ports to support its Dual-Link OLDI video output coming from a single VP. >>> >>> Not a biggie, but this sentence is a bit odd here at the end. Shouldn't >>> it be after the "...stands true for the new AM625 DSS."? >> >> Yes! It should be. Will make the edit. >> >>> Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/tidss/tidss_dispc.c | 47 + drivers/gpu/drm/tidss/tidss_dispc.h | 21 +++-- drivers/gpu/drm/tidss/tidss_drv.h | 5 +-- drivers/gpu/drm/tidss/tidss_irq.h | 2 +- drivers/gpu/drm/tidss/tidss_kms.c | 12 5 files changed, 48 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c index 165365b515e1..c1c4faccbddc 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -61,7 +61,7 @@ const struct dispc_features dispc_k2g_feats = { .min_pclk_khz = 4375, .max_pclk_khz = { - [DISPC_VP_DPI] = 15, + [DISPC_PORT_DPI] = 15, }, /* @@ -96,7 +96,6 @@ const struct dispc_features dispc_k2g_feats = { .vp_name = { "vp1" }, .ovr_name = { "ovr1" }, .vpclk_name = { "vp1" }, - .vp_bus_type = { DISPC_VP_DPI }, .vp_feat = { .color = { .has_ctm = true, @@ -109,6 +108,9 @@ const struct dispc_features dispc_k2g_feats = { .vid_name = { "vid1" }, .vid_lite = { false }, .vid_order = { 0 }, + + .num_output_ports = 1, + .output_port_bus_type = { DISPC_PORT_DPI }, }; >>> >>> Just thinking out loud, as these will get more complex in the future, >>> maybe we should finally group them with struct. E.g. we could define >>> struct array for vps, like (just hacky example): >>> >>> struct { >>> const char *name; >>> const char *clkname; >>> struct tidss_vp_feat feat; >>> } vps[TIDSS_MAX_PORTS]; >>> >>> and then use them as: >>> >>> .vps = { >>> { >>> .name = "kala", >>> .clkname = "kissa", >>> .feat.color.has_ctm = true, >>> }, { >>> .name = "kala2", >>> .clkname = "kissa2", >>> .feat.color.has_ctm = false, >>> }, >>> }, >>> >>> Perhaps something to try in the future. >>> >> >> Yes, agreed! Having that structure will tidy this up. >> I will keep this under future work. >> static const u16 tidss_am65x_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { @@ -140,8 +142,8 @@ static const u16 tidss_am65x_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { const struct dispc_features dispc_am65x_feats = { .max_pclk_khz = { - [DISPC_VP_DPI] = 165000, - [DISPC_VP_OLDI] = 165000, + [DISPC_PORT_DPI] = 165000, + [DISPC_PORT_OLDI] = 165000, }, .scaling = { @@ -171,7 +173,6 @@ const struct dispc_features dispc_am65x_feats = { .vp_name = { "vp1", "vp2" }, .ovr_name = { "ovr1", "ovr2" }, .vpclk_name = { "vp1", "vp2" }, - .vp_bus_type = { DISPC_VP_OLDI, DISPC_VP_DPI }, .vp_feat = { .color = { .has_ctm = true, @@ -185,6 +186,9 @@ const struct dispc_features dispc_am65x_feats = { .vid_name = { "vid", "vidl1" }, .vid_lite = { false, true, }, .vid_order = { 1, 0 }, + + .num_output_ports = 2, + .output_port_bus_type = { DISPC_PORT_OLDI, DISPC_PORT_DPI }, }; static const u16 tidss_j721e_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { @@ -229,8 +233,8 @@ static const u16 tidss_j721e_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { const struct dispc_features dispc_j721e_feats = { .max_pclk_khz = { - [DISPC_VP_DPI] = 17, - [DISPC_VP_INTERNAL] = 60, + [DISPC_PORT_DPI] = 17, + [DISPC_PORT_INTERNAL] = 60, }, .scaling = { @@ -260,9 +264,7 @@ const struct dispc_features
Re: [PATCH v2] drm/virtio: exbuf->fence_fd unmodified on interrupted wait
On 2/4/23 02:33, Ryan Neph wrote: > An interrupted dma_fence_wait() becomes an -ERESTARTSYS returned > to userspace ioctl(DRM_IOCTL_VIRTGPU_EXECBUFFER) calls, prompting to > retry the ioctl(), but the passed exbuf->fence_fd has been reset to -1, > making the retry attempt fail at sync_file_get_fence(). > > The uapi for DRM_IOCTL_VIRTGPU_EXECBUFFER is changed to retain the > passed value for exbuf->fence_fd when returning anything besides a > successful result from the ioctl. > > Fixes: 2cd7b6f08bc4 ("drm/virtio: add in/out fence support for explicit > synchronization") > Signed-off-by: Ryan Neph > Reviewed-by: Rob Clark > Reviewed-by: Dmitry Osipenko > > --- > > Changes in v2: > - No longer modifies exbuf->fence_fd unless DRM_IOCTL_VIRTGPU_EXECBUFFER > succeeds. > - Added r-b tags (Rob/Dmitry) from v1. Thanks! Applied to misc-fixes -- Best regards, Dmitry
Re: [PATCH 3/3] drm/connector: Deprecate split for BT.2020 in drm_colorspace enum
On 2/6/23 04:47, Ville Syrjälä wrote: > On Sat, Feb 04, 2023 at 06:09:45AM +, Joshua Ashton wrote: >> >> >> On 2/3/23 19:34, Ville Syrjälä wrote: >>> On Fri, Feb 03, 2023 at 09:25:38PM +0200, Ville Syrjälä wrote: On Fri, Feb 03, 2023 at 08:56:55PM +0200, Ville Syrjälä wrote: > On Fri, Feb 03, 2023 at 01:28:20PM -0500, Harry Wentland wrote: >> >> >> On 2/3/23 11:00, Ville Syrjälä wrote: >>> On Fri, Feb 03, 2023 at 10:24:52AM -0500, Harry Wentland wrote: On 2/3/23 10:19, Ville Syrjälä wrote: > On Fri, Feb 03, 2023 at 09:39:42AM -0500, Harry Wentland wrote: >> >> >> On 2/3/23 07:59, Sebastian Wick wrote: >>> On Fri, Feb 3, 2023 at 11:40 AM Ville Syrjälä >>> wrote: On Fri, Feb 03, 2023 at 02:07:44AM +, Joshua Ashton wrote: > Userspace has no way of controlling or knowing the pixel encoding > currently, so there is no way for it to ever get the right values > here. That applies to a lot of the other values as well (they are explicitly RGB or YCC). The idea was that this property sets the infoframe/MSA/SDP value exactly, and other properties should be added to for use userspace to control the pixel encoding/colorspace conversion(if desired, or userspace just makes sure to directly feed in correct kind of data). >>> >>> I'm all for getting userspace control over pixel encoding but even >>> then the kernel always knows which pixel encoding is selected and >>> which InfoFrame has to be sent. Is there a reason why userspace >>> would >>> want to control the variant explicitly to the wrong value? >>> >> >> I've asked this before but haven't seen an answer: Is there an >> existing >> upstream userspace project that makes use of this property (other >> than >> what Joshua is working on in gamescope right now)? That would help us >> understand the intent better. > > The intent was to control the infoframe colorimetry bits, > nothing more. No idea what real userspace there was, if any. >> >> Controlling the infoframe alone isn't useful at all unless you can >> guarantee the wire encoding, which we cannot do. >> > >> >> I don't think giving userspace explicit control over the exact >> infoframe >> values is the right thing to do. >> >> +1 >> > > Only userspace knows what kind of data it's stuffing into > the pixels (and/or how it configures the csc units/etc.) to > generate them. > Yes, but userspace doesn't control or know whether we drive RGB or YCbCr on the wire. In fact, in some cases our driver needs to fallback to YCbCr420 for bandwidth reasons. There is currently no way for userspace to know that and I don't think it makes sense. >>> >>> People want that control as well for whatever reason. We've >>> been asked to allow YCbCr 4:4:4 output many times. >>> >>> The automagic 4:2:0 fallback I think is rather fundementally >>> incompatible with fancy color management. How would we even >>> know whether to use eg. BT.2020 vs. BT.709 matrix? In i915 >>> that stuff is just always BT.709 limited range, no questions >>> asked. >> >> That's what the Colorspace property *should* be determining here. >> That's what we have it set up to do in SteamOS/my tree right now. >> >>> >> >> We use what we're telling the display, i.e., the value in the >> colorspace property. That way we know whether to use a BT.2020 >> or BT.709 matrix. > > And given how these things have gone in the past I think > that is likey to bite someone at in the future. Also not > what this property was meant to do nor does on any other > driver AFAIK. > >> I don't see how it's fundamentally incompatible with fancy >> color management stuff. >> >> If we start forbidding drivers from falling back to YCbCr >> (whether 4:4:4 or 4:2:0) we will break existing behavior on >> amdgpu and will see bug reports. > > The compositors could deal with that if/when they start doing > the full color management stuff. The current stuff only really > works when the kernel is allowed to do whatever it wants. > >> >>> So I think if userspace wants real color management it's >>> going to have to set up the whole pipeline. And for that >>> we need at least one new property to control the RGB->YCbCr >>> conversion (or to explicitly avoid it). >> >> I mentioned this in my commit description, we absolutely should offer >> fine control here eventually. >> >> I don't think we need to solve that problem here though.
Re: [Intel-gfx] [PATCH v2 2/2] drm/i915: Remove unused/wrong INF_UNIT_LEVEL_CLKGATE
On Mon, Feb 06, 2023 at 08:54:10AM -0800, Lucas De Marchi wrote: > INF_UNIT_LEVEL_CLKGATE is not replicated, but since it's not actually > used it can just be removed. > > Signed-off-by: Lucas De Marchi Reviewed-by: Matt Roper Looks like the only reference to the register was removed in commit eee42141e498fa3df3ce524846d52f67a92b6845 Author: Matt Roper AuthorDate: Tue Jul 13 12:36:35 2021 -0700 Commit: Matt Roper CommitDate: Wed Jul 14 17:49:02 2021 -0700 drm/i915/icl: Drop workarounds that only apply to pre-production steppings > --- > drivers/gpu/drm/i915/gt/intel_gt_regs.h | 3 --- > 1 file changed, 3 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h > b/drivers/gpu/drm/i915/gt/intel_gt_regs.h > index cc1539c7a6b6..7256f7e3fd11 100644 > --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h > +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h > @@ -769,9 +769,6 @@ > #define GEN10_DFR_RATIO_EN_AND_CHICKEN MCR_REG(0x9550) > #define DFR_DISABLE(1 << 9) > > -#define INF_UNIT_LEVEL_CLKGATE MCR_REG(0x9560) > -#define CGPSF_CLKGATE_DIS (1 << 3) > - > #define MICRO_BP0_0 _MMIO(0x9800) > #define MICRO_BP0_2 _MMIO(0x9804) > #define MICRO_BP0_1 _MMIO(0x9808) > -- > 2.39.0 > -- Matt Roper Graphics Software Engineer Linux GPU Platform Enablement Intel Corporation
Re: [PATCH 3/8] dt-bindings: display/msm/gmu: add Adreno 660 support
On Mon, 06 Feb 2023 02:27:30 +0200, Dmitry Baryshkov wrote: > Add Adreno A660 to the A635 clause to define all version-specific > properties. There is no need to add it to the top-level clause, since > top-level compatible uses pattern to define compatible strings. > > Signed-off-by: Dmitry Baryshkov > --- > Documentation/devicetree/bindings/display/msm/gmu.yaml | 1 + > 1 file changed, 1 insertion(+) > Acked-by: Rob Herring
Re: [PATCH 1/8] dt-bindings: clock: Merge qcom,gpucc-sm8350 into qcom,gpucc.yaml
On Mon, 06 Feb 2023 02:27:27 +0200, Dmitry Baryshkov wrote: > The GPU clock controller bindings for the Qualcomm sm8350 platform are > not correct. The driver uses .fw_name instead of using indices to bind > parent clocks, thus demanding the clock-names usage. With the proper > clock-names in place, the bindings becomes equal to the bindings defined > by qcom,gpucc.yaml, so it is impractical to keep them in a separate > file. > > Signed-off-by: Dmitry Baryshkov > --- > .../bindings/clock/qcom,gpucc-sm8350.yaml | 71 --- > .../devicetree/bindings/clock/qcom,gpucc.yaml | 2 + > 2 files changed, 2 insertions(+), 71 deletions(-) > delete mode 100644 > Documentation/devicetree/bindings/clock/qcom,gpucc-sm8350.yaml > Acked-by: Rob Herring
Re: [PATCH v7 3/6] drm/tidss: Add support for AM625 DSS
Hi Tomi, On 06-Feb-23 16:28, Tomi Valkeinen wrote: > On 05/02/2023 16:31, Aradhya Bhatia wrote: >> >> >> On 03-Feb-23 21:03, Tomi Valkeinen wrote: >>> On 25/01/2023 13:35, Aradhya Bhatia wrote: Add support for the DSS controller on TI's new AM625 SoC in the tidss driver. The first video port (VP0) in am625-dss can output OLDI signals through 2 OLDI TXes. A 3rd output port has been added with "DISPC_PORT_OLDI" bus type. >>> >>> Not a big thing here as you add support for a new SoC, but the ordering >>> of the patches is not optimal. Here you add the AM625 DSS support, but >>> then you continue actually adding the DSS support (well, mainly OLDI) in >>> the following patches. >>> >>> I think patch 6 could be before this patch. Parts of patch 4 could also >>> be before this patch. The AM65X renames from patch 5 could be before >>> this patch. >> >> I can move whole of Patch 6 and even of Patch 4 before this one. I have >> mentioned 'AM625-DSS' in a couple comments which I can make generic, >> and the rest everything is SoC-agnostic. >> >> I haven't tried this, but my concern is if we break patch 5 into 2 >> separate patches, >> >> i. AM65X rename plus SoC based switch case, and >> ii. Addition of AM625 SoC case >> >> then I might have to overwrite some changes implemented during (i) in >> (ii). I don't suppose that would be okay, would it? > > I'm not sure I follow here. Wouldn't (i) be a valid patch in its own? > Nothing wrong in expanding that later (even if you end up changing a lot > of it). > (i) would be a valid patch, but implementing (ii) would over-write certain changes done in (i), albeit small changes in terms of brackets and indents. That didn't feel right initially and hence the question. > That said, I don't think this is a very important topic. There are only > a few commits in the history that might be problematic. A simple fix > would be to add all the features first, and only last add the compatible > string for am625. > > Or do all the changes for am625 in a single patch, and try to implement > all the generic restructuring work before that. > > Here we do have to change the vp-to-output mapping management, so maybe > the second option won't be simple enough, and it's better to do the > am625 changes in pieces, as in the first option. > Yeah, the first option does seem a little less complicated. Will try to re-order this as much clearly as possible. > So, it's really up to you. Just wanted to raise this possible issue so > that you are aware of it and can do any easy fixes (if there are such). > >> Also, is it important to keep the compatible-addition patches of >> DT-binding and driver next to each other in the series? Or should >> the DT-binding patches should be the first ones? Just curious! =) > > I believe the convention is to have the DT-binding changes before you > add the compatible string to the driver (if I recall right checkpatch or > some other checking tool complains if you add a driver for a compatible > that doesn't have a DT binding). Generic restructurings could be before > the DT patch, of course, but usually I like to keep the DT binding > changes at the very beginning of the series. > Okay, I will keep the compatible-append in the binding as the first patch in the series, before the other general structurings. Thank you! Regards Aradhya
[PATCH v2 2/2] drm/i915: Remove unused/wrong INF_UNIT_LEVEL_CLKGATE
INF_UNIT_LEVEL_CLKGATE is not replicated, but since it's not actually used it can just be removed. Signed-off-by: Lucas De Marchi --- drivers/gpu/drm/i915/gt/intel_gt_regs.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h index cc1539c7a6b6..7256f7e3fd11 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h @@ -769,9 +769,6 @@ #define GEN10_DFR_RATIO_EN_AND_CHICKEN MCR_REG(0x9550) #define DFR_DISABLE (1 << 9) -#define INF_UNIT_LEVEL_CLKGATE MCR_REG(0x9560) -#define CGPSF_CLKGATE_DIS(1 << 3) - #define MICRO_BP0_0_MMIO(0x9800) #define MICRO_BP0_2_MMIO(0x9804) #define MICRO_BP0_1_MMIO(0x9808) -- 2.39.0
[PATCH v2 1/2] drm/i915: Fix GEN8_MISCCPCTL
Register 0x9424 is not replicated on any platform, so it shouldn't be declared with REG_MCR(). Declaring it with _MMIO() is basically duplicate of the GEN7 version, so just remove the GEN8 and change all the callers to use the right functions. Old versions of the gen8 bspec page used to contain a table with MCR registers, apparently implying 0x9400 - 0x94ff registers were replicated. However that table went away and there is no information related to the ranges for gen8 anymore. Moreover the current behavior of the driver wouldn't do anything special for 0x9424 since there is no equivalent table in intel_gt_mcr.c: the driver would just fallback to intel_uncore_{read,write}(). Therefore, do not care about the possible special case for gen8 and just use the register as non-MCR for all the platforms. One place doing read + write is also converted to intel_uncore_rmw(). v2: Reword commit message adding the justification wrt gen8 Fixes: a9e69428b1b4 ("drm/i915: Define MCR registers explicitly") Cc: Balasubramani Vivekanandan Cc: Rodrigo Vivi Cc: Gustavo Sousa Cc: Matt Atwood Cc: Ashutosh Dixit Signed-off-by: Lucas De Marchi Reviewed-by: Matt Roper --- drivers/gpu/drm/i915/gt/intel_gt_regs.h | 5 + drivers/gpu/drm/i915/gt/intel_workarounds.c | 4 ++-- drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 5 ++--- drivers/gpu/drm/i915/intel_pm.c | 10 +- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h index 7fa18a3b3957..cc1539c7a6b6 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h @@ -686,10 +686,7 @@ #define GEN6_RSTCTL_MMIO(0x9420) #define GEN7_MISCCPCTL _MMIO(0x9424) -#define GEN7_DOP_CLOCK_GATE_ENABLE (1 << 0) - -#define GEN8_MISCCPCTL MCR_REG(0x9424) -#define GEN8_DOP_CLOCK_GATE_ENABLE REG_BIT(0) +#define GEN7_DOP_CLOCK_GATE_ENABLE REG_BIT(0) #define GEN12_DOP_CLOCK_GATE_RENDER_ENABLE REG_BIT(1) #define GEN8_DOP_CLOCK_GATE_CFCLK_ENABLE (1 << 2) #define GEN8_DOP_CLOCK_GATE_GUC_ENABLE (1 << 4) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index 29718d0595f4..cfc122c17e28 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -1645,7 +1645,7 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal) wa_mcr_write_or(wal, XEHP_SQCM, EN_32B_ACCESS); /* Wa_14015795083 */ - wa_mcr_write_clr(wal, GEN8_MISCCPCTL, GEN12_DOP_CLOCK_GATE_RENDER_ENABLE); + wa_write_clr(wal, GEN7_MISCCPCTL, GEN12_DOP_CLOCK_GATE_RENDER_ENABLE); /* Wa_18018781329 */ wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB); @@ -1664,7 +1664,7 @@ pvc_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal) pvc_init_mcr(gt, wal); /* Wa_14015795083 */ - wa_mcr_write_clr(wal, GEN8_MISCCPCTL, GEN12_DOP_CLOCK_GATE_RENDER_ENABLE); + wa_write_clr(wal, GEN7_MISCCPCTL, GEN12_DOP_CLOCK_GATE_RENDER_ENABLE); /* Wa_18018781329 */ wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB); diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c index 3d2249bda368..69133420c78b 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c @@ -39,9 +39,8 @@ static void guc_prepare_xfer(struct intel_gt *gt) if (GRAPHICS_VER(uncore->i915) == 9) { /* DOP Clock Gating Enable for GuC clocks */ - intel_gt_mcr_multicast_write(gt, GEN8_MISCCPCTL, -GEN8_DOP_CLOCK_GATE_GUC_ENABLE | -intel_gt_mcr_read_any(gt, GEN8_MISCCPCTL)); + intel_uncore_rmw(uncore, GEN7_MISCCPCTL, 0, +GEN8_DOP_CLOCK_GATE_GUC_ENABLE); /* allows for 5us (in 10ns units) before GT can go to RC6 */ intel_uncore_write(uncore, GUC_ARAT_C6DIS, 0x1FF); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index e0364c4141b8..798607959458 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4300,8 +4300,8 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv, u32 val; /* WaTempDisableDOPClkGating:bdw */ - misccpctl = intel_gt_mcr_multicast_rmw(to_gt(dev_priv), GEN8_MISCCPCTL, - GEN8_DOP_CLOCK_GATE_ENABLE, 0); + misccpctl = intel_uncore_rmw(_priv->uncore, GEN7_MISCCPCTL, +GEN7_DOP_CLOCK_GATE_ENABLE, 0); val = intel_gt_mcr_read_any(to_gt(dev_priv), GEN8_L3SQCREG1); val &=
Re: [PATCH 1/3] drm/i915/doc: Escape wildcard in method names
On Fri, Feb 03, 2023 at 05:02:13PM +0700, Bagas Sanjaya wrote: > Stephen Rothwell reported htmldocs warnings: > > Documentation/gpu/i915:64: drivers/gpu/drm/i915/gt/intel_workarounds.c:32: > WARNING: Inline emphasis start-string without end-string. > Documentation/gpu/i915:64: drivers/gpu/drm/i915/gt/intel_workarounds.c:57: > WARNING: Inline emphasis start-string without end-string. > Documentation/gpu/i915:64: drivers/gpu/drm/i915/gt/intel_workarounds.c:66: > WARNING: Inline emphasis start-string without end-string. > > Escape wildcards in *_ctx_workarounds_init(), *_gt_workarounds_init(), and > *_whitelist_build() to fix above warnings. > > Link: > https://lore.kernel.org/linux-next/20230203134622.0b631...@canb.auug.org.au/ > Fixes: 0c3064cf33fbfa ("drm/i915/doc: Document where to implement register > workarounds") > Reported-by: Stephen Rothwell > Signed-off-by: Bagas Sanjaya Reviewed-by: Rodrigo Vivi pushing this now. thank you. > --- > drivers/gpu/drm/i915/gt/intel_workarounds.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c > b/drivers/gpu/drm/i915/gt/intel_workarounds.c > index 3111df350f5722..a00ec692d980c0 100644 > --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c > +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c > @@ -30,7 +30,7 @@ > * creation to have a "primed golden context", i.e. a context image that > * already contains the changes needed to all the registers. > * > - * Context workarounds should be implemented in the > *_ctx_workarounds_init() > + * Context workarounds should be implemented in the > \*_ctx_workarounds_init() > * variants respective to the targeted platforms. > * > * - Engine workarounds: the list of these WAs is applied whenever the > specific > @@ -55,7 +55,7 @@ > * - GT workarounds: the list of these WAs is applied whenever these > registers > * revert to their default values: on GPU reset, suspend/resume [1]_, etc. > * > - * GT workarounds should be implemented in the *_gt_workarounds_init() > + * GT workarounds should be implemented in the \*_gt_workarounds_init() > * variants respective to the targeted platforms. > * > * - Register whitelist: some workarounds need to be implemented in > userspace, > @@ -64,7 +64,7 @@ > * this is just a special case of a MMIO workaround (as we write the list > of > * these to/be-whitelisted registers to some special HW registers). > * > - * Register whitelisting should be done in the *_whitelist_build() variants > + * Register whitelisting should be done in the \*_whitelist_build() > variants > * respective to the targeted platforms. > * > * - Workaround batchbuffers: buffers that get executed automatically by the > -- > An old man doll... just what I always wanted! - Clara >
Re: [Nouveau] [PATCH drm-next 05/14] drm/nouveau: new VM_BIND uapi interfaces
Concentrating this discussion on a very big misunderstanding first. Am 06.02.23 um 14:27 schrieb Danilo Krummrich: [SNIP] My understanding is that userspace is fully responsible on the parts of the GPU VA space it owns. This means that userspace needs to take care to *not* ask the kernel to modify mappings that are in use currently. This is a completely wrong assumption! Take a look at what games like Forza Horizzon are doing. Basically that game allocates a very big sparse area and fills it with pages from BOs while shaders are accessing it. And yes, as far as I know this is completely valid behavior. So you need to be able to handle this case anyway and the approach with the regions won't help you at all preventing that. Regards, Christian.
Re: [PATCH v3 0/3] drm/rockchip: dw_hdmi: Add 4k@30 support
Hi Sascha, On Mon, 6 Feb 2023 at 15:49, Sascha Hauer wrote: > On Mon, Feb 06, 2023 at 03:04:48PM +0100, Sascha Hauer wrote: > > I guess a first step would be to limit the maximum resolution of vopl > > to what the hardware can do. We would likely end up with 1080p by > > default then for the applications. > > I did that, but the result is not what I expected. Discarding a mode in > the connector means it won't show up in the connectors list of modes. > Discarding it in the CRTC though means the mode is still exposed by the > connector, but actually trying to use it then fails. > > This means when discarding the mode in the CRTC the screen stays black. > > I am not sure where I should go from here. You've done the right thing. Userspace should detect this and try with alternative CRTC routing. The kernel shouldn't be trying to solve this problem. Cheers, Daniel
Re: [PATCH] drm/amdgpu: Fix potential race processing vm->freed
Am 06.02.23 um 16:52 schrieb Rob Clark: On Mon, Feb 6, 2023 at 2:15 AM Christian König wrote: Am 03.02.23 um 19:10 schrieb Rob Clark: From: Rob Clark If userspace calls the AMDGPU_CS ioctl from multiple threads, because the vm is global to the drm_file, you can end up with multiple threads racing in amdgpu_vm_clear_freed(). So the freed list should be protected with the status_lock, similar to other vm lists. Well this is nonsense. To process the freed list the VM root PD lock must be held anyway. If we have a call path where this isn't true then we have a major bug at a different place here. I'm not super familiar w/ the amdgpu cs parser stuff, but the only thing that I'm seeing that protects things is the bo_list_mutex and it isn't clear to me that this is 1:1 with the vm (it looks like it is not). Do you have a backtrace? Take a look at the reservation object of vm->root.bo. This should always be locked first before doing *anything* in a CS. If that isn't the case we have a much worse problem. (I cc'd you on the bug report, jfyi) I unfortunately only get a permission denied when I try to access that one. Regards, Christian. BR, -R Regards, Christian. Fixes: d38ceaf99ed0 ("drm/amdgpu: add core driver (v4)") Signed-off-by: Rob Clark --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 33 ++ 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index b9441ab457ea..aeed7bc1512f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1240,10 +1240,19 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, struct amdgpu_bo_va_mapping *mapping; uint64_t init_pte_value = 0; struct dma_fence *f = NULL; + struct list_head freed; int r; - while (!list_empty(>freed)) { - mapping = list_first_entry(>freed, + /* + * Move the contents of the VM's freed list to a local list + * that we can iterate without racing against other threads: + */ + spin_lock(>status_lock); + list_replace_init(>freed, ); + spin_unlock(>status_lock); + + while (!list_empty()) { + mapping = list_first_entry(, struct amdgpu_bo_va_mapping, list); list_del(>list); @@ -1258,6 +1267,15 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, amdgpu_vm_free_mapping(adev, vm, mapping, f); if (r) { dma_fence_put(f); + + /* + * Move any unprocessed mappings back to the freed + * list: + */ + spin_lock(>status_lock); + list_splice_tail(, >freed); + spin_unlock(>status_lock); + return r; } } @@ -1583,11 +1601,14 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, mapping->bo_va = NULL; trace_amdgpu_vm_bo_unmap(bo_va, mapping); - if (valid) + if (valid) { + spin_lock(>status_lock); list_add(>list, >freed); - else + spin_unlock(>status_lock); + } else { amdgpu_vm_free_mapping(adev, vm, mapping, bo_va->last_pt_update); + } return 0; } @@ -1671,7 +1692,9 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, tmp->last = eaddr; tmp->bo_va = NULL; + spin_lock(>status_lock); list_add(>list, >freed); + spin_unlock(>status_lock); trace_amdgpu_vm_bo_unmap(NULL, tmp); } @@ -1788,7 +1811,9 @@ void amdgpu_vm_bo_del(struct amdgpu_device *adev, amdgpu_vm_it_remove(mapping, >va); mapping->bo_va = NULL; trace_amdgpu_vm_bo_unmap(bo_va, mapping); + spin_lock(>status_lock); list_add(>list, >freed); + spin_unlock(>status_lock); } list_for_each_entry_safe(mapping, next, _va->invalids, list) { list_del(>list);
Re: [PATCH] Revert "fbdev: Remove conflicting devices on PCI bus"
On Mon, Feb 06, 2023 at 06:59:40AM +1000, Dave Airlie wrote: > On Sat, 4 Feb 2023 at 09:09, Bjorn Helgaas wrote: > > From: Bjorn Helgaas > > > > This reverts commit 145eed48de278007f646b908fd70ac59d24ed81a. > > > > Zeno Davatz reported that 145eed48de27 ("fbdev: Remove conflicting devices > > on PCI bus") caused a console hang. The machine was actually still usable > > via ssh, etc., but there was no activity on the console. > > > > Reverting 145eed48de27 for the nvidiafb on that system fixed the problem. > > > > Revert 145eed48de27 ("fbdev: Remove conflicting devices on PCI bus") since > > we don't know what caused the problem. > > Why is the user using nvidiafb? I don't know, and of course, it really doesn't matter; we shouldn't regress a user's experience, and there's no hint to the user of where to look for a resolution. Thanks for working out a better fix! Bjorn
Re: [PATCH] drm/amdgpu: Fix potential race processing vm->freed
On Mon, Feb 6, 2023 at 2:15 AM Christian König wrote: > > Am 03.02.23 um 19:10 schrieb Rob Clark: > > From: Rob Clark > > > > If userspace calls the AMDGPU_CS ioctl from multiple threads, because > > the vm is global to the drm_file, you can end up with multiple threads > > racing in amdgpu_vm_clear_freed(). So the freed list should be > > protected with the status_lock, similar to other vm lists. > > Well this is nonsense. To process the freed list the VM root PD lock > must be held anyway. > > If we have a call path where this isn't true then we have a major bug at > a different place here. I'm not super familiar w/ the amdgpu cs parser stuff, but the only thing that I'm seeing that protects things is the bo_list_mutex and it isn't clear to me that this is 1:1 with the vm (it looks like it is not). (I cc'd you on the bug report, jfyi) BR, -R > > Regards, > Christian. > > > > > Fixes: d38ceaf99ed0 ("drm/amdgpu: add core driver (v4)") > > Signed-off-by: Rob Clark > > --- > > drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 33 ++ > > 1 file changed, 29 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > > index b9441ab457ea..aeed7bc1512f 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > > @@ -1240,10 +1240,19 @@ int amdgpu_vm_clear_freed(struct amdgpu_device > > *adev, > > struct amdgpu_bo_va_mapping *mapping; > > uint64_t init_pte_value = 0; > > struct dma_fence *f = NULL; > > + struct list_head freed; > > int r; > > > > - while (!list_empty(>freed)) { > > - mapping = list_first_entry(>freed, > > + /* > > + * Move the contents of the VM's freed list to a local list > > + * that we can iterate without racing against other threads: > > + */ > > + spin_lock(>status_lock); > > + list_replace_init(>freed, ); > > + spin_unlock(>status_lock); > > + > > + while (!list_empty()) { > > + mapping = list_first_entry(, > > struct amdgpu_bo_va_mapping, list); > > list_del(>list); > > > > @@ -1258,6 +1267,15 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, > > amdgpu_vm_free_mapping(adev, vm, mapping, f); > > if (r) { > > dma_fence_put(f); > > + > > + /* > > + * Move any unprocessed mappings back to the freed > > + * list: > > + */ > > + spin_lock(>status_lock); > > + list_splice_tail(, >freed); > > + spin_unlock(>status_lock); > > + > > return r; > > } > > } > > @@ -1583,11 +1601,14 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, > > mapping->bo_va = NULL; > > trace_amdgpu_vm_bo_unmap(bo_va, mapping); > > > > - if (valid) > > + if (valid) { > > + spin_lock(>status_lock); > > list_add(>list, >freed); > > - else > > + spin_unlock(>status_lock); > > + } else { > > amdgpu_vm_free_mapping(adev, vm, mapping, > > bo_va->last_pt_update); > > + } > > > > return 0; > > } > > @@ -1671,7 +1692,9 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device > > *adev, > > tmp->last = eaddr; > > > > tmp->bo_va = NULL; > > + spin_lock(>status_lock); > > list_add(>list, >freed); > > + spin_unlock(>status_lock); > > trace_amdgpu_vm_bo_unmap(NULL, tmp); > > } > > > > @@ -1788,7 +1811,9 @@ void amdgpu_vm_bo_del(struct amdgpu_device *adev, > > amdgpu_vm_it_remove(mapping, >va); > > mapping->bo_va = NULL; > > trace_amdgpu_vm_bo_unmap(bo_va, mapping); > > + spin_lock(>status_lock); > > list_add(>list, >freed); > > + spin_unlock(>status_lock); > > } > > list_for_each_entry_safe(mapping, next, _va->invalids, list) { > > list_del(>list); >
Re: [PATCH v3 0/3] drm/rockchip: dw_hdmi: Add 4k@30 support
On Mon, Feb 06, 2023 at 03:04:48PM +0100, Sascha Hauer wrote: > On Wed, Feb 01, 2023 at 09:23:56AM +0900, FUKAUMI Naoki wrote: > > hi, > > > > I'm trying this patch series with 6.1.x kernel. it works fine on rk356x > > based boards (ROCK 3), but it has a problem on rk3399 boards (ROCK 4). > > > > on rk3399 with this patch, I can see large noise area (about one third right > > side of the screen) at 4k@30. 1080p works fine as same as before. > > > > can someone reproduce this problem on rk3399? > > Ok, I could easily reproduce the problem here. > > The RK3399 has two VOPs, vopb(ig) and vopl(ittle). Only the former can > do 4k@30 while the latter can only do 1080p. Unfortunately vopl is used > by default. We can force using vopb by disabling vopl in the device tree > and get a good 4k@30 picture then. The other possibility I found is to > use the other CRTC with modetest. I have no idea how we could set the > default to vopb. > > I guess a first step would be to limit the maximum resolution of vopl > to what the hardware can do. We would likely end up with 1080p by > default then for the applications. I did that, but the result is not what I expected. Discarding a mode in the connector means it won't show up in the connectors list of modes. Discarding it in the CRTC though means the mode is still exposed by the connector, but actually trying to use it then fails. This means when discarding the mode in the CRTC the screen stays black. I am not sure where I should go from here. Sascha -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
Re: [PATCH v6 01/17] dt-bindings: display: rockchip: convert rockchip-lvds.txt to YAML
On Sun, Feb 5, 2023 at 8:12 AM Heiko Stübner wrote: > > Hi, > > Am Freitag, 3. Februar 2023, 20:02:54 CET schrieb Johan Jonker: > > > > On 2/3/23 19:21, Rob Herring wrote: > > > On Thu, Dec 22, 2022 at 03:22:14PM +0100, Johan Jonker wrote: > > >> Convert rockchip-lvds.txt to YAML. > > >> > > >> Changed: > > >> Add power-domains property. > > >> Requirements between PX30 and RK3288 > > >> > > >> Signed-off-by: Johan Jonker > > >> Reviewed-by: Rob Herring > > >> --- > > >> > > >> Changed V3: > > >> Filename matching compatible style > > >> Drop "Regulator phandle for " > > >> Specify properties and requirements per SoC > > >> Sort order and restyle > > >> > > >> Changed V2: > > >> Fix title > > >> --- > > >> .../display/rockchip/rockchip,lvds.yaml | 170 ++ > > >> .../display/rockchip/rockchip-lvds.txt| 92 -- > > >> 2 files changed, 170 insertions(+), 92 deletions(-) > > >> create mode 100644 > > >> Documentation/devicetree/bindings/display/rockchip/rockchip,lvds.yaml > > >> delete mode 100644 > > >> Documentation/devicetree/bindings/display/rockchip/rockchip-lvds.txt > > > > > > > > What's the plan for these patches? Don't see them in linux-next still. > > > Do you want me to take patches 1-8? > > > > Hi, > > > > The display patches normally go through the DRM git. > > Patch 2 must merge with grf.yaml. > > Heiko has merged now 3 PHY related patches to grf.yaml first. > > > > [PATCH v6 02/17] dt-bindings: soc: rockchip: grf: add rockchip,lvds.yaml > > > > See current > > https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/log/?h=for-next=grep=jonker > > > > Not sure what Heiko's plans are. > > Patch 2 replaces only a description text and some accolades removal, so > > not "too" important. > > > > I urgent then you could merge without conflict: > > 1, 3-8 > > So I've applied patches 1-7 to the drm-tree now. That would have been good a month ago. Now these won't land til 6.4. :( For that reason, if it is after the drm-misc cutoff, I prefer to take DT bindings via my tree. > For the GRF-patch, I've dropped the quotes changes, as they are somewhat > unrelated to the lvds inclusion and so prevented any conflicts when applying > the rest to the DRM tree. Only 1 hunk needed to be dropped to avoid the conflict (which also dropped quotes). If all the quote changes were dropped, please send another patch for that. > @Rob, if you could pick the fusb302 patch (number8), that would be great Will do. Rob
[PATCH v2 4/8] accel/qaic: Add control path
Add the control path component that talks to the management processor (QSM) to load workloads onto the AIC100 device. This implements the KMD portion of the NNC protocol over the QAIC_CONTROL MHI channel and the DRM_IOCTL_QAIC_MANAGE IOCTL to userspace. With this functionality, QAIC clients are able to load, run, and cleanup their workloads on the device but not interact with the workloads (run inferences). Signed-off-by: Jeffrey Hugo Reviewed-by: Carl Vanderlip --- drivers/accel/qaic/qaic_control.c | 1656 + 1 file changed, 1656 insertions(+) create mode 100644 drivers/accel/qaic/qaic_control.c diff --git a/drivers/accel/qaic/qaic_control.c b/drivers/accel/qaic/qaic_control.c new file mode 100644 index 000..9f5d5e2 --- /dev/null +++ b/drivers/accel/qaic/qaic_control.c @@ -0,0 +1,1656 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */ +/* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qaic.h" + +#define MANAGE_MAGIC_NUMBER ((__force __le32)0x43494151) /* "QAIC" in little endian */ +#define QAIC_DBC_Q_GAP0x100 +#define QAIC_DBC_Q_BUF_ALIGN SZ_4K +#define QAIC_MANAGE_EXT_MSG_LENGTH SZ_64K /* Max DMA message length */ +#define QAIC_WRAPPER_MAX_SIZE SZ_4K +#define QAIC_MHI_RETRY_WAIT_MS100 +#define QAIC_MHI_RETRY_MAX20 + +static unsigned int control_resp_timeout = 60; /* 60 sec default */ +module_param(control_resp_timeout, uint, 0600); + +struct manage_msg { + u32 len; + u32 count; + u8 data[]; +}; + +/* + * wire encoding structures for the manage protocol. + * All fields are little endian on the wire + */ +struct _msg_hdr { + __le32 crc32; /* crc of everything following this field in the message */ + __le32 magic_number; + __le32 sequence_number; + __le32 len; /* length of this message */ + __le32 count; /* number of transactions in this message */ + __le32 handle; /* unique id to track the resources consumed */ + __le32 partition_id; /* partition id for the request (signed)*/ + __le32 padding; /* must be 0 */ +} __packed; + +struct _msg { + struct _msg_hdr hdr; + u8 data[]; +} __packed; + +struct _trans_hdr { + __le32 type; + __le32 len; +} __packed; + +/* Each message sent from driver to device are organized in a list of wrapper_msg */ +struct wrapper_msg { + struct list_head list; + struct kref ref_count; + u32 len; /* length of data to transfer */ + struct wrapper_list *head; + union { + struct _msg msg; + struct _trans_hdr trans; + }; +}; + +struct wrapper_list { + struct list_head list; + spinlock_t lock; +}; + +struct _trans_passthrough { + struct _trans_hdr hdr; + u8 data[]; +} __packed; + +struct _addr_size_pair { + __le64 addr; + __le64 size; +} __packed; + +struct _trans_dma_xfer { + struct _trans_hdr hdr; + __le32 tag; + __le32 count; + __le32 dma_chunk_id; + __le32 padding; + struct _addr_size_pair data[]; +} __packed; + +/* Initiated by device to continue the DMA xfer of a large piece of data */ +struct _trans_dma_xfer_cont { + struct _trans_hdr hdr; + __le32 dma_chunk_id; + __le32 padding; + __le64 xferred_size; +} __packed; + +struct _trans_activate_to_dev { + struct _trans_hdr hdr; + __le64 req_q_addr; + __le64 rsp_q_addr; + __le32 req_q_size; + __le32 rsp_q_size; + __le32 buf_len; + __le32 options; /* unused, but BIT(16) has meaning to the device */ +} __packed; + +struct _trans_activate_from_dev { + struct _trans_hdr hdr; + __le32 status; + __le32 dbc_id; + __le64 options; /* unused */ +} __packed; + +struct _trans_deactivate_from_dev { + struct _trans_hdr hdr; + __le32 status; + __le32 dbc_id; +} __packed; + +struct _trans_terminate_to_dev { + struct _trans_hdr hdr; + __le32 handle; + __le32 padding; +} __packed; + +struct _trans_terminate_from_dev { + struct _trans_hdr hdr; + __le32 status; + __le32 padding; +} __packed; + +struct _trans_status_to_dev { + struct _trans_hdr hdr; +} __packed; + +struct _trans_status_from_dev { + struct _trans_hdr hdr; + __le16 major; + __le16 minor; + __le32 status; + __le64 status_flags; +} __packed; + +struct _trans_validate_part_to_dev { + struct _trans_hdr hdr; + __le32 part_id; + __le32 padding; +} __packed; + +struct _trans_validate_part_from_dev { + struct _trans_hdr hdr; + __le32 status; +
[PATCH v2 6/8] accel/qaic: Add mhi_qaic_cntl
From: Pranjal Ramajor Asha Kanojiya Some of the MHI channels for an AIC100 device need to be routed to userspace so that userspace can communicate directly with QSM. The MHI bus does not support this, and while the WWAN subsystem does (for the same reasons), AIC100 is not a WWAN device. Also, MHI is not something that other accelerators are expected to share, thus an accel subsystem function that meets this usecase is unlikely. Create a QAIC specific MHI userspace shim that exposes these channels. Start with QAIC_SAHARA which is required to boot AIC100 and is consumed by the kickstart application as documented in aic100.rst Each AIC100 instance (currently, up to 16) in a system will create a chardev for QAIC_SAHARA. This chardev will be found as /dev/_QAIC_SAHARA For example - /dev/mhi0_QAIC_SAHARA Signed-off-by: Pranjal Ramajor Asha Kanojiya Signed-off-by: Jeffrey Hugo Reviewed-by: Carl Vanderlip --- drivers/accel/qaic/mhi_qaic_ctrl.c | 586 + drivers/accel/qaic/mhi_qaic_ctrl.h | 11 + 2 files changed, 597 insertions(+) create mode 100644 drivers/accel/qaic/mhi_qaic_ctrl.c create mode 100644 drivers/accel/qaic/mhi_qaic_ctrl.h diff --git a/drivers/accel/qaic/mhi_qaic_ctrl.c b/drivers/accel/qaic/mhi_qaic_ctrl.c new file mode 100644 index 000..1f1ccf1 --- /dev/null +++ b/drivers/accel/qaic/mhi_qaic_ctrl.c @@ -0,0 +1,586 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qaic.h" + +#define MHI_QAIC_CTRL_DRIVER_NAME "mhi_qaic_ctrl" +#define MHI_QAIC_CTRL_MAX_MINORS 128 +#define MHI_MAX_MTU0x +static DEFINE_XARRAY_ALLOC(mqc_xa); +static struct class *mqc_dev_class; +static int mqc_dev_major; + +/** + * @brief struct mqc_buf - Buffer structure used to receive data from device + * @data: Address of data to read from + * @odata: Original address returned from *alloc() API. Used to free this buf. + * @len: Length of data in byte + * @node: This buffer will be part of list managed in struct mqc_dev + */ +struct mqc_buf { + void *data; + void *odata; + size_t len; + struct list_head node; +}; + +/** + * @brief struct mqc_dev - MHI QAIC Control Device + * @minor: MQC device node minor number + * @mhi_dev: Associated mhi device object + * @mtu: Max TRE buffer length + * @enabled: Flag to track the state of the MQC device + * @lock: Mutex lock to serialize access to open_count + * @read_lock: Mutex lock to serialize readers + * @write_lock: Mutex lock to serialize writers + * @ul_wq: Wait queue for writers + * @dl_wq: Wait queue for readers + * @dl_queue_lock: Spin lock to serialize access to download queue + * @dl_queue: Queue of downloaded buffers + * @open_count: Track open counts + * @ref_count: Reference count for this structure + */ +struct mqc_dev { + uint32_t minor; + struct mhi_device *mhi_dev; + size_t mtu; + bool enabled; + struct mutex lock; + struct mutex read_lock; + struct mutex write_lock; + wait_queue_head_t ul_wq; + wait_queue_head_t dl_wq; + spinlock_t dl_queue_lock; + struct list_head dl_queue; + unsigned int open_count; + struct kref ref_count; +}; + +static void mqc_dev_release(struct kref *ref) +{ + struct mqc_dev *mqcdev = container_of(ref, struct mqc_dev, ref_count); + + mutex_destroy(>read_lock); + mutex_destroy(>write_lock); + mutex_destroy(>lock); + kfree(mqcdev); +} + +static int mhi_qaic_ctrl_fill_dl_queue(struct mqc_dev *mqcdev) +{ + struct mhi_device *mhi_dev = mqcdev->mhi_dev; + struct mqc_buf *ctrlbuf; + int rx_budget; + int ret = 0; + void *data; + + rx_budget = mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE); + if (rx_budget < 0) + return -EIO; + + while (rx_budget--) { + data = kzalloc(mqcdev->mtu + sizeof(*ctrlbuf), GFP_KERNEL); + if (!data) + return -ENOMEM; + + ctrlbuf = data + mqcdev->mtu; + ctrlbuf->odata = data; + + ret = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, data, + mqcdev->mtu, MHI_EOT); + if (ret) { + kfree(data); + dev_err(_dev->dev, "Failed to queue buffer\n"); + return ret; + } + } + + return ret; +} + +static int mhi_qaic_ctrl_dev_start_chan(struct mqc_dev *mqcdev) +{ + struct device *dev = >mhi_dev->dev; + int ret = 0; + + ret = mutex_lock_interruptible(>lock); + if (ret) + return ret; + if (!mqcdev->enabled) { + ret = -ENODEV; + goto release_dev_lock; + } + if (!mqcdev->open_count) { +
[PATCH v2 5/8] accel/qaic: Add datapath
Add the datapath component that manages BOs and submits them to running workloads on the qaic device via the dma_bridge hardware. This allows QAIC clients to interact with their workloads (run inferences) via the following ioctls along with mmap(): DRM_IOCTL_QAIC_CREATE_BO DRM_IOCTL_QAIC_MMAP_BO DRM_IOCTL_QAIC_ATTACH_SLICE_BO DRM_IOCTL_QAIC_EXECUTE_BO DRM_IOCTL_QAIC_PARTIAL_EXECUTE_BO DRM_IOCTL_QAIC_WAIT_BO DRM_IOCTL_QAIC_PERF_STATS_BO Signed-off-by: Jeffrey Hugo Reviewed-by: Carl Vanderlip --- drivers/accel/qaic/qaic_data.c | 1952 1 file changed, 1952 insertions(+) create mode 100644 drivers/accel/qaic/qaic_data.c diff --git a/drivers/accel/qaic/qaic_data.c b/drivers/accel/qaic/qaic_data.c new file mode 100644 index 000..d37cdbe --- /dev/null +++ b/drivers/accel/qaic/qaic_data.c @@ -0,0 +1,1952 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */ +/* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qaic.h" + +#define SEM_VAL_MASK GENMASK_ULL(11, 0) +#define SEM_INDEX_MASK GENMASK_ULL(4, 0) +#define BULK_XFER BIT(3) +#define GEN_COMPLETION BIT(4) +#define INBOUND_XFER 1 +#define OUTBOUND_XFER 2 +#define REQHP_OFF 0x0 /* we read this */ +#define REQTP_OFF 0x4 /* we write this */ +#define RSPHP_OFF 0x8 /* we write this */ +#define RSPTP_OFF 0xc /* we read this */ + +#define ENCODE_SEM(val, index, sync, cmd, flags) \ + ((val) |\ + (index) << 16 | \ + (sync) << 22 | \ + (cmd) << 24 | \ + ((cmd) ? BIT(31) : 0) | \ + (((flags) & SEM_INSYNCFENCE) ? BIT(30) : 0) | \ + (((flags) & SEM_OUTSYNCFENCE) ? BIT(29) : 0)) +#define NUM_EVENTS 128 +#define NUM_DELAYS 10 + +static unsigned int wait_exec_default_timeout = 5000; /* 5 sec default */ +module_param(wait_exec_default_timeout, uint, 0600); + +static unsigned int datapath_poll_interval_us = 100; /* 100 usec default */ +module_param(datapath_poll_interval_us, uint, 0600); + +struct dbc_req { /* everything must be little endian encoded */ + /* +* A request ID is assigned to each memory handle going in DMA queue. +* As a single memory handle can enqueue multiple elements in DMA queue +* all of them will have the same request ID. +*/ + __le16 req_id; + /* Future use */ + __u8seq_id; + /* +* Special encoded variable +* 70 - Do not force to generate MSI after DMA is completed +* 1 - Force to generate MSI after DMA is completed +* 6:5 Reserved +* 41 - Generate completion element in the response queue +* 0 - No Completion Code +* 30 - DMA request is a Link list transfer +* 1 - DMA request is a Bulk transfer +* 2Reserved +* 1:0 00 - No DMA transfer involved +* 01 - DMA transfer is part of inbound transfer +* 10 - DMA transfer has outbound transfer +* 11 - NA +*/ + __u8cmd; + __le32 resv; + /* Source address for the transfer */ + __le64 src_addr; + /* Destination address for the transfer */ + __le64 dest_addr; + /* Length of transfer request */ + __le32 len; + __le32 resv2; + /* Doorbell address */ + __le64 db_addr; + /* +* Special encoded variable +* 71 - Doorbell(db) write +* 0 - No doorbell write +* 6:2 Reserved +* 1:0 00 - 32 bit access, db address must be aligned to 32bit-boundary +* 01 - 16 bit access, db address must be aligned to 16bit-boundary +* 10 - 8 bit access, db address must be aligned to 8bit-boundary +* 11 - Reserved +*/ + __u8db_len; + __u8resv3; + __le16 resv4; + /* 32 bit data written to doorbell address */ + __le32 db_data; + /* +* Special encoded variable +* All the fields of sem_cmdX are passed from user and all are ORed +* together to form sem_cmd. +* 0:11 Semaphore value +* 15:12Reserved +* 20:16Semaphore index +* 21 Reserved +* 22 Semaphore Sync +* 23 Reserved +* 26:24Semaphore command +* 28:27Reserved +
[PATCH v2 8/8] MAINTAINERS: Add entry for QAIC driver
Add MAINTAINERS entry for the Qualcomm Cloud AI 100 driver. Signed-off-by: Jeffrey Hugo Reviewed-by: Carl Vanderlip --- MAINTAINERS | 8 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 263d37a..0a264f1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17170,6 +17170,14 @@ F: Documentation/devicetree/bindings/clock/qcom,* F: drivers/clk/qcom/ F: include/dt-bindings/clock/qcom,* +QUALCOMM CLOUD AI (QAIC) DRIVER +M: Jeffrey Hugo +L: linux-arm-...@vger.kernel.org +S: Supported +F: Documentation/accel/qaic/ +F: drivers/accel/qaic/ +F: include/uapi/drm/qaic_accel.h + QUALCOMM CORE POWER REDUCTION (CPR) AVS DRIVER M: Niklas Cassel L: linux...@vger.kernel.org -- 2.7.4
[PATCH v2 7/8] accel/qaic: Add qaic driver to the build system
Now that we have all the components of a minimum QAIC which can boot and run an AIC100 device, add the infrastructure that allows the QAIC driver to be built. Signed-off-by: Jeffrey Hugo Reviewed-by: Carl Vanderlip --- drivers/accel/Kconfig | 1 + drivers/accel/Makefile | 1 + drivers/accel/qaic/Kconfig | 23 +++ drivers/accel/qaic/Makefile | 13 + 4 files changed, 38 insertions(+) create mode 100644 drivers/accel/qaic/Kconfig create mode 100644 drivers/accel/qaic/Makefile diff --git a/drivers/accel/Kconfig b/drivers/accel/Kconfig index 8348639..56d0d01 100644 --- a/drivers/accel/Kconfig +++ b/drivers/accel/Kconfig @@ -25,3 +25,4 @@ menuconfig DRM_ACCEL source "drivers/accel/habanalabs/Kconfig" source "drivers/accel/ivpu/Kconfig" +source "drivers/accel/qaic/Kconfig" diff --git a/drivers/accel/Makefile b/drivers/accel/Makefile index 07aa77a..3cb6f14 100644 --- a/drivers/accel/Makefile +++ b/drivers/accel/Makefile @@ -2,3 +2,4 @@ obj-y += habanalabs/ obj-y += ivpu/ +obj-y += qaic/ diff --git a/drivers/accel/qaic/Kconfig b/drivers/accel/qaic/Kconfig new file mode 100644 index 000..a9f8662 --- /dev/null +++ b/drivers/accel/qaic/Kconfig @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Qualcomm Cloud AI accelerators driver +# + +config DRM_ACCEL_QAIC + tristate "Qualcomm Cloud AI accelerators" + depends on DRM_ACCEL + depends on PCI && HAS_IOMEM + depends on MHI_BUS + depends on MMU + select CRC32 + help + Enables driver for Qualcomm's Cloud AI accelerator PCIe cards that are + designed to accelerate Deep Learning inference workloads. + + The driver manages the PCIe devices and provides an IOCTL interface + for users to submit workloads to the devices. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called qaic. diff --git a/drivers/accel/qaic/Makefile b/drivers/accel/qaic/Makefile new file mode 100644 index 000..d5f4952 --- /dev/null +++ b/drivers/accel/qaic/Makefile @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Makefile for Qualcomm Cloud AI accelerators driver +# + +obj-$(CONFIG_DRM_ACCEL_QAIC) := qaic.o + +qaic-y := \ + mhi_controller.o \ + mhi_qaic_ctrl.o \ + qaic_control.o \ + qaic_data.o \ + qaic_drv.o -- 2.7.4
[PATCH v2 0/8] QAIC accel driver
From: Jeffrey Hugo This series introduces a driver under the accel subsystem (QAIC - Qualcomm AIC) for the Qualcomm Cloud AI 100 product (AIC100). AIC100 is a PCIe adapter card that hosts a dedicated machine learning inference accelerator. Regarding the open userspace (see the documentation patch), the UMD and compiler are a week or so away from being posted in the indicated repos. Just need to polish some documentation. The previous version (RFC) can be found at: https://lore.kernel.org/all/1660588956-24027-1-git-send-email-quic_jh...@quicinc.com/ v2: -Addressed comments from RFC -Reduced the code to the core minimum by dropping telemetery, etc -Conversion to accel subsystem -Dropped versioning -Add mhi_qaic_cntl component -Restructure the documentation -Pull in a few fixes from the downstream tree Jeffrey Hugo (7): accel/qaic: Add documentation for AIC100 accelerator driver accel/qaic: Add uapi and core driver file accel/qaic: Add MHI controller accel/qaic: Add control path accel/qaic: Add datapath accel/qaic: Add qaic driver to the build system MAINTAINERS: Add entry for QAIC driver Pranjal Ramajor Asha Kanojiya (1): accel/qaic: Add mhi_qaic_cntl Documentation/accel/index.rst |1 + Documentation/accel/qaic/aic100.rst | 498 + Documentation/accel/qaic/index.rst | 13 + Documentation/accel/qaic/qaic.rst | 169 +++ MAINTAINERS |8 + drivers/accel/Kconfig |1 + drivers/accel/Makefile |1 + drivers/accel/qaic/Kconfig | 23 + drivers/accel/qaic/Makefile | 13 + drivers/accel/qaic/mhi_controller.c | 576 +++ drivers/accel/qaic/mhi_controller.h | 19 + drivers/accel/qaic/mhi_qaic_ctrl.c | 586 +++ drivers/accel/qaic/mhi_qaic_ctrl.h | 11 + drivers/accel/qaic/qaic.h | 321 ++ drivers/accel/qaic/qaic_control.c | 1656 + drivers/accel/qaic/qaic_data.c | 1952 +++ drivers/accel/qaic/qaic_drv.c | 771 ++ include/uapi/drm/qaic_accel.h | 283 + 18 files changed, 6902 insertions(+) create mode 100644 Documentation/accel/qaic/aic100.rst create mode 100644 Documentation/accel/qaic/index.rst create mode 100644 Documentation/accel/qaic/qaic.rst create mode 100644 drivers/accel/qaic/Kconfig create mode 100644 drivers/accel/qaic/Makefile create mode 100644 drivers/accel/qaic/mhi_controller.c create mode 100644 drivers/accel/qaic/mhi_controller.h create mode 100644 drivers/accel/qaic/mhi_qaic_ctrl.c create mode 100644 drivers/accel/qaic/mhi_qaic_ctrl.h create mode 100644 drivers/accel/qaic/qaic.h create mode 100644 drivers/accel/qaic/qaic_control.c create mode 100644 drivers/accel/qaic/qaic_data.c create mode 100644 drivers/accel/qaic/qaic_drv.c create mode 100644 include/uapi/drm/qaic_accel.h -- 2.7.4
[PATCH v2 2/8] accel/qaic: Add uapi and core driver file
Add the QAIC driver uapi file and core driver file that binds to the PCIe device. The core driver file also creates the accel device and manages all the interconnections between the different parts of the driver. The driver can be built as a module. If so, it will be called "qaic.ko". Signed-off-by: Jeffrey Hugo Reviewed-by: Carl Vanderlip --- drivers/accel/qaic/qaic.h | 321 ++ drivers/accel/qaic/qaic_drv.c | 771 ++ include/uapi/drm/qaic_accel.h | 283 3 files changed, 1375 insertions(+) create mode 100644 drivers/accel/qaic/qaic.h create mode 100644 drivers/accel/qaic/qaic_drv.c create mode 100644 include/uapi/drm/qaic_accel.h diff --git a/drivers/accel/qaic/qaic.h b/drivers/accel/qaic/qaic.h new file mode 100644 index 000..3f7ea76 --- /dev/null +++ b/drivers/accel/qaic/qaic.h @@ -0,0 +1,321 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QAICINTERNAL_H_ +#define QAICINTERNAL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define QAIC_DBC_BASE 0x2 +#define QAIC_DBC_SIZE 0x1000 + +#define QAIC_NO_PARTITION -1 + +#define QAIC_DBC_OFF(i)((i) * QAIC_DBC_SIZE + QAIC_DBC_BASE) + +#define to_qaic_bo(obj) container_of(obj, struct qaic_bo, base) + +extern bool poll_datapath; + +struct qaic_user { + /* Uniquely identifies this user for the device */ + int handle; + struct kref ref_count; + /* Char device opened by this user */ + struct qaic_drm_device *qddev; + /* Node in list of users that opened this drm device */ + struct list_headnode; + /* SRCU used to synchronize this user during cleanup */ + struct srcu_struct qddev_lock; + atomic_tchunk_id; +}; + +struct dma_bridge_chan { + /* Pointer to device strcut maintained by driver */ + struct qaic_device *qdev; + /* ID of this DMA bridge channel(DBC) */ + unsigned intid; + /* Synchronizes access to xfer_list */ + spinlock_t xfer_lock; + /* Base address of request queue */ + void*req_q_base; + /* Base address of response queue */ + void*rsp_q_base; + /* +* Base bus address of request queue. Response queue bus address can be +* calculated by adding request queue size to this variable +*/ + dma_addr_t dma_addr; + /* Total size of request and response queue in byte */ + u32 total_size; + /* Capacity of request/response queue */ + u32 nelem; + /* The user that opened this DBC */ + struct qaic_user*usr; + /* +* Request ID of next memory handle that goes in request queue. One +* memory handle can enqueue more than one request elements, all +* this requests that belong to same memory handle have same request ID +*/ + u16 next_req_id; + /* TRUE: DBC is in use; FALSE: DBC not in use */ + boolin_use; + /* +* Base address of device registers. Used to read/write request and +* response queue's head and tail pointer of this DBC. +*/ + void __iomem*dbc_base; + /* Head of list where each node is a memory handle queued in request queue */ + struct list_headxfer_list; + /* Synchronizes DBC readers during cleanup */ + struct srcu_struct ch_lock; + /* +* When this DBC is released, any thread waiting on this wait queue is +* woken up +*/ + wait_queue_head_t dbc_release; + /* Head of list where each node is a bo associated with this DBC */ + struct list_headbo_lists; + /* The irq line for this DBC. Used for polling */ + unsigned intirq; + /* Polling work item to simulate interrupts */ + struct work_struct poll_work; +}; + +struct qaic_device { + /* Pointer to base PCI device struct of our physical device */ + struct pci_dev *pdev; + /* Mask of all bars of this device */ + int bars; + /* Req. ID of request that will be queued next in MHI control device */ + u32 next_seq_num; + /* Base address of bar 0 */ + void __iomem*bar_0; + /* Base address of bar 2 */ + void __iomem*bar_2; + /* Controller structure for MHI devices */ + struct mhi_controller *mhi_cntl; + /* MHI control channel device */ +
[PATCH v2 1/8] accel/qaic: Add documentation for AIC100 accelerator driver
The Qualcomm Cloud AI 100 (AIC100) device is an Artificial Intelligence accelerator PCIe card. It contains a number of components both in the SoC and on the card which facilitate running workloads: QSM: management processor NSPs: workload compute units DMA Bridge: dedicated data mover for the workloads MHI: multiplexed communication channels DDR: workload storage and memory The Linux kernel driver for AIC100 is called "QAIC" and is located in the accel subsystem. Signed-off-by: Jeffrey Hugo Reviewed-by: Carl Vanderlip --- Documentation/accel/index.rst | 1 + Documentation/accel/qaic/aic100.rst | 498 Documentation/accel/qaic/index.rst | 13 + Documentation/accel/qaic/qaic.rst | 169 4 files changed, 681 insertions(+) create mode 100644 Documentation/accel/qaic/aic100.rst create mode 100644 Documentation/accel/qaic/index.rst create mode 100644 Documentation/accel/qaic/qaic.rst diff --git a/Documentation/accel/index.rst b/Documentation/accel/index.rst index 2b43c9a..e94a016 100644 --- a/Documentation/accel/index.rst +++ b/Documentation/accel/index.rst @@ -8,6 +8,7 @@ Compute Accelerators :maxdepth: 1 introduction + qaic/index .. only:: subproject and html diff --git a/Documentation/accel/qaic/aic100.rst b/Documentation/accel/qaic/aic100.rst new file mode 100644 index 000..773aa54 --- /dev/null +++ b/Documentation/accel/qaic/aic100.rst @@ -0,0 +1,498 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +=== + Qualcomm Cloud AI 100 (AIC100) +=== + +Overview + + +The Qualcomm Cloud AI 100/AIC100 family of products (including SA9000P - part of +Snapdragon Ride) are PCIe adapter cards which contain a dedicated SoC ASIC for +the purpose of efficiently running Artificial Intelligence (AI) Deep Learning +inference workloads. They are AI accelerators. + +The PCIe interface of AIC100 is capable of PCIe Gen4 speeds over eight lanes +(x8). An individual SoC on a card can have up to 16 NSPs for running workloads. +Each SoC has an A53 management CPU. On card, there can be up to 32 GB of DDR. + +Multiple AIC100 cards can be hosted in a single system to scale overall +performance. + +Hardware Description + + +An AIC100 card consists of an AIC100 SoC, on-card DDR, and a set of misc +peripherals (PMICs, etc). + +An AIC100 card can either be a PCIe HHHL form factor (a traditional PCIe card), +or a Dual M.2 card. Both use PCIe to connect to the host system. + +As a PCIe endpoint/adapter, AIC100 uses the standard VendorID(VID)/ +DeviceID(DID) combination to uniquely identify itself to the host. AIC100 +uses the standard Qualcomm VID (0x17cb). All AIC100 instances use the same +AIC100 DID (0xa100). + +AIC100 does not implement FLR (function level reset). + +AIC100 implements MSI but does not implement MSI-X. AIC100 requires 17 MSIs to +operate (1 for MHI, 16 for the DMA Bridge). + +As a PCIe device, AIC100 utilizes BARs to provide host interfaces to the device +hardware. AIC100 provides 3, 64-bit BARs. + +* The first BAR is 4K in size, and exposes the MHI interface to the host. + +* The second BAR is 2M in size, and exposes the DMA Bridge interface to the + host. + +* The third BAR is variable in size based on an individual AIC100's + configuration, but defaults to 64K. This BAR currently has no purpose. + +From the host perspective, AIC100 has several key hardware components- + +* QSM (QAIC Service Manager) +* NSPs (Neural Signal Processor) +* DMA Bridge +* DDR +* MHI (Modem Host Interface) + +QSM +--- + +QAIC Service Manager. This is an ARM A53 CPU that runs the primary +firmware of the card and performs on-card management tasks. It also +communicates with the host via MHI. Each AIC100 has one of +these. + +NSP +--- + +Neural Signal Processor. Each AIC100 has up to 16 of these. These are +the processors that run the workloads on AIC100. Each NSP is a Qualcomm Hexagon +(Q6) DSP with HVX and HMX. Each NSP can only run one workload at a time, but +multiple NSPs may be assigned to a single workload. Since each NSP can only run +one workload, AIC100 is limited to 16 concurrent workloads. Workload +"scheduling" is under the purview of the host. AIC100 does not automatically +timeslice. + +DMA Bridge +-- + +The DMA Bridge is custom DMA engine that manages the flow of data +in and out of workloads. AIC100 has one of these. The DMA Bridge has 16 +channels, each consisting of a set of request/response FIFOs. Each active +workload is assigned a single DMA Bridge channel. The DMA Bridge exposes +hardware registers to manage the FIFOs (head/tail pointers), but requires host +memory to store the FIFOs. + +DDR +--- + +AIC100 has on-card DDR. In total, an AIC100 can have up to 32 GB of DDR. +This DDR is used to store workloads, data for the workloads, and is used by the +QSM for managing the device. NSPs are granted access to
[PATCH v2 3/8] accel/qaic: Add MHI controller
An AIC100 device contains a MHI interface with a number of different channels for controlling different aspects of the device. The MHI controller works with the MHI bus to enable and drive that interface. AIC100 uses the BHI protocol in PBL to load SBL. The MHI controller expects the sbl to be located at /lib/firmware/qcom/aic100/sbl.bin and expects the MHI bus to manage the process of loading and sending SBL to the device. Signed-off-by: Jeffrey Hugo Reviewed-by: Carl Vanderlip --- drivers/accel/qaic/mhi_controller.c | 576 drivers/accel/qaic/mhi_controller.h | 19 ++ 2 files changed, 595 insertions(+) create mode 100644 drivers/accel/qaic/mhi_controller.c create mode 100644 drivers/accel/qaic/mhi_controller.h diff --git a/drivers/accel/qaic/mhi_controller.c b/drivers/accel/qaic/mhi_controller.c new file mode 100644 index 000..984428c --- /dev/null +++ b/drivers/accel/qaic/mhi_controller.c @@ -0,0 +1,576 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */ +/* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ + +#include +#include +#include +#include +#include +#include +#include + +#include "mhi_controller.h" +#include "qaic.h" + +#define MAX_RESET_TIME_SEC 25 + +static unsigned int mhi_timeout = 2000; /* 2 sec default */ +module_param(mhi_timeout, uint, 0600); + +static struct mhi_channel_config aic100_channels[] = { + { + .name = "QAIC_LOOPBACK", + .num = 0, + .num_elements = 32, + .local_elements = 0, + .event_ring = 0, + .dir = DMA_TO_DEVICE, + .ee_mask = MHI_CH_EE_AMSS, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = false, + .wake_capable = false, + }, + { + .name = "QAIC_LOOPBACK", + .num = 1, + .num_elements = 32, + .local_elements = 0, + .event_ring = 0, + .dir = DMA_FROM_DEVICE, + .ee_mask = MHI_CH_EE_AMSS, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = false, + .wake_capable = false, + }, + { + .name = "QAIC_SAHARA", + .num = 2, + .num_elements = 32, + .local_elements = 0, + .event_ring = 0, + .dir = DMA_TO_DEVICE, + .ee_mask = MHI_CH_EE_SBL, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = false, + .wake_capable = false, + }, + { + .name = "QAIC_SAHARA", + .num = 3, + .num_elements = 32, + .local_elements = 0, + .event_ring = 0, + .dir = DMA_FROM_DEVICE, + .ee_mask = MHI_CH_EE_SBL, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = false, + .wake_capable = false, + }, + { + .name = "QAIC_DIAG", + .num = 4, + .num_elements = 32, + .local_elements = 0, + .event_ring = 0, + .dir = DMA_TO_DEVICE, + .ee_mask = MHI_CH_EE_AMSS, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = false, + .wake_capable = false, + }, + { + .name = "QAIC_DIAG", + .num = 5, + .num_elements = 32, + .local_elements = 0, + .event_ring = 0, + .dir = DMA_FROM_DEVICE, + .ee_mask = MHI_CH_EE_AMSS, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = false, + .wake_capable = false, + }, + { + .name = "QAIC_SSR", + .num = 6, + .num_elements = 32, + .local_elements = 0, +
[PATCH v2 7/8] arm64: dts: qcom: sm8350: add GPU, GMU, GPU CC and SMMU nodes
Add device nodes required to enable GPU on the SM8350 platform. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sm8350.dtsi | 178 +++ 1 file changed, 178 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index e5b308957f88..c0992cf54d3a 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -1767,6 +1768,183 @@ tcsr_mutex: hwlock@1f4 { #hwlock-cells = <1>; }; + gpu: gpu@3d0 { + compatible = "qcom,adreno-660.1", "qcom,adreno"; + + reg = <0 0x03d0 0 0x4>, + <0 0x03d9e000 0 0x1000>, + <0 0x03d61000 0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; + + interrupts = ; + + iommus = <_smmu 0 0x400>, <_smmu 1 0x400>; + + operating-points-v2 = <_opp_table>; + + qcom,gmu = <>; + + status = "disabled"; + + zap-shader { + memory-region = <_gpu_mem>; + }; + + /* note: downstream checks gpu binning for 670 Mhz */ + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-84000 { + opp-hz = /bits/ 64 <84000>; + opp-level = ; + }; + + opp-77800 { + opp-hz = /bits/ 64 <77800>; + opp-level = ; + }; + + opp-73800 { + opp-hz = /bits/ 64 <73800>; + opp-level = ; + }; + + opp-67600 { + opp-hz = /bits/ 64 <67600>; + opp-level = ; + }; + + opp-60800 { + opp-hz = /bits/ 64 <60800>; + opp-level = ; + }; + + opp-54000 { + opp-hz = /bits/ 64 <54000>; + opp-level = ; + }; + + opp-49100 { + opp-hz = /bits/ 64 <49100>; + opp-level = ; + }; + + opp-44300 { + opp-hz = /bits/ 64 <44300>; + opp-level = ; + }; + + opp-37900 { + opp-hz = /bits/ 64 <37900>; + opp-level = ; + }; + + opp-31500 { + opp-hz = /bits/ 64 <31500>; + opp-level = ; + }; + }; + }; + + gmu: gmu@3d6a000 { + compatible = "qcom,adreno-gmu-660.1", "qcom,adreno-gmu"; + + reg = <0 0x03d6a000 0 0x34000>, + <0 0x03de 0 0x1>, + <0 0x0b29 0 0x1>; + reg-names = "gmu", "rscc", "gmu_pdc"; + + interrupts = , +; + interrupt-names = "hfi", "gmu"; + + clocks = < GPU_CC_CX_GMU_CLK>, +< GPU_CC_CXO_CLK>, +< GCC_DDRSS_GPU_AXI_CLK>, +< GCC_GPU_MEMNOC_GFX_CLK>, +< GPU_CC_AHB_CLK>, +< GPU_CC_HUB_CX_INT_CLK>, +< GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>; + clock-names = "gmu", + "cxo", + "axi", + "memnoc", + "ahb", + "hub", +
[PATCH v2 6/8] arm64: dts: qcom: sm8350: finish reordering nodes
Finish reordering DT nodes. Move PDC, tsens, AOSS, SRAM, SPMI and TLMM nodes to the proper position. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sm8350.dtsi | 764 +-- 1 file changed, 382 insertions(+), 382 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index c327dc925793..e5b308957f88 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -1884,276 +1884,6 @@ compute-cb@3 { }; }; - pdc: interrupt-controller@b22 { - compatible = "qcom,sm8350-pdc", "qcom,pdc"; - reg = <0 0x0b22 0 0x3>, <0 0x17c000f0 0 0x60>; - qcom,pdc-ranges = <0 480 40>, <40 140 14>, <54 263 1>, <55 306 4>, - <59 312 3>, <62 374 2>, <64 434 2>, <66 438 3>, - <69 86 1>, <70 520 54>, <124 609 31>, <155 63 1>, - <156 716 12>; - #interrupt-cells = <2>; - interrupt-parent = <>; - interrupt-controller; - }; - - tsens0: thermal-sensor@c263000 { - compatible = "qcom,sm8350-tsens", "qcom,tsens-v2"; - reg = <0 0x0c263000 0 0x1ff>, /* TM */ - <0 0x0c222000 0 0x8>; /* SROT */ - #qcom,sensors = <15>; - interrupts-extended = < 26 IRQ_TYPE_LEVEL_HIGH>, -< 28 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "uplow", "critical"; - #thermal-sensor-cells = <1>; - }; - - tsens1: thermal-sensor@c265000 { - compatible = "qcom,sm8350-tsens", "qcom,tsens-v2"; - reg = <0 0x0c265000 0 0x1ff>, /* TM */ - <0 0x0c223000 0 0x8>; /* SROT */ - #qcom,sensors = <14>; - interrupts-extended = < 27 IRQ_TYPE_LEVEL_HIGH>, -< 29 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "uplow", "critical"; - #thermal-sensor-cells = <1>; - }; - - aoss_qmp: power-management@c30 { - compatible = "qcom,sm8350-aoss-qmp", "qcom,aoss-qmp"; - reg = <0 0x0c30 0 0x400>; - interrupts-extended = < IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_GLINK_QMP -IRQ_TYPE_EDGE_RISING>; - mboxes = < IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_GLINK_QMP>; - - #clock-cells = <0>; - }; - - sram@c3f { - compatible = "qcom,rpmh-stats"; - reg = <0 0x0c3f 0 0x400>; - }; - - spmi_bus: spmi@c44 { - compatible = "qcom,spmi-pmic-arb"; - reg = <0x0 0x0c44 0x0 0x1100>, - <0x0 0x0c60 0x0 0x200>, - <0x0 0x0e60 0x0 0x10>, - <0x0 0x0e70 0x0 0xa>, - <0x0 0x0c40a000 0x0 0x26000>; - reg-names = "core", "chnls", "obsrvr", "intr", "cnfg"; - interrupt-names = "periph_irq"; - interrupts-extended = < 1 IRQ_TYPE_LEVEL_HIGH>; - qcom,ee = <0>; - qcom,channel = <0>; - #address-cells = <2>; - #size-cells = <0>; - interrupt-controller; - #interrupt-cells = <4>; - }; - - tlmm: pinctrl@f10 { - compatible = "qcom,sm8350-tlmm"; - reg = <0 0x0f10 0 0x30>; - interrupts = ; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - gpio-ranges = < 0 0 204>; - wakeup-parent = <>; - - sdc2_default_state: sdc2-default-state { - clk-pins { - pins = "sdc2_clk"; - drive-strength = <16>; - bias-disable; - }; - - cmd-pins { - pins = "sdc2_cmd"; - drive-strength = <16>; - bias-pull-up; -
[PATCH v2 5/8] arm64: dts: qcom: sm8350: move more nodes to correct place
Continue ordering DT nodes. Move RNG, UFS, system NoC and SLPI nodes to the proper position. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sm8350.dtsi | 314 +-- 1 file changed, 157 insertions(+), 157 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index 061aa3fec1c4..c327dc925793 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -1423,6 +1423,13 @@ spi13: spi@a94000 { }; }; + rng: rng@10d3000 { + compatible = "qcom,prng-ee"; + reg = <0 0x010d3000 0 0x1000>; + clocks = < RPMH_HWKM_CLK>; + clock-names = "core"; + }; + config_noc: interconnect@150 { compatible = "qcom,sm8350-config-noc"; reg = <0 0x0150 0 0xa580>; @@ -1643,18 +1650,76 @@ pcie1_phy: phy@1c0f000 { status = "disabled"; }; - lpass_ag_noc: interconnect@3c4 { - compatible = "qcom,sm8350-lpass-ag-noc"; - reg = <0 0x03c4 0 0xf080>; - #interconnect-cells = <2>; - qcom,bcm-voters = <_bcm_voter>; + ufs_mem_hc: ufshc@1d84000 { + compatible = "qcom,sm8350-ufshc", "qcom,ufshc", +"jedec,ufs-2.0"; + reg = <0 0x01d84000 0 0x3000>; + interrupts = ; + phys = <_mem_phy_lanes>; + phy-names = "ufsphy"; + lanes-per-direction = <2>; + #reset-cells = <1>; + resets = < GCC_UFS_PHY_BCR>; + reset-names = "rst"; + + power-domains = < UFS_PHY_GDSC>; + + iommus = <_smmu 0xe0 0x0>; + + clock-names = + "core_clk", + "bus_aggr_clk", + "iface_clk", + "core_clk_unipro", + "ref_clk", + "tx_lane0_sync_clk", + "rx_lane0_sync_clk", + "rx_lane1_sync_clk"; + clocks = + < GCC_UFS_PHY_AXI_CLK>, + < GCC_AGGRE_UFS_PHY_AXI_CLK>, + < GCC_UFS_PHY_AHB_CLK>, + < GCC_UFS_PHY_UNIPRO_CORE_CLK>, + < RPMH_CXO_CLK>, + < GCC_UFS_PHY_TX_SYMBOL_0_CLK>, + < GCC_UFS_PHY_RX_SYMBOL_0_CLK>, + < GCC_UFS_PHY_RX_SYMBOL_1_CLK>; + freq-table-hz = + <7500 3>, + <0 0>, + <0 0>, + <7500 3>, + <0 0>, + <0 0>, + <0 0>, + <0 0>; + status = "disabled"; }; - compute_noc: interconnect@a0c { - compatible = "qcom,sm8350-compute-noc"; - reg = <0 0x0a0c 0 0xa180>; - #interconnect-cells = <2>; - qcom,bcm-voters = <_bcm_voter>; + ufs_mem_phy: phy@1d87000 { + compatible = "qcom,sm8350-qmp-ufs-phy"; + reg = <0 0x01d87000 0 0x1c4>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + clock-names = "ref", + "ref_aux"; + clocks = < RPMH_CXO_CLK>, +< GCC_UFS_PHY_PHY_AUX_CLK>; + + resets = <_mem_hc 0>; + reset-names = "ufsphy"; + status = "disabled"; + + ufs_mem_phy_lanes: phy@1d87400 { + reg = <0 0x01d87400 0 0x188>, + <0 0x01d87600 0 0x200>, + <0 0x01d87c00 0 0x200>, + <0 0x01d87800 0 0x188>, + <0 0x01d87a00 0 0x200>; + #clock-cells = <1>; + #phy-cells = <0>; + }; }; ipa: ipa@1e4 { @@ -1702,6 +1767,13 @@ tcsr_mutex: hwlock@1f4 { #hwlock-cells =
[PATCH v2 8/8] arm64: dts: qcom: sm8350-hdk: enable GPU
Enable the GPU on the SM8350-HDK device. The ZAP shader is required for the GPU to function properly. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sm8350-hdk.dts | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts index df841230d1b7..5e744423a673 100644 --- a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts +++ b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts @@ -284,6 +284,14 @@ _dma1 { status = "okay"; }; + { + status = "okay"; + + zap-shader { + firmware-name = "qcom/sm8350/a660_zap.mbn"; + }; +}; + { clock-frequency = <40>; status = "okay"; -- 2.39.1
[PATCH v2 4/8] arm64: dts: qcom: sm8350: reorder device nodes
Start ordering DT nodes according to agreed order. Move apps SMMU, GIC, timer, apps RSC, cpufreq ADSP and cDSP nodes to the end to the proper position at the end of /soc/. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sm8350.dtsi | 1228 +- 1 file changed, 614 insertions(+), 614 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index 0de42a333d32..061aa3fec1c4 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -1423,111 +1423,6 @@ spi13: spi@a94000 { }; }; - apps_smmu: iommu@1500 { - compatible = "qcom,sm8350-smmu-500", "arm,mmu-500"; - reg = <0 0x1500 0 0x10>; - #iommu-cells = <2>; - #global-interrupts = <2>; - interrupts =, - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , -
[PATCH v2 3/8] dt-bindings: display/msm/gmu: add Adreno 660 support
Add Adreno A660 to the A635 clause to define all version-specific properties. There is no need to add it to the top-level clause, since top-level compatible uses pattern to define compatible strings. Signed-off-by: Dmitry Baryshkov --- Documentation/devicetree/bindings/display/msm/gmu.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/display/msm/gmu.yaml b/Documentation/devicetree/bindings/display/msm/gmu.yaml index ab14e81cb050..d5ce0dff4220 100644 --- a/Documentation/devicetree/bindings/display/msm/gmu.yaml +++ b/Documentation/devicetree/bindings/display/msm/gmu.yaml @@ -122,6 +122,7 @@ allOf: contains: enum: - qcom,adreno-gmu-635.0 + - qcom,adreno-gmu-660.1 then: properties: reg: -- 2.39.1
[PATCH v2 2/8] dt-bindings: power: qcom, rpmpd: add RPMH_REGULATOR_LEVEL_LOW_SVS_L1
Add define for another power saving state used on SM8350 for the GPU. Signed-off-by: Dmitry Baryshkov --- include/dt-bindings/power/qcom-rpmpd.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index 4a30d10e6b7d..1bf8e87ecd7e 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -211,6 +211,7 @@ #define RPMH_REGULATOR_LEVEL_MIN_SVS 48 #define RPMH_REGULATOR_LEVEL_LOW_SVS_D156 #define RPMH_REGULATOR_LEVEL_LOW_SVS 64 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_L180 #define RPMH_REGULATOR_LEVEL_SVS 128 #define RPMH_REGULATOR_LEVEL_SVS_L0144 #define RPMH_REGULATOR_LEVEL_SVS_L1192 -- 2.39.1
[PATCH v2 1/8] dt-bindings: clock: Merge qcom, gpucc-sm8350 into qcom, gpucc.yaml
The GPU clock controller bindings for the Qualcomm sm8350 platform are not correct. The driver uses .fw_name instead of using indices to bind parent clocks, thus demanding the clock-names usage. With the proper clock-names in place, the bindings becomes equal to the bindings defined by qcom,gpucc.yaml, so it is impractical to keep them in a separate file. Signed-off-by: Dmitry Baryshkov --- .../bindings/clock/qcom,gpucc-sm8350.yaml | 71 --- .../devicetree/bindings/clock/qcom,gpucc.yaml | 2 + 2 files changed, 2 insertions(+), 71 deletions(-) delete mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc-sm8350.yaml diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc-sm8350.yaml b/Documentation/devicetree/bindings/clock/qcom,gpucc-sm8350.yaml deleted file mode 100644 index fb7ae3d18503.. --- a/Documentation/devicetree/bindings/clock/qcom,gpucc-sm8350.yaml +++ /dev/null @@ -1,71 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 -$id: http://devicetree.org/schemas/clock/qcom,gpucc-sm8350.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Qualcomm Graphics Clock & Reset Controller on SM8350 - -maintainers: - - Robert Foss - -description: | - Qualcomm graphics clock control module provides the clocks, resets and power - domains on Qualcomm SoCs. - - See also:: include/dt-bindings/clock/qcom,gpucc-sm8350.h - -properties: - compatible: -enum: - - qcom,sm8350-gpucc - - clocks: -items: - - description: Board XO source - - description: GPLL0 main branch source - - description: GPLL0 div branch source - - '#clock-cells': -const: 1 - - '#reset-cells': -const: 1 - - '#power-domain-cells': -const: 1 - - reg: -maxItems: 1 - -required: - - compatible - - reg - - clocks - - '#clock-cells' - - '#reset-cells' - - '#power-domain-cells' - -additionalProperties: false - -examples: - - | -#include -#include - -soc { -#address-cells = <2>; -#size-cells = <2>; - -clock-controller@3d9 { -compatible = "qcom,sm8350-gpucc"; -reg = <0 0x03d9 0 0x9000>; -clocks = < RPMH_CXO_CLK>, - < GCC_GPU_GPLL0_CLK_SRC>, - < GCC_GPU_GPLL0_DIV_CLK_SRC>; -#clock-cells = <1>; -#reset-cells = <1>; -#power-domain-cells = <1>; -}; -}; -... diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml index 7256c438a4cf..db53eb288995 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml @@ -21,6 +21,7 @@ description: | include/dt-bindings/clock/qcom,gpucc-sm6350.h include/dt-bindings/clock/qcom,gpucc-sm8150.h include/dt-bindings/clock/qcom,gpucc-sm8250.h +include/dt-bindings/clock/qcom,gpucc-sm8350.h properties: compatible: @@ -33,6 +34,7 @@ properties: - qcom,sm6350-gpucc - qcom,sm8150-gpucc - qcom,sm8250-gpucc + - qcom,sm8350-gpucc clocks: items: -- 2.39.1
[PATCH v2 0/8] arm64: dts: qcom: sm8350: enable GPU on the HDK board
Add A660 device to the Qualcomm SM8350 platform and enable it for the sm8350-hdk board. Unfortunately while adding the GPU & related devices I noticed that DT nodes on SM8350 are greatly out of the preagreed order, so patches 4-6 reorder DT nodes to follow the agreement. Changes since v1: - Fixed the subject and commit message for patch 1 - Fixed GMU's clocks to follow the vendor kernel - Marked Adreno SMMU as dma-coherent - Dropped comments targeting sm8350 v1, we do not support that chip revision. Dmitry Baryshkov (8): dt-bindings: clock: Merge qcom,gpucc-sm8350 into qcom,gpucc.yaml dt-bindings: power: qcom,rpmpd: add RPMH_REGULATOR_LEVEL_LOW_SVS_L1 dt-bindings: display/msm/gmu: add Adreno 660 support arm64: dts: qcom: sm8350: reorder device nodes arm64: dts: qcom: sm8350: move more nodes to correct place arm64: dts: qcom: sm8350: finish reordering nodes arm64: dts: qcom: sm8350: add GPU, GMU, GPU CC and SMMU nodes arm64: dts: qcom: sm8350-hdk: enable GPU .../bindings/clock/qcom,gpucc-sm8350.yaml | 71 - .../devicetree/bindings/clock/qcom,gpucc.yaml |2 + .../devicetree/bindings/display/msm/gmu.yaml |1 + arch/arm64/boot/dts/qcom/sm8350-hdk.dts |8 + arch/arm64/boot/dts/qcom/sm8350.dtsi | 2512 + include/dt-bindings/power/qcom-rpmpd.h|1 + 6 files changed, 1357 insertions(+), 1238 deletions(-) delete mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc-sm8350.yaml -- 2.39.1
Re: [PATCH drm-next 00/14] [RFC] DRM GPUVA Manager & Nouveau VM_BIND UAPI
On Thu, Jan 19, 2023 at 7:24 AM Matthew Brost wrote: > > On Thu, Jan 19, 2023 at 05:04:32AM +0100, Danilo Krummrich wrote: > > On 1/18/23 20:48, Christian König wrote: > > > Am 18.01.23 um 20:17 schrieb Dave Airlie: > > > > On Thu, 19 Jan 2023 at 02:54, Alex Deucher > > > > wrote: > > > > > On Wed, Jan 18, 2023 at 11:50 AM Danilo Krummrich > > > > > wrote: > > > > > > > > > > > > > > > > > > On 1/18/23 17:30, Alex Deucher wrote: > > > > > > > On Wed, Jan 18, 2023 at 11:19 AM Danilo Krummrich > > > > > > > wrote: > > > > > > > > On 1/18/23 16:37, Christian König wrote: > > > > > > > > > Am 18.01.23 um 16:34 schrieb Danilo Krummrich: > > > > > > > > > > Hi Christian, > > > > > > > > > > > > > > > > > > > > On 1/18/23 09:53, Christian König wrote: > > > > > > > > > > > Am 18.01.23 um 07:12 schrieb Danilo Krummrich: > > > > > > > > > > > > This patch series provides a new UAPI for the Nouveau > > > > > > > > > > > > driver in > > > > > > > > > > > > order to > > > > > > > > > > > > support Vulkan features, such as > > > > > > > > > > > > sparse bindings and sparse > > > > > > > > > > > > residency. > > > > > > > > > > > > > > > > > > > > > > > > Furthermore, with the DRM GPUVA > > > > > > > > > > > > manager it provides a new DRM core > > > > > > > > > > > > feature to > > > > > > > > > > > > keep track of GPU virtual address > > > > > > > > > > > > (VA) mappings in a more generic way. > > > > > > > > > > > > > > > > > > > > > > > > The DRM GPUVA manager is indented to help drivers > > > > > > > > > > > > implement > > > > > > > > > > > > userspace-manageable > > > > > > > > > > > > GPU VA spaces in reference to the Vulkan API. In order > > > > > > > > > > > > to achieve > > > > > > > > > > > > this goal it > > > > > > > > > > > > serves the following purposes in this context. > > > > > > > > > > > > > > > > > > > > > > > >1) Provide a dedicated range allocator to track > > > > > > > > > > > > GPU VA > > > > > > > > > > > > allocations and > > > > > > > > > > > > mappings, making use of the drm_mm range > > > > > > > > > > > > allocator. > > > > > > > > > > > This means that the ranges are allocated > > > > > > > > > > > by the kernel? If yes that's > > > > > > > > > > > a really really bad idea. > > > > > > > > > > No, it's just for keeping track of the > > > > > > > > > > ranges userspace has allocated. > > > > > > > > > Ok, that makes more sense. > > > > > > > > > > > > > > > > > > So basically you have an IOCTL which asks kernel > > > > > > > > > for a free range? Or > > > > > > > > > what exactly is the drm_mm used for here? > > > > > > > > Not even that, userspace provides both the base > > > > > > > > address and the range, > > > > > > > > the kernel really just keeps track of things. > > > > > > > > Though, writing a UAPI on > > > > > > > > top of the GPUVA manager asking for a free range instead would > > > > > > > > be > > > > > > > > possible by just adding the corresponding wrapper functions to > > > > > > > > get a > > > > > > > > free hole. > > > > > > > > > > > > > > > > Currently, and that's what I think I read out of > > > > > > > > your question, the main > > > > > > > > benefit of using drm_mm over simply stuffing the > > > > > > > > entries into a list or > > > > > > > > something boils down to easier collision detection and iterating > > > > > > > > sub-ranges of the whole VA space. > > > > > > > Why not just do this in userspace? We have a range manager in > > > > > > > libdrm_amdgpu that you could lift out into libdrm or some other > > > > > > > helper. > > > > > > The kernel still needs to keep track of the mappings within the > > > > > > various > > > > > > VA spaces, e.g. it silently needs to unmap mappings that are backed > > > > > > by > > > > > > BOs that get evicted and remap them once they're validated (or > > > > > > swapped > > > > > > back in). > > > > > Ok, you are just using this for maintaining the GPU VM space in > > > > > the kernel. > > > > > > > > > Yes the idea behind having common code wrapping drm_mm for this is to > > > > allow us to make the rules consistent across drivers. > > > > > > > > Userspace (generally Vulkan, some compute) has interfaces that pretty > > > > much dictate a lot of how VMA tracking works, esp around lifetimes, > > > > sparse mappings and splitting/merging underlying page tables, I'd > > > > really like this to be more consistent across drivers, because already > > > > I think we've seen with freedreno some divergence from amdgpu and we > > > > also have i915/xe to deal with. I'd like to at least have one place > > > > that we can say this is how it should work, since this is something > > > > that *should* be consistent across drivers mostly, as it is more about > > > > how the uapi is exposed. > > > > > > That's a really good idea, but the implementation with drm_mm won't work > > > like that. > > > > > > We have Vulkan applications which use the sparse feature to create > > > literally millions of
Re: [PATCH 2/2] drm/panel: simple: Add EDT ETML1010G0DKA panel
Hello, ping here, this one got forgotten. It still applies on drm-misc-next and v6.2-rc7 On 18.08.22 14:45, Dominik Haller wrote: > Add support for the EDT ETML1010G0DKA 10.1" 1280x800 LVDS panel. > > Signed-off-by: Dominik Haller > --- > drivers/gpu/drm/panel/panel-simple.c | 29 > 1 file changed, 29 insertions(+) > > diff --git a/drivers/gpu/drm/panel/panel-simple.c > b/drivers/gpu/drm/panel/panel-simple.c > index f9e1f85daef7..9314db24ab51 100644 > --- a/drivers/gpu/drm/panel/panel-simple.c > +++ b/drivers/gpu/drm/panel/panel-simple.c > @@ -1779,6 +1779,32 @@ static const struct panel_desc edt_etml0700y5dha = { > .connector_type = DRM_MODE_CONNECTOR_LVDS, > }; > > +static const struct drm_display_mode edt_etml1010g0dka_mode = { > + .clock = 7, > + .hdisplay = 1280, > + .hsync_start = 1280 + 100, > + .hsync_end = 1280 + 100 + 19, > + .htotal = 1280 + 100 + 19 + 41, > + .vdisplay = 800, > + .vsync_start = 800 + 4, > + .vsync_end = 800 + 4 + 4, > + .vtotal = 800 + 4 + 4 + 15, > + .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, > +}; > + > +static const struct panel_desc edt_etml1010g0dka = { > + .modes = _etml1010g0dka_mode, > + .num_modes = 1, > + .bpc = 8, > + .size = { > + .width = 216, > + .height = 135, > + }, > + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, > + .bus_flags = DRM_BUS_FLAG_DE_HIGH, > + .connector_type = DRM_MODE_CONNECTOR_LVDS, > +}; > + > static const struct drm_display_mode edt_etmv570g2dhu_mode = { > .clock = 25175, > .hdisplay = 640, > @@ -4057,6 +4083,9 @@ static const struct of_device_id platform_of_match[] = { > }, { > .compatible = "edt,etml0700y5dha", > .data = _etml0700y5dha, > + }, { > + .compatible = "edt,etml1010g0dka", > + .data = _etml1010g0dka, > }, { > .compatible = "edt,etmv570g2dhu", > .data = _etmv570g2dhu, -- PHYTEC Messtechnik GmbH | Barcelona-Allee 1 | 55129 Mainz, Germany Geschäftsführer: Dipl.-Ing. Michael Mitezki, Dipl.-Ing. Bodo Huber | Handelsregister Mainz HRB 4656 | Finanzamt Mainz-Mitte | St.Nr. 266500608, DE 149059855
Re: [PATCH drm-next 03/14] drm: manager to keep track of GPUs VA mappings
On 2/6/23 14:35, Christian König wrote: Am 03.02.23 um 18:37 schrieb Matthew Brost: On Wed, Jan 18, 2023 at 07:12:45AM +0100, Danilo Krummrich wrote: This adds the infrastructure for a manager implementation to keep track of GPU virtual address (VA) mappings. New UAPIs, motivated by Vulkan sparse memory bindings graphics drivers start implementing, allow userspace applications to request multiple and arbitrary GPU VA mappings of buffer objects. The DRM GPU VA manager is intended to serve the following purposes in this context. 1) Provide a dedicated range allocator to track GPU VA allocations and mappings, making use of the drm_mm range allocator. 2) Generically connect GPU VA mappings to their backing buffers, in particular DRM GEM objects. 3) Provide a common implementation to perform more complex mapping operations on the GPU VA space. In particular splitting and merging of GPU VA mappings, e.g. for intersecting mapping requests or partial unmap requests. Over the past week I've hacked together a PoC port of Xe to GPUVA [1], so far it seems really promising. 95% of the way to being feature equivalent of the current Xe VM bind implementation and have line of sight to getting sparse bindings implemented on top of GPUVA too. IMO this has basically everything we need for Xe with a few tweaks. I am out until 2/14 but wanted to get my thoughts / suggestions out on the list before I leave. 1. GPUVA post didn't support the way Xe does userptrs - a NULL GEM. I believe with [2], [3], and [4] GPUVA will support NULL GEMs. Also my thinking sparse binds will also have NULL GEMs, more on sparse bindings below. 2. I agree with Christian that drm_mm probably isn't what we want to base the GPUVA implementation on, rather a RB tree or Maple tree has been discussed. The implementation should be fairly easy to tune once we have benchmarks running so not to concerned here as we can figure this out down the line. 3. In Xe we want create xe_vm_op list which inherits from drm_gpuva_op I've done this with a hack [5], I believe when we rebase we can do this with a custom callback to allocate a large op size. 4. I'd like add user bits to drm_gpuva_flags like I do in [6]. This is similar to DMA_FENCE_FLAG_USER_BITS. 5. In Xe we have VM prefetch operation which is needed for our compute UMD with page faults. I'd like add prefetch type of operation like we do in [7]. 6. In Xe we have VM unbind all mappings for a GEM IOCTL, I'd like to add support to generate this operation list to GPUVA like we do in [8]. 7. I've thought about how Xe will implement sparse mappings (read 0, writes dropped). My current thinking is a sparse mapping will be represented as a drm_gpuva rather than region like in Nouveau. Making regions optional to me seems likes good idea rather than forcing the user of GPUVA code to create 1 large region for the manager as I currently do in the Xe PoC. From Danilo's explanation I'm now pretty sure that regions won't work for Nouveau either. He seems to use an incorrect assumption about applications not changing the sparse mappings behind a VkBuffer while the GPU is using it. As far as I can see games like Forza won't work with this approach. I appreciate sharing your concerns since they're seriously helping me to improve things and consider things I missed before. However, I'd prefer to wait for clarification before distributing them to other sub-threads. Depending on whether the understanding of where those concerns arise from turns out to be right or wrong, this might cause confusion for people not following *all* sub-threads. 8. Personally I'd like the caller to own the locking for GEM drm_gpuva list (drm_gpuva_link_*, drm_gpuva_unlink_* functions). In Xe we almost certainly will have the GEM dma-resv lock when we touch this list so an extra lock here is redundant. Also it kinda goofy that caller owns the for drm_gpuva insertion / removal but not the locking for this list. WRT to Christian thoughts on a common uAPI rules for VM binds, I kinda like that idea but I don't think that is necessary. All of pur uAPI should be close but also the GPUVA implementation should be flexible enough to fit all of our needs and I think for the most part it is. Maybe I should refine my concerns: A common component for GPUVM mappings is a good idea, but we should not expect that to define any driver independent UAPI. If we want to define driver independent UAPI we should do so explicitly. Christian. Let me know what everything thinks about this. It would be great if when I'm back on 2/14 I can rebase the Xe port to GPUVA on another version of the GPUVA code and get sparse binding support implementation. Also I'd like to get GPUVA merged in the Xe repo ASAP as our VM bind code badly needed to be cleaned and this was the push we needed to make this happen. Matt [1] https://gitlab.freedesktop.org/drm/xe/kernel/-/merge_requests/314 [2]
Re: [Nouveau] [PATCH drm-next 05/14] drm/nouveau: new VM_BIND uapi interfaces
On 2/6/23 10:48, Christian König wrote: Am 02.02.23 um 19:31 schrieb Danilo Krummrich: On 2/2/23 12:53, Christian König wrote: Am 01.02.23 um 09:10 schrieb Dave Airlie: [SNIP] For drivers that don't intend to merge at all and (somehow) are capable of dealing with sparse regions without knowing the sparse region's boundaries, it'd be easy to make those gpuva_regions optional. Yeah, but this then defeats the approach of having the same hw independent interface/implementation for all drivers. I think you are running a few steps ahead here. The plan isn't to have an independent interface, it's to provide a set of routines and tracking that will be consistent across drivers, so that all drivers once using them will operate in mostly the same fashion with respect to GPU VA tracking and VA/BO lifetimes. Already in the tree we have amdgpu and freedreno which I think end up operating slightly different around lifetimes. I'd like to save future driver writers the effort of dealing with those decisions and this should drive their user api design so to enable vulkan sparse bindings. Ok in this case I'm pretty sure this is *NOT* a good idea. See this means that we define the UAPI implicitly by saying to drivers to use a common framework for their VM implementation which then results in behavior A,B,C,D If a driver strides away from this common framework because it has different requirements based on how his hw work you certainly get different behavior again (and you have tons of hw specific requirements in here). What we should do instead if we want to have some common handling among drivers (which I totally agree on makes sense) then we should define the UAPI explicitly. By asking that I don't want to say I'm against this idea, I'm just wondering how it becomes easier to deal with "tons of hw specific requirements" by generalizing things even more? I'm already maintaining two different GPU VM solutions in the GPU drivers in the kernel, radeon and amdgpu. The hw they driver is identical, just the UAPI is different. And only because of the different UAPI they can't have the same VM backend implementation. The hw stuff is completely abstract able. That's just stuff you need to consider when defining the structures you pass around. Wouldn't we need to have strict limitations on that, such that HW specific structures / fields are not allowed to break the semantics of the UAPI? Because otherwise we wouldn't be able to attach generalized components to the unified UAPI which ultimately would be the whole purpose. So, if this consideration is correct, I'd still see a risk of drivers striding away from it because of their requirements. Again, I think a unified UAPI is a good idea, but it sounds more difficult to me than this last paragraph implies. But a messed up UAPI is sometimes impossible to fix because of backward compatibility. We learned that the hard way with radeon and mostly fixed it by coming up with a completely new implementation for amdgpu. What makes us think that we do a better job in considering all hw specific requirements with a unified UAPI than with a more lightweight generic component for tracking VA mappings? Because this defines the UAPI implicitly and that's seldom a good idea. As I said before tracking is the easy part of the job. Defining this generic component helps a little bit writing new drivers, but it leaves way to much room for speculations on the UAPI. Trying to move forward, I agree that a unified UAPI would improve the situation regarding the problems you mentioned and the examples you have given. However, not having the GPUVA manager wouldn't give us a unified UAPI either. And as long as it delivers a generic component to solve a problem while not making the overall situation worse or preventing us from reaching this desirable goal of having a unified UAPI I tend to think it's fine to have such a component. Also, wouldn't we need something like the GPUVA manager as part of a unified UAPI? Not necessarily. We can write components to help drivers implement the UAPI, but this isn't mandatory. Well, yes, not necessarily. However, as mentioned above, wouldn't it be a major goal of a unified UAPI to be able to attach generic components to it? For example we could have a DRM_IOCTL_GPU_VM which takes both driver independent as well as driver dependent information and then has the documented behavior: a) VAs do (or don't) vanish automatically when the GEM handle is closed. b) GEM BOs do (or don't) get an additional reference for each VM they are used in. c) Can handle some common use cases driver independent (BO mappings, readonly, writeonly, sparse etc...). d) Has a well defined behavior when the operation is executed async. E.g. in/out fences. e) Can still handle hw specific stuff like (for example) trap on access etc ... Especially d is what Bas and I have pretty much already created a
Re: [PATCH v3 0/3] drm/rockchip: dw_hdmi: Add 4k@30 support
On Wed, Feb 01, 2023 at 09:23:56AM +0900, FUKAUMI Naoki wrote: > hi, > > I'm trying this patch series with 6.1.x kernel. it works fine on rk356x > based boards (ROCK 3), but it has a problem on rk3399 boards (ROCK 4). > > on rk3399 with this patch, I can see large noise area (about one third right > side of the screen) at 4k@30. 1080p works fine as same as before. > > can someone reproduce this problem on rk3399? Ok, I could easily reproduce the problem here. The RK3399 has two VOPs, vopb(ig) and vopl(ittle). Only the former can do 4k@30 while the latter can only do 1080p. Unfortunately vopl is used by default. We can force using vopb by disabling vopl in the device tree and get a good 4k@30 picture then. The other possibility I found is to use the other CRTC with modetest. I have no idea how we could set the default to vopb. I guess a first step would be to limit the maximum resolution of vopl to what the hardware can do. We would likely end up with 1080p by default then for the applications. Sascha -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
Re: [PATCH 7/8] arm64: dts: qcom: sm8350: add GPU, GMU, GPU CC and SMMU nodes
On 06/02/2023 12:51, Konrad Dybcio wrote: On 6.02.2023 01:27, Dmitry Baryshkov wrote: Add device nodes required to enable GPU on the SM8350 platform. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sm8350.dtsi | 179 +++ 1 file changed, 179 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index e5b308957f88..a73cd9eb63e0 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -1767,6 +1768,184 @@ tcsr_mutex: hwlock@1f4 { #hwlock-cells = <1>; }; + gpu: gpu@3d0 { + compatible = "qcom,adreno-660.1", +"qcom,adreno"; No need to wrap this line. + + reg = <0 0x03d0 0 0x4>, + <0 0x03d9e000 0 0x1000>, + <0 0x03d61000 0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; + + interrupts = ; + + iommus = <_smmu 0 0x400>, <_smmu 1 0x400>; + + operating-points-v2 = <_opp_table>; + + qcom,gmu = <>; + + status = "disabled"; + + zap-shader { + memory-region = <_gpu_mem>; + }; + + /* note: downstream checks gpu binning for 670 Mhz */ + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* not for v1 */ The shipping version is v2.1 and you defined the 660.1 chipid, which maps to lahaina(>=v2) Yes, let's drop these comments. + opp-84000 { + opp-hz = /bits/ 64 <84000>; + opp-level = ; + }; + + /* not for v1 */ + opp-77800 { + opp-hz = /bits/ 64 <77800>; + opp-level = ; + }; + + /* not for v1 */ + opp-73800 { + opp-hz = /bits/ 64 <73800>; + opp-level = ; + }; + + /* for v1 + opp-71000 { + opp-hz = /bits/ 64 <71000>; + opp-level = ; + }; + */ + + opp-67600 { + opp-hz = /bits/ 64 <67600>; + opp-level = ; + }; + + opp-60800 { + opp-hz = /bits/ 64 <60800>; + opp-level = ; + }; + + opp-54000 { + opp-hz = /bits/ 64 <54000>; + opp-level = ; + }; + + /* not for v1 */ + opp-49100 { + opp-hz = /bits/ 64 <49100>; + opp-level = ; + }; + + opp-44300 { + opp-hz = /bits/ 64 <44300>; + opp-level = ; + }; + + /* not for v1 */ + opp-37900 { + opp-hz = /bits/ 64 <37900>; + opp-level = ; + }; + + opp-31500 { + opp-hz = /bits/ 64 <31500>; + opp-level = ; + }; + }; + }; + + gmu: gmu@3d6a000 { + compatible = "qcom,adreno-gmu-660.1", "qcom,adreno-gmu"; + + reg = <0 0x03d6a000 0 0x34000>, + <0 0x03de 0 0x1>, + <0 0x0b29 0 0x1>; + reg-names = "gmu", "rscc", "gmu_pdc"; + +
Re: [PATCH v7 4/6] drm/tidss: Add support to configure OLDI mode for am625-dss
On 05/02/2023 15:42, Aradhya Bhatia wrote: Hi Tomi, On 03-Feb-23 20:42, Tomi Valkeinen wrote: On 25/01/2023 13:35, Aradhya Bhatia wrote: The newer version of DSS (AM625-DSS) has 2 OLDI TXes at its disposal. These can be configured to support the following modes: 1. OLDI_SINGLE_LINK_SINGLE_MODE Single Output over OLDI 0. +--+ +-+ +---+ | | | | | | | CRTC +--->+ ENCODER +->| PANEL | | | | | | | +--+ +-+ +---+ 2. OLDI_SINGLE_LINK_CLONE_MODE Duplicate Output over OLDI 0 and 1. +--+ +-+ +---+ | | | | | | | CRTC +---+--->| ENCODER +->| PANEL | | | | | | | | +--+ | +-+ +---+ | | +-+ +---+ | | | | | +--->| ENCODER +->| PANEL | | | | | +-+ +---+ 3. OLDI_DUAL_LINK_MODE Combined Output over OLDI 0 and 1. +--+ +-+ +---+ | | | +->| | | CRTC +--->+ ENCODER | | PANEL | | | | +->| | +--+ +-+ +---+ Following the above pathways for different modes, 2 encoder/panel-bridge pipes get created for clone mode, and 1 pipe in cases of single link and dual link mode. Add support for confguring the OLDI modes using OF and LVDS DRM helper functions. Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/tidss/tidss_dispc.c | 24 ++- drivers/gpu/drm/tidss/tidss_dispc.h | 12 ++ drivers/gpu/drm/tidss/tidss_drv.h | 3 + drivers/gpu/drm/tidss/tidss_encoder.c | 4 +- drivers/gpu/drm/tidss/tidss_encoder.h | 3 +- drivers/gpu/drm/tidss/tidss_kms.c | 221 -- 6 files changed, 245 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c index b55ccbcaa67f..37a73e309330 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -88,6 +88,8 @@ const struct dispc_features dispc_k2g_feats = { .subrev = DISPC_K2G, + .has_oldi = false, + .common = "common", .common_regs = tidss_k2g_common_regs, @@ -166,6 +168,8 @@ const struct dispc_features dispc_am625_feats = { .subrev = DISPC_AM625, + .has_oldi = true, + .common = "common", .common_regs = tidss_am65x_common_regs, @@ -218,6 +222,8 @@ const struct dispc_features dispc_am65x_feats = { .subrev = DISPC_AM65X, + .has_oldi = true, + .common = "common", .common_regs = tidss_am65x_common_regs, @@ -309,6 +315,8 @@ const struct dispc_features dispc_j721e_feats = { .subrev = DISPC_J721E, + .has_oldi = false, + .common = "common_m", .common_regs = tidss_j721e_common_regs, @@ -361,6 +369,8 @@ struct dispc_device { struct dss_vp_data vp_data[TIDSS_MAX_VPS]; + enum dispc_oldi_modes oldi_mode; + u32 *fourccs; u32 num_fourccs; @@ -1963,6 +1973,12 @@ const u32 *dispc_plane_formats(struct dispc_device *dispc, unsigned int *len) return dispc->fourccs; } +void dispc_set_oldi_mode(struct dispc_device *dispc, + enum dispc_oldi_modes oldi_mode) +{ + dispc->oldi_mode = oldi_mode; +} + static s32 pixinc(int pixels, u8 ps) { if (pixels == 1) @@ -2647,7 +2663,7 @@ int dispc_runtime_resume(struct dispc_device *dispc) REG_GET(dispc, DSS_SYSSTATUS, 2, 2), REG_GET(dispc, DSS_SYSSTATUS, 3, 3)); - if (dispc->feat->subrev == DISPC_AM65X) + if (dispc->feat->has_oldi) dev_dbg(dispc->dev, "OLDI RESETDONE %d,%d,%d\n", REG_GET(dispc, DSS_SYSSTATUS, 5, 5), REG_GET(dispc, DSS_SYSSTATUS, 6, 6), @@ -2688,7 +2704,7 @@ static int dispc_iomap_resource(struct platform_device *pdev, const char *name, return 0; } -static int dispc_init_am65x_oldi_io_ctrl(struct device *dev, +static int dispc_init_am6xx_oldi_io_ctrl(struct device *dev, struct dispc_device *dispc) { dispc->oldi_io_ctrl = @@ -2827,8 +2843,8 @@ int dispc_init(struct tidss_device *tidss) dispc->vp_data[i].gamma_table = gamma_table; } - if (feat->subrev == DISPC_AM65X) { - r = dispc_init_am65x_oldi_io_ctrl(dev, dispc); + if (feat->has_oldi) { + r = dispc_init_am6xx_oldi_io_ctrl(dev, dispc); if (r) return r; } diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/tidss_dispc.h index 971f2856f015..880bc7de68b3 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.h +++ b/drivers/gpu/drm/tidss/tidss_dispc.h @@ -64,6 +64,15 @@ enum dispc_dss_subrevision { DISPC_J721E, }; +enum
Re: [PATCH drm-next 03/14] drm: manager to keep track of GPUs VA mappings
Am 03.02.23 um 18:37 schrieb Matthew Brost: On Wed, Jan 18, 2023 at 07:12:45AM +0100, Danilo Krummrich wrote: This adds the infrastructure for a manager implementation to keep track of GPU virtual address (VA) mappings. New UAPIs, motivated by Vulkan sparse memory bindings graphics drivers start implementing, allow userspace applications to request multiple and arbitrary GPU VA mappings of buffer objects. The DRM GPU VA manager is intended to serve the following purposes in this context. 1) Provide a dedicated range allocator to track GPU VA allocations and mappings, making use of the drm_mm range allocator. 2) Generically connect GPU VA mappings to their backing buffers, in particular DRM GEM objects. 3) Provide a common implementation to perform more complex mapping operations on the GPU VA space. In particular splitting and merging of GPU VA mappings, e.g. for intersecting mapping requests or partial unmap requests. Over the past week I've hacked together a PoC port of Xe to GPUVA [1], so far it seems really promising. 95% of the way to being feature equivalent of the current Xe VM bind implementation and have line of sight to getting sparse bindings implemented on top of GPUVA too. IMO this has basically everything we need for Xe with a few tweaks. I am out until 2/14 but wanted to get my thoughts / suggestions out on the list before I leave. 1. GPUVA post didn't support the way Xe does userptrs - a NULL GEM. I believe with [2], [3], and [4] GPUVA will support NULL GEMs. Also my thinking sparse binds will also have NULL GEMs, more on sparse bindings below. 2. I agree with Christian that drm_mm probably isn't what we want to base the GPUVA implementation on, rather a RB tree or Maple tree has been discussed. The implementation should be fairly easy to tune once we have benchmarks running so not to concerned here as we can figure this out down the line. 3. In Xe we want create xe_vm_op list which inherits from drm_gpuva_op I've done this with a hack [5], I believe when we rebase we can do this with a custom callback to allocate a large op size. 4. I'd like add user bits to drm_gpuva_flags like I do in [6]. This is similar to DMA_FENCE_FLAG_USER_BITS. 5. In Xe we have VM prefetch operation which is needed for our compute UMD with page faults. I'd like add prefetch type of operation like we do in [7]. 6. In Xe we have VM unbind all mappings for a GEM IOCTL, I'd like to add support to generate this operation list to GPUVA like we do in [8]. 7. I've thought about how Xe will implement sparse mappings (read 0, writes dropped). My current thinking is a sparse mapping will be represented as a drm_gpuva rather than region like in Nouveau. Making regions optional to me seems likes good idea rather than forcing the user of GPUVA code to create 1 large region for the manager as I currently do in the Xe PoC. From Danilo's explanation I'm now pretty sure that regions won't work for Nouveau either. He seems to use an incorrect assumption about applications not changing the sparse mappings behind a VkBuffer while the GPU is using it. As far as I can see games like Forza won't work with this approach. 8. Personally I'd like the caller to own the locking for GEM drm_gpuva list (drm_gpuva_link_*, drm_gpuva_unlink_* functions). In Xe we almost certainly will have the GEM dma-resv lock when we touch this list so an extra lock here is redundant. Also it kinda goofy that caller owns the for drm_gpuva insertion / removal but not the locking for this list. WRT to Christian thoughts on a common uAPI rules for VM binds, I kinda like that idea but I don't think that is necessary. All of pur uAPI should be close but also the GPUVA implementation should be flexible enough to fit all of our needs and I think for the most part it is. Maybe I should refine my concerns: A common component for GPUVM mappings is a good idea, but we should not expect that to define any driver independent UAPI. If we want to define driver independent UAPI we should do so explicitly. Christian. Let me know what everything thinks about this. It would be great if when I'm back on 2/14 I can rebase the Xe port to GPUVA on another version of the GPUVA code and get sparse binding support implementation. Also I'd like to get GPUVA merged in the Xe repo ASAP as our VM bind code badly needed to be cleaned and this was the push we needed to make this happen. Matt [1] https://gitlab.freedesktop.org/drm/xe/kernel/-/merge_requests/314 [2] https://gitlab.freedesktop.org/drm/xe/kernel/-/merge_requests/314/diffs?commit_id=2ae21d7a3f52e5eb2c105ed8ae231471274bdc36 [3] https://gitlab.freedesktop.org/drm/xe/kernel/-/merge_requests/314/diffs?commit_id=49fca9f5d96201f5cbd1b19c7ff17eedfac65cdc [4] https://gitlab.freedesktop.org/drm/xe/kernel/-/merge_requests/314/diffs?commit_id=61fa6b1e1f10e791ae82358fa971b04421d53024 [5]
Re: [PATCH 2/2] drm: fsl-dcu: enable PIXCLK on LS1021A
Hi, any feedback on this? Best regards Alexander Am Dienstag, 17. Januar 2023, 12:08:01 CET schrieb Alexander Stein: > From: Matthias Schiffer > > The PIXCLK needs to be enabled in SCFG before accessing certain DCU > registers, or the access will hang. > > Signed-off-by: Matthias Schiffer > Signed-off-by: Alexander Stein > --- > drivers/gpu/drm/fsl-dcu/Kconfig | 1 + > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 14 ++ > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h | 3 +++ > 3 files changed, 18 insertions(+) > > diff --git a/drivers/gpu/drm/fsl-dcu/Kconfig > b/drivers/gpu/drm/fsl-dcu/Kconfig index 5ca71ef87325..c9ee98693b48 100644 > --- a/drivers/gpu/drm/fsl-dcu/Kconfig > +++ b/drivers/gpu/drm/fsl-dcu/Kconfig > @@ -8,6 +8,7 @@ config DRM_FSL_DCU > select DRM_PANEL > select REGMAP_MMIO > select VIDEOMODE_HELPERS > + select MFD_SYSCON if SOC_LS1021A > help > Choose this option if you have an Freescale DCU chipset. > If M is selected the module will be called fsl-dcu-drm. > diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c > b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index > 418887654bac..314cb8af89ee 100644 > --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c > +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c > @@ -100,12 +100,26 @@ static void fsl_dcu_irq_uninstall(struct drm_device > *dev) static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) > { > struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; > + struct regmap *scfg; > int ret; > > ret = fsl_dcu_drm_modeset_init(fsl_dev); > if (ret < 0) > return dev_err_probe(dev->dev, ret, "failed to initialize mode > setting\n"); > > + scfg = syscon_regmap_lookup_by_compatible("fsl,ls1021a-scfg"); > + if (PTR_ERR(scfg) != -ENODEV) { > + /* > + * For simplicity, enable the PIXCLK unconditionally. Disabling > + * the clock in PM or on unload could be implemented as a future > + * improvement. > + */ > + ret = regmap_update_bits(scfg, SCFG_PIXCLKCR, SCFG_PIXCLKCR_PXCEN, > + SCFG_PIXCLKCR_PXCEN); > + if (ret < 0) > + return dev_err_probe(dev->dev, ret, "failed to enable pixclk\n"); > + } > + > ret = drm_vblank_init(dev, dev->mode_config.num_crtc); > if (ret < 0) { > dev_err(dev->dev, "failed to initialize vblank\n"); > diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h > b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h index > e2049a0e8a92..566396013c04 100644 > --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h > +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h > @@ -160,6 +160,9 @@ > #define FSL_DCU_ARGB 12 > #define FSL_DCU_YUV422 14 > > +#define SCFG_PIXCLKCR0x28 > +#define SCFG_PIXCLKCR_PXCEN BIT(31) > + > #define VF610_LAYER_REG_NUM 9 > #define LS1021A_LAYER_REG_NUM10
Re: [PATCH v7 1/6] drm/tidss: Remove Video Port to Output Port coupling
On 05/02/2023 15:08, Aradhya Bhatia wrote: Hi Tomi, Thanks for the review! On 03-Feb-23 16:53, Tomi Valkeinen wrote: On 25/01/2023 13:35, Aradhya Bhatia wrote: Make DSS Video Ports agnostic of output bus types. DSS controllers have had a 1-to-1 coupling between its VPs and its output ports. This no longer stands true for the new AM625 DSS. This coupling, hence, has been removed by renaming the 'vp_bus_type' to 'output_port_bus_type' because the VPs are essentially agnostic of the bus type and it is the output ports which have a bus type. The AM625 DSS has 2 VPs but requires 3 output ports to support its Dual-Link OLDI video output coming from a single VP. Not a biggie, but this sentence is a bit odd here at the end. Shouldn't it be after the "...stands true for the new AM625 DSS."? Yes! It should be. Will make the edit. Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/tidss/tidss_dispc.c | 47 + drivers/gpu/drm/tidss/tidss_dispc.h | 21 +++-- drivers/gpu/drm/tidss/tidss_drv.h | 5 +-- drivers/gpu/drm/tidss/tidss_irq.h | 2 +- drivers/gpu/drm/tidss/tidss_kms.c | 12 5 files changed, 48 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c index 165365b515e1..c1c4faccbddc 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -61,7 +61,7 @@ const struct dispc_features dispc_k2g_feats = { .min_pclk_khz = 4375, .max_pclk_khz = { - [DISPC_VP_DPI] = 15, + [DISPC_PORT_DPI] = 15, }, /* @@ -96,7 +96,6 @@ const struct dispc_features dispc_k2g_feats = { .vp_name = { "vp1" }, .ovr_name = { "ovr1" }, .vpclk_name = { "vp1" }, - .vp_bus_type = { DISPC_VP_DPI }, .vp_feat = { .color = { .has_ctm = true, @@ -109,6 +108,9 @@ const struct dispc_features dispc_k2g_feats = { .vid_name = { "vid1" }, .vid_lite = { false }, .vid_order = { 0 }, + + .num_output_ports = 1, + .output_port_bus_type = { DISPC_PORT_DPI }, }; Just thinking out loud, as these will get more complex in the future, maybe we should finally group them with struct. E.g. we could define struct array for vps, like (just hacky example): struct { const char *name; const char *clkname; struct tidss_vp_feat feat; } vps[TIDSS_MAX_PORTS]; and then use them as: .vps = { { .name = "kala", .clkname = "kissa", .feat.color.has_ctm = true, }, { .name = "kala2", .clkname = "kissa2", .feat.color.has_ctm = false, }, }, Perhaps something to try in the future. Yes, agreed! Having that structure will tidy this up. I will keep this under future work. static const u16 tidss_am65x_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { @@ -140,8 +142,8 @@ static const u16 tidss_am65x_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { const struct dispc_features dispc_am65x_feats = { .max_pclk_khz = { - [DISPC_VP_DPI] = 165000, - [DISPC_VP_OLDI] = 165000, + [DISPC_PORT_DPI] = 165000, + [DISPC_PORT_OLDI] = 165000, }, .scaling = { @@ -171,7 +173,6 @@ const struct dispc_features dispc_am65x_feats = { .vp_name = { "vp1", "vp2" }, .ovr_name = { "ovr1", "ovr2" }, .vpclk_name = { "vp1", "vp2" }, - .vp_bus_type = { DISPC_VP_OLDI, DISPC_VP_DPI }, .vp_feat = { .color = { .has_ctm = true, @@ -185,6 +186,9 @@ const struct dispc_features dispc_am65x_feats = { .vid_name = { "vid", "vidl1" }, .vid_lite = { false, true, }, .vid_order = { 1, 0 }, + + .num_output_ports = 2, + .output_port_bus_type = { DISPC_PORT_OLDI, DISPC_PORT_DPI }, }; static const u16 tidss_j721e_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { @@ -229,8 +233,8 @@ static const u16 tidss_j721e_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { const struct dispc_features dispc_j721e_feats = { .max_pclk_khz = { - [DISPC_VP_DPI] = 17, - [DISPC_VP_INTERNAL] = 60, + [DISPC_PORT_DPI] = 17, + [DISPC_PORT_INTERNAL] = 60, }, .scaling = { @@ -260,9 +264,7 @@ const struct dispc_features dispc_j721e_feats = { .vp_name = { "vp1", "vp2", "vp3", "vp4" }, .ovr_name = { "ovr1", "ovr2", "ovr3", "ovr4" }, .vpclk_name = { "vp1", "vp2", "vp3", "vp4" }, - /* Currently hard coded VP routing (see dispc_initial_config()) */ - .vp_bus_type = { DISPC_VP_INTERNAL, DISPC_VP_DPI, - DISPC_VP_INTERNAL, DISPC_VP_DPI, }, + I think this line feed is extra. Okay! Will remove that from all SoC feat structs. .vp_feat = { .color = { .has_ctm = true, .gamma_size = 1024, @@ -273,6 +275,11 @@ const struct dispc_features
Re: [PATCH 2/8] arm64: dts: qcom: sm8350: add RPMH_REGULATOR_LEVEL_LOW_SVS_L1
On 06/02/2023 13:23, Konrad Dybcio wrote: On 6.02.2023 12:22, Dmitry Baryshkov wrote: On 06/02/2023 12:44, Konrad Dybcio wrote: On 6.02.2023 01:27, Dmitry Baryshkov wrote: Add another power saving state used on SM8350. Signed-off-by: Dmitry Baryshkov --- include/dt-bindings/power/qcom-rpmpd.h | 1 + Wrong patch? And this patch is correct. sm8350 GPU OPP table uses this value (but as doesn't reference the rpmh's opp states, we don't have to add one there). Okay, but it's *just* a header entry, so the subject is misleading and you're not adding the dt part here. Ack, I got your point now. Yes, it should be `dt-bindings: add RPMH_REGULATOR_LEVEL_LOW_SVS_L1'. Konrad Konrad 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index 4a30d10e6b7d..1bf8e87ecd7e 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -211,6 +211,7 @@ #define RPMH_REGULATOR_LEVEL_MIN_SVS 48 #define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56 #define RPMH_REGULATOR_LEVEL_LOW_SVS 64 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80 #define RPMH_REGULATOR_LEVEL_SVS 128 #define RPMH_REGULATOR_LEVEL_SVS_L0 144 #define RPMH_REGULATOR_LEVEL_SVS_L1 192 -- With best wishes Dmitry
Re: [PATCH 1/5] dt-bindings: display: msm: dp-controller: document SM8450 compatible
On 06/02/2023 14:36, Neil Armstrong wrote: On 06/02/2023 12:20, Dmitry Baryshkov wrote: On 06/02/2023 12:33, Krzysztof Kozlowski wrote: On 06/02/2023 11:17, Neil Armstrong wrote: The SM8450 & SM350 shares the same DT TX IP version, use the SM8350 compatible as fallback for SM8450. Signed-off-by: Neil Armstrong --- Documentation/devicetree/bindings/display/msm/dp-controller.yaml | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml index 0e8d8df686dc..98bae326e655 100644 --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml @@ -25,6 +25,10 @@ properties: - qcom,sc8280xp-edp - qcom,sdm845-dp - qcom,sm8350-dp + - items: + - enum: + - qcom,sm8450-dp Indentation looks wrong here. Testing should fail, did you test it? Moreover it also breaks dt-schema, see https://github.com/devicetree-org/dt-schema/issues/98 Yep the change totally broke on rebase, will fix it Sorry for the noise. N/p. You might want to check the sm8350 GPU patchset. I had to reorder DT nodes. -- With best wishes Dmitry
Re: [PATCH 1/5] dt-bindings: display: msm: dp-controller: document SM8450 compatible
On 06/02/2023 12:20, Dmitry Baryshkov wrote: On 06/02/2023 12:33, Krzysztof Kozlowski wrote: On 06/02/2023 11:17, Neil Armstrong wrote: The SM8450 & SM350 shares the same DT TX IP version, use the SM8350 compatible as fallback for SM8450. Signed-off-by: Neil Armstrong --- Documentation/devicetree/bindings/display/msm/dp-controller.yaml | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml index 0e8d8df686dc..98bae326e655 100644 --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml @@ -25,6 +25,10 @@ properties: - qcom,sc8280xp-edp - qcom,sdm845-dp - qcom,sm8350-dp + - items: + - enum: + - qcom,sm8450-dp Indentation looks wrong here. Testing should fail, did you test it? Moreover it also breaks dt-schema, see https://github.com/devicetree-org/dt-schema/issues/98 Yep the change totally broke on rebase, will fix it Sorry for the noise. Neil Best regards, Krzysztof
Re: [PATCH 4/5] arm64: dst: qcom: sm8450: switch to usb3/dp combo phy
On 06/02/2023 12:03, Konrad Dybcio wrote: subject: s/dst/dts here and in 5/5 On 6.02.2023 11:17, Neil Armstrong wrote: The QMP PHY is a USB3/DP combo phy, switch to the newly documented bindings and register the clocks to the GCC and DISPCC controllers. Signed-off-by: Neil Armstrong --- arch/arm64/boot/dts/qcom/sm8450.dtsi | 38 +--- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi index d66dcd8fe61f..757b7c56d5f5 100644 --- a/arch/arm64/boot/dts/qcom/sm8450.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi @@ -748,7 +748,7 @@ gcc: clock-controller@10 { <_mem_phy_lanes 0>, <_mem_phy_lanes 1>, <_mem_phy_lanes 2>, -<0>; +<_1_qmpphy 0>; clock-names = "bi_tcxo", "sleep_clk", "pcie_0_pipe_clk", @@ -2038,37 +2038,27 @@ usb_1_hsphy: phy@88e3000 { resets = < GCC_QUSB2PHY_PRIM_BCR>; }; - usb_1_qmpphy: phy-wrapper@88e9000 { - compatible = "qcom,sm8450-qmp-usb3-phy"; - reg = <0 0x088e9000 0 0x200>, - <0 0x088e8000 0 0x20>; - status = "disabled"; + usb_1_qmpphy: phy@88e8000 { + compatible = "qcom,sm8450-qmp-usb3-dp-phy"; + reg = <0 0x088e8000 0 0x4000>; #address-cells = <2>; #size-cells = <2>; ranges; These can go since you're removing the subnode, I think.. Indeed will remove clocks = < GCC_USB3_PRIM_PHY_AUX_CLK>, < RPMH_CXO_CLK>, -< GCC_USB3_PRIM_PHY_COM_AUX_CLK>; - clock-names = "aux", "ref_clk_src", "com_aux"; +< GCC_USB3_PRIM_PHY_COM_AUX_CLK>, +< GCC_USB3_PRIM_PHY_PIPE_CLK>; + clock-names = "aux", "ref", "com_aux", "usb3_pipe"; resets = < GCC_USB3_DP_PHY_PRIM_BCR>, < GCC_USB3_PHY_PRIM_BCR>; reset-names = "phy", "common"; - usb_1_ssphy: phy@88e9200 { - reg = <0 0x088e9200 0 0x200>, - <0 0x088e9400 0 0x200>, - <0 0x088e9c00 0 0x400>, - <0 0x088e9600 0 0x200>, - <0 0x088e9800 0 0x200>, - <0 0x088e9a00 0 0x100>; - #phy-cells = <0>; - #clock-cells = <0>; - clocks = < GCC_USB3_PRIM_PHY_PIPE_CLK>; - clock-names = "pipe0"; - clock-output-names = "usb3_phy_pipe_clk_src"; - }; + #clock-cells = <1>; + #phy-cells = <1>; + + status = "disabled"; }; remoteproc_slpi: remoteproc@240 { @@ -2976,8 +2966,8 @@ dispcc: clock-controller@af0 { <_dsi0_phy 1>, <_dsi1_phy 0>, <_dsi1_phy 1>, -<0>, /* dp0 */ -<0>, +<_1_qmpphy 0>, +<_1_qmpphy 1>, <0>, /* dp1 */ <0>, <0>, /* dp2 */ @@ -4157,7 +4147,7 @@ usb_1_dwc3: usb@a60 { iommus = <_smmu 0x0 0x0>; snps,dis_u2_susphy_quirk; snps,dis_enblslpm_quirk; - phys = <_1_hsphy>, <_1_ssphy>; + phys = <_1_hsphy>, <_1_qmpphy 0>; phy-names = "usb2-phy", "usb3-phy"; BTW msm-5.10 marks the dwc3 subdevice dma-coherent, maybe we should too? Probably, not sure it's related to this patchset Neil Konrad }; };
Re: [PATCH v11 9/9] drm/bridge: it6505: Register Type C mode switches
On Sat, Feb 04, 2023 at 09:30:40PM +0800, Pin-yen Lin wrote: > Register USB Type-C mode switches when the "mode-switch" property and > relevant port are available in Device Tree. Configure the "lane_swap" > state based on the entered alternate mode for a specific Type-C > connector, which ends up updating the lane swap registers of the it6505 > chip. Same / similar comments as per previous patch. -- With Best Regards, Andy Shevchenko
Re: [PATCH v11 6/9] drm/bridge: anx7625: Register Type C mode switches
On Sat, Feb 04, 2023 at 09:30:37PM +0800, Pin-yen Lin wrote: > Register USB Type-C mode switches when the "mode-switch" property and > relevant ports are available in Device Tree. Configure the crosspoint > switch based on the entered alternate mode for a specific Type-C > connector. > > Crosspoint switch can also be used for switching the output signal for > different orientations of a single USB Type-C connector, but the > orientation switch is not implemented yet. A TODO is added for this. ... > + for (i = 0; i < 2; i++) { > + if (ctx->port_data[i].dp_connected) > + anx7625_set_crosspoint_switch( > + ctx, ctx->port_data[i].orientation); It's more than enough room to place ctx on the previous line. > + } ... > + struct anx7625_data *ctx = (struct anx7625_data *) port->data; Redundant explicit casting. ... > + struct device *dev = >client->dev; Do you really need to keep client in that struct and not simply dev? ... > + /* dp on, power on first */ DP ? ... > + /* dp off, power off last */ Ditto. ... > + num_lanes = fwnode_property_read_u32_array(fwnode, "data-lanes", > +NULL, 0); Read the kernel doc for this API and amend your code accordingly. ... > + if (num_lanes <= 0 || num_lanes > 2) { > + dev_err(dev, > + "Error on getting data lanes count from %pfwP: > %d\n", > + fwnode, num_lanes); > + ret = num_lanes; ret == 0?! Carefully consider all cases. > + goto unregister_mux; > + } -- With Best Regards, Andy Shevchenko
Re: [PATCH v11 3/9] drm/display: Add Type-C switch helpers
On Mon, 06 Feb 2023, Andy Shevchenko wrote: > On Sat, Feb 04, 2023 at 09:30:34PM +0800, Pin-yen Lin wrote: >> Add helpers to register and unregister Type-C "switches" for bridges >> capable of switching their output between two downstream devices. >> >> The helper registers USB Type-C mode switches when the "mode-switch" >> and the "reg" properties are available in Device Tree. > > ... > >> +fwnode_for_each_child_node(port, sw) { >> +if (fwnode_property_present(sw, "mode-switch")) > > This idiom is being used at least twice (in this code, haven't checked the > rest > of the patches, though), perhaps > > #define fwnode_for_each_typec_mode_switch(port, sw) \ > fwnode_for_each_child_node(port, sw)\ > if (!fwnode_property_present(sw, "mode-switch")) {} else > > ? See for_each_if() in drm_util.h. BR, Jani. -- Jani Nikula, Intel Open Source Graphics Center
Re: [PATCH v11 5/9] drm/bridge: anx7625: Check for Type-C during panel registration
On Sat, Feb 04, 2023 at 09:30:36PM +0800, Pin-yen Lin wrote: > The output port endpoints can be connected to USB-C connectors. > Running drm_of_find_panel_or_bridge() with such endpoints leads to > a continuous return value of -EPROBE_DEFER, even though there is > no panel present. > > To avoid this, check for the existence of a "mode-switch" property in > the port endpoint, and skip panel registration completely if so. ... > + /* > + * Don't bother finding a panel if a Type-C `mode-switch` property is > + * present in one of the endpoints. > + */ > + for_each_endpoint_of_node(np, sw) { > + if (of_property_read_bool(sw, "mode-switch")) { Might be that the same helper can be used here. Dunno if the endpoint traverse should be used for the other driver as well. > + of_node_put(sw); > + return 0; > + } > + } -- With Best Regards, Andy Shevchenko
Re: [PATCH v11 3/9] drm/display: Add Type-C switch helpers
On Sat, Feb 04, 2023 at 09:30:34PM +0800, Pin-yen Lin wrote: > Add helpers to register and unregister Type-C "switches" for bridges > capable of switching their output between two downstream devices. > > The helper registers USB Type-C mode switches when the "mode-switch" > and the "reg" properties are available in Device Tree. ... > + fwnode_for_each_child_node(port, sw) { > + if (fwnode_property_present(sw, "mode-switch")) This idiom is being used at least twice (in this code, haven't checked the rest of the patches, though), perhaps #define fwnode_for_each_typec_mode_switch(port, sw) \ fwnode_for_each_child_node(port, sw)\ if (!fwnode_property_present(sw, "mode-switch")) {} else ? -- With Best Regards, Andy Shevchenko
[CI 3/4] drm/display/dp_mst: Add drm_atomic_get_old_mst_topology_state()
Add a function to get the old MST topology state, required by a follow-up i915 patch. While at it clarify the code comment of drm_atomic_get_new_mst_topology_state() and add _new prefix to the new state pointer to remind about its difference from the old state. v2: Use old_/new_ prefixes for the state pointers. (Ville) Cc: Lyude Paul Cc: Ville Syrjälä Cc: sta...@vger.kernel.org # 6.1 Cc: dri-devel@lists.freedesktop.org Reviewed-by: Ville Syrjälä Reviewed-by: Lyude Paul Signed-off-by: Imre Deak --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 33 --- include/drm/display/drm_dp_mst_helper.h | 3 ++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 1990ff5dc7ddd..38dab76ae69ea 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -5364,28 +5364,53 @@ struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_a } EXPORT_SYMBOL(drm_atomic_get_mst_topology_state); +/** + * drm_atomic_get_old_mst_topology_state: get old MST topology state in atomic state, if any + * @state: global atomic state + * @mgr: MST topology manager, also the private object in this case + * + * This function wraps drm_atomic_get_old_private_obj_state() passing in the MST atomic + * state vtable so that the private object state returned is that of a MST + * topology object. + * + * Returns: + * + * The old MST topology state, or NULL if there's no topology state for this MST mgr + * in the global atomic state + */ +struct drm_dp_mst_topology_state * +drm_atomic_get_old_mst_topology_state(struct drm_atomic_state *state, + struct drm_dp_mst_topology_mgr *mgr) +{ + struct drm_private_state *old_priv_state = + drm_atomic_get_old_private_obj_state(state, >base); + + return old_priv_state ? to_dp_mst_topology_state(old_priv_state) : NULL; +} +EXPORT_SYMBOL(drm_atomic_get_old_mst_topology_state); + /** * drm_atomic_get_new_mst_topology_state: get new MST topology state in atomic state, if any * @state: global atomic state * @mgr: MST topology manager, also the private object in this case * - * This function wraps drm_atomic_get_priv_obj_state() passing in the MST atomic + * This function wraps drm_atomic_get_new_private_obj_state() passing in the MST atomic * state vtable so that the private object state returned is that of a MST * topology object. * * Returns: * - * The MST topology state, or NULL if there's no topology state for this MST mgr + * The new MST topology state, or NULL if there's no topology state for this MST mgr * in the global atomic state */ struct drm_dp_mst_topology_state * drm_atomic_get_new_mst_topology_state(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr) { - struct drm_private_state *priv_state = + struct drm_private_state *new_priv_state = drm_atomic_get_new_private_obj_state(state, >base); - return priv_state ? to_dp_mst_topology_state(priv_state) : NULL; + return new_priv_state ? to_dp_mst_topology_state(new_priv_state) : NULL; } EXPORT_SYMBOL(drm_atomic_get_new_mst_topology_state); diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h index f5eb9aa152b14..32c764fb9cb56 100644 --- a/include/drm/display/drm_dp_mst_helper.h +++ b/include/drm/display/drm_dp_mst_helper.h @@ -868,6 +868,9 @@ struct drm_dp_mst_topology_state * drm_atomic_get_mst_topology_state(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr); struct drm_dp_mst_topology_state * +drm_atomic_get_old_mst_topology_state(struct drm_atomic_state *state, + struct drm_dp_mst_topology_mgr *mgr); +struct drm_dp_mst_topology_state * drm_atomic_get_new_mst_topology_state(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr); struct drm_dp_mst_atomic_payload * -- 2.37.1
[CI 2/4] drm/display/dp_mst: Handle old/new payload states in drm_dp_remove_payload()
Atm, drm_dp_remove_payload() uses the same payload state to both get the vc_start_slot required for the payload removal DPCD message and to deduct time_slots from vc_start_slot of all payloads after the one being removed. The above isn't always correct, as vc_start_slot must be the up-to-date version contained in the new payload state, but time_slots must be the one used when the payload was previously added, contained in the old payload state. The new payload's time_slots can change vs. the old one if the current atomic commit changes the corresponding mode. This patch let's drivers pass the old and new payload states to drm_dp_remove_payload(), but keeps these the same for now in all drivers not to change the behavior. A follow-up i915 patch will pass in that driver the correct old and new states to the function. Cc: Lyude Paul Cc: Ville Syrjälä Cc: Ben Skeggs Cc: Karol Herbst Cc: Harry Wentland Cc: Alex Deucher Cc: Wayne Lin Cc: sta...@vger.kernel.org # 6.1 Cc: dri-devel@lists.freedesktop.org Reviewed-by: Ville Syrjälä Reviewed-by: Lyude Paul Signed-off-by: Imre Deak --- .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 +- drivers/gpu/drm/display/drm_dp_mst_topology.c | 26 ++- drivers/gpu/drm/i915/display/intel_dp_mst.c | 4 ++- drivers/gpu/drm/nouveau/dispnv50/disp.c | 2 +- include/drm/display/drm_dp_mst_helper.h | 3 ++- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index a50319fc42b11..180d3893b68da 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -208,7 +208,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( if (enable) drm_dp_add_payload_part1(mst_mgr, mst_state, payload); else - drm_dp_remove_payload(mst_mgr, mst_state, payload); + drm_dp_remove_payload(mst_mgr, mst_state, payload, payload); /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or * AUX message. The sequence is slot 1-63 allocated sequence for each diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 847c10aa2098c..1990ff5dc7ddd 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -3342,7 +3342,8 @@ EXPORT_SYMBOL(drm_dp_add_payload_part1); * drm_dp_remove_payload() - Remove an MST payload * @mgr: Manager to use. * @mst_state: The MST atomic state - * @payload: The payload to write + * @old_payload: The payload with its old state + * @new_payload: The payload to write * * Removes a payload from an MST topology if it was successfully assigned a start slot. Also updates * the starting time slots of all other payloads which would have been shifted towards the start of @@ -3350,36 +3351,37 @@ EXPORT_SYMBOL(drm_dp_add_payload_part1); */ void drm_dp_remove_payload(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_topology_state *mst_state, - struct drm_dp_mst_atomic_payload *payload) + const struct drm_dp_mst_atomic_payload *old_payload, + struct drm_dp_mst_atomic_payload *new_payload) { struct drm_dp_mst_atomic_payload *pos; bool send_remove = false; /* We failed to make the payload, so nothing to do */ - if (payload->vc_start_slot == -1) + if (new_payload->vc_start_slot == -1) return; mutex_lock(>lock); - send_remove = drm_dp_mst_port_downstream_of_branch(payload->port, mgr->mst_primary); + send_remove = drm_dp_mst_port_downstream_of_branch(new_payload->port, mgr->mst_primary); mutex_unlock(>lock); if (send_remove) - drm_dp_destroy_payload_step1(mgr, mst_state, payload); + drm_dp_destroy_payload_step1(mgr, mst_state, new_payload); else drm_dbg_kms(mgr->dev, "Payload for VCPI %d not in topology, not sending remove\n", - payload->vcpi); + new_payload->vcpi); list_for_each_entry(pos, _state->payloads, next) { - if (pos != payload && pos->vc_start_slot > payload->vc_start_slot) - pos->vc_start_slot -= payload->time_slots; + if (pos != new_payload && pos->vc_start_slot > new_payload->vc_start_slot) + pos->vc_start_slot -= old_payload->time_slots; } - payload->vc_start_slot = -1; + new_payload->vc_start_slot = -1; mgr->payload_count--; - mgr->next_start_slot -= payload->time_slots; + mgr->next_start_slot -= old_payload->time_slots; - if (payload->delete) -
Re: [PATCH 2/2] backlight: hx8357: stop using of-specific APIs
On Tue, Jan 31, 2023 at 02:57:07PM -0800, Dmitry Torokhov wrote: > There is no need for this driver to be OF-specific, so switch it to > use device_get_match_data() and stop including various of-related > headers. > > Signed-off-by: Dmitry Torokhov Reviewed-by: Daniel Thompson Daniel.
Re: [Intel-gfx] [PATCH v2] drm/i915: Initialize the obj flags for shmem objects
On 06-02-2023 15:21, Tvrtko Ursulin wrote: > > > On 03/02/2023 13:52, Aravind Iddamsetty wrote: >> Obj flags for shmem objects is not being set correctly. Fixes in setting >> BO_ALLOC_USER flag which applies to shmem objs as well. >> >> Fixes: 13d29c823738 ("drm/i915/ehl: unconditionally flush the pages on >> acquire") >> Cc: # v5.15+ > > These tags should have been grouped with the ones below in one block. > > I have tidied this while pushing, thanks for the fix and review! Thanks Tvrtko. Regards, Aravind. > > Regards, > > Tvrtko > >> v2: Add fixes tag (Tvrtko, Matt A) >> >> Cc: Matthew Auld >> Cc: Tvrtko Ursulin >> Reviewed-by: Matthew Auld >> Signed-off-by: Aravind Iddamsetty >> --- >> drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c >> b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c >> index 114443096841..37d1efcd3ca6 100644 >> --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c >> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c >> @@ -596,7 +596,7 @@ static int shmem_object_init(struct >> intel_memory_region *mem, >> mapping_set_gfp_mask(mapping, mask); >> GEM_BUG_ON(!(mapping_gfp_mask(mapping) & __GFP_RECLAIM)); >> - i915_gem_object_init(obj, _gem_shmem_ops, _class, 0); >> + i915_gem_object_init(obj, _gem_shmem_ops, _class, flags); >> obj->mem_flags |= I915_BO_FLAG_STRUCT_PAGE; >> obj->write_domain = I915_GEM_DOMAIN_CPU; >> obj->read_domains = I915_GEM_DOMAIN_CPU;
Re: [PATCH 1/2] backlight: hx8357: switch to using gpiod API
On Tue, Jan 31, 2023 at 02:57:06PM -0800, Dmitry Torokhov wrote: > Switch the driver from legacy gpio API that is deprecated to the newer > gpiod API that respects line polarities described in ACPI/DT. > > This makes driver use standard property name for the reset gpio > ("reset-gpios" vs "gpios-reset"), however there is a quirk in gpiolib > to also recognize the legacy name and keep compatibility with older > DTSes. > > Signed-off-by: Dmitry Torokhov > --- > > All preparation gpiolib work to handle legacy names and polarity quirks > has landed in mainline... > > drivers/video/backlight/hx8357.c | 82 ++-- > 1 file changed, 37 insertions(+), 45 deletions(-) > > diff --git a/drivers/video/backlight/hx8357.c > b/drivers/video/backlight/hx8357.c > index 9b50bc96e00f..a93e14adb846 100644 > --- a/drivers/video/backlight/hx8357.c > +++ b/drivers/video/backlight/hx8357.c > [snip] > - if (of_find_property(spi->dev.of_node, "im-gpios", NULL)) { > - lcd->use_im_pins = 1; > - > - for (i = 0; i < HX8357_NUM_IM_PINS; i++) { > - lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node, > - "im-gpios", i); > - if (lcd->im_pins[i] == -EPROBE_DEFER) { > - dev_info(>dev, "GPIO requested is not here > yet, deferring the probe\n"); > - return -EPROBE_DEFER; > - } > - if (!gpio_is_valid(lcd->im_pins[i])) { > - dev_err(>dev, "Missing dt property: > im-gpios\n"); > - return -EINVAL; > + gpiod_set_consumer_name(lcd->reset, "hx8357-reset"); > + > + for (i = 0; i < HX8357_NUM_IM_PINS; i++) { > + lcd->im_pins[i] = devm_gpiod_get_index(>dev, > +"im", i, GPIOD_OUT_LOW); > + ret = PTR_ERR_OR_ZERO(lcd->im_pins[i]); > + if (ret) { > + if (ret == -ENOENT) { > + if (i == 0) > + break; > + dev_err(>dev, "Missing im gpios[%d]\n", i); > + ret = -EINVAL; > + } if (ret == -EPROBE_DEFER) { > + dev_info(>dev, "im gpio[%d] is not here > yet, deferring the probe\n", > + i); > + } else { > + dev_err(>dev, "failed to request im > gpio[%d]: %d\n", > + i, ret); > } These last two clauses should be updated to return dev_err_probe(...) instead. With that change: Reviewed-by: Daniel Thompson Daniel.
Re: [PATCH 2/8] arm64: dts: qcom: sm8350: add RPMH_REGULATOR_LEVEL_LOW_SVS_L1
On 6.02.2023 12:22, Dmitry Baryshkov wrote: > On 06/02/2023 12:44, Konrad Dybcio wrote: >> >> >> On 6.02.2023 01:27, Dmitry Baryshkov wrote: >>> Add another power saving state used on SM8350. >>> >>> Signed-off-by: Dmitry Baryshkov >>> --- >>> include/dt-bindings/power/qcom-rpmpd.h | 1 + >> Wrong patch? > > And this patch is correct. sm8350 GPU OPP table uses this value (but as > doesn't reference the rpmh's opp states, we don't have to add one there). Okay, but it's *just* a header entry, so the subject is misleading and you're not adding the dt part here. Konrad > >> >> Konrad >>> 1 file changed, 1 insertion(+) >>> >>> diff --git a/include/dt-bindings/power/qcom-rpmpd.h >>> b/include/dt-bindings/power/qcom-rpmpd.h >>> index 4a30d10e6b7d..1bf8e87ecd7e 100644 >>> --- a/include/dt-bindings/power/qcom-rpmpd.h >>> +++ b/include/dt-bindings/power/qcom-rpmpd.h >>> @@ -211,6 +211,7 @@ >>> #define RPMH_REGULATOR_LEVEL_MIN_SVS 48 >>> #define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56 >>> #define RPMH_REGULATOR_LEVEL_LOW_SVS 64 >>> +#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80 >>> #define RPMH_REGULATOR_LEVEL_SVS 128 >>> #define RPMH_REGULATOR_LEVEL_SVS_L0 144 >>> #define RPMH_REGULATOR_LEVEL_SVS_L1 192 >
Re: [PATCH 2/8] arm64: dts: qcom: sm8350: add RPMH_REGULATOR_LEVEL_LOW_SVS_L1
On 06/02/2023 12:44, Konrad Dybcio wrote: On 6.02.2023 01:27, Dmitry Baryshkov wrote: Add another power saving state used on SM8350. Signed-off-by: Dmitry Baryshkov --- include/dt-bindings/power/qcom-rpmpd.h | 1 + Wrong patch? And this patch is correct. sm8350 GPU OPP table uses this value (but as doesn't reference the rpmh's opp states, we don't have to add one there). Konrad 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index 4a30d10e6b7d..1bf8e87ecd7e 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -211,6 +211,7 @@ #define RPMH_REGULATOR_LEVEL_MIN_SVS 48 #define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56 #define RPMH_REGULATOR_LEVEL_LOW_SVS 64 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_L180 #define RPMH_REGULATOR_LEVEL_SVS 128 #define RPMH_REGULATOR_LEVEL_SVS_L0 144 #define RPMH_REGULATOR_LEVEL_SVS_L1 192 -- With best wishes Dmitry