Lines Matching +full:sparx5 +full:- +full:switch
1 // SPDX-License-Identifier: GPL-2.0+
2 /* Microchip Sparx5 Switch driver
28 u64 sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5) in sparx5_sdlb_clk_hz_get() argument
33 (sparx5_clk_period(sparx5->coreclock) / 100); in sparx5_sdlb_clk_hz_get()
38 static int sparx5_sdlb_pup_interval_get(struct sparx5 *sparx5, u32 max_token, in sparx5_sdlb_pup_interval_get() argument
43 clk_hz = sparx5_sdlb_clk_hz_get(sparx5); in sparx5_sdlb_pup_interval_get()
48 int sparx5_sdlb_pup_token_get(struct sparx5 *sparx5, u32 pup_interval, u64 rate) in sparx5_sdlb_pup_token_get() argument
55 clk_hz = sparx5_sdlb_clk_hz_get(sparx5); in sparx5_sdlb_pup_token_get()
60 static void sparx5_sdlb_group_disable(struct sparx5 *sparx5, u32 group) in sparx5_sdlb_group_disable() argument
63 ANA_AC_SDLB_PUP_CTRL_PUP_ENA, sparx5, in sparx5_sdlb_group_disable()
67 static void sparx5_sdlb_group_enable(struct sparx5 *sparx5, u32 group) in sparx5_sdlb_group_enable() argument
70 ANA_AC_SDLB_PUP_CTRL_PUP_ENA, sparx5, in sparx5_sdlb_group_enable()
74 static u32 sparx5_sdlb_group_get_first(struct sparx5 *sparx5, u32 group) in sparx5_sdlb_group_get_first() argument
78 val = spx5_rd(sparx5, ANA_AC_SDLB_XLB_START(group)); in sparx5_sdlb_group_get_first()
83 static u32 sparx5_sdlb_group_get_next(struct sparx5 *sparx5, u32 group, in sparx5_sdlb_group_get_next() argument
88 val = spx5_rd(sparx5, ANA_AC_SDLB_XLB_NEXT(lb)); in sparx5_sdlb_group_get_next()
93 static bool sparx5_sdlb_group_is_first(struct sparx5 *sparx5, u32 group, in sparx5_sdlb_group_is_first() argument
96 return lb == sparx5_sdlb_group_get_first(sparx5, group); in sparx5_sdlb_group_is_first()
99 static bool sparx5_sdlb_group_is_last(struct sparx5 *sparx5, u32 group, in sparx5_sdlb_group_is_last() argument
102 return lb == sparx5_sdlb_group_get_next(sparx5, group, lb); in sparx5_sdlb_group_is_last()
105 static bool sparx5_sdlb_group_is_empty(struct sparx5 *sparx5, u32 group) in sparx5_sdlb_group_is_empty() argument
109 val = spx5_rd(sparx5, ANA_AC_SDLB_PUP_CTRL(group)); in sparx5_sdlb_group_is_empty()
114 static u32 sparx5_sdlb_group_get_last(struct sparx5 *sparx5, u32 group) in sparx5_sdlb_group_get_last() argument
118 itr = sparx5_sdlb_group_get_first(sparx5, group); in sparx5_sdlb_group_get_last()
121 next = sparx5_sdlb_group_get_next(sparx5, group, itr); in sparx5_sdlb_group_get_last()
129 static bool sparx5_sdlb_group_is_singular(struct sparx5 *sparx5, u32 group) in sparx5_sdlb_group_is_singular() argument
131 if (sparx5_sdlb_group_is_empty(sparx5, group)) in sparx5_sdlb_group_is_singular()
134 return sparx5_sdlb_group_get_first(sparx5, group) == in sparx5_sdlb_group_is_singular()
135 sparx5_sdlb_group_get_last(sparx5, group); in sparx5_sdlb_group_is_singular()
138 static int sparx5_sdlb_group_get_adjacent(struct sparx5 *sparx5, u32 group, in sparx5_sdlb_group_get_adjacent() argument
144 *first = sparx5_sdlb_group_get_first(sparx5, group); in sparx5_sdlb_group_get_adjacent()
150 *next = sparx5_sdlb_group_get_next(sparx5, group, itr); in sparx5_sdlb_group_get_adjacent()
156 return -EINVAL; /* Was not found */ in sparx5_sdlb_group_get_adjacent()
163 static int sparx5_sdlb_group_get_count(struct sparx5 *sparx5, u32 group) in sparx5_sdlb_group_get_count() argument
168 itr = sparx5_sdlb_group_get_first(sparx5, group); in sparx5_sdlb_group_get_count()
171 next = sparx5_sdlb_group_get_next(sparx5, group, itr); in sparx5_sdlb_group_get_count()
180 int sparx5_sdlb_group_get_by_rate(struct sparx5 *sparx5, u32 rate, u32 burst) in sparx5_sdlb_group_get_by_rate() argument
182 const struct sparx5_ops *ops = sparx5->data->ops; in sparx5_sdlb_group_get_by_rate()
189 for (i = sparx5->data->consts->n_lb_groups - 1; i >= 0; i--) { in sparx5_sdlb_group_get_by_rate()
190 group = ops->get_sdlb_group(i); in sparx5_sdlb_group_get_by_rate()
192 count = sparx5_sdlb_group_get_count(sparx5, i); in sparx5_sdlb_group_get_by_rate()
196 * in a group must not exceed PUP_INTERVAL/4 - 1. in sparx5_sdlb_group_get_by_rate()
198 if (count > ((group->pup_interval / 4) - 1)) in sparx5_sdlb_group_get_by_rate()
201 if (rate_bps < group->max_rate) in sparx5_sdlb_group_get_by_rate()
205 return -ENOSPC; in sparx5_sdlb_group_get_by_rate()
208 int sparx5_sdlb_group_get_by_index(struct sparx5 *sparx5, u32 idx, u32 *group) in sparx5_sdlb_group_get_by_index() argument
213 for (i = 0; i < sparx5->data->consts->n_lb_groups; i++) { in sparx5_sdlb_group_get_by_index()
214 if (sparx5_sdlb_group_is_empty(sparx5, i)) in sparx5_sdlb_group_get_by_index()
217 itr = sparx5_sdlb_group_get_first(sparx5, i); in sparx5_sdlb_group_get_by_index()
220 next = sparx5_sdlb_group_get_next(sparx5, i, itr); in sparx5_sdlb_group_get_by_index()
233 return -EINVAL; in sparx5_sdlb_group_get_by_index()
236 static int sparx5_sdlb_group_link(struct sparx5 *sparx5, u32 group, u32 idx, in sparx5_sdlb_group_link() argument
240 sparx5_sdlb_group_disable(sparx5, group); in sparx5_sdlb_group_link()
248 sparx5, ANA_AC_SDLB_XLB_NEXT(idx)); in sparx5_sdlb_group_link()
251 spx5_wr(ANA_AC_SDLB_XLB_START_LBSET_START_SET(first), sparx5, in sparx5_sdlb_group_link()
255 sparx5_sdlb_group_enable(sparx5, group); in sparx5_sdlb_group_link()
260 int sparx5_sdlb_group_add(struct sparx5 *sparx5, u32 group, u32 idx) in sparx5_sdlb_group_add() argument
267 if (sparx5_sdlb_group_is_empty(sparx5, group)) in sparx5_sdlb_group_add()
270 next = sparx5_sdlb_group_get_first(sparx5, group); in sparx5_sdlb_group_add()
272 return sparx5_sdlb_group_link(sparx5, group, idx, first, next, false); in sparx5_sdlb_group_add()
275 int sparx5_sdlb_group_del(struct sparx5 *sparx5, u32 group, u32 idx) in sparx5_sdlb_group_del() argument
280 if (sparx5_sdlb_group_get_adjacent(sparx5, group, idx, &prev, &next, in sparx5_sdlb_group_del()
284 return -EINVAL; in sparx5_sdlb_group_del()
287 if (sparx5_sdlb_group_is_singular(sparx5, group)) { in sparx5_sdlb_group_del()
289 } else if (sparx5_sdlb_group_is_last(sparx5, group, idx)) { in sparx5_sdlb_group_del()
293 } else if (sparx5_sdlb_group_is_first(sparx5, group, idx)) { in sparx5_sdlb_group_del()
302 return sparx5_sdlb_group_link(sparx5, group, idx, first, next, empty); in sparx5_sdlb_group_del()
305 void sparx5_sdlb_group_init(struct sparx5 *sparx5, u64 max_rate, u32 min_burst, in sparx5_sdlb_group_init() argument
308 const struct sparx5_ops *ops = sparx5->data->ops; in sparx5_sdlb_group_init()
313 group = ops->get_sdlb_group(idx); in sparx5_sdlb_group_init()
315 /* Number of positions to right-shift LB's threshold value. */ in sparx5_sdlb_group_init()
320 thres_shift = SPX5_SDLB_2CYCLES_TYPE2_THRES_OFFSET - power; in sparx5_sdlb_group_init()
325 group->pup_interval = in sparx5_sdlb_group_init()
326 sparx5_sdlb_pup_interval_get(sparx5, max_token, max_rate); in sparx5_sdlb_group_init()
328 group->frame_size = frame_size; in sparx5_sdlb_group_init()
330 spx5_wr(ANA_AC_SDLB_PUP_INTERVAL_PUP_INTERVAL_SET(group->pup_interval), in sparx5_sdlb_group_init()
331 sparx5, ANA_AC_SDLB_PUP_INTERVAL(idx)); in sparx5_sdlb_group_init()
334 sparx5, ANA_AC_SDLB_FRM_RATE_TOKENS(idx)); in sparx5_sdlb_group_init()
336 spx5_wr(ANA_AC_SDLB_LBGRP_MISC_THRES_SHIFT_SET(thres_shift), sparx5, in sparx5_sdlb_group_init()