mvebu: cp110: avoid pcie power on/off sequence when called from Linux

In Armada 8K DB boards, PCIe initialization can be executed only once
because PCIe reset performed during chip power on and it cannot be
executed via GPIO later.
This means that power on can be executed only once, when it's called
from the bootloader.
Power on:
	Read bit 21 of the mode, it marks if the caller is
	the bootloader or the Linux Kernel.
Power off:
	Check if the comphy was already configured to PCIe, if yes,
	check if the caller is bootloader, if both conditions are true
	(PCIe mode and called by Linux) - skip the power-off.

In addition, fix incorrect documentation describing mode fields -
PCIe width is 3 bits, not 2.

NOTE: with this patch, please use LK4.14.76 (LK4.4.120 may not work
with it).

Change-Id: I4b929011f97a0a1869a51ba378687e78b3eca4ff
Signed-off-by: Igal Liberman <igall@marvell.com>
Reviewed-by: Grzegorz Jaszczyk <jaz@semihalf.com>
Reviewed-by: Kostya Porotchkin <kostap@marvell.com>
diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c
index 897a0b0..86e5f1c 100644
--- a/drivers/marvell/comphy/phy-comphy-cp110.c
+++ b/drivers/marvell/comphy/phy-comphy-cp110.c
@@ -1205,6 +1205,22 @@
 	uint32_t clk_dir;
 	uintptr_t hpipe_addr, comphy_addr, addr;
 	_Bool clk_src = COMPHY_GET_CLK_SRC(comphy_mode);
+	_Bool called_from_uboot = COMPHY_GET_CALLER(comphy_mode);
+
+	/* In Armada 8K DB boards, PCIe initialization can be executed
+	 * only once (PCIe reset performed during chip power on and
+	 * it cannot be executed via GPIO later).
+	 * This means that power on can be executed only once, so let's
+	 * mark if the caller is bootloader or Linux.
+	 * If bootloader -> run power on.
+	 * If Linux -> exit.
+	 *
+	 * TODO: In MacciatoBIN, PCIe reset is connected via GPIO,
+	 * so after GPIO reset is added to Linux Kernel, it can be
+	 * powered-on by Linux.
+	 */
+	if (!called_from_uboot)
+		return ret;
 
 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
 				comphy_index);
@@ -2366,14 +2382,45 @@
 	return err;
 }
 
-int mvebu_cp110_comphy_power_off(uint64_t comphy_base, uint8_t comphy_index)
+int mvebu_cp110_comphy_power_off(uint64_t comphy_base, uint8_t comphy_index,
+				 uint64_t comphy_mode)
 {
 	uintptr_t sd_ip_addr, comphy_ip_addr;
 	uint32_t mask, data;
 	uint8_t ap_nr, cp_nr;
+	_Bool called_from_uboot = COMPHY_GET_CALLER(comphy_mode);
 
 	debug_enter();
 
+	/* Power-off might happen because of 2 things:
+	 *	1. Bootloader turns off unconnected lanes
+	 *	2. Linux turns off all lanes during boot
+	 *	   (and then reconfigure it).
+	 *
+	 * For PCIe, there's a problem:
+	 * In Armada 8K DB boards, PCIe initialization can be executed
+	 * only once (PCIe reset performed during chip power on and
+	 * it cannot be executed via GPIO later) so a lane configured to
+	 * PCIe should not be powered off by Linux.
+	 *
+	 * So, check 2 things:
+	 *	1. Is Linux called for power-off?
+	 *	2. Is the comphy configured to PCIe?
+	 * If the answer is YES for both 1 and 2, skip the power-off.
+	 *
+	 * TODO: In MacciatoBIN, PCIe reset is connected via GPIO,
+	 * so after GPIO reset is added to Linux Kernel, it can be
+	 * powered-off.
+	 */
+	if (!called_from_uboot) {
+		data = mmio_read_32(comphy_base +
+				    COMMON_SELECTOR_PIPE_REG_OFFSET);
+		data >>= (COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index);
+		data &= COMMON_SELECTOR_COMPHY_MASK;
+		if (data == COMMON_SELECTOR_PIPE_COMPHY_PCIE)
+			return 0;
+	}
+
 	mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
 
 	if (rx_trainng_done[ap_nr][cp_nr][comphy_index]) {