dm: ppc: T4240: add i2c DM support
authorBiwen Li <biwen.li@nxp.com>
Fri, 1 May 2020 12:04:17 +0000 (20:04 +0800)
committerPriyanka Jain <priyanka.jain@nxp.com>
Mon, 4 May 2020 03:42:36 +0000 (09:12 +0530)
This supports i2c DM for SoC T4240

Signed-off-by: Biwen Li <biwen.li@nxp.com>
Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
arch/powerpc/dts/t4240.dtsi
board/freescale/common/vsc3316_3308.c
board/freescale/t4qds/t4240qds.c
include/configs/T4240QDS.h
include/configs/T4240RDB.h

index 43f98cd9e1630e884f835e0080d4e0bf56632d7a..9b5902fe9e228167cd99ec33b7c4711fdfc5fca8 100644 (file)
@@ -3,7 +3,7 @@
  * T4240 Silicon/SoC Device Tree Source (pre include)
  *
  * Copyright 2013 Freescale Semiconductor Inc.
- * Copyright 2019 NXP
+ * Copyright 2019-2020 NXP
  */
 
 /dts-v1/;
                        reg = <0x114000 0x1000>;
                        clock-frequency = <0>;
                };
+
+               /include/ "qoriq-i2c-0.dtsi"
+               /include/ "qoriq-i2c-1.dtsi"
        };
 
        pcie@ffe240000 {
index 033fae020f12c01b9758674636db3905d66dec49..f0d273ca201bb9859d1872b86ded3fc7bf46152a 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2020 NXP
  */
 
 #include "vsc3316_3308.h"
@@ -32,7 +33,22 @@ int vsc_if_enable(unsigned int vsc_addr)
 
        /* enable 2-wire Serial InterFace (I2C) */
        data = 0x02;
+#ifdef CONFIG_DM_I2C
+       int ret, bus_num = 0;
+       struct udevice *dev;
+
+       ret = i2c_get_chip_for_busnum(bus_num, vsc_addr,
+                                     1, &dev);
+       if (ret) {
+               printf("%s: Cannot find udev for a bus %d\n", __func__,
+                      bus_num);
+               return ret;
+       }
+
+       return dm_i2c_write(dev, INTERFACE_MODE_REG, &data, 1);
+#else
        return i2c_write(vsc_addr, INTERFACE_MODE_REG, 1, &data, 1);
+#endif
 }
 
 int vsc3316_config(unsigned int vsc_addr, int8_t con_arr[][2],
@@ -45,6 +61,66 @@ int vsc3316_config(unsigned int vsc_addr, int8_t con_arr[][2],
        debug("VSC:Initializing VSC3316 at I2C address 0x%2x"
                " for Tx\n", vsc_addr);
 
+#ifdef CONFIG_DM_I2C
+       int bus_num = 0;
+       struct udevice *dev;
+
+       ret = i2c_get_chip_for_busnum(bus_num, vsc_addr,
+                                     1, &dev);
+       if (ret) {
+               printf("%s: Cannot find udev for a bus %d\n", __func__,
+                      bus_num);
+               return ret;
+       }
+
+       ret = dm_i2c_read(dev, REVISION_ID_REG, &rev_id, 1);
+       if (ret < 0) {
+               printf("VSC:0x%x could not read REV_ID from device.\n",
+                      vsc_addr);
+               return ret;
+       }
+
+       if (rev_id != 0xab) {
+               printf("VSC: device at address 0x%x is not VSC3316/3308.\n",
+                      vsc_addr);
+               return -ENODEV;
+       }
+
+       ret = vsc_if_enable(vsc_addr);
+       if (ret) {
+               printf("VSC:0x%x could not configured for 2-wire I/F.\n",
+                      vsc_addr);
+               return ret;
+       }
+
+       /* config connections - page 0x00 */
+       dm_i2c_reg_write(dev, CURRENT_PAGE_REGISTER, CONNECTION_CONFIG_PAGE);
+
+       /* Making crosspoint connections, by connecting required
+        * input to output
+        */
+       for (i = 0; i < num_con ; i++)
+               dm_i2c_reg_write(dev, con_arr[i][1], con_arr[i][0]);
+
+       /* input state - page 0x13 */
+       dm_i2c_reg_write(dev, CURRENT_PAGE_REGISTER, INPUT_STATE_REG);
+       /* Configuring the required input of the switch */
+       for (i = 0; i < num_con ; i++)
+               dm_i2c_reg_write(dev, con_arr[i][0], 0x80);
+
+       /* Setting Global Input LOS threshold value */
+       dm_i2c_reg_write(dev, GLOBAL_INPUT_LOS, 0x60);
+
+       /* config output mode - page 0x23 */
+       dm_i2c_reg_write(dev, CURRENT_PAGE_REGISTER, OUTPUT_MODE_PAGE);
+       /* Turn ON the Output driver correspond to required output*/
+       for (i = 0; i < num_con ; i++)
+               dm_i2c_reg_write(dev,  con_arr[i][1], 0);
+
+       /* configure global core control register, Turn on Global core power */
+       dm_i2c_reg_write(dev, GLOBAL_CORE_CNTRL, 0);
+
+#else
        ret = i2c_read(vsc_addr, REVISION_ID_REG, 1, &rev_id, 1);
        if (ret < 0) {
                printf("VSC:0x%x could not read REV_ID from device.\n",
@@ -90,6 +166,7 @@ int vsc3316_config(unsigned int vsc_addr, int8_t con_arr[][2],
 
        /* configure global core control register, Turn on Global core power */
        i2c_reg_write(vsc_addr, GLOBAL_CORE_CNTRL, 0);
+#endif
 
        vsc_wp_config(vsc_addr);
 
@@ -107,6 +184,105 @@ int vsc3308_config_adjust(unsigned int vsc_addr, const int8_t con_arr[][2],
        debug("VSC:Initializing VSC3308 at I2C address 0x%x for Tx\n",
              vsc_addr);
 
+#ifdef CONFIG_DM_I2C
+       int bus_num = 0;
+       struct udevice *dev;
+
+       ret = i2c_get_chip_for_busnum(bus_num, vsc_addr,
+                                     1, &dev);
+       if (ret) {
+               printf("%s: Cannot find udev for a bus %d\n", __func__,
+                      bus_num);
+               return ret;
+       }
+
+       ret = dm_i2c_read(dev, REVISION_ID_REG, &rev_id, 1);
+       if (ret < 0) {
+               printf("VSC:0x%x could not read REV_ID from device.\n",
+                      vsc_addr);
+               return ret;
+       }
+
+       if (rev_id != 0xab) {
+               printf("VSC: device at address 0x%x is not VSC3316/3308.\n",
+                      vsc_addr);
+               return -ENODEV;
+       }
+
+       ret = vsc_if_enable(vsc_addr);
+       if (ret) {
+               printf("VSC:0x%x could not configured for 2-wire I/F.\n",
+                      vsc_addr);
+               return ret;
+       }
+
+       /* config connections - page 0x00 */
+       dm_i2c_reg_write(dev, CURRENT_PAGE_REGISTER, CONNECTION_CONFIG_PAGE);
+
+       /* Configure Global Input ISE */
+       dm_i2c_reg_write(dev, GLOBAL_INPUT_ISE1, 0);
+       dm_i2c_reg_write(dev, GLOBAL_INPUT_ISE2, 0);
+
+       /* Configure Tx/Rx Global Output PE1 */
+       dm_i2c_reg_write(dev, GLOBAL_OUTPUT_PE1, 0);
+
+       /* Configure Tx/Rx Global Output PE2 */
+       dm_i2c_reg_write(dev, GLOBAL_OUTPUT_PE2, 0);
+
+       /* Configure Tx/Rx Global Input GAIN */
+       dm_i2c_reg_write(dev, GLOBAL_INPUT_GAIN, 0x3F);
+
+       /* Setting Global Input LOS threshold value */
+       dm_i2c_reg_write(dev, GLOBAL_INPUT_LOS, 0xE0);
+
+       /* Setting Global output termination */
+       dm_i2c_reg_write(dev, GLOBAL_OUTPUT_TERMINATION, 0);
+
+       /* Configure Tx/Rx Global Output level */
+       if (vsc_addr == VSC3308_TX_ADDRESS)
+               dm_i2c_reg_write(dev, GLOBAL_OUTPUT_LEVEL, 4);
+       else
+               dm_i2c_reg_write(dev, GLOBAL_OUTPUT_LEVEL, 2);
+
+       /* Making crosspoint connections, by connecting required
+        * input to output
+        */
+       for (i = 0; i < num_con ; i++)
+               dm_i2c_reg_write(dev, con_arr[i][1], con_arr[i][0]);
+
+       /* input state - page 0x13 */
+       dm_i2c_reg_write(dev, CURRENT_PAGE_REGISTER, INPUT_STATE_REG);
+       /* Turning off all the required input of the switch */
+       for (i = 0; i < num_con; i++)
+               dm_i2c_reg_write(dev, con_arr[i][0], 1);
+
+       /* only turn on specific Tx/Rx requested by the XFI erratum */
+       if (vsc_addr == VSC3308_TX_ADDRESS) {
+               dm_i2c_reg_write(dev, 2, 0);
+               dm_i2c_reg_write(dev, 3, 0);
+       } else {
+               dm_i2c_reg_write(dev, 0, 0);
+               dm_i2c_reg_write(dev, 1, 0);
+       }
+
+       /* config output mode - page 0x23 */
+       dm_i2c_reg_write(dev, CURRENT_PAGE_REGISTER, OUTPUT_MODE_PAGE);
+       /* Turn off the Output driver correspond to required output*/
+       for (i = 0; i < num_con ; i++)
+               dm_i2c_reg_write(dev,  con_arr[i][1], 1);
+
+       /* only turn on specific Tx/Rx requested by the XFI erratum */
+       if (vsc_addr == VSC3308_TX_ADDRESS) {
+               dm_i2c_reg_write(dev, 0, 0);
+               dm_i2c_reg_write(dev, 1, 0);
+       } else {
+               dm_i2c_reg_write(dev, 3, 0);
+               dm_i2c_reg_write(dev, 4, 0);
+       }
+
+       /* configure global core control register, Turn on Global core power */
+       dm_i2c_reg_write(dev, GLOBAL_CORE_CNTRL, 0);
+#else
        ret = i2c_read(vsc_addr, REVISION_ID_REG, 1, &rev_id, 1);
        if (ret < 0) {
                printf("VSC:0x%x could not read REV_ID from device.\n",
@@ -192,7 +368,7 @@ int vsc3308_config_adjust(unsigned int vsc_addr, const int8_t con_arr[][2],
 
        /* configure global core control register, Turn on Global core power */
        i2c_reg_write(vsc_addr, GLOBAL_CORE_CNTRL, 0);
-
+#endif
        vsc_wp_config(vsc_addr);
 
        return 0;
@@ -208,7 +384,69 @@ int vsc3308_config(unsigned int vsc_addr, const int8_t con_arr[][2],
 
        debug("VSC:Initializing VSC3308 at I2C address 0x%x"
                " for Tx\n", vsc_addr);
+#ifdef CONFIG_DM_I2C
+       int bus_num = 0;
+       struct udevice *dev;
+
+       ret = i2c_get_chip_for_busnum(bus_num, vsc_addr,
+                                     1, &dev);
+       if (ret) {
+               printf("%s: Cannot find udev for a bus %d\n", __func__,
+                      bus_num);
+               return ret;
+       }
 
+       ret = dm_i2c_read(dev, REVISION_ID_REG, &rev_id, 1);
+       if (ret < 0) {
+               printf("VSC:0x%x could not read REV_ID from device.\n",
+                      vsc_addr);
+               return ret;
+       }
+
+       if (rev_id != 0xab) {
+               printf("VSC: device at address 0x%x is not VSC3316/3308.\n",
+                      vsc_addr);
+               return -ENODEV;
+       }
+
+       ret = vsc_if_enable(vsc_addr);
+       if (ret) {
+               printf("VSC:0x%x could not configured for 2-wire I/F.\n",
+                      vsc_addr);
+               return ret;
+       }
+
+       /* config connections - page 0x00 */
+       dm_i2c_reg_write(dev, CURRENT_PAGE_REGISTER, CONNECTION_CONFIG_PAGE);
+
+       /* Making crosspoint connections, by connecting required
+        * input to output
+        */
+       for (i = 0; i < num_con ; i++)
+               dm_i2c_reg_write(dev, con_arr[i][1], con_arr[i][0]);
+
+       /*Configure Global Input ISE and gain */
+       dm_i2c_reg_write(dev, GLOBAL_INPUT_ISE1, 0x12);
+       dm_i2c_reg_write(dev, GLOBAL_INPUT_ISE2, 0x12);
+
+       /* input state - page 0x13 */
+       dm_i2c_reg_write(dev, CURRENT_PAGE_REGISTER, INPUT_STATE_REG);
+       /* Turning ON the required input of the switch */
+       for (i = 0; i < num_con ; i++)
+               dm_i2c_reg_write(dev, con_arr[i][0], 0);
+
+       /* Setting Global Input LOS threshold value */
+       dm_i2c_reg_write(dev, GLOBAL_INPUT_LOS, 0x60);
+
+       /* config output mode - page 0x23 */
+       dm_i2c_reg_write(dev, CURRENT_PAGE_REGISTER, OUTPUT_MODE_PAGE);
+       /* Turn ON the Output driver correspond to required output*/
+       for (i = 0; i < num_con ; i++)
+               dm_i2c_reg_write(dev,  con_arr[i][1], 0);
+
+       /* configure global core control register, Turn on Global core power */
+       dm_i2c_reg_write(dev, GLOBAL_CORE_CNTRL, 0);
+#else
        ret = i2c_read(vsc_addr, REVISION_ID_REG, 1, &rev_id, 1);
        if (ret < 0) {
                printf("VSC:0x%x could not read REV_ID from device.\n",
@@ -258,7 +496,7 @@ int vsc3308_config(unsigned int vsc_addr, const int8_t con_arr[][2],
 
        /* configure global core control register, Turn on Global core power */
        i2c_reg_write(vsc_addr, GLOBAL_CORE_CNTRL, 0);
-
+#endif
        vsc_wp_config(vsc_addr);
 
        return 0;
@@ -270,6 +508,22 @@ void vsc_wp_config(unsigned int vsc_addr)
 
        /* For new crosspoint configuration to occur, WP bit of
         * CORE_CONFIG_REG should be set 1 and then reset to 0 */
+#ifdef CONFIG_DM_I2C
+       int ret, bus_num = 0;
+       struct udevice *dev;
+
+       ret = i2c_get_chip_for_busnum(bus_num, vsc_addr,
+                                     1, &dev);
+       if (ret) {
+               printf("%s: Cannot find udev for a bus %d\n", __func__,
+                      bus_num);
+               return;
+       }
+
+       dm_i2c_reg_write(dev, CORE_CONFIG_REG, 0x01);
+       dm_i2c_reg_write(dev, CORE_CONFIG_REG, 0x0);
+#else
        i2c_reg_write(vsc_addr, CORE_CONFIG_REG, 0x01);
        i2c_reg_write(vsc_addr, CORE_CONFIG_REG, 0x0);
+#endif
 }
index 5608774afd19e3194808179d0c8494da5af235be..869c01de92b91fd2658058f119849d8844e63c10 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2009-2012 Freescale Semiconductor, Inc.
+ * Copyright 2020 NXP
  */
 
 #include <common.h>
@@ -91,11 +92,25 @@ int checkboard(void)
        return 0;
 }
 
-int select_i2c_ch_pca9547(u8 ch)
+int select_i2c_ch_pca9547(u8 ch, int bus_num)
 {
        int ret;
 
+#ifdef CONFIG_DM_I2C
+       struct udevice *dev;
+
+       ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_PCA_ADDR_PRI,
+                                     1, &dev);
+       if (ret) {
+               printf("%s: Cannot find udev for a bus %d\n", __func__,
+                      bus_num);
+               return ret;
+       }
+
+       ret = dm_i2c_write(dev, 0, &ch, 1);
+#else
        ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1);
+#endif
        if (ret) {
                puts("PCA: failed to select proper channel\n");
                return ret;
@@ -115,10 +130,28 @@ static inline int read_voltage(void)
 {
        int i, ret, voltage_read = 0;
        u16 vol_mon;
+#ifdef CONFIG_DM_I2C
+       struct udevice *dev;
+       int bus_num = 0;
+#endif
 
        for (i = 0; i < NUM_READINGS; i++) {
+#ifdef CONFIG_DM_I2C
+               ret = i2c_get_chip_for_busnum(bus_num, I2C_VOL_MONITOR_ADDR,
+                                             1, &dev);
+               if (ret) {
+                       printf("%s: Cannot find udev for a bus %d\n", __func__,
+                              bus_num);
+                       return ret;
+               }
+
+               ret = dm_i2c_read(dev,
+                                 I2C_VOL_MONITOR_BUS_V_OFFSET,
+                                 (void *)&vol_mon, 2);
+#else
                ret = i2c_read(I2C_VOL_MONITOR_ADDR,
                        I2C_VOL_MONITOR_BUS_V_OFFSET, 1, (void *)&vol_mon, 2);
+#endif
                if (ret) {
                        printf("VID: failed to read core voltage\n");
                        return ret;
@@ -250,7 +283,7 @@ static int adjust_vdd(ulong vdd_override)
                unsigned voltage;
        };
 
-       ret = select_i2c_ch_pca9547(I2C_MUX_CH_VOL_MONITOR);
+       ret = select_i2c_ch_pca9547(I2C_MUX_CH_VOL_MONITOR, 0);
        if (ret) {
                debug("VID: I2c failed to switch channel\n");
                ret = -1;
@@ -348,7 +381,7 @@ int config_frontside_crossbar_vsc3316(void)
        u32 srds_prtcl_s1, srds_prtcl_s2;
        int ret;
 
-       ret = select_i2c_ch_pca9547(I2C_MUX_CH_VSC3316_FS);
+       ret = select_i2c_ch_pca9547(I2C_MUX_CH_VSC3316_FS, 0);
        if (ret)
                return ret;
 
@@ -567,7 +600,7 @@ int board_early_init_r(void)
        /* Configure board SERDES ports crossbar */
        config_frontside_crossbar_vsc3316();
        config_backside_crossbar_mux();
-       select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
+       select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT, 0);
 
        return 0;
 }
@@ -732,11 +765,11 @@ void board_detail(void)
        }
 
        /* Voltage secion */
-       if (!select_i2c_ch_pca9547(I2C_MUX_CH_VOL_MONITOR)) {
+       if (!select_i2c_ch_pca9547(I2C_MUX_CH_VOL_MONITOR, 0)) {
                vdd = read_voltage();
                if (vdd > 0)
                        printf("Core voltage= %d mV\n", vdd);
-               select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
+               select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT, 0);
        }
 
        printf("XVDD        = 1.%d V\n", ((brdcfg[8] & 0xf) - 4) * 5 + 25);
index 91a7c70356edef88e1f23ee44ebaa14c9f8ee00d..5f91a52bbe9bf5021d30e210e8be4d2064665815 100644 (file)
@@ -280,6 +280,19 @@ unsigned long get_board_ddr_clk(void);
 #endif
 
 /* I2C */
+#ifndef CONFIG_DM_I2C
+#define CONFIG_SYS_I2C
+#else
+#undef CONFIG_SYS_I2C
+#undef CONFIG_SYS_FSL_I2C2_OFFSET
+#undef CONFIG_SYS_FSL_I2C2_SLAVE
+#undef CONFIG_SYS_FSL_I2C2_SPEED
+#undef CONFIG_SYS_FSL_I2C_SLAVE
+#undef CONFIG_SYS_FSL_I2C_SPEED
+#undef CONFIG_SYS_FSL_I2C_OFFSET
+#endif
+
+#define CONFIG_SYS_I2C_FSL
 #define CONFIG_SYS_FSL_I2C_SPEED       100000  /* I2C speed */
 #define CONFIG_SYS_FSL_I2C2_SPEED      100000  /* I2C2 speed */
 #define I2C_MUX_PCA_ADDR_PRI           0x77 /* I2C bus multiplexer,primary */
index 31cb1cf34a84922a24bdca482dd3923e6b20783a..ce7634f4ea97863640eabd79d827ab1ccaf2edd5 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2020 NXP
  */
 
 /*
 #define CONFIG_SYS_NS16550_COM4        (CONFIG_SYS_CCSRBAR+0x11D600)
 
 /* I2C */
+#ifndef CONFIG_DM_I2C
 #define CONFIG_SYS_I2C
-#define CONFIG_SYS_I2C_FSL
 #define CONFIG_SYS_FSL_I2C_SLAVE       0x7F
 #define CONFIG_SYS_FSL_I2C_OFFSET      0x118000
 #define CONFIG_SYS_FSL_I2C2_SLAVE      0x7F
 #define CONFIG_SYS_FSL_I2C2_OFFSET     0x118100
+#else
+#define CONFIG_I2C_SET_DEFAULT_BUS_NUM
+#define CONFIG_I2C_DEFAULT_BUS_NUMBER  0
+#endif
+
+#define CONFIG_SYS_I2C_FSL
 
 /*
  * General PCI