File tree Expand file tree Collapse file tree 3 files changed +47
-0
lines changed Expand file tree Collapse file tree 3 files changed +47
-0
lines changed Original file line number Diff line number Diff line change @@ -813,6 +813,16 @@ void sdw_extract_slave_id(struct sdw_bus *bus,
813
813
}
814
814
EXPORT_SYMBOL (sdw_extract_slave_id );
815
815
816
+ bool is_clock_scaling_supported_by_slave (struct sdw_slave * slave )
817
+ {
818
+ /*
819
+ * Dynamic scaling is a defined by SDCA. However, some devices expose the class ID but
820
+ * can't support dynamic scaling. We might need a quirk to handle such devices.
821
+ */
822
+ return slave -> id .class_id ;
823
+ }
824
+ EXPORT_SYMBOL (is_clock_scaling_supported_by_slave );
825
+
816
826
static int sdw_program_device_num (struct sdw_bus * bus , bool * programmed )
817
827
{
818
828
u8 buf [SDW_NUM_DEV_ID_REGISTERS ] = {0 };
Original file line number Diff line number Diff line change @@ -629,8 +629,44 @@ static int sdw_notify_config(struct sdw_master_runtime *m_rt)
629
629
static int sdw_program_params (struct sdw_bus * bus , bool prepare )
630
630
{
631
631
struct sdw_master_runtime * m_rt ;
632
+ struct sdw_slave * slave ;
632
633
int ret = 0 ;
634
+ u32 addr1 ;
635
+
636
+ /* Check if all Peripherals comply with SDCA */
637
+ list_for_each_entry (slave , & bus -> slaves , node ) {
638
+ if (!slave -> dev_num_sticky )
639
+ continue ;
640
+ if (!is_clock_scaling_supported_by_slave (slave )) {
641
+ dev_dbg (& slave -> dev , "The Peripheral doesn't comply with SDCA\n" );
642
+ goto manager_runtime ;
643
+ }
644
+ }
645
+
646
+ if (bus -> params .next_bank )
647
+ addr1 = SDW_SCP_BUSCLOCK_SCALE_B1 ;
648
+ else
649
+ addr1 = SDW_SCP_BUSCLOCK_SCALE_B0 ;
650
+
651
+ /* Program SDW_SCP_BUSCLOCK_SCALE if all Peripherals comply with SDCA */
652
+ list_for_each_entry (slave , & bus -> slaves , node ) {
653
+ int scale_index ;
654
+ u8 base ;
655
+
656
+ if (!slave -> dev_num_sticky )
657
+ continue ;
658
+ scale_index = sdw_slave_get_scale_index (slave , & base );
659
+ if (scale_index < 0 )
660
+ return scale_index ;
661
+
662
+ ret = sdw_write_no_pm (slave , addr1 , scale_index );
663
+ if (ret < 0 ) {
664
+ dev_err (& slave -> dev , "SDW_SCP_BUSCLOCK_SCALE register write failed\n" );
665
+ return ret ;
666
+ }
667
+ }
633
668
669
+ manager_runtime :
634
670
list_for_each_entry (m_rt , & bus -> m_rt_list , bus_node ) {
635
671
636
672
/*
Original file line number Diff line number Diff line change @@ -1041,6 +1041,7 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus);
1041
1041
1042
1042
int sdw_compare_devid (struct sdw_slave * slave , struct sdw_slave_id id );
1043
1043
void sdw_extract_slave_id (struct sdw_bus * bus , u64 addr , struct sdw_slave_id * id );
1044
+ bool is_clock_scaling_supported_by_slave (struct sdw_slave * slave );
1044
1045
1045
1046
#if IS_ENABLED (CONFIG_SOUNDWIRE )
1046
1047
You can’t perform that action at this time.
0 commit comments