18
18
19
19
struct sdw_group_params {
20
20
unsigned int rate ;
21
+ unsigned int lane ;
21
22
int full_bw ;
22
23
int payload_bw ;
23
24
int hwidth ;
@@ -27,6 +28,7 @@ struct sdw_group {
27
28
unsigned int count ;
28
29
unsigned int max_size ;
29
30
unsigned int * rates ;
31
+ unsigned int * lanes ;
30
32
};
31
33
32
34
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,
48
50
slave_total_ch = 0 ;
49
51
50
52
list_for_each_entry (p_rt , & s_rt -> port_list , port_node ) {
53
+ if (p_rt -> lane != t_data -> lane )
54
+ continue ;
55
+
51
56
ch = hweight32 (p_rt -> ch_mask );
52
57
53
58
sdw_fill_xport_params (& p_rt -> transport_params ,
@@ -105,6 +110,8 @@ static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
105
110
t_data .hstart = hstart ;
106
111
107
112
list_for_each_entry (p_rt , & m_rt -> port_list , port_node ) {
113
+ if (p_rt -> lane != params -> lane )
114
+ continue ;
108
115
109
116
sdw_fill_xport_params (& p_rt -> transport_params , p_rt -> num ,
110
117
false, SDW_BLK_GRP_CNT_1 , sample_int ,
@@ -131,94 +138,130 @@ static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
131
138
(* port_bo ) += bps * ch ;
132
139
}
133
140
141
+ t_data .lane = params -> lane ;
134
142
sdw_compute_slave_ports (m_rt , & t_data );
135
143
}
136
144
137
145
static void _sdw_compute_port_params (struct sdw_bus * bus ,
138
146
struct sdw_group_params * params , int count )
139
147
{
140
148
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 ;
143
151
144
152
/* 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 ;
147
162
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
+ }
151
166
152
- hstop = hstop - params [i ].hwidth ;
167
+ hstop = hstop - params [i ].hwidth ;
168
+ }
153
169
}
154
170
}
155
171
156
172
static int sdw_compute_group_params (struct sdw_bus * bus ,
157
173
struct sdw_group_params * params ,
158
- int * rates , int count )
174
+ struct sdw_group * group )
159
175
{
160
176
struct sdw_master_runtime * m_rt ;
177
+ struct sdw_port_runtime * p_rt ;
161
178
int sel_col = bus -> params .col ;
162
179
unsigned int rate , bps , ch ;
163
- int i , column_needed = 0 ;
180
+ int i , l , column_needed ;
164
181
165
182
/* 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 ];
168
186
params [i ].full_bw = bus -> params .curr_dr_freq / params [i ].rate ;
169
187
}
170
188
171
189
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 );
175
194
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
+ }
179
199
}
180
200
}
181
201
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 ;
186
210
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
+ }
188
222
}
189
223
190
- if (column_needed > sel_col - 1 )
191
- return - EINVAL ;
192
224
193
225
return 0 ;
194
226
}
195
227
196
228
static int sdw_add_element_group_count (struct sdw_group * group ,
197
- unsigned int rate )
229
+ unsigned int rate , unsigned int lane )
198
230
{
199
231
int num = group -> count ;
200
232
int i ;
201
233
202
234
for (i = 0 ; i <= num ; i ++ ) {
203
- if (rate == group -> rates [i ])
235
+ if (rate == group -> rates [i ] && lane == group -> lanes [ i ] )
204
236
break ;
205
237
206
238
if (i != num )
207
239
continue ;
208
240
209
241
if (group -> count >= group -> max_size ) {
210
242
unsigned int * rates ;
243
+ unsigned int * lanes ;
211
244
212
245
group -> max_size += 1 ;
213
246
rates = krealloc (group -> rates ,
214
247
(sizeof (int ) * group -> max_size ),
215
248
GFP_KERNEL );
216
249
if (!rates )
217
250
return - ENOMEM ;
251
+
218
252
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 ;
219
261
}
220
262
221
- group -> rates [group -> count ++ ] = rate ;
263
+ group -> rates [group -> count ] = rate ;
264
+ group -> lanes [group -> count ++ ] = lane ;
222
265
}
223
266
224
267
return 0 ;
@@ -228,6 +271,7 @@ static int sdw_get_group_count(struct sdw_bus *bus,
228
271
struct sdw_group * group )
229
272
{
230
273
struct sdw_master_runtime * m_rt ;
274
+ struct sdw_port_runtime * p_rt ;
231
275
unsigned int rate ;
232
276
int ret = 0 ;
233
277
@@ -237,6 +281,13 @@ static int sdw_get_group_count(struct sdw_bus *bus,
237
281
if (!group -> rates )
238
282
return - ENOMEM ;
239
283
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
+
240
291
list_for_each_entry (m_rt , & bus -> m_rt_list , bus_node ) {
241
292
if (m_rt -> stream -> state == SDW_STREAM_DEPREPARED )
242
293
continue ;
@@ -246,11 +297,16 @@ static int sdw_get_group_count(struct sdw_bus *bus,
246
297
struct sdw_master_runtime ,
247
298
bus_node )) {
248
299
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 );
252
307
if (ret < 0 ) {
253
308
kfree (group -> rates );
309
+ kfree (group -> lanes );
254
310
return ret ;
255
311
}
256
312
}
@@ -284,8 +340,7 @@ static int sdw_compute_port_params(struct sdw_bus *bus)
284
340
}
285
341
286
342
/* 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 );
289
344
if (ret < 0 )
290
345
goto free_params ;
291
346
@@ -295,6 +350,7 @@ static int sdw_compute_port_params(struct sdw_bus *bus)
295
350
kfree (params );
296
351
out :
297
352
kfree (group .rates );
353
+ kfree (group .lanes );
298
354
299
355
return ret ;
300
356
}
0 commit comments