|
@@ -720,3 +720,104 @@ static const struct l2x0_of_data pl310_data = {
|
|
|
.resume = pl310_resume,
|
|
|
.inv_range = l2x0_inv_range,
|
|
|
.clean_range = l2x0_clean_range,
|
|
|
+ .flush_range = l2x0_flush_range,
|
|
|
+ .sync = l2x0_cache_sync,
|
|
|
+ .flush_all = l2x0_flush_all,
|
|
|
+ .inv_all = l2x0_inv_all,
|
|
|
+ .disable = l2x0_disable,
|
|
|
+ .set_debug = pl310_set_debug,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static const struct l2x0_of_data l2x0_data = {
|
|
|
+ .setup = l2x0_of_setup,
|
|
|
+ .save = NULL,
|
|
|
+ .outer_cache = {
|
|
|
+ .resume = l2x0_resume,
|
|
|
+ .inv_range = l2x0_inv_range,
|
|
|
+ .clean_range = l2x0_clean_range,
|
|
|
+ .flush_range = l2x0_flush_range,
|
|
|
+ .sync = l2x0_cache_sync,
|
|
|
+ .flush_all = l2x0_flush_all,
|
|
|
+ .inv_all = l2x0_inv_all,
|
|
|
+ .disable = l2x0_disable,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static const struct l2x0_of_data aurora_with_outer_data = {
|
|
|
+ .setup = aurora_of_setup,
|
|
|
+ .save = aurora_save,
|
|
|
+ .outer_cache = {
|
|
|
+ .resume = aurora_resume,
|
|
|
+ .inv_range = aurora_inv_range,
|
|
|
+ .clean_range = aurora_clean_range,
|
|
|
+ .flush_range = aurora_flush_range,
|
|
|
+ .sync = l2x0_cache_sync,
|
|
|
+ .flush_all = l2x0_flush_all,
|
|
|
+ .inv_all = l2x0_inv_all,
|
|
|
+ .disable = l2x0_disable,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static const struct l2x0_of_data aurora_no_outer_data = {
|
|
|
+ .setup = aurora_of_setup,
|
|
|
+ .save = aurora_save,
|
|
|
+ .outer_cache = {
|
|
|
+ .resume = aurora_resume,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static const struct of_device_id l2x0_ids[] __initconst = {
|
|
|
+ { .compatible = "arm,pl310-cache", .data = (void *)&pl310_data },
|
|
|
+ { .compatible = "arm,l220-cache", .data = (void *)&l2x0_data },
|
|
|
+ { .compatible = "arm,l210-cache", .data = (void *)&l2x0_data },
|
|
|
+ { .compatible = "marvell,aurora-system-cache",
|
|
|
+ .data = (void *)&aurora_no_outer_data},
|
|
|
+ { .compatible = "marvell,aurora-outer-cache",
|
|
|
+ .data = (void *)&aurora_with_outer_data},
|
|
|
+ {}
|
|
|
+};
|
|
|
+
|
|
|
+int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
|
|
|
+{
|
|
|
+ struct device_node *np;
|
|
|
+ const struct l2x0_of_data *data;
|
|
|
+ struct resource res;
|
|
|
+
|
|
|
+ np = of_find_matching_node(NULL, l2x0_ids);
|
|
|
+ if (!np)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ if (of_address_to_resource(np, 0, &res))
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ l2x0_base = ioremap(res.start, resource_size(&res));
|
|
|
+ if (!l2x0_base)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ l2x0_saved_regs.phy_base = res.start;
|
|
|
+
|
|
|
+ data = of_match_node(l2x0_ids, np)->data;
|
|
|
+
|
|
|
+ /* L2 configuration can only be changed if the cache is disabled */
|
|
|
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
|
|
|
+ if (data->setup)
|
|
|
+ data->setup(np, &aux_val, &aux_mask);
|
|
|
+
|
|
|
+ /* For aurora cache in no outer mode select the
|
|
|
+ * correct mode using the coprocessor*/
|
|
|
+ if (data == &aurora_no_outer_data)
|
|
|
+ aurora_broadcast_l2_commands();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (data->save)
|
|
|
+ data->save();
|
|
|
+
|
|
|
+ of_init = true;
|
|
|
+ l2x0_init(l2x0_base, aux_val, aux_mask);
|
|
|
+
|
|
|
+ memcpy(&outer_cache, &data->outer_cache, sizeof(outer_cache));
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+#endif
|