1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
8 #define IOBP_RETRY 1000
10 static inline int iobp_poll(void)
14 for (try = IOBP_RETRY
; try > 0; try--) {
15 u16 status
= RCBA16(IOBPS
);
16 if ((status
& IOBPS_READY
) == 0)
21 printk(BIOS_ERR
, "IOBP: timeout waiting for transaction to complete\n");
25 u32
pch_iobp_read(u32 address
)
33 RCBA32(IOBPIRI
) = address
;
36 status
= RCBA16(IOBPS
);
37 status
&= ~IOBPS_MASK
;
39 RCBA16(IOBPS
) = status
;
41 /* Undocumented magic */
42 RCBA16(IOBPU
) = IOBPU_MAGIC
;
45 status
= RCBA16(IOBPS
);
46 status
|= IOBPS_READY
;
47 RCBA16(IOBPS
) = status
;
52 /* Check for successful transaction */
53 status
= RCBA16(IOBPS
);
54 if (status
& IOBPS_TX_MASK
) {
55 printk(BIOS_ERR
, "IOBP: read 0x%08x failed\n", address
);
63 void pch_iobp_write(u32 address
, u32 data
)
71 RCBA32(IOBPIRI
) = address
;
74 status
= RCBA16(IOBPS
);
75 status
&= ~IOBPS_MASK
;
76 status
|= IOBPS_WRITE
;
77 RCBA16(IOBPS
) = status
;
81 /* Undocumented magic */
82 RCBA16(IOBPU
) = IOBPU_MAGIC
;
85 status
= RCBA16(IOBPS
);
86 status
|= IOBPS_READY
;
87 RCBA16(IOBPS
) = status
;
92 /* Check for successful transaction */
93 status
= RCBA16(IOBPS
);
94 if (status
& IOBPS_TX_MASK
) {
95 printk(BIOS_ERR
, "IOBP: write 0x%08x failed\n", address
);
99 printk(BIOS_SPEW
, "IOBP: set 0x%08x to 0x%08x\n", address
, data
);
102 void pch_iobp_update(u32 address
, u32 andvalue
, u32 orvalue
)
104 u32 data
= pch_iobp_read(address
);
106 /* Update the data */
110 pch_iobp_write(address
, data
);
113 void pch_iobp_exec(u32 addr
, u16 op_code
, u8 route_id
, u32
*data
, u8
*resp
)
122 /* RCBA2330[31:0] = Address */
123 RCBA32(IOBPIRI
) = addr
;
124 /* RCBA2338[15:8] = opcode */
125 RCBA16(IOBPS
) = (RCBA16(IOBPS
) & 0x00ff) | op_code
;
126 /* RCBA233A[15:8] = 0xf0 RCBA233A[7:0] = Route ID */
127 RCBA16(IOBPU
) = IOBPU_MAGIC
| route_id
;
129 if (op_code
== IOBP_PCICFG_WRITE
)
130 RCBA32(IOBPD
) = *data
;
131 /* Set RCBA2338[0] to trigger IOBP transaction*/
132 RCBA16(IOBPS
) = RCBA16(IOBPS
) | 0x1;
137 *resp
= (RCBA16(IOBPS
) & IOBPS_TX_MASK
) >> 1;
138 *data
= RCBA32(IOBPD
);