8585#define PACKET_HEADER0_PROTOCOL GENMASK(7, 4)
8686#define PACKET_HEADER0_PROTOCOL_I2C 1
8787
88+ #define I2C_HEADER_HS_MODE BIT(22)
8889#define I2C_HEADER_CONT_ON_NAK BIT(21)
8990#define I2C_HEADER_READ BIT(19)
9091#define I2C_HEADER_10BIT_ADDR BIT(18)
@@ -200,6 +201,8 @@ enum msg_end_type {
200201 * @thigh_fast_mode: High period of the clock in fast mode.
201202 * @tlow_fastplus_mode: Low period of the clock in fast-plus mode.
202203 * @thigh_fastplus_mode: High period of the clock in fast-plus mode.
204+ * @tlow_hs_mode: Low period of the clock in HS mode.
205+ * @thigh_hs_mode: High period of the clock in HS mode.
203206 * @setup_hold_time_std_mode: Setup and hold time for start and stop conditions
204207 * in standard mode.
205208 * @setup_hold_time_fast_mode: Setup and hold time for start and stop
@@ -210,6 +213,7 @@ enum msg_end_type {
210213 * in HS mode.
211214 * @has_interface_timing_reg: Has interface timing register to program the tuned
212215 * timing settings.
216+ * @enable_hs_mode_support: Enable support for high speed (HS) mode transfers.
213217 */
214218struct tegra_i2c_hw_feature {
215219 bool has_continue_xfer_support ;
@@ -232,11 +236,14 @@ struct tegra_i2c_hw_feature {
232236 u32 thigh_fast_mode ;
233237 u32 tlow_fastplus_mode ;
234238 u32 thigh_fastplus_mode ;
239+ u32 tlow_hs_mode ;
240+ u32 thigh_hs_mode ;
235241 u32 setup_hold_time_std_mode ;
236242 u32 setup_hold_time_fast_mode ;
237243 u32 setup_hold_time_fastplus_mode ;
238244 u32 setup_hold_time_hs_mode ;
239245 bool has_interface_timing_reg ;
246+ bool enable_hs_mode_support ;
240247};
241248
242249/**
@@ -646,6 +653,7 @@ static int tegra_i2c_master_reset(struct tegra_i2c_dev *i2c_dev)
646653static int tegra_i2c_init (struct tegra_i2c_dev * i2c_dev )
647654{
648655 u32 val , clk_divisor , clk_multiplier , tsu_thd , tlow , thigh , non_hs_mode ;
656+ u32 max_bus_freq_hz ;
649657 struct i2c_timings * t = & i2c_dev -> timings ;
650658 int err ;
651659
@@ -684,6 +692,14 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
684692 if (IS_VI (i2c_dev ))
685693 tegra_i2c_vi_init (i2c_dev );
686694
695+ if (i2c_dev -> hw -> enable_hs_mode_support )
696+ max_bus_freq_hz = I2C_MAX_HIGH_SPEED_MODE_FREQ ;
697+ else
698+ max_bus_freq_hz = I2C_MAX_FAST_MODE_PLUS_FREQ ;
699+
700+ if (WARN_ON (t -> bus_freq_hz > max_bus_freq_hz ))
701+ t -> bus_freq_hz = max_bus_freq_hz ;
702+
687703 if (t -> bus_freq_hz <= I2C_MAX_STANDARD_MODE_FREQ ) {
688704 tlow = i2c_dev -> hw -> tlow_std_mode ;
689705 thigh = i2c_dev -> hw -> thigh_std_mode ;
@@ -694,11 +710,22 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
694710 thigh = i2c_dev -> hw -> thigh_fast_mode ;
695711 tsu_thd = i2c_dev -> hw -> setup_hold_time_fast_mode ;
696712 non_hs_mode = i2c_dev -> hw -> clk_divisor_fast_mode ;
697- } else {
713+ } else if ( t -> bus_freq_hz <= I2C_MAX_FAST_MODE_PLUS_FREQ ) {
698714 tlow = i2c_dev -> hw -> tlow_fastplus_mode ;
699715 thigh = i2c_dev -> hw -> thigh_fastplus_mode ;
700716 tsu_thd = i2c_dev -> hw -> setup_hold_time_fastplus_mode ;
701717 non_hs_mode = i2c_dev -> hw -> clk_divisor_fast_plus_mode ;
718+ } else {
719+ /*
720+ * When using HS mode, i.e. when the bus frequency is greater than fast plus mode,
721+ * the non-hs timing registers will be used for sending the master code byte for
722+ * transition to HS mode. Configure the non-hs timing registers for Fast Mode to
723+ * send the master code byte at 400kHz.
724+ */
725+ tlow = i2c_dev -> hw -> tlow_fast_mode ;
726+ thigh = i2c_dev -> hw -> thigh_fast_mode ;
727+ tsu_thd = i2c_dev -> hw -> setup_hold_time_fast_mode ;
728+ non_hs_mode = i2c_dev -> hw -> clk_divisor_fast_mode ;
702729 }
703730
704731 /* make sure clock divisor programmed correctly */
@@ -720,6 +747,18 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
720747 if (i2c_dev -> hw -> has_interface_timing_reg && tsu_thd )
721748 i2c_writel (i2c_dev , tsu_thd , I2C_INTERFACE_TIMING_1 );
722749
750+ /* Write HS mode registers. These will get used only for HS mode*/
751+ if (i2c_dev -> hw -> enable_hs_mode_support ) {
752+ tlow = i2c_dev -> hw -> tlow_hs_mode ;
753+ thigh = i2c_dev -> hw -> thigh_hs_mode ;
754+ tsu_thd = i2c_dev -> hw -> setup_hold_time_hs_mode ;
755+
756+ val = FIELD_PREP (I2C_HS_INTERFACE_TIMING_THIGH , thigh ) |
757+ FIELD_PREP (I2C_HS_INTERFACE_TIMING_TLOW , tlow );
758+ i2c_writel (i2c_dev , val , I2C_HS_INTERFACE_TIMING_0 );
759+ i2c_writel (i2c_dev , tsu_thd , I2C_HS_INTERFACE_TIMING_1 );
760+ }
761+
723762 clk_multiplier = (tlow + thigh + 2 ) * (non_hs_mode + 1 );
724763
725764 err = clk_set_rate (i2c_dev -> div_clk ,
@@ -1217,6 +1256,9 @@ static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,
12171256 if (msg -> flags & I2C_M_RD )
12181257 packet_header |= I2C_HEADER_READ ;
12191258
1259+ if (i2c_dev -> timings .bus_freq_hz > I2C_MAX_FAST_MODE_PLUS_FREQ )
1260+ packet_header |= I2C_HEADER_HS_MODE ;
1261+
12201262 if (i2c_dev -> dma_mode && !i2c_dev -> msg_read )
12211263 * dma_buf ++ = packet_header ;
12221264 else
@@ -1508,6 +1550,7 @@ static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
15081550 .setup_hold_time_fastplus_mode = 0x0 ,
15091551 .setup_hold_time_hs_mode = 0x0 ,
15101552 .has_interface_timing_reg = false,
1553+ .enable_hs_mode_support = false,
15111554};
15121555
15131556static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
@@ -1536,6 +1579,7 @@ static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
15361579 .setup_hold_time_fastplus_mode = 0x0 ,
15371580 .setup_hold_time_hs_mode = 0x0 ,
15381581 .has_interface_timing_reg = false,
1582+ .enable_hs_mode_support = false,
15391583};
15401584
15411585static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
@@ -1564,6 +1608,7 @@ static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
15641608 .setup_hold_time_fastplus_mode = 0x0 ,
15651609 .setup_hold_time_hs_mode = 0x0 ,
15661610 .has_interface_timing_reg = false,
1611+ .enable_hs_mode_support = false,
15671612};
15681613
15691614static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
@@ -1592,6 +1637,7 @@ static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
15921637 .setup_hold_time_fastplus_mode = 0x0 ,
15931638 .setup_hold_time_hs_mode = 0x0 ,
15941639 .has_interface_timing_reg = true,
1640+ .enable_hs_mode_support = false,
15951641};
15961642
15971643static const struct tegra_i2c_hw_feature tegra210_i2c_hw = {
@@ -1620,6 +1666,7 @@ static const struct tegra_i2c_hw_feature tegra210_i2c_hw = {
16201666 .setup_hold_time_fastplus_mode = 0 ,
16211667 .setup_hold_time_hs_mode = 0 ,
16221668 .has_interface_timing_reg = true,
1669+ .enable_hs_mode_support = false,
16231670};
16241671
16251672static const struct tegra_i2c_hw_feature tegra186_i2c_hw = {
@@ -1648,6 +1695,7 @@ static const struct tegra_i2c_hw_feature tegra186_i2c_hw = {
16481695 .setup_hold_time_fastplus_mode = 0 ,
16491696 .setup_hold_time_hs_mode = 0 ,
16501697 .has_interface_timing_reg = true,
1698+ .enable_hs_mode_support = false,
16511699};
16521700
16531701static const struct tegra_i2c_hw_feature tegra194_i2c_hw = {
@@ -1671,17 +1719,20 @@ static const struct tegra_i2c_hw_feature tegra194_i2c_hw = {
16711719 .thigh_fast_mode = 0x2 ,
16721720 .tlow_fastplus_mode = 0x2 ,
16731721 .thigh_fastplus_mode = 0x2 ,
1722+ .tlow_hs_mode = 0x8 ,
1723+ .thigh_hs_mode = 0x3 ,
16741724 .setup_hold_time_std_mode = 0x08080808 ,
16751725 .setup_hold_time_fast_mode = 0x02020202 ,
16761726 .setup_hold_time_fastplus_mode = 0x02020202 ,
16771727 .setup_hold_time_hs_mode = 0x090909 ,
16781728 .has_interface_timing_reg = true,
1729+ .enable_hs_mode_support = true,
16791730};
16801731
16811732static const struct tegra_i2c_hw_feature tegra256_i2c_hw = {
16821733 .has_continue_xfer_support = true,
16831734 .has_per_pkt_xfer_complete_irq = true,
1684- .clk_divisor_hs_mode = 7 ,
1735+ .clk_divisor_hs_mode = 9 ,
16851736 .clk_divisor_std_mode = 0x7a ,
16861737 .clk_divisor_fast_mode = 0x40 ,
16871738 .clk_divisor_fast_plus_mode = 0x14 ,
@@ -1699,10 +1750,14 @@ static const struct tegra_i2c_hw_feature tegra256_i2c_hw = {
16991750 .thigh_fast_mode = 0x2 ,
17001751 .tlow_fastplus_mode = 0x4 ,
17011752 .thigh_fastplus_mode = 0x4 ,
1753+ .tlow_hs_mode = 0x3 ,
1754+ .thigh_hs_mode = 0x2 ,
17021755 .setup_hold_time_std_mode = 0x08080808 ,
17031756 .setup_hold_time_fast_mode = 0x04010101 ,
17041757 .setup_hold_time_fastplus_mode = 0x04020202 ,
1758+ .setup_hold_time_hs_mode = 0x030303 ,
17051759 .has_interface_timing_reg = true,
1760+ .enable_hs_mode_support = true,
17061761};
17071762
17081763static const struct of_device_id tegra_i2c_of_match [] = {
0 commit comments