summaryrefslogtreecommitdiff
path: root/include/p2sb.h
blob: a25170e3d1195357be3e241fba6363a678f3187d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * Copyright 2019 Google LLC
 * Written by Simon Glass <sjg@chromium.org>
 */

#ifndef __p2sb_h
#define __p2sb_h

/* Port Id lives in bits 23:16 and register offset lives in 15:0 of address */
#define PCR_PORTID_SHIFT	16

#if !defined(__ACPI__)

/* These registers contain IOAPIC and HPET devfn */
#define PCH_P2SB_IBDF		0x6c
#define PCH_P2SB_HBDF		0x70

/**
 * struct p2sb_child_platdata - Information about each child of a p2sb device
 *
 * @pid: Port ID for this child
 */
struct p2sb_child_platdata {
	uint pid;
};

/**
 * struct p2sb_uc_priv - information for the uclass about each device
 *
 * This must be set up by the driver when it is probed
 *
 * @mmio_base: Base address of P2SB region
 */
struct p2sb_uc_priv {
	uint mmio_base;
};

/**
 * struct p2sb_ops - Operations for the P2SB
 */
struct p2sb_ops {
	/**
	 * set_hide() - Set/clear the 'hide' bit on the p2sb
	 *
	 * This device can be hidden from the PCI bus if needed. This method
	 * can be called before the p2sb is probed.
	 *
	 * @dev: P2SB device
	 * @hide: true to hide the device, false to show it
	 * @return 0 if OK, -ve on error
	 */
	int (*set_hide)(struct udevice *dev, bool hide);
};

#define p2sb_get_ops(dev)        ((struct p2sb_ops *)(dev)->driver->ops)

/**
 * p2sb_set_hide() - Set/clear the 'hide' bit on the p2sb
 *
 * This device can be hidden from the PCI bus if needed. This method
 * can be called before the p2sb is probed.
 *
 * @dev: P2SB device
 * @hide: true to hide the device, false to show it
 * @return 0 if OK, -ve on error
 */
int p2sb_set_hide(struct udevice *dev, bool hide);

/**
 * pcr_read32/16/8() - Read from a PCR device
 *
 * Reads data from a PCR device within the P2SB
 *
 * @dev: Device to read from
 * @offset: Offset within device to read
 * @return value read
 */
uint pcr_read32(struct udevice *dev, uint offset);
uint pcr_read16(struct udevice *dev, uint offset);
uint pcr_read8(struct udevice *dev, uint offset);

/**
 * pcr_read32/16/8() - Write to a PCR device
 *
 * Writes data to a PCR device within the P2SB
 *
 * @dev: Device to write to
 * @offset: Offset within device to write
 * @data: Data to write
 */
void pcr_write32(struct udevice *dev, uint offset, uint data);
void pcr_write16(struct udevice *dev, uint offset, uint data);
void pcr_write8(struct udevice *dev, uint offset, uint data);

/**
 * pcr_clrsetbits32/16/8() - Update a PCR device
 *
 * Updates dat in a PCR device within the P2SB
 *
 * This reads from the device, clears and set bits, then writes back.
 *
 * new_data = (old_data & ~clr) | set
 *
 * @dev: Device to update
 * @offset: Offset within device to update
 * @clr: Bits to clear after reading
 * @set: Bits to set before writing
 */
void pcr_clrsetbits32(struct udevice *dev, uint offset, uint clr, uint set);
void pcr_clrsetbits16(struct udevice *dev, uint offset, uint clr, uint set);
void pcr_clrsetbits8(struct udevice *dev, uint offset, uint clr, uint set);

static inline void pcr_setbits32(struct udevice *dev, uint offset, uint set)
{
	return pcr_clrsetbits32(dev, offset, 0, set);
}

static inline void pcr_setbits16(struct udevice *dev, uint offset, uint set)
{
	return pcr_clrsetbits16(dev, offset, 0, set);
}

static inline void pcr_setbits8(struct udevice *dev, uint offset, uint set)
{
	return pcr_clrsetbits8(dev, offset, 0, set);
}

static inline void pcr_clrbits32(struct udevice *dev, uint offset, uint clr)
{
	return pcr_clrsetbits32(dev, offset, clr, 0);
}

static inline void pcr_clrbits16(struct udevice *dev, uint offset, uint clr)
{
	return pcr_clrsetbits16(dev, offset, clr, 0);
}

static inline void pcr_clrbits8(struct udevice *dev, uint offset, uint clr)
{
	return pcr_clrsetbits8(dev, offset, clr, 0);
}

/**
 * p2sb_set_port_id() - Set the port ID for a p2sb child device
 *
 * This must be called in a device's bind() method when OF_PLATDATA is used
 * since the uclass cannot access the device's of-platdata.
 *
 * @dev: Child device (whose parent is UCLASS_P2SB)
 * @portid: Port ID of child device
 * @return 0 if OK, -ENODEV is the p2sb device could not be found
 */
int p2sb_set_port_id(struct udevice *dev, int portid);

/**
 * p2sb_get_port_id() - Get the port ID for a p2sb child device
 *
 * @dev: Child device (whose parent is UCLASS_P2SB)
 * @return Port ID of that child
 */
int p2sb_get_port_id(struct udevice *dev);

/**
 * pcr_reg_address() Convert an offset in p2sb space to an absolute address
 *
 * @dev: Child device (whose parent is UCLASS_P2SB)
 * @offset: Offset within that child's address space
 * @return pointer to that offset within the child's address space
 */
void *pcr_reg_address(struct udevice *dev, uint offset);

#endif /* !__ACPI__ */

#endif