blob: bbab64699e8791f7e27c6492e9adfb2e4a4a0c55 [file] [log] [blame]
Simon Glassf3077082014-11-14 18:18:34 -07001/*
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
14static int pch_revision_id = -1;
15static int pch_type = -1;
16
17int pch_silicon_revision(void)
18{
19 pci_dev_t dev;
20
21 dev = PCH_LPC_DEV;
22
23 if (pch_revision_id < 0)
Simon Glass240d06d2015-03-05 12:25:15 -070024 pch_revision_id = x86_pci_read_config8(dev, PCI_REVISION_ID);
Simon Glassf3077082014-11-14 18:18:34 -070025 return pch_revision_id;
26}
27
28int pch_silicon_type(void)
29{
30 pci_dev_t dev;
31
32 dev = PCH_LPC_DEV;
33
34 if (pch_type < 0)
Simon Glass240d06d2015-03-05 12:25:15 -070035 pch_type = x86_pci_read_config8(dev, PCI_DEVICE_ID + 1);
Simon Glassf3077082014-11-14 18:18:34 -070036 return pch_type;
37}
38
39int pch_silicon_supported(int type, int rev)
40{
41 int cur_type = pch_silicon_type();
42 int cur_rev = pch_silicon_revision();
43
44 switch (type) {
45 case PCH_TYPE_CPT:
46 /* CougarPoint minimum revision */
47 if (cur_type == PCH_TYPE_CPT && cur_rev >= rev)
48 return 1;
49 /* PantherPoint any revision */
50 if (cur_type == PCH_TYPE_PPT)
51 return 1;
52 break;
53
54 case PCH_TYPE_PPT:
55 /* PantherPoint minimum revision */
56 if (cur_type == PCH_TYPE_PPT && cur_rev >= rev)
57 return 1;
58 break;
59 }
60
61 return 0;
62}
63
64#define IOBP_RETRY 1000
65static inline int iobp_poll(void)
66{
67 unsigned try = IOBP_RETRY;
68 u32 data;
69
70 while (try--) {
71 data = readl(RCB_REG(IOBPS));
72 if ((data & 1) == 0)
73 return 1;
74 udelay(10);
75 }
76
77 printf("IOBP timeout\n");
78 return 0;
79}
80
81void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
82{
83 u32 data;
84
85 /* Set the address */
86 writel(address, RCB_REG(IOBPIRI));
87
88 /* READ OPCODE */
89 if (pch_silicon_supported(PCH_TYPE_CPT, PCH_STEP_B0))
90 writel(IOBPS_RW_BX, RCB_REG(IOBPS));
91 else
92 writel(IOBPS_READ_AX, RCB_REG(IOBPS));
93 if (!iobp_poll())
94 return;
95
96 /* Read IOBP data */
97 data = readl(RCB_REG(IOBPD));
98 if (!iobp_poll())
99 return;
100
101 /* Check for successful transaction */
102 if ((readl(RCB_REG(IOBPS)) & 0x6) != 0) {
103 printf("IOBP read 0x%08x failed\n", address);
104 return;
105 }
106
107 /* Update the data */
108 data &= andvalue;
109 data |= orvalue;
110
111 /* WRITE OPCODE */
112 if (pch_silicon_supported(PCH_TYPE_CPT, PCH_STEP_B0))
113 writel(IOBPS_RW_BX, RCB_REG(IOBPS));
114 else
115 writel(IOBPS_WRITE_AX, RCB_REG(IOBPS));
116 if (!iobp_poll())
117 return;
118
119 /* Write IOBP data */
120 writel(data, RCB_REG(IOBPD));
121 if (!iobp_poll())
122 return;
123}