xref: /aosp_15_r20/external/coreboot/src/southbridge/intel/bd82x6x/common.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #define __SIMPLE_DEVICE__
4 
5 #include <console/console.h>
6 #include <delay.h>
7 #include <device/pci.h>
8 #include <device/pci_ids.h>
9 #include <device/pci_ops.h>
10 #include <stdint.h>
11 
12 #include "pch.h"
13 
pch_silicon_revision(void)14 int pch_silicon_revision(void)
15 {
16 	static int pch_revision_id = 0;
17 
18 	if (!pch_revision_id)
19 		pch_revision_id = pci_read_config8(PCH_LPC_DEV, PCI_REVISION_ID);
20 
21 	return pch_revision_id;
22 }
23 
pch_silicon_type(void)24 int pch_silicon_type(void)
25 {
26 	static int pch_type = 0;
27 
28 	if (!pch_type)
29 		pch_type = pci_read_config8(PCH_LPC_DEV, PCI_DEVICE_ID + 1);
30 
31 	return pch_type;
32 }
33 
pch_is_mobile(void)34 bool pch_is_mobile(void)
35 {
36 	const u16 devids[] = {
37 		PCI_DID_INTEL_6_SERIES_MOBILE_SFF, PCI_DID_INTEL_6_SERIES_MOBILE,
38 		PCI_DID_INTEL_6_SERIES_UM67, PCI_DID_INTEL_6_SERIES_HM65,
39 		PCI_DID_INTEL_6_SERIES_HM67, PCI_DID_INTEL_6_SERIES_QS67,
40 		PCI_DID_INTEL_6_SERIES_QM67,
41 		PCI_DID_INTEL_7_SERIES_MOBILE, PCI_DID_INTEL_7_SERIES_MOBILE_SFF,
42 		PCI_DID_INTEL_7_SERIES_QM77, PCI_DID_INTEL_7_SERIES_QS77,
43 		PCI_DID_INTEL_7_SERIES_HM77, PCI_DID_INTEL_7_SERIES_UM77,
44 		PCI_DID_INTEL_7_SERIES_HM76, PCI_DID_INTEL_7_SERIES_HM75,
45 		PCI_DID_INTEL_7_SERIES_HM70, PCI_DID_INTEL_7_SERIES_NM70
46 	};
47 	u16 devid = pci_s_read_config16(PCH_LPC_DEV, PCI_DEVICE_ID);
48 
49 	for (size_t i = 0; i < ARRAY_SIZE(devids); i++)
50 		if (devid == devids[i])
51 			return true;
52 	return false;
53 }
54 
pch_silicon_supported(int type,int rev)55 int pch_silicon_supported(int type, int rev)
56 {
57 	int cur_type = pch_silicon_type();
58 	int cur_rev = pch_silicon_revision();
59 
60 	switch (type) {
61 	case PCH_TYPE_CPT:
62 		/* CougarPoint minimum revision */
63 		if (cur_type == PCH_TYPE_CPT && cur_rev >= rev)
64 			return 1;
65 		/* PantherPoint any revision */
66 		if (cur_type == PCH_TYPE_PPT)
67 			return 1;
68 		break;
69 
70 	case PCH_TYPE_PPT:
71 		/* PantherPoint minimum revision */
72 		if (cur_type == PCH_TYPE_PPT && cur_rev >= rev)
73 			return 1;
74 		break;
75 	}
76 
77 	return 0;
78 }
79 
80 #define IOBP_RETRY 1000
iobp_poll(void)81 static inline int iobp_poll(void)
82 {
83 	unsigned int try = IOBP_RETRY;
84 	u32 data;
85 
86 	while (try--) {
87 		data = RCBA32(IOBPS);
88 		if ((data & 1) == 0)
89 			return 1;
90 		udelay(10);
91 	}
92 
93 	printk(BIOS_ERR, "IOBP timeout\n");
94 	return 0;
95 }
96 
pch_iobp_update(u32 address,u32 andvalue,u32 orvalue)97 void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
98 {
99 	u32 data;
100 
101 	/* Set the address */
102 	RCBA32(IOBPIRI) = address;
103 
104 	/* READ OPCODE */
105 	if (pch_silicon_supported(PCH_TYPE_CPT, PCH_STEP_B0))
106 		RCBA32(IOBPS) = IOBPS_RW_BX;
107 	else
108 		RCBA32(IOBPS) = IOBPS_READ_AX;
109 	if (!iobp_poll())
110 		return;
111 
112 	/* Read IOBP data */
113 	data = RCBA32(IOBPD);
114 	if (!iobp_poll())
115 		return;
116 
117 	/* Check for successful transaction */
118 	if ((RCBA32(IOBPS) & 0x6) != 0) {
119 		printk(BIOS_ERR, "IOBP read 0x%08x failed\n", address);
120 		return;
121 	}
122 
123 	/* Update the data */
124 	data &= andvalue;
125 	data |= orvalue;
126 
127 	/* WRITE OPCODE */
128 	if (pch_silicon_supported(PCH_TYPE_CPT, PCH_STEP_B0))
129 		RCBA32(IOBPS) = IOBPS_RW_BX;
130 	else
131 		RCBA32(IOBPS) = IOBPS_WRITE_AX;
132 	if (!iobp_poll())
133 		return;
134 
135 	/* Write IOBP data */
136 	RCBA32(IOBPD) = data;
137 	if (!iobp_poll())
138 		return;
139 }
140