@@ -516,151 +516,54 @@ static void p8_i2c_translate_error(struct i2c_request *req, uint64_t status)
516
516
req -> result = OPAL_I2C_TIMEOUT ;
517
517
}
518
518
519
- static void p8_i2c_force_reset (struct p8_i2c_master * master )
519
+ static int p8_i2c_reset_port (struct p8_i2c_master_port * p )
520
520
{
521
- struct p8_i2c_master_port * p ;
522
- uint64_t mode ;
523
- int rc ;
521
+ struct p8_i2c_master * master = p -> master ;
522
+ int reset_loops , rc ;
523
+ uint64_t status ;
524
524
525
- /* Reset the i2c engine */
526
- rc = xscom_write (master -> chip_id , master -> xscom_base +
527
- I2C_RESET_I2C_REG , 0 );
528
- if (rc ) {
529
- log_simple_error (& e_info (OPAL_RC_I2C_RESET ), "I2C: Failed "
530
- "to reset the i2c engine\n" );
531
- return ;
532
- }
533
- time_wait_us_nopoll (10 );
534
- /* Reset port busy */
535
- rc = xscom_write (master -> chip_id , master -> xscom_base +
536
- I2C_PORT_BUSY_REG , 0x8000000000000000ULL );
525
+ /* FIXME: this should per per-port rather than per-master */
526
+ master -> state = state_error ;
527
+
528
+ /*
529
+ * Put the master into enhanced STOP mode when recovering the
530
+ * port. This causes the master to send additional STOP conditions
531
+ * to work around some particularly stupid I2C devices and it's
532
+ * required on secure I2C masters since they will not send a bare
533
+ * stop condition.
534
+ */
535
+ rc = p8_i2c_prog_mode (p , true);
537
536
if (rc ) {
538
- log_simple_error (& e_info (OPAL_RC_I2C_RESET ), "I2C: Failed "
539
- "to reset port busy on i2c engine \n" );
540
- return ;
537
+ log_simple_error (& e_info (OPAL_RC_I2C_RESET ),
538
+ "I2C: Failed to enable enhanced mode \n" );
539
+ return -1 ;
541
540
}
542
- time_wait_us_nopoll (10 );
543
- list_for_each (& master -> ports , p , link ) {
544
- mode = 0 ;
545
- mode = SETFIELD (I2C_MODE_PORT_NUM , mode , p -> port_num );
546
- mode = SETFIELD (I2C_MODE_BIT_RATE_DIV , mode , p -> bit_rate_div );
547
- mode |= I2C_MODE_DIAGNOSTIC ;
548
- rc = xscom_write (master -> chip_id ,
549
- master -> xscom_base + I2C_MODE_REG ,
550
- mode );
551
- if (rc )
552
- prlog (PR_ERR , "I2C: Failed to write the MODE_REG\n" );
553
-
554
- time_wait_us_nopoll (10 );
555
- rc = xscom_write (master -> chip_id ,
556
- master -> xscom_base + I2C_RESET_S_SCL_REG ,
557
- 0 );
558
- if (rc )
559
- prlog (PR_ERR , "I2C: Failed to reset S_SCL\n" );
560
-
561
- time_wait_us_nopoll (10 );
562
- rc = xscom_write (master -> chip_id ,
563
- master -> xscom_base + I2C_SET_S_SCL_REG ,
564
- 0 );
565
- if (rc )
566
- prlog (PR_ERR , "I2C: Failed to set S_SCL\n" );
567
-
568
- /* Manually reset */
569
- time_wait_us_nopoll (10 );
570
- rc = xscom_write (master -> chip_id ,
571
- master -> xscom_base + I2C_RESET_S_SCL_REG ,
572
- 0 );
573
- if (rc )
574
- prlog (PR_ERR , "I2C: sendStop: fail reset S_SCL\n" );
575
541
576
- time_wait_us_nopoll (10 );
577
- rc = xscom_write (master -> chip_id ,
578
- master -> xscom_base + I2C_RESET_S_SDA_REG ,
579
- 0 );
580
- if (rc )
581
- prlog (PR_ERR , "I2C: sendStop: fail reset S_SDA\n" );
542
+ rc = xscom_write (master -> chip_id , master -> xscom_base +
543
+ I2C_CMD_REG , I2C_CMD_WITH_STOP );
544
+ if (rc )
545
+ goto err ;
582
546
583
- time_wait_us_nopoll (10 );
584
- rc = xscom_write (master -> chip_id ,
585
- master -> xscom_base + I2C_SET_S_SCL_REG ,
586
- 0 );
587
- if (rc )
588
- prlog (PR_ERR , "I2C: sendStop: fail set S_SCL\n" );
547
+ /* Wait for COMMAND COMPLETE */
548
+ for (reset_loops = 0 ; reset_loops < 10 ; reset_loops ++ ) {
549
+ time_wait_ms (10 );
589
550
590
- time_wait_us_nopoll (10 );
591
- rc = xscom_write (master -> chip_id ,
592
- master -> xscom_base + I2C_SET_S_SDA_REG ,
593
- 0 );
551
+ rc = xscom_read (master -> chip_id ,
552
+ master -> xscom_base + I2C_STAT_REG ,
553
+ & status );
594
554
if (rc )
595
- prlog ( PR_ERR , "I2C: sendStop: fail set 2 S_SDA\n" ) ;
555
+ goto err ;
596
556
597
- mode ^= I2C_MODE_DIAGNOSTIC ;
598
- time_wait_us_nopoll (10 );
599
- rc = xscom_write (master -> chip_id ,
600
- master -> xscom_base + I2C_MODE_REG ,
601
- mode );
602
- if (rc )
603
- prlog (PR_ERR , "I2C: Failed to write the MODE_REG\n" );
557
+ if (status & I2C_STAT_CMD_COMP )
558
+ break ;
604
559
}
605
- }
606
-
607
- static int p8_i2c_reset_engine (struct p8_i2c_master * master )
608
- {
609
- struct p8_i2c_master_port * p ;
610
- int reset_loops ;
611
- int rc ;
612
- uint64_t status ;
613
560
614
- list_for_each (& master -> ports , p , link ) {
615
- /*
616
- * Reset each port by issuing a STOP command to slave.
617
- *
618
- * Reprogram the mode register with 'enhanced bit' set
619
- */
620
- rc = p8_i2c_prog_mode (p , true);
621
- if (rc ) {
622
- log_simple_error (& e_info (OPAL_RC_I2C_RESET ),
623
- "I2C: Failed to program the MODE_REG\n" );
624
- return -1 ;
625
- }
626
-
627
- /* Send an immediate stop */
628
- master -> state = state_error ;
629
- rc = xscom_write (master -> chip_id , master -> xscom_base +
630
- I2C_CMD_REG , I2C_CMD_WITH_STOP );
631
- if (rc ) {
632
- log_simple_error (& e_info (OPAL_RC_I2C_RESET ),
633
- "I2C: Failed to issue immediate STOP\n" );
634
- return -1 ;
635
- }
636
-
637
- /* Wait for COMMAND COMPLETE */
638
- reset_loops = 0 ;
639
- do {
640
- rc = xscom_read (master -> chip_id ,
641
- master -> xscom_base + I2C_STAT_REG ,
642
- & status );
643
- if (rc ) {
644
- log_simple_error (& e_info (OPAL_RC_I2C_TRANSFER ),
645
- "I2C: Failed to read the STAT_REG\n" );
646
- return -1 ;
647
- }
648
- if (! (status & I2C_STAT_CMD_COMP )) {
649
- time_wait_ms (10 );
650
- if (reset_loops ++ == 5 ) {
651
- prlog (PR_WARNING , "I2C: Retrying reset, with force!\n" );
652
- p8_i2c_force_reset (master );
653
- continue ;
654
- }
655
- if (reset_loops == 10 ) {
656
- log_simple_error (& e_info (OPAL_RC_I2C_TRANSFER ),
657
- "I2C: Failed to recover i2c engine\n" );
658
- break ;
659
- }
660
- }
661
- } while (! (status & I2C_STAT_CMD_COMP ));
662
- }
663
- return 0 ;
561
+ if (status & I2C_STAT_CMD_COMP )
562
+ return 0 ;
563
+ err :
564
+ prerror ("I2C: Failed to reset c%de%dp%d\n" ,
565
+ master -> chip_id , master -> engine_id , p -> port_num );
566
+ return -1 ;
664
567
}
665
568
666
569
static void p8_i2c_status_error (struct p8_i2c_master_port * port ,
@@ -699,7 +602,7 @@ static void p8_i2c_status_error(struct p8_i2c_master_port *port,
699
602
*/
700
603
p8_i2c_complete_request (master , req , req -> result );
701
604
} else {
702
- if (p8_i2c_reset_engine ( master ))
605
+ if (p8_i2c_reset_port ( port ))
703
606
goto exit ;
704
607
/* Enable the interrupt */
705
608
p8_i2c_enable_irqs (master );
0 commit comments