u-boot/drivers/phy/marvell/comphy_core.c
Tom Rini 83d290c56f SPDX: Convert all of our single license tags to Linux Kernel style
When U-Boot started using SPDX tags we were among the early adopters and
there weren't a lot of other examples to borrow from.  So we picked the
area of the file that usually had a full license text and replaced it
with an appropriate SPDX-License-Identifier: entry.  Since then, the
Linux Kernel has adopted SPDX tags and they place it as the very first
line in a file (except where shebangs are used, then it's second line)
and with slightly different comment styles than us.

In part due to community overlap, in part due to better tag visibility
and in part for other minor reasons, switch over to that style.

This commit changes all instances where we have a single declared
license in the tag as both the before and after are identical in tag
contents.  There's also a few places where I found we did not have a tag
and have introduced one.

Signed-off-by: Tom Rini <trini@konsulko.com>
2018-05-07 09:34:12 -04:00

211 lines
5.6 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2015-2016 Marvell International Ltd.
*
* Copyright (C) 2016 Stefan Roese <sr@denx.de>
*/
#include <common.h>
#include <dm.h>
#include <fdtdec.h>
#include <linux/errno.h>
#include <asm/io.h>
#include "comphy.h"
#define COMPHY_MAX_CHIP 4
DECLARE_GLOBAL_DATA_PTR;
static char *get_speed_string(u32 speed)
{
char *speed_strings[] = {"1.25 Gbps", "1.5 Gbps", "2.5 Gbps",
"3.0 Gbps", "3.125 Gbps", "5 Gbps", "6 Gbps",
"6.25 Gbps", "10.31 Gbps" };
if (speed < 0 || speed > PHY_SPEED_MAX)
return "invalid";
return speed_strings[speed];
}
static char *get_type_string(u32 type)
{
char *type_strings[] = {"UNCONNECTED", "PEX0", "PEX1", "PEX2", "PEX3",
"SATA0", "SATA1", "SATA2", "SATA3", "SGMII0",
"SGMII1", "SGMII2", "SGMII3", "QSGMII",
"USB3_HOST0", "USB3_HOST1", "USB3_DEVICE",
"XAUI0", "XAUI1", "XAUI2", "XAUI3",
"RXAUI0", "RXAUI1", "SFI", "IGNORE"};
if (type < 0 || type > PHY_TYPE_MAX)
return "invalid";
return type_strings[type];
}
void reg_set(void __iomem *addr, u32 data, u32 mask)
{
debug("Write to address = %#010lx, data = %#010x (mask = %#010x) - ",
(unsigned long)addr, data, mask);
debug("old value = %#010x ==> ", readl(addr));
reg_set_silent(addr, data, mask);
debug("new value %#010x\n", readl(addr));
}
void reg_set_silent(void __iomem *addr, u32 data, u32 mask)
{
u32 reg_data;
reg_data = readl(addr);
reg_data &= ~mask;
reg_data |= data;
writel(reg_data, addr);
}
void reg_set16(void __iomem *addr, u16 data, u16 mask)
{
debug("Write to address = %#010lx, data = %#06x (mask = %#06x) - ",
(unsigned long)addr, data, mask);
debug("old value = %#06x ==> ", readw(addr));
reg_set_silent16(addr, data, mask);
debug("new value %#06x\n", readw(addr));
}
void reg_set_silent16(void __iomem *addr, u16 data, u16 mask)
{
u16 reg_data;
reg_data = readw(addr);
reg_data &= ~mask;
reg_data |= data;
writew(reg_data, addr);
}
void comphy_print(struct chip_serdes_phy_config *chip_cfg,
struct comphy_map *comphy_map_data)
{
u32 lane;
for (lane = 0; lane < chip_cfg->comphy_lanes_count;
lane++, comphy_map_data++) {
if (comphy_map_data->speed == PHY_SPEED_INVALID) {
printf("Comphy-%d: %-13s\n", lane,
get_type_string(comphy_map_data->type));
} else {
printf("Comphy-%d: %-13s %-10s\n", lane,
get_type_string(comphy_map_data->type),
get_speed_string(comphy_map_data->speed));
}
}
}
static int comphy_probe(struct udevice *dev)
{
const void *blob = gd->fdt_blob;
int node = dev_of_offset(dev);
struct chip_serdes_phy_config *chip_cfg = dev_get_priv(dev);
struct comphy_map comphy_map_data[MAX_LANE_OPTIONS];
int subnode;
int lane;
int last_idx = 0;
static int current_idx;
/* Save base addresses for later use */
chip_cfg->comphy_base_addr = (void *)devfdt_get_addr_index(dev, 0);
if (IS_ERR(chip_cfg->comphy_base_addr))
return PTR_ERR(chip_cfg->comphy_base_addr);
chip_cfg->hpipe3_base_addr = (void *)devfdt_get_addr_index(dev, 1);
if (IS_ERR(chip_cfg->hpipe3_base_addr))
return PTR_ERR(chip_cfg->hpipe3_base_addr);
chip_cfg->comphy_lanes_count = fdtdec_get_int(blob, node,
"max-lanes", 0);
if (chip_cfg->comphy_lanes_count <= 0) {
dev_err(&dev->dev, "comphy max lanes is wrong\n");
return -EINVAL;
}
chip_cfg->comphy_mux_bitcount = fdtdec_get_int(blob, node,
"mux-bitcount", 0);
if (chip_cfg->comphy_mux_bitcount <= 0) {
dev_err(&dev->dev, "comphy mux bit count is wrong\n");
return -EINVAL;
}
if (device_is_compatible(dev, "marvell,comphy-armada-3700"))
chip_cfg->ptr_comphy_chip_init = comphy_a3700_init;
if (device_is_compatible(dev, "marvell,comphy-cp110"))
chip_cfg->ptr_comphy_chip_init = comphy_cp110_init;
/*
* Bail out if no chip_init function is defined, e.g. no
* compatible node is found
*/
if (!chip_cfg->ptr_comphy_chip_init) {
dev_err(&dev->dev, "comphy: No compatible DT node found\n");
return -ENODEV;
}
lane = 0;
fdt_for_each_subnode(subnode, blob, node) {
/* Skip disabled ports */
if (!fdtdec_get_is_enabled(blob, subnode))
continue;
comphy_map_data[lane].speed = fdtdec_get_int(
blob, subnode, "phy-speed", PHY_TYPE_INVALID);
comphy_map_data[lane].type = fdtdec_get_int(
blob, subnode, "phy-type", PHY_SPEED_INVALID);
comphy_map_data[lane].invert = fdtdec_get_int(
blob, subnode, "phy-invert", PHY_POLARITY_NO_INVERT);
comphy_map_data[lane].clk_src = fdtdec_get_bool(blob, subnode,
"clk-src");
comphy_map_data[lane].end_point = fdtdec_get_bool(blob, subnode,
"end_point");
if (comphy_map_data[lane].type == PHY_TYPE_INVALID) {
printf("no phy type for lane %d, setting lane as unconnected\n",
lane + 1);
}
lane++;
}
/* Save CP index for MultiCP devices (A8K) */
chip_cfg->cp_index = current_idx++;
/* PHY power UP sequence */
chip_cfg->ptr_comphy_chip_init(chip_cfg, comphy_map_data);
/* PHY print SerDes status */
if (of_machine_is_compatible("marvell,armada8040"))
printf("Comphy chip #%d:\n", chip_cfg->cp_index);
comphy_print(chip_cfg, comphy_map_data);
/*
* Only run the dedicated PHY init code once, in the last PHY init call
*/
if (of_machine_is_compatible("marvell,armada8040"))
last_idx = 1;
if (chip_cfg->cp_index == last_idx) {
/* Initialize dedicated PHYs (not muxed SerDes lanes) */
comphy_dedicated_phys_init();
}
return 0;
}
static const struct udevice_id comphy_ids[] = {
{ .compatible = "marvell,mvebu-comphy" },
{ }
};
U_BOOT_DRIVER(mvebu_comphy) = {
.name = "mvebu_comphy",
.id = UCLASS_MISC,
.of_match = comphy_ids,
.probe = comphy_probe,
.priv_auto_alloc_size = sizeof(struct chip_serdes_phy_config),
};