uboot/include/asm-avr32/arch-at32ap700x/clk.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2006 Atmel Corporation
   3 *
   4 * See file CREDITS for list of people who contributed to this
   5 * project.
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License as
   9 * published by the Free Software Foundation; either version 2 of
  10 * the License, or (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 * MA 02111-1307 USA
  21 */
  22#ifndef __ASM_AVR32_ARCH_CLK_H__
  23#define __ASM_AVR32_ARCH_CLK_H__
  24
  25#include <asm/arch/chip-features.h>
  26#include <asm/arch/portmux.h>
  27
  28#ifdef CONFIG_PLL
  29#define PLL0_RATE       ((CONFIG_SYS_OSC0_HZ / CONFIG_SYS_PLL0_DIV)     \
  30                                * CONFIG_SYS_PLL0_MUL)
  31#define MAIN_CLK_RATE   PLL0_RATE
  32#else
  33#define MAIN_CLK_RATE   (CONFIG_SYS_OSC0_HZ)
  34#endif
  35
  36static inline unsigned long get_cpu_clk_rate(void)
  37{
  38        return MAIN_CLK_RATE >> CONFIG_SYS_CLKDIV_CPU;
  39}
  40static inline unsigned long get_hsb_clk_rate(void)
  41{
  42        return MAIN_CLK_RATE >> CONFIG_SYS_CLKDIV_HSB;
  43}
  44static inline unsigned long get_pba_clk_rate(void)
  45{
  46        return MAIN_CLK_RATE >> CONFIG_SYS_CLKDIV_PBA;
  47}
  48static inline unsigned long get_pbb_clk_rate(void)
  49{
  50        return MAIN_CLK_RATE >> CONFIG_SYS_CLKDIV_PBB;
  51}
  52
  53/* Accessors for specific devices. More will be added as needed. */
  54static inline unsigned long get_sdram_clk_rate(void)
  55{
  56        return get_hsb_clk_rate();
  57}
  58#ifdef AT32AP700x_CHIP_HAS_USART
  59static inline unsigned long get_usart_clk_rate(unsigned int dev_id)
  60{
  61        return get_pba_clk_rate();
  62}
  63#endif
  64#ifdef AT32AP700x_CHIP_HAS_MACB
  65static inline unsigned long get_macb_pclk_rate(unsigned int dev_id)
  66{
  67        return get_pbb_clk_rate();
  68}
  69static inline unsigned long get_macb_hclk_rate(unsigned int dev_id)
  70{
  71        return get_hsb_clk_rate();
  72}
  73#endif
  74#ifdef AT32AP700x_CHIP_HAS_MMCI
  75static inline unsigned long get_mci_clk_rate(void)
  76{
  77        return get_pbb_clk_rate();
  78}
  79#endif
  80#ifdef AT32AP700x_CHIP_HAS_SPI
  81static inline unsigned long get_spi_clk_rate(unsigned int dev_id)
  82{
  83        return get_pba_clk_rate();
  84}
  85#endif
  86#ifdef AT32AP700x_CHIP_HAS_LCDC
  87static inline unsigned long get_lcdc_clk_rate(unsigned int dev_id)
  88{
  89        return get_hsb_clk_rate();
  90}
  91#endif
  92
  93extern void clk_init(void);
  94
  95/* Board code may need the SDRAM base clock as a compile-time constant */
  96#define SDRAMC_BUS_HZ   (MAIN_CLK_RATE >> CONFIG_SYS_CLKDIV_HSB)
  97
  98/* Generic clock control */
  99enum gclk_parent {
 100        GCLK_PARENT_OSC0 = 0,
 101        GCLK_PARENT_OSC1 = 1,
 102        GCLK_PARENT_PLL0 = 2,
 103        GCLK_PARENT_PLL1 = 3,
 104};
 105
 106/* Some generic clocks have specific roles */
 107#define GCLK_DAC_SAMPLE_CLK     6
 108#define GCLK_LCDC_PIXCLK        7
 109
 110extern unsigned long __gclk_set_rate(unsigned int id, enum gclk_parent parent,
 111                unsigned long rate, unsigned long parent_rate);
 112
 113/**
 114 * gclk_set_rate - configure and enable a generic clock
 115 * @id: Which GCLK[id] to enable
 116 * @parent: Parent clock feeding the GCLK
 117 * @rate: Target rate of the GCLK in Hz
 118 *
 119 * Returns the actual GCLK rate in Hz, after rounding to the nearest
 120 * supported rate.
 121 *
 122 * All three parameters are usually constant, hence the inline.
 123 */
 124static inline unsigned long gclk_set_rate(unsigned int id,
 125                enum gclk_parent parent, unsigned long rate)
 126{
 127        unsigned long parent_rate;
 128
 129        if (id > 7)
 130                return 0;
 131
 132        switch (parent) {
 133        case GCLK_PARENT_OSC0:
 134                parent_rate = CONFIG_SYS_OSC0_HZ;
 135                break;
 136#ifdef CONFIG_SYS_OSC1_HZ
 137        case GCLK_PARENT_OSC1:
 138                parent_rate = CONFIG_SYS_OSC1_HZ;
 139                break;
 140#endif
 141#ifdef PLL0_RATE
 142        case GCLK_PARENT_PLL0:
 143                parent_rate = PLL0_RATE;
 144                break;
 145#endif
 146#ifdef PLL1_RATE
 147        case GCLK_PARENT_PLL1:
 148                parent_rate = PLL1_RATE;
 149                break;
 150#endif
 151        default:
 152                parent_rate = 0;
 153                break;
 154        }
 155
 156        return __gclk_set_rate(id, parent, rate, parent_rate);
 157}
 158
 159/**
 160 * gclk_enable_output - enable output on a GCLK pin
 161 * @id: Which GCLK[id] pin to enable
 162 * @drive_strength: Drive strength of external GCLK pin, if applicable
 163 */
 164static inline void gclk_enable_output(unsigned int id,
 165                unsigned long drive_strength)
 166{
 167        switch (id) {
 168        case 0:
 169                portmux_select_peripheral(PORTMUX_PORT_A, 1 << 30,
 170                                PORTMUX_FUNC_A, drive_strength);
 171                break;
 172        case 1:
 173                portmux_select_peripheral(PORTMUX_PORT_A, 1 << 31,
 174                                PORTMUX_FUNC_A, drive_strength);
 175                break;
 176        case 2:
 177                portmux_select_peripheral(PORTMUX_PORT_B, 1 << 19,
 178                                PORTMUX_FUNC_A, drive_strength);
 179                break;
 180        case 3:
 181                portmux_select_peripheral(PORTMUX_PORT_B, 1 << 29,
 182                                PORTMUX_FUNC_A, drive_strength);
 183                break;
 184        case 4:
 185                portmux_select_peripheral(PORTMUX_PORT_B, 1 << 30,
 186                                PORTMUX_FUNC_A, drive_strength);
 187                break;
 188        }
 189}
 190
 191#endif /* __ASM_AVR32_ARCH_CLK_H__ */
 192