From 1b1692ff06a563db90e812a4edf8c1434bc4976d Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Sun, 11 Aug 2013 19:18:58 +0200 Subject: hwstub: add stmp clkctrl code and generic register dumper Change-Id: I432853fb4171f07ed23b73dc0499814fe8ce8748 --- utils/hwstub/tools/init.lua | 2 +- utils/hwstub/tools/lua/dumper.lua | 38 +++++++ utils/hwstub/tools/lua/load.lua | 1 + utils/hwstub/tools/lua/stmp.lua | 1 + utils/hwstub/tools/lua/stmp/clkctrl.lua | 174 ++++++++++++++++++++++++++++++++ 5 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 utils/hwstub/tools/lua/dumper.lua create mode 100644 utils/hwstub/tools/lua/stmp/clkctrl.lua (limited to 'utils/hwstub') 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 h = HELP:create_topic("HW"); h:add("This variable redirects to the current soc under hwstub.soc and should be changed by calling hwstub:soc:select only."); - h:add("The complete register tree can be found under HW in a well organise fashion."); + h:add("The complete register tree can be found under HW in a well organised fashion."); h:add("* HW.dev points to device dev"); h:add("* HW.dev[i] points to device devi if there are several copies of the device at different addresses."); 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 @@ +DUMPER = {} + +local h = HELP:create_topic("DUMPER") +h:add("This table contains some tools to dump the registers from the device to a file.") + +local hh = h:create_topic("dump_all") +hh:add("The DUMPER.dump_all(file) function dumps all the registers under HW to a file.") +hh:add("If the argument is a string, the function will interpret it as a path.") +hh:add("Otherwise it will be interpreted as an object returned by io.open") + +function DUMPER.dump_all_reg(prefix, hw, f) + for reg, tabl in pairs(hw) do + if type(reg) == "string" and type(tabl) == "table" and tabl.read ~= nil then + f:write(string.format("%s%s = %#08x\n", prefix, tabl.name, tabl.read())) + end + end +end + +function DUMPER.dump_all_dev(prefix, hw, f) + for block, tabl in pairs(hw) do + if type(block) == "string" and type(tabl) == "table" then + DUMPER.dump_all_reg(prefix .. block .. ".", tabl, f) + end + end +end + +function DUMPER.dump_all(file) + local f = file + if type(file) == "string" then + f = io.open(file, "w") + end + if f == nil then error("Cannot open file or write to nil") end + f:write(string.format("HW = %s\n", HW.name)) + DUMPER.dump_all_dev("HW.", HW, f) + if type(file) == "string" then + io.close(f) + end +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 @@ package.path = string.sub(string.gsub(debug.getinfo(1).source, "load.lua", "?.lua"),2) .. ";" .. package.path require "stmp" +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 require "stmp/pinctrl" require "stmp/lcdif" require "stmp/pwm" + require "stmp/clkctrl" 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 @@ +--- +--- DIGCTL +--- +STMP.clkctrl = {} + +local h = HELP:get_topic("STMP"):create_topic("clkctrl") +h:add("The STMP.clkctrl table handles the clkctrl device for all STMPs.") + +local hh = h:create_topic("list_all") +hh:add("The STMP.clkctrl.list_all() function returns the list of all clocks names.") + +local hh = h:create_topic("is_enabled") +hh:add("The STMP.clkctrl.is_enabled(clk) function returns the state of the clock gate or true is there is none.") +hh:add("Note that some clock is disabled though other means than a clock gate (divider gate).") + +local hh = h:create_topic("is_enabled") +hh:add("The STMP.clkctrl.is_enabled(clk) function returns the state of the clock gate or true is there is none.") +hh:add("Note that some clock is disabled though other means than a clock gate (divider gate).") + +local hh = h:create_topic("get_div") +hh:add("The STMP.clkctrl.get_div(clk) function returns the integer divider of the clock or 1 if there is none.") + +local hh = h:create_topic("get_frac_div") +hh:add("The STMP.clkctrl.get_frac_div(clk) function returns the fractional divider of the clock gate or 1 is there is none.") +hh:add("Note that the effect of a fractional divider might depend on other fields or on the clock itself.") + +local hh = h:create_topic("get_bypass") +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.") + +local hh = h:create_topic("get_freq") +hh:add("The STMP.clkctrl.get_frac(clk) function returns the frequency of the clock in HZ, or 0 if it is disabled.") + +function STMP.clkctrl.list_all() + local list = {"clk_pll", "clk_xtal", "clk_io", "clk_cpu", "clk_hbus", "clk_ssp", + "clk_emi", "clk_xbus", "clk_filt", "clk_dri", "clk_pwm", "clk_timrot", + "clk_uart"} + if hwstub.dev.stmp.chipid >= 0x3700 then + table.insert(list, "clk_pix") + end + return list +end + +function STMP.clkctrl.is_enabled(clk) + if clk == "clk_pll" then return HW.CLKCTRL.PLLCTRL0.POWER.read() == 1 + elseif clk == "clk_pix" then return HW.CLKCTRL.PIX.CLKGATE.read() == 0 + elseif clk == "clk_ssp" then return HW.CLKCTRL.SSP.CLKGATE.read() == 0 + elseif clk == "clk_dri" then return HW.CLKCTRL.XTAL.DRI_CLK24M_GATE.read() == 0 + elseif clk == "clk_pwm" then return HW.CLKCTRL.XTAL.PWM_CLK24M_GATE.read() == 0 + elseif clk == "clk_uart" then return HW.CLKCTRL.XTAL.UART_CLK24M_GATE.read() == 0 + elseif clk == "clk_filt" then return HW.CLKCTRL.XTAL.FILT_CLK24M_GATE.read() == 0 + elseif clk == "clk_timrot" then return HW.CLKCTRL.XTAL.TIMROT_CLK24M_GATE.read() == 0 + else return true end +end + +function STMP.clkctrl.get_div(clk) + if hwstub.dev.stmp.chipid >= 0x3700 then + if clk == "clk_pix" then return HW.CLKCTRL.PIX.DIV.read() + elseif clk == "clk_cpu" then return HW.CLKCTRL.CPU.DIV_CPU.read() + elseif clk == "clk_emi" then return HW.CLKCTRL.EMI.DIV_EMI.read() end + else + if clk == "clk_cpu" then return HW.CLKCTRL.CPU.DIV.read() + elseif clk == "clk_emi" then return HW.CLKCTRL.EMI.DIV.read() end + end + if clk == "clk_ssp" then return HW.CLKCTRL.SSP.DIV.read() + elseif clk == "clk_hbus" then return HW.CLKCTRL.HBUS.DIV.read() + elseif clk == "clk_xbus" then return HW.CLKCTRL.XBUS.read() + else return 0 end +end + +function STMP.clkctrl.get_frac_div(clk) + local name = nil + if hwstub.dev.stmp.chipid >= 0x3700 and clk == "clk_pix" then name = "PIX" + elseif clk == "clk_io" then name = "IO" + elseif clk == "clk_cpu" then name = "CPU" + elseif clk == "clk_emi" then name = "EMI" + else return 0 end + + if name == nil then return 0 end + if HW.CLKCTRL.FRAC["CLKGATE" .. name].read() == 1 then return 0 + else return HW.CLKCTRL.FRAC[name .. "FRAC"].read() end +end + +function STMP.clkctrl.get_bypass(clk) + if hwstub.dev.stmp.chipid >= 0x3700 and clk == "clk_pix" then return HW.CLKCTRL.CLKSEQ.BYPASS_PIX.read() == 1 + elseif clk == "clk_ssp" then return HW.CLKCTRL.CLKSEQ.BYPASS_SSP.read() == 1 + elseif clk == "clk_cpu" then return HW.CLKCTRL.CLKSEQ.BYPASS_CPU.read() == 1 + elseif clk == "clk_emi" then return HW.CLKCTRL.CLKSEQ.BYPASS_EMI.read() == 1 + else return false end +end + +function STMP.clkctrl.get_freq(clk) + if clk == "clk_pll" then + return STMP.clkctrl.is_enabled(clk) and 480000000 or 0 + elseif clk == "clk_xtal" then return 24000000 + elseif clk == "clk_cpu" then + if hwstub.dev.stmp.chipid >= 0x3700 then + if STMP.clkctrl.get_bypass(clk) then + local ref = STMP.clkctrl.get_freq("clk_xtal") + if HW.CLKCTRL.CPU.DIV_XTAL_FRAC_EN.read() == 1 then + return ref * HW.CLKCTRL.CPU.DIV_XTAL.read() / 32 + else + return ref / STMP.clkctrl.get_div(clk) + end + else + local ref = STMP.clkctrl.get_freq("clk_pll") + if STMP.clkctrl.get_frac_div(clk) ~= 0 then + ref = ref * 18 / STMP.clkctrl.get_frac_div(clk) + end + return ref / STMP.clkctrl.get_div(clk) + end + else + return STMP.CLKCTRL.get_freq("clk_pll") / STMP.clkctrl.get_div(clk) + end + elseif clk == "clk_hbus" then + local ref = STMP.clkctrl.get_freq("clk_cpu") + if hwstub.dev.stmp.chipid >= 0x3700 and STMP.clkctrl.get_frac_div(clk) ~= 0 then + ref = ref * STMP.clkctrl.get_frac_div(clk) / 32 + end + if STMP.clkctrl.get_div(clk) ~= 0 then + ref = ref / STMP.clkctrl.get_div(clk) + end + return ref + elseif clk == "clk_io" then + local ref = STMP.clkctrl.get_freq("clk_pll") + if hwstub.dev.stmp.chipid >= 0x3700 and STMP.clkctrl.get_frac_div(clk) ~= 0 then + ref = ref * 18 / STMP.clkctrl.get_frac_div(clk) + end + return ref + elseif hwstub.dev.stmp.chipid >= 0x3700 and clk == "clk_pix" then + local ref = nil + if not STMP.clkctrl.is_enabled(clk) then + ref = 0 + elseif STMP.clkctrl.get_bypass(clk) then + ref = STMP.clkctrl.get_freq("clk_xtal") + else + ref = STMP.clkctrl.get_freq("clk_pll") + if STMP.clkctrl.get_frac_div(clk) ~= 0 then + ref = ref * 18 / STMP.clkctrl.get_frac_div(clk) + else + ref = 0 + end + end + return ref / STMP.clkctrl.get_div(clk) + elseif clk == "clk_ssp" then + local ref = nil + if not STMP.clkctrl.is_enabled(clk) then + ref = 0 + elseif hwstub.dev.stmp.chipid >= 0x3700 and STMP.clkctrl.get_bypass(clk) then + ref = STMP.clkctrl.get_freq("clk_xtal") + else + ref = STMP.clkctrl.get_freq("clk_io") + end + return ref / STMP.clkctrl.get_div(clk) + elseif clk == "clk_emi" then + if hwstub.dev.stmp.chipid >= 0x3700 then + if STMP.clkctrl.get_bypass("clk_emi") then + if HW.CLKCTRL.EMI.CLKGATE.read() then return 0 + else return STMP.clkctrl.get_freq("clk_xtal") / HW.CLKCTRL.EMI.DIV_XTAL.read() end + else + local ref = STMP.clkctrl.get_freq("clk_pll") + if STMP.clkctrl.get_frac_div(clk) ~= 0 then + ref = ref * 18 / STMP.clkctrl.get_frac_div(clk) + end + return ref / STMP.clkctrl.get_div(clk) + end + else + return STMP.clkctrl.get_freq("clk_pll") / STMP.clkctrl.get_div(clk); + end + elseif clk == "clk_xbus" then + return STMP.clkctrl.get_freq("clk_xtal") / STMP.clkctrl.get_div(clk) + else + return 0 + end +end -- cgit v1.2.3