linux/arch/mips/lantiq/xway/clk.c
<<
>>
Prefs
   1/*
   2 *  This program is free software; you can redistribute it and/or modify it
   3 *  under the terms of the GNU General Public License version 2 as published
   4 *  by the Free Software Foundation.
   5 *
   6 *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
   7 */
   8
   9#include <linux/io.h>
  10#include <linux/export.h>
  11#include <linux/init.h>
  12#include <linux/clk.h>
  13
  14#include <asm/time.h>
  15#include <asm/irq.h>
  16#include <asm/div64.h>
  17
  18#include <lantiq_soc.h>
  19
  20#include "../clk.h"
  21
  22static unsigned int ram_clocks[] = {
  23        CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
  24#define DDR_HZ ram_clocks[ltq_cgu_r32(CGU_SYS) & 0x3]
  25
  26/* legacy xway clock */
  27#define CGU_SYS                 0x10
  28
  29/* vr9 clock */
  30#define CGU_SYS_VR9             0x0c
  31#define CGU_IF_CLK_VR9          0x24
  32
  33unsigned long ltq_danube_fpi_hz(void)
  34{
  35        unsigned long ddr_clock = DDR_HZ;
  36
  37        if (ltq_cgu_r32(CGU_SYS) & 0x40)
  38                return ddr_clock >> 1;
  39        return ddr_clock;
  40}
  41
  42unsigned long ltq_danube_cpu_hz(void)
  43{
  44        switch (ltq_cgu_r32(CGU_SYS) & 0xc) {
  45        case 0:
  46                return CLOCK_333M;
  47        case 4:
  48                return DDR_HZ;
  49        case 8:
  50                return DDR_HZ << 1;
  51        default:
  52                return DDR_HZ >> 1;
  53        }
  54}
  55
  56unsigned long ltq_danube_pp32_hz(void)
  57{
  58        unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 7) & 3;
  59        unsigned long clk;
  60
  61        switch (clksys) {
  62        case 1:
  63                clk = CLOCK_240M;
  64                break;
  65        case 2:
  66                clk = CLOCK_222M;
  67                break;
  68        case 3:
  69                clk = CLOCK_133M;
  70                break;
  71        default:
  72                clk = CLOCK_266M;
  73                break;
  74        }
  75
  76        return clk;
  77}
  78
  79unsigned long ltq_ar9_sys_hz(void)
  80{
  81        if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2)
  82                return CLOCK_393M;
  83        return CLOCK_333M;
  84}
  85
  86unsigned long ltq_ar9_fpi_hz(void)
  87{
  88        unsigned long sys = ltq_ar9_sys_hz();
  89
  90        if (ltq_cgu_r32(CGU_SYS) & BIT(0))
  91                return sys;
  92        return sys >> 1;
  93}
  94
  95unsigned long ltq_ar9_cpu_hz(void)
  96{
  97        if (ltq_cgu_r32(CGU_SYS) & BIT(2))
  98                return ltq_ar9_fpi_hz();
  99        else
 100                return ltq_ar9_sys_hz();
 101}
 102
 103unsigned long ltq_vr9_cpu_hz(void)
 104{
 105        unsigned int cpu_sel;
 106        unsigned long clk;
 107
 108        cpu_sel = (ltq_cgu_r32(CGU_SYS_VR9) >> 4) & 0xf;
 109
 110        switch (cpu_sel) {
 111        case 0:
 112                clk = CLOCK_600M;
 113                break;
 114        case 1:
 115                clk = CLOCK_500M;
 116                break;
 117        case 2:
 118                clk = CLOCK_393M;
 119                break;
 120        case 3:
 121                clk = CLOCK_333M;
 122                break;
 123        case 5:
 124        case 6:
 125                clk = CLOCK_196_608M;
 126                break;
 127        case 7:
 128                clk = CLOCK_167M;
 129                break;
 130        case 4:
 131        case 8:
 132        case 9:
 133                clk = CLOCK_125M;
 134                break;
 135        default:
 136                clk = 0;
 137                break;
 138        }
 139
 140        return clk;
 141}
 142
 143unsigned long ltq_vr9_fpi_hz(void)
 144{
 145        unsigned int ocp_sel, cpu_clk;
 146        unsigned long clk;
 147
 148        cpu_clk = ltq_vr9_cpu_hz();
 149        ocp_sel = ltq_cgu_r32(CGU_SYS_VR9) & 0x3;
 150
 151        switch (ocp_sel) {
 152        case 0:
 153                /* OCP ratio 1 */
 154                clk = cpu_clk;
 155                break;
 156        case 2:
 157                /* OCP ratio 2 */
 158                clk = cpu_clk / 2;
 159                break;
 160        case 3:
 161                /* OCP ratio 2.5 */
 162                clk = (cpu_clk * 2) / 5;
 163                break;
 164        case 4:
 165                /* OCP ratio 3 */
 166                clk = cpu_clk / 3;
 167                break;
 168        default:
 169                clk = 0;
 170                break;
 171        }
 172
 173        return clk;
 174}
 175
 176unsigned long ltq_vr9_pp32_hz(void)
 177{
 178        unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 3;
 179        unsigned long clk;
 180
 181        switch (clksys) {
 182        case 1:
 183                clk = CLOCK_450M;
 184                break;
 185        case 2:
 186                clk = CLOCK_300M;
 187                break;
 188        default:
 189                clk = CLOCK_500M;
 190                break;
 191        }
 192
 193        return clk;
 194}
 195