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,
813813}
814814EXPORT_SYMBOL (sdw_extract_slave_id );
815815
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+
816826static int sdw_program_device_num (struct sdw_bus * bus , bool * programmed )
817827{
818828 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)
629629static int sdw_program_params (struct sdw_bus * bus , bool prepare )
630630{
631631 struct sdw_master_runtime * m_rt ;
632+ struct sdw_slave * slave ;
632633 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+ }
633668
669+ manager_runtime :
634670 list_for_each_entry (m_rt , & bus -> m_rt_list , bus_node ) {
635671
636672 /*
Original file line number Diff line number Diff line change @@ -1041,6 +1041,7 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus);
10411041
10421042int sdw_compare_devid (struct sdw_slave * slave , struct sdw_slave_id id );
10431043void 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 );
10441045
10451046#if IS_ENABLED (CONFIG_SOUNDWIRE )
10461047
You can’t perform that action at this time.
0 commit comments