Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0+
  2/* Microchip Sparx5 Switch driver
  3 *
  4 * Copyright (c) 2023 Microchip Technology Inc. and its subsidiaries.
  5 */
  6
  7#include "sparx5_main_regs.h"
  8#include "sparx5_main.h"
  9
 10struct sparx5_sdlb_group sdlb_groups[SPX5_SDLB_GROUP_CNT] = {
 11	{ SPX5_SDLB_GROUP_RATE_MAX,    8192 / 1, 64 }, /*  25 G */
 12	{ 15000000000ULL,              8192 / 1, 64 }, /*  15 G */
 13	{ 10000000000ULL,              8192 / 1, 64 }, /*  10 G */
 14	{  5000000000ULL,              8192 / 1, 64 }, /*   5 G */
 15	{  2500000000ULL,              8192 / 1, 64 }, /* 2.5 G */
 16	{  1000000000ULL,              8192 / 2, 64 }, /*   1 G */
 17	{   500000000ULL,              8192 / 2, 64 }, /* 500 M */
 18	{   100000000ULL,              8192 / 4, 64 }, /* 100 M */
 19	{    50000000ULL,              8192 / 4, 64 }, /*  50 M */
 20	{     5000000ULL,              8192 / 8, 64 }  /*   5 M */
 21};
 22
 23struct sparx5_sdlb_group *sparx5_get_sdlb_group(int idx)
 24{
 25	return &sdlb_groups[idx];
 26}
 27
 28u64 sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5)
 29{
 
 30	u64 clk_hz;
 31
 32	clk_hz = (10 * 1000 * 1000) /
 33		 (sparx5_clk_period(sparx5->coreclock) / 100);
 
 
 34
 
 35	return clk_hz *= 1000;
 36}
 37
 38static int sparx5_sdlb_pup_interval_get(struct sparx5 *sparx5, u32 max_token,
 39					u64 max_rate)
 40{
 41	u64 clk_hz;
 42
 43	clk_hz = sparx5_sdlb_clk_hz_get(sparx5);
 44
 45	return div64_u64((8 * clk_hz * max_token), max_rate);
 46}
 47
 48int sparx5_sdlb_pup_token_get(struct sparx5 *sparx5, u32 pup_interval, u64 rate)
 49{
 50	u64 clk_hz;
 51
 52	if (!rate)
 53		return SPX5_SDLB_PUP_TOKEN_DISABLE;
 54
 55	clk_hz = sparx5_sdlb_clk_hz_get(sparx5);
 56
 57	return DIV64_U64_ROUND_UP((rate * pup_interval), (clk_hz * 8));
 58}
 59
 60static void sparx5_sdlb_group_disable(struct sparx5 *sparx5, u32 group)
 61{
 62	spx5_rmw(ANA_AC_SDLB_PUP_CTRL_PUP_ENA_SET(0),
 63		 ANA_AC_SDLB_PUP_CTRL_PUP_ENA, sparx5,
 64		 ANA_AC_SDLB_PUP_CTRL(group));
 65}
 66
 67static void sparx5_sdlb_group_enable(struct sparx5 *sparx5, u32 group)
 68{
 69	spx5_rmw(ANA_AC_SDLB_PUP_CTRL_PUP_ENA_SET(1),
 70		 ANA_AC_SDLB_PUP_CTRL_PUP_ENA, sparx5,
 71		 ANA_AC_SDLB_PUP_CTRL(group));
 72}
 73
 74static u32 sparx5_sdlb_group_get_first(struct sparx5 *sparx5, u32 group)
 75{
 76	u32 val;
 77
 78	val = spx5_rd(sparx5, ANA_AC_SDLB_XLB_START(group));
 79
 80	return ANA_AC_SDLB_XLB_START_LBSET_START_GET(val);
 81}
 82
 83static u32 sparx5_sdlb_group_get_next(struct sparx5 *sparx5, u32 group,
 84				      u32 lb)
 85{
 86	u32 val;
 87
 88	val = spx5_rd(sparx5, ANA_AC_SDLB_XLB_NEXT(lb));
 89
 90	return ANA_AC_SDLB_XLB_NEXT_LBSET_NEXT_GET(val);
 91}
 92
 93static bool sparx5_sdlb_group_is_first(struct sparx5 *sparx5, u32 group,
 94				       u32 lb)
 95{
 96	return lb == sparx5_sdlb_group_get_first(sparx5, group);
 97}
 98
 99static bool sparx5_sdlb_group_is_last(struct sparx5 *sparx5, u32 group,
100				      u32 lb)
101{
102	return lb == sparx5_sdlb_group_get_next(sparx5, group, lb);
103}
104
105static bool sparx5_sdlb_group_is_empty(struct sparx5 *sparx5, u32 group)
106{
107	u32 val;
108
109	val = spx5_rd(sparx5, ANA_AC_SDLB_PUP_CTRL(group));
110
111	return ANA_AC_SDLB_PUP_CTRL_PUP_ENA_GET(val) == 0;
112}
113
114static u32 sparx5_sdlb_group_get_last(struct sparx5 *sparx5, u32 group)
115{
116	u32 itr, next;
117
118	itr = sparx5_sdlb_group_get_first(sparx5, group);
119
120	for (;;) {
121		next = sparx5_sdlb_group_get_next(sparx5, group, itr);
122		if (itr == next)
123			return itr;
124
125		itr = next;
126	}
127}
128
129static bool sparx5_sdlb_group_is_singular(struct sparx5 *sparx5, u32 group)
130{
131	if (sparx5_sdlb_group_is_empty(sparx5, group))
132		return false;
133
134	return sparx5_sdlb_group_get_first(sparx5, group) ==
135	       sparx5_sdlb_group_get_last(sparx5, group);
136}
137
138static int sparx5_sdlb_group_get_adjacent(struct sparx5 *sparx5, u32 group,
139					  u32 idx, u32 *prev, u32 *next,
140					  u32 *first)
141{
142	u32 itr;
143
144	*first = sparx5_sdlb_group_get_first(sparx5, group);
145	*prev = *first;
146	*next = *first;
147	itr = *first;
148
149	for (;;) {
150		*next = sparx5_sdlb_group_get_next(sparx5, group, itr);
151
152		if (itr == idx)
153			return 0; /* Found it */
154
155		if (itr == *next)
156			return -EINVAL; /* Was not found */
157
158		*prev = itr;
159		itr = *next;
160	}
161}
162
163static int sparx5_sdlb_group_get_count(struct sparx5 *sparx5, u32 group)
164{
165	u32 itr, next;
166	int count = 0;
167
168	itr = sparx5_sdlb_group_get_first(sparx5, group);
169
170	for (;;) {
171		next = sparx5_sdlb_group_get_next(sparx5, group, itr);
172		if (itr == next)
173			return count;
174
175		itr = next;
176		count++;
177	}
178}
179
180int sparx5_sdlb_group_get_by_rate(struct sparx5 *sparx5, u32 rate, u32 burst)
181{
182	const struct sparx5_ops *ops = sparx5->data->ops;
183	const struct sparx5_sdlb_group *group;
184	u64 rate_bps;
185	int i, count;
186
187	rate_bps = rate * 1000;
188
189	for (i = sparx5->data->consts->n_lb_groups - 1; i >= 0; i--) {
190		group = ops->get_sdlb_group(i);
191
192		count = sparx5_sdlb_group_get_count(sparx5, i);
193
194		/* Check that this group is not full.
195		 * According to LB group configuration rules: the number of XLBs
196		 * in a group must not exceed PUP_INTERVAL/4 - 1.
197		 */
198		if (count > ((group->pup_interval / 4) - 1))
199			continue;
200
201		if (rate_bps < group->max_rate)
202			return i;
203	}
204
205	return -ENOSPC;
206}
207
208int sparx5_sdlb_group_get_by_index(struct sparx5 *sparx5, u32 idx, u32 *group)
209{
210	u32 itr, next;
211	int i;
212
213	for (i = 0; i < sparx5->data->consts->n_lb_groups; i++) {
214		if (sparx5_sdlb_group_is_empty(sparx5, i))
215			continue;
216
217		itr = sparx5_sdlb_group_get_first(sparx5, i);
218
219		for (;;) {
220			next = sparx5_sdlb_group_get_next(sparx5, i, itr);
221
222			if (itr == idx) {
223				*group = i;
224				return 0; /* Found it */
225			}
226			if (itr == next)
227				break; /* Was not found */
228
229			itr = next;
230		}
231	}
232
233	return -EINVAL;
234}
235
236static int sparx5_sdlb_group_link(struct sparx5 *sparx5, u32 group, u32 idx,
237				  u32 first, u32 next, bool empty)
238{
239	/* Stop leaking */
240	sparx5_sdlb_group_disable(sparx5, group);
241
242	if (empty)
243		return 0;
244
245	/* Link insertion lb to next lb */
246	spx5_wr(ANA_AC_SDLB_XLB_NEXT_LBSET_NEXT_SET(next) |
247			ANA_AC_SDLB_XLB_NEXT_LBGRP_SET(group),
248		sparx5, ANA_AC_SDLB_XLB_NEXT(idx));
249
250	/* Set the first lb */
251	spx5_wr(ANA_AC_SDLB_XLB_START_LBSET_START_SET(first), sparx5,
252		ANA_AC_SDLB_XLB_START(group));
253
254	/* Start leaking */
255	sparx5_sdlb_group_enable(sparx5, group);
256
257	return 0;
258};
259
260int sparx5_sdlb_group_add(struct sparx5 *sparx5, u32 group, u32 idx)
261{
262	u32 first, next;
263
264	/* We always add to head of the list */
265	first = idx;
266
267	if (sparx5_sdlb_group_is_empty(sparx5, group))
268		next = idx;
269	else
270		next = sparx5_sdlb_group_get_first(sparx5, group);
271
272	return sparx5_sdlb_group_link(sparx5, group, idx, first, next, false);
273}
274
275int sparx5_sdlb_group_del(struct sparx5 *sparx5, u32 group, u32 idx)
276{
277	u32 first, next, prev;
278	bool empty = false;
279
280	if (sparx5_sdlb_group_get_adjacent(sparx5, group, idx, &prev, &next,
281					   &first) < 0) {
282		pr_err("%s:%d Could not find idx: %d in group: %d", __func__,
283		       __LINE__, idx, group);
284		return -EINVAL;
285	}
286
287	if (sparx5_sdlb_group_is_singular(sparx5, group)) {
288		empty = true;
289	} else if (sparx5_sdlb_group_is_last(sparx5, group, idx)) {
290		/* idx is removed, prev is now last */
291		idx = prev;
292		next = prev;
293	} else if (sparx5_sdlb_group_is_first(sparx5, group, idx)) {
294		/* idx is removed and points to itself, first is next */
295		first = next;
296		next = idx;
297	} else {
298		/* Next is not touched */
299		idx = prev;
300	}
301
302	return sparx5_sdlb_group_link(sparx5, group, idx, first, next, empty);
303}
304
305void sparx5_sdlb_group_init(struct sparx5 *sparx5, u64 max_rate, u32 min_burst,
306			    u32 frame_size, u32 idx)
307{
308	const struct sparx5_ops *ops = sparx5->data->ops;
309	u32 thres_shift, mask = 0x01, power = 0;
310	struct sparx5_sdlb_group *group;
311	u64 max_token;
312
313	group = ops->get_sdlb_group(idx);
314
315	/* Number of positions to right-shift LB's threshold value. */
316	while ((min_burst & mask) == 0) {
317		power++;
318		mask <<= 1;
319	}
320	thres_shift = SPX5_SDLB_2CYCLES_TYPE2_THRES_OFFSET - power;
321
322	max_token = (min_burst > SPX5_SDLB_PUP_TOKEN_MAX) ?
323			    SPX5_SDLB_PUP_TOKEN_MAX :
324			    min_burst;
325	group->pup_interval =
326		sparx5_sdlb_pup_interval_get(sparx5, max_token, max_rate);
327
328	group->frame_size = frame_size;
329
330	spx5_wr(ANA_AC_SDLB_PUP_INTERVAL_PUP_INTERVAL_SET(group->pup_interval),
331		sparx5, ANA_AC_SDLB_PUP_INTERVAL(idx));
332
333	spx5_wr(ANA_AC_SDLB_FRM_RATE_TOKENS_FRM_RATE_TOKENS_SET(frame_size),
334		sparx5, ANA_AC_SDLB_FRM_RATE_TOKENS(idx));
335
336	spx5_wr(ANA_AC_SDLB_LBGRP_MISC_THRES_SHIFT_SET(thres_shift), sparx5,
337		ANA_AC_SDLB_LBGRP_MISC(idx));
338}
v6.8
  1// SPDX-License-Identifier: GPL-2.0+
  2/* Microchip Sparx5 Switch driver
  3 *
  4 * Copyright (c) 2023 Microchip Technology Inc. and its subsidiaries.
  5 */
  6
  7#include "sparx5_main_regs.h"
  8#include "sparx5_main.h"
  9
 10struct sparx5_sdlb_group sdlb_groups[SPX5_SDLB_GROUP_CNT] = {
 11	{ SPX5_SDLB_GROUP_RATE_MAX,    8192 / 1, 64 }, /*  25 G */
 12	{ 15000000000ULL,              8192 / 1, 64 }, /*  15 G */
 13	{ 10000000000ULL,              8192 / 1, 64 }, /*  10 G */
 14	{  5000000000ULL,              8192 / 1, 64 }, /*   5 G */
 15	{  2500000000ULL,              8192 / 1, 64 }, /* 2.5 G */
 16	{  1000000000ULL,              8192 / 2, 64 }, /*   1 G */
 17	{   500000000ULL,              8192 / 2, 64 }, /* 500 M */
 18	{   100000000ULL,              8192 / 4, 64 }, /* 100 M */
 19	{    50000000ULL,              8192 / 4, 64 }, /*  50 M */
 20	{     5000000ULL,              8192 / 8, 64 }  /*   5 M */
 21};
 22
 23int sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5)
 
 
 
 
 
 24{
 25	u32 clk_per_100ps;
 26	u64 clk_hz;
 27
 28	clk_per_100ps = HSCH_SYS_CLK_PER_100PS_GET(spx5_rd(sparx5,
 29							   HSCH_SYS_CLK_PER));
 30	if (!clk_per_100ps)
 31		clk_per_100ps = SPX5_CLK_PER_100PS_DEFAULT;
 32
 33	clk_hz = (10 * 1000 * 1000) / clk_per_100ps;
 34	return clk_hz *= 1000;
 35}
 36
 37static int sparx5_sdlb_pup_interval_get(struct sparx5 *sparx5, u32 max_token,
 38					u64 max_rate)
 39{
 40	u64 clk_hz;
 41
 42	clk_hz = sparx5_sdlb_clk_hz_get(sparx5);
 43
 44	return div64_u64((8 * clk_hz * max_token), max_rate);
 45}
 46
 47int sparx5_sdlb_pup_token_get(struct sparx5 *sparx5, u32 pup_interval, u64 rate)
 48{
 49	u64 clk_hz;
 50
 51	if (!rate)
 52		return SPX5_SDLB_PUP_TOKEN_DISABLE;
 53
 54	clk_hz = sparx5_sdlb_clk_hz_get(sparx5);
 55
 56	return DIV64_U64_ROUND_UP((rate * pup_interval), (clk_hz * 8));
 57}
 58
 59static void sparx5_sdlb_group_disable(struct sparx5 *sparx5, u32 group)
 60{
 61	spx5_rmw(ANA_AC_SDLB_PUP_CTRL_PUP_ENA_SET(0),
 62		 ANA_AC_SDLB_PUP_CTRL_PUP_ENA, sparx5,
 63		 ANA_AC_SDLB_PUP_CTRL(group));
 64}
 65
 66static void sparx5_sdlb_group_enable(struct sparx5 *sparx5, u32 group)
 67{
 68	spx5_rmw(ANA_AC_SDLB_PUP_CTRL_PUP_ENA_SET(1),
 69		 ANA_AC_SDLB_PUP_CTRL_PUP_ENA, sparx5,
 70		 ANA_AC_SDLB_PUP_CTRL(group));
 71}
 72
 73static u32 sparx5_sdlb_group_get_first(struct sparx5 *sparx5, u32 group)
 74{
 75	u32 val;
 76
 77	val = spx5_rd(sparx5, ANA_AC_SDLB_XLB_START(group));
 78
 79	return ANA_AC_SDLB_XLB_START_LBSET_START_GET(val);
 80}
 81
 82static u32 sparx5_sdlb_group_get_next(struct sparx5 *sparx5, u32 group,
 83				      u32 lb)
 84{
 85	u32 val;
 86
 87	val = spx5_rd(sparx5, ANA_AC_SDLB_XLB_NEXT(lb));
 88
 89	return ANA_AC_SDLB_XLB_NEXT_LBSET_NEXT_GET(val);
 90}
 91
 92static bool sparx5_sdlb_group_is_first(struct sparx5 *sparx5, u32 group,
 93				       u32 lb)
 94{
 95	return lb == sparx5_sdlb_group_get_first(sparx5, group);
 96}
 97
 98static bool sparx5_sdlb_group_is_last(struct sparx5 *sparx5, u32 group,
 99				      u32 lb)
