]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Soundwire: generic_bandwidth_allocation: set frame shape on fly
authorBard Liao <yung-chuan.liao@linux.intel.com>
Wed, 18 Dec 2024 08:01:49 +0000 (16:01 +0800)
committerVinod Koul <vkoul@kernel.org>
Mon, 23 Dec 2024 06:30:33 +0000 (12:00 +0530)
We need to recalculate frame shape when sdw bus clock is changed.
And need to make sure all Peripherals connected to the Manager support
dynamic clock change.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20241218080155.102405-9-yung-chuan.liao@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/soundwire/generic_bandwidth_allocation.c

index 2950a3d002ce2d651e392305c00e77428a8481ea..d847413141d392c05bbd614197c236372f03d5da 100644 (file)
@@ -327,6 +327,19 @@ static int sdw_select_row_col(struct sdw_bus *bus, int clk_freq)
        return -EINVAL;
 }
 
+static bool is_clock_scaling_supported(struct sdw_bus *bus)
+{
+       struct sdw_master_runtime *m_rt;
+       struct sdw_slave_runtime *s_rt;
+
+       list_for_each_entry(m_rt, &bus->m_rt_list, bus_node)
+               list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node)
+                       if (!is_clock_scaling_supported_by_slave(s_rt->slave))
+                               return false;
+
+       return true;
+}
+
 /**
  * sdw_compute_bus_params: Compute bus parameters
  *
@@ -352,6 +365,10 @@ static int sdw_compute_bus_params(struct sdw_bus *bus)
                clk_buf = NULL;
        }
 
+       /* If dynamic scaling is not supported, don't try higher freq */
+       if (!is_clock_scaling_supported(bus))
+               clk_values = 1;
+
        for (i = 0; i < clk_values; i++) {
                if (!clk_buf)
                        curr_dr_freq = bus->params.max_dr_freq;
@@ -378,6 +395,12 @@ static int sdw_compute_bus_params(struct sdw_bus *bus)
                return -EINVAL;
        }
 
+       if (!mstr_prop->default_frame_rate || !mstr_prop->default_row)
+               return -EINVAL;
+
+       mstr_prop->default_col = curr_dr_freq / mstr_prop->default_frame_rate /
+                                mstr_prop->default_row;
+
        ret = sdw_select_row_col(bus, curr_dr_freq);
        if (ret < 0) {
                dev_err(bus->dev, "%s: could not find frame configuration for bus dr_freq %d\n",