static int clk_programmable_is_ready(struct clk_hw *hw) { struct clk_programmable *prog = to_clk_programmable(hw); struct at91_pmc *pmc = prog->pmc; return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_PCKR(prog->id)); }
/* * Verify that all the clocks are correct before entering * slow-clock mode. */ static int at91_pm_verify_clocks(void) { unsigned long scsr; int i; scsr = at91_sys_read(AT91_PMC_SCSR); /* USB must not be using PLLB */ if ((scsr & (AT91_PMC_UHP | AT91_PMC_UDP)) != 0) { pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); return 0; } #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS /* PCK0..PCK3 must be disabled, or configured to use clk32k */ for (i = 0; i < 4; i++) { u32 css; if ((scsr & (AT91_PMC_PCK0 << i)) == 0) continue; css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; if (css != AT91_PMC_CSS_SLOW) { pr_debug("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); return 0; } } #endif return 1; }
static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { u32 tmp; struct clk_programmable *prog = to_clk_programmable(hw); struct at91_pmc *pmc = prog->pmc; const struct clk_programmable_layout *layout = prog->layout; tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)); prog->pres = (tmp >> layout->pres_shift) & PROG_PRES_MASK; return parent_rate >> prog->pres; }
static u8 clk_programmable_get_parent(struct clk_hw *hw) { u32 tmp; u8 ret; struct clk_programmable *prog = to_clk_programmable(hw); struct at91_pmc *pmc = prog->pmc; const struct clk_programmable_layout *layout = prog->layout; tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)); prog->css = tmp & layout->css_mask; ret = prog->css; if (layout->have_slck_mck) { prog->slckmck = !!(tmp & AT91_PMC_CSSMCK_MCK); if (prog->slckmck && !ret) ret = PROG_MAX_RM9200_CSS + 1; } return ret; }
static int clk_programmable_prepare(struct clk_hw *hw) { u32 tmp; struct clk_programmable *prog = to_clk_programmable(hw); struct at91_pmc *pmc = prog->pmc; const struct clk_programmable_layout *layout = prog->layout; u8 id = prog->id; u32 mask = PROG_STATUS_MASK(id); tmp = prog->css | (prog->pres << layout->pres_shift); if (layout->have_slck_mck && prog->slckmck) tmp |= AT91_PMC_CSSMCK_MCK; pmc_write(pmc, AT91_PMC_PCKR(id), tmp); while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) wait_event(prog->wait, pmc_read(pmc, AT91_PMC_SR) & mask); return 0; }
/* * Verify that all the clocks are correct before entering * slow-clock mode. */ static int at91_pm_verify_clocks(void) { unsigned long scsr; int i; scsr = at91_pmc_read(AT91_PMC_SCSR); /* USB must not be using PLLB */ if (cpu_is_at91rm9200()) { if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) { pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); return 0; } } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) { if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) { pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); return 0; } } if (!IS_ENABLED(CONFIG_AT91_PROGRAMMABLE_CLOCKS)) return 1; /* PCK0..PCK3 must be disabled, or configured to use clk32k */ for (i = 0; i < 4; i++) { u32 css; if ((scsr & (AT91_PMC_PCK0 << i)) == 0) continue; css = at91_pmc_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; if (css != AT91_PMC_CSS_SLOW) { pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); return 0; } } return 1; }
static int at91_pm_verify_clocks(void) { unsigned long scsr; int i; scsr = at91_pmc_read(AT91_PMC_SCSR); /* */ if (cpu_is_at91rm9200()) { if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) { pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); return 0; } } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) { if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) { pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); return 0; } } #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS /* */ for (i = 0; i < 4; i++) { u32 css; if ((scsr & (AT91_PMC_PCK0 << i)) == 0) continue; css = at91_pmc_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; if (css != AT91_PMC_CSS_SLOW) { pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); return 0; } } #endif return 1; }
/* * initialize the som-9g20 for apcc. */ static void apcc_init(void) { unsigned int cnt = 10000; { /* initialize PCK1 - this is output to the FPGA as clock reference. * select PLLA as clock source (18.432 * 42) and div by 32 * 24.192 mHz. */ at91_sys_write(AT91_PMC_PCKR(1), AT91_PMC_CSS_PLLA | AT91_PMC_PRES_32); /* Enable PCK1 output */ at91_sys_write(AT91_PMC_SCER, AT91_PMC_PCK1); /* Wait for PCK1 to come ready or timeout */ while (cnt-- > 0) { volatile unsigned long scsr = at91_sys_read(AT91_PMC_SCSR); if ((scsr & AT91_PMC_PCK1RDY) != 0) { break; } } /* configure PB31 to be used as PCK1 */ at91_set_A_periph(AT91_PIN_PB31, 0); } { /* initialize sensys fpga */ /* * Configure CS0 (Chip Select 0) for FPGA (SMC @ FFFFEC00) * * SETUP - 0x1F3F1F3F * PULSE - 0x403F403F * CYCLE - 0x013E013E * MODE - 0x000F0003 */ at91_sys_write(AT91_SMC_SETUP(0), AT91_SMC_NWESETUP_(4) | AT91_SMC_NCS_WRSETUP_(4) | AT91_SMC_NRDSETUP_(4) | AT91_SMC_NCS_RDSETUP_(4)); at91_sys_write(AT91_SMC_PULSE(0), AT91_SMC_NWEPULSE_(20) | AT91_SMC_NCS_WRPULSE_(20) | AT91_SMC_NRDPULSE_(22) | AT91_SMC_NCS_RDPULSE_(22)); at91_sys_write(AT91_SMC_CYCLE(0), AT91_SMC_NWECYCLE_(35) | AT91_SMC_NRDCYCLE_(29)); at91_sys_write(AT91_SMC_MODE(0), AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8 | AT91_SMC_TDF_(1)); } { /* to conserve power, disable the AtoD of phy. */ at91_set_gpio_output(AT91_PIN_PA22, 1); } #ifdef CONFIG_HW_WATCHDOG { /* set up watchdog port */ at91_set_gpio_output(AT91_PIN_PB18, 1); WATCHDOG_RESET(); } #endif }