Subversion Repositories Kolibri OS

Rev

Rev 4104 | Rev 5060 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4104 Serge 1
/*
2
 * Copyright © 2013 Intel Corporation
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice (including the next
12
 * paragraph) shall be included in all copies or substantial portions of the
13
 * Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
 * IN THE SOFTWARE.
22
 *
23
 */
24
 
25
#include "i915_drv.h"
26
#include "intel_drv.h"
27
 
4560 Serge 28
/*
29
 * IOSF sideband, see VLV2_SidebandMsg_HAS.docx and
30
 * VLV_VLV2_PUNIT_HAS_0.8.docx
31
 */
4104 Serge 32
static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
33
			   u32 port, u32 opcode, u32 addr, u32 *val)
34
{
35
	u32 cmd, be = 0xf, bar = 0;
36
	bool is_read = (opcode == PUNIT_OPCODE_REG_READ ||
37
			opcode == DPIO_OPCODE_REG_READ);
38
 
39
	cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
40
		(port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
41
		(bar << IOSF_BAR_SHIFT);
42
 
43
	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
44
 
45
	if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
46
		DRM_DEBUG_DRIVER("IOSF sideband idle wait (%s) timed out\n",
47
				 is_read ? "read" : "write");
48
		return -EAGAIN;
49
	}
50
 
51
	I915_WRITE(VLV_IOSF_ADDR, addr);
52
	if (!is_read)
53
		I915_WRITE(VLV_IOSF_DATA, *val);
54
	I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd);
55
 
56
	if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
57
		DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n",
58
				 is_read ? "read" : "write");
59
		return -ETIMEDOUT;
60
	}
61
 
62
	if (is_read)
63
		*val = I915_READ(VLV_IOSF_DATA);
64
	I915_WRITE(VLV_IOSF_DATA, 0);
65
 
66
	return 0;
67
}
68
 
69
u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr)
70
{
71
	u32 val = 0;
72
 
73
	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
74
 
75
	mutex_lock(&dev_priv->dpio_lock);
76
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
77
			PUNIT_OPCODE_REG_READ, addr, &val);
78
	mutex_unlock(&dev_priv->dpio_lock);
79
 
80
	return val;
81
}
82
 
83
void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val)
84
{
85
	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
86
 
87
	mutex_lock(&dev_priv->dpio_lock);
88
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
89
			PUNIT_OPCODE_REG_WRITE, addr, &val);
90
	mutex_unlock(&dev_priv->dpio_lock);
91
}
92
 
4560 Serge 93
u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg)
94
{
95
	u32 val = 0;
96
 
97
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_BUNIT,
98
			PUNIT_OPCODE_REG_READ, reg, &val);
99
 
100
	return val;
101
}
102
 
103
void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
104
{
105
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_BUNIT,
106
			PUNIT_OPCODE_REG_WRITE, reg, &val);
107
}
108
 
4104 Serge 109
u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
110
{
111
	u32 val = 0;
112
 
113
	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
114
 
115
	mutex_lock(&dev_priv->dpio_lock);
116
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_NC,
117
			PUNIT_OPCODE_REG_READ, addr, &val);
118
	mutex_unlock(&dev_priv->dpio_lock);
119
 
120
	return val;
121
}
122
 
4560 Serge 123
u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg)
4104 Serge 124
{
125
	u32 val = 0;
4560 Serge 126
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPIO_NC,
127
			PUNIT_OPCODE_REG_READ, reg, &val);
128
	return val;
129
}
4104 Serge 130
 
4560 Serge 131
void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
132
{
133
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPIO_NC,
134
			PUNIT_OPCODE_REG_WRITE, reg, &val);
135
}
4104 Serge 136
 
4560 Serge 137
u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg)
138
{
139
	u32 val = 0;
140
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCK,
141
			PUNIT_OPCODE_REG_READ, reg, &val);
4104 Serge 142
	return val;
143
}
144
 
4560 Serge 145
void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
4104 Serge 146
{
4560 Serge 147
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCK,
148
			PUNIT_OPCODE_REG_WRITE, reg, &val);
149
}
150
 
151
u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg)
152
{
153
	u32 val = 0;
154
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCU,
155
			PUNIT_OPCODE_REG_READ, reg, &val);
156
	return val;
157
}
158
 
159
void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
160
{
161
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCU,
162
			PUNIT_OPCODE_REG_WRITE, reg, &val);
163
}
164
 
165
u32 vlv_gps_core_read(struct drm_i915_private *dev_priv, u32 reg)
166
{
167
	u32 val = 0;
168
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPS_CORE,
169
			PUNIT_OPCODE_REG_READ, reg, &val);
170
	return val;
171
}
172
 
173
void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
174
{
175
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPS_CORE,
176
			PUNIT_OPCODE_REG_WRITE, reg, &val);
177
}
178
 
179
u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg)
180
{
181
	u32 val = 0;
182
 
183
	vlv_sideband_rw(dev_priv, DPIO_DEVFN, DPIO_PHY_IOSF_PORT(DPIO_PHY(pipe)),
184
			DPIO_OPCODE_REG_READ, reg, &val);
185
	return val;
186
}
187
 
188
void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val)
189
{
190
	vlv_sideband_rw(dev_priv, DPIO_DEVFN, DPIO_PHY_IOSF_PORT(DPIO_PHY(pipe)),
4104 Serge 191
			DPIO_OPCODE_REG_WRITE, reg, &val);
192
}
193
 
194
/* SBI access */
195
u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
196
		   enum intel_sbi_destination destination)
197
{
198
	u32 value = 0;
199
	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
200
 
201
	if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
202
				100)) {
203
		DRM_ERROR("timeout waiting for SBI to become ready\n");
204
		return 0;
205
	}
206
 
207
	I915_WRITE(SBI_ADDR, (reg << 16));
208
 
209
	if (destination == SBI_ICLK)
210
		value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
211
	else
212
		value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
213
	I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY);
214
 
215
	if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
216
				100)) {
217
		DRM_ERROR("timeout waiting for SBI to complete read transaction\n");
218
		return 0;
219
	}
220
 
221
	return I915_READ(SBI_DATA);
222
}
223
 
224
void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
225
		     enum intel_sbi_destination destination)
226
{
227
	u32 tmp;
228
 
229
	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
230
 
231
	if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
232
				100)) {
233
		DRM_ERROR("timeout waiting for SBI to become ready\n");
234
		return;
235
	}
236
 
237
	I915_WRITE(SBI_ADDR, (reg << 16));
238
	I915_WRITE(SBI_DATA, value);
239
 
240
	if (destination == SBI_ICLK)
241
		tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR;
242
	else
243
		tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR;
244
	I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp);
245
 
246
	if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
247
				100)) {
248
		DRM_ERROR("timeout waiting for SBI to complete write transaction\n");
249
		return;
250
	}
251
}
4560 Serge 252
 
253
u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg)
254
{
255
	u32 val = 0;
256
	vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI,
257
					DPIO_OPCODE_REG_READ, reg, &val);
258
	return val;
259
}
260
 
261
void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
262
{
263
	vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI,
264
					DPIO_OPCODE_REG_WRITE, reg, &val);
265
}