From owner-svn-src-projects@FreeBSD.ORG Tue Nov 13 14:15:27 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 4F34F66B; Tue, 13 Nov 2012 14:15:27 +0000 (UTC) (envelope-from ray@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 34C948FC17; Tue, 13 Nov 2012 14:15:27 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qADEFRZI059914; Tue, 13 Nov 2012 14:15:27 GMT (envelope-from ray@svn.freebsd.org) Received: (from ray@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qADEFRnR059913; Tue, 13 Nov 2012 14:15:27 GMT (envelope-from ray@svn.freebsd.org) Message-Id: <201211131415.qADEFRnR059913@svn.freebsd.org> From: Aleksandr Rybalko Date: Tue, 13 Nov 2012 14:15:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r242965 - projects/efika_mx/sys/dev/ata/chipsets X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Nov 2012 14:15:27 -0000 Author: ray Date: Tue Nov 13 14:15:26 2012 New Revision: 242965 URL: http://svnweb.freebsd.org/changeset/base/242965 Log: Add PATA support for i.MX5xx (PIO yet) Sponsored by: FreeBSD Foundation Added: projects/efika_mx/sys/dev/ata/chipsets/ata-fsl.c Added: projects/efika_mx/sys/dev/ata/chipsets/ata-fsl.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/efika_mx/sys/dev/ata/chipsets/ata-fsl.c Tue Nov 13 14:15:26 2012 (r242965) @@ -0,0 +1,237 @@ +/*- + * Copyright (c) 2012 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Oleksandr Rybalko under sponsorship + * from the FreeBSD Foundation. + * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 +__FBSDID("$FreeBSD$"); + +#include "opt_ata.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* local prototypes */ +static int imx_ata_ch_attach(device_t dev); +static int imx_ata_setmode(device_t dev, int target, int mode); + +static int +imx_ata_probe(device_t dev) +{ + struct ata_pci_controller *ctlr; + + if (!ofw_bus_is_compatible(dev, "fsl,imx51-ata")) + return (ENXIO); + + ctlr = device_get_softc(dev); + + device_set_desc(dev, "Freescale Integrated PATA Controller"); + return (BUS_PROBE_DEFAULT); +} + +static void +imx_ata_intr(void *data) +{ + struct ata_pci_controller *ctlr = data; + + bus_write_2(ctlr->r_res1, 0x28, bus_read_2(ctlr->r_res1, 0x28)); + ctlr->interrupt[0].function(ctlr->interrupt[0].argument); +} + +static int +imx_ata_attach(device_t dev) +{ + struct ata_pci_controller *ctlr; + device_t child; + int unit; + + ctlr = device_get_softc(dev); + /* do chipset specific setups only needed once */ + ctlr->legacy = ata_legacy(dev); + ctlr->channels = 1; + ctlr->ichannels = -1; + ctlr->ch_attach = ata_pci_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; + ctlr->dev = dev; + + ctlr->r_type1 = SYS_RES_MEMORY; + ctlr->r_rid1 = 0; + ctlr->r_res1 = bus_alloc_resource_any(dev, ctlr->r_type1, + &ctlr->r_rid1, RF_ACTIVE); + + if (ata_setup_interrupt(dev, imx_ata_intr)) { + device_printf(dev, "failed to setup interrupt\n"); + return ENXIO; + } + + ctlr->channels = 1; + + ctlr->ch_attach = imx_ata_ch_attach; + ctlr->setmode = imx_ata_setmode; + + /* attach all channels on this controller */ + unit = 0; + child = device_add_child(dev, "ata", ((unit == 0) && ctlr->legacy) ? + unit : devclass_find_free_unit(ata_devclass, 2)); + if (child == NULL) + device_printf(dev, "failed to add ata child device\n"); + else + device_set_ivars(child, (void *)(intptr_t)unit); + + bus_generic_attach(dev); + return 0; +} + +static int +imx_ata_ch_attach(device_t dev) +{ + struct ata_pci_controller *ctrl; + struct ata_channel *ch; + int i; + + ctlr = device_get_softc(device_get_parent(dev)); + ch = device_get_softc(dev); + for (i = ATA_DATA; i < ATA_MAX_RES; i++) + ch->r_io[i].res = ctlr->r_res1; + + bus_write_2(ctlr->r_res1, 0x24, 0x80); + DELAY(100); + bus_write_2(ctlr->r_res1, 0x24, 0xc0); + DELAY(100); + + + /* Write TIME_OFF/ON/1/2W */ + bus_write_1(ctlr->r_res1, 0x00, 3); + bus_write_1(ctlr->r_res1, 0x01, 3); + bus_write_1(ctlr->r_res1, 0x02, (25 + 15) / 15); + bus_write_1(ctlr->r_res1, 0x03, (70 + 15) / 15); + + /* Write TIME_2R/AX/RDX/4 */ + bus_write_1(ctlr->r_res1, 0x04, (70 + 15) / 15); + bus_write_1(ctlr->r_res1, 0x05, (50 + 15) / 15 + 2); + bus_write_1(ctlr->r_res1, 0x06, 1); + bus_write_1(ctlr->r_res1, 0x07, (10 + 15) / 15); + + /* Write TIME_9 ; the rest of timing registers is irrelevant for PIO */ + bus_write_1(ctlr->r_res1, 0x08, (10 + 15) / 15); + + bus_write_2(ctlr->r_res1, 0x24, 0xc1); + DELAY(30000); + + /* setup ATA registers */ + ch->r_io[ATA_DATA ].offset = 0xa0; + ch->r_io[ATA_FEATURE].offset = 0xa4; + ch->r_io[ATA_ERROR ].offset = 0xa4; + ch->r_io[ATA_COUNT ].offset = 0xa8; + ch->r_io[ATA_SECTOR ].offset = 0xac; + ch->r_io[ATA_CYL_LSB].offset = 0xb0; + ch->r_io[ATA_CYL_MSB].offset = 0xb4; + ch->r_io[ATA_DRIVE ].offset = 0xb8; + ch->r_io[ATA_COMMAND].offset = 0xbc; + + ch->r_io[ATA_STATUS ].offset = 0xbc; + ch->r_io[ATA_ALTSTAT].offset = 0xd8; + ch->r_io[ATA_CONTROL].offset = 0xd8; + + ata_pci_hw(dev); + + ch->flags |= ATA_NO_SLAVE; + ch->flags |= ATA_USE_16BIT; + ch->flags |= ATA_CHECKS_CABLE; + ch->flags |= ATA_KNOWN_PRESENCE; + + /* Clear pending interrupts. */ + bus_write_2(ctlr->r_res1, 0x28, 0xf8); + /* Enable all, but Idle interrupts. */ + bus_write_2(ctlr->r_res1, 0x2c, 0x88); + + return 0; +} + +static int +imx_ata_setmode(device_t dev, int target, int mode) +{ + + return (min(mode, ATA_PIO4)); +} + +static device_method_t imx_ata_methods[] = { + DEVMETHOD(device_probe, imx_ata_probe), + DEVMETHOD(device_attach, imx_ata_attach), + DEVMETHOD(device_detach, ata_pci_detach), + DEVMETHOD(device_suspend, ata_pci_suspend), + DEVMETHOD(device_resume, ata_pci_resume), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(bus_read_ivar, ata_pci_read_ivar), + DEVMETHOD(bus_write_ivar, ata_pci_write_ivar), + DEVMETHOD(bus_alloc_resource, ata_pci_alloc_resource), + DEVMETHOD(bus_release_resource, ata_pci_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_setup_intr, ata_pci_setup_intr), + DEVMETHOD(bus_teardown_intr, ata_pci_teardown_intr), + DEVMETHOD(pci_read_config, ata_pci_read_config), + DEVMETHOD(pci_write_config, ata_pci_write_config), + DEVMETHOD(bus_print_child, ata_pci_print_child), + DEVMETHOD(bus_child_location_str, ata_pci_child_location_str), + DEVMETHOD_END +}; +static driver_t imx_ata_driver = { + "atapci", + imx_ata_methods, + sizeof(struct ata_pci_controller) +}; +DRIVER_MODULE(imx_ata, simplebus, imx_ata_driver, ata_pci_devclass, NULL, + NULL); +MODULE_VERSION(imx_ata, 1); +MODULE_DEPEND(imx_ata, ata, 1, 1, 1); +MODULE_DEPEND(imx_ata, atapci, 1, 1, 1);