static void keep_power_up_count( struct engine *engine, bool keep_power_up) { struct i2c_hw_engine_dce110 *hw_engine = FROM_ENGINE(engine); if (keep_power_up) ++hw_engine->engine_keep_power_up_count; else { --hw_engine->engine_keep_power_up_count; if (!hw_engine->engine_keep_power_up_count) disable_i2c_hw_engine(hw_engine); } }
static void release_engine( struct engine *engine) { struct i2c_hw_engine_dce110 *hw_engine = FROM_ENGINE(engine); struct i2c_engine *base = NULL; bool safe_to_reset; base = &hw_engine->base.base; /* Restore original HW engine speed */ base->funcs->set_speed(base, hw_engine->base.original_speed); /* Release I2C */ REG_UPDATE(DC_I2C_ARBITRATION, DC_I2C_SW_DONE_USING_I2C_REG, 1); /* Reset HW engine */ { uint32_t i2c_sw_status = 0; REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status); /* if used by SW, safe to reset */ safe_to_reset = (i2c_sw_status == 1); } if (safe_to_reset) REG_UPDATE_2( DC_I2C_CONTROL, DC_I2C_SOFT_RESET, 1, DC_I2C_SW_STATUS_RESET, 1); else REG_UPDATE(DC_I2C_CONTROL, DC_I2C_SW_STATUS_RESET, 1); /* HW I2c engine - clock gating feature */ if (!hw_engine->engine_keep_power_up_count) disable_i2c_hw_engine(hw_engine); }
static void release_engine( struct engine *engine) { struct i2c_hw_engine_dce110 *hw_engine = FROM_ENGINE(engine); struct i2c_engine *base = NULL; bool safe_to_reset; uint32_t value = 0; base = &hw_engine->base.base; /* Restore original HW engine speed */ base->funcs->set_speed(base, hw_engine->base.original_speed); /* Release I2C */ { value = dal_read_reg(engine->ctx, mmDC_I2C_ARBITRATION); set_reg_field_value( value, 1, DC_I2C_ARBITRATION, DC_I2C_SW_DONE_USING_I2C_REG); dal_write_reg(engine->ctx, mmDC_I2C_ARBITRATION, value); } /* Reset HW engine */ { uint32_t i2c_sw_status = 0; value = dal_read_reg(engine->ctx, mmDC_I2C_SW_STATUS); i2c_sw_status = get_reg_field_value( value, DC_I2C_SW_STATUS, DC_I2C_SW_STATUS); /* if used by SW, safe to reset */ safe_to_reset = (i2c_sw_status == 1); } { value = dal_read_reg(engine->ctx, mmDC_I2C_CONTROL); if (safe_to_reset) set_reg_field_value( value, 1, DC_I2C_CONTROL, DC_I2C_SOFT_RESET); set_reg_field_value( value, 1, DC_I2C_CONTROL, DC_I2C_SW_STATUS_RESET); dal_write_reg(engine->ctx, mmDC_I2C_CONTROL, value); } /* HW I2c engine - clock gating feature */ if (!hw_engine->engine_keep_power_up_count) disable_i2c_hw_engine(hw_engine); }