Skip to content

Commit

Permalink
cpufreq: imx6q: read OCOTP through nvmem for imx6ul/imx6ull
Browse files Browse the repository at this point in the history
On i.MX6UL/i.MX6ULL, accessing OCOTP directly is wrong because
the ocotp clock needs to be enabled first. Add support for reading
OCOTP through the nvmem API, and keep the old method there to
support old dtb.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Anson-Huang authored and rafaeljw committed Oct 8, 2018
1 parent 9d21d33 commit 2733fb0
Showing 1 changed file with 35 additions and 17 deletions.
52 changes: 35 additions & 17 deletions drivers/cpufreq/imx6q-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/cpu_cooling.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/pm_opp.h>
Expand Down Expand Up @@ -290,20 +291,32 @@ static void imx6q_opp_check_speed_grading(struct device *dev)
#define OCOTP_CFG3_6ULL_SPEED_792MHZ 0x2
#define OCOTP_CFG3_6ULL_SPEED_900MHZ 0x3

static void imx6ul_opp_check_speed_grading(struct device *dev)
static int imx6ul_opp_check_speed_grading(struct device *dev)
{
struct device_node *np;
void __iomem *base;
u32 val;
int ret = 0;

np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-ocotp");
if (!np)
return;
if (of_find_property(dev->of_node, "nvmem-cells", NULL)) {
ret = nvmem_cell_read_u32(dev, "speed_grade", &val);
if (ret)
return ret;
} else {
struct device_node *np;
void __iomem *base;

np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-ocotp");
if (!np)
return -ENOENT;

base = of_iomap(np, 0);
of_node_put(np);
if (!base) {
dev_err(dev, "failed to map ocotp\n");
return -EFAULT;
}

base = of_iomap(np, 0);
if (!base) {
dev_err(dev, "failed to map ocotp\n");
goto put_node;
val = readl_relaxed(base + OCOTP_CFG3);
iounmap(base);
}

/*
Expand All @@ -314,7 +327,6 @@ static void imx6ul_opp_check_speed_grading(struct device *dev)
* 2b'11: 900000000Hz on i.MX6ULL only;
* We need to set the max speed of ARM according to fuse map.
*/
val = readl_relaxed(base + OCOTP_CFG3);
val >>= OCOTP_CFG3_SPEED_SHIFT;
val &= 0x3;

Expand All @@ -334,9 +346,7 @@ static void imx6ul_opp_check_speed_grading(struct device *dev)
dev_warn(dev, "failed to disable 900MHz OPP\n");
}

iounmap(base);
put_node:
of_node_put(np);
return ret;
}

static int imx6q_cpufreq_probe(struct platform_device *pdev)
Expand Down Expand Up @@ -394,10 +404,18 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
}

if (of_machine_is_compatible("fsl,imx6ul") ||
of_machine_is_compatible("fsl,imx6ull"))
imx6ul_opp_check_speed_grading(cpu_dev);
else
of_machine_is_compatible("fsl,imx6ull")) {
ret = imx6ul_opp_check_speed_grading(cpu_dev);
if (ret == -EPROBE_DEFER)
return ret;
if (ret) {
dev_err(cpu_dev, "failed to read ocotp: %d\n",
ret);
return ret;
}
} else {
imx6q_opp_check_speed_grading(cpu_dev);
}

/* Because we have added the OPPs here, we must free them */
free_opp = true;
Expand Down

0 comments on commit 2733fb0

Please sign in to comment.