1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/pkg/devices/lib/dma/include/dma-jz4730.h Sun Jan 10 22:21:57 2021 +0100
1.3 @@ -0,0 +1,217 @@
1.4 +/*
1.5 + * DMA support for the JZ4730.
1.6 + *
1.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk>
1.8 + *
1.9 + * This program is free software; you can redistribute it and/or
1.10 + * modify it under the terms of the GNU General Public License as
1.11 + * published by the Free Software Foundation; either version 2 of
1.12 + * the License, or (at your option) any later version.
1.13 + *
1.14 + * This program is distributed in the hope that it will be useful,
1.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.17 + * GNU General Public License for more details.
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License
1.20 + * along with this program; if not, write to the Free Software
1.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
1.22 + * Boston, MA 02110-1301, USA
1.23 + */
1.24 +
1.25 +#pragma once
1.26 +
1.27 +#include <l4/sys/types.h>
1.28 +#include <stdint.h>
1.29 +
1.30 +
1.31 +
1.32 +/* Enumerated types for various transfer parameters. */
1.33 +
1.34 +enum Dma_jz4730_request_type : unsigned
1.35 +{
1.36 + Dma_request_external = 0,
1.37 + Dma_request_pcmcia_out = 4,
1.38 + Dma_request_pcmcia_in = 5,
1.39 + Dma_request_auto = 8,
1.40 + Dma_request_des_out = 10,
1.41 + Dma_request_des_in = 11,
1.42 + Dma_request_uart3_out = 14,
1.43 + Dma_request_uart3_in = 15,
1.44 + Dma_request_uart2_out = 16,
1.45 + Dma_request_uart2_in = 17,
1.46 + Dma_request_uart1_out = 18,
1.47 + Dma_request_uart1_in = 19,
1.48 + Dma_request_uart0_out = 20,
1.49 + Dma_request_uart0_in = 21,
1.50 + Dma_request_ssi_send_empty = 22,
1.51 + Dma_request_ssi_recv_full = 23,
1.52 + Dma_request_aic_send_empty = 24,
1.53 + Dma_request_aic_recv_full = 25,
1.54 + Dma_request_msc_send_empty = 26,
1.55 + Dma_request_msc_recv_full = 27,
1.56 + Dma_request_ost2_underflow = 28,
1.57 +};
1.58 +
1.59 +enum Dma_jz4730_ext_level : unsigned
1.60 +{
1.61 + Dma_ext_active_high = 0,
1.62 + Dma_ext_active_low = 1,
1.63 +};
1.64 +
1.65 +enum Dma_jz4730_ext_output_mode_cycle : unsigned
1.66 +{
1.67 + Dma_ext_output_mode_read_cycle = 0,
1.68 + Dma_ext_output_mode_write_cycle = 1,
1.69 +};
1.70 +
1.71 +enum Dma_jz4730_ext_req_detect_mode : unsigned
1.72 +{
1.73 + Dma_ext_req_detect_mode_low_level = 0,
1.74 + Dma_ext_req_detect_mode_falling_edge = 1,
1.75 + Dma_ext_req_detect_mode_high_level = 2,
1.76 + Dma_ext_req_detect_mode_rising_edge = 3,
1.77 +};
1.78 +
1.79 +enum Dma_jz4730_trans_unit_size : unsigned
1.80 +{
1.81 + Dma_trans_unit_size_32_bit = 0,
1.82 + Dma_trans_unit_size_8_bit = 1,
1.83 + Dma_trans_unit_size_16_bit = 2,
1.84 + Dma_trans_unit_size_16_byte = 3,
1.85 + Dma_trans_unit_size_32_byte = 4,
1.86 +};
1.87 +
1.88 +
1.89 +
1.90 +#ifdef __cplusplus
1.91 +
1.92 +#include <l4/devices/cpm-jz4730.h>
1.93 +#include <l4/devices/hw_mmio_register_block.h>
1.94 +
1.95 +// Forward declaration.
1.96 +
1.97 +class Dma_jz4730_chip;
1.98 +
1.99 +
1.100 +
1.101 +// DMA channel.
1.102 +
1.103 +class Dma_jz4730_channel
1.104 +{
1.105 +private:
1.106 + Hw::Register_block<32> _regs;
1.107 + Dma_jz4730_chip *_chip;
1.108 + uint8_t _channel;
1.109 + l4_cap_idx_t _irq=L4_INVALID_CAP;
1.110 +
1.111 + // External transfer properties with defaults.
1.112 +
1.113 + enum Dma_jz4730_ext_level _ext_output_polarity = Dma_ext_active_high;
1.114 + enum Dma_jz4730_ext_level _ext_end_of_process_mode = Dma_ext_active_high;
1.115 + enum Dma_jz4730_ext_output_mode_cycle _ext_output_mode_cycle = Dma_ext_output_mode_read_cycle;
1.116 + enum Dma_jz4730_ext_req_detect_mode _ext_req_detect_mode = Dma_ext_req_detect_mode_high_level;
1.117 +
1.118 +public:
1.119 + Dma_jz4730_channel(Dma_jz4730_chip *chip, uint8_t channel, l4_addr_t start, l4_cap_idx_t irq);
1.120 +
1.121 + unsigned int transfer(uint32_t source, uint32_t destination,
1.122 + unsigned int count,
1.123 + enum Dma_jz4730_trans_unit_size size,
1.124 + enum Dma_jz4730_request_type type=Dma_request_auto);
1.125 +
1.126 + // External transfer property configuration.
1.127 +
1.128 + void set_output_polarity(enum Dma_jz4730_ext_level polarity)
1.129 + { _ext_output_polarity = polarity; }
1.130 +
1.131 + void set_end_of_process_mode(enum Dma_jz4730_ext_level mode)
1.132 + { _ext_end_of_process_mode = mode; }
1.133 +
1.134 + void set_output_mode_cycle(enum Dma_jz4730_ext_output_mode_cycle cycle)
1.135 + { _ext_output_mode_cycle = cycle; }
1.136 +
1.137 + void set_req_detect_mode(enum Dma_jz4730_ext_req_detect_mode mode)
1.138 + { _ext_req_detect_mode = mode; }
1.139 +
1.140 +protected:
1.141 + // Transfer property configuration.
1.142 +
1.143 + uint32_t encode_external_transfer(enum Dma_jz4730_request_type type);
1.144 +
1.145 + uint32_t encode_source_address_increment(enum Dma_jz4730_request_type type);
1.146 +
1.147 + uint32_t encode_destination_address_increment(enum Dma_jz4730_request_type type);
1.148 +
1.149 + uint32_t encode_req_detect_int_length(uint8_t units);
1.150 +
1.151 + uint32_t encode_source_port_width(enum Dma_jz4730_request_type type);
1.152 +
1.153 + uint32_t encode_destination_port_width(enum Dma_jz4730_request_type type);
1.154 +
1.155 + // Transaction control.
1.156 +
1.157 + void ack_irq();
1.158 +
1.159 + bool completed();
1.160 +
1.161 + bool error();
1.162 +
1.163 + bool halted();
1.164 +
1.165 + bool wait_for_irq();
1.166 +
1.167 + bool wait_for_irq(unsigned int timeout);
1.168 +};
1.169 +
1.170 +// DMA device control.
1.171 +
1.172 +class Dma_jz4730_chip
1.173 +{
1.174 +private:
1.175 + Hw::Register_block<32> _regs;
1.176 + l4_addr_t _start, _end;
1.177 + Cpm_jz4730_chip *_cpm;
1.178 +
1.179 +public:
1.180 + Dma_jz4730_chip(l4_addr_t start, l4_addr_t end, Cpm_jz4730_chip *cpm);
1.181 +
1.182 + void disable();
1.183 +
1.184 + void enable();
1.185 +
1.186 + Dma_jz4730_channel *get_channel(uint8_t channel, l4_cap_idx_t irq);
1.187 +
1.188 + bool have_interrupt(uint8_t channel);
1.189 +};
1.190 +
1.191 +#endif /* __cplusplus */
1.192 +
1.193 +
1.194 +
1.195 +/* C language interface. */
1.196 +
1.197 +EXTERN_C_BEGIN
1.198 +
1.199 +void *jz4730_dma_init(l4_addr_t start, l4_addr_t end, void *cpm);
1.200 +
1.201 +void jz4730_dma_disable(void *dma_chip);
1.202 +
1.203 +void jz4730_dma_enable(void *dma_chip);
1.204 +
1.205 +void *jz4730_dma_get_channel(void *dma, uint8_t channel, l4_cap_idx_t irq);
1.206 +
1.207 +void jz4730_dma_set_output_polarity(void *dma_channel, enum Dma_jz4730_ext_level polarity);
1.208 +
1.209 +void jz4730_dma_set_end_of_process_mode(void *dma_channel, enum Dma_jz4730_ext_level mode);
1.210 +
1.211 +void jz4730_dma_set_output_mode_cycle(void *dma_channel, enum Dma_jz4730_ext_output_mode_cycle cycle);
1.212 +
1.213 +void jz4730_dma_set_req_detect_mode(void *dma_channel, enum Dma_jz4730_ext_req_detect_mode mode);
1.214 +
1.215 +unsigned int jz4730_dma_transfer(void *dma_channel, uint32_t source,
1.216 + uint32_t destination, unsigned int count,
1.217 + enum Dma_jz4730_trans_unit_size size,
1.218 + enum Dma_jz4730_request_type type);
1.219 +
1.220 +EXTERN_C_END