^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (c) 2003-2014 Broadcom Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This software is available to you under a choice of one of two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * licenses. You may choose to be licensed under the terms of the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * General Public License (GPL) Version 2, available from the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * COPYING in the main directory of this source tree, or the Broadcom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * license below:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * notice, this list of conditions and the following disclaimer in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * the documentation and/or other materials provided with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^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) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/pci_ids.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/nodemask.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <asm/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <asm/netlogic/common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <asm/netlogic/haldefs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <asm/netlogic/mips-extns.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <asm/netlogic/xlp-hal/xlp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <asm/netlogic/xlp-hal/iomap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define SATA_CTL 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define SATA_STATUS 0x1 /* Status Reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SATA_INT 0x2 /* Interrupt Reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SATA_INT_MASK 0x3 /* Interrupt Mask Reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define SATA_BIU_TIMEOUT 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define AXIWRSPERRLOG 0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define AXIRDSPERRLOG 0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define BiuTimeoutLow 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define BiuTimeoutHi 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define BiuSlvErLow 0x9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define BiuSlvErHi 0xa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define IO_CONFIG_SWAP_DIS 0xb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define CR_REG_TIMER 0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define CORE_ID 0xd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define AXI_SLAVE_OPT1 0xe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define PHY_MEM_ACCESS 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define PHY0_CNTRL 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define PHY0_STAT 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define PHY0_RX_ALIGN 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define PHY0_RX_EQ_LO 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define PHY0_RX_EQ_HI 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define PHY0_BIST_LOOP 0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define PHY1_CNTRL 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define PHY1_STAT 0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define PHY1_RX_ALIGN 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define PHY1_RX_EQ_LO 0x19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define PHY1_RX_EQ_HI 0x1a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define PHY1_BIST_LOOP 0x1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define RdExBase 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define RdExLimit 0x1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define CacheAllocBase 0x1e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define CacheAllocLimit 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define BiuSlaveCmdGstNum 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /*SATA_CTL Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define SATA_RST_N BIT(0) /* Active low reset sata_core phy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define SataCtlReserve0 BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define M_CSYSREQ BIT(2) /* AXI master low power, not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define S_CSYSREQ BIT(3) /* AXI slave low power, not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define P0_CP_DET BIT(8) /* Reserved, bring in from pad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define P0_MP_SW BIT(9) /* Mech Switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define P0_DISABLE BIT(10) /* disable p0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define P0_ACT_LED_EN BIT(11) /* Active LED enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define P0_IRST_HARD_SYNTH BIT(12) /* PHY hard synth reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define P0_IRST_HARD_TXRX BIT(13) /* PHY lane hard reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define P0_IRST_POR BIT(14) /* PHY power on reset*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define P0_IPDTXL BIT(15) /* PHY Tx lane dis/power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define P0_IPDRXL BIT(16) /* PHY Rx lane dis/power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define P0_IPDIPDMSYNTH BIT(17) /* PHY synthesizer dis/porwer down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define P0_CP_POD_EN BIT(18) /* CP_POD enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define P0_AT_BYPASS BIT(19) /* P0 address translation by pass */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define P1_CP_DET BIT(20) /* Reserved,Cold Detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define P1_MP_SW BIT(21) /* Mech Switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define P1_DISABLE BIT(22) /* disable p1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define P1_ACT_LED_EN BIT(23) /* Active LED enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define P1_IRST_HARD_SYNTH BIT(24) /* PHY hard synth reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define P1_IRST_HARD_TXRX BIT(25) /* PHY lane hard reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define P1_IRST_POR BIT(26) /* PHY power on reset*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define P1_IPDTXL BIT(27) /* PHY Tx lane dis/porwer down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define P1_IPDRXL BIT(28) /* PHY Rx lane dis/porwer down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define P1_IPDIPDMSYNTH BIT(29) /* PHY synthesizer dis/porwer down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define P1_CP_POD_EN BIT(30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define P1_AT_BYPASS BIT(31) /* P1 address translation by pass */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* Status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define M_CACTIVE BIT(0) /* m_cactive, not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define S_CACTIVE BIT(1) /* s_cactive, not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define P0_PHY_READY BIT(8) /* phy is ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define P0_CP_POD BIT(9) /* Cold PowerOn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define P0_SLUMBER BIT(10) /* power mode slumber */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define P0_PATIAL BIT(11) /* power mode patial */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define P0_PHY_SIG_DET BIT(12) /* phy dignal detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define P0_PHY_CALI BIT(13) /* phy calibration done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define P1_PHY_READY BIT(16) /* phy is ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define P1_CP_POD BIT(17) /* Cold PowerOn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define P1_SLUMBER BIT(18) /* power mode slumber */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define P1_PATIAL BIT(19) /* power mode patial */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define P1_PHY_SIG_DET BIT(20) /* phy dignal detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define P1_PHY_CALI BIT(21) /* phy calibration done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* SATA CR_REG_TIMER bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define CR_TIME_SCALE (0x1000 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* SATA PHY specific registers start and end address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define RXCDRCALFOSC0 0x0065
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define CALDUTY 0x006e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define RXDPIF 0x8065
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define PPMDRIFTMAX_HI 0x80A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define nlm_read_sata_reg(b, r) nlm_read_reg(b, r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define nlm_write_sata_reg(b, r, v) nlm_write_reg(b, r, v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define nlm_get_sata_pcibase(node) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) nlm_pcicfg_base(XLP9XX_IO_SATA_OFFSET(node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define nlm_get_sata_regbase(node) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) (nlm_get_sata_pcibase(node) + 0x100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* SATA PHY config for register block 1 0x0065 .. 0x006e */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static const u8 sata_phy_config1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 0xC9, 0xC9, 0x07, 0x07, 0x18, 0x18, 0x01, 0x01, 0x22, 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* SATA PHY config for register block 2 0x8065 .. 0x80A4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static const u8 sata_phy_config2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 0xAA, 0x00, 0x4C, 0xC9, 0xC9, 0x07, 0x07, 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 0x18, 0x05, 0x0C, 0x10, 0x00, 0x10, 0x00, 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 0xCF, 0xF7, 0xE1, 0xF5, 0xFD, 0xFD, 0xFF, 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 0xFF, 0xFF, 0xE3, 0xE7, 0xDB, 0xF5, 0xFD, 0xFD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 0xF5, 0xF5, 0xFF, 0xFF, 0xE3, 0xE7, 0xDB, 0xF5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 0xFD, 0xFD, 0xF5, 0xF5, 0xFF, 0xFF, 0xFF, 0xF5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 0x3F, 0x00, 0x32, 0x00, 0x03, 0x01, 0x05, 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 0x04, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) const int sata_phy_debug = 0; /* set to verify PHY writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static void sata_clear_glue_reg(u64 regbase, u32 off, u32 bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u32 reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) reg_val = nlm_read_sata_reg(regbase, off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) nlm_write_sata_reg(regbase, off, (reg_val & ~bit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static void sata_set_glue_reg(u64 regbase, u32 off, u32 bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u32 reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) reg_val = nlm_read_sata_reg(regbase, off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) nlm_write_sata_reg(regbase, off, (reg_val | bit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static void write_phy_reg(u64 regbase, u32 addr, u32 physel, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) nlm_write_sata_reg(regbase, PHY_MEM_ACCESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) (1u << 31) | (physel << 24) | (data << 16) | addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) udelay(850);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static u8 read_phy_reg(u64 regbase, u32 addr, u32 physel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) nlm_write_sata_reg(regbase, PHY_MEM_ACCESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) (0 << 31) | (physel << 24) | (0 << 16) | addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) udelay(850);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) val = nlm_read_sata_reg(regbase, PHY_MEM_ACCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return (val >> 16) & 0xff;
^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 config_sata_phy(u64 regbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u32 port, i, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) for (port = 0; port < 2; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) for (i = 0, reg = RXCDRCALFOSC0; reg <= CALDUTY; reg++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) write_phy_reg(regbase, reg, port, sata_phy_config1[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) for (i = 0, reg = RXDPIF; reg <= PPMDRIFTMAX_HI; reg++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) write_phy_reg(regbase, reg, port, sata_phy_config2[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* Fix for PHY link up failures at lower temperatures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) write_phy_reg(regbase, 0x800F, port, 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) val = read_phy_reg(regbase, 0x0029, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) write_phy_reg(regbase, 0x0029, port, val | (0x7 << 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) val = read_phy_reg(regbase, 0x0056, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) write_phy_reg(regbase, 0x0056, port, val & ~(1 << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) val = read_phy_reg(regbase, 0x0018, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) write_phy_reg(regbase, 0x0018, port, val & ~(0x7 << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static void check_phy_register(u64 regbase, u32 addr, u32 physel, u8 xdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) data = read_phy_reg(regbase, addr, physel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) pr_info("PHY read addr = 0x%x physel = %d data = 0x%x %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) addr, physel, data, data == xdata ? "TRUE" : "FALSE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static void verify_sata_phy_config(u64 regbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u32 port, i, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) for (port = 0; port < 2; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) for (i = 0, reg = RXCDRCALFOSC0; reg <= CALDUTY; reg++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) check_phy_register(regbase, reg, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) sata_phy_config1[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) for (i = 0, reg = RXDPIF; reg <= PPMDRIFTMAX_HI; reg++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) check_phy_register(regbase, reg, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) sata_phy_config2[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static void nlm_sata_firmware_init(int node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) u32 reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u64 regbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) pr_info("Initializing XLP9XX On-chip AHCI...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) regbase = nlm_get_sata_regbase(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* Reset port0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) sata_clear_glue_reg(regbase, SATA_CTL, P0_IRST_POR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) sata_clear_glue_reg(regbase, SATA_CTL, P0_IRST_HARD_TXRX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) sata_clear_glue_reg(regbase, SATA_CTL, P0_IRST_HARD_SYNTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) sata_clear_glue_reg(regbase, SATA_CTL, P0_IPDTXL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) sata_clear_glue_reg(regbase, SATA_CTL, P0_IPDRXL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) sata_clear_glue_reg(regbase, SATA_CTL, P0_IPDIPDMSYNTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* port1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) sata_clear_glue_reg(regbase, SATA_CTL, P1_IRST_POR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) sata_clear_glue_reg(regbase, SATA_CTL, P1_IRST_HARD_TXRX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) sata_clear_glue_reg(regbase, SATA_CTL, P1_IRST_HARD_SYNTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) sata_clear_glue_reg(regbase, SATA_CTL, P1_IPDTXL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) sata_clear_glue_reg(regbase, SATA_CTL, P1_IPDRXL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) sata_clear_glue_reg(regbase, SATA_CTL, P1_IPDIPDMSYNTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) udelay(300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* Set PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) sata_set_glue_reg(regbase, SATA_CTL, P0_IPDTXL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) sata_set_glue_reg(regbase, SATA_CTL, P0_IPDRXL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) sata_set_glue_reg(regbase, SATA_CTL, P0_IPDIPDMSYNTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) sata_set_glue_reg(regbase, SATA_CTL, P1_IPDTXL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) sata_set_glue_reg(regbase, SATA_CTL, P1_IPDRXL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) sata_set_glue_reg(regbase, SATA_CTL, P1_IPDIPDMSYNTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) sata_set_glue_reg(regbase, SATA_CTL, P0_IRST_POR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) sata_set_glue_reg(regbase, SATA_CTL, P1_IRST_POR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* setup PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) config_sata_phy(regbase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (sata_phy_debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) verify_sata_phy_config(regbase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) sata_set_glue_reg(regbase, SATA_CTL, P0_IRST_HARD_TXRX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) sata_set_glue_reg(regbase, SATA_CTL, P0_IRST_HARD_SYNTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) sata_set_glue_reg(regbase, SATA_CTL, P1_IRST_HARD_TXRX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) sata_set_glue_reg(regbase, SATA_CTL, P1_IRST_HARD_SYNTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) udelay(300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* Override reset in serial PHY mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) sata_set_glue_reg(regbase, CR_REG_TIMER, CR_TIME_SCALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* Set reset SATA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) sata_set_glue_reg(regbase, SATA_CTL, SATA_RST_N);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) sata_set_glue_reg(regbase, SATA_CTL, M_CSYSREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) sata_set_glue_reg(regbase, SATA_CTL, S_CSYSREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) pr_debug("Waiting for PHYs to come up.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) n = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) reg_val = nlm_read_sata_reg(regbase, SATA_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if ((reg_val & P1_PHY_READY) && (reg_val & P0_PHY_READY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) } while (--n > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (reg_val & P0_PHY_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) pr_info("PHY0 is up.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) pr_info("PHY0 is down.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (reg_val & P1_PHY_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) pr_info("PHY1 is up.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) pr_info("PHY1 is down.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) pr_info("XLP AHCI Init Done.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int __init nlm_ahci_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) int node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (!cpu_is_xlp9xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) for (node = 0; node < NLM_NR_NODES; node++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (nlm_node_present(node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) nlm_sata_firmware_init(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static void nlm_sata_intr_ack(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) u64 regbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) int node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) node = data->irq / NLM_IRQS_PER_NODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) regbase = nlm_get_sata_regbase(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) val = nlm_read_sata_reg(regbase, SATA_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) sata_set_glue_reg(regbase, SATA_INT, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static void nlm_sata_fixup_bar(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) dev->resource[5] = dev->resource[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) memset(&dev->resource[0], 0, sizeof(dev->resource[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static void nlm_sata_fixup_final(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) u64 regbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) int node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* Find end bridge function to find node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) node = xlp_socdev_to_node(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) regbase = nlm_get_sata_regbase(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* clear pending interrupts and then enable them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) val = nlm_read_sata_reg(regbase, SATA_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) sata_set_glue_reg(regbase, SATA_INT, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* Enable only the core interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) sata_set_glue_reg(regbase, SATA_INT_MASK, 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) dev->irq = nlm_irq_to_xirq(node, PIC_SATA_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) nlm_set_pic_extra_ack(node, PIC_SATA_IRQ, nlm_sata_intr_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) arch_initcall(nlm_ahci_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_XLP9XX_SATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) nlm_sata_fixup_bar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_XLP9XX_SATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) nlm_sata_fixup_final);