diff options
-rw-r--r-- | utils/hwstub/tools/init.lua | 2 | ||||
-rw-r--r-- | utils/hwstub/tools/lua/dumper.lua | 38 | ||||
-rw-r--r-- | utils/hwstub/tools/lua/load.lua | 1 | ||||
-rw-r--r-- | utils/hwstub/tools/lua/stmp.lua | 1 | ||||
-rw-r--r-- | utils/hwstub/tools/lua/stmp/clkctrl.lua | 174 |
5 files changed, 215 insertions, 1 deletions
diff --git a/utils/hwstub/tools/init.lua b/utils/hwstub/tools/init.lua index 97d393dab1..74f610a2ee 100644 --- a/utils/hwstub/tools/init.lua +++ b/utils/hwstub/tools/init.lua | |||
@@ -44,7 +44,7 @@ do | |||
44 | 44 | ||
45 | h = HELP:create_topic("HW"); | 45 | h = HELP:create_topic("HW"); |
46 | h:add("This variable redirects to the current soc under hwstub.soc and should be changed by calling hwstub:soc:select only."); | 46 | h:add("This variable redirects to the current soc under hwstub.soc and should be changed by calling hwstub:soc:select only."); |
47 | h:add("The complete register tree can be found under HW in a well organise fashion."); | 47 | h:add("The complete register tree can be found under HW in a well organised fashion."); |
48 | h:add("* HW.dev points to device dev"); | 48 | h:add("* HW.dev points to device dev"); |
49 | h:add("* HW.dev[i] points to device devi if there are several copies of the device at different addresses."); | 49 | h:add("* HW.dev[i] points to device devi if there are several copies of the device at different addresses."); |
50 | h:add("* HW.dev.reg points to the register reg under dev"); | 50 | h:add("* HW.dev.reg points to the register reg under dev"); |
diff --git a/utils/hwstub/tools/lua/dumper.lua b/utils/hwstub/tools/lua/dumper.lua new file mode 100644 index 0000000000..51d9bc7ecc --- /dev/null +++ b/utils/hwstub/tools/lua/dumper.lua | |||
@@ -0,0 +1,38 @@ | |||
1 | DUMPER = {} | ||
2 | |||
3 | local h = HELP:create_topic("DUMPER") | ||
4 | h:add("This table contains some tools to dump the registers from the device to a file.") | ||
5 | |||
6 | local hh = h:create_topic("dump_all") | ||
7 | hh:add("The DUMPER.dump_all(file) function dumps all the registers under HW to a file.") | ||
8 | hh:add("If the argument is a string, the function will interpret it as a path.") | ||
9 | hh:add("Otherwise it will be interpreted as an object returned by io.open") | ||
10 | |||
11 | function DUMPER.dump_all_reg(prefix, hw, f) | ||
12 | for reg, tabl in pairs(hw) do | ||
13 | if type(reg) == "string" and type(tabl) == "table" and tabl.read ~= nil then | ||
14 | f:write(string.format("%s%s = %#08x\n", prefix, tabl.name, tabl.read())) | ||
15 | end | ||
16 | end | ||
17 | end | ||
18 | |||
19 | function DUMPER.dump_all_dev(prefix, hw, f) | ||
20 | for block, tabl in pairs(hw) do | ||
21 | if type(block) == "string" and type(tabl) == "table" then | ||
22 | DUMPER.dump_all_reg(prefix .. block .. ".", tabl, f) | ||
23 | end | ||
24 | end | ||
25 | end | ||
26 | |||
27 | function DUMPER.dump_all(file) | ||
28 | local f = file | ||
29 | if type(file) == "string" then | ||
30 | f = io.open(file, "w") | ||
31 | end | ||
32 | if f == nil then error("Cannot open file or write to nil") end | ||
33 | f:write(string.format("HW = %s\n", HW.name)) | ||
34 | DUMPER.dump_all_dev("HW.", HW, f) | ||
35 | if type(file) == "string" then | ||
36 | io.close(f) | ||
37 | end | ||
38 | end \ No newline at end of file | ||
diff --git a/utils/hwstub/tools/lua/load.lua b/utils/hwstub/tools/lua/load.lua index a6f453d667..133105a645 100644 --- a/utils/hwstub/tools/lua/load.lua +++ b/utils/hwstub/tools/lua/load.lua | |||
@@ -1,3 +1,4 @@ | |||
1 | package.path = string.sub(string.gsub(debug.getinfo(1).source, "load.lua", "?.lua"),2) .. ";" .. package.path | 1 | package.path = string.sub(string.gsub(debug.getinfo(1).source, "load.lua", "?.lua"),2) .. ";" .. package.path |
2 | 2 | ||
3 | require "stmp" | 3 | require "stmp" |
4 | require "dumper" \ No newline at end of file | ||
diff --git a/utils/hwstub/tools/lua/stmp.lua b/utils/hwstub/tools/lua/stmp.lua index 8f93b86c46..18cb59d72d 100644 --- a/utils/hwstub/tools/lua/stmp.lua +++ b/utils/hwstub/tools/lua/stmp.lua | |||
@@ -75,4 +75,5 @@ if STMP.info.chip ~= nil then | |||
75 | require "stmp/pinctrl" | 75 | require "stmp/pinctrl" |
76 | require "stmp/lcdif" | 76 | require "stmp/lcdif" |
77 | require "stmp/pwm" | 77 | require "stmp/pwm" |
78 | require "stmp/clkctrl" | ||
78 | end \ No newline at end of file | 79 | end \ No newline at end of file |
diff --git a/utils/hwstub/tools/lua/stmp/clkctrl.lua b/utils/hwstub/tools/lua/stmp/clkctrl.lua new file mode 100644 index 0000000000..a6b84f9f64 --- /dev/null +++ b/utils/hwstub/tools/lua/stmp/clkctrl.lua | |||
@@ -0,0 +1,174 @@ | |||
1 | --- | ||
2 | --- DIGCTL | ||
3 | --- | ||
4 | STMP.clkctrl = {} | ||
5 | |||
6 | local h = HELP:get_topic("STMP"):create_topic("clkctrl") | ||
7 | h:add("The STMP.clkctrl table handles the clkctrl device for all STMPs.") | ||
8 | |||
9 | local hh = h:create_topic("list_all") | ||
10 | hh:add("The STMP.clkctrl.list_all() function returns the list of all clocks names.") | ||
11 | |||
12 | local hh = h:create_topic("is_enabled") | ||
13 | hh:add("The STMP.clkctrl.is_enabled(clk) function returns the state of the clock gate or true is there is none.") | ||
14 | hh:add("Note that some clock is disabled though other means than a clock gate (divider gate).") | ||
15 | |||
16 | local hh = h:create_topic("is_enabled") | ||
17 | hh:add("The STMP.clkctrl.is_enabled(clk) function returns the state of the clock gate or true is there is none.") | ||
18 | hh:add("Note that some clock is disabled though other means than a clock gate (divider gate).") | ||
19 | |||
20 | local hh = h:create_topic("get_div") | ||
21 | hh:add("The STMP.clkctrl.get_div(clk) function returns the integer divider of the clock or 1 if there is none.") | ||
22 | |||
23 | local hh = h:create_topic("get_frac_div") | ||
24 | hh:add("The STMP.clkctrl.get_frac_div(clk) function returns the fractional divider of the clock gate or 1 is there is none.") | ||
25 | hh:add("Note that the effect of a fractional divider might depend on other fields or on the clock itself.") | ||
26 | |||
27 | local hh = h:create_topic("get_bypass") | ||
28 | hh:add("The STMP.clkctrl.get_bypass(clk) function returns the state of the PLL bypass of the clock or false if there is none.") | ||
29 | |||
30 | local hh = h:create_topic("get_freq") | ||
31 | hh:add("The STMP.clkctrl.get_frac(clk) function returns the frequency of the clock in HZ, or 0 if it is disabled.") | ||
32 | |||
33 | function STMP.clkctrl.list_all() | ||
34 | local list = {"clk_pll", "clk_xtal", "clk_io", "clk_cpu", "clk_hbus", "clk_ssp", | ||
35 | "clk_emi", "clk_xbus", "clk_filt", "clk_dri", "clk_pwm", "clk_timrot", | ||
36 | "clk_uart"} | ||
37 | if hwstub.dev.stmp.chipid >= 0x3700 then | ||
38 | table.insert(list, "clk_pix") | ||
39 | end | ||
40 | return list | ||
41 | end | ||
42 | |||
43 | function STMP.clkctrl.is_enabled(clk) | ||
44 | if clk == "clk_pll" then return HW.CLKCTRL.PLLCTRL0.POWER.read() == 1 | ||
45 | elseif clk == "clk_pix" then return HW.CLKCTRL.PIX.CLKGATE.read() == 0 | ||
46 | elseif clk == "clk_ssp" then return HW.CLKCTRL.SSP.CLKGATE.read() == 0 | ||
47 | elseif clk == "clk_dri" then return HW.CLKCTRL.XTAL.DRI_CLK24M_GATE.read() == 0 | ||
48 | elseif clk == "clk_pwm" then return HW.CLKCTRL.XTAL.PWM_CLK24M_GATE.read() == 0 | ||
49 | elseif clk == "clk_uart" then return HW.CLKCTRL.XTAL.UART_CLK24M_GATE.read() == 0 | ||
50 | elseif clk == "clk_filt" then return HW.CLKCTRL.XTAL.FILT_CLK24M_GATE.read() == 0 | ||
51 | elseif clk == "clk_timrot" then return HW.CLKCTRL.XTAL.TIMROT_CLK24M_GATE.read() == 0 | ||
52 | else return true end | ||
53 | end | ||
54 | |||
55 | function STMP.clkctrl.get_div(clk) | ||
56 | if hwstub.dev.stmp.chipid >= 0x3700 then | ||
57 | if clk == "clk_pix" then return HW.CLKCTRL.PIX.DIV.read() | ||
58 | elseif clk == "clk_cpu" then return HW.CLKCTRL.CPU.DIV_CPU.read() | ||
59 | elseif clk == "clk_emi" then return HW.CLKCTRL.EMI.DIV_EMI.read() end | ||
60 | else | ||
61 | if clk == "clk_cpu" then return HW.CLKCTRL.CPU.DIV.read() | ||
62 | elseif clk == "clk_emi" then return HW.CLKCTRL.EMI.DIV.read() end | ||
63 | end | ||
64 | if clk == "clk_ssp" then return HW.CLKCTRL.SSP.DIV.read() | ||
65 | elseif clk == "clk_hbus" then return HW.CLKCTRL.HBUS.DIV.read() | ||
66 | elseif clk == "clk_xbus" then return HW.CLKCTRL.XBUS.read() | ||
67 | else return 0 end | ||
68 | end | ||
69 | |||
70 | function STMP.clkctrl.get_frac_div(clk) | ||
71 | local name = nil | ||
72 | if hwstub.dev.stmp.chipid >= 0x3700 and clk == "clk_pix" then name = "PIX" | ||
73 | elseif clk == "clk_io" then name = "IO" | ||
74 | elseif clk == "clk_cpu" then name = "CPU" | ||
75 | elseif clk == "clk_emi" then name = "EMI" | ||
76 | else return 0 end | ||
77 | |||
78 | if name == nil then return 0 end | ||
79 | if HW.CLKCTRL.FRAC["CLKGATE" .. name].read() == 1 then return 0 | ||
80 | else return HW.CLKCTRL.FRAC[name .. "FRAC"].read() end | ||
81 | end | ||
82 | |||
83 | function STMP.clkctrl.get_bypass(clk) | ||
84 | if hwstub.dev.stmp.chipid >= 0x3700 and clk == "clk_pix" then return HW.CLKCTRL.CLKSEQ.BYPASS_PIX.read() == 1 | ||
85 | elseif clk == "clk_ssp" then return HW.CLKCTRL.CLKSEQ.BYPASS_SSP.read() == 1 | ||
86 | elseif clk == "clk_cpu" then return HW.CLKCTRL.CLKSEQ.BYPASS_CPU.read() == 1 | ||
87 | elseif clk == "clk_emi" then return HW.CLKCTRL.CLKSEQ.BYPASS_EMI.read() == 1 | ||
88 | else return false end | ||
89 | end | ||
90 | |||
91 | function STMP.clkctrl.get_freq(clk) | ||
92 | if clk == "clk_pll" then | ||
93 | return STMP.clkctrl.is_enabled(clk) and 480000000 or 0 | ||
94 | elseif clk == "clk_xtal" then return 24000000 | ||
95 | elseif clk == "clk_cpu" then | ||
96 | if hwstub.dev.stmp.chipid >= 0x3700 then | ||
97 | if STMP.clkctrl.get_bypass(clk) then | ||
98 | local ref = STMP.clkctrl.get_freq("clk_xtal") | ||
99 | if HW.CLKCTRL.CPU.DIV_XTAL_FRAC_EN.read() == 1 then | ||
100 | return ref * HW.CLKCTRL.CPU.DIV_XTAL.read() / 32 | ||
101 | else | ||
102 | return ref / STMP.clkctrl.get_div(clk) | ||
103 | end | ||
104 | else | ||
105 | local ref = STMP.clkctrl.get_freq("clk_pll") | ||
106 | if STMP.clkctrl.get_frac_div(clk) ~= 0 then | ||
107 | ref = ref * 18 / STMP.clkctrl.get_frac_div(clk) | ||
108 | end | ||
109 | return ref / STMP.clkctrl.get_div(clk) | ||
110 | end | ||
111 | else | ||
112 | return STMP.CLKCTRL.get_freq("clk_pll") / STMP.clkctrl.get_div(clk) | ||
113 | end | ||
114 | elseif clk == "clk_hbus" then | ||
115 | local ref = STMP.clkctrl.get_freq("clk_cpu") | ||
116 | if hwstub.dev.stmp.chipid >= 0x3700 and STMP.clkctrl.get_frac_div(clk) ~= 0 then | ||
117 | ref = ref * STMP.clkctrl.get_frac_div(clk) / 32 | ||
118 | end | ||
119 | if STMP.clkctrl.get_div(clk) ~= 0 then | ||
120 | ref = ref / STMP.clkctrl.get_div(clk) | ||
121 | end | ||
122 | return ref | ||
123 | elseif clk == "clk_io" then | ||
124 | local ref = STMP.clkctrl.get_freq("clk_pll") | ||
125 | if hwstub.dev.stmp.chipid >= 0x3700 and STMP.clkctrl.get_frac_div(clk) ~= 0 then | ||
126 | ref = ref * 18 / STMP.clkctrl.get_frac_div(clk) | ||
127 | end | ||
128 | return ref | ||
129 | elseif hwstub.dev.stmp.chipid >= 0x3700 and clk == "clk_pix" then | ||
130 | local ref = nil | ||
131 | if not STMP.clkctrl.is_enabled(clk) then | ||
132 | ref = 0 | ||
133 | elseif STMP.clkctrl.get_bypass(clk) then | ||
134 | ref = STMP.clkctrl.get_freq("clk_xtal") | ||
135 | else | ||
136 | ref = STMP.clkctrl.get_freq("clk_pll") | ||
137 | if STMP.clkctrl.get_frac_div(clk) ~= 0 then | ||
138 | ref = ref * 18 / STMP.clkctrl.get_frac_div(clk) | ||
139 | else | ||
140 | ref = 0 | ||
141 | end | ||
142 | end | ||
143 | return ref / STMP.clkctrl.get_div(clk) | ||
144 | elseif clk == "clk_ssp" then | ||
145 | local ref = nil | ||
146 | if not STMP.clkctrl.is_enabled(clk) then | ||
147 | ref = 0 | ||
148 | elseif hwstub.dev.stmp.chipid >= 0x3700 and STMP.clkctrl.get_bypass(clk) then | ||
149 | ref = STMP.clkctrl.get_freq("clk_xtal") | ||
150 | else | ||
151 | ref = STMP.clkctrl.get_freq("clk_io") | ||
152 | end | ||
153 | return ref / STMP.clkctrl.get_div(clk) | ||
154 | elseif clk == "clk_emi" then | ||
155 | if hwstub.dev.stmp.chipid >= 0x3700 then | ||
156 | if STMP.clkctrl.get_bypass("clk_emi") then | ||
157 | if HW.CLKCTRL.EMI.CLKGATE.read() then return 0 | ||
158 | else return STMP.clkctrl.get_freq("clk_xtal") / HW.CLKCTRL.EMI.DIV_XTAL.read() end | ||
159 | else | ||
160 | local ref = STMP.clkctrl.get_freq("clk_pll") | ||
161 | if STMP.clkctrl.get_frac_div(clk) ~= 0 then | ||
162 | ref = ref * 18 / STMP.clkctrl.get_frac_div(clk) | ||
163 | end | ||
164 | return ref / STMP.clkctrl.get_div(clk) | ||
165 | end | ||
166 | else | ||
167 | return STMP.clkctrl.get_freq("clk_pll") / STMP.clkctrl.get_div(clk); | ||
168 | end | ||
169 | elseif clk == "clk_xbus" then | ||
170 | return STMP.clkctrl.get_freq("clk_xtal") / STMP.clkctrl.get_div(clk) | ||
171 | else | ||
172 | return 0 | ||
173 | end | ||
174 | end | ||