1 /* 10G controller driver for Samsung SoCs
3 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16 #include <linux/errno.h>
17 #include <linux/export.h>
18 #include <linux/jiffies.h>
20 #include "sxgbe_mtl.h"
21 #include "sxgbe_reg.h"
23 static void sxgbe_mtl_init(void __iomem *ioaddr, unsigned int etsalg,
28 reg_val = readl(ioaddr + SXGBE_MTL_OP_MODE_REG);
32 switch (etsalg & SXGBE_MTL_OPMODE_ESTMASK) {
43 writel(reg_val, ioaddr + SXGBE_MTL_OP_MODE_REG);
45 switch (raa & SXGBE_MTL_OPMODE_RAAMASK) {
53 writel(reg_val, ioaddr + SXGBE_MTL_OP_MODE_REG);
56 /* For Dynamic DMA channel mapping for Rx queue */
57 static void sxgbe_mtl_dma_dm_rxqueue(void __iomem *ioaddr)
59 writel(RX_QUEUE_DYNAMIC, ioaddr + SXGBE_MTL_RXQ_DMAMAP0_REG);
60 writel(RX_QUEUE_DYNAMIC, ioaddr + SXGBE_MTL_RXQ_DMAMAP1_REG);
61 writel(RX_QUEUE_DYNAMIC, ioaddr + SXGBE_MTL_RXQ_DMAMAP2_REG);
64 static void sxgbe_mtl_set_txfifosize(void __iomem *ioaddr, int queue_num,
67 u32 fifo_bits, reg_val;
69 /* 0 means 256 bytes */
70 fifo_bits = (queue_fifo / SXGBE_MTL_TX_FIFO_DIV) - 1;
71 reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
72 reg_val |= (fifo_bits << SXGBE_MTL_FIFO_LSHIFT);
73 writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
76 static void sxgbe_mtl_set_rxfifosize(void __iomem *ioaddr, int queue_num,
79 u32 fifo_bits, reg_val;
81 /* 0 means 256 bytes */
82 fifo_bits = (queue_fifo / SXGBE_MTL_RX_FIFO_DIV)-1;
83 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
84 reg_val |= (fifo_bits << SXGBE_MTL_FIFO_LSHIFT);
85 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
88 static void sxgbe_mtl_enable_txqueue(void __iomem *ioaddr, int queue_num)
92 reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
93 reg_val |= SXGBE_MTL_ENABLE_QUEUE;
94 writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
97 static void sxgbe_mtl_disable_txqueue(void __iomem *ioaddr, int queue_num)
101 reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
102 reg_val &= ~SXGBE_MTL_ENABLE_QUEUE;
103 writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
106 static void sxgbe_mtl_fc_active(void __iomem *ioaddr, int queue_num,
111 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
112 reg_val &= ~(SXGBE_MTL_FCMASK << RX_FC_ACTIVE);
113 reg_val |= (threshold << RX_FC_ACTIVE);
115 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
118 static void sxgbe_mtl_fc_enable(void __iomem *ioaddr, int queue_num)
122 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
123 reg_val |= SXGBE_MTL_ENABLE_FC;
124 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
127 static void sxgbe_mtl_fc_deactive(void __iomem *ioaddr, int queue_num,
132 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
133 reg_val &= ~(SXGBE_MTL_FCMASK << RX_FC_DEACTIVE);
134 reg_val |= (threshold << RX_FC_DEACTIVE);
136 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
139 static void sxgbe_mtl_fep_enable(void __iomem *ioaddr, int queue_num)
143 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
144 reg_val |= SXGBE_MTL_RXQ_OP_FEP;
146 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
149 static void sxgbe_mtl_fep_disable(void __iomem *ioaddr, int queue_num)
153 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
154 reg_val &= ~(SXGBE_MTL_RXQ_OP_FEP);
156 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
159 static void sxgbe_mtl_fup_enable(void __iomem *ioaddr, int queue_num)
163 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
164 reg_val |= SXGBE_MTL_RXQ_OP_FUP;
166 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
169 static void sxgbe_mtl_fup_disable(void __iomem *ioaddr, int queue_num)
173 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
174 reg_val &= ~(SXGBE_MTL_RXQ_OP_FUP);
176 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
180 static void sxgbe_set_tx_mtl_mode(void __iomem *ioaddr, int queue_num,
185 reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
186 /* TX specific MTL mode settings */
187 if (tx_mode == SXGBE_MTL_SFMODE) {
188 reg_val |= SXGBE_MTL_SFMODE;
190 /* set the TTC values */
192 reg_val |= MTL_CONTROL_TTC_64;
193 else if (tx_mode <= 96)
194 reg_val |= MTL_CONTROL_TTC_96;
195 else if (tx_mode <= 128)
196 reg_val |= MTL_CONTROL_TTC_128;
197 else if (tx_mode <= 192)
198 reg_val |= MTL_CONTROL_TTC_192;
199 else if (tx_mode <= 256)
200 reg_val |= MTL_CONTROL_TTC_256;
201 else if (tx_mode <= 384)
202 reg_val |= MTL_CONTROL_TTC_384;
204 reg_val |= MTL_CONTROL_TTC_512;
207 /* write into TXQ operation register */
208 writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
211 static void sxgbe_set_rx_mtl_mode(void __iomem *ioaddr, int queue_num,
216 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
217 /* RX specific MTL mode settings */
218 if (rx_mode == SXGBE_RX_MTL_SFMODE) {
219 reg_val |= SXGBE_RX_MTL_SFMODE;
222 reg_val |= MTL_CONTROL_RTC_64;
223 else if (rx_mode <= 96)
224 reg_val |= MTL_CONTROL_RTC_96;
225 else if (rx_mode <= 128)
226 reg_val |= MTL_CONTROL_RTC_128;
229 /* write into RXQ operation register */
230 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
233 static const struct sxgbe_mtl_ops mtl_ops = {
234 .mtl_set_txfifosize = sxgbe_mtl_set_txfifosize,
235 .mtl_set_rxfifosize = sxgbe_mtl_set_rxfifosize,
236 .mtl_enable_txqueue = sxgbe_mtl_enable_txqueue,
237 .mtl_disable_txqueue = sxgbe_mtl_disable_txqueue,
238 .mtl_dynamic_dma_rxqueue = sxgbe_mtl_dma_dm_rxqueue,
239 .set_tx_mtl_mode = sxgbe_set_tx_mtl_mode,
240 .set_rx_mtl_mode = sxgbe_set_rx_mtl_mode,
241 .mtl_init = sxgbe_mtl_init,
242 .mtl_fc_active = sxgbe_mtl_fc_active,
243 .mtl_fc_deactive = sxgbe_mtl_fc_deactive,
244 .mtl_fc_enable = sxgbe_mtl_fc_enable,
245 .mtl_fep_enable = sxgbe_mtl_fep_enable,
246 .mtl_fep_disable = sxgbe_mtl_fep_disable,
247 .mtl_fup_enable = sxgbe_mtl_fup_enable,
248 .mtl_fup_disable = sxgbe_mtl_fup_disable
251 const struct sxgbe_mtl_ops *sxgbe_get_mtl_ops(void)