]>
Commit | Line | Data |
---|---|---|
e6a84624 GS |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
3 | * Texas Instruments Ethernet Switch Driver | |
4 | * | |
5 | * Copyright (C) 2019 Texas Instruments | |
6 | */ | |
7 | ||
8 | #include <linux/if_ether.h> | |
9 | #include <linux/if_vlan.h> | |
10 | #include <linux/module.h> | |
11 | #include <linux/netdevice.h> | |
12 | #include <linux/phy.h> | |
13 | #include <linux/platform_device.h> | |
14 | #include <linux/skbuff.h> | |
15 | ||
16 | #include "cpts.h" | |
17 | #include "cpsw_ale.h" | |
18 | #include "cpsw_priv.h" | |
19 | #include "davinci_cpdma.h" | |
20 | ||
21 | int cpsw_init_common(struct cpsw_common *cpsw, void __iomem *ss_regs, | |
22 | int ale_ageout, phys_addr_t desc_mem_phys, | |
23 | int descs_pool_size) | |
24 | { | |
25 | u32 slave_offset, sliver_offset, slave_size; | |
26 | struct cpsw_ale_params ale_params; | |
27 | struct cpsw_platform_data *data; | |
28 | struct cpdma_params dma_params; | |
29 | struct device *dev = cpsw->dev; | |
30 | void __iomem *cpts_regs; | |
31 | int ret = 0, i; | |
32 | ||
33 | data = &cpsw->data; | |
34 | cpsw->rx_ch_num = 1; | |
35 | cpsw->tx_ch_num = 1; | |
36 | ||
37 | cpsw->version = readl(&cpsw->regs->id_ver); | |
38 | ||
39 | memset(&dma_params, 0, sizeof(dma_params)); | |
40 | memset(&ale_params, 0, sizeof(ale_params)); | |
41 | ||
42 | switch (cpsw->version) { | |
43 | case CPSW_VERSION_1: | |
44 | cpsw->host_port_regs = ss_regs + CPSW1_HOST_PORT_OFFSET; | |
45 | cpts_regs = ss_regs + CPSW1_CPTS_OFFSET; | |
46 | cpsw->hw_stats = ss_regs + CPSW1_HW_STATS; | |
47 | dma_params.dmaregs = ss_regs + CPSW1_CPDMA_OFFSET; | |
48 | dma_params.txhdp = ss_regs + CPSW1_STATERAM_OFFSET; | |
49 | ale_params.ale_regs = ss_regs + CPSW1_ALE_OFFSET; | |
50 | slave_offset = CPSW1_SLAVE_OFFSET; | |
51 | slave_size = CPSW1_SLAVE_SIZE; | |
52 | sliver_offset = CPSW1_SLIVER_OFFSET; | |
53 | dma_params.desc_mem_phys = 0; | |
54 | break; | |
55 | case CPSW_VERSION_2: | |
56 | case CPSW_VERSION_3: | |
57 | case CPSW_VERSION_4: | |
58 | cpsw->host_port_regs = ss_regs + CPSW2_HOST_PORT_OFFSET; | |
59 | cpts_regs = ss_regs + CPSW2_CPTS_OFFSET; | |
60 | cpsw->hw_stats = ss_regs + CPSW2_HW_STATS; | |
61 | dma_params.dmaregs = ss_regs + CPSW2_CPDMA_OFFSET; | |
62 | dma_params.txhdp = ss_regs + CPSW2_STATERAM_OFFSET; | |
63 | ale_params.ale_regs = ss_regs + CPSW2_ALE_OFFSET; | |
64 | slave_offset = CPSW2_SLAVE_OFFSET; | |
65 | slave_size = CPSW2_SLAVE_SIZE; | |
66 | sliver_offset = CPSW2_SLIVER_OFFSET; | |
67 | dma_params.desc_mem_phys = desc_mem_phys; | |
68 | break; | |
69 | default: | |
70 | dev_err(dev, "unknown version 0x%08x\n", cpsw->version); | |
71 | return -ENODEV; | |
72 | } | |
73 | ||
74 | for (i = 0; i < cpsw->data.slaves; i++) { | |
75 | struct cpsw_slave *slave = &cpsw->slaves[i]; | |
76 | void __iomem *regs = cpsw->regs; | |
77 | ||
78 | slave->slave_num = i; | |
79 | slave->data = &cpsw->data.slave_data[i]; | |
80 | slave->regs = regs + slave_offset; | |
81 | slave->sliver = regs + sliver_offset; | |
82 | slave->port_vlan = slave->data->dual_emac_res_vlan; | |
83 | ||
84 | slave_offset += slave_size; | |
85 | sliver_offset += SLIVER_SIZE; | |
86 | } | |
87 | ||
88 | ale_params.dev = dev; | |
89 | ale_params.ale_ageout = ale_ageout; | |
90 | ale_params.ale_entries = data->ale_entries; | |
91 | ale_params.ale_ports = CPSW_ALE_PORTS_NUM; | |
92 | ||
93 | cpsw->ale = cpsw_ale_create(&ale_params); | |
94 | if (!cpsw->ale) { | |
95 | dev_err(dev, "error initializing ale engine\n"); | |
96 | return -ENODEV; | |
97 | } | |
98 | ||
99 | dma_params.dev = dev; | |
100 | dma_params.rxthresh = dma_params.dmaregs + CPDMA_RXTHRESH; | |
101 | dma_params.rxfree = dma_params.dmaregs + CPDMA_RXFREE; | |
102 | dma_params.rxhdp = dma_params.txhdp + CPDMA_RXHDP; | |
103 | dma_params.txcp = dma_params.txhdp + CPDMA_TXCP; | |
104 | dma_params.rxcp = dma_params.txhdp + CPDMA_RXCP; | |
105 | ||
106 | dma_params.num_chan = data->channels; | |
107 | dma_params.has_soft_reset = true; | |
108 | dma_params.min_packet_size = CPSW_MIN_PACKET_SIZE; | |
109 | dma_params.desc_mem_size = data->bd_ram_size; | |
110 | dma_params.desc_align = 16; | |
111 | dma_params.has_ext_regs = true; | |
112 | dma_params.desc_hw_addr = dma_params.desc_mem_phys; | |
113 | dma_params.bus_freq_mhz = cpsw->bus_freq_mhz; | |
114 | dma_params.descs_pool_size = descs_pool_size; | |
115 | ||
116 | cpsw->dma = cpdma_ctlr_create(&dma_params); | |
117 | if (!cpsw->dma) { | |
118 | dev_err(dev, "error initializing dma\n"); | |
119 | return -ENOMEM; | |
120 | } | |
121 | ||
122 | cpsw->cpts = cpts_create(cpsw->dev, cpts_regs, cpsw->dev->of_node); | |
123 | if (IS_ERR(cpsw->cpts)) { | |
124 | ret = PTR_ERR(cpsw->cpts); | |
125 | cpdma_ctlr_destroy(cpsw->dma); | |
126 | } | |
127 | ||
128 | return ret; | |
129 | } |