Message ID | 20250107015824.5046-2-yung-chuan.liao@linux.intel.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | soundwire: set frame shape and divider based on actual clk freq | expand |
> -static void cdns_init_clock_ctrl(struct sdw_cdns *cdns) > +static int cdns_init_clock_ctrl(struct sdw_cdns *cdns) > { > struct sdw_bus *bus = &cdns->bus; > struct sdw_master_prop *prop = &bus->prop; > u32 val; > u32 ssp_interval; > int divider; > + int freq; > > dev_dbg(cdns->dev, "mclk %d max %d row %d col %d\n", > prop->mclk_freq, > @@ -1356,13 +1357,25 @@ static void cdns_init_clock_ctrl(struct sdw_cdns *cdns) > prop->default_col); > > /* Set clock divider */ > - divider = (prop->mclk_freq / prop->max_clk_freq) - 1; > + divider = (prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR / > + bus->params.curr_dr_freq) - 1; > + freq = bus->params.curr_dr_freq >> 1; do you actually need this intermediate variable? see below [1] ... > > cdns_updatel(cdns, CDNS_MCP_CLK_CTRL0, > CDNS_MCP_CLK_MCLKD_MASK, divider); > cdns_updatel(cdns, CDNS_MCP_CLK_CTRL1, > CDNS_MCP_CLK_MCLKD_MASK, divider); > > + /* Set frame shape base on the actual bus frequency. */ > + if (!prop->default_frame_rate || !prop->default_row) { > + dev_err(cdns->dev, "Default frame_rate %d or row %d is invalid\n", > + prop->default_frame_rate, prop->default_row); > + return -EINVAL; > + } maybe check the values before writing the divider registers? > + > + prop->default_col = freq * SDW_DOUBLE_RATE_FACTOR / > + prop->default_frame_rate / prop->default_row; [1] ... this is the only place where 'freq' is used, and you multiply it by two after dividing it by two. couldn't this just be: prop->default_col = bus->params.curr_dr_freq / prop->default_frame_rate / prop->default_row;
diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c index f367670ea991..a49d4e521a8f 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -1341,13 +1341,14 @@ static u32 cdns_set_initial_frame_shape(int n_rows, int n_cols) return val; } -static void cdns_init_clock_ctrl(struct sdw_cdns *cdns) +static int cdns_init_clock_ctrl(struct sdw_cdns *cdns) { struct sdw_bus *bus = &cdns->bus; struct sdw_master_prop *prop = &bus->prop; u32 val; u32 ssp_interval; int divider; + int freq; dev_dbg(cdns->dev, "mclk %d max %d row %d col %d\n", prop->mclk_freq, @@ -1356,13 +1357,25 @@ static void cdns_init_clock_ctrl(struct sdw_cdns *cdns) prop->default_col); /* Set clock divider */ - divider = (prop->mclk_freq / prop->max_clk_freq) - 1; + divider = (prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR / + bus->params.curr_dr_freq) - 1; + freq = bus->params.curr_dr_freq >> 1; cdns_updatel(cdns, CDNS_MCP_CLK_CTRL0, CDNS_MCP_CLK_MCLKD_MASK, divider); cdns_updatel(cdns, CDNS_MCP_CLK_CTRL1, CDNS_MCP_CLK_MCLKD_MASK, divider); + /* Set frame shape base on the actual bus frequency. */ + if (!prop->default_frame_rate || !prop->default_row) { + dev_err(cdns->dev, "Default frame_rate %d or row %d is invalid\n", + prop->default_frame_rate, prop->default_row); + return -EINVAL; + } + + prop->default_col = freq * SDW_DOUBLE_RATE_FACTOR / + prop->default_frame_rate / prop->default_row; + /* * Frame shape changes after initialization have to be done * with the bank switch mechanism @@ -1375,6 +1388,8 @@ static void cdns_init_clock_ctrl(struct sdw_cdns *cdns) ssp_interval = prop->default_frame_rate / SDW_CADENCE_GSYNC_HZ; cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, ssp_interval); cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, ssp_interval); + + return 0; } /** @@ -1408,9 +1423,12 @@ EXPORT_SYMBOL(sdw_cdns_soft_reset); */ int sdw_cdns_init(struct sdw_cdns *cdns) { + int ret; u32 val; - cdns_init_clock_ctrl(cdns); + ret = cdns_init_clock_ctrl(cdns); + if (ret) + return ret; sdw_cdns_check_self_clearing_bits(cdns, __func__, false, 0);