summaryrefslogtreecommitdiff
path: root/drivers/phy/marvell/comphy_mux.c
diff options
context:
space:
mode:
authorStefan Roese <sr@denx.de>2016-05-23 11:12:05 +0200
committerStefan Roese <sr@denx.de>2016-09-27 17:29:53 +0200
commit3335786a982578abf9a25e4d6ce67d3416ebe15e (patch)
tree20db66398cfb2c42c8834b53fe65d796348728c3 /drivers/phy/marvell/comphy_mux.c
parentc6cfcc91ea59d800672274a056eefa93a10711e9 (diff)
downloadu-boot-imx-3335786a982578abf9a25e4d6ce67d3416ebe15e.zip
u-boot-imx-3335786a982578abf9a25e4d6ce67d3416ebe15e.tar.gz
u-boot-imx-3335786a982578abf9a25e4d6ce67d3416ebe15e.tar.bz2
drivers/phy: Add Marvell SerDes / PHY drivers used on Armada 3k
This version is based on the Marvell U-Boot version with this patch applied as latest patch: Git ID 7f408573: "fix: comphy: cp110: add comphy initialization for usb device mode" from 2016-07-05. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Nadav Haklai <nadavh@marvell.com> Cc: Kostya Porotchkin <kostap@marvell.com> Cc: Wilson Ding <dingwei@marvell.com> Cc: Victor Gu <xigu@marvell.com> Cc: Hua Jing <jinghua@marvell.com> Cc: Terry Zhou <bjzhou@marvell.com> Cc: Hanna Hawa <hannah@marvell.com> Cc: Haim Boot <hayim@marvell.com>
Diffstat (limited to 'drivers/phy/marvell/comphy_mux.c')
-rw-r--r--drivers/phy/marvell/comphy_mux.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/drivers/phy/marvell/comphy_mux.c b/drivers/phy/marvell/comphy_mux.c
new file mode 100644
index 0000000..1dc7426
--- /dev/null
+++ b/drivers/phy/marvell/comphy_mux.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2015-2016 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#include "comphy.h"
+#include "comphy_hpipe.h"
+
+/*
+ * comphy_mux_check_config()
+ * description: this function passes over the COMPHY lanes and check if the type
+ * is valid for specific lane. If the type is not valid,
+ * the function update the struct and set the type of the lane as
+ * PHY_TYPE_UNCONNECTED
+ */
+static void comphy_mux_check_config(struct comphy_mux_data *mux_data,
+ struct comphy_map *comphy_map_data, int comphy_max_lanes)
+{
+ struct comphy_mux_options *mux_opt;
+ int lane, opt, valid;
+
+ debug_enter();
+
+ for (lane = 0; lane < comphy_max_lanes;
+ lane++, comphy_map_data++, mux_data++) {
+ mux_opt = mux_data->mux_values;
+ for (opt = 0, valid = 0; opt < mux_data->max_lane_values;
+ opt++, mux_opt++) {
+ if (mux_opt->type == comphy_map_data->type) {
+ valid = 1;
+ break;
+ }
+ }
+ if (valid == 0) {
+ debug("lane number %d, had invalid type %d\n",
+ lane, comphy_map_data->type);
+ debug("set lane %d as type %d\n", lane,
+ PHY_TYPE_UNCONNECTED);
+ comphy_map_data->type = PHY_TYPE_UNCONNECTED;
+ } else {
+ debug("lane number %d, has type %d\n",
+ lane, comphy_map_data->type);
+ }
+ }
+
+ debug_exit();
+}
+
+static u32 comphy_mux_get_mux_value(struct comphy_mux_data *mux_data,
+ u32 type, int lane)
+{
+ struct comphy_mux_options *mux_opt;
+ int opt;
+ u32 value = 0;
+
+ debug_enter();
+
+ mux_opt = mux_data->mux_values;
+ for (opt = 0 ; opt < mux_data->max_lane_values; opt++, mux_opt++) {
+ if (mux_opt->type == type) {
+ value = mux_opt->mux_value;
+ break;
+ }
+ }
+
+ debug_exit();
+
+ return value;
+}
+
+static void comphy_mux_reg_write(struct comphy_mux_data *mux_data,
+ struct comphy_map *comphy_map_data,
+ int comphy_max_lanes,
+ void __iomem *selector_base, u32 bitcount)
+{
+ u32 lane, value, offset, mask;
+
+ debug_enter();
+
+ for (lane = 0; lane < comphy_max_lanes;
+ lane++, comphy_map_data++, mux_data++) {
+ offset = lane * bitcount;
+ mask = (((1 << bitcount) - 1) << offset);
+ value = (comphy_mux_get_mux_value(mux_data,
+ comphy_map_data->type,
+ lane) << offset);
+ reg_set(selector_base, value, mask);
+ }
+
+ debug_exit();
+}
+
+void comphy_mux_init(struct chip_serdes_phy_config *chip_cfg,
+ struct comphy_map *comphy_map_data,
+ void __iomem *selector_base)
+{
+ struct comphy_mux_data *mux_data;
+ u32 mux_bitcount;
+ u32 comphy_max_lanes;
+
+ debug_enter();
+
+ comphy_max_lanes = chip_cfg->comphy_lanes_count;
+ mux_data = chip_cfg->mux_data;
+ mux_bitcount = chip_cfg->comphy_mux_bitcount;
+
+ /* check if the configuration is valid */
+ comphy_mux_check_config(mux_data, comphy_map_data, comphy_max_lanes);
+ /* Init COMPHY selectors */
+ comphy_mux_reg_write(mux_data, comphy_map_data, comphy_max_lanes,
+ selector_base, mux_bitcount);
+
+ debug_exit();
+}