diff options
author | Salona Sinha <salonas@nvidia.com> | 2014-02-14 16:22:01 +0530 |
---|---|---|
committer | Nitin Kumbhar <nkumbhar@nvidia.com> | 2014-03-12 00:14:29 -0700 |
commit | 0670c42e535ba0a7a681fbd2f5a5bd24fae02aa4 (patch) | |
tree | c4cac013a49b0df309fd61ddc7940b3ef3ebbf70 | |
parent | 058a6c02bf967c13b1a08319bfb813bbce324baf (diff) |
misc: tegra: fuse: add dt support for tegra fuse
Add bindings file for tegra-fuse driver and add tegra fuse specific
read and write functions to tegra-fuse driver.
Bug 1449516
Change-Id: I1d15dd1341b27eb370fd56be0ecce40726701499
Signed-off-by: Salona Sinha <salonas@nvidia.com>
Reviewed-on: http://git-master/r/367716
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Shardar Mohammed <smohammed@nvidia.com>
Reviewed-by: Nitin Kumbhar <nkumbhar@nvidia.com>
Tested-by: Nitin Kumbhar <nkumbhar@nvidia.com>
-rw-r--r-- | Documentation/devicetree/bindings/misc/tegra-fuse.txt | 14 | ||||
-rw-r--r-- | drivers/misc/tegra-fuse/tegra_fuse.c | 62 |
2 files changed, 56 insertions, 20 deletions
diff --git a/Documentation/devicetree/bindings/misc/tegra-fuse.txt b/Documentation/devicetree/bindings/misc/tegra-fuse.txt new file mode 100644 index 000000000000..aa1ad4f9d7bc --- /dev/null +++ b/Documentation/devicetree/bindings/misc/tegra-fuse.txt @@ -0,0 +1,14 @@ +NVIDIA tegra efuse driver interface. + +Required properties: +-compatible: the driver is compatible with + "nvidia, tegra114-efuse" + "nvidia, tegra124-efuse" +-reg: Should contain tegra-fuse registers location and length. + +Example: + + efuse@7000f800 { + compatible = "nvidia,tegra114-efuse"; + reg = <0x7000f800 0x400>; + }; diff --git a/drivers/misc/tegra-fuse/tegra_fuse.c b/drivers/misc/tegra-fuse/tegra_fuse.c index 3d05b76f3f25..d243b2f8c19d 100644 --- a/drivers/misc/tegra-fuse/tegra_fuse.c +++ b/drivers/misc/tegra-fuse/tegra_fuse.c @@ -72,6 +72,8 @@ DEVICE_ATTR(aid, 0444, tegra_fuse_show, NULL); #define MINOR_ASIM_LINSIM 3 #define MINOR_DSIM_ASIM_LINSIM 4 +static void __iomem *fuse_base; + struct tegra_id { enum tegra_chipid chipid; unsigned int major, minor, netlist, patch; @@ -253,6 +255,16 @@ static struct param_info fuse_info_tbl[] = { }, }; +u32 fuse_readl(unsigned long offset) +{ + return readl(fuse_base + offset); +} + +void fuse_writel(u32 val, unsigned long offset) +{ + writel(val, fuse_base + offset); +} + bool tegra_spare_fuse(int bit) { return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4); @@ -573,7 +585,7 @@ static int get_revision(char *val, const struct kernel_param *kp) static unsigned int get_fuse_vp8_enable(char *val, struct kernel_param *kp) { - tegra_fuse_vp8_enable = tegra_fuse_readl(FUSE_VP8_ENABLE_0); + tegra_fuse_vp8_enable = fuse_readl(FUSE_VP8_ENABLE_0); return param_get_uint(val, kp); } @@ -599,7 +611,7 @@ static void wait_for_idle(void) do { udelay(1); - reg = tegra_fuse_readl(FUSE_CTRL); + reg = fuse_readl(FUSE_CTRL); } while ((reg & (0xF << 16)) != STATE_IDLE); } @@ -608,14 +620,14 @@ static u32 fuse_cmd_read(u32 addr) u32 reg; wait_for_idle(); - tegra_fuse_writel(addr, FUSE_REG_ADDR); - reg = tegra_fuse_readl(FUSE_CTRL); + fuse_writel(addr, FUSE_REG_ADDR); + reg = fuse_readl(FUSE_CTRL); reg &= ~FUSE_CMD_MASK; reg |= FUSE_READ; - tegra_fuse_writel(reg, FUSE_CTRL); + fuse_writel(reg, FUSE_CTRL); wait_for_idle(); - reg = tegra_fuse_readl(FUSE_REG_READ); + reg = fuse_readl(FUSE_REG_READ); return reg; } @@ -624,13 +636,13 @@ static void fuse_cmd_write(u32 value, u32 addr) u32 reg; wait_for_idle(); - tegra_fuse_writel(addr, FUSE_REG_ADDR); - tegra_fuse_writel(value, FUSE_REG_WRITE); + fuse_writel(addr, FUSE_REG_ADDR); + fuse_writel(value, FUSE_REG_WRITE); - reg = tegra_fuse_readl(FUSE_CTRL); + reg = fuse_readl(FUSE_CTRL); reg &= ~FUSE_CMD_MASK; reg |= FUSE_WRITE; - tegra_fuse_writel(reg, FUSE_CTRL); + fuse_writel(reg, FUSE_CTRL); wait_for_idle(); } @@ -639,10 +651,10 @@ static void fuse_cmd_sense(void) u32 reg; wait_for_idle(); - reg = tegra_fuse_readl(FUSE_CTRL); + reg = fuse_readl(FUSE_CTRL); reg &= ~FUSE_CMD_MASK; reg |= FUSE_SENSE; - tegra_fuse_writel(reg, FUSE_CTRL); + fuse_writel(reg, FUSE_CTRL); wait_for_idle(); } @@ -790,13 +802,13 @@ out: static void fuse_power_enable(void) { - tegra_fuse_writel(0x1, FUSE_PWR_GOOD_SW); + fuse_writel(0x1, FUSE_PWR_GOOD_SW); udelay(1); } static void fuse_power_disable(void) { - tegra_fuse_writel(0, FUSE_PWR_GOOD_SW); + fuse_writel(0, FUSE_PWR_GOOD_SW); udelay(1); } @@ -826,7 +838,7 @@ static void fuse_program_array(int pgm_cycles) */ if (pgm_cycles > 0) { reg = pgm_cycles; - tegra_fuse_writel(reg, FUSE_TIME_PGM2); + fuse_writel(reg, FUSE_TIME_PGM2); } fuse_val[0] = (0x1 & ~fuse_val[0]); fuse_val[1] = (0x1 & ~fuse_val[1]); @@ -883,7 +895,7 @@ static void fuse_program_array(int pgm_cycles) */ do { udelay(1); - reg = tegra_fuse_readl(FUSE_CTRL); + reg = fuse_readl(FUSE_CTRL); } while ((reg & BIT(30)) != SENSE_DONE); } @@ -1008,7 +1020,7 @@ int tegra_fuse_program(struct fuse_data *pgm_data, u32 flags) /* check that fuse options write access hasn't been disabled */ mutex_lock(&fuse_lock); - reg = tegra_fuse_readl(FUSE_DIS_PGM); + reg = fuse_readl(FUSE_DIS_PGM); mutex_unlock(&fuse_lock); if (reg) { pr_err("fuse programming disabled"); @@ -1017,7 +1029,7 @@ int tegra_fuse_program(struct fuse_data *pgm_data, u32 flags) } /* enable software writes to the fuse registers */ - tegra_fuse_writel(0, FUSE_WRITE_ACCESS); + fuse_writel(0, FUSE_WRITE_ACCESS); mutex_lock(&fuse_lock); memcpy(&fuse_info, pgm_data, sizeof(fuse_info)); @@ -1047,7 +1059,7 @@ int tegra_fuse_program(struct fuse_data *pgm_data, u32 flags) mutex_unlock(&fuse_lock); /* disable software writes to the fuse registers */ - tegra_fuse_writel(1, FUSE_WRITE_ACCESS); + fuse_writel(1, FUSE_WRITE_ACCESS); clk_disable(clk_fuse); @@ -1226,6 +1238,8 @@ MODULE_DEVICE_TABLE(of, tegra_fuse_of_match); static int tegra_fuse_probe(struct platform_device *pdev) { + struct resource *fuse_res; + #ifndef CONFIG_TEGRA_PRE_SILICON_SUPPORT /* get fuse_regulator regulator */ fuse_regulator = devm_regulator_get(&pdev->dev, TEGRA_FUSE_SUPPLY); @@ -1241,6 +1255,14 @@ static int tegra_fuse_probe(struct platform_device *pdev) } mutex_init(&fuse_lock); + fuse_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!fuse_res) { + dev_err(&pdev->dev, "no mem resource\n"); + return -EINVAL; + } + fuse_base = devm_ioremap_resource(&pdev->dev, fuse_res); + if (IS_ERR(fuse_base)) + return PTR_ERR(fuse_base); /* change fuse file permissions, if ODM production fuse is not blown */ if (!fuse_odm_prod_mode()) { @@ -1267,7 +1289,7 @@ static int tegra_fuse_probe(struct platform_device *pdev) CHK_ERR(sysfs_create_file(&pdev->dev.kobj, &dev_attr_secure_boot_key.attr)); CHK_ERR(sysfs_create_file(&pdev->dev.kobj, - &dev_attr_sw_reserved.attr)); + &dev_attr_sw_reserved.attr)); CHK_ERR(sysfs_create_file(&pdev->dev.kobj, &dev_attr_ignore_dev_sel_straps.attr)); CHK_ERR(sysfs_create_file(&pdev->dev.kobj, |