Lines Matching +full:transfer +full:- +full:function
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
60 * A DMA transfer block consists of a number of frames (FN). Each frame
90 /* Callback function used when an interrupt is tripped on the given channel */
133 #define TI_SDMA_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
134 #define TI_SDMA_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx)
136 mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \
138 #define TI_SDMA_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx);
139 #define TI_SDMA_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED);
140 #define TI_SDMA_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
143 * Function prototypes
149 * ti_sdma_read_4 - reads a 32-bit value from one of the DMA registers
155 * 32-bit value read from the register.
160 return bus_read_4(sc->sc_mem_res, off); in ti_sdma_read_4()
164 * ti_sdma_write_4 - writes a 32-bit value to one of the DMA registers
170 * 32-bit value read from the register.
175 bus_write_4(sc->sc_mem_res, off, val); in ti_sdma_write_4()
179 * ti_sdma_is_omap3_rev - returns true if H/W is from OMAP3 series
186 return (sc->sc_hw_rev == DMA4_OMAP3_REV); in ti_sdma_is_omap3_rev()
190 * ti_sdma_is_omap4_rev - returns true if H/W is from OMAP4 series
197 return (sc->sc_hw_rev == DMA4_OMAP4_REV); in ti_sdma_is_omap4_rev()
201 * ti_sdma_intr - interrupt handler for all 4 DMA IRQs
233 channel = &sc->sc_channel[ch]; in ti_sdma_intr()
238 device_printf(sc->sc_dev, "Spurious DMA IRQ for channel " in ti_sdma_intr()
244 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_intr()
245 device_printf(sc->sc_dev, "IRQ %d for a non-activated " in ti_sdma_intr()
252 device_printf(sc->sc_dev, "Synchronization event drop " in ti_sdma_intr()
253 "occurred during the transfer on channel %u\n", in ti_sdma_intr()
256 device_printf(sc->sc_dev, "Secure transaction error event " in ti_sdma_intr()
259 device_printf(sc->sc_dev, "Misaligned address error event " in ti_sdma_intr()
262 device_printf(sc->sc_dev, "Transaction error event on " in ti_sdma_intr()
277 if (channel->callback) in ti_sdma_intr()
278 channel->callback(ch, csr, channel->callback_data); in ti_sdma_intr()
289 * ti_sdma_activate_channel - activates a DMA channel
291 * @callback: a callback function to associate with the channel
298 * Note this function doesn't enable interrupts, for that you need to call
300 * transfer, you can use ti_sdma_status_poll() to detect a change in the
332 if (sc->sc_active_channels == 0xffffffff) { in ti_sdma_activate_channel()
337 /* Find the first non-active channel */ in ti_sdma_activate_channel()
339 if (!(sc->sc_active_channels & (0x1 << i))) { in ti_sdma_activate_channel()
340 sc->sc_active_channels |= (0x1 << i); in ti_sdma_activate_channel()
347 channel = &sc->sc_channel[*ch]; in ti_sdma_activate_channel()
349 channel->callback = callback; in ti_sdma_activate_channel()
350 channel->callback_data = data; in ti_sdma_activate_channel()
352 channel->need_reg_write = 1; in ti_sdma_activate_channel()
355 channel->reg_csdp = DMA4_CSDP_DATA_TYPE(0x2) in ti_sdma_activate_channel()
364 channel->reg_ccr = DMA4_CCR_DST_ADDRESS_MODE(1) in ti_sdma_activate_channel()
372 channel->reg_cicr = DMA4_CICR_TRANS_ERR_IE in ti_sdma_activate_channel()
387 * ti_sdma_deactivate_channel - deactivates a channel
412 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_deactivate_channel()
418 sc->sc_active_channels &= ~(1 << ch); in ti_sdma_deactivate_channel()
423 /* Make sure the DMA transfer is stopped. */ in ti_sdma_deactivate_channel()
442 * ti_sdma_disable_channel_irq - disables IRQ's on the given channel
466 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_disable_channel_irq()
472 sc->sc_channel[ch].reg_cicr = 0x0000; in ti_sdma_disable_channel_irq()
484 sc->sc_channel[ch].need_reg_write = 1; in ti_sdma_disable_channel_irq()
492 * ti_sdma_disable_channel_irq - enables IRQ's on the given channel
524 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_enable_channel_irq()
533 sc->sc_channel[ch].reg_cicr = flags; in ti_sdma_enable_channel_irq()
545 sc->sc_channel[ch].need_reg_write = 1; in ti_sdma_enable_channel_irq()
553 * ti_sdma_get_channel_status - returns the status of a given channel
590 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_get_channel_status()
606 * ti_sdma_start_xfer - starts a DMA transfer
612 * or 32-bit value as defined by ti_sdma_set_xfer_burst()
636 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_start_xfer()
641 channel = &sc->sc_channel[ch]; in ti_sdma_start_xfer()
645 channel->reg_csdp | DMA4_CSDP_WRITE_MODE(1)); in ti_sdma_start_xfer()
658 ti_sdma_write_4(sc, DMA4_CCR(ch), channel->reg_ccr); in ti_sdma_start_xfer()
660 /* f) - Set the source element index increment CSEI[15:0] */ in ti_sdma_start_xfer()
663 /* - Set the source frame index increment CSFI[15:0] */ in ti_sdma_start_xfer()
666 /* - Set the destination element index increment CDEI[15:0]*/ in ti_sdma_start_xfer()
669 /* - Set the destination frame index increment CDFI[31:0] */ in ti_sdma_start_xfer()
675 /* Write the start-bit and away we go */ in ti_sdma_start_xfer()
681 channel->need_reg_write = 0; in ti_sdma_start_xfer()
689 * ti_sdma_start_xfer_packet - starts a packet DMA transfer
690 * @ch: the channel number to use for the transfer
693 * @frmcnt: the number of frames to transfer
695 * or 32-bit value as defined by ti_sdma_set_xfer_burst()
696 * @pktsize: the number of elements in each transfer packet
698 * The @frmcnt and @elmcnt define the overall number of bytes to transfer,
701 * packets per transfer. i.e. for the following with element size of 32-bits
705 * Total transfer bytes = 1 * 512 = 512 elements or 2048 bytes
730 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_start_xfer_packet()
735 channel = &sc->sc_channel[ch]; in ti_sdma_start_xfer_packet()
738 if (channel->need_reg_write) in ti_sdma_start_xfer_packet()
740 channel->reg_csdp | DMA4_CSDP_WRITE_MODE(1)); in ti_sdma_start_xfer_packet()
742 /* b) Set the number of elements to transfer CEN[23:0] */ in ti_sdma_start_xfer_packet()
745 /* c) Set the number of frames to transfer CFN[15:0] */ in ti_sdma_start_xfer_packet()
754 channel->reg_ccr | DMA4_CCR_PACKET_TRANS); in ti_sdma_start_xfer_packet()
756 /* f) - Set the source element index increment CSEI[15:0] */ in ti_sdma_start_xfer_packet()
759 /* - Set the packet size, this is dependent on the sync source */ in ti_sdma_start_xfer_packet()
760 if (channel->reg_ccr & DMA4_CCR_SEL_SRC_DST_SYNC(1)) in ti_sdma_start_xfer_packet()
765 /* - Set the destination frame index increment CDFI[31:0] */ in ti_sdma_start_xfer_packet()
771 /* Write the start-bit and away we go */ in ti_sdma_start_xfer_packet()
777 channel->need_reg_write = 0; in ti_sdma_start_xfer_packet()
785 * ti_sdma_stop_xfer - stops any currently active transfers
788 * This function call is effectively a NOP if no transaction is in progress.
808 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_stop_xfer()
816 /* Make sure the DMA transfer is stopped. */ in ti_sdma_stop_xfer()
825 /* Configuration registers need to be re-written on the next xfer */ in ti_sdma_stop_xfer()
826 sc->sc_channel[ch].need_reg_write = 1; in ti_sdma_stop_xfer()
834 * ti_sdma_set_xfer_endianess - sets the endianness of subsequent transfers
857 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_set_xfer_endianess()
862 sc->sc_channel[ch].reg_csdp &= ~DMA4_CSDP_SRC_ENDIANISM(1); in ti_sdma_set_xfer_endianess()
863 sc->sc_channel[ch].reg_csdp |= DMA4_CSDP_SRC_ENDIANISM(src); in ti_sdma_set_xfer_endianess()
865 sc->sc_channel[ch].reg_csdp &= ~DMA4_CSDP_DST_ENDIANISM(1); in ti_sdma_set_xfer_endianess()
866 sc->sc_channel[ch].reg_csdp |= DMA4_CSDP_DST_ENDIANISM(dst); in ti_sdma_set_xfer_endianess()
868 sc->sc_channel[ch].need_reg_write = 1; in ti_sdma_set_xfer_endianess()
876 * ti_sdma_set_xfer_burst - sets the source and destination element size
883 * This function sets the size of the elements for all subsequent transfers.
902 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_set_xfer_burst()
907 sc->sc_channel[ch].reg_csdp &= ~DMA4_CSDP_SRC_BURST_MODE(0x3); in ti_sdma_set_xfer_burst()
908 sc->sc_channel[ch].reg_csdp |= DMA4_CSDP_SRC_BURST_MODE(src); in ti_sdma_set_xfer_burst()
910 sc->sc_channel[ch].reg_csdp &= ~DMA4_CSDP_DST_BURST_MODE(0x3); in ti_sdma_set_xfer_burst()
911 sc->sc_channel[ch].reg_csdp |= DMA4_CSDP_DST_BURST_MODE(dst); in ti_sdma_set_xfer_burst()
913 sc->sc_channel[ch].need_reg_write = 1; in ti_sdma_set_xfer_burst()
921 * ti_sdma_set_xfer_data_type - driver attach function
944 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_set_xfer_data_type()
949 sc->sc_channel[ch].reg_csdp &= ~DMA4_CSDP_DATA_TYPE(0x3); in ti_sdma_set_xfer_data_type()
950 sc->sc_channel[ch].reg_csdp |= DMA4_CSDP_DATA_TYPE(type); in ti_sdma_set_xfer_data_type()
952 sc->sc_channel[ch].need_reg_write = 1; in ti_sdma_set_xfer_data_type()
960 * ti_sdma_set_callback - driver attach function
984 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_set_callback()
989 sc->sc_channel[ch].callback = callback; in ti_sdma_set_callback()
990 sc->sc_channel[ch].callback_data = data; in ti_sdma_set_callback()
992 sc->sc_channel[ch].need_reg_write = 1; in ti_sdma_set_callback()
1000 * ti_sdma_sync_params - sets channel sync settings
1028 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_sync_params()
1033 ccr = sc->sc_channel[ch].reg_ccr; in ti_sdma_sync_params()
1053 sc->sc_channel[ch].reg_ccr = ccr; in ti_sdma_sync_params()
1055 sc->sc_channel[ch].need_reg_write = 1; in ti_sdma_sync_params()
1063 * ti_sdma_set_addr_mode - driver attach function
1092 if ((sc->sc_active_channels & (1 << ch)) == 0) { in ti_sdma_set_addr_mode()
1097 ccr = sc->sc_channel[ch].reg_ccr; in ti_sdma_set_addr_mode()
1105 sc->sc_channel[ch].reg_ccr = ccr; in ti_sdma_set_addr_mode()
1107 sc->sc_channel[ch].need_reg_write = 1; in ti_sdma_set_addr_mode()
1115 * ti_sdma_probe - driver probe function
1130 if (!ofw_bus_is_compatible(dev, "ti,omap4430-sdma")) in ti_sdma_probe()
1138 * ti_sdma_attach - driver attach function
1142 * IRQs. This is effectively the setup function for the driver.
1158 sc->sc_dev = dev; in ti_sdma_attach()
1161 sc->sc_active_channels = 0x00000000; in ti_sdma_attach()
1168 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); in ti_sdma_attach()
1169 if (sc->sc_mem_res == NULL) in ti_sdma_attach()
1176 sc->sc_hw_rev = ti_sdma_read_4(sc, in ti_sdma_attach()
1178 device_printf(dev, "sDMA revision %08x\n", sc->sc_hw_rev); in ti_sdma_attach()
1181 device_printf(sc->sc_dev, "error - unknown sDMA H/W revision\n"); in ti_sdma_attach()
1190 /* Soft-reset is only supported on pre-OMAP44xx devices */ in ti_sdma_attach()
1192 /* Soft-reset */ in ti_sdma_attach()
1203 if (timeout-- == 0) { in ti_sdma_attach()
1204 device_printf(sc->sc_dev, "sDMA reset operation timed out\n"); in ti_sdma_attach()
1215 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in ti_sdma_attach()
1217 if (sc->sc_irq_res == NULL) in ti_sdma_attach()
1220 err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, in ti_sdma_attach()