Commit 5e1ff6480fbe7cf1b2be1f8a13086b217b2f8578
1 parent
ac206a0f4e
Exists in
smarc_8mq_lf_v2020.04
and in
17 other branches
dm: mailbox: Update uclass to support livetree
Update the mailbox uclass to support livetree. Fix the xlate() method in all callers. Signed-off-by: Simon Glass <sjg@chromium.org>
Showing 3 changed files with 10 additions and 14 deletions Inline Diff
drivers/mailbox/mailbox-uclass.c
1 | /* | 1 | /* |
2 | * Copyright (c) 2016, NVIDIA CORPORATION. | 2 | * Copyright (c) 2016, NVIDIA CORPORATION. |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0 | 4 | * SPDX-License-Identifier: GPL-2.0 |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <common.h> | 7 | #include <common.h> |
8 | #include <dm.h> | 8 | #include <dm.h> |
9 | #include <fdtdec.h> | ||
10 | #include <mailbox.h> | 9 | #include <mailbox.h> |
11 | #include <mailbox-uclass.h> | 10 | #include <mailbox-uclass.h> |
12 | 11 | ||
13 | DECLARE_GLOBAL_DATA_PTR; | 12 | DECLARE_GLOBAL_DATA_PTR; |
14 | 13 | ||
15 | static inline struct mbox_ops *mbox_dev_ops(struct udevice *dev) | 14 | static inline struct mbox_ops *mbox_dev_ops(struct udevice *dev) |
16 | { | 15 | { |
17 | return (struct mbox_ops *)dev->driver->ops; | 16 | return (struct mbox_ops *)dev->driver->ops; |
18 | } | 17 | } |
19 | 18 | ||
20 | static int mbox_of_xlate_default(struct mbox_chan *chan, | 19 | static int mbox_of_xlate_default(struct mbox_chan *chan, |
21 | struct fdtdec_phandle_args *args) | 20 | struct ofnode_phandle_args *args) |
22 | { | 21 | { |
23 | debug("%s(chan=%p)\n", __func__, chan); | 22 | debug("%s(chan=%p)\n", __func__, chan); |
24 | 23 | ||
25 | if (args->args_count != 1) { | 24 | if (args->args_count != 1) { |
26 | debug("Invaild args_count: %d\n", args->args_count); | 25 | debug("Invaild args_count: %d\n", args->args_count); |
27 | return -EINVAL; | 26 | return -EINVAL; |
28 | } | 27 | } |
29 | 28 | ||
30 | chan->id = args->args[0]; | 29 | chan->id = args->args[0]; |
31 | 30 | ||
32 | return 0; | 31 | return 0; |
33 | } | 32 | } |
34 | 33 | ||
35 | int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan) | 34 | int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan) |
36 | { | 35 | { |
37 | struct fdtdec_phandle_args args; | 36 | struct ofnode_phandle_args args; |
38 | int ret; | 37 | int ret; |
39 | struct udevice *dev_mbox; | 38 | struct udevice *dev_mbox; |
40 | struct mbox_ops *ops; | 39 | struct mbox_ops *ops; |
41 | 40 | ||
42 | debug("%s(dev=%p, index=%d, chan=%p)\n", __func__, dev, index, chan); | 41 | debug("%s(dev=%p, index=%d, chan=%p)\n", __func__, dev, index, chan); |
43 | 42 | ||
44 | ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev), | 43 | ret = dev_read_phandle_with_args(dev, "mboxes", "#mbox-cells", 0, index, |
45 | "mboxes", "#mbox-cells", 0, | 44 | &args); |
46 | index, &args); | ||
47 | if (ret) { | 45 | if (ret) { |
48 | debug("%s: fdtdec_parse_phandle_with_args failed: %d\n", | 46 | debug("%s: dev_read_phandle_with_args failed: %d\n", __func__, |
49 | __func__, ret); | 47 | ret); |
50 | return ret; | 48 | return ret; |
51 | } | 49 | } |
52 | 50 | ||
53 | ret = uclass_get_device_by_of_offset(UCLASS_MAILBOX, args.node, | 51 | ret = uclass_get_device_by_ofnode(UCLASS_MAILBOX, args.node, &dev_mbox); |
54 | &dev_mbox); | ||
55 | if (ret) { | 52 | if (ret) { |
56 | debug("%s: uclass_get_device_by_of_offset failed: %d\n", | 53 | debug("%s: uclass_get_device_by_of_offset failed: %d\n", |
57 | __func__, ret); | 54 | __func__, ret); |
58 | return ret; | 55 | return ret; |
59 | } | 56 | } |
60 | ops = mbox_dev_ops(dev_mbox); | 57 | ops = mbox_dev_ops(dev_mbox); |
61 | 58 | ||
62 | chan->dev = dev_mbox; | 59 | chan->dev = dev_mbox; |
63 | if (ops->of_xlate) | 60 | if (ops->of_xlate) |
64 | ret = ops->of_xlate(chan, &args); | 61 | ret = ops->of_xlate(chan, &args); |
65 | else | 62 | else |
66 | ret = mbox_of_xlate_default(chan, &args); | 63 | ret = mbox_of_xlate_default(chan, &args); |
67 | if (ret) { | 64 | if (ret) { |
68 | debug("of_xlate() failed: %d\n", ret); | 65 | debug("of_xlate() failed: %d\n", ret); |
69 | return ret; | 66 | return ret; |
70 | } | 67 | } |
71 | 68 | ||
72 | ret = ops->request(chan); | 69 | ret = ops->request(chan); |
73 | if (ret) { | 70 | if (ret) { |
74 | debug("ops->request() failed: %d\n", ret); | 71 | debug("ops->request() failed: %d\n", ret); |
75 | return ret; | 72 | return ret; |
76 | } | 73 | } |
77 | 74 | ||
78 | return 0; | 75 | return 0; |
79 | } | 76 | } |
80 | 77 | ||
81 | int mbox_get_by_name(struct udevice *dev, const char *name, | 78 | int mbox_get_by_name(struct udevice *dev, const char *name, |
82 | struct mbox_chan *chan) | 79 | struct mbox_chan *chan) |
83 | { | 80 | { |
84 | int index; | 81 | int index; |
85 | 82 | ||
86 | debug("%s(dev=%p, name=%s, chan=%p)\n", __func__, dev, name, chan); | 83 | debug("%s(dev=%p, name=%s, chan=%p)\n", __func__, dev, name, chan); |
87 | 84 | ||
88 | index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev), | 85 | index = dev_read_stringlist_search(dev, "mbox-names", name); |
89 | "mbox-names", name); | ||
90 | if (index < 0) { | 86 | if (index < 0) { |
91 | debug("fdt_stringlist_search() failed: %d\n", index); | 87 | debug("fdt_stringlist_search() failed: %d\n", index); |
92 | return index; | 88 | return index; |
93 | } | 89 | } |
94 | 90 | ||
95 | return mbox_get_by_index(dev, index, chan); | 91 | return mbox_get_by_index(dev, index, chan); |
96 | } | 92 | } |
97 | 93 | ||
98 | int mbox_free(struct mbox_chan *chan) | 94 | int mbox_free(struct mbox_chan *chan) |
99 | { | 95 | { |
100 | struct mbox_ops *ops = mbox_dev_ops(chan->dev); | 96 | struct mbox_ops *ops = mbox_dev_ops(chan->dev); |
101 | 97 | ||
102 | debug("%s(chan=%p)\n", __func__, chan); | 98 | debug("%s(chan=%p)\n", __func__, chan); |
103 | 99 | ||
104 | return ops->free(chan); | 100 | return ops->free(chan); |
105 | } | 101 | } |
106 | 102 | ||
107 | int mbox_send(struct mbox_chan *chan, const void *data) | 103 | int mbox_send(struct mbox_chan *chan, const void *data) |
108 | { | 104 | { |
109 | struct mbox_ops *ops = mbox_dev_ops(chan->dev); | 105 | struct mbox_ops *ops = mbox_dev_ops(chan->dev); |
110 | 106 | ||
111 | debug("%s(chan=%p, data=%p)\n", __func__, chan, data); | 107 | debug("%s(chan=%p, data=%p)\n", __func__, chan, data); |
112 | 108 | ||
113 | return ops->send(chan, data); | 109 | return ops->send(chan, data); |
114 | } | 110 | } |
115 | 111 | ||
116 | int mbox_recv(struct mbox_chan *chan, void *data, ulong timeout_us) | 112 | int mbox_recv(struct mbox_chan *chan, void *data, ulong timeout_us) |
117 | { | 113 | { |
118 | struct mbox_ops *ops = mbox_dev_ops(chan->dev); | 114 | struct mbox_ops *ops = mbox_dev_ops(chan->dev); |
119 | ulong start_time; | 115 | ulong start_time; |
120 | int ret; | 116 | int ret; |
121 | 117 | ||
122 | debug("%s(chan=%p, data=%p, timeout_us=%ld)\n", __func__, chan, data, | 118 | debug("%s(chan=%p, data=%p, timeout_us=%ld)\n", __func__, chan, data, |
123 | timeout_us); | 119 | timeout_us); |
124 | 120 | ||
125 | start_time = timer_get_us(); | 121 | start_time = timer_get_us(); |
126 | /* | 122 | /* |
127 | * Account for partial us ticks, but if timeout_us is 0, ensure we | 123 | * Account for partial us ticks, but if timeout_us is 0, ensure we |
128 | * still don't wait at all. | 124 | * still don't wait at all. |
129 | */ | 125 | */ |
130 | if (timeout_us) | 126 | if (timeout_us) |
131 | timeout_us++; | 127 | timeout_us++; |
132 | 128 | ||
133 | for (;;) { | 129 | for (;;) { |
134 | ret = ops->recv(chan, data); | 130 | ret = ops->recv(chan, data); |
135 | if (ret != -ENODATA) | 131 | if (ret != -ENODATA) |
136 | return ret; | 132 | return ret; |
137 | if ((timer_get_us() - start_time) >= timeout_us) | 133 | if ((timer_get_us() - start_time) >= timeout_us) |
138 | return -ETIMEDOUT; | 134 | return -ETIMEDOUT; |
139 | } | 135 | } |
140 | } | 136 | } |
141 | 137 | ||
142 | UCLASS_DRIVER(mailbox) = { | 138 | UCLASS_DRIVER(mailbox) = { |
143 | .id = UCLASS_MAILBOX, | 139 | .id = UCLASS_MAILBOX, |
144 | .name = "mailbox", | 140 | .name = "mailbox", |
145 | }; | 141 | }; |
146 | 142 |
drivers/mailbox/tegra-hsp.c
1 | /* | 1 | /* |
2 | * Copyright (c) 2016, NVIDIA CORPORATION. | 2 | * Copyright (c) 2016, NVIDIA CORPORATION. |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0 | 4 | * SPDX-License-Identifier: GPL-2.0 |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <common.h> | 7 | #include <common.h> |
8 | #include <asm/io.h> | 8 | #include <asm/io.h> |
9 | #include <dm.h> | 9 | #include <dm.h> |
10 | #include <mailbox-uclass.h> | 10 | #include <mailbox-uclass.h> |
11 | #include <dt-bindings/mailbox/tegra186-hsp.h> | 11 | #include <dt-bindings/mailbox/tegra186-hsp.h> |
12 | 12 | ||
13 | #define TEGRA_HSP_INT_DIMENSIONING 0x380 | 13 | #define TEGRA_HSP_INT_DIMENSIONING 0x380 |
14 | #define TEGRA_HSP_INT_DIMENSIONING_NSI_SHIFT 16 | 14 | #define TEGRA_HSP_INT_DIMENSIONING_NSI_SHIFT 16 |
15 | #define TEGRA_HSP_INT_DIMENSIONING_NSI_MASK 0xf | 15 | #define TEGRA_HSP_INT_DIMENSIONING_NSI_MASK 0xf |
16 | #define TEGRA_HSP_INT_DIMENSIONING_NDB_SHIFT 12 | 16 | #define TEGRA_HSP_INT_DIMENSIONING_NDB_SHIFT 12 |
17 | #define TEGRA_HSP_INT_DIMENSIONING_NDB_MASK 0xf | 17 | #define TEGRA_HSP_INT_DIMENSIONING_NDB_MASK 0xf |
18 | #define TEGRA_HSP_INT_DIMENSIONING_NAS_SHIFT 8 | 18 | #define TEGRA_HSP_INT_DIMENSIONING_NAS_SHIFT 8 |
19 | #define TEGRA_HSP_INT_DIMENSIONING_NAS_MASK 0xf | 19 | #define TEGRA_HSP_INT_DIMENSIONING_NAS_MASK 0xf |
20 | #define TEGRA_HSP_INT_DIMENSIONING_NSS_SHIFT 4 | 20 | #define TEGRA_HSP_INT_DIMENSIONING_NSS_SHIFT 4 |
21 | #define TEGRA_HSP_INT_DIMENSIONING_NSS_MASK 0xf | 21 | #define TEGRA_HSP_INT_DIMENSIONING_NSS_MASK 0xf |
22 | #define TEGRA_HSP_INT_DIMENSIONING_NSM_SHIFT 0 | 22 | #define TEGRA_HSP_INT_DIMENSIONING_NSM_SHIFT 0 |
23 | #define TEGRA_HSP_INT_DIMENSIONING_NSM_MASK 0xf | 23 | #define TEGRA_HSP_INT_DIMENSIONING_NSM_MASK 0xf |
24 | 24 | ||
25 | #define TEGRA_HSP_DB_REG_TRIGGER 0x0 | 25 | #define TEGRA_HSP_DB_REG_TRIGGER 0x0 |
26 | #define TEGRA_HSP_DB_REG_ENABLE 0x4 | 26 | #define TEGRA_HSP_DB_REG_ENABLE 0x4 |
27 | #define TEGRA_HSP_DB_REG_RAW 0x8 | 27 | #define TEGRA_HSP_DB_REG_RAW 0x8 |
28 | #define TEGRA_HSP_DB_REG_PENDING 0xc | 28 | #define TEGRA_HSP_DB_REG_PENDING 0xc |
29 | 29 | ||
30 | #define TEGRA_HSP_DB_ID_CCPLEX 1 | 30 | #define TEGRA_HSP_DB_ID_CCPLEX 1 |
31 | #define TEGRA_HSP_DB_ID_BPMP 3 | 31 | #define TEGRA_HSP_DB_ID_BPMP 3 |
32 | #define TEGRA_HSP_DB_ID_NUM 7 | 32 | #define TEGRA_HSP_DB_ID_NUM 7 |
33 | 33 | ||
34 | struct tegra_hsp { | 34 | struct tegra_hsp { |
35 | fdt_addr_t regs; | 35 | fdt_addr_t regs; |
36 | uint32_t db_base; | 36 | uint32_t db_base; |
37 | }; | 37 | }; |
38 | 38 | ||
39 | DECLARE_GLOBAL_DATA_PTR; | 39 | DECLARE_GLOBAL_DATA_PTR; |
40 | 40 | ||
41 | static uint32_t *tegra_hsp_reg(struct tegra_hsp *thsp, uint32_t db_id, | 41 | static uint32_t *tegra_hsp_reg(struct tegra_hsp *thsp, uint32_t db_id, |
42 | uint32_t reg) | 42 | uint32_t reg) |
43 | { | 43 | { |
44 | return (uint32_t *)(thsp->regs + thsp->db_base + (db_id * 0x100) + reg); | 44 | return (uint32_t *)(thsp->regs + thsp->db_base + (db_id * 0x100) + reg); |
45 | } | 45 | } |
46 | 46 | ||
47 | static uint32_t tegra_hsp_readl(struct tegra_hsp *thsp, uint32_t db_id, | 47 | static uint32_t tegra_hsp_readl(struct tegra_hsp *thsp, uint32_t db_id, |
48 | uint32_t reg) | 48 | uint32_t reg) |
49 | { | 49 | { |
50 | uint32_t *r = tegra_hsp_reg(thsp, db_id, reg); | 50 | uint32_t *r = tegra_hsp_reg(thsp, db_id, reg); |
51 | return readl(r); | 51 | return readl(r); |
52 | } | 52 | } |
53 | 53 | ||
54 | static void tegra_hsp_writel(struct tegra_hsp *thsp, uint32_t val, | 54 | static void tegra_hsp_writel(struct tegra_hsp *thsp, uint32_t val, |
55 | uint32_t db_id, uint32_t reg) | 55 | uint32_t db_id, uint32_t reg) |
56 | { | 56 | { |
57 | uint32_t *r = tegra_hsp_reg(thsp, db_id, reg); | 57 | uint32_t *r = tegra_hsp_reg(thsp, db_id, reg); |
58 | 58 | ||
59 | writel(val, r); | 59 | writel(val, r); |
60 | readl(r); | 60 | readl(r); |
61 | } | 61 | } |
62 | 62 | ||
63 | static int tegra_hsp_db_id(ulong chan_id) | 63 | static int tegra_hsp_db_id(ulong chan_id) |
64 | { | 64 | { |
65 | switch (chan_id) { | 65 | switch (chan_id) { |
66 | case (HSP_MBOX_TYPE_DB << 16) | HSP_DB_MASTER_BPMP: | 66 | case (HSP_MBOX_TYPE_DB << 16) | HSP_DB_MASTER_BPMP: |
67 | return TEGRA_HSP_DB_ID_BPMP; | 67 | return TEGRA_HSP_DB_ID_BPMP; |
68 | default: | 68 | default: |
69 | debug("Invalid channel ID\n"); | 69 | debug("Invalid channel ID\n"); |
70 | return -EINVAL; | 70 | return -EINVAL; |
71 | } | 71 | } |
72 | } | 72 | } |
73 | 73 | ||
74 | static int tegra_hsp_of_xlate(struct mbox_chan *chan, | 74 | static int tegra_hsp_of_xlate(struct mbox_chan *chan, |
75 | struct fdtdec_phandle_args *args) | 75 | struct ofnode_phandle_args *args) |
76 | { | 76 | { |
77 | debug("%s(chan=%p)\n", __func__, chan); | 77 | debug("%s(chan=%p)\n", __func__, chan); |
78 | 78 | ||
79 | if (args->args_count != 2) { | 79 | if (args->args_count != 2) { |
80 | debug("Invaild args_count: %d\n", args->args_count); | 80 | debug("Invaild args_count: %d\n", args->args_count); |
81 | return -EINVAL; | 81 | return -EINVAL; |
82 | } | 82 | } |
83 | 83 | ||
84 | chan->id = (args->args[0] << 16) | args->args[1]; | 84 | chan->id = (args->args[0] << 16) | args->args[1]; |
85 | 85 | ||
86 | return 0; | 86 | return 0; |
87 | } | 87 | } |
88 | 88 | ||
89 | static int tegra_hsp_request(struct mbox_chan *chan) | 89 | static int tegra_hsp_request(struct mbox_chan *chan) |
90 | { | 90 | { |
91 | int db_id; | 91 | int db_id; |
92 | 92 | ||
93 | debug("%s(chan=%p)\n", __func__, chan); | 93 | debug("%s(chan=%p)\n", __func__, chan); |
94 | 94 | ||
95 | db_id = tegra_hsp_db_id(chan->id); | 95 | db_id = tegra_hsp_db_id(chan->id); |
96 | if (db_id < 0) { | 96 | if (db_id < 0) { |
97 | debug("tegra_hsp_db_id() failed: %d\n", db_id); | 97 | debug("tegra_hsp_db_id() failed: %d\n", db_id); |
98 | return -EINVAL; | 98 | return -EINVAL; |
99 | } | 99 | } |
100 | 100 | ||
101 | return 0; | 101 | return 0; |
102 | } | 102 | } |
103 | 103 | ||
104 | static int tegra_hsp_free(struct mbox_chan *chan) | 104 | static int tegra_hsp_free(struct mbox_chan *chan) |
105 | { | 105 | { |
106 | debug("%s(chan=%p)\n", __func__, chan); | 106 | debug("%s(chan=%p)\n", __func__, chan); |
107 | 107 | ||
108 | return 0; | 108 | return 0; |
109 | } | 109 | } |
110 | 110 | ||
111 | static int tegra_hsp_send(struct mbox_chan *chan, const void *data) | 111 | static int tegra_hsp_send(struct mbox_chan *chan, const void *data) |
112 | { | 112 | { |
113 | struct tegra_hsp *thsp = dev_get_priv(chan->dev); | 113 | struct tegra_hsp *thsp = dev_get_priv(chan->dev); |
114 | int db_id; | 114 | int db_id; |
115 | 115 | ||
116 | debug("%s(chan=%p, data=%p)\n", __func__, chan, data); | 116 | debug("%s(chan=%p, data=%p)\n", __func__, chan, data); |
117 | 117 | ||
118 | db_id = tegra_hsp_db_id(chan->id); | 118 | db_id = tegra_hsp_db_id(chan->id); |
119 | tegra_hsp_writel(thsp, 1, db_id, TEGRA_HSP_DB_REG_TRIGGER); | 119 | tegra_hsp_writel(thsp, 1, db_id, TEGRA_HSP_DB_REG_TRIGGER); |
120 | 120 | ||
121 | return 0; | 121 | return 0; |
122 | } | 122 | } |
123 | 123 | ||
124 | static int tegra_hsp_recv(struct mbox_chan *chan, void *data) | 124 | static int tegra_hsp_recv(struct mbox_chan *chan, void *data) |
125 | { | 125 | { |
126 | struct tegra_hsp *thsp = dev_get_priv(chan->dev); | 126 | struct tegra_hsp *thsp = dev_get_priv(chan->dev); |
127 | uint32_t db_id = TEGRA_HSP_DB_ID_CCPLEX; | 127 | uint32_t db_id = TEGRA_HSP_DB_ID_CCPLEX; |
128 | uint32_t val; | 128 | uint32_t val; |
129 | 129 | ||
130 | debug("%s(chan=%p, data=%p)\n", __func__, chan, data); | 130 | debug("%s(chan=%p, data=%p)\n", __func__, chan, data); |
131 | 131 | ||
132 | val = tegra_hsp_readl(thsp, db_id, TEGRA_HSP_DB_REG_RAW); | 132 | val = tegra_hsp_readl(thsp, db_id, TEGRA_HSP_DB_REG_RAW); |
133 | if (!(val & BIT(chan->id))) | 133 | if (!(val & BIT(chan->id))) |
134 | return -ENODATA; | 134 | return -ENODATA; |
135 | 135 | ||
136 | tegra_hsp_writel(thsp, BIT(chan->id), db_id, TEGRA_HSP_DB_REG_RAW); | 136 | tegra_hsp_writel(thsp, BIT(chan->id), db_id, TEGRA_HSP_DB_REG_RAW); |
137 | 137 | ||
138 | return 0; | 138 | return 0; |
139 | } | 139 | } |
140 | 140 | ||
141 | static int tegra_hsp_bind(struct udevice *dev) | 141 | static int tegra_hsp_bind(struct udevice *dev) |
142 | { | 142 | { |
143 | debug("%s(dev=%p)\n", __func__, dev); | 143 | debug("%s(dev=%p)\n", __func__, dev); |
144 | 144 | ||
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
148 | static int tegra_hsp_probe(struct udevice *dev) | 148 | static int tegra_hsp_probe(struct udevice *dev) |
149 | { | 149 | { |
150 | struct tegra_hsp *thsp = dev_get_priv(dev); | 150 | struct tegra_hsp *thsp = dev_get_priv(dev); |
151 | u32 val; | 151 | u32 val; |
152 | int nr_sm, nr_ss, nr_as; | 152 | int nr_sm, nr_ss, nr_as; |
153 | 153 | ||
154 | debug("%s(dev=%p)\n", __func__, dev); | 154 | debug("%s(dev=%p)\n", __func__, dev); |
155 | 155 | ||
156 | thsp->regs = devfdt_get_addr(dev); | 156 | thsp->regs = devfdt_get_addr(dev); |
157 | if (thsp->regs == FDT_ADDR_T_NONE) | 157 | if (thsp->regs == FDT_ADDR_T_NONE) |
158 | return -ENODEV; | 158 | return -ENODEV; |
159 | 159 | ||
160 | val = readl(thsp->regs + TEGRA_HSP_INT_DIMENSIONING); | 160 | val = readl(thsp->regs + TEGRA_HSP_INT_DIMENSIONING); |
161 | nr_sm = (val >> TEGRA_HSP_INT_DIMENSIONING_NSM_SHIFT) & | 161 | nr_sm = (val >> TEGRA_HSP_INT_DIMENSIONING_NSM_SHIFT) & |
162 | TEGRA_HSP_INT_DIMENSIONING_NSM_MASK; | 162 | TEGRA_HSP_INT_DIMENSIONING_NSM_MASK; |
163 | nr_ss = (val >> TEGRA_HSP_INT_DIMENSIONING_NSS_SHIFT) & | 163 | nr_ss = (val >> TEGRA_HSP_INT_DIMENSIONING_NSS_SHIFT) & |
164 | TEGRA_HSP_INT_DIMENSIONING_NSS_MASK; | 164 | TEGRA_HSP_INT_DIMENSIONING_NSS_MASK; |
165 | nr_as = (val >> TEGRA_HSP_INT_DIMENSIONING_NAS_SHIFT) & | 165 | nr_as = (val >> TEGRA_HSP_INT_DIMENSIONING_NAS_SHIFT) & |
166 | TEGRA_HSP_INT_DIMENSIONING_NAS_MASK; | 166 | TEGRA_HSP_INT_DIMENSIONING_NAS_MASK; |
167 | 167 | ||
168 | thsp->db_base = (1 + (nr_sm >> 1) + nr_ss + nr_as) << 16; | 168 | thsp->db_base = (1 + (nr_sm >> 1) + nr_ss + nr_as) << 16; |
169 | 169 | ||
170 | return 0; | 170 | return 0; |
171 | } | 171 | } |
172 | 172 | ||
173 | static const struct udevice_id tegra_hsp_ids[] = { | 173 | static const struct udevice_id tegra_hsp_ids[] = { |
174 | { .compatible = "nvidia,tegra186-hsp" }, | 174 | { .compatible = "nvidia,tegra186-hsp" }, |
175 | { } | 175 | { } |
176 | }; | 176 | }; |
177 | 177 | ||
178 | struct mbox_ops tegra_hsp_mbox_ops = { | 178 | struct mbox_ops tegra_hsp_mbox_ops = { |
179 | .of_xlate = tegra_hsp_of_xlate, | 179 | .of_xlate = tegra_hsp_of_xlate, |
180 | .request = tegra_hsp_request, | 180 | .request = tegra_hsp_request, |
181 | .free = tegra_hsp_free, | 181 | .free = tegra_hsp_free, |
182 | .send = tegra_hsp_send, | 182 | .send = tegra_hsp_send, |
183 | .recv = tegra_hsp_recv, | 183 | .recv = tegra_hsp_recv, |
184 | }; | 184 | }; |
185 | 185 | ||
186 | U_BOOT_DRIVER(tegra_hsp) = { | 186 | U_BOOT_DRIVER(tegra_hsp) = { |
187 | .name = "tegra-hsp", | 187 | .name = "tegra-hsp", |
188 | .id = UCLASS_MAILBOX, | 188 | .id = UCLASS_MAILBOX, |
189 | .of_match = tegra_hsp_ids, | 189 | .of_match = tegra_hsp_ids, |
190 | .bind = tegra_hsp_bind, | 190 | .bind = tegra_hsp_bind, |
191 | .probe = tegra_hsp_probe, | 191 | .probe = tegra_hsp_probe, |
192 | .priv_auto_alloc_size = sizeof(struct tegra_hsp), | 192 | .priv_auto_alloc_size = sizeof(struct tegra_hsp), |
193 | .ops = &tegra_hsp_mbox_ops, | 193 | .ops = &tegra_hsp_mbox_ops, |
194 | }; | 194 | }; |
195 | 195 |
include/mailbox-uclass.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2016, NVIDIA CORPORATION. | 2 | * Copyright (c) 2016, NVIDIA CORPORATION. |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0 | 4 | * SPDX-License-Identifier: GPL-2.0 |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef _MAILBOX_UCLASS_H | 7 | #ifndef _MAILBOX_UCLASS_H |
8 | #define _MAILBOX_UCLASS_H | 8 | #define _MAILBOX_UCLASS_H |
9 | 9 | ||
10 | /* See mailbox.h for background documentation. */ | 10 | /* See mailbox.h for background documentation. */ |
11 | 11 | ||
12 | #include <mailbox.h> | 12 | #include <mailbox.h> |
13 | 13 | ||
14 | struct udevice; | 14 | struct udevice; |
15 | 15 | ||
16 | /** | 16 | /** |
17 | * struct mbox_ops - The functions that a mailbox driver must implement. | 17 | * struct mbox_ops - The functions that a mailbox driver must implement. |
18 | */ | 18 | */ |
19 | struct mbox_ops { | 19 | struct mbox_ops { |
20 | /** | 20 | /** |
21 | * of_xlate - Translate a client's device-tree (OF) mailbox specifier. | 21 | * of_xlate - Translate a client's device-tree (OF) mailbox specifier. |
22 | * | 22 | * |
23 | * The mailbox core calls this function as the first step in | 23 | * The mailbox core calls this function as the first step in |
24 | * implementing a client's mbox_get_by_*() call. | 24 | * implementing a client's mbox_get_by_*() call. |
25 | * | 25 | * |
26 | * If this function pointer is set to NULL, the mailbox core will use | 26 | * If this function pointer is set to NULL, the mailbox core will use |
27 | * a default implementation, which assumes #mbox-cells = <1>, and that | 27 | * a default implementation, which assumes #mbox-cells = <1>, and that |
28 | * the DT cell contains a simple integer channel ID. | 28 | * the DT cell contains a simple integer channel ID. |
29 | * | 29 | * |
30 | * At present, the mailbox API solely supports device-tree. If this | 30 | * At present, the mailbox API solely supports device-tree. If this |
31 | * changes, other xxx_xlate() functions may be added to support those | 31 | * changes, other xxx_xlate() functions may be added to support those |
32 | * other mechanisms. | 32 | * other mechanisms. |
33 | * | 33 | * |
34 | * @chan: The channel to hold the translation result. | 34 | * @chan: The channel to hold the translation result. |
35 | * @args: The mailbox specifier values from device tree. | 35 | * @args: The mailbox specifier values from device tree. |
36 | * @return 0 if OK, or a negative error code. | 36 | * @return 0 if OK, or a negative error code. |
37 | */ | 37 | */ |
38 | int (*of_xlate)(struct mbox_chan *chan, | 38 | int (*of_xlate)(struct mbox_chan *chan, |
39 | struct fdtdec_phandle_args *args); | 39 | struct ofnode_phandle_args *args); |
40 | /** | 40 | /** |
41 | * request - Request a translated channel. | 41 | * request - Request a translated channel. |
42 | * | 42 | * |
43 | * The mailbox core calls this function as the second step in | 43 | * The mailbox core calls this function as the second step in |
44 | * implementing a client's mbox_get_by_*() call, following a successful | 44 | * implementing a client's mbox_get_by_*() call, following a successful |
45 | * xxx_xlate() call. | 45 | * xxx_xlate() call. |
46 | * | 46 | * |
47 | * @chan: The channel to request; this has been filled in by a | 47 | * @chan: The channel to request; this has been filled in by a |
48 | * previoux xxx_xlate() function call. | 48 | * previoux xxx_xlate() function call. |
49 | * @return 0 if OK, or a negative error code. | 49 | * @return 0 if OK, or a negative error code. |
50 | */ | 50 | */ |
51 | int (*request)(struct mbox_chan *chan); | 51 | int (*request)(struct mbox_chan *chan); |
52 | /** | 52 | /** |
53 | * free - Free a previously requested channel. | 53 | * free - Free a previously requested channel. |
54 | * | 54 | * |
55 | * This is the implementation of the client mbox_free() API. | 55 | * This is the implementation of the client mbox_free() API. |
56 | * | 56 | * |
57 | * @chan: The channel to free. | 57 | * @chan: The channel to free. |
58 | * @return 0 if OK, or a negative error code. | 58 | * @return 0 if OK, or a negative error code. |
59 | */ | 59 | */ |
60 | int (*free)(struct mbox_chan *chan); | 60 | int (*free)(struct mbox_chan *chan); |
61 | /** | 61 | /** |
62 | * send - Send a message over a mailbox channel | 62 | * send - Send a message over a mailbox channel |
63 | * | 63 | * |
64 | * @chan: The channel to send to the message to. | 64 | * @chan: The channel to send to the message to. |
65 | * @data: A pointer to the message to send. | 65 | * @data: A pointer to the message to send. |
66 | * @return 0 if OK, or a negative error code. | 66 | * @return 0 if OK, or a negative error code. |
67 | */ | 67 | */ |
68 | int (*send)(struct mbox_chan *chan, const void *data); | 68 | int (*send)(struct mbox_chan *chan, const void *data); |
69 | /** | 69 | /** |
70 | * recv - Receive any available message from the channel. | 70 | * recv - Receive any available message from the channel. |
71 | * | 71 | * |
72 | * This function does not block. If not message is immediately | 72 | * This function does not block. If not message is immediately |
73 | * available, the function should return an error. | 73 | * available, the function should return an error. |
74 | * | 74 | * |
75 | * @chan: The channel to receive to the message from. | 75 | * @chan: The channel to receive to the message from. |
76 | * @data: A pointer to the buffer to hold the received message. | 76 | * @data: A pointer to the buffer to hold the received message. |
77 | * @return 0 if OK, -ENODATA if no message was available, or a negative | 77 | * @return 0 if OK, -ENODATA if no message was available, or a negative |
78 | * error code. | 78 | * error code. |
79 | */ | 79 | */ |
80 | int (*recv)(struct mbox_chan *chan, void *data); | 80 | int (*recv)(struct mbox_chan *chan, void *data); |
81 | }; | 81 | }; |
82 | 82 | ||
83 | #endif | 83 | #endif |
84 | 84 |