aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/pch_phub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/pch_phub.c')
-rw-r--r--drivers/misc/pch_phub.c153
1 files changed, 129 insertions, 24 deletions
diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c
index a19cb710a246..5fe79df44838 100644
--- a/drivers/misc/pch_phub.c
+++ b/drivers/misc/pch_phub.c
@@ -34,12 +34,18 @@
34#define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */ 34#define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */
35#define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */ 35#define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */
36#define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */ 36#define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */
37#define PCH_PHUB_MAC_START_ADDR 0x20C /* MAC data area start address offset */ 37#define PCH_PHUB_MAC_START_ADDR_EG20T 0x14 /* MAC data area start address
38#define PCH_PHUB_ROM_START_ADDR_EG20T 0x14 /* ROM data area start address offset 38 offset */
39#define PCH_PHUB_MAC_START_ADDR_ML7223 0x20C /* MAC data area start address
40 offset */
41#define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset
39 (Intel EG20T PCH)*/ 42 (Intel EG20T PCH)*/
40#define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address 43#define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address
41 offset(OKI SEMICONDUCTOR ML7213) 44 offset(OKI SEMICONDUCTOR ML7213)
42 */ 45 */
46#define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address
47 offset(OKI SEMICONDUCTOR ML7223)
48 */
43 49
44/* MAX number of INT_REDUCE_CONTROL registers */ 50/* MAX number of INT_REDUCE_CONTROL registers */
45#define MAX_NUM_INT_REDUCE_CONTROL_REG 128 51#define MAX_NUM_INT_REDUCE_CONTROL_REG 128
@@ -63,6 +69,10 @@
63#define PCI_VENDOR_ID_ROHM 0x10db 69#define PCI_VENDOR_ID_ROHM 0x10db
64#define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A 70#define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A
65 71
72/* Macros for ML7223 */
73#define PCI_DEVICE_ID_ROHM_ML7223_mPHUB 0x8012 /* for Bus-m */
74#define PCI_DEVICE_ID_ROHM_ML7223_nPHUB 0x8002 /* for Bus-n */
75
66/* SROM ACCESS Macro */ 76/* SROM ACCESS Macro */
67#define PCH_WORD_ADDR_MASK (~((1 << 2) - 1)) 77#define PCH_WORD_ADDR_MASK (~((1 << 2) - 1))
68 78
@@ -100,6 +110,9 @@
100 * @clkcfg_reg: CLK CFG register val 110 * @clkcfg_reg: CLK CFG register val
101 * @pch_phub_base_address: Register base address 111 * @pch_phub_base_address: Register base address
102 * @pch_phub_extrom_base_address: external rom base address 112 * @pch_phub_extrom_base_address: external rom base address
113 * @pch_mac_start_address: MAC address area start address
114 * @pch_opt_rom_start_address: Option ROM start address
115 * @ioh_type: Save IOH type
103 */ 116 */
104struct pch_phub_reg { 117struct pch_phub_reg {
105 u32 phub_id_reg; 118 u32 phub_id_reg;
@@ -117,6 +130,9 @@ struct pch_phub_reg {
117 u32 clkcfg_reg; 130 u32 clkcfg_reg;
118 void __iomem *pch_phub_base_address; 131 void __iomem *pch_phub_base_address;
119 void __iomem *pch_phub_extrom_base_address; 132 void __iomem *pch_phub_extrom_base_address;
133 u32 pch_mac_start_address;
134 u32 pch_opt_rom_start_address;
135 int ioh_type;
120}; 136};
121 137
122/* SROM SPEC for MAC address assignment offset */ 138/* SROM SPEC for MAC address assignment offset */
@@ -319,7 +335,7 @@ static void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip,
319{ 335{
320 unsigned int mem_addr; 336 unsigned int mem_addr;
321 337
322 mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T + 338 mem_addr = chip->pch_mac_start_address +
323 pch_phub_mac_offset[offset_address]; 339 pch_phub_mac_offset[offset_address];
324 340
325 pch_phub_read_serial_rom(chip, mem_addr, data); 341 pch_phub_read_serial_rom(chip, mem_addr, data);
@@ -336,7 +352,7 @@ static int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip,
336 int retval; 352 int retval;
337 unsigned int mem_addr; 353 unsigned int mem_addr;
338 354
339 mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T + 355 mem_addr = chip->pch_mac_start_address +
340 pch_phub_mac_offset[offset_address]; 356 pch_phub_mac_offset[offset_address];
341 357
342 retval = pch_phub_write_serial_rom(chip, mem_addr, data); 358 retval = pch_phub_write_serial_rom(chip, mem_addr, data);
@@ -384,6 +400,48 @@ static int pch_phub_gbe_serial_rom_conf(struct pch_phub_reg *chip)
384 return retval; 400 return retval;
385} 401}
386 402
403/* pch_phub_gbe_serial_rom_conf_mp - makes SerialROM header format configuration
404 * for Gigabit Ethernet MAC address
405 */
406static int pch_phub_gbe_serial_rom_conf_mp(struct pch_phub_reg *chip)
407{
408 int retval;
409 u32 offset_addr;
410
411 offset_addr = 0x200;
412 retval = pch_phub_write_serial_rom(chip, 0x03 + offset_addr, 0xbc);
413 retval |= pch_phub_write_serial_rom(chip, 0x02 + offset_addr, 0x00);
414 retval |= pch_phub_write_serial_rom(chip, 0x01 + offset_addr, 0x40);
415 retval |= pch_phub_write_serial_rom(chip, 0x00 + offset_addr, 0x02);
416
417 retval |= pch_phub_write_serial_rom(chip, 0x07 + offset_addr, 0x00);
418 retval |= pch_phub_write_serial_rom(chip, 0x06 + offset_addr, 0x00);
419 retval |= pch_phub_write_serial_rom(chip, 0x05 + offset_addr, 0x00);
420 retval |= pch_phub_write_serial_rom(chip, 0x04 + offset_addr, 0x80);
421
422 retval |= pch_phub_write_serial_rom(chip, 0x0b + offset_addr, 0xbc);
423 retval |= pch_phub_write_serial_rom(chip, 0x0a + offset_addr, 0x00);
424 retval |= pch_phub_write_serial_rom(chip, 0x09 + offset_addr, 0x40);
425 retval |= pch_phub_write_serial_rom(chip, 0x08 + offset_addr, 0x18);
426
427 retval |= pch_phub_write_serial_rom(chip, 0x13 + offset_addr, 0xbc);
428 retval |= pch_phub_write_serial_rom(chip, 0x12 + offset_addr, 0x00);
429 retval |= pch_phub_write_serial_rom(chip, 0x11 + offset_addr, 0x40);
430 retval |= pch_phub_write_serial_rom(chip, 0x10 + offset_addr, 0x19);
431
432 retval |= pch_phub_write_serial_rom(chip, 0x1b + offset_addr, 0xbc);
433 retval |= pch_phub_write_serial_rom(chip, 0x1a + offset_addr, 0x00);
434 retval |= pch_phub_write_serial_rom(chip, 0x19 + offset_addr, 0x40);
435 retval |= pch_phub_write_serial_rom(chip, 0x18 + offset_addr, 0x3a);
436
437 retval |= pch_phub_write_serial_rom(chip, 0x1f + offset_addr, 0x01);
438 retval |= pch_phub_write_serial_rom(chip, 0x1e + offset_addr, 0x00);
439 retval |= pch_phub_write_serial_rom(chip, 0x1d + offset_addr, 0x00);
440 retval |= pch_phub_write_serial_rom(chip, 0x1c + offset_addr, 0x00);
441
442 return retval;
443}
444
387/** 445/**
388 * pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address 446 * pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address
389 * @offset_address: Gigabit Ethernet MAC address offset value. 447 * @offset_address: Gigabit Ethernet MAC address offset value.
@@ -406,7 +464,10 @@ static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
406 int retval; 464 int retval;
407 int i; 465 int i;
408 466
409 retval = pch_phub_gbe_serial_rom_conf(chip); 467 if (chip->ioh_type == 1) /* EG20T */
468 retval = pch_phub_gbe_serial_rom_conf(chip);
469 else /* ML7223 */
470 retval = pch_phub_gbe_serial_rom_conf_mp(chip);
410 if (retval) 471 if (retval)
411 return retval; 472 return retval;
412 473
@@ -441,12 +502,16 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
441 } 502 }
442 503
443 /* Get Rom signature */ 504 /* Get Rom signature */
444 pch_phub_read_serial_rom(chip, 0x80, (unsigned char *)&rom_signature); 505 pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address,
506 (unsigned char *)&rom_signature);
445 rom_signature &= 0xff; 507 rom_signature &= 0xff;
446 pch_phub_read_serial_rom(chip, 0x81, (unsigned char *)&tmp); 508 pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address + 1,
509 (unsigned char *)&tmp);
447 rom_signature |= (tmp & 0xff) << 8; 510 rom_signature |= (tmp & 0xff) << 8;
448 if (rom_signature == 0xAA55) { 511 if (rom_signature == 0xAA55) {
449 pch_phub_read_serial_rom(chip, 0x82, &rom_length); 512 pch_phub_read_serial_rom(chip,
513 chip->pch_opt_rom_start_address + 2,
514 &rom_length);
450 orom_size = rom_length * 512; 515 orom_size = rom_length * 512;
451 if (orom_size < off) { 516 if (orom_size < off) {
452 addr_offset = 0; 517 addr_offset = 0;
@@ -458,8 +523,9 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
458 } 523 }
459 524
460 for (addr_offset = 0; addr_offset < count; addr_offset++) { 525 for (addr_offset = 0; addr_offset < count; addr_offset++) {
461 pch_phub_read_serial_rom(chip, 0x80 + addr_offset + off, 526 pch_phub_read_serial_rom(chip,
462 &buf[addr_offset]); 527 chip->pch_opt_rom_start_address + addr_offset + off,
528 &buf[addr_offset]);
463 } 529 }
464 } else { 530 } else {
465 err = -ENODATA; 531 err = -ENODATA;
@@ -502,8 +568,9 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
502 if (PCH_PHUB_OROM_SIZE < off + addr_offset) 568 if (PCH_PHUB_OROM_SIZE < off + addr_offset)
503 goto return_ok; 569 goto return_ok;
504 570
505 ret = pch_phub_write_serial_rom(chip, 0x80 + addr_offset + off, 571 ret = pch_phub_write_serial_rom(chip,
506 buf[addr_offset]); 572 chip->pch_opt_rom_start_address + addr_offset + off,
573 buf[addr_offset]);
507 if (ret) { 574 if (ret) {
508 err = ret; 575 err = ret;
509 goto return_err; 576 goto return_err;
@@ -603,19 +670,22 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
603 dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value " 670 dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value "
604 "in pch_phub_base_address variable is %p\n", __func__, 671 "in pch_phub_base_address variable is %p\n", __func__,
605 chip->pch_phub_base_address); 672 chip->pch_phub_base_address);
606 chip->pch_phub_extrom_base_address = pci_map_rom(pdev, &rom_size);
607 673
608 if (chip->pch_phub_extrom_base_address == 0) { 674 if (id->driver_data != 3) {
609 dev_err(&pdev->dev, "%s : pci_map_rom FAILED", __func__); 675 chip->pch_phub_extrom_base_address =\
610 ret = -ENOMEM; 676 pci_map_rom(pdev, &rom_size);
611 goto err_pci_map; 677 if (chip->pch_phub_extrom_base_address == 0) {
678 dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__);
679 ret = -ENOMEM;
680 goto err_pci_map;
681 }
682 dev_dbg(&pdev->dev, "%s : "
683 "pci_map_rom SUCCESS and value in "
684 "pch_phub_extrom_base_address variable is %p\n",
685 __func__, chip->pch_phub_extrom_base_address);
612 } 686 }
613 dev_dbg(&pdev->dev, "%s : "
614 "pci_map_rom SUCCESS and value in "
615 "pch_phub_extrom_base_address variable is %p\n", __func__,
616 chip->pch_phub_extrom_base_address);
617 687
618 if (id->driver_data == 1) { 688 if (id->driver_data == 1) { /* EG20T PCH */
619 retval = sysfs_create_file(&pdev->dev.kobj, 689 retval = sysfs_create_file(&pdev->dev.kobj,
620 &dev_attr_pch_mac.attr); 690 &dev_attr_pch_mac.attr);
621 if (retval) 691 if (retval)
@@ -642,7 +712,9 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
642 iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); 712 iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
643 /* set the interrupt delay value */ 713 /* set the interrupt delay value */
644 iowrite32(0x25, chip->pch_phub_base_address + 0x44); 714 iowrite32(0x25, chip->pch_phub_base_address + 0x44);
645 } else if (id->driver_data == 2) { 715 chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
716 chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
717 } else if (id->driver_data == 2) { /* ML7213 IOH */
646 retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); 718 retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
647 if (retval) 719 if (retval)
648 goto err_sysfs_create; 720 goto err_sysfs_create;
@@ -653,7 +725,38 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
653 * Device8(USB OHCI #0/ USB EHCI #0):a 725 * Device8(USB OHCI #0/ USB EHCI #0):a
654 */ 726 */
655 iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14); 727 iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14);
728 chip->pch_opt_rom_start_address =\
729 PCH_PHUB_ROM_START_ADDR_ML7213;
730 } else if (id->driver_data == 3) { /* ML7223 IOH Bus-m*/
731 /* set the prefech value
732 * Device8(GbE)
733 */
734 iowrite32(0x000a0000, chip->pch_phub_base_address + 0x14);
735 chip->pch_opt_rom_start_address =\
736 PCH_PHUB_ROM_START_ADDR_ML7223;
737 chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
738 } else if (id->driver_data == 4) { /* ML7223 IOH Bus-n*/
739 retval = sysfs_create_file(&pdev->dev.kobj,
740 &dev_attr_pch_mac.attr);
741 if (retval)
742 goto err_sysfs_create;
743 retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
744 if (retval)
745 goto exit_bin_attr;
746 /* set the prefech value
747 * Device2(USB OHCI #0,1,2,3/ USB EHCI #0):a
748 * Device4(SDIO #0,1):f
749 * Device6(SATA 2):f
750 */
751 iowrite32(0x0000ffa0, chip->pch_phub_base_address + 0x14);
752 /* set the interrupt delay value */
753 iowrite32(0x25, chip->pch_phub_base_address + 0x140);
754 chip->pch_opt_rom_start_address =\
755 PCH_PHUB_ROM_START_ADDR_ML7223;
756 chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
656 } 757 }
758
759 chip->ioh_type = id->driver_data;
657 pci_set_drvdata(pdev, chip); 760 pci_set_drvdata(pdev, chip);
658 761
659 return 0; 762 return 0;
@@ -733,6 +836,8 @@ static int pch_phub_resume(struct pci_dev *pdev)
733static struct pci_device_id pch_phub_pcidev_id[] = { 836static struct pci_device_id pch_phub_pcidev_id[] = {
734 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB), 1, }, 837 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB), 1, },
735 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, }, 838 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, },
839 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3, },
840 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4, },
736 { } 841 { }
737}; 842};
738MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id); 843MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id);
@@ -759,5 +864,5 @@ static void __exit pch_phub_pci_exit(void)
759module_init(pch_phub_pci_init); 864module_init(pch_phub_pci_init);
760module_exit(pch_phub_pci_exit); 865module_exit(pch_phub_pci_exit);
761 866
762MODULE_DESCRIPTION("PCH Packet Hub PCI Driver"); 867MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB");
763MODULE_LICENSE("GPL"); 868MODULE_LICENSE("GPL");