forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/bus/fsl-mc/fsl-mc-bus.c
....@@ -3,6 +3,7 @@
33 * Freescale Management Complex (MC) bus driver
44 *
55 * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
6
+ * Copyright 2019-2020 NXP
67 * Author: German Rivera <German.Rivera@freescale.com>
78 *
89 */
....@@ -18,6 +19,8 @@
1819 #include <linux/bitops.h>
1920 #include <linux/msi.h>
2021 #include <linux/dma-mapping.h>
22
+#include <linux/acpi.h>
23
+#include <linux/iommu.h>
2124
2225 #include "fsl-mc-private.h"
2326
....@@ -25,6 +28,8 @@
2528 * Default DMA mask for devices on a fsl-mc bus
2629 */
2730 #define FSL_MC_DEFAULT_DMA_MASK (~0ULL)
31
+
32
+static struct fsl_mc_version mc_version;
2833
2934 /**
3035 * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device
....@@ -36,6 +41,7 @@
3641 struct fsl_mc_device *root_mc_bus_dev;
3742 u8 num_translation_ranges;
3843 struct fsl_mc_addr_translation_range *translation_ranges;
44
+ void *fsl_mc_regs;
3945 };
4046
4147 /**
....@@ -54,19 +60,11 @@
5460 phys_addr_t start_phys_addr;
5561 };
5662
57
-/**
58
- * struct mc_version
59
- * @major: Major version number: incremented on API compatibility changes
60
- * @minor: Minor version number: incremented on API additions (that are
61
- * backward compatible); reset when major version is incremented
62
- * @revision: Internal revision number: incremented on implementation changes
63
- * and/or bug fixes that have no impact on API
64
- */
65
-struct mc_version {
66
- u32 major;
67
- u32 minor;
68
- u32 revision;
69
-};
63
+#define FSL_MC_FAPR 0x28
64
+#define MC_FAPR_PL BIT(18)
65
+#define MC_FAPR_BMT BIT(17)
66
+
67
+static phys_addr_t mc_portal_base_phys_addr;
7068
7169 /**
7270 * fsl_mc_bus_match - device to driver matching callback
....@@ -82,6 +80,12 @@
8280 struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
8381 struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
8482 bool found = false;
83
+
84
+ /* When driver_override is set, only bind to the matching driver */
85
+ if (mc_dev->driver_override) {
86
+ found = !strcmp(mc_dev->driver_override, mc_drv->driver.name);
87
+ goto out;
88
+ }
8589
8690 if (!mc_drv->match_id_table)
8791 goto out;
....@@ -127,6 +131,21 @@
127131 return 0;
128132 }
129133
134
+static int fsl_mc_dma_configure(struct device *dev)
135
+{
136
+ struct device *dma_dev = dev;
137
+ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
138
+ u32 input_id = mc_dev->icid;
139
+
140
+ while (dev_is_fsl_mc(dma_dev))
141
+ dma_dev = dma_dev->parent;
142
+
143
+ if (dev_of_node(dma_dev))
144
+ return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
145
+
146
+ return acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id);
147
+}
148
+
130149 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
131150 char *buf)
132151 {
....@@ -137,8 +156,52 @@
137156 }
138157 static DEVICE_ATTR_RO(modalias);
139158
159
+static ssize_t driver_override_store(struct device *dev,
160
+ struct device_attribute *attr,
161
+ const char *buf, size_t count)
162
+{
163
+ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
164
+ char *driver_override, *old = mc_dev->driver_override;
165
+ char *cp;
166
+
167
+ if (WARN_ON(dev->bus != &fsl_mc_bus_type))
168
+ return -EINVAL;
169
+
170
+ if (count >= (PAGE_SIZE - 1))
171
+ return -EINVAL;
172
+
173
+ driver_override = kstrndup(buf, count, GFP_KERNEL);
174
+ if (!driver_override)
175
+ return -ENOMEM;
176
+
177
+ cp = strchr(driver_override, '\n');
178
+ if (cp)
179
+ *cp = '\0';
180
+
181
+ if (strlen(driver_override)) {
182
+ mc_dev->driver_override = driver_override;
183
+ } else {
184
+ kfree(driver_override);
185
+ mc_dev->driver_override = NULL;
186
+ }
187
+
188
+ kfree(old);
189
+
190
+ return count;
191
+}
192
+
193
+static ssize_t driver_override_show(struct device *dev,
194
+ struct device_attribute *attr, char *buf)
195
+{
196
+ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
197
+
198
+ return snprintf(buf, PAGE_SIZE, "%s\n", mc_dev->driver_override);
199
+}
200
+static DEVICE_ATTR_RW(driver_override);
201
+
140202 static struct attribute *fsl_mc_dev_attrs[] = {
141203 &dev_attr_modalias.attr,
204
+ &dev_attr_driver_override.attr,
142205 NULL,
143206 };
144207
....@@ -148,6 +211,7 @@
148211 .name = "fsl-mc",
149212 .match = fsl_mc_bus_match,
150213 .uevent = fsl_mc_bus_uevent,
214
+ .dma_configure = fsl_mc_dma_configure,
151215 .dev_groups = fsl_mc_dev_groups,
152216 };
153217 EXPORT_SYMBOL_GPL(fsl_mc_bus_type);
....@@ -155,38 +219,77 @@
155219 struct device_type fsl_mc_bus_dprc_type = {
156220 .name = "fsl_mc_bus_dprc"
157221 };
222
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dprc_type);
158223
159224 struct device_type fsl_mc_bus_dpni_type = {
160225 .name = "fsl_mc_bus_dpni"
161226 };
227
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dpni_type);
162228
163229 struct device_type fsl_mc_bus_dpio_type = {
164230 .name = "fsl_mc_bus_dpio"
165231 };
232
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dpio_type);
166233
167234 struct device_type fsl_mc_bus_dpsw_type = {
168235 .name = "fsl_mc_bus_dpsw"
169236 };
237
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dpsw_type);
170238
171239 struct device_type fsl_mc_bus_dpbp_type = {
172240 .name = "fsl_mc_bus_dpbp"
173241 };
242
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dpbp_type);
174243
175244 struct device_type fsl_mc_bus_dpcon_type = {
176245 .name = "fsl_mc_bus_dpcon"
177246 };
247
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dpcon_type);
178248
179249 struct device_type fsl_mc_bus_dpmcp_type = {
180250 .name = "fsl_mc_bus_dpmcp"
181251 };
252
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dpmcp_type);
182253
183254 struct device_type fsl_mc_bus_dpmac_type = {
184255 .name = "fsl_mc_bus_dpmac"
185256 };
257
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dpmac_type);
186258
187259 struct device_type fsl_mc_bus_dprtc_type = {
188260 .name = "fsl_mc_bus_dprtc"
189261 };
262
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dprtc_type);
263
+
264
+struct device_type fsl_mc_bus_dpseci_type = {
265
+ .name = "fsl_mc_bus_dpseci"
266
+};
267
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dpseci_type);
268
+
269
+struct device_type fsl_mc_bus_dpdmux_type = {
270
+ .name = "fsl_mc_bus_dpdmux"
271
+};
272
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdmux_type);
273
+
274
+struct device_type fsl_mc_bus_dpdcei_type = {
275
+ .name = "fsl_mc_bus_dpdcei"
276
+};
277
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdcei_type);
278
+
279
+struct device_type fsl_mc_bus_dpaiop_type = {
280
+ .name = "fsl_mc_bus_dpaiop"
281
+};
282
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dpaiop_type);
283
+
284
+struct device_type fsl_mc_bus_dpci_type = {
285
+ .name = "fsl_mc_bus_dpci"
286
+};
287
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dpci_type);
288
+
289
+struct device_type fsl_mc_bus_dpdmai_type = {
290
+ .name = "fsl_mc_bus_dpdmai"
291
+};
292
+EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdmai_type);
190293
191294 static struct device_type *fsl_mc_get_device_type(const char *type)
192295 {
....@@ -203,6 +306,12 @@
203306 { &fsl_mc_bus_dpmcp_type, "dpmcp" },
204307 { &fsl_mc_bus_dpmac_type, "dpmac" },
205308 { &fsl_mc_bus_dprtc_type, "dprtc" },
309
+ { &fsl_mc_bus_dpseci_type, "dpseci" },
310
+ { &fsl_mc_bus_dpdmux_type, "dpdmux" },
311
+ { &fsl_mc_bus_dpdcei_type, "dpdcei" },
312
+ { &fsl_mc_bus_dpaiop_type, "dpaiop" },
313
+ { &fsl_mc_bus_dpci_type, "dpci" },
314
+ { &fsl_mc_bus_dpdmai_type, "dpdmai" },
206315 { NULL, NULL }
207316 };
208317 int i;
....@@ -312,7 +421,7 @@
312421 */
313422 static int mc_get_version(struct fsl_mc_io *mc_io,
314423 u32 cmd_flags,
315
- struct mc_version *mc_ver_info)
424
+ struct fsl_mc_version *mc_ver_info)
316425 {
317426 struct fsl_mc_command cmd = { 0 };
318427 struct dpmng_rsp_get_version *rsp_params;
....@@ -338,10 +447,24 @@
338447 }
339448
340449 /**
450
+ * fsl_mc_get_version - function to retrieve the MC f/w version information
451
+ *
452
+ * Return: mc version when called after fsl-mc-bus probe; NULL otherwise.
453
+ */
454
+struct fsl_mc_version *fsl_mc_get_version(void)
455
+{
456
+ if (mc_version.major)
457
+ return &mc_version;
458
+
459
+ return NULL;
460
+}
461
+EXPORT_SYMBOL_GPL(fsl_mc_get_version);
462
+
463
+/**
341464 * fsl_mc_get_root_dprc - function to traverse to the root dprc
342465 */
343
-static void fsl_mc_get_root_dprc(struct device *dev,
344
- struct device **root_dprc_dev)
466
+void fsl_mc_get_root_dprc(struct device *dev,
467
+ struct device **root_dprc_dev)
345468 {
346469 if (!dev) {
347470 *root_dprc_dev = NULL;
....@@ -382,7 +505,7 @@
382505 }
383506
384507 static int get_dprc_icid(struct fsl_mc_io *mc_io,
385
- int container_id, u16 *icid)
508
+ int container_id, u32 *icid)
386509 {
387510 struct dprc_attributes attr;
388511 int error;
....@@ -471,10 +594,35 @@
471594 "dprc_get_obj_region() failed: %d\n", error);
472595 goto error_cleanup_regions;
473596 }
474
-
475
- error = translate_mc_addr(mc_dev, mc_region_type,
597
+ /*
598
+ * Older MC only returned region offset and no base address
599
+ * If base address is in the region_desc use it otherwise
600
+ * revert to old mechanism
601
+ */
602
+ if (region_desc.base_address) {
603
+ regions[i].start = region_desc.base_address +
604
+ region_desc.base_offset;
605
+ } else {
606
+ error = translate_mc_addr(mc_dev, mc_region_type,
476607 region_desc.base_offset,
477608 &regions[i].start);
609
+
610
+ /*
611
+ * Some versions of the MC firmware wrongly report
612
+ * 0 for register base address of the DPMCP associated
613
+ * with child DPRC objects thus rendering them unusable.
614
+ * This is particularly troublesome in ACPI boot
615
+ * scenarios where the legacy way of extracting this
616
+ * base address from the device tree does not apply.
617
+ * Given that DPMCPs share the same base address,
618
+ * workaround this by using the base address extracted
619
+ * from the root DPRC container.
620
+ */
621
+ if (is_fsl_mc_bus_dprc(mc_dev) &&
622
+ regions[i].start == region_desc.base_offset)
623
+ regions[i].start += mc_portal_base_phys_addr;
624
+ }
625
+
478626 if (error < 0) {
479627 dev_err(parent_dev,
480628 "Invalid MC offset: %#x (for %s.%d\'s region %d)\n",
....@@ -485,9 +633,8 @@
485633
486634 regions[i].end = regions[i].start + region_desc.size - 1;
487635 regions[i].name = "fsl-mc object MMIO region";
488
- regions[i].flags = IORESOURCE_IO;
489
- if (region_desc.flags & DPRC_REGION_CACHEABLE)
490
- regions[i].flags |= IORESOURCE_CACHEABLE;
636
+ regions[i].flags = region_desc.flags & IORESOURCE_BITS;
637
+ regions[i].flags |= IORESOURCE_MEM;
491638 }
492639
493640 mc_dev->regions = regions;
....@@ -549,6 +696,7 @@
549696 if (!mc_bus)
550697 return -ENOMEM;
551698
699
+ mutex_init(&mc_bus->scan_mutex);
552700 mc_dev = &mc_bus->mc_dev;
553701 } else {
554702 /*
....@@ -616,6 +764,7 @@
616764 mc_dev->icid = parent_mc_dev->icid;
617765 mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK;
618766 mc_dev->dev.dma_mask = &mc_dev->dma_mask;
767
+ mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask;
619768 dev_set_msi_domain(&mc_dev->dev,
620769 dev_get_msi_domain(&parent_mc_dev->dev));
621770 }
....@@ -632,10 +781,6 @@
632781 if (error < 0)
633782 goto error_cleanup_dev;
634783 }
635
-
636
- /* Objects are coherent, unless 'no shareability' flag set. */
637
- if (!(obj_desc->flags & FSL_MC_OBJ_FLAG_NO_MEM_SHAREABILITY))
638
- arch_setup_dma_ops(&mc_dev->dev, 0, 0, NULL, true);
639784
640785 /*
641786 * The device-specific probe callback will get invoked by device_add()
....@@ -670,6 +815,9 @@
670815 */
671816 void fsl_mc_device_remove(struct fsl_mc_device *mc_dev)
672817 {
818
+ kfree(mc_dev->driver_override);
819
+ mc_dev->driver_override = NULL;
820
+
673821 /*
674822 * The device-specific remove callback will get invoked by device_del()
675823 */
....@@ -677,6 +825,39 @@
677825 put_device(&mc_dev->dev);
678826 }
679827 EXPORT_SYMBOL_GPL(fsl_mc_device_remove);
828
+
829
+struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev)
830
+{
831
+ struct fsl_mc_device *mc_bus_dev, *endpoint;
832
+ struct fsl_mc_obj_desc endpoint_desc = {{ 0 }};
833
+ struct dprc_endpoint endpoint1 = {{ 0 }};
834
+ struct dprc_endpoint endpoint2 = {{ 0 }};
835
+ int state, err;
836
+
837
+ mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
838
+ strcpy(endpoint1.type, mc_dev->obj_desc.type);
839
+ endpoint1.id = mc_dev->obj_desc.id;
840
+
841
+ err = dprc_get_connection(mc_bus_dev->mc_io, 0,
842
+ mc_bus_dev->mc_handle,
843
+ &endpoint1, &endpoint2,
844
+ &state);
845
+
846
+ if (err == -ENOTCONN || state == -1)
847
+ return ERR_PTR(-ENOTCONN);
848
+
849
+ if (err < 0) {
850
+ dev_err(&mc_bus_dev->dev, "dprc_get_connection() = %d\n", err);
851
+ return ERR_PTR(err);
852
+ }
853
+
854
+ strcpy(endpoint_desc.type, endpoint2.type);
855
+ endpoint_desc.id = endpoint2.id;
856
+ endpoint = fsl_mc_device_lookup(&endpoint_desc, mc_bus_dev);
857
+
858
+ return endpoint;
859
+}
860
+EXPORT_SYMBOL_GPL(fsl_mc_get_endpoint);
680861
681862 static int parse_mc_ranges(struct device *dev,
682863 int *paddr_cells,
....@@ -693,8 +874,8 @@
693874 *ranges_start = of_get_property(mc_node, "ranges", &ranges_len);
694875 if (!(*ranges_start) || !ranges_len) {
695876 dev_warn(dev,
696
- "missing or empty ranges property for device tree node '%s'\n",
697
- mc_node->name);
877
+ "missing or empty ranges property for device tree node '%pOFn'\n",
878
+ mc_node);
698879 return 0;
699880 }
700881
....@@ -717,7 +898,7 @@
717898
718899 tuple_len = range_tuple_cell_count * sizeof(__be32);
719900 if (ranges_len % tuple_len != 0) {
720
- dev_err(dev, "malformed ranges property '%s'\n", mc_node->name);
901
+ dev_err(dev, "malformed ranges property '%pOFn'\n", mc_node);
721902 return -EINVAL;
722903 }
723904
....@@ -794,9 +975,8 @@
794975 struct fsl_mc_io *mc_io = NULL;
795976 int container_id;
796977 phys_addr_t mc_portal_phys_addr;
797
- u32 mc_portal_size;
798
- struct mc_version mc_version;
799
- struct resource res;
978
+ u32 mc_portal_size, mc_stream_id;
979
+ struct resource *plat_res;
800980
801981 mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
802982 if (!mc)
....@@ -804,19 +984,38 @@
804984
805985 platform_set_drvdata(pdev, mc);
806986
987
+ plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
988
+ if (plat_res) {
989
+ mc->fsl_mc_regs = devm_ioremap_resource(&pdev->dev, plat_res);
990
+ if (IS_ERR(mc->fsl_mc_regs))
991
+ return PTR_ERR(mc->fsl_mc_regs);
992
+ }
993
+
994
+ if (mc->fsl_mc_regs && IS_ENABLED(CONFIG_ACPI) &&
995
+ !dev_of_node(&pdev->dev)) {
996
+ mc_stream_id = readl(mc->fsl_mc_regs + FSL_MC_FAPR);
997
+ /*
998
+ * HW ORs the PL and BMT bit, places the result in bit 15 of
999
+ * the StreamID and ORs in the ICID. Calculate it accordingly.
1000
+ */
1001
+ mc_stream_id = (mc_stream_id & 0xffff) |
1002
+ ((mc_stream_id & (MC_FAPR_PL | MC_FAPR_BMT)) ?
1003
+ 0x4000 : 0);
1004
+ error = acpi_dma_configure_id(&pdev->dev, DEV_DMA_COHERENT,
1005
+ &mc_stream_id);
1006
+ if (error)
1007
+ dev_warn(&pdev->dev, "failed to configure dma: %d.\n",
1008
+ error);
1009
+ }
1010
+
8071011 /*
8081012 * Get physical address of MC portal for the root DPRC:
8091013 */
810
- error = of_address_to_resource(pdev->dev.of_node, 0, &res);
811
- if (error < 0) {
812
- dev_err(&pdev->dev,
813
- "of_address_to_resource() failed for %pOF\n",
814
- pdev->dev.of_node);
815
- return error;
816
- }
1014
+ plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1015
+ mc_portal_phys_addr = plat_res->start;
1016
+ mc_portal_size = resource_size(plat_res);
1017
+ mc_portal_base_phys_addr = mc_portal_phys_addr & ~0x3ffffff;
8171018
818
- mc_portal_phys_addr = res.start;
819
- mc_portal_size = resource_size(&res);
8201019 error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
8211020 mc_portal_size, NULL,
8221021 FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
....@@ -833,11 +1032,13 @@
8331032 dev_info(&pdev->dev, "MC firmware version: %u.%u.%u\n",
8341033 mc_version.major, mc_version.minor, mc_version.revision);
8351034
836
- error = get_mc_addr_translation_ranges(&pdev->dev,
837
- &mc->translation_ranges,
838
- &mc->num_translation_ranges);
839
- if (error < 0)
840
- goto error_cleanup_mc_io;
1035
+ if (dev_of_node(&pdev->dev)) {
1036
+ error = get_mc_addr_translation_ranges(&pdev->dev,
1037
+ &mc->translation_ranges,
1038
+ &mc->num_translation_ranges);
1039
+ if (error < 0)
1040
+ goto error_cleanup_mc_io;
1041
+ }
8411042
8421043 error = dprc_get_container_id(mc_io, 0, &container_id);
8431044 if (error < 0) {
....@@ -864,6 +1065,7 @@
8641065 goto error_cleanup_mc_io;
8651066
8661067 mc->root_mc_bus_dev = mc_bus_dev;
1068
+ mc_bus_dev->dev.fwnode = pdev->dev.fwnode;
8671069 return 0;
8681070
8691071 error_cleanup_mc_io:
....@@ -897,11 +1099,18 @@
8971099
8981100 MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table);
8991101
1102
+static const struct acpi_device_id fsl_mc_bus_acpi_match_table[] = {
1103
+ {"NXP0008", 0 },
1104
+ { }
1105
+};
1106
+MODULE_DEVICE_TABLE(acpi, fsl_mc_bus_acpi_match_table);
1107
+
9001108 static struct platform_driver fsl_mc_bus_driver = {
9011109 .driver = {
9021110 .name = "fsl_mc_bus",
9031111 .pm = NULL,
9041112 .of_match_table = fsl_mc_bus_match_table,
1113
+ .acpi_match_table = fsl_mc_bus_acpi_match_table,
9051114 },
9061115 .probe = fsl_mc_bus_probe,
9071116 .remove = fsl_mc_bus_remove,