Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
0004  */
0005 
0006 #include <linux/module.h>
0007 #include <linux/kernel.h>
0008 #include <linux/types.h>
0009 #include <linux/fs.h>
0010 #include <linux/uaccess.h>
0011 #include <linux/string.h>
0012 #include <linux/pci.h>
0013 #include <linux/io.h>
0014 #include <linux/delay.h>
0015 #include <linux/mutex.h>
0016 #include <linux/if_ether.h>
0017 #include <linux/ctype.h>
0018 #include <linux/dmi.h>
0019 #include <linux/of.h>
0020 
0021 #define PHUB_STATUS 0x00        /* Status Register offset */
0022 #define PHUB_CONTROL 0x04       /* Control Register offset */
0023 #define PHUB_TIMEOUT 0x05       /* Time out value for Status Register */
0024 #define PCH_PHUB_ROM_WRITE_ENABLE 0x01  /* Enabling for writing ROM */
0025 #define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */
0026 #define PCH_PHUB_MAC_START_ADDR_EG20T 0x14  /* MAC data area start address
0027                            offset */
0028 #define PCH_PHUB_MAC_START_ADDR_ML7223 0x20C  /* MAC data area start address
0029                          offset */
0030 #define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset
0031                           (Intel EG20T PCH)*/
0032 #define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address
0033                         offset(LAPIS Semicon ML7213)
0034                           */
0035 #define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address
0036                         offset(LAPIS Semicon ML7223)
0037                           */
0038 
0039 /* MAX number of INT_REDUCE_CONTROL registers */
0040 #define MAX_NUM_INT_REDUCE_CONTROL_REG 128
0041 #define PCI_DEVICE_ID_PCH1_PHUB 0x8801
0042 #define PCH_MINOR_NOS 1
0043 #define CLKCFG_CAN_50MHZ 0x12000000
0044 #define CLKCFG_CANCLK_MASK 0xFF000000
0045 #define CLKCFG_UART_MASK            0xFFFFFF
0046 
0047 /* CM-iTC */
0048 #define CLKCFG_UART_48MHZ           (1 << 16)
0049 #define CLKCFG_UART_25MHZ           (2 << 16)
0050 #define CLKCFG_BAUDDIV              (2 << 20)
0051 #define CLKCFG_PLL2VCO              (8 << 9)
0052 #define CLKCFG_UARTCLKSEL           (1 << 18)
0053 
0054 /* Macros for ML7213 */
0055 #define PCI_DEVICE_ID_ROHM_ML7213_PHUB      0x801A
0056 
0057 /* Macros for ML7223 */
0058 #define PCI_DEVICE_ID_ROHM_ML7223_mPHUB 0x8012 /* for Bus-m */
0059 #define PCI_DEVICE_ID_ROHM_ML7223_nPHUB 0x8002 /* for Bus-n */
0060 
0061 /* Macros for ML7831 */
0062 #define PCI_DEVICE_ID_ROHM_ML7831_PHUB 0x8801
0063 
0064 /* SROM ACCESS Macro */
0065 #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1))
0066 
0067 /* Registers address offset */
0068 #define PCH_PHUB_ID_REG             0x0000
0069 #define PCH_PHUB_QUEUE_PRI_VAL_REG      0x0004
0070 #define PCH_PHUB_RC_QUEUE_MAXSIZE_REG       0x0008
0071 #define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG      0x000C
0072 #define PCH_PHUB_COMP_RESP_TIMEOUT_REG      0x0010
0073 #define PCH_PHUB_BUS_SLAVE_CONTROL_REG      0x0014
0074 #define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG    0x0018
0075 #define PCH_PHUB_INTPIN_REG_WPERMIT_REG0    0x0020
0076 #define PCH_PHUB_INTPIN_REG_WPERMIT_REG1    0x0024
0077 #define PCH_PHUB_INTPIN_REG_WPERMIT_REG2    0x0028
0078 #define PCH_PHUB_INTPIN_REG_WPERMIT_REG3    0x002C
0079 #define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE    0x0040
0080 #define CLKCFG_REG_OFFSET           0x500
0081 #define FUNCSEL_REG_OFFSET          0x508
0082 
0083 #define PCH_PHUB_OROM_SIZE 15360
0084 
0085 /**
0086  * struct pch_phub_reg - PHUB register structure
0087  * @phub_id_reg:            PHUB_ID register val
0088  * @q_pri_val_reg:          QUEUE_PRI_VAL register val
0089  * @rc_q_maxsize_reg:           RC_QUEUE_MAXSIZE register val
0090  * @bri_q_maxsize_reg:          BRI_QUEUE_MAXSIZE register val
0091  * @comp_resp_timeout_reg:      COMP_RESP_TIMEOUT register val
0092  * @bus_slave_control_reg:      BUS_SLAVE_CONTROL_REG register val
0093  * @deadlock_avoid_type_reg:        DEADLOCK_AVOID_TYPE register val
0094  * @intpin_reg_wpermit_reg0:        INTPIN_REG_WPERMIT register 0 val
0095  * @intpin_reg_wpermit_reg1:        INTPIN_REG_WPERMIT register 1 val
0096  * @intpin_reg_wpermit_reg2:        INTPIN_REG_WPERMIT register 2 val
0097  * @intpin_reg_wpermit_reg3:        INTPIN_REG_WPERMIT register 3 val
0098  * @int_reduce_control_reg:     INT_REDUCE_CONTROL registers val
0099  * @clkcfg_reg:             CLK CFG register val
0100  * @funcsel_reg:            Function select register value
0101  * @pch_phub_base_address:      Register base address
0102  * @pch_phub_extrom_base_address:   external rom base address
0103  * @pch_mac_start_address:      MAC address area start address
0104  * @pch_opt_rom_start_address:      Option ROM start address
0105  * @ioh_type:               Save IOH type
0106  * @pdev:               pointer to pci device struct
0107  */
0108 struct pch_phub_reg {
0109     u32 phub_id_reg;
0110     u32 q_pri_val_reg;
0111     u32 rc_q_maxsize_reg;
0112     u32 bri_q_maxsize_reg;
0113     u32 comp_resp_timeout_reg;
0114     u32 bus_slave_control_reg;
0115     u32 deadlock_avoid_type_reg;
0116     u32 intpin_reg_wpermit_reg0;
0117     u32 intpin_reg_wpermit_reg1;
0118     u32 intpin_reg_wpermit_reg2;
0119     u32 intpin_reg_wpermit_reg3;
0120     u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG];
0121     u32 clkcfg_reg;
0122     u32 funcsel_reg;
0123     void __iomem *pch_phub_base_address;
0124     void __iomem *pch_phub_extrom_base_address;
0125     u32 pch_mac_start_address;
0126     u32 pch_opt_rom_start_address;
0127     int ioh_type;
0128     struct pci_dev *pdev;
0129 };
0130 
0131 /* SROM SPEC for MAC address assignment offset */
0132 static const int pch_phub_mac_offset[ETH_ALEN] = {0x3, 0x2, 0x1, 0x0, 0xb, 0xa};
0133 
0134 static DEFINE_MUTEX(pch_phub_mutex);
0135 
0136 /**
0137  * pch_phub_read_modify_write_reg() - Reading modifying and writing register
0138  * @chip:       Pointer to the PHUB register structure
0139  * @reg_addr_offset:    Register offset address value.
0140  * @data:       Writing value.
0141  * @mask:       Mask value.
0142  */
0143 static void pch_phub_read_modify_write_reg(struct pch_phub_reg *chip,
0144                        unsigned int reg_addr_offset,
0145                        unsigned int data, unsigned int mask)
0146 {
0147     void __iomem *reg_addr = chip->pch_phub_base_address + reg_addr_offset;
0148     iowrite32(((ioread32(reg_addr) & ~mask)) | data, reg_addr);
0149 }
0150 
0151 /* pch_phub_save_reg_conf - saves register configuration */
0152 static void __maybe_unused pch_phub_save_reg_conf(struct pci_dev *pdev)
0153 {
0154     unsigned int i;
0155     struct pch_phub_reg *chip = pci_get_drvdata(pdev);
0156 
0157     void __iomem *p = chip->pch_phub_base_address;
0158 
0159     chip->phub_id_reg = ioread32(p + PCH_PHUB_ID_REG);
0160     chip->q_pri_val_reg = ioread32(p + PCH_PHUB_QUEUE_PRI_VAL_REG);
0161     chip->rc_q_maxsize_reg = ioread32(p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
0162     chip->bri_q_maxsize_reg = ioread32(p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
0163     chip->comp_resp_timeout_reg =
0164                 ioread32(p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
0165     chip->bus_slave_control_reg =
0166                 ioread32(p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
0167     chip->deadlock_avoid_type_reg =
0168                 ioread32(p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
0169     chip->intpin_reg_wpermit_reg0 =
0170                 ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
0171     chip->intpin_reg_wpermit_reg1 =
0172                 ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
0173     chip->intpin_reg_wpermit_reg2 =
0174                 ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
0175     chip->intpin_reg_wpermit_reg3 =
0176                 ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
0177     dev_dbg(&pdev->dev, "%s : "
0178         "chip->phub_id_reg=%x, "
0179         "chip->q_pri_val_reg=%x, "
0180         "chip->rc_q_maxsize_reg=%x, "
0181         "chip->bri_q_maxsize_reg=%x, "
0182         "chip->comp_resp_timeout_reg=%x, "
0183         "chip->bus_slave_control_reg=%x, "
0184         "chip->deadlock_avoid_type_reg=%x, "
0185         "chip->intpin_reg_wpermit_reg0=%x, "
0186         "chip->intpin_reg_wpermit_reg1=%x, "
0187         "chip->intpin_reg_wpermit_reg2=%x, "
0188         "chip->intpin_reg_wpermit_reg3=%x\n", __func__,
0189         chip->phub_id_reg,
0190         chip->q_pri_val_reg,
0191         chip->rc_q_maxsize_reg,
0192         chip->bri_q_maxsize_reg,
0193         chip->comp_resp_timeout_reg,
0194         chip->bus_slave_control_reg,
0195         chip->deadlock_avoid_type_reg,
0196         chip->intpin_reg_wpermit_reg0,
0197         chip->intpin_reg_wpermit_reg1,
0198         chip->intpin_reg_wpermit_reg2,
0199         chip->intpin_reg_wpermit_reg3);
0200     for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
0201         chip->int_reduce_control_reg[i] =
0202             ioread32(p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
0203         dev_dbg(&pdev->dev, "%s : "
0204             "chip->int_reduce_control_reg[%d]=%x\n",
0205             __func__, i, chip->int_reduce_control_reg[i]);
0206     }
0207     chip->clkcfg_reg = ioread32(p + CLKCFG_REG_OFFSET);
0208     if ((chip->ioh_type == 2) || (chip->ioh_type == 4))
0209         chip->funcsel_reg = ioread32(p + FUNCSEL_REG_OFFSET);
0210 }
0211 
0212 /* pch_phub_restore_reg_conf - restore register configuration */
0213 static void __maybe_unused pch_phub_restore_reg_conf(struct pci_dev *pdev)
0214 {
0215     unsigned int i;
0216     struct pch_phub_reg *chip = pci_get_drvdata(pdev);
0217     void __iomem *p;
0218     p = chip->pch_phub_base_address;
0219 
0220     iowrite32(chip->phub_id_reg, p + PCH_PHUB_ID_REG);
0221     iowrite32(chip->q_pri_val_reg, p + PCH_PHUB_QUEUE_PRI_VAL_REG);
0222     iowrite32(chip->rc_q_maxsize_reg, p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
0223     iowrite32(chip->bri_q_maxsize_reg, p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
0224     iowrite32(chip->comp_resp_timeout_reg,
0225                     p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
0226     iowrite32(chip->bus_slave_control_reg,
0227                     p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
0228     iowrite32(chip->deadlock_avoid_type_reg,
0229                     p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
0230     iowrite32(chip->intpin_reg_wpermit_reg0,
0231                     p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
0232     iowrite32(chip->intpin_reg_wpermit_reg1,
0233                     p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
0234     iowrite32(chip->intpin_reg_wpermit_reg2,
0235                     p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
0236     iowrite32(chip->intpin_reg_wpermit_reg3,
0237                     p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
0238     dev_dbg(&pdev->dev, "%s : "
0239         "chip->phub_id_reg=%x, "
0240         "chip->q_pri_val_reg=%x, "
0241         "chip->rc_q_maxsize_reg=%x, "
0242         "chip->bri_q_maxsize_reg=%x, "
0243         "chip->comp_resp_timeout_reg=%x, "
0244         "chip->bus_slave_control_reg=%x, "
0245         "chip->deadlock_avoid_type_reg=%x, "
0246         "chip->intpin_reg_wpermit_reg0=%x, "
0247         "chip->intpin_reg_wpermit_reg1=%x, "
0248         "chip->intpin_reg_wpermit_reg2=%x, "
0249         "chip->intpin_reg_wpermit_reg3=%x\n", __func__,
0250         chip->phub_id_reg,
0251         chip->q_pri_val_reg,
0252         chip->rc_q_maxsize_reg,
0253         chip->bri_q_maxsize_reg,
0254         chip->comp_resp_timeout_reg,
0255         chip->bus_slave_control_reg,
0256         chip->deadlock_avoid_type_reg,
0257         chip->intpin_reg_wpermit_reg0,
0258         chip->intpin_reg_wpermit_reg1,
0259         chip->intpin_reg_wpermit_reg2,
0260         chip->intpin_reg_wpermit_reg3);
0261     for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
0262         iowrite32(chip->int_reduce_control_reg[i],
0263             p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
0264         dev_dbg(&pdev->dev, "%s : "
0265             "chip->int_reduce_control_reg[%d]=%x\n",
0266             __func__, i, chip->int_reduce_control_reg[i]);
0267     }
0268 
0269     iowrite32(chip->clkcfg_reg, p + CLKCFG_REG_OFFSET);
0270     if ((chip->ioh_type == 2) || (chip->ioh_type == 4))
0271         iowrite32(chip->funcsel_reg, p + FUNCSEL_REG_OFFSET);
0272 }
0273 
0274 /**
0275  * pch_phub_read_serial_rom() - Reading Serial ROM
0276  * @chip:       Pointer to the PHUB register structure
0277  * @offset_address: Serial ROM offset address to read.
0278  * @data:       Read buffer for specified Serial ROM value.
0279  */
0280 static void pch_phub_read_serial_rom(struct pch_phub_reg *chip,
0281                      unsigned int offset_address, u8 *data)
0282 {
0283     void __iomem *mem_addr = chip->pch_phub_extrom_base_address +
0284                                 offset_address;
0285 
0286     *data = ioread8(mem_addr);
0287 }
0288 
0289 /**
0290  * pch_phub_write_serial_rom() - Writing Serial ROM
0291  * @chip:       Pointer to the PHUB register structure
0292  * @offset_address: Serial ROM offset address.
0293  * @data:       Serial ROM value to write.
0294  */
0295 static int pch_phub_write_serial_rom(struct pch_phub_reg *chip,
0296                      unsigned int offset_address, u8 data)
0297 {
0298     void __iomem *mem_addr = chip->pch_phub_extrom_base_address +
0299                     (offset_address & PCH_WORD_ADDR_MASK);
0300     int i;
0301     unsigned int word_data;
0302     unsigned int pos;
0303     unsigned int mask;
0304     pos = (offset_address % 4) * 8;
0305     mask = ~(0xFF << pos);
0306 
0307     iowrite32(PCH_PHUB_ROM_WRITE_ENABLE,
0308             chip->pch_phub_extrom_base_address + PHUB_CONTROL);
0309 
0310     word_data = ioread32(mem_addr);
0311     iowrite32((word_data & mask) | (u32)data << pos, mem_addr);
0312 
0313     i = 0;
0314     while (ioread8(chip->pch_phub_extrom_base_address +
0315                         PHUB_STATUS) != 0x00) {
0316         msleep(1);
0317         if (i == PHUB_TIMEOUT)
0318             return -ETIMEDOUT;
0319         i++;
0320     }
0321 
0322     iowrite32(PCH_PHUB_ROM_WRITE_DISABLE,
0323             chip->pch_phub_extrom_base_address + PHUB_CONTROL);
0324 
0325     return 0;
0326 }
0327 
0328 /**
0329  * pch_phub_read_serial_rom_val() - Read Serial ROM value
0330  * @chip:       Pointer to the PHUB register structure
0331  * @offset_address: Serial ROM address offset value.
0332  * @data:       Serial ROM value to read.
0333  */
0334 static void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip,
0335                      unsigned int offset_address, u8 *data)
0336 {
0337     unsigned int mem_addr;
0338 
0339     mem_addr = chip->pch_mac_start_address +
0340             pch_phub_mac_offset[offset_address];
0341 
0342     pch_phub_read_serial_rom(chip, mem_addr, data);
0343 }
0344 
0345 /**
0346  * pch_phub_write_serial_rom_val() - writing Serial ROM value
0347  * @chip:       Pointer to the PHUB register structure
0348  * @offset_address: Serial ROM address offset value.
0349  * @data:       Serial ROM value.
0350  */
0351 static int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip,
0352                      unsigned int offset_address, u8 data)
0353 {
0354     int retval;
0355     unsigned int mem_addr;
0356 
0357     mem_addr = chip->pch_mac_start_address +
0358             pch_phub_mac_offset[offset_address];
0359 
0360     retval = pch_phub_write_serial_rom(chip, mem_addr, data);
0361 
0362     return retval;
0363 }
0364 
0365 /* pch_phub_gbe_serial_rom_conf - makes Serial ROM header format configuration
0366  * for Gigabit Ethernet MAC address
0367  */
0368 static int pch_phub_gbe_serial_rom_conf(struct pch_phub_reg *chip)
0369 {
0370     int retval;
0371 
0372     retval = pch_phub_write_serial_rom(chip, 0x0b, 0xbc);
0373     retval |= pch_phub_write_serial_rom(chip, 0x0a, 0x10);
0374     retval |= pch_phub_write_serial_rom(chip, 0x09, 0x01);
0375     retval |= pch_phub_write_serial_rom(chip, 0x08, 0x02);
0376 
0377     retval |= pch_phub_write_serial_rom(chip, 0x0f, 0x00);
0378     retval |= pch_phub_write_serial_rom(chip, 0x0e, 0x00);
0379     retval |= pch_phub_write_serial_rom(chip, 0x0d, 0x00);
0380     retval |= pch_phub_write_serial_rom(chip, 0x0c, 0x80);
0381 
0382     retval |= pch_phub_write_serial_rom(chip, 0x13, 0xbc);
0383     retval |= pch_phub_write_serial_rom(chip, 0x12, 0x10);
0384     retval |= pch_phub_write_serial_rom(chip, 0x11, 0x01);
0385     retval |= pch_phub_write_serial_rom(chip, 0x10, 0x18);
0386 
0387     retval |= pch_phub_write_serial_rom(chip, 0x1b, 0xbc);
0388     retval |= pch_phub_write_serial_rom(chip, 0x1a, 0x10);
0389     retval |= pch_phub_write_serial_rom(chip, 0x19, 0x01);
0390     retval |= pch_phub_write_serial_rom(chip, 0x18, 0x19);
0391 
0392     retval |= pch_phub_write_serial_rom(chip, 0x23, 0xbc);
0393     retval |= pch_phub_write_serial_rom(chip, 0x22, 0x10);
0394     retval |= pch_phub_write_serial_rom(chip, 0x21, 0x01);
0395     retval |= pch_phub_write_serial_rom(chip, 0x20, 0x3a);
0396 
0397     retval |= pch_phub_write_serial_rom(chip, 0x27, 0x01);
0398     retval |= pch_phub_write_serial_rom(chip, 0x26, 0x00);
0399     retval |= pch_phub_write_serial_rom(chip, 0x25, 0x00);
0400     retval |= pch_phub_write_serial_rom(chip, 0x24, 0x00);
0401 
0402     return retval;
0403 }
0404 
0405 /* pch_phub_gbe_serial_rom_conf_mp - makes SerialROM header format configuration
0406  * for Gigabit Ethernet MAC address
0407  */
0408 static int pch_phub_gbe_serial_rom_conf_mp(struct pch_phub_reg *chip)
0409 {
0410     int retval;
0411     u32 offset_addr;
0412 
0413     offset_addr = 0x200;
0414     retval = pch_phub_write_serial_rom(chip, 0x03 + offset_addr, 0xbc);
0415     retval |= pch_phub_write_serial_rom(chip, 0x02 + offset_addr, 0x00);
0416     retval |= pch_phub_write_serial_rom(chip, 0x01 + offset_addr, 0x40);
0417     retval |= pch_phub_write_serial_rom(chip, 0x00 + offset_addr, 0x02);
0418 
0419     retval |= pch_phub_write_serial_rom(chip, 0x07 + offset_addr, 0x00);
0420     retval |= pch_phub_write_serial_rom(chip, 0x06 + offset_addr, 0x00);
0421     retval |= pch_phub_write_serial_rom(chip, 0x05 + offset_addr, 0x00);
0422     retval |= pch_phub_write_serial_rom(chip, 0x04 + offset_addr, 0x80);
0423 
0424     retval |= pch_phub_write_serial_rom(chip, 0x0b + offset_addr, 0xbc);
0425     retval |= pch_phub_write_serial_rom(chip, 0x0a + offset_addr, 0x00);
0426     retval |= pch_phub_write_serial_rom(chip, 0x09 + offset_addr, 0x40);
0427     retval |= pch_phub_write_serial_rom(chip, 0x08 + offset_addr, 0x18);
0428 
0429     retval |= pch_phub_write_serial_rom(chip, 0x13 + offset_addr, 0xbc);
0430     retval |= pch_phub_write_serial_rom(chip, 0x12 + offset_addr, 0x00);
0431     retval |= pch_phub_write_serial_rom(chip, 0x11 + offset_addr, 0x40);
0432     retval |= pch_phub_write_serial_rom(chip, 0x10 + offset_addr, 0x19);
0433 
0434     retval |= pch_phub_write_serial_rom(chip, 0x1b + offset_addr, 0xbc);
0435     retval |= pch_phub_write_serial_rom(chip, 0x1a + offset_addr, 0x00);
0436     retval |= pch_phub_write_serial_rom(chip, 0x19 + offset_addr, 0x40);
0437     retval |= pch_phub_write_serial_rom(chip, 0x18 + offset_addr, 0x3a);
0438 
0439     retval |= pch_phub_write_serial_rom(chip, 0x1f + offset_addr, 0x01);
0440     retval |= pch_phub_write_serial_rom(chip, 0x1e + offset_addr, 0x00);
0441     retval |= pch_phub_write_serial_rom(chip, 0x1d + offset_addr, 0x00);
0442     retval |= pch_phub_write_serial_rom(chip, 0x1c + offset_addr, 0x00);
0443 
0444     return retval;
0445 }
0446 
0447 /**
0448  * pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address
0449  * @chip:       Pointer to the PHUB register structure
0450  * @data:       Buffer of the Gigabit Ethernet MAC address value.
0451  */
0452 static void pch_phub_read_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
0453 {
0454     int i;
0455     for (i = 0; i < ETH_ALEN; i++)
0456         pch_phub_read_serial_rom_val(chip, i, &data[i]);
0457 }
0458 
0459 /**
0460  * pch_phub_write_gbe_mac_addr() - Write MAC address
0461  * @chip:       Pointer to the PHUB register structure
0462  * @data:       Gigabit Ethernet MAC address value.
0463  */
0464 static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
0465 {
0466     int retval;
0467     int i;
0468 
0469     if ((chip->ioh_type == 1) || (chip->ioh_type == 5)) /* EG20T or ML7831*/
0470         retval = pch_phub_gbe_serial_rom_conf(chip);
0471     else    /* ML7223 */
0472         retval = pch_phub_gbe_serial_rom_conf_mp(chip);
0473     if (retval)
0474         return retval;
0475 
0476     for (i = 0; i < ETH_ALEN; i++) {
0477         retval = pch_phub_write_serial_rom_val(chip, i, data[i]);
0478         if (retval)
0479             return retval;
0480     }
0481 
0482     return retval;
0483 }
0484 
0485 static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
0486                  struct bin_attribute *attr, char *buf,
0487                  loff_t off, size_t count)
0488 {
0489     unsigned int rom_signature;
0490     unsigned char rom_length;
0491     unsigned int tmp;
0492     unsigned int addr_offset;
0493     unsigned int orom_size;
0494     int ret;
0495     int err;
0496     ssize_t rom_size;
0497 
0498     struct pch_phub_reg *chip = dev_get_drvdata(kobj_to_dev(kobj));
0499 
0500     ret = mutex_lock_interruptible(&pch_phub_mutex);
0501     if (ret) {
0502         err = -ERESTARTSYS;
0503         goto return_err_nomutex;
0504     }
0505 
0506     /* Get Rom signature */
0507     chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
0508     if (!chip->pch_phub_extrom_base_address) {
0509         err = -ENODATA;
0510         goto exrom_map_err;
0511     }
0512 
0513     pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address,
0514                 (unsigned char *)&rom_signature);
0515     rom_signature &= 0xff;
0516     pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address + 1,
0517                 (unsigned char *)&tmp);
0518     rom_signature |= (tmp & 0xff) << 8;
0519     if (rom_signature == 0xAA55) {
0520         pch_phub_read_serial_rom(chip,
0521                      chip->pch_opt_rom_start_address + 2,
0522                      &rom_length);
0523         orom_size = rom_length * 512;
0524         if (orom_size < off) {
0525             addr_offset = 0;
0526             goto return_ok;
0527         }
0528         if (orom_size < count) {
0529             addr_offset = 0;
0530             goto return_ok;
0531         }
0532 
0533         for (addr_offset = 0; addr_offset < count; addr_offset++) {
0534             pch_phub_read_serial_rom(chip,
0535                 chip->pch_opt_rom_start_address + addr_offset + off,
0536                 &buf[addr_offset]);
0537         }
0538     } else {
0539         err = -ENODATA;
0540         goto return_err;
0541     }
0542 return_ok:
0543     pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
0544     mutex_unlock(&pch_phub_mutex);
0545     return addr_offset;
0546 
0547 return_err:
0548     pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
0549 exrom_map_err:
0550     mutex_unlock(&pch_phub_mutex);
0551 return_err_nomutex:
0552     return err;
0553 }
0554 
0555 static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
0556                   struct bin_attribute *attr,
0557                   char *buf, loff_t off, size_t count)
0558 {
0559     int err;
0560     unsigned int addr_offset;
0561     int ret;
0562     ssize_t rom_size;
0563     struct pch_phub_reg *chip = dev_get_drvdata(kobj_to_dev(kobj));
0564 
0565     ret = mutex_lock_interruptible(&pch_phub_mutex);
0566     if (ret)
0567         return -ERESTARTSYS;
0568 
0569     if (off > PCH_PHUB_OROM_SIZE) {
0570         addr_offset = 0;
0571         goto return_ok;
0572     }
0573     if (count > PCH_PHUB_OROM_SIZE) {
0574         addr_offset = 0;
0575         goto return_ok;
0576     }
0577 
0578     chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
0579     if (!chip->pch_phub_extrom_base_address) {
0580         err = -ENOMEM;
0581         goto exrom_map_err;
0582     }
0583 
0584     for (addr_offset = 0; addr_offset < count; addr_offset++) {
0585         if (PCH_PHUB_OROM_SIZE < off + addr_offset)
0586             goto return_ok;
0587 
0588         ret = pch_phub_write_serial_rom(chip,
0589                 chip->pch_opt_rom_start_address + addr_offset + off,
0590                 buf[addr_offset]);
0591         if (ret) {
0592             err = ret;
0593             goto return_err;
0594         }
0595     }
0596 
0597 return_ok:
0598     pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
0599     mutex_unlock(&pch_phub_mutex);
0600     return addr_offset;
0601 
0602 return_err:
0603     pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
0604 
0605 exrom_map_err:
0606     mutex_unlock(&pch_phub_mutex);
0607     return err;
0608 }
0609 
0610 static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr,
0611                 char *buf)
0612 {
0613     u8 mac[8];
0614     struct pch_phub_reg *chip = dev_get_drvdata(dev);
0615     ssize_t rom_size;
0616 
0617     chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
0618     if (!chip->pch_phub_extrom_base_address)
0619         return -ENOMEM;
0620 
0621     pch_phub_read_gbe_mac_addr(chip, mac);
0622     pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
0623 
0624     return sprintf(buf, "%pM\n", mac);
0625 }
0626 
0627 static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
0628                  const char *buf, size_t count)
0629 {
0630     u8 mac[ETH_ALEN];
0631     ssize_t rom_size;
0632     struct pch_phub_reg *chip = dev_get_drvdata(dev);
0633     int ret;
0634 
0635     if (!mac_pton(buf, mac))
0636         return -EINVAL;
0637 
0638     chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
0639     if (!chip->pch_phub_extrom_base_address)
0640         return -ENOMEM;
0641 
0642     ret = pch_phub_write_gbe_mac_addr(chip, mac);
0643     pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
0644     if (ret)
0645         return ret;
0646 
0647     return count;
0648 }
0649 
0650 static DEVICE_ATTR(pch_mac, S_IRUGO | S_IWUSR, show_pch_mac, store_pch_mac);
0651 
0652 static const struct bin_attribute pch_bin_attr = {
0653     .attr = {
0654         .name = "pch_firmware",
0655         .mode = S_IRUGO | S_IWUSR,
0656     },
0657     .size = PCH_PHUB_OROM_SIZE + 1,
0658     .read = pch_phub_bin_read,
0659     .write = pch_phub_bin_write,
0660 };
0661 
0662 static int pch_phub_probe(struct pci_dev *pdev,
0663                     const struct pci_device_id *id)
0664 {
0665     int ret;
0666     struct pch_phub_reg *chip;
0667 
0668     chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL);
0669     if (chip == NULL)
0670         return -ENOMEM;
0671 
0672     ret = pci_enable_device(pdev);
0673     if (ret) {
0674         dev_err(&pdev->dev,
0675         "%s : pci_enable_device FAILED(ret=%d)", __func__, ret);
0676         goto err_pci_enable_dev;
0677     }
0678     dev_dbg(&pdev->dev, "%s : pci_enable_device returns %d\n", __func__,
0679         ret);
0680 
0681     ret = pci_request_regions(pdev, KBUILD_MODNAME);
0682     if (ret) {
0683         dev_err(&pdev->dev,
0684         "%s : pci_request_regions FAILED(ret=%d)", __func__, ret);
0685         goto err_req_regions;
0686     }
0687     dev_dbg(&pdev->dev, "%s : "
0688         "pci_request_regions returns %d\n", __func__, ret);
0689 
0690     chip->pch_phub_base_address = pci_iomap(pdev, 1, 0);
0691 
0692 
0693     if (chip->pch_phub_base_address == NULL) {
0694         dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__);
0695         ret = -ENOMEM;
0696         goto err_pci_iomap;
0697     }
0698     dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value "
0699         "in pch_phub_base_address variable is %p\n", __func__,
0700         chip->pch_phub_base_address);
0701 
0702     chip->pdev = pdev; /* Save pci device struct */
0703 
0704     if (id->driver_data == 1) { /* EG20T PCH */
0705         const char *board_name;
0706         unsigned int prefetch = 0x000affaa;
0707 
0708         if (pdev->dev.of_node)
0709             of_property_read_u32(pdev->dev.of_node,
0710                           "intel,eg20t-prefetch",
0711                           &prefetch);
0712 
0713         ret = sysfs_create_file(&pdev->dev.kobj,
0714                     &dev_attr_pch_mac.attr);
0715         if (ret)
0716             goto err_sysfs_create;
0717 
0718         ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
0719         if (ret)
0720             goto exit_bin_attr;
0721 
0722         pch_phub_read_modify_write_reg(chip,
0723                            (unsigned int)CLKCFG_REG_OFFSET,
0724                            CLKCFG_CAN_50MHZ,
0725                            CLKCFG_CANCLK_MASK);
0726 
0727         /* quirk for CM-iTC board */
0728         board_name = dmi_get_system_info(DMI_BOARD_NAME);
0729         if (board_name && strstr(board_name, "CM-iTC"))
0730             pch_phub_read_modify_write_reg(chip,
0731                         (unsigned int)CLKCFG_REG_OFFSET,
0732                         CLKCFG_UART_48MHZ | CLKCFG_BAUDDIV |
0733                         CLKCFG_PLL2VCO | CLKCFG_UARTCLKSEL,
0734                         CLKCFG_UART_MASK);
0735 
0736         /* set the prefech value */
0737         iowrite32(prefetch, chip->pch_phub_base_address + 0x14);
0738         /* set the interrupt delay value */
0739         iowrite32(0x25, chip->pch_phub_base_address + 0x44);
0740         chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
0741         chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
0742 
0743         /* quirk for MIPS Boston platform */
0744         if (pdev->dev.of_node) {
0745             if (of_machine_is_compatible("img,boston")) {
0746                 pch_phub_read_modify_write_reg(chip,
0747                     (unsigned int)CLKCFG_REG_OFFSET,
0748                     CLKCFG_UART_25MHZ,
0749                     CLKCFG_UART_MASK);
0750             }
0751         }
0752     } else if (id->driver_data == 2) { /* ML7213 IOH */
0753         ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
0754         if (ret)
0755             goto err_sysfs_create;
0756         /* set the prefech value
0757          * Device2(USB OHCI #1/ USB EHCI #1/ USB Device):a
0758          * Device4(SDIO #0,1,2):f
0759          * Device6(SATA 2):f
0760          * Device8(USB OHCI #0/ USB EHCI #0):a
0761          */
0762         iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14);
0763         chip->pch_opt_rom_start_address =\
0764                          PCH_PHUB_ROM_START_ADDR_ML7213;
0765     } else if (id->driver_data == 3) { /* ML7223 IOH Bus-m*/
0766         /* set the prefech value
0767          * Device8(GbE)
0768          */
0769         iowrite32(0x000a0000, chip->pch_phub_base_address + 0x14);
0770         /* set the interrupt delay value */
0771         iowrite32(0x25, chip->pch_phub_base_address + 0x140);
0772         chip->pch_opt_rom_start_address =\
0773                          PCH_PHUB_ROM_START_ADDR_ML7223;
0774         chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
0775     } else if (id->driver_data == 4) { /* ML7223 IOH Bus-n*/
0776         ret = sysfs_create_file(&pdev->dev.kobj,
0777                     &dev_attr_pch_mac.attr);
0778         if (ret)
0779             goto err_sysfs_create;
0780         ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
0781         if (ret)
0782             goto exit_bin_attr;
0783         /* set the prefech value
0784          * Device2(USB OHCI #0,1,2,3/ USB EHCI #0):a
0785          * Device4(SDIO #0,1):f
0786          * Device6(SATA 2):f
0787          */
0788         iowrite32(0x0000ffa0, chip->pch_phub_base_address + 0x14);
0789         chip->pch_opt_rom_start_address =\
0790                          PCH_PHUB_ROM_START_ADDR_ML7223;
0791         chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
0792     } else if (id->driver_data == 5) { /* ML7831 */
0793         ret = sysfs_create_file(&pdev->dev.kobj,
0794                     &dev_attr_pch_mac.attr);
0795         if (ret)
0796             goto err_sysfs_create;
0797 
0798         ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
0799         if (ret)
0800             goto exit_bin_attr;
0801 
0802         /* set the prefech value */
0803         iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
0804         /* set the interrupt delay value */
0805         iowrite32(0x25, chip->pch_phub_base_address + 0x44);
0806         chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
0807         chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
0808     }
0809 
0810     chip->ioh_type = id->driver_data;
0811     pci_set_drvdata(pdev, chip);
0812 
0813     return 0;
0814 exit_bin_attr:
0815     sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
0816 
0817 err_sysfs_create:
0818     pci_iounmap(pdev, chip->pch_phub_base_address);
0819 err_pci_iomap:
0820     pci_release_regions(pdev);
0821 err_req_regions:
0822     pci_disable_device(pdev);
0823 err_pci_enable_dev:
0824     kfree(chip);
0825     dev_err(&pdev->dev, "%s returns %d\n", __func__, ret);
0826     return ret;
0827 }
0828 
0829 static void pch_phub_remove(struct pci_dev *pdev)
0830 {
0831     struct pch_phub_reg *chip = pci_get_drvdata(pdev);
0832 
0833     sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
0834     sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr);
0835     pci_iounmap(pdev, chip->pch_phub_base_address);
0836     pci_release_regions(pdev);
0837     pci_disable_device(pdev);
0838     kfree(chip);
0839 }
0840 
0841 static int __maybe_unused pch_phub_suspend(struct device *dev_d)
0842 {
0843     device_wakeup_disable(dev_d);
0844 
0845     return 0;
0846 }
0847 
0848 static int __maybe_unused pch_phub_resume(struct device *dev_d)
0849 {
0850     device_wakeup_disable(dev_d);
0851 
0852     return 0;
0853 }
0854 
0855 static const struct pci_device_id pch_phub_pcidev_id[] = {
0856     { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB),       1,  },
0857     { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2,  },
0858     { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3,  },
0859     { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4,  },
0860     { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7831_PHUB), 5,  },
0861     { }
0862 };
0863 MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id);
0864 
0865 static SIMPLE_DEV_PM_OPS(pch_phub_pm_ops, pch_phub_suspend, pch_phub_resume);
0866 
0867 static struct pci_driver pch_phub_driver = {
0868     .name = "pch_phub",
0869     .id_table = pch_phub_pcidev_id,
0870     .probe = pch_phub_probe,
0871     .remove = pch_phub_remove,
0872     .driver.pm = &pch_phub_pm_ops,
0873 };
0874 
0875 module_pci_driver(pch_phub_driver);
0876 
0877 MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7223) PHUB");
0878 MODULE_LICENSE("GPL");