Hi Heiko, On Sun, Dec 04, 2011 at 15:11:19, Heiko Schocher wrote:
Please provide a patch description. Nice to see device tree support being added for DaVinci devices. > Signed-off-by: Heiko Schocher <[email protected]> > Cc: [email protected] > Cc: [email protected] > Cc: [email protected] > Cc: [email protected] > Cc: Sekhar Nori <[email protected]> > Cc: Kevin Hilman <[email protected]> > Cc: Wolfgang Denk <[email protected]> > --- > .../devicetree/bindings/arm/davinci/aemif.txt | 85 ++++++++++++++++ > arch/arm/mach-davinci/aemif.c | 105 > +++++++++++++++++++- > arch/arm/mach-davinci/include/mach/aemif.h | 1 + > 3 files changed, 190 insertions(+), 1 deletions(-) > create mode 100644 Documentation/devicetree/bindings/arm/davinci/aemif.txt > > diff --git a/Documentation/devicetree/bindings/arm/davinci/aemif.txt > b/Documentation/devicetree/bindings/arm/davinci/aemif.txt > new file mode 100644 > index 0000000..c9ed551 > --- /dev/null > +++ b/Documentation/devicetree/bindings/arm/davinci/aemif.txt > @@ -0,0 +1,85 @@ > +* Texas Instruments Davinci AEMIF > + > +This file provides information, what the device node for the > +davinci aemifa interface contain. ^^^^^^ aemif > + > +Required properties: > +- compatible: "ti,davinci-emifa"; > +- #address-cells : Should be either two or three. The first cell is the > + chipselect number, and the remaining cells are the > + offset into the chipselect. > +- #size-cells : Either one or two, depending on how large each chipselect > + can be. > +- ranges : Each range corresponds to a single chipselect, and cover > + the entire access window as configured. > + > +Optional properties: > +- none > + > +Optional subnodes: > +- Chipselect setup: > + - Required properties: > + - compatible: "ti,davinci-cs"; > + - #address-cells = <1>; > + - #size-cells = <1>; > + > + Timing setup, all timings in nanoseconds > + - cs: chipselect (value 2,3,4 or 5) > + - asize: Asynchronous Data Bus Width. > + value: > + 0: 8 bit > + 1: 16 bit > + - ta: Minimum Turn-Around time. > + - rhold: Read hold width > + - rstrobe: Read strobe width > + - rsetup: Read setup width > + - whold: Write hold width > + - wstrobe: Write strobe width > + - wsetup: Write setup width > + - ew: Extend Wait bit > + value: > + 0: Extended wait cycles disabled. > + 1: Extended wait cycles enabled. > + -ss: Select Strobe bit. > + value: > + 0: Normal Mode enabled. > + 1: Select Strobe Mode enabled. > +- CFI driver: > + see: Documentation/devicetree/bindings/mtd/mtd-physmap.txt > + > +Example (enbw_cmc board): > + aemif@60000000 { > + compatible = "ti,davinci-emifa"; > + #address-cells = <2>; > + #size-cells = <1>; > + reg = <0x68000000 0x80000>; > + ranges = <2 0 0x60000000 0x02000000 > + 3 0 0x62000000 0x02000000 > + 4 0 0x64000000 0x02000000 > + 5 0 0x66000000 0x02000000>; > + cs2@0x60000000 { > + compatible = "ti,davinci-cs"; > + #address-cells = <1>; > + #size-cells = <1>; > + /* all timings in nanoseconds */ > + cs = <2>; > + asize = <1>; > + ta = <0>; > + rhold = <7>; > + rstrobe = <42>; > + rsetup = <14>; > + whold = <7>; > + wstrobe = <42>; > + wsetup = <14>; > + ew = <0>; > + ss = <0>; > + }; > + flash@2,0 { > + compatible = "cfi-flash"; > + reg = <2 0x0 0x400000>; > + #address-cells = <1>; > + #size-cells = <1>; > + bank-width = <2>; > + device-width = <2>; > + }; > + }; > diff --git a/arch/arm/mach-davinci/aemif.c b/arch/arm/mach-davinci/aemif.c > index 1ce70a9..12c559f 100644 > --- a/arch/arm/mach-davinci/aemif.c > +++ b/arch/arm/mach-davinci/aemif.c > @@ -13,12 +13,14 @@ > #include <linux/err.h> > #include <linux/clk.h> > #include <linux/module.h> > +#include <linux/of.h> > +#include <linux/of_address.h> > #include <linux/time.h> > > #include <mach/aemif.h> > > /* Timing value configuration */ > - > +#define ASIZE(x) (x) > #define TA(x) ((x) << 2) > #define RHOLD(x) ((x) << 4) > #define RSTROBE(x) ((x) << 7) > @@ -26,7 +28,10 @@ > #define WHOLD(x) ((x) << 17) > #define WSTROBE(x) ((x) << 20) > #define WSETUP(x) ((x) << 26) > +#define EW(x) ((x) << 30) > +#define SS(x) ((x) << 31) You are adding support for additional configuration parameters which should be done in a separate patch. > > +#define ASIZE_MAX 0x1 > #define TA_MAX 0x3 > #define RHOLD_MAX 0x7 > #define RSTROBE_MAX 0x3f > @@ -34,6 +39,8 @@ > #define WHOLD_MAX 0x7 > #define WSTROBE_MAX 0x3f > #define WSETUP_MAX 0xf > +#define EW_MAX 0x1 > +#define SS_MAX 0x1 > > #define TIMING_MASK (TA(TA_MAX) | \ > RHOLD(RHOLD_MAX) | \ > @@ -131,3 +138,99 @@ int davinci_aemif_setup_timing(struct > davinci_aemif_timing *t, > return 0; > } > EXPORT_SYMBOL(davinci_aemif_setup_timing); > + > +#if defined(CONFIG_OF) > +static int dv_get_value(struct device_node *np, const char *name) > +{ > + const u32 *data; > + int len; > + > + data = of_get_property(np, name, &len); > + if (data) > + return be32_to_cpu(readl(data)); > + > + return -EINVAL; > +} > + > +static int davinci_aemif_setup_timing_of_one(struct device_node *np, > + void __iomem *base) > +{ > + unsigned val; > + int asize, ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup; > + int ew, ss; > + int cs; > + unsigned offset; > + struct clk *aemif_clk; > + unsigned long clkrate; > + > + aemif_clk = clk_get(NULL, "aemif"); > + if (IS_ERR(aemif_clk)) > + return PTR_ERR(aemif_clk); > + > + clkrate = clk_get_rate(aemif_clk); > + > + clkrate /= 1000; /* turn clock into kHz for ease of use */ > + > + cs = dv_get_value(np, "cs"); > + if (cs < 2) > + return -EINVAL; > + > + offset = A1CR_OFFSET + (cs - 2) * 4; > + asize = dv_get_value(np, "asize"); > + ta = aemif_calc_rate(dv_get_value(np, "ta"), clkrate, TA_MAX); > + rhold = aemif_calc_rate(dv_get_value(np, "rhold"), clkrate, > + RHOLD_MAX); > + rstrobe = aemif_calc_rate(dv_get_value(np, "rstrobe"), clkrate, > + RSTROBE_MAX); > + rsetup = aemif_calc_rate(dv_get_value(np, "rsetup"), clkrate, > + RSETUP_MAX); > + whold = aemif_calc_rate(dv_get_value(np, "whold"), clkrate, > + WHOLD_MAX); > + wstrobe = aemif_calc_rate(dv_get_value(np, "wstrobe"), clkrate, > + WSTROBE_MAX); > + wsetup = aemif_calc_rate(dv_get_value(np, "wsetup"), clkrate, > + WSETUP_MAX); > + ew = dv_get_value(np, "ew"); > + ss = dv_get_value(np, "ss"); > + > + if (asize < 0 || ta < 0 || rhold < 0 || rstrobe < 0 || rsetup < 0 || > + whold < 0 || wstrobe < 0 || wsetup < 0 || ew < 0 || > + ss < 0) { > + pr_err("%s: cannot get suitable timings\n", __func__); > + return -EINVAL; > + } > + > + val = ASIZE(asize) | TA(ta) | RHOLD(rhold) | RSTROBE(rstrobe) | > + RSETUP(rsetup) | WHOLD(whold) | WSTROBE(wstrobe) | > + WSETUP(wsetup) | EW(ew) | SS(ss); > + > + __raw_writel(val, base + offset); > + > + return 0; > +} This shares a large amount of code with davinci_aemif_setup_timing(). Can you try writing this as a OF wrapper to the existing function? Thanks, Sekhar _______________________________________________ devicetree-discuss mailing list [email protected] https://lists.ozlabs.org/listinfo/devicetree-discuss
