@@ -91,3 +91,368 @@ struct pci_ecam_ops al_pcie_ops = {
9191};
9292
9393#endif /* defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) */
94+
95+ #ifdef CONFIG_PCIE_AL
96+
97+ #include <linux/of_pci.h>
98+ #include "pcie-designware.h"
99+
100+ #define AL_PCIE_REV_ID_2 2
101+ #define AL_PCIE_REV_ID_3 3
102+ #define AL_PCIE_REV_ID_4 4
103+
104+ #define AXI_BASE_OFFSET 0x0
105+
106+ #define DEVICE_ID_OFFSET 0x16c
107+
108+ #define DEVICE_REV_ID 0x0
109+ #define DEVICE_REV_ID_DEV_ID_MASK GENMASK(31, 16)
110+
111+ #define DEVICE_REV_ID_DEV_ID_X4 0
112+ #define DEVICE_REV_ID_DEV_ID_X8 2
113+ #define DEVICE_REV_ID_DEV_ID_X16 4
114+
115+ #define OB_CTRL_REV1_2_OFFSET 0x0040
116+ #define OB_CTRL_REV3_5_OFFSET 0x0030
117+
118+ #define CFG_TARGET_BUS 0x0
119+ #define CFG_TARGET_BUS_MASK_MASK GENMASK(7, 0)
120+ #define CFG_TARGET_BUS_BUSNUM_MASK GENMASK(15, 8)
121+
122+ #define CFG_CONTROL 0x4
123+ #define CFG_CONTROL_SUBBUS_MASK GENMASK(15, 8)
124+ #define CFG_CONTROL_SEC_BUS_MASK GENMASK(23, 16)
125+
126+ struct al_pcie_reg_offsets {
127+ unsigned int ob_ctrl ;
128+ };
129+
130+ struct al_pcie_target_bus_cfg {
131+ u8 reg_val ;
132+ u8 reg_mask ;
133+ u8 ecam_mask ;
134+ };
135+
136+ struct al_pcie {
137+ struct dw_pcie * pci ;
138+ void __iomem * controller_base ; /* base of PCIe unit (not DW core) */
139+ struct device * dev ;
140+ resource_size_t ecam_size ;
141+ unsigned int controller_rev_id ;
142+ struct al_pcie_reg_offsets reg_offsets ;
143+ struct al_pcie_target_bus_cfg target_bus_cfg ;
144+ };
145+
146+ #define PCIE_ECAM_DEVFN (x ) (((x) & 0xff) << 12)
147+
148+ #define to_al_pcie (x ) dev_get_drvdata((x)->dev)
149+
150+ static inline u32 al_pcie_controller_readl (struct al_pcie * pcie , u32 offset )
151+ {
152+ return readl_relaxed (pcie -> controller_base + offset );
153+ }
154+
155+ static inline void al_pcie_controller_writel (struct al_pcie * pcie , u32 offset ,
156+ u32 val )
157+ {
158+ writel_relaxed (val , pcie -> controller_base + offset );
159+ }
160+
161+ static int al_pcie_rev_id_get (struct al_pcie * pcie , unsigned int * rev_id )
162+ {
163+ u32 dev_rev_id_val ;
164+ u32 dev_id_val ;
165+
166+ dev_rev_id_val = al_pcie_controller_readl (pcie , AXI_BASE_OFFSET +
167+ DEVICE_ID_OFFSET +
168+ DEVICE_REV_ID );
169+ dev_id_val = FIELD_GET (DEVICE_REV_ID_DEV_ID_MASK , dev_rev_id_val );
170+
171+ switch (dev_id_val ) {
172+ case DEVICE_REV_ID_DEV_ID_X4 :
173+ * rev_id = AL_PCIE_REV_ID_2 ;
174+ break ;
175+ case DEVICE_REV_ID_DEV_ID_X8 :
176+ * rev_id = AL_PCIE_REV_ID_3 ;
177+ break ;
178+ case DEVICE_REV_ID_DEV_ID_X16 :
179+ * rev_id = AL_PCIE_REV_ID_4 ;
180+ break ;
181+ default :
182+ dev_err (pcie -> dev , "Unsupported dev_id_val (0x%x)\n" ,
183+ dev_id_val );
184+ return - EINVAL ;
185+ }
186+
187+ dev_dbg (pcie -> dev , "dev_id_val: 0x%x\n" , dev_id_val );
188+
189+ return 0 ;
190+ }
191+
192+ static int al_pcie_reg_offsets_set (struct al_pcie * pcie )
193+ {
194+ switch (pcie -> controller_rev_id ) {
195+ case AL_PCIE_REV_ID_2 :
196+ pcie -> reg_offsets .ob_ctrl = OB_CTRL_REV1_2_OFFSET ;
197+ break ;
198+ case AL_PCIE_REV_ID_3 :
199+ case AL_PCIE_REV_ID_4 :
200+ pcie -> reg_offsets .ob_ctrl = OB_CTRL_REV3_5_OFFSET ;
201+ break ;
202+ default :
203+ dev_err (pcie -> dev , "Unsupported controller rev_id: 0x%x\n" ,
204+ pcie -> controller_rev_id );
205+ return - EINVAL ;
206+ }
207+
208+ return 0 ;
209+ }
210+
211+ static inline void al_pcie_target_bus_set (struct al_pcie * pcie ,
212+ u8 target_bus ,
213+ u8 mask_target_bus )
214+ {
215+ u32 reg ;
216+
217+ reg = FIELD_PREP (CFG_TARGET_BUS_MASK_MASK , mask_target_bus ) |
218+ FIELD_PREP (CFG_TARGET_BUS_BUSNUM_MASK , target_bus );
219+
220+ al_pcie_controller_writel (pcie , AXI_BASE_OFFSET +
221+ pcie -> reg_offsets .ob_ctrl + CFG_TARGET_BUS ,
222+ reg );
223+ }
224+
225+ static void __iomem * al_pcie_conf_addr_map (struct al_pcie * pcie ,
226+ unsigned int busnr ,
227+ unsigned int devfn )
228+ {
229+ struct al_pcie_target_bus_cfg * target_bus_cfg = & pcie -> target_bus_cfg ;
230+ unsigned int busnr_ecam = busnr & target_bus_cfg -> ecam_mask ;
231+ unsigned int busnr_reg = busnr & target_bus_cfg -> reg_mask ;
232+ struct pcie_port * pp = & pcie -> pci -> pp ;
233+ void __iomem * pci_base_addr ;
234+
235+ pci_base_addr = (void __iomem * )((uintptr_t )pp -> va_cfg0_base +
236+ (busnr_ecam << 20 ) +
237+ PCIE_ECAM_DEVFN (devfn ));
238+
239+ if (busnr_reg != target_bus_cfg -> reg_val ) {
240+ dev_dbg (pcie -> pci -> dev , "Changing target bus busnum val from 0x%x to 0x%x\n" ,
241+ target_bus_cfg -> reg_val , busnr_reg );
242+ target_bus_cfg -> reg_val = busnr_reg ;
243+ al_pcie_target_bus_set (pcie ,
244+ target_bus_cfg -> reg_val ,
245+ target_bus_cfg -> reg_mask );
246+ }
247+
248+ return pci_base_addr ;
249+ }
250+
251+ static int al_pcie_rd_other_conf (struct pcie_port * pp , struct pci_bus * bus ,
252+ unsigned int devfn , int where , int size ,
253+ u32 * val )
254+ {
255+ struct dw_pcie * pci = to_dw_pcie_from_pp (pp );
256+ struct al_pcie * pcie = to_al_pcie (pci );
257+ unsigned int busnr = bus -> number ;
258+ void __iomem * pci_addr ;
259+ int rc ;
260+
261+ pci_addr = al_pcie_conf_addr_map (pcie , busnr , devfn );
262+
263+ rc = dw_pcie_read (pci_addr + where , size , val );
264+
265+ dev_dbg (pci -> dev , "%d-byte config read from %04x:%02x:%02x.%d offset 0x%x (pci_addr: 0x%px) - val:0x%x\n" ,
266+ size , pci_domain_nr (bus ), bus -> number ,
267+ PCI_SLOT (devfn ), PCI_FUNC (devfn ), where ,
268+ (pci_addr + where ), * val );
269+
270+ return rc ;
271+ }
272+
273+ static int al_pcie_wr_other_conf (struct pcie_port * pp , struct pci_bus * bus ,
274+ unsigned int devfn , int where , int size ,
275+ u32 val )
276+ {
277+ struct dw_pcie * pci = to_dw_pcie_from_pp (pp );
278+ struct al_pcie * pcie = to_al_pcie (pci );
279+ unsigned int busnr = bus -> number ;
280+ void __iomem * pci_addr ;
281+ int rc ;
282+
283+ pci_addr = al_pcie_conf_addr_map (pcie , busnr , devfn );
284+
285+ rc = dw_pcie_write (pci_addr + where , size , val );
286+
287+ dev_dbg (pci -> dev , "%d-byte config write to %04x:%02x:%02x.%d offset 0x%x (pci_addr: 0x%px) - val:0x%x\n" ,
288+ size , pci_domain_nr (bus ), bus -> number ,
289+ PCI_SLOT (devfn ), PCI_FUNC (devfn ), where ,
290+ (pci_addr + where ), val );
291+
292+ return rc ;
293+ }
294+
295+ static void al_pcie_config_prepare (struct al_pcie * pcie )
296+ {
297+ struct al_pcie_target_bus_cfg * target_bus_cfg ;
298+ struct pcie_port * pp = & pcie -> pci -> pp ;
299+ unsigned int ecam_bus_mask ;
300+ u32 cfg_control_offset ;
301+ u8 subordinate_bus ;
302+ u8 secondary_bus ;
303+ u32 cfg_control ;
304+ u32 reg ;
305+
306+ target_bus_cfg = & pcie -> target_bus_cfg ;
307+
308+ ecam_bus_mask = (pcie -> ecam_size >> 20 ) - 1 ;
309+ if (ecam_bus_mask > 255 ) {
310+ dev_warn (pcie -> dev , "ECAM window size is larger than 256MB. Cutting off at 256\n" );
311+ ecam_bus_mask = 255 ;
312+ }
313+
314+ /* This portion is taken from the transaction address */
315+ target_bus_cfg -> ecam_mask = ecam_bus_mask ;
316+ /* This portion is taken from the cfg_target_bus reg */
317+ target_bus_cfg -> reg_mask = ~target_bus_cfg -> ecam_mask ;
318+ target_bus_cfg -> reg_val = pp -> busn -> start & target_bus_cfg -> reg_mask ;
319+
320+ al_pcie_target_bus_set (pcie , target_bus_cfg -> reg_val ,
321+ target_bus_cfg -> reg_mask );
322+
323+ secondary_bus = pp -> busn -> start + 1 ;
324+ subordinate_bus = pp -> busn -> end ;
325+
326+ /* Set the valid values of secondary and subordinate buses */
327+ cfg_control_offset = AXI_BASE_OFFSET + pcie -> reg_offsets .ob_ctrl +
328+ CFG_CONTROL ;
329+
330+ cfg_control = al_pcie_controller_readl (pcie , cfg_control_offset );
331+
332+ reg = cfg_control &
333+ ~(CFG_CONTROL_SEC_BUS_MASK | CFG_CONTROL_SUBBUS_MASK );
334+
335+ reg |= FIELD_PREP (CFG_CONTROL_SUBBUS_MASK , subordinate_bus ) |
336+ FIELD_PREP (CFG_CONTROL_SEC_BUS_MASK , secondary_bus );
337+
338+ al_pcie_controller_writel (pcie , cfg_control_offset , reg );
339+ }
340+
341+ static int al_pcie_host_init (struct pcie_port * pp )
342+ {
343+ struct dw_pcie * pci = to_dw_pcie_from_pp (pp );
344+ struct al_pcie * pcie = to_al_pcie (pci );
345+ int rc ;
346+
347+ rc = al_pcie_rev_id_get (pcie , & pcie -> controller_rev_id );
348+ if (rc )
349+ return rc ;
350+
351+ rc = al_pcie_reg_offsets_set (pcie );
352+ if (rc )
353+ return rc ;
354+
355+ al_pcie_config_prepare (pcie );
356+
357+ return 0 ;
358+ }
359+
360+ static const struct dw_pcie_host_ops al_pcie_host_ops = {
361+ .rd_other_conf = al_pcie_rd_other_conf ,
362+ .wr_other_conf = al_pcie_wr_other_conf ,
363+ .host_init = al_pcie_host_init ,
364+ };
365+
366+ static int al_add_pcie_port (struct pcie_port * pp ,
367+ struct platform_device * pdev )
368+ {
369+ struct device * dev = & pdev -> dev ;
370+ int ret ;
371+
372+ pp -> ops = & al_pcie_host_ops ;
373+
374+ ret = dw_pcie_host_init (pp );
375+ if (ret ) {
376+ dev_err (dev , "failed to initialize host\n" );
377+ return ret ;
378+ }
379+
380+ return 0 ;
381+ }
382+
383+ static const struct dw_pcie_ops dw_pcie_ops = {
384+ };
385+
386+ static int al_pcie_probe (struct platform_device * pdev )
387+ {
388+ struct device * dev = & pdev -> dev ;
389+ struct resource * controller_res ;
390+ struct resource * ecam_res ;
391+ struct resource * dbi_res ;
392+ struct al_pcie * al_pcie ;
393+ struct dw_pcie * pci ;
394+
395+ al_pcie = devm_kzalloc (dev , sizeof (* al_pcie ), GFP_KERNEL );
396+ if (!al_pcie )
397+ return - ENOMEM ;
398+
399+ pci = devm_kzalloc (dev , sizeof (* pci ), GFP_KERNEL );
400+ if (!pci )
401+ return - ENOMEM ;
402+
403+ pci -> dev = dev ;
404+ pci -> ops = & dw_pcie_ops ;
405+
406+ al_pcie -> pci = pci ;
407+ al_pcie -> dev = dev ;
408+
409+ dbi_res = platform_get_resource_byname (pdev , IORESOURCE_MEM , "dbi" );
410+ pci -> dbi_base = devm_pci_remap_cfg_resource (dev , dbi_res );
411+ if (IS_ERR (pci -> dbi_base )) {
412+ dev_err (dev , "couldn't remap dbi base %pR\n" , dbi_res );
413+ return PTR_ERR (pci -> dbi_base );
414+ }
415+
416+ ecam_res = platform_get_resource_byname (pdev , IORESOURCE_MEM , "config" );
417+ if (!ecam_res ) {
418+ dev_err (dev , "couldn't find 'config' reg in DT\n" );
419+ return - ENOENT ;
420+ }
421+ al_pcie -> ecam_size = resource_size (ecam_res );
422+
423+ controller_res = platform_get_resource_byname (pdev , IORESOURCE_MEM ,
424+ "controller" );
425+ al_pcie -> controller_base = devm_ioremap_resource (dev , controller_res );
426+ if (IS_ERR (al_pcie -> controller_base )) {
427+ dev_err (dev , "couldn't remap controller base %pR\n" ,
428+ controller_res );
429+ return PTR_ERR (al_pcie -> controller_base );
430+ }
431+
432+ dev_dbg (dev , "From DT: dbi_base: %pR, controller_base: %pR\n" ,
433+ dbi_res , controller_res );
434+
435+ platform_set_drvdata (pdev , al_pcie );
436+
437+ return al_add_pcie_port (& pci -> pp , pdev );
438+ }
439+
440+ static const struct of_device_id al_pcie_of_match [] = {
441+ { .compatible = "amazon,al-alpine-v2-pcie" ,
442+ },
443+ { .compatible = "amazon,al-alpine-v3-pcie" ,
444+ },
445+ {},
446+ };
447+
448+ static struct platform_driver al_pcie_driver = {
449+ .driver = {
450+ .name = "al-pcie" ,
451+ .of_match_table = al_pcie_of_match ,
452+ .suppress_bind_attrs = true,
453+ },
454+ .probe = al_pcie_probe ,
455+ };
456+ builtin_platform_driver (al_pcie_driver );
457+
458+ #endif /* CONFIG_PCIE_AL*/
0 commit comments