static int __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate)
{
int idx, max_opp = clk->opps->count;
- u32 *freqs = clk->opps->freqs;
+ struct scpi_opp_entry *opp = clk->opps->opp;
u32 fmin = 0, fmax = ~0, ftmp;
- for (idx = 0; idx < max_opp; idx++, freqs++) {
- ftmp = *freqs;
+ for (idx = 0; idx < max_opp; idx++, opp++) {
+ ftmp = opp->freq_hz;
if (ftmp >= (u32)rate) {
if (ftmp <= fmax)
fmax = ftmp;
{
struct scpi_clk *clk = to_scpi_clk(hw);
int idx = scpi_dvfs_get_idx(clk->id);
- u32 *freqs = clk->opps->freqs;
+ struct scpi_opp_entry *opp = clk->opps->opp;
if (idx < 0)
return 0;
else
- return *(freqs + idx);
+ return opp[idx].freq_hz;
}
static long scpi_dvfs_round_rate(struct clk_hw *hw, unsigned long rate,
static int __scpi_find_dvfs_index(struct scpi_clk *clk, unsigned long rate)
{
int idx, max_opp = clk->opps->count;
- u32 *freqs = clk->opps->freqs;
+ struct scpi_opp_entry *opp = clk->opps->opp;
- for (idx = 0; idx < max_opp; idx++, freqs++)
- if (*freqs == (u32)rate)
+ for (idx = 0; idx < max_opp; idx++, opp++)
+ if (opp->freq_hz == (u32)rate)
break;
return (idx == max_opp) ? -EINVAL : idx;
}
struct scpi_clk *sclk)
{
struct clk_init_data init;
- struct scpi_opp *opp;
+ struct scpi_opp *opps;
init.name = sclk->name;
init.flags = CLK_IS_ROOT;
init.ops = &scpi_dvfs_ops;
sclk->hw.init = &init;
- opp = scpi_dvfs_get_opps(sclk->id);
- if (IS_ERR(opp))
- return (struct clk *)opp;
+ opps = scpi_dvfs_get_opps(sclk->id);
+ if (IS_ERR(opps))
+ return (struct clk *)opps;
- sclk->opps = opp;
+ sclk->opps = opps;
return devm_clk_register(dev, &sclk->hw);
}
static int scpi_init_opp_table(struct device *cpu_dev)
{
u8 domain = topology_physical_package_id(cpu_dev->id);
- struct scpi_opp *opp;
+ struct scpi_opp *opps;
int idx, ret = 0, max_opp;
- u32 *freqs;
+ struct scpi_opp_entry *opp;
if ((dev_pm_opp_get_opp_count(cpu_dev)) > 0)
return 0;
- opp = scpi_dvfs_get_opps(domain);
- if (IS_ERR(opp))
- return PTR_ERR(opp);
+ opps = scpi_dvfs_get_opps(domain);
+ if (IS_ERR(opps))
+ return PTR_ERR(opps);
- freqs = opp->freqs;
- max_opp = opp->count;
- for (idx = 0; idx < max_opp; idx++, freqs++) {
- ret = dev_pm_opp_add(cpu_dev, *freqs, 900000000 /* TODO */);
+ opp = opps->opp;
+ max_opp = opps->count;
+ for (idx = 0; idx < max_opp; idx++, opp++) {
+ ret = dev_pm_opp_add(cpu_dev, opp->freq_hz, opp->volt_mv*1000);
if (ret) {
- dev_warn(cpu_dev, "failed to add opp %u\n", *freqs);
+ dev_warn(cpu_dev, "failed to add opp %uHz %umV\n",
+ opp->freq_hz, opp->volt_mv);
return ret;
}
}
struct __packed {
u32 status;
u32 header;
- u32 freqs[MAX_DVFS_OPPS];
+ struct scpi_opp_entry opp[MAX_DVFS_OPPS];
} buf;
- struct scpi_opp *opp;
- size_t freqs_sz;
+ struct scpi_opp *opps;
+ size_t opps_sz;
int count, ret;
if (domain >= MAX_DVFS_DOMAINS)
if (ret)
return ERR_PTR(ret);
- opp = kmalloc(sizeof(*opp), GFP_KERNEL);
- if (!opp)
+ opps = kmalloc(sizeof(*opps), GFP_KERNEL);
+ if (!opps)
return ERR_PTR(-ENOMEM);
count = DVFS_OPP_COUNT(buf.header);
- freqs_sz = count * sizeof(*(opp->freqs));
+ opps_sz = count * sizeof(*(opps->opp));
- opp->count = count;
- opp->latency = DVFS_LATENCY(buf.header);
- opp->freqs = kmalloc(freqs_sz, GFP_KERNEL);
- if (!opp->freqs) {
- kfree(opp);
+ opps->count = count;
+ opps->latency = DVFS_LATENCY(buf.header);
+ opps->opp = kmalloc(opps_sz, GFP_KERNEL);
+ if (!opps->opp) {
+ kfree(opps);
return ERR_PTR(-ENOMEM);
}
- memcpy(opp->freqs, &buf.freqs[0], freqs_sz);
- scpi_opps[domain] = opp;
+ memcpy(opps->opp, &buf.opp[0], opps_sz);
+ scpi_opps[domain] = opps;
- return opp;
+ return opps;
}
EXPORT_SYMBOL_GPL(scpi_dvfs_get_opps);
*/
#include <linux/types.h>
+struct scpi_opp_entry {
+ u32 freq_hz;
+ u32 volt_mv;
+} __packed;
+
struct scpi_opp {
- u32 *freqs;
+ struct scpi_opp_entry *opp;
u32 latency; /* in usecs */
int count;
-};
+} __packed;
unsigned long scpi_clk_get_val(u16 clk_id);
int scpi_clk_set_val(u16 clk_id, unsigned long rate);