]> git.itanic.dy.fi Git - linux-stable/commitdiff
net: ipa: define more fields for GSI registers
authorAlex Elder <elder@linaro.org>
Mon, 13 Feb 2023 16:22:26 +0000 (10:22 -0600)
committerJakub Kicinski <kuba@kernel.org>
Wed, 15 Feb 2023 04:39:38 +0000 (20:39 -0800)
Beyond the CH_C_QOS register, two other registers whose offset is
related to channel number have fields within them.

Define the fields within the CH_C_CNTXT_0 GSI register, using an
enumerated type to identify the register's fields, and define an
array of field masks to use for that register's reg structure.

For the CH_C_CNTXT_1 GSI register, ch_c_cntxt_1_length_encode()
previously hid the difference in bit width in the channel ring
length field.  Instead, define a new field CH_R_LENGTH and encode
the ring size with reg_encode().

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ipa/gsi.c
drivers/net/ipa/gsi_reg.h
drivers/net/ipa/reg/gsi_reg-v3.1.c
drivers/net/ipa/reg/gsi_reg-v3.5.1.c
drivers/net/ipa/reg/gsi_reg-v4.0.c
drivers/net/ipa/reg/gsi_reg-v4.5.c
drivers/net/ipa/reg/gsi_reg-v4.9.c

index cbf4b2d843acbb2d4ae2561339f631604b8facb0..ff00c833043a9377a5f65bad87a21d76dfcd9e05 100644 (file)
@@ -164,9 +164,6 @@ static void gsi_validate_build(void)
         */
        BUILD_BUG_ON(!is_power_of_2(GSI_RING_ELEMENT_SIZE));
 
-       /* The channel element size must fit in this field */
-       BUILD_BUG_ON(GSI_RING_ELEMENT_SIZE > field_max(ELEMENT_SIZE_FMASK));
-
        /* The event ring element size must fit in this field */
        BUILD_BUG_ON(GSI_RING_ELEMENT_SIZE > field_max(EV_ELEMENT_SIZE_FMASK));
 }
@@ -185,26 +182,18 @@ static bool gsi_channel_initialized(struct gsi_channel *channel)
 
 /* Encode the channel protocol for the CH_C_CNTXT_0 register */
 static u32 ch_c_cntxt_0_type_encode(enum ipa_version version,
+                                   const struct reg *reg,
                                    enum gsi_channel_type type)
 {
        u32 val;
 
-       val = u32_encode_bits(type, CHTYPE_PROTOCOL_FMASK);
+       val = reg_encode(reg, CHTYPE_PROTOCOL, type);
        if (version < IPA_VERSION_4_5)
                return val;
 
-       type >>= hweight32(CHTYPE_PROTOCOL_FMASK);
-
-       return val | u32_encode_bits(type, CHTYPE_PROTOCOL_MSB_FMASK);
-}
-
-/* Encode a channel ring buffer length for the CH_C_CNTXT_1 register */
-static u32 ch_c_cntxt_1_length_encode(enum ipa_version version, u32 length)
-{
-       if (version < IPA_VERSION_4_9)
-               return u32_encode_bits(length, GENMASK(15, 0));
+       type >>= hweight32(reg_fmask(reg, CHTYPE_PROTOCOL));
 
-       return u32_encode_bits(length, GENMASK(19, 0));
+       return val | reg_encode(reg, CHTYPE_PROTOCOL_MSB, type);
 }
 
 /* Encode the length of the event channel ring buffer for the
@@ -544,7 +533,7 @@ static enum gsi_channel_state gsi_channel_state(struct gsi_channel *channel)
        reg = gsi_reg(gsi, CH_C_CNTXT_0);
        val = ioread32(virt + reg_n_offset(reg, channel_id));
 
-       return u32_get_bits(val, CHSTATE_FMASK);
+       return reg_decode(reg, CHSTATE, val);
 }
 
 /* Issue a channel command and wait for it to complete */
@@ -862,15 +851,15 @@ static void gsi_channel_program(struct gsi_channel *channel, bool doorbell)
        reg = gsi_reg(gsi, CH_C_CNTXT_0);
 
        /* We program all channels as GPI type/protocol */
