diff options
author | Alex Frid <afrid@nvidia.com> | 2014-08-23 03:59:10 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:11:03 -0400 |
commit | c3d31210f8ff706658ebacf89ee74a071ba76c8b (patch) | |
tree | 5ac3335586132aa76f0ef6168ba5f9e18f8e08dc /drivers/gpu/nvgpu/gm20b | |
parent | ef3882d8aa8b2dde43c615fd354329f9181120ae (diff) |
gpu: nvgpu: Add debugfs access to GM20b GPCPLL
Added direct read and write debugfs access to GM20b GPCPLL registers.
Change-Id: I203621906ee094991eecd5c18fd5b6c70b20a4c1
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/487314
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bo Yan <byan@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b')
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/clk_gm20b.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c index ee4103fa..74a5cb96 100644 --- a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/delay.h> /* for mdelay */ | 20 | #include <linux/delay.h> /* for mdelay */ |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/debugfs.h> | 22 | #include <linux/debugfs.h> |
23 | #include <linux/uaccess.h> | ||
23 | #include <linux/clk/tegra.h> | 24 | #include <linux/clk/tegra.h> |
24 | 25 | ||
25 | #include "gk20a/gk20a.h" | 26 | #include "gk20a/gk20a.h" |
@@ -881,6 +882,87 @@ static const struct file_operations pll_reg_fops = { | |||
881 | .release = single_release, | 882 | .release = single_release, |
882 | }; | 883 | }; |
883 | 884 | ||
885 | static int pll_reg_raw_show(struct seq_file *s, void *data) | ||
886 | { | ||
887 | struct gk20a *g = s->private; | ||
888 | u32 reg; | ||
889 | |||
890 | mutex_lock(&g->clk.clk_mutex); | ||
891 | if (!g->clk.clk_hw_on) { | ||
892 | seq_puts(s, "gk20a powered down - no access to registers\n"); | ||
893 | mutex_unlock(&g->clk.clk_mutex); | ||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | seq_puts(s, "GPCPLL REGISTERS:\n"); | ||
898 | for (reg = trim_sys_gpcpll_cfg_r(); reg <= trim_sys_gpcpll_dvfs2_r(); | ||
899 | reg += sizeof(u32)) | ||
900 | seq_printf(s, "[0x%02x] = 0x%08x\n", reg, gk20a_readl(g, reg)); | ||
901 | |||
902 | seq_puts(s, "\nGPC CLK OUT REGISTERS:\n"); | ||
903 | |||
904 | reg = trim_sys_sel_vco_r(); | ||
905 | seq_printf(s, "[0x%02x] = 0x%08x\n", reg, gk20a_readl(g, reg)); | ||
906 | reg = trim_sys_gpc2clk_out_r(); | ||
907 | seq_printf(s, "[0x%02x] = 0x%08x\n", reg, gk20a_readl(g, reg)); | ||
908 | reg = trim_sys_bypassctrl_r(); | ||
909 | seq_printf(s, "[0x%02x] = 0x%08x\n", reg, gk20a_readl(g, reg)); | ||
910 | |||
911 | mutex_unlock(&g->clk.clk_mutex); | ||
912 | return 0; | ||
913 | } | ||
914 | |||
915 | static int pll_reg_raw_open(struct inode *inode, struct file *file) | ||
916 | { | ||
917 | return single_open(file, pll_reg_raw_show, inode->i_private); | ||
918 | } | ||
919 | |||
920 | static ssize_t pll_reg_raw_write(struct file *file, | ||
921 | const char __user *userbuf, size_t count, loff_t *ppos) | ||
922 | { | ||
923 | struct gk20a *g = file->f_path.dentry->d_inode->i_private; | ||
924 | char buf[80]; | ||
925 | u32 reg, val; | ||
926 | |||
927 | if (sizeof(buf) <= count) | ||
928 | return -EINVAL; | ||
929 | |||
930 | if (copy_from_user(buf, userbuf, count)) | ||
931 | return -EFAULT; | ||
932 | |||
933 | /* terminate buffer and trim - white spaces may be appended | ||
934 | * at the end when invoked from shell command line */ | ||
935 | buf[count] = '\0'; | ||
936 | strim(buf); | ||
937 | |||
938 | if (sscanf(buf, "[0x%x] = 0x%x", ®, &val) != 2) | ||
939 | return -EINVAL; | ||
940 | |||
941 | if (((reg < trim_sys_gpcpll_cfg_r()) || | ||
942 | (reg > trim_sys_gpcpll_dvfs2_r())) && | ||
943 | (reg != trim_sys_sel_vco_r()) && | ||
944 | (reg != trim_sys_gpc2clk_out_r()) && | ||
945 | (reg != trim_sys_bypassctrl_r())) | ||
946 | return -EPERM; | ||
947 | |||
948 | mutex_lock(&g->clk.clk_mutex); | ||
949 | if (!g->clk.clk_hw_on) { | ||
950 | mutex_unlock(&g->clk.clk_mutex); | ||
951 | return -EBUSY; | ||
952 | } | ||
953 | gk20a_writel(g, reg, val); | ||
954 | mutex_unlock(&g->clk.clk_mutex); | ||
955 | return count; | ||
956 | } | ||
957 | |||
958 | static const struct file_operations pll_reg_raw_fops = { | ||
959 | .open = pll_reg_raw_open, | ||
960 | .read = seq_read, | ||
961 | .write = pll_reg_raw_write, | ||
962 | .llseek = seq_lseek, | ||
963 | .release = single_release, | ||
964 | }; | ||
965 | |||
884 | static int monitor_get(void *data, u64 *val) | 966 | static int monitor_get(void *data, u64 *val) |
885 | { | 967 | { |
886 | struct gk20a *g = (struct gk20a *)data; | 968 | struct gk20a *g = (struct gk20a *)data; |
@@ -953,6 +1035,11 @@ static int clk_gm20b_debugfs_init(struct gk20a *g) | |||
953 | if (!d) | 1035 | if (!d) |
954 | goto err_out; | 1036 | goto err_out; |
955 | 1037 | ||
1038 | d = debugfs_create_file("pll_reg_raw", | ||
1039 | S_IRUGO, platform->debugfs, g, &pll_reg_raw_fops); | ||
1040 | if (!d) | ||
1041 | goto err_out; | ||
1042 | |||
956 | d = debugfs_create_file( | 1043 | d = debugfs_create_file( |
957 | "monitor", S_IRUGO, platform->debugfs, g, &monitor_fops); | 1044 | "monitor", S_IRUGO, platform->debugfs, g, &monitor_fops); |
958 | if (!d) | 1045 | if (!d) |