Skip to content

Commit 366fd59

Browse files
bardliaovinodkoul
authored andcommitted
soundwire: generic_bandwidth_allocation: add lane in sdw_group_params
All active streams with the same parameters are grouped together and the params are stored in the sdw_group struct. We compute the required bandwidth for each group. However, each lane has individual bandwidth. Therefore, we should separate different lanes in different params groups. Add lane variable to separate params groups. Signed-off-by: Bard Liao <[email protected]> Reviewed-by: Ranjani Sridharan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 7a30292 commit 366fd59

File tree

2 files changed

+90
-33
lines changed

2 files changed

+90
-33
lines changed

drivers/soundwire/bus.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ struct sdw_transport_data {
151151
int hstop;
152152
int block_offset;
153153
int sub_block_offset;
154+
unsigned int lane;
154155
};
155156

156157
struct sdw_dpn_prop *sdw_get_slave_dpn_prop(struct sdw_slave *slave,

drivers/soundwire/generic_bandwidth_allocation.c

Lines changed: 89 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
struct sdw_group_params {
2020
unsigned int rate;
21+
unsigned int lane;
2122
int full_bw;
2223
int payload_bw;
2324
int hwidth;
@@ -27,6 +28,7 @@ struct sdw_group {
2728
unsigned int count;
2829
unsigned int max_size;
2930
unsigned int *rates;
31+
unsigned int *lanes;
3032
};
3133

3234
void sdw_compute_slave_ports(struct sdw_master_runtime *m_rt,
@@ -48,6 +50,9 @@ void sdw_compute_slave_ports(struct sdw_master_runtime *m_rt,
4850
slave_total_ch = 0;
4951

5052
list_for_each_entry(p_rt, &s_rt->port_list, port_node) {
53+
if (p_rt->lane != t_data->lane)
54+
continue;
55+
5156
ch = hweight32(p_rt->ch_mask);
5257

5358
sdw_fill_xport_params(&p_rt->transport_params,
@@ -105,6 +110,8 @@ static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
105110
t_data.hstart = hstart;
106111

107112
list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
113+
if (p_rt->lane != params->lane)
114+
continue;
108115

109116
sdw_fill_xport_params(&p_rt->transport_params, p_rt->num,
110117
false, SDW_BLK_GRP_CNT_1, sample_int,
@@ -131,94 +138,130 @@ static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
131138
(*port_bo) += bps * ch;
132139
}
133140

141+
t_data.lane = params->lane;
134142
sdw_compute_slave_ports(m_rt, &t_data);
135143
}
136144

137145
static void _sdw_compute_port_params(struct sdw_bus *bus,
138146
struct sdw_group_params *params, int count)
139147
{
140148
struct sdw_master_runtime *m_rt;
141-
int hstop = bus->params.col - 1;
142-
int port_bo, i;
149+
int port_bo, i, l;
150+
int hstop;
143151

144152
/* Run loop for all groups to compute transport parameters */
145-
for (i = 0; i < count; i++) {
146-
port_bo = 1;
153+
for (l = 0; l < SDW_MAX_LANES; l++) {
154+
if (l > 0 && !bus->lane_used_bandwidth[l])
155+
continue;
156+
/* reset hstop for each lane */
157+
hstop = bus->params.col - 1;
158+
for (i = 0; i < count; i++) {
159+
if (params[i].lane != l)
160+
continue;
161+
port_bo = 1;
147162

148-
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
149-
sdw_compute_master_ports(m_rt, &params[i], &port_bo, hstop);
150-
}
163+
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
164+
sdw_compute_master_ports(m_rt, &params[i], &port_bo, hstop);
165+
}
151166

152-
hstop = hstop - params[i].hwidth;
167+
hstop = hstop - params[i].hwidth;
168+
}
153169
}
154170
}
155171

156172
static int sdw_compute_group_params(struct sdw_bus *bus,
157173
struct sdw_group_params *params,
158-
int *rates, int count)
174+
struct sdw_group *group)
159175
{
160176
struct sdw_master_runtime *m_rt;
177+
struct sdw_port_runtime *p_rt;
161178
int sel_col = bus->params.col;
162179
unsigned int rate, bps, ch;
163-
int i, column_needed = 0;
180+
int i, l, column_needed;
164181

165182
/* Calculate bandwidth per group */
166-
for (i = 0; i < count; i++) {
167-
params[i].rate = rates[i];
183+
for (i = 0; i < group->count; i++) {
184+
params[i].rate = group->rates[i];
185+
params[i].lane = group->lanes[i];
168186
params[i].full_bw = bus->params.curr_dr_freq / params[i].rate;
169187
}
170188

171189
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
172-
rate = m_rt->stream->params.rate;
173-
bps = m_rt->stream->params.bps;
174-
ch = m_rt->ch_count;
190+
list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
191+
rate = m_rt->stream->params.rate;
192+
bps = m_rt->stream->params.bps;
193+
ch = hweight32(p_rt->ch_mask);
175194

176-
for (i = 0; i < count; i++) {
177-
if (rate == params[i].rate)
178-
params[i].payload_bw += bps * ch;
195+
for (i = 0; i < group->count; i++) {
196+
if (rate == params[i].rate && p_rt->lane == params[i].lane)
197+
params[i].payload_bw += bps * ch;
198+
}
179199
}
180200
}
181201

182-
for (i = 0; i < count; i++) {
183-
params[i].hwidth = (sel_col *
184-
params[i].payload_bw + params[i].full_bw - 1) /
185-
params[i].full_bw;
202+
for (l = 0; l < SDW_MAX_LANES; l++) {
203+
if (l > 0 && !bus->lane_used_bandwidth[l])
204+
continue;
205+
/* reset column_needed for each lane */
206+
column_needed = 0;
207+
for (i = 0; i < group->count; i++) {
208+
if (params[i].lane != l)
209+
continue;
186210

187-
column_needed += params[i].hwidth;
211+
params[i].hwidth = (sel_col * params[i].payload_bw +
212+
params[i].full_bw - 1) / params[i].full_bw;
213+
214+
column_needed += params[i].hwidth;
215+
/* There is no control column for lane 1 and above */
216+
if (column_needed > sel_col)
217+
return -EINVAL;
218+
/* Column 0 is control column on lane 0 */
219+
if (params[i].lane == 0 && column_needed > sel_col - 1)
220+
return -EINVAL;
221+
}
188222
}
189223

190-
if (column_needed > sel_col - 1)
191-
return -EINVAL;
192224

193225
return 0;
194226
}
195227

196228
static int sdw_add_element_group_count(struct sdw_group *group,
197-
unsigned int rate)
229+
unsigned int rate, unsigned int lane)
198230
{
199231
int num = group->count;
200232
int i;
201233

202234
for (i = 0; i <= num; i++) {
203-
if (rate == group->rates[i])
235+
if (rate == group->rates[i] && lane == group->lanes[i])
204236
break;
205237

206238
if (i != num)
207239
continue;
208240

209241
if (group->count >= group->max_size) {
210242
unsigned int *rates;
243+
unsigned int *lanes;
211244

212245
group->max_size += 1;
213246
rates = krealloc(group->rates,
214247
(sizeof(int) * group->max_size),
215248
GFP_KERNEL);
216249
if (!rates)
217250
return -ENOMEM;
251+
218252
group->rates = rates;
253+
254+
lanes = krealloc(group->lanes,
255+
(sizeof(int) * group->max_size),
256+
GFP_KERNEL);
257+
if (!lanes)
258+
return -ENOMEM;
259+
260+
group->lanes = lanes;
219261
}
220262

221-
group->rates[group->count++] = rate;
263+
group->rates[group->count] = rate;
264+
group->lanes[group->count++] = lane;
222265
}
223266

224267
return 0;
@@ -228,6 +271,7 @@ static int sdw_get_group_count(struct sdw_bus *bus,
228271
struct sdw_group *group)
229272
{
230273
struct sdw_master_runtime *m_rt;
274+
struct sdw_port_runtime *p_rt;
231275
unsigned int rate;
232276
int ret = 0;
233277

@@ -237,6 +281,13 @@ static int sdw_get_group_count(struct sdw_bus *bus,
237281
if (!group->rates)
238282
return -ENOMEM;
239283

284+
group->lanes = kcalloc(group->max_size, sizeof(int), GFP_KERNEL);
285+
if (!group->lanes) {
286+
kfree(group->rates);
287+
group->rates = NULL;
288+
return -ENOMEM;
289+
}
290+
240291
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
241292
if (m_rt->stream->state == SDW_STREAM_DEPREPARED)
242293
continue;
@@ -246,11 +297,16 @@ static int sdw_get_group_count(struct sdw_bus *bus,
246297
struct sdw_master_runtime,
247298
bus_node)) {
248299
group->rates[group->count++] = rate;
249-
250-
} else {
251-
ret = sdw_add_element_group_count(group, rate);
300+
}
301+
/*
302+
* Different ports could use different lane, add group element
303+
* even if m_rt is the first entry
304+
*/
305+
list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
306+
ret = sdw_add_element_group_count(group, rate, p_rt->lane);
252307
if (ret < 0) {
253308
kfree(group->rates);
309+
kfree(group->lanes);
254310
return ret;
255311
}
256312
}
@@ -284,8 +340,7 @@ static int sdw_compute_port_params(struct sdw_bus *bus)
284340
}
285341

286342
/* Compute transport parameters for grouped streams */
287-
ret = sdw_compute_group_params(bus, params,
288-
&group.rates[0], group.count);
343+
ret = sdw_compute_group_params(bus, params, &group);
289344
if (ret < 0)
290345
goto free_params;
291346

@@ -295,6 +350,7 @@ static int sdw_compute_port_params(struct sdw_bus *bus)
295350
kfree(params);
296351
out:
297352
kfree(group.rates);
353+
kfree(group.lanes);
298354

299355
return ret;
300356
}

0 commit comments

Comments
 (0)