summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorBiwen Li <biwen.li@nxp.com>2020-05-01 20:04:17 +0800
committerPriyanka Jain <priyanka.jain@nxp.com>2020-05-04 09:12:36 +0530
commite6bd72f880a76652ce1d6742880e7efcd85b8fb1 (patch)
tree3d3b33bb623023c5b955ec806a9d97a324659523 /board
parent1321aef8cd13d89d36e8cda8482b87fcea93994a (diff)
dm: ppc: T4240: add i2c DM support
This supports i2c DM for SoC T4240 Signed-off-by: Biwen Li <biwen.li@nxp.com> Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
Diffstat (limited to 'board')
-rw-r--r--board/freescale/common/vsc3316_3308.c258
-rw-r--r--board/freescale/t4qds/t4240qds.c45
2 files changed, 295 insertions, 8 deletions
diff --git a/board/freescale/common/vsc3316_3308.c b/board/freescale/common/vsc3316_3308.c
index 033fae020f..f0d273ca20 100644
--- a/board/freescale/common/vsc3316_3308.c
+++ b/board/freescale/common/vsc3316_3308.c
@@ -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
}
diff --git a/board/freescale/t4qds/t4240qds.c b/board/freescale/t4qds/t4240qds.c
index 5608774afd..869c01de92 100644
--- a/board/freescale/t4qds/t4240qds.c
+++ b/board/freescale/t4qds/t4240qds.c
@@ -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);