drivers/i2c/designware: Check if the device is powered
If the device doesn't return a valid component type, that means the device is non-functional. The dw_i2c_regs had invalid offsets for the version field. I got the correct value from the DesignWare DW_apb_i2c Databook v2.02a. It also matches what the Picasso PPR says. I also print out the version field of the controller. BUG=b:153001807 BRANCH=none TEST=Tested on PSP where I2C is non functional. Also tested on trembyle and verified i2c was initialized. Saw the following in the logs I2C bus 2 version 0x3132322a Signed-off-by: Raul E Rangel <rrangel@chromium.org> Change-Id: If5527972508e0f4b35cc9ecdb1491b1ce85ff3af Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/coreboot/+/2144540 Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Furquan Shaikh <furquan@chromium.org> Tested-by: Simon Glass <sjg@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/40870 Reviewed-by: Furquan Shaikh <furquan@google.com> Reviewed-by: Angel Pons <th3fanbus@gmail.com> Reviewed-by: Aaron Durbin <adurbin@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
6ad7010542
commit
6191b85f87
|
@ -91,54 +91,58 @@ enum {
|
||||||
|
|
||||||
/* I2C Controller MMIO register space */
|
/* I2C Controller MMIO register space */
|
||||||
struct dw_i2c_regs {
|
struct dw_i2c_regs {
|
||||||
uint32_t control;
|
uint32_t control; /* 0x0 */
|
||||||
uint32_t target_addr;
|
uint32_t target_addr; /* 0x4 */
|
||||||
uint32_t slave_addr;
|
uint32_t slave_addr; /* 0x8 */
|
||||||
uint32_t master_addr;
|
uint32_t master_addr; /* 0xc */
|
||||||
uint32_t cmd_data;
|
uint32_t cmd_data; /* 0x10 */
|
||||||
uint32_t ss_scl_hcnt;
|
uint32_t ss_scl_hcnt; /* 0x14 */
|
||||||
uint32_t ss_scl_lcnt;
|
uint32_t ss_scl_lcnt; /* 0x18 */
|
||||||
uint32_t fs_scl_hcnt;
|
uint32_t fs_scl_hcnt; /* 0x1c */
|
||||||
uint32_t fs_scl_lcnt;
|
uint32_t fs_scl_lcnt; /* 0x20 */
|
||||||
uint32_t hs_scl_hcnt;
|
uint32_t hs_scl_hcnt; /* 0x24 */
|
||||||
uint32_t hs_scl_lcnt;
|
uint32_t hs_scl_lcnt; /* 0x28 */
|
||||||
uint32_t intr_stat;
|
uint32_t intr_stat; /* 0x2c */
|
||||||
uint32_t intr_mask;
|
uint32_t intr_mask; /* 0x30 */
|
||||||
uint32_t raw_intr_stat;
|
uint32_t raw_intr_stat; /* 0x34 */
|
||||||
uint32_t rx_thresh;
|
uint32_t rx_thresh; /* 0x38 */
|
||||||
uint32_t tx_thresh;
|
uint32_t tx_thresh; /* 0x3c */
|
||||||
uint32_t clear_intr;
|
uint32_t clear_intr; /* 0x40 */
|
||||||
uint32_t clear_rx_under_intr;
|
uint32_t clear_rx_under_intr; /* 0x44 */
|
||||||
uint32_t clear_rx_over_intr;
|
uint32_t clear_rx_over_intr; /* 0x48 */
|
||||||
uint32_t clear_tx_over_intr;
|
uint32_t clear_tx_over_intr; /* 0x4c */
|
||||||
uint32_t clear_rd_req_intr;
|
uint32_t clear_rd_req_intr; /* 0x50 */
|
||||||
uint32_t clear_tx_abrt_intr;
|
uint32_t clear_tx_abrt_intr; /* 0x54 */
|
||||||
uint32_t clear_rx_done_intr;
|
uint32_t clear_rx_done_intr; /* 0x58 */
|
||||||
uint32_t clear_activity_intr;
|
uint32_t clear_activity_intr; /* 0x5c */
|
||||||
uint32_t clear_stop_det_intr;
|
uint32_t clear_stop_det_intr; /* 0x60 */
|
||||||
uint32_t clear_start_det_intr;
|
uint32_t clear_start_det_intr; /* 0x64 */
|
||||||
uint32_t clear_gen_call_intr;
|
uint32_t clear_gen_call_intr; /* 0x68 */
|
||||||
uint32_t enable;
|
uint32_t enable; /* 0x6c */
|
||||||
uint32_t status;
|
uint32_t status; /* 0x70 */
|
||||||
uint32_t tx_level;
|
uint32_t tx_level; /* 0x74 */
|
||||||
uint32_t rx_level;
|
uint32_t rx_level; /* 0x78 */
|
||||||
uint32_t sda_hold;
|
uint32_t sda_hold; /* 0x7c */
|
||||||
uint32_t tx_abort_source;
|
uint32_t tx_abort_source; /* 0x80 */
|
||||||
uint32_t slv_data_nak_only;
|
uint32_t slv_data_nak_only; /* 0x84 */
|
||||||
uint32_t dma_cr;
|
uint32_t dma_cr; /* 0x88 */
|
||||||
uint32_t dma_tdlr;
|
uint32_t dma_tdlr; /* 0x8c */
|
||||||
uint32_t dma_rdlr;
|
uint32_t dma_rdlr; /* 0x90 */
|
||||||
uint32_t sda_setup;
|
uint32_t sda_setup; /* 0x94 */
|
||||||
uint32_t ack_general_call;
|
uint32_t ack_general_call; /* 0x98 */
|
||||||
uint32_t enable_status;
|
uint32_t enable_status; /* 0x9c */
|
||||||
uint32_t fs_spklen;
|
uint32_t fs_spklen; /* 0xa0 */
|
||||||
uint32_t hs_spklen;
|
uint32_t hs_spklen; /* 0xa4 */
|
||||||
uint32_t clr_restart_det;
|
uint32_t clr_restart_det; /* 0xa8 */
|
||||||
uint32_t comp_param1;
|
uint32_t reserved[18]; /* 0xac - 0xf0 */
|
||||||
uint32_t comp_version;
|
uint32_t comp_param1; /* 0xf4 */
|
||||||
uint32_t comp_type;
|
uint32_t comp_version; /* 0xf8 */
|
||||||
|
uint32_t comp_type; /* 0xfc */
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/* Constant value defined in the DesignWare DW_apb_i2c Databook. */
|
||||||
|
#define DW_I2C_COMP_TYPE 0x44570140
|
||||||
|
|
||||||
static const struct i2c_descriptor {
|
static const struct i2c_descriptor {
|
||||||
enum i2c_speed speed;
|
enum i2c_speed speed;
|
||||||
struct freq freq;
|
struct freq freq;
|
||||||
|
@ -717,6 +721,14 @@ int dw_i2c_init(unsigned int bus, const struct dw_i2c_bus_config *bcfg)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (read32(®s->comp_type) != DW_I2C_COMP_TYPE) {
|
||||||
|
printk(BIOS_ERR, "I2C bus %u has unknown type 0x%x.\n", bus,
|
||||||
|
read32(®s->comp_type));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "I2C bus %u version 0x%x\n", bus, read32(®s->comp_version));
|
||||||
|
|
||||||
if (dw_i2c_disable(regs) < 0) {
|
if (dw_i2c_disable(regs) < 0) {
|
||||||
printk(BIOS_ERR, "I2C timeout disabling bus %u\n", bus);
|
printk(BIOS_ERR, "I2C timeout disabling bus %u\n", bus);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in New Issue