board: freescale: Refactor NXP common mux code

Refactors similar mux code from multiple NXP boards into a common location,
and allows it to be disabled in config.

New config: CONFIG_FSL_USE_PCA9547_MUX to enable PCA9547 mux functionality.

Signed-off-by: Stephen Carlson <stcarlso@linux.microsoft.com>
Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
This commit is contained in:
Stephen Carlson 2021-06-22 16:35:20 -07:00 committed by Priyanka Jain
parent dd3dfa50d8
commit 15347d2dea
7 changed files with 148 additions and 46 deletions

View file

@ -21,6 +21,12 @@ config CMD_ESBC_VALIDATE
esbc_validate - validate signature using RSA verification
esbc_halt - put the core in spin loop (Secure Boot Only)
config FSL_USE_PCA9547_MUX
bool "Enable PCA9547 I2C Mux on Freescale boards"
default n
help
This option enables the PCA9547 I2C mux on Freescale boards.
config VID
depends on DM_I2C
bool "Enable Freescale VID"

View file

@ -15,6 +15,15 @@ ifdef MINIMAL
# necessary to create built-in.o
obj- := __dummy__.o
else
# include i2c_common.o once if either VID or FSL_USE_PCA9547_MUX
I2C_COMMON=
ifdef CONFIG_VID
I2C_COMMON=y
endif
ifdef CONFIG_FSL_USE_PCA9547_MUX
I2C_COMMON=y
endif
obj-$(CONFIG_FSL_CADMUS) += cadmus.o
obj-$(CONFIG_FSL_VIA) += cds_via.o
obj-$(CONFIG_FMAN_ENET) += fman.o
@ -22,6 +31,8 @@ obj-$(CONFIG_FSL_PIXIS) += pixis.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_FSL_NGPIXIS) += ngpixis.o
endif
obj-$(I2C_COMMON) += i2c_common.o
obj-$(CONFIG_FSL_USE_PCA9547_MUX) += i2c_mux.o
obj-$(CONFIG_VID) += vid.o
obj-$(CONFIG_FSL_QIXIS) += qixis.o
obj-$(CONFIG_PQ_MDS_PIB) += pq-mds-pib.o

View file

@ -0,0 +1,34 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2014 Freescale Semiconductor, Inc.
* Copyright 2020-21 NXP
* Copyright 2021 Microsoft Corporation
*/
#include <common.h>
#include <i2c.h>
#include "i2c_common.h"
#ifdef CONFIG_DM_I2C
/* If DM is in use, retrieve the chip for the specified bus number */
int fsl_i2c_get_device(int address, int bus, DEVICE_HANDLE_T *dev)
{
int ret = i2c_get_chip_for_busnum(bus, address, 1, dev);
if (ret)
printf("I2C: Bus %d has no device with address 0x%02X\n",
bus, address);
return ret;
}
#else
/* Handle is passed directly */
int fsl_i2c_get_device(int address, int bus, DEVICE_HANDLE_T *dev)
{
*dev = address;
return 0;
}
#endif

View file

@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2014 Freescale Semiconductor, Inc.
* Copyright 2020-21 NXP
* Copyright 2021 Microsoft Corporation
*/
#ifndef __NXP_I2C_COMMON_H__
#define __NXP_I2C_COMMON_H__
/* Common functionality shared by the I2C drivers for VID and the mux. */
#ifdef CONFIG_DM_I2C
#define DEVICE_HANDLE_T struct udevice *
#define I2C_READ(dev, register, data, length) \
dm_i2c_read(dev, register, data, length)
#define I2C_WRITE(dev, register, data, length) \
dm_i2c_write(dev, register, data, length)
#else
#define DEVICE_HANDLE_T int
#define I2C_READ(dev, register, data, length) \
i2c_read(dev, register, 1, data, length)
#define I2C_WRITE(dev, register, data, length) \
i2c_write(dev, register, 1, data, length)
#endif
int fsl_i2c_get_device(int address, int bus, DEVICE_HANDLE_T *dev);
#endif

View file

@ -0,0 +1,40 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2014 Freescale Semiconductor, Inc.
* Copyright 2020-21 NXP
* Copyright 2021 Microsoft Corporation
*/
#include <common.h>
#include <i2c.h>
#include "i2c_common.h"
#include "i2c_mux.h"
/*
* A new Kconfig option for something that used to always be built should be
* default y.
*/
#ifdef CONFIG_FSL_USE_PCA9547_MUX
int select_i2c_ch_pca9547(u8 ch, int bus)
{
int ret;
DEVICE_HANDLE_T dev;
/* Open device handle */
ret = fsl_i2c_get_device(I2C_MUX_PCA_ADDR_PRI, bus, &dev);
if (ret) {
printf("PCA: No PCA9547 device found\n");
return ret;
}
ret = I2C_WRITE(dev, 0, &ch, sizeof(ch));
if (ret) {
printf("PCA: Unable to select channel %d (%d)\n", (int)ch, ret);
return ret;
}
return 0;
}
#endif

View file

@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2014 Freescale Semiconductor, Inc.
* Copyright 2020-21 NXP
* Copyright 2021 Microsoft Corporation
*/
#ifndef __NXP_I2C_MUX_H__
#define __NXP_I2C_MUX_H__
#ifdef CONFIG_FSL_USE_PCA9547_MUX
int select_i2c_ch_pca9547(u8 ch, int bus);
#endif
#endif

View file

@ -20,8 +20,13 @@
#include <asm/immap_85xx.h>
#endif
#include <linux/delay.h>
#include "i2c_common.h"
#include "vid.h"
#ifndef I2C_VOL_MONITOR_BUS
#define I2C_VOL_MONITOR_BUS 0
#endif
/* Voltages are generally handled in mV to keep them as integers */
#define MV_PER_V 1000
@ -95,44 +100,6 @@ u16 __weak soc_get_fuse_vid(int vid_index)
#define I2C_VOL_MONITOR_ADDR 0
#endif
#if CONFIG_IS_ENABLED(DM_I2C)
#define DEVICE_HANDLE_T struct udevice *
#ifndef I2C_VOL_MONITOR_BUS
#define I2C_VOL_MONITOR_BUS 0
#endif
/* If DM is in use, retrieve the udevice chip for the specified bus number */
static int vid_get_device(int address, DEVICE_HANDLE_T *dev)
{
int ret = i2c_get_chip_for_busnum(I2C_VOL_MONITOR_BUS, address, 1, dev);
if (ret)
printf("VID: Bus %d has no device with address 0x%02X\n",
I2C_VOL_MONITOR_BUS, address);
return ret;
}
#define I2C_READ(dev, register, data, length) \
dm_i2c_read(dev, register, data, length)
#define I2C_WRITE(dev, register, data, length) \
dm_i2c_write(dev, register, data, length)
#else
#define DEVICE_HANDLE_T int
/* If DM is not in use, I2C addresses are passed directly */
static int vid_get_device(int address, DEVICE_HANDLE_T *dev)
{
*dev = address;
return 0;
}
#define I2C_READ(dev, register, data, length) \
i2c_read(dev, register, 1, data, length)
#define I2C_WRITE(dev, register, data, length) \
i2c_write(dev, register, 1, data, length)
#endif
#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
defined(CONFIG_VOL_MONITOR_IR36021_READ)
/*
@ -158,7 +125,7 @@ static int find_ir_chip_on_i2c(void)
/* Check all the address */
for (i = 0; i < (sizeof(ir_i2c_addr)/sizeof(ir_i2c_addr[0])); i++) {
i2caddress = ir_i2c_addr[i];
ret = vid_get_device(i2caddress, &dev);
ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev);
if (!ret) {
ret = I2C_READ(dev, IR36021_MFR_ID_OFFSET,
(void *)&mfrID, sizeof(mfrID));
@ -202,7 +169,7 @@ static int read_voltage_from_INA220(int i2caddress)
DEVICE_HANDLE_T dev;
/* Open device handle */
ret = vid_get_device(i2caddress, &dev);
ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev);
if (ret)
return ret;
@ -243,7 +210,7 @@ static int read_voltage_from_IR(int i2caddress)
DEVICE_HANDLE_T dev;
/* Open device handle */
ret = vid_get_device(i2caddress, &dev);
ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev);
if (ret)
return ret;
@ -344,7 +311,7 @@ static int read_voltage_from_pmbus(int i2caddress)
DEVICE_HANDLE_T dev;
/* Open device handle */
ret = vid_get_device(i2caddress, &dev);
ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev);
if (ret)
return ret;
@ -457,7 +424,7 @@ static int set_voltage_to_IR(int i2caddress, int vdd)
DEVICE_HANDLE_T dev;
/* Open device handle */
ret = vid_get_device(i2caddress, &dev);
ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev);
if (ret)
return ret;
@ -503,7 +470,7 @@ static int set_voltage_to_pmbus(int i2caddress, int vdd)
DEVICE_HANDLE_T dev;
/* Open device handle */
ret = vid_get_device(i2caddress, &dev);
ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev);
if (ret)
return ret;
@ -653,7 +620,7 @@ int adjust_vdd(ulong vdd_override)
debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
}
ret = vid_get_device(i2caddress, &dev);
ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev);
if (ret)
return ret;
@ -785,7 +752,6 @@ exit:
i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT);
return ret < 0 ? -1 : 0;
}
static int do_vdd_override(struct cmd_tbl *cmdtp,