1 /* 2 * (C) Copyright 2015 - 2016 Xilinx, Inc. 3 * Michal Simek <michal.simek@xilinx.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 #include <common.h> 8 #include <dm.h> 9 #include <ahci.h> 10 #include <scsi.h> 11 #include <asm/arch/hardware.h> 12 13 #include <asm/io.h> 14 15 /* Vendor Specific Register Offsets */ 16 #define AHCI_VEND_PCFG 0xA4 17 #define AHCI_VEND_PPCFG 0xA8 18 #define AHCI_VEND_PP2C 0xAC 19 #define AHCI_VEND_PP3C 0xB0 20 #define AHCI_VEND_PP4C 0xB4 21 #define AHCI_VEND_PP5C 0xB8 22 #define AHCI_VEND_PAXIC 0xC0 23 #define AHCI_VEND_PTC 0xC8 24 25 /* Vendor Specific Register bit definitions */ 26 #define PAXIC_ADBW_BW64 0x1 27 #define PAXIC_MAWIDD (1 << 8) 28 #define PAXIC_MARIDD (1 << 16) 29 #define PAXIC_OTL (0x4 << 20) 30 31 #define PCFG_TPSS_VAL (0x32 << 16) 32 #define PCFG_TPRS_VAL (0x2 << 12) 33 #define PCFG_PAD_VAL 0x2 34 35 #define PPCFG_TTA 0x1FFFE 36 #define PPCFG_PSSO_EN (1 << 28) 37 #define PPCFG_PSS_EN (1 << 29) 38 #define PPCFG_ESDF_EN (1 << 31) 39 40 #define PP2C_CIBGMN 0x0F 41 #define PP2C_CIBGMX (0x25 << 8) 42 #define PP2C_CIBGN (0x18 << 16) 43 #define PP2C_CINMP (0x29 << 24) 44 45 #define PP3C_CWBGMN 0x04 46 #define PP3C_CWBGMX (0x0B << 8) 47 #define PP3C_CWBGN (0x08 << 16) 48 #define PP3C_CWNMP (0x0F << 24) 49 50 #define PP4C_BMX 0x0a 51 #define PP4C_BNM (0x08 << 8) 52 #define PP4C_SFD (0x4a << 16) 53 #define PP4C_PTST (0x06 << 24) 54 55 #define PP5C_RIT 0x60216 56 #define PP5C_RCT (0x7f0 << 20) 57 58 #define PTC_RX_WM_VAL 0x40 59 #define PTC_RSVD (1 << 27) 60 61 #define PORT0_BASE 0x100 62 #define PORT1_BASE 0x180 63 64 /* Port Control Register Bit Definitions */ 65 #define PORT_SCTL_SPD_GEN3 (0x3 << 4) 66 #define PORT_SCTL_SPD_GEN2 (0x2 << 4) 67 #define PORT_SCTL_SPD_GEN1 (0x1 << 4) 68 #define PORT_SCTL_IPM (0x3 << 8) 69 70 #define PORT_BASE 0x100 71 #define PORT_OFFSET 0x80 72 #define NR_PORTS 2 73 #define DRV_NAME "ahci-ceva" 74 #define CEVA_FLAG_BROKEN_GEN2 1 75 76 static int ceva_init_sata(ulong mmio) 77 { 78 ulong tmp; 79 int i; 80 81 /* 82 * AXI Data bus width to 64 83 * Set Mem Addr Read, Write ID for data transfers 84 * Transfer limit to 72 DWord 85 */ 86 tmp = PAXIC_ADBW_BW64 | PAXIC_MAWIDD | PAXIC_MARIDD | PAXIC_OTL; 87 writel(tmp, mmio + AHCI_VEND_PAXIC); 88 89 /* Set AHCI Enable */ 90 tmp = readl(mmio + HOST_CTL); 91 tmp |= HOST_AHCI_EN; 92 writel(tmp, mmio + HOST_CTL); 93 94 for (i = 0; i < NR_PORTS; i++) { 95 /* TPSS TPRS scalars, CISE and Port Addr */ 96 tmp = PCFG_TPSS_VAL | PCFG_TPRS_VAL | (PCFG_PAD_VAL + i); 97 writel(tmp, mmio + AHCI_VEND_PCFG); 98 99 /* Port Phy Cfg register enables */ 100 tmp = PPCFG_TTA | PPCFG_PSS_EN | PPCFG_ESDF_EN; 101 writel(tmp, mmio + AHCI_VEND_PPCFG); 102 103 /* Rx Watermark setting */ 104 tmp = PTC_RX_WM_VAL | PTC_RSVD; 105 writel(tmp, mmio + AHCI_VEND_PTC); 106 107 /* Default to Gen 2 Speed and Gen 1 if Gen2 is broken */ 108 tmp = PORT_SCTL_SPD_GEN3 | PORT_SCTL_IPM; 109 writel(tmp, mmio + PORT_SCR_CTL + PORT_BASE + PORT_OFFSET * i); 110 } 111 return 0; 112 } 113 114 static int sata_ceva_probe(struct udevice *dev) 115 { 116 int ret; 117 struct scsi_platdata *plat = dev_get_uclass_platdata(dev); 118 119 ceva_init_sata(plat->base); 120 121 ret = ahci_init_one_dm(dev); 122 if (ret) 123 return ret; 124 125 return ahci_start_ports_dm(dev); 126 } 127 128 static const struct udevice_id sata_ceva_ids[] = { 129 { .compatible = "ceva,ahci-1v84" }, 130 { } 131 }; 132 133 static int sata_ceva_ofdata_to_platdata(struct udevice *dev) 134 { 135 struct scsi_platdata *plat = dev_get_uclass_platdata(dev); 136 137 plat->base = devfdt_get_addr(dev); 138 if (plat->base == FDT_ADDR_T_NONE) 139 return -EINVAL; 140 141 /* Hardcode number for ceva sata controller */ 142 plat->max_lun = 1; /* Actually two but untested */ 143 plat->max_id = 2; 144 145 return 0; 146 } 147 148 U_BOOT_DRIVER(ceva_host_blk) = { 149 .name = "ceva_sata", 150 .id = UCLASS_SCSI, 151 .of_match = sata_ceva_ids, 152 .ops = &scsi_ops, 153 .probe = sata_ceva_probe, 154 .ofdata_to_platdata = sata_ceva_ofdata_to_platdata, 155 }; 156