@@ -177,6 +177,36 @@ int mhi_download_rddm_image(struct mhi_controller *mhi_cntrl, bool in_panic)
177177}
178178EXPORT_SYMBOL_GPL (mhi_download_rddm_image );
179179
180+ static void mhi_fw_load_error_dump (struct mhi_controller * mhi_cntrl )
181+ {
182+ struct device * dev = & mhi_cntrl -> mhi_dev -> dev ;
183+ rwlock_t * pm_lock = & mhi_cntrl -> pm_lock ;
184+ void __iomem * base = mhi_cntrl -> bhi ;
185+ int ret , i ;
186+ u32 val ;
187+ struct {
188+ char * name ;
189+ u32 offset ;
190+ } error_reg [] = {
191+ { "ERROR_CODE" , BHI_ERRCODE },
192+ { "ERROR_DBG1" , BHI_ERRDBG1 },
193+ { "ERROR_DBG2" , BHI_ERRDBG2 },
194+ { "ERROR_DBG3" , BHI_ERRDBG3 },
195+ { NULL },
196+ };
197+
198+ read_lock_bh (pm_lock );
199+ if (MHI_REG_ACCESS_VALID (mhi_cntrl -> pm_state )) {
200+ for (i = 0 ; error_reg [i ].name ; i ++ ) {
201+ ret = mhi_read_reg (mhi_cntrl , base , error_reg [i ].offset , & val );
202+ if (ret )
203+ break ;
204+ dev_err (dev , "Reg: %s value: 0x%x\n" , error_reg [i ].name , val );
205+ }
206+ }
207+ read_unlock_bh (pm_lock );
208+ }
209+
180210static int mhi_fw_load_bhie (struct mhi_controller * mhi_cntrl ,
181211 const struct mhi_buf * mhi_buf )
182212{
@@ -226,24 +256,13 @@ static int mhi_fw_load_bhie(struct mhi_controller *mhi_cntrl,
226256}
227257
228258static int mhi_fw_load_bhi (struct mhi_controller * mhi_cntrl ,
229- dma_addr_t dma_addr ,
230- size_t size )
259+ const struct mhi_buf * mhi_buf )
231260{
232- u32 tx_status , val , session_id ;
233- int i , ret ;
234- void __iomem * base = mhi_cntrl -> bhi ;
235- rwlock_t * pm_lock = & mhi_cntrl -> pm_lock ;
236261 struct device * dev = & mhi_cntrl -> mhi_dev -> dev ;
237- struct {
238- char * name ;
239- u32 offset ;
240- } error_reg [] = {
241- { "ERROR_CODE" , BHI_ERRCODE },
242- { "ERROR_DBG1" , BHI_ERRDBG1 },
243- { "ERROR_DBG2" , BHI_ERRDBG2 },
244- { "ERROR_DBG3" , BHI_ERRDBG3 },
245- { NULL },
246- };
262+ rwlock_t * pm_lock = & mhi_cntrl -> pm_lock ;
263+ void __iomem * base = mhi_cntrl -> bhi ;
264+ u32 tx_status , session_id ;
265+ int ret ;
247266
248267 read_lock_bh (pm_lock );
249268 if (!MHI_REG_ACCESS_VALID (mhi_cntrl -> pm_state )) {
@@ -255,11 +274,9 @@ static int mhi_fw_load_bhi(struct mhi_controller *mhi_cntrl,
255274 dev_dbg (dev , "Starting image download via BHI. Session ID: %u\n" ,
256275 session_id );
257276 mhi_write_reg (mhi_cntrl , base , BHI_STATUS , 0 );
258- mhi_write_reg (mhi_cntrl , base , BHI_IMGADDR_HIGH ,
259- upper_32_bits (dma_addr ));
260- mhi_write_reg (mhi_cntrl , base , BHI_IMGADDR_LOW ,
261- lower_32_bits (dma_addr ));
262- mhi_write_reg (mhi_cntrl , base , BHI_IMGSIZE , size );
277+ mhi_write_reg (mhi_cntrl , base , BHI_IMGADDR_HIGH , upper_32_bits (mhi_buf -> dma_addr ));
278+ mhi_write_reg (mhi_cntrl , base , BHI_IMGADDR_LOW , lower_32_bits (mhi_buf -> dma_addr ));
279+ mhi_write_reg (mhi_cntrl , base , BHI_IMGSIZE , mhi_buf -> len );
263280 mhi_write_reg (mhi_cntrl , base , BHI_IMGTXDB , session_id );
264281 read_unlock_bh (pm_lock );
265282
@@ -274,18 +291,7 @@ static int mhi_fw_load_bhi(struct mhi_controller *mhi_cntrl,
274291
275292 if (tx_status == BHI_STATUS_ERROR ) {
276293 dev_err (dev , "Image transfer failed\n" );
277- read_lock_bh (pm_lock );
278- if (MHI_REG_ACCESS_VALID (mhi_cntrl -> pm_state )) {
279- for (i = 0 ; error_reg [i ].name ; i ++ ) {
280- ret = mhi_read_reg (mhi_cntrl , base ,
281- error_reg [i ].offset , & val );
282- if (ret )
283- break ;
284- dev_err (dev , "Reg: %s value: 0x%x\n" ,
285- error_reg [i ].name , val );
286- }
287- }
288- read_unlock_bh (pm_lock );
294+ mhi_fw_load_error_dump (mhi_cntrl );
289295 goto invalid_pm_state ;
290296 }
291297
@@ -296,6 +302,16 @@ static int mhi_fw_load_bhi(struct mhi_controller *mhi_cntrl,
296302 return - EIO ;
297303}
298304
305+ static void mhi_free_bhi_buffer (struct mhi_controller * mhi_cntrl ,
306+ struct image_info * image_info )
307+ {
308+ struct mhi_buf * mhi_buf = image_info -> mhi_buf ;
309+
310+ dma_free_coherent (mhi_cntrl -> cntrl_dev , mhi_buf -> len , mhi_buf -> buf , mhi_buf -> dma_addr );
311+ kfree (image_info -> mhi_buf );
312+ kfree (image_info );
313+ }
314+
299315void mhi_free_bhie_table (struct mhi_controller * mhi_cntrl ,
300316 struct image_info * image_info )
301317{
@@ -310,6 +326,45 @@ void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl,
310326 kfree (image_info );
311327}
312328
329+ static int mhi_alloc_bhi_buffer (struct mhi_controller * mhi_cntrl ,
330+ struct image_info * * image_info ,
331+ size_t alloc_size )
332+ {
333+ struct image_info * img_info ;
334+ struct mhi_buf * mhi_buf ;
335+
336+ img_info = kzalloc (sizeof (* img_info ), GFP_KERNEL );
337+ if (!img_info )
338+ return - ENOMEM ;
339+
340+ /* Allocate memory for entry */
341+ img_info -> mhi_buf = kzalloc (sizeof (* img_info -> mhi_buf ), GFP_KERNEL );
342+ if (!img_info -> mhi_buf )
343+ goto error_alloc_mhi_buf ;
344+
345+ /* Allocate and populate vector table */
346+ mhi_buf = img_info -> mhi_buf ;
347+
348+ mhi_buf -> len = alloc_size ;
349+ mhi_buf -> buf = dma_alloc_coherent (mhi_cntrl -> cntrl_dev , mhi_buf -> len ,
350+ & mhi_buf -> dma_addr , GFP_KERNEL );
351+ if (!mhi_buf -> buf )
352+ goto error_alloc_segment ;
353+
354+ img_info -> bhi_vec = NULL ;
355+ img_info -> entries = 1 ;
356+ * image_info = img_info ;
357+
358+ return 0 ;
359+
360+ error_alloc_segment :
361+ kfree (mhi_buf );
362+ error_alloc_mhi_buf :
363+ kfree (img_info );
364+
365+ return - ENOMEM ;
366+ }
367+
313368int mhi_alloc_bhie_table (struct mhi_controller * mhi_cntrl ,
314369 struct image_info * * image_info ,
315370 size_t alloc_size )
@@ -365,9 +420,9 @@ int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl,
365420 return - ENOMEM ;
366421}
367422
368- static void mhi_firmware_copy (struct mhi_controller * mhi_cntrl ,
369- const u8 * buf , size_t remainder ,
370- struct image_info * img_info )
423+ static void mhi_firmware_copy_bhie (struct mhi_controller * mhi_cntrl ,
424+ const u8 * buf , size_t remainder ,
425+ struct image_info * img_info )
371426{
372427 size_t to_cpy ;
373428 struct mhi_buf * mhi_buf = img_info -> mhi_buf ;
@@ -386,15 +441,61 @@ static void mhi_firmware_copy(struct mhi_controller *mhi_cntrl,
386441 }
387442}
388443
444+ static enum mhi_fw_load_type mhi_fw_load_type_get (const struct mhi_controller * mhi_cntrl )
445+ {
446+ if (mhi_cntrl -> fbc_download ) {
447+ return MHI_FW_LOAD_FBC ;
448+ } else {
449+ if (mhi_cntrl -> seg_len )
450+ return MHI_FW_LOAD_BHIE ;
451+ else
452+ return MHI_FW_LOAD_BHI ;
453+ }
454+ }
455+
456+ static int mhi_load_image_bhi (struct mhi_controller * mhi_cntrl , const u8 * fw_data , size_t size )
457+ {
458+ struct image_info * image ;
459+ int ret ;
460+
461+ ret = mhi_alloc_bhi_buffer (mhi_cntrl , & image , size );
462+ if (ret )
463+ return ret ;
464+
465+ /* Load the firmware into BHI vec table */
466+ memcpy (image -> mhi_buf -> buf , fw_data , size );
467+
468+ ret = mhi_fw_load_bhi (mhi_cntrl , & image -> mhi_buf [image -> entries - 1 ]);
469+ mhi_free_bhi_buffer (mhi_cntrl , image );
470+
471+ return ret ;
472+ }
473+
474+ static int mhi_load_image_bhie (struct mhi_controller * mhi_cntrl , const u8 * fw_data , size_t size )
475+ {
476+ struct image_info * image ;
477+ int ret ;
478+
479+ ret = mhi_alloc_bhie_table (mhi_cntrl , & image , size );
480+ if (ret )
481+ return ret ;
482+
483+ mhi_firmware_copy_bhie (mhi_cntrl , fw_data , size , image );
484+
485+ ret = mhi_fw_load_bhie (mhi_cntrl , & image -> mhi_buf [image -> entries - 1 ]);
486+ mhi_free_bhie_table (mhi_cntrl , image );
487+
488+ return ret ;
489+ }
490+
389491void mhi_fw_load_handler (struct mhi_controller * mhi_cntrl )
390492{
391493 const struct firmware * firmware = NULL ;
392494 struct device * dev = & mhi_cntrl -> mhi_dev -> dev ;
495+ enum mhi_fw_load_type fw_load_type ;
393496 enum mhi_pm_state new_state ;
394497 const char * fw_name ;
395498 const u8 * fw_data ;
396- void * buf ;
397- dma_addr_t dma_addr ;
398499 size_t size , fw_sz ;
399500 int ret ;
400501
@@ -453,21 +554,17 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
453554 fw_sz = firmware -> size ;
454555
455556skip_req_fw :
456- buf = dma_alloc_coherent (mhi_cntrl -> cntrl_dev , size , & dma_addr ,
457- GFP_KERNEL );
458- if (!buf ) {
459- release_firmware (firmware );
460- goto error_fw_load ;
461- }
462-
463- /* Download image using BHI */
464- memcpy (buf , fw_data , size );
465- ret = mhi_fw_load_bhi (mhi_cntrl , dma_addr , size );
466- dma_free_coherent (mhi_cntrl -> cntrl_dev , size , buf , dma_addr );
557+ fw_load_type = mhi_fw_load_type_get (mhi_cntrl );
558+ if (fw_load_type == MHI_FW_LOAD_BHIE )
559+ ret = mhi_load_image_bhie (mhi_cntrl , fw_data , size );
560+ else
561+ ret = mhi_load_image_bhi (mhi_cntrl , fw_data , size );
467562
468563 /* Error or in EDL mode, we're done */
469564 if (ret ) {
470- dev_err (dev , "MHI did not load image over BHI, ret: %d\n" , ret );
565+ dev_err (dev , "MHI did not load image over BHI%s, ret: %d\n" ,
566+ fw_load_type == MHI_FW_LOAD_BHIE ? "e" : "" ,
567+ ret );
471568 release_firmware (firmware );
472569 goto error_fw_load ;
473570 }
@@ -486,15 +583,15 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
486583 * If we're doing fbc, populate vector tables while
487584 * device transitioning into MHI READY state
488585 */
489- if (mhi_cntrl -> fbc_download ) {
586+ if (fw_load_type == MHI_FW_LOAD_FBC ) {
490587 ret = mhi_alloc_bhie_table (mhi_cntrl , & mhi_cntrl -> fbc_image , fw_sz );
491588 if (ret ) {
492589 release_firmware (firmware );
493590 goto error_fw_load ;
494591 }
495592
496593 /* Load the firmware into BHIE vec table */
497- mhi_firmware_copy (mhi_cntrl , fw_data , fw_sz , mhi_cntrl -> fbc_image );
594+ mhi_firmware_copy_bhie (mhi_cntrl , fw_data , fw_sz , mhi_cntrl -> fbc_image );
498595 }
499596
500597 release_firmware (firmware );
@@ -511,7 +608,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
511608 return ;
512609
513610error_ready_state :
514- if (mhi_cntrl -> fbc_download ) {
611+ if (mhi_cntrl -> fbc_image ) {
515612 mhi_free_bhie_table (mhi_cntrl , mhi_cntrl -> fbc_image );
516613 mhi_cntrl -> fbc_image = NULL ;
517614 }
0 commit comments