ARM/clk: move the ICST library to drivers/clk
This moves the ICST clock divider helper library from arch/arm/common to drivers/clk/versatile so it is maintained with the other clock drivers. We keep the structure as a helper library intact and do not fuse it with the clk-icst.c Versatile ICST clock driver: there may be other users out there that need to use this library for their clocking, and then it will be helpful to keep the library contained. (The icst.[c|h] files could just be moved to drivers/clk/lib or a similar location to share the library.) Acked-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
config ICST
|
||||
bool
|
||||
|
||||
config COMMON_CLK_VERSATILE
|
||||
bool "Clock driver for ARM Reference designs"
|
||||
depends on ARCH_INTEGRATOR || ARCH_REALVIEW || \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Makefile for Versatile-specific clocks
|
||||
obj-$(CONFIG_ICST) += clk-icst.o clk-versatile.o
|
||||
obj-$(CONFIG_ICST) += icst.o clk-icst.o clk-versatile.o
|
||||
obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o
|
||||
obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o
|
||||
obj-$(CONFIG_CLK_SP810) += clk-sp810.o
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
|
||||
#include "icst.h"
|
||||
#include "clk-icst.h"
|
||||
|
||||
/* Magic unlocking token used on all Versatile boards */
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#include <asm/hardware/icst.h>
|
||||
|
||||
/**
|
||||
* struct clk_icst_desc - descriptor for the ICST VCO
|
||||
* @params: ICST parameters
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_data/clk-integrator.h>
|
||||
|
||||
#include "icst.h"
|
||||
#include "clk-icst.h"
|
||||
|
||||
#define IMPD1_OSC1 0x00
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
#include "icst.h"
|
||||
#include "clk-icst.h"
|
||||
|
||||
#define REALVIEW_SYS_OSC0_OFFSET 0x0C
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include "icst.h"
|
||||
#include "clk-icst.h"
|
||||
|
||||
#define INTEGRATOR_HDR_LOCK_OFFSET 0x14
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* linux/arch/arm/common/icst307.c
|
||||
*
|
||||
* Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Support functions for calculating clocks/divisors for the ICST307
|
||||
* clock generators. See http://www.idt.com/ for more information
|
||||
* on these devices.
|
||||
*
|
||||
* This is an almost identical implementation to the ICST525 clock generator.
|
||||
* The s2div and idx2s files are different
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/div64.h>
|
||||
#include "icst.h"
|
||||
|
||||
/*
|
||||
* Divisors for each OD setting.
|
||||
*/
|
||||
const unsigned char icst307_s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 };
|
||||
const unsigned char icst525_s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 };
|
||||
EXPORT_SYMBOL(icst307_s2div);
|
||||
EXPORT_SYMBOL(icst525_s2div);
|
||||
|
||||
unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco)
|
||||
{
|
||||
u64 dividend = p->ref * 2 * (u64)(vco.v + 8);
|
||||
u32 divisor = (vco.r + 2) * p->s2div[vco.s];
|
||||
|
||||
do_div(dividend, divisor);
|
||||
return (unsigned long)dividend;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(icst_hz);
|
||||
|
||||
/*
|
||||
* Ascending divisor S values.
|
||||
*/
|
||||
const unsigned char icst307_idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 };
|
||||
const unsigned char icst525_idx2s[8] = { 1, 3, 4, 7, 5, 2, 6, 0 };
|
||||
EXPORT_SYMBOL(icst307_idx2s);
|
||||
EXPORT_SYMBOL(icst525_idx2s);
|
||||
|
||||
struct icst_vco
|
||||
icst_hz_to_vco(const struct icst_params *p, unsigned long freq)
|
||||
{
|
||||
struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
|
||||
unsigned long f;
|
||||
unsigned int i = 0, rd, best = (unsigned int)-1;
|
||||
|
||||
/*
|
||||
* First, find the PLL output divisor such
|
||||
* that the PLL output is within spec.
|
||||
*/
|
||||
do {
|
||||
f = freq * p->s2div[p->idx2s[i]];
|
||||
|
||||
if (f > p->vco_min && f <= p->vco_max)
|
||||
break;
|
||||
i++;
|
||||
} while (i < 8);
|
||||
|
||||
if (i >= 8)
|
||||
return vco;
|
||||
|
||||
vco.s = p->idx2s[i];
|
||||
|
||||
/*
|
||||
* Now find the closest divisor combination
|
||||
* which gives a PLL output of 'f'.
|
||||
*/
|
||||
for (rd = p->rd_min; rd <= p->rd_max; rd++) {
|
||||
unsigned long fref_div, f_pll;
|
||||
unsigned int vd;
|
||||
int f_diff;
|
||||
|
||||
fref_div = (2 * p->ref) / rd;
|
||||
|
||||
vd = (f + fref_div / 2) / fref_div;
|
||||
if (vd < p->vd_min || vd > p->vd_max)
|
||||
continue;
|
||||
|
||||
f_pll = fref_div * vd;
|
||||
f_diff = f_pll - f;
|
||||
if (f_diff < 0)
|
||||
f_diff = -f_diff;
|
||||
|
||||
if ((unsigned)f_diff < best) {
|
||||
vco.v = vd - 8;
|
||||
vco.r = rd - 2;
|
||||
if (f_diff == 0)
|
||||
break;
|
||||
best = f_diff;
|
||||
}
|
||||
}
|
||||
|
||||
return vco;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(icst_hz_to_vco);
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Support functions for calculating clocks/divisors for the ICST
|
||||
* clock generators. See http://www.idt.com/ for more information
|
||||
* on these devices.
|
||||
*/
|
||||
#ifndef ICST_H
|
||||
#define ICST_H
|
||||
|
||||
struct icst_params {
|
||||
unsigned long ref;
|
||||
unsigned long vco_max; /* inclusive */
|
||||
unsigned long vco_min; /* exclusive */
|
||||
unsigned short vd_min; /* inclusive */
|
||||
unsigned short vd_max; /* inclusive */
|
||||
unsigned char rd_min; /* inclusive */
|
||||
unsigned char rd_max; /* inclusive */
|
||||
const unsigned char *s2div; /* chip specific s2div array */
|
||||
const unsigned char *idx2s; /* chip specific idx2s array */
|
||||
};
|
||||
|
||||
struct icst_vco {
|
||||
unsigned short v;
|
||||
unsigned char r;
|
||||
unsigned char s;
|
||||
};
|
||||
|
||||
unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco);
|
||||
struct icst_vco icst_hz_to_vco(const struct icst_params *p, unsigned long freq);
|
||||
|
||||
/*
|
||||
* ICST307 VCO frequency must be between 6MHz and 200MHz (3.3 or 5V).
|
||||
* This frequency is pre-output divider.
|
||||
*/
|
||||
#define ICST307_VCO_MIN 6000000
|
||||
#define ICST307_VCO_MAX 200000000
|
||||
|
||||
extern const unsigned char icst307_s2div[];
|
||||
extern const unsigned char icst307_idx2s[];
|
||||
|
||||
/*
|
||||
* ICST525 VCO frequency must be between 10MHz and 200MHz (3V) or 320MHz (5V).
|
||||
* This frequency is pre-output divider.
|
||||
*/
|
||||
#define ICST525_VCO_MIN 10000000
|
||||
#define ICST525_VCO_MAX_3V 200000000
|
||||
#define ICST525_VCO_MAX_5V 320000000
|
||||
|
||||
extern const unsigned char icst525_s2div[];
|
||||
extern const unsigned char icst525_idx2s[];
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user