Skip to content

Commit f240eba

Browse files
bardliaoranj063
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 <yung-chuan.liao@linux.intel.com>
1 parent 315a806 commit f240eba

2 files changed

Lines changed: 90 additions & 33 deletions

File tree

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
dev_dbg(&s_rt->slave->dev, "%s p_rt->lane %d\n", __func__, p_rt->lane);
@@ -106,6 +111,8 @@ static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
106111
t_data.hstart = hstart;
107112

108113
list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
114+
if (p_rt->lane != params->lane)
115+
continue;
109116

110117
dev_dbg(bus->dev, "%s p_rt->lane %d\n", __func__, p_rt->lane);
111118
sdw_fill_xport_params(&p_rt->transport_params, p_rt->num,
@@ -133,94 +140,130 @@ static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
133140
(*port_bo) += bps * ch;
134141
}
135142

143+
t_data.lane = params->lane;
136144
sdw_compute_slave_ports(m_rt, &t_data);
137145
}
138146

139147
static void _sdw_compute_port_params(struct sdw_bus *bus,
140148
struct sdw_group_params *params, int count)
141149
{
142150
struct sdw_master_runtime *m_rt;
143-
int hstop = bus->params.col - 1;
144-
int port_bo, i;
151+
int port_bo, i, l;
152+
int hstop;
145153

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

150-
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
151-
sdw_compute_master_ports(m_rt, &params[i], &port_bo, hstop);
152-
}
165+
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
166+
sdw_compute_master_ports(m_rt, &params[i], &port_bo, hstop);
167+
}
153168

154-
hstop = hstop - params[i].hwidth;
169+
hstop = hstop - params[i].hwidth;
170+
}
155171
}
156172
}
157173

158174
static int sdw_compute_group_params(struct sdw_bus *bus,
159175
struct sdw_group_params *params,
160-
int *rates, int count)
176+
struct sdw_group *group)
161177
{
162178
struct sdw_master_runtime *m_rt;
179+
struct sdw_port_runtime *p_rt;
163180
int sel_col = bus->params.col;
164181
unsigned int rate, bps, ch;
165-
int i, column_needed = 0;
182+
int i, l, column_needed;
166183

167184
/* Calculate bandwidth per group */
168-
for (i = 0; i < count; i++) {
169-
params[i].rate = rates[i];
185+
for (i = 0; i < group->count; i++) {
186+
params[i].rate = group->rates[i];
187+
params[i].lane = group->lanes[i];
170188
params[i].full_bw = bus->params.curr_dr_freq / params[i].rate;
171189
}
172190

173191
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
174-
rate = m_rt->stream->params.rate;
175-
bps = m_rt->stream->params.bps;
176-
ch = m_rt->ch_count;
192+
list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
193+
rate = m_rt->stream->params.rate;
194+
bps = m_rt->stream->params.bps;
195+
ch = hweight32(p_rt->ch_mask);
177196

178-
for (i = 0; i < count; i++) {
179-
if (rate == params[i].rate)
180-
params[i].payload_bw += bps * ch;
197+
for (i = 0; i < group->count; i++) {
198+
if (rate == params[i].rate && p_rt->lane == params[i].lane)
199+
params[i].payload_bw += bps * ch;
200+
}
181201
}
182202
}
183203

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

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

192-
if (column_needed > sel_col - 1)
193-
return -EINVAL;
194226

195227
return 0;
196228
}
197229

198230
static int sdw_add_element_group_count(struct sdw_group *group,
199-
unsigned int rate)
231+
unsigned int rate, unsigned int lane)
200232
{
201233
int num = group->count;
202234
int i;
203235

204236
for (i = 0; i <= num; i++) {
205-
if (rate == group->rates[i])
237+
if (rate == group->rates[i] && lane == group->lanes[i])
206238
break;
207239

208240
if (i != num)
209241
continue;
210242

211243
if (group->count >= group->max_size) {
212244
unsigned int *rates;
245+
unsigned int *lanes;
213246

214247
group->max_size += 1;
215248
rates = krealloc(group->rates,
216249
(sizeof(int) * group->max_size),
217250
GFP_KERNEL);
218251
if (!rates)
219252
return -ENOMEM;
253+
220254
group->rates = rates;
255+
256+
lanes = krealloc(group->lanes,
257+
(sizeof(int) * group->max_size),
258+
GFP_KERNEL);
259+
if (!lanes)
260+
return -ENOMEM;
261+
262+
group->lanes = lanes;
221263
}
222264

223-
group->rates[group->count++] = rate;
265+
group->rates[group->count] = rate;
266+
group->lanes[group->count++] = lane;
224267
}
225268

226269
return 0;
@@ -230,6 +273,7 @@ static int sdw_get_group_count(struct sdw_bus *bus,
230273
struct sdw_group *group)
231274
{
232275
struct sdw_master_runtime *m_rt;
276+
struct sdw_port_runtime *p_rt;
233277
unsigned int rate;
234278
int ret = 0;
235279

@@ -239,6 +283,13 @@ static int sdw_get_group_count(struct sdw_bus *bus,
239283
if (!group->rates)
240284
return -ENOMEM;
241285

286+
group->lanes = kcalloc(group->max_size, sizeof(int), GFP_KERNEL);
287+
if (!group->lanes) {
288+
kfree(group->rates);
289+
group->rates = NULL;
290+
return -ENOMEM;
291+
}
292+
242293
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
243294
if (m_rt->stream->state == SDW_STREAM_DEPREPARED)
244295
continue;
@@ -248,11 +299,16 @@ static int sdw_get_group_count(struct sdw_bus *bus,
248299
struct sdw_master_runtime,
249300
bus_node)) {
250301
group->rates[group->count++] = rate;
251-
252-
} else {
253-
ret = sdw_add_element_group_count(group, rate);
302+
}
303+
/*
304+
* Different ports could use different lane, add group element
305+
* even if m_rt is the first entry
306+
*/
307+
list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
308+
ret = sdw_add_element_group_count(group, rate, p_rt->lane);
254309
if (ret < 0) {
255310
kfree(group->rates);
311+
kfree(group->lanes);
256312
return ret;
257313
}
258314
}
@@ -286,8 +342,7 @@ static int sdw_compute_port_params(struct sdw_bus *bus)
286342
}
287343

288344
/* Compute transport parameters for grouped streams */
289-
ret = sdw_compute_group_params(bus, params,
290-
&group.rates[0], group.count);
345+
ret = sdw_compute_group_params(bus, params, &group);
291346
if (ret < 0)
292347
goto free_params;
293348

@@ -297,6 +352,7 @@ static int sdw_compute_port_params(struct sdw_bus *bus)
297352
kfree(params);
298353
out:
299354
kfree(group.rates);
355+
kfree(group.lanes);
300356

301357
return ret;
302358
}

0 commit comments

Comments
 (0)