AR7: add support for Titan (TNETV10xx) SoC variant
PATCH 2/2 AR7: add support for Titan (TNETV10xx) SoC variant
Add support for Titan TNETV1050,1055,1056,1060 variants. This SoC is almost completely identical to AR7 except on a few points:
- a second bank of gpios is available
- vlynq0 on titan is vlynq1 on ar7
- different PHY addresses for cpmac0
This SoC can be found on commercial products like the Linksys WRTP54G
Signed-off-by Xin Zhen <[email protected]>
Signed-off-by Florian Fainelli <[email protected]>
---
arch/mips/ar7/gpio.c +230 -10
@@ -1,7 +1,7 @@/* * Copyright (C) 2007 Felix Fietkau <[email protected]> * Copyright (C) 2007 Eugene Konev <[email protected]> -* Copyright (C) 2009 Florian Fainelli <[email protected]> +* Copyright (C) 2009-2010 Florian Fainelli <[email protected]> * * 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
@@ -37,6 +37,16 @@ static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)return readl (gpio_in) & (1 << gpio); } +static int titan_gpio_get_value (struct gpio_chip *chip,unsigned gpio) +{ +struct ar7_gpio_chip *gpch = + container_of(chip, struct ar7_gpio_chip, chip); +void __iomem *gpio_in0 = gpch->regs +TITAN_GPIO_INPUT_0 ; +void __iomem *gpio_in1 = gpch->regs +TITAN_GPIO_INPUT_1 ; + +return readl (gpio >>5 ? gpio_in1 : gpio_in0) & (1 << (gpio &0x1f )); +} +static void ar7_gpio_set_value (struct gpio_chip *chip,unsigned gpio,int value) {
@@ -51,6 +61,21 @@ static void ar7_gpio_set_value(struct gpio_chip *chip,writel (tmp, gpio_out); } +static void titan_gpio_set_value (struct gpio_chip *chip, +unsigned gpio,int value) +{ +struct ar7_gpio_chip *gpch = + container_of(chip, struct ar7_gpio_chip, chip); +void __iomem *gpio_out0 = gpch->regs +TITAN_GPIO_OUTPUT_0 ; +void __iomem *gpio_out1 = gpch->regs +TITAN_GPIO_OUTPUT_1 ; +unsigned tmp; + + tmp =readl (gpio >>5 ? gpio_out1 : gpio_out0) & ~(1 << (gpio &0x1f )); +if (value) + tmp |=1 << (gpio &0x1f ); +writel (tmp, gpio >>5 ? gpio_out1 : gpio_out0); +} +static int ar7_gpio_direction_input (struct gpio_chip *chip,unsigned gpio) { struct ar7_gpio_chip *gpch =
@@ -62,6 +87,21 @@ static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)return 0 ; } +static int titan_gpio_direction_input (struct gpio_chip *chip,unsigned gpio) +{ +struct ar7_gpio_chip *gpch = + container_of(chip, struct ar7_gpio_chip, chip); +void __iomem *gpio_dir0 = gpch->regs +TITAN_GPIO_DIR_0 ; +void __iomem *gpio_dir1 = gpch->regs +TITAN_GPIO_DIR_1 ; + +if (gpio >=TITAN_GPIO_MAX ) +return -EINVAL ; + +writel (readl (gpio >>5 ? gpio_dir1 : gpio_dir0) | (1 << (gpio &0x1f )), + gpio >>5 ? gpio_dir1 : gpio_dir0); +return 0 ; +} +static int ar7_gpio_direction_output (struct gpio_chip *chip,unsigned gpio,int value) {
@@ -75,6 +115,24 @@ static int ar7_gpio_direction_output(struct gpio_chip *chip,return 0 ; } +static int titan_gpio_direction_output (struct gpio_chip *chip, +unsigned gpio,int value) +{ +struct ar7_gpio_chip *gpch = + container_of(chip, struct ar7_gpio_chip, chip); +void __iomem *gpio_dir0 = gpch->regs +TITAN_GPIO_DIR_0 ; +void __iomem *gpio_dir1 = gpch->regs +TITAN_GPIO_DIR_1 ; + +if (gpio >=TITAN_GPIO_MAX ) +return -EINVAL ; + +titan_gpio_set_value (chip, gpio, value); +writel (readl (gpio >>5 ? gpio_dir1 : gpio_dir0) & ~(1 << + (gpio &0x1f )), gpio >>5 ? gpio_dir1 : gpio_dir0); + +return 0 ; +} +static struct ar7_gpio_chip ar7_gpio_chip = { .chip = { .label ="ar7-gpio" ,
@@ -87,7 +145,19 @@ static struct ar7_gpio_chip ar7_gpio_chip = { } }; -int ar7_gpio_enable (unsigned gpio) +static struct ar7_gpio_chip titan_gpio_chip = { + .chip = { + .label ="titan-gpio" , + .direction_input = titan_gpio_direction_input, + .direction_output = titan_gpio_direction_output, + .set = titan_gpio_set_value, + .get = titan_gpio_get_value, + .base =0 , + .ngpio =TITAN_GPIO_MAX , + } +}; + +static inline int ar7_gpio_enable_ar7 (unsigned gpio) {void __iomem *gpio_en = ar7_gpio_chip.regs +AR7_GPIO_ENABLE ;
@@ -95,9 +165,26 @@ int ar7_gpio_enable(unsigned gpio)return 0 ; } + +static inline int ar7_gpio_enable_titan (unsigned gpio) +{ +void __iomem *gpio_en0 = titan_gpio_chip.regs +TITAN_GPIO_ENBL_0 ; +void __iomem *gpio_en1 = titan_gpio_chip.regs +TITAN_GPIO_ENBL_1 ; + +writel (readl (gpio >>5 ? gpio_en1 : gpio_en0) | (1 << (gpio &0x1f )), + gpio >>5 ? gpio_en1 : gpio_en0); + +return 0 ; +} + +int ar7_gpio_enable (unsigned gpio) +{ +return ar7_is_titan () ?ar7_gpio_enable_titan (gpio) : +ar7_gpio_enable_ar7 (gpio); +}EXPORT_SYMBOL (ar7_gpio_enable); -int ar7_gpio_disable (unsigned gpio) +static inline int ar7_gpio_disable_ar7 (unsigned gpio) {void __iomem *gpio_en = ar7_gpio_chip.regs +AR7_GPIO_ENABLE ;
@@ -105,26 +192,159 @@ int ar7_gpio_disable(unsigned gpio)return 0 ; } + +static inline int ar7_gpio_disable_titan (unsigned gpio) +{ +void __iomem *gpio_en0 = titan_gpio_chip.regs +TITAN_GPIO_ENBL_0 ; +void __iomem *gpio_en1 = titan_gpio_chip.regs +TITAN_GPIO_ENBL_1 ; + +writel (readl (gpio >>5 ? gpio_en1 : gpio_en0) & ~(1 << (gpio &0x1f )), + gpio >>5 ? gpio_en1 : gpio_en0); + +return 0 ; +} + +int ar7_gpio_disable (unsigned gpio) +{ +return ar7_is_titan () ?ar7_gpio_disable_titan (gpio) : +ar7_gpio_disable_ar7 (gpio); +}EXPORT_SYMBOL (ar7_gpio_disable); +struct titan_gpio_cfg { +u32 reg; +u32 shift; +u32 func; +}; + +static struct titan_gpio_cfg titan_gpio_table[] = { +/* reg, start bit, mux value */ + {4 ,24 ,1 }, + {4 ,26 ,1 }, + {4 ,28 ,1 }, + {4 ,30 ,1 }, + {5 ,6 ,1 }, + {5 ,8 ,1 }, + {5 ,10 ,1 }, + {5 ,12 ,1 }, + {7 ,14 ,3 }, + {7 ,16 ,3 }, + {7 ,18 ,3 }, + {7 ,20 ,3 }, + {7 ,22 ,3 }, + {7 ,26 ,3 }, + {7 ,28 ,3 }, + {7 ,30 ,3 }, + {8 ,0 ,3 }, + {8 ,2 ,3 }, + {8 ,4 ,3 }, + {8 ,10 ,3 }, + {8 ,14 ,3 }, + {8 ,16 ,3 }, + {8 ,18 ,3 }, + {8 ,20 ,3 }, + {9 ,8 ,3 }, + {9 ,10 ,3 }, + {9 ,12 ,3 }, + {9 ,14 ,3 }, + {9 ,18 ,3 }, + {9 ,20 ,3 }, + {9 ,24 ,3 }, + {9 ,26 ,3 }, + {9 ,28 ,3 }, + {9 ,30 ,3 }, + {10 ,0 ,3 }, + {10 ,2 ,3 }, + {10 ,8 ,3 }, + {10 ,10 ,3 }, + {10 ,12 ,3 }, + {10 ,14 ,3 }, + {13 ,12 ,3 }, + {13 ,14 ,3 }, + {13 ,16 ,3 }, + {13 ,18 ,3 }, + {13 ,24 ,3 }, + {13 ,26 ,3 }, + {13 ,28 ,3 }, + {13 ,30 ,3 }, + {14 ,2 ,3 }, + {14 ,6 ,3 }, + {14 ,8 ,3 }, + {14 ,12 ,3 } +}; + +static int titan_gpio_pinsel (unsigned gpio) +{ +struct titan_gpio_cfg gpio_cfg; +u32 mux_status, pin_sel_reg, tmp; +void __iomem *pin_sel = (void __iomem *)KSEG1ADDR (AR7_REGS_PINSEL ); + +if (gpio >=ARRAY_SIZE (titan_gpio_table)) +return -EINVAL ; + + gpio_cfg = titan_gpio_table[gpio]; + pin_sel_reg = gpio_cfg.reg -1 ; + + mux_status = (readl (pin_sel + pin_sel_reg) >> gpio_cfg.shift) &0x3 ; + +/* Check the mux status */ +if (!((mux_status ==0 ) || (mux_status == gpio_cfg.func))) +return 0 ; + +/* Set the pin sel value */ + tmp =readl (pin_sel + pin_sel_reg); + tmp |= ((gpio_cfg.func &0x3 ) << gpio_cfg.shift); +writel (tmp, pin_sel + pin_sel_reg); + +return 0 ; +} + +/* Perform minimal Titan GPIO configuration */ +static void titan_gpio_init (void ) +{ +unsigned i; + +for (i =44 ; i <48 ; i++) { +titan_gpio_pinsel (i); +ar7_gpio_enable_titan (i); +titan_gpio_direction_input (&titan_gpio_chip.chip, i); + } +} +int __init ar7_gpio_init (void ) {int ret; +struct ar7_gpio_chip *gpch; +unsigned size; + +if (!ar7_is_titan ()) { + gpch = &ar7_gpio_chip; + size =0x10 ; + }else { + gpch = &titan_gpio_chip; + size =0x1f ; + } - ar7_gpio_chip.regs =ioremap_nocache (AR7_REGS_GPIO , + gpch->regs =ioremap_nocache (AR7_REGS_GPIO ,AR7_REGS_GPIO +0x10 ); -if (!ar7_gpio_chip.regs) { -printk (KERN_ERR "ar7-gpio: failed to ioremap regs\n" ); +if (!gpch->regs) { +printk (KERN_ERR "%s: failed to ioremap regs\n" , + gpch->chip.label);return -ENOMEM ; } - ret =gpiochip_add (&ar7_gpio_chip.chip); + ret =gpiochip_add (&gpch->chip);if (ret) { -printk (KERN_ERR "ar7-gpio: failed to add gpiochip\n" ); +printk (KERN_ERR "%s: failed to add gpiochip\n" , + gpch->chip.label);return ret; } -printk (KERN_INFO "ar7-gpio: registered %d GPIOs\n" , - ar7_gpio_chip.chip.ngpio); +printk (KERN_INFO "%s: registered %d GPIOs\n" , + gpch->chip.label, gpch->chip.ngpio); + +if (ar7_is_titan ()) +titan_gpio_init (); +return ret; }
arch/mips/ar7/platform.c +56 -0
80 lines not on this page · raw message
arch/mips/ar7/setup.c +14 -0
@@ -23,6 +23,7 @@#include <asm/reboot.h> #include <asm/mach-ar7/ar7.h> #include <asm/mach-ar7/prom.h> +#include <asm/mach-ar7/gpio.h> static void ar7_machine_restart (char *command) {
@@ -49,6 +50,8 @@ static void ar7_machine_power_off(void)const char *get_system_type (void ) {u16 chip_id =ar7_chip_id (); +u16 titan_variant_id =titan_chip_id (); +switch (chip_id) {case AR7_CHIP_7100 :return "TI AR7 (TNETD7100)" ;
@@ -56,6 +59,17 @@ const char *get_system_type(void)return "TI AR7 (TNETD7200)" ;case AR7_CHIP_7300 :return "TI AR7 (TNETD7300)" ; +case AR7_CHIP_TITAN : +switch (titan_variant_id) { +case TITAN_CHIP_1050 : +return "TI AR7 (TNETV1050)" ; +case TITAN_CHIP_1055 : +return "TI AR7 (TNETV1055)" ; +case TITAN_CHIP_1056 : +return "TI AR7 (TNETV1056)" ; +case TITAN_CHIP_1060 : +return "TI AR7 (TNETV1060)" ; + }default :return "TI AR7 (unknown)" ; }
arch/mips/include/asm/mach-ar7/ar7.h +43 -2
88 lines not on this page · raw message
arch/mips/include/asm/mach-ar7/gpio.h +2 -1
@@ -22,7 +22,8 @@#include <asm/mach-ar7/ar7.h> #define AR7_GPIO_MAX 32 -#define NR_BUILTIN_GPIO AR7_GPIO_MAX +#define TITAN_GPIO_MAX 51 +#define NR_BUILTIN_GPIO TITAN_GPIO_MAX#define gpio_to_irq (gpio) -1
Thanks, queued for 2.6.37.
Ralf