clk: si570: Skip NVM to RAM recall operation if an optional property is set
Recalling NVM data into RAM during probe() initiates a re-calibration of the clock. If the clock is already in-use, the recall operation can cause a glitch on the frequency out. At power on, the factory data are loaded from NVM into RAM by default. If the clock frequency has been changed since power on, the recall operation can be used to re-initialize the clock to factory setting. Signed-off-by: Michal Simek <michal.simek@xilinx.com> Signed-off-by: Saeed Nowshadi <saeed.nowshadi@xilinx.com> Link: https://lore.kernel.org/r/1612496104-3437-3-git-send-email-saeed.nowshadi@xilinx.com Signed-off-by: Stephen Boyd <sboyd@kernel.org>
This commit is contained in:
parent
3dff4becef
commit
d9d4944d36
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2010, 2011 Ericsson AB.
|
* Copyright (C) 2010, 2011 Ericsson AB.
|
||||||
* Copyright (C) 2011 Guenter Roeck.
|
* Copyright (C) 2011 Guenter Roeck.
|
||||||
* Copyright (C) 2011 - 2013 Xilinx Inc.
|
* Copyright (C) 2011 - 2021 Xilinx Inc.
|
||||||
*
|
*
|
||||||
* Author: Guenter Roeck <guenter.roeck@ericsson.com>
|
* Author: Guenter Roeck <guenter.roeck@ericsson.com>
|
||||||
* Sören Brinkmann <soren.brinkmann@xilinx.com>
|
* Sören Brinkmann <soren.brinkmann@xilinx.com>
|
||||||
@ -123,14 +123,18 @@ static int si570_get_divs(struct clk_si570 *data, u64 *rfreq,
|
|||||||
* si570_get_defaults() - Get default values
|
* si570_get_defaults() - Get default values
|
||||||
* @data: Driver data structure
|
* @data: Driver data structure
|
||||||
* @fout: Factory frequency output
|
* @fout: Factory frequency output
|
||||||
|
* @skip_recall: If true, don't recall NVM into RAM
|
||||||
* Returns 0 on success, negative errno otherwise.
|
* Returns 0 on success, negative errno otherwise.
|
||||||
*/
|
*/
|
||||||
static int si570_get_defaults(struct clk_si570 *data, u64 fout)
|
static int si570_get_defaults(struct clk_si570 *data, u64 fout,
|
||||||
|
bool skip_recall)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
u64 fdco;
|
u64 fdco;
|
||||||
|
|
||||||
regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_RECALL);
|
if (!skip_recall)
|
||||||
|
regmap_write(data->regmap, SI570_REG_CONTROL,
|
||||||
|
SI570_CNTRL_RECALL);
|
||||||
|
|
||||||
err = si570_get_divs(data, &data->rfreq, &data->n1, &data->hs_div);
|
err = si570_get_divs(data, &data->rfreq, &data->n1, &data->hs_div);
|
||||||
if (err)
|
if (err)
|
||||||
@ -400,6 +404,7 @@ static int si570_probe(struct i2c_client *client,
|
|||||||
struct clk_si570 *data;
|
struct clk_si570 *data;
|
||||||
struct clk_init_data init;
|
struct clk_init_data init;
|
||||||
u32 initial_fout, factory_fout, stability;
|
u32 initial_fout, factory_fout, stability;
|
||||||
|
bool skip_recall;
|
||||||
int err;
|
int err;
|
||||||
enum clk_si570_variant variant = id->driver_data;
|
enum clk_si570_variant variant = id->driver_data;
|
||||||
|
|
||||||
@ -441,6 +446,9 @@ static int si570_probe(struct i2c_client *client,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip_recall = of_property_read_bool(client->dev.of_node,
|
||||||
|
"silabs,skip-recall");
|
||||||
|
|
||||||
data->regmap = devm_regmap_init_i2c(client, &si570_regmap_config);
|
data->regmap = devm_regmap_init_i2c(client, &si570_regmap_config);
|
||||||
if (IS_ERR(data->regmap)) {
|
if (IS_ERR(data->regmap)) {
|
||||||
dev_err(&client->dev, "failed to allocate register map\n");
|
dev_err(&client->dev, "failed to allocate register map\n");
|
||||||
@ -448,7 +456,7 @@ static int si570_probe(struct i2c_client *client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
i2c_set_clientdata(client, data);
|
i2c_set_clientdata(client, data);
|
||||||
err = si570_get_defaults(data, factory_fout);
|
err = si570_get_defaults(data, factory_fout, skip_recall);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user