aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/xilinx/ll_temac.h12
-rw-r--r--drivers/net/ethernet/xilinx/ll_temac_main.c87
-rw-r--r--include/linux/platform_data/xilinx-ll-temac.h2
3 files changed, 79 insertions, 22 deletions
diff --git a/drivers/net/ethernet/xilinx/ll_temac.h b/drivers/net/ethernet/xilinx/ll_temac.h
index e338b4fa3c60..23d8dd5330f8 100644
--- a/drivers/net/ethernet/xilinx/ll_temac.h
+++ b/drivers/net/ethernet/xilinx/ll_temac.h
@@ -347,8 +347,10 @@ struct temac_local {
347#ifdef CONFIG_PPC_DCR 347#ifdef CONFIG_PPC_DCR
348 dcr_host_t sdma_dcrs; 348 dcr_host_t sdma_dcrs;
349#endif 349#endif
350 u32 (*dma_in)(struct temac_local *, int); 350 u32 (*temac_ior)(struct temac_local *lp, int offset);
351 void (*dma_out)(struct temac_local *, int, u32); 351 void (*temac_iow)(struct temac_local *lp, int offset, u32 value);
352 u32 (*dma_in)(struct temac_local *lp, int reg);
353 void (*dma_out)(struct temac_local *lp, int reg, u32 value);
352 354
353 int tx_irq; 355 int tx_irq;
354 int rx_irq; 356 int rx_irq;
@@ -372,9 +374,11 @@ struct temac_local {
372 int rx_bd_ci; 374 int rx_bd_ci;
373}; 375};
374 376
377/* Wrappers for temac_ior()/temac_iow() function pointers above */
378#define temac_ior(lp, o) ((lp)->temac_ior(lp, o))
379#define temac_iow(lp, o, v) ((lp)->temac_iow(lp, o, v))
380
375/* xilinx_temac.c */ 381/* xilinx_temac.c */
376u32 temac_ior(struct temac_local *lp, int offset);
377void temac_iow(struct temac_local *lp, int offset, u32 value);
378int temac_indirect_busywait(struct temac_local *lp); 382int temac_indirect_busywait(struct temac_local *lp);
379u32 temac_indirect_in32(struct temac_local *lp, int reg); 383u32 temac_indirect_in32(struct temac_local *lp, int reg);
380void temac_indirect_out32(struct temac_local *lp, int reg, u32 value); 384void temac_indirect_out32(struct temac_local *lp, int reg, u32 value);
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index bcafb8925f75..58c67138ed2b 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -63,14 +63,24 @@
63 * Low level register access functions 63 * Low level register access functions
64 */ 64 */
65 65
66u32 temac_ior(struct temac_local *lp, int offset) 66u32 _temac_ior_be(struct temac_local *lp, int offset)
67{ 67{
68 return in_be32(lp->regs + offset); 68 return ioread32be(lp->regs + offset);
69} 69}
70 70
71void temac_iow(struct temac_local *lp, int offset, u32 value) 71void _temac_iow_be(struct temac_local *lp, int offset, u32 value)
72{ 72{
73 out_be32(lp->regs + offset, value); 73 return iowrite32be(value, lp->regs + offset);
74}
75
76u32 _temac_ior_le(struct temac_local *lp, int offset)
77{
78 return ioread32(lp->regs + offset);
79}
80
81void _temac_iow_le(struct temac_local *lp, int offset, u32 value)
82{
83 return iowrite32(value, lp->regs + offset);
74} 84}
75 85
76int temac_indirect_busywait(struct temac_local *lp) 86int temac_indirect_busywait(struct temac_local *lp)
@@ -121,23 +131,35 @@ void temac_indirect_out32(struct temac_local *lp, int reg, u32 value)
121} 131}
122 132
123/** 133/**
124 * temac_dma_in32 - Memory mapped DMA read, this function expects a 134 * temac_dma_in32_* - Memory mapped DMA read, these function expects a
125 * register input that is based on DCR word addresses which 135 * register input that is based on DCR word addresses which are then
126 * are then converted to memory mapped byte addresses 136 * converted to memory mapped byte addresses. To be assigned to
137 * lp->dma_in32.
127 */ 138 */
128static u32 temac_dma_in32(struct temac_local *lp, int reg) 139static u32 temac_dma_in32_be(struct temac_local *lp, int reg)
129{ 140{
130 return in_be32(lp->sdma_regs + (reg << 2)); 141 return ioread32be(lp->sdma_regs + (reg << 2));
142}
143
144static u32 temac_dma_in32_le(struct temac_local *lp, int reg)
145{
146 return ioread32(lp->sdma_regs + (reg << 2));
131} 147}
132 148
133/** 149/**
134 * temac_dma_out32 - Memory mapped DMA read, this function expects a 150 * temac_dma_out32_* - Memory mapped DMA read, these function expects
135 * register input that is based on DCR word addresses which 151 * a register input that is based on DCR word addresses which are then
136 * are then converted to memory mapped byte addresses 152 * converted to memory mapped byte addresses. To be assigned to
153 * lp->dma_out32.
137 */ 154 */
138static void temac_dma_out32(struct temac_local *lp, int reg, u32 value) 155static void temac_dma_out32_be(struct temac_local *lp, int reg, u32 value)
156{
157 iowrite32be(value, lp->sdma_regs + (reg << 2));
158}
159
160static void temac_dma_out32_le(struct temac_local *lp, int reg, u32 value)
139{ 161{
140 out_be32(lp->sdma_regs + (reg << 2), value); 162 iowrite32(value, lp->sdma_regs + (reg << 2));
141} 163}
142 164
143/* DMA register access functions can be DCR based or memory mapped. 165/* DMA register access functions can be DCR based or memory mapped.
@@ -1024,6 +1046,7 @@ static int temac_probe(struct platform_device *pdev)
1024 struct resource *res; 1046 struct resource *res;
1025 const void *addr; 1047 const void *addr;
1026 __be32 *p; 1048 __be32 *p;
1049 bool little_endian;
1027 int rc = 0; 1050 int rc = 0;
1028 1051
1029 /* Init network device structure */ 1052 /* Init network device structure */
@@ -1068,6 +1091,24 @@ static int temac_probe(struct platform_device *pdev)
1068 return PTR_ERR(lp->regs); 1091 return PTR_ERR(lp->regs);
1069 } 1092 }
1070 1093
1094 /* Select register access functions with the specified
1095 * endianness mode. Default for OF devices is big-endian.
1096 */
1097 little_endian = false;
1098 if (temac_np) {
1099 if (of_get_property(temac_np, "little-endian", NULL))
1100 little_endian = true;
1101 } else if (pdata) {
1102 little_endian = pdata->reg_little_endian;
1103 }
1104 if (little_endian) {
1105 lp->temac_ior = _temac_ior_le;
1106 lp->temac_iow = _temac_iow_le;
1107 } else {
1108 lp->temac_ior = _temac_ior_be;
1109 lp->temac_iow = _temac_iow_be;
1110 }
1111
1071 /* Setup checksum offload, but default to off if not specified */ 1112 /* Setup checksum offload, but default to off if not specified */
1072 lp->temac_features = 0; 1113 lp->temac_features = 0;
1073 if (temac_np) { 1114 if (temac_np) {
@@ -1111,8 +1152,13 @@ static int temac_probe(struct platform_device *pdev)
1111 of_node_put(dma_np); 1152 of_node_put(dma_np);
1112 return PTR_ERR(lp->sdma_regs); 1153 return PTR_ERR(lp->sdma_regs);
1113 } 1154 }
1114 lp->dma_in = temac_dma_in32; 1155 if (of_get_property(dma_np, "little-endian", NULL)) {
1115 lp->dma_out = temac_dma_out32; 1156 lp->dma_in = temac_dma_in32_le;
1157 lp->dma_out = temac_dma_out32_le;
1158 } else {
1159 lp->dma_in = temac_dma_in32_be;
1160 lp->dma_out = temac_dma_out32_be;
1161 }
1116 dev_dbg(&pdev->dev, "MEM base: %p\n", lp->sdma_regs); 1162 dev_dbg(&pdev->dev, "MEM base: %p\n", lp->sdma_regs);
1117 } 1163 }
1118 1164
@@ -1132,8 +1178,13 @@ static int temac_probe(struct platform_device *pdev)
1132 "could not map DMA registers\n"); 1178 "could not map DMA registers\n");
1133 return PTR_ERR(lp->sdma_regs); 1179 return PTR_ERR(lp->sdma_regs);
1134 } 1180 }
1135 lp->dma_in = temac_dma_in32; 1181 if (pdata->dma_little_endian) {
1136 lp->dma_out = temac_dma_out32; 1182 lp->dma_in = temac_dma_in32_le;
1183 lp->dma_out = temac_dma_out32_le;
1184 } else {
1185 lp->dma_in = temac_dma_in32_be;
1186 lp->dma_out = temac_dma_out32_be;
1187 }
1137 1188
1138 /* Get DMA RX and TX interrupts */ 1189 /* Get DMA RX and TX interrupts */
1139 lp->rx_irq = platform_get_irq(pdev, 0); 1190 lp->rx_irq = platform_get_irq(pdev, 0);
diff --git a/include/linux/platform_data/xilinx-ll-temac.h b/include/linux/platform_data/xilinx-ll-temac.h
index 82e2f80648b0..af87927abab3 100644
--- a/include/linux/platform_data/xilinx-ll-temac.h
+++ b/include/linux/platform_data/xilinx-ll-temac.h
@@ -14,6 +14,8 @@ struct ll_temac_platform_data {
14 unsigned long long mdio_bus_id; /* Unique id for MDIO bus */ 14 unsigned long long mdio_bus_id; /* Unique id for MDIO bus */
15 int phy_addr; /* Address of the PHY to connect to */ 15 int phy_addr; /* Address of the PHY to connect to */
16 phy_interface_t phy_interface; /* PHY interface mode */ 16 phy_interface_t phy_interface; /* PHY interface mode */
17 bool reg_little_endian; /* Little endian TEMAC register access */
18 bool dma_little_endian; /* Little endian DMA register access */
17}; 19};
18 20
19#endif /* __LINUX_XILINX_LL_TEMAC_H */ 21#endif /* __LINUX_XILINX_LL_TEMAC_H */