blob: 3b5a137000aa7f100947d37db3a02a14aeaf7e22 [file] [log] [blame]
Jesse Barnes25339592013-04-16 13:14:58 -07001#include <unistd.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <err.h>
5#include <errno.h>
Daniel Vetter71ac5de2014-08-26 15:13:06 +02006
Daniel Vetterc03c6ce2014-03-22 21:34:29 +01007#include "intel_io.h"
Daniel Vetter6cfcd712014-03-22 20:07:35 +01008#include "intel_reg.h"
Daniel Vetter71ac5de2014-08-26 15:13:06 +02009#include "igt_core.h"
Jesse Barnes25339592013-04-16 13:14:58 -070010
11#define TIMEOUT_US 500000
12
Imre Deakad089992014-05-19 13:26:35 +030013/* Standard MMIO read, non-posted */
14#define SB_MRD_NP 0x00
15/* Standard MMIO write, non-posted */
16#define SB_MWR_NP 0x01
17/* Private register read, double-word addressing, non-posted */
18#define SB_CRRDDA_NP 0x06
19/* Private register write, double-word addressing, non-posted */
20#define SB_CRWRDA_NP 0x07
21
Jesse Barnes5e21b432014-01-28 14:17:30 -080022static int vlv_sideband_rw(uint32_t port, uint8_t opcode, uint32_t addr,
Jesse Barnes81095302014-01-28 13:46:38 -080023 uint32_t *val)
Jesse Barnes25339592013-04-16 13:14:58 -070024{
Jesse Barnes25339592013-04-16 13:14:58 -070025 int timeout = 0;
26 uint32_t cmd, devfn, be, bar;
Imre Deakad089992014-05-19 13:26:35 +030027 int is_read = (opcode == SB_CRRDDA_NP || opcode == SB_MRD_NP);
Jesse Barnes25339592013-04-16 13:14:58 -070028
29 bar = 0;
30 be = 0xf;
Ville Syrjälä0a3ef582015-02-05 16:12:11 +020031 devfn = 0;
Jesse Barnes25339592013-04-16 13:14:58 -070032
33 cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
34 (port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
35 (bar << IOSF_BAR_SHIFT);
36
Jesse Barnes5e21b432014-01-28 14:17:30 -080037 if (intel_register_read(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) {
Daniel Vetter71ac5de2014-08-26 15:13:06 +020038 igt_warn("warning: pcode (%s) mailbox access failed\n", is_read ? "read" : "write");
Jesse Barnes25339592013-04-16 13:14:58 -070039 return -EAGAIN;
40 }
41
Jesse Barnes5e21b432014-01-28 14:17:30 -080042 intel_register_write(VLV_IOSF_ADDR, addr);
43 if (!is_read)
44 intel_register_write(VLV_IOSF_DATA, *val);
45
46 intel_register_write(VLV_IOSF_DOORBELL_REQ, cmd);
47
Jesse Barnes25339592013-04-16 13:14:58 -070048 do {
49 usleep(1);
50 timeout++;
Jesse Barnes5e21b432014-01-28 14:17:30 -080051 } while (intel_register_read(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY &&
52 timeout < TIMEOUT_US);
Jesse Barnes25339592013-04-16 13:14:58 -070053
54 if (timeout >= TIMEOUT_US) {
Daniel Vetter71ac5de2014-08-26 15:13:06 +020055 igt_warn("timeout waiting for pcode %s (%d) to finish\n", is_read ? "read" : "write", addr);
Jesse Barnes25339592013-04-16 13:14:58 -070056 return -ETIMEDOUT;
57 }
58
Jesse Barnes5e21b432014-01-28 14:17:30 -080059 if (is_read)
60 *val = intel_register_read(VLV_IOSF_DATA);
61 intel_register_write(VLV_IOSF_DATA, 0);
Jesse Barnes25339592013-04-16 13:14:58 -070062
63 return 0;
64}
65
Daniel Vetter95e89f02014-03-22 22:41:28 +010066/**
67 * intel_punit_read:
68 * @addr: register offset
Thomas Woodd01ebbd2015-06-29 16:47:14 +010069 * @val: pointer to store the read result
Daniel Vetter95e89f02014-03-22 22:41:28 +010070 *
71 * 32-bit read of the register at @offset through the P-Unit sideband port.
72 *
73 * Returns:
74 * 0 when the register access succeeded, negative errno code on failure.
75 */
Ville Syrjäläac28ece2015-03-16 13:36:50 +020076int intel_punit_read(uint32_t addr, uint32_t *val)
Jesse Barnes25339592013-04-16 13:14:58 -070077{
Imre Deakad089992014-05-19 13:26:35 +030078 return vlv_sideband_rw(IOSF_PORT_PUNIT, SB_CRRDDA_NP, addr, val);
Jesse Barnes25339592013-04-16 13:14:58 -070079}
80
Daniel Vetter95e89f02014-03-22 22:41:28 +010081/**
82 * intel_punit_write:
83 * @addr: register offset
84 * @val: value to write
85 *
86 * 32-bit write of the register at @offset through the P-Unit sideband port.
87 *
88 * Returns:
89 * 0 when the register access succeeded, negative errno code on failure.
90 */
Ville Syrjäläac28ece2015-03-16 13:36:50 +020091int intel_punit_write(uint32_t addr, uint32_t val)
Jesse Barnes25339592013-04-16 13:14:58 -070092{
Imre Deakad089992014-05-19 13:26:35 +030093 return vlv_sideband_rw(IOSF_PORT_PUNIT, SB_CRWRDA_NP, addr, &val);
Jesse Barnes25339592013-04-16 13:14:58 -070094}
95
Daniel Vetter95e89f02014-03-22 22:41:28 +010096/**
97 * intel_nc_read:
98 * @addr: register offset
99 * @val: pointer to starge for the read result
100 *
101 * 32-bit read of the register at @offset through the NC sideband port.
102 *
103 * Returns:
104 * 0 when the register access succeeded, negative errno code on failure.
105 */
Ville Syrjäläac28ece2015-03-16 13:36:50 +0200106int intel_nc_read(uint32_t addr, uint32_t *val)
Jesse Barnes25339592013-04-16 13:14:58 -0700107{
Imre Deakad089992014-05-19 13:26:35 +0300108 return vlv_sideband_rw(IOSF_PORT_NC, SB_CRRDDA_NP, addr, val);
Jesse Barnes25339592013-04-16 13:14:58 -0700109}
110
Daniel Vetter95e89f02014-03-22 22:41:28 +0100111/**
112 * intel_nc_write:
113 * @addr: register offset
114 * @val: value to write
115 *
116 * 32-bit write of the register at @offset through the NC sideband port.
117 *
118 * Returns:
119 * 0 when the register access succeeded, negative errno code on failure.
120 */
Ville Syrjäläac28ece2015-03-16 13:36:50 +0200121int intel_nc_write(uint32_t addr, uint32_t val)
Jesse Barnes25339592013-04-16 13:14:58 -0700122{
Imre Deakad089992014-05-19 13:26:35 +0300123 return vlv_sideband_rw(IOSF_PORT_NC, SB_CRWRDA_NP, addr, &val);
Jesse Barnes81095302014-01-28 13:46:38 -0800124}
125
Daniel Vetter95e89f02014-03-22 22:41:28 +0100126/**
127 * intel_dpio_reg_read:
128 * @reg: register offset
129 * @phy: DPIO PHY to use
130 *
131 * 32-bit read of the register at @offset through the DPIO sideband port.
132 *
133 * Returns:
134 * The value read from the register.
135 */
Jesse Barnes81095302014-01-28 13:46:38 -0800136uint32_t intel_dpio_reg_read(uint32_t reg, int phy)
137{
138 uint32_t val;
139
Ville Syrjälä0f906082014-05-28 18:26:39 +0300140 if (phy == 0)
141 vlv_sideband_rw(IOSF_PORT_DPIO, SB_MRD_NP, reg, &val);
142 else
143 vlv_sideband_rw(IOSF_PORT_DPIO_2, SB_MRD_NP, reg, &val);
Jesse Barnes81095302014-01-28 13:46:38 -0800144 return val;
145}
146
Daniel Vetter95e89f02014-03-22 22:41:28 +0100147/**
148 * intel_dpio_reg_write:
149 * @reg: register offset
150 * @val: value to write
151 * @phy: dpio PHY to use
152 *
153 * 32-bit write of the register at @offset through the DPIO sideband port.
154 */
Jesse Barnes81095302014-01-28 13:46:38 -0800155void intel_dpio_reg_write(uint32_t reg, uint32_t val, int phy)
156{
Ville Syrjälä0f906082014-05-28 18:26:39 +0300157 if (phy == 0)
158 vlv_sideband_rw(IOSF_PORT_DPIO, SB_MWR_NP, reg, &val);
159 else
160 vlv_sideband_rw(IOSF_PORT_DPIO_2, SB_MWR_NP, reg, &val);
Jesse Barnes25339592013-04-16 13:14:58 -0700161}
Imre Deaka6eaa292014-05-18 23:37:56 +0300162
163uint32_t intel_flisdsi_reg_read(uint32_t reg)
164{
165 uint32_t val = 0;
166
167 vlv_sideband_rw(IOSF_PORT_FLISDSI, SB_CRRDDA_NP, reg, &val);
168
169 return val;
170}
171
172void intel_flisdsi_reg_write(uint32_t reg, uint32_t val)
173{
174 vlv_sideband_rw(IOSF_PORT_FLISDSI, SB_CRWRDA_NP, reg, &val);
175}
Ville Syrjälä71874f42014-06-10 21:28:10 +0300176
177uint32_t intel_iosf_sb_read(uint32_t port, uint32_t reg)
178{
179 uint32_t val;
180
181 vlv_sideband_rw(port, SB_CRRDDA_NP, reg, &val);
182
183 return val;
184}
185
186void intel_iosf_sb_write(uint32_t port, uint32_t reg, uint32_t val)
187{
188 vlv_sideband_rw(port, SB_CRWRDA_NP, reg, &val);
189}