• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * (C) Copyright 2019
4  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
5  *
6  */
7 #include <common.h>
8 #include <asm/cpm_85xx.h>
9 #include <pci.h>
10 #include <dm.h>
11 #include <asm/fsl_law.h>
12 
13 struct mpc85xx_pci_priv {
14 	void __iomem		*cfg_addr;
15 	void __iomem		*cfg_data;
16 };
17 
mpc85xx_pci_dm_read_config(struct udevice * dev,pci_dev_t bdf,uint offset,ulong * value,enum pci_size_t size)18 static int mpc85xx_pci_dm_read_config(struct udevice *dev, pci_dev_t bdf,
19 				      uint offset, ulong *value,
20 				      enum pci_size_t size)
21 {
22 	struct mpc85xx_pci_priv *priv = dev_get_priv(dev);
23 	u32 addr;
24 
25 	addr = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000;
26 	out_be32(priv->cfg_addr, addr);
27 	sync();
28 	*value = pci_conv_32_to_size(in_le32(priv->cfg_data), offset, size);
29 
30 	return 0;
31 }
32 
mpc85xx_pci_dm_write_config(struct udevice * dev,pci_dev_t bdf,uint offset,ulong value,enum pci_size_t size)33 static int mpc85xx_pci_dm_write_config(struct udevice *dev, pci_dev_t bdf,
34 				       uint offset, ulong value,
35 				       enum pci_size_t size)
36 {
37 	struct mpc85xx_pci_priv *priv = dev_get_priv(dev);
38 	u32 addr;
39 
40 	addr = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000;
41 	out_be32(priv->cfg_addr, addr);
42 	sync();
43 	out_le32(priv->cfg_data, pci_conv_size_to_32(0, value, offset, size));
44 
45 	return 0;
46 }
47 
48 static int
mpc85xx_pci_dm_setup_laws(struct pci_region * io,struct pci_region * mem,struct pci_region * pre)49 mpc85xx_pci_dm_setup_laws(struct pci_region *io, struct pci_region *mem,
50 			  struct pci_region *pre)
51 {
52 	/*
53 	 * Unfortunately we have defines for this addresse,
54 	 * as we have to setup the TLB, and at this stage
55 	 * we have no access to DT ... may we check here
56 	 * if the value in the define is the same ?
57 	 */
58 	if (mem)
59 		set_next_law(mem->phys_start, law_size_bits(mem->size),
60 			     LAW_TRGT_IF_PCI);
61 	if (io)
62 		set_next_law(io->phys_start, law_size_bits(io->size),
63 			     LAW_TRGT_IF_PCI);
64 	if (pre)
65 		set_next_law(pre->phys_start, law_size_bits(pre->size),
66 			     LAW_TRGT_IF_PCI);
67 
68 	return 0;
69 }
70 
mpc85xx_pci_dm_probe(struct udevice * dev)71 static int mpc85xx_pci_dm_probe(struct udevice *dev)
72 {
73 	struct mpc85xx_pci_priv *priv = dev_get_priv(dev);
74 	struct pci_region *io;
75 	struct pci_region *mem;
76 	struct pci_region *pre;
77 	int count;
78 	ccsr_pcix_t *pcix;
79 
80 	count = pci_get_regions(dev, &io, &mem, &pre);
81 	if (count != 2) {
82 		printf("%s: wrong count of regions %d only 2 allowed\n",
83 		       __func__, count);
84 		return -EINVAL;
85 	}
86 
87 	mpc85xx_pci_dm_setup_laws(io, mem, pre);
88 
89 	pcix = priv->cfg_addr;
90 	/* BAR 1: memory */
91 	out_be32(&pcix->potar1, (mem->bus_start >> 12) & 0x000fffff);
92 	out_be32(&pcix->potear1, 0);
93 	out_be32(&pcix->powbar1, (mem->phys_start >> 12) & 0x000fffff);
94 	out_be32(&pcix->powbear1, 0);
95 	out_be32(&pcix->powar1, (POWAR_EN | POWAR_MEM_READ |
96 		 POWAR_MEM_WRITE | (__ilog2(mem->size) - 1)));
97 
98 	/* BAR 1: IO */
99 	out_be32(&pcix->potar2, (io->bus_start >> 12) & 0x000fffff);
100 	out_be32(&pcix->potear2, 0);
101 	out_be32(&pcix->powbar2, (io->phys_start >> 12) & 0x000fffff);
102 	out_be32(&pcix->powbear2, 0);
103 	out_be32(&pcix->powar2, (POWAR_EN | POWAR_IO_READ |
104 		 POWAR_IO_WRITE | (__ilog2(io->size) - 1)));
105 
106 	out_be32(&pcix->pitar1, 0);
107 	out_be32(&pcix->piwbar1, 0);
108 	out_be32(&pcix->piwar1, (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
109 		 PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G));
110 
111 	out_be32(&pcix->powar3, 0);
112 	out_be32(&pcix->powar4, 0);
113 	out_be32(&pcix->piwar2, 0);
114 	out_be32(&pcix->piwar3, 0);
115 
116 	return 0;
117 }
118 
mpc85xx_pci_dm_remove(struct udevice * dev)119 static int mpc85xx_pci_dm_remove(struct udevice *dev)
120 {
121 	return 0;
122 }
123 
mpc85xx_pci_ofdata_to_platdata(struct udevice * dev)124 static int mpc85xx_pci_ofdata_to_platdata(struct udevice *dev)
125 {
126 	struct mpc85xx_pci_priv *priv = dev_get_priv(dev);
127 	fdt_addr_t addr;
128 
129 	addr = devfdt_get_addr_index(dev, 0);
130 	if (addr == FDT_ADDR_T_NONE)
131 		return -EINVAL;
132 	priv->cfg_addr = (void __iomem *)addr;
133 	addr += 4;
134 	priv->cfg_data = (void __iomem *)addr;
135 
136 	return 0;
137 }
138 
139 static const struct dm_pci_ops mpc85xx_pci_ops = {
140 	.read_config	= mpc85xx_pci_dm_read_config,
141 	.write_config	= mpc85xx_pci_dm_write_config,
142 };
143 
144 static const struct udevice_id mpc85xx_pci_ids[] = {
145 	{ .compatible = "fsl,mpc8540-pci" },
146 	{ }
147 };
148 
149 U_BOOT_DRIVER(mpc85xx_pci) = {
150 	.name			= "mpc85xx_pci",
151 	.id			= UCLASS_PCI,
152 	.of_match		= mpc85xx_pci_ids,
153 	.ops			= &mpc85xx_pci_ops,
154 	.probe			= mpc85xx_pci_dm_probe,
155 	.remove			= mpc85xx_pci_dm_remove,
156 	.ofdata_to_platdata	= mpc85xx_pci_ofdata_to_platdata,
157 	.priv_auto_alloc_size	= sizeof(struct mpc85xx_pci_priv),
158 };
159