Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'ipa-versions-and-registers'

Alex Elder says:

====================
net: ipa: versions and registers

Version 2 of this series adds kernel-doc descriptions for all
members of the ipa_version enumerated type in patch 2.

The original description of the series is below.

-Alex

This series is sort of a mix of things, generally related to
updating IPA versions and register definitions.

The first patch fixes some version-related tests throughout the code
so the conditions are valid for IPA versions other than the two that
are currently supported. Support for additional versions is
forthcoming, and this is a preparatory step.

The second patch adds to the set of defined IPA versions, to include
all versions between 3.0 and 4.11.

The next defines an endpoint initialization register that was
previously not being configured. We now initialize that register
(so that NAT is explicitly disabled) on all AP endpoints.

The fourth adds support for an extra bit in a field in a register,
which is present starting at IPA v4.5.

The last two are sort of standalone. One just moves a function
definition and makes it private. The other increases the number of
GSI channels and events supported by the driver, sufficient for IPA
v4.5.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+121 -57
+4 -4
drivers/net/ipa/gsi.c
··· 827 827 828 828 /* Max prefetch is 1 segment (do not set MAX_PREFETCH_FMASK) */ 829 829 830 - /* We enable the doorbell engine for IPA v3.5.1 */ 831 - if (gsi->version == IPA_VERSION_3_5_1 && doorbell) 830 + /* No need to use the doorbell engine starting at IPA v4.0 */ 831 + if (gsi->version < IPA_VERSION_4_0 && doorbell) 832 832 val |= USE_DB_ENG_FMASK; 833 833 834 834 /* v4.0 introduces an escape buffer for prefetch. We use it 835 835 * on all but the AP command channel. 836 836 */ 837 - if (gsi->version != IPA_VERSION_3_5_1 && !channel->command) { 837 + if (gsi->version >= IPA_VERSION_4_0 && !channel->command) { 838 838 /* If not otherwise set, prefetch buffers are used */ 839 839 if (gsi->version < IPA_VERSION_4_5) 840 840 val |= USE_ESCAPE_BUF_ONLY_FMASK; ··· 973 973 974 974 gsi_channel_reset_command(channel); 975 975 /* Due to a hardware quirk we may need to reset RX channels twice. */ 976 - if (gsi->version == IPA_VERSION_3_5_1 && !channel->toward_ipa) 976 + if (gsi->version < IPA_VERSION_4_0 && !channel->toward_ipa) 977 977 gsi_channel_reset_command(channel); 978 978 979 979 gsi_channel_program(channel, doorbell);
+2 -2
drivers/net/ipa/gsi.h
··· 16 16 #include "ipa_version.h" 17 17 18 18 /* Maximum number of channels and event rings supported by the driver */ 19 - #define GSI_CHANNEL_COUNT_MAX 17 20 - #define GSI_EVT_RING_COUNT_MAX 13 19 + #define GSI_CHANNEL_COUNT_MAX 23 20 + #define GSI_EVT_RING_COUNT_MAX 20 21 21 22 22 /* Maximum TLV FIFO size for a channel; 64 here is arbitrary (and high) */ 23 23 #define GSI_TLV_MAX 64
+15 -11
drivers/net/ipa/ipa_cmd.c
··· 71 71 72 72 /* IPA_CMD_REGISTER_WRITE */ 73 73 74 - /* For IPA v4.0+, this opcode gets modified with pipeline clear options */ 75 - 74 + /* For IPA v4.0+, the pipeline clear options are encoded in the opcode */ 76 75 #define REGISTER_WRITE_OPCODE_SKIP_CLEAR_FMASK GENMASK(8, 8) 77 76 #define REGISTER_WRITE_OPCODE_CLEAR_OPTION_FMASK GENMASK(10, 9) 78 77 79 78 struct ipa_cmd_register_write { 80 - __le16 flags; /* Unused/reserved for IPA v3.5.1 */ 79 + __le16 flags; /* Unused/reserved prior to IPA v4.0 */ 81 80 __le16 offset; 82 81 __le32 value; 83 82 __le32 value_mask; ··· 84 85 }; 85 86 86 87 /* Field masks for ipa_cmd_register_write structure fields */ 87 - /* The next field is present for IPA v4.0 and above */ 88 + /* The next field is present for IPA v4.0+ */ 88 89 #define REGISTER_WRITE_FLAGS_OFFSET_HIGH_FMASK GENMASK(14, 11) 89 - /* The next field is present for IPA v3.5.1 only */ 90 + /* The next field is not present for IPA v4.0+ */ 90 91 #define REGISTER_WRITE_FLAGS_SKIP_CLEAR_FMASK GENMASK(15, 15) 91 92 92 - /* The next field and its values are present for IPA v3.5.1 only */ 93 + /* The next field and its values are not present for IPA v4.0+ */ 93 94 #define REGISTER_WRITE_CLEAR_OPTIONS_FMASK GENMASK(1, 0) 94 95 95 96 /* IPA_CMD_IP_PACKET_INIT */ ··· 122 123 123 124 /* Field masks for ipa_cmd_hw_dma_mem_mem structure fields */ 124 125 #define DMA_SHARED_MEM_FLAGS_DIRECTION_FMASK GENMASK(0, 0) 125 - /* The next two fields are present for IPA v3.5.1 only. */ 126 + /* The next two fields are not present for IPA v4.0+ */ 126 127 #define DMA_SHARED_MEM_FLAGS_SKIP_CLEAR_FMASK GENMASK(1, 1) 127 128 #define DMA_SHARED_MEM_FLAGS_CLEAR_OPTIONS_FMASK GENMASK(3, 2) 128 129 ··· 236 237 u32 bit_count; 237 238 238 239 /* The maximum offset in a register_write immediate command depends 239 - * on the version of IPA. IPA v3.5.1 supports a 16 bit offset, but 240 - * newer versions allow some additional high-order bits. 240 + * on the version of IPA. A 16 bit offset is always supported, 241 + * but starting with IPA v4.0 some additional high-order bits are 242 + * allowed. 241 243 */ 242 244 bit_count = BITS_PER_BYTE * sizeof(payload->offset); 243 - if (ipa->version != IPA_VERSION_3_5_1) 245 + if (ipa->version >= IPA_VERSION_4_0) 244 246 bit_count += hweight32(REGISTER_WRITE_FLAGS_OFFSET_HIGH_FMASK); 245 247 BUILD_BUG_ON(bit_count > 32); 246 248 offset_max = ~0U >> (32 - bit_count); ··· 440 440 /* pipeline_clear_src_grp is not used */ 441 441 clear_option = clear_full ? pipeline_clear_full : pipeline_clear_hps; 442 442 443 - if (ipa->version != IPA_VERSION_3_5_1) { 443 + /* IPA v4.0+ represents the pipeline clear options in the opcode. It 444 + * also supports a larger offset by encoding additional high-order 445 + * bits in the payload flags field. 446 + */ 447 + if (ipa->version >= IPA_VERSION_4_0) { 444 448 u16 offset_high; 445 449 u32 val; 446 450
+30 -12
drivers/net/ipa/ipa_endpoint.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 3 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. 4 - * Copyright (C) 2019-2020 Linaro Ltd. 4 + * Copyright (C) 2019-2021 Linaro Ltd. 5 5 */ 6 6 7 7 #include <linux/types.h> ··· 266 266 * if (endpoint->toward_ipa) 267 267 * assert(ipa->version != IPA_VERSION_4.2); 268 268 * else 269 - * assert(ipa->version == IPA_VERSION_3_5_1); 269 + * assert(ipa->version < IPA_VERSION_4_0); 270 270 */ 271 271 mask = endpoint->toward_ipa ? ENDP_DELAY_FMASK : ENDP_SUSPEND_FMASK; 272 272 ··· 347 347 { 348 348 bool suspended; 349 349 350 - if (endpoint->ipa->version != IPA_VERSION_3_5_1) 350 + if (endpoint->ipa->version >= IPA_VERSION_4_0) 351 351 return enable; /* For IPA v4.0+, no change made */ 352 352 353 353 /* assert(!endpoint->toward_ipa); */ ··· 468 468 iowrite32(val, endpoint->ipa->reg_virt + offset); 469 469 } 470 470 471 + static void ipa_endpoint_init_nat(struct ipa_endpoint *endpoint) 472 + { 473 + u32 offset; 474 + u32 val; 475 + 476 + if (!endpoint->toward_ipa) 477 + return; 478 + 479 + offset = IPA_REG_ENDP_INIT_NAT_N_OFFSET(endpoint->endpoint_id); 480 + val = u32_encode_bits(IPA_NAT_BYPASS, NAT_EN_FMASK); 481 + 482 + iowrite32(val, endpoint->ipa->reg_virt + offset); 483 + } 484 + 471 485 /** 472 486 * ipa_endpoint_init_hdr() - Initialize HDR endpoint configuration register 473 487 * @endpoint: Endpoint pointer ··· 529 515 /* Where IPA will write the length */ 530 516 offset = offsetof(struct rmnet_map_header, pkt_len); 531 517 /* Upper bits are stored in HDR_EXT with IPA v4.5 */ 532 - if (version == IPA_VERSION_4_5) 518 + if (version >= IPA_VERSION_4_5) 533 519 offset &= field_mask(HDR_OFST_PKT_SIZE_FMASK); 534 520 535 521 val |= HDR_OFST_PKT_SIZE_VALID_FMASK; ··· 576 562 /* IPA v4.5 adds some most-significant bits to a few fields, 577 563 * two of which are defined in the HDR (not HDR_EXT) register. 578 564 */ 579 - if (ipa->version == IPA_VERSION_4_5) { 565 + if (ipa->version >= IPA_VERSION_4_5) { 580 566 /* HDR_TOTAL_LEN_OR_PAD_OFFSET is 0, so MSB is 0 */ 581 567 if (endpoint->data->qmap && !endpoint->toward_ipa) { 582 568 u32 offset; ··· 790 776 if (!microseconds) 791 777 return 0; /* Nothing to compute if timer period is 0 */ 792 778 793 - if (ipa->version == IPA_VERSION_4_5) 779 + if (ipa->version >= IPA_VERSION_4_5) 794 780 return hol_block_timer_qtime_val(ipa, microseconds); 795 781 796 782 /* Use 64 bit arithmetic to avoid overflow... */ ··· 1482 1468 * is active, we need to handle things specially to recover. 1483 1469 * All other cases just need to reset the underlying GSI channel. 1484 1470 */ 1485 - special = ipa->version == IPA_VERSION_3_5_1 && 1486 - !endpoint->toward_ipa && 1471 + special = ipa->version < IPA_VERSION_4_0 && !endpoint->toward_ipa && 1487 1472 endpoint->data->aggregation; 1488 1473 if (special && ipa_endpoint_aggr_active(endpoint)) 1489 1474 ret = ipa_endpoint_reset_rx_aggr(endpoint); ··· 1502 1489 else 1503 1490 (void)ipa_endpoint_program_suspend(endpoint, false); 1504 1491 ipa_endpoint_init_cfg(endpoint); 1492 + ipa_endpoint_init_nat(endpoint); 1505 1493 ipa_endpoint_init_hdr(endpoint); 1506 1494 ipa_endpoint_init_hdr_ext(endpoint); 1507 1495 ipa_endpoint_init_hdr_metadata_mask(endpoint); ··· 1581 1567 (void)ipa_endpoint_program_suspend(endpoint, true); 1582 1568 } 1583 1569 1584 - /* IPA v3.5.1 doesn't use channel stop for suspend */ 1585 - stop_channel = endpoint->ipa->version != IPA_VERSION_3_5_1; 1570 + /* Starting with IPA v4.0, endpoints are suspended by stopping the 1571 + * underlying GSI channel rather than using endpoint suspend mode. 1572 + */ 1573 + stop_channel = endpoint->ipa->version >= IPA_VERSION_4_0; 1586 1574 ret = gsi_channel_suspend(gsi, endpoint->channel_id, stop_channel); 1587 1575 if (ret) 1588 1576 dev_err(dev, "error %d suspending channel %u\n", ret, ··· 1604 1588 if (!endpoint->toward_ipa) 1605 1589 (void)ipa_endpoint_program_suspend(endpoint, false); 1606 1590 1607 - /* IPA v3.5.1 doesn't use channel start for resume */ 1608 - start_channel = endpoint->ipa->version != IPA_VERSION_3_5_1; 1591 + /* Starting with IPA v4.0, the underlying GSI channel must be 1592 + * restarted for resume. 1593 + */ 1594 + start_channel = endpoint->ipa->version >= IPA_VERSION_4_0; 1609 1595 ret = gsi_channel_resume(gsi, endpoint->channel_id, start_channel); 1610 1596 if (ret) 1611 1597 dev_err(dev, "error %d resuming channel %u\n", ret,
+18 -3
drivers/net/ipa/ipa_main.c
··· 227 227 { 228 228 u32 val; 229 229 230 - /* Nothing to configure for IPA v3.5.1 */ 231 - if (ipa->version == IPA_VERSION_3_5_1) 230 + /* Nothing to configure prior to IPA v4.0 */ 231 + if (ipa->version < IPA_VERSION_4_0) 232 232 return; 233 233 234 234 val = ioread32(ipa->reg_virt + IPA_REG_COMP_CFG_OFFSET); ··· 285 285 GEN_QMB_1_MAX_READS_BEATS_FMASK); 286 286 } 287 287 iowrite32(val, ipa->reg_virt + IPA_REG_QSB_MAX_READS_OFFSET); 288 + } 289 + 290 + /* The internal inactivity timer clock is used for the aggregation timer */ 291 + #define TIMER_FREQUENCY 32000 /* 32 KHz inactivity timer clock */ 292 + 293 + /* Compute the value to use in the COUNTER_CFG register AGGR_GRANULARITY 294 + * field to represent the given number of microseconds. The value is one 295 + * less than the number of timer ticks in the requested period. 0 is not 296 + * a valid granularity value. 297 + */ 298 + static u32 ipa_aggr_granularity_val(u32 usec) 299 + { 300 + /* assert(usec != 0); */ 301 + 302 + return DIV_ROUND_CLOSEST(usec * TIMER_FREQUENCY, USEC_PER_SEC) - 1; 288 303 } 289 304 290 305 /* IPA uses unified Qtime starting at IPA v4.5, implementing various ··· 403 388 } 404 389 405 390 /* Implement some hardware workarounds */ 406 - if (version != IPA_VERSION_3_5_1 && version < IPA_VERSION_4_5) { 391 + if (version >= IPA_VERSION_4_0 && version < IPA_VERSION_4_5) { 407 392 /* Enable open global clocks (not needed for IPA v4.5) */ 408 393 val = GLOBAL_FMASK; 409 394 val |= GLOBAL_2X_CLK_FMASK;
+4 -2
drivers/net/ipa/ipa_mem.c
··· 61 61 struct gsi_trans *trans; 62 62 u32 offset; 63 63 u16 size; 64 + u32 val; 64 65 65 66 /* Get a transaction to define the header memory region and to zero 66 67 * the processing context and modem memory regions. ··· 90 89 gsi_trans_commit_wait(trans); 91 90 92 91 /* Tell the hardware where the processing context area is located */ 93 - iowrite32(ipa->mem_offset + ipa->mem[IPA_MEM_MODEM_PROC_CTX].offset, 94 - ipa->reg_virt + IPA_REG_LOCAL_PKT_PROC_CNTXT_BASE_OFFSET); 92 + offset = ipa->mem_offset + ipa->mem[IPA_MEM_MODEM_PROC_CTX].offset; 93 + val = proc_cntxt_base_addr_encoded(ipa->version, offset); 94 + iowrite32(val, ipa->reg_virt + IPA_REG_LOCAL_PKT_PROC_CNTXT_OFFSET); 95 95 96 96 return 0; 97 97 }
+1 -1
drivers/net/ipa/ipa_qmi.c
··· 377 377 378 378 /* None of the stats fields are valid (IPA v4.0 and above) */ 379 379 380 - if (ipa->version != IPA_VERSION_3_5_1) { 380 + if (ipa->version >= IPA_VERSION_4_0) { 381 381 mem = &ipa->mem[IPA_MEM_STATS_QUOTA_MODEM]; 382 382 if (mem->size) { 383 383 req.hw_stats_quota_base_addr_valid = 1;
+25 -15
drivers/net/ipa/ipa_reg.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 2 3 3 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. 4 - * Copyright (C) 2018-2020 Linaro Ltd. 4 + * Copyright (C) 2018-2021 Linaro Ltd. 5 5 */ 6 6 #ifndef _IPA_REG_H_ 7 7 #define _IPA_REG_H_ ··· 217 217 return 0x00000000; 218 218 } 219 219 220 - /* The value of the next register must be a multiple of 8 */ 221 - #define IPA_REG_LOCAL_PKT_PROC_CNTXT_BASE_OFFSET 0x000001e8 220 + /* The value of the next register must be a multiple of 8 (bottom 3 bits 0) */ 221 + #define IPA_REG_LOCAL_PKT_PROC_CNTXT_OFFSET 0x000001e8 222 + 223 + /* Encoded value for LOCAL_PKT_PROC_CNTXT register BASE_ADDR field */ 224 + static inline u32 proc_cntxt_base_addr_encoded(enum ipa_version version, 225 + u32 addr) 226 + { 227 + if (version < IPA_VERSION_4_5) 228 + return u32_encode_bits(addr, GENMASK(16, 0)); 229 + 230 + return u32_encode_bits(addr, GENMASK(17, 0)); 231 + } 222 232 223 233 /* ipa->available defines the valid bits in the AGGR_FORCE_CLOSE register */ 224 234 #define IPA_REG_AGGR_FORCE_CLOSE_OFFSET 0x000001ec ··· 236 226 /* The next register is not present for IPA v4.5 */ 237 227 #define IPA_REG_COUNTER_CFG_OFFSET 0x000001f0 238 228 #define AGGR_GRANULARITY_FMASK GENMASK(8, 4) 239 - 240 - /* The internal inactivity timer clock is used for the aggregation timer */ 241 - #define TIMER_FREQUENCY 32000 /* 32 KHz inactivity timer clock */ 242 - 243 - /* Compute the value to use in the AGGR_GRANULARITY field representing the 244 - * given number of microseconds. The value is one less than the number of 245 - * timer ticks in the requested period. 0 not a valid granularity value. 246 - */ 247 - static inline u32 ipa_aggr_granularity_val(u32 usec) 248 - { 249 - return DIV_ROUND_CLOSEST(usec * TIMER_FREQUENCY, USEC_PER_SEC) - 1; 250 - } 251 229 252 230 /* The next register is not present for IPA v4.5 */ 253 231 #define IPA_REG_TX_CFG_OFFSET 0x000001fc ··· 384 386 IPA_CS_OFFLOAD_NONE = 0x0, 385 387 IPA_CS_OFFLOAD_UL = 0x1, 386 388 IPA_CS_OFFLOAD_DL = 0x2, 389 + }; 390 + 391 + /* Valid only for TX (IPA consumer) endpoints */ 392 + #define IPA_REG_ENDP_INIT_NAT_N_OFFSET(ep) \ 393 + (0x0000080c + 0x0070 * (ep)) 394 + #define NAT_EN_FMASK GENMASK(1, 0) 395 + 396 + /** enum ipa_nat_en - ENDP_INIT_NAT register NAT_EN field value */ 397 + enum ipa_nat_en { 398 + IPA_NAT_BYPASS = 0x0, 399 + IPA_NAT_SRC = 0x1, 400 + IPA_NAT_DST = 0x2, 387 401 }; 388 402 389 403 #define IPA_REG_ENDP_INIT_HDR_N_OFFSET(ep) \
+22 -7
drivers/net/ipa/ipa_version.h
··· 8 8 9 9 /** 10 10 * enum ipa_version 11 + * @IPA_VERSION_3_0: IPA version 3.0/GSI version 1.0 12 + * @IPA_VERSION_3_1: IPA version 3.1/GSI version 1.1 13 + * @IPA_VERSION_3_5: IPA version 3.5/GSI version 1.2 14 + * @IPA_VERSION_3_5_1: IPA version 3.5.1/GSI version 1.3 15 + * @IPA_VERSION_4_0: IPA version 4.0/GSI version 2.0 16 + * @IPA_VERSION_4_1: IPA version 4.1/GSI version 2.0 17 + * @IPA_VERSION_4_2: IPA version 4.2/GSI version 2.2 18 + * @IPA_VERSION_4_5: IPA version 4.5/GSI version 2.5 19 + * @IPA_VERSION_4_7: IPA version 4.7/GSI version 2.7 20 + * @IPA_VERSION_4_9: IPA version 4.9/GSI version 2.9 21 + * @IPA_VERSION_4_11: IPA version 4.11/GSI version 2.11 (2.1.1) 11 22 * 12 23 * Defines the version of IPA (and GSI) hardware present on the platform. 13 - * It seems this might be better defined elsewhere, but having it here gets 14 - * it where it's needed. 15 24 */ 16 25 enum ipa_version { 17 - IPA_VERSION_3_5_1, /* GSI version 1.3.0 */ 18 - IPA_VERSION_4_0, /* GSI version 2.0 */ 19 - IPA_VERSION_4_1, /* GSI version 2.1 */ 20 - IPA_VERSION_4_2, /* GSI version 2.2 */ 21 - IPA_VERSION_4_5, /* GSI version 2.5 */ 26 + IPA_VERSION_3_0, 27 + IPA_VERSION_3_1, 28 + IPA_VERSION_3_5, 29 + IPA_VERSION_3_5_1, 30 + IPA_VERSION_4_0, 31 + IPA_VERSION_4_1, 32 + IPA_VERSION_4_2, 33 + IPA_VERSION_4_5, 34 + IPA_VERSION_4_7, 35 + IPA_VERSION_4_9, 36 + IPA_VERSION_4_11, 22 37 }; 23 38 24 39 #endif /* _IPA_VERSION_H_ */