intel_iosf.c 4.39 KB
Newer Older
1 2 3 4 5
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <errno.h>
6

7
#include "intel_io.h"
8
#include "intel_reg.h"
9
#include "igt_core.h"
10 11 12

#define TIMEOUT_US 500000

13 14 15 16 17 18 19 20 21
/* Standard MMIO read, non-posted */
#define SB_MRD_NP      0x00
/* Standard MMIO write, non-posted */
#define SB_MWR_NP      0x01
/* Private register read, double-word addressing, non-posted */
#define SB_CRRDDA_NP   0x06
/* Private register write, double-word addressing, non-posted */
#define SB_CRWRDA_NP   0x07

22
static int vlv_sideband_rw(uint32_t port, uint8_t opcode, uint32_t addr,
23
			   uint32_t *val)
24 25 26
{
	int timeout = 0;
	uint32_t cmd, devfn, be, bar;
27
	int is_read = (opcode == SB_CRRDDA_NP || opcode == SB_MRD_NP);
28 29 30

	bar = 0;
	be = 0xf;
31
	devfn = 0;
32 33 34 35 36

	cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
		(port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
		(bar << IOSF_BAR_SHIFT);

37
	if (intel_register_read(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) {
38
		igt_warn("warning: pcode (%s) mailbox access failed\n", is_read ? "read" : "write");
39 40 41
		return -EAGAIN;
	}

42 43 44 45 46 47
	intel_register_write(VLV_IOSF_ADDR, addr);
	if (!is_read)
		intel_register_write(VLV_IOSF_DATA, *val);

	intel_register_write(VLV_IOSF_DOORBELL_REQ, cmd);

48 49 50
	do {
		usleep(1);
		timeout++;
51 52
	} while (intel_register_read(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY &&
		 timeout < TIMEOUT_US);
53 54

	if (timeout >= TIMEOUT_US) {
55
		igt_warn("timeout waiting for pcode %s (%d) to finish\n", is_read ? "read" : "write", addr);
56 57 58
		return -ETIMEDOUT;
	}

59 60 61
	if (is_read)
		*val = intel_register_read(VLV_IOSF_DATA);
	intel_register_write(VLV_IOSF_DATA, 0);
62 63 64 65

	return 0;
}

66 67 68
/**
 * intel_punit_read:
 * @addr: register offset
69
 * @val: pointer to store the read result
70 71 72 73 74 75
 *
 * 32-bit read of the register at @offset through the P-Unit sideband port.
 *
 * Returns:
 * 0 when the register access succeeded, negative errno code on failure.
 */
76
int intel_punit_read(uint32_t addr, uint32_t *val)
77
{
78
	return vlv_sideband_rw(IOSF_PORT_PUNIT, SB_CRRDDA_NP, addr, val);
79 80
}

81 82 83 84 85 86 87 88 89 90
/**
 * intel_punit_write:
 * @addr: register offset
 * @val: value to write
 *
 * 32-bit write of the register at @offset through the P-Unit sideband port.
 *
 * Returns:
 * 0 when the register access succeeded, negative errno code on failure.
 */
91
int intel_punit_write(uint32_t addr, uint32_t val)
92
{
93
	return vlv_sideband_rw(IOSF_PORT_PUNIT, SB_CRWRDA_NP, addr, &val);
94 95
}

96 97 98 99 100 101 102 103 104 105
/**
 * intel_nc_read:
 * @addr: register offset
 * @val: pointer to starge for the read result
 *
 * 32-bit read of the register at @offset through the NC sideband port.
 *
 * Returns:
 * 0 when the register access succeeded, negative errno code on failure.
 */
106
int intel_nc_read(uint32_t addr, uint32_t *val)
107
{
108
	return vlv_sideband_rw(IOSF_PORT_NC, SB_CRRDDA_NP, addr, val);
109 110
}

111 112 113 114 115 116 117 118 119 120
/**
 * intel_nc_write:
 * @addr: register offset
 * @val: value to write
 *
 * 32-bit write of the register at @offset through the NC sideband port.
 *
 * Returns:
 * 0 when the register access succeeded, negative errno code on failure.
 */
121
int intel_nc_write(uint32_t addr, uint32_t val)
122
{
123
	return vlv_sideband_rw(IOSF_PORT_NC, SB_CRWRDA_NP, addr, &val);
124 125
}

126 127 128 129 130 131 132 133 134 135
/**
 * intel_dpio_reg_read:
 * @reg: register offset
 * @phy: DPIO PHY to use
 *
 * 32-bit read of the register at @offset through the DPIO sideband port.
 *
 * Returns:
 * The value read from the register.
 */
136 137 138 139
uint32_t intel_dpio_reg_read(uint32_t reg, int phy)
{
	uint32_t val;

140 141 142 143
	if (phy == 0)
		vlv_sideband_rw(IOSF_PORT_DPIO, SB_MRD_NP, reg, &val);
	else
		vlv_sideband_rw(IOSF_PORT_DPIO_2, SB_MRD_NP, reg, &val);
144 145 146
	return val;
}

147 148 149 150 151 152 153 154
/**
 * intel_dpio_reg_write:
 * @reg: register offset
 * @val: value to write
 * @phy: dpio PHY to use
 *
 * 32-bit write of the register at @offset through the DPIO sideband port.
 */
155 156
void intel_dpio_reg_write(uint32_t reg, uint32_t val, int phy)
{
157 158 159 160
	if (phy == 0)
		vlv_sideband_rw(IOSF_PORT_DPIO, SB_MWR_NP, reg, &val);
	else
		vlv_sideband_rw(IOSF_PORT_DPIO_2, SB_MWR_NP, reg, &val);
161
}
162 163 164 165 166 167 168 169 170 171 172 173 174 175

uint32_t intel_flisdsi_reg_read(uint32_t reg)
{
	uint32_t val = 0;

	vlv_sideband_rw(IOSF_PORT_FLISDSI, SB_CRRDDA_NP, reg, &val);

	return val;
}

void intel_flisdsi_reg_write(uint32_t reg, uint32_t val)
{
	vlv_sideband_rw(IOSF_PORT_FLISDSI, SB_CRWRDA_NP, reg, &val);
}
176 177 178 179 180 181 182 183 184 185 186 187 188 189

uint32_t intel_iosf_sb_read(uint32_t port, uint32_t reg)
{
	uint32_t val;

	vlv_sideband_rw(port, SB_CRRDDA_NP, reg, &val);

	return val;
}

void intel_iosf_sb_write(uint32_t port, uint32_t reg, uint32_t val)
{
	vlv_sideband_rw(port, SB_CRWRDA_NP, reg, &val);
}