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