mirror of
https://github.com/smaeul/u-boot.git
synced 2025-10-16 21:58:15 +01:00
When bringing in the series 'arm: dts: am62-beagleplay: Fix Beagleplay Ethernet"' I failed to notice that b4 noticed it was based on next and so took that as the base commit and merged that part of next to master. This reverts commit c8ffd1356d42223cbb8c86280a083cc3c93e6426, reversing changes made to 2ee6f3a5f7550de3599faef9704e166e5dcace35. Reported-by: Jonas Karlman <jonas@kwiboo.se> Signed-off-by: Tom Rini <trini@konsulko.com>
165 lines
3.1 KiB
C
165 lines
3.1 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* (C) Copyright 2014
|
|
* Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <linux/delay.h>
|
|
|
|
#include <miiphy.h>
|
|
#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
|
|
#include <gdsys_fpga.h>
|
|
#else
|
|
#include <fdtdec.h>
|
|
#include <dm.h>
|
|
#include <regmap.h>
|
|
#endif
|
|
|
|
#include "ihs_mdio.h"
|
|
|
|
#ifndef CONFIG_GDSYS_LEGACY_DRIVERS
|
|
enum {
|
|
REG_MDIO_CONTROL = 0x0,
|
|
REG_MDIO_ADDR_DATA = 0x2,
|
|
REG_MDIO_RX_DATA = 0x4,
|
|
};
|
|
|
|
static inline u16 read_reg(struct udevice *fpga, uint base, uint addr)
|
|
{
|
|
struct regmap *map;
|
|
u8 *ptr;
|
|
|
|
regmap_init_mem(dev_ofnode(fpga), &map);
|
|
ptr = regmap_get_range(map, 0);
|
|
|
|
return in_le16((u16 *)(ptr + base + addr));
|
|
}
|
|
|
|
static inline void write_reg(struct udevice *fpga, uint base, uint addr,
|
|
u16 val)
|
|
{
|
|
struct regmap *map;
|
|
u8 *ptr;
|
|
|
|
regmap_init_mem(dev_ofnode(fpga), &map);
|
|
ptr = regmap_get_range(map, 0);
|
|
|
|
out_le16((u16 *)(ptr + base + addr), val);
|
|
}
|
|
#endif
|
|
|
|
static inline u16 read_control(struct ihs_mdio_info *info)
|
|
{
|
|
u16 val;
|
|
#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
|
|
FPGA_GET_REG(info->fpga, mdio.control, &val);
|
|
#else
|
|
val = read_reg(info->fpga, info->base, REG_MDIO_CONTROL);
|
|
#endif
|
|
return val;
|
|
}
|
|
|
|
static inline void write_control(struct ihs_mdio_info *info, u16 val)
|
|
{
|
|
#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
|
|
FPGA_SET_REG(info->fpga, mdio.control, val);
|
|
#else
|
|
write_reg(info->fpga, info->base, REG_MDIO_CONTROL, val);
|
|
#endif
|
|
}
|
|
|
|
static inline void write_addr_data(struct ihs_mdio_info *info, u16 val)
|
|
{
|
|
#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
|
|
FPGA_SET_REG(info->fpga, mdio.address_data, val);
|
|
#else
|
|
write_reg(info->fpga, info->base, REG_MDIO_ADDR_DATA, val);
|
|
#endif
|
|
}
|
|
|
|
static inline u16 read_rx_data(struct ihs_mdio_info *info)
|
|
{
|
|
u16 val;
|
|
#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
|
|
FPGA_GET_REG(info->fpga, mdio.rx_data, &val);
|
|
#else
|
|
val = read_reg(info->fpga, info->base, REG_MDIO_RX_DATA);
|
|
#endif
|
|
return val;
|
|
}
|
|
|
|
static int ihs_mdio_idle(struct mii_dev *bus)
|
|
{
|
|
struct ihs_mdio_info *info = bus->priv;
|
|
u16 val;
|
|
unsigned int ctr = 0;
|
|
|
|
do {
|
|
val = read_control(info);
|
|
udelay(100);
|
|
if (ctr++ > 10)
|
|
return -1;
|
|
} while (!(val & (1 << 12)));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ihs_mdio_reset(struct mii_dev *bus)
|
|
{
|
|
ihs_mdio_idle(bus);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ihs_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
|
|
int regnum)
|
|
{
|
|
struct ihs_mdio_info *info = bus->priv;
|
|
u16 val;
|
|
|
|
ihs_mdio_idle(bus);
|
|
|
|
write_control(info,
|
|
((addr & 0x1f) << 5) | (regnum & 0x1f) | (2 << 10));
|
|
|
|
/* wait for rx data available */
|
|
udelay(100);
|
|
|
|
val = read_rx_data(info);
|
|
|
|
return val;
|
|
}
|
|
|
|
static int ihs_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
|
|
int regnum, u16 value)
|
|
{
|
|
struct ihs_mdio_info *info = bus->priv;
|
|
|
|
ihs_mdio_idle(bus);
|
|
|
|
write_addr_data(info, value);
|
|
write_control(info, ((addr & 0x1f) << 5) | (regnum & 0x1f) | (1 << 10));
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ihs_mdio_init(struct ihs_mdio_info *info)
|
|
{
|
|
struct mii_dev *bus = mdio_alloc();
|
|
|
|
if (!bus) {
|
|
printf("Failed to allocate FSL MDIO bus\n");
|
|
return -1;
|
|
}
|
|
|
|
bus->read = ihs_mdio_read;
|
|
bus->write = ihs_mdio_write;
|
|
bus->reset = ihs_mdio_reset;
|
|
strcpy(bus->name, info->name);
|
|
|
|
bus->priv = info;
|
|
|
|
return mdio_register(bus);
|
|
}
|