brintos

brintos / linux-shallow public Read only

0
0
Text · 18.6 KiB · 1f2b61d Raw
815 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Marvell 88SE64xx hardware specific4 *5 * Copyright 2007 Red Hat, Inc.6 * Copyright 2008 Marvell. <kewei@marvell.com>7 * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>8*/9 10#include "mv_sas.h"11#include "mv_64xx.h"12#include "mv_chips.h"13 14static void mvs_64xx_detect_porttype(struct mvs_info *mvi, int i)15{16	void __iomem *regs = mvi->regs;17	u32 reg;18	struct mvs_phy *phy = &mvi->phy[i];19 20	reg = mr32(MVS_GBL_PORT_TYPE);21	phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);22	if (reg & MODE_SAS_SATA & (1 << i))23		phy->phy_type |= PORT_TYPE_SAS;24	else25		phy->phy_type |= PORT_TYPE_SATA;26}27 28static void mvs_64xx_enable_xmt(struct mvs_info *mvi, int phy_id)29{30	void __iomem *regs = mvi->regs;31	u32 tmp;32 33	tmp = mr32(MVS_PCS);34	if (mvi->chip->n_phy <= MVS_SOC_PORTS)35		tmp |= 1 << (phy_id + PCS_EN_PORT_XMT_SHIFT);36	else37		tmp |= 1 << (phy_id + PCS_EN_PORT_XMT_SHIFT2);38	mw32(MVS_PCS, tmp);39}40 41static void mvs_64xx_phy_hacks(struct mvs_info *mvi)42{43	void __iomem *regs = mvi->regs;44	int i;45 46	mvs_phy_hacks(mvi);47 48	if (!(mvi->flags & MVF_FLAG_SOC)) {49		for (i = 0; i < MVS_SOC_PORTS; i++) {50			mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE8);51			mvs_write_port_vsr_data(mvi, i, 0x2F0);52		}53	} else {54		/* disable auto port detection */55		mw32(MVS_GBL_PORT_TYPE, 0);56		for (i = 0; i < mvi->chip->n_phy; i++) {57			mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE7);58			mvs_write_port_vsr_data(mvi, i, 0x90000000);59			mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE9);60			mvs_write_port_vsr_data(mvi, i, 0x50f2);61			mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE11);62			mvs_write_port_vsr_data(mvi, i, 0x0e);63		}64	}65}66 67static void mvs_64xx_stp_reset(struct mvs_info *mvi, u32 phy_id)68{69	void __iomem *regs = mvi->regs;70	u32 reg, tmp;71 72	if (!(mvi->flags & MVF_FLAG_SOC)) {73		if (phy_id < MVS_SOC_PORTS)74			pci_read_config_dword(mvi->pdev, PCR_PHY_CTL, &reg);75		else76			pci_read_config_dword(mvi->pdev, PCR_PHY_CTL2, &reg);77 78	} else79		reg = mr32(MVS_PHY_CTL);80 81	tmp = reg;82	if (phy_id < MVS_SOC_PORTS)83		tmp |= (1U << phy_id) << PCTL_LINK_OFFS;84	else85		tmp |= (1U << (phy_id - MVS_SOC_PORTS)) << PCTL_LINK_OFFS;86 87	if (!(mvi->flags & MVF_FLAG_SOC)) {88		if (phy_id < MVS_SOC_PORTS) {89			pci_write_config_dword(mvi->pdev, PCR_PHY_CTL, tmp);90			mdelay(10);91			pci_write_config_dword(mvi->pdev, PCR_PHY_CTL, reg);92		} else {93			pci_write_config_dword(mvi->pdev, PCR_PHY_CTL2, tmp);94			mdelay(10);95			pci_write_config_dword(mvi->pdev, PCR_PHY_CTL2, reg);96		}97	} else {98		mw32(MVS_PHY_CTL, tmp);99		mdelay(10);100		mw32(MVS_PHY_CTL, reg);101	}102}103 104static void mvs_64xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard)105{106	u32 tmp;107	tmp = mvs_read_port_irq_stat(mvi, phy_id);108	tmp &= ~PHYEV_RDY_CH;109	mvs_write_port_irq_stat(mvi, phy_id, tmp);110	tmp = mvs_read_phy_ctl(mvi, phy_id);111	if (hard == MVS_HARD_RESET)112		tmp |= PHY_RST_HARD;113	else if (hard == MVS_SOFT_RESET)114		tmp |= PHY_RST;115	mvs_write_phy_ctl(mvi, phy_id, tmp);116	if (hard) {117		do {118			tmp = mvs_read_phy_ctl(mvi, phy_id);119		} while (tmp & PHY_RST_HARD);120	}121}122 123static void124mvs_64xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set, u8 clear_all)125{126	void __iomem *regs = mvi->regs;127	u32 tmp;128	if (clear_all) {129		tmp = mr32(MVS_INT_STAT_SRS_0);130		if (tmp) {131			printk(KERN_DEBUG "check SRS 0 %08X.\n", tmp);132			mw32(MVS_INT_STAT_SRS_0, tmp);133		}134	} else {135		tmp = mr32(MVS_INT_STAT_SRS_0);136		if (tmp &  (1 << (reg_set % 32))) {137			printk(KERN_DEBUG "register set 0x%x was stopped.\n",138			       reg_set);139			mw32(MVS_INT_STAT_SRS_0, 1 << (reg_set % 32));140		}141	}142}143 144static int mvs_64xx_chip_reset(struct mvs_info *mvi)145{146	void __iomem *regs = mvi->regs;147	u32 tmp;148	int i;149 150	/* make sure interrupts are masked immediately (paranoia) */151	mw32(MVS_GBL_CTL, 0);152	tmp = mr32(MVS_GBL_CTL);153 154	/* Reset Controller */155	if (!(tmp & HBA_RST)) {156		if (mvi->flags & MVF_PHY_PWR_FIX) {157			pci_read_config_dword(mvi->pdev, PCR_PHY_CTL, &tmp);158			tmp &= ~PCTL_PWR_OFF;159			tmp |= PCTL_PHY_DSBL;160			pci_write_config_dword(mvi->pdev, PCR_PHY_CTL, tmp);161 162			pci_read_config_dword(mvi->pdev, PCR_PHY_CTL2, &tmp);163			tmp &= ~PCTL_PWR_OFF;164			tmp |= PCTL_PHY_DSBL;165			pci_write_config_dword(mvi->pdev, PCR_PHY_CTL2, tmp);166		}167	}168 169	/* make sure interrupts are masked immediately (paranoia) */170	mw32(MVS_GBL_CTL, 0);171	tmp = mr32(MVS_GBL_CTL);172 173	/* Reset Controller */174	if (!(tmp & HBA_RST)) {175		/* global reset, incl. COMRESET/H_RESET_N (self-clearing) */176		mw32_f(MVS_GBL_CTL, HBA_RST);177	}178 179	/* wait for reset to finish; timeout is just a guess */180	i = 1000;181	while (i-- > 0) {182		msleep(10);183 184		if (!(mr32(MVS_GBL_CTL) & HBA_RST))185			break;186	}187	if (mr32(MVS_GBL_CTL) & HBA_RST) {188		dev_printk(KERN_ERR, mvi->dev, "HBA reset failed\n");189		return -EBUSY;190	}191	return 0;192}193 194static void mvs_64xx_phy_disable(struct mvs_info *mvi, u32 phy_id)195{196	void __iomem *regs = mvi->regs;197	u32 tmp;198	if (!(mvi->flags & MVF_FLAG_SOC)) {199		u32 offs;200		if (phy_id < 4)201			offs = PCR_PHY_CTL;202		else {203			offs = PCR_PHY_CTL2;204			phy_id -= 4;205		}206		pci_read_config_dword(mvi->pdev, offs, &tmp);207		tmp |= 1U << (PCTL_PHY_DSBL_OFFS + phy_id);208		pci_write_config_dword(mvi->pdev, offs, tmp);209	} else {210		tmp = mr32(MVS_PHY_CTL);211		tmp |= 1U << (PCTL_PHY_DSBL_OFFS + phy_id);212		mw32(MVS_PHY_CTL, tmp);213	}214}215 216static void mvs_64xx_phy_enable(struct mvs_info *mvi, u32 phy_id)217{218	void __iomem *regs = mvi->regs;219	u32 tmp;220	if (!(mvi->flags & MVF_FLAG_SOC)) {221		u32 offs;222		if (phy_id < 4)223			offs = PCR_PHY_CTL;224		else {225			offs = PCR_PHY_CTL2;226			phy_id -= 4;227		}228		pci_read_config_dword(mvi->pdev, offs, &tmp);229		tmp &= ~(1U << (PCTL_PHY_DSBL_OFFS + phy_id));230		pci_write_config_dword(mvi->pdev, offs, tmp);231	} else {232		tmp = mr32(MVS_PHY_CTL);233		tmp &= ~(1U << (PCTL_PHY_DSBL_OFFS + phy_id));234		mw32(MVS_PHY_CTL, tmp);235	}236}237 238static int mvs_64xx_init(struct mvs_info *mvi)239{240	void __iomem *regs = mvi->regs;241	int i;242	u32 tmp, cctl;243 244	if (mvi->pdev && mvi->pdev->revision == 0)245		mvi->flags |= MVF_PHY_PWR_FIX;246	if (!(mvi->flags & MVF_FLAG_SOC)) {247		mvs_show_pcie_usage(mvi);248		tmp = mvs_64xx_chip_reset(mvi);249		if (tmp)250			return tmp;251	} else {252		tmp = mr32(MVS_PHY_CTL);253		tmp &= ~PCTL_PWR_OFF;254		tmp |= PCTL_PHY_DSBL;255		mw32(MVS_PHY_CTL, tmp);256	}257 258	/* Init Chip */259	/* make sure RST is set; HBA_RST /should/ have done that for us */260	cctl = mr32(MVS_CTL) & 0xFFFF;261	if (cctl & CCTL_RST)262		cctl &= ~CCTL_RST;263	else264		mw32_f(MVS_CTL, cctl | CCTL_RST);265 266	if (!(mvi->flags & MVF_FLAG_SOC)) {267		/* write to device control _AND_ device status register */268		pci_read_config_dword(mvi->pdev, PCR_DEV_CTRL, &tmp);269		tmp &= ~PRD_REQ_MASK;270		tmp |= PRD_REQ_SIZE;271		pci_write_config_dword(mvi->pdev, PCR_DEV_CTRL, tmp);272 273		pci_read_config_dword(mvi->pdev, PCR_PHY_CTL, &tmp);274		tmp &= ~PCTL_PWR_OFF;275		tmp &= ~PCTL_PHY_DSBL;276		pci_write_config_dword(mvi->pdev, PCR_PHY_CTL, tmp);277 278		pci_read_config_dword(mvi->pdev, PCR_PHY_CTL2, &tmp);279		tmp &= PCTL_PWR_OFF;280		tmp &= ~PCTL_PHY_DSBL;281		pci_write_config_dword(mvi->pdev, PCR_PHY_CTL2, tmp);282	} else {283		tmp = mr32(MVS_PHY_CTL);284		tmp &= ~PCTL_PWR_OFF;285		tmp |= PCTL_COM_ON;286		tmp &= ~PCTL_PHY_DSBL;287		tmp |= PCTL_LINK_RST;288		mw32(MVS_PHY_CTL, tmp);289		msleep(100);290		tmp &= ~PCTL_LINK_RST;291		mw32(MVS_PHY_CTL, tmp);292		msleep(100);293	}294 295	/* reset control */296	mw32(MVS_PCS, 0);		/* MVS_PCS */297	/* init phys */298	mvs_64xx_phy_hacks(mvi);299 300	tmp = mvs_cr32(mvi, CMD_PHY_MODE_21);301	tmp &= 0x0000ffff;302	tmp |= 0x00fa0000;303	mvs_cw32(mvi, CMD_PHY_MODE_21, tmp);304 305	/* enable auto port detection */306	mw32(MVS_GBL_PORT_TYPE, MODE_AUTO_DET_EN);307 308	mw32(MVS_CMD_LIST_LO, mvi->slot_dma);309	mw32(MVS_CMD_LIST_HI, (mvi->slot_dma >> 16) >> 16);310 311	mw32(MVS_RX_FIS_LO, mvi->rx_fis_dma);312	mw32(MVS_RX_FIS_HI, (mvi->rx_fis_dma >> 16) >> 16);313 314	mw32(MVS_TX_CFG, MVS_CHIP_SLOT_SZ);315	mw32(MVS_TX_LO, mvi->tx_dma);316	mw32(MVS_TX_HI, (mvi->tx_dma >> 16) >> 16);317 318	mw32(MVS_RX_CFG, MVS_RX_RING_SZ);319	mw32(MVS_RX_LO, mvi->rx_dma);320	mw32(MVS_RX_HI, (mvi->rx_dma >> 16) >> 16);321 322	for (i = 0; i < mvi->chip->n_phy; i++) {323		/* set phy local SAS address */324		/* should set little endian SAS address to 64xx chip */325		mvs_set_sas_addr(mvi, i, PHYR_ADDR_LO, PHYR_ADDR_HI,326				cpu_to_be64(mvi->phy[i].dev_sas_addr));327 328		mvs_64xx_enable_xmt(mvi, i);329 330		mvs_64xx_phy_reset(mvi, i, MVS_HARD_RESET);331		msleep(500);332		mvs_64xx_detect_porttype(mvi, i);333	}334	if (mvi->flags & MVF_FLAG_SOC) {335		/* set select registers */336		writel(0x0E008000, regs + 0x000);337		writel(0x59000008, regs + 0x004);338		writel(0x20, regs + 0x008);339		writel(0x20, regs + 0x00c);340		writel(0x20, regs + 0x010);341		writel(0x20, regs + 0x014);342		writel(0x20, regs + 0x018);343		writel(0x20, regs + 0x01c);344	}345	for (i = 0; i < mvi->chip->n_phy; i++) {346		/* clear phy int status */347		tmp = mvs_read_port_irq_stat(mvi, i);348		tmp &= ~PHYEV_SIG_FIS;349		mvs_write_port_irq_stat(mvi, i, tmp);350 351		/* set phy int mask */352		tmp = PHYEV_RDY_CH | PHYEV_BROAD_CH | PHYEV_UNASSOC_FIS |353			PHYEV_ID_DONE | PHYEV_DCDR_ERR | PHYEV_CRC_ERR |354			PHYEV_DEC_ERR;355		mvs_write_port_irq_mask(mvi, i, tmp);356 357		msleep(100);358		mvs_update_phyinfo(mvi, i, 1);359	}360 361	/* little endian for open address and command table, etc. */362	cctl = mr32(MVS_CTL);363	cctl |= CCTL_ENDIAN_CMD;364	cctl |= CCTL_ENDIAN_DATA;365	cctl &= ~CCTL_ENDIAN_OPEN;366	cctl |= CCTL_ENDIAN_RSP;367	mw32_f(MVS_CTL, cctl);368 369	/* reset CMD queue */370	tmp = mr32(MVS_PCS);371	tmp |= PCS_CMD_RST;372	tmp &= ~PCS_SELF_CLEAR;373	mw32(MVS_PCS, tmp);374	/*375	 * the max count is 0x1ff, while our max slot is 0x200,376	 * it will make count 0.377	 */378	tmp = 0;379	if (MVS_CHIP_SLOT_SZ > 0x1ff)380		mw32(MVS_INT_COAL, 0x1ff | COAL_EN);381	else382		mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ | COAL_EN);383 384	tmp = 0x10000 | interrupt_coalescing;385	mw32(MVS_INT_COAL_TMOUT, tmp);386 387	/* ladies and gentlemen, start your engines */388	mw32(MVS_TX_CFG, 0);389	mw32(MVS_TX_CFG, MVS_CHIP_SLOT_SZ | TX_EN);390	mw32(MVS_RX_CFG, MVS_RX_RING_SZ | RX_EN);391	/* enable CMD/CMPL_Q/RESP mode */392	mw32(MVS_PCS, PCS_SATA_RETRY | PCS_FIS_RX_EN |393		PCS_CMD_EN | PCS_CMD_STOP_ERR);394 395	/* enable completion queue interrupt */396	tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS | CINT_CI_STOP |397		CINT_DMA_PCIE);398 399	mw32(MVS_INT_MASK, tmp);400 401	/* Enable SRS interrupt */402	mw32(MVS_INT_MASK_SRS_0, 0xFFFF);403 404	return 0;405}406 407static int mvs_64xx_ioremap(struct mvs_info *mvi)408{409	if (!mvs_ioremap(mvi, 4, 2))410		return 0;411	return -1;412}413 414static void mvs_64xx_iounmap(struct mvs_info *mvi)415{416	mvs_iounmap(mvi->regs);417	mvs_iounmap(mvi->regs_ex);418}419 420static void mvs_64xx_interrupt_enable(struct mvs_info *mvi)421{422	void __iomem *regs = mvi->regs;423	u32 tmp;424 425	tmp = mr32(MVS_GBL_CTL);426	mw32(MVS_GBL_CTL, tmp | INT_EN);427}428 429static void mvs_64xx_interrupt_disable(struct mvs_info *mvi)430{431	void __iomem *regs = mvi->regs;432	u32 tmp;433 434	tmp = mr32(MVS_GBL_CTL);435	mw32(MVS_GBL_CTL, tmp & ~INT_EN);436}437 438static u32 mvs_64xx_isr_status(struct mvs_info *mvi, int irq)439{440	void __iomem *regs = mvi->regs;441	u32 stat;442 443	if (!(mvi->flags & MVF_FLAG_SOC)) {444		stat = mr32(MVS_GBL_INT_STAT);445 446		if (stat == 0 || stat == 0xffffffff)447			return 0;448	} else449		stat = 1;450	return stat;451}452 453static irqreturn_t mvs_64xx_isr(struct mvs_info *mvi, int irq, u32 stat)454{455	void __iomem *regs = mvi->regs;456 457	/* clear CMD_CMPLT ASAP */458	mw32_f(MVS_INT_STAT, CINT_DONE);459 460	spin_lock(&mvi->lock);461	mvs_int_full(mvi);462	spin_unlock(&mvi->lock);463 464	return IRQ_HANDLED;465}466 467static void mvs_64xx_command_active(struct mvs_info *mvi, u32 slot_idx)468{469	u32 tmp;470	mvs_cw32(mvi, 0x40 + (slot_idx >> 3), 1 << (slot_idx % 32));471	mvs_cw32(mvi, 0x00 + (slot_idx >> 3), 1 << (slot_idx % 32));472	do {473		tmp = mvs_cr32(mvi, 0x00 + (slot_idx >> 3));474	} while (tmp & 1 << (slot_idx % 32));475	do {476		tmp = mvs_cr32(mvi, 0x40 + (slot_idx >> 3));477	} while (tmp & 1 << (slot_idx % 32));478}479 480static void mvs_64xx_issue_stop(struct mvs_info *mvi, enum mvs_port_type type,481				u32 tfs)482{483	void __iomem *regs = mvi->regs;484	u32 tmp;485 486	if (type == PORT_TYPE_SATA) {487		tmp = mr32(MVS_INT_STAT_SRS_0) | (1U << tfs);488		mw32(MVS_INT_STAT_SRS_0, tmp);489	}490	mw32(MVS_INT_STAT, CINT_CI_STOP);491	tmp = mr32(MVS_PCS) | 0xFF00;492	mw32(MVS_PCS, tmp);493}494 495static void mvs_64xx_free_reg_set(struct mvs_info *mvi, u8 *tfs)496{497	void __iomem *regs = mvi->regs;498	u32 tmp, offs;499 500	if (*tfs == MVS_ID_NOT_MAPPED)501		return;502 503	offs = 1U << ((*tfs & 0x0f) + PCS_EN_SATA_REG_SHIFT);504	if (*tfs < 16) {505		tmp = mr32(MVS_PCS);506		mw32(MVS_PCS, tmp & ~offs);507	} else {508		tmp = mr32(MVS_CTL);509		mw32(MVS_CTL, tmp & ~offs);510	}511 512	tmp = mr32(MVS_INT_STAT_SRS_0) & (1U << *tfs);513	if (tmp)514		mw32(MVS_INT_STAT_SRS_0, tmp);515 516	*tfs = MVS_ID_NOT_MAPPED;517	return;518}519 520static u8 mvs_64xx_assign_reg_set(struct mvs_info *mvi, u8 *tfs)521{522	int i;523	u32 tmp, offs;524	void __iomem *regs = mvi->regs;525 526	if (*tfs != MVS_ID_NOT_MAPPED)527		return 0;528 529	tmp = mr32(MVS_PCS);530 531	for (i = 0; i < mvi->chip->srs_sz; i++) {532		if (i == 16)533			tmp = mr32(MVS_CTL);534		offs = 1U << ((i & 0x0f) + PCS_EN_SATA_REG_SHIFT);535		if (!(tmp & offs)) {536			*tfs = i;537 538			if (i < 16)539				mw32(MVS_PCS, tmp | offs);540			else541				mw32(MVS_CTL, tmp | offs);542			tmp = mr32(MVS_INT_STAT_SRS_0) & (1U << i);543			if (tmp)544				mw32(MVS_INT_STAT_SRS_0, tmp);545			return 0;546		}547	}548	return MVS_ID_NOT_MAPPED;549}550 551static void mvs_64xx_make_prd(struct scatterlist *scatter, int nr, void *prd)552{553	int i;554	struct scatterlist *sg;555	struct mvs_prd *buf_prd = prd;556	for_each_sg(scatter, sg, nr, i) {557		buf_prd->addr = cpu_to_le64(sg_dma_address(sg));558		buf_prd->len = cpu_to_le32(sg_dma_len(sg));559		buf_prd++;560	}561}562 563static int mvs_64xx_oob_done(struct mvs_info *mvi, int i)564{565	u32 phy_st;566	mvs_write_port_cfg_addr(mvi, i,567			PHYR_PHY_STAT);568	phy_st = mvs_read_port_cfg_data(mvi, i);569	if (phy_st & PHY_OOB_DTCTD)570		return 1;571	return 0;572}573 574static void mvs_64xx_fix_phy_info(struct mvs_info *mvi, int i,575				struct sas_identify_frame *id)576 577{578	struct mvs_phy *phy = &mvi->phy[i];579	struct asd_sas_phy *sas_phy = &phy->sas_phy;580 581	sas_phy->linkrate =582		(phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >>583			PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET;584 585	phy->minimum_linkrate =586		(phy->phy_status &587			PHY_MIN_SPP_PHYS_LINK_RATE_MASK) >> 8;588	phy->maximum_linkrate =589		(phy->phy_status &590			PHY_MAX_SPP_PHYS_LINK_RATE_MASK) >> 12;591 592	mvs_write_port_cfg_addr(mvi, i, PHYR_IDENTIFY);593	phy->dev_info = mvs_read_port_cfg_data(mvi, i);594 595	mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_DEV_INFO);596	phy->att_dev_info = mvs_read_port_cfg_data(mvi, i);597 598	mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_HI);599	phy->att_dev_sas_addr =600	     (u64) mvs_read_port_cfg_data(mvi, i) << 32;601	mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_LO);602	phy->att_dev_sas_addr |= mvs_read_port_cfg_data(mvi, i);603	phy->att_dev_sas_addr = SAS_ADDR(&phy->att_dev_sas_addr);604}605 606static void mvs_64xx_phy_work_around(struct mvs_info *mvi, int i)607{608	u32 tmp;609	struct mvs_phy *phy = &mvi->phy[i];610	mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE6);611	tmp = mvs_read_port_vsr_data(mvi, i);612	if (((phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >>613	     PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET) ==614		SAS_LINK_RATE_1_5_GBPS)615		tmp &= ~PHY_MODE6_LATECLK;616	else617		tmp |= PHY_MODE6_LATECLK;618	mvs_write_port_vsr_data(mvi, i, tmp);619}620 621static void mvs_64xx_phy_set_link_rate(struct mvs_info *mvi, u32 phy_id,622			struct sas_phy_linkrates *rates)623{624	u32 lrmin = 0, lrmax = 0;625	u32 tmp;626 627	tmp = mvs_read_phy_ctl(mvi, phy_id);628	lrmin = (rates->minimum_linkrate << 8);629	lrmax = (rates->maximum_linkrate << 12);630 631	if (lrmin) {632		tmp &= ~(0xf << 8);633		tmp |= lrmin;634	}635	if (lrmax) {636		tmp &= ~(0xf << 12);637		tmp |= lrmax;638	}639	mvs_write_phy_ctl(mvi, phy_id, tmp);640	mvs_64xx_phy_reset(mvi, phy_id, MVS_HARD_RESET);641}642 643static void mvs_64xx_clear_active_cmds(struct mvs_info *mvi)644{645	u32 tmp;646	void __iomem *regs = mvi->regs;647	tmp = mr32(MVS_PCS);648	mw32(MVS_PCS, tmp & 0xFFFF);649	mw32(MVS_PCS, tmp);650	tmp = mr32(MVS_CTL);651	mw32(MVS_CTL, tmp & 0xFFFF);652	mw32(MVS_CTL, tmp);653}654 655 656static u32 mvs_64xx_spi_read_data(struct mvs_info *mvi)657{658	void __iomem *regs = mvi->regs_ex;659	return ior32(SPI_DATA_REG_64XX);660}661 662static void mvs_64xx_spi_write_data(struct mvs_info *mvi, u32 data)663{664	void __iomem *regs = mvi->regs_ex;665 666	iow32(SPI_DATA_REG_64XX, data);667}668 669 670static int mvs_64xx_spi_buildcmd(struct mvs_info *mvi,671			u32      *dwCmd,672			u8       cmd,673			u8       read,674			u8       length,675			u32      addr676			)677{678	u32  dwTmp;679 680	dwTmp = ((u32)cmd << 24) | ((u32)length << 19);681	if (read)682		dwTmp |= 1U<<23;683 684	if (addr != MV_MAX_U32) {685		dwTmp |= 1U<<22;686		dwTmp |= (addr & 0x0003FFFF);687	}688 689	*dwCmd = dwTmp;690	return 0;691}692 693 694static int mvs_64xx_spi_issuecmd(struct mvs_info *mvi, u32 cmd)695{696	void __iomem *regs = mvi->regs_ex;697	int     retry;698 699	for (retry = 0; retry < 1; retry++) {700		iow32(SPI_CTRL_REG_64XX, SPI_CTRL_VENDOR_ENABLE);701		iow32(SPI_CMD_REG_64XX, cmd);702		iow32(SPI_CTRL_REG_64XX,703			SPI_CTRL_VENDOR_ENABLE | SPI_CTRL_SPISTART);704	}705 706	return 0;707}708 709static int mvs_64xx_spi_waitdataready(struct mvs_info *mvi, u32 timeout)710{711	void __iomem *regs = mvi->regs_ex;712	u32 i, dwTmp;713 714	for (i = 0; i < timeout; i++) {715		dwTmp = ior32(SPI_CTRL_REG_64XX);716		if (!(dwTmp & SPI_CTRL_SPISTART))717			return 0;718		msleep(10);719	}720 721	return -1;722}723 724static void mvs_64xx_fix_dma(struct mvs_info *mvi, u32 phy_mask,725				int buf_len, int from, void *prd)726{727	int i;728	struct mvs_prd *buf_prd = prd;729	dma_addr_t buf_dma = mvi->bulk_buffer_dma;730 731	buf_prd	+= from;732	for (i = 0; i < MAX_SG_ENTRY - from; i++) {733		buf_prd->addr = cpu_to_le64(buf_dma);734		buf_prd->len = cpu_to_le32(buf_len);735		++buf_prd;736	}737}738 739static void mvs_64xx_tune_interrupt(struct mvs_info *mvi, u32 time)740{741	void __iomem *regs = mvi->regs;742	u32 tmp = 0;743	/*744	 * the max count is 0x1ff, while our max slot is 0x200,745	 * it will make count 0.746	 */747	if (time == 0) {748		mw32(MVS_INT_COAL, 0);749		mw32(MVS_INT_COAL_TMOUT, 0x10000);750	} else {751		if (MVS_CHIP_SLOT_SZ > 0x1ff)752			mw32(MVS_INT_COAL, 0x1ff|COAL_EN);753		else754			mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ|COAL_EN);755 756		tmp = 0x10000 | time;757		mw32(MVS_INT_COAL_TMOUT, tmp);758	}759}760 761const struct mvs_dispatch mvs_64xx_dispatch = {762	"mv64xx",763	mvs_64xx_init,764	NULL,765	mvs_64xx_ioremap,766	mvs_64xx_iounmap,767	mvs_64xx_isr,768	mvs_64xx_isr_status,769	mvs_64xx_interrupt_enable,770	mvs_64xx_interrupt_disable,771	mvs_read_phy_ctl,772	mvs_write_phy_ctl,773	mvs_read_port_cfg_data,774	mvs_write_port_cfg_data,775	mvs_write_port_cfg_addr,776	mvs_read_port_vsr_data,777	mvs_write_port_vsr_data,778	mvs_write_port_vsr_addr,779	mvs_read_port_irq_stat,780	mvs_write_port_irq_stat,781	mvs_read_port_irq_mask,782	mvs_write_port_irq_mask,783	mvs_64xx_command_active,784	mvs_64xx_clear_srs_irq,785	mvs_64xx_issue_stop,786	mvs_start_delivery,787	mvs_rx_update,788	mvs_int_full,789	mvs_64xx_assign_reg_set,790	mvs_64xx_free_reg_set,791	mvs_get_prd_size,792	mvs_get_prd_count,793	mvs_64xx_make_prd,794	mvs_64xx_detect_porttype,795	mvs_64xx_oob_done,796	mvs_64xx_fix_phy_info,797	mvs_64xx_phy_work_around,798	mvs_64xx_phy_set_link_rate,799	mvs_hw_max_link_rate,800	mvs_64xx_phy_disable,801	mvs_64xx_phy_enable,802	mvs_64xx_phy_reset,803	mvs_64xx_stp_reset,804	mvs_64xx_clear_active_cmds,805	mvs_64xx_spi_read_data,806	mvs_64xx_spi_write_data,807	mvs_64xx_spi_buildcmd,808	mvs_64xx_spi_issuecmd,809	mvs_64xx_spi_waitdataready,810	mvs_64xx_fix_dma,811	mvs_64xx_tune_interrupt,812	NULL,813};814 815