]>
Commit | Line | Data |
---|---|---|
8c74a573 SG |
1 | /* |
2 | * From Coreboot | |
3 | * Copyright (C) 2008-2009 coresystems GmbH | |
4 | * Copyright (C) 2012 The Chromium OS Authors. | |
5 | * | |
6 | * SPDX-License-Identifier: GPL-2.0 | |
7 | */ | |
8 | ||
9 | #include <common.h> | |
10 | #include <asm/io.h> | |
11 | #include <asm/pci.h> | |
12 | #include <asm/arch/pch.h> | |
13 | ||
14 | static int pch_revision_id = -1; | |
15 | static int pch_type = -1; | |
16 | ||
9434c7a3 | 17 | int pch_silicon_revision(struct udevice *dev) |
8c74a573 | 18 | { |
9434c7a3 | 19 | u8 val; |
8c74a573 | 20 | |
9434c7a3 SG |
21 | if (pch_revision_id < 0) { |
22 | dm_pci_read_config8(dev, PCI_REVISION_ID, &val); | |
23 | pch_revision_id = val; | |
24 | } | |
8c74a573 | 25 | |
8c74a573 SG |
26 | return pch_revision_id; |
27 | } | |
28 | ||
9434c7a3 | 29 | int pch_silicon_type(struct udevice *dev) |
8c74a573 | 30 | { |
9434c7a3 | 31 | u8 val; |
8c74a573 | 32 | |
9434c7a3 SG |
33 | if (pch_type < 0) { |
34 | dm_pci_read_config8(dev, PCI_DEVICE_ID + 1, &val); | |
35 | pch_type = val; | |
36 | } | |
8c74a573 | 37 | |
8c74a573 SG |
38 | return pch_type; |
39 | } | |
40 | ||
9434c7a3 | 41 | int pch_silicon_supported(struct udevice *dev, int type, int rev) |
8c74a573 | 42 | { |
9434c7a3 SG |
43 | int cur_type = pch_silicon_type(dev); |
44 | int cur_rev = pch_silicon_revision(dev); | |
8c74a573 SG |
45 | |
46 | switch (type) { | |
47 | case PCH_TYPE_CPT: | |
48 | /* CougarPoint minimum revision */ | |
49 | if (cur_type == PCH_TYPE_CPT && cur_rev >= rev) | |
50 | return 1; | |
51 | /* PantherPoint any revision */ | |
52 | if (cur_type == PCH_TYPE_PPT) | |
53 | return 1; | |
54 | break; | |
55 | ||
56 | case PCH_TYPE_PPT: | |
57 | /* PantherPoint minimum revision */ | |
58 | if (cur_type == PCH_TYPE_PPT && cur_rev >= rev) | |
59 | return 1; | |
60 | break; | |
61 | } | |
62 | ||
63 | return 0; | |
64 | } | |
65 | ||
66 | #define IOBP_RETRY 1000 | |
67 | static inline int iobp_poll(void) | |
68 | { | |
69 | unsigned try = IOBP_RETRY; | |
70 | u32 data; | |
71 | ||
72 | while (try--) { | |
73 | data = readl(RCB_REG(IOBPS)); | |
74 | if ((data & 1) == 0) | |
75 | return 1; | |
76 | udelay(10); | |
77 | } | |
78 | ||
79 | printf("IOBP timeout\n"); | |
80 | return 0; | |
81 | } | |
82 | ||
9434c7a3 SG |
83 | void pch_iobp_update(struct udevice *dev, u32 address, u32 andvalue, |
84 | u32 orvalue) | |
8c74a573 SG |
85 | { |
86 | u32 data; | |
87 | ||
88 | /* Set the address */ | |
89 | writel(address, RCB_REG(IOBPIRI)); | |
90 | ||
91 | /* READ OPCODE */ | |
9434c7a3 | 92 | if (pch_silicon_supported(dev, PCH_TYPE_CPT, PCH_STEP_B0)) |
8c74a573 SG |
93 | writel(IOBPS_RW_BX, RCB_REG(IOBPS)); |
94 | else | |
95 | writel(IOBPS_READ_AX, RCB_REG(IOBPS)); | |
96 | if (!iobp_poll()) | |
97 | return; | |
98 | ||
99 | /* Read IOBP data */ | |
100 | data = readl(RCB_REG(IOBPD)); | |
101 | if (!iobp_poll()) | |
102 | return; | |
103 | ||
104 | /* Check for successful transaction */ | |
105 | if ((readl(RCB_REG(IOBPS)) & 0x6) != 0) { | |
106 | printf("IOBP read 0x%08x failed\n", address); | |
107 | return; | |
108 | } | |
109 | ||
110 | /* Update the data */ | |
111 | data &= andvalue; | |
112 | data |= orvalue; | |
113 | ||
114 | /* WRITE OPCODE */ | |
9434c7a3 | 115 | if (pch_silicon_supported(dev, PCH_TYPE_CPT, PCH_STEP_B0)) |
8c74a573 SG |
116 | writel(IOBPS_RW_BX, RCB_REG(IOBPS)); |
117 | else | |
118 | writel(IOBPS_WRITE_AX, RCB_REG(IOBPS)); | |
119 | if (!iobp_poll()) | |
120 | return; | |
121 | ||
122 | /* Write IOBP data */ | |
123 | writel(data, RCB_REG(IOBPD)); | |
124 | if (!iobp_poll()) | |
125 | return; | |
126 | } |