Hi Sneha,
On Fri, Dec 04, 2009 at 02:26:54, Narnakaje, Snehaprabha wrote:
> Sekhar,
>
> Not sure if you have looked at the clock requirements for VPIF on
> DA850/OMAP-L138, it
> seems like we also need similar support - CDCE913.
No, honestly didn't realize there was a CDCE in there
so far :)
>
> I believe, it supports only one clock - 27MHz for VPIF display.
>
Okay. On reset the CDCE should give the this clock out
by default without a need to re-program. We only support
SD resolutions on DA850, so I assume there is no need to
reprogram the CDCE for higher/different clocks.
> May be we could re-use the same driver? The values and registers do match with
> cdce_y1_27000[].
Unless there is a need to reprogram the CDCE, there
should be no need for the driver. The VPIF driver
should simply refer the 27MHz clock as "pixel_clk"
or "data_clk" and the platform code should provide
the definition for that clock. In the case of DA850
the board code can register a clock with this name
and having a fixed rate of 27MHz.
Thanks,
Sekhar
>
> On DA850/OMAP-L138:
> { 0x14, 0xED },
> { 0x18, 0x00 },
> { 0x19, 0x40 },
> { 0x1a, 0x02 },
> { 0x1b, 0x08 },
>
> Thanks
> Sneha
>
> > -----Original Message-----
> > From: [email protected]
> > [mailto:[email protected]] On Behalf
> > Of Nori, Sekhar
> > Sent: Thursday, December 03, 2009 5:07 AM
> > To: [email protected]
> > Subject: [PATCH 4/5] davinci: add support for CDCE949 clock synthesizer
> >
> > From: Nageswari Srinivasan <[email protected]>
> >
> > This patch adds support for TI's CDCE949 - a clock
> > synthesizer with 4 PLLs and 9 outputs.
> >
> > It is used on DM6467 EVM. On the EVM, it generates
> > clocks required for VPIF, TSIF and Audio modules.
> >
> > This patch adds it as part of the DaVinci clock framework.
> >
> > Testing:
> > The various frequency outputs on Y1 have been tested using
> > a out-of-tree VPIF video driver supporting HD video.
> > The register values for Y5 frequency outputs have been
> > derived from TSIF driver sources in MontaVista LSP kernel,
> > but actual output has not been tested for lack of TSIF
> > driver which actually works on the latest kernel.
> >
> > Signed-off-by: Nageswari Srinivasan <[email protected]>
> > Signed-off-by: Sekhar Nori <[email protected]>
> > ---
> > arch/arm/mach-davinci/cdce949.c | 289
> > ++++++++++++++++++++++++++
> > arch/arm/mach-davinci/include/mach/cdce949.h | 19 ++
> > 2 files changed, 308 insertions(+), 0 deletions(-)
> > create mode 100644 arch/arm/mach-davinci/cdce949.c
> > create mode 100644 arch/arm/mach-davinci/include/mach/cdce949.h
> >
> > diff --git a/arch/arm/mach-davinci/cdce949.c b/arch/arm/mach-
> > davinci/cdce949.c
> > new file mode 100644
> > index 0000000..5a08283
> > --- /dev/null
> > +++ b/arch/arm/mach-davinci/cdce949.c
> > @@ -0,0 +1,289 @@
> > +/*
> > + * TI CDCE949 clock synthesizer driver
> > + *
> > + * Note: This implementation assumes an input of 27MHz to the CDCE.
> > + * This is by no means constrained by CDCE hardware although the
> > datasheet
> > + * does use this as an example for all illustrations and more
> > importantly:
> > + * that is the crystal input on boards it is currently used on.
> > + *
> > + * Copyright (C) 2009 Texas Instruments Incorporated. http://www.ti.com/
> > + *
> > + * 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.
> > + *
> > + */
> > +#include <linux/kernel.h>
> > +#include <linux/clk.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/i2c.h>
> > +
> > +#include <mach/clock.h>
> > +
> > +#include "clock.h"
> > +
> > +static struct i2c_client *cdce_i2c_client;
> > +
> > +/* CDCE register descriptor */
> > +struct cdce_reg {
> > + u8 addr;
> > + u8 val;
> > +};
> > +
> > +/* Per-Output (Y1, Y2 etc.) frequency descriptor */
> > +struct cdce_freq {
> > + /* Frequency in KHz */
> > + unsigned long frequency;
> > + /*
> > + * List of registers to program to obtain a particular frequency.
> > + * 0x0 in register address and value is the end of list marker.
> > + */
> > + struct cdce_reg *reglist;
> > +};
> > +
> > +#define CDCE_FREQ_TABLE_ENTRY(line, out) \
> > +{ \
> > + .reglist = cdce_y ##line## _ ##out, \
> > + .frequency = out, \
> > +}
> > +
> > +/* List of CDCE outputs */
> > +struct cdce_output {
> > + /* List of frequencies on this output */
> > + struct cdce_freq *freq_table;
> > + /* Number of possible frequencies */
> > + int size;
> > +};
> > +
> > +/*
> > + * Finding out the values to program into CDCE949 registers for a
> > particular
> > + * frequency output is not a simple calculation. Have a look at the
> > datasheet
> > + * for the details. There is desktop software available to help users
> > with
> > + * the calculations. Here, we just depend on the output of that software
> > + * (or hand calculations) instead trying to runtime calculate the
> > register
> > + * values and inflicting misery on ourselves.
> > + */
> > +static struct cdce_reg cdce_y1_148500[] = {
> > + { 0x13, 0x00 },
> > + /* program PLL1_0 multiplier */
> > + { 0x18, 0xaf },
> > + { 0x19, 0x50 },
> > + { 0x1a, 0x02 },
> > + { 0x1b, 0xc9 },
> > + /* program PLL1_11 multiplier */
> > + { 0x1c, 0x00 },
> > + { 0x1d, 0x40 },
> > + { 0x1e, 0x02 },
> > + { 0x1f, 0xc9 },
> > + /* output state selection */
> > + { 0x15, 0x00 },
> > + { 0x14, 0xef },
> > + /* switch MUX to PLL1 output */
> > + { 0x14, 0x6f },
> > + { 0x16, 0x06 },
> > + /* set P2DIV divider, P3DIV and input crystal */
> > + { 0x17, 0x06 },
> > + { 0x01, 0x00 },
> > + { 0x05, 0x48 },
> > + { 0x02, 0x80 },
> > + /* enable and disable PLL */
> > + { 0x02, 0xbc },
> > + { 0x03, 0x01 },
> > + { },
> > +};
> > +
> > +static struct cdce_reg cdce_y1_74250[] = {
> > + { 0x13, 0x00 },
> > + { 0x18, 0xaf },
> > + { 0x19, 0x50 },
> > + { 0x1a, 0x02 },
> > + { 0x1b, 0xc9 },
> > + { 0x1c, 0x00 },
> > + { 0x1d, 0x40 },
> > + { 0x1e, 0x02 },
> > + { 0x1f, 0xc9 },
> > + /* output state selection */
> > + { 0x15, 0x00 },
> > + { 0x14, 0xef },
> > + /* switch MUX to PLL1 output */
> > + { 0x14, 0x6f },
> > + { 0x16, 0x06 },
> > + /* set P2DIV divider, P3DIV and input crystal */
> > + { 0x17, 0x06 },
> > + { 0x01, 0x00 },
> > + { 0x05, 0x48 },
> > + { 0x02, 0x80 },
> > + /* enable and disable PLL */
> > + { 0x02, 0xbc },
> > + { 0x03, 0x02 },
> > + { },
> > +};
> > +
> > +static struct cdce_reg cdce_y1_27000[] = {
> > + { 0x13, 0x00 },
> > + { 0x18, 0x00 },
> > + { 0x19, 0x40 },
> > + { 0x1a, 0x02 },
> > + { 0x1b, 0x08 },
> > + { 0x1c, 0x00 },
> > + { 0x1d, 0x40 },
> > + { 0x1e, 0x02 },
> > + { 0x1f, 0x08 },
> > + { 0x15, 0x02 },
> > + { 0x14, 0xed },
> > + { 0x16, 0x01 },
> > + { 0x17, 0x01 },
> > + { 0x01, 0x00 },
> > + { 0x05, 0x50 },
> > + { 0x02, 0xb4 },
> > + { 0x03, 0x01 },
> > + { },
> > +};
> > +
> > +static struct cdce_freq cdce_y1_freqs[] = {
> > + CDCE_FREQ_TABLE_ENTRY(1, 148500),
> > + CDCE_FREQ_TABLE_ENTRY(1, 74250),
> > + CDCE_FREQ_TABLE_ENTRY(1, 27000),
> > +};
> > +
> > +static struct cdce_reg cdce_y5_13500[] = {
> > + { 0x27, 0x08 },
> > + { 0x28, 0x00 },
> > + { 0x29, 0x40 },
> > + { 0x2a, 0x02 },
> > + { 0x2b, 0x08 },
> > + { 0x24, 0x6f },
> > + { },
> > +};
> > +
> > +static struct cdce_reg cdce_y5_16875[] = {
> > + { 0x27, 0x08 },
> > + { 0x28, 0x9f },
> > + { 0x29, 0xb0 },
> > + { 0x2a, 0x02 },
> > + { 0x2b, 0x89 },
> > + { 0x24, 0x6f },
> > + { },
> > +};
> > +
> > +static struct cdce_reg cdce_y5_27000[] = {
> > + { 0x27, 0x04 },
> > + { 0x28, 0x00 },
> > + { 0x29, 0x40 },
> > + { 0x2a, 0x02 },
> > + { 0x2b, 0x08 },
> > + { 0x24, 0x6f },
> > + { },
> > +};
> > +static struct cdce_reg cdce_y5_54000[] = {
> > + { 0x27, 0x04 },
> > + { 0x28, 0xff },
> > + { 0x29, 0x80 },
> > + { 0x2a, 0x02 },
> > + { 0x2b, 0x07 },
> > + { 0x24, 0x6f },
> > + { },
> > +};
> > +
> > +static struct cdce_reg cdce_y5_81000[] = {
> > + { 0x27, 0x02 },
> > + { 0x28, 0xbf },
> > + { 0x29, 0xa0 },
> > + { 0x2a, 0x03 },
> > + { 0x2b, 0x0a },
> > + { 0x24, 0x6f },
> > + { },
> > +};
> > +
> > +static struct cdce_freq cdce_y5_freqs[] = {
> > + CDCE_FREQ_TABLE_ENTRY(5, 13500),
> > + CDCE_FREQ_TABLE_ENTRY(5, 16875),
> > + CDCE_FREQ_TABLE_ENTRY(5, 27000),
> > + CDCE_FREQ_TABLE_ENTRY(5, 54000),
> > + CDCE_FREQ_TABLE_ENTRY(5, 81000),
> > +};
> > +
> > +
> > +static struct cdce_output output_list[] = {
> > + [1] = { cdce_y1_freqs, ARRAY_SIZE(cdce_y1_freqs) },
> > + [5] = { cdce_y5_freqs, ARRAY_SIZE(cdce_y5_freqs) },
> > +};
> > +
> > +int cdce_set_rate(struct clk *clk, unsigned long rate)
> > +{
> > + int i, ret = 0;
> > + struct cdce_freq *freq_table = output_list[clk->lpsc].freq_table;
> > + struct cdce_reg *regs = NULL;
> > +
> > + if (!cdce_i2c_client)
> > + return -ENODEV;
> > +
> > + if (!freq_table)
> > + return -EINVAL;
> > +
> > + for (i = 0; i < output_list[clk->lpsc].size; i++) {
> > + if (freq_table[i].frequency == rate / 1000) {
> > + regs = freq_table[i].reglist;
> > + break;
> > + }
> > + }
> > +
> > + if (!regs)
> > + return -EINVAL;
> > +
> > + for (i = 0; regs[i].addr; i++) {
> > + ret = i2c_smbus_write_byte_data(cdce_i2c_client,
> > + regs[i].addr | 0x80, regs[i].val);
> > + if (ret)
> > + return ret;
> > + }
> > +
> > + atomic_set(&clk->rate, rate);
> > +
> > + return 0;
> > +}
> > +
> > +static int cdce_probe(struct i2c_client *client,
> > + const struct i2c_device_id *id)
> > +{
> > + cdce_i2c_client = client;
> > + return 0;
> > +}
> > +
> > +static int __devexit cdce_remove(struct i2c_client *client)
> > +{
> > + cdce_i2c_client = NULL;
> > + return 0;
> > +}
> > +
> > +static const struct i2c_device_id cdce_id[] = {
> > + {"cdce949", 0},
> > + {},
> > +};
> > +MODULE_DEVICE_TABLE(i2c, cdce_id);
> > +
> > +static struct i2c_driver cdce_driver = {
> > + .driver = {
> > + .owner = THIS_MODULE,
> > + .name = "cdce949",
> > + },
> > + .probe = cdce_probe,
> > + .remove = __devexit_p(cdce_remove),
> > + .id_table = cdce_id,
> > +};
> > +
> > +static int __init cdce_init(void)
> > +{
> > + return i2c_add_driver(&cdce_driver);
> > +}
> > +subsys_initcall(cdce_init);
> > +
> > +static void __exit cdce_exit(void)
> > +{
> > + i2c_del_driver(&cdce_driver);
> > +}
> > +module_exit(cdce_exit);
> > +
> > +MODULE_AUTHOR("Texas Instruments");
> > +MODULE_DESCRIPTION("CDCE949 clock synthesizer driver");
> > +MODULE_LICENSE("GPL v2");
> > diff --git a/arch/arm/mach-davinci/include/mach/cdce949.h b/arch/arm/mach-
> > davinci/include/mach/cdce949.h
> > new file mode 100644
> > index 0000000..c73331f
> > --- /dev/null
> > +++ b/arch/arm/mach-davinci/include/mach/cdce949.h
> > @@ -0,0 +1,19 @@
> > +/*
> > + * TI CDCE949 off-chip clock synthesizer support
> > + *
> > + * 2009 (C) Texas Instruments, Inc. http://www.ti.com/
> > + *
> > + * This file is licensed under the terms of the GNU General Public
> > License
> > + * version 2. This program is licensed "as is" without any warranty of
> > any
> > + * kind, whether express or implied.
> > + */
> > +#ifndef _MACH_DAVINCI_CDCE949_H
> > +#define _MACH_DAVINCI_CDCE949_H
> > +
> > +#include <linux/clk.h>
> > +
> > +#include <mach/clock.h>
> > +
> > +int cdce_set_rate(struct clk *clk, unsigned long rate);
> > +
> > +#endif
> > --
> > 1.6.2.4
> >
> > _______________________________________________
> > Davinci-linux-open-source mailing list
> > [email protected]
> > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
>
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source