Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151683722
D11177.id29542.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D11177.id29542.diff
View Options
Index: sys/arm/freescale/imx/files.imx6
===================================================================
--- sys/arm/freescale/imx/files.imx6
+++ sys/arm/freescale/imx/files.imx6
@@ -23,6 +23,7 @@
arm/freescale/imx/imx6_sdma.c optional sdma
arm/freescale/imx/imx6_audmux.c optional sound
arm/freescale/imx/imx6_ssi.c optional sound
+arm/freescale/imx/imx6_ahci.c optional ahci
arm/arm/hdmi_if.m optional hdmi
arm/freescale/imx/imx6_hdmi.c optional hdmi
Index: sys/arm/freescale/imx/imx6_ahci.c
===================================================================
--- /dev/null
+++ sys/arm/freescale/imx/imx6_ahci.c
@@ -0,0 +1,345 @@
+/*-
+ * Copyright (c) 2017 Rogiel Sulzbach <rogiel@allogica.com>
+ * All rights reserved.
+ *
+ * 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 <sys/cdefs.h>
+
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/ahci/ahci.h>
+#include <arm/freescale/imx/imx_iomuxreg.h>
+#include <arm/freescale/imx/imx_iomuxvar.h>
+#include <arm/freescale/imx/imx_ccmvar.h>
+#include <arm/freescale/imx/imx6_ccmvar.h>
+
+#define SATA_P0PHYCR 0x00000178
+#define SATA_P0PHYCR_CR_READ (1 << 19)
+#define SATA_P0PHYCR_CR_WRITE (1 << 18)
+#define SATA_P0PHYCR_CR_CAP_DATA (1 << 17)
+#define SATA_P0PHYCR_CR_CAP_ADDR (1 << 16)
+#define SATA_P0PHYCR_CR_DATA_IN(v) ((v) & 0xffff)
+#define SATA_P0PHYSR 0x0000017c
+#define SATA_P0PHYSR_CR_ACK (1 << 18)
+#define SATA_P0PHYSR_CR_DATA_OUT(v) ((v) & 0xffff)
+
+#define SATA_TIMER1MS 0x000000e0
+
+/* phy registers */
+#define SATA_PHY_CLOCK_RESET 0x7f3f
+#define SATA_PHY_CLOCK_RESET_RST (1 << 0)
+
+#define SATA_PHY_LANE0_OUT_STAT 0x2003
+#define SATA_PHY_LANE0_OUT_STAT_RX_PLL_STATE (1 << 1)
+
+static int
+imx6_ahci_phy_ctrl(struct ahci_controller* sc, uint32_t bitmask, int on)
+{
+ uint32_t v;
+ int timeout;
+
+ v = ATA_INL(sc->r_mem, SATA_P0PHYCR);
+ if(on) {
+ v |= bitmask;
+ } else {
+ v &= ~bitmask;
+ }
+ ATA_OUTL(sc->r_mem, SATA_P0PHYCR, v);
+
+ for(timeout = 5000; timeout > 0; --timeout) {
+ v = ATA_INL(sc->r_mem, SATA_P0PHYSR);
+ if(!!(v & SATA_P0PHYSR_CR_ACK) == !!on) {
+ break;
+ }
+ DELAY(100);
+ }
+
+ if(timeout > 0) {
+ return 0;
+ }
+
+ return ETIMEDOUT;
+}
+
+static int
+imx6_ahci_phy_addr(struct ahci_controller* sc, uint32_t addr)
+{
+ int error;
+ DELAY(100);
+
+ ATA_OUTL(sc->r_mem, SATA_P0PHYCR, addr);
+
+ error = imx6_ahci_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_ADDR, 1);
+ if(error != 0) {
+ if(bootverbose) {
+ device_printf(sc->dev, "%s: timeout on SATA_P0PHYCR_CR_CAP_ADDR=1\n", __FUNCTION__);
+ }
+ return error;
+ }
+
+ error = imx6_ahci_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_ADDR, 0);
+ if(error != 0) {
+ if(bootverbose) {
+ device_printf(sc->dev, "%s: timeout on SATA_P0PHYCR_CR_CAP_ADDR=0\n", __FUNCTION__);
+ }
+ return error;
+ }
+
+ return 0;
+}
+
+static int
+imx6_ahci_phy_write(struct ahci_controller* sc, uint32_t addr,
+ uint16_t data)
+{
+ int error;
+
+ error = imx6_ahci_phy_addr(sc, addr);
+ if(error != 0) {
+ if(bootverbose) { device_printf(sc->dev, "%s: error on imx6_ahci_phy_addr\n", __FUNCTION__); }
+ return error;
+ }
+
+ ATA_OUTL(sc->r_mem, SATA_P0PHYCR, data);
+
+ error = imx6_ahci_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_DATA, 1);
+ if(error != 0) {
+ if(bootverbose) {
+ device_printf(sc->dev, "%s: error on SATA_P0PHYCR_CR_CAP_DATA=1\n", __FUNCTION__);
+ }
+ return error;
+ }
+ if(imx6_ahci_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_DATA, 0) != 0) {
+ if(bootverbose) {
+ device_printf(sc->dev, "%s: error on SATA_P0PHYCR_CR_CAP_DATA=0\n", __FUNCTION__);
+ }
+ return error;
+ }
+
+ if((addr == SATA_PHY_CLOCK_RESET) && data) {
+ /* we can't check ACK after RESET */
+ ATA_OUTL(sc->r_mem, SATA_P0PHYCR,
+ SATA_P0PHYCR_CR_DATA_IN(data) | SATA_P0PHYCR_CR_WRITE);
+ return 0;
+ }
+
+ error = imx6_ahci_phy_ctrl(sc, SATA_P0PHYCR_CR_WRITE, 1);
+ if(error != 0) {
+ if(bootverbose) { device_printf(sc->dev, "%s: error on SATA_P0PHYCR_CR_WRITE=1\n", __FUNCTION__); }
+ return error;
+ }
+
+ error = imx6_ahci_phy_ctrl(sc, SATA_P0PHYCR_CR_WRITE, 0);
+ if(error != 0) {
+ if(bootverbose) { device_printf(sc->dev, "%s: error on SATA_P0PHYCR_CR_WRITE=0\n", __FUNCTION__); }
+ return error;
+ }
+
+ return 0;
+}
+
+static int
+imx6_ahci_phy_read(struct ahci_controller* sc, uint32_t addr)
+{
+ int error;
+ uint32_t v;
+
+ error = imx6_ahci_phy_addr(sc, addr);
+ if(error != 0) {
+ if(bootverbose) { device_printf(sc->dev, "%s: error on imx6_ahci_phy_addr\n", __FUNCTION__); }
+ return error;
+ }
+
+ error = imx6_ahci_phy_ctrl(sc, SATA_P0PHYCR_CR_READ, 1);
+ if(error != 0) {
+ if(bootverbose) { device_printf(sc->dev, "%s: error on SATA_P0PHYCR_CR_READ=1\n", __FUNCTION__); }
+ return error;
+ }
+
+ v = ATA_INL(sc->r_mem, SATA_P0PHYSR);
+
+ error = imx6_ahci_phy_ctrl(sc, SATA_P0PHYCR_CR_READ, 0);
+ if(error != 0) {
+ if(bootverbose) { device_printf(sc->dev, "%s: error on SATA_P0PHYCR_CR_READ=0\n", __FUNCTION__); }
+ return error;
+ }
+
+ return SATA_P0PHYSR_CR_DATA_OUT(v);
+}
+
+static int
+imx6_ahci_probe(device_t dev)
+{
+ if(!ofw_bus_is_compatible(dev, "fsl,imx6q-ahci")) {
+ return (ENXIO);
+ }
+ device_set_desc(dev, "i.MX6 Integrated AHCI controller");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+imx6_ahci_attach(device_t dev)
+{
+ struct ahci_controller* ctlr;
+ uint32_t v;
+ int timeout;
+ int pllstat;
+ int error;
+
+ /*
+ * Init the device PHY
+ */
+ ctlr = device_get_softc(dev);
+
+ error = imx6_ccm_sataphy_enable();
+ if(error != 0) {
+ device_printf(dev, "time out resetting AHCI PHY\n");
+ return error;
+ }
+
+ ctlr->vendorid = 0;
+ ctlr->deviceid = 0;
+ ctlr->subvendorid = 0;
+ ctlr->subdeviceid = 0;
+ ctlr->numirqs = 1;
+ ctlr->r_rid = 0;
+ if(!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &ctlr->r_rid, RF_ACTIVE))) {
+ return (ENXIO);
+ }
+
+ v = imx_iomux_gpr_get(IOMUX_GPR13);
+ v &= ~(IOMUX_GPR13_SATA_PHY_8(7) |
+ IOMUX_GPR13_SATA_PHY_7(0x1f) |
+ IOMUX_GPR13_SATA_PHY_6(7) |
+ IOMUX_GPR13_SATA_SPEED(1) |
+ IOMUX_GPR13_SATA_PHY_5(1) |
+ IOMUX_GPR13_SATA_PHY_4(7) |
+ IOMUX_GPR13_SATA_PHY_3(0xf) |
+ IOMUX_GPR13_SATA_PHY_2(0x1f) |
+ IOMUX_GPR13_SATA_PHY_1(1) |
+ IOMUX_GPR13_SATA_PHY_0(1));
+ /* setting */
+ v |= IOMUX_GPR13_SATA_PHY_8(5) | /* Rx 3.0db */
+ IOMUX_GPR13_SATA_PHY_7(0x12) | /* Rx SATA2m */
+ IOMUX_GPR13_SATA_PHY_6(3) | /* Rx DPLL mode */
+ IOMUX_GPR13_SATA_SPEED(1) | /* 3.0GHz */
+ IOMUX_GPR13_SATA_PHY_5(0) | /* SpreadSpectram */
+ IOMUX_GPR13_SATA_PHY_4(4) | /* Tx Attenuation 9/16 */
+ IOMUX_GPR13_SATA_PHY_3(0) | /* Tx Boost 0db */
+ IOMUX_GPR13_SATA_PHY_2(0x11) | /* Tx Level 1.104V */
+ IOMUX_GPR13_SATA_PHY_1(1); /* PLL clock enable */
+ imx_iomux_gpr_set(IOMUX_GPR13, v);
+
+ /* phy reset */
+ error = imx6_ahci_phy_write(ctlr, SATA_PHY_CLOCK_RESET,
+ SATA_PHY_CLOCK_RESET_RST);
+ if(error != 0) {
+ device_printf(dev, "cannot reset PHY\n");
+ goto fail;
+ }
+
+ for(timeout = 50; timeout > 0; --timeout) {
+ DELAY(100);
+ pllstat = imx6_ahci_phy_read(ctlr, SATA_PHY_LANE0_OUT_STAT);
+ if(pllstat < 0) {
+ device_printf(dev, "cannot read LANE0 status\n");
+ break;
+ }
+ if(pllstat & SATA_PHY_LANE0_OUT_STAT_RX_PLL_STATE) {
+ break;
+ }
+ }
+ if(timeout <= 0) {
+ device_printf(dev, "time out reading LANE0 status\n");
+ error = ETIMEDOUT;
+ goto fail;
+ }
+
+ /* Support Staggered Spin-up */
+ v = ATA_INL(ctlr->r_mem, AHCI_CAP);
+ ATA_OUTL(ctlr->r_mem, AHCI_CAP, v | AHCI_CAP_SSS);
+
+ /* Ports Implemented. must set 1 */
+ v = ATA_INL(ctlr->r_mem, AHCI_PI);
+ ATA_OUTL(ctlr->r_mem, AHCI_PI, v | (1 << 0));
+
+ /* set 1ms-timer = AHB clock / 1000 */
+ ATA_OUTL(ctlr->r_mem, SATA_TIMER1MS,
+ imx_ccm_ahb_hz() / 1000);
+
+ /*
+ * Note: ahci_attach will release ctlr->r_mem on errors automatically
+ */
+ return (ahci_attach(dev));
+
+ fail:
+ bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
+ return error;
+}
+
+static int
+imx6_ahci_detach(device_t dev)
+{
+ return (ahci_detach(dev));
+}
+
+devclass_t ahci_devclass;
+
+static device_method_t imx6_ahci_ata_methods[] = {
+ /* device probe, attach and detach methods */
+ DEVMETHOD(device_probe, imx6_ahci_probe),
+ DEVMETHOD(device_attach, imx6_ahci_attach),
+ DEVMETHOD(device_detach, imx6_ahci_detach),
+
+ /* ahci bus methods */
+ DEVMETHOD(bus_print_child, ahci_print_child),
+ DEVMETHOD(bus_alloc_resource, ahci_alloc_resource),
+ DEVMETHOD(bus_release_resource, ahci_release_resource),
+ DEVMETHOD(bus_setup_intr, ahci_setup_intr),
+ DEVMETHOD(bus_teardown_intr, ahci_teardown_intr),
+ DEVMETHOD(bus_child_location_str, ahci_child_location_str),
+
+ DEVMETHOD_END
+};
+
+static driver_t ahci_ata_driver = {
+ "ahci",
+ imx6_ahci_ata_methods,
+ sizeof(struct ahci_controller)
+};
+
+DRIVER_MODULE(ahci, simplebus, ahci_ata_driver, ahci_devclass, 0, 0);
Index: sys/arm/freescale/imx/imx6_ccm.c
===================================================================
--- sys/arm/freescale/imx/imx6_ccm.c
+++ sys/arm/freescale/imx/imx6_ccm.c
@@ -117,7 +117,7 @@
/* uarts, ssi, sdma */
reg = CCGR5_SDMA | CCGR5_SSI1 | CCGR5_SSI2 | CCGR5_SSI3 |
- CCGR5_UART | CCGR5_UART_SERIAL;
+ CCGR5_UART | CCGR5_UART_SERIAL | CCGR5_SATA;
WR4(sc, CCM_CCGR5, reg);
/* usdhc 1-4, usboh3 */
@@ -314,6 +314,36 @@
#endif
}
+int
+imx6_ccm_sataphy_enable(void)
+{
+ uint32_t v;
+ int timeout;
+
+ v = RD4(ccm_sc, CCM_ANALOG_PLL_ENET);
+ v &= ~CCM_ANALOG_PLL_ENET_POWERDOWN;
+ WR4(ccm_sc, CCM_ANALOG_PLL_ENET, v);
+
+ for(timeout = 100000; timeout > 0; timeout--) {
+ if(RD4(ccm_sc, CCM_ANALOG_PLL_ENET) &
+ CCM_ANALOG_PLL_ENET_LOCK) {
+ break;
+ }
+ }
+ if(timeout <= 0) {
+ return ETIMEDOUT;
+ }
+
+ v |= CCM_ANALOG_PLL_ENET_ENABLE;
+ v &= ~CCM_ANALOG_PLL_ENET_BYPASS;
+ WR4(ccm_sc, CCM_ANALOG_PLL_ENET, v);
+
+ v |= CCM_ANALOG_PLL_ENET_ENABLE_100M;
+ WR4(ccm_sc, CCM_ANALOG_PLL_ENET, v);
+
+ return 0;
+}
+
uint32_t
imx_ccm_ipg_hz(void)
{
Index: sys/arm/freescale/imx/imx6_ccmreg.h
===================================================================
--- sys/arm/freescale/imx/imx6_ccmreg.h
+++ sys/arm/freescale/imx/imx6_ccmreg.h
@@ -113,6 +113,7 @@
#define CCGR4_PL301_MX6QPER1_BCH (0x3 << 12)
#define CCGR4_PL301_MX6QPER2_MAIN (0x3 << 14)
#define CCM_CCGR5 0x07C
+#define CCGR5_SATA (0x3 << 4)
#define CCGR5_SDMA (0x3 << 6)
#define CCGR5_SSI1 (0x3 << 18)
#define CCGR5_SSI2 (0x3 << 20)
@@ -127,4 +128,11 @@
#define CCGR6_USDHC4 (0x3 << 8)
#define CCM_CMEOR 0x088
+#define CCM_ANALOG_PLL_ENET 0x000040e0
+#define CCM_ANALOG_PLL_ENET_LOCK (1 << 31)
+#define CCM_ANALOG_PLL_ENET_ENABLE_100M (1 << 20) /* SATA */
+#define CCM_ANALOG_PLL_ENET_BYPASS (1 << 16)
+#define CCM_ANALOG_PLL_ENET_ENABLE (1 << 13) /* Ether */
+#define CCM_ANALOG_PLL_ENET_POWERDOWN (1 << 12)
+
#endif
Index: sys/arm/freescale/imx/imx6_ccmvar.h
===================================================================
--- /dev/null
+++ sys/arm/freescale/imx/imx6_ccmvar.h
@@ -0,0 +1,32 @@
+/*-
+ * Copyright (c) 2017 Rogiel Sulzbach <rogiel@allogica.com>
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef IMX6_CCMVAR_H
+#define IMX6_CCMVAR_H
+
+int imx6_ccm_sataphy_enable(void);
+
+#endif
Index: sys/arm/freescale/imx/imx_iomuxreg.h
===================================================================
--- sys/arm/freescale/imx/imx_iomuxreg.h
+++ sys/arm/freescale/imx/imx_iomuxreg.h
@@ -29,6 +29,13 @@
#ifndef IMX_IOMUXREG_H
#define IMX_IOMUXREG_H
+#define IMX_IOMUXREG_LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask))
+#define IMX_IOMUXREG_SHIFTIN(__x, __mask) ((__x) * IMX_IOMUXREG_LOWEST_SET_BIT(__mask))
+
+#define IMX_IOMUXREG_BIT(n) (1 << (n))
+#define IMX_IOMUXREG_BITS(__m, __n) \
+ ((IMX_IOMUXREG_BIT(MAX((__m), (__n)) + 1) - 1) ^ (IMX_IOMUXREG_BIT(MIN((__m), (__n))) - 1))
+
#define IOMUXC_GPR0 0x00
#define IOMUXC_GPR1 0x04
#define IOMUXC_GPR2 0x08
@@ -39,4 +46,16 @@
#define IOMUXC_GPR3_HDMI_IPU2_DI0 (2 << 2)
#define IOMUXC_GPR3_HDMI_IPU2_DI1 (3 << 2)
+#define IOMUX_GPR13 0x34
+#define IOMUX_GPR13_SATA_PHY_8(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(26, 24))
+#define IOMUX_GPR13_SATA_PHY_7(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(23, 19))
+#define IOMUX_GPR13_SATA_PHY_6(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(18, 16))
+#define IOMUX_GPR13_SATA_SPEED(n) IMX_IOMUXREG_SHIFTIN(n, (1 << 15))
+#define IOMUX_GPR13_SATA_PHY_5(n) IMX_IOMUXREG_SHIFTIN(n, (1 << 14))
+#define IOMUX_GPR13_SATA_PHY_4(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(13, 11))
+#define IOMUX_GPR13_SATA_PHY_3(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(10, 7))
+#define IOMUX_GPR13_SATA_PHY_2(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(6, 2))
+#define IOMUX_GPR13_SATA_PHY_1(n) IMX_IOMUXREG_SHIFTIN(n, (1 << 1))
+#define IOMUX_GPR13_SATA_PHY_0(n) IMX_IOMUXREG_SHIFTIN(n, (1 << 0))
+
#endif
Index: sys/arm/freescale/imx/std.imx6
===================================================================
--- sys/arm/freescale/imx/std.imx6
+++ sys/arm/freescale/imx/std.imx6
@@ -10,6 +10,7 @@
options IPI_IRQ_END=15
device fdt_pinctrl
+device ahci
files "../freescale/imx/files.imx6"
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 11, 12:10 AM (15 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31255990
Default Alt Text
D11177.id29542.diff (15 KB)
Attached To
Mode
D11177: Driver for i.MX6 AHCI controller
Attached
Detach File
Event Timeline
Log In to Comment