aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/sata_highbank.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
index 5eb93de75e43..ba43c7217545 100644
--- a/drivers/ata/sata_highbank.c
+++ b/drivers/ata/sata_highbank.c
@@ -46,14 +46,19 @@
46#define CR_BUSY 0x0001 46#define CR_BUSY 0x0001
47#define CR_START 0x0001 47#define CR_START 0x0001
48#define CR_WR_RDN 0x0002 48#define CR_WR_RDN 0x0002
49#define CPHY_TX_INPUT_STS 0x2001
49#define CPHY_RX_INPUT_STS 0x2002 50#define CPHY_RX_INPUT_STS 0x2002
50#define CPHY_SATA_OVERRIDE 0x4000 51#define CPHY_SATA_TX_OVERRIDE 0x8000
51#define CPHY_OVERRIDE 0x2005 52#define CPHY_SATA_RX_OVERRIDE 0x4000
53#define CPHY_TX_OVERRIDE 0x2004
54#define CPHY_RX_OVERRIDE 0x2005
52#define SPHY_LANE 0x100 55#define SPHY_LANE 0x100
53#define SPHY_HALF_RATE 0x0001 56#define SPHY_HALF_RATE 0x0001
54#define CPHY_SATA_DPLL_MODE 0x0700 57#define CPHY_SATA_DPLL_MODE 0x0700
55#define CPHY_SATA_DPLL_SHIFT 8 58#define CPHY_SATA_DPLL_SHIFT 8
56#define CPHY_SATA_DPLL_RESET (1 << 11) 59#define CPHY_SATA_DPLL_RESET (1 << 11)
60#define CPHY_SATA_TX_ATTEN 0x1c00
61#define CPHY_SATA_TX_ATTEN_SHIFT 10
57#define CPHY_PHY_COUNT 6 62#define CPHY_PHY_COUNT 6
58#define CPHY_LANE_COUNT 4 63#define CPHY_LANE_COUNT 4
59#define CPHY_PORT_COUNT (CPHY_PHY_COUNT * CPHY_LANE_COUNT) 64#define CPHY_PORT_COUNT (CPHY_PHY_COUNT * CPHY_LANE_COUNT)
@@ -66,6 +71,7 @@ struct phy_lane_info {
66 void __iomem *phy_base; 71 void __iomem *phy_base;
67 u8 lane_mapping; 72 u8 lane_mapping;
68 u8 phy_devs; 73 u8 phy_devs;
74 u8 tx_atten;
69}; 75};
70static struct phy_lane_info port_data[CPHY_PORT_COUNT]; 76static struct phy_lane_info port_data[CPHY_PORT_COUNT];
71 77
@@ -76,7 +82,6 @@ static DEFINE_SPINLOCK(sgpio_lock);
76#define SGPIO_PINS 3 82#define SGPIO_PINS 3
77#define SGPIO_PORTS 8 83#define SGPIO_PORTS 8
78 84
79/* can be cast as an ahci_host_priv for compatibility with most functions */
80struct ecx_plat_data { 85struct ecx_plat_data {
81 u32 n_ports; 86 u32 n_ports;
82 unsigned sgpio_gpio[SGPIO_PINS]; 87 unsigned sgpio_gpio[SGPIO_PINS];
@@ -259,8 +264,27 @@ static void highbank_cphy_disable_overrides(u8 sata_port)
259 if (unlikely(port_data[sata_port].phy_base == NULL)) 264 if (unlikely(port_data[sata_port].phy_base == NULL))
260 return; 265 return;
261 tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE); 266 tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
262 tmp &= ~CPHY_SATA_OVERRIDE; 267 tmp &= ~CPHY_SATA_RX_OVERRIDE;
263 combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp); 268 combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
269}
270
271static void cphy_override_tx_attenuation(u8 sata_port, u32 val)
272{
273 u8 lane = port_data[sata_port].lane_mapping;
274 u32 tmp;
275
276 if (val & 0x8)
277 return;
278
279 tmp = combo_phy_read(sata_port, CPHY_TX_INPUT_STS + lane * SPHY_LANE);
280 tmp &= ~CPHY_SATA_TX_OVERRIDE;
281 combo_phy_write(sata_port, CPHY_TX_OVERRIDE + lane * SPHY_LANE, tmp);
282
283 tmp |= CPHY_SATA_TX_OVERRIDE;
284 combo_phy_write(sata_port, CPHY_TX_OVERRIDE + lane * SPHY_LANE, tmp);
285
286 tmp |= (val << CPHY_SATA_TX_ATTEN_SHIFT) & CPHY_SATA_TX_ATTEN;
287 combo_phy_write(sata_port, CPHY_TX_OVERRIDE + lane * SPHY_LANE, tmp);
264} 288}
265 289
266static void cphy_override_rx_mode(u8 sata_port, u32 val) 290static void cphy_override_rx_mode(u8 sata_port, u32 val)
@@ -268,21 +292,21 @@ static void cphy_override_rx_mode(u8 sata_port, u32 val)
268 u8 lane = port_data[sata_port].lane_mapping; 292 u8 lane = port_data[sata_port].lane_mapping;
269 u32 tmp; 293 u32 tmp;
270 tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE); 294 tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
271 tmp &= ~CPHY_SATA_OVERRIDE; 295 tmp &= ~CPHY_SATA_RX_OVERRIDE;
272 combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp); 296 combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
273 297
274 tmp |= CPHY_SATA_OVERRIDE; 298 tmp |= CPHY_SATA_RX_OVERRIDE;
275 combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp); 299 combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
276 300
277 tmp &= ~CPHY_SATA_DPLL_MODE; 301 tmp &= ~CPHY_SATA_DPLL_MODE;
278 tmp |= val << CPHY_SATA_DPLL_SHIFT; 302 tmp |= val << CPHY_SATA_DPLL_SHIFT;
279 combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp); 303 combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
280 304
281 tmp |= CPHY_SATA_DPLL_RESET; 305 tmp |= CPHY_SATA_DPLL_RESET;
282 combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp); 306 combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
283 307
284 tmp &= ~CPHY_SATA_DPLL_RESET; 308 tmp &= ~CPHY_SATA_DPLL_RESET;
285 combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp); 309 combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
286 310
287 msleep(15); 311 msleep(15);
288} 312}
@@ -299,16 +323,20 @@ static void highbank_cphy_override_lane(u8 sata_port)
299 lane * SPHY_LANE); 323 lane * SPHY_LANE);
300 } while ((tmp & SPHY_HALF_RATE) && (k++ < 1000)); 324 } while ((tmp & SPHY_HALF_RATE) && (k++ < 1000));
301 cphy_override_rx_mode(sata_port, 3); 325 cphy_override_rx_mode(sata_port, 3);
326 cphy_override_tx_attenuation(sata_port, port_data[sata_port].tx_atten);
302} 327}
303 328
304static int highbank_initialize_phys(struct device *dev, void __iomem *addr) 329static int highbank_initialize_phys(struct device *dev, void __iomem *addr)
305{ 330{
306 struct device_node *sata_node = dev->of_node; 331 struct device_node *sata_node = dev->of_node;
307 int phy_count = 0, phy, port = 0; 332 int phy_count = 0, phy, port = 0, i;
308 void __iomem *cphy_base[CPHY_PHY_COUNT]; 333 void __iomem *cphy_base[CPHY_PHY_COUNT];
309 struct device_node *phy_nodes[CPHY_PHY_COUNT]; 334 struct device_node *phy_nodes[CPHY_PHY_COUNT];
335 u32 tx_atten[CPHY_PORT_COUNT];
336
310 memset(port_data, 0, sizeof(struct phy_lane_info) * CPHY_PORT_COUNT); 337 memset(port_data, 0, sizeof(struct phy_lane_info) * CPHY_PORT_COUNT);
311 memset(phy_nodes, 0, sizeof(struct device_node*) * CPHY_PHY_COUNT); 338 memset(phy_nodes, 0, sizeof(struct device_node*) * CPHY_PHY_COUNT);
339 memset(tx_atten, 0xff, CPHY_PORT_COUNT);
312 340
313 do { 341 do {
314 u32 tmp; 342 u32 tmp;
@@ -336,6 +364,10 @@ static int highbank_initialize_phys(struct device *dev, void __iomem *addr)
336 of_node_put(phy_data.np); 364 of_node_put(phy_data.np);
337 port += 1; 365 port += 1;
338 } while (port < CPHY_PORT_COUNT); 366 } while (port < CPHY_PORT_COUNT);
367 of_property_read_u32_array(sata_node, "calxeda,tx-atten",
368 tx_atten, port);
369 for (i = 0; i < port; i++)
370 port_data[i].tx_atten = (u8) tx_atten[i];
339 return 0; 371 return 0;
340} 372}
341 373