blob: 6c57e170f93ba6ae1244e2592557d1b2ec014918 [file] [log] [blame]
Yangbo Lu9bdf43b2018-04-23 11:55:00 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2013-2016 Freescale Semiconductor Inc.
4 * Copyright 2016-2018 NXP
5 */
6
7#include <linux/module.h>
Yangbo Lud346c9e2019-06-14 18:40:51 +08008#include <linux/of.h>
9#include <linux/of_address.h>
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080010#include <linux/fsl/mc.h>
Yangbo Lud346c9e2019-06-14 18:40:51 +080011#include <linux/fsl/ptp_qoriq.h>
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080012
Yangbo Lu0a006a22018-10-08 15:44:25 +080013#include "dpaa2-ptp.h"
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080014
Yangbo Lud346c9e2019-06-14 18:40:51 +080015static const struct ptp_clock_info dpaa2_ptp_caps = {
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080016 .owner = THIS_MODULE,
17 .name = "DPAA2 PTP Clock",
18 .max_adj = 512000,
19 .n_alarm = 2,
20 .n_ext_ts = 2,
21 .n_per_out = 3,
22 .n_pins = 0,
23 .pps = 1,
Yangbo Lud346c9e2019-06-14 18:40:51 +080024 .adjfine = ptp_qoriq_adjfine,
25 .adjtime = ptp_qoriq_adjtime,
26 .gettime64 = ptp_qoriq_gettime,
27 .settime64 = ptp_qoriq_settime,
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080028};
29
Yangbo Lu180f5392018-10-08 15:44:28 +080030static int dpaa2_ptp_probe(struct fsl_mc_device *mc_dev)
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080031{
32 struct device *dev = &mc_dev->dev;
Yangbo Lud346c9e2019-06-14 18:40:51 +080033 struct ptp_qoriq *ptp_qoriq;
34 struct device_node *node;
35 void __iomem *base;
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080036 int err;
37
Yangbo Lud346c9e2019-06-14 18:40:51 +080038 ptp_qoriq = devm_kzalloc(dev, sizeof(*ptp_qoriq), GFP_KERNEL);
39 if (!ptp_qoriq)
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080040 return -ENOMEM;
41
42 err = fsl_mc_portal_allocate(mc_dev, 0, &mc_dev->mc_io);
43 if (err) {
Ioana Ciornei55005982018-11-09 15:26:46 +000044 if (err == -ENXIO)
45 err = -EPROBE_DEFER;
46 else
47 dev_err(dev, "fsl_mc_portal_allocate err %d\n", err);
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080048 goto err_exit;
49 }
50
51 err = dprtc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
52 &mc_dev->mc_handle);
53 if (err) {
54 dev_err(dev, "dprtc_open err %d\n", err);
55 goto err_free_mcp;
56 }
57
Yangbo Lud346c9e2019-06-14 18:40:51 +080058 ptp_qoriq->dev = dev;
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080059
Yangbo Lud346c9e2019-06-14 18:40:51 +080060 node = of_find_compatible_node(NULL, NULL, "fsl,dpaa2-ptp");
61 if (!node) {
62 err = -ENODEV;
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080063 goto err_close;
64 }
65
Yangbo Lud346c9e2019-06-14 18:40:51 +080066 dev->of_node = node;
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080067
Yangbo Lud346c9e2019-06-14 18:40:51 +080068 base = of_iomap(node, 0);
69 if (!base) {
70 err = -ENOMEM;
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080071 goto err_close;
72 }
73
Yangbo Lud346c9e2019-06-14 18:40:51 +080074 err = ptp_qoriq_init(ptp_qoriq, base, &dpaa2_ptp_caps);
75 if (err)
76 goto err_unmap;
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080077
Yangbo Lud346c9e2019-06-14 18:40:51 +080078 dpaa2_phc_index = ptp_qoriq->phc_index;
79 dev_set_drvdata(dev, ptp_qoriq);
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080080
81 return 0;
82
Yangbo Lud346c9e2019-06-14 18:40:51 +080083err_unmap:
84 iounmap(base);
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080085err_close:
86 dprtc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
87err_free_mcp:
88 fsl_mc_portal_free(mc_dev->mc_io);
89err_exit:
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080090 return err;
91}
92
Yangbo Lu180f5392018-10-08 15:44:28 +080093static int dpaa2_ptp_remove(struct fsl_mc_device *mc_dev)
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080094{
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080095 struct device *dev = &mc_dev->dev;
Yangbo Lud346c9e2019-06-14 18:40:51 +080096 struct ptp_qoriq *ptp_qoriq;
Yangbo Lu9bdf43b2018-04-23 11:55:00 +080097
Yangbo Lud346c9e2019-06-14 18:40:51 +080098 ptp_qoriq = dev_get_drvdata(dev);
99
100 dpaa2_phc_index = -1;
101 ptp_qoriq_free(ptp_qoriq);
Yangbo Lu9bdf43b2018-04-23 11:55:00 +0800102
103 dprtc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
104 fsl_mc_portal_free(mc_dev->mc_io);
105
Yangbo Lu9bdf43b2018-04-23 11:55:00 +0800106 return 0;
107}
108
Yangbo Lu180f5392018-10-08 15:44:28 +0800109static const struct fsl_mc_device_id dpaa2_ptp_match_id_table[] = {
Yangbo Lu9bdf43b2018-04-23 11:55:00 +0800110 {
111 .vendor = FSL_MC_VENDOR_FREESCALE,
112 .obj_type = "dprtc",
113 },
114 {}
115};
Yangbo Lu180f5392018-10-08 15:44:28 +0800116MODULE_DEVICE_TABLE(fslmc, dpaa2_ptp_match_id_table);
Yangbo Lu9bdf43b2018-04-23 11:55:00 +0800117
Yangbo Lu180f5392018-10-08 15:44:28 +0800118static struct fsl_mc_driver dpaa2_ptp_drv = {
Yangbo Lu9bdf43b2018-04-23 11:55:00 +0800119 .driver = {
120 .name = KBUILD_MODNAME,
121 .owner = THIS_MODULE,
122 },
Yangbo Lu180f5392018-10-08 15:44:28 +0800123 .probe = dpaa2_ptp_probe,
124 .remove = dpaa2_ptp_remove,
125 .match_id_table = dpaa2_ptp_match_id_table,
Yangbo Lu9bdf43b2018-04-23 11:55:00 +0800126};
127
Yangbo Lu180f5392018-10-08 15:44:28 +0800128module_fsl_mc_driver(dpaa2_ptp_drv);
Yangbo Lu9bdf43b2018-04-23 11:55:00 +0800129
130MODULE_LICENSE("GPL v2");
131MODULE_DESCRIPTION("DPAA2 PTP Clock Driver");