drivers: i2c: microchip: I2C reset fix
Updated the code to to invoke reset using PCR block z_mchp_xec_pcr_periph_reset() instead of resetting using I2C Configuration register Signed-off-by: Manimaran A <manimaran.a@microchip.com>
This commit is contained in:
parent
e28f90f7d2
commit
519477fbf1
|
@ -109,6 +109,9 @@ struct pcr_hw_regs {
|
|||
volatile uint32_t CLK32K_MON_IEN;
|
||||
};
|
||||
|
||||
#define XEC_CC_PCR_RST_EN_UNLOCK 0xa6382d4cu
|
||||
#define XEC_CC_PCR_RST_EN_LOCK 0xa6382d4du
|
||||
|
||||
#define XEC_CC_PCR_OSC_ID_PLL_LOCK BIT(8)
|
||||
#define XEC_CC_PCR_TURBO_CLK_96M BIT(2)
|
||||
|
||||
|
@ -791,6 +794,29 @@ int z_mchp_xec_pcr_periph_sleep(uint8_t slp_idx, uint8_t slp_pos,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Most peripherals have a write only reset bit in the PCR reset enable registers.
|
||||
* The layout of these registers is identical to the PCR sleep enable registers.
|
||||
* Reset enables are protected by a lock register.
|
||||
*/
|
||||
int z_mchp_xec_pcr_periph_reset(uint8_t slp_idx, uint8_t slp_pos)
|
||||
{
|
||||
struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)DT_INST_REG_ADDR_BY_IDX(0, 0);
|
||||
|
||||
if ((slp_idx >= MCHP_MAX_PCR_SCR_REGS) || (slp_pos >= 32)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
uint32_t lock = irq_lock();
|
||||
|
||||
pcr->RST_EN_LOCK = XEC_CC_PCR_RST_EN_UNLOCK;
|
||||
pcr->RST_EN[slp_idx] = BIT(slp_pos);
|
||||
pcr->RST_EN_LOCK = XEC_CC_PCR_RST_EN_LOCK;
|
||||
|
||||
irq_unlock(lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* clock control driver API implementation */
|
||||
|
||||
static int xec_cc_on(const struct device *dev,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#define DT_DRV_COMPAT microchip_xec_i2c
|
||||
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/drivers/clock_control/mchp_xec_clock_control.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <soc.h>
|
||||
#include <errno.h>
|
||||
|
@ -49,6 +50,8 @@ struct i2c_xec_config {
|
|||
uint32_t base_addr;
|
||||
uint8_t girq_id;
|
||||
uint8_t girq_bit;
|
||||
uint8_t pcr_idx;
|
||||
uint8_t pcr_bitpos;
|
||||
struct gpio_dt_spec sda_gpio;
|
||||
struct gpio_dt_spec scl_gpio;
|
||||
const struct pinctrl_dev_config *pcfg;
|
||||
|
@ -102,17 +105,10 @@ static void i2c_xec_reset_config(const struct device *dev)
|
|||
(const struct i2c_xec_config *const) (dev->config);
|
||||
struct i2c_xec_data *data =
|
||||
(struct i2c_xec_data *const) (dev->data);
|
||||
|
||||
uint32_t ba = config->base_addr;
|
||||
|
||||
/* Assert RESET and clr others */
|
||||
MCHP_I2C_SMB_CFG(ba) = MCHP_I2C_SMB_CFG_RESET;
|
||||
|
||||
k_busy_wait(RESET_WAIT_US);
|
||||
|
||||
/* Bus reset */
|
||||
MCHP_I2C_SMB_CFG(ba) = 0;
|
||||
|
||||
/* Assert RESET */
|
||||
z_mchp_xec_pcr_periph_reset(config->pcr_idx, config->pcr_bitpos);
|
||||
/* Write 0x80. i.e Assert PIN bit, ESO = 0 and Interrupts
|
||||
* disabled (ENI)
|
||||
*/
|
||||
|
@ -899,6 +895,8 @@ static int i2c_xec_init(const struct device *dev)
|
|||
.port_sel = DT_INST_PROP(n, port_sel), \
|
||||
.girq_id = DT_INST_PROP(n, girq), \
|
||||
.girq_bit = DT_INST_PROP(n, girq_bit), \
|
||||
.pcr_idx = DT_INST_PROP_BY_IDX(n, pcrs, 0), \
|
||||
.pcr_bitpos = DT_INST_PROP_BY_IDX(n, pcrs, 1), \
|
||||
.sda_gpio = GPIO_DT_SPEC_INST_GET(n, sda_gpios), \
|
||||
.scl_gpio = GPIO_DT_SPEC_INST_GET(n, scl_gpios), \
|
||||
.irq_config_func = i2c_xec_irq_config_func_##n, \
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <soc.h>
|
||||
#include <errno.h>
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/drivers/clock_control/mchp_xec_clock_control.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/drivers/interrupt_controller/intc_mchp_xec_ecia.h>
|
||||
|
@ -223,11 +224,9 @@ static int i2c_xec_reset_config(const struct device *dev)
|
|||
data->state = I2C_XEC_STATE_STOPPED;
|
||||
data->read_discard = 0;
|
||||
|
||||
/* Assert RESET and clr others */
|
||||
regs->CFG = MCHP_I2C_SMB_CFG_RESET;
|
||||
k_busy_wait(RESET_WAIT_US);
|
||||
/* clear reset, set filter enable, select port */
|
||||
regs->CFG = 0;
|
||||
/* Assert RESET */
|
||||
z_mchp_xec_pcr_periph_reset(cfg->pcr_idx, cfg->pcr_bitpos);
|
||||
|
||||
regs->CFG = MCHP_I2C_SMB_CFG_FLUSH_SXBUF_WO |
|
||||
MCHP_I2C_SMB_CFG_FLUSH_SRBUF_WO |
|
||||
MCHP_I2C_SMB_CFG_FLUSH_MXBUF_WO |
|
||||
|
@ -318,8 +317,8 @@ static int i2c_xec_recover_bus(const struct device *dev)
|
|||
LOG_ERR("I2C attempt bus recovery\n");
|
||||
|
||||
/* reset controller to a known state */
|
||||
regs->CFG = MCHP_I2C_SMB_CFG_RESET;
|
||||
k_busy_wait(RESET_WAIT_US);
|
||||
z_mchp_xec_pcr_periph_reset(cfg->pcr_idx, cfg->pcr_bitpos);
|
||||
|
||||
regs->CFG = BIT(14) | MCHP_I2C_SMB_CFG_FEN |
|
||||
(cfg->port_sel & MCHP_I2C_SMB_CFG_PORT_SEL_MASK);
|
||||
regs->CFG |= MCHP_I2C_SMB_CFG_FLUSH_SXBUF_WO |
|
||||
|
|
|
@ -201,6 +201,7 @@
|
|||
reg = <0x40004000 0x80>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <20 1>;
|
||||
pcrs = <1 10>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
@ -213,6 +214,7 @@
|
|||
reg = <0x40004400 0x80>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <21 1>;
|
||||
pcrs = <3 13>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
@ -225,6 +227,7 @@
|
|||
reg = <0x40004800 0x80>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <22 1>;
|
||||
pcrs = <3 14>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
@ -237,6 +240,7 @@
|
|||
reg = <0x40004C00 0x80>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <23 1>;
|
||||
pcrs = <3 15>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
@ -249,6 +253,7 @@
|
|||
reg = <0x40005000 0x80>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <158 1>;
|
||||
pcrs = <3 20>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
|
|
@ -26,6 +26,11 @@ properties:
|
|||
required: true
|
||||
description: Bit position in GIRQ for this device
|
||||
|
||||
pcrs:
|
||||
type: array
|
||||
required: true
|
||||
description: PCR sleep register index and bit position
|
||||
|
||||
pinctrl-0:
|
||||
required: true
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
int z_mchp_xec_pcr_periph_sleep(uint8_t slp_idx, uint8_t slp_pos,
|
||||
uint8_t slp_en);
|
||||
|
||||
int z_mchp_xec_pcr_periph_reset(uint8_t slp_idx, uint8_t slp_pos);
|
||||
|
||||
#if defined(CONFIG_PM)
|
||||
void mchp_xec_clk_ctrl_sys_sleep_enable(bool is_deep);
|
||||
void mchp_xec_clk_ctrl_sys_sleep_disable(void);
|
||||
|
|
Loading…
Reference in a new issue