Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Marvell 88SE94xx hardware specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright 2007 Red Hat, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright 2008 Marvell. <kewei@marvell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include "mv_sas.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include "mv_94xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include "mv_chips.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) static void mvs_94xx_detect_porttype(struct mvs_info *mvi, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) 	u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) 	struct mvs_phy *phy = &mvi->phy[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 	u32 phy_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 	mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 	reg = mvs_read_port_vsr_data(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 	phy_status = ((reg & 0x3f0000) >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 	phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 	switch (phy_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 	case 0x10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) 		phy->phy_type |= PORT_TYPE_SAS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 	case 0x1d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 		phy->phy_type |= PORT_TYPE_SATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) static void set_phy_tuning(struct mvs_info *mvi, int phy_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 			   struct phy_tuning phy_tuning)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	u32 tmp, setting_0 = 0, setting_1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	/* Remap information for B0 chip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	* R0Ch -> R118h[15:0] (Adapted DFE F3 - F5 coefficient)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	* R0Dh -> R118h[31:16] (Generation 1 Setting 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	* R0Eh -> R11Ch[15:0]  (Generation 1 Setting 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	* R0Fh -> R11Ch[31:16] (Generation 2 Setting 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	* R10h -> R120h[15:0]  (Generation 2 Setting 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	* R11h -> R120h[31:16] (Generation 3 Setting 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	* R12h -> R124h[15:0]  (Generation 3 Setting 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	* R13h -> R124h[31:16] (Generation 4 Setting 0 (Reserved))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	/* A0 has a different set of registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	if (mvi->pdev->revision == VANIR_A0_REV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 		/* loop 3 times, set Gen 1, Gen 2, Gen 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 		switch (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 		case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 			setting_0 = GENERATION_1_SETTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 			setting_1 = GENERATION_1_2_SETTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 		case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 			setting_0 = GENERATION_1_2_SETTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 			setting_1 = GENERATION_2_3_SETTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 		case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 			setting_0 = GENERATION_2_3_SETTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 			setting_1 = GENERATION_3_4_SETTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 		/* Set:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 		*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 		* Transmitter Emphasis Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 		* Transmitter Emphasis Amplitude
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 		* Transmitter Amplitude
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 		mvs_write_port_vsr_addr(mvi, phy_id, setting_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 		tmp = mvs_read_port_vsr_data(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 		tmp &= ~(0xFBE << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 		tmp |= (((phy_tuning.trans_emp_en << 11) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 			(phy_tuning.trans_emp_amp << 7) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 			(phy_tuning.trans_amp << 1)) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 		mvs_write_port_vsr_data(mvi, phy_id, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 		/* Set Transmitter Amplitude Adjust */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 		mvs_write_port_vsr_addr(mvi, phy_id, setting_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 		tmp = mvs_read_port_vsr_data(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 		tmp &= ~(0xC000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 		tmp |= (phy_tuning.trans_amp_adj << 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 		mvs_write_port_vsr_data(mvi, phy_id, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) static void set_phy_ffe_tuning(struct mvs_info *mvi, int phy_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 			       struct ffe_control ffe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	/* Don't run this if A0/B0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	if ((mvi->pdev->revision == VANIR_A0_REV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 		|| (mvi->pdev->revision == VANIR_B0_REV))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	/* FFE Resistor and Capacitor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	/* R10Ch DFE Resolution Control/Squelch and FFE Setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	 * FFE_FORCE            [7]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	 * FFE_RES_SEL          [6:4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	 * FFE_CAP_SEL          [3:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_FFE_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	tmp = mvs_read_port_vsr_data(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	tmp &= ~0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	/* Read from HBA_Info_Page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	tmp |= ((0x1 << 7) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 		(ffe.ffe_rss_sel << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 		(ffe.ffe_cap_sel << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	mvs_write_port_vsr_data(mvi, phy_id, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	/* R064h PHY Mode Register 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	 * DFE_DIS		18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	mvs_write_port_vsr_addr(mvi, phy_id, VSR_REF_CLOCK_CRTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	tmp = mvs_read_port_vsr_data(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	tmp &= ~0x40001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	/* Hard coding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	/* No defines in HBA_Info_Page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	tmp |= (0 << 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	mvs_write_port_vsr_data(mvi, phy_id, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	/* R110h DFE F0-F1 Coefficient Control/DFE Update Control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	 * DFE_UPDATE_EN        [11:6]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	 * DFE_FX_FORCE         [5:0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_DFE_UPDATE_CRTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	tmp = mvs_read_port_vsr_data(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	tmp &= ~0xFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	/* Hard coding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	/* No defines in HBA_Info_Page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	tmp |= ((0x3F << 6) | (0x0 << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	mvs_write_port_vsr_data(mvi, phy_id, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	/* R1A0h Interface and Digital Reference Clock Control/Reserved_50h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	 * FFE_TRAIN_EN         3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	mvs_write_port_vsr_addr(mvi, phy_id, VSR_REF_CLOCK_CRTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	tmp = mvs_read_port_vsr_data(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	tmp &= ~0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	/* Hard coding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	/* No defines in HBA_Info_Page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	tmp |= (0 << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	mvs_write_port_vsr_data(mvi, phy_id, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) /*Notice: this function must be called when phy is disabled*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) static void set_phy_rate(struct mvs_info *mvi, int phy_id, u8 rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	union reg_phy_cfg phy_cfg, phy_cfg_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	phy_cfg_tmp.v = mvs_read_port_vsr_data(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	phy_cfg.v = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	phy_cfg.u.disable_phy = phy_cfg_tmp.u.disable_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	phy_cfg.u.sas_support = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	phy_cfg.u.sata_support = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	phy_cfg.u.sata_host_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	switch (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	case 0x0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 		/* support 1.5 Gbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 		phy_cfg.u.speed_support = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 		phy_cfg.u.snw_3_support = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 		phy_cfg.u.tx_lnk_parity = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		phy_cfg.u.tx_spt_phs_lnk_rate = 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	case 0x1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		/* support 1.5, 3.0 Gbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		phy_cfg.u.speed_support = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 		phy_cfg.u.tx_spt_phs_lnk_rate = 0x3c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		phy_cfg.u.tx_lgcl_lnk_rate = 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	case 0x2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		/* support 1.5, 3.0, 6.0 Gbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		phy_cfg.u.speed_support = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		phy_cfg.u.snw_3_support = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 		phy_cfg.u.tx_lnk_parity = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		phy_cfg.u.tx_spt_phs_lnk_rate = 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		phy_cfg.u.tx_lgcl_lnk_rate = 0x09;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	mvs_write_port_vsr_data(mvi, phy_id, phy_cfg.v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) static void mvs_94xx_config_reg_from_hba(struct mvs_info *mvi, int phy_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	u32 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	temp = (u32)(*(u32 *)&mvi->hba_info_param.phy_tuning[phy_id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	if (temp == 0xFFFFFFFFL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 		mvi->hba_info_param.phy_tuning[phy_id].trans_emp_amp = 0x6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 		mvi->hba_info_param.phy_tuning[phy_id].trans_amp = 0x1A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		mvi->hba_info_param.phy_tuning[phy_id].trans_amp_adj = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	temp = (u8)(*(u8 *)&mvi->hba_info_param.ffe_ctl[phy_id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	if (temp == 0xFFL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 		switch (mvi->pdev->revision) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 		case VANIR_A0_REV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 		case VANIR_B0_REV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 			mvi->hba_info_param.ffe_ctl[phy_id].ffe_rss_sel = 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 			mvi->hba_info_param.ffe_ctl[phy_id].ffe_cap_sel = 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		case VANIR_C0_REV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 		case VANIR_C1_REV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		case VANIR_C2_REV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 			mvi->hba_info_param.ffe_ctl[phy_id].ffe_rss_sel = 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 			mvi->hba_info_param.ffe_ctl[phy_id].ffe_cap_sel = 0xC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	temp = (u8)(*(u8 *)&mvi->hba_info_param.phy_rate[phy_id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	if (temp == 0xFFL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 		/*set default phy_rate = 6Gbps*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		mvi->hba_info_param.phy_rate[phy_id] = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	set_phy_tuning(mvi, phy_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		mvi->hba_info_param.phy_tuning[phy_id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	set_phy_ffe_tuning(mvi, phy_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		mvi->hba_info_param.ffe_ctl[phy_id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	set_phy_rate(mvi, phy_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		mvi->hba_info_param.phy_rate[phy_id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) static void mvs_94xx_enable_xmt(struct mvs_info *mvi, int phy_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	void __iomem *regs = mvi->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	tmp = mr32(MVS_PCS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	tmp |= 1 << (phy_id + PCS_EN_PORT_XMT_SHIFT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	mw32(MVS_PCS, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) static void mvs_94xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	u32 delay = 5000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	if (hard == MVS_PHY_TUNE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		mvs_write_port_cfg_addr(mvi, phy_id, PHYR_SATA_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 		tmp = mvs_read_port_cfg_data(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		mvs_write_port_cfg_data(mvi, phy_id, tmp|0x20000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		mvs_write_port_cfg_data(mvi, phy_id, tmp|0x100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	tmp = mvs_read_port_irq_stat(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	tmp &= ~PHYEV_RDY_CH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	mvs_write_port_irq_stat(mvi, phy_id, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	if (hard) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		tmp = mvs_read_phy_ctl(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		tmp |= PHY_RST_HARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 		mvs_write_phy_ctl(mvi, phy_id, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 			tmp = mvs_read_phy_ctl(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 			udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 			delay--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 		} while ((tmp & PHY_RST_HARD) && delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		if (!delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 			mv_dprintk("phy hard reset failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 		tmp = mvs_read_phy_ctl(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		tmp |= PHY_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		mvs_write_phy_ctl(mvi, phy_id, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) static void mvs_94xx_phy_disable(struct mvs_info *mvi, u32 phy_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	tmp = mvs_read_port_vsr_data(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	mvs_write_port_vsr_data(mvi, phy_id, tmp | 0x00800000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) static void mvs_94xx_phy_enable(struct mvs_info *mvi, u32 phy_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	u8 revision = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	revision = mvi->pdev->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	if (revision == VANIR_A0_REV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		mvs_write_port_vsr_addr(mvi, phy_id, CMD_HOST_RD_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		mvs_write_port_vsr_data(mvi, phy_id, 0x8300ffc1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	if (revision == VANIR_B0_REV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 		mvs_write_port_vsr_addr(mvi, phy_id, CMD_APP_MEM_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		mvs_write_port_vsr_data(mvi, phy_id, 0x08001006);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		mvs_write_port_vsr_addr(mvi, phy_id, CMD_HOST_RD_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 		mvs_write_port_vsr_data(mvi, phy_id, 0x0000705f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	tmp = mvs_read_port_vsr_data(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	tmp |= bit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	mvs_write_port_vsr_data(mvi, phy_id, tmp & 0xfd7fffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) static void mvs_94xx_sgpio_init(struct mvs_info *mvi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	void __iomem *regs = mvi->regs_ex - 0x10200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	tmp = mr32(MVS_HST_CHIP_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	tmp |= 0x100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	mw32(MVS_HST_CHIP_CONFIG, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	mw32(MVS_SGPIO_CTRL + MVS_SGPIO_HOST_OFFSET * mvi->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		MVS_SGPIO_CTRL_SDOUT_AUTO << MVS_SGPIO_CTRL_SDOUT_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	mw32(MVS_SGPIO_CFG1 + MVS_SGPIO_HOST_OFFSET * mvi->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		8 << MVS_SGPIO_CFG1_LOWA_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		8 << MVS_SGPIO_CFG1_HIA_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		4 << MVS_SGPIO_CFG1_LOWB_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 		4 << MVS_SGPIO_CFG1_HIB_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		2 << MVS_SGPIO_CFG1_MAXACTON_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		1 << MVS_SGPIO_CFG1_FORCEACTOFF_SHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	mw32(MVS_SGPIO_CFG2 + MVS_SGPIO_HOST_OFFSET * mvi->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		(300000 / 100) << MVS_SGPIO_CFG2_CLK_SHIFT | /* 100kHz clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		66 << MVS_SGPIO_CFG2_BLINK_SHIFT /* (66 * 0,121 Hz?)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	mw32(MVS_SGPIO_CFG0 + MVS_SGPIO_HOST_OFFSET * mvi->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 		MVS_SGPIO_CFG0_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		MVS_SGPIO_CFG0_BLINKA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		MVS_SGPIO_CFG0_BLINKB |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		/* 3*4 data bits / PDU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		(12 - 1) << MVS_SGPIO_CFG0_AUT_BITLEN_SHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		DEFAULT_SGPIO_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	mw32(MVS_SGPIO_DSRC + MVS_SGPIO_HOST_OFFSET * mvi->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 		((mvi->id * 4) + 3) << (8 * 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 		((mvi->id * 4) + 2) << (8 * 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		((mvi->id * 4) + 1) << (8 * 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		((mvi->id * 4) + 0) << (8 * 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) static int mvs_94xx_init(struct mvs_info *mvi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	void __iomem *regs = mvi->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	u32 tmp, cctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	u8 revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	revision = mvi->pdev->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	mvs_show_pcie_usage(mvi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	if (mvi->flags & MVF_FLAG_SOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		tmp = mr32(MVS_PHY_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 		tmp &= ~PCTL_PWR_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		tmp |= PCTL_PHY_DSBL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		mw32(MVS_PHY_CTL, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	/* Init Chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	/* make sure RST is set; HBA_RST /should/ have done that for us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	cctl = mr32(MVS_CTL) & 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	if (cctl & CCTL_RST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		cctl &= ~CCTL_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 		mw32_f(MVS_CTL, cctl | CCTL_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	if (mvi->flags & MVF_FLAG_SOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		tmp = mr32(MVS_PHY_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		tmp &= ~PCTL_PWR_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		tmp |= PCTL_COM_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		tmp &= ~PCTL_PHY_DSBL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		tmp |= PCTL_LINK_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		mw32(MVS_PHY_CTL, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		tmp &= ~PCTL_LINK_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		mw32(MVS_PHY_CTL, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	/* disable Multiplexing, enable phy implemented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	mw32(MVS_PORTS_IMP, 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	if (revision == VANIR_A0_REV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		mw32(MVS_PA_VSR_ADDR, CMD_CMWK_OOB_DET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		mw32(MVS_PA_VSR_PORT, 0x00018080);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	mw32(MVS_PA_VSR_ADDR, VSR_PHY_MODE2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	if (revision == VANIR_A0_REV || revision == VANIR_B0_REV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		/* set 6G/3G/1.5G, multiplexing, without SSC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		mw32(MVS_PA_VSR_PORT, 0x0084d4fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		/* set 6G/3G/1.5G, multiplexing, with and without SSC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 		mw32(MVS_PA_VSR_PORT, 0x0084fffe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	if (revision == VANIR_B0_REV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		mw32(MVS_PA_VSR_ADDR, CMD_APP_MEM_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		mw32(MVS_PA_VSR_PORT, 0x08001006);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 		mw32(MVS_PA_VSR_ADDR, CMD_HOST_RD_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		mw32(MVS_PA_VSR_PORT, 0x0000705f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	/* reset control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	mw32(MVS_PCS, 0);		/* MVS_PCS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	mw32(MVS_STP_REG_SET_0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	mw32(MVS_STP_REG_SET_1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	/* init phys */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	mvs_phy_hacks(mvi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	/* disable non data frame retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	tmp = mvs_cr32(mvi, CMD_SAS_CTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	if ((revision == VANIR_A0_REV) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 		(revision == VANIR_B0_REV) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		(revision == VANIR_C0_REV)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		tmp &= ~0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		tmp |= 0x007f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		mvs_cw32(mvi, CMD_SAS_CTL1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	/* set LED blink when IO*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	mw32(MVS_PA_VSR_ADDR, VSR_PHY_ACT_LED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	tmp = mr32(MVS_PA_VSR_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	tmp &= 0xFFFF00FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	tmp |= 0x00003300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	mw32(MVS_PA_VSR_PORT, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	mw32(MVS_CMD_LIST_LO, mvi->slot_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	mw32(MVS_CMD_LIST_HI, (mvi->slot_dma >> 16) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	mw32(MVS_RX_FIS_LO, mvi->rx_fis_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	mw32(MVS_RX_FIS_HI, (mvi->rx_fis_dma >> 16) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	mw32(MVS_TX_CFG, MVS_CHIP_SLOT_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	mw32(MVS_TX_LO, mvi->tx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	mw32(MVS_TX_HI, (mvi->tx_dma >> 16) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	mw32(MVS_RX_CFG, MVS_RX_RING_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	mw32(MVS_RX_LO, mvi->rx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	mw32(MVS_RX_HI, (mvi->rx_dma >> 16) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	for (i = 0; i < mvi->chip->n_phy; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		mvs_94xx_phy_disable(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		/* set phy local SAS address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		mvs_set_sas_addr(mvi, i, CONFIG_ID_FRAME3, CONFIG_ID_FRAME4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 						cpu_to_le64(mvi->phy[i].dev_sas_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		mvs_94xx_enable_xmt(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		mvs_94xx_config_reg_from_hba(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		mvs_94xx_phy_enable(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		mvs_94xx_phy_reset(mvi, i, PHY_RST_HARD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		msleep(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		mvs_94xx_detect_porttype(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	if (mvi->flags & MVF_FLAG_SOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		/* set select registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		writel(0x0E008000, regs + 0x000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		writel(0x59000008, regs + 0x004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		writel(0x20, regs + 0x008);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		writel(0x20, regs + 0x00c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		writel(0x20, regs + 0x010);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		writel(0x20, regs + 0x014);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		writel(0x20, regs + 0x018);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		writel(0x20, regs + 0x01c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	for (i = 0; i < mvi->chip->n_phy; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		/* clear phy int status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		tmp = mvs_read_port_irq_stat(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		tmp &= ~PHYEV_SIG_FIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 		mvs_write_port_irq_stat(mvi, i, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		/* set phy int mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		tmp = PHYEV_RDY_CH | PHYEV_BROAD_CH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 			PHYEV_ID_DONE  | PHYEV_DCDR_ERR | PHYEV_CRC_ERR ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		mvs_write_port_irq_mask(mvi, i, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 		mvs_update_phyinfo(mvi, i, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	/* little endian for open address and command table, etc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	cctl = mr32(MVS_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	cctl |= CCTL_ENDIAN_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	cctl &= ~CCTL_ENDIAN_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	cctl |= CCTL_ENDIAN_RSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	mw32_f(MVS_CTL, cctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	/* reset CMD queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	tmp = mr32(MVS_PCS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	tmp |= PCS_CMD_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	tmp &= ~PCS_SELF_CLEAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	mw32(MVS_PCS, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	 * the max count is 0x1ff, while our max slot is 0x200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	 * it will make count 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	if (MVS_CHIP_SLOT_SZ > 0x1ff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		mw32(MVS_INT_COAL, 0x1ff | COAL_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ | COAL_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	/* default interrupt coalescing time is 128us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	tmp = 0x10000 | interrupt_coalescing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	mw32(MVS_INT_COAL_TMOUT, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	/* ladies and gentlemen, start your engines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	mw32(MVS_TX_CFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	mw32(MVS_TX_CFG, MVS_CHIP_SLOT_SZ | TX_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	mw32(MVS_RX_CFG, MVS_RX_RING_SZ | RX_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	/* enable CMD/CMPL_Q/RESP mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	mw32(MVS_PCS, PCS_SATA_RETRY_2 | PCS_FIS_RX_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		PCS_CMD_EN | PCS_CMD_STOP_ERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	/* enable completion queue interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS | CINT_CI_STOP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		CINT_DMA_PCIE | CINT_NON_SPEC_NCQ_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	tmp |= CINT_PHY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	mw32(MVS_INT_MASK, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	tmp = mvs_cr32(mvi, CMD_LINK_TIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	tmp |= 0xFFFF0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	mvs_cw32(mvi, CMD_LINK_TIMER, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	/* tune STP performance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	tmp = 0x003F003F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	mvs_cw32(mvi, CMD_PL_TIMER, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	/* This can improve expander large block size seq write performance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	tmp = mvs_cr32(mvi, CMD_PORT_LAYER_TIMER1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	tmp |= 0xFFFF007F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	mvs_cw32(mvi, CMD_PORT_LAYER_TIMER1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	/* change the connection open-close behavior (bit 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	 * set bit8 to 1 for performance tuning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	tmp = mvs_cr32(mvi, CMD_SL_MODE0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	tmp |= 0x00000300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	/* set bit0 to 0 to enable retry for no_dest reject case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	tmp &= 0xFFFFFFFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	mvs_cw32(mvi, CMD_SL_MODE0, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	/* Enable SRS interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	mw32(MVS_INT_MASK_SRS_0, 0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	mvs_94xx_sgpio_init(mvi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) static int mvs_94xx_ioremap(struct mvs_info *mvi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	if (!mvs_ioremap(mvi, 2, -1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		mvi->regs_ex = mvi->regs + 0x10200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		mvi->regs += 0x20000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		if (mvi->id == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 			mvi->regs += 0x4000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) static void mvs_94xx_iounmap(struct mvs_info *mvi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	if (mvi->regs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 		mvi->regs -= 0x20000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		if (mvi->id == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 			mvi->regs -= 0x4000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		mvs_iounmap(mvi->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) static void mvs_94xx_interrupt_enable(struct mvs_info *mvi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	void __iomem *regs = mvi->regs_ex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	tmp = mr32(MVS_GBL_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	tmp |= (MVS_IRQ_SAS_A | MVS_IRQ_SAS_B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	mw32(MVS_GBL_INT_STAT, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	writel(tmp, regs + 0x0C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	writel(tmp, regs + 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	writel(tmp, regs + 0x14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	writel(tmp, regs + 0x18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	mw32(MVS_GBL_CTL, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) static void mvs_94xx_interrupt_disable(struct mvs_info *mvi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	void __iomem *regs = mvi->regs_ex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	tmp = mr32(MVS_GBL_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	tmp &= ~(MVS_IRQ_SAS_A | MVS_IRQ_SAS_B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	mw32(MVS_GBL_INT_STAT, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	writel(tmp, regs + 0x0C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	writel(tmp, regs + 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	writel(tmp, regs + 0x14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	writel(tmp, regs + 0x18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	mw32(MVS_GBL_CTL, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) static u32 mvs_94xx_isr_status(struct mvs_info *mvi, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	void __iomem *regs = mvi->regs_ex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	u32 stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	if (!(mvi->flags & MVF_FLAG_SOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		stat = mr32(MVS_GBL_INT_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 		if (!(stat & (MVS_IRQ_SAS_A | MVS_IRQ_SAS_B)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) static irqreturn_t mvs_94xx_isr(struct mvs_info *mvi, int irq, u32 stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	void __iomem *regs = mvi->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	if (((stat & MVS_IRQ_SAS_A) && mvi->id == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 			((stat & MVS_IRQ_SAS_B) && mvi->id == 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		mw32_f(MVS_INT_STAT, CINT_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		spin_lock(&mvi->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		mvs_int_full(mvi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		spin_unlock(&mvi->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) static void mvs_94xx_command_active(struct mvs_info *mvi, u32 slot_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	tmp = mvs_cr32(mvi, MVS_COMMAND_ACTIVE+(slot_idx >> 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	if (tmp & 1 << (slot_idx % 32)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		mv_printk("command active %08X,  slot [%x].\n", tmp, slot_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		mvs_cw32(mvi, MVS_COMMAND_ACTIVE + (slot_idx >> 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			1 << (slot_idx % 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 			tmp = mvs_cr32(mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 				MVS_COMMAND_ACTIVE + (slot_idx >> 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		} while (tmp & 1 << (slot_idx % 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) mvs_94xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set, u8 clear_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	void __iomem *regs = mvi->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	if (clear_all) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		tmp = mr32(MVS_INT_STAT_SRS_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		if (tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 			mv_dprintk("check SRS 0 %08X.\n", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 			mw32(MVS_INT_STAT_SRS_0, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		tmp = mr32(MVS_INT_STAT_SRS_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		if (tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 			mv_dprintk("check SRS 1 %08X.\n", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 			mw32(MVS_INT_STAT_SRS_1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 		if (reg_set > 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 			tmp = mr32(MVS_INT_STAT_SRS_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 			tmp = mr32(MVS_INT_STAT_SRS_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		if (tmp & (1 << (reg_set % 32))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 			mv_dprintk("register set 0x%x was stopped.\n", reg_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 			if (reg_set > 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 				mw32(MVS_INT_STAT_SRS_1, 1 << (reg_set % 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 				mw32(MVS_INT_STAT_SRS_0, 1 << (reg_set % 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) static void mvs_94xx_issue_stop(struct mvs_info *mvi, enum mvs_port_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 				u32 tfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	void __iomem *regs = mvi->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	mvs_94xx_clear_srs_irq(mvi, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	tmp = mr32(MVS_INT_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	mw32(MVS_INT_STAT, tmp | CINT_CI_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	tmp = mr32(MVS_PCS) | 0xFF00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	mw32(MVS_PCS, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) static void mvs_94xx_non_spec_ncq_error(struct mvs_info *mvi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	void __iomem *regs = mvi->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	u32 err_0, err_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	struct mvs_device *device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	err_0 = mr32(MVS_NON_NCQ_ERR_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	err_1 = mr32(MVS_NON_NCQ_ERR_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	mv_dprintk("non specific ncq error err_0:%x,err_1:%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 			err_0, err_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	for (i = 0; i < 32; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		if (err_0 & bit(i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 			device = mvs_find_dev_by_reg_set(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 			if (device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 				mvs_release_task(mvi, device->sas_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		if (err_1 & bit(i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 			device = mvs_find_dev_by_reg_set(mvi, i+32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			if (device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 				mvs_release_task(mvi, device->sas_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	mw32(MVS_NON_NCQ_ERR_0, err_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	mw32(MVS_NON_NCQ_ERR_1, err_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) static void mvs_94xx_free_reg_set(struct mvs_info *mvi, u8 *tfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	void __iomem *regs = mvi->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	u8 reg_set = *tfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	if (*tfs == MVS_ID_NOT_MAPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	mvi->sata_reg_set &= ~bit(reg_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	if (reg_set < 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		w_reg_set_enable(reg_set, (u32)mvi->sata_reg_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		w_reg_set_enable(reg_set, (u32)(mvi->sata_reg_set >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	*tfs = MVS_ID_NOT_MAPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) static u8 mvs_94xx_assign_reg_set(struct mvs_info *mvi, u8 *tfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	void __iomem *regs = mvi->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	if (*tfs != MVS_ID_NOT_MAPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	i = mv_ffc64(mvi->sata_reg_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	if (i >= 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		mvi->sata_reg_set |= bit(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		w_reg_set_enable(i, (u32)(mvi->sata_reg_set >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		*tfs = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	} else if (i >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		mvi->sata_reg_set |= bit(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		w_reg_set_enable(i, (u32)mvi->sata_reg_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		*tfs = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	return MVS_ID_NOT_MAPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) static void mvs_94xx_make_prd(struct scatterlist *scatter, int nr, void *prd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	struct mvs_prd *buf_prd = prd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	struct mvs_prd_imt im_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	*(u32 *)&im_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	for_each_sg(scatter, sg, nr, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		buf_prd->addr = cpu_to_le64(sg_dma_address(sg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		im_len.len = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		buf_prd->im_len = cpu_to_le32(*(u32 *)&im_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		buf_prd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) static int mvs_94xx_oob_done(struct mvs_info *mvi, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	u32 phy_st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	phy_st = mvs_read_phy_ctl(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	if (phy_st & PHY_READY_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) static void mvs_94xx_get_dev_identify_frame(struct mvs_info *mvi, int port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 					struct sas_identify_frame *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	u32 id_frame[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	for (i = 0; i < 7; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		mvs_write_port_cfg_addr(mvi, port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 					CONFIG_ID_FRAME0 + i * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		id_frame[i] = cpu_to_le32(mvs_read_port_cfg_data(mvi, port_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	memcpy(id, id_frame, 28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) static void mvs_94xx_get_att_identify_frame(struct mvs_info *mvi, int port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 					struct sas_identify_frame *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	u32 id_frame[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	for (i = 0; i < 7; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		mvs_write_port_cfg_addr(mvi, port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 					CONFIG_ATT_ID_FRAME0 + i * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		id_frame[i] = cpu_to_le32(mvs_read_port_cfg_data(mvi, port_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		mv_dprintk("94xx phy %d atta frame %d %x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 			port_id + mvi->id * mvi->chip->n_phy, i, id_frame[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	memcpy(id, id_frame, 28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) static u32 mvs_94xx_make_dev_info(struct sas_identify_frame *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	u32 att_dev_info = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	att_dev_info |= id->dev_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	if (id->stp_iport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		att_dev_info |= PORT_DEV_STP_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	if (id->smp_iport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		att_dev_info |= PORT_DEV_SMP_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	if (id->ssp_iport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		att_dev_info |= PORT_DEV_SSP_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	if (id->stp_tport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		att_dev_info |= PORT_DEV_STP_TRGT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	if (id->smp_tport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		att_dev_info |= PORT_DEV_SMP_TRGT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	if (id->ssp_tport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		att_dev_info |= PORT_DEV_SSP_TRGT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	att_dev_info |= (u32)id->phy_id<<24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	return att_dev_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) static u32 mvs_94xx_make_att_info(struct sas_identify_frame *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	return mvs_94xx_make_dev_info(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) static void mvs_94xx_fix_phy_info(struct mvs_info *mvi, int i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 				struct sas_identify_frame *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	struct mvs_phy *phy = &mvi->phy[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	struct asd_sas_phy *sas_phy = &phy->sas_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	mv_dprintk("get all reg link rate is 0x%x\n", phy->phy_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	sas_phy->linkrate =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		(phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 			PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	sas_phy->linkrate += 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	mv_dprintk("get link rate is %d\n", sas_phy->linkrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	phy->maximum_linkrate = SAS_LINK_RATE_6_0_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	mvs_94xx_get_dev_identify_frame(mvi, i, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	phy->dev_info = mvs_94xx_make_dev_info(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	if (phy->phy_type & PORT_TYPE_SAS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		mvs_94xx_get_att_identify_frame(mvi, i, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		phy->att_dev_info = mvs_94xx_make_att_info(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		phy->att_dev_sas_addr = *(u64 *)id->sas_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		phy->att_dev_info = PORT_DEV_STP_TRGT | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	/* enable spin up bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	mvs_write_port_cfg_addr(mvi, i, PHYR_PHY_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	mvs_write_port_cfg_data(mvi, i, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) static void mvs_94xx_phy_set_link_rate(struct mvs_info *mvi, u32 phy_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 				       struct sas_phy_linkrates *rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	u32 lrmax = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	tmp = mvs_read_phy_ctl(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	lrmax = (rates->maximum_linkrate - SAS_LINK_RATE_1_5_GBPS) << 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	if (lrmax) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		tmp &= ~(0x3 << 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		tmp |= lrmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	mvs_write_phy_ctl(mvi, phy_id, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	mvs_94xx_phy_reset(mvi, phy_id, PHY_RST_HARD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) static void mvs_94xx_clear_active_cmds(struct mvs_info *mvi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	void __iomem *regs = mvi->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	tmp = mr32(MVS_STP_REG_SET_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	mw32(MVS_STP_REG_SET_0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	mw32(MVS_STP_REG_SET_0, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	tmp = mr32(MVS_STP_REG_SET_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	mw32(MVS_STP_REG_SET_1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	mw32(MVS_STP_REG_SET_1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) static u32 mvs_94xx_spi_read_data(struct mvs_info *mvi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	void __iomem *regs = mvi->regs_ex - 0x10200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	return mr32(SPI_RD_DATA_REG_94XX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) static void mvs_94xx_spi_write_data(struct mvs_info *mvi, u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	void __iomem *regs = mvi->regs_ex - 0x10200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	mw32(SPI_RD_DATA_REG_94XX, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) static int mvs_94xx_spi_buildcmd(struct mvs_info *mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 				 u32      *dwCmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 				 u8       cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 				 u8       read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 				 u8       length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 				 u32      addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 				)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	void __iomem *regs = mvi->regs_ex - 0x10200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	u32  dwTmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	dwTmp = ((u32)cmd << 8) | ((u32)length << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	if (read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		dwTmp |= SPI_CTRL_READ_94XX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	if (addr != MV_MAX_U32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		mw32(SPI_ADDR_REG_94XX, (addr & 0x0003FFFFL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		dwTmp |= SPI_ADDR_VLD_94XX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	*dwCmd = dwTmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) static int mvs_94xx_spi_issuecmd(struct mvs_info *mvi, u32 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	void __iomem *regs = mvi->regs_ex - 0x10200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	mw32(SPI_CTRL_REG_94XX, cmd | SPI_CTRL_SpiStart_94XX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) static int mvs_94xx_spi_waitdataready(struct mvs_info *mvi, u32 timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	void __iomem *regs = mvi->regs_ex - 0x10200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	u32   i, dwTmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	for (i = 0; i < timeout; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		dwTmp = mr32(SPI_CTRL_REG_94XX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		if (!(dwTmp & SPI_CTRL_SpiStart_94XX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) static void mvs_94xx_fix_dma(struct mvs_info *mvi, u32 phy_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 			     int buf_len, int from, void *prd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	struct mvs_prd *buf_prd = prd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	dma_addr_t buf_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	struct mvs_prd_imt im_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	*(u32 *)&im_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	buf_prd += from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) #define PRD_CHAINED_ENTRY 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	if ((mvi->pdev->revision == VANIR_A0_REV) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 			(mvi->pdev->revision == VANIR_B0_REV))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		buf_dma = (phy_mask <= 0x08) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 				mvi->bulk_buffer_dma : mvi->bulk_buffer_dma1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	for (i = from; i < MAX_SG_ENTRY; i++, ++buf_prd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		if (i == MAX_SG_ENTRY - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 			buf_prd->addr = cpu_to_le64(virt_to_phys(buf_prd - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 			im_len.len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 			im_len.misc_ctl = PRD_CHAINED_ENTRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 			buf_prd->addr = cpu_to_le64(buf_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 			im_len.len = buf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		buf_prd->im_len = cpu_to_le32(*(u32 *)&im_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) static void mvs_94xx_tune_interrupt(struct mvs_info *mvi, u32 time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	void __iomem *regs = mvi->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	u32 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	 * the max count is 0x1ff, while our max slot is 0x200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	 * it will make count 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	if (time == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		mw32(MVS_INT_COAL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		mw32(MVS_INT_COAL_TMOUT, 0x10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		if (MVS_CHIP_SLOT_SZ > 0x1ff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 			mw32(MVS_INT_COAL, 0x1ff|COAL_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 			mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ|COAL_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		tmp = 0x10000 | time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		mw32(MVS_INT_COAL_TMOUT, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) static int mvs_94xx_gpio_write(struct mvs_prv_info *mvs_prv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 			u8 reg_type, u8 reg_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 			u8 reg_count, u8 *write_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	switch (reg_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	case SAS_GPIO_REG_TX_GP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		if (reg_index == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		if (reg_count > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		if (reg_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		/* maximum supported bits = hosts * 4 drives * 3 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		for (i = 0; i < mvs_prv->n_host * 4 * 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 			/* select host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 			struct mvs_info *mvi = mvs_prv->mvi[i/(4*3)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 			void __iomem *regs = mvi->regs_ex - 0x10200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 			int drive = (i/3) & (4-1); /* drive number on host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 			int driveshift = drive * 8; /* bit offset of drive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 			u32 block = ioread32be(regs + MVS_SGPIO_DCTRL +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 				MVS_SGPIO_HOST_OFFSET * mvi->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 			* if bit is set then create a mask with the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			* bit of the drive set in the mask ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 			*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 			u32 bit = get_unaligned_be32(write_data) & (1 << i) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 				1 << driveshift : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 			* ... and then shift it to the right position based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			* on the led type (activity/id/fail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 			*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			switch (i%3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 			case 0: /* activity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 				block &= ~((0x7 << MVS_SGPIO_DCTRL_ACT_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 					<< driveshift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 					/* hardwire activity bit to SOF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 				block |= LED_BLINKA_SOF << (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 					MVS_SGPIO_DCTRL_ACT_SHIFT +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 					driveshift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 			case 1: /* id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 				block &= ~((0x3 << MVS_SGPIO_DCTRL_LOC_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 					<< driveshift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 				block |= bit << MVS_SGPIO_DCTRL_LOC_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 			case 2: /* fail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 				block &= ~((0x7 << MVS_SGPIO_DCTRL_ERR_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 					<< driveshift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 				block |= bit << MVS_SGPIO_DCTRL_ERR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 			iowrite32be(block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 				regs + MVS_SGPIO_DCTRL +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 				MVS_SGPIO_HOST_OFFSET * mvi->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		return reg_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	case SAS_GPIO_REG_TX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		if (reg_index + reg_count > mvs_prv->n_host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		for (i = 0; i < reg_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 			struct mvs_info *mvi = mvs_prv->mvi[i+reg_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 			void __iomem *regs = mvi->regs_ex - 0x10200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 			mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 				((u32 *) write_data)[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		return reg_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) const struct mvs_dispatch mvs_94xx_dispatch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	"mv94xx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	mvs_94xx_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	mvs_94xx_ioremap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	mvs_94xx_iounmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	mvs_94xx_isr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	mvs_94xx_isr_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	mvs_94xx_interrupt_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	mvs_94xx_interrupt_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	mvs_read_phy_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	mvs_write_phy_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	mvs_read_port_cfg_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	mvs_write_port_cfg_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	mvs_write_port_cfg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	mvs_read_port_vsr_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	mvs_write_port_vsr_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	mvs_write_port_vsr_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	mvs_read_port_irq_stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	mvs_write_port_irq_stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	mvs_read_port_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	mvs_write_port_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	mvs_94xx_command_active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	mvs_94xx_clear_srs_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	mvs_94xx_issue_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	mvs_start_delivery,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	mvs_rx_update,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	mvs_int_full,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	mvs_94xx_assign_reg_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	mvs_94xx_free_reg_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	mvs_get_prd_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	mvs_get_prd_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	mvs_94xx_make_prd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	mvs_94xx_detect_porttype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	mvs_94xx_oob_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	mvs_94xx_fix_phy_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	mvs_94xx_phy_set_link_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	mvs_hw_max_link_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	mvs_94xx_phy_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	mvs_94xx_phy_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	mvs_94xx_phy_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	mvs_94xx_clear_active_cmds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	mvs_94xx_spi_read_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	mvs_94xx_spi_write_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	mvs_94xx_spi_buildcmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	mvs_94xx_spi_issuecmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	mvs_94xx_spi_waitdataready,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	mvs_94xx_fix_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	mvs_94xx_tune_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	mvs_94xx_non_spec_ncq_error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	mvs_94xx_gpio_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)