/*
* Copyright (C) 2014 STMicroelectronics R&D Ltd
*
* 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.
*
*/
/*
* Authors:
* Stephen Gallimore <stephen.gallimore@st.com>,
* Pankaj Dev <pankaj.dev@st.com>.
*/
#include <linux/slab.h>
#include <linux/of_address.h>
#include <linux/clk-provider.h>
#include "clkgen.h"
/*
* Maximum input clock to the PLL before we divide it down by 2
* although in reality in actual systems this has never been seen to
* be used.
*/
#define QUADFS_NDIV_THRESHOLD 30000000
#define PLL_BW_GOODREF (0L)
#define PLL_BW_VBADREF (1L)
#define PLL_BW_BADREF (2L)
#define PLL_BW_VGOODREF (3L)
#define QUADFS_MAX_CHAN 4
struct stm_fs {
unsigned long ndiv;
unsigned long mdiv;
unsigned long pe;
unsigned long sdiv;
unsigned long nsdiv;
};
static struct stm_fs fs216c65_rtbl[] = {
{ .mdiv = 0x1f, .pe = 0x0, .sdiv = 0x7, .nsdiv = 0 }, /* 312.5 Khz */
{ .mdiv = 0x17, .pe = 0x25ed, .sdiv = 0x1, .nsdiv = 0 }, /* 27 MHz */
{ .mdiv = 0x1a, .pe = 0x7b36, .sdiv = 0x2, .nsdiv = 1 }, /* 36.87 MHz */
{ .mdiv = 0x13, .pe = 0x0, .sdiv = 0x2, .nsdiv = 1 }, /* 48 MHz */
{ .mdiv = 0x11, .pe = 0x1c72, .sdiv = 0x1, .nsdiv = 1 }, /* 108 MHz */
};
static struct stm_fs fs432c65_rtbl[] = {
{ .mdiv = 0x1f, .pe = 0x0, .sdiv = 0x7, .nsdiv = 0 }, /* 625 Khz */
{ .mdiv = 0x11, .pe = 0x1c72, .sdiv = 0x2, .nsdiv = 1 }, /* 108 MHz */
{ .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x0, .nsdiv = 1 }, /* 297 MHz */
};
static struct stm_fs fs660c32_rtbl[] = {
{ .mdiv = 0x01, .pe = 0x2aaa, .sdiv = 0x8, .nsdiv = 0 }, /* 600 KHz */
{ .mdiv = 0x02, .pe = 0x3d33, .sdiv = 0x0, .nsdiv = 0 }, /* 148.5 Mhz */
{ .mdiv = 0x13, .pe = 0x5bcc, .sdiv = 0x0, .nsdiv = 1 }, /* 297 Mhz */
{ .mdiv = 0x0e, .pe = 0x1025, .sdiv = 0x0, .nsdiv = 1 }, /* 333 Mhz */
{ .mdiv = 0x0b, .pe = 0x715f, .sdiv = 0x0, .nsdiv = 1 }, /* 350 Mhz */
};
struct clkgen_quadfs_data {
bool reset_present;
bool bwfilter_present;
bool lockstatus_present;
bool nsdiv_present;
struct clkgen_field ndiv;
struct clkgen_field ref_bw;
struct clkgen_field nreset;
struct clkgen_field npda;
struct clkgen_field lock_status;
struct clkgen_field nsb[QUADFS_MAX_CHAN];
struct clkgen_field en[QUADFS_MAX_CHAN];
struct clkgen_field mdiv[QUADFS_MAX_CHAN];
struct clkgen_field pe[QUADFS_MAX_CHAN];
struct clkgen_field sdiv[QUADFS_MAX_CHAN];
struct clkgen_field nsdiv[QUADFS_MAX_CHAN];
const struct clk_ops *pll_ops;
struct stm_fs *rtbl;
u8 rtbl_cnt;
int (*get_rate)(unsigned long , struct stm_fs *,
unsigned long *);
};
static const struct clk_ops st_quadfs_pll_c65_ops;
static const struct clk_ops st_quadfs_pll_c32_ops;
static const struct clk_ops st_quadfs_fs216c65_ops;
static const struct clk_ops st_quadfs_fs432c65_ops;
static const struct clk_ops st_quadfs_fs660c32_ops;
static