1/* 2 * Hawkboard.org based on TI's OMAP-L138 Platform 3 * 4 * Initial code: Syed Mohammed Khasim 5 * 6 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com 7 * 8 * This file is licensed under the terms of the GNU General Public License 9 * version 2. This program is licensed "as is" without any warranty of 10 * any kind, whether express or implied. 11 */ 12#include <linux/kernel.h> 13#include <linux/init.h> 14#include <linux/console.h> 15#include <linux/gpio.h> 16#include <linux/platform_data/gpio-davinci.h> 17 18#include <asm/mach-types.h> 19#include <asm/mach/arch.h> 20 21#include <mach/common.h> 22#include <mach/cp_intc.h> 23#include <mach/da8xx.h> 24#include <mach/mux.h> 25 26#define HAWKBOARD_PHY_ID "davinci_mdio-0:07" 27#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) 28#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) 29 30#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4) 31#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13) 32 33static short omapl138_hawk_mii_pins[] __initdata = { 34 DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, 35 DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, 36 DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, 37 DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, 38 DA850_MDIO_D, 39 -1 40}; 41 42static __init void omapl138_hawk_config_emac(void) 43{ 44 void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); 45 int ret; 46 u32 val; 47 struct davinci_soc_info *soc_info = &davinci_soc_info; 48 49 val = __raw_readl(cfgchip3); 50 val &= ~BIT(8); 51 ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); 52 if (ret) { 53 pr_warn("%s: CPGMAC/MII mux setup failed: %d\n", __func__, ret); 54 return; 55 } 56 57 /* configure the CFGCHIP3 register for MII */ 58 __raw_writel(val, cfgchip3); 59 pr_info("EMAC: MII PHY configured\n"); 60 61 soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; 62 63 ret = da8xx_register_emac(); 64 if (ret) 65 pr_warn("%s: EMAC registration failed: %d\n", __func__, ret); 66} 67 68/* 69 * The following EDMA channels/slots are not being used by drivers (for 70 * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM/Hawkboard, 71 * hence they are being reserved for codecs on the DSP side. 72 */ 73static const s16 da850_dma0_rsv_chans[][2] = { 74 /* (offset, number) */ 75 { 8, 6}, 76 {24, 4}, 77 {30, 2}, 78 {-1, -1} 79}; 80 81static const s16 da850_dma0_rsv_slots[][2] = { 82 /* (offset, number) */ 83 { 8, 6}, 84 {24, 4}, 85 {30, 50}, 86 {-1, -1} 87}; 88 89static const s16 da850_dma1_rsv_chans[][2] = { 90 /* (offset, number) */ 91 { 0, 28}, 92 {30, 2}, 93 {-1, -1} 94}; 95 96static const s16 da850_dma1_rsv_slots[][2] = { 97 /* (offset, number) */ 98 { 0, 28}, 99 {30, 90}, 100 {-1, -1} 101}; 102 103static struct edma_rsv_info da850_edma_cc0_rsv = { 104 .rsv_chans = da850_dma0_rsv_chans, 105 .rsv_slots = da850_dma0_rsv_slots, 106}; 107 108static struct edma_rsv_info da850_edma_cc1_rsv = { 109 .rsv_chans = da850_dma1_rsv_chans, 110 .rsv_slots = da850_dma1_rsv_slots, 111}; 112 113static struct edma_rsv_info *da850_edma_rsv[2] = { 114 &da850_edma_cc0_rsv, 115 &da850_edma_cc1_rsv, 116}; 117 118static const short hawk_mmcsd0_pins[] = { 119 DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, 120 DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, 121 DA850_GPIO3_12, DA850_GPIO3_13, 122 -1 123}; 124 125static int da850_hawk_mmc_get_ro(int index) 126{ 127 return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); 128} 129 130static int da850_hawk_mmc_get_cd(int index) 131{ 132 return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN); 133} 134 135static struct davinci_mmc_config da850_mmc_config = { 136 .get_ro = da850_hawk_mmc_get_ro, 137 .get_cd = da850_hawk_mmc_get_cd, 138 .wires = 4, 139 .max_freq = 50000000, 140 .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, 141}; 142 143static __init void omapl138_hawk_mmc_init(void) 144{ 145 int ret; 146 147 ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); 148 if (ret) { 149 pr_warn("%s: MMC/SD0 mux setup failed: %d\n", __func__, ret); 150 return; 151 } 152 153 ret = gpio_request_one(DA850_HAWK_MMCSD_CD_PIN, 154 GPIOF_DIR_IN, "MMC CD"); 155 if (ret < 0) { 156 pr_warn("%s: can not open GPIO %d\n", 157 __func__, DA850_HAWK_MMCSD_CD_PIN); 158 return; 159 } 160 161 ret = gpio_request_one(DA850_HAWK_MMCSD_WP_PIN, 162 GPIOF_DIR_IN, "MMC WP"); 163 if (ret < 0) { 164 pr_warn("%s: can not open GPIO %d\n", 165 __func__, DA850_HAWK_MMCSD_WP_PIN); 166 goto mmc_setup_wp_fail; 167 } 168 169 ret = da8xx_register_mmcsd0(&da850_mmc_config); 170 if (ret) { 171 pr_warn("%s: MMC/SD0 registration failed: %d\n", __func__, ret); 172 goto mmc_setup_mmcsd_fail; 173 } 174 175 return; 176 177mmc_setup_mmcsd_fail: 178 gpio_free(DA850_HAWK_MMCSD_WP_PIN); 179mmc_setup_wp_fail: 180 gpio_free(DA850_HAWK_MMCSD_CD_PIN); 181} 182 183static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); 184static da8xx_ocic_handler_t hawk_usb_ocic_handler; 185 186static const short da850_hawk_usb11_pins[] = { 187 DA850_GPIO2_4, DA850_GPIO6_13, 188 -1 189}; 190 191static int hawk_usb_set_power(unsigned port, int on) 192{ 193 gpio_set_value(DA850_USB1_VBUS_PIN, on); 194 return 0; 195} 196 197static int hawk_usb_get_power(unsigned port) 198{ 199 return gpio_get_value(DA850_USB1_VBUS_PIN); 200} 201 202static int hawk_usb_get_oci(unsigned port) 203{ 204 return !gpio_get_value(DA850_USB1_OC_PIN); 205} 206 207static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) 208{ 209 int irq = gpio_to_irq(DA850_USB1_OC_PIN); 210 int error = 0; 211 212 if (handler != NULL) { 213 hawk_usb_ocic_handler = handler; 214 215 error = request_irq(irq, omapl138_hawk_usb_ocic_irq, 216 IRQF_TRIGGER_RISING | 217 IRQF_TRIGGER_FALLING, 218 "OHCI over-current indicator", NULL); 219 if (error) 220 pr_err("%s: could not request IRQ to watch " 221 "over-current indicator changes\n", __func__); 222 } else { 223 free_irq(irq, NULL); 224 } 225 return error; 226} 227 228static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { 229 .set_power = hawk_usb_set_power, 230 .get_power = hawk_usb_get_power, 231 .get_oci = hawk_usb_get_oci, 232 .ocic_notify = hawk_usb_ocic_notify, 233 /* TPS2087 switch @ 5V */ 234 .potpgt = (3 + 1) / 2, /* 3 ms max */ 235}; 236 237static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) 238{ 239 hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); 240 return IRQ_HANDLED; 241} 242 243static __init void omapl138_hawk_usb_init(void) 244{ 245 int ret; 246 u32 cfgchip2; 247 248 ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); 249 if (ret) { 250 pr_warn("%s: USB 1.1 PinMux setup failed: %d\n", __func__, ret); 251 return; 252 } 253 254 /* Setup the Ref. clock frequency for the HAWK at 24 MHz. */ 255 256 cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); 257 cfgchip2 &= ~CFGCHIP2_REFFREQ; 258 cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; 259 __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); 260 261 ret = gpio_request_one(DA850_USB1_VBUS_PIN, 262 GPIOF_DIR_OUT, "USB1 VBUS"); 263 if (ret < 0) { 264 pr_err("%s: failed to request GPIO for USB 1.1 port " 265 "power control: %d\n", __func__, ret); 266 return; 267 } 268 269 ret = gpio_request_one(DA850_USB1_OC_PIN, 270 GPIOF_DIR_IN, "USB1 OC"); 271 if (ret < 0) { 272 pr_err("%s: failed to request GPIO for USB 1.1 port " 273 "over-current indicator: %d\n", __func__, ret); 274 goto usb11_setup_oc_fail; 275 } 276 277 ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); 278 if (ret) { 279 pr_warn("%s: USB 1.1 registration failed: %d\n", __func__, ret); 280 goto usb11_setup_fail; 281 } 282 283 return; 284 285usb11_setup_fail: 286 gpio_free(DA850_USB1_OC_PIN); 287usb11_setup_oc_fail: 288 gpio_free(DA850_USB1_VBUS_PIN); 289} 290 291static __init void omapl138_hawk_init(void) 292{ 293 int ret; 294 295 ret = da850_register_gpio(); 296 if (ret) 297 pr_warn("%s: GPIO init failed: %d\n", __func__, ret); 298 299 davinci_serial_init(da8xx_serial_device); 300 301 omapl138_hawk_config_emac(); 302 303 ret = da850_register_edma(da850_edma_rsv); 304 if (ret) 305 pr_warn("%s: EDMA registration failed: %d\n", __func__, ret); 306 307 omapl138_hawk_mmc_init(); 308 309 omapl138_hawk_usb_init(); 310 311 ret = da8xx_register_watchdog(); 312 if (ret) 313 pr_warn("%s: watchdog registration failed: %d\n", 314 __func__, ret); 315 316 ret = da8xx_register_rproc(); 317 if (ret) 318 pr_warn("%s: dsp/rproc registration failed: %d\n", 319 __func__, ret); 320} 321 322#ifdef CONFIG_SERIAL_8250_CONSOLE 323static int __init omapl138_hawk_console_init(void) 324{ 325 if (!machine_is_omapl138_hawkboard()) 326 return 0; 327 328 return add_preferred_console("ttyS", 2, "115200"); 329} 330console_initcall(omapl138_hawk_console_init); 331#endif 332 333static void __init omapl138_hawk_map_io(void) 334{ 335 da850_init(); 336} 337 338MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard") 339 .atag_offset = 0x100, 340 .map_io = omapl138_hawk_map_io, 341 .init_irq = cp_intc_init, 342 .init_time = davinci_timer_init, 343 .init_machine = omapl138_hawk_init, 344 .init_late = davinci_init_late, 345 .dma_zone_size = SZ_128M, 346 .restart = da8xx_restart, 347 .reserve = da8xx_rproc_reserve_cma, 348MACHINE_END 349