xref: /linux/drivers/gpu/drm/i915/display/intel_sbi.c (revision 7fb3a1f7a48d9512f092d2b18bd4b9361ff88e51)
1*7fb3a1f7SJani Nikula // SPDX-License-Identifier: MIT
2*7fb3a1f7SJani Nikula /*
3*7fb3a1f7SJani Nikula  * Copyright © 2013-2021 Intel Corporation
4*7fb3a1f7SJani Nikula  *
5*7fb3a1f7SJani Nikula  * LPT/WPT IOSF sideband.
6*7fb3a1f7SJani Nikula  */
7*7fb3a1f7SJani Nikula 
8*7fb3a1f7SJani Nikula #include "i915_drv.h"
9*7fb3a1f7SJani Nikula #include "intel_sbi.h"
10*7fb3a1f7SJani Nikula #include "i915_reg.h"
11*7fb3a1f7SJani Nikula 
12*7fb3a1f7SJani Nikula /* SBI access */
13*7fb3a1f7SJani Nikula static int intel_sbi_rw(struct drm_i915_private *i915, u16 reg,
14*7fb3a1f7SJani Nikula 			enum intel_sbi_destination destination,
15*7fb3a1f7SJani Nikula 			u32 *val, bool is_read)
16*7fb3a1f7SJani Nikula {
17*7fb3a1f7SJani Nikula 	struct intel_uncore *uncore = &i915->uncore;
18*7fb3a1f7SJani Nikula 	u32 cmd;
19*7fb3a1f7SJani Nikula 
20*7fb3a1f7SJani Nikula 	lockdep_assert_held(&i915->sbi_lock);
21*7fb3a1f7SJani Nikula 
22*7fb3a1f7SJani Nikula 	if (intel_wait_for_register_fw(uncore,
23*7fb3a1f7SJani Nikula 				       SBI_CTL_STAT, SBI_BUSY, 0,
24*7fb3a1f7SJani Nikula 				       100)) {
25*7fb3a1f7SJani Nikula 		drm_err(&i915->drm,
26*7fb3a1f7SJani Nikula 			"timeout waiting for SBI to become ready\n");
27*7fb3a1f7SJani Nikula 		return -EBUSY;
28*7fb3a1f7SJani Nikula 	}
29*7fb3a1f7SJani Nikula 
30*7fb3a1f7SJani Nikula 	intel_uncore_write_fw(uncore, SBI_ADDR, (u32)reg << 16);
31*7fb3a1f7SJani Nikula 	intel_uncore_write_fw(uncore, SBI_DATA, is_read ? 0 : *val);
32*7fb3a1f7SJani Nikula 
33*7fb3a1f7SJani Nikula 	if (destination == SBI_ICLK)
34*7fb3a1f7SJani Nikula 		cmd = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
35*7fb3a1f7SJani Nikula 	else
36*7fb3a1f7SJani Nikula 		cmd = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
37*7fb3a1f7SJani Nikula 	if (!is_read)
38*7fb3a1f7SJani Nikula 		cmd |= BIT(8);
39*7fb3a1f7SJani Nikula 	intel_uncore_write_fw(uncore, SBI_CTL_STAT, cmd | SBI_BUSY);
40*7fb3a1f7SJani Nikula 
41*7fb3a1f7SJani Nikula 	if (__intel_wait_for_register_fw(uncore,
42*7fb3a1f7SJani Nikula 					 SBI_CTL_STAT, SBI_BUSY, 0,
43*7fb3a1f7SJani Nikula 					 100, 100, &cmd)) {
44*7fb3a1f7SJani Nikula 		drm_err(&i915->drm,
45*7fb3a1f7SJani Nikula 			"timeout waiting for SBI to complete read\n");
46*7fb3a1f7SJani Nikula 		return -ETIMEDOUT;
47*7fb3a1f7SJani Nikula 	}
48*7fb3a1f7SJani Nikula 
49*7fb3a1f7SJani Nikula 	if (cmd & SBI_RESPONSE_FAIL) {
50*7fb3a1f7SJani Nikula 		drm_err(&i915->drm, "error during SBI read of reg %x\n", reg);
51*7fb3a1f7SJani Nikula 		return -ENXIO;
52*7fb3a1f7SJani Nikula 	}
53*7fb3a1f7SJani Nikula 
54*7fb3a1f7SJani Nikula 	if (is_read)
55*7fb3a1f7SJani Nikula 		*val = intel_uncore_read_fw(uncore, SBI_DATA);
56*7fb3a1f7SJani Nikula 
57*7fb3a1f7SJani Nikula 	return 0;
58*7fb3a1f7SJani Nikula }
59*7fb3a1f7SJani Nikula 
60*7fb3a1f7SJani Nikula void intel_sbi_lock(struct drm_i915_private *i915)
61*7fb3a1f7SJani Nikula {
62*7fb3a1f7SJani Nikula 	mutex_lock(&i915->sbi_lock);
63*7fb3a1f7SJani Nikula }
64*7fb3a1f7SJani Nikula 
65*7fb3a1f7SJani Nikula void intel_sbi_unlock(struct drm_i915_private *i915)
66*7fb3a1f7SJani Nikula {
67*7fb3a1f7SJani Nikula 	mutex_unlock(&i915->sbi_lock);
68*7fb3a1f7SJani Nikula }
69*7fb3a1f7SJani Nikula 
70*7fb3a1f7SJani Nikula u32 intel_sbi_read(struct drm_i915_private *i915, u16 reg,
71*7fb3a1f7SJani Nikula 		   enum intel_sbi_destination destination)
72*7fb3a1f7SJani Nikula {
73*7fb3a1f7SJani Nikula 	u32 result = 0;
74*7fb3a1f7SJani Nikula 
75*7fb3a1f7SJani Nikula 	intel_sbi_rw(i915, reg, destination, &result, true);
76*7fb3a1f7SJani Nikula 
77*7fb3a1f7SJani Nikula 	return result;
78*7fb3a1f7SJani Nikula }
79*7fb3a1f7SJani Nikula 
80*7fb3a1f7SJani Nikula void intel_sbi_write(struct drm_i915_private *i915, u16 reg, u32 value,
81*7fb3a1f7SJani Nikula 		     enum intel_sbi_destination destination)
82*7fb3a1f7SJani Nikula {
83*7fb3a1f7SJani Nikula 	intel_sbi_rw(i915, reg, destination, &value, false);
84*7fb3a1f7SJani Nikula }
85*7fb3a1f7SJani Nikula 
86*7fb3a1f7SJani Nikula void intel_sbi_init(struct drm_i915_private *i915)
87*7fb3a1f7SJani Nikula {
88*7fb3a1f7SJani Nikula 	mutex_init(&i915->sbi_lock);
89*7fb3a1f7SJani Nikula }
90*7fb3a1f7SJani Nikula 
91*7fb3a1f7SJani Nikula void intel_sbi_fini(struct drm_i915_private *i915)
92*7fb3a1f7SJani Nikula {
93*7fb3a1f7SJani Nikula 	mutex_destroy(&i915->sbi_lock);
94*7fb3a1f7SJani Nikula }
95