Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: split out intel_pcode.[ch] to separate file

The snb+ pcode mailbox code is not sideband, so split it out to a
separate file. As can be seen from the #include changes, very few places
use both sideband and pcode.

Code movement only.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/185deb18eb739e5ae019e27834b9997dcc1347bc.1634207064.git.jani.nikula@intel.com

+277 -255
+1
drivers/gpu/drm/i915/Makefile
··· 47 47 intel_dram.o \ 48 48 intel_memory_region.o \ 49 49 intel_pch.o \ 50 + intel_pcode.o \ 50 51 intel_pm.o \ 51 52 intel_region_ttm.o \ 52 53 intel_runtime_pm.o \
+1 -1
drivers/gpu/drm/i915/display/intel_bw.c
··· 9 9 #include "intel_bw.h" 10 10 #include "intel_cdclk.h" 11 11 #include "intel_display_types.h" 12 + #include "intel_pcode.h" 12 13 #include "intel_pm.h" 13 - #include "intel_sideband.h" 14 14 15 15 /* Parameters for Qclk Geyserville (QGV) */ 16 16 struct intel_qgv_point {
+1 -1
drivers/gpu/drm/i915/display/intel_cdclk.c
··· 28 28 #include "intel_cdclk.h" 29 29 #include "intel_de.h" 30 30 #include "intel_display_types.h" 31 + #include "intel_pcode.h" 31 32 #include "intel_psr.h" 32 - #include "intel_sideband.h" 33 33 #include "vlv_sideband.h" 34 34 35 35 /**
+2 -1
drivers/gpu/drm/i915/display/intel_display.c
··· 88 88 #include "intel_dp_link_training.h" 89 89 #include "intel_dpt.h" 90 90 #include "intel_fbc.h" 91 - #include "intel_fdi.h" 92 91 #include "intel_fbdev.h" 92 + #include "intel_fdi.h" 93 93 #include "intel_fifo_underrun.h" 94 94 #include "intel_frontbuffer.h" 95 95 #include "intel_hdcp.h" 96 96 #include "intel_hotplug.h" 97 97 #include "intel_overlay.h" 98 98 #include "intel_panel.h" 99 + #include "intel_pcode.h" 99 100 #include "intel_pipe_crc.h" 100 101 #include "intel_plane_initial.h" 101 102 #include "intel_pm.h"
+1 -1
drivers/gpu/drm/i915/display/intel_display_power.c
··· 15 15 #include "intel_dpio_phy.h" 16 16 #include "intel_dpll.h" 17 17 #include "intel_hotplug.h" 18 + #include "intel_pcode.h" 18 19 #include "intel_pm.h" 19 20 #include "intel_pps.h" 20 - #include "intel_sideband.h" 21 21 #include "intel_snps_phy.h" 22 22 #include "intel_tc.h" 23 23 #include "intel_vga.h"
+3 -3
drivers/gpu/drm/i915/display/intel_hdcp.c
··· 17 17 18 18 #include "i915_drv.h" 19 19 #include "i915_reg.h" 20 - #include "intel_display_power.h" 20 + #include "intel_connector.h" 21 21 #include "intel_de.h" 22 + #include "intel_display_power.h" 22 23 #include "intel_display_types.h" 23 24 #include "intel_hdcp.h" 24 - #include "intel_sideband.h" 25 - #include "intel_connector.h" 25 + #include "intel_pcode.h" 26 26 27 27 #define KEY_LOAD_TRIES 5 28 28 #define HDCP2_LC_RETRY_CNT 3
+1 -1
drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c
··· 13 13 #include "intel_gt_pm.h" 14 14 #include "intel_gt_pm_debugfs.h" 15 15 #include "intel_llc.h" 16 + #include "intel_pcode.h" 16 17 #include "intel_rc6.h" 17 18 #include "intel_rps.h" 18 19 #include "intel_runtime_pm.h" 19 - #include "intel_sideband.h" 20 20 #include "intel_uncore.h" 21 21 #include "vlv_sideband.h" 22 22
+1 -1
drivers/gpu/drm/i915/gt/intel_llc.c
··· 8 8 #include "i915_drv.h" 9 9 #include "intel_gt.h" 10 10 #include "intel_llc.h" 11 - #include "intel_sideband.h" 11 + #include "intel_pcode.h" 12 12 13 13 struct ia_constants { 14 14 unsigned int min_gpu_freq;
+1 -1
drivers/gpu/drm/i915/gt/intel_rc6.c
··· 9 9 #include "i915_vgpu.h" 10 10 #include "intel_gt.h" 11 11 #include "intel_gt_pm.h" 12 + #include "intel_pcode.h" 12 13 #include "intel_rc6.h" 13 - #include "intel_sideband.h" 14 14 15 15 /** 16 16 * DOC: RC6
+1 -1
drivers/gpu/drm/i915/gt/intel_rps.c
··· 11 11 #include "intel_gt_clock_utils.h" 12 12 #include "intel_gt_irq.h" 13 13 #include "intel_gt_pm_irq.h" 14 + #include "intel_pcode.h" 14 15 #include "intel_rps.h" 15 - #include "intel_sideband.h" 16 16 #include "vlv_sideband.h" 17 17 #include "../../../platform/x86/intel_ips.h" 18 18
+1 -1
drivers/gpu/drm/i915/i915_drv.c
··· 84 84 #include "intel_dram.h" 85 85 #include "intel_gvt.h" 86 86 #include "intel_memory_region.h" 87 + #include "intel_pcode.h" 87 88 #include "intel_pm.h" 88 89 #include "intel_region_ttm.h" 89 - #include "intel_sideband.h" 90 90 #include "vlv_suspend.h" 91 91 92 92 static const struct drm_driver driver;
+1 -1
drivers/gpu/drm/i915/intel_dram.c
··· 5 5 6 6 #include "i915_drv.h" 7 7 #include "intel_dram.h" 8 - #include "intel_sideband.h" 8 + #include "intel_pcode.h" 9 9 10 10 struct dram_dimm_info { 11 11 u16 size;
+235
drivers/gpu/drm/i915/intel_pcode.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright © 2013-2021 Intel Corporation 4 + */ 5 + 6 + #include "i915_drv.h" 7 + #include "intel_pcode.h" 8 + 9 + static int gen6_check_mailbox_status(u32 mbox) 10 + { 11 + switch (mbox & GEN6_PCODE_ERROR_MASK) { 12 + case GEN6_PCODE_SUCCESS: 13 + return 0; 14 + case GEN6_PCODE_UNIMPLEMENTED_CMD: 15 + return -ENODEV; 16 + case GEN6_PCODE_ILLEGAL_CMD: 17 + return -ENXIO; 18 + case GEN6_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: 19 + case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: 20 + return -EOVERFLOW; 21 + case GEN6_PCODE_TIMEOUT: 22 + return -ETIMEDOUT; 23 + default: 24 + MISSING_CASE(mbox & GEN6_PCODE_ERROR_MASK); 25 + return 0; 26 + } 27 + } 28 + 29 + static int gen7_check_mailbox_status(u32 mbox) 30 + { 31 + switch (mbox & GEN6_PCODE_ERROR_MASK) { 32 + case GEN6_PCODE_SUCCESS: 33 + return 0; 34 + case GEN6_PCODE_ILLEGAL_CMD: 35 + return -ENXIO; 36 + case GEN7_PCODE_TIMEOUT: 37 + return -ETIMEDOUT; 38 + case GEN7_PCODE_ILLEGAL_DATA: 39 + return -EINVAL; 40 + case GEN11_PCODE_ILLEGAL_SUBCOMMAND: 41 + return -ENXIO; 42 + case GEN11_PCODE_LOCKED: 43 + return -EBUSY; 44 + case GEN11_PCODE_REJECTED: 45 + return -EACCES; 46 + case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: 47 + return -EOVERFLOW; 48 + default: 49 + MISSING_CASE(mbox & GEN6_PCODE_ERROR_MASK); 50 + return 0; 51 + } 52 + } 53 + 54 + static int __sandybridge_pcode_rw(struct drm_i915_private *i915, 55 + u32 mbox, u32 *val, u32 *val1, 56 + int fast_timeout_us, 57 + int slow_timeout_ms, 58 + bool is_read) 59 + { 60 + struct intel_uncore *uncore = &i915->uncore; 61 + 62 + lockdep_assert_held(&i915->sb_lock); 63 + 64 + /* 65 + * GEN6_PCODE_* are outside of the forcewake domain, we can use 66 + * intel_uncore_read/write_fw variants to reduce the amount of work 67 + * required when reading/writing. 68 + */ 69 + 70 + if (intel_uncore_read_fw(uncore, GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) 71 + return -EAGAIN; 72 + 73 + intel_uncore_write_fw(uncore, GEN6_PCODE_DATA, *val); 74 + intel_uncore_write_fw(uncore, GEN6_PCODE_DATA1, val1 ? *val1 : 0); 75 + intel_uncore_write_fw(uncore, 76 + GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox); 77 + 78 + if (__intel_wait_for_register_fw(uncore, 79 + GEN6_PCODE_MAILBOX, 80 + GEN6_PCODE_READY, 0, 81 + fast_timeout_us, 82 + slow_timeout_ms, 83 + &mbox)) 84 + return -ETIMEDOUT; 85 + 86 + if (is_read) 87 + *val = intel_uncore_read_fw(uncore, GEN6_PCODE_DATA); 88 + if (is_read && val1) 89 + *val1 = intel_uncore_read_fw(uncore, GEN6_PCODE_DATA1); 90 + 91 + if (GRAPHICS_VER(i915) > 6) 92 + return gen7_check_mailbox_status(mbox); 93 + else 94 + return gen6_check_mailbox_status(mbox); 95 + } 96 + 97 + int sandybridge_pcode_read(struct drm_i915_private *i915, u32 mbox, 98 + u32 *val, u32 *val1) 99 + { 100 + int err; 101 + 102 + mutex_lock(&i915->sb_lock); 103 + err = __sandybridge_pcode_rw(i915, mbox, val, val1, 104 + 500, 20, 105 + true); 106 + mutex_unlock(&i915->sb_lock); 107 + 108 + if (err) { 109 + drm_dbg(&i915->drm, 110 + "warning: pcode (read from mbox %x) mailbox access failed for %ps: %d\n", 111 + mbox, __builtin_return_address(0), err); 112 + } 113 + 114 + return err; 115 + } 116 + 117 + int sandybridge_pcode_write_timeout(struct drm_i915_private *i915, 118 + u32 mbox, u32 val, 119 + int fast_timeout_us, 120 + int slow_timeout_ms) 121 + { 122 + int err; 123 + 124 + mutex_lock(&i915->sb_lock); 125 + err = __sandybridge_pcode_rw(i915, mbox, &val, NULL, 126 + fast_timeout_us, slow_timeout_ms, 127 + false); 128 + mutex_unlock(&i915->sb_lock); 129 + 130 + if (err) { 131 + drm_dbg(&i915->drm, 132 + "warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps: %d\n", 133 + val, mbox, __builtin_return_address(0), err); 134 + } 135 + 136 + return err; 137 + } 138 + 139 + static bool skl_pcode_try_request(struct drm_i915_private *i915, u32 mbox, 140 + u32 request, u32 reply_mask, u32 reply, 141 + u32 *status) 142 + { 143 + *status = __sandybridge_pcode_rw(i915, mbox, &request, NULL, 144 + 500, 0, 145 + true); 146 + 147 + return *status || ((request & reply_mask) == reply); 148 + } 149 + 150 + /** 151 + * skl_pcode_request - send PCODE request until acknowledgment 152 + * @i915: device private 153 + * @mbox: PCODE mailbox ID the request is targeted for 154 + * @request: request ID 155 + * @reply_mask: mask used to check for request acknowledgment 156 + * @reply: value used to check for request acknowledgment 157 + * @timeout_base_ms: timeout for polling with preemption enabled 158 + * 159 + * Keep resending the @request to @mbox until PCODE acknowledges it, PCODE 160 + * reports an error or an overall timeout of @timeout_base_ms+50 ms expires. 161 + * The request is acknowledged once the PCODE reply dword equals @reply after 162 + * applying @reply_mask. Polling is first attempted with preemption enabled 163 + * for @timeout_base_ms and if this times out for another 50 ms with 164 + * preemption disabled. 165 + * 166 + * Returns 0 on success, %-ETIMEDOUT in case of a timeout, <0 in case of some 167 + * other error as reported by PCODE. 168 + */ 169 + int skl_pcode_request(struct drm_i915_private *i915, u32 mbox, u32 request, 170 + u32 reply_mask, u32 reply, int timeout_base_ms) 171 + { 172 + u32 status; 173 + int ret; 174 + 175 + mutex_lock(&i915->sb_lock); 176 + 177 + #define COND \ 178 + skl_pcode_try_request(i915, mbox, request, reply_mask, reply, &status) 179 + 180 + /* 181 + * Prime the PCODE by doing a request first. Normally it guarantees 182 + * that a subsequent request, at most @timeout_base_ms later, succeeds. 183 + * _wait_for() doesn't guarantee when its passed condition is evaluated 184 + * first, so send the first request explicitly. 185 + */ 186 + if (COND) { 187 + ret = 0; 188 + goto out; 189 + } 190 + ret = _wait_for(COND, timeout_base_ms * 1000, 10, 10); 191 + if (!ret) 192 + goto out; 193 + 194 + /* 195 + * The above can time out if the number of requests was low (2 in the 196 + * worst case) _and_ PCODE was busy for some reason even after a 197 + * (queued) request and @timeout_base_ms delay. As a workaround retry 198 + * the poll with preemption disabled to maximize the number of 199 + * requests. Increase the timeout from @timeout_base_ms to 50ms to 200 + * account for interrupts that could reduce the number of these 201 + * requests, and for any quirks of the PCODE firmware that delays 202 + * the request completion. 203 + */ 204 + drm_dbg_kms(&i915->drm, 205 + "PCODE timeout, retrying with preemption disabled\n"); 206 + drm_WARN_ON_ONCE(&i915->drm, timeout_base_ms > 3); 207 + preempt_disable(); 208 + ret = wait_for_atomic(COND, 50); 209 + preempt_enable(); 210 + 211 + out: 212 + mutex_unlock(&i915->sb_lock); 213 + return ret ? ret : status; 214 + #undef COND 215 + } 216 + 217 + int intel_pcode_init(struct drm_i915_private *i915) 218 + { 219 + int ret = 0; 220 + 221 + if (!IS_DGFX(i915)) 222 + return ret; 223 + 224 + ret = skl_pcode_request(i915, DG1_PCODE_STATUS, 225 + DG1_UNCORE_GET_INIT_STATUS, 226 + DG1_UNCORE_INIT_STATUS_COMPLETE, 227 + DG1_UNCORE_INIT_STATUS_COMPLETE, 180000); 228 + 229 + drm_dbg(&i915->drm, "PCODE init status %d\n", ret); 230 + 231 + if (ret) 232 + drm_err(&i915->drm, "Pcode did not report uncore initialization completion!\n"); 233 + 234 + return ret; 235 + }
+26
drivers/gpu/drm/i915/intel_pcode.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Copyright © 2013-2021 Intel Corporation 4 + */ 5 + 6 + #ifndef _INTEL_PCODE_H_ 7 + #define _INTEL_PCODE_H_ 8 + 9 + #include <linux/types.h> 10 + 11 + struct drm_i915_private; 12 + 13 + int sandybridge_pcode_read(struct drm_i915_private *i915, u32 mbox, 14 + u32 *val, u32 *val1); 15 + int sandybridge_pcode_write_timeout(struct drm_i915_private *i915, u32 mbox, 16 + u32 val, int fast_timeout_us, 17 + int slow_timeout_ms); 18 + #define sandybridge_pcode_write(i915, mbox, val) \ 19 + sandybridge_pcode_write_timeout(i915, mbox, val, 500, 0) 20 + 21 + int skl_pcode_request(struct drm_i915_private *i915, u32 mbox, u32 request, 22 + u32 reply_mask, u32 reply, int timeout_base_ms); 23 + 24 + int intel_pcode_init(struct drm_i915_private *i915); 25 + 26 + #endif /* _INTEL_PCODE_H */
+1 -1
drivers/gpu/drm/i915/intel_pm.c
··· 47 47 #include "i915_fixed.h" 48 48 #include "i915_irq.h" 49 49 #include "i915_trace.h" 50 + #include "intel_pcode.h" 50 51 #include "intel_pm.h" 51 - #include "intel_sideband.h" 52 52 #include "vlv_sideband.h" 53 53 #include "../../../platform/x86/intel_ips.h" 54 54
-228
drivers/gpu/drm/i915/intel_sideband.c
··· 90 90 { 91 91 intel_sbi_rw(i915, reg, destination, &value, false); 92 92 } 93 - 94 - static int gen6_check_mailbox_status(u32 mbox) 95 - { 96 - switch (mbox & GEN6_PCODE_ERROR_MASK) { 97 - case GEN6_PCODE_SUCCESS: 98 - return 0; 99 - case GEN6_PCODE_UNIMPLEMENTED_CMD: 100 - return -ENODEV; 101 - case GEN6_PCODE_ILLEGAL_CMD: 102 - return -ENXIO; 103 - case GEN6_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: 104 - case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: 105 - return -EOVERFLOW; 106 - case GEN6_PCODE_TIMEOUT: 107 - return -ETIMEDOUT; 108 - default: 109 - MISSING_CASE(mbox & GEN6_PCODE_ERROR_MASK); 110 - return 0; 111 - } 112 - } 113 - 114 - static int gen7_check_mailbox_status(u32 mbox) 115 - { 116 - switch (mbox & GEN6_PCODE_ERROR_MASK) { 117 - case GEN6_PCODE_SUCCESS: 118 - return 0; 119 - case GEN6_PCODE_ILLEGAL_CMD: 120 - return -ENXIO; 121 - case GEN7_PCODE_TIMEOUT: 122 - return -ETIMEDOUT; 123 - case GEN7_PCODE_ILLEGAL_DATA: 124 - return -EINVAL; 125 - case GEN11_PCODE_ILLEGAL_SUBCOMMAND: 126 - return -ENXIO; 127 - case GEN11_PCODE_LOCKED: 128 - return -EBUSY; 129 - case GEN11_PCODE_REJECTED: 130 - return -EACCES; 131 - case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: 132 - return -EOVERFLOW; 133 - default: 134 - MISSING_CASE(mbox & GEN6_PCODE_ERROR_MASK); 135 - return 0; 136 - } 137 - } 138 - 139 - static int __sandybridge_pcode_rw(struct drm_i915_private *i915, 140 - u32 mbox, u32 *val, u32 *val1, 141 - int fast_timeout_us, 142 - int slow_timeout_ms, 143 - bool is_read) 144 - { 145 - struct intel_uncore *uncore = &i915->uncore; 146 - 147 - lockdep_assert_held(&i915->sb_lock); 148 - 149 - /* 150 - * GEN6_PCODE_* are outside of the forcewake domain, we can use 151 - * intel_uncore_read/write_fw variants to reduce the amount of work 152 - * required when reading/writing. 153 - */ 154 - 155 - if (intel_uncore_read_fw(uncore, GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) 156 - return -EAGAIN; 157 - 158 - intel_uncore_write_fw(uncore, GEN6_PCODE_DATA, *val); 159 - intel_uncore_write_fw(uncore, GEN6_PCODE_DATA1, val1 ? *val1 : 0); 160 - intel_uncore_write_fw(uncore, 161 - GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox); 162 - 163 - if (__intel_wait_for_register_fw(uncore, 164 - GEN6_PCODE_MAILBOX, 165 - GEN6_PCODE_READY, 0, 166 - fast_timeout_us, 167 - slow_timeout_ms, 168 - &mbox)) 169 - return -ETIMEDOUT; 170 - 171 - if (is_read) 172 - *val = intel_uncore_read_fw(uncore, GEN6_PCODE_DATA); 173 - if (is_read && val1) 174 - *val1 = intel_uncore_read_fw(uncore, GEN6_PCODE_DATA1); 175 - 176 - if (GRAPHICS_VER(i915) > 6) 177 - return gen7_check_mailbox_status(mbox); 178 - else 179 - return gen6_check_mailbox_status(mbox); 180 - } 181 - 182 - int sandybridge_pcode_read(struct drm_i915_private *i915, u32 mbox, 183 - u32 *val, u32 *val1) 184 - { 185 - int err; 186 - 187 - mutex_lock(&i915->sb_lock); 188 - err = __sandybridge_pcode_rw(i915, mbox, val, val1, 189 - 500, 20, 190 - true); 191 - mutex_unlock(&i915->sb_lock); 192 - 193 - if (err) { 194 - drm_dbg(&i915->drm, 195 - "warning: pcode (read from mbox %x) mailbox access failed for %ps: %d\n", 196 - mbox, __builtin_return_address(0), err); 197 - } 198 - 199 - return err; 200 - } 201 - 202 - int sandybridge_pcode_write_timeout(struct drm_i915_private *i915, 203 - u32 mbox, u32 val, 204 - int fast_timeout_us, 205 - int slow_timeout_ms) 206 - { 207 - int err; 208 - 209 - mutex_lock(&i915->sb_lock); 210 - err = __sandybridge_pcode_rw(i915, mbox, &val, NULL, 211 - fast_timeout_us, slow_timeout_ms, 212 - false); 213 - mutex_unlock(&i915->sb_lock); 214 - 215 - if (err) { 216 - drm_dbg(&i915->drm, 217 - "warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps: %d\n", 218 - val, mbox, __builtin_return_address(0), err); 219 - } 220 - 221 - return err; 222 - } 223 - 224 - static bool skl_pcode_try_request(struct drm_i915_private *i915, u32 mbox, 225 - u32 request, u32 reply_mask, u32 reply, 226 - u32 *status) 227 - { 228 - *status = __sandybridge_pcode_rw(i915, mbox, &request, NULL, 229 - 500, 0, 230 - true); 231 - 232 - return *status || ((request & reply_mask) == reply); 233 - } 234 - 235 - /** 236 - * skl_pcode_request - send PCODE request until acknowledgment 237 - * @i915: device private 238 - * @mbox: PCODE mailbox ID the request is targeted for 239 - * @request: request ID 240 - * @reply_mask: mask used to check for request acknowledgment 241 - * @reply: value used to check for request acknowledgment 242 - * @timeout_base_ms: timeout for polling with preemption enabled 243 - * 244 - * Keep resending the @request to @mbox until PCODE acknowledges it, PCODE 245 - * reports an error or an overall timeout of @timeout_base_ms+50 ms expires. 246 - * The request is acknowledged once the PCODE reply dword equals @reply after 247 - * applying @reply_mask. Polling is first attempted with preemption enabled 248 - * for @timeout_base_ms and if this times out for another 50 ms with 249 - * preemption disabled. 250 - * 251 - * Returns 0 on success, %-ETIMEDOUT in case of a timeout, <0 in case of some 252 - * other error as reported by PCODE. 253 - */ 254 - int skl_pcode_request(struct drm_i915_private *i915, u32 mbox, u32 request, 255 - u32 reply_mask, u32 reply, int timeout_base_ms) 256 - { 257 - u32 status; 258 - int ret; 259 - 260 - mutex_lock(&i915->sb_lock); 261 - 262 - #define COND \ 263 - skl_pcode_try_request(i915, mbox, request, reply_mask, reply, &status) 264 - 265 - /* 266 - * Prime the PCODE by doing a request first. Normally it guarantees 267 - * that a subsequent request, at most @timeout_base_ms later, succeeds. 268 - * _wait_for() doesn't guarantee when its passed condition is evaluated 269 - * first, so send the first request explicitly. 270 - */ 271 - if (COND) { 272 - ret = 0; 273 - goto out; 274 - } 275 - ret = _wait_for(COND, timeout_base_ms * 1000, 10, 10); 276 - if (!ret) 277 - goto out; 278 - 279 - /* 280 - * The above can time out if the number of requests was low (2 in the 281 - * worst case) _and_ PCODE was busy for some reason even after a 282 - * (queued) request and @timeout_base_ms delay. As a workaround retry 283 - * the poll with preemption disabled to maximize the number of 284 - * requests. Increase the timeout from @timeout_base_ms to 50ms to 285 - * account for interrupts that could reduce the number of these 286 - * requests, and for any quirks of the PCODE firmware that delays 287 - * the request completion. 288 - */ 289 - drm_dbg_kms(&i915->drm, 290 - "PCODE timeout, retrying with preemption disabled\n"); 291 - drm_WARN_ON_ONCE(&i915->drm, timeout_base_ms > 3); 292 - preempt_disable(); 293 - ret = wait_for_atomic(COND, 50); 294 - preempt_enable(); 295 - 296 - out: 297 - mutex_unlock(&i915->sb_lock); 298 - return ret ? ret : status; 299 - #undef COND 300 - } 301 - 302 - int intel_pcode_init(struct drm_i915_private *i915) 303 - { 304 - int ret = 0; 305 - 306 - if (!IS_DGFX(i915)) 307 - return ret; 308 - 309 - ret = skl_pcode_request(i915, DG1_PCODE_STATUS, 310 - DG1_UNCORE_GET_INIT_STATUS, 311 - DG1_UNCORE_INIT_STATUS_COMPLETE, 312 - DG1_UNCORE_INIT_STATUS_COMPLETE, 180000); 313 - 314 - drm_dbg(&i915->drm, "PCODE init status %d\n", ret); 315 - 316 - if (ret) 317 - drm_err(&i915->drm, "Pcode did not report uncore initialization completion!\n"); 318 - 319 - return ret; 320 - }
-13
drivers/gpu/drm/i915/intel_sideband.h
··· 17 17 void intel_sbi_write(struct drm_i915_private *i915, u16 reg, u32 value, 18 18 enum intel_sbi_destination destination); 19 19 20 - int sandybridge_pcode_read(struct drm_i915_private *i915, u32 mbox, 21 - u32 *val, u32 *val1); 22 - int sandybridge_pcode_write_timeout(struct drm_i915_private *i915, u32 mbox, 23 - u32 val, int fast_timeout_us, 24 - int slow_timeout_ms); 25 - #define sandybridge_pcode_write(i915, mbox, val) \ 26 - sandybridge_pcode_write_timeout(i915, mbox, val, 500, 0) 27 - 28 - int skl_pcode_request(struct drm_i915_private *i915, u32 mbox, u32 request, 29 - u32 reply_mask, u32 reply, int timeout_base_ms); 30 - 31 - int intel_pcode_init(struct drm_i915_private *i915); 32 - 33 20 #endif /* _INTEL_SIDEBAND_H */