Subversion Repositories Kolibri OS

Rev

Rev 5060 | Go to most recent revision | Details | 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
 
28
/* IOSF sideband */
29
static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
30
			   u32 port, u32 opcode, u32 addr, u32 *val)
31
{
32
	u32 cmd, be = 0xf, bar = 0;
33
	bool is_read = (opcode == PUNIT_OPCODE_REG_READ ||
34
			opcode == DPIO_OPCODE_REG_READ);
35
 
36
	cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
37
		(port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
38
		(bar << IOSF_BAR_SHIFT);
39
 
40
	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
41
 
42
	if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
43
		DRM_DEBUG_DRIVER("IOSF sideband idle wait (%s) timed out\n",
44
				 is_read ? "read" : "write");
45
		return -EAGAIN;
46
	}
47
 
48
	I915_WRITE(VLV_IOSF_ADDR, addr);
49
	if (!is_read)
50
		I915_WRITE(VLV_IOSF_DATA, *val);
51
	I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd);
52
 
53
	if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
54
		DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n",
55
				 is_read ? "read" : "write");
56
		return -ETIMEDOUT;
57
	}
58
 
59
	if (is_read)
60
		*val = I915_READ(VLV_IOSF_DATA);
61
	I915_WRITE(VLV_IOSF_DATA, 0);
62
 
63
	return 0;
64
}
65
 
66
u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr)
67
{
68
	u32 val = 0;
69
 
70
	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
71
 
72
	mutex_lock(&dev_priv->dpio_lock);
73
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
74
			PUNIT_OPCODE_REG_READ, addr, &val);
75
	mutex_unlock(&dev_priv->dpio_lock);
76
 
77
	return val;
78
}
79
 
80
void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val)
81
{
82
	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
83
 
84
	mutex_lock(&dev_priv->dpio_lock);
85
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
86
			PUNIT_OPCODE_REG_WRITE, addr, &val);
87
	mutex_unlock(&dev_priv->dpio_lock);
88
}
89
 
90
u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
91
{
92
	u32 val = 0;
93
 
94
	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
95
 
96
	mutex_lock(&dev_priv->dpio_lock);
97
	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_NC,
98
			PUNIT_OPCODE_REG_READ, addr, &val);
99
	mutex_unlock(&dev_priv->dpio_lock);
100
 
101
	return val;
102
}
103
 
104
u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg)
105
{
106
	u32 val = 0;
107
 
108
	vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_DPIO,
109
			DPIO_OPCODE_REG_READ, reg, &val);
110
 
111
	return val;
112
}
113
 
114
void vlv_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val)
115
{
116
	vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_DPIO,
117
			DPIO_OPCODE_REG_WRITE, reg, &val);
118
}
119
 
120
/* SBI access */
121
u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
122
		   enum intel_sbi_destination destination)
123
{
124
	u32 value = 0;
125
	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
126
 
127
	if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
128
				100)) {
129
		DRM_ERROR("timeout waiting for SBI to become ready\n");
130
		return 0;
131
	}
132
 
133
	I915_WRITE(SBI_ADDR, (reg << 16));
134
 
135
	if (destination == SBI_ICLK)
136
		value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
137
	else
138
		value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
139
	I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY);
140
 
141
	if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
142
				100)) {
143
		DRM_ERROR("timeout waiting for SBI to complete read transaction\n");
144
		return 0;
145
	}
146
 
147
	return I915_READ(SBI_DATA);
148
}
149
 
150
void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
151
		     enum intel_sbi_destination destination)
152
{
153
	u32 tmp;
154
 
155
	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
156
 
157
	if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
158
				100)) {
159
		DRM_ERROR("timeout waiting for SBI to become ready\n");
160
		return;
161
	}
162
 
163
	I915_WRITE(SBI_ADDR, (reg << 16));
164
	I915_WRITE(SBI_DATA, value);
165
 
166
	if (destination == SBI_ICLK)
167
		tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR;
168
	else
169
		tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR;
170
	I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp);
171
 
172
	if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
173
				100)) {
174
		DRM_ERROR("timeout waiting for SBI to complete write transaction\n");
175
		return;
176
	}
177
}