[U-Boot] [PATCH 3/3] arm: mvebu: a38x: serdes specification cleanup

Kevin Smith kevin.smith at elecsyscorp.com
Fri Oct 23 19:53:19 CEST 2015


Instead of allocating space in the driver for the serdes
specification table, just allow the board file to set a pointer
to it.  Also, allow the board to only specify the lanes that are
used instead of including unused lanes.

Signed-off-by: Kevin Smith <kevin.smith at elecsyscorp.com>
Cc: Stefan Roese <sr at denx.de>
Cc: Dirk Eibach <eibach at gdsys.de>
Cc: Luka Perkov <luka.perkov at sartura.hr>
---
 arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c         | 13 ++--
 arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h         |  2 +-
 .../mach-mvebu/serdes/a38x/high_speed_env_spec.c   | 77 +++++++++++-----------
 .../mach-mvebu/serdes/a38x/high_speed_env_spec.h   |  8 +--
 board/Marvell/db-88f6820-gp/db-88f6820-gp.c        |  5 +-
 5 files changed, 51 insertions(+), 54 deletions(-)

diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
index 9947412..06a7715 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
+++ b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
@@ -13,17 +13,16 @@
 #include "ctrl_pex.h"
 #include "sys_env_lib.h"
 
-int hws_pex_config(const struct serdes_map *serdes_map)
+int hws_pex_config(const struct serdes_map *serdes_map, u8 count)
 {
 	u32 pex_idx, tmp, next_busno, first_busno, temp_pex_reg,
 	    temp_reg, addr, dev_id, ctrl_mode;
 	enum serdes_type serdes_type;
-	u32 idx, max_lane_num;
+	u32 idx;
 
 	DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n");
 
-	max_lane_num = hws_serdes_get_max_lane();
-	for (idx = 0; idx < max_lane_num; idx++) {
+	for (idx = 0; idx < count; idx++) {
 		serdes_type = serdes_map[idx].serdes_type;
 		/* configuration for PEX only */
 		if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
@@ -47,7 +46,7 @@ int hws_pex_config(const struct serdes_map *serdes_map)
 	tmp = reg_read(SOC_CTRL_REG);
 	tmp &= ~0x03;
 
-	for (idx = 0; idx < max_lane_num; idx++) {
+	for (idx = 0; idx < count; idx++) {
 		serdes_type = serdes_map[idx].serdes_type;
 		if ((serdes_type != PEX0) &&
 		    ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
@@ -81,7 +80,7 @@ int hws_pex_config(const struct serdes_map *serdes_map)
 	next_busno = 0;
 	mdelay(150);
 
-	for (idx = 0; idx < max_lane_num; idx++) {
+	for (idx = 0; idx < count; idx++) {
 		serdes_type = serdes_map[idx].serdes_type;
 		DEBUG_INIT_FULL_S(" serdes_type=0x");
 		DEBUG_INIT_FULL_D(serdes_type, 8);
@@ -191,7 +190,7 @@ int hws_pex_config(const struct serdes_map *serdes_map)
 	/* Update pex DEVICE ID */
 	ctrl_mode = sys_env_model_get();
 
-	for (idx = 0; idx < max_lane_num; idx++) {
+	for (idx = 0; idx < count; idx++) {
 		serdes_type = serdes_map[idx].serdes_type;
 		/* configuration for PEX only */
 		if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
index 16ee4cb..5f7e2c7 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
+++ b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
@@ -78,7 +78,7 @@
 #define PEX_STATUS_AND_COMMAND		0x004
 #define PXSAC_MABORT			BIT(29) /* Recieved Master Abort */
 
-int hws_pex_config(const struct serdes_map *serdes_map);
+int hws_pex_config(const struct serdes_map *serdes_map, u8 count);
 int pex_local_bus_num_set(u32 pex_if, u32 bus_num);
 int pex_local_dev_num_set(u32 pex_if, u32 dev_num);
 u32 pex_config_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 reg_off);
diff --git a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
index 24e9af6..7d67199 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
+++ b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
@@ -20,11 +20,6 @@
 #error "No device is defined"
 #endif
 
-/*
- * The board topology map, initialized in the beginning of
- * ctrl_high_speed_serdes_phy_config
- */
-struct serdes_map serdes_configuration_map[MAX_SERDES_LANES];
 
 /*
  * serdes_seq_db - holds all serdes sequences, their size and the
@@ -1362,7 +1357,8 @@ enum serdes_seq serdes_type_and_speed_to_speed_seq(enum serdes_type serdes_type,
 	return seq_id;
 }
 
-void print_topology_details(const struct serdes_map *serdes_map_array)
+static void print_topology_details(const struct serdes_map *serdes_map,
+								u8 count)
 {
 	u32 lane_num;
 
@@ -1370,16 +1366,16 @@ void print_topology_details(const struct serdes_map *serdes_map_array)
 
 	DEBUG_INIT_S(" | Lane #  | Speed |  Type       |\n");
 	DEBUG_INIT_S(" --------------------------------\n");
-	for (lane_num = 0; lane_num < hws_serdes_get_max_lane(); lane_num++) {
-		if (serdes_map_array[lane_num].serdes_type == DEFAULT_SERDES)
+	for (lane_num = 0; lane_num < count; lane_num++) {
+		if (serdes_map[lane_num].serdes_type == DEFAULT_SERDES)
 			continue;
 		DEBUG_INIT_S(" |   ");
 		DEBUG_INIT_D(hws_get_physical_serdes_num(lane_num), 1);
 		DEBUG_INIT_S("    |  ");
-		DEBUG_INIT_D(serdes_map_array[lane_num].serdes_speed, 2);
+		DEBUG_INIT_D(serdes_map[lane_num].serdes_speed, 2);
 		DEBUG_INIT_S("   |  ");
 		DEBUG_INIT_S((char *)
-			     serdes_type_to_string[serdes_map_array[lane_num].
+			     serdes_type_to_string[serdes_map[lane_num].
 						   serdes_type]);
 		DEBUG_INIT_S("\t|\n");
 	}
@@ -1413,6 +1409,9 @@ int hws_pre_serdes_init_config(void)
 
 int serdes_phy_config(void)
 {
+	struct serdes_map *serdes_map;
+	u8 serdes_count;
+
 	DEBUG_INIT_FULL_S("\n### ctrl_high_speed_serdes_phy_config ###\n");
 
 	DEBUG_INIT_S("High speed PHY - Version: ");
@@ -1428,17 +1427,21 @@ int serdes_phy_config(void)
 	/* Board topology load */
 	DEBUG_INIT_FULL_S
 	    ("ctrl_high_speed_serdes_phy_config: Loading board topology..\n");
-	CHECK_STATUS(hws_board_topology_load(serdes_configuration_map));
+	CHECK_STATUS(hws_board_topology_load(&serdes_map, &serdes_count));
+	if (serdes_count > hws_serdes_get_max_lane()) {
+		printf("Error: too many serdes lanes specified by board\n");
+		return MV_FAIL;
+	}
 
 	/* print topology */
-	print_topology_details(serdes_configuration_map);
+	print_topology_details(serdes_map, serdes_count);
 	CHECK_STATUS(hws_pre_serdes_init_config());
 
 	/* Power-Up sequence */
 	DEBUG_INIT_FULL_S
 		("ctrl_high_speed_serdes_phy_config: Starting serdes power up sequence\n");
 
-	CHECK_STATUS(hws_power_up_serdes_lanes(serdes_configuration_map));
+	CHECK_STATUS(hws_power_up_serdes_lanes(serdes_map, serdes_count));
 
 	DEBUG_INIT_FULL_S
 		("\n### ctrl_high_speed_serdes_phy_config ended successfully ###\n");
@@ -1462,7 +1465,7 @@ int serdes_polarity_config(u32 serdes_num, int is_rx)
 	return MV_OK;
 }
 
-int hws_power_up_serdes_lanes(const struct serdes_map *serdes_config_map)
+int hws_power_up_serdes_lanes(struct serdes_map *serdes_map, u8 count)
 {
 	u32 serdes_id, serdes_lane_num;
 	enum ref_clock ref_clock;
@@ -1484,22 +1487,21 @@ int hws_power_up_serdes_lanes(const struct serdes_map *serdes_config_map)
 	/* COMMON PHYS SELECTORS register configuration */
 	DEBUG_INIT_FULL_S
 	    ("hws_power_up_serdes_lanes: Updating COMMON PHYS SELECTORS reg\n");
-	CHECK_STATUS(hws_update_serdes_phy_selectors(serdes_configuration_map));
+	CHECK_STATUS(hws_update_serdes_phy_selectors(serdes_map, count));
 
 	/* per Serdes Power Up */
-	for (serdes_id = 0; serdes_id < hws_serdes_get_max_lane();
-	     serdes_id++) {
+	for (serdes_id = 0; serdes_id < count; serdes_id++) {
 		DEBUG_INIT_FULL_S
 		    ("calling serdes_power_up_ctrl: serdes lane number ");
 		DEBUG_INIT_FULL_D_10(serdes_lane_num, 1);
 		DEBUG_INIT_FULL_S("\n");
 
 		serdes_lane_num = hws_get_physical_serdes_num(serdes_id);
-		serdes_type = serdes_config_map[serdes_id].serdes_type;
-		serdes_speed = serdes_config_map[serdes_id].serdes_speed;
-		serdes_mode = serdes_config_map[serdes_id].serdes_mode;
-		serdes_rx_polarity_swap = serdes_config_map[serdes_id].swap_rx;
-		serdes_tx_polarity_swap = serdes_config_map[serdes_id].swap_tx;
+		serdes_type = serdes_map[serdes_id].serdes_type;
+		serdes_speed = serdes_map[serdes_id].serdes_speed;
+		serdes_mode = serdes_map[serdes_id].serdes_mode;
+		serdes_rx_polarity_swap = serdes_map[serdes_id].swap_rx;
+		serdes_tx_polarity_swap = serdes_map[serdes_id].swap_tx;
 
 		/* serdes lane is not in use */
 		if (serdes_type == DEFAULT_SERDES)
@@ -1534,10 +1536,10 @@ int hws_power_up_serdes_lanes(const struct serdes_map *serdes_config_map)
 		/* Set PEX_TX_CONFIG_SEQ sequence for PEXx4 mode.
 		   After finish the Power_up sequence for all lanes,
 		   the lanes should be released from reset state.       */
-		CHECK_STATUS(hws_pex_tx_config_seq(serdes_config_map));
+		CHECK_STATUS(hws_pex_tx_config_seq(serdes_map, count));
 
 		/* PEX configuration */
-		CHECK_STATUS(hws_pex_config(serdes_config_map));
+		CHECK_STATUS(hws_pex_config(serdes_map, count));
 	}
 
 	/* USB2 configuration */
@@ -1905,7 +1907,7 @@ int serdes_power_up_ctrl(u32 serdes_num, int serdes_power_up,
 	return MV_OK;
 }
 
-int hws_update_serdes_phy_selectors(struct serdes_map *serdes_config_map)
+int hws_update_serdes_phy_selectors(struct serdes_map *serdes_map, u8 count)
 {
 	u32 lane_data, idx, serdes_lane_hw_num, reg_data = 0;
 	enum serdes_type serdes_type;
@@ -1927,10 +1929,9 @@ int hws_update_serdes_phy_selectors(struct serdes_map *serdes_config_map)
 	 * Updating bits 0-17 in the COMMON PHYS SELECTORS register
 	 * according to the serdes types
 	 */
-	for (idx = 0; idx < hws_serdes_get_max_lane();
-	     idx++) {
-		serdes_type = serdes_config_map[idx].serdes_type;
-		serdes_mode = serdes_config_map[idx].serdes_mode;
+	for (idx = 0; idx < count; idx++) {
+		serdes_type = serdes_map[idx].serdes_type;
+		serdes_mode = serdes_map[idx].serdes_mode;
 		serdes_lane_hw_num = hws_get_physical_serdes_num(idx);
 
 		lane_data =
@@ -1942,7 +1943,7 @@ int hws_update_serdes_phy_selectors(struct serdes_map *serdes_config_map)
 
 		if (hws_serdes_topology_verify
 		    (serdes_type, idx, serdes_mode) != MV_OK) {
-			serdes_config_map[idx].serdes_type =
+			serdes_map[idx].serdes_type =
 			    DEFAULT_SERDES;
 			printf("%s: SerDes lane #%d is  disabled\n", __func__,
 			       serdes_lane_hw_num);
@@ -1968,8 +1969,7 @@ int hws_update_serdes_phy_selectors(struct serdes_map *serdes_config_map)
 			printf
 			    ("%s: Warning: SerDes lane #%d and type %d are not supported together\n",
 			     __func__, serdes_lane_hw_num, serdes_mode);
-			serdes_config_map[idx].serdes_type =
-				DEFAULT_SERDES;
+			serdes_map[idx].serdes_type = DEFAULT_SERDES;
 			printf("%s: SerDes lane #%d is  disabled\n", __func__,
 			       serdes_lane_hw_num);
 			continue;
@@ -1991,7 +1991,7 @@ int hws_update_serdes_phy_selectors(struct serdes_map *serdes_config_map)
 
 	/* Print topology */
 	if (updated_topology_print)
-		print_topology_details(serdes_config_map);
+		print_topology_details(serdes_map, count);
 
 	/*
 	 * Updating the PEXx4 Enable bit in the COMMON PHYS SELECTORS
@@ -2145,7 +2145,7 @@ int hws_ref_clock_set(u32 serdes_num, enum serdes_type serdes_type,
  * RETURNS:              MV_OK           - for success
  *                       MV_BAD_PARAM    - for fail
  */
-int hws_pex_tx_config_seq(const struct serdes_map *serdes_map)
+int hws_pex_tx_config_seq(const struct serdes_map *serdes_map, u8 count)
 {
 	enum serdes_mode serdes_mode;
 	u32 serdes_lane_id, serdes_lane_hw_num;
@@ -2159,8 +2159,7 @@ int hws_pex_tx_config_seq(const struct serdes_map *serdes_map)
 	 */
 
 	/* relese pipe soft reset for all lanes */
-	for (serdes_lane_id = 0; serdes_lane_id < hws_serdes_get_max_lane();
-	     serdes_lane_id++) {
+	for (serdes_lane_id = 0; serdes_lane_id < count; serdes_lane_id++) {
 		serdes_mode = serdes_map[serdes_lane_id].serdes_mode;
 		serdes_lane_hw_num =
 		    hws_get_physical_serdes_num(serdes_lane_id);
@@ -2173,8 +2172,7 @@ int hws_pex_tx_config_seq(const struct serdes_map *serdes_map)
 	}
 
 	/* set phy soft reset for all lanes */
-	for (serdes_lane_id = 0; serdes_lane_id < hws_serdes_get_max_lane();
-	     serdes_lane_id++) {
+	for (serdes_lane_id = 0; serdes_lane_id < count; serdes_lane_id++) {
 		serdes_mode = serdes_map[serdes_lane_id].serdes_mode;
 		serdes_lane_hw_num =
 		    hws_get_physical_serdes_num(serdes_lane_id);
@@ -2186,8 +2184,7 @@ int hws_pex_tx_config_seq(const struct serdes_map *serdes_map)
 	}
 
 	/* set phy soft reset for all lanes */
-	for (serdes_lane_id = 0; serdes_lane_id < hws_serdes_get_max_lane();
-	     serdes_lane_id++) {
+	for (serdes_lane_id = 0; serdes_lane_id < count; serdes_lane_id++) {
 		serdes_mode = serdes_map[serdes_lane_id].serdes_mode;
 		serdes_lane_hw_num =
 		    hws_get_physical_serdes_num(serdes_lane_id);
diff --git a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.h b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.h
index 5f3b9d8..3513770 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.h
+++ b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.h
@@ -215,12 +215,12 @@ extern u8 selectors_serdes_rev2_map[LAST_SERDES_TYPE][MAX_SERDES_LANES];
 
 u8 hws_ctrl_serdes_rev_get(void);
 int mv_update_serdes_select_phy_mode_seq(void);
-int hws_board_topology_load(struct serdes_map *serdes_map_array);
+int hws_board_topology_load(struct serdes_map **serdes_map, u8 *count);
 enum serdes_seq serdes_type_and_speed_to_speed_seq(enum serdes_type serdes_type,
 						   enum serdes_speed baud_rate);
 int hws_serdes_seq_init(void);
 int hws_serdes_seq_db_init(void);
-int hws_power_up_serdes_lanes(const struct serdes_map *serdes_config_map);
+int hws_power_up_serdes_lanes(struct serdes_map *serdes_map, u8 count);
 int hws_ctrl_high_speed_serdes_phy_config(void);
 int serdes_power_up_ctrl(u32 serdes_num, int serdes_power_up,
 			 enum serdes_type serdes_type,
@@ -237,14 +237,14 @@ int hws_serdes_pex_ref_clock_get(enum serdes_type serdes_type,
 				 enum ref_clock *ref_clock);
 int hws_ref_clock_set(u32 serdes_num, enum serdes_type serdes_type,
 		      enum ref_clock ref_clock);
-int hws_update_serdes_phy_selectors(struct serdes_map *serdes_config_map);
+int hws_update_serdes_phy_selectors(struct serdes_map *serdes_map, u8 count);
 u32 hws_serdes_get_phy_selector_val(int serdes_num,
 				    enum serdes_type serdes_type);
 u32 hws_serdes_get_ref_clock_val(enum serdes_type serdes_type);
 u32 hws_serdes_get_max_lane(void);
 int hws_get_ext_base_addr(u32 serdes_num, u32 base_addr, u32 unit_base_offset,
 			  u32 *unit_base_reg, u32 *unit_offset);
-int hws_pex_tx_config_seq(const struct serdes_map *serdes_map);
+int hws_pex_tx_config_seq(const struct serdes_map *serdes_map, u8 count);
 u32 hws_get_physical_serdes_num(u32 serdes_num);
 int hws_is_serdes_active(u8 lane_num);
 
diff --git a/board/Marvell/db-88f6820-gp/db-88f6820-gp.c b/board/Marvell/db-88f6820-gp/db-88f6820-gp.c
index 384d002..e700781 100644
--- a/board/Marvell/db-88f6820-gp/db-88f6820-gp.c
+++ b/board/Marvell/db-88f6820-gp/db-88f6820-gp.c
@@ -65,9 +65,10 @@ static struct serdes_map board_serdes_map[] = {
 	{USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}
 };
 
-int hws_board_topology_load(struct serdes_map *serdes_map_array)
+int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
 {
-	memcpy(serdes_map_array, board_serdes_map, sizeof(board_serdes_map));
+	*serdes_map_array = board_serdes_map;
+	*count = ARRAY_SIZE(board_serdes_map);
 	return 0;
 }
 
-- 
2.4.6


More information about the U-Boot mailing list