19886c3d7SIgor Grinberg /*
29886c3d7SIgor Grinberg * (C) Copyright 2014 CompuLab, Ltd. <www.compulab.co.il>
39886c3d7SIgor Grinberg *
49886c3d7SIgor Grinberg * Authors: Igor Grinberg <grinberg@compulab.co.il>
59886c3d7SIgor Grinberg *
69886c3d7SIgor Grinberg * SPDX-License-Identifier: GPL-2.0+
79886c3d7SIgor Grinberg */
89886c3d7SIgor Grinberg
99886c3d7SIgor Grinberg #include <common.h>
109886c3d7SIgor Grinberg #include <netdev.h>
119886c3d7SIgor Grinberg
129886c3d7SIgor Grinberg #include <asm/io.h>
13*1221ce45SMasahiro Yamada #include <linux/errno.h>
149886c3d7SIgor Grinberg #include <asm/arch/cpu.h>
159886c3d7SIgor Grinberg #include <asm/arch/mem.h>
169886c3d7SIgor Grinberg #include <asm/arch/sys_proto.h>
179886c3d7SIgor Grinberg #include <asm/gpio.h>
189886c3d7SIgor Grinberg
199886c3d7SIgor Grinberg #include "common.h"
209886c3d7SIgor Grinberg
219886c3d7SIgor Grinberg static u32 cl_omap3_smc911x_gpmc_net_config[GPMC_MAX_REG] = {
229886c3d7SIgor Grinberg NET_GPMC_CONFIG1,
239886c3d7SIgor Grinberg NET_GPMC_CONFIG2,
249886c3d7SIgor Grinberg NET_GPMC_CONFIG3,
259886c3d7SIgor Grinberg NET_GPMC_CONFIG4,
269886c3d7SIgor Grinberg NET_GPMC_CONFIG5,
279886c3d7SIgor Grinberg NET_GPMC_CONFIG6,
289886c3d7SIgor Grinberg 0
299886c3d7SIgor Grinberg };
309886c3d7SIgor Grinberg
cl_omap3_smc911x_setup_net_chip_gmpc(int cs,u32 base_addr)319886c3d7SIgor Grinberg static void cl_omap3_smc911x_setup_net_chip_gmpc(int cs, u32 base_addr)
329886c3d7SIgor Grinberg {
339886c3d7SIgor Grinberg struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE;
349886c3d7SIgor Grinberg
359886c3d7SIgor Grinberg enable_gpmc_cs_config(cl_omap3_smc911x_gpmc_net_config,
369886c3d7SIgor Grinberg &gpmc_cfg->cs[cs], base_addr, GPMC_SIZE_16M);
379886c3d7SIgor Grinberg
389886c3d7SIgor Grinberg /* Enable off mode for NWE in PADCONF_GPMC_NWE register */
399886c3d7SIgor Grinberg writew(readw(&ctrl_base->gpmc_nwe) | 0x0E00, &ctrl_base->gpmc_nwe);
409886c3d7SIgor Grinberg
419886c3d7SIgor Grinberg /* Enable off mode for NOE in PADCONF_GPMC_NADV_ALE register */
429886c3d7SIgor Grinberg writew(readw(&ctrl_base->gpmc_noe) | 0x0E00, &ctrl_base->gpmc_noe);
439886c3d7SIgor Grinberg
449886c3d7SIgor Grinberg /* Enable off mode for ALE in PADCONF_GPMC_NADV_ALE register */
459886c3d7SIgor Grinberg writew(readw(&ctrl_base->gpmc_nadv_ale) | 0x0E00,
469886c3d7SIgor Grinberg &ctrl_base->gpmc_nadv_ale);
479886c3d7SIgor Grinberg }
489886c3d7SIgor Grinberg
499886c3d7SIgor Grinberg #ifdef CONFIG_OMAP_GPIO
cl_omap3_smc911x_reset_net_chip(int gpio)509886c3d7SIgor Grinberg static int cl_omap3_smc911x_reset_net_chip(int gpio)
519886c3d7SIgor Grinberg {
529886c3d7SIgor Grinberg int err;
539886c3d7SIgor Grinberg
549886c3d7SIgor Grinberg if (!gpio_is_valid(gpio))
559886c3d7SIgor Grinberg return -EINVAL;
569886c3d7SIgor Grinberg
579886c3d7SIgor Grinberg err = gpio_request(gpio, "eth rst");
589886c3d7SIgor Grinberg if (err)
599886c3d7SIgor Grinberg return err;
609886c3d7SIgor Grinberg
619886c3d7SIgor Grinberg /* Set gpio as output and send a pulse */
629886c3d7SIgor Grinberg gpio_direction_output(gpio, 1);
639886c3d7SIgor Grinberg udelay(1);
649886c3d7SIgor Grinberg gpio_set_value(gpio, 0);
659886c3d7SIgor Grinberg mdelay(40);
669886c3d7SIgor Grinberg gpio_set_value(gpio, 1);
679886c3d7SIgor Grinberg mdelay(1);
689886c3d7SIgor Grinberg
699886c3d7SIgor Grinberg return 0;
709886c3d7SIgor Grinberg }
719886c3d7SIgor Grinberg #else /* !CONFIG_OMAP_GPIO */
cl_omap3_smc911x_reset_net_chip(int gpio)729886c3d7SIgor Grinberg static inline int cl_omap3_smc911x_reset_net_chip(int gpio) { return 0; }
739886c3d7SIgor Grinberg #endif /* CONFIG_OMAP_GPIO */
749886c3d7SIgor Grinberg
cl_omap3_smc911x_init(int id,int cs,u32 base_addr,int (* reset)(int),int rst_gpio)759886c3d7SIgor Grinberg int cl_omap3_smc911x_init(int id, int cs, u32 base_addr,
769886c3d7SIgor Grinberg int (*reset)(int), int rst_gpio)
779886c3d7SIgor Grinberg {
789886c3d7SIgor Grinberg int ret;
799886c3d7SIgor Grinberg
809886c3d7SIgor Grinberg cl_omap3_smc911x_setup_net_chip_gmpc(cs, base_addr);
819886c3d7SIgor Grinberg
829886c3d7SIgor Grinberg if (reset)
839886c3d7SIgor Grinberg reset(rst_gpio);
849886c3d7SIgor Grinberg else
859886c3d7SIgor Grinberg cl_omap3_smc911x_reset_net_chip(rst_gpio);
869886c3d7SIgor Grinberg
879886c3d7SIgor Grinberg ret = smc911x_initialize(id, base_addr);
889886c3d7SIgor Grinberg if (ret > 0)
899886c3d7SIgor Grinberg return ret;
909886c3d7SIgor Grinberg
919886c3d7SIgor Grinberg printf("Failed initializing SMC911x! ");
929886c3d7SIgor Grinberg return 0;
939886c3d7SIgor Grinberg }
94