diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/sata_highbank.c | 58 |
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 | }; |
70 | static struct phy_lane_info port_data[CPHY_PORT_COUNT]; | 76 | static 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 */ | ||
80 | struct ecx_plat_data { | 85 | struct 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 | |||
271 | static 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 | ||
266 | static void cphy_override_rx_mode(u8 sata_port, u32 val) | 290 | static 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 | ||
304 | static int highbank_initialize_phys(struct device *dev, void __iomem *addr) | 329 | static 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 | ||