#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cpufreq.h>
#include <linux/threads.h>
static struct cpufreq_driver *cpufreq_us2e_driver;
struct us2e_freq_percpu_info {
struct cpufreq_frequency_table table[6];
static struct us2e_freq_percpu_info *us2e_freq_table;
#define HBIRD_MEM_CNTL0_ADDR 0x1fe0000f010UL
#define HBIRD_ESTAR_MODE_ADDR 0x1fe0000f080UL
#define ESTAR_MODE_DIV_1 0x0000000000000000UL
#define ESTAR_MODE_DIV_2 0x0000000000000001UL
#define ESTAR_MODE_DIV_4 0x0000000000000003UL
#define ESTAR_MODE_DIV_6 0x0000000000000002UL
#define ESTAR_MODE_DIV_8 0x0000000000000004UL
#define ESTAR_MODE_DIV_MASK 0x0000000000000007UL
#define MCTRL0_SREFRESH_ENAB 0x0000000000010000UL
#define MCTRL0_REFR_COUNT_MASK 0x0000000000007f00UL
#define MCTRL0_REFR_COUNT_SHIFT 8
#define MCTRL0_REFR_INTERVAL 7800
#define MCTRL0_REFR_CLKS_P_CNT 64
static unsigned long read_hbreg(unsigned long addr)
__asm__ __volatile__("ldxa [%1] %2, %0"
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
static void write_hbreg(unsigned long addr, unsigned long val)
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
: "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
if (addr == HBIRD_ESTAR_MODE_ADDR) {
static void self_refresh_ctl(int enable)
unsigned long mctrl = read_hbreg(HBIRD_MEM_CNTL0_ADDR);
mctrl |= MCTRL0_SREFRESH_ENAB;
mctrl &= ~MCTRL0_SREFRESH_ENAB;
write_hbreg(HBIRD_MEM_CNTL0_ADDR, mctrl);
(void) read_hbreg(HBIRD_MEM_CNTL0_ADDR);
static void frob_mem_refresh(int cpu_slowing_down,
unsigned long clock_tick,
unsigned long old_divisor, unsigned long divisor)
unsigned long old_refr_count, refr_count, mctrl;
refr_count = (clock_tick * MCTRL0_REFR_INTERVAL);
refr_count /= (MCTRL0_REFR_CLKS_P_CNT * divisor * 1000000000UL);