linux/arch/arm/mach-omap2/pdata-quirks.c
<<
>>
Prefs
   1/*
   2 * Legacy platform_data quirks
   3 *
   4 * Copyright (C) 2013 Texas Instruments
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10#include <linux/clk.h>
  11#include <linux/davinci_emac.h>
  12#include <linux/gpio.h>
  13#include <linux/init.h>
  14#include <linux/kernel.h>
  15#include <linux/of_platform.h>
  16#include <linux/wl12xx.h>
  17
  18#include <linux/platform_data/pinctrl-single.h>
  19#include <linux/platform_data/iommu-omap.h>
  20
  21#include "am35xx.h"
  22#include "common.h"
  23#include "common-board-devices.h"
  24#include "dss-common.h"
  25#include "control.h"
  26#include "omap_device.h"
  27#include "omap-secure.h"
  28#include "soc.h"
  29
  30struct pdata_init {
  31        const char *compatible;
  32        void (*fn)(void);
  33};
  34
  35struct of_dev_auxdata omap_auxdata_lookup[];
  36static struct twl4030_gpio_platform_data twl_gpio_auxdata;
  37
  38#if IS_ENABLED(CONFIG_WL12XX)
  39
  40static struct wl12xx_platform_data wl12xx __initdata;
  41
  42static void __init __used legacy_init_wl12xx(unsigned ref_clock,
  43                                             unsigned tcxo_clock,
  44                                             int gpio)
  45{
  46        int res;
  47
  48        wl12xx.board_ref_clock = ref_clock;
  49        wl12xx.board_tcxo_clock = tcxo_clock;
  50        wl12xx.irq = gpio_to_irq(gpio);
  51
  52        res = wl12xx_set_platform_data(&wl12xx);
  53        if (res) {
  54                pr_err("error setting wl12xx data: %d\n", res);
  55                return;
  56        }
  57}
  58#else
  59static inline void legacy_init_wl12xx(unsigned ref_clock,
  60                                      unsigned tcxo_clock,
  61                                      int gpio)
  62{
  63}
  64#endif
  65
  66#ifdef CONFIG_MACH_NOKIA_N8X0
  67static void __init omap2420_n8x0_legacy_init(void)
  68{
  69        omap_auxdata_lookup[0].platform_data = n8x0_legacy_init();
  70}
  71#else
  72#define omap2420_n8x0_legacy_init       NULL
  73#endif
  74
  75#ifdef CONFIG_ARCH_OMAP3
  76static void __init hsmmc2_internal_input_clk(void)
  77{
  78        u32 reg;
  79
  80        reg = omap_ctrl_readl(OMAP343X_CONTROL_DEVCONF1);
  81        reg |= OMAP2_MMCSDIO2ADPCLKISEL;
  82        omap_ctrl_writel(reg, OMAP343X_CONTROL_DEVCONF1);
  83}
  84
  85static struct iommu_platform_data omap3_iommu_pdata = {
  86        .reset_name = "mmu",
  87        .assert_reset = omap_device_assert_hardreset,
  88        .deassert_reset = omap_device_deassert_hardreset,
  89};
  90
  91static int omap3_sbc_t3730_twl_callback(struct device *dev,
  92                                           unsigned gpio,
  93                                           unsigned ngpio)
  94{
  95        int res;
  96
  97        res = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH,
  98                               "wlan pwr");
  99        if (res)
 100                return res;
 101
 102        gpio_export(gpio, 0);
 103
 104        return 0;
 105}
 106
 107static void __init omap3_sbc_t3x_usb_hub_init(int gpio, char *hub_name)
 108{
 109        int err = gpio_request_one(gpio, GPIOF_OUT_INIT_LOW, hub_name);
 110
 111        if (err) {
 112                pr_err("SBC-T3x: %s reset gpio request failed: %d\n",
 113                        hub_name, err);
 114                return;
 115        }
 116
 117        gpio_export(gpio, 0);
 118
 119        udelay(10);
 120        gpio_set_value(gpio, 1);
 121        msleep(1);
 122}
 123
 124static void __init omap3_sbc_t3730_twl_init(void)
 125{
 126        twl_gpio_auxdata.setup = omap3_sbc_t3730_twl_callback;
 127}
 128
 129static void __init omap3_sbc_t3730_legacy_init(void)
 130{
 131        omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub");
 132        legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 136);
 133        omap_ads7846_init(1, 57, 0, NULL);
 134}
 135
 136static void __init omap3_sbc_t3530_legacy_init(void)
 137{
 138        omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub");
 139        omap_ads7846_init(1, 57, 0, NULL);
 140}
 141
 142static void __init omap3_igep0020_legacy_init(void)
 143{
 144}
 145
 146static void __init omap3_evm_legacy_init(void)
 147{
 148        legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 149);
 149}
 150
 151static void __init omap3_zoom_legacy_init(void)
 152{
 153        legacy_init_wl12xx(WL12XX_REFCLOCK_26, 0, 162);
 154}
 155
 156static void am35xx_enable_emac_int(void)
 157{
 158        u32 v;
 159
 160        v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
 161        v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR |
 162              AM35XX_CPGMAC_C0_MISC_PULSE_CLR | AM35XX_CPGMAC_C0_RX_THRESH_CLR);
 163        omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
 164        omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
 165}
 166
 167static void am35xx_disable_emac_int(void)
 168{
 169        u32 v;
 170
 171        v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
 172        v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR);
 173        omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
 174        omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
 175}
 176
 177static struct emac_platform_data am35xx_emac_pdata = {
 178        .interrupt_enable       = am35xx_enable_emac_int,
 179        .interrupt_disable      = am35xx_disable_emac_int,
 180};
 181
 182static void __init am35xx_emac_reset(void)
 183{
 184        u32 v;
 185
 186        v = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
 187        v &= ~AM35XX_CPGMACSS_SW_RST;
 188        omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET);
 189        omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */
 190}
 191
 192static struct gpio cm_t3517_wlan_gpios[] __initdata = {
 193        { 56,   GPIOF_OUT_INIT_HIGH,    "wlan pwr" },
 194        { 4,    GPIOF_OUT_INIT_HIGH,    "xcvr noe" },
 195};
 196
 197static void __init omap3_sbc_t3517_wifi_init(void)
 198{
 199        int err = gpio_request_array(cm_t3517_wlan_gpios,
 200                                ARRAY_SIZE(cm_t3517_wlan_gpios));
 201        if (err) {
 202                pr_err("SBC-T3517: wl12xx gpios request failed: %d\n", err);
 203                return;
 204        }
 205
 206        gpio_export(cm_t3517_wlan_gpios[0].gpio, 0);
 207        gpio_export(cm_t3517_wlan_gpios[1].gpio, 0);
 208
 209        msleep(100);
 210        gpio_set_value(cm_t3517_wlan_gpios[1].gpio, 0);
 211}
 212
 213static void __init omap3_sbc_t3517_legacy_init(void)
 214{
 215        omap3_sbc_t3x_usb_hub_init(152, "cm-t3517 usb hub");
 216        omap3_sbc_t3x_usb_hub_init(98, "sb-t35 usb hub");
 217        am35xx_emac_reset();
 218        hsmmc2_internal_input_clk();
 219        omap3_sbc_t3517_wifi_init();
 220        legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 145);
 221        omap_ads7846_init(1, 57, 0, NULL);
 222}
 223
 224static void __init am3517_evm_legacy_init(void)
 225{
 226        am35xx_emac_reset();
 227}
 228
 229static struct platform_device omap3_rom_rng_device = {
 230        .name           = "omap3-rom-rng",
 231        .id             = -1,
 232        .dev    = {
 233                .platform_data  = rx51_secure_rng_call,
 234        },
 235};
 236
 237static void __init nokia_n900_legacy_init(void)
 238{
 239        hsmmc2_internal_input_clk();
 240
 241        if (omap_type() == OMAP2_DEVICE_TYPE_SEC) {
 242                if (IS_ENABLED(CONFIG_ARM_ERRATA_430973)) {
 243                        pr_info("RX-51: Enabling ARM errata 430973 workaround\n");
 244                        /* set IBE to 1 */
 245                        rx51_secure_update_aux_cr(BIT(6), 0);
 246                } else {
 247                        pr_warn("RX-51: Not enabling ARM errata 430973 workaround\n");
 248                        pr_warn("Thumb binaries may crash randomly without this workaround\n");
 249                }
 250
 251                pr_info("RX-51: Registring OMAP3 HWRNG device\n");
 252                platform_device_register(&omap3_rom_rng_device);
 253
 254        }
 255}
 256
 257static void __init omap3_tao3530_legacy_init(void)
 258{
 259        hsmmc2_internal_input_clk();
 260}
 261#endif /* CONFIG_ARCH_OMAP3 */
 262
 263#ifdef CONFIG_ARCH_OMAP4
 264static void __init omap4_sdp_legacy_init(void)
 265{
 266        legacy_init_wl12xx(WL12XX_REFCLOCK_26,
 267                           WL12XX_TCXOCLOCK_26, 53);
 268}
 269
 270static void __init omap4_panda_legacy_init(void)
 271{
 272        legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 53);
 273}
 274
 275static void __init var_som_om44_legacy_init(void)
 276{
 277        legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 41);
 278}
 279#endif
 280
 281#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
 282static struct iommu_platform_data omap4_iommu_pdata = {
 283        .reset_name = "mmu_cache",
 284        .assert_reset = omap_device_assert_hardreset,
 285        .deassert_reset = omap_device_deassert_hardreset,
 286};
 287#endif
 288
 289#ifdef CONFIG_SOC_AM33XX
 290static void __init am335x_evmsk_legacy_init(void)
 291{
 292        legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 31);
 293}
 294#endif
 295
 296#ifdef CONFIG_SOC_OMAP5
 297static void __init omap5_uevm_legacy_init(void)
 298{
 299}
 300#endif
 301
 302static struct pcs_pdata pcs_pdata;
 303
 304void omap_pcs_legacy_init(int irq, void (*rearm)(void))
 305{
 306        pcs_pdata.irq = irq;
 307        pcs_pdata.rearm = rearm;
 308}
 309
 310/*
 311 * GPIOs for TWL are initialized by the I2C bus and need custom
 312 * handing until DSS has device tree bindings.
 313 */
 314void omap_auxdata_legacy_init(struct device *dev)
 315{
 316        if (dev->platform_data)
 317                return;
 318
 319        if (strcmp("twl4030-gpio", dev_name(dev)))
 320                return;
 321
 322        dev->platform_data = &twl_gpio_auxdata;
 323}
 324
 325/*
 326 * Few boards still need auxdata populated before we populate
 327 * the dev entries in of_platform_populate().
 328 */
 329static struct pdata_init auxdata_quirks[] __initdata = {
 330#ifdef CONFIG_SOC_OMAP2420
 331        { "nokia,n800", omap2420_n8x0_legacy_init, },
 332        { "nokia,n810", omap2420_n8x0_legacy_init, },
 333        { "nokia,n810-wimax", omap2420_n8x0_legacy_init, },
 334#endif
 335#ifdef CONFIG_ARCH_OMAP3
 336        { "compulab,omap3-sbc-t3730", omap3_sbc_t3730_twl_init, },
 337#endif
 338        { /* sentinel */ },
 339};
 340
 341struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
 342#ifdef CONFIG_MACH_NOKIA_N8X0
 343        OF_DEV_AUXDATA("ti,omap2420-mmc", 0x4809c000, "mmci-omap.0", NULL),
 344        OF_DEV_AUXDATA("menelaus", 0x72, "1-0072", &n8x0_menelaus_platform_data),
 345        OF_DEV_AUXDATA("tlv320aic3x", 0x18, "2-0018", &n810_aic33_data),
 346#endif
 347#ifdef CONFIG_ARCH_OMAP3
 348        OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002030, "48002030.pinmux", &pcs_pdata),
 349        OF_DEV_AUXDATA("ti,omap3-padconf", 0x480025a0, "480025a0.pinmux", &pcs_pdata),
 350        OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002a00, "48002a00.pinmux", &pcs_pdata),
 351        OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu",
 352                       &omap3_iommu_pdata),
 353        /* Only on am3517 */
 354        OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL),
 355        OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",
 356                       &am35xx_emac_pdata),
 357#endif
 358#ifdef CONFIG_ARCH_OMAP4
 359        OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a100040, "4a100040.pinmux", &pcs_pdata),
 360        OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a31e040, "4a31e040.pinmux", &pcs_pdata),
 361#endif
 362#ifdef CONFIG_SOC_OMAP5
 363        OF_DEV_AUXDATA("ti,omap5-padconf", 0x4a002840, "4a002840.pinmux", &pcs_pdata),
 364        OF_DEV_AUXDATA("ti,omap5-padconf", 0x4ae0c840, "4ae0c840.pinmux", &pcs_pdata),
 365#endif
 366#ifdef CONFIG_SOC_DRA7XX
 367        OF_DEV_AUXDATA("ti,dra7-padconf", 0x4a003400, "4a003400.pinmux", &pcs_pdata),
 368#endif
 369#ifdef CONFIG_SOC_AM43XX
 370        OF_DEV_AUXDATA("ti,am437-padconf", 0x44e10800, "44e10800.pinmux", &pcs_pdata),
 371#endif
 372#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
 373        OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu",
 374                       &omap4_iommu_pdata),
 375        OF_DEV_AUXDATA("ti,omap4-iommu", 0x55082000, "55082000.mmu",
 376                       &omap4_iommu_pdata),
 377#endif
 378        { /* sentinel */ },
 379};
 380
 381/*
 382 * Few boards still need to initialize some legacy devices with
 383 * platform data until the drivers support device tree.
 384 */
 385static struct pdata_init pdata_quirks[] __initdata = {
 386#ifdef CONFIG_ARCH_OMAP3
 387        { "compulab,omap3-sbc-t3517", omap3_sbc_t3517_legacy_init, },
 388        { "compulab,omap3-sbc-t3530", omap3_sbc_t3530_legacy_init, },
 389        { "compulab,omap3-sbc-t3730", omap3_sbc_t3730_legacy_init, },
 390        { "nokia,omap3-n900", nokia_n900_legacy_init, },
 391        { "nokia,omap3-n9", hsmmc2_internal_input_clk, },
 392        { "nokia,omap3-n950", hsmmc2_internal_input_clk, },
 393        { "isee,omap3-igep0020", omap3_igep0020_legacy_init, },
 394        { "ti,omap3-evm-37xx", omap3_evm_legacy_init, },
 395        { "ti,omap3-zoom3", omap3_zoom_legacy_init, },
 396        { "ti,am3517-evm", am3517_evm_legacy_init, },
 397        { "technexion,omap3-tao3530", omap3_tao3530_legacy_init, },
 398#endif
 399#ifdef CONFIG_ARCH_OMAP4
 400        { "ti,omap4-sdp", omap4_sdp_legacy_init, },
 401        { "ti,omap4-panda", omap4_panda_legacy_init, },
 402        { "variscite,var-dvk-om44", var_som_om44_legacy_init, },
 403        { "variscite,var-stk-om44", var_som_om44_legacy_init, },
 404#endif
 405#ifdef CONFIG_SOC_AM33XX
 406        { "ti,am335x-evmsk", am335x_evmsk_legacy_init, },
 407#endif
 408#ifdef CONFIG_SOC_OMAP5
 409        { "ti,omap5-uevm", omap5_uevm_legacy_init, },
 410#endif
 411        { /* sentinel */ },
 412};
 413
 414static void pdata_quirks_check(struct pdata_init *quirks)
 415{
 416        while (quirks->compatible) {
 417                if (of_machine_is_compatible(quirks->compatible)) {
 418                        if (quirks->fn)
 419                                quirks->fn();
 420                        break;
 421                }
 422                quirks++;
 423        }
 424}
 425
 426void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
 427{
 428        omap_sdrc_init(NULL, NULL);
 429        pdata_quirks_check(auxdata_quirks);
 430        of_platform_populate(NULL, omap_dt_match_table,
 431                             omap_auxdata_lookup, NULL);
 432        pdata_quirks_check(pdata_quirks);
 433}
 434