diff options
Diffstat (limited to 'zephyr/emul/emul_bb_retimer.c')
-rw-r--r-- | zephyr/emul/emul_bb_retimer.c | 365 |
1 files changed, 0 insertions, 365 deletions
diff --git a/zephyr/emul/emul_bb_retimer.c b/zephyr/emul/emul_bb_retimer.c deleted file mode 100644 index b391070b1f..0000000000 --- a/zephyr/emul/emul_bb_retimer.c +++ /dev/null @@ -1,365 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#define DT_DRV_COMPAT cros_bb_retimer_emul - -#define LOG_LEVEL CONFIG_I2C_LOG_LEVEL -#include <logging/log.h> -LOG_MODULE_REGISTER(emul_bb_retimer); - -#include <device.h> -#include <emul.h> -#include <drivers/i2c.h> -#include <drivers/i2c_emul.h> - -#include "emul/emul_common_i2c.h" -#include "emul/emul_bb_retimer.h" - -#include "driver/retimer/bb_retimer.h" - -#define BB_DATA_FROM_I2C_EMUL(_emul) \ - CONTAINER_OF(CONTAINER_OF(_emul, struct i2c_common_emul_data, emul), \ - struct bb_emul_data, common) - -/** Run-time data used by the emulator */ -struct bb_emul_data { - /** Common I2C data */ - struct i2c_common_emul_data common; - - /** Current state of all emulated BB retimer registers */ - uint32_t reg[BB_RETIMER_REG_COUNT]; - - /** Vendor ID of emulated device */ - uint32_t vendor_id; - - /** Return error when trying to write to RO register */ - bool error_on_ro_write; - /** Return error when trying to write 1 to reserved bit */ - bool error_on_rsvd_write; - - /** Value of data dword in ongoing i2c message */ - uint32_t data_dword; -}; - -/** Check description in emul_bb_retimer.h */ -void bb_emul_set_reg(struct i2c_emul *emul, int reg, uint32_t val) -{ - struct bb_emul_data *data; - - if (reg < 0 || reg > BB_RETIMER_REG_COUNT) { - return; - } - - data = BB_DATA_FROM_I2C_EMUL(emul); - data->reg[reg] = val; -} - -/** Check description in emul_bb_retimer.h */ -uint32_t bb_emul_get_reg(struct i2c_emul *emul, int reg) -{ - struct bb_emul_data *data; - - if (reg < 0 || reg > BB_RETIMER_REG_COUNT) { - return 0; - } - - data = BB_DATA_FROM_I2C_EMUL(emul); - - return data->reg[reg]; -} - -/** Check description in emul_bb_retimer.h */ -void bb_emul_set_err_on_ro_write(struct i2c_emul *emul, bool set) -{ - struct bb_emul_data *data; - - data = BB_DATA_FROM_I2C_EMUL(emul); - data->error_on_ro_write = set; -} - -/** Check description in emul_bb_retimer.h */ -void bb_emul_set_err_on_rsvd_write(struct i2c_emul *emul, bool set) -{ - struct bb_emul_data *data; - - data = BB_DATA_FROM_I2C_EMUL(emul); - data->error_on_rsvd_write = set; -} - -/** Mask reserved bits in each register of BB retimer */ -static const uint32_t bb_emul_rsvd_mask[] = { - [BB_RETIMER_REG_VENDOR_ID] = 0x00000000, - [BB_RETIMER_REG_DEVICE_ID] = 0x00000000, - [0x02] = 0xffffffff, /* Reserved */ - [0x03] = 0xffffffff, /* Reserved */ - [BB_RETIMER_REG_CONNECTION_STATE] = 0xc0201000, - [BB_RETIMER_REG_TBT_CONTROL] = 0xffffdfff, - [0x06] = 0xffffffff, /* Reserved */ - [BB_RETIMER_REG_EXT_CONNECTION_MODE] = 0x08007f00, -}; - -/** - * @brief Reset registers to default values - * - * @param emul Pointer to BB retimer emulator - */ -static void bb_emul_reset(struct i2c_emul *emul) -{ - struct bb_emul_data *data; - - data = BB_DATA_FROM_I2C_EMUL(emul); - - data->reg[BB_RETIMER_REG_VENDOR_ID] = data->vendor_id; - data->reg[BB_RETIMER_REG_DEVICE_ID] = BB_RETIMER_DEVICE_ID; - data->reg[0x02] = 0x00; /* Reserved */ - data->reg[0x03] = 0x00; /* Reserved */ - data->reg[BB_RETIMER_REG_CONNECTION_STATE] = 0x00; - data->reg[BB_RETIMER_REG_TBT_CONTROL] = 0x00; - data->reg[0x06] = 0x00; /* Reserved */ - data->reg[BB_RETIMER_REG_EXT_CONNECTION_MODE] = 0x00; -} - -/** - * @brief Handle I2C write message. It is checked if accessed register isn't RO - * and reserved bits are set to 0. Write set value of reg field of BB - * retimer emulator data ignoring reserved bits and write only bits. - * - * @param emul Pointer to BB retimer emulator - * @param reg Register which is written - * @param msg_len Length of handled I2C message - * - * @return 0 on success - * @return -EIO on error - */ -static int bb_emul_handle_write(struct i2c_emul *emul, int reg, int msg_len) -{ - struct bb_emul_data *data; - uint32_t val; - - data = BB_DATA_FROM_I2C_EMUL(emul); - - /* This write only selected register for I2C read message */ - if (msg_len < 2) { - return 0; - } - - val = data->data_dword; - - /* - * BB retimer ignores data bytes above 4 and use zeros if there is less - * then 4 data bytes. Emulator prints warning in that case. - */ - if (msg_len != 6) { - LOG_WRN("Got %d bytes of WR data, expected 4", msg_len - 2); - } - - if (reg <= BB_RETIMER_REG_DEVICE_ID || - reg >= BB_RETIMER_REG_COUNT || - reg == BB_RETIMER_REG_TBT_CONTROL) { - if (data->error_on_ro_write) { - LOG_ERR("Writing to reg 0x%x which is RO", reg); - return -EIO; - } - - return 0; - } - - if (data->error_on_rsvd_write && bb_emul_rsvd_mask[reg] & val) { - LOG_ERR("Writing 0x%x to reg 0x%x with rsvd bits mask 0x%x", - val, reg, bb_emul_rsvd_mask[reg]); - return -EIO; - } - - /* Ignore all reserved bits */ - val &= ~bb_emul_rsvd_mask[reg]; - val |= data->reg[reg] & bb_emul_rsvd_mask[reg]; - - data->reg[reg] = val; - - return 0; -} - -/** - * @brief Handle I2C read message. Response is obtained from reg field of bb - * emul data. - * - * @param emul Pointer to BB retimer emulator - * @param reg Register address to read - * - * @return 0 on success - * @return -EIO on error - */ -static int bb_emul_handle_read(struct i2c_emul *emul, int reg) -{ - struct bb_emul_data *data; - - data = BB_DATA_FROM_I2C_EMUL(emul); - - if (reg >= BB_RETIMER_REG_COUNT) { - LOG_ERR("Read unknown register 0x%x", reg); - - return -EIO; - } - - data->data_dword = data->reg[reg]; - - return 0; -} - -/** - * @brief Function called for each byte of write message. Data are stored - * in data_dword field of bb_emul_data - * - * @param emul Pointer to BB retimer emulator - * @param reg First byte of write message - * @param val Received byte of write message - * @param bytes Number of bytes already received - * - * @return 0 on success - */ -static int bb_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val, - int bytes) -{ - struct bb_emul_data *data; - - data = BB_DATA_FROM_I2C_EMUL(emul); - - if (bytes == 1) { - data->data_dword = 0; - if (val != 4) { - LOG_WRN("Invalid write size"); - } - } else if (bytes < 6) { - data->data_dword |= val << (8 * (bytes - 2)); - } - - return 0; -} - -/** - * @brief Function called for each byte of read message. data_dword is converted - * to read message response. - * - * @param emul Pointer to BB retimer emulator - * @param reg First byte of last write message - * @param val Pointer where byte to read should be stored - * @param bytes Number of bytes already readed - * - * @return 0 on success - */ -static int bb_emul_read_byte(struct i2c_emul *emul, int reg, uint8_t *val, - int bytes) -{ - struct bb_emul_data *data; - - data = BB_DATA_FROM_I2C_EMUL(emul); - - /* First byte of read message is read size which is always 4 */ - if (bytes == 0) { - *val = 4; - return 0; - } - - *val = data->data_dword & 0xff; - data->data_dword >>= 8; - - return 0; -} - -/** - * @brief Get currently accessed register, which always equals to selected - * register. - * - * @param emul Pointer to BB retimer emulator - * @param reg First byte of last write message - * @param bytes Number of bytes already handled from current message - * @param read If currently handled is read message - * - * @return Currently accessed register - */ -static int bb_emul_access_reg(struct i2c_emul *emul, int reg, int bytes, - bool read) -{ - return reg; -} - -/* Device instantiation */ - -static struct i2c_emul_api bb_emul_api = { - .transfer = i2c_common_emul_transfer, -}; - -/** - * @brief Set up a new BB retimer emulator - * - * This should be called for each BB retimer device that needs to be - * emulated. It registers it with the I2C emulation controller. - * - * @param emul Emulation information - * @param parent Device to emulate - * - * @return 0 indicating success (always) - */ -static int bb_emul_init(const struct emul *emul, - const struct device *parent) -{ - const struct i2c_common_emul_cfg *cfg = emul->cfg; - struct i2c_common_emul_data *data = cfg->data; - int ret; - - data->emul.api = &bb_emul_api; - data->emul.addr = cfg->addr; - data->i2c = parent; - data->cfg = cfg; - i2c_common_emul_init(data); - - ret = i2c_emul_register(parent, emul->dev_label, &data->emul); - - bb_emul_reset(&data->emul); - - return ret; -} - -#define BB_RETIMER_EMUL(n) \ - static struct bb_emul_data bb_emul_data_##n = { \ - .vendor_id = DT_STRING_TOKEN(DT_DRV_INST(n), vendor), \ - .error_on_ro_write = DT_INST_PROP(n, error_on_ro_write),\ - .error_on_rsvd_write = DT_INST_PROP(n, \ - error_on_reserved_bit_write), \ - .common = { \ - .start_write = NULL, \ - .write_byte = bb_emul_write_byte, \ - .finish_write = bb_emul_handle_write, \ - .start_read = bb_emul_handle_read, \ - .read_byte = bb_emul_read_byte, \ - .finish_read = NULL, \ - .access_reg = bb_emul_access_reg, \ - }, \ - }; \ - \ - static const struct i2c_common_emul_cfg bb_emul_cfg_##n = { \ - .i2c_label = DT_INST_BUS_LABEL(n), \ - .dev_label = DT_INST_LABEL(n), \ - .data = &bb_emul_data_##n.common, \ - .addr = DT_INST_REG_ADDR(n), \ - }; \ - EMUL_DEFINE(bb_emul_init, DT_DRV_INST(n), &bb_emul_cfg_##n, \ - &bb_emul_data_##n) - -DT_INST_FOREACH_STATUS_OKAY(BB_RETIMER_EMUL) - -#define BB_RETIMER_EMUL_CASE(n) \ - case DT_INST_DEP_ORD(n): return &bb_emul_data_##n.common.emul; - -/** Check description in emul_bb_emulator.h */ -struct i2c_emul *bb_emul_get(int ord) -{ - switch (ord) { - DT_INST_FOREACH_STATUS_OKAY(BB_RETIMER_EMUL_CASE) - - default: - return NULL; - } -} |