1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #pragma once
6 
7 #include <ddk/debug.h>
8 #include <ddk/driver.h>
9 #include <ddk/platform-defs.h>
10 #include <ddk/protocol/platform-device-lib.h>
11 #include <ddk/protocol/platform/device.h>
12 #include <ddktl/device.h>
13 #include <ddktl/mmio.h>
14 #include <ddktl/pdev.h>
15 #include <ddktl/protocol/mailbox.h>
16 #include <hw/reg.h>
17 #include <lib/sync/completion.h>
18 #include <lib/zx/interrupt.h>
19 #include <threads.h>
20 
21 #include <optional>
22 
23 #define GET_NUM_WORDS(x) ((x) / 4 + (((x) % 4) ? 1 : 0))
24 
25 namespace mailbox {
26 
27 class AmlMailbox;
28 using DeviceType = ddk::Device<AmlMailbox, ddk::Unbindable>;
29 
30 class AmlMailbox : public DeviceType,
31                    public ddk::MailboxProtocol<AmlMailbox, ddk::base_protocol> {
32 public:
33     DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(AmlMailbox);
34 
AmlMailbox(zx_device_t * parent)35     explicit AmlMailbox(zx_device_t* parent)
36         : DeviceType(parent), pdev_(parent) {}
37 
38     static zx_status_t Create(zx_device_t* parent);
39 
40     // DDK Hooks.
41     void DdkRelease();
42     void DdkUnbind();
43 
44     // ZX_PROTOCOL_MAILBOX protocol.
45     zx_status_t MailboxSendCommand(const mailbox_channel_t* channel,
46                                    const mailbox_data_buf_t* mdata);
47 
48 private:
49     static constexpr uint32_t kNumMailboxes = 6;
50 
51     // MMIO Indexes
52     enum {
53         MMIO_MAILBOX,
54         MMIO_MAILBOX_PAYLOAD,
55     };
56 
57     // IRQ Indexes
58     enum {
59         MAILBOX_IRQ_RECEIV0,
60         MAILBOX_IRQ_RECEIV1,
61         MAILBOX_IRQ_RECEIV2,
62         MAILBOX_IRQ_SEND3,
63         MAILBOX_IRQ_SEND4,
64         MAILBOX_IRQ_SEND5,
65     };
66 
67     zx_status_t InitPdev();
68     zx_status_t Bind();
69     mailbox_type_t GetRxMailbox(mailbox_type_t tx_mailbox);
70     size_t GetNumWords(size_t size);
71 
72     ddk::PDev pdev_;
73     zx::interrupt inth_[kNumMailboxes];
74     mtx_t mailbox_chan_lock_[kNumMailboxes];
75 
76     std::optional<ddk::MmioBuffer> mailbox_mmio_;
77     std::optional<ddk::MmioBuffer> mailbox_payload_mmio_;
78 };
79 
80 } // namespace mailbox
81