2727
2828#define to_amd_sdw (b ) container_of(b, struct amd_sdw_manager, bus)
2929
30+ static int amd_sdw_clk_init_ctrl (struct amd_sdw_manager * amd_manager )
31+ {
32+ struct sdw_bus * bus = & amd_manager -> bus ;
33+ struct sdw_master_prop * prop = & bus -> prop ;
34+ u32 divider ;
35+
36+ dev_dbg (amd_manager -> dev , "mclk %d max %d row %d col %d frame_rate:%d\n" ,
37+ prop -> mclk_freq , prop -> max_clk_freq , prop -> default_row ,
38+ prop -> default_col , prop -> default_frame_rate );
39+
40+ if (!prop -> default_frame_rate || !prop -> default_row ) {
41+ dev_err (amd_manager -> dev , "Default frame_rate %d or row %d is invalid\n" ,
42+ prop -> default_frame_rate , prop -> default_row );
43+ return - EINVAL ;
44+ }
45+
46+ /* Set clock divider */
47+ divider = (prop -> mclk_freq / bus -> params .curr_dr_freq );
48+ writel (divider , amd_manager -> mmio + ACP_SW_CLK_FREQUENCY_CTRL );
49+
50+ /* Set frame shape base on the actual bus frequency. */
51+ prop -> default_col = bus -> params .curr_dr_freq /
52+ prop -> default_frame_rate / prop -> default_row ;
53+ amd_manager -> cols_index = sdw_find_col_index (prop -> default_col );
54+ amd_manager -> rows_index = sdw_find_row_index (prop -> default_row );
55+ bus -> params .col = prop -> default_col ;
56+ bus -> params .row = prop -> default_row ;
57+ return 0 ;
58+ }
59+
3060static int amd_init_sdw_manager (struct amd_sdw_manager * amd_manager )
3161{
3262 u32 val ;
@@ -437,12 +467,16 @@ static u32 amd_sdw_read_ping_status(struct sdw_bus *bus)
437467
438468static int amd_sdw_compute_params (struct sdw_bus * bus , struct sdw_stream_runtime * stream )
439469{
470+ struct amd_sdw_manager * amd_manager = to_amd_sdw (bus );
440471 struct sdw_transport_data t_data = {0 };
441472 struct sdw_master_runtime * m_rt ;
442473 struct sdw_port_runtime * p_rt ;
443474 struct sdw_bus_params * b_params = & bus -> params ;
444475 int port_bo , hstart , hstop , sample_int ;
445- unsigned int rate , bps ;
476+ unsigned int rate , bps , channels ;
477+ unsigned int stream_slot_size , max_slots ;
478+ static unsigned int next_offset [AMD_SDW_MAX_MANAGER_COUNT ] = {1 };
479+ unsigned int inst_id = amd_manager -> instance ;
446480
447481 port_bo = 0 ;
448482 hstart = 1 ;
@@ -453,11 +487,51 @@ static int amd_sdw_compute_params(struct sdw_bus *bus, struct sdw_stream_runtime
453487 list_for_each_entry (m_rt , & bus -> m_rt_list , bus_node ) {
454488 rate = m_rt -> stream -> params .rate ;
455489 bps = m_rt -> stream -> params .bps ;
490+ channels = m_rt -> stream -> params .ch_count ;
456491 sample_int = (bus -> params .curr_dr_freq / rate );
492+
493+ /* Compute slots required for this stream dynamically */
494+ stream_slot_size = bps * channels ;
495+
457496 list_for_each_entry (p_rt , & m_rt -> port_list , port_node ) {
458- port_bo = (p_rt -> num * 64 ) + 1 ;
459- dev_dbg (bus -> dev , "p_rt->num=%d hstart=%d hstop=%d port_bo=%d\n" ,
460- p_rt -> num , hstart , hstop , port_bo );
497+ if (p_rt -> num >= amd_manager -> max_ports ) {
498+ dev_err (bus -> dev , "Port %d exceeds max ports %d\n" ,
499+ p_rt -> num , amd_manager -> max_ports );
500+ return - EINVAL ;
501+ }
502+
503+ if (!amd_manager -> port_offset_map [p_rt -> num ]) {
504+ /*
505+ * port block offset calculation for 6MHz bus clock frequency with
506+ * different frame sizes 50 x 10 and 125 x 2
507+ */
508+ if (bus -> params .curr_dr_freq == 12000000 ) {
509+ max_slots = bus -> params .row * (bus -> params .col - 1 );
510+ if (next_offset [inst_id ] + stream_slot_size <=
511+ (max_slots - 1 )) {
512+ amd_manager -> port_offset_map [p_rt -> num ] =
513+ next_offset [inst_id ];
514+ next_offset [inst_id ] += stream_slot_size ;
515+ } else {
516+ dev_err (bus -> dev ,
517+ "No space for port %d\n" , p_rt -> num );
518+ return - ENOMEM ;
519+ }
520+ } else {
521+ /*
522+ * port block offset calculation for 12MHz bus clock
523+ * frequency
524+ */
525+ amd_manager -> port_offset_map [p_rt -> num ] =
526+ (p_rt -> num * 64 ) + 1 ;
527+ }
528+ }
529+ port_bo = amd_manager -> port_offset_map [p_rt -> num ];
530+ dev_dbg (bus -> dev ,
531+ "Port=%d hstart=%d hstop=%d port_bo=%d slots=%d max_ports=%d\n" ,
532+ p_rt -> num , hstart , hstop , port_bo , stream_slot_size ,
533+ amd_manager -> max_ports );
534+
461535 sdw_fill_xport_params (& p_rt -> transport_params , p_rt -> num ,
462536 false, SDW_BLK_GRP_CNT_1 , sample_int ,
463537 port_bo , port_bo >> 8 , hstart , hstop ,
@@ -960,6 +1034,9 @@ int amd_sdw_manager_start(struct amd_sdw_manager *amd_manager)
9601034
9611035 prop = & amd_manager -> bus .prop ;
9621036 if (!prop -> hw_disabled ) {
1037+ ret = amd_sdw_clk_init_ctrl (amd_manager );
1038+ if (ret )
1039+ return ret ;
9631040 ret = amd_init_sdw_manager (amd_manager );
9641041 if (ret )
9651042 return ret ;
@@ -984,7 +1061,6 @@ static int amd_sdw_manager_probe(struct platform_device *pdev)
9841061 struct resource * res ;
9851062 struct device * dev = & pdev -> dev ;
9861063 struct sdw_master_prop * prop ;
987- struct sdw_bus_params * params ;
9881064 struct amd_sdw_manager * amd_manager ;
9891065 int ret ;
9901066
@@ -1047,15 +1123,14 @@ static int amd_sdw_manager_probe(struct platform_device *pdev)
10471123 default :
10481124 return - EINVAL ;
10491125 }
1126+ amd_manager -> max_ports = amd_manager -> num_dout_ports + amd_manager -> num_din_ports ;
1127+ amd_manager -> port_offset_map = devm_kcalloc (dev , amd_manager -> max_ports ,
1128+ sizeof (int ), GFP_KERNEL );
1129+ if (!amd_manager -> port_offset_map )
1130+ return - ENOMEM ;
10501131
1051- params = & amd_manager -> bus .params ;
1052-
1053- params -> col = AMD_SDW_DEFAULT_COLUMNS ;
1054- params -> row = AMD_SDW_DEFAULT_ROWS ;
10551132 prop = & amd_manager -> bus .prop ;
1056- prop -> clk_freq = & amd_sdw_freq_tbl [0 ];
10571133 prop -> mclk_freq = AMD_SDW_BUS_BASE_FREQ ;
1058- prop -> max_clk_freq = AMD_SDW_DEFAULT_CLK_FREQ ;
10591134
10601135 ret = sdw_bus_master_add (& amd_manager -> bus , dev , dev -> fwnode );
10611136 if (ret ) {
@@ -1347,6 +1422,9 @@ static int __maybe_unused amd_resume_runtime(struct device *dev)
13471422 }
13481423 }
13491424 sdw_clear_slave_status (bus , SDW_UNATTACH_REQUEST_MASTER_RESET );
1425+ ret = amd_sdw_clk_init_ctrl (amd_manager );
1426+ if (ret )
1427+ return ret ;
13501428 amd_init_sdw_manager (amd_manager );
13511429 amd_enable_sdw_interrupts (amd_manager );
13521430 ret = amd_enable_sdw_manager (amd_manager );
0 commit comments