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 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
137145static 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
156172static 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
196228static 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 );
296351out :
297352 kfree (group .rates );
353+ kfree (group .lanes );
298354
299355 return ret ;
300356}
0 commit comments