xref: /rk3399_rockchip-uboot/drivers/ata/sata_ceva.c (revision f2105c61821b67bc1d572304d901518e88ee007b)
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