1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2014 Google, Inc 4 */ 5 #include <common.h> 6 #include <dm.h> 7 #include <errno.h> 8 #include <fdtdec.h> 9 #include <malloc.h> 10 #include <pch.h> 11 #include <asm/cpu.h> 12 #include <asm/intel_regs.h> 13 #include <asm/io.h> 14 #include <asm/lapic.h> 15 #include <asm/lpc_common.h> 16 #include <asm/pci.h> 17 #include <asm/arch/model_206ax.h> 18 #include <asm/arch/pch.h> 19 #include <asm/arch/sandybridge.h> 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 #define GPIO_BASE 0x48 24 #define BIOS_CTRL 0xdc 25 26 #ifndef CONFIG_HAVE_FSP 27 static int pch_revision_id = -1; 28 static int pch_type = -1; 29 30 /** 31 * pch_silicon_revision() - Read silicon revision ID from the PCH 32 * 33 * @dev: PCH device 34 * @return silicon revision ID 35 */ 36 static int pch_silicon_revision(struct udevice *dev) 37 { 38 u8 val; 39 40 if (pch_revision_id < 0) { 41 dm_pci_read_config8(dev, PCI_REVISION_ID, &val); 42 pch_revision_id = val; 43 } 44 45 return pch_revision_id; 46 } 47 48 int pch_silicon_type(struct udevice *dev) 49 { 50 u8 val; 51 52 if (pch_type < 0) { 53 dm_pci_read_config8(dev, PCI_DEVICE_ID + 1, &val); 54 pch_type = val; 55 } 56 57 return pch_type; 58 } 59 60 /** 61 * pch_silicon_supported() - Check if a certain revision is supported 62 * 63 * @dev: PCH device 64 * @type: PCH type 65 * @rev: Minimum required resion 66 * @return 0 if not supported, 1 if supported 67 */ 68 static int pch_silicon_supported(struct udevice *dev, int type, int rev) 69 { 70 int cur_type = pch_silicon_type(dev); 71 int cur_rev = pch_silicon_revision(dev); 72 73 switch (type) { 74 case PCH_TYPE_CPT: 75 /* CougarPoint minimum revision */ 76 if (cur_type == PCH_TYPE_CPT && cur_rev >= rev) 77 return 1; 78 /* PantherPoint any revision */ 79 if (cur_type == PCH_TYPE_PPT) 80 return 1; 81 break; 82 83 case PCH_TYPE_PPT: 84 /* PantherPoint minimum revision */ 85 if (cur_type == PCH_TYPE_PPT && cur_rev >= rev) 86 return 1; 87 break; 88 } 89 90 return 0; 91 } 92 93 #define IOBP_RETRY 1000 94 static inline int iobp_poll(void) 95 { 96 unsigned try = IOBP_RETRY; 97 u32 data; 98 99 while (try--) { 100 data = readl(RCB_REG(IOBPS)); 101 if ((data & 1) == 0) 102 return 1; 103 udelay(10); 104 } 105 106 printf("IOBP timeout\n"); 107 return 0; 108 } 109 110 void pch_iobp_update(struct udevice *dev, u32 address, u32 andvalue, 111 u32 orvalue) 112 { 113 u32 data; 114 115 /* Set the address */ 116 writel(address, RCB_REG(IOBPIRI)); 117 118 /* READ OPCODE */ 119 if (pch_silicon_supported(dev, PCH_TYPE_CPT, PCH_STEP_B0)) 120 writel(IOBPS_RW_BX, RCB_REG(IOBPS)); 121 else 122 writel(IOBPS_READ_AX, RCB_REG(IOBPS)); 123 if (!iobp_poll()) 124 return; 125 126 /* Read IOBP data */ 127 data = readl(RCB_REG(IOBPD)); 128 if (!iobp_poll()) 129 return; 130 131 /* Check for successful transaction */ 132 if ((readl(RCB_REG(IOBPS)) & 0x6) != 0) { 133 printf("IOBP read 0x%08x failed\n", address); 134 return; 135 } 136 137 /* Update the data */ 138 data &= andvalue; 139 data |= orvalue; 140 141 /* WRITE OPCODE */ 142 if (pch_silicon_supported(dev, PCH_TYPE_CPT, PCH_STEP_B0)) 143 writel(IOBPS_RW_BX, RCB_REG(IOBPS)); 144 else 145 writel(IOBPS_WRITE_AX, RCB_REG(IOBPS)); 146 if (!iobp_poll()) 147 return; 148 149 /* Write IOBP data */ 150 writel(data, RCB_REG(IOBPD)); 151 if (!iobp_poll()) 152 return; 153 } 154 155 static int bd82x6x_probe(struct udevice *dev) 156 { 157 if (!(gd->flags & GD_FLG_RELOC)) 158 return 0; 159 160 /* Cause the SATA device to do its init */ 161 uclass_first_device(UCLASS_AHCI, &dev); 162 163 return 0; 164 } 165 #endif /* CONFIG_HAVE_FSP */ 166 167 static int bd82x6x_pch_get_spi_base(struct udevice *dev, ulong *sbasep) 168 { 169 u32 rcba; 170 171 dm_pci_read_config32(dev, PCH_RCBA, &rcba); 172 /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable */ 173 rcba = rcba & 0xffffc000; 174 *sbasep = rcba + 0x3800; 175 176 return 0; 177 } 178 179 static int bd82x6x_set_spi_protect(struct udevice *dev, bool protect) 180 { 181 return lpc_set_spi_protect(dev, BIOS_CTRL, protect); 182 } 183 184 static int bd82x6x_get_gpio_base(struct udevice *dev, u32 *gbasep) 185 { 186 u32 base; 187 188 /* 189 * GPIO_BASE moved to its current offset with ICH6, but prior to 190 * that it was unused (or undocumented). Check that it looks 191 * okay: not all ones or zeros. 192 * 193 * Note we don't need check bit0 here, because the Tunnel Creek 194 * GPIO base address register bit0 is reserved (read returns 0), 195 * while on the Ivybridge the bit0 is used to indicate it is an 196 * I/O space. 197 */ 198 dm_pci_read_config32(dev, GPIO_BASE, &base); 199 if (base == 0x00000000 || base == 0xffffffff) { 200 debug("%s: unexpected BASE value\n", __func__); 201 return -ENODEV; 202 } 203 204 /* 205 * Okay, I guess we're looking at the right device. The actual 206 * GPIO registers are in the PCI device's I/O space, starting 207 * at the offset that we just read. Bit 0 indicates that it's 208 * an I/O address, not a memory address, so mask that off. 209 */ 210 *gbasep = base & 1 ? base & ~3 : base & ~15; 211 212 return 0; 213 } 214 215 static const struct pch_ops bd82x6x_pch_ops = { 216 .get_spi_base = bd82x6x_pch_get_spi_base, 217 .set_spi_protect = bd82x6x_set_spi_protect, 218 .get_gpio_base = bd82x6x_get_gpio_base, 219 }; 220 221 static const struct udevice_id bd82x6x_ids[] = { 222 { .compatible = "intel,bd82x6x" }, 223 { } 224 }; 225 226 U_BOOT_DRIVER(bd82x6x_drv) = { 227 .name = "bd82x6x", 228 .id = UCLASS_PCH, 229 .of_match = bd82x6x_ids, 230 #ifndef CONFIG_HAVE_FSP 231 .probe = bd82x6x_probe, 232 #endif 233 .ops = &bd82x6x_pch_ops, 234 }; 235