Module Name: src Committed By: bouyer Date: Mon Apr 4 14:33:51 UTC 2011
Modified Files: src/sys/arch/i386/conf: ALL GENERIC src/sys/dev/pci: files.pci pcidevs Added Files: src/sys/dev/pci: rdcide.c rdcide_reg.h Log Message: Add rdcide(4), a driver for the IDE controller found in RDC's vortex86/PMX-1000 system-on-chip. To generate a diff of this commit: cvs rdiff -u -r1.301 -r1.302 src/sys/arch/i386/conf/ALL cvs rdiff -u -r1.1027 -r1.1028 src/sys/arch/i386/conf/GENERIC cvs rdiff -u -r1.339 -r1.340 src/sys/dev/pci/files.pci cvs rdiff -u -r1.1068 -r1.1069 src/sys/dev/pci/pcidevs cvs rdiff -u -r0 -r1.1 src/sys/dev/pci/rdcide.c src/sys/dev/pci/rdcide_reg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/i386/conf/ALL diff -u src/sys/arch/i386/conf/ALL:1.301 src/sys/arch/i386/conf/ALL:1.302 --- src/sys/arch/i386/conf/ALL:1.301 Sun Mar 6 17:08:25 2011 +++ src/sys/arch/i386/conf/ALL Mon Apr 4 14:33:51 2011 @@ -1,4 +1,4 @@ -# $NetBSD: ALL,v 1.301 2011/03/06 17:08:25 bouyer Exp $ +# $NetBSD: ALL,v 1.302 2011/04/04 14:33:51 bouyer Exp $ # From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp # # ALL machine description file @@ -17,7 +17,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "ALL-$Revision: 1.301 $" +#ident "ALL-$Revision: 1.302 $" maxusers 64 # estimated number of users @@ -900,6 +900,7 @@ pdcide* at pci? dev ? function ? # Promise IDE controllers pdcsata* at pci? dev ? function ? # Promise SATA150 controllers rccide* at pci? dev ? function ? # ServerWorks IDE controllers +rdcide* at pci? dev ? function ? # RDC PMX-1000 IDE controllers satalink* at pci? dev ? function ? # SiI SATALink controllers schide* at pci? dev ? function ? # Intel SCH IDE controllers siisata* at pci? dev ? function ? # SiI SteelVine controllers Index: src/sys/arch/i386/conf/GENERIC diff -u src/sys/arch/i386/conf/GENERIC:1.1027 src/sys/arch/i386/conf/GENERIC:1.1028 --- src/sys/arch/i386/conf/GENERIC:1.1027 Fri Apr 1 12:11:16 2011 +++ src/sys/arch/i386/conf/GENERIC Mon Apr 4 14:33:51 2011 @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.1027 2011/04/01 12:11:16 jruoho Exp $ +# $NetBSD: GENERIC,v 1.1028 2011/04/04 14:33:51 bouyer Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.1027 $" +#ident "GENERIC-$Revision: 1.1028 $" maxusers 64 # estimated number of users @@ -847,6 +847,7 @@ pdcide* at pci? dev ? function ? # Promise IDE controllers pdcsata* at pci? dev ? function ? # Promise SATA150 controllers rccide* at pci? dev ? function ? # ServerWorks IDE controllers +rdcide* at pci? dev ? function ? # RDC PMX-1000 IDE controllers satalink* at pci? dev ? function ? # SiI SATALink controllers schide* at pci? dev ? function ? # Intel SCH IDE controllers siisata* at pci? dev ? function ? # SiI SteelVine controllers Index: src/sys/dev/pci/files.pci diff -u src/sys/dev/pci/files.pci:1.339 src/sys/dev/pci/files.pci:1.340 --- src/sys/dev/pci/files.pci:1.339 Wed Feb 23 00:35:29 2011 +++ src/sys/dev/pci/files.pci Mon Apr 4 14:33:51 2011 @@ -1,4 +1,4 @@ -# $NetBSD: files.pci,v 1.339 2011/02/23 00:35:29 jmcneill Exp $ +# $NetBSD: files.pci,v 1.340 2011/04/04 14:33:51 bouyer Exp $ # # Config file and device description for machine-independent PCI code. # Included by ports that need it. Requires that the SCSI files be @@ -306,6 +306,11 @@ attach rccide at pci file dev/pci/rccide.c rccide +# RDC IDE controllers +device rdcide: ata, ata_dma, ata_udma, pciide_common, wdc_common +attach rdcide at pci +file dev/pci/rdcide.c rdcide + # ServerWorks SATA controllers device svwsata: ata, ata_dma, ata_udma, pciide_common, wdc_common, sata attach svwsata at pci Index: src/sys/dev/pci/pcidevs diff -u src/sys/dev/pci/pcidevs:1.1068 src/sys/dev/pci/pcidevs:1.1069 --- src/sys/dev/pci/pcidevs:1.1068 Wed Mar 16 23:19:32 2011 +++ src/sys/dev/pci/pcidevs Mon Apr 4 14:33:51 2011 @@ -1,4 +1,4 @@ -$NetBSD: pcidevs,v 1.1068 2011/03/16 23:19:32 matt Exp $ +$NetBSD: pcidevs,v 1.1069 2011/04/04 14:33:51 bouyer Exp $ /* * Copyright (c) 1995, 1996 Christopher G. Demetriou @@ -3915,6 +3915,7 @@ /* RDC Semiconductor products */ product RDC R6040 0x6040 RDC R6040 10/100 Ethernet +product RDC IDE 0x1011 RDC IDE controller /* Realtek products */ product REALTEK RT8029 0x8029 8029 Ethernet Added files: Index: src/sys/dev/pci/rdcide.c diff -u /dev/null src/sys/dev/pci/rdcide.c:1.1 --- /dev/null Mon Apr 4 14:33:52 2011 +++ src/sys/dev/pci/rdcide.c Mon Apr 4 14:33:51 2011 @@ -0,0 +1,267 @@ +/* $NetBSD: rdcide.c,v 1.1 2011/04/04 14:33:51 bouyer Exp $ */ + +/* + * Copyright (c) 2011 Manuel Bouyer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: rdcide.c,v 1.1 2011/04/04 14:33:51 bouyer Exp $"); + +#include <sys/param.h> +#include <sys/systm.h> + +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> +#include <dev/pci/pciidereg.h> +#include <dev/pci/pciidevar.h> +#include <dev/pci/rdcide_reg.h> + +static void rdcide_chip_map(struct pciide_softc*, struct pci_attach_args *); +static void rdcide_setup_channel(struct ata_channel *); + +static bool rdcide_resume(device_t, const pmf_qual_t *); +static bool rdcide_suspend(device_t, const pmf_qual_t *); +static int rdcide_match(device_t, cfdata_t, void *); +static void rdcide_attach(device_t, device_t, void *); + +static const struct pciide_product_desc pciide_intel_products[] = { + { PCI_PRODUCT_RDC_IDE, + 0, + "RDC IDE controller", + rdcide_chip_map, + }, +}; + +CFATTACH_DECL_NEW(rdcide, sizeof(struct pciide_softc), + rdcide_match, rdcide_attach, NULL, NULL); + +static int +rdcide_match(device_t parent, cfdata_t match, void *aux) +{ + struct pci_attach_args *pa = aux; + + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_RDC) { + if (pciide_lookup_product(pa->pa_id, pciide_intel_products)) + return (2); + } + return (0); +} + +static void +rdcide_attach(device_t parent, device_t self, void *aux) +{ + struct pci_attach_args *pa = aux; + struct pciide_softc *sc = device_private(self); + + sc->sc_wdcdev.sc_atac.atac_dev = self; + + pciide_common_attach(sc, pa, + pciide_lookup_product(pa->pa_id, pciide_intel_products)); + + if (!pmf_device_register(self, rdcide_suspend, rdcide_resume)) + aprint_error_dev(self, "couldn't establish power handler\n"); +} + +static bool +rdcide_resume(device_t dv, const pmf_qual_t *qual) +{ + struct pciide_softc *sc = device_private(dv); + + pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_PATR, + sc->sc_pm_reg[0]); + pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR, + sc->sc_pm_reg[1]); + pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR, + sc->sc_pm_reg[2]); + pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR, + sc->sc_pm_reg[3]); + + return true; +} + +static bool +rdcide_suspend(device_t dv, const pmf_qual_t *qual) +{ + struct pciide_softc *sc = device_private(dv); + + sc->sc_pm_reg[0] = pci_conf_read(sc->sc_pc, sc->sc_tag, + RDCIDE_PATR); + sc->sc_pm_reg[1] = pci_conf_read(sc->sc_pc, sc->sc_tag, + RDCIDE_PSD1ATR); + sc->sc_pm_reg[2] = pci_conf_read(sc->sc_pc, sc->sc_tag, + RDCIDE_UDCCR); + sc->sc_pm_reg[3] = pci_conf_read(sc->sc_pc, sc->sc_tag, + RDCIDE_IIOCR); + + return true; +} + +static void +rdcide_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) +{ + struct pciide_channel *cp; + int channel; + u_int32_t patr; + pcireg_t interface = PCI_INTERFACE(pa->pa_class); + + if (pciide_chipen(sc, pa) == 0) + return; + + aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev, + "bus-master DMA support present"); + pciide_mapreg_dma(sc, pa); + aprint_verbose("\n"); + sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32; + if (sc->sc_dma_ok) { + sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA | ATAC_CAP_UDMA; + sc->sc_wdcdev.irqack = pciide_irqack; + sc->sc_wdcdev.dma_init = pciide_dma_init; + } + sc->sc_wdcdev.sc_atac.atac_pio_cap = 4; + sc->sc_wdcdev.sc_atac.atac_dma_cap = 2; + sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; + sc->sc_wdcdev.sc_atac.atac_set_modes = rdcide_setup_channel; + sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; + sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + + ATADEBUG_PRINT(("rdcide_setup_chip: old PATR=0x%x", + pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PATR)), + DEBUG_PROBE); + ATADEBUG_PRINT((", PSD1ATR=0x%x", + pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR)), + DEBUG_PROBE); + ATADEBUG_PRINT((", UDCCR 0x%x", + pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR)), + DEBUG_PROBE); + ATADEBUG_PRINT((", IIOCR 0x%x", + pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR)), + DEBUG_PROBE); + ATADEBUG_PRINT(("\n"), DEBUG_PROBE); + + wdc_allocate_regs(&sc->sc_wdcdev); + + for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels; + channel++) { + cp = &sc->pciide_channels[channel]; + if (pciide_chansetup(sc, channel, interface) == 0) + continue; + patr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PATR); + if ((patr & RDCIDE_PATR_EN(channel)) == 0) { + aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, + "%s channel ignored (disabled)\n", cp->name); + cp->ata_channel.ch_flags |= ATACH_DISABLED; + continue; + } + pciide_mapchan(pa, cp, interface, pciide_pci_intr); + } + ATADEBUG_PRINT(("rdcide_setup_chip: PATR=0x%x", + pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PATR)), + DEBUG_PROBE); + ATADEBUG_PRINT((", PSD1ATR=0x%x", + pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR)), + DEBUG_PROBE); + ATADEBUG_PRINT((", UDCCR 0x%x", + pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR)), + DEBUG_PROBE); + ATADEBUG_PRINT((", IIOCR 0x%x", + pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR)), + DEBUG_PROBE); + ATADEBUG_PRINT(("\n"), DEBUG_PROBE); + +} + +static void +rdcide_setup_channel(struct ata_channel *chp) +{ + u_int8_t drive; + u_int32_t patr, psd1atr, udccr, iiocr; + struct pciide_channel *cp = CHAN_TO_PCHAN(chp); + struct pciide_softc *sc = CHAN_TO_PCIIDE(chp); + struct ata_drive_datas *drvp = cp->ata_channel.ch_drive; + + patr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PATR); + psd1atr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR); + udccr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR); + iiocr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR); + + /* setup DMA */ + pciide_channel_dma_setup(cp); + + /* clear modes */ + patr = patr & (RDCIDE_PATR_EN(0) | RDCIDE_PATR_EN(1)); + psd1atr &= ~RDCIDE_PSD1ATR_SETUP_MASK(chp->ch_channel); + psd1atr &= ~RDCIDE_PSD1ATR_HOLD_MASK(chp->ch_channel); + for (drive = 0; drive < 2; drive++) { + udccr &= ~RDCIDE_UDCCR_EN(chp->ch_channel, drive); + udccr &= ~RDCIDE_UDCCR_TIM_MASK(chp->ch_channel, drive); + iiocr &= ~RDCIDE_IIOCR_CLK_MASK(chp->ch_channel, drive); + } + /* now setup modes */ + for (drive = 0; drive < 2; drive++) { + if ((drvp[drive].drive_flags & DRIVE) == 0) + continue; + if ((drvp[drive].drive_flags & DRIVE_ATAPI) == 0) + patr |= RDCIDE_PATR_ATA(chp->ch_channel, drive); + if (drive == 0) { + patr |= RDCIDE_PATR_SETUP( + rdcide_setup[drvp[drive].PIO_mode], + chp->ch_channel); + patr |= RDCIDE_PATR_HOLD( + rdcide_hold[drvp[drive].PIO_mode], + chp->ch_channel); + } else { + patr |= RDCIDE_PATR_DEV1_TEN(chp->ch_channel); + psd1atr |= RDCIDE_PSD1ATR_SETUP( + rdcide_setup[drvp[drive].PIO_mode], + chp->ch_channel); + psd1atr |= RDCIDE_PSD1ATR_HOLD( + rdcide_hold[drvp[drive].PIO_mode], + chp->ch_channel); + } + if (drvp[drive].PIO_mode > 0) { + patr |= RDCIDE_PATR_FTIM(chp->ch_channel, drive); + patr |= RDCIDE_PATR_IORDY(chp->ch_channel, drive); + } + if (drvp[drive].drive_flags & DRIVE_DMA) { + patr |= RDCIDE_PATR_DMAEN(chp->ch_channel, drive); + } + if ((drvp[drive].drive_flags & DRIVE_UDMA) == 0) + continue; + + if ((iiocr & RDCIDE_IIOCR_CABLE(chp->ch_channel, drive)) == 0 + && drvp[drive].UDMA_mode > 2) + drvp[drive].UDMA_mode = 2; + udccr |= RDCIDE_UDCCR_EN(chp->ch_channel, drive); + udccr |= RDCIDE_UDCCR_TIM( + rdcide_udmatim[drvp[drive].UDMA_mode], + chp->ch_channel, drive); + iiocr |= RDCIDE_IIOCR_CLK( + rdcide_udmaclk[drvp[drive].UDMA_mode], + chp->ch_channel, drive); + } + + pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_PATR, patr); + pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR, psd1atr); + pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR, udccr); + pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR, iiocr); +} Index: src/sys/dev/pci/rdcide_reg.h diff -u /dev/null src/sys/dev/pci/rdcide_reg.h:1.1 --- /dev/null Mon Apr 4 14:33:52 2011 +++ src/sys/dev/pci/rdcide_reg.h Mon Apr 4 14:33:51 2011 @@ -0,0 +1,74 @@ +/* $NetBSD: rdcide_reg.h,v 1.1 2011/04/04 14:33:51 bouyer Exp $ */ + +/* + * Copyright (c) 2011 Manuel Bouyer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * register definitions for the RDC ide controller as found in the + * PMX-1000 SoC + */ +/* ATA Timing Register */ +#define RDCIDE_PATR 0x40 +#define RDCIDE_PATR_EN(chan) (0x8000 << ((chan) * 16)) +#define RDCIDE_PATR_DEV1_TEN(chan) (0x4000 << ((chan) * 16)) +#define RDCIDE_PATR_SETUP(val, chan) (((val) << 12) << ((chan) * 16)) +#define RDCIDE_PATR_SETUP_MASK(chan) (0x3000 << ((chan) * 16)) +#define RDCIDE_PATR_HOLD(val, chan) (((val) << 8) << ((chan) * 16)) +#define RDCIDE_PATR_HOLD_MASK(chan) (0x0300 << ((chan) * 16)) +#define RDCIDE_PATR_DMAEN(chan, drv) ((0x0008 << (drv * 4)) << ((chan) * 16)) +#define RDCIDE_PATR_ATA(chan, drv) ((0x0004 << (drv * 4)) << ((chan) * 16)) +#define RDCIDE_PATR_IORDY(chan, drv) ((0x0002 << (drv * 4)) << ((chan) * 16)) +#define RDCIDE_PATR_FTIM(chan, drv) ((0x0001 << (drv * 4)) << ((chan) * 16)) + +/* Primary and Secondary Device 1 ATA Timing */ +#define RDCIDE_PSD1ATR 0x44 +#define RDCIDE_PSD1ATR_SETUP(val, chan) (((val) << 2) << (chan * 4)) +#define RDCIDE_PSD1ATR_SETUP_MASK(chan) (0x0c << (chan * 4)) +#define RDCIDE_PSD1ATR_HOLD(val, chan) (((val) << 0) << (chan * 4)) +#define RDCIDE_PSD1ATR_HOLD_MASK(chan) (0x03 << (chan * 4)) + +const uint8_t rdcide_setup[] = {0, 0, 1, 2, 2}; +const uint8_t rdcide_hold[] = {0, 0, 0, 1, 3}; + +/* Ultra DMA Control and timing Register */ +#define RDCIDE_UDCCR 0x48 +#define RDCIDE_UDCCR_EN(chan, drv) ((1 << (drv)) << (chan * 2)) +#define RDCIDE_UDCCR_TIM(val, chan, drv) (((val) << ((drv) * 4)) << (chan * 8)) +#define RDCIDE_UDCCR_TIM_MASK(chan, drv) ((0x3 << ((drv) * 4)) << (chan * 8)) + +const uint8_t rdcide_udmatim[] = {0, 1, 2, 1, 2, 1}; + +/* IDE I/O Configuration Registers */ +#define RDCIDE_IIOCR 0x54 +#define RDCIDE_IIOCR_CABLE(chan, drv) ((0x10 << (drv)) << (chan * 2)) +#define RDCIDE_IIOCR_CLK(val, chan, drv) (((val) << drv) << (chan * 2)) +#define RDCIDE_IIOCR_CLK_MASK(chan, drv) ((0x1001 << drv) << (chan * 2)) + +const uint32_t rdcide_udmaclk[] = + {0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x1000}; + +/* Miscellaneous Control Register */ +#define RDCIDE_MCR 0x90 +#define RDCIDE_MCR_RESET(chan) (0x01000000 << (chan))