Message ID | 1412690200-6630-1-git-send-email-ijc@hellion.org.uk |
---|---|
State | New |
Headers | show |
Dear Ian Campbell, On 7 October 2014 22:56, Ian Campbell <ijc@hellion.org.uk> wrote: > From: Ian Campbell <ian.campbell@citrix.com> > > This is based on some old patches from the chromeos-v2011.12 branch of > http://git.chromium.org/chromiumos/third_party/u-boot.git by Taylor Hutt. > Specifically: > > > http://git.chromium.org/gitweb/?p=chromiumos/third_party/u-boot.git;a=commit;h=26f6c570b5deb37c52306920ae049203c68f014a > exynos: sata: on-board controller initialization > Signed-off-by: Taylor Hutt <thutt@chromium.org> > > > http://git.chromium.org/gitweb/?p=chromiumos/third_party/u-boot.git;a=commit;h=d8cac5cf0b63df00d2d6ac7df814613e4b60b9d1 > exynos: sata: Add sata_initialize() interface > Signed-off-by: Taylor Hutt <thutt@chromium.org> > > > http://git.chromium.org/gitweb/?p=chromiumos/third_party/u-boot.git;a=commit;h=dd32462453d6328bc5770859d1b56501f7920d7d > exynos: sata: SATA self-configuration for when SATA device is enabled > Signed-off-by: Taylor Hutt <thutt@chromium.org> > > As well as rebasing there have been some significant changes. > > - Drop support for smdk5250, which I don't own. > - Implement support for arndale, which I do. > - Since arndale has no need to frob a GPIO on SATA init drop the > associated > code. > - Initialise via the existing scsi_init hook rather than introducing > sata_initialize, associated build system and include/configs/*.h > changes. > - Use set/clrbits in a bunch of places > - Add some #defines for some magic numbers. > > This relies on "ahci: Don't start command DMA engine before buffers are > set" > > NOTE: For some reason when running u-boot with this patch Linux is unable > to > correct probe devices. See the next patch for an attempt at a > hack/workaround. > Any ideas would be appreciated. > So, is it RFC? or not? Why you tied up this RFC patch? ([U-Boot,2/2] HACK: arndale: deinit scsi before launching Linux <http://patchwork.ozlabs.org/patch/397316/>) > > Signed-off-by: Ian Campbell <ian.campbell@citrix.com> > Cc: Taylor Hutt <thutt@chromium.org> > Cc: Simon Glass <sjg@chromium.org> > --- > arch/arm/cpu/armv7/exynos/Makefile | 4 + > arch/arm/cpu/armv7/exynos/sata.c | 370 > ++++++++++++++++++++++++++++++++ > arch/arm/include/asm/arch-exynos/sata.h | 29 +++ > arch/arm/lib/board.c | 1 + > board/samsung/arndale/arndale.c | 9 + > include/configs/arndale.h | 13 ++ > 6 files changed, 426 insertions(+) > create mode 100644 arch/arm/cpu/armv7/exynos/sata.c > create mode 100644 arch/arm/include/asm/arch-exynos/sata.h > > diff --git a/arch/arm/cpu/armv7/exynos/Makefile > b/arch/arm/cpu/armv7/exynos/Makefile > index e207bd6..c74a2d4 100644 > --- a/arch/arm/cpu/armv7/exynos/Makefile > +++ b/arch/arm/cpu/armv7/exynos/Makefile > @@ -7,6 +7,10 @@ > > obj-y += clock.o power.o soc.o system.o pinmux.o tzpc.o > > +ifndef CONFIG_SPL_BUILD > +obj-$(CONFIG_EXYNOS5250_AHCI) += sata.o > +endif > + > ifdef CONFIG_SPL_BUILD > obj-$(CONFIG_EXYNOS5) += clock_init_exynos5.o > obj-$(CONFIG_EXYNOS5) += dmc_common.o dmc_init_ddr3.o > diff --git a/arch/arm/cpu/armv7/exynos/sata.c > b/arch/arm/cpu/armv7/exynos/sata.c > new file mode 100644 > index 0000000..14d42e7 > --- /dev/null > +++ b/arch/arm/cpu/armv7/exynos/sata.c > @@ -0,0 +1,370 @@ > +/* > + * Copyright (c) 2012 The Chromium OS Authors. > + * > + * See file CREDITS for list of people who contributed to this > + * project. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of > + * the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, > + * MA 02111-1307 USA > + */ > +#include <asm/types.h> > +#include <ahci.h> > +#include <common.h> > +#include <fdtdec.h> > +#include <scsi.h> > +#include <asm/arch/sata.h> > +#include <asm/arch/pinmux.h> > +#include <asm/arch/clock.h> > +#include <asm/arch/clk.h> > +#include <asm/errno.h> > +#include <asm/gpio.h> > +#include <linux/compiler.h> > + > +#define SATA_AHCI_AXI 0x122f0000 > +#define SATA_PHCTRL_APB 0x12170000 > +#define SATA_PHY_I2C_ABP 0x121d0000 > +#define EXYNOS5_SATA_PHY_CONTROL (0x10040000 + 0x724) > +#define S5P_PMU_SATA_PHY_CONTROL_EN 0x1 > + > +void * const phy_ctrl = (void *)SATA_PHCTRL_APB; > +void * const phy_i2c_base = (void *)SATA_PHY_I2C_ABP; > we don't allow direct access to the register. please refer to other driver. > + > +#define SATA_TIME_LIMIT 10000 > +#define SATA_PHY_I2C_SLAVE_ADDRS 0x70 > + > +#define SATA_RESET 0x4 > +#define RESET_GLOBAL_RST_N (1 << 0) > +#define RESET_CMN_RST_N (1 << 1) > +#define RESET_CMN_BLOCK_RST_N (1 << 2) > +#define RESET_CMN_I2C_RST_N (1 << 3) > +#define RESET_TX_RX_PIPE_RST_N (1 << 4) > +#define RESET_TX_RX_BLOCK_RST_N (1 << 5) > +#define RESET_TX_RX_I2C_RST_N ((1 << 6) | BIT(7)) > + > +#define LINK_RESET 0xF0000 > + > +#define SATA_MODE0 0x10 > + > +#define SATA_CTRL0 0x14 > +#define CTRL0_P0_PHY_CALIBRATED_SEL (1 << 9) > +#define CTRL0_P0_PHY_CALIBRATED (1 << 8) > + > +#define SATA_PHSATA_CTRLM 0xE0 > +#define PHCTRLM_REF_RATE (1 << 1) > +#define PHCTRLM_HIGH_SPEED (1 << 0) > + > +#define SATA_PHSATA_STATM 0xF0 > +#define PHSTATM_PLL_LOCKED (1 << 0) > + > + > please remove blank line. > +/********************** I2C**************/ > +#define SATA_I2C_CON 0x00 > +#define SATA_I2C_STAT 0x04 > +#define SATA_I2C_ADDR 0x08 > +#define SATA_I2C_DS 0x0C > +#define SATA_I2C_LC 0x10 > + > +/* I2CCON reg */ > +#define CON_ACKEN (1 << 7) > +#define CON_CLK512 (1 << 6) > +#define CON_CLK16 (~CON_CLK512) > +#define CON_INTEN (1 << 5) > +#define CON_INTPND (1 << 4) > +#define CON_TXCLK_PS (0xF) > + > +/* I2CSTAT reg */ > +#define STAT_MSTT (0x3 << 6) > +#define STAT_BSYST (1 << 5) > +#define STAT_RTEN (1 << 4) > +#define STAT_LAST (1 << 0) > + > +#define LC_FLTR_EN (1 << 2) > + > +#define SATA_PHY_CON_RESET 0xF003F > + > +#define SCLK_SATA_FREQ (66 * MHZ) > + > + > + > ditto. Do not add more than 2 consecutive empty lines to source files. > +enum { > + SATA_GENERATION1, > + SATA_GENERATION2, > + SATA_GENERATION3, > +}; > + > +static bool sata_is_reg(void __iomem *base, u32 reg, u32 checkbit, u32 > Status) > Please do not use uppercase. > +{ > + if ((__raw_readl(base + reg) & checkbit) == Status) > Please define registers as structure and access via structure. Please fix it globally. > + return true; > + else > + return false; > +} > + > +static bool wait_for_reg_status(void __iomem *base, u32 reg, u32 checkbit, > + u32 Status) > +{ > + u32 time_limit_cnt = 0; > please add blank line. > + while (!sata_is_reg(base, reg, checkbit, Status)) { > + if (time_limit_cnt == SATA_TIME_LIMIT) { > + return false; > + } > please remove brace please check the rule before you make a patch. http://www.denx.de/wiki/U-Boot/CodingStyle I'll stop the review at here. Please send next version patch. > + udelay(1000); > + time_limit_cnt++; > + } > + return true; > +} > Thanks, Minkyu Kang.
On Sun, 2014-10-26 at 16:27 +0900, Minkyu Kang wrote: > Dear Ian Campbell, > > On 7 October 2014 22:56, Ian Campbell <ijc@hellion.org.uk> wrote: > From: Ian Campbell <ian.campbell@citrix.com> > > This is based on some old patches from the chromeos-v2011.12 > branch of > http://git.chromium.org/chromiumos/third_party/u-boot.git by > Taylor Hutt. > Specifically: > > http://git.chromium.org/gitweb/?p=chromiumos/third_party/u-boot.git;a=commit;h=26f6c570b5deb37c52306920ae049203c68f014a > exynos: sata: on-board controller initialization > Signed-off-by: Taylor Hutt <thutt@chromium.org> > > http://git.chromium.org/gitweb/?p=chromiumos/third_party/u-boot.git;a=commit;h=d8cac5cf0b63df00d2d6ac7df814613e4b60b9d1 > exynos: sata: Add sata_initialize() interface > Signed-off-by: Taylor Hutt <thutt@chromium.org> > > http://git.chromium.org/gitweb/?p=chromiumos/third_party/u-boot.git;a=commit;h=dd32462453d6328bc5770859d1b56501f7920d7d > exynos: sata: SATA self-configuration for when SATA device > is enabled > Signed-off-by: Taylor Hutt <thutt@chromium.org> > > As well as rebasing there have been some significant changes. > > - Drop support for smdk5250, which I don't own. > - Implement support for arndale, which I do. > - Since arndale has no need to frob a GPIO on SATA init drop > the associated > code. > - Initialise via the existing scsi_init hook rather than > introducing > sata_initialize, associated build system and > include/configs/*.h changes. > - Use set/clrbits in a bunch of places > - Add some #defines for some magic numbers. > > This relies on "ahci: Don't start command DMA engine before > buffers are set" > > NOTE: For some reason when running u-boot with this patch > Linux is unable to > correct probe devices. See the next patch for an attempt at a > hack/workaround. > Any ideas would be appreciated. > > > So, is it RFC? or not? This patch is, so far as I know, OK wrt the functionality it tries to enable (i.e. sata access from u-boot), but there is a caveat wrt launching Linux afterwards, which I obviously expect means it cannot be applied as is. I have requested any help/ideas you may have. So, do you have advice/ideas on the issue I raised? > Why you tied up this RFC patch? ([U-Boot,2/2] HACK: arndale: deinit > scsi before launching Linux) I'm afraid I don't understand this question. > +void * const phy_ctrl = (void *)SATA_PHCTRL_APB; > +void * const phy_i2c_base = (void *)SATA_PHY_I2C_ABP; > > > we don't allow direct access to the register. > please refer to other driver. There seem to be plenty of drivers in u-boot which use this pattern. Perhaps you could be more specific about what you would like to be done here? [...] > please remove blank line. I'll fix up all the coding style issues before reposting. Ian.
Dear Ian Campbell, On 29/10/14 19:34, Ian Campbell wrote: > On Sun, 2014-10-26 at 16:27 +0900, Minkyu Kang wrote: >> Dear Ian Campbell, >> >> On 7 October 2014 22:56, Ian Campbell <ijc@hellion.org.uk> wrote: >> From: Ian Campbell <ian.campbell@citrix.com> >> >> This is based on some old patches from the chromeos-v2011.12 >> branch of >> http://git.chromium.org/chromiumos/third_party/u-boot.git by >> Taylor Hutt. >> Specifically: >> >> http://git.chromium.org/gitweb/?p=chromiumos/third_party/u-boot.git;a=commit;h=26f6c570b5deb37c52306920ae049203c68f014a >> exynos: sata: on-board controller initialization >> Signed-off-by: Taylor Hutt <thutt@chromium.org> >> >> http://git.chromium.org/gitweb/?p=chromiumos/third_party/u-boot.git;a=commit;h=d8cac5cf0b63df00d2d6ac7df814613e4b60b9d1 >> exynos: sata: Add sata_initialize() interface >> Signed-off-by: Taylor Hutt <thutt@chromium.org> >> >> http://git.chromium.org/gitweb/?p=chromiumos/third_party/u-boot.git;a=commit;h=dd32462453d6328bc5770859d1b56501f7920d7d >> exynos: sata: SATA self-configuration for when SATA device >> is enabled >> Signed-off-by: Taylor Hutt <thutt@chromium.org> >> >> As well as rebasing there have been some significant changes. >> >> - Drop support for smdk5250, which I don't own. >> - Implement support for arndale, which I do. >> - Since arndale has no need to frob a GPIO on SATA init drop >> the associated >> code. >> - Initialise via the existing scsi_init hook rather than >> introducing >> sata_initialize, associated build system and >> include/configs/*.h changes. >> - Use set/clrbits in a bunch of places >> - Add some #defines for some magic numbers. >> >> This relies on "ahci: Don't start command DMA engine before >> buffers are set" >> >> NOTE: For some reason when running u-boot with this patch >> Linux is unable to >> correct probe devices. See the next patch for an attempt at a >> hack/workaround. >> Any ideas would be appreciated. >> >> >> So, is it RFC? or not? > > This patch is, so far as I know, OK wrt the functionality it tries to > enable (i.e. sata access from u-boot), but there is a caveat wrt > launching Linux afterwards, which I obviously expect means it cannot be > applied as is. I have requested any help/ideas you may have. So, do you > have advice/ideas on the issue I raised? Then it's a RFC patch. > >> Why you tied up this RFC patch? ([U-Boot,2/2] HACK: arndale: deinit >> scsi before launching Linux) > > I'm afraid I don't understand this question. > >> +void * const phy_ctrl = (void *)SATA_PHCTRL_APB; >> +void * const phy_i2c_base = (void *)SATA_PHY_I2C_ABP; >> >> >> we don't allow direct access to the register. >> please refer to other driver. > > There seem to be plenty of drivers in u-boot which use this pattern. > Perhaps you could be more specific about what you would like to be done > here? first, we get the base address by accessor function (samsung_get_base_xxx) second, when read the register, we use structures instead of offsets. You can refer other drivers. Thanks, Minkyu Kang.
diff --git a/arch/arm/cpu/armv7/exynos/Makefile b/arch/arm/cpu/armv7/exynos/Makefile index e207bd6..c74a2d4 100644 --- a/arch/arm/cpu/armv7/exynos/Makefile +++ b/arch/arm/cpu/armv7/exynos/Makefile @@ -7,6 +7,10 @@ obj-y += clock.o power.o soc.o system.o pinmux.o tzpc.o +ifndef CONFIG_SPL_BUILD +obj-$(CONFIG_EXYNOS5250_AHCI) += sata.o +endif + ifdef CONFIG_SPL_BUILD obj-$(CONFIG_EXYNOS5) += clock_init_exynos5.o obj-$(CONFIG_EXYNOS5) += dmc_common.o dmc_init_ddr3.o diff --git a/arch/arm/cpu/armv7/exynos/sata.c b/arch/arm/cpu/armv7/exynos/sata.c new file mode 100644 index 0000000..14d42e7 --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/sata.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <asm/types.h> +#include <ahci.h> +#include <common.h> +#include <fdtdec.h> +#include <scsi.h> +#include <asm/arch/sata.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/clock.h> +#include <asm/arch/clk.h> +#include <asm/errno.h> +#include <asm/gpio.h> +#include <linux/compiler.h> + +#define SATA_AHCI_AXI 0x122f0000 +#define SATA_PHCTRL_APB 0x12170000 +#define SATA_PHY_I2C_ABP 0x121d0000 +#define EXYNOS5_SATA_PHY_CONTROL (0x10040000 + 0x724) +#define S5P_PMU_SATA_PHY_CONTROL_EN 0x1 + +void * const phy_ctrl = (void *)SATA_PHCTRL_APB; +void * const phy_i2c_base = (void *)SATA_PHY_I2C_ABP; + +#define SATA_TIME_LIMIT 10000 +#define SATA_PHY_I2C_SLAVE_ADDRS 0x70 + +#define SATA_RESET 0x4 +#define RESET_GLOBAL_RST_N (1 << 0) +#define RESET_CMN_RST_N (1 << 1) +#define RESET_CMN_BLOCK_RST_N (1 << 2) +#define RESET_CMN_I2C_RST_N (1 << 3) +#define RESET_TX_RX_PIPE_RST_N (1 << 4) +#define RESET_TX_RX_BLOCK_RST_N (1 << 5) +#define RESET_TX_RX_I2C_RST_N ((1 << 6) | BIT(7)) + +#define LINK_RESET 0xF0000 + +#define SATA_MODE0 0x10 + +#define SATA_CTRL0 0x14 +#define CTRL0_P0_PHY_CALIBRATED_SEL (1 << 9) +#define CTRL0_P0_PHY_CALIBRATED (1 << 8) + +#define SATA_PHSATA_CTRLM 0xE0 +#define PHCTRLM_REF_RATE (1 << 1) +#define PHCTRLM_HIGH_SPEED (1 << 0) + +#define SATA_PHSATA_STATM 0xF0 +#define PHSTATM_PLL_LOCKED (1 << 0) + + +/********************** I2C**************/ +#define SATA_I2C_CON 0x00 +#define SATA_I2C_STAT 0x04 +#define SATA_I2C_ADDR 0x08 +#define SATA_I2C_DS 0x0C +#define SATA_I2C_LC 0x10 + +/* I2CCON reg */ +#define CON_ACKEN (1 << 7) +#define CON_CLK512 (1 << 6) +#define CON_CLK16 (~CON_CLK512) +#define CON_INTEN (1 << 5) +#define CON_INTPND (1 << 4) +#define CON_TXCLK_PS (0xF) + +/* I2CSTAT reg */ +#define STAT_MSTT (0x3 << 6) +#define STAT_BSYST (1 << 5) +#define STAT_RTEN (1 << 4) +#define STAT_LAST (1 << 0) + +#define LC_FLTR_EN (1 << 2) + +#define SATA_PHY_CON_RESET 0xF003F + +#define SCLK_SATA_FREQ (66 * MHZ) + + + +enum { + SATA_GENERATION1, + SATA_GENERATION2, + SATA_GENERATION3, +}; + +static bool sata_is_reg(void __iomem *base, u32 reg, u32 checkbit, u32 Status) +{ + if ((__raw_readl(base + reg) & checkbit) == Status) + return true; + else + return false; +} + +static bool wait_for_reg_status(void __iomem *base, u32 reg, u32 checkbit, + u32 Status) +{ + u32 time_limit_cnt = 0; + while (!sata_is_reg(base, reg, checkbit, Status)) { + if (time_limit_cnt == SATA_TIME_LIMIT) { + return false; + } + udelay(1000); + time_limit_cnt++; + } + return true; +} + + +static void sata_set_gen(u8 gen) +{ + setbits_le32(phy_ctrl + SATA_MODE0, gen); +} + +/* Address :I2C Address */ +static void sata_i2c_write_addrs(u8 data) +{ + __raw_writeb((data & 0xFE), phy_i2c_base + SATA_I2C_DS); +} + +static void sata_i2c_write_data(u8 data) +{ + __raw_writeb((data), phy_i2c_base + SATA_I2C_DS); +} + +static void sata_i2c_start(void) +{ + setbits_le32(phy_i2c_base + SATA_I2C_STAT, STAT_BSYST); +} + +static void sata_i2c_stop(void) +{ + clrbits_le32(phy_i2c_base + SATA_I2C_STAT, STAT_BSYST); +} + +static bool sata_i2c_get_int_status(void) +{ + if ((__raw_readl(phy_i2c_base + SATA_I2C_CON)) & CON_INTPND) + return true; + else + return false; +} + +static bool sata_i2c_is_tx_ack(void) +{ + if ((__raw_readl(phy_i2c_base + SATA_I2C_STAT)) & STAT_LAST) + return false; + else + return true; +} + +static bool sata_i2c_is_bus_ready(void) +{ + if ((__raw_readl(phy_i2c_base + SATA_I2C_STAT)) & STAT_BSYST) + return false; + else + return true; +} + +static bool sata_i2c_wait_for_busready(u32 time_out) +{ + while (--time_out) { + if (sata_i2c_is_bus_ready()) + return true; + udelay(100); + } + return false; +} + +static bool sata_i2c_wait_for_tx_ack(u32 time_out) +{ + while (--time_out) { + if (sata_i2c_get_int_status()) { + if (sata_i2c_is_tx_ack()) + return true; + } + udelay(100); + } + return false; +} + +static void sata_i2c_clear_int_status(void) +{ + clrbits_le32(phy_i2c_base + SATA_I2C_CON, CON_INTPND); +} + +static void sata_i2c_set_ack_gen(bool enable) +{ + if (enable) + setbits_le32(phy_i2c_base + SATA_I2C_CON, CON_ACKEN); + else + clrbits_le32(phy_i2c_base + SATA_I2C_CON, CON_ACKEN); +} + +static void sata_i2c_set_master_tx(void) +{ + /* Disable I2C */ + clrbits_le32(phy_i2c_base + SATA_I2C_STAT, STAT_RTEN); + + /* Clear Mode */ + clrbits_le32(phy_i2c_base + SATA_I2C_STAT, STAT_MSTT); + + sata_i2c_clear_int_status(); + + /* interrupt disable */ + clrbits_le32(phy_i2c_base + SATA_I2C_CON, CON_INTEN); + + /* Master, Send mode */ + setbits_le32(phy_i2c_base + SATA_I2C_STAT, STAT_MSTT); + + /* interrupt enable */ + setbits_le32(phy_i2c_base + SATA_I2C_CON, CON_INTEN); + + /* Enable I2C */ + setbits_le32(phy_i2c_base + SATA_I2C_STAT, STAT_RTEN); +} + +static void sata_i2c_init(void) +{ + clrbits_le32(phy_i2c_base + SATA_I2C_CON, ~CON_CLK16); + clrbits_le32(phy_i2c_base + SATA_I2C_CON, CON_TXCLK_PS); + setbits_le32(phy_i2c_base + SATA_I2C_CON, 2 & CON_TXCLK_PS); + clrbits_le32(phy_i2c_base + SATA_I2C_LC, LC_FLTR_EN); + + sata_i2c_set_ack_gen(false); +} +static bool sata_i2c_send(u8 slave_addrs, u8 addrs, u8 ucData) +{ + s32 ret = 0; + if (!sata_i2c_wait_for_busready(SATA_TIME_LIMIT)) + return false; + + sata_i2c_init(); + sata_i2c_set_master_tx(); + + __raw_writel(SATA_PHY_CON_RESET, phy_ctrl + SATA_RESET); + sata_i2c_write_addrs(slave_addrs); + sata_i2c_start(); + if (!sata_i2c_wait_for_tx_ack(SATA_TIME_LIMIT)) { + ret = false; + goto STOP; + } + sata_i2c_write_data(addrs); + sata_i2c_clear_int_status(); + if (!sata_i2c_wait_for_tx_ack(SATA_TIME_LIMIT)) { + ret = false; + goto STOP; + } + sata_i2c_write_data(ucData); + sata_i2c_clear_int_status(); + if (!sata_i2c_wait_for_tx_ack(SATA_TIME_LIMIT)) { + ret = false; + goto STOP; + } + ret = true; + +STOP: + sata_i2c_stop(); + sata_i2c_clear_int_status(); + sata_i2c_wait_for_busready(SATA_TIME_LIMIT); + + return ret; +} + +static bool ahci_phy_init(void __iomem *mmio) +{ + u8 uCount, i = 0; + /* 0x3A for 40bit I/F */ + u8 reg_addrs[] = {0x3A}; + /* 0x0B for 40bit I/F */ + u8 default_setting_value[] = {0x0B}; + + uCount = sizeof(reg_addrs)/sizeof(u8); + while (i < uCount) { + if (!sata_i2c_send(SATA_PHY_I2C_SLAVE_ADDRS, reg_addrs[i], + default_setting_value[i])) + return false; + i++; + } + return true; +} + +static int exynos5_ahci_init(void __iomem *mmio) +{ + int ret; + + if (sata_is_reg(phy_ctrl, SATA_CTRL0, + CTRL0_P0_PHY_CALIBRATED, CTRL0_P0_PHY_CALIBRATED)) + { + printf("%s: already calibrated?\n", __func__); + } + + setbits_le32(EXYNOS5_SATA_PHY_CONTROL, S5P_PMU_SATA_PHY_CONTROL_EN); + + __raw_writel(0, phy_ctrl + SATA_RESET); + setbits_le32(phy_ctrl + SATA_RESET, + RESET_GLOBAL_RST_N| + RESET_CMN_BLOCK_RST_N|RESET_CMN_I2C_RST_N| + RESET_TX_RX_PIPE_RST_N|RESET_TX_RX_BLOCK_RST_N); + + setbits_le32(phy_ctrl + SATA_RESET, LINK_RESET); + + setbits_le32(phy_ctrl + SATA_RESET, RESET_CMN_RST_N); + + clrbits_le32(phy_ctrl + SATA_PHSATA_CTRLM, PHCTRLM_REF_RATE); + + /* High speed enable for Gen3 */ + setbits_le32(phy_ctrl + SATA_PHSATA_CTRLM, PHCTRLM_HIGH_SPEED); + + setbits_le32(phy_ctrl + SATA_CTRL0, + CTRL0_P0_PHY_CALIBRATED_SEL|CTRL0_P0_PHY_CALIBRATED); + + sata_set_gen(SATA_GENERATION3); + + ret = ahci_phy_init(mmio); + + /* release cmu reset */ + clrbits_le32(phy_ctrl + SATA_RESET, RESET_CMN_RST_N); + + setbits_le32(phy_ctrl + SATA_RESET, RESET_CMN_RST_N); + + if (wait_for_reg_status(phy_ctrl, SATA_PHSATA_STATM, + PHSTATM_PLL_LOCKED, 1)) + return ret; + + return 0; +} + +static void exynos5_enable_clock_gates(void) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + + /* Turn on all SATA clock gates & DMA gates. */ + const unsigned sata_clocks = (1 << 25) | (1 << 24) | (1 << 6); + const unsigned dma_clocks = (2 << 1) | (1 << 1); + + setbits_le32(&clk->gate_ip_fsys, sata_clocks|dma_clocks); +} + +int exynos5_sata_init(void) +{ + exynos5_enable_clock_gates(); + + if (exynos5_ahci_init((void *)SATA_AHCI_AXI)) { + ahci_init(SATA_AHCI_AXI); + return 0; + } + return -ENODEV; +} diff --git a/arch/arm/include/asm/arch-exynos/sata.h b/arch/arm/include/asm/arch-exynos/sata.h new file mode 100644 index 0000000..a181d01 --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/sata.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __EXYNOS5_SATA_H +#define __EXYNOS5_SATA_H + +int exynos5_sata_init(void); +int exynos5_sata_deinit(void); + +#endif + diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index 76adaf3..c06af34 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -34,6 +34,7 @@ #include <onenand_uboot.h> #include <mmc.h> #include <scsi.h> +#include <sata.h> #include <libfdt.h> #include <fdtdec.h> #include <post.h> diff --git a/board/samsung/arndale/arndale.c b/board/samsung/arndale/arndale.c index 83fd3bd..551bfce 100644 --- a/board/samsung/arndale/arndale.c +++ b/board/samsung/arndale/arndale.c @@ -10,6 +10,7 @@ #include <asm/arch/dwmmc.h> #include <asm/arch/gpio.h> #include <asm/arch/power.h> +#include <asm/arch/sata.h> DECLARE_GLOBAL_DATA_PTR; @@ -29,6 +30,14 @@ int board_usb_init(int index, enum usb_init_type init) } #endif +#ifdef CONFIG_SCSI_AHCI +int scsi_init(void) +{ + printf("ARNDALE SCSI INIT\n"); + return exynos5_sata_init(); +} +#endif + int board_init(void) { gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); diff --git a/include/configs/arndale.h b/include/configs/arndale.h index 292729b..e992769 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -75,6 +75,7 @@ #define CONFIG_SUPPORT_EMMC_BOOT #define CONFIG_BOUNCE_BUFFER +#define CONFIG_EXYNOS5250_AHCI #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_SKIP_LOWLEVEL_INIT @@ -91,6 +92,17 @@ #define CONFIG_CMD_MMC #define CONFIG_CMD_HASH +#ifdef CONFIG_EXYNOS5250_AHCI +#define CONFIG_CMD_SCSI +#define CONFIG_SYS_SCSI_MAX_SCSI_ID 1 +#define CONFIG_SYS_SCSI_MAX_LUN 1 +#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \ + CONFIG_SYS_SCSI_MAX_LUN) +#define CONFIG_LIBATA +#define CONFIG_SCSI_AHCI +#define CONFIG_SCSI_AHCI_PLAT +#endif + #define CONFIG_ZERO_BOOTDELAY_CHECK /* USB */ @@ -204,6 +216,7 @@ #define BOOT_TARGET_DEVICES(func) \ func(MMC, mmc, 1) \ func(MMC, mmc, 0) \ + func(SCSI, scsi, 0) \ func(PXE, pxe, na) \ func(DHCP, dhcp, na)