diff options
| -rw-r--r-- | drivers/net/ethernet/xilinx/ll_temac.h | 12 | ||||
| -rw-r--r-- | drivers/net/ethernet/xilinx/ll_temac_main.c | 87 | ||||
| -rw-r--r-- | include/linux/platform_data/xilinx-ll-temac.h | 2 |
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 */ |
| 376 | u32 temac_ior(struct temac_local *lp, int offset); | ||
| 377 | void temac_iow(struct temac_local *lp, int offset, u32 value); | ||
| 378 | int temac_indirect_busywait(struct temac_local *lp); | 382 | int temac_indirect_busywait(struct temac_local *lp); |
| 379 | u32 temac_indirect_in32(struct temac_local *lp, int reg); | 383 | u32 temac_indirect_in32(struct temac_local *lp, int reg); |
| 380 | void temac_indirect_out32(struct temac_local *lp, int reg, u32 value); | 384 | void 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 | ||
| 66 | u32 temac_ior(struct temac_local *lp, int offset) | 66 | u32 _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 | ||
| 71 | void temac_iow(struct temac_local *lp, int offset, u32 value) | 71 | void _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 | |||
| 76 | u32 _temac_ior_le(struct temac_local *lp, int offset) | ||
| 77 | { | ||
| 78 | return ioread32(lp->regs + offset); | ||
| 79 | } | ||
| 80 | |||
| 81 | void _temac_iow_le(struct temac_local *lp, int offset, u32 value) | ||
| 82 | { | ||
| 83 | return iowrite32(value, lp->regs + offset); | ||
| 74 | } | 84 | } |
| 75 | 85 | ||
| 76 | int temac_indirect_busywait(struct temac_local *lp) | 86 | int 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 | */ |
| 128 | static u32 temac_dma_in32(struct temac_local *lp, int reg) | 139 | static 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 | |||
| 144 | static 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 | */ |
| 138 | static void temac_dma_out32(struct temac_local *lp, int reg, u32 value) | 155 | static void temac_dma_out32_be(struct temac_local *lp, int reg, u32 value) |
| 156 | { | ||
| 157 | iowrite32be(value, lp->sdma_regs + (reg << 2)); | ||
| 158 | } | ||
| 159 | |||
| 160 | static 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 */ |