100{
101	return lb == sparx5_sdlb_group_get_next(sparx5, group, lb);
102}
103
104static bool sparx5_sdlb_group_is_empty(struct sparx5 *sparx5, u32 group)
105{
106	u32 val;
107
108	val = spx5_rd(sparx5, ANA_AC_SDLB_PUP_CTRL(group));
109
110	return ANA_AC_SDLB_PUP_CTRL_PUP_ENA_GET(val) == 0;
111}
112
113static u32 sparx5_sdlb_group_get_last(struct sparx5 *sparx5, u32 group)
114{
115	u32 itr, next;
116
117	itr = sparx5_sdlb_group_get_first(sparx5, group);
118
119	for (;;) {
120		next = sparx5_sdlb_group_get_next(sparx5, group, itr);
121		if (itr == next)
122			return itr;
123
124		itr = next;
125	}
126}
127
128static bool sparx5_sdlb_group_is_singular(struct sparx5 *sparx5, u32 group)
129{
130	if (sparx5_sdlb_group_is_empty(sparx5, group))
131		return false;
132
133	return sparx5_sdlb_group_get_first(sparx5, group) ==
134	       sparx5_sdlb_group_get_last(sparx5, group);
135}
136
137static int sparx5_sdlb_group_get_adjacent(struct sparx5 *sparx5, u32 group,
138					  u32 idx, u32 *prev, u32 *next,
139					  u32 *first)
140{
141	u32 itr;
142
143	*first = sparx5_sdlb_group_get_first(sparx5, group);
144	*prev = *first;
145	*next = *first;
146	itr = *first;
147
148	for (;;) {
149		*next = sparx5_sdlb_group_get_next(sparx5, group, itr);
150
151		if (itr == idx)
152			return 0; /* Found it */
153
154		if (itr == *next)
155			return -EINVAL; /* Was not found */
156
157		*prev = itr;
158		itr = *next;
159	}
160}
161
162static int sparx5_sdlb_group_get_count(struct sparx5 *sparx5, u32 group)
163{
164	u32 itr, next;
165	int count = 0;
166
167	itr = sparx5_sdlb_group_get_first(sparx5, group);
168
169	for (;;) {
170		next = sparx5_sdlb_group_get_next(sparx5, group, itr);
171		if (itr == next)
172			return count;
173
174		itr = next;
175		count++;
176	}
177}
178
179int sparx5_sdlb_group_get_by_rate(struct sparx5 *sparx5, u32 rate, u32 burst)
180{
 
181	const struct sparx5_sdlb_group *group;
182	u64 rate_bps;
183	int i, count;
184
185	rate_bps = rate * 1000;
186
187	for (i = SPX5_SDLB_GROUP_CNT - 1; i >= 0; i--) {
188		group = &sdlb_groups[i];
189
190		count = sparx5_sdlb_group_get_count(sparx5, i);
191
192		/* Check that this group is not full.
193		 * According to LB group configuration rules: the number of XLBs
194		 * in a group must not exceed PUP_INTERVAL/4 - 1.
195		 */
196		if (count > ((group->pup_interval / 4) - 1))
197			continue;
198
199		if (rate_bps < group->max_rate)
200			return i;
201	}
202
203	return -ENOSPC;
204}
205
206int sparx5_sdlb_group_get_by_index(struct sparx5 *sparx5, u32 idx, u32 *group)
207{
208	u32 itr, next;
209	int i;
210
211	for (i = 0; i < SPX5_SDLB_GROUP_CNT; i++) {
212		if (sparx5_sdlb_group_is_empty(sparx5, i))
213			continue;
214
215		itr = sparx5_sdlb_group_get_first(sparx5, i);
216
217		for (;;) {
218			next = sparx5_sdlb_group_get_next(sparx5, i, itr);
219
220			if (itr == idx) {
221				*group = i;
222				return 0; /* Found it */
223			}
224			if (itr == next)
225				break; /* Was not found */
226
227			itr = next;
228		}
229	}
230
231	return -EINVAL;
232}
233
234static int sparx5_sdlb_group_link(struct sparx5 *sparx5, u32 group, u32 idx,
235				  u32 first, u32 next, bool empty)
236{
237	/* Stop leaking */
238	sparx5_sdlb_group_disable(sparx5, group);
239
240	if (empty)
241		return 0;
242
243	/* Link insertion lb to next lb */
244	spx5_wr(ANA_AC_SDLB_XLB_NEXT_LBSET_NEXT_SET(next) |
245			ANA_AC_SDLB_XLB_NEXT_LBGRP_SET(group),
246		sparx5, ANA_AC_SDLB_XLB_NEXT(idx));
247
248	/* Set the first lb */
249	spx5_wr(ANA_AC_SDLB_XLB_START_LBSET_START_SET(first), sparx5,
250		ANA_AC_SDLB_XLB_START(group));
251
252	/* Start leaking */
253	sparx5_sdlb_group_enable(sparx5, group);
254
255	return 0;
256};
257
258int sparx5_sdlb_group_add(struct sparx5 *sparx5, u32 group, u32 idx)
259{
260	u32 first, next;
261
262	/* We always add to head of the list */
263	first = idx;
264
265	if (sparx5_sdlb_group_is_empty(sparx5, group))
266		next = idx;
267	else
268		next = sparx5_sdlb_group_get_first(sparx5, group);
269
270	return sparx5_sdlb_group_link(sparx5, group, idx, first, next, false);
271}
272
273int sparx5_sdlb_group_del(struct sparx5 *sparx5, u32 group, u32 idx)
274{
275	u32 first, next, prev;
276	bool empty = false;
277
278	if (sparx5_sdlb_group_get_adjacent(sparx5, group, idx, &prev, &next,
279					   &first) < 0) {
280		pr_err("%s:%d Could not find idx: %d in group: %d", __func__,
281		       __LINE__, idx, group);
282		return -EINVAL;
283	}
284
285	if (sparx5_sdlb_group_is_singular(sparx5, group)) {
286		empty = true;
287	} else if (sparx5_sdlb_group_is_last(sparx5, group, idx)) {
288		/* idx is removed, prev is now last */
289		idx = prev;
290		next = prev;
291	} else if (sparx5_sdlb_group_is_first(sparx5, group, idx)) {
292		/* idx is removed and points to itself, first is next */
293		first = next;
294		next = idx;
295	} else {
296		/* Next is not touched */
297		idx = prev;
298	}
299
300	return sparx5_sdlb_group_link(sparx5, group, idx, first, next, empty);
301}
302
303void sparx5_sdlb_group_init(struct sparx5 *sparx5, u64 max_rate, u32 min_burst,
304			    u32 frame_size, u32 idx)
305{
 
306	u32 thres_shift, mask = 0x01, power = 0;
307	struct sparx5_sdlb_group *group;
308	u64 max_token;
309
310	group = &sdlb_groups[idx];
311
312	/* Number of positions to right-shift LB's threshold value. */
313	while ((min_burst & mask) == 0) {
314		power++;
315		mask <<= 1;
316	}
317	thres_shift = SPX5_SDLB_2CYCLES_TYPE2_THRES_OFFSET - power;
318
319	max_token = (min_burst > SPX5_SDLB_PUP_TOKEN_MAX) ?
320			    SPX5_SDLB_PUP_TOKEN_MAX :
321			    min_burst;
322	group->pup_interval =
323		sparx5_sdlb_pup_interval_get(sparx5, max_token, max_rate);
324
325	group->frame_size = frame_size;
326
327	spx5_wr(ANA_AC_SDLB_PUP_INTERVAL_PUP_INTERVAL_SET(group->pup_interval),
328		sparx5, ANA_AC_SDLB_PUP_INTERVAL(idx));
329
330	spx5_wr(ANA_AC_SDLB_FRM_RATE_TOKENS_FRM_RATE_TOKENS_SET(frame_size),
331		sparx5, ANA_AC_SDLB_FRM_RATE_TOKENS(idx));
332
333	spx5_wr(ANA_AC_SDLB_LBGRP_MISC_THRES_SHIFT_SET(thres_shift), sparx5,
334		ANA_AC_SDLB_LBGRP_MISC(idx));
335}