From fefac937fbd87f380042501c63b874994b3dccee Mon Sep 17 00:00:00 2001 From: Biwen Li Date: Wed, 5 Feb 2020 22:02:16 +0800 Subject: dm: arm64: ls1043a: add i2c DM support This supports i2c DM and enables CONFIG_DM_I2C for SoC LS1043A Signed-off-by: Biwen Li Signed-off-by: Priyanka Jain --- board/freescale/ls1043aqds/ls1043aqds.c | 98 +++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 6 deletions(-) (limited to 'board/freescale/ls1043aqds') diff --git a/board/freescale/ls1043aqds/ls1043aqds.c b/board/freescale/ls1043aqds/ls1043aqds.c index 8c96b962b7..2d4b18cdbc 100644 --- a/board/freescale/ls1043aqds/ls1043aqds.c +++ b/board/freescale/ls1043aqds/ls1043aqds.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2015 Freescale Semiconductor, Inc. + * Copyright 2019 NXP */ #include @@ -271,11 +272,24 @@ unsigned long get_board_ddr_clk(void) return 66666666; } -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; @@ -290,8 +304,10 @@ int dram_init(void) * When resuming from deep sleep, the I2C channel may not be * in the default channel. So, switch to the default channel * before accessing DDR SPD. + * + * PCA9547 mount on I2C1 bus */ - select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); + select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT, 0); fsl_initdram(); #if (!defined(CONFIG_SPL) && !defined(CONFIG_TFABOOT)) || \ defined(CONFIG_SPL_BUILD) @@ -304,16 +320,83 @@ int dram_init(void) int i2c_multiplexer_select_vid_channel(u8 channel) { - return select_i2c_ch_pca9547(channel); + return select_i2c_ch_pca9547(channel, 0); } void board_retimer_init(void) { u8 reg; + int bus_num = 0; /* Retimer is connected to I2C1_CH7_CH5 */ - select_i2c_ch_pca9547(I2C_MUX_CH7); + select_i2c_ch_pca9547(I2C_MUX_CH7, bus_num); reg = I2C_MUX_CH5; +#ifdef CONFIG_DM_I2C + struct udevice *dev; + int ret; + + ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_PCA_ADDR_SEC, + 1, &dev); + if (ret) { + printf("%s: Cannot find udev for a bus %d\n", __func__, + bus_num); + return; + } + dm_i2c_write(dev, 0, ®, 1); + + /* Access to Control/Shared register */ + ret = i2c_get_chip_for_busnum(bus_num, I2C_RETIMER_ADDR, + 1, &dev); + if (ret) { + printf("%s: Cannot find udev for a bus %d\n", __func__, + bus_num); + return; + } + + reg = 0x0; + dm_i2c_write(dev, 0xff, ®, 1); + + /* Read device revision and ID */ + dm_i2c_read(dev, 1, ®, 1); + debug("Retimer version id = 0x%x\n", reg); + + /* Enable Broadcast. All writes target all channel register sets */ + reg = 0x0c; + dm_i2c_write(dev, 0xff, ®, 1); + + /* Reset Channel Registers */ + dm_i2c_read(dev, 0, ®, 1); + reg |= 0x4; + dm_i2c_write(dev, 0, ®, 1); + + /* Enable override divider select and Enable Override Output Mux */ + dm_i2c_read(dev, 9, ®, 1); + reg |= 0x24; + dm_i2c_write(dev, 9, ®, 1); + + /* Select VCO Divider to full rate (000) */ + dm_i2c_read(dev, 0x18, ®, 1); + reg &= 0x8f; + dm_i2c_write(dev, 0x18, ®, 1); + + /* Selects active PFD MUX Input as Re-timed Data (001) */ + dm_i2c_read(dev, 0x1e, ®, 1); + reg &= 0x3f; + reg |= 0x20; + dm_i2c_write(dev, 0x1e, ®, 1); + + /* Set data rate as 10.3125 Gbps */ + reg = 0x0; + dm_i2c_write(dev, 0x60, ®, 1); + reg = 0xb2; + dm_i2c_write(dev, 0x61, ®, 1); + reg = 0x90; + dm_i2c_write(dev, 0x62, ®, 1); + reg = 0xb3; + dm_i2c_write(dev, 0x63, ®, 1); + reg = 0xcd; + dm_i2c_write(dev, 0x64, ®, 1); +#else i2c_write(I2C_MUX_PCA_ADDR_SEC, 0, 1, ®, 1); /* Access to Control/Shared register */ @@ -360,9 +443,10 @@ void board_retimer_init(void) i2c_write(I2C_RETIMER_ADDR, 0x63, 1, ®, 1); reg = 0xcd; i2c_write(I2C_RETIMER_ADDR, 0x64, 1, ®, 1); +#endif /* Return the default channel */ - select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); + select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT, bus_num); } int board_early_init_f(void) @@ -375,8 +459,10 @@ int board_early_init_f(void) u8 uart; #endif +#ifdef CONFIG_SYS_I2C #ifdef CONFIG_SYS_I2C_EARLY_INIT i2c_early_init_f(); +#endif #endif fsl_lsch2_early_init_f(); @@ -457,7 +543,7 @@ int board_init(void) erratum_a010315(); #endif - select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); + select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT, 0); board_retimer_init(); #ifdef CONFIG_SYS_FSL_SERDES -- cgit v1.2.3