ich.c (fffe25db04b428f34b72264ff50c40f395fcd936) | ich.c (f2b85ab5e6a91e29c1d64304be371753d75ed172) |
---|---|
1/* 2 * Copyright (c) 2011-12 The Chromium OS Authors. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 * 6 * This file is derived from the flashrom project. 7 */ | 1/* 2 * Copyright (c) 2011-12 The Chromium OS Authors. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 * 6 * This file is derived from the flashrom project. 7 */ |
8 | |
9#include <common.h> 10#include <dm.h> 11#include <errno.h> 12#include <malloc.h> | 8#include <common.h> 9#include <dm.h> 10#include <errno.h> 11#include <malloc.h> |
13#include <spi.h> | 12#include <pch.h> |
14#include <pci.h> 15#include <pci_ids.h> | 13#include <pci.h> 14#include <pci_ids.h> |
15#include <spi.h> |
|
16#include <asm/io.h> 17 18#include "ich.h" 19 20#define SPI_OPCODE_WREN 0x06 21#define SPI_OPCODE_FAST_READ 0x0b 22 23#ifdef DEBUG_TRACE 24#define debug_trace(fmt, args...) debug(fmt, ##args) 25#else 26#define debug_trace(x, args...) 27#endif 28 29struct ich_spi_platdata { | 16#include <asm/io.h> 17 18#include "ich.h" 19 20#define SPI_OPCODE_WREN 0x06 21#define SPI_OPCODE_FAST_READ 0x0b 22 23#ifdef DEBUG_TRACE 24#define debug_trace(fmt, args...) debug(fmt, ##args) 25#else 26#define debug_trace(x, args...) 27#endif 28 29struct ich_spi_platdata { |
30 pci_dev_t dev; /* PCI device number */ 31 int ich_version; /* Controller version, 7 or 9 */ 32 bool use_sbase; /* Use SBASE instead of RCB */ | 30 enum pch_version ich_version; /* Controller version, 7 or 9 */ |
33}; 34 35struct ich_spi_priv { 36 int ichspi_lock; 37 int locked; 38 int opmenu; 39 int menubytes; 40 void *base; /* Base of register set */ --- 76 unchanged lines hidden (view full) --- 117 uint32_t ichspi_bbar; 118 119 minaddr &= bbar_mask; 120 ichspi_bbar = ich_readl(ctlr, ctlr->bbar) & ~bbar_mask; 121 ichspi_bbar |= minaddr; 122 ich_writel(ctlr, ichspi_bbar, ctlr->bbar); 123} 124 | 31}; 32 33struct ich_spi_priv { 34 int ichspi_lock; 35 int locked; 36 int opmenu; 37 int menubytes; 38 void *base; /* Base of register set */ --- 76 unchanged lines hidden (view full) --- 115 uint32_t ichspi_bbar; 116 117 minaddr &= bbar_mask; 118 ichspi_bbar = ich_readl(ctlr, ctlr->bbar) & ~bbar_mask; 119 ichspi_bbar |= minaddr; 120 ich_writel(ctlr, ichspi_bbar, ctlr->bbar); 121} 122 |
125/* 126 * Check if this device ID matches one of supported Intel PCH devices. 127 * 128 * Return the ICH version if there is a match, or zero otherwise. 129 */ 130static int get_ich_version(uint16_t device_id) 131{ 132 if (device_id == PCI_DEVICE_ID_INTEL_TGP_LPC || 133 device_id == PCI_DEVICE_ID_INTEL_ITC_LPC || 134 device_id == PCI_DEVICE_ID_INTEL_QRK_ILB) 135 return 7; 136 137 if ((device_id >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN && 138 device_id <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX) || 139 (device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN && 140 device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX) || 141 device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC || 142 device_id == PCI_DEVICE_ID_INTEL_LYNXPOINT_LPC || 143 device_id == PCI_DEVICE_ID_INTEL_WILDCATPOINT_LPC) 144 return 9; 145 146 return 0; 147} 148 | |
149/* @return 1 if the SPI flash supports the 33MHz speed */ | 123/* @return 1 if the SPI flash supports the 33MHz speed */ |
150static int ich9_can_do_33mhz(pci_dev_t dev) | 124static int ich9_can_do_33mhz(struct udevice *dev) |
151{ 152 u32 fdod, speed; 153 154 /* Observe SPI Descriptor Component Section 0 */ | 125{ 126 u32 fdod, speed; 127 128 /* Observe SPI Descriptor Component Section 0 */ |
155 pci_write_config_dword(dev, 0xb0, 0x1000); | 129 dm_pci_write_config32(dev->parent, 0xb0, 0x1000); |
156 157 /* Extract the Write/Erase SPI Frequency from descriptor */ | 130 131 /* Extract the Write/Erase SPI Frequency from descriptor */ |
158 pci_read_config_dword(dev, 0xb4, &fdod); | 132 dm_pci_read_config32(dev->parent, 0xb4, &fdod); |
159 160 /* Bits 23:21 have the fast read clock frequency, 0=20MHz, 1=33MHz */ 161 speed = (fdod >> 21) & 7; 162 163 return speed == 1; 164} 165 | 133 134 /* Bits 23:21 have the fast read clock frequency, 0=20MHz, 1=33MHz */ 135 speed = (fdod >> 21) & 7; 136 137 return speed == 1; 138} 139 |
166static int ich_find_spi_controller(struct ich_spi_platdata *ich) 167{ 168 int last_bus = pci_last_busno(); 169 int bus; 170 171 if (last_bus == -1) { 172 debug("No PCI busses?\n"); 173 return -ENODEV; 174 } 175 176 for (bus = 0; bus <= last_bus; bus++) { 177 uint16_t vendor_id, device_id; 178 uint32_t ids; 179 pci_dev_t dev; 180 181 dev = PCI_BDF(bus, 31, 0); 182 pci_read_config_dword(dev, 0, &ids); 183 vendor_id = ids; 184 device_id = ids >> 16; 185 186 if (vendor_id == PCI_VENDOR_ID_INTEL) { 187 ich->dev = dev; 188 ich->ich_version = get_ich_version(device_id); 189 if (device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC) 190 ich->use_sbase = true; 191 return ich->ich_version == 0 ? -ENODEV : 0; 192 } 193 } 194 195 debug("ICH SPI: No ICH found.\n"); 196 return -ENODEV; 197} 198 199static int ich_init_controller(struct ich_spi_platdata *plat, | 140static int ich_init_controller(struct udevice *dev, 141 struct ich_spi_platdata *plat, |
200 struct ich_spi_priv *ctlr) 201{ | 142 struct ich_spi_priv *ctlr) 143{ |
202 uint8_t *rcrb; /* Root Complex Register Block */ 203 uint32_t rcba; /* Root Complex Base Address */ 204 uint32_t sbase_addr; 205 uint8_t *sbase; | 144 ulong sbase_addr; 145 void *sbase; |
206 | 146 |
207 pci_read_config_dword(plat->dev, 0xf0, &rcba); 208 /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */ 209 rcrb = (uint8_t *)(rcba & 0xffffc000); 210 | |
211 /* SBASE is similar */ | 147 /* SBASE is similar */ |
212 pci_read_config_dword(plat->dev, 0x54, &sbase_addr); 213 sbase = (uint8_t *)(sbase_addr & 0xfffffe00); | 148 pch_get_sbase(dev->parent, &sbase_addr); 149 sbase = (void *)sbase_addr; 150 debug("%s: sbase=%p\n", __func__, sbase); |
214 | 151 |
215 if (plat->ich_version == 7) { 216 struct ich7_spi_regs *ich7_spi; | 152 if (plat->ich_version == PCHV_7) { 153 struct ich7_spi_regs *ich7_spi = sbase; |
217 | 154 |
218 ich7_spi = (struct ich7_spi_regs *)(rcrb + 0x3020); | 155 ich7_spi = (struct ich7_spi_regs *)sbase; |
219 ctlr->ichspi_lock = readw(&ich7_spi->spis) & SPIS_LOCK; 220 ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu); 221 ctlr->menubytes = sizeof(ich7_spi->opmenu); 222 ctlr->optype = offsetof(struct ich7_spi_regs, optype); 223 ctlr->addr = offsetof(struct ich7_spi_regs, spia); 224 ctlr->data = offsetof(struct ich7_spi_regs, spid); 225 ctlr->databytes = sizeof(ich7_spi->spid); 226 ctlr->status = offsetof(struct ich7_spi_regs, spis); 227 ctlr->control = offsetof(struct ich7_spi_regs, spic); 228 ctlr->bbar = offsetof(struct ich7_spi_regs, bbar); 229 ctlr->preop = offsetof(struct ich7_spi_regs, preop); 230 ctlr->base = ich7_spi; | 156 ctlr->ichspi_lock = readw(&ich7_spi->spis) & SPIS_LOCK; 157 ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu); 158 ctlr->menubytes = sizeof(ich7_spi->opmenu); 159 ctlr->optype = offsetof(struct ich7_spi_regs, optype); 160 ctlr->addr = offsetof(struct ich7_spi_regs, spia); 161 ctlr->data = offsetof(struct ich7_spi_regs, spid); 162 ctlr->databytes = sizeof(ich7_spi->spid); 163 ctlr->status = offsetof(struct ich7_spi_regs, spis); 164 ctlr->control = offsetof(struct ich7_spi_regs, spic); 165 ctlr->bbar = offsetof(struct ich7_spi_regs, bbar); 166 ctlr->preop = offsetof(struct ich7_spi_regs, preop); 167 ctlr->base = ich7_spi; |
231 } else if (plat->ich_version == 9) { 232 struct ich9_spi_regs *ich9_spi; | 168 } else if (plat->ich_version == PCHV_9) { 169 struct ich9_spi_regs *ich9_spi = sbase; |
233 | 170 |
234 if (plat->use_sbase) 235 ich9_spi = (struct ich9_spi_regs *)sbase; 236 else 237 ich9_spi = (struct ich9_spi_regs *)(rcrb + 0x3800); | |
238 ctlr->ichspi_lock = readw(&ich9_spi->hsfs) & HSFS_FLOCKDN; 239 ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu); 240 ctlr->menubytes = sizeof(ich9_spi->opmenu); 241 ctlr->optype = offsetof(struct ich9_spi_regs, optype); 242 ctlr->addr = offsetof(struct ich9_spi_regs, faddr); 243 ctlr->data = offsetof(struct ich9_spi_regs, fdata); 244 ctlr->databytes = sizeof(ich9_spi->fdata); 245 ctlr->status = offsetof(struct ich9_spi_regs, ssfs); --- 7 unchanged lines hidden (view full) --- 253 } else { 254 debug("ICH SPI: Unrecognised ICH version %d\n", 255 plat->ich_version); 256 return -EINVAL; 257 } 258 259 /* Work out the maximum speed we can support */ 260 ctlr->max_speed = 20000000; | 171 ctlr->ichspi_lock = readw(&ich9_spi->hsfs) & HSFS_FLOCKDN; 172 ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu); 173 ctlr->menubytes = sizeof(ich9_spi->opmenu); 174 ctlr->optype = offsetof(struct ich9_spi_regs, optype); 175 ctlr->addr = offsetof(struct ich9_spi_regs, faddr); 176 ctlr->data = offsetof(struct ich9_spi_regs, fdata); 177 ctlr->databytes = sizeof(ich9_spi->fdata); 178 ctlr->status = offsetof(struct ich9_spi_regs, ssfs); --- 7 unchanged lines hidden (view full) --- 186 } else { 187 debug("ICH SPI: Unrecognised ICH version %d\n", 188 plat->ich_version); 189 return -EINVAL; 190 } 191 192 /* Work out the maximum speed we can support */ 193 ctlr->max_speed = 20000000; |
261 if (plat->ich_version == 9 && ich9_can_do_33mhz(plat->dev)) | 194 if (plat->ich_version == PCHV_9 && ich9_can_do_33mhz(dev)) |
262 ctlr->max_speed = 33000000; | 195 ctlr->max_speed = 33000000; |
263 debug("ICH SPI: Version %d detected at %p, speed %ld\n", | 196 debug("ICH SPI: Version ID %d detected at %p, speed %ld\n", |
264 plat->ich_version, ctlr->base, ctlr->max_speed); 265 266 ich_set_bbar(ctlr, 0); 267 268 return 0; 269} 270 271static inline void spi_use_out(struct spi_trans *trans, unsigned bytes) --- 210 unchanged lines hidden (view full) --- 482 debug("ICH SPI: No opcode for transfer\n"); 483 return -EPROTO; 484 } 485 486 ret = ich_status_poll(ctlr, SPIS_SCIP, 0); 487 if (ret < 0) 488 return ret; 489 | 197 plat->ich_version, ctlr->base, ctlr->max_speed); 198 199 ich_set_bbar(ctlr, 0); 200 201 return 0; 202} 203 204static inline void spi_use_out(struct spi_trans *trans, unsigned bytes) --- 210 unchanged lines hidden (view full) --- 415 debug("ICH SPI: No opcode for transfer\n"); 416 return -EPROTO; 417 } 418 419 ret = ich_status_poll(ctlr, SPIS_SCIP, 0); 420 if (ret < 0) 421 return ret; 422 |
490 if (plat->ich_version == 7) | 423 if (plat->ich_version == PCHV_7) |
491 ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status); 492 else 493 ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status); 494 495 spi_setup_type(trans, using_cmd ? bytes : 0); 496 opcode_index = spi_setup_opcode(ctlr, trans); 497 if (opcode_index < 0) 498 return -EINVAL; --- 178 unchanged lines hidden (view full) --- 677 678 printf("%s: writing 0x%08x to %p\n", __func__, tmplong, 679 &ctlr->pr[hint]); 680 ctlr->pr[hint] = tmplong; 681 682 return 0; 683} 684 | 424 ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status); 425 else 426 ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status); 427 428 spi_setup_type(trans, using_cmd ? bytes : 0); 429 opcode_index = spi_setup_opcode(ctlr, trans); 430 if (opcode_index < 0) 431 return -EINVAL; --- 178 unchanged lines hidden (view full) --- 610 611 printf("%s: writing 0x%08x to %p\n", __func__, tmplong, 612 &ctlr->pr[hint]); 613 ctlr->pr[hint] = tmplong; 614 615 return 0; 616} 617 |
685static int ich_spi_probe(struct udevice *bus) | 618static int ich_spi_probe(struct udevice *dev) |
686{ | 619{ |
687 struct ich_spi_platdata *plat = dev_get_platdata(bus); 688 struct ich_spi_priv *priv = dev_get_priv(bus); | 620 struct ich_spi_platdata *plat = dev_get_platdata(dev); 621 struct ich_spi_priv *priv = dev_get_priv(dev); |
689 uint8_t bios_cntl; 690 int ret; 691 | 622 uint8_t bios_cntl; 623 int ret; 624 |
692 ret = ich_init_controller(plat, priv); | 625 /* Check the ICH version */ 626 plat->ich_version = pch_get_version(dev->parent); 627 628 ret = ich_init_controller(dev, plat, priv); |
693 if (ret) 694 return ret; | 629 if (ret) 630 return ret; |
695 /* 696 * Disable the BIOS write protect so write commands are allowed. On 697 * v9, deassert SMM BIOS Write Protect Disable. 698 */ 699 if (plat->use_sbase) { | 631 /* Disable the BIOS write protect so write commands are allowed */ 632 ret = pch_set_spi_protect(dev->parent, false); 633 if (ret == -ENOSYS) { |
700 bios_cntl = ich_readb(priv, priv->bcr); 701 bios_cntl &= ~BIT(5); /* clear Enable InSMM_STS (EISS) */ 702 bios_cntl |= 1; /* Write Protect Disable (WPD) */ 703 ich_writeb(priv, bios_cntl, priv->bcr); | 634 bios_cntl = ich_readb(priv, priv->bcr); 635 bios_cntl &= ~BIT(5); /* clear Enable InSMM_STS (EISS) */ 636 bios_cntl |= 1; /* Write Protect Disable (WPD) */ 637 ich_writeb(priv, bios_cntl, priv->bcr); |
704 } else { 705 pci_read_config_byte(plat->dev, 0xdc, &bios_cntl); 706 if (plat->ich_version == 9) 707 bios_cntl &= ~BIT(5); 708 pci_write_config_byte(plat->dev, 0xdc, bios_cntl | 0x1); | 638 } else if (ret) { 639 debug("%s: Failed to disable write-protect: err=%d\n", 640 __func__, ret); 641 return ret; |
709 } 710 711 priv->cur_speed = priv->max_speed; 712 713 return 0; 714} 715 | 642 } 643 644 priv->cur_speed = priv->max_speed; 645 646 return 0; 647} 648 |
716static int ich_spi_ofdata_to_platdata(struct udevice *bus) 717{ 718 struct ich_spi_platdata *plat = dev_get_platdata(bus); 719 int ret; 720 721 ret = ich_find_spi_controller(plat); 722 if (ret) 723 return ret; 724 725 return 0; 726} 727 | |
728static int ich_spi_set_speed(struct udevice *bus, uint speed) 729{ 730 struct ich_spi_priv *priv = dev_get_priv(bus); 731 732 priv->cur_speed = speed; 733 734 return 0; 735} --- 16 unchanged lines hidden (view full) --- 752 * Yes this controller can only write a small number of bytes at 753 * once! The limit is typically 64 bytes. 754 */ 755 slave->max_write_size = priv->databytes; 756 /* 757 * ICH 7 SPI controller only supports array read command 758 * and byte program command for SST flash 759 */ | 649static int ich_spi_set_speed(struct udevice *bus, uint speed) 650{ 651 struct ich_spi_priv *priv = dev_get_priv(bus); 652 653 priv->cur_speed = speed; 654 655 return 0; 656} --- 16 unchanged lines hidden (view full) --- 673 * Yes this controller can only write a small number of bytes at 674 * once! The limit is typically 64 bytes. 675 */ 676 slave->max_write_size = priv->databytes; 677 /* 678 * ICH 7 SPI controller only supports array read command 679 * and byte program command for SST flash 680 */ |
760 if (plat->ich_version == 7) { | 681 if (plat->ich_version == PCHV_7) { |
761 slave->mode_rx = SPI_RX_SLOW; 762 slave->mode = SPI_TX_BYTE; 763 } 764 765 return 0; 766} 767 768static const struct dm_spi_ops ich_spi_ops = { --- 11 unchanged lines hidden (view full) --- 780 { } 781}; 782 783U_BOOT_DRIVER(ich_spi) = { 784 .name = "ich_spi", 785 .id = UCLASS_SPI, 786 .of_match = ich_spi_ids, 787 .ops = &ich_spi_ops, | 682 slave->mode_rx = SPI_RX_SLOW; 683 slave->mode = SPI_TX_BYTE; 684 } 685 686 return 0; 687} 688 689static const struct dm_spi_ops ich_spi_ops = { --- 11 unchanged lines hidden (view full) --- 701 { } 702}; 703 704U_BOOT_DRIVER(ich_spi) = { 705 .name = "ich_spi", 706 .id = UCLASS_SPI, 707 .of_match = ich_spi_ids, 708 .ops = &ich_spi_ops, |
788 .ofdata_to_platdata = ich_spi_ofdata_to_platdata, | |
789 .platdata_auto_alloc_size = sizeof(struct ich_spi_platdata), 790 .priv_auto_alloc_size = sizeof(struct ich_spi_priv), 791 .child_pre_probe = ich_spi_child_pre_probe, 792 .probe = ich_spi_probe, 793}; | 709 .platdata_auto_alloc_size = sizeof(struct ich_spi_platdata), 710 .priv_auto_alloc_size = sizeof(struct ich_spi_priv), 711 .child_pre_probe = ich_spi_child_pre_probe, 712 .probe = ich_spi_probe, 713}; |