Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c0c1076 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "i2c-msm-v2: QUP I2C does not support 50MHz source frequency"

parents 47b89a11 e22b30cb
Loading
Loading
Loading
Loading
+15 −44
Original line number Diff line number Diff line
@@ -841,18 +841,15 @@ static void i2c_msm_prof_evnt_dump(struct i2c_msm_ctrl *ctrl)
}

/*
 * tag_lookup_table[is_high_speed][start_req][is_last][is_rx]
 * @start_req   start or repeated-start
 * tag_lookup_table[is_new_addr][is_last][is_rx]
 * @is_new_addr Is start tag required? (which requires two more bytes.)
 * @is_last     Use the XXXXX_N_STOP tag varient
 * @is_rx       READ/WRITE
 * is_high_speed Requires a post-fix of a start-tag and the reserved
 *               high-speed address.
 *
 * workaround! Due to an HW issues, a stop is issued after every read.
 *    QUP_TAG2_DATA_READ is replaced by QUP_TAG2_DATA_READ_N_STOP.
 */
static const struct i2c_msm_tag tag_lookup_table[2][2][2][2] = {
	{{{{QUP_TAG2_DATA_WRITE                                   , 2},
static const struct i2c_msm_tag tag_lookup_table[2][2][2] = {
	{{{QUP_TAG2_DATA_WRITE                                   , 2},
	   {QUP_TAG2_DATA_READ_N_STOP                             , 2} },
	/* last buffer */
	  {{QUP_TAG2_DATA_WRITE_N_STOP                            , 2},
@@ -862,48 +859,29 @@ static const struct i2c_msm_tag tag_lookup_table[2][2][2][2] = {
	   {QUP_TAG2_START | (QUP_TAG2_DATA_READ_N_STOP     << 16), 4} },
	/* last buffer + new addr */
	  {{QUP_TAG2_START | (QUP_TAG2_DATA_WRITE_N_STOP    << 16), 4},
	   {QUP_TAG2_START | (QUP_TAG2_DATA_READ_N_STOP     << 16), 4} } } },
	/* high speed */
	{{{{QUP_TAG2_DATA_WRITE                                   , 2},
	   {QUP_TAG2_DATA_READ_N_STOP                             , 2} },
	/* high speed + last buffer */
	  {{QUP_TAG2_DATA_WRITE_N_STOP                            , 2},
	   {QUP_TAG2_DATA_READ_N_STOP                             , 2} } },
	/* high speed + new addr */
	 {{{QUP_TAG2_START_HS | (QUP_TAG2_DATA_WRITE        << 32), 6},
	   {QUP_TAG2_START_HS | (QUP_TAG2_DATA_READ_N_STOP  << 32), 6} },
	/* high speed + last buffer + new addr */
	  {{QUP_TAG2_START_HS | (QUP_TAG2_DATA_WRITE_N_STOP << 32), 6},
	   {QUP_TAG2_START_HS | (QUP_TAG2_DATA_READ_N_STOP  << 32), 6} } } },
	   {QUP_TAG2_START | (QUP_TAG2_DATA_READ_N_STOP     << 16), 4} } },
};

/*
 * i2c_msm_tag_create: format a qup tag ver2
 */
static struct i2c_msm_tag i2c_msm_tag_create(bool is_high_speed,
	bool start_req, bool is_last_buf, bool is_rx, u8 buf_len,
	u8 slave_addr)
static struct i2c_msm_tag i2c_msm_tag_create(bool is_new_addr, bool is_last_buf,
					bool is_rx, u8 buf_len, u8 slave_addr)
{
	struct i2c_msm_tag tag;
	/* Normalize booleans to 1 or 0 */
	start_req = start_req ? 1 : 0;
	is_new_addr = is_new_addr ? 1 : 0;
	is_last_buf = is_last_buf ? 1 : 0;
	is_rx = is_rx ? 1 : 0;

	tag = tag_lookup_table[is_high_speed][start_req][is_last_buf][is_rx];
	tag = tag_lookup_table[is_new_addr][is_last_buf][is_rx];
	/* fill in the non-const value: the address and the length */
	switch (tag.len) {
	case 6:
		*i2c_msm_tag_byte(&tag, 3) = slave_addr;
		*i2c_msm_tag_byte(&tag, 5) = buf_len;
		break;
	case 4:
	if (tag.len == I2C_MSM_TAG2_MAX_LEN) {
		*i2c_msm_tag_byte(&tag, 1) = slave_addr;
		*i2c_msm_tag_byte(&tag, 3) = buf_len;
		break;
	default:
	} else {
		*i2c_msm_tag_byte(&tag, 1) = buf_len;
	};
	}

	return tag;
}
@@ -1082,11 +1060,6 @@ i2c_msm_qup_xfer_init_reset_state(struct i2c_msm_ctrl *ctrl)
	wmb();
}

bool i2c_msm_xfer_is_high_speed(struct i2c_msm_ctrl *ctrl)
{
	return ctrl->rsrcs.clk_freq_out > I2C_MSM_CLK_FAST_MAX_FREQ;
}

/*
 * i2c_msm_clk_div_fld:
 * @clk_freq_out output clock frequency
@@ -3221,9 +3194,7 @@ static void i2c_msm_xfer_create_cur_tag(struct i2c_msm_ctrl *ctrl,
{
	struct i2c_msm_xfer_buf *cur_buf = &ctrl->xfer.cur_buf;

	cur_buf->out_tag = i2c_msm_tag_create(
					i2c_msm_xfer_is_high_speed(ctrl),
					start_req, cur_buf->is_last,
	cur_buf->out_tag = i2c_msm_tag_create(start_req, cur_buf->is_last,
					cur_buf->is_rx, cur_buf->len,
					cur_buf->slv_addr);

@@ -3728,7 +3699,7 @@ static int i2c_msm_rsrcs_clk_init(struct i2c_msm_ctrl *ctrl)
	int ret = 0;

	if ((ctrl->rsrcs.clk_freq_out <= 0) ||
	    (ctrl->rsrcs.clk_freq_out > I2C_MSM_CLK_HIGH_MAX_FREQ)) {
	    (ctrl->rsrcs.clk_freq_out > I2C_MSM_CLK_FAST_PLUS_FREQ)) {
		dev_err(ctrl->dev,
			"error clock frequency %dKHZ is not supported\n",
			(ctrl->rsrcs.clk_freq_out / 1000));
+11 −14
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ enum msm_i2_debug_level {
#define MASK_IS_SET(val, mask)      ((val & mask) == mask)
#define MASK_IS_SET_BOOL(val, mask) (MASK_IS_SET(val, mask) ? 1 : 0)
#define KHz(freq) (1000 * freq)
#define I2C_MSM_CLK_FAST_PLUS_FREQ  (1000000)
#define I2C_MSM_TAG2_MAX_LEN (4)

/* QUP Registers */
enum {
@@ -144,11 +146,6 @@ enum {
	QUP_EN_VERSION_TWO_TAG  = 1U,
};

enum {
	I2C_MSM_CLK_FAST_MAX_FREQ    = 1000000,
	I2C_MSM_CLK_HIGH_MAX_FREQ    = 3400000,
};

/* Register:QUP_I2C_MASTER_CLK_CTL field setters */
#define I2C_MSM_SCL_NOISE_REJECTION(reg_val, noise_rej_val) \
		(((reg_val) & ~(0x3 << 24)) | (((noise_rej_val) & 0x3) << 24))
@@ -202,11 +199,11 @@ enum msm_i2c_power_state {

/*
 * The max buffer size required for tags is for holding the following sequence:
 * [start | hs-addr] + [start | slv-addr] + [ rd/wr | len]
 * [start] + [start | slv-addr] + [ rd/wr | len]
 * which sum up to 6 bytes. However, we use u64 to hold the value, thus we say
 * that max length is 8 bytes.
 */
#define I2C_MSM_TAG2_MAX_LEN            (8)
#define I2C_MSM_TAG2_MAX_LEN            (4)
#define I2C_MSM_BAM_CONS_SZ             (64) /* consumer pipe n entries */
#define I2C_MSM_BAM_PROD_SZ             (32) /* producer pipe n entries */
#define I2C_MSM_BAM_DESC_ARR_SIZ  (I2C_MSM_BAM_CONS_SZ + I2C_MSM_BAM_PROD_SZ)
@@ -217,7 +214,6 @@ enum msm_i2c_power_state {
#define I2C_MSM_MAX_POLL_MSEC           (100)
#define I2C_MSM_TIMEOUT_SAFTY_COEF      (10)
#define I2C_MSM_TIMEOUT_MIN_USEC        (500000)
#define I2C_MSM_HS_ADDR                 (0x0f)
#define I2C_QUP_MAX_BUS_RECOVERY_RETRY  (10)

/* QUP v2 tags */
@@ -230,9 +226,6 @@ enum msm_i2c_power_state {
#define QUP_TAG2_START_STOP        (0x8AULL)
#define QUP_TAG2_INPUT_EOT         (0x93ULL)
#define QUP_TAG2_FLUSH_STOP        (0x96ULL)
/* Aggregate the constatnt values of HS start sequence */
#define QUP_TAG2_START_HS  (QUP_TAG2_START | (I2C_MSM_HS_ADDR << 8) | \
			   (QUP_TAG2_START << 16))

enum msm_spi_clk_path_vec_idx {
	I2C_MSM_CLK_PATH_SUSPEND_VEC,
@@ -383,9 +376,13 @@ struct i2c_msm_xfer_mode_bam {
 * | input_tag | eot_... | tag_arr 0 | tag_arr 1 | .. | tag_arr n |
 * +-----------+---------+-----------+-----------+----+-----------+
 *
 * I2C_MSM_TAG2_MAX_LEN bytes for input_tag
 * I2C_MSM_TAG2_MAX_LEN bytes for eot_n_flush_stop_tags
 * I2C_MSM_BAM_DESC_ARR_SIZ * I2C_MSM_TAG2_MAX_LEN bytes for tag_arr
 * Why +2?
 * One tag buffer for the input tags. This is a write only buffer for BAM, it is
 *    used to read the tags of the input fifo. We let them overwrite each other,
 *    since it is a throw-away from the driver's perspective.
 * Second tag buffer for the EOT and flush-stop tags. This is a read only
 *    buffer (from BAM perspective). It is used to put EOT and flush-stop at the
 *    end of every transaction.
 */
#define I2C_MSM_BAM_TAG_MEM_SZ  \
	((I2C_MSM_BAM_DESC_ARR_SIZ + 2) * I2C_MSM_TAG2_MAX_LEN)