-       val = ch_c_cntxt_0_type_encode(gsi->version, GSI_CHANNEL_TYPE_GPI);
+       val = ch_c_cntxt_0_type_encode(gsi->version, reg, GSI_CHANNEL_TYPE_GPI);
        if (channel->toward_ipa)
-               val |= CHTYPE_DIR_FMASK;
-       val |= u32_encode_bits(channel->evt_ring_id, ERINDEX_FMASK);
-       val |= u32_encode_bits(GSI_RING_ELEMENT_SIZE, ELEMENT_SIZE_FMASK);
+               val |= reg_bit(reg, CHTYPE_DIR);
+       val |= reg_encode(reg, ERINDEX, channel->evt_ring_id);
+       val |= reg_encode(reg, ELEMENT_SIZE, GSI_RING_ELEMENT_SIZE);
        iowrite32(val, gsi->virt + reg_n_offset(reg, channel_id));
 
        reg = gsi_reg(gsi, CH_C_CNTXT_1);
-       val = ch_c_cntxt_1_length_encode(gsi->version, size);
+       val = reg_encode(reg, CH_R_LENGTH, size);
        iowrite32(val, gsi->virt + reg_n_offset(reg, channel_id));
 
        /* The context 2 and 3 registers store the low-order and
index f625afdfd6d9f7e47a9a0bd66ec58b47acc60179..3f1a49a4f7c47124cc358fb7ed2c77b9e0aafd37 100644 (file)
@@ -96,15 +96,16 @@ enum gsi_reg_id {
 };
 
 /* CH_C_CNTXT_0 register */
-#define CHTYPE_PROTOCOL_FMASK          GENMASK(2, 0)
-#define CHTYPE_DIR_FMASK               GENMASK(3, 3)
-#define EE_FMASK                       GENMASK(7, 4)
-#define CHID_FMASK                     GENMASK(12, 8)
-/* The next field is present for IPA v4.5 and above */
-#define CHTYPE_PROTOCOL_MSB_FMASK      GENMASK(13, 13)
-#define ERINDEX_FMASK                  GENMASK(18, 14)
-#define CHSTATE_FMASK                  GENMASK(23, 20)
-#define ELEMENT_SIZE_FMASK             GENMASK(31, 24)
+enum gsi_reg_ch_c_cntxt_0_field_id {
+       CHTYPE_PROTOCOL,
+       CHTYPE_DIR,
+       CH_EE,
+       CHID,
+       CHTYPE_PROTOCOL_MSB,                            /* IPA v4.9+ */
+       ERINDEX,
+       CHSTATE,
+       ELEMENT_SIZE,
+};
 
 /** enum gsi_channel_type - CHTYPE_PROTOCOL field values in CH_C_CNTXT_0 */
 enum gsi_channel_type {
@@ -120,6 +121,11 @@ enum gsi_channel_type {
        GSI_CHANNEL_TYPE_11AD                   = 0x9,
 };
 
+/* CH_C_CNTXT_1 register */
+enum gsi_reg_ch_c_cntxt_1_field_id {
+       CH_R_LENGTH,
+};
+
 /* CH_C_QOS register */
 enum gsi_reg_ch_c_qos_field_id {
        WRR_WEIGHT,
index 56cf487ae4fc6085e540561236baba8005ce1d35..4aa7a1c52cb353f1356266fe74ef7d23fa8f949f 100644 (file)
@@ -18,9 +18,28 @@ REG(INTER_EE_SRC_EV_CH_IRQ_MSK, inter_ee_src_ev_ch_irq_msk,
 
 /* All other register offsets are relative to gsi->virt */
 
-REG_STRIDE(CH_C_CNTXT_0, ch_c_cntxt_0, 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80);
+static const u32 reg_ch_c_cntxt_0_fmask[] = {
+       [CHTYPE_PROTOCOL]                               = GENMASK(2, 0),
+       [CHTYPE_DIR]                                    = BIT(3),
+       [CH_EE]                                         = GENMASK(7, 4),
+       [CHID]                                          = GENMASK(12, 8),
+                                               /* Bit 13 reserved */
+       [ERINDEX]                                       = GENMASK(18, 14),
+                                               /* Bit 19 reserved */
+       [CHSTATE]                                       = GENMASK(23, 20),
+       [ELEMENT_SIZE]                                  = GENMASK(31, 24),
+};
+
+REG_STRIDE_FIELDS(CH_C_CNTXT_0, ch_c_cntxt_0,
+                 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80);
+
+static const u32 reg_ch_c_cntxt_1_fmask[] = {
+       [CH_R_LENGTH]                                   = GENMASK(15, 0),
+                                               /* Bits 16-31 reserved */
+};
 
-REG_STRIDE(CH_C_CNTXT_1, ch_c_cntxt_1, 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80);
+REG_STRIDE_FIELDS(CH_C_CNTXT_1, ch_c_cntxt_1,
+                 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(CH_C_CNTXT_2, ch_c_cntxt_2, 0x0001c008 + 0x4000 * GSI_EE_AP, 0x80);
 
index 866bae3ff530b9da819547cc98f4782e410e686b..045061a870032add9775bdd29f751030207a51ae 100644 (file)
@@ -18,9 +18,28 @@ REG(INTER_EE_SRC_EV_CH_IRQ_MSK, inter_ee_src_ev_ch_irq_msk,
 
 /* All other register offsets are relative to gsi->virt */
 
-REG_STRIDE(CH_C_CNTXT_0, ch_c_cntxt_0, 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80);
+static const u32 reg_ch_c_cntxt_0_fmask[] = {
+       [CHTYPE_PROTOCOL]                               = GENMASK(2, 0),
+       [CHTYPE_DIR]                                    = BIT(3),
+       [CH_EE]                                         = GENMASK(7, 4),
+       [CHID]                                          = GENMASK(12, 8),
+                                               /* Bit 13 reserved */
+       [ERINDEX]                                       = GENMASK(18, 14),
+                                               /* Bit 19 reserved */
+       [CHSTATE]                                       = GENMASK(23, 20),
+       [ELEMENT_SIZE]                                  = GENMASK(31, 24),
+};
+
+REG_STRIDE_FIELDS(CH_C_CNTXT_0, ch_c_cntxt_0,
+                 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80);
+
+static const u32 reg_ch_c_cntxt_1_fmask[] = {
+       [CH_R_LENGTH]                                   = GENMASK(15, 0),
+                                               /* Bits 16-31 reserved */
+};
 
-REG_STRIDE(CH_C_CNTXT_1, ch_c_cntxt_1, 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80);
+REG_STRIDE_FIELDS(CH_C_CNTXT_1, ch_c_cntxt_1,
+                 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(CH_C_CNTXT_2, ch_c_cntxt_2, 0x0001c008 + 0x4000 * GSI_EE_AP, 0x80);
 
index 060876e4aab41e8940f0443cf7bd8318f212eb75..3374d4e9272d866bebb34b558251bbc61d23e82c 100644 (file)
@@ -18,9 +18,28 @@ REG(INTER_EE_SRC_EV_CH_IRQ_MSK, inter_ee_src_ev_ch_irq_msk,
 
 /* All other register offsets are relative to gsi->virt */
 
-REG_STRIDE(CH_C_CNTXT_0, ch_c_cntxt_0, 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80);
+static const u32 reg_ch_c_cntxt_0_fmask[] = {
+       [CHTYPE_PROTOCOL]                               = GENMASK(2, 0),
+       [CHTYPE_DIR]                                    = BIT(3),
+       [CH_EE]                                         = GENMASK(7, 4),
+       [CHID]                                          = GENMASK(12, 8),
+                                               /* Bit 13 reserved */
+       [ERINDEX]                                       = GENMASK(18, 14),
+                                               /* Bit 19 reserved */
+       [CHSTATE]                                       = GENMASK(23, 20),
+       [ELEMENT_SIZE]                                  = GENMASK(31, 24),
+};
+
+REG_STRIDE_FIELDS(CH_C_CNTXT_0, ch_c_cntxt_0,
+                 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80);
+
+static const u32 reg_ch_c_cntxt_1_fmask[] = {
+       [CH_R_LENGTH]                                   = GENMASK(15, 0),
+                                               /* Bits 16-31 reserved */
+};
 
-REG_STRIDE(CH_C_CNTXT_1, ch_c_cntxt_1, 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80);
+REG_STRIDE_FIELDS(CH_C_CNTXT_1, ch_c_cntxt_1,
+                 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(CH_C_CNTXT_2, ch_c_cntxt_2, 0x0001c008 + 0x4000 * GSI_EE_AP, 0x80);
 
index 98121fd40fd8c116e7f7bfad676aa5621d40fe2b..0502f3e635dab25a8ea7bfe4022029f9477b47e4 100644 (file)
@@ -18,9 +18,28 @@ REG(INTER_EE_SRC_EV_CH_IRQ_MSK, inter_ee_src_ev_ch_irq_msk,
 
 /* All other register offsets are relative to gsi->virt */
 
-REG_STRIDE(CH_C_CNTXT_0, ch_c_cntxt_0, 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80);
+static const u32 reg_ch_c_cntxt_0_fmask[] = {
+       [CHTYPE_PROTOCOL]                               = GENMASK(2, 0),
+       [CHTYPE_DIR]                                    = BIT(3),
+       [CH_EE]                                         = GENMASK(7, 4),
+       [CHID]                                          = GENMASK(12, 8),
+       [CHTYPE_PROTOCOL_MSB]                           = BIT(13),
+       [ERINDEX]                                       = GENMASK(18, 14),
+                                               /* Bit 19 reserved */
+       [CHSTATE]                                       = GENMASK(23, 20),
+       [ELEMENT_SIZE]                                  = GENMASK(31, 24),
+};
+
+REG_STRIDE_FIELDS(CH_C_CNTXT_0, ch_c_cntxt_0,
+                 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80);
+
+static const u32 reg_ch_c_cntxt_1_fmask[] = {
+       [CH_R_LENGTH]                                   = GENMASK(15, 0),
+                                               /* Bits 16-31 reserved */
+};
 
-REG_STRIDE(CH_C_CNTXT_1, ch_c_cntxt_1, 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80);
+REG_STRIDE_FIELDS(CH_C_CNTXT_1, ch_c_cntxt_1,
+                 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(CH_C_CNTXT_2, ch_c_cntxt_2, 0x0001c008 + 0x4000 * GSI_EE_AP, 0x80);
 
index 72ff78863eaaf601db0ca51aedf00ac0be9c6507..2c61633fdb427960e545411c68b4fb0c2418d700 100644 (file)
@@ -18,9 +18,28 @@ REG(INTER_EE_SRC_EV_CH_IRQ_MSK, inter_ee_src_ev_ch_irq_msk,
 
 /* All other register offsets are relative to gsi->virt */
 
-REG_STRIDE(CH_C_CNTXT_0, ch_c_cntxt_0, 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80);
+static const u32 reg_ch_c_cntxt_0_fmask[] = {
+       [CHTYPE_PROTOCOL]                               = GENMASK(2, 0),
+       [CHTYPE_DIR]                                    = BIT(3),
+       [CH_EE]                                         = GENMASK(7, 4),
+       [CHID]                                          = GENMASK(12, 8),
+       [CHTYPE_PROTOCOL_MSB]                           = BIT(13),
+       [ERINDEX]                                       = GENMASK(18, 14),
+                                               /* Bit 19 reserved */
+       [CHSTATE]                                       = GENMASK(23, 20),
+       [ELEMENT_SIZE]                                  = GENMASK(31, 24),
+};
+
+REG_STRIDE_FIELDS(CH_C_CNTXT_0, ch_c_cntxt_0,
+                 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80);
+
+static const u32 reg_ch_c_cntxt_1_fmask[] = {
+       [CH_R_LENGTH]                                   = GENMASK(19, 0),
+                                               /* Bits 20-31 reserved */
+};
 
-REG_STRIDE(CH_C_CNTXT_1, ch_c_cntxt_1, 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80);
+REG_STRIDE_FIELDS(CH_C_CNTXT_1, ch_c_cntxt_1,
+                 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(CH_C_CNTXT_2, ch_c_cntxt_2, 0x0001c008 + 0x4000 * GSI_EE_AP, 0x80);