RE: [PATCH v4 1/2] davinci: Add generic PWM support for PWM control
On Fri, Sep 10, 2010 at 22:04:08, Caglar Akyuz wrote: > On Thursday 09 September 2010 01:40:49 pm Sugumar Natarajan wrote: > > This patch adds generic PWM support where it maintains the list of PWM > > control devices that can be added or removed. > > > > The interface provides a list of functions that can be accessed by the > > PWM control driver module and the generic PWM driver. > > > > The PWM control driver module such as eCAP uses the interface to > > register and add itself to the list as a PWM control device. > > The generic PWM driver uses the interface to search for a PWM control > > device and if present, uses the device for PWM control. > > > > How does real pwm modules fit in this architecture? For instance L-138 have > eHRPWM modules for PWM generation. > > * Should we add a seperate file for eHRPWM module? > > or > > * Should we integrate it in davinci_pwm file? > > Best Regards, > Caglar > > > Signed-off-by: Sugumar Natarajan > > --- > > Changes since v2: > > a) pwm_config_device callback is made more flexible. > > b) pwm_request function code has been made more cleaner. > > c) Sanity-check/warn has been included. > > > > arch/arm/mach-davinci/Makefile |3 + > > arch/arm/mach-davinci/davinci_pwm.c | 130 > > ++ arch/arm/mach-davinci/include/mach/davinci_pwm.h | > > 32 ++ > > 3 files changed, 165 insertions(+), 0 deletions(-) create mode > > 100644 arch/arm/mach-davinci/davinci_pwm.c > > create mode 100644 arch/arm/mach-davinci/include/mach/davinci_pwm.h > > > > diff --git a/arch/arm/mach-davinci/Makefile > > b/arch/arm/mach-davinci/Makefile index a7a70d1..90ca821 100644 > > --- a/arch/arm/mach-davinci/Makefile > > +++ b/arch/arm/mach-davinci/Makefile > > @@ -39,3 +39,6 @@ obj-$(CONFIG_MACH_MITYOMAPL138) += > > board-mityomapl138.o > > obj-$(CONFIG_CPU_FREQ) += cpufreq.o > > obj-$(CONFIG_CPU_IDLE) += cpuidle.o > > obj-$(CONFIG_SUSPEND) += pm.o sleep.o > > + > > +# Generic PWM control support > > +obj-$(CONFIG_HAVE_PWM) += davinci_pwm.o > > diff --git a/arch/arm/mach-davinci/davinci_pwm.c > > b/arch/arm/mach-davinci/davinci_pwm.c new file mode 100644 index > > 000..c2b8b9a > > --- /dev/null > > +++ b/arch/arm/mach-davinci/davinci_pwm.c > > @@ -0,0 +1,130 @@ > > +/* > > + * Copyright (C) 2010 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 as > > + * published by the Free Software Foundation version 2. > > + * > > + * This program is distributed .as is. WITHOUT ANY WARRANTY of any > > + * kind, whether express or implied; without even the implied > > +warranty > > + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > + * GNU General Public License for more details. > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) { > > + unsigned int clock_freq; > > + unsigned int period_cycles; > > + unsigned int duty_cycle; > > + int ret = 0; > > + > > + if (WARN_ON(!pwm)) > > + return -EINVAL; > > + > > + if (pwm->pwm_config_device) { > > + if (!period_ns || duty_ns > period_ns) > > + return -EINVAL; > > + > > + clock_freq = clk_get_rate(pwm->clk) / USEC_PER_SEC; > > + period_cycles = (clock_freq * period_ns) / MSEC_PER_SEC; > > + duty_cycle = (clock_freq * duty_ns) / MSEC_PER_SEC; > > + ret = pwm->pwm_config_device(pwm, period_cycles, duty_cycle); > > + } > > + > > + return ret; > > +} > > +EXPORT_SYMBOL(pwm_config); > > + > > +int pwm_enable(struct pwm_device *pwm) { > > + if (WARN_ON(!pwm)) > > + return -EINVAL; > > + > > + return clk_enable(pwm->clk); > > +} > > +EXPORT_SYMBOL(pwm_enable); > > + > > +void pwm_disable(struct pwm_device *pwm) { > > + if (WARN_ON(!pwm)) > > + return; > > + > > + clk_disable(pwm->clk); > > +} > > +EXPORT_SYMBOL(pwm_disable); > > + > > +static DEFINE_MUTEX(pwm_lock); > > +static LIST_HEAD(pwm_list); > > + > > +struct pwm_device *pwm_request(int pwm_id, const char *label) { > > + struct pwm_device *pwm, *tmp_pwm = ERR_PTR(-ENOENT); > > + > > + mutex_lock(&pwm_lock); > > + > > + list_for_each_entry(pwm, &pwm_list, node) { > > + if (pwm->pwm_id == pwm_id) { > > + if (pwm->use_count == 0) { > > + pwm->use_count++; > > + pwm->label = label; > > + } else { > > + pwm = ERR_PTR(-EBUSY); > > + } > > + tmp_pwm = pwm; > > + break; > > + } > > + } > > + >
RE: [PATCH v4 1/2] davinci: Add generic PWM support for PWM control
On Fri, Sep 10, 2010 at 23:12:36, Caglar Akyuz wrote: > On Thursday 09 September 2010 01:40:49 pm Sugumar Natarajan wrote: > > This patch adds generic PWM support where it maintains the list of PWM > > control devices that can be added or removed. > > > > The interface provides a list of functions that can be accessed by the > > PWM control driver module and the generic PWM driver. > > > > The PWM control driver module such as eCAP uses the interface to > > register and add itself to the list as a PWM control device. > > The generic PWM driver uses the interface to search for a PWM control > > device and if present, uses the device for PWM control. > > > > Signed-off-by: Sugumar Natarajan > > --- > > Hi, > > [...] > > > + > > +int pwm_enable(struct pwm_device *pwm) { > > + if (WARN_ON(!pwm)) > > + return -EINVAL; > > + > > + return clk_enable(pwm->clk); > > +} > > +EXPORT_SYMBOL(pwm_enable); > > + > > I think 'clk_enable' should be controlled for un-matched pwm_enable/disable > operation. Otherwise, disabling PWM won't shut down peripheral clock. If I understand inner workings of DaVinci clock implementation clock use_count is incremented with every clk_enable. > > Regards, > Caglar > Caglar, I could not understand what you mean by "un-match" .could you please explain? Regards, N.sugumar ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
voice codec driver
Hi everybody are there any plans/schedule to add the DM365 internal voice codec to the linux tree? Thanks all -- Albert Burbea Harishonim 8 Ramat Gan 52502, Israel Tel/Fax + 972-3-7526016 Mobile: +972-52-3541842 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: voice codec driver
Hello. Albert Burbea wrote: Hi everybody are there any plans/schedule to add the DM365 internal voice codec to the linux tree? The DM365 voice codec support has been merged back in March already. WBR, Sergei ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: voice codec driver
On Mon, Sep 13, 2010 at 3:28 PM, Sergei Shtylyov wrote: > Hello. > > Albert Burbea wrote: > >> Hi everybody >> are there any plans/schedule to add the DM365 internal voice codec to the >> linux tree? > > The DM365 voice codec support has been merged back in March already. And I have checked it in 2.6.32 arago kernel. Some fixes are needed. Look at the following for more info: http://e2e.ti.com/support/embedded/f/354/p/56231/226155.aspx#226155 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 00/10] split out emac cpdma and mdio for reuse
Hi Caglar, [...] > Unfortunately emac driver is not stable after this series. I face lock-ups > time to time, followed by attached kernel trace. Could you elaborate on your test scenario so that I can try and reproduce the problem at my end? Also, did you have the contents of my commit stack in this particular kernel build? Assuming that the DMA got stuck at some point leading up to the transmit timeout, any ideas as to why a host error was not thrown? To help debug, I'll post out a set of patches that dump out the MAC (and DMA) registers on timeout. That should give us some visibility into the problem. > [ 1651.44] nfs: server 192.168.2.34 not responding, still trying > [ 1859.01] [ cut here ] > [ 1859.01] WARNING: at net/sched/sch_generic.c:258 > dev_watchdog+0x184/0x294() > [ 1859.02] NETDEV WATCHDOG: eth0 (davinci_emac): transmit queue 0 timed > out [...] Regards Cyril. ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH 6/6] i2c: davinci: bus recovery procedure to clear the bus
Hi Philby, On Wed, Jan 27, 2010 at 1:41 AM, Kevin Hilman wrote: > From: Philby John > > Come out of i2c time out condition by following the > bus recovery procedure outlined in the i2c protocol v3 spec. > The kernel must be robust enough to gracefully recover > from i2c bus failure without having to reset the machine. > This is done by first NACKing the slave, pulsing the SCL > line 9 times and then sending the stop command. > > This patch has been tested on a DM6446 and DM355 > > Signed-off-by: Philby John > Signed-off-by: Srinivasan, Nageswari > Acked-by: Kevin Hilman > --- > drivers/i2c/busses/i2c-davinci.c | 57 > +++-- > 1 files changed, 53 insertions(+), 4 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-davinci.c > b/drivers/i2c/busses/i2c-davinci.c > index 35f9daa..5459065 100644 > --- a/drivers/i2c/busses/i2c-davinci.c > +++ b/drivers/i2c/busses/i2c-davinci.c > @@ -36,6 +36,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -43,6 +44,7 @@ > /* - global defines --- */ > > #define DAVINCI_I2C_TIMEOUT(1*HZ) > +#define DAVINCI_I2C_MAX_TRIES 2 > #define I2C_DAVINCI_INTR_ALL(DAVINCI_I2C_IMR_AAS | \ > DAVINCI_I2C_IMR_SCD | \ > DAVINCI_I2C_IMR_ARDY | \ > @@ -130,6 +132,44 @@ static inline u16 davinci_i2c_read_reg(struct > davinci_i2c_dev *i2c_dev, int reg) >return __raw_readw(i2c_dev->base + reg); > } > > +/* Generate a pulse on the i2c clock pin. */ > +static void generic_i2c_clock_pulse(unsigned int scl_pin) > +{ > + u16 i; > + > + if (scl_pin) { > + /* Send high and low on the SCL line */ > + for (i = 0; i < 9; i++) { > + gpio_set_value(scl_pin, 0); > + udelay(20); > + gpio_set_value(scl_pin, 1); > + udelay(20); > + } > + } > +} > + > +/* This routine does i2c bus recovery as specified in the > + * i2c protocol Rev. 03 section 3.16 titled "Bus clear" > + */ > +static void i2c_recover_bus(struct davinci_i2c_dev *dev) > +{ > + u32 flag = 0; > + struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; > + > + dev_err(dev->dev, "initiating i2c bus recovery\n"); > + /* Send NACK to the slave */ > + flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); > + flag |= DAVINCI_I2C_MDR_NACK; > + /* write the data into mode register */ > + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); > + if (pdata) > + generic_i2c_clock_pulse(pdata->scl_pin); > + /* Send STOP */ > + flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); > + flag |= DAVINCI_I2C_MDR_STP; > + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); > +} > + > static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev, >int val) > { > @@ -235,14 +275,22 @@ static int i2c_davinci_wait_bus_not_busy(struct > davinci_i2c_dev *dev, > char allow_sleep) > { >unsigned long timeout; > + static u16 to_cnt; > >timeout = jiffies + dev->adapter.timeout; >while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG) > & DAVINCI_I2C_STR_BB) { > - if (time_after(jiffies, timeout)) { > - dev_warn(dev->dev, > -"timeout waiting for bus ready\n"); > - return -ETIMEDOUT; > + if (to_cnt <= DAVINCI_I2C_MAX_TRIES) { > + if (time_after(jiffies, timeout)) { > + dev_warn(dev->dev, > + "timeout waiting for bus ready\n"); > + to_cnt++; > + return -ETIMEDOUT; > + } else { > + to_cnt = 0; > + i2c_recover_bus(dev); > + i2c_davinci_init(dev); > + } >} >if (allow_sleep) >schedule_timeout(1); > The resulting loop has the following drawbacks: 1) If to_cnt reaches DAVINCI_I2C_MAX_TRIES+1 (which it currently can't, see 2) and the i2c bus collapses, the kernel will be stuck in the loop forever, especially if allow_sleep is false. 2) The to_cnt static var never increments beyond 1. It's initialized to zero and then kept at zero until the timeout expires. When the timeout expires, to_cnt is incremented once, until the next call to the function, where it will be zeroed again. 3) Do we really want to retry recovering the bus thousands of times, until the timeout arrives? It seems to me that if the bus recovery procedure didn't hel
Re: [PATCH v3 00/10] split out emac cpdma and mdio for reuse
Hi Caglar, [...] > Assuming that the DMA got stuck at some point leading up to the transmit > timeout, any ideas as to why a host error was not thrown? To help > debug, I'll post out a set of patches that dump out the MAC (and DMA) > registers on timeout. That should give us some visibility into the problem. I have posted a couple of additional patches for this on [1]. Would you mind giving these a quick try? The register dumps should prove useful in figuring this out. Regards Cyril. [1] http://arago-project.org/git/people/?p=cyril/linux-tnetv107x.git;a=shortlog;h=refs/heads/emac-cpdma-mdio-fixes ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 0/7] add tnetv107x input drivers
Texas Instruments' TNETV107X is an ARM1176 based SoC, with on-chip touchscreen and keypad controllers. This patch series adds drivers for these controllers. Cyril Chemparathy (7): davinci: define tnetv107x keypad platform data input: add driver for tnetv107x on-chip keypad controller davinci: add tnetv107x keypad platform device davinci: add keypad config for tnetv107x evm board input: add driver for tnetv107x touchscreen controller davinci: add tnetv107x touchscreen platform device davinci: add touchscreen config for tnetv107x evm board arch/arm/mach-davinci/board-tnetv107x-evm.c| 51 +++ arch/arm/mach-davinci/devices-tnetv107x.c | 54 +++ arch/arm/mach-davinci/include/mach/tnetv107x.h | 24 ++ drivers/input/keyboard/Kconfig |9 + drivers/input/keyboard/Makefile|1 + drivers/input/keyboard/tnetv107x-keypad.c | 324 drivers/input/touchscreen/Kconfig |6 + drivers/input/touchscreen/Makefile |1 + drivers/input/touchscreen/tnetv107x-ts.c | 481 9 files changed, 951 insertions(+), 0 deletions(-) create mode 100644 drivers/input/keyboard/tnetv107x-keypad.c create mode 100644 drivers/input/touchscreen/tnetv107x-ts.c ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 1/7] davinci: define tnetv107x keypad platform data
This patch adds a definition for the platform data structure needed to configure the keypad controller on tnetv107x socs. Since this controller is (so far) present only on tnetv107x devices, the data structure definition has been kept local to tnetv107x. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/include/mach/tnetv107x.h | 10 ++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h index c720647..1ee3035 100644 --- a/arch/arm/mach-davinci/include/mach/tnetv107x.h +++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h @@ -37,6 +37,16 @@ #include #include +struct tnetv107x_keypad_data { + int *keymap; + const char **keynames; + int keymap_size; + int rows; + int cols; + u32 debounce; + u32 stable; +}; + struct tnetv107x_device_info { struct davinci_uart_config *serial_config; struct davinci_mmc_config *mmc_config[2]; /* 2 controllers */ -- 1.7.0.4 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 2/7] input: add driver for tnetv107x on-chip keypad controller
This patch adds support for tnetv107x's on-chip keypad controller. Signed-off-by: Cyril Chemparathy --- drivers/input/keyboard/Kconfig|9 + drivers/input/keyboard/Makefile |1 + drivers/input/keyboard/tnetv107x-keypad.c | 324 + 3 files changed, 334 insertions(+), 0 deletions(-) create mode 100644 drivers/input/keyboard/tnetv107x-keypad.c diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 9cc488d..0ea8648 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -457,4 +457,13 @@ config KEYBOARD_W90P910 To compile this driver as a module, choose M here: the module will be called w90p910_keypad. +config KEYBOARD_TNETV107X + tristate "TI TNETV107X keypad support" + depends on ARCH_DAVINCI_TNETV107X + help + Say Y here if you want to use the TNETV107X keypad. + + To compile this driver as a module, choose M here: the + module will be called tnetv107x-keypad. + endif diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 504b591..63261b0 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -41,3 +41,4 @@ obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o +obj-$(CONFIG_KEYBOARD_TNETV107X) += tnetv107x-keypad.o diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c new file mode 100644 index 000..5039164 --- /dev/null +++ b/drivers/input/keyboard/tnetv107x-keypad.c @@ -0,0 +1,324 @@ +/* + * Texas Instruments TNETV107X Keypad Driver + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define KEYPAD_ROWS9 +#define KEYPAD_COLS9 + +struct keypad_regs { + u32 rev; + u32 mode; + u32 mask; + u32 pol; + u32 dclock; + u32 rclock; + u32 stable_cnt; + u32 in_en; + u32 out; + u32 out_en; + u32 in; + u32 lock; + u32 pres[3]; +}; + +#define keypad_read(kp, reg) __raw_readl(&(kp)->regs->reg) +#define keypad_write(kp, reg, val) __raw_writel(val, &(kp)->regs->reg) + +struct keypad_data { + struct tnetv107x_keypad_datadata; + struct input_dev*input_dev; + struct resource *res; + struct keypad_regs __iomem *regs; + struct clk *clk; + struct device *dev; + u32 irq_press; + u32 irq_release; + u32 curr_keys[3]; + u32 prev_keys[3]; +}; + +static void handle_change(struct keypad_data *kp) +{ + int bit, i; + + for (bit = 0; bit < (KEYPAD_ROWS * KEYPAD_COLS); bit++) { + int idx = bit / 32; + u32 mask= 1 << (bit % 32); + u32 curr= kp->curr_keys[idx] & mask; + u32 prev= kp->prev_keys[idx] & mask; + int row = bit / KEYPAD_COLS; + int col = bit % KEYPAD_COLS; + int ofs = row * kp->data.cols + col; + + if (col >= kp->data.cols || row >= kp->data.rows) + continue; + + if (curr && !prev) { + /* Report key press */ + if (kp->data.keynames && kp->data.keynames[ofs]) + dev_dbg(kp->dev, "%s (%d) pressed\n", + kp->data.keynames[ofs], ofs); + input_report_key(kp->input_dev, +kp->data.keymap[ofs], 1); + } else if (!curr && prev) { + /* Report key release */ + if (kp->data.keynames && kp->data.keynames[ofs]) + dev_dbg(kp->dev, "%s (%d) released\n", + kp->data.keynames[ofs], ofs); + input_report_key(kp->input_dev, +kp->data.keymap[ofs], 0); +
[PATCH 4/7] davinci: add keypad config for tnetv107x evm board
This patch adds evm board specific keymap definitions and controller configuration data for on-chip keypad controller on tnetv107x silicon. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 42 +++ 1 files changed, 42 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index fe2a9d9..2fe7a3f 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -141,10 +142,51 @@ static struct davinci_uart_config serial_config __initconst = { .enabled_uarts = BIT(1), }; +static int keymap[] = { + /* row 0 */ + KEY_NUMERIC_1, KEY_NUMERIC_2, KEY_NUMERIC_3, KEY_FN_F1, KEY_MENU, + /* row 1 */ + KEY_NUMERIC_4, KEY_NUMERIC_5, KEY_NUMERIC_6, KEY_UP, KEY_FN_F2, + /* row 2 */ + KEY_NUMERIC_7, KEY_NUMERIC_8, KEY_NUMERIC_9, KEY_LEFT, KEY_ENTER, + /* row 3 */ + KEY_NUMERIC_STAR, KEY_NUMERIC_0, KEY_NUMERIC_POUND, KEY_DOWN, KEY_RIGHT, + /* row 4 */ + KEY_FN_F3, KEY_FN_F4, KEY_MUTE, KEY_HOME, KEY_BACK, + /* row 5 */ + KEY_VOLUMEDOWN, KEY_VOLUMEUP, KEY_F1, KEY_F2, KEY_F3, +}; + +static const char *keynames[] = { + /* row 0 */ + "1", "2", "3", "S1 (FN_F1)", "MENU", + /* row 1 */ + "4", "5", "6", "UP", "S2 (FN_F2)", + /* row 2 */ + "7", "8", "9", "LEFT", "ENTER", + /* row 3 */ + "*", "0", "#", "DOWN", "RIGHT", + /* row 4 */ + "SPEAKER (FN_F3)", "HEADSET (FN_F4)", "MUTE", "HOME", "BACK", + /* row 5 */ + "VOL_DOWN", "VOL_UP", "F1", "F2", "F3", +}; + +static struct tnetv107x_keypad_data keypad_config = { + .keynames = keynames, + .keymap = keymap, + .keymap_size= ARRAY_SIZE(keymap), + .rows = 6, + .cols = 5, + .debounce = 0x400, + .stable = 0x3, +}; + static struct tnetv107x_device_info evm_device_info __initconst = { .serial_config = &serial_config, .mmc_config[1] = &mmc_config, /* controller 1 */ .nand_config[0] = &nand_config, /* chip select 0 */ + .keypad_config = &keypad_config, }; static __init void tnetv107x_evm_board_init(void) -- 1.7.0.4 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 5/7] input: add driver for tnetv107x touchscreen controller
This patch adds support for tnetv107x's on-chip touchscreen controller. Signed-off-by: Cyril Chemparathy --- drivers/input/touchscreen/Kconfig|6 + drivers/input/touchscreen/Makefile |1 + drivers/input/touchscreen/tnetv107x-ts.c | 481 ++ 3 files changed, 488 insertions(+), 0 deletions(-) create mode 100644 drivers/input/touchscreen/tnetv107x-ts.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 0069d97..e56a170 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -638,4 +638,10 @@ config TOUCHSCREEN_STMPE To compile this driver as a module, choose M here: the module will be called stmpe-ts. +config TOUCHSCREEN_TNETV107X + tristate "TI TNETV107X touchscreen support" + depends on ARCH_DAVINCI_TNETV107X + help + Say Y here if you want to use the TNETV107X touchscreen. + endif diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 28217e1..55a7db9 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -52,3 +52,4 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE)+= mainstone-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o +obj-$(CONFIG_TOUCHSCREEN_TNETV107X)+= tnetv107x-ts.o diff --git a/drivers/input/touchscreen/tnetv107x-ts.c b/drivers/input/touchscreen/tnetv107x-ts.c new file mode 100644 index 000..a8543c5 --- /dev/null +++ b/drivers/input/touchscreen/tnetv107x-ts.c @@ -0,0 +1,481 @@ +/* + * Texas Instruments TNETV107X Touchscreen Driver + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Poll Rates */ +#define TSC_PENUP_POLL (HZ / 5) + +/* + * The first and last samples of a touch interval are usually garbage and need + * to be filtered out with these devices. The following definitions control + * the number of samples skipped. + */ +#define TSC_HEAD_SKIP 1 +#define TSC_TAIL_SKIP 1 +#define TSC_SKIP (TSC_HEAD_SKIP + TSC_TAIL_SKIP + 1) +#define TSC_SAMPLES(TSC_SKIP + 1) + +/* Register Offsets */ +struct tsc_regs { + u32 rev; + u32 tscm; + u32 bwcm; + u32 swc; + u32 adcchnl; + u32 adcdata; + u32 chval[4]; +}; + +/* TSC Mode Configuration Register (tscm) bits */ +#define WMODE BIT(0) +#define TSKIND BIT(1) +#define ZMEASURE_ENBIT(2) +#define IDLE BIT(3) +#define TSC_EN BIT(4) +#define STOP BIT(5) +#define ONE_SHOT BIT(6) +#define SINGLE BIT(7) +#define AVGBIT(8) +#define AVGNUM(x) (((x) & 0x03) << 9) +#define PVSTC(x) (((x) & 0x07) << 11) +#define PONBIT(14) +#define PONBG BIT(15) +#define AFERST BIT(16) + +/* ADC DATA Capture Register bits */ +#define DATA_VALID BIT(16) + +/* Register Access Macros */ +#define tsc_read(ts, reg) __raw_readl(&(ts)->regs->reg) +#define tsc_write(ts, reg, val)__raw_writel(val, &(ts)->regs->reg); +#define tsc_set_bits(ts, reg, val) \ + tsc_write(ts, reg, tsc_read(ts, reg) | (val)) +#define tsc_clr_bits(ts, reg, val) \ + tsc_write(ts, reg, tsc_read(ts, reg) & ~(val)) + +struct sample { + int x, y, p; +}; + +struct tsc_data { + struct tnetv107x_tsc_data data; + struct input_dev*input_dev; + struct resource *res; + struct tsc_regs __iomem *regs; + struct timer_list timer; + spinlock_t lock; + struct clk *clk; + struct device *dev; + int sample_count; + struct sample samples[TSC_SAMPLES]; + int tsc_irq; + int cal[TSC_CAL_SIZE]; +}; + +/* default calibration that works for most evm boards */ +static int tscal_set; +static int tscal[TSC_CAL_SIZE]; +module_param_array(tscal, int, &tscal_set, 0); + +static inline int +tsc_read_sample(struct tsc_data *ts, struct sample* sample) +{ + int x, y, z1, z2, t, p = 0; + u3
[PATCH 3/7] davinci: add tnetv107x keypad platform device
This patch adds a platform device definition for tnetv107x's keypad controller. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/devices-tnetv107x.c | 30 arch/arm/mach-davinci/include/mach/tnetv107x.h |1 + 2 files changed, 31 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index 2718a3a..086269f 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm/mach-davinci/devices-tnetv107x.c @@ -33,6 +33,7 @@ #define TNETV107X_WDOG_BASE0x08086700 #define TNETV107X_SDIO0_BASE 0x08088700 #define TNETV107X_SDIO1_BASE 0x08088800 +#define TNETV107X_KEYPAD_BASE 0x08088a00 #define TNETV107X_ASYNC_EMIF_CNTRL_BASE0x0820 #define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE 0x3000 #define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE 0x4000 @@ -298,6 +299,30 @@ static int __init nand_init(int chipsel, struct davinci_nand_pdata *data) return platform_device_register(pdev); } +static struct resource keypad_resources[] = { + { + .start = TNETV107X_KEYPAD_BASE, + .end= TNETV107X_KEYPAD_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_TNETV107X_KEYPAD, + .flags = IORESOURCE_IRQ, + .name = "press", + }, + { + .start = IRQ_TNETV107X_KEYPAD_FREE, + .flags = IORESOURCE_IRQ, + .name = "release", + }, +}; + +static struct platform_device keypad_device = { + .name = "tnetv107x-keypad", + .num_resources = ARRAY_SIZE(keypad_resources), + .resource = keypad_resources, +}; + void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) { int i; @@ -317,4 +342,9 @@ void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) for (i = 0; i < 4; i++) if (info->nand_config[i]) nand_init(i, info->nand_config[i]); + + if (info->keypad_config) { + keypad_device.dev.platform_data = info->keypad_config; + platform_device_register(&keypad_device); + } } diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h index 1ee3035..9f5350f 100644 --- a/arch/arm/mach-davinci/include/mach/tnetv107x.h +++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h @@ -51,6 +51,7 @@ struct tnetv107x_device_info { struct davinci_uart_config *serial_config; struct davinci_mmc_config *mmc_config[2]; /* 2 controllers */ struct davinci_nand_pdata *nand_config[4]; /* 4 chipsels */ + struct tnetv107x_keypad_data*keypad_config; }; extern struct platform_device tnetv107x_wdt_device; -- 1.7.0.4 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 7/7] davinci: add touchscreen config for tnetv107x evm board
This patch adds evm board specific definitions (dimensions, default calibration, etc.) for the on-chip keypad controller on tnetv107x silicon. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c |9 + 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 2fe7a3f..287c5ee 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -182,11 +182,20 @@ static struct tnetv107x_keypad_data keypad_config = { .stable = 0x3, }; +static struct tnetv107x_tsc_data tsc_config = { + .xres = 800, + .yres = 480, + .calibration_data = { + 217, 14019, -2540712, 8690, -140, -1651470, 65536, + }, +}; + static struct tnetv107x_device_info evm_device_info __initconst = { .serial_config = &serial_config, .mmc_config[1] = &mmc_config, /* controller 1 */ .nand_config[0] = &nand_config, /* chip select 0 */ .keypad_config = &keypad_config, + .tsc_config = &tsc_config, }; static __init void tnetv107x_evm_board_init(void) -- 1.7.0.4 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 6/7] davinci: add tnetv107x touchscreen platform device
This patch adds a platform device definition for tnetv107x's touchscreen controller. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/devices-tnetv107x.c | 24 arch/arm/mach-davinci/include/mach/tnetv107x.h | 13 + 2 files changed, 37 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index 086269f..018ca13 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm/mach-davinci/devices-tnetv107x.c @@ -31,6 +31,7 @@ #define TNETV107X_TPTC0_BASE 0x01c1 #define TNETV107X_TPTC1_BASE 0x01c10400 #define TNETV107X_WDOG_BASE0x08086700 +#define TNETV107X_TSC_BASE 0x08088500 #define TNETV107X_SDIO0_BASE 0x08088700 #define TNETV107X_SDIO1_BASE 0x08088800 #define TNETV107X_KEYPAD_BASE 0x08088a00 @@ -323,6 +324,24 @@ static struct platform_device keypad_device = { .resource = keypad_resources, }; +static struct resource tsc_resources[] = { + { + .start = TNETV107X_TSC_BASE, + .end= TNETV107X_TSC_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_TNETV107X_TSC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device tsc_device = { + .name = "tnetv107x-ts", + .num_resources = ARRAY_SIZE(tsc_resources), + .resource = tsc_resources, +}; + void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) { int i; @@ -347,4 +366,9 @@ void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) keypad_device.dev.platform_data = info->keypad_config; platform_device_register(&keypad_device); } + + if (info->tsc_config) { + tsc_device.dev.platform_data = info->tsc_config; + platform_device_register(&tsc_device); + } } diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h index 9f5350f..7e33148 100644 --- a/arch/arm/mach-davinci/include/mach/tnetv107x.h +++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h @@ -47,11 +47,24 @@ struct tnetv107x_keypad_data { u32 stable; }; +struct tnetv107x_tsc_data { + int xres, yres; + + /* +* Calibration info: +* out_x = (C0 * in_x + C1 * in_y + C2) / C6 +* out_y = (C3 * in_x + C4 * in_y + C5) / C6 +*/ +#define TSC_CAL_SIZE 7 + int calibration_data[TSC_CAL_SIZE]; +}; + struct tnetv107x_device_info { struct davinci_uart_config *serial_config; struct davinci_mmc_config *mmc_config[2]; /* 2 controllers */ struct davinci_nand_pdata *nand_config[4]; /* 4 chipsels */ struct tnetv107x_keypad_data*keypad_config; + struct tnetv107x_tsc_data *tsc_config; }; extern struct platform_device tnetv107x_wdt_device; -- 1.7.0.4 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 00/10] split out emac cpdma and mdio for reuse
On Monday 13 September 2010 05:09:15 pm Cyril Chemparathy wrote: > Hi Caglar, > > [...] > > > Unfortunately emac driver is not stable after this series. I face > > lock-ups time to time, followed by attached kernel trace. > > Could you elaborate on your test scenario so that I can try and > reproduce the problem at my end? Also, did you have the contents of my > commit stack in this particular kernel build? > Ooops! I didn't noticed your commits till you noted, I was working with DaVinci head. Applying patches in your tree solves all my problems and all my use cases are working now. However, I just barely tested them. To make myself forgiven here are my 'netperf' numbers before and after your patches applied: TCP_STREAM: 54.64 Mbit vs 52.84 Mbit UDP_STREAM: 96.27 Mbit vs 96.22 Mbit Regards, Caglar > Assuming that the DMA got stuck at some point leading up to the transmit > timeout, any ideas as to why a host error was not thrown? To help > debug, I'll post out a set of patches that dump out the MAC (and DMA) > registers on timeout. That should give us some visibility into the > problem. > > > [ 1651.44] nfs: server 192.168.2.34 not responding, still trying > > [ 1859.01] [ cut here ] > > [ 1859.01] WARNING: at net/sched/sch_generic.c:258 > > dev_watchdog+0x184/0x294() > > [ 1859.02] NETDEV WATCHDOG: eth0 (davinci_emac): transmit queue 0 > > timed out > > [...] > > Regards > Cyril. > ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v4 1/2] davinci: Add generic PWM support for PWM control
> Sugumar Natarajan wrote: >On Fri, Sep 10, 2010 at 23:12:36, Caglar Akyuz wrote: >> On Thursday 09 September 2010 01:40:49 pm Sugumar Natarajan wrote: >> > This patch adds generic PWM support where it maintains the list of PWM >> > control devices that can be added or removed. >> > >> > The interface provides a list of functions that can be accessed by the >> > PWM control driver module and the generic PWM driver. >> > >> > The PWM control driver module such as eCAP uses the interface to >> > register and add itself to the list as a PWM control device. >> > The generic PWM driver uses the interface to search for a PWM control >> > device and if present, uses the device for PWM control. >> > >> > Signed-off-by: Sugumar Natarajan >> > --- >> >> Hi, >> >> [...] >> >> > + >> > +int pwm_enable(struct pwm_device *pwm) { >> > + if (WARN_ON(!pwm)) >> > + return -EINVAL; >> > + >> > + return clk_enable(pwm->clk); >> > +} >> > +EXPORT_SYMBOL(pwm_enable); >> > + >> >> I think 'clk_enable' should be controlled for un-matched pwm_enable/disable >operation. Otherwise, disabling PWM won't shut down >peripheral clock. If I understand inner workings of DaVinci clock >implementation clock use_count is incremented with every >clk_enable. >> >> Regards, >> Caglar >> > >Caglar, > I could not understand what you mean by "un-match" .could you please >explain? >Regards, >N.sugumar List server didn't deliver this mail to me, I saw it from the archives. I mean something like this: int pwm_enable(struct pwm_device *pwm) { int rc = 0; if (WARN_ON(!pwm)) return -EINVAL; if (!pwm->clk_enabled) { rc = clk_enable(pwm->clk); if (!rc) pwm->clk_enabled = 1; } return rc; } The reason is 'pwm_enable' can be called over and over without 'pwm_disable' and vice versa. For instance, every time backlight value is changed, pwm_enable is called by the backlight framework. Regards, Caglar ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 3/9] net: davinci_cpdma: requeue on early end-of-queue
When chaining descriptors to the end of a cpdma queue, there is a chance that the cpdma engine has already traversed the last descriptor and signalled an end-of-queue. The original cpdma code detected this condition and requeued descriptors on submission. With this patch, an early end-of-queue condition is detected on descriptor submission as well. This is necessary on davinci style emac controllers, and prevents transmit timeouts when sending out a burst of packets. Signed-off-by: Cyril Chemparathy Signed-off-by: Michael Williamson Signed-off-by: Caglar Akyuz --- drivers/net/davinci_cpdma.c | 12 ++-- drivers/net/davinci_cpdma.h |1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/davinci_cpdma.c b/drivers/net/davinci_cpdma.c index ab7ecd7..abc2b14 100644 --- a/drivers/net/davinci_cpdma.c +++ b/drivers/net/davinci_cpdma.c @@ -488,6 +488,7 @@ static void __cpdma_chan_submit(struct cpdma_chan *chan, struct cpdma_desc __iomem *prev = chan->tail; struct cpdma_desc_pool *pool = ctlr->pool; dma_addr_t desc_dma; + u32 mode; desc_dma = desc_phys(pool, desc); @@ -507,8 +508,10 @@ static void __cpdma_chan_submit(struct cpdma_chan *chan, chan->stats.tail_enqueue++; /* next check if EOQ has been triggered already */ - if (desc_read(prev, hw_mode) & CPDMA_DESC_EOQ && - chan->state == CPDMA_STATE_ACTIVE) { + mode = desc_read(prev, hw_mode); + if (((mode & (CPDMA_DESC_EOQ | CPDMA_DESC_OWNER)) == CPDMA_DESC_EOQ) && + (chan->state == CPDMA_STATE_ACTIVE)) { + desc_write(prev, hw_mode, mode & ~CPDMA_DESC_EOQ); chan_write(chan, hdp, desc_dma); chan->stats.misqueued++; } @@ -618,6 +621,11 @@ static int __cpdma_chan_process(struct cpdma_chan *chan) chan->count--; chan->stats.good_dequeue++; + if (status & CPDMA_DESC_EOQ) { + chan->stats.requeue++; + chan_write(chan, hdp, desc_phys(pool, chan->head)); + } + spin_unlock_irqrestore(&chan->lock, flags); __cpdma_chan_free(chan, desc, outlen, status); diff --git a/drivers/net/davinci_cpdma.h b/drivers/net/davinci_cpdma.h index d50ee35..9baacca 100644 --- a/drivers/net/davinci_cpdma.h +++ b/drivers/net/davinci_cpdma.h @@ -56,6 +56,7 @@ struct cpdma_chan_stats { u32 empty_dequeue; u32 busy_dequeue; u32 good_dequeue; + u32 requeue; u32 teardown_dequeue; }; -- 1.7.0.4 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 1/9] net: davinci_emac: allow forced 100/full via phy_id
With this patch, phy_id can be one of the following: 1) NULL : use the first phy on the bus, 2) "" : force to 100/full, no mdio control 3) ":" : use the specified bus and phy The ability to force 100/full is necessary on some platforms (e.g. da830 evm), where an on-board switch may be connected on the emac mii. Signed-off-by: Cyril Chemparathy Signed-off-by: Michael Williamson Signed-off-by: Caglar Akyuz --- drivers/net/davinci_emac.c |2 +- include/linux/davinci_emac.h |7 +++ 2 files changed, 8 insertions(+), 1 deletions(-) diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 525b84c..363c970 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -1566,7 +1566,7 @@ static int emac_dev_open(struct net_device *ndev) priv->phy_id = dev_name(phy); } - if (priv->phy_id) { + if (priv->phy_id && *priv->phy_id) { priv->phydev = phy_connect(ndev, priv->phy_id, &emac_adjust_link, 0, PHY_INTERFACE_MODE_MII); diff --git a/include/linux/davinci_emac.h b/include/linux/davinci_emac.h index 7508e49..9ae9ff0 100644 --- a/include/linux/davinci_emac.h +++ b/include/linux/davinci_emac.h @@ -25,6 +25,13 @@ struct emac_platform_data { u32 ctrl_ram_offset; u32 hw_ram_addr; u32 ctrl_ram_size; + + /* +* phy_id can be one of the following: +* - NULL : use the first phy on the bus, +* - "" : force to 100/full, no mdio control +* - ":" : use the specified bus and phy +*/ const char *phy_id; u8 rmii_en; u8 version; -- 1.7.0.4 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 4/9] net: davinci_emac: fix rx error handling
This patch adds the following fixes to the emac receive handler: 1. WARN_ON during interface shutdown. Although harmless, these complaints were quite disconcerting. With this patch, the receive handler explicitly checks for the shutdown condition, in which case is bails quietly. 2. Update rx_error stats on dma receive error 3. Rate limit error messages on buffer allocation failures Signed-off-by: Cyril Chemparathy Signed-off-by: Michael Williamson Signed-off-by: Caglar Akyuz --- drivers/net/davinci_emac.c | 25 +++-- 1 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 363c970..9e866ae 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -1002,13 +1002,22 @@ static void emac_rx_handler(void *token, int len, int status) struct sk_buff *skb = token; struct net_device *ndev = skb->dev; struct emac_priv*priv = netdev_priv(ndev); + struct device *emac_dev = &ndev->dev; int ret; + /* free and bail if we are shutting down */ + if (unlikely(!netif_running(ndev))) { + dev_kfree_skb_any(skb); + return; + } + + /* recycle on recieve error */ if (status < 0) { - /* error */ + ndev->stats.rx_errors++; goto recycle; } + /* feed received packet up the stack */ skb_put(skb, len); skb->protocol = eth_type_trans(skb, ndev); netif_receive_skb(skb); @@ -1017,13 +1026,17 @@ static void emac_rx_handler(void *token, int len, int status) /* alloc a new packet for receive */ skb = emac_rx_alloc(priv); + if (!skb) { + if (netif_msg_rx_err(priv) && net_ratelimit()) + dev_err(emac_dev, "failed rx buffer alloc\n"); + return; + } recycle: - if (skb) { - ret = cpdma_chan_submit(priv->rxchan, skb, skb->data, - skb_tailroom(skb), GFP_KERNEL); - WARN_ON(ret < 0); - } + ret = cpdma_chan_submit(priv->rxchan, skb, skb->data, + skb_tailroom(skb), GFP_KERNEL); + if (WARN_ON(ret < 0)) + dev_kfree_skb_any(skb); } static void emac_tx_handler(void *token, int len, int status) -- 1.7.0.4 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 6/9] net: davinci_mdio: use calculated bus access times
This patch replaces the hardcoded scan delay with a calculated delay that adjusts to clock rates. This delay is calculated on the basis of a worst case bus transaction time, with generous built-in margins of error. Signed-off-by: Cyril Chemparathy Signed-off-by: Michael Williamson Signed-off-by: Caglar Akyuz --- drivers/net/davinci_mdio.c | 33 +++-- 1 files changed, 23 insertions(+), 10 deletions(-) diff --git a/drivers/net/davinci_mdio.c b/drivers/net/davinci_mdio.c index a9fbc26..f2d7639 100644 --- a/drivers/net/davinci_mdio.c +++ b/drivers/net/davinci_mdio.c @@ -83,11 +83,12 @@ struct davinci_mdio_data { struct device *dev; struct mii_bus *bus; boolsuspended; + unsigned long access_time; /* jiffies */ }; static void __davinci_mdio_reset(struct davinci_mdio_data *data) { - u32 mdio_in, div; + u32 mdio_in, div, mdio_out_khz, access_time; mdio_in = clk_get_rate(data->clk); div = (mdio_in / data->pdata.bus_freq) - 1; @@ -96,6 +97,25 @@ static void __davinci_mdio_reset(struct davinci_mdio_data *data) /* set enable and clock divider */ __raw_writel(div | CONTROL_ENABLE, &data->regs->control); + + /* +* One mdio transaction consists of: +* 32 bits of preamble +* 32 bits of transferred data +* 24 bits of bus yield (not needed unless shared?) +*/ + mdio_out_khz = mdio_in / (1000 * (div + 1)); + access_time = (88 * 1000) / mdio_out_khz; + + /* +* In the worst case, we could be kicking off a user-access immediately +* after the mdio bus scan state-machine triggered its own read. If +* so, our request could get deferred by one access cycle. We +* defensively allow for 4 access cycles. +*/ + data->access_time = usecs_to_jiffies(access_time * 4); + if (!data->access_time) + data->access_time = 1; } static int davinci_mdio_reset(struct mii_bus *bus) @@ -105,15 +125,8 @@ static int davinci_mdio_reset(struct mii_bus *bus) __davinci_mdio_reset(data); - /* -* wait for scan logic to settle: -* the scan time consists of (a) a large fixed component, and (b) a -* small component that varies with the mii bus frequency. These -* were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x -* silicon. Since the effect of (b) was found to be largely -* negligible, we keep things simple here. -*/ - mdelay(1); + /* wait for scan logic to settle */ + msleep(PHY_MAX_ADDR * data->access_time); /* dump hardware version info */ ver = __raw_readl(&data->regs->version); -- 1.7.0.4 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 2/9] davinci: specify phy_id rather than auto-detect
The cpdma/mdio refactoring incorrectly defaulted to using the first phy detected on the platform. Although auto detection works on most sane platforms, it can prove to be problematic on some. For example, the da830/omap-l137 evm has an on-board switch that always connects 100/full. Consequently, normal phy auto-detection does not work on this platform. Rather than risk breaking other boards, this patch reverts to using hard-coded phy ids on platforms that did so earlier. Signed-off-by: Cyril Chemparathy Signed-off-by: Michael Williamson Signed-off-by: Caglar Akyuz --- arch/arm/mach-davinci/board-da830-evm.c|2 ++ arch/arm/mach-davinci/board-da850-evm.c|3 +++ arch/arm/mach-davinci/board-dm365-evm.c|4 arch/arm/mach-davinci/board-dm644x-evm.c |3 +++ arch/arm/mach-davinci/board-dm646x-evm.c |5 + arch/arm/mach-davinci/board-mityomapl138.c |3 +++ arch/arm/mach-davinci/board-neuros-osd2.c |4 arch/arm/mach-davinci/board-sffsdr.c |4 8 files changed, 28 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 2613324..1bb89d3 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -31,6 +31,7 @@ #include #include +#define DA830_EVM_PHY_ID "" /* * USB1 VBUS is controlled by GPIO1[15], over-current is reported on GPIO2[4]. */ @@ -556,6 +557,7 @@ static __init void da830_evm_init(void) da830_evm_usb_init(); soc_info->emac_pdata->rmii_en = 1; + soc_info->emac_pdata->phy_id = DA830_EVM_PHY_ID; ret = davinci_cfg_reg_list(da830_cpgmac_pins); if (ret) diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 9d4dfcb..5e435b0 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -38,6 +38,7 @@ #include #include +#define DA850_EVM_PHY_ID "0:00" #define DA850_LCD_PWR_PIN GPIO_TO_PIN(2, 8) #define DA850_LCD_BL_PIN GPIO_TO_PIN(2, 15) @@ -675,6 +676,8 @@ static int __init da850_evm_config_emac(void) /* Enable/Disable MII MDIO clock */ gpio_direction_output(DA850_MII_MDIO_CLKEN_PIN, rmii_en); + soc_info->emac_pdata->phy_id = DA850_EVM_PHY_ID; + ret = da8xx_register_emac(); if (ret) pr_warning("da850_evm_init: emac registration failed: %d\n", diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index f697914..86d9abc 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -54,6 +54,7 @@ static inline int have_tvp7002(void) return 0; } +#define DM365_EVM_PHY_ID "0:01" /* * A MAX-II CPLD is used for various board control functions. */ @@ -527,12 +528,15 @@ fail: /* externally mux MMC1/ENET/AIC33 to imager */ mux |= BIT(6) | BIT(5) | BIT(3); } else { + struct davinci_soc_info *soc_info = &davinci_soc_info; + /* we can use MMC1 ... */ dm365evm_mmc_configure(); davinci_setup_mmc(1, &dm365evm_mmc_config); /* ... and ENET ... */ dm365evm_emac_configure(); + soc_info->emac_pdata->phy_id = DM365_EVM_PHY_ID; resets &= ~BIT(3); /* ... and AIC33 */ diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index c86bf23..44a2f0a 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -39,6 +39,7 @@ #include #include +#define DM644X_EVM_PHY_ID "0:01" #define LXT971_PHY_ID (0x001378e2) #define LXT971_PHY_MASK(0xfff0) @@ -669,6 +670,7 @@ static int davinci_phy_fixup(struct phy_device *phydev) static __init void davinci_evm_init(void) { struct clk *aemif_clk; + struct davinci_soc_info *soc_info = &davinci_soc_info; aemif_clk = clk_get(NULL, "aemif"); clk_enable(aemif_clk); @@ -703,6 +705,7 @@ static __init void davinci_evm_init(void) davinci_serial_init(&uart_config); dm644x_init_asp(&dm644x_evm_snd_data); + soc_info->emac_pdata->phy_id = DM644X_EVM_PHY_ID; /* Register the fixup for PHY on DaVinci */ phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK, davinci_phy_fixup); diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 3f34221..67669bb 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -729,6 +729,7 @@ static struct davinci_uart_config uart_config __initdata = { .enabled_uarts = (1 << 0), }; +#define DM646X_EVM_PHY_ID
[PATCH 0/9] post cpdma/mdio refactoring fixes
This series consists of fixes for issues found during broader testing of the davinci cpdma/mdio separation series. The fixes included here are: 1. Ability to force 100/full rather than auto-detect phy. This is necessary for the external switch on the da830 evm platform 2. Fix end-of-queue requeue to include checks at submission time (in addition to pre-existing completion time checks). 3. Cleanups to rx path error handling. This prevents unnecessary stack dumps for perfectly legal situations. 4. Work around for emac-soft-reset tie-up to mdio controller. This affects all da8xx family devices (and possibly am35xx as well). 5. Reworked hard-coded scan-time estimate to use a more accurate calculated number instead. 6. Code to generate cpdma register dumps, useful during debug. Many thanks to Mike and Caglar for patiently working with me through these issues, I've taken the liberty of adding their sign offs. Cyril Chemparathy (9): net: davinci_emac: allow forced 100/full via phy_id davinci: specify phy_id rather than auto-detect net: davinci_cpdma: requeue on early end-of-queue net: davinci_emac: fix rx error handling net: davinci_mdio: separate out controller reset net: davinci_mdio: use calculated bus access times net: davinci_mdio: work around emac soft-reset during i/o net: davinci_cpdma: add register dump routines net: davinci_emac: extended register dumps on tx timeout arch/arm/mach-davinci/board-da830-evm.c|2 + arch/arm/mach-davinci/board-da850-evm.c|3 + arch/arm/mach-davinci/board-dm365-evm.c|4 + arch/arm/mach-davinci/board-dm644x-evm.c |3 + arch/arm/mach-davinci/board-dm646x-evm.c |5 + arch/arm/mach-davinci/board-mityomapl138.c |3 + arch/arm/mach-davinci/board-neuros-osd2.c |4 + arch/arm/mach-davinci/board-sffsdr.c |4 + drivers/net/davinci_cpdma.c| 132 ++- drivers/net/davinci_cpdma.h|3 + drivers/net/davinci_emac.c | 31 - drivers/net/davinci_mdio.c | 195 include/linux/davinci_emac.h |7 + 13 files changed, 334 insertions(+), 62 deletions(-) ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 7/9] net: davinci_mdio: work around emac soft-reset during i/o
On certain devices (e.g. da8xx), the hardware design ties emac soft-reset to the mdio module. In these cases, when the emac device is opened, an in-flight mdio transaction could fail by returning the controller to idle state. This patch detects this condition and works around it by retrying the failed transaction. In addition, defensive timeouts have been added to prevent an indefinite lockup in case of an unexpected hardware error. Signed-off-by: Cyril Chemparathy Signed-off-by: Michael Williamson Signed-off-by: Caglar Akyuz --- drivers/net/davinci_mdio.c | 92 --- 1 files changed, 77 insertions(+), 15 deletions(-) diff --git a/drivers/net/davinci_mdio.c b/drivers/net/davinci_mdio.c index f2d7639..7615040 100644 --- a/drivers/net/davinci_mdio.c +++ b/drivers/net/davinci_mdio.c @@ -36,6 +36,13 @@ #include #include +/* + * This timeout definition is a worst-case ultra defensive measure against + * unexpected controller lock ups. Ideally, we should never ever hit this + * scenario in practice. + */ +#define MDIO_TIMEOUT 100 /* msecs */ + #define PHY_REG_MASK 0x1f #define PHY_ID_MASK0x1f @@ -150,30 +157,53 @@ static int davinci_mdio_reset(struct mii_bus *bus) } /* wait until hardware is ready for another user access */ -static inline u32 wait_for_user_access(struct davinci_mdio_data *data) +static inline int wait_for_user_access(struct davinci_mdio_data *data) { struct davinci_mdio_regs __iomem *regs = data->regs; + unsigned long timeout = jiffies + msecs_to_jiffies(MDIO_TIMEOUT); u32 reg; - while ((reg = __raw_readl(®s->user[0].access)) & USERACCESS_GO) - ; - - return reg; + while (time_after(timeout, jiffies)) { + reg = __raw_readl(®s->user[0].access); + if ((reg & USERACCESS_GO) == 0) + return 0; + + reg = __raw_readl(®s->control); + if ((reg & CONTROL_IDLE) == 0) + continue; + + /* +* An emac soft_reset may have clobbered the mdio controller's +* state machine. We need to reset and retry the current +* operation +*/ + dev_warn(data->dev, "resetting idled controller\n"); + __davinci_mdio_reset(data); + return -EAGAIN; + } + dev_err(data->dev, "timed out waiting for user access\n"); + return -ETIMEDOUT; } /* wait until hardware state machine is idle */ -static inline void wait_for_idle(struct davinci_mdio_data *data) +static inline int wait_for_idle(struct davinci_mdio_data *data) { struct davinci_mdio_regs __iomem *regs = data->regs; + unsigned long timeout = jiffies + msecs_to_jiffies(MDIO_TIMEOUT); - while ((__raw_readl(®s->control) & CONTROL_IDLE) == 0) - ; + while (time_after(timeout, jiffies)) { + if (__raw_readl(®s->control) & CONTROL_IDLE) + return 0; + } + dev_err(data->dev, "timed out waiting for idle\n"); + return -ETIMEDOUT; } static int davinci_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg) { struct davinci_mdio_data *data = bus->priv; u32 reg; + int ret; if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK) return -EINVAL; @@ -185,14 +215,32 @@ static int davinci_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg) return -ENODEV; } - wait_for_user_access(data); reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) | (phy_id << 16)); - __raw_writel(reg, &data->regs->user[0].access); - reg = wait_for_user_access(data); + + while (1) { + ret = wait_for_user_access(data); + if (ret == -EAGAIN) + continue; + if (ret < 0) + break; + + __raw_writel(reg, &data->regs->user[0].access); + + ret = wait_for_user_access(data); + if (ret == -EAGAIN) + continue; + if (ret < 0) + break; + + reg = __raw_readl(&data->regs->user[0].access); + ret = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -EIO; + break; + } + spin_unlock(&data->lock); - return (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -EIO; + return ret; } static int davinci_mdio_write(struct mii_bus *bus, int phy_id, @@ -200,6 +248,7 @@ static int davinci_mdio_write(struct mii_bus *bus, int phy_id, { struct davinci_mdio_data *data = bus->priv; u32 reg; + int ret; if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK) return -EINVAL; @@ -211,11 +260,24 @@ static int davinci_mdio_write(struct mii_bus *bus, int phy_i
[PATCH 8/9] net: davinci_cpdma: add register dump routines
This patch adds register dump routines at both controller and channel levels. These are intended to be used in higher level driver debug dumps, e.g. emac_dump_regs(). Signed-off-by: Cyril Chemparathy Signed-off-by: Michael Williamson Signed-off-by: Caglar Akyuz --- drivers/net/davinci_cpdma.c | 120 +++ drivers/net/davinci_cpdma.h |2 + 2 files changed, 122 insertions(+), 0 deletions(-) diff --git a/drivers/net/davinci_cpdma.c b/drivers/net/davinci_cpdma.c index abc2b14..e92b2b6 100644 --- a/drivers/net/davinci_cpdma.c +++ b/drivers/net/davinci_cpdma.c @@ -91,6 +91,8 @@ enum cpdma_state { CPDMA_STATE_TEARDOWN, }; +const char *cpdma_state_str[] = { "idle", "active", "teardown" }; + struct cpdma_ctlr { enum cpdma_statestate; struct cpdma_params params; @@ -345,6 +347,76 @@ int cpdma_ctlr_stop(struct cpdma_ctlr *ctlr) return 0; } +int cpdma_ctlr_dump(struct cpdma_ctlr *ctlr) +{ + struct device *dev = ctlr->dev; + unsigned long flags; + int i; + + spin_lock_irqsave(&ctlr->lock, flags); + + dev_info(dev, "CPDMA: state: %s", cpdma_state_str[ctlr->state]); + + dev_info(dev, "CPDMA: txidver: %x", +dma_reg_read(ctlr, CPDMA_TXIDVER)); + dev_info(dev, "CPDMA: txcontrol: %x", +dma_reg_read(ctlr, CPDMA_TXCONTROL)); + dev_info(dev, "CPDMA: txteardown: %x", +dma_reg_read(ctlr, CPDMA_TXTEARDOWN)); + dev_info(dev, "CPDMA: rxidver: %x", +dma_reg_read(ctlr, CPDMA_RXIDVER)); + dev_info(dev, "CPDMA: rxcontrol: %x", +dma_reg_read(ctlr, CPDMA_RXCONTROL)); + dev_info(dev, "CPDMA: softreset: %x", +dma_reg_read(ctlr, CPDMA_SOFTRESET)); + dev_info(dev, "CPDMA: rxteardown: %x", +dma_reg_read(ctlr, CPDMA_RXTEARDOWN)); + dev_info(dev, "CPDMA: txintstatraw: %x", +dma_reg_read(ctlr, CPDMA_TXINTSTATRAW)); + dev_info(dev, "CPDMA: txintstatmasked: %x", +dma_reg_read(ctlr, CPDMA_TXINTSTATMASKED)); + dev_info(dev, "CPDMA: txintmaskset: %x", +dma_reg_read(ctlr, CPDMA_TXINTMASKSET)); + dev_info(dev, "CPDMA: txintmaskclear: %x", +dma_reg_read(ctlr, CPDMA_TXINTMASKCLEAR)); + dev_info(dev, "CPDMA: macinvector: %x", +dma_reg_read(ctlr, CPDMA_MACINVECTOR)); + dev_info(dev, "CPDMA: maceoivector: %x", +dma_reg_read(ctlr, CPDMA_MACEOIVECTOR)); + dev_info(dev, "CPDMA: rxintstatraw: %x", +dma_reg_read(ctlr, CPDMA_RXINTSTATRAW)); + dev_info(dev, "CPDMA: rxintstatmasked: %x", +dma_reg_read(ctlr, CPDMA_RXINTSTATMASKED)); + dev_info(dev, "CPDMA: rxintmaskset: %x", +dma_reg_read(ctlr, CPDMA_RXINTMASKSET)); + dev_info(dev, "CPDMA: rxintmaskclear: %x", +dma_reg_read(ctlr, CPDMA_RXINTMASKCLEAR)); + dev_info(dev, "CPDMA: dmaintstatraw: %x", +dma_reg_read(ctlr, CPDMA_DMAINTSTATRAW)); + dev_info(dev, "CPDMA: dmaintstatmasked: %x", +dma_reg_read(ctlr, CPDMA_DMAINTSTATMASKED)); + dev_info(dev, "CPDMA: dmaintmaskset: %x", +dma_reg_read(ctlr, CPDMA_DMAINTMASKSET)); + dev_info(dev, "CPDMA: dmaintmaskclear: %x", +dma_reg_read(ctlr, CPDMA_DMAINTMASKCLEAR)); + + if (!ctlr->params.has_ext_regs) { + dev_info(dev, "CPDMA: dmacontrol: %x", +dma_reg_read(ctlr, CPDMA_DMACONTROL)); + dev_info(dev, "CPDMA: dmastatus: %x", +dma_reg_read(ctlr, CPDMA_DMASTATUS)); + dev_info(dev, "CPDMA: rxbuffofs: %x", +dma_reg_read(ctlr, CPDMA_RXBUFFOFS)); + } + + for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++) + if (ctlr->channels[i]) + cpdma_chan_dump(ctlr->channels[i]); + + spin_unlock_irqrestore(&ctlr->lock, flags); + return 0; +} + int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr) { unsigned long flags; @@ -481,6 +553,54 @@ int cpdma_chan_get_stats(struct cpdma_chan *chan, return 0; } +int cpdma_chan_dump(struct cpdma_chan *chan) +{ + unsigned long flags; + struct device *dev = chan->ctlr->dev; + + spin_lock_irqsave(&chan->lock, flags); + + dev_info(dev, "channel %d (%s %d) state %s", +chan->chan_num, is_rx_chan(chan) ? "rx" : "tx", +chan_linear(chan), cpdma_state_str[chan->state]); + dev_info(dev, "\thdp: %x\n", chan_read(chan, hdp)); + dev_info(dev, "\tcp: %x\n", chan_read(chan, cp)); + if (chan->rxfree) { + dev_info(dev, "\trxfree: %x\n", +chan_read(chan, rxfree)); + } + + dev_info(dev, "\tstats head_enqueue: %d\n", +chan->stats.head_enqueue); + dev_info(dev, "\tstats t
[PATCH 5/9] net: davinci_mdio: separate out controller reset
This patch separates out the controller reset logic, and makes this available via mii_bus->reset. Signed-off-by: Cyril Chemparathy Signed-off-by: Michael Williamson Signed-off-by: Caglar Akyuz --- drivers/net/davinci_mdio.c | 90 +-- 1 files changed, 52 insertions(+), 38 deletions(-) diff --git a/drivers/net/davinci_mdio.c b/drivers/net/davinci_mdio.c index d34a53a..a9fbc26 100644 --- a/drivers/net/davinci_mdio.c +++ b/drivers/net/davinci_mdio.c @@ -85,6 +85,57 @@ struct davinci_mdio_data { boolsuspended; }; +static void __davinci_mdio_reset(struct davinci_mdio_data *data) +{ + u32 mdio_in, div; + + mdio_in = clk_get_rate(data->clk); + div = (mdio_in / data->pdata.bus_freq) - 1; + if (div > CONTROL_MAX_DIV) + div = CONTROL_MAX_DIV; + + /* set enable and clock divider */ + __raw_writel(div | CONTROL_ENABLE, &data->regs->control); +} + +static int davinci_mdio_reset(struct mii_bus *bus) +{ + struct davinci_mdio_data *data = bus->priv; + u32 phy_mask, ver; + + __davinci_mdio_reset(data); + + /* +* wait for scan logic to settle: +* the scan time consists of (a) a large fixed component, and (b) a +* small component that varies with the mii bus frequency. These +* were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x +* silicon. Since the effect of (b) was found to be largely +* negligible, we keep things simple here. +*/ + mdelay(1); + + /* dump hardware version info */ + ver = __raw_readl(&data->regs->version); + dev_info(data->dev, "davinci mdio revision %d.%d\n", +(ver >> 8) & 0xff, ver & 0xff); + + /* get phy mask from the alive register */ + phy_mask = __raw_readl(&data->regs->alive); + if (phy_mask) { + /* restrict mdio bus to live phys only */ + dev_info(data->dev, "detected phy mask %x\n", ~phy_mask); + phy_mask = ~phy_mask; + } else { + /* desperately scan all phys */ + dev_warn(data->dev, "no live phy, scanning all\n"); + phy_mask = 0; + } + data->bus->phy_mask = phy_mask; + + return 0; +} + /* wait until hardware is ready for another user access */ static inline u32 wait_for_user_access(struct davinci_mdio_data *data) { @@ -163,7 +214,6 @@ static int __devinit davinci_mdio_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct davinci_mdio_data *data; struct resource *res; - u32 mdio_in_freq, mdio_out_freq, div, phy_mask, ver; struct phy_device *phy; int ret, addr; @@ -185,6 +235,7 @@ static int __devinit davinci_mdio_probe(struct platform_device *pdev) data->bus->name = dev_name(dev); data->bus->read = davinci_mdio_read, data->bus->write= davinci_mdio_write, + data->bus->reset= davinci_mdio_reset, data->bus->parent = dev; data->bus->priv = data; snprintf(data->bus->id, MII_BUS_ID_SIZE, "%x", pdev->id); @@ -225,43 +276,6 @@ static int __devinit davinci_mdio_probe(struct platform_device *pdev) goto bail_out; } - mdio_in_freq = clk_get_rate(data->clk); - div = (mdio_in_freq / data->pdata.bus_freq) - 1; - if (div > CONTROL_MAX_DIV) - div = CONTROL_MAX_DIV; - mdio_out_freq = mdio_in_freq / (div + 1); - - /* set enable and clock divider */ - __raw_writel(div | CONTROL_ENABLE, &data->regs->control); - - /* -* wait for scan logic to settle: -* the scan time consists of (a) a large fixed component, and (b) a -* small component that varies with the mii bus frequency. These -* were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x -* silicon. Since the effect of (b) was found to be largely -* negligible, we keep things simple here. -*/ - mdelay(1); - - /* dump hardware version info */ - ver = __raw_readl(&data->regs->version); - dev_info(dev, "davinci mdio revision %d.%d\n", - (ver >> 8) & 0xff, ver & 0xff); - - /* get phy mask from the alive register */ - phy_mask = __raw_readl(&data->regs->alive); - if (phy_mask) { - /* restrict mdio bus to live phys only */ - dev_info(dev, "detected phy mask %x\n", ~phy_mask); - phy_mask = ~phy_mask; - } else { - /* desperately scan all phys */ - dev_warn(dev, "failed to detect live phys, scanning all\n"); - phy_mask = 0; - } - data->bus->phy_mask = phy_mask; - /* register the mii bus */ ret = mdiobus_register(data->bus); if (ret) -- 1.7.0.4 ___ Dav
[PATCH 9/9] net: davinci_emac: extended register dumps on tx timeout
This patch hooks up the emac_dump_regs() function to use cpdma dump routines. Further, we dump registers on transmit timeout, to make such timeouts debuggable. Signed-off-by: Cyril Chemparathy Signed-off-by: Michael Williamson Signed-off-by: Caglar Akyuz --- drivers/net/davinci_emac.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 9e866ae..2a628d1 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -460,6 +460,8 @@ static void emac_dump_regs(struct emac_priv *priv) emac_read(EMAC_RXMOFOVERRUNS)); dev_info(emac_dev, "EMAC: rx_dma_overruns:%d\n", emac_read(EMAC_RXDMAOVERRUNS)); + + cpdma_ctlr_dump(priv->dma); } /** @@ -1115,6 +1117,8 @@ static void emac_dev_tx_timeout(struct net_device *ndev) if (netif_msg_tx_err(priv)) dev_err(emac_dev, "DaVinci EMAC: xmit timeout, restarting TX"); + emac_dump_regs(priv); + ndev->stats.tx_errors++; emac_int_disable(priv); cpdma_chan_stop(priv->txchan); -- 1.7.0.4 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
mt9p031 driver for dm355 (for the latest arago staging 2.6.32 tree)
Hi The patch below was tested against the following kernel: http://arago-project.org/git/projects/?p=linux-davinci.git;a=commit;h=0a9d0bc0057964ba667de67395ba5de0447d23b2 The driver supports the full speeds as advertised by micron From e282f467860f58a5b32081521f5219a7de333f99 Mon Sep 17 00:00:00 2001 From: Yanir Lubetkin Date: Mon, 13 Sep 2010 13:51:47 +0200 Subject: [PATCH] mt9p031 support for dm355-evm --- arch/arm/mach-davinci/board-dm355-evm.c| 49 ++- drivers/media/video/Kconfig| 10 + drivers/media/video/Makefile |1 + drivers/media/video/davinci/vpfe_capture.c |2 +- drivers/media/video/mt9p031.c | 834 drivers/mfd/dm355evm_msp.c | 12 +- include/media/davinci/vpfe_capture.h |1 + include/media/v4l2-chip-ident.h|3 + 8 files changed, 902 insertions(+), 10 deletions(-) create mode 100644 drivers/media/video/mt9p031.c diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 5d3946e..dd329dd 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -179,9 +179,11 @@ static struct i2c_board_info dm355evm_i2c_info[] = { { I2C_BOARD_INFO("dm355evm_msp", 0x25), .platform_data = dm355evm_mmcsd_gpios, }, +#if defined(CONFIG_SOC_CAMERA_MT9T031) { I2C_BOARD_INFO("PCA9543A", 0x73), }, +#endif /* { plus irq }, */ { I2C_BOARD_INFO("tlv320aic33", 0x1b), }, }; @@ -190,8 +192,10 @@ static struct i2c_board_info dm355evm_i2c_info[] = { static inline int have_sensor(void) { #if defined(CONFIG_SOC_CAMERA_MT9T031) || \ -defined(CONFIG_SOC_CAMERA_MT9T031_MODULE) - return 1; +defined(CONFIG_SOC_CAMERA_MT9T031_MODULE) || \ +defined(CONFIG_VIDEO_MT9P031) || \ +defined(CONFIG_VIDEO_MT9P031_MODULE) + return 1; #else return 0; #endif @@ -204,8 +208,10 @@ static void __init evm_init_i2c(void) gpio_request(5, "dm355evm_msp"); gpio_direction_input(5); dm355evm_i2c_info[0].irq = gpio_to_irq(5); +#if defined(CONFIG_SOC_CAMERA_MT9T031) if (have_sensor()) i2c_add_driver(&pca9543a_driver); +#endif i2c_register_board_info(1, dm355evm_i2c_info, ARRAY_SIZE(dm355evm_i2c_info)); } @@ -266,18 +272,21 @@ static int dm355evm_enable_pca9543a(int en) */ static int dm355evm_setup_video_input(enum vpfe_subdev_id id) { - int ret; - + int ret = 0; +#if defined CONFIG_VIDEO_CAPTURE_DRIVERS switch (id) { + case VPFE_SUBDEV_MT9P031: case VPFE_SUBDEV_MT9T031: { ret = dm355evm_msp_write(MSP_VIDEO_IMAGER, DM355EVM_MSP_VIDEO_IN); +#if defined(CONFIG_SOC_CAMERA_MT9T031) if (ret>= 0) ret = dm355evm_enable_pca9543a(1); else /* switch off i2c switch since we failed */ ret = dm355evm_enable_pca9543a(0); +#endif break; } case VPFE_SUBDEV_TVP5146: @@ -288,6 +297,7 @@ static int dm355evm_setup_video_input(enum vpfe_subdev_id id) default: return -EINVAL; } +#endif return (ret>= 0 ? 0 : ret); } @@ -300,6 +310,15 @@ static struct v4l2_input mt9t031_inputs[] = { } }; +/* Input available at the mt9p031 */ +static struct v4l2_input mt9p031_inputs[] = { + { + .index = 0, + .name = "Camera", + .type = V4L2_INPUT_TYPE_CAMERA, + } +}; + static struct tvp514x_platform_data tvp5146_pdata = { .clk_polarity = 0, .hs_polarity = 1, @@ -357,6 +376,7 @@ static struct vpfe_subdev_info vpfe_sub_devs[] = { .platform_data =&tvp5146_pdata, }, }, +#if defined(CONFIG_SOC_CAMERA_MT9T031) { .module_name = "mt9t031", .is_camera = 1, @@ -373,7 +393,26 @@ static struct vpfe_subdev_info vpfe_sub_devs[] = { /* this is for PCLK rising edge */ .platform_data = (void *)1, }, - } + }, +#elif defined(CONFIG_VIDEO_MT9P031) /* mutually exclusive (same i2c addr) */ + { + .module_name = "mt9p031", + .is_camera = 1, + .grp_id = VPFE_SUBDEV_MT9P031, + .num_inputs = ARRAY_SIZE(mt9p031_inputs), + .inputs = mt9p031_inputs, + .ccdc_if_params = { + .if_type = VPFE_RAW_BAYER, + .hdpol = VPFE_PINPOL_POSITIVE, + .vdpol = VPFE_PINPOL_POSITIVE, + }, + .board_info = { + I2C_BOARD_INFO("mt9p031", 0x5d), + /* this is for PCLK rising edge
Re: [PATCH] musb_gadget: restart request on clearing endpoint halt
On Sat, Sep 11, 2010 at 01:23:12PM -0500, Sergei Shtylyov wrote: Commit 46034dca515bc4ddca0399ae58106d1f5f0d809f (USB: musb_gadget_ep0: stop abusing musb_gadget_set_halt()) forgot to add in the code to restart a queued request to the code handling clearing the endpoint halt. This results in a couple of USB resets while enumerating the file-backed storage gadget due to CSW packet not being sent for the MODE SENSE(10) command. Signed-off-by: Sergei Shtylyov Cc: sta...@kernel.org applied, thanks -- balbi ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v5 1/1] davinci: spi: replace existing driver
Hi Sekhar, On 08/23/2010 05:30 AM, Nori, Sekhar wrote: > On Mon, Aug 23, 2010 at 14:24:10, Caglar Akyuz wrote: >> On Monday 23 August 2010 07:28:48 am Nori, Sekhar wrote: >>> Hi Caglar, >>> >> >> Hi, >> >> [...] >> >>> I have been spending time on this (admittedly on and off) since I wrote >>> that email and have broken down the work into ~20 patches so far. Starting >>> to scratch the DMA related changes right now. So, I guess I am somewhere >>> midway. >>> >>> I pushed a branch containing the work so far here: >>> >>> http://arago-project.org/git/projects/?p=linux-davinci.git;a=shortlog;h=ref >>> s/heads/davinci-spi-rewrite >>> >> I've been trying to take a peek, but the arago site seems to be flakey lately, giving a lot of messages like the one below. Not sure if you are aware of this. Looking forward to seeing this... Thanks! -Mike (Arago Error Message). XML Parsing Error: undefined entity Location: http://arago-project.org/git/projects/?p=linux-davinci.git;a=summary Line Number 41, Column 20: ---^ ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
RE: [PATCH v5 1/1] davinci: spi: replace existing driver
On Tue, Sep 14, 2010 at 05:15:25, Michael Williamson wrote: > Hi Sekhar, > > On 08/23/2010 05:30 AM, Nori, Sekhar wrote: > > On Mon, Aug 23, 2010 at 14:24:10, Caglar Akyuz wrote: > >> On Monday 23 August 2010 07:28:48 am Nori, Sekhar wrote: > >>> Hi Caglar, > >>> > >> > >> Hi, > >> > >> [...] > >> > >>> I have been spending time on this (admittedly on and off) since I wrote > >>> that email and have broken down the work into ~20 patches so far. > >>> Starting > >>> to scratch the DMA related changes right now. So, I guess I am somewhere > >>> midway. > >>> > >>> I pushed a branch containing the work so far here: > >>> > >>> http://arago-project.org/git/projects/?p=linux-davinci.git;a=shortlog;h=ref > >>> s/heads/davinci-spi-rewrite > >>> > >> > > I've been trying to take a peek, but the arago site seems to be flakey lately, > giving a lot of messages like the one below. Not sure if you are aware of > this. Hmm, I have seen this kind of error in the past, but not lately. Accessed the site just now without issues. > Looking forward to seeing this... Thanks! Got side-tracked the last two weeks. The DMA changes are the major chunk left. Hopefully will have the final patch set ready with little more effort. Thanks, Sekhar ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v5 1/1] davinci: spi: replace existing driver
On Tuesday 14 September 2010 08:43:41 am Nori, Sekhar wrote: > On Tue, Sep 14, 2010 at 05:15:25, Michael Williamson wrote: > > Hi Sekhar, > > > > On 08/23/2010 05:30 AM, Nori, Sekhar wrote: > > > On Mon, Aug 23, 2010 at 14:24:10, Caglar Akyuz wrote: > > >> On Monday 23 August 2010 07:28:48 am Nori, Sekhar wrote: > > >>> Hi Caglar, > > >> > > >> Hi, > > >> > > >> [...] > > >> > > >>> I have been spending time on this (admittedly on and off) since I > > >>> wrote that email and have broken down the work into ~20 patches so > > >>> far. Starting to scratch the DMA related changes right now. So, I > > >>> guess I am somewhere midway. > > >>> > > >>> I pushed a branch containing the work so far here: > > >>> > > >>> http://arago-project.org/git/projects/?p=linux-davinci.git;a=shortlog > > >>>;h=ref s/heads/davinci-spi-rewrite > > > > I've been trying to take a peek, but the arago site seems to be flakey > > lately, giving a lot of messages like the one below. Not sure if you are > > aware of this. > > Hmm, I have seen this kind of error in the past, but not lately. Accessed > the site just now without issues. > > > Looking forward to seeing this... Thanks! > > Got side-tracked the last two weeks. The DMA changes are the major > chunk left. Hopefully will have the final patch set ready with > little more effort. > Yes, your patches seems ok and mostly complete. I'm waiting for hardware to test those, will let you know when I do some testing. Regards, Caglar > Thanks, > Sekhar > > ___ > Davinci-linux-open-source mailing list > Davinci-linux-open-source@linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source