]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/x86/cpu/ivybridge/pch.c
Merge branch 'master' of git://git.denx.de/u-boot-usb
[karo-tx-uboot.git] / arch / x86 / cpu / ivybridge / pch.c
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
17 int pch_silicon_revision(void)
18 {
19         pci_dev_t dev;
20
21         dev = PCH_LPC_DEV;
22
23         if (pch_revision_id < 0)
24                 pch_revision_id = pci_read_config8(dev, PCI_REVISION_ID);
25         return pch_revision_id;
26 }
27
28 int pch_silicon_type(void)
29 {
30         pci_dev_t dev;
31
32         dev = PCH_LPC_DEV;
33
34         if (pch_type < 0)
35                 pch_type = pci_read_config8(dev, PCI_DEVICE_ID + 1);
36         return pch_type;
37 }
38
39 int 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
65 static 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
81 void 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 }