1818
1919struct 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
3234void 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
139147static 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
158174static 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
198230static 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 );
298353out :
299354 kfree (group .rates );
355+ kfree (group .lanes );
300356
301357 return ret ;
302358}
0 commit comments