uboot/arch/arm/mach-at91/clock.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2015 Atmel Corporation
   4 *                    Wenyou Yang <wenyou.yang@atmel.com>
   5 */
   6
   7#include <common.h>
   8#include <dm.h>
   9#include <wdt.h>
  10#include <asm/io.h>
  11#include <asm/arch/hardware.h>
  12#include <asm/arch/at91_pmc.h>
  13#include <asm/arch/at91_wdt.h>
  14
  15#define EN_UPLL_TIMEOUT         500
  16
  17void at91_periph_clk_enable(int id)
  18{
  19        struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
  20
  21#ifdef CPU_HAS_PCR
  22        u32 regval;
  23        u32 div_value;
  24
  25        if (id > AT91_PMC_PCR_PID_MASK)
  26                return;
  27
  28        writel(id, &pmc->pcr);
  29
  30        div_value = readl(&pmc->pcr) & AT91_PMC_PCR_DIV;
  31
  32        regval = AT91_PMC_PCR_EN | AT91_PMC_PCR_CMD_WRITE | id | div_value;
  33
  34        writel(regval, &pmc->pcr);
  35#else
  36        writel(0x01 << id, &pmc->pcer);
  37#endif
  38}
  39
  40void at91_periph_clk_disable(int id)
  41{
  42        struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
  43
  44#ifdef CPU_HAS_PCR
  45        u32 regval;
  46
  47        if (id > AT91_PMC_PCR_PID_MASK)
  48                return;
  49
  50        regval = AT91_PMC_PCR_CMD_WRITE | id;
  51
  52        writel(regval, &pmc->pcr);
  53#else
  54        writel(0x01 << id, &pmc->pcdr);
  55#endif
  56}
  57
  58void at91_system_clk_enable(int sys_clk)
  59{
  60        struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
  61
  62        writel(sys_clk, &pmc->scer);
  63}
  64
  65void at91_system_clk_disable(int sys_clk)
  66{
  67        struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
  68
  69        writel(sys_clk, &pmc->scdr);
  70}
  71
  72int at91_upll_clk_enable(void)
  73{
  74        struct at91_pmc *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
  75        ulong start_time, tmp_time;
  76
  77        if ((readl(&pmc->uckr) & AT91_PMC_UPLLEN) == AT91_PMC_UPLLEN)
  78                return 0;
  79
  80        start_time = get_timer(0);
  81        writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr);
  82        while ((readl(&pmc->sr) & AT91_PMC_LOCKU) != AT91_PMC_LOCKU) {
  83                tmp_time = get_timer(0);
  84                if ((tmp_time - start_time) > EN_UPLL_TIMEOUT) {
  85                        printf("ERROR: failed to enable UPLL\n");
  86                        return -1;
  87                }
  88        }
  89
  90        return 0;
  91}
  92
  93int at91_upll_clk_disable(void)
  94{
  95        struct at91_pmc *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
  96        ulong start_time, tmp_time;
  97
  98        start_time = get_timer(0);
  99        writel(readl(&pmc->uckr) & ~AT91_PMC_UPLLEN, &pmc->uckr);
 100        while ((readl(&pmc->sr) & AT91_PMC_LOCKU) == AT91_PMC_LOCKU) {
 101                tmp_time = get_timer(0);
 102                if ((tmp_time - start_time) > EN_UPLL_TIMEOUT) {
 103                        printf("ERROR: failed to stop UPLL\n");
 104                        return -1;
 105                }
 106        }
 107
 108        return 0;
 109}
 110
 111void at91_usb_clk_init(u32 value)
 112{
 113        struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
 114
 115        writel(value, &pmc->usb);
 116}
 117
 118void at91_pllicpr_init(u32 icpr)
 119{
 120        struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
 121
 122        writel(icpr, &pmc->pllicpr);
 123}
 124