diff options
Diffstat (limited to 'src/cpu/samsung/exynos5420')
49 files changed, 0 insertions, 13034 deletions
diff --git a/src/cpu/samsung/exynos5420/Kconfig b/src/cpu/samsung/exynos5420/Kconfig deleted file mode 100644 index a0d6c9882c..0000000000 --- a/src/cpu/samsung/exynos5420/Kconfig +++ /dev/null @@ -1,110 +0,0 @@ -config CPU_SAMSUNG_EXYNOS5420 - select ARCH_BOOTBLOCK_ARMV7 - select ARCH_ROMSTAGE_ARMV7 - select ARCH_RAMSTAGE_ARMV7 - select CPU_HAS_BOOTBLOCK_INIT - select HAVE_MONOTONIC_TIMER - select HAVE_UART_SPECIAL - select RELOCATABLE_MODULES - select DYNAMIC_CBMEM - bool - default n - -if CPU_SAMSUNG_EXYNOS5420 - -# ROM image layout. -# -# 0x0000: vendor-provided BL1 (8k). -# 0x2000: variable length bootblock checksum header -# 0x2010: bootblock -# 0x2020-0x20A0: reserved for CBFS master header. -# 0xA000: Free for CBFS data. - -config BOOTBLOCK_ROM_OFFSET - hex - default 0x2010 - -config CBFS_HEADER_ROM_OFFSET - hex "offset of master CBFS header in ROM" - default 0x2020 - -config CBFS_ROM_OFFSET - # Calculated by BOOTBLOCK_ROM_OFFSET + max bootblock size. - hex "offset of CBFS data in ROM" - default 0x0A000 - -config SYS_SDRAM_BASE - hex - default 0x20000000 - -# Example SRAM/iRAM map for Exynos5420 platform: -# -# 0x0202_0000: vendor-provided BL1 -# 0x0202_4400: variable length bootblock checksum header. -# 0x0202_4410: bootblock, assume up to 32KB in size -# 0x0203_0000: romstage, assume up to 128KB in size. -# 0x0205_8000: TTB buffer. -# 0x0205_c000: cache for CBFS data. -# 0x0206_f000: stack bottom -# 0x0207_3000: stack pointer -# 0x0207_3000: shared (with kernel) page for cpu & secondary core states. -# the shared data is currently only <0x50 bytes so we can share -# this page with stack. - -config BOOTBLOCK_BASE - hex - default 0x02024410 - -config ROMSTAGE_BASE - hex - default 0x02030000 - -config RAMSTAGE_BASE - hex - default SYS_SDRAM_BASE - -# Stack may reside in either IRAM or DRAM. We will define it to live -# at the top of IRAM for now. -# -# Stack grows downward, push operation stores register contents in -# consecutive memory locations ending just below SP. -# The setup in the exynos 5420 is a new one for coreboot. We have got -# the bootblock, romstage, and ramstage sharing the same stack space. -# The SRAM is always there and having a known-good stack memory -# makes for a more reliable setup. -# Thus, in this case: -# STACK_TOP: highest stack address in SRAM -# STACK_BOTTOM: lowest stack address in SRAM -# STACK_SIZE: as in standard coreboot usage, size of thread stacks in ramstage -# ROMSTAGE_STACK_SIZE: size of the single stack in romstage - -config STACK_TOP - hex - default 0x02073000 - -config STACK_BOTTOM - hex - default 0x0206f000 - -# STACK_SIZE is for the ramstage core and thread stacks. -# It must be a power of 2, to make the cpu_info computation work, -# and cpu_info needs to work to make SMP startup and threads work. -config STACK_SIZE - hex - default 0x0800 - -# TODO We may probably move this to board-specific implementation files instead -# of KConfig values. -config CBFS_CACHE_ADDRESS - hex "memory address to put CBFS cache data" - default 0x0205c000 - -config CBFS_CACHE_SIZE - hex "size of CBFS cache data" - default 0x00013000 - -config TTB_BUFFER - hex "memory address of the TTB buffer" - default 0x02058000 - -endif diff --git a/src/cpu/samsung/exynos5420/Makefile.inc b/src/cpu/samsung/exynos5420/Makefile.inc deleted file mode 100644 index fd9d3797d6..0000000000 --- a/src/cpu/samsung/exynos5420/Makefile.inc +++ /dev/null @@ -1,61 +0,0 @@ -bootblock-y += spi.c alternate_cbfs.c -bootblock-y += bootblock.c -bootblock-y += pinmux.c mct.c power.c -# Clock is required for UART -bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += clock_init.c -bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += clock.c -bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += monotonic_timer.c -ifeq ($(CONFIG_DRIVERS_UART),y) -bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += uart.c -endif -bootblock-y += wakeup.c -bootblock-y += gpio.c -bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += timer.c - -romstage-y += spi.c alternate_cbfs.c -romstage-y += smp.c -romstage-y += clock.c -romstage-y += clock_init.c -romstage-y += pinmux.c # required by s3c24x0_i2c and uart. -romstage-y += dmc_common.c -romstage-y += dmc_init_ddr3.c -romstage-y += power.c -romstage-y += mct.c -romstage-y += monotonic_timer.c -ifeq ($(CONFIG_DRIVERS_UART),y) -romstage-y += uart.c -endif -romstage-y += wakeup.c -romstage-y += gpio.c -romstage-y += timer.c -romstage-y += i2c.c -#romstage-y += wdt.c -romstage-y += cbmem.c -romstage-y += trustzone.c - -ramstage-y += spi.c alternate_cbfs.c -ramstage-y += clock.c -ramstage-y += clock_init.c -ramstage-y += pinmux.c -ramstage-y += power.c -ramstage-$(CONFIG_DRIVERS_UART) += uart.c -ramstage-y += cpu.c -ramstage-y += tmu.c -ramstage-y += mct.c -ramstage-y += monotonic_timer.c -ramstage-y += timer.c -ramstage-y += gpio.c -ramstage-y += i2c.c -ramstage-y += dp.c dp_lowlevel.c fimd.c -ramstage-y += usb.c -ramstage-y += cbmem.c - -# Run an intermediate step when producing coreboot.rom -# that adds additional components to the final firmware -# image outside of CBFS -.PHONY: exynos5420_add_bl1 -$(obj)/coreboot.rom: exynos5420_add_bl1 -exynos5420_add_bl1: $(obj)/coreboot.pre - printf " DD Adding Samsung Exynos5420 BL1\n" - dd if=3rdparty/cpu/samsung/exynos5420/bl1.bin \ - of=$(obj)/coreboot.pre conv=notrunc >/dev/null 2>&1 diff --git a/src/cpu/samsung/exynos5420/alternate_cbfs.c b/src/cpu/samsung/exynos5420/alternate_cbfs.c deleted file mode 100644 index d19098b948..0000000000 --- a/src/cpu/samsung/exynos5420/alternate_cbfs.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include <assert.h> -#include <cbfs.h> /* This driver serves as a CBFS media source. */ -#include <stdlib.h> -#include <string.h> -#include <arch/cache.h> -#include <console/console.h> -#include "alternate_cbfs.h" -#include "power.h" -#include "spi.h" - -/* This allows USB A-A firmware upload from a compatible host in four parts: - * The first two are the bare BL1 and the Coreboot boot block, which are just - * written to their respective loading addresses. These transfers are initiated - * by the IROM / BL1, so this code has nothing to do with them. - * - * The third transfer is a valid CBFS image that contains only the romstage, - * and must be small enough to fit into alternate_cbfs_size[__BOOT_BLOCK__] in - * IRAM. It is loaded when this function gets called in the boot block, and - * the normal CBFS code extracts the romstage from it. - * - * The fourth transfer is also a CBFS image, but can be of arbitrary size and - * should contain all available stages/payloads/etc. It is loaded when this - * function is called a second time at the end of the romstage, and copied to - * alternate_cbfs_buffer[!__BOOT_BLOCK__] in DRAM. It will reside there for the - * rest of the firmware's lifetime and all subsequent stages (which will not - * have __PRE_RAM__ defined) can just directly reference it there. - */ -static int usb_cbfs_open(struct cbfs_media *media) -{ -#ifdef __PRE_RAM__ - static int first_run = 1; - int (*irom_load_usb)(void) = *irom_load_image_from_usb_ptr; - - if (!first_run) - return 0; - - dcache_mmu_disable(); - if (!irom_load_usb()) { - dcache_mmu_enable(); - printk(BIOS_EMERG, "Unable to load CBFS image via USB!\n"); - return -1; - } - dcache_mmu_enable(); - - /* - * We need to trust the host/irom to copy the image to our - * alternate_cbfs_buffer address... there is no way to control or even - * check the transfer size or target address from our side. - */ - - printk(BIOS_DEBUG, "USB A-A transfer successful, CBFS image should now" - " be at %p\n", alternate_cbfs_buffer); - first_run = 0; -#endif - return 0; -} - -/* - * SDMMC works very similar to USB A-A: we copy the CBFS image into memory - * and read it from there. While SDMMC would also allow direct block by block - * on-demand reading, we might run into problems if we call back into the IROM - * in very late boot stages (e.g. after initializing/changing MMC clocks)... so - * this seems like a safer approach. It also makes it easy to pass our image - * down to payloads. - */ -static int sdmmc_cbfs_open(struct cbfs_media *media) -{ -#ifdef __PRE_RAM__ - /* - * In the bootblock, we just copy the small part that fits in the buffer - * and hope that it's enough (since the romstage is currently always the - * first component in the image, this should work out). In the romstage, - * we copy until our buffer is full (currently 12M) to avoid the pain of - * figuring out the true image size from in here. Since this is mainly a - * developer/debug boot mode, those shortcomings should be bearable. - */ - const u32 count = alternate_cbfs_size / 512; - static int first_run = 1; - int (*irom_load_sdmmc)(u32 start, u32 count, void *dst) = - *irom_sdmmc_read_blocks_ptr; - - if (!first_run) - return 0; - - dcache_mmu_disable(); - if (!irom_load_sdmmc(1, count, alternate_cbfs_buffer)) { - dcache_mmu_enable(); - printk(BIOS_EMERG, "Unable to load CBFS image from SDMMC!\n"); - return -1; - } - dcache_mmu_enable(); - - printk(BIOS_DEBUG, "SDMMC read successful, CBFS image should now be" - " at %p\n", alternate_cbfs_buffer); - first_run = 0; -#endif - return 0; -} - -static int alternate_cbfs_close(struct cbfs_media *media) { return 0; } - -static size_t alternate_cbfs_read(struct cbfs_media *media, void *dest, - size_t offset, size_t count) -{ - ASSERT(offset + count < alternate_cbfs_size); - memcpy(dest, alternate_cbfs_buffer + offset, count); - return count; -} - -static void *alternate_cbfs_map(struct cbfs_media *media, size_t offset, - size_t count) -{ - ASSERT(offset + count < alternate_cbfs_size); - return alternate_cbfs_buffer + offset; -} - -static void *alternate_cbfs_unmap(struct cbfs_media *media, - const void *buffer) { return 0; } - -static int initialize_exynos_sdmmc_cbfs_media(struct cbfs_media *media) -{ - printk(BIOS_DEBUG, "Using Exynos alternate boot mode SDMMC\n"); - - media->open = sdmmc_cbfs_open; - media->close = alternate_cbfs_close; - media->read = alternate_cbfs_read; - media->map = alternate_cbfs_map; - media->unmap = alternate_cbfs_unmap; - - return 0; -} - -static int initialize_exynos_usb_cbfs_media(struct cbfs_media *media) -{ - printk(BIOS_DEBUG, "Using Exynos alternate boot mode USB A-A\n"); - - media->open = usb_cbfs_open; - media->close = alternate_cbfs_close; - media->read = alternate_cbfs_read; - media->map = alternate_cbfs_map; - media->unmap = alternate_cbfs_unmap; - - return 0; -} - -int init_default_cbfs_media(struct cbfs_media *media) -{ - if (*iram_secondary_base == SECONDARY_BASE_BOOT_USB) - return initialize_exynos_usb_cbfs_media(media); - - switch (exynos_power->om_stat & OM_STAT_MASK) { - case OM_STAT_SDMMC: - return initialize_exynos_sdmmc_cbfs_media(media); - case OM_STAT_SPI: - return initialize_exynos_spi_cbfs_media(media, - (void*)CONFIG_CBFS_CACHE_ADDRESS, - CONFIG_CBFS_CACHE_SIZE); - default: - printk(BIOS_EMERG, "Exynos OM_STAT value 0x%x not supported!\n", - exynos_power->om_stat); - return 0; - } -} diff --git a/src/cpu/samsung/exynos5420/alternate_cbfs.h b/src/cpu/samsung/exynos5420/alternate_cbfs.h deleted file mode 100644 index af7751d4ee..0000000000 --- a/src/cpu/samsung/exynos5420/alternate_cbfs.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_ALTERNATE_CBFS_H -#define CPU_SAMSUNG_EXYNOS5420_ALTERNATE_CBFS_H - -/* These are pointers to function pointers. Double indirection! */ -static void * * const irom_sdmmc_read_blocks_ptr = (void * *)0x02020030; -static void * * const irom_msh_read_from_fifo_emmc_ptr = (void * *)0x02020044; -static void * * const irom_msh_end_boot_op_emmc_ptr = (void * *)0x02020048; -static void * * const irom_spi_sf_read_ptr = (void * *)0x02020058; -static void * * const irom_load_image_from_usb_ptr = (void * *)0x02020070; - -#define SECONDARY_BASE_BOOT_USB 0xfeed0002 -static u32 * const iram_secondary_base = (u32 *)0x02020018; - -/* Values pulled from U-Boot, I think the manual is wrong here (for SPI) */ -#define OM_STAT_SDMMC 0x4 -#define OM_STAT_EMMC 0x8 -#define OM_STAT_SPI 0x14 -#define OM_STAT_MASK 0x7f - -#if defined(__BOOT_BLOCK__) - /* A small space in IRAM to hold the romstage-only image */ - static void * const alternate_cbfs_buffer = - (void *)CONFIG_CBFS_CACHE_ADDRESS; - static size_t const alternate_cbfs_size = CONFIG_CBFS_CACHE_SIZE; -#else - /* Just put this anywhere in RAM that's far enough from anything else */ - /* TODO: Find a better way to "reserve" this region? */ - static void * const alternate_cbfs_buffer = (void *)0x77400000; - static size_t const alternate_cbfs_size = 0xc00000; -#endif - -#endif /* CPU_SAMSUNG_EXYNOS5420_ALTERNATE_CBFS_H */ diff --git a/src/cpu/samsung/exynos5420/bootblock.c b/src/cpu/samsung/exynos5420/bootblock.c deleted file mode 100644 index 5d2d2b73ca..0000000000 --- a/src/cpu/samsung/exynos5420/bootblock.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <bootblock_common.h> -#include <arch/cache.h> - -#include "clk.h" -#include "wakeup.h" -#include "cpu.h" - -/* convenient shorthand (in MB) */ -#define SRAM_START (EXYNOS5_SRAM_BASE >> 20) -#define SRAM_SIZE 1 -#define SRAM_END (SRAM_START + SRAM_SIZE) /* plus one... */ - -void bootblock_cpu_init(void) -{ - /* kick off the multi-core timer. - * We want to do this as early as we can. - */ - mct_start(); - - if (get_wakeup_state() == WAKEUP_DIRECT) { - wakeup(); - /* Never returns. */ - } - - /* set up dcache and MMU */ - mmu_init(); - mmu_disable_range(0, SRAM_START); - mmu_config_range(SRAM_START, SRAM_SIZE, DCACHE_WRITEBACK); - mmu_config_range(SRAM_END, 4096 - SRAM_END, DCACHE_OFF); - dcache_mmu_enable(); - - /* For most ARM systems, we have to initialize firmware media source - * (ex, SPI, SD/MMC, or eMMC) now; but for Exynos platform, that is - * already handled by iROM so there's no need to setup again. - */ -} diff --git a/src/cpu/samsung/exynos5420/cbmem.c b/src/cpu/samsung/exynos5420/cbmem.c deleted file mode 100644 index 465032013b..0000000000 --- a/src/cpu/samsung/exynos5420/cbmem.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stddef.h> -#include <cbmem.h> -#include "cpu.h" - -void *cbmem_top(void) -{ - return (void *)(get_fb_base_kb() * KiB); -} diff --git a/src/cpu/samsung/exynos5420/chip.h b/src/cpu/samsung/exynos5420/chip.h deleted file mode 100644 index 220a315380..0000000000 --- a/src/cpu/samsung/exynos5420/chip.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_H -#define CPU_SAMSUNG_EXYNOS5420_H - -#include "gpio.h" - -struct cpu_samsung_exynos5420_config { - /* special magic numbers! */ - int clkval_f; - int upper_margin; - int lower_margin; - int vsync; - int left_margin; - int right_margin; - int hsync; - - int xres; - int yres; - int framebuffer_bits_per_pixel; - - int usb_vbus_gpio; - int usb_hsic_gpio; - - u32 lcdbase; -}; - -#endif /* CPU_SAMSUNG_EXYNOS5420_H */ diff --git a/src/cpu/samsung/exynos5420/clk.h b/src/cpu/samsung/exynos5420/clk.h deleted file mode 100644 index 83d4ad6320..0000000000 --- a/src/cpu/samsung/exynos5420/clk.h +++ /dev/null @@ -1,764 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_CLK_H -#define CPU_SAMSUNG_EXYNOS5420_CLK_H - -#include <stdint.h> - -#include "cpu.h" - -enum periph_id; - -/* This master list of PLLs is ordered arbitrarily. */ -#define APLL 0 -#define MPLL 1 -#define EPLL 2 -#define HPLL 3 -#define VPLL 4 -#define BPLL 5 -#define RPLL 6 -#define SPLL 7 -#define CPLL 8 -#define DPLL 9 -#define IPLL 10 - -unsigned long get_pll_clk(int pllreg); -unsigned long get_arm_clk(void); -unsigned long get_pwm_clk(void); -unsigned long get_uart_clk(int dev_index); -void set_mmc_clk(int dev_index, unsigned int div); - -/** - * get the clk frequency of the required peripherial - * - * @param peripherial Peripherial id - * - * @return frequency of the peripherial clk - */ -unsigned long clock_get_periph_rate(enum periph_id peripheral); - -#include "pinmux.h" - - -#define MCT_HZ 24000000 - -/* - * Set mshci controller instances clock drivder - * - * @param enum periph_id instance of the mshci controller - * - * Return 0 if ok else -1 - */ -int clock_set_mshci(enum periph_id peripheral); - -/* - * Set dwmci controller instances clock drivder - * - * @param enum periph_id instance of the dwmci controller - * - * Return 0 if ok else -1 - */ -int clock_set_dwmci(enum periph_id peripheral); - -/* - * Sets the epll clockrate - * - * @param rate Required clock rate to the presacaler in Hz - * - * Return 0 if ok else -1 - */ -int clock_epll_set_rate(unsigned long rate); - -/* - * selects the clk source for I2S MCLK - */ -void clock_select_i2s_clk_source(void); - -/* - * Set prescaler division based on input and output frequency - * for i2s audio clock - * - * @param src_frq Source frequency in Hz - * @param dst_frq Required MCLK frequency in Hz - * - * Return 0 if ok else -1 - */ -int clock_set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq); - -struct exynos5420_clock { - uint32_t apll_lock; /* 0x10010000 */ - uint8_t res1[0xfc]; - uint32_t apll_con0; - uint32_t apll_con1; - uint8_t res2[0xf8]; - uint32_t clk_src_cpu; - uint8_t res3[0x1fc]; - uint32_t clk_mux_stat_cpu; - uint8_t res4[0xfc]; - uint32_t clk_div_cpu0; /* 0x10010500 */ - uint32_t clk_div_cpu1; - uint8_t res5[0xf8]; - uint32_t clk_div_stat_cpu0; - uint32_t clk_div_stat_cpu1; - uint8_t res6[0xf8]; - uint32_t clk_gate_bus_cpu; - uint8_t res7[0xfc]; - uint32_t clk_gate_sclk_cpu; - uint8_t res8[0x1fc]; - uint32_t clkout_cmu_cpu; /* 0x10010a00 */ - uint32_t clkout_cmu_cpu_div_stat; - uint8_t res9[0x5f8]; - uint32_t armclk_stopctrl; - uint8_t res10[0x4]; - uint32_t arm_ema_ctrl; - uint32_t arm_ema_status; - uint8_t res11[0x10]; - uint32_t pwr_ctrl; - uint32_t pwr_ctrl2; - uint8_t res12[0xd8]; - uint32_t apll_con0_l8; /* 0x1001100 */ - uint32_t apll_con0_l7; - uint32_t apll_con0_l6; - uint32_t apll_con0_l5; - uint32_t apll_con0_l4; - uint32_t apll_con0_l3; - uint32_t apll_con0_l2; - uint32_t apll_con0_l1; - uint32_t iem_control; - uint8_t res13[0xdc]; - uint32_t apll_con1_l8; /* 0x10011200 */ - uint32_t apll_con1_l7; - uint32_t apll_con1_l6; - uint32_t apll_con1_l5; - uint32_t apll_con1_l4; - uint32_t apll_con1_l3; - uint32_t apll_con1_l2; - uint32_t apll_con1_l1; - uint8_t res14[0xe0]; - uint32_t clkdiv_iem_l8; - uint32_t clkdiv_iem_l7; /* 0x10011304 */ - uint32_t clkdiv_iem_l6; - uint32_t clkdiv_iem_l5; - uint32_t clkdiv_iem_l4; - uint32_t clkdiv_iem_l3; - uint32_t clkdiv_iem_l2; - uint32_t clkdiv_iem_l1; - uint8_t res15[0xe0]; - uint32_t l2_status; - uint8_t res16[0x0c]; - uint32_t cpu_status; /* 0x10011410 */ - uint8_t res17[0x0c]; - uint32_t ptm_status; - uint8_t res18[0xbdc]; - uint32_t cmu_cpu_spare0; - uint32_t cmu_cpu_spare1; - uint32_t cmu_cpu_spare2; - uint32_t cmu_cpu_spare3; - uint32_t cmu_cpu_spare4; - uint8_t res19[0x1fdc]; - uint32_t cmu_cpu_version; - uint8_t res20[0x20c]; - uint32_t clk_src_cperi0; /* 0x10014200 */ - uint32_t clk_src_cperi1; - uint8_t res21[0xf8]; - uint32_t clk_src_mask_cperi; - uint8_t res22[0x100]; - uint32_t clk_mux_stat_cperi1; - uint8_t res23[0xfc]; - uint32_t clk_div_cperi1; - uint8_t res24[0xfc]; - uint32_t clk_div_stat_cperi1; - uint8_t res25[0xf8]; - uint32_t clk_gate_bus_cperi0; /* 0x10014700 */ - uint32_t clk_gate_bus_cperi1; - uint8_t res26[0xf8]; - uint32_t clk_gate_sclk_cperi; - uint8_t res27[0xfc]; - uint32_t clk_gate_ip_cperi; - uint8_t res28[0xfc]; - uint32_t clkout_cmu_cperi; - uint32_t clkout_cmu_cperi_div_stat; - uint8_t res29[0x5f8]; - uint32_t dcgidx_map0; /* 0x10015000 */ - uint32_t dcgidx_map1; - uint32_t dcgidx_map2; - uint8_t res30[0x14]; - uint32_t dcgperf_map0; - uint32_t dcgperf_map1; - uint8_t res31[0x18]; - uint32_t dvcidx_map; - uint8_t res32[0x1c]; - uint32_t freq_cpu; - uint32_t freq_dpm; - uint8_t res33[0x18]; - uint32_t dvsemclk_en; /* 0x10015080 */ - uint32_t maxperf; - uint8_t res34[0x2e78]; - uint32_t cmu_cperi_spare0; - uint32_t cmu_cperi_spare1; - uint32_t cmu_cperi_spare2; - uint32_t cmu_cperi_spare3; - uint32_t cmu_cperi_spare4; - uint32_t cmu_cperi_spare5; - uint32_t cmu_cperi_spare6; - uint32_t cmu_cperi_spare7; - uint32_t cmu_cperi_spare8; - uint8_t res35[0xcc]; - uint32_t cmu_cperi_version; /* 0x10017ff0 */ - uint8_t res36[0x50c]; - uint32_t clk_div_g2d; - uint8_t res37[0xfc]; - uint32_t clk_div_stat_g2d; - uint8_t res38[0xfc]; - uint32_t clk_gate_bus_g2d; - uint8_t res39[0xfc]; - uint32_t clk_gate_ip_g2d; - uint8_t res40[0x1fc]; - uint32_t clkout_cmu_g2d; - uint32_t clkout_cmu_g2d_div_stat;/* 0x10018a04 */ - uint8_t res41[0xf8]; - uint32_t cmu_g2d_spare0; - uint32_t cmu_g2d_spare1; - uint32_t cmu_g2d_spare2; - uint32_t cmu_g2d_spare3; - uint32_t cmu_g2d_spare4; - uint8_t res42[0x34dc]; - uint32_t cmu_g2d_version; - uint8_t res43[0x30c]; - uint32_t clk_div_cmu_isp0; - uint32_t clk_div_cmu_isp1; - uint32_t clk_div_isp2; /* 0x1001c308 */ - uint8_t res44[0xf4]; - uint32_t clk_div_stat_cmu_isp0; - uint32_t clk_div_stat_cmu_isp1; - uint32_t clk_div_stat_isp2; - uint8_t res45[0x2f4]; - uint32_t clk_gate_bus_isp0; - uint32_t clk_gate_bus_isp1; - uint32_t clk_gate_bus_isp2; - uint32_t clk_gate_bus_isp3; - uint8_t res46[0xf0]; - uint32_t clk_gate_ip_isp0; - uint32_t clk_gate_ip_isp1; - uint8_t res47[0xf8]; - uint32_t clk_gate_sclk_isp; - uint8_t res48[0x0c]; - uint32_t mcuisp_pwr_ctrl; /* 0x1001c910 */ - uint8_t res49[0x0ec]; - uint32_t clkout_cmu_isp; - uint32_t clkout_cmu_isp_div_stat; - uint8_t res50[0xf8]; - uint32_t cmu_isp_spare0; - uint32_t cmu_isp_spare1; - uint32_t cmu_isp_spare2; - uint32_t cmu_isp_spare3; - uint8_t res51[0x34e0]; - uint32_t cmu_isp_version; - uint8_t res52[0x2c]; - uint32_t cpll_lock; /* 10020020 */ - uint8_t res53[0xc]; - uint32_t dpll_lock; - uint8_t res54[0xc]; - uint32_t epll_lock; - uint8_t res55[0xc]; - uint32_t rpll_lock; - uint8_t res56[0xc]; - uint32_t ipll_lock; - uint8_t res57[0xc]; - uint32_t spll_lock; - uint8_t res58[0xc]; - uint32_t vpll_lock; - uint8_t res59[0xc]; - uint32_t mpll_lock; - uint8_t res60[0x8c]; - uint32_t cpll_con0; /* 10020120 */ - uint32_t cpll_con1; - uint32_t dpll_con0; - uint32_t dpll_con1; - uint32_t epll_con0; - uint32_t epll_con1; - uint32_t epll_con2; - uint8_t res601[0x4]; - uint32_t rpll_con0; - uint32_t rpll_con1; - uint32_t rpll_con2; - uint8_t res602[0x4]; - uint32_t ipll_con0; - uint32_t ipll_con1; - uint8_t res61[0x8]; - uint32_t spll_con0; - uint32_t spll_con1; - uint8_t res62[0x8]; - uint32_t vpll_con0; - uint32_t vpll_con1; - uint8_t res63[0x8]; - uint32_t mpll_con0; - uint32_t mpll_con1; - uint8_t res64[0x78]; - uint32_t clk_src_top0; /* 0x10020200 */ - uint32_t clk_src_top1; - uint32_t clk_src_top2; - uint32_t clk_src_top3; - uint32_t clk_src_top4; - uint32_t clk_src_top5; - uint32_t clk_src_top6; - uint32_t clk_src_top7; - uint8_t res65[0xc]; - uint32_t clk_src_disp10; /* 0x1002022c */ - uint8_t res66[0x10]; - uint32_t clk_src_mau; - uint32_t clk_src_fsys; - uint8_t res67[0x8]; - uint32_t clk_src_peric0; - uint32_t clk_src_peric1; - uint8_t res68[0x18]; - uint32_t clk_src_isp; - uint8_t res69[0x0c]; - uint32_t clk_src_top10; - uint32_t clk_src_top11; - uint32_t clk_src_top12; - uint8_t res70[0x74]; - uint32_t clk_src_mask_top0; - uint32_t clk_src_mask_top1; - uint32_t clk_src_mask_top2; - uint8_t res71[0x10]; - uint32_t clk_src_mask_top7; - uint8_t res72[0xc]; - uint32_t clk_src_mask_disp10; /* 0x1002032c */ - uint8_t res73[0x4]; - uint32_t clk_src_mask_mau; - uint8_t res74[0x8]; - uint32_t clk_src_mask_fsys; - uint8_t res75[0xc]; - uint32_t clk_src_mask_peric0; - uint32_t clk_src_mask_peric1; - uint8_t res76[0x18]; - uint32_t clk_src_mask_isp; - uint8_t res77[0x8c]; - uint32_t clk_mux_stat_top0; /* 0x10020400 */ - uint32_t clk_mux_stat_top1; - uint32_t clk_mux_stat_top2; - uint32_t clk_mux_stat_top3; - uint32_t clk_mux_stat_top4; - uint32_t clk_mux_stat_top5; - uint32_t clk_mux_stat_top6; - uint32_t clk_mux_stat_top7; - uint8_t res78[0x60]; - uint32_t clk_mux_stat_top10; - uint32_t clk_mux_stat_top11; - uint32_t clk_mux_stat_top12; - uint8_t res79[0x74]; - uint32_t clk_div_top0; /* 0x10020500 */ - uint32_t clk_div_top1; - uint32_t clk_div_top2; - uint8_t res80[0x20]; - uint32_t clk_div_disp10; - uint8_t res81[0x14]; - uint32_t clk_div_mau; - uint32_t clk_div_fsys0; - uint32_t clk_div_fsys1; - uint32_t clk_div_fsys2; - uint8_t res82[0x4]; - uint32_t clk_div_peric0; - uint32_t clk_div_peric1; - uint32_t clk_div_peric2; - uint32_t clk_div_peric3; - uint32_t clk_div_peric4; /* 0x10020568 */ - uint8_t res83[0x14]; - uint32_t clk_div_isp0; - uint32_t clk_div_isp1; - uint8_t res84[0x8]; - uint32_t clkdiv2_ratio; - uint8_t res850[0xc]; - uint32_t clkdiv4_ratio; - uint8_t res85[0x5c]; - uint32_t clk_div_stat_top0; - uint32_t clk_div_stat_top1; - uint32_t clk_div_stat_top2; - uint8_t res86[0x20]; - uint32_t clk_div_stat_disp10; - uint8_t res87[0x14]; - uint32_t clk_div_stat_mau; /* 0x10020644 */ - uint32_t clk_div_stat_fsys0; - uint32_t clk_div_stat_fsys1; - uint32_t clk_div_stat_fsys2; - uint8_t res88[0x4]; - uint32_t clk_div_stat_peric0; - uint32_t clk_div_stat_peric1; - uint32_t clk_div_stat_peric2; - uint32_t clk_div_stat_peric3; - uint32_t clk_div_stat_peric4; - uint8_t res89[0x14]; - uint32_t clk_div_stat_isp0; - uint32_t clk_div_stat_isp1; - uint8_t res90[0x8]; - uint32_t clkdiv2_stat0; - uint8_t res91[0xc]; - uint32_t clkdiv4_stat; - uint8_t res92[0x5c]; - uint32_t clk_gate_bus_top; /* 0x10020700 */ - uint8_t res93[0xc]; - uint32_t clk_gate_bus_gscl0; - uint8_t res94[0xc]; - uint32_t clk_gate_bus_gscl1; - uint8_t res95[0x4]; - uint32_t clk_gate_bus_disp1; - uint8_t res96[0x4]; - uint32_t clk_gate_bus_wcore; - uint32_t clk_gate_bus_mfc; - uint32_t clk_gate_bus_g3d; - uint32_t clk_gate_bus_gen; - uint32_t clk_gate_bus_fsys0; - uint32_t clk_gate_bus_fsys1; - uint32_t clk_gate_bus_fsys2; - uint32_t clk_gate_bus_mscl; - uint32_t clk_gate_bus_peric; - uint32_t clk_gate_bus_peric1; - uint8_t res97[0x8]; - uint32_t clk_gate_bus_peris0; - uint32_t clk_gate_bus_peris1; /* 0x10020764 */ - uint8_t res98[0x8]; - uint32_t clk_gate_bus_noc; - uint8_t res99[0xac]; - uint32_t clk_gate_top_sclk_gscl; - uint8_t res1000[0x4]; - uint32_t clk_gate_top_sclk_disp1; - uint8_t res100[0x10]; - uint32_t clk_gate_top_sclk_mau; - uint32_t clk_gate_top_sclk_fsys; - uint8_t res101[0xc]; - uint32_t clk_gate_top_sclk_peric; - uint8_t res102[0xc]; - uint32_t clk_gate_top_sclk_cperi; - uint8_t res103[0xc]; - uint32_t clk_gate_top_sclk_isp; - uint8_t res104[0x9c]; - uint32_t clk_gate_ip_gscl0; - uint8_t res105[0xc]; - uint32_t clk_gate_ip_gscl1; - uint8_t res106[0x4]; - uint32_t clk_gate_ip_disp1; - uint32_t clk_gate_ip_mfc; - uint32_t clk_gate_ip_g3d; - uint32_t clk_gate_ip_gen; /* 0x10020934 */ - uint8_t res107[0xc]; - uint32_t clk_gate_ip_fsys; - uint8_t res108[0x8]; - uint32_t clk_gate_ip_peric; - uint8_t res109[0xc]; - uint32_t clk_gate_ip_peris; - uint8_t res110[0xc]; - uint32_t clk_gate_ip_mscl; - uint8_t res111[0xc]; - uint32_t clk_gate_ip_block; - uint8_t res112[0xc]; - uint32_t bypass; - uint8_t res113[0x6c]; - uint32_t clkout_cmu_top; - uint32_t clkout_cmu_top_div_stat; - uint8_t res114[0xf8]; - uint32_t clkout_top_spare0; - uint32_t clkout_top_spare1; - uint32_t clkout_top_spare2; - uint32_t clkout_top_spare3; - uint8_t res115[0x34e0]; - uint32_t clkout_top_version; - uint8_t res116[0xc01c]; - uint32_t bpll_lock; /* 0x10030010 */ - uint8_t res117[0xfc]; - uint32_t bpll_con0; - uint32_t bpll_con1; - uint8_t res118[0xe8]; - uint32_t clk_src_cdrex; - uint8_t res119[0x1fc]; - uint32_t clk_mux_stat_cdrex; - uint8_t res120[0xfc]; - uint32_t clk_div_cdrex0; - uint32_t clk_div_cdrex1; - uint8_t res121[0xf8]; - uint32_t clk_div_stat_cdrex; - uint8_t res1211[0xfc]; - uint32_t clk_gate_bus_cdrex; - uint32_t clk_gate_bus_cdrex1; - uint8_t res122[0x1f8]; - uint32_t clk_gate_ip_cdrex; - uint8_t res123[0x10]; - uint32_t dmc_freq_ctrl; /* 0x10030914 */ - uint8_t res124[0x4]; - uint32_t pause; - uint32_t ddrphy_lock_ctrl; - uint8_t res125[0xdc]; - uint32_t clkout_cmu_cdrex; - uint32_t clkout_cmu_cdrex_div_stat; - uint8_t res126[0x8]; - uint32_t lpddr3phy_ctrl; - uint32_t lpddr3phy_con0; - uint32_t lpddr3phy_con1; - uint32_t lpddr3phy_con2; - uint32_t lpddr3phy_con3; - uint32_t lpddr3phy_con4; - uint32_t lpddr3phy_con5; /* 0x10030a28 */ - uint32_t pll_div2_sel; - uint8_t res127[0xd0]; - uint32_t cmu_cdrex_spare0; - uint32_t cmu_cdrex_spare1; - uint32_t cmu_cdrex_spare2; - uint32_t cmu_cdrex_spare3; - uint32_t cmu_cdrex_spare4; - uint8_t res128[0x34dc]; - uint32_t cmu_cdrex_version; /* 0x10033ff0 */ - uint8_t res129[0x400c]; - uint32_t kpll_lock; - uint8_t res130[0xfc]; - uint32_t kpll_con0; - uint32_t kpll_con1; - uint8_t res131[0xf8]; - uint32_t clk_src_kfc; - uint8_t res132[0x1fc]; - uint32_t clk_mux_stat_kfc; /* 0x10038400 */ - uint8_t res133[0xfc]; - uint32_t clk_div_kfc0; - uint8_t res134[0xfc]; - uint32_t clk_div_stat_kfc0; - uint8_t res135[0xfc]; - uint32_t clk_gate_bus_cpu_kfc; - uint8_t res136[0xfc]; - uint32_t clk_gate_sclk_cpu_kfc; - uint8_t res137[0x1fc]; - uint32_t clkout_cmu_kfc; - uint32_t clkout_cmu_kfc_div_stat;/* 0x10038a04 */ - uint8_t res138[0x5f8]; - uint32_t armclk_stopctrl_kfc; - uint8_t res139[0x4]; - uint32_t armclk_ema_ctrl_kfc; - uint32_t armclk_ema_status_kfc; - uint8_t res140[0x10]; - uint32_t pwr_ctrl_kfc; - uint32_t pwr_ctrl2_kfc; - uint8_t res141[0xd8]; - uint32_t kpll_con0_l8; - uint32_t kpll_con0_l7; - uint32_t kpll_con0_l6; - uint32_t kpll_con0_l5; - uint32_t kpll_con0_l4; - uint32_t kpll_con0_l3; - uint32_t kpll_con0_l2; - uint32_t kpll_con0_l1; - uint32_t iem_control_kfc; /* 0x10039120 */ - uint8_t res142[0xdc]; - uint32_t kpll_con1_l8; - uint32_t kpll_con1_l7; - uint32_t kpll_con1_l6; - uint32_t kpll_con1_l5; - uint32_t kpll_con1_l4; - uint32_t kpll_con1_l3; - uint32_t kpll_con1_l2; - uint32_t kpll_con1_l1; - uint8_t res143[0xe0]; - uint32_t clkdiv_iem_l8_kfc; /* 0x10039300 */ - uint32_t clkdiv_iem_l7_kfc; - uint32_t clkdiv_iem_l6_kfc; - uint32_t clkdiv_iem_l5_kfc; - uint32_t clkdiv_iem_l4_kfc; - uint32_t clkdiv_iem_l3_kfc; - uint32_t clkdiv_iem_l2_kfc; - uint32_t clkdiv_iem_l1_kfc; - uint8_t res144[0xe0]; - uint32_t l2_status_kfc; - uint8_t res145[0xc]; - uint32_t cpu_status_kfc; /* 0x10039410 */ - uint8_t res146[0xc]; - uint32_t ptm_status_kfc; - uint8_t res147[0xbdc]; - uint32_t cmu_kfc_spare0; - uint32_t cmu_kfc_spare1; - uint32_t cmu_kfc_spare2; - uint32_t cmu_kfc_spare3; - uint32_t cmu_kfc_spare4; - uint8_t res148[0x1fdc]; - uint32_t cmu_kfc_version; /* 0x1003bff0 */ -}; - -static struct exynos5420_clock * const exynos_clock = - (void *)EXYNOS5_CLOCK_BASE; - -struct exynos5_mct { - uint32_t mct_cfg; - uint8_t reserved0[0xfc]; - uint32_t g_cnt_l; - uint32_t g_cnt_u; - uint8_t reserved1[0x8]; - uint32_t g_cnt_wstat; - uint8_t reserved2[0xec]; - uint32_t g_comp0_l; - uint32_t g_comp0_u; - uint32_t g_comp0_addr_incr; - uint8_t reserved3[0x4]; - uint32_t g_comp1_l; - uint32_t g_comp1_u; - uint32_t g_comp1_addr_incr; - uint8_t reserved4[0x4]; - uint32_t g_comp2_l; - uint32_t g_comp2_u; - uint32_t g_comp2_addr_incr; - uint8_t reserved5[0x4]; - uint32_t g_comp3_l; - uint32_t g_comp3_u; - uint32_t g_comp3_addr_incr; - uint8_t reserved6[0x4]; - uint32_t g_tcon; - uint32_t g_int_cstat; - uint32_t g_int_enb; - uint32_t g_wstat; - uint8_t reserved7[0xb0]; - uint32_t l0_tcntb; - uint32_t l0_tcnto; - uint32_t l0_icntb; - uint32_t l0_icnto; - uint32_t l0_frcntb; - uint32_t l0_frcnto; - uint8_t reserved8[0x8]; - uint32_t l0_tcon; - uint8_t reserved9[0xc]; - uint32_t l0_int_cstat; - uint32_t l0_int_enb; - uint8_t reserved10[0x8]; - uint32_t l0_wstat; - uint8_t reserved11[0xbc]; - uint32_t l1_tcntb; - uint32_t l1_tcnto; - uint32_t l1_icntb; - uint32_t l1_icnto; - uint32_t l1_frcntb; - uint32_t l1_frcnto; - uint8_t reserved12[0x8]; - uint32_t l1_tcon; - uint8_t reserved13[0xc]; - uint32_t l1_int_cstat; - uint32_t l1_int_enb; - uint8_t reserved14[0x8]; - uint32_t l1_wstat; -}; - -static struct exynos5_mct * const exynos_mct = - (void *)EXYNOS5_MULTI_CORE_TIMER_BASE; - -#define EXYNOS5_EPLLCON0_LOCKED_SHIFT 29 /* EPLL Locked bit position*/ -#define EPLL_SRC_CLOCK 24000000 /*24 MHz Cristal Input */ -#define TIMEOUT_EPLL_LOCK 1000 - -#define AUDIO_0_RATIO_MASK 0x0f -#define AUDIO_1_RATIO_MASK 0x0f - -#define CLK_SRC_PERIC1 0x254 -#define AUDIO1_SEL_MASK 0xf -#define CLK_SRC_AUDIOCDCLK1 0x0 -#define CLK_SRC_XXTI 0x1 -#define CLK_SRC_SCLK_EPLL 0x7 - -/* CON0 bit-fields */ -#define EPLL_CON0_MDIV_MASK 0x1ff -#define EPLL_CON0_PDIV_MASK 0x3f -#define EPLL_CON0_SDIV_MASK 0x7 -#define EPLL_CON0_LOCKED_SHIFT 29 -#define EPLL_CON0_MDIV_SHIFT 16 -#define EPLL_CON0_PDIV_SHIFT 8 -#define EPLL_CON0_SDIV_SHIFT 0 -#define EPLL_CON0_LOCK_DET_EN_SHIFT 28 -#define EPLL_CON0_LOCK_DET_EN_MASK 1 - -/* structure for epll configuration used in audio clock configuration */ -struct st_epll_con_val { - unsigned int freq_out; /* frequency out */ - unsigned int en_lock_det; /* enable lock detect */ - unsigned int m_div; /* m divider value */ - unsigned int p_div; /* p divider value */ - unsigned int s_div; /* s divider value */ - unsigned int k_dsm; /* k value of delta signal modulator */ -}; - -/** - * Low-level function to set the clock pre-ratio for a peripheral - * - * @param periph_id Peripheral ID of peripheral to change - * @param divisor New divisor for this peripheral's clock - */ -void clock_ll_set_pre_ratio(enum periph_id periph_id, unsigned divisor); - -/** - * Low-level function to set the clock ratio for a peripheral - * - * @param periph_id Peripheral ID of peripheral to change - * @param divisor New divisor for this peripheral's clock - */ -void clock_ll_set_ratio(enum periph_id periph_id, unsigned divisor); - -/** - * Low-level function that selects the best clock scalars for a given rate and - * sets up the given peripheral's clock accordingly. - * - * @param periph_id Peripheral ID of peripheral to change - * @param rate Desired clock rate in Hz - * - * @return zero on success, negative on error - */ -int clock_set_rate(enum periph_id periph_id, unsigned int rate); - -/* Clock gate unused IP */ -void clock_gate(void); - -void mct_start(void); -uint64_t mct_raw_value(void); - -#include "dmc.h" - -/* These are the ratio's for configuring ARM clock */ -struct arm_clk_ratios { - unsigned int arm_freq_mhz; /* Frequency of ARM core in MHz */ - - unsigned int apll_mdiv; - unsigned int apll_pdiv; - unsigned int apll_sdiv; - - unsigned int arm2_ratio; - unsigned int apll_ratio; - unsigned int pclk_dbg_ratio; - unsigned int atb_ratio; - unsigned int periph_ratio; - unsigned int acp_ratio; - unsigned int cpud_ratio; - unsigned int arm_ratio; -}; - -/** - * Get the clock ratios for CPU configuration - * - * @return pointer to the clock ratios that we should use - */ -struct arm_clk_ratios *get_arm_clk_ratios(void); - -/* - * Initialize clock for the device - */ -struct mem_timings; -void system_clock_init(void); - -#endif diff --git a/src/cpu/samsung/exynos5420/clock.c b/src/cpu/samsung/exynos5420/clock.c deleted file mode 100644 index 7043310a43..0000000000 --- a/src/cpu/samsung/exynos5420/clock.c +++ /dev/null @@ -1,639 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <assert.h> -#include <stdlib.h> -#include <timer.h> -#include <arch/io.h> -#include <console/console.h> -#include "clk.h" -#include "periph.h" - -/* input clock of PLL: SMDK5420 has 24MHz input clock */ -#define CONFIG_SYS_CLK_FREQ 24000000 - -/* Epll Clock division values to achive different frequency output */ -static struct st_epll_con_val epll_div[] = { - { 192000000, 0, 48, 3, 1, 0 }, - { 180000000, 0, 45, 3, 1, 0 }, - { 73728000, 1, 73, 3, 3, 47710 }, - { 67737600, 1, 90, 4, 3, 20762 }, - { 49152000, 0, 49, 3, 3, 9961 }, - { 45158400, 0, 45, 3, 3, 10381 }, - { 180633600, 0, 45, 3, 1, 10381 } -}; - -/* exynos5: return pll clock frequency */ -unsigned long get_pll_clk(int pllreg) -{ - unsigned long r, m, p, s, k = 0, mask, fout; - unsigned int freq; - - switch (pllreg) { - case APLL: - r = readl(&exynos_clock->apll_con0); - break; - case MPLL: - r = readl(&exynos_clock->mpll_con0); - break; - case EPLL: - r = readl(&exynos_clock->epll_con0); - k = readl(&exynos_clock->epll_con1); - break; - case VPLL: - r = readl(&exynos_clock->vpll_con0); - k = readl(&exynos_clock->vpll_con1); - break; - case BPLL: - r = readl(&exynos_clock->bpll_con0); - break; - case RPLL: - r = readl(&exynos_clock->rpll_con0); - k = readl(&exynos_clock->rpll_con1); - break; - case SPLL: - r = readl(&exynos_clock->spll_con0); - break; - case CPLL: - r = readl(&exynos_clock->cpll_con0); - break; - case DPLL: - r = readl(&exynos_clock->dpll_con0); - break; - default: - printk(BIOS_DEBUG, "Unsupported PLL (%d)\n", pllreg); - return 0; - } - - /* - * APLL_CON: MIDV [25:16] - * MPLL_CON: MIDV [25:16] - * EPLL_CON: MIDV [24:16] - * VPLL_CON: MIDV [24:16] - */ - if (pllreg == APLL || pllreg == BPLL || pllreg == MPLL || - pllreg == SPLL) - mask = 0x3ff; - else - mask = 0x1ff; - - m = (r >> 16) & mask; - - /* PDIV [13:8] */ - p = (r >> 8) & 0x3f; - /* SDIV [2:0] */ - s = r & 0x7; - - freq = CONFIG_SYS_CLK_FREQ; - - if (pllreg == EPLL || pllreg == RPLL) { - k = k & 0xffff; - /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */ - fout = (m + k / 65536) * (freq / (p * (1 << s))); - } else if (pllreg == VPLL) { - k = k & 0xfff; - /* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */ - fout = (m + k / 1024) * (freq / (p * (1 << s))); - } else { - /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ - fout = m * (freq / (p * (1 << s))); - } - - return fout; -} - -enum peripheral_clock_select { - PERIPH_SRC_CPLL = 1, - PERIPH_SRC_DPLL = 2, - PERIPH_SRC_MPLL = 3, - PERIPH_SRC_SPLL = 4, - PERIPH_SRC_IPLL = 5, - PERIPH_SRC_EPLL = 6, - PERIPH_SRC_RPLL = 7, -}; - -static int clock_select_to_pll(enum peripheral_clock_select sel) -{ - int pll; - - switch (sel) { - case PERIPH_SRC_CPLL: - pll = CPLL; - break; - case PERIPH_SRC_DPLL: - pll = DPLL; - break; - case PERIPH_SRC_MPLL: - pll = MPLL; - break; - case PERIPH_SRC_SPLL: - pll = SPLL; - break; - case PERIPH_SRC_IPLL: - pll = IPLL; - break; - case PERIPH_SRC_EPLL: - pll = EPLL; - break; - case PERIPH_SRC_RPLL: - pll = RPLL; - break; - default: - pll = -1; - break; - } - - return pll; -} - -unsigned long clock_get_periph_rate(enum periph_id peripheral) -{ - unsigned long sclk; - unsigned int src, div; - - switch (peripheral) { - case PERIPH_ID_UART0: - src = (readl(&exynos_clock->clk_src_peric0) >> 4) & 0x7; - div = (readl(&exynos_clock->clk_div_peric0) >> 8) & 0xf; - break; - case PERIPH_ID_UART1: - src = (readl(&exynos_clock->clk_src_peric0) >> 8) & 0x7; - div = (readl(&exynos_clock->clk_div_peric0) >> 12) & 0xf; - break; - case PERIPH_ID_UART2: - src = (readl(&exynos_clock->clk_src_peric0) >> 12) & 0x7; - div = (readl(&exynos_clock->clk_div_peric0) >> 16) & 0xf; - break; - case PERIPH_ID_UART3: - src = (readl(&exynos_clock->clk_src_peric0) >> 16) & 0x7; - div = (readl(&exynos_clock->clk_div_peric0) >> 20) & 0xf; - break; - case PERIPH_ID_PWM0: - case PERIPH_ID_PWM1: - case PERIPH_ID_PWM2: - case PERIPH_ID_PWM3: - case PERIPH_ID_PWM4: - src = (readl(&exynos_clock->clk_src_peric0) >> 24) & 0x7; - div = (readl(&exynos_clock->clk_div_peric0) >> 28) & 0x7; - break; - case PERIPH_ID_SPI0: - src = (readl(&exynos_clock->clk_src_peric1) >> 20) & 0x7; - div = (readl(&exynos_clock->clk_div_peric1) >> 20) & 0xf; - break; - case PERIPH_ID_SPI1: - src = (readl(&exynos_clock->clk_src_peric1) >> 24) & 0x7; - div = (readl(&exynos_clock->clk_div_peric1) >> 24) & 0xf; - break; - case PERIPH_ID_SPI2: - src = (readl(&exynos_clock->clk_src_peric1) >> 28) & 0x7; - div = (readl(&exynos_clock->clk_div_peric1) >> 28) & 0xf; - break; - case PERIPH_ID_SPI3: /* aka SPI0_ISP */ - src = (readl(&exynos_clock->clk_src_isp) >> 16) & 0x7; - div = (readl(&exynos_clock->clk_div_isp0) >> 0) & 0x7; - break; - case PERIPH_ID_SPI4: /* aka SPI1_ISP */ - src = (readl(&exynos_clock->clk_src_isp) >> 12) & 0x7; - div = (readl(&exynos_clock->clk_div_isp1) >> 4) & 0x7; - break; - case PERIPH_ID_I2C0: - case PERIPH_ID_I2C1: - case PERIPH_ID_I2C2: - case PERIPH_ID_I2C3: - case PERIPH_ID_I2C4: - case PERIPH_ID_I2C5: - case PERIPH_ID_I2C6: - case PERIPH_ID_I2C7: - case PERIPH_ID_I2C8: - case PERIPH_ID_I2C9: - case PERIPH_ID_I2C10: - /* - * I2C block parent clock selection is different from other - * peripherals, so we handle it all here. - * TODO: Add a helper function like with the peripheral clock - * select fields? - */ - src = (readl(&exynos_clock->clk_src_top1) >> 8) & 0x3; - if (src == 0x0) - src = CPLL; - else if (src == 0x1) - src = DPLL; - else if (src == 0x2) - src = MPLL; - else - return -1; - - sclk = get_pll_clk(src); - div = ((readl(&exynos_clock->clk_div_top1) >> 8) & 0x3f) + 1; - return sclk / div; - default: - printk(BIOS_DEBUG, "%s: invalid peripheral %d", - __func__, peripheral); - return -1; - }; - - src = clock_select_to_pll(src); - if (src < 0) { - printk(BIOS_DEBUG, "%s: cannot determine source PLL", __func__); - return -1; - } - - sclk = get_pll_clk(src); - - return sclk / (div + 1); -} - -/* exynos5: return ARM clock frequency */ -unsigned long get_arm_clk(void) -{ - unsigned long div; - unsigned long armclk; - unsigned int arm_ratio; - unsigned int arm2_ratio; - - div = readl(&exynos_clock->clk_div_cpu0); - - /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */ - arm_ratio = (div >> 0) & 0x7; - arm2_ratio = (div >> 28) & 0x7; - - armclk = get_pll_clk(APLL) / (arm_ratio + 1); - armclk /= (arm2_ratio + 1); - - return armclk; -} - -/* exynos5: get the mmc clock */ -static unsigned long get_mmc_clk(int dev_index) -{ - unsigned long uclk, sclk; - unsigned int sel, ratio; - int shift = 0; - - sel = readl(&exynos_clock->clk_src_fsys); - sel = (sel >> ((dev_index * 4) + 8)) & 0x7; - - if (sel == 0x3) - sclk = get_pll_clk(MPLL); - else if (sel == 0x6) - sclk = get_pll_clk(EPLL); - else - return 0; - - ratio = readl(&exynos_clock->clk_div_fsys1); - - shift = dev_index * 10; - - ratio = (ratio >> shift) & 0x3ff; - uclk = (sclk / (ratio + 1)); - printk(BIOS_DEBUG, "%s(%d): %lu\n", __func__, dev_index, uclk); - - return uclk; -} - -/* exynos5: set the mmc clock */ -void set_mmc_clk(int dev_index, unsigned int div) -{ - void *addr; - unsigned int val, shift; - - addr = &exynos_clock->clk_div_fsys1; - shift = dev_index * 10; - - val = readl(addr); - val &= ~(0x3ff << shift); - val |= (div & 0x3ff) << shift; - writel(val, addr); -} - -/* Set DW MMC Controller clock */ -int clock_set_dwmci(enum periph_id peripheral) -{ - /* Request MMC clock value to 52MHz. */ - const unsigned long freq = 52000000; - unsigned long sdclkin, cclkin; - int device_index = (int)peripheral - (int)PERIPH_ID_SDMMC0; - - ASSERT(device_index >= 0 && device_index < 4); - sdclkin = get_mmc_clk(device_index); - if (!sdclkin) { - return -1; - } - - /* The SDCLKIN is divided insided controller by the DIVRATIO field in - * CLKSEL register, so we must calculate clock value as - * cclk_in = SDCLKIN / (DIVRATIO + 1) - * Currently the RIVRATIO must be 3 for MMC0 and MMC2 on Exynos5420 - * (and must be configured in payload). - */ - if (device_index == 0 || device_index == 2){ - int divratio = 3; - sdclkin /= (divratio + 1); - } - printk(BIOS_DEBUG, "%s(%d): sdclkin: %ld\n", __func__, device_index, sdclkin); - - cclkin = CEIL_DIV(sdclkin, freq); - set_mmc_clk(device_index, cclkin); - return 0; -} - -void clock_ll_set_pre_ratio(enum periph_id periph_id, unsigned divisor) -{ - unsigned shift; - unsigned mask = 0xff; - u32 *reg; - - /* - * For now we only handle a very small subset of peipherals here. - * Others will need to (and do) mangle the clock registers - * themselves, At some point it is hoped that this function can work - * from a table or calculated register offset / mask. For now this - * is at least better than spreading clock control code around - * U-Boot. - */ - switch (periph_id) { - case PERIPH_ID_SPI0: - reg = &exynos_clock->clk_div_peric4; - shift = 8; - break; - case PERIPH_ID_SPI1: - reg = &exynos_clock->clk_div_peric4; - shift = 16; - break; - case PERIPH_ID_SPI2: - reg = &exynos_clock->clk_div_peric4; - shift = 24; - break; - case PERIPH_ID_SPI3: - reg = &exynos_clock->clk_div_isp1; - shift = 0; - break; - case PERIPH_ID_SPI4: - reg = &exynos_clock->clk_div_isp1; - shift = 8; - break; - default: - printk(BIOS_DEBUG, "%s: Unsupported peripheral ID %d\n", __func__, - periph_id); - return; - } - clrsetbits_le32(reg, mask << shift, (divisor & mask) << shift); -} - -void clock_ll_set_ratio(enum periph_id periph_id, unsigned divisor) -{ - unsigned shift; - unsigned mask = 0xf; - u32 *reg; - - switch (periph_id) { - case PERIPH_ID_SPI0: - reg = &exynos_clock->clk_div_peric1; - shift = 20; - break; - case PERIPH_ID_SPI1: - reg = &exynos_clock->clk_div_peric1; - shift = 24; - break; - case PERIPH_ID_SPI2: - reg = &exynos_clock->clk_div_peric1; - shift = 28; - break; - case PERIPH_ID_SPI3: - reg = &exynos_clock->clk_div_isp1; - shift = 16; - break; - case PERIPH_ID_SPI4: - reg = &exynos_clock->clk_div_isp1; - shift = 20; - break; - default: - printk(BIOS_DEBUG, "%s: Unsupported peripheral ID %d\n", __func__, - periph_id); - return; - } - clrsetbits_le32(reg, mask << shift, (divisor & mask) << shift); -} - -/** - * Linearly searches for the most accurate main and fine stage clock scalars - * (divisors) for a specified target frequency and scalar bit sizes by checking - * all multiples of main_scalar_bits values. Will always return scalars up to or - * slower than target. - * - * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32 - * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32 - * @param input_freq Clock frequency to be scaled in Hz - * @param target_freq Desired clock frequency in Hz - * @param best_fine_scalar Pointer to store the fine stage divisor - * - * @return best_main_scalar Main scalar for desired frequency or -1 if none - * found - */ -static int clock_calc_best_scalar(unsigned int main_scaler_bits, - unsigned int fine_scalar_bits, unsigned int input_rate, - unsigned int target_rate, unsigned int *best_fine_scalar) -{ - int i; - int best_main_scalar = -1; - unsigned int best_error = target_rate; - const unsigned int cap = (1 << fine_scalar_bits) - 1; - const unsigned int loops = 1 << main_scaler_bits; - - printk(BIOS_DEBUG, "Input Rate is %u, Target is %u, Cap is %u\n", input_rate, - target_rate, cap); - - ASSERT(best_fine_scalar != NULL); - ASSERT(main_scaler_bits <= fine_scalar_bits); - - *best_fine_scalar = 1; - - if (input_rate == 0 || target_rate == 0) - return -1; - - if (target_rate >= input_rate) - return 1; - - for (i = 1; i <= loops; i++) { - const unsigned int effective_div = MAX(MIN(input_rate / i / - target_rate, cap), 1); - const unsigned int effective_rate = input_rate / i / - effective_div; - const int error = target_rate - effective_rate; - - printk(BIOS_DEBUG, "%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div, - effective_rate, error); - - if (error >= 0 && error <= best_error) { - best_error = error; - best_main_scalar = i; - *best_fine_scalar = effective_div; - } - } - - return best_main_scalar; -} - -int clock_set_rate(enum periph_id periph_id, unsigned int rate) -{ - int main_scalar; - unsigned int fine; - - switch (periph_id) { - case PERIPH_ID_SPI0: - case PERIPH_ID_SPI1: - case PERIPH_ID_SPI2: - case PERIPH_ID_SPI3: - case PERIPH_ID_SPI4: - main_scalar = clock_calc_best_scalar(4, 8, 400000000, rate, &fine); - if (main_scalar < 0) { - printk(BIOS_DEBUG, "%s: Cannot set clock rate for periph %d", - __func__, periph_id); - return -1; - } - clock_ll_set_ratio(periph_id, main_scalar - 1); - clock_ll_set_pre_ratio(periph_id, fine - 1); - break; - default: - printk(BIOS_DEBUG, "%s: Unsupported peripheral ID %d\n", __func__, - periph_id); - return -1; - } - - return 0; -} - -int clock_set_mshci(enum periph_id peripheral) -{ - u32 *addr; - unsigned int clock; - unsigned int tmp; - unsigned int i; - - /* get mpll clock */ - clock = get_pll_clk(MPLL) / 1000000; - - /* - * CLK_DIV_FSYS1 - * MMC0_PRE_RATIO [15:8], MMC0_RATIO [3:0] - * CLK_DIV_FSYS2 - * MMC2_PRE_RATIO [15:8], MMC2_RATIO [3:0] - */ - switch (peripheral) { - case PERIPH_ID_SDMMC0: - addr = &exynos_clock->clk_div_fsys1; - break; - case PERIPH_ID_SDMMC2: - addr = &exynos_clock->clk_div_fsys2; - break; - default: - printk(BIOS_DEBUG, "invalid peripheral\n"); - return -1; - } - tmp = readl(addr) & ~0xff0f; - for (i = 0; i <= 0xf; i++) { - if ((clock / (i + 1)) <= 400) { - writel(tmp | i << 0, addr); - break; - } - } - return 0; -} - -int clock_epll_set_rate(unsigned long rate) -{ - unsigned int epll_con, epll_con_k; - unsigned int i; - unsigned int lockcnt; - struct mono_time current, end; - - epll_con = readl(&exynos_clock->epll_con0); - epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK << - EPLL_CON0_LOCK_DET_EN_SHIFT) | - EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT | - EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT | - EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT); - - for (i = 0; i < ARRAY_SIZE(epll_div); i++) { - if (epll_div[i].freq_out == rate) - break; - } - - if (i == ARRAY_SIZE(epll_div)) - return -1; - - epll_con_k = epll_div[i].k_dsm << 0; - epll_con |= epll_div[i].en_lock_det << EPLL_CON0_LOCK_DET_EN_SHIFT; - epll_con |= epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT; - epll_con |= epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT; - epll_con |= epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT; - - /* - * Required period ( in cycles) to genarate a stable clock output. - * The maximum clock time can be up to 3000 * PDIV cycles of PLLs - * frequency input (as per spec) - */ - lockcnt = 3000 * epll_div[i].p_div; - - writel(lockcnt, &exynos_clock->epll_lock); - writel(epll_con, &exynos_clock->epll_con0); - writel(epll_con_k, &exynos_clock->epll_con1); - - timer_monotonic_get(¤t); - end = current; - mono_time_add_msecs(&end, TIMEOUT_EPLL_LOCK); - - while (!(readl(&exynos_clock->epll_con0) & - (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) { - if (mono_time_after(¤t, &end)) { - printk(BIOS_DEBUG, "%s: Timeout waiting for EPLL lock\n", __func__); - return -1; - } - timer_monotonic_get(¤t); - } - - return 0; -} - -void clock_select_i2s_clk_source(void) -{ - clrsetbits_le32(&exynos_clock->clk_src_peric1, AUDIO1_SEL_MASK, - (CLK_SRC_SCLK_EPLL)); -} - -int clock_set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq) -{ - unsigned int div ; - - if ((dst_frq == 0) || (src_frq == 0)) { - printk(BIOS_DEBUG, "%s: Invalid requency input for prescaler\n", __func__); - printk(BIOS_DEBUG, "src frq = %d des frq = %d ", src_frq, dst_frq); - return -1; - } - - div = (src_frq / dst_frq); - if (div > AUDIO_1_RATIO_MASK) { - printk(BIOS_DEBUG, "%s: Frequency ratio is out of range\n", __func__); - printk(BIOS_DEBUG, "src frq = %d des frq = %d ", src_frq, dst_frq); - return -1; - } - clrsetbits_le32(&exynos_clock->clk_div_peric4, AUDIO_1_RATIO_MASK, - (div & AUDIO_1_RATIO_MASK)); - return 0; -} diff --git a/src/cpu/samsung/exynos5420/clock_init.c b/src/cpu/samsung/exynos5420/clock_init.c deleted file mode 100644 index cfac01e307..0000000000 --- a/src/cpu/samsung/exynos5420/clock_init.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Clock setup for SMDK5420 board based on EXYNOS5 */ - -#include <delay.h> -#include <console/console.h> -#include "clk.h" -#include "cpu.h" -#include "dp.h" -#include "dmc.h" -#include "setup.h" - -void system_clock_init(void) -{ - u32 val; - - /* Turn on the MCT as early as possible. */ - exynos_mct->g_tcon |= (1 << 8); - - /* PLL locktime */ - writel(APLL_LOCK_VAL, &exynos_clock->apll_lock); - writel(MPLL_LOCK_VAL, &exynos_clock->mpll_lock); - writel(BPLL_LOCK_VAL, &exynos_clock->bpll_lock); - writel(CPLL_LOCK_VAL, &exynos_clock->cpll_lock); - writel(DPLL_LOCK_VAL, &exynos_clock->dpll_lock); - writel(EPLL_LOCK_VAL, &exynos_clock->epll_lock); - writel(VPLL_LOCK_VAL, &exynos_clock->vpll_lock); - writel(IPLL_LOCK_VAL, &exynos_clock->ipll_lock); - writel(SPLL_LOCK_VAL, &exynos_clock->spll_lock); - writel(KPLL_LOCK_VAL, &exynos_clock->kpll_lock); - writel(RPLL_LOCK_VAL, &exynos_clock->rpll_lock); - - setbits_le32(&exynos_clock->clk_src_cpu, MUX_HPM_SEL_MASK); - - writel(0, &exynos_clock->clk_src_top6); - - writel(0, &exynos_clock->clk_src_cdrex); - writel(SRC_KFC_HPM_SEL, &exynos_clock->clk_src_kfc); - writel(HPM_RATIO, &exynos_clock->clk_div_cpu1); - writel(CLK_DIV_CPU0_VAL, &exynos_clock->clk_div_cpu0); - - /* switch A15 clock source to OSC clock before changing APLL */ - clrbits_le32(&exynos_clock->clk_src_cpu, APLL_FOUT); - - /* Set APLL */ - writel(APLL_CON1_VAL, &exynos_clock->apll_con1); - val = set_pll(225, 3, 0); /* FOUT=1800MHz */ - writel(val, &exynos_clock->apll_con0); - while ((readl(&exynos_clock->apll_con0) & PLL_LOCKED) == 0) - ; - - /* now it is safe to switch to APLL */ - setbits_le32(&exynos_clock->clk_src_cpu, APLL_FOUT); - - writel(SRC_KFC_HPM_SEL, &exynos_clock->clk_src_kfc); - writel(CLK_DIV_KFC_VAL, &exynos_clock->clk_div_kfc0); - - /* switch A7 clock source to OSC clock before changing KPLL */ - clrbits_le32(&exynos_clock->clk_src_kfc, KPLL_FOUT); - - /* Set KPLL*/ - writel(KPLL_CON1_VAL, &exynos_clock->kpll_con1); - val = set_pll(0x190, 0x4, 0x2); - writel(val, &exynos_clock->kpll_con0); - while ((readl(&exynos_clock->kpll_con0) & PLL_LOCKED) == 0) - ; - - /* now it is safe to switch to KPLL */ - setbits_le32(&exynos_clock->clk_src_kfc, KPLL_FOUT); - - /* Set MPLL */ - writel(MPLL_CON1_VAL, &exynos_clock->mpll_con1); - val = set_pll(0xc8, 0x3, 0x1); - writel(val, &exynos_clock->mpll_con0); - while ((readl(&exynos_clock->mpll_con0) & PLL_LOCKED) == 0) - ; - - /* Set DPLL */ - writel(DPLL_CON1_VAL, &exynos_clock->dpll_con1); - val = set_pll(0x190, 0x4, 0x2); - writel(val, &exynos_clock->dpll_con0); - while ((readl(&exynos_clock->dpll_con0) & PLL_LOCKED) == 0) - ; - - /* Set EPLL */ - writel(EPLL_CON2_VAL, &exynos_clock->epll_con2); - writel(EPLL_CON1_VAL, &exynos_clock->epll_con1); - val = set_pll(0x64, 0x2, 0x1); - writel(val, &exynos_clock->epll_con0); - while ((readl(&exynos_clock->epll_con0) & PLL_LOCKED) == 0) - ; - - /* Set CPLL */ - writel(CPLL_CON1_VAL, &exynos_clock->cpll_con1); - val = set_pll(0xde, 0x4, 0x1); - writel(val, &exynos_clock->cpll_con0); - while ((readl(&exynos_clock->cpll_con0) & PLL_LOCKED) == 0) - ; - - /* Set IPLL */ - writel(IPLL_CON1_VAL, &exynos_clock->ipll_con1); - val = set_pll(0xB9, 0x3, 0x2); - writel(val, &exynos_clock->ipll_con0); - while ((readl(&exynos_clock->ipll_con0) & PLL_LOCKED) == 0) - ; - - /* Set VPLL */ - writel(VPLL_CON1_VAL, &exynos_clock->vpll_con1); - val = set_pll(0xd7, 0x3, 0x2); - writel(val, &exynos_clock->vpll_con0); - while ((readl(&exynos_clock->vpll_con0) & PLL_LOCKED) == 0) - ; - - /* Set BPLL */ - writel(BPLL_CON1_VAL, &exynos_clock->bpll_con1); - val = set_pll(0xc8, 0x3, 0x1); - writel(val, &exynos_clock->bpll_con0); - while ((readl(&exynos_clock->bpll_con0) & PLL_LOCKED) == 0) - ; - - /* Set SPLL */ - writel(SPLL_CON1_VAL, &exynos_clock->spll_con1); - val = set_pll(200, 0x3, 0x2); /* 400MHz */ - writel(val, &exynos_clock->spll_con0); - while ((readl(&exynos_clock->spll_con0) & PLL_LOCKED) == 0) - ; - - /* We use RPLL as the source for FIMD video stream clock */ - writel(RPLL_CON1_VAL, &exynos_clock->rpll_con1); - writel(RPLL_CON2_VAL, &exynos_clock->rpll_con2); - /* computed by gabe from first principles; u-boot is probably - * wrong again - */ - val = set_pll(0xa0, 0x3, 0x2); - writel(val, &exynos_clock->rpll_con0); - /* note: this is a meaningless exercise. The hardware lock - * detection does not work. So this just spins for some - * time and is done. NO indication of success should attach - * to this or any other spin on a con0 value. - */ - while ((readl(&exynos_clock->rpll_con0) & PLL_LOCKED) == 0) - ; - - writel(CLK_DIV_CDREX0_VAL, &exynos_clock->clk_div_cdrex0); - writel(CLK_DIV_CDREX1_VAL, &exynos_clock->clk_div_cdrex1); - - writel(CLK_SRC_TOP0_VAL, &exynos_clock->clk_src_top0); - writel(CLK_SRC_TOP1_VAL, &exynos_clock->clk_src_top1); - writel(CLK_SRC_TOP2_VAL, &exynos_clock->clk_src_top2); - writel(CLK_SRC_TOP7_VAL, &exynos_clock->clk_src_top7); - - writel(CLK_DIV_TOP0_VAL, &exynos_clock->clk_div_top0); - writel(CLK_DIV_TOP1_VAL, &exynos_clock->clk_div_top1); - writel(CLK_DIV_TOP2_VAL, &exynos_clock->clk_div_top2); - - writel(0, &exynos_clock->clk_src_top10); - writel(0, &exynos_clock->clk_src_top11); - writel(0, &exynos_clock->clk_src_top12); - - writel(CLK_SRC_TOP3_VAL, &exynos_clock->clk_src_top3); - writel(CLK_SRC_TOP4_VAL, &exynos_clock->clk_src_top4); - writel(CLK_SRC_TOP5_VAL, &exynos_clock->clk_src_top5); - - /* DISP1 BLK CLK SELECTION */ - writel(CLK_SRC_DISP1_0_VAL, &exynos_clock->clk_src_disp10); - writel(CLK_DIV_DISP1_0_VAL, &exynos_clock->clk_div_disp10); - - /* AUDIO BLK */ - writel(AUDIO0_SEL_EPLL, &exynos_clock->clk_src_mau); - writel(DIV_MAU_VAL, &exynos_clock->clk_div_mau); - - /* FSYS */ - writel(CLK_SRC_FSYS0_VAL, &exynos_clock->clk_src_fsys); - writel(CLK_DIV_FSYS0_VAL, &exynos_clock->clk_div_fsys0); - writel(CLK_DIV_FSYS1_VAL, &exynos_clock->clk_div_fsys1); - writel(CLK_DIV_FSYS2_VAL, &exynos_clock->clk_div_fsys2); - - writel(CLK_SRC_ISP_VAL, &exynos_clock->clk_src_isp); - writel(CLK_DIV_ISP0_VAL, &exynos_clock->clk_div_isp0); - writel(CLK_DIV_ISP1_VAL, &exynos_clock->clk_div_isp1); - - writel(CLK_SRC_PERIC0_VAL, &exynos_clock->clk_src_peric0); - writel(CLK_SRC_PERIC1_VAL, &exynos_clock->clk_src_peric1); - - writel(CLK_DIV_PERIC0_VAL, &exynos_clock->clk_div_peric0); - writel(CLK_DIV_PERIC1_VAL, &exynos_clock->clk_div_peric1); - writel(CLK_DIV_PERIC2_VAL, &exynos_clock->clk_div_peric2); - writel(CLK_DIV_PERIC3_VAL, &exynos_clock->clk_div_peric3); - writel(CLK_DIV_PERIC4_VAL, &exynos_clock->clk_div_peric4); - - writel(CLK_DIV_CPERI1_VAL, &exynos_clock->clk_div_cperi1); - - writel(CLK_DIV2_RATIO, &exynos_clock->clkdiv2_ratio); - writel(CLK_DIV4_RATIO, &exynos_clock->clkdiv4_ratio); - writel(CLK_DIV_G2D, &exynos_clock->clk_div_g2d); - - writel(CLK_SRC_CPU_VAL, &exynos_clock->clk_src_cpu); - writel(CLK_SRC_TOP6_VAL, &exynos_clock->clk_src_top6); - writel(CLK_SRC_CDREX_VAL, &exynos_clock->clk_src_cdrex); - writel(CLK_SRC_KFC_VAL, &exynos_clock->clk_src_kfc); -} - -void clock_gate(void) -{ - /* Not implemented for now. */ -} diff --git a/src/cpu/samsung/exynos5420/cpu.c b/src/cpu/samsung/exynos5420/cpu.c deleted file mode 100644 index bfb8421910..0000000000 --- a/src/cpu/samsung/exynos5420/cpu.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdlib.h> -#include <string.h> -#include <stddef.h> -#include <delay.h> -#include <console/console.h> -#include <device/device.h> -#include <cbmem.h> -#include <arch/cache.h> -#include "dp.h" -#include "fimd.h" -#include "cpu.h" -#include "clk.h" -#include "chip.h" - -#include <ec/google/chromeec/ec.h> - -static unsigned int cpu_id; -static unsigned int cpu_rev; - -static void set_cpu_id(void) -{ - u32 pro_id = (read32((void *)EXYNOS5_PRO_ID) & 0x00FFF000) >> 12; - - switch (pro_id) { - case 0x200: - /* Exynos4210 EVT0 */ - cpu_id = 0x4210; - cpu_rev = 0; - break; - case 0x210: - /* Exynos4210 EVT1 */ - cpu_id = 0x4210; - break; - case 0x412: - /* Exynos4412 */ - cpu_id = 0x4412; - break; - case 0x520: - /* Exynos5250 */ - cpu_id = 0x5250; - break; - case 0x420: - /* Exynos5420 */ - cpu_id = 0x5420; - break; - } -} - -/* we distinguish a display port device from a raw graphics device - * because there are dramatic differences in startup depending on - * graphics usage. To make startup fast and easier to understand and - * debug we explicitly name this common case. The alternate approach, - * involving lots of machine and callbacks, is hard to debug and - * verify. - */ -static void exynos_displayport_init(device_t dev, u32 lcdbase, - unsigned long fb_size) -{ - struct cpu_samsung_exynos5420_config *conf = dev->chip_info; - /* put these on the stack. If, at some point, we want to move - * this code to a pre-ram stage, it will be much easier. - */ - struct exynos5_fimd_panel panel; - memset(&panel, 0, sizeof(panel)); - - panel.is_dp = 1; /* Display I/F is eDP */ - /* while it is true that we did a memset to zero, - * we leave some 'set to zero' entries here to make - * it clear what's going on. Graphics is confusing. - */ - panel.is_mipi = 0; - panel.fixvclk = 0; - panel.ivclk = 0; - panel.clkval_f = conf->clkval_f; - panel.upper_margin = conf->upper_margin; - panel.lower_margin = conf->lower_margin; - panel.vsync = conf->vsync; - panel.left_margin = conf->left_margin; - panel.right_margin = conf->right_margin; - panel.hsync = conf->hsync; - panel.xres = conf->xres; - panel.yres = conf->yres; - - printk(BIOS_SPEW, "LCD framebuffer @%p\n", (void *)(lcdbase)); - memset((void *)lcdbase, 0, fb_size); /* clear the framebuffer */ - - /* - * We need to clean and invalidate the framebuffer region and disable - * caching as well. We assume that our dcache <--> memory address - * space is identity-mapped in 1MB chunks, so align accordingly. - * - * Note: We may want to do something clever to ensure the framebuffer - * region is aligned such that we don't change dcache policy for other - * stuff inadvertantly. - */ - uint32_t lower = ALIGN_DOWN(lcdbase, MiB); - uint32_t upper = ALIGN_UP(lcdbase + fb_size, MiB); - - dcache_clean_invalidate_by_mva(lower, upper - lower); - mmu_config_range(lower / MiB, (upper - lower) / MiB, DCACHE_OFF); - - mmio_resource(dev, 1, lcdbase/KiB, CEIL_DIV(fb_size, KiB)); -} - -static void tps65090_thru_ec_fet_disable(int index) -{ - uint8_t value = 0; - - if (google_chromeec_i2c_xfer(0x48, 0xe + index, 1, &value, 1, 0)) { - printk(BIOS_ERR, - "Error sending i2c pass through command to EC.\n"); - return; - } -} - -static void cpu_enable(device_t dev) -{ - unsigned long fb_size = FB_SIZE_KB * KiB; - u32 lcdbase = get_fb_base_kb() * KiB; - - ram_resource(dev, 0, RAM_BASE_KB, RAM_SIZE_KB - FB_SIZE_KB); - mmio_resource(dev, 1, lcdbase / KiB, CEIL_DIV(fb_size, KiB)); - - /* - * Disable LCD FETs before we do anything with the display. - * FIXME(dhendrix): This is a gross hack and should be done - * elsewhere (romstage?). - */ - tps65090_thru_ec_fet_disable(1); - tps65090_thru_ec_fet_disable(6); - - exynos_displayport_init(dev, lcdbase, fb_size); - - set_cpu_id(); -} - -static void cpu_init(device_t dev) -{ - printk(BIOS_INFO, "CPU: S5P%X @ %ldMHz\n", - cpu_id, get_arm_clk() / 1000000); -} - -static void cpu_noop(device_t dev) -{ -} - -static struct device_operations cpu_ops = { - .read_resources = cpu_noop, - .set_resources = cpu_noop, - .enable_resources = cpu_enable, - .init = cpu_init, - .scan_bus = 0, -}; - -static void enable_exynos5420_dev(device_t dev) -{ - dev->ops = &cpu_ops; -} - -struct chip_operations cpu_samsung_exynos5420_ops = { - CHIP_NAME("CPU Samsung Exynos 5420") - .enable_dev = enable_exynos5420_dev, -}; diff --git a/src/cpu/samsung/exynos5420/cpu.h b/src/cpu/samsung/exynos5420/cpu.h deleted file mode 100644 index 5b5c731bf0..0000000000 --- a/src/cpu/samsung/exynos5420/cpu.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_CPU_H -#define CPU_SAMSUNG_EXYNOS5420_CPU_H - -#include <arch/io.h> - -#define EXYNOS5_SRAM_BASE 0x02020000 - -/* Base address registers */ -#define EXYNOS5420_GPIO_PART6_BASE 0x03860000 /* Z0 */ -#define EXYNOS5_PRO_ID 0x10000000 -#define EXYNOS5_CLOCK_BASE 0x10010000 -#define EXYNOS5_POWER_BASE 0x10040000 -#define EXYNOS5_SYSREG_BASE 0x10050000 -#define EXYNOS5_TZPC1_DECPROT1SET 0x10110810 -#define EXYNOS5_MULTI_CORE_TIMER_BASE 0x101C0000 -#define EXYNOS5_WATCHDOG_BASE 0x101D0000 -#define EXYNOS5_ACE_SFR_BASE 0x10830000 -#define EXYNOS5_DMC_PHY0_BASE 0x10C00000 -#define EXYNOS5_DMC_PHY1_BASE 0x10C10000 -#define EXYNOS5420_DMC_DREXI_0 0x10C20000 -#define EXYNOS5420_DMC_DREXI_1 0x10C30000 -#define EXYNOS5420_DMC_TZASC_0 0x10D40000 -#define EXYNOS5420_DMC_TZASC_1 0x10D50000 -#define EXYNOS5420_USB_DRD0_XHCI_BASE 0x12000000 -#define EXYNOS5420_USB_DRD0_DWC3_BASE 0x1200C100 -#define EXYNOS5420_USB_DRD0_PHY_BASE 0x12100000 -#define EXYNOS5_USB_HOST_EHCI_BASE 0x12110000 -#define EXYNOS5_USB_HOST_PHY_BASE 0x12130000 -#define EXYNOS5_MMC_BASE 0x12200000 -#define EXYNOS5_MSHC_BASE 0x12240000 -#define EXYNOS5_SROMC_BASE 0x12250000 -#define EXYNOS5420_USB_DRD1_XHCI_BASE 0x12400000 -#define EXYNOS5420_USB_DRD1_DWC3_BASE 0x1240C100 -#define EXYNOS5420_USB_DRD1_PHY_BASE 0x12500000 -#define EXYNOS5_UART0_BASE 0x12C00000 -#define EXYNOS5_UART1_BASE 0x12C10000 -#define EXYNOS5_UART2_BASE 0x12C20000 -#define EXYNOS5_UART3_BASE 0x12C30000 -#define EXYNOS5_I2C_BASE 0x12C60000 -#define EXYNOS5_SPI0_BASE 0x12D20000 -#define EXYNOS5_SPI1_BASE 0x12D30000 -#define EXYNOS5_SPI2_BASE 0x12D40000 -#define EXYNOS5_I2S_BASE 0x12D60000 -#define EXYNOS5420_I2C_8910_BASE 0x12E00000 -#define EXYNOS5_UART_ISP_BASE 0x13190000 -#define EXYNOS5_SPI_ISP_BASE 0x131A0000 -#define EXYNOS5420_GPIO_PART1_BASE 0x13400000 /* Y0 */ -#define EXYNOS5420_GPIO_PART2_BASE 0x13400C00 /* X0..3 */ -#define EXYNOS5420_GPIO_PART3_BASE 0x13410000 /* C0..4, D1, Y0..6 */ -#define EXYNOS5420_GPIO_PART4_BASE 0x14000000 /* E0..1, F0..1, G0..2, J4 */ -#define EXYNOS5420_GPIO_PART5_BASE 0x14010000 /* A0..2, B0..4, H0 */ -#define EXYNOS5420_MIPI_DSIM_BASE 0x14500000 -#define EXYNOS5_DP0_BASE 0x14510000 -#define EXYNOS5_DP1_BASE 0x145B0000 - -/* Marker values stored at the bottom of IRAM stack by SPL */ -#define EXYNOS5_SPL_MARKER 0xb004f1a9 /* hexspeak word: bootflag */ - -#define RST_FLAG_VAL 0xfcba0d10 - -#define EXYNOS5_SPI_NUM_CONTROLLERS 5 -#define EXYNOS_I2C_MAX_CONTROLLERS 8 - -extern struct tmu_info exynos5420_tmu_info; - -/* TODO clean up defines. */ -#define FB_SIZE_KB 4096 -#define RAM_BASE_KB (CONFIG_SYS_SDRAM_BASE >> 10) -#define RAM_SIZE_KB (CONFIG_DRAM_SIZE_MB << 10UL) - -static inline u32 get_fb_base_kb(void) -{ - return RAM_BASE_KB + RAM_SIZE_KB - FB_SIZE_KB; -} - -/* Procedures to setup Exynos5420 CPU */ -void exynos5420_config_smp(void); - -#endif /* _EXYNOS5420_CPU_H */ diff --git a/src/cpu/samsung/exynos5420/dmc.h b/src/cpu/samsung/exynos5420/dmc.h deleted file mode 100644 index fa7482ae89..0000000000 --- a/src/cpu/samsung/exynos5420/dmc.h +++ /dev/null @@ -1,412 +0,0 @@ -/* - * This file is part of the coreboot 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_DMC_H -#define CPU_SAMSUNG_EXYNOS5420_DMC_H - -#define DMC_INTERLEAVE_SIZE 0x1f - -#define PAD_RETENTION_DRAM_COREBLK_VAL 0x10000000 - -/* CONCONTROL register fields */ -#define CONCONTROL_DFI_INIT_START_SHIFT 28 -#define CONCONTROL_RD_FETCH_SHIFT 12 -#define CONCONTROL_RD_FETCH_MASK (0x7 << CONCONTROL_RD_FETCH_SHIFT) -#define CONCONTROL_AREF_EN_SHIFT 5 - -/* PRECHCONFIG register field */ -#define PRECHCONFIG_TP_CNT_SHIFT 24 - -/* PWRDNCONFIG register field */ -#define PWRDNCONFIG_DPWRDN_CYC_SHIFT 0 -#define PWRDNCONFIG_DSREF_CYC_SHIFT 16 - -/* PHY_CON0 register fields */ -#define PHY_CON0_T_WRRDCMD_SHIFT 17 -#define PHY_CON0_T_WRRDCMD_MASK (0x7 << PHY_CON0_T_WRRDCMD_SHIFT) -#define PHY_CON0_CTRL_DDR_MODE_MASK 0x3 -#define PHY_CON0_CTRL_DDR_MODE_SHIFT 11 - -/* PHY_CON1 register fields */ -#define PHY_CON1_RDLVL_RDDATA_ADJ_SHIFT 0 - -/* PHY_CON12 register fields */ -#define PHY_CON12_CTRL_START_POINT_SHIFT 24 -#define PHY_CON12_CTRL_INC_SHIFT 16 -#define PHY_CON12_CTRL_FORCE_SHIFT 8 -#define PHY_CON12_CTRL_START_SHIFT 6 -#define PHY_CON12_CTRL_START_MASK (1 << PHY_CON12_CTRL_START_SHIFT) -#define PHY_CON12_CTRL_DLL_ON_SHIFT 5 -#define PHY_CON12_CTRL_DLL_ON_MASK (1 << PHY_CON12_CTRL_DLL_ON_SHIFT) -#define PHY_CON12_CTRL_REF_SHIFT 1 - -/* PHY_CON16 register fields */ -#define PHY_CON16_ZQ_MODE_DDS_SHIFT 24 -#define PHY_CON16_ZQ_MODE_DDS_MASK (0x7 << PHY_CON16_ZQ_MODE_DDS_SHIFT) - -#define PHY_CON16_ZQ_MODE_TERM_SHIFT 21 -#define PHY_CON16_ZQ_MODE_TERM_MASK (0x7 << PHY_CON16_ZQ_MODE_TERM_SHIFT) - -#define PHY_CON16_ZQ_MODE_NOTERM_MASK (1 << 19) - -/* PHY_CON42 register fields */ -#define PHY_CON42_CTRL_BSTLEN_SHIFT 8 -#define PHY_CON42_CTRL_BSTLEN_MASK (0xff << PHY_CON42_CTRL_BSTLEN_SHIFT) - -#define PHY_CON42_CTRL_RDLAT_SHIFT 0 -#define PHY_CON42_CTRL_RDLAT_MASK (0x1f << PHY_CON42_CTRL_RDLAT_SHIFT) - -#ifndef __ASSEMBLER__ - -#include "cpu.h" - -struct exynos5_dmc { - uint32_t concontrol; - uint32_t memcontrol; - uint32_t cgcontrol; - uint32_t memconfig1; - uint32_t directcmd; - uint32_t prechconfig0; - uint32_t phycontrol0; - uint32_t prechconfig1; - uint8_t res1[0x8]; - uint32_t pwrdnconfig; /* 0x0028*/ - uint32_t timingpzq; - uint32_t timingref; - uint32_t timingrow; - uint32_t timingdata; - uint32_t timingpower; - uint32_t phystatus; - uint8_t res2[0x4]; - uint32_t chipstatus_ch0; /* 0x0048 */ - uint32_t chipstatus_ch1; - uint8_t res3[0x4]; - uint32_t mrstatus; - uint8_t res4[0x8]; - uint32_t qoscontrol0; /* 0x0060 */ - uint8_t resr5[0x4]; - uint32_t qoscontrol1; - uint8_t res6[0x4]; - uint32_t qoscontrol2; - uint8_t res7[0x4]; - uint32_t qoscontrol3; - uint8_t res8[0x4]; - uint32_t qoscontrol4; - uint8_t res9[0x4]; - uint32_t qoscontrol5; - uint8_t res10[0x4]; - uint32_t qoscontrol6; - uint8_t res11[0x4]; - uint32_t qoscontrol7; - uint8_t res12[0x4]; - uint32_t qoscontrol8; - uint8_t res13[0x4]; - uint32_t qoscontrol9; - uint8_t res14[0x4]; - uint32_t qoscontrol10; - uint8_t res15[0x4]; - uint32_t qoscontrol11; - uint8_t res16[0x4]; - uint32_t qoscontrol12; - uint8_t res17[0x4]; - uint32_t qoscontrol13; - uint8_t res18[0x4]; - uint32_t qoscontrol14; - uint8_t res19[0x4]; - uint32_t qoscontrol15; - uint8_t res20[0x4]; - uint32_t timing_set_sw; /* 0x00e0 */ - uint32_t timingrow1; - uint32_t timingdata1; - uint32_t timingpower1; - uint32_t ivcontrol; - uint32_t wrtra_config; - uint32_t rdlvl_config; - uint8_t res21[0x4]; - uint32_t brbrsvcontrol; /* 0x0100*/ - uint32_t brbrsvconfig; - uint32_t brbqosconfig; - uint32_t membaseconfig0; - uint32_t membaseconfig1; /* 0x0110 */ - uint8_t res22[0xc]; - uint32_t wrlvl_config0; /* 0x0120 */ - uint32_t wrlvl_config1; - uint32_t wrlvl_status; - uint8_t res23[0x4]; - uint32_t perevcontrol; /* 0x0130 */ - uint32_t perev0config; - uint32_t perev1config; - uint32_t perev2config; - uint32_t perev3config; - uint8_t res22a[0xc]; - uint32_t ctrl_io_rdata_ch0; - uint32_t ctrl_io_rdata_ch1; - uint8_t res23a[0x8]; - uint32_t cacal_config0; - uint32_t cacal_config1; - uint32_t cacal_status; - uint8_t res24[0x94]; - uint32_t emergent_config0; /* 0x0200 */ - uint32_t emergent_config1; - uint8_t res25[0x8]; - uint32_t bp_control0; - uint32_t bp_control0_r; - uint32_t bp_control0_w; - uint8_t res26[0x4]; - uint32_t bp_control1; - uint32_t bp_control1_r; - uint32_t bp_control1_w; - uint8_t res27[0x4]; - uint32_t bp_control2; - uint32_t bp_control2_r; - uint32_t bp_control2_w; - uint8_t res28[0x4]; - uint32_t bp_control3; - uint32_t bp_control3_r; - uint32_t bp_control3_w; - uint8_t res29[0xb4]; - uint32_t winconfig_odt_w; /* 0x0300 */ - uint8_t res30[0x4]; - uint32_t winconfig_ctrl_read; - uint32_t winconfig_ctrl_gate; - uint8_t res31[0xdcf0]; - uint32_t pmnc_ppc; - uint8_t res32[0xc]; - uint32_t cntens_ppc; - uint8_t res33[0xc]; - uint32_t cntenc_ppc; - uint8_t res34[0xc]; - uint32_t intens_ppc; - uint8_t res35[0xc]; - uint32_t intenc_ppc; - uint8_t res36[0xc]; - uint32_t flag_ppc; /* 0xe050 */ - uint8_t res37[0xac]; - uint32_t ccnt_ppc; - uint8_t res38[0xc]; - uint32_t pmcnt0_ppc; - uint8_t res39[0xc]; - uint32_t pmcnt1_ppc; - uint8_t res40[0xc]; - uint32_t pmcnt2_ppc; - uint8_t res41[0xc]; - uint32_t pmcnt3_ppc; /* 0xe140 */ -} __attribute__((packed)); - -static struct exynos5_dmc * const exynos_drex0 = (void *)EXYNOS5420_DMC_DREXI_0; -static struct exynos5_dmc * const exynos_drex1 = (void *)EXYNOS5420_DMC_DREXI_1; - -struct exynos5_phy_control { - uint32_t phy_con0; - uint32_t phy_con1; - uint32_t phy_con2; - uint32_t phy_con3; - uint32_t phy_con4; - uint8_t res1[4]; - uint32_t phy_con6; - uint8_t res2[4]; - uint32_t phy_con8; - uint32_t phy_con9; - uint32_t phy_con10; - uint8_t res3[4]; - uint32_t phy_con12; - uint32_t phy_con13; - uint32_t phy_con14; - uint32_t phy_con15; - uint32_t phy_con16; - uint8_t res4[4]; - uint32_t phy_con17; - uint32_t phy_con18; - uint32_t phy_con19; - uint32_t phy_con20; - uint32_t phy_con21; - uint32_t phy_con22; - uint32_t phy_con23; - uint32_t phy_con24; - uint32_t phy_con25; - uint32_t phy_con26; - uint32_t phy_con27; - uint32_t phy_con28; - uint32_t phy_con29; - uint32_t phy_con30; - uint32_t phy_con31; - uint32_t phy_con32; - uint32_t phy_con33; - uint32_t phy_con34; - uint32_t phy_con35; - uint32_t phy_con36; - uint32_t phy_con37; - uint32_t phy_con38; - uint32_t phy_con39; - uint32_t phy_con40; - uint32_t phy_con41; - uint32_t phy_con42; -} __attribute__((packed)); - -static struct exynos5_phy_control * const exynos_phy0_control = - (void *)EXYNOS5_DMC_PHY0_BASE; -static struct exynos5_phy_control * const exynos_phy1_control = - (void *)EXYNOS5_DMC_PHY1_BASE; - -struct exynos5_tzasc { - uint8_t res1[0xf00]; - uint32_t membaseconfig0; - uint32_t membaseconfig1; - uint8_t res2[0x8]; - uint32_t memconfig0; - uint32_t memconfig1; -} __attribute__((packed)); - -static struct exynos5_tzasc * const exynos_tzasc0 = - (void *)EXYNOS5420_DMC_TZASC_0; -static struct exynos5_tzasc * const exynos_tzasc1 = - (void *)EXYNOS5420_DMC_TZASC_1; - -enum ddr_mode { - /* This is in order of ctrl_ddr_mode values. Do not change. */ - DDR_MODE_DDR2 = 0x0, - DDR_MODE_DDR3 = 0x1, - DDR_MODE_LPDDR2 = 0x2, - DDR_MODE_LPDDR3 = 0x3, - - DDR_MODE_COUNT, -}; - -/* For reasons unknown, people are in the habit of taking a 32-bit - * field with 2 possible values and packing it with, say, 2 bits. A - * non-robust encoding, using only 2 bits of a 32-bit field, is - * incredibly difficult to deal with when things go wrong, because - * there are a lot of things that get expressed as 0, 1, or 2. If - * you're scanning with jtag or dumping memory it is really hard to - * tell when you've hit the beginning of the struct. So, let's be a - * bit smart here. First, while it's common to let the enum count - * entries for you, when there are two of them, we can do the - * counting. And, let's set the values to something we can easily scan - * for in memory. Since '1' and '2' are rather common, we pick - * something that's actually of some value when things go wrong. This - * setup motivated by a use case: something's going wrong and having a - * manuf name of '1' or '2' is completely useless! - */ -enum mem_manuf { - MEM_MANUF_AUTODETECT, - MEM_MANUF_ELPIDA = 0xe7b1da, - MEM_MANUF_SAMSUNG = 0x5a5096, - - MEM_MANUF_COUNT = 2, // fancy that. -}; - -enum { - MEM_TIMINGS_MSR_COUNT = 5, -}; - - -/* These are the memory timings for a particular memory type and speed */ -struct mem_timings { - enum mem_manuf mem_manuf; /* Memory manufacturer */ - enum ddr_mode mem_type; /* Memory type */ - unsigned int frequency_mhz; /* Frequency of memory in MHz */ - - /* Here follow the timing parameters for the selected memory */ - uint8_t apll_mdiv; - uint8_t apll_pdiv; - uint8_t apll_sdiv; - uint8_t mpll_mdiv; - uint8_t mpll_pdiv; - uint8_t mpll_sdiv; - uint8_t cpll_mdiv; - uint8_t cpll_pdiv; - uint8_t cpll_sdiv; - uint8_t gpll_pdiv; - uint16_t gpll_mdiv; - uint8_t gpll_sdiv; - uint8_t epll_mdiv; - uint8_t epll_pdiv; - uint8_t epll_sdiv; - uint8_t vpll_mdiv; - uint8_t vpll_pdiv; - uint8_t vpll_sdiv; - uint8_t bpll_mdiv; - uint8_t bpll_pdiv; - uint8_t bpll_sdiv; - uint8_t use_bpll; /* 1 to use BPLL for cdrex, 0 to use MPLL */ - uint8_t pclk_cdrex_ratio; - unsigned int direct_cmd_msr[MEM_TIMINGS_MSR_COUNT]; - - unsigned int timing_ref; - unsigned int timing_row; - unsigned int timing_data; - unsigned int timing_power; - - /* DQS, DQ, DEBUG offsets */ - unsigned int phy0_dqs; - unsigned int phy1_dqs; - unsigned int phy0_dq; - unsigned int phy1_dq; - uint8_t phy0_tFS; - uint8_t phy1_tFS; - uint8_t phy0_pulld_dqs; - uint8_t phy1_pulld_dqs; - - uint8_t lpddr3_ctrl_phy_reset; - uint8_t ctrl_start_point; - uint8_t ctrl_inc; - uint8_t ctrl_start; - uint8_t ctrl_dll_on; - uint8_t ctrl_ref; - - uint8_t ctrl_force; - uint8_t ctrl_rdlat; - uint8_t ctrl_bstlen; - - uint8_t fp_resync; - uint8_t iv_size; - uint8_t dfi_init_start; - uint8_t aref_en; - - uint8_t rd_fetch; - - uint8_t zq_mode_dds; - uint8_t zq_mode_term; - uint8_t zq_mode_noterm; /* 1 to allow termination disable */ - - unsigned int memcontrol; - unsigned int memconfig; - - unsigned int membaseconfig0; - unsigned int membaseconfig1; - unsigned int prechconfig_tp_cnt; - unsigned int dpwrdn_cyc; - unsigned int dsref_cyc; - unsigned int concontrol; - /* Channel and Chip Selection */ - uint8_t dmc_channels; /* number of memory channels */ - uint8_t chips_per_channel; /* number of chips per channel */ - uint8_t chips_to_configure; /* number of chips to configure */ - uint8_t send_zq_init; /* 1 to send this command */ - unsigned int impedance; /* drive strength impedeance */ - uint8_t gate_leveling_enable; /* check gate leveling is enabled */ -}; - -/** - * Get the correct memory timings for our selected memory type and speed. - * - * @return pointer to the memory timings that we should use - */ -struct mem_timings *get_mem_timings(void); - -#endif -#endif diff --git a/src/cpu/samsung/exynos5420/dmc_common.c b/src/cpu/samsung/exynos5420/dmc_common.c deleted file mode 100644 index 433312eb3e..0000000000 --- a/src/cpu/samsung/exynos5420/dmc_common.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Mem setup common file for different types of DDR present on SMDK5420 boards. - */ - -#include <console/console.h> -#include <arch/io.h> -#include <delay.h> -#include "dmc.h" -#include "setup.h" -#include "clk.h" - -#define ZQ_INIT_TIMEOUT 10000 - -int dmc_config_zq(struct mem_timings *mem, - struct exynos5_phy_control *phy0_ctrl, - struct exynos5_phy_control *phy1_ctrl) -{ - unsigned long val = 0; - int i; - - /* - * ZQ Calibration: - * Select Driver Strength, - * long calibration for manual calibration - */ - val = PHY_CON16_RESET_VAL; - val |= mem->zq_mode_dds << PHY_CON16_ZQ_MODE_DDS_SHIFT; - val |= mem->zq_mode_term << PHY_CON16_ZQ_MODE_TERM_SHIFT; - val |= ZQ_CLK_DIV_EN; - writel(val, &phy0_ctrl->phy_con16); - writel(val, &phy1_ctrl->phy_con16); - - /* Disable termination */ - if (mem->zq_mode_noterm) - val |= PHY_CON16_ZQ_MODE_NOTERM_MASK; - writel(val, &phy0_ctrl->phy_con16); - writel(val, &phy1_ctrl->phy_con16); - - /* ZQ_MANUAL_START: Enable */ - val |= ZQ_MANUAL_STR; - writel(val, &phy0_ctrl->phy_con16); - writel(val, &phy1_ctrl->phy_con16); - - /* ZQ_MANUAL_START: Disable */ - val &= ~ZQ_MANUAL_STR; - - /* - * Since we are manaully calibrating the ZQ values, - * we are looping for the ZQ_init to complete. - */ - i = ZQ_INIT_TIMEOUT; - while ((readl(&phy0_ctrl->phy_con17) & ZQ_DONE) != ZQ_DONE && i > 0) { - udelay(1); - i--; - } - if (!i) - return -1; - writel(val, &phy0_ctrl->phy_con16); - - i = ZQ_INIT_TIMEOUT; - while ((readl(&phy1_ctrl->phy_con17) & ZQ_DONE) != ZQ_DONE && i > 0) { - udelay(1); - i--; - } - if (!i) - return -1; - writel(val, &phy1_ctrl->phy_con16); - - return 0; -} - -void update_reset_dll(struct exynos5_dmc *dmc, enum ddr_mode mode) -{ - unsigned long val; - - if (mode == DDR_MODE_DDR3) { - val = MEM_TERM_EN | PHY_TERM_EN | DMC_CTRL_SHGATE; - writel(val, &dmc->phycontrol0); - } - - /* Update DLL Information: Force DLL Resyncronization */ - val = readl(&dmc->phycontrol0); - val |= FP_RSYNC; - writel(val, &dmc->phycontrol0); - - /* Reset Force DLL Resyncronization */ - val = readl(&dmc->phycontrol0); - val &= ~FP_RSYNC; - writel(val, &dmc->phycontrol0); -} - -void dmc_config_mrs(struct mem_timings *mem, struct exynos5_dmc *dmc) -{ - int channel, chip; - - for (channel = 0; channel < mem->dmc_channels; channel++) { - unsigned long mask; - - mask = channel << DIRECT_CMD_CHANNEL_SHIFT; - for (chip = 0; chip < mem->chips_to_configure; chip++) { - int i; - - mask |= chip << DIRECT_CMD_CHIP_SHIFT; - - /* Sending NOP command */ - writel(DIRECT_CMD_NOP | mask, &dmc->directcmd); - - /* - * TODO(alim.akhtar@samsung.com): Do we need these - * delays? This one and the next were not there for - * DDR3. - */ - udelay(100); - - /* Sending EMRS/MRS commands */ - for (i = 0; i < MEM_TIMINGS_MSR_COUNT; i++) { - writel(mem->direct_cmd_msr[i] | mask, - &dmc->directcmd); - udelay(100); - } - - if (mem->send_zq_init) { - /* Sending ZQINIT command */ - writel(DIRECT_CMD_ZQINIT | mask, - &dmc->directcmd); - /* - * FIXME: This was originally sdelay(10000) - * in the imported u-boot code. That may have - * been meant to be sdelay(0x10000) since that - * was used elsewhere in this function. Either - * way seems to work, though. - */ - udelay(12); - } - } - } -} - -void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc) -{ - int channel, chip; - - for (channel = 0; channel < mem->dmc_channels; channel++) { - unsigned long mask; - - mask = channel << DIRECT_CMD_CHANNEL_SHIFT; - for (chip = 0; chip < mem->chips_per_channel; chip++) { - mask |= chip << DIRECT_CMD_CHIP_SHIFT; - - /* PALL (all banks precharge) CMD */ - writel(DIRECT_CMD_PALL | mask, &dmc->directcmd); - udelay(100); - } - } -} diff --git a/src/cpu/samsung/exynos5420/dmc_init_ddr3.c b/src/cpu/samsung/exynos5420/dmc_init_ddr3.c deleted file mode 100644 index 4acf7d13f3..0000000000 --- a/src/cpu/samsung/exynos5420/dmc_init_ddr3.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * DDR3 mem setup file for EXYNOS5 based board - * - * Copyright (C) 2012 Samsung Electronics - * - * 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 <delay.h> -#include <arch/io.h> -#include <console/console.h> -#include "clk.h" -#include "dmc.h" -#include "power.h" -#include "setup.h" - -#define TIMEOUT 10000 - -/* 'reset' field is currently ignored. */ - -int ddr3_mem_ctrl_init(struct mem_timings *mem, int interleave_size, int reset) -{ - u32 val, nLockR, nLockW_phy0, nLockW_phy1; - int i, chip; - - /* Enable PAUSE for DREX */ - setbits_le32(&exynos_clock->pause, ENABLE_BIT); - - /* Enable BYPASS mode */ - setbits_le32(&exynos_clock->bpll_con1, BYPASS_EN); - - writel(MUX_BPLL_SEL_FOUTBPLL, &exynos_clock->clk_src_cdrex); - do { - val = readl(&exynos_clock->clk_mux_stat_cdrex); - val &= BPLL_SEL_MASK; - } while (val != FOUTBPLL); - - clrbits_le32(&exynos_clock->bpll_con1, BYPASS_EN); - - /* Specify the DDR memory type as DDR3 */ - val = readl(&exynos_phy0_control->phy_con0); - val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT); - val |= (mem->mem_type << PHY_CON0_CTRL_DDR_MODE_SHIFT); - writel(val, &exynos_phy0_control->phy_con0); - - val = readl(&exynos_phy1_control->phy_con0); - val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT); - val |= (mem->mem_type << PHY_CON0_CTRL_DDR_MODE_SHIFT); - writel(val, &exynos_phy1_control->phy_con0); - - /* Set Read Latency and Burst Length for PHY0 and PHY1 */ - val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) | - (mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT); - writel(val, &exynos_phy0_control->phy_con42); - writel(val, &exynos_phy1_control->phy_con42); - - val = readl(&exynos_phy0_control->phy_con26); - val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET); - val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET); - writel(val, &exynos_phy0_control->phy_con26); - - val = readl(&exynos_phy1_control->phy_con26); - val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET); - val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET); - writel(val, &exynos_phy1_control->phy_con26); - - /* Set Driver strength for CK, CKE, CS & CA to 0x7 - * Set Driver strength for Data Slice 0~3 to 0x6 - */ - val = (0x7 << CA_CK_DRVR_DS_OFFSET) | (0x7 << CA_CKE_DRVR_DS_OFFSET) | - (0x7 << CA_CS_DRVR_DS_OFFSET) | (0x7 << CA_ADR_DRVR_DS_OFFSET); - val |= (0x7 << DA_3_DS_OFFSET) | (0x7 << DA_2_DS_OFFSET) | - (0x7 << DA_1_DS_OFFSET) | (0x7 << DA_0_DS_OFFSET); - writel(val, &exynos_phy0_control->phy_con39); - writel(val, &exynos_phy1_control->phy_con39); - - /* ZQ Calibration */ - if (dmc_config_zq(mem, exynos_phy0_control, exynos_phy1_control)) - return SETUP_ERR_ZQ_CALIBRATION_FAILURE; - - clrbits_le32(&exynos_phy0_control->phy_con16, ZQ_CLK_DIV_EN); - clrbits_le32(&exynos_phy1_control->phy_con16, ZQ_CLK_DIV_EN); - - /* DQ Signal */ - val = readl(&exynos_phy0_control->phy_con14); - val |= mem->phy0_pulld_dqs; - writel(val, &exynos_phy0_control->phy_con14); - val = readl(&exynos_phy1_control->phy_con14); - val |= mem->phy1_pulld_dqs; - writel(val, &exynos_phy1_control->phy_con14); - - val = MEM_TERM_EN | PHY_TERM_EN; - writel(val, &exynos_drex0->phycontrol0); - writel(val, &exynos_drex1->phycontrol0); - - writel(mem->concontrol | - (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) | - (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT), - &exynos_drex0->concontrol); - writel(mem->concontrol | - (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) | - (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT), - &exynos_drex1->concontrol); - - do { - val = readl(&exynos_drex0->phystatus); - } while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE); - do { - val = readl(&exynos_drex1->phystatus); - } while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE); - - clrbits_le32(&exynos_drex0->concontrol, DFI_INIT_START); - clrbits_le32(&exynos_drex1->concontrol, DFI_INIT_START); - - update_reset_dll(exynos_drex0, mem->mem_type); - update_reset_dll(exynos_drex1, mem->mem_type); - - /* MEMBASECONFIG0 (CS0) */ - writel(mem->membaseconfig0, &exynos_tzasc0->membaseconfig0); - writel(mem->membaseconfig0, &exynos_tzasc1->membaseconfig0); - - /* MEMBASECONFIG1 (CS1) */ - if (mem->chips_per_channel == 2) { - writel(mem->membaseconfig1, &exynos_tzasc0->membaseconfig1); - writel(mem->membaseconfig1, &exynos_tzasc1->membaseconfig1); - } - - /* Memory Channel Inteleaving Size - * Exynos5420 Channel interleaving = 128 bytes - */ - /* MEMCONFIG0/1 */ - writel(mem->memconfig, &exynos_tzasc0->memconfig0); - writel(mem->memconfig, &exynos_tzasc1->memconfig0); - writel(mem->memconfig, &exynos_tzasc0->memconfig1); - writel(mem->memconfig, &exynos_tzasc1->memconfig1); - - /* Precharge Configuration */ - writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT, - &exynos_drex0->prechconfig0); - writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT, - &exynos_drex1->prechconfig0); - - /* TimingRow, TimingData, TimingPower and Timingaref - * values as per Memory AC parameters - */ - writel(mem->timing_ref, &exynos_drex0->timingref); - writel(mem->timing_ref, &exynos_drex1->timingref); - writel(mem->timing_row, &exynos_drex0->timingrow); - writel(mem->timing_row, &exynos_drex1->timingrow); - writel(mem->timing_data, &exynos_drex0->timingdata); - writel(mem->timing_data, &exynos_drex1->timingdata); - writel(mem->timing_power, &exynos_drex0->timingpower); - writel(mem->timing_power, &exynos_drex1->timingpower); - - if (reset) { - /* Send NOP, MRS and ZQINIT commands. - * Sending MRS command will reset the DRAM. We should not be - * reseting the DRAM after resume, this will lead to memory - * corruption as DRAM content is lost after DRAM reset. - */ - dmc_config_mrs(mem, exynos_drex0); - dmc_config_mrs(mem, exynos_drex1); - } else { - u32 ret; - - /* - * During Suspend-Resume & S/W-Reset, as soon as PMU releases - * pad retention, CKE goes high. This causes memory contents - * not to be retained during DRAM initialization. Therfore, - * there is a new control register(0x100431e8[28]) which lets us - * release pad retention and retain the memory content until the - * initialization is complete. - */ - write32(PAD_RETENTION_DRAM_COREBLK_VAL, - &exynos_power->padret_dram_cblk_opt); - do { - ret = read32(&exynos_power->padret_dram_status); - } while (ret != 0x1); - - /* - * CKE PAD retention disables DRAM self-refresh mode. - * Send auto refresh command for DRAM refresh. - */ - for (i = 0; i < 128; i++) { - for (chip = 0; chip < mem->chips_to_configure; chip++) { - writel(DIRECT_CMD_REFA | - (chip << DIRECT_CMD_CHIP_SHIFT), - &exynos_drex0->directcmd); - writel(DIRECT_CMD_REFA | - (chip << DIRECT_CMD_CHIP_SHIFT), - &exynos_drex1->directcmd); - } - } - } - - if (mem->gate_leveling_enable) { - - writel(PHY_CON0_RESET_VAL, &exynos_phy0_control->phy_con0); - writel(PHY_CON0_RESET_VAL, &exynos_phy1_control->phy_con0); - - setbits_le32(&exynos_phy0_control->phy_con0, P0_CMD_EN); - setbits_le32(&exynos_phy1_control->phy_con0, P0_CMD_EN); - - val = PHY_CON2_RESET_VAL; - val |= INIT_DESKEW_EN; - writel(val, &exynos_phy0_control->phy_con2); - writel(val, &exynos_phy1_control->phy_con2); - - val = readl(&exynos_phy0_control->phy_con1); - val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET); - writel(val, &exynos_phy0_control->phy_con1); - - val = readl(&exynos_phy1_control->phy_con1); - val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET); - writel(val, &exynos_phy1_control->phy_con1); - - nLockR = readl(&exynos_phy0_control->phy_con13); - nLockW_phy0 = (nLockR & CTRL_LOCK_COARSE_MASK) >> 2; - nLockR = readl(&exynos_phy0_control->phy_con12); - nLockR &= ~CTRL_DLL_ON; - nLockR |= nLockW_phy0; - writel(nLockR, &exynos_phy0_control->phy_con12); - - nLockR = readl(&exynos_phy1_control->phy_con13); - nLockW_phy1 = (nLockR & CTRL_LOCK_COARSE_MASK) >> 2; - nLockR = readl(&exynos_phy1_control->phy_con12); - nLockR &= ~CTRL_DLL_ON; - nLockR |= nLockW_phy1; - writel(nLockR, &exynos_phy1_control->phy_con12); - - val = (0x3 << DIRECT_CMD_BANK_SHIFT) | 0x4; - for (chip = 0; chip < mem->chips_to_configure; chip++) { - writel(val | (chip << DIRECT_CMD_CHIP_SHIFT), - &exynos_drex0->directcmd); - writel(val | (chip << DIRECT_CMD_CHIP_SHIFT), - &exynos_drex1->directcmd); - } - - setbits_le32(&exynos_phy0_control->phy_con2, RDLVL_GATE_EN); - setbits_le32(&exynos_phy1_control->phy_con2, RDLVL_GATE_EN); - - setbits_le32(&exynos_phy0_control->phy_con0, CTRL_SHGATE); - setbits_le32(&exynos_phy1_control->phy_con0, CTRL_SHGATE); - - val = readl(&exynos_phy0_control->phy_con1); - val &= ~(CTRL_GATEDURADJ_MASK); - writel(val, &exynos_phy0_control->phy_con1); - - val = readl(&exynos_phy1_control->phy_con1); - val &= ~(CTRL_GATEDURADJ_MASK); - writel(val, &exynos_phy1_control->phy_con1); - - writel(CTRL_RDLVL_GATE_ENABLE, &exynos_drex0->rdlvl_config); - i = TIMEOUT; - while (((readl(&exynos_drex0->phystatus) & RDLVL_COMPLETE_CHO) - != RDLVL_COMPLETE_CHO) && (i > 0)) { - /* - * TODO(waihong): Comment on how long this take to - * timeout - */ - udelay(1); - i--; - } - if (!i) - return SETUP_ERR_RDLV_COMPLETE_TIMEOUT; - writel(CTRL_RDLVL_GATE_DISABLE, &exynos_drex0->rdlvl_config); - - writel(CTRL_RDLVL_GATE_ENABLE, &exynos_drex1->rdlvl_config); - i = TIMEOUT; - while (((readl(&exynos_drex1->phystatus) & RDLVL_COMPLETE_CHO) - != RDLVL_COMPLETE_CHO) && (i > 0)) { - /* - * TODO(waihong): Comment on how long this take to - * timeout - */ - udelay(1); - i--; - } - if (!i) - return SETUP_ERR_RDLV_COMPLETE_TIMEOUT; - writel(CTRL_RDLVL_GATE_DISABLE, &exynos_drex1->rdlvl_config); - - writel(0, &exynos_phy0_control->phy_con14); - writel(0, &exynos_phy1_control->phy_con14); - - val = (0x3 << DIRECT_CMD_BANK_SHIFT); - for (chip = 0; chip < mem->chips_to_configure; chip++) { - writel(val | (chip << DIRECT_CMD_CHIP_SHIFT), - &exynos_drex0->directcmd); - writel(val | (chip << DIRECT_CMD_CHIP_SHIFT), - &exynos_drex1->directcmd); - } - - /* Common Settings for Leveling */ - val = PHY_CON12_RESET_VAL; - writel((val + nLockW_phy0), &exynos_phy0_control->phy_con12); - writel((val + nLockW_phy1), &exynos_phy1_control->phy_con12); - - setbits_le32(&exynos_phy0_control->phy_con2, DLL_DESKEW_EN); - setbits_le32(&exynos_phy1_control->phy_con2, DLL_DESKEW_EN); - } - - /* Send PALL command */ - dmc_config_prech(mem, exynos_drex0); - dmc_config_prech(mem, exynos_drex1); - - writel(mem->memcontrol, &exynos_drex0->memcontrol); - writel(mem->memcontrol, &exynos_drex1->memcontrol); - - /* - * Set DMC Concontrol: Enable auto-refresh counter, provide - * read data fetch cycles and enable DREX auto set powerdown - * for input buffer of I/O in none read memory state. - */ - writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) | - (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)| - DMC_CONCONTROL_IO_PD_CON(0x2), - &exynos_drex0->concontrol); - writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) | - (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)| - DMC_CONCONTROL_IO_PD_CON(0x2), - &exynos_drex1->concontrol); - - /* Enable Clock Gating Control for DMC - * this saves around 25 mw dmc power as compared to the power - * consumption without these bits enabled - */ - setbits_le32(&exynos_drex0->cgcontrol, DMC_INTERNAL_CG); - setbits_le32(&exynos_drex1->cgcontrol, DMC_INTERNAL_CG); - - return 0; -} diff --git a/src/cpu/samsung/exynos5420/dp.c b/src/cpu/samsung/exynos5420/dp.c deleted file mode 100644 index b147035b64..0000000000 --- a/src/cpu/samsung/exynos5420/dp.c +++ /dev/null @@ -1,910 +0,0 @@ -/* - * Copyright (C) 2012 Samsung Electronics - * - * Author: Donghwa Lee <dh09.lee@samsung.com> - * - * 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 <arch/io.h> -#include <stdlib.h> -#include <string.h> -#include <timer.h> -#include <delay.h> -#include <console/console.h> -#include <lib.h> -#include "timer.h" -#include "power.h" -#include "sysreg.h" - -#include "dp.h" -#include "fimd.h" -#include "i2c.h" - -/* - * Here is the rough outline of how we bring up the display: - * 1. Upon power-on Sink generates a hot plug detection pulse thru HPD - * 2. Source determines video mode by reading DPCD receiver capability field - * (DPCD 00000h to 0000Dh) including eDP CP capability register (DPCD - * 0000Dh). - * 3. Sink replies DPCD receiver capability field. - * 4. Source starts EDID read thru I2C-over-AUX. - * 5. Sink replies EDID thru I2C-over-AUX. - * 6. Source determines link configuration, such as MAX_LINK_RATE and - * MAX_LANE_COUNT. Source also determines which type of eDP Authentication - * method to use and writes DPCD link configuration field (DPCD 00100h to - * 0010Ah) including eDP configuration set (DPCD 0010Ah). - * 7. Source starts link training. Sink does clock recovery and equalization. - * 8. Source reads DPCD link status field (DPCD 00200h to 0020Bh). - * 9. Sink replies DPCD link status field. If main link is not stable, Source - * repeats Step 7. - * 10. Source sends MSA (Main Stream Attribute) data. Sink extracts video - * parameters and recovers stream clock. - * 11. Source sends video data. - */ - - -static int exynos_dp_init_dp(void) -{ - int ret; - exynos_dp_reset(); - - /* SW defined function Normal operation */ - exynos_dp_enable_sw_func(DP_ENABLE); - - ret = exynos_dp_init_analog_func(); - if (ret != EXYNOS_DP_SUCCESS) - return ret; - - exynos_dp_init_hpd(); - exynos_dp_init_aux(); - - return ret; -} - -static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data) -{ - int i; - unsigned char sum = 0; - - for (i = 0; i < EDID_BLOCK_LENGTH; i++) - sum = sum + edid_data[i]; - - return sum; -} - -static unsigned int exynos_dp_read_edid(void) -{ - unsigned char edid[EDID_BLOCK_LENGTH * 2]; - unsigned int extend_block = 0; - unsigned char sum; - unsigned char test_vector; - int retval = 0; - - /* - * EDID device address is 0x50. - * However, if necessary, you must have set upper address - * into E-EDID in I2C device, 0x30. - */ - - /* Read Extension Flag, Number of 128-byte EDID extension blocks */ - if (exynos_dp_read_byte_from_i2c - (I2C_EDID_DEVICE_ADDR, EDID_EXTENSION_FLAG, &extend_block)) - return -1; - - if (extend_block > 0) { - /* Read EDID data */ - retval = exynos_dp_read_bytes_from_i2c(I2C_EDID_DEVICE_ADDR, - EDID_HEADER_PATTERN, - EDID_BLOCK_LENGTH, - &edid[EDID_HEADER_PATTERN]); - - if (retval != 0) { - printk(BIOS_ERR, "DP EDID Read failed!\n"); - return -1; - } - sum = exynos_dp_calc_edid_check_sum(edid); - if (sum != 0) { - printk(BIOS_ERR, "DP EDID bad checksum!\n"); - return -1; - } - /* Read additional EDID data */ - retval = exynos_dp_read_bytes_from_i2c(I2C_EDID_DEVICE_ADDR, - EDID_BLOCK_LENGTH, - EDID_BLOCK_LENGTH, - &edid[EDID_BLOCK_LENGTH]); - if (retval != 0) { - printk(BIOS_ERR, "DP EDID Read failed!\n"); - return -1; - } - sum = exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]); - if (sum != 0) { - printk(BIOS_ERR, "DP EDID bad checksum!\n"); - return -1; - } - exynos_dp_read_byte_from_dpcd(DPCD_TEST_REQUEST, - &test_vector); - if (test_vector & DPCD_TEST_EDID_READ) { - exynos_dp_write_byte_to_dpcd(DPCD_TEST_EDID_CHECKSUM, - edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]); - exynos_dp_write_byte_to_dpcd(DPCD_TEST_RESPONSE, - DPCD_TEST_EDID_CHECKSUM_WRITE); - } - } else { - /* Read EDID data */ - retval = exynos_dp_read_bytes_from_i2c(I2C_EDID_DEVICE_ADDR, - EDID_HEADER_PATTERN, - EDID_BLOCK_LENGTH, - &edid[EDID_HEADER_PATTERN]); - - if (retval != 0) { - printk(BIOS_ERR, "DP EDID Read failed!\n"); - return -1; - } - sum = exynos_dp_calc_edid_check_sum(edid); - if (sum != 0) { - printk(BIOS_ERR, "DP EDID bad checksum!\n"); - return -1; - } - - exynos_dp_read_byte_from_dpcd(DPCD_TEST_REQUEST, - &test_vector); - if (test_vector & DPCD_TEST_EDID_READ) { - exynos_dp_write_byte_to_dpcd(DPCD_TEST_EDID_CHECKSUM, - edid[EDID_CHECKSUM]); - exynos_dp_write_byte_to_dpcd(DPCD_TEST_RESPONSE, - DPCD_TEST_EDID_CHECKSUM_WRITE); - } - - } - - return 0; -} - -static unsigned int exynos_dp_handle_edid(struct edp_device_info *edp_info) -{ - unsigned char buf[12]; - unsigned int ret; - unsigned char temp; - unsigned char retry_cnt; - unsigned char dpcd_rev[16]; - unsigned char lane_bw[16]; - unsigned char lane_cnt[16]; - - memset(dpcd_rev, 0, sizeof(dpcd_rev)); - memset(lane_bw, 0, sizeof(lane_bw)); - memset(lane_cnt, 0, sizeof(lane_cnt)); - memset(buf, 0, sizeof(buf)); - - retry_cnt = 5; - while (retry_cnt) { - /* Read DPCD 0x0000-0x000b */ - ret = exynos_dp_read_bytes_from_dpcd(DPCD_DPCD_REV, 12, - buf); - if (ret != EXYNOS_DP_SUCCESS) { - if (retry_cnt == 0) { - printk(BIOS_ERR, "DP read_byte_from_dpcd() failed\n"); - return ret; - } - retry_cnt--; - } else - break; - } - /* */ - temp = buf[DPCD_DPCD_REV]; - if (temp == DP_DPCD_REV_10 || temp == DP_DPCD_REV_11) - edp_info->dpcd_rev = temp; - else { - printk(BIOS_ERR, "DP Wrong DPCD Rev : %x\n", temp); - return -1; - } - temp = buf[DPCD_MAX_LINK_RATE]; - if (temp == DP_LANE_BW_1_62 || temp == DP_LANE_BW_2_70) - edp_info->lane_bw = temp; - else { - printk(BIOS_ERR, "DP Wrong MAX LINK RATE : %x\n", temp); - return -1; - } - /*Refer VESA Display Port Stnadard Ver1.1a Page 120 */ - if (edp_info->dpcd_rev == DP_DPCD_REV_11) { - temp = buf[DPCD_MAX_LANE_COUNT] & 0x1f; - if (buf[DPCD_MAX_LANE_COUNT] & 0x80) - edp_info->dpcd_efc = 1; - else - edp_info->dpcd_efc = 0; - } else { - temp = buf[DPCD_MAX_LANE_COUNT]; - edp_info->dpcd_efc = 0; - } - - if (temp == DP_LANE_CNT_1 || temp == DP_LANE_CNT_2 || - temp == DP_LANE_CNT_4) { - edp_info->lane_cnt = temp; - } else { - printk(BIOS_ERR, "DP Wrong MAX LANE COUNT : %x\n", temp); - return -1; - } - - if (edp_info->raw_edid){ - ret = EXYNOS_DP_SUCCESS; - printk(BIOS_SPEW, "EDID compiled in, skipping read\n"); - } else { - ret = exynos_dp_read_edid(); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP exynos_dp_read_edid() failed\n"); - return -1; - } - } - - return ret; -} - -static void exynos_dp_init_training(void) -{ - /* - * MACRO_RST must be applied after the PLL_LOCK to avoid - * the DP inter pair skew issue for at least 10 us - */ - exynos_dp_reset_macro(); - - /* All DP analog module power up */ - exynos_dp_set_analog_power_down(POWER_ALL, 0); -} - -static unsigned int exynos_dp_link_start(struct edp_device_info *edp_info) -{ - unsigned char buf[5]; - unsigned int ret; - - edp_info->lt_info.lt_status = DP_LT_CR; - edp_info->lt_info.ep_loop = 0; - edp_info->lt_info.cr_loop[0] = 0; - edp_info->lt_info.cr_loop[1] = 0; - edp_info->lt_info.cr_loop[2] = 0; - edp_info->lt_info.cr_loop[3] = 0; - - /* Set sink to D0 (Sink Not Ready) mode. */ - ret = exynos_dp_write_byte_to_dpcd(DPCD_SINK_POWER_STATE, - DPCD_SET_POWER_STATE_D0); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP write_dpcd_byte failed\n"); - return ret; - } - - /* Set link rate and count as you want to establish*/ - exynos_dp_set_link_bandwidth(edp_info->lane_bw); - exynos_dp_set_lane_count(edp_info->lane_cnt); - - /* Setup RX configuration */ - buf[0] = edp_info->lane_bw; - buf[1] = edp_info->lane_cnt; - - ret = exynos_dp_write_bytes_to_dpcd(DPCD_LINK_BW_SET, 2, - buf); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP write_dpcd_byte failed\n"); - return ret; - } - - exynos_dp_set_lane_pre_emphasis(PRE_EMPHASIS_LEVEL_0, - edp_info->lane_cnt); - - /* Set training pattern 1 */ - exynos_dp_set_training_pattern(TRAINING_PTN1); - - /* Set RX training pattern */ - buf[0] = DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1; - - buf[1] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 | - DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0; - buf[2] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 | - DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0; - buf[3] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 | - DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0; - buf[4] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 | - DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0; - - ret = exynos_dp_write_bytes_to_dpcd(DPCD_TRAINING_PATTERN_SET, - 5, buf); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP write_dpcd_byte failed\n"); - return ret; - } - return ret; -} - -static unsigned int exynos_dp_training_pattern_dis(void) -{ - unsigned int ret; - - exynos_dp_set_training_pattern(DP_NONE); - - ret = exynos_dp_write_byte_to_dpcd(DPCD_TRAINING_PATTERN_SET, - DPCD_TRAINING_PATTERN_DISABLED); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP requst_link_traninig_req failed\n"); - return -1; - } - - return ret; -} - -static unsigned int exynos_dp_enable_rx_to_enhanced_mode(unsigned char enable) -{ - unsigned char data; - unsigned int ret; - - ret = exynos_dp_read_byte_from_dpcd(DPCD_LANE_COUNT_SET, - &data); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP read_from_dpcd failed\n"); - return -1; - } - - if (enable) - data = DPCD_ENHANCED_FRAME_EN | DPCD_LN_COUNT_SET(data); - else - data = DPCD_LN_COUNT_SET(data); - - ret = exynos_dp_write_byte_to_dpcd(DPCD_LANE_COUNT_SET, - data); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP write_to_dpcd failed\n"); - return -1; - - } - - return ret; -} - -static unsigned int exynos_dp_set_enhanced_mode(unsigned char enhance_mode) -{ - unsigned int ret; - - ret = exynos_dp_enable_rx_to_enhanced_mode(enhance_mode); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP rx_enhance_mode failed\n"); - return -1; - } - - exynos_dp_enable_enhanced_mode(enhance_mode); - - return ret; -} - -static int exynos_dp_read_dpcd_lane_stat(struct edp_device_info *edp_info, - unsigned char *status) -{ - unsigned int ret, i; - unsigned char buf[2]; - unsigned char lane_stat[DP_LANE_CNT_4] = {0,}; - const unsigned char shift_val[] = {0, 4, 0, 4}; - - ret = exynos_dp_read_bytes_from_dpcd(DPCD_LANE0_1_STATUS, 2, buf); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP read lane status failed\n"); - return ret; - } - - for (i = 0; i < edp_info->lane_cnt; i++) { - lane_stat[i] = (buf[(i / 2)] >> shift_val[i]) & 0x0f; - if (lane_stat[0] != lane_stat[i]) { - printk(BIOS_ERR, "Wrong lane status\n"); - return -1; - } - } - - *status = lane_stat[0]; - - return ret; -} - -static unsigned int exynos_dp_read_dpcd_adj_req(unsigned char lane_num, - unsigned char *sw, unsigned char *em) -{ - const unsigned char shift_val[] = {0, 4, 0, 4}; - unsigned int ret; - unsigned char buf; - unsigned int dpcd_addr; - - /*lane_num value is used as arry index, so this range 0 ~ 3 */ - dpcd_addr = DPCD_ADJUST_REQUEST_LANE0_1 + (lane_num / 2); - - ret = exynos_dp_read_byte_from_dpcd(dpcd_addr, &buf); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP read adjust request failed\n"); - return -1; - } - - *sw = ((buf >> shift_val[lane_num]) & 0x03); - *em = ((buf >> shift_val[lane_num]) & 0x0c) >> 2; - - return ret; -} - -static int exynos_dp_equalizer_err_link(struct edp_device_info *edp_info) -{ - int ret; - - ret = exynos_dp_training_pattern_dis(); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP training_patter_disable() failed\n"); - edp_info->lt_info.lt_status = DP_LT_FAIL; - } - - ret = exynos_dp_set_enhanced_mode(edp_info->dpcd_efc); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP set_enhanced_mode() failed\n"); - edp_info->lt_info.lt_status = DP_LT_FAIL; - } - - return ret; -} - -static int exynos_dp_reduce_link_rate(struct edp_device_info *edp_info) -{ - int ret; - - if (edp_info->lane_bw == DP_LANE_BW_2_70) { - edp_info->lane_bw = DP_LANE_BW_1_62; - printk(BIOS_ERR, "DP Change lane bw to 1.62Gbps\n"); - edp_info->lt_info.lt_status = DP_LT_START; - ret = EXYNOS_DP_SUCCESS; - } else { - ret = exynos_dp_training_pattern_dis(); - if (ret != EXYNOS_DP_SUCCESS) - printk(BIOS_ERR, "DP training_patter_disable() failed\n"); - - ret = exynos_dp_set_enhanced_mode(edp_info->dpcd_efc); - if (ret != EXYNOS_DP_SUCCESS) - printk(BIOS_ERR, "DP set_enhanced_mode() failed\n"); - - edp_info->lt_info.lt_status = DP_LT_FAIL; - } - - return ret; -} - -static unsigned int exynos_dp_process_clock_recovery(struct edp_device_info - *edp_info) -{ - unsigned int ret; - unsigned char lane_stat; - unsigned char lt_ctl_val[DP_LANE_CNT_4] = {0, }; - unsigned int i; - unsigned char adj_req_sw; - unsigned char adj_req_em; - unsigned char buf[5]; - - mdelay(1); - - ret = exynos_dp_read_dpcd_lane_stat(edp_info, &lane_stat); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP read lane status failed\n"); - edp_info->lt_info.lt_status = DP_LT_FAIL; - return ret; - } - - if (lane_stat & DP_LANE_STAT_CR_DONE) { - printk(BIOS_DEBUG,"DP clock Recovery training succeed\n"); - exynos_dp_set_training_pattern(TRAINING_PTN2); - - for (i = 0; i < edp_info->lane_cnt; i++) { - ret = exynos_dp_read_dpcd_adj_req(i, &adj_req_sw, - &adj_req_em); - if (ret != EXYNOS_DP_SUCCESS) { - edp_info->lt_info.lt_status = DP_LT_FAIL; - return ret; - } - - lt_ctl_val[i] = 0; - lt_ctl_val[i] = adj_req_em << 3 | adj_req_sw; - - if ((adj_req_sw == VOLTAGE_LEVEL_3) - || (adj_req_em == PRE_EMPHASIS_LEVEL_3)) { - lt_ctl_val[i] |= MAX_DRIVE_CURRENT_REACH_3 | - MAX_PRE_EMPHASIS_REACH_3; - } - exynos_dp_set_lanex_pre_emphasis(lt_ctl_val[i], i); - } - - buf[0] = DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_2; - buf[1] = lt_ctl_val[0]; - buf[2] = lt_ctl_val[1]; - buf[3] = lt_ctl_val[2]; - buf[4] = lt_ctl_val[3]; - - ret = exynos_dp_write_bytes_to_dpcd( - DPCD_TRAINING_PATTERN_SET, 5, buf); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP write training pattern1 failed\n"); - edp_info->lt_info.lt_status = DP_LT_FAIL; - return ret; - } else - edp_info->lt_info.lt_status = DP_LT_ET; - } else { - for (i = 0; i < edp_info->lane_cnt; i++) { - lt_ctl_val[i] = exynos_dp_get_lanex_pre_emphasis(i); - ret = exynos_dp_read_dpcd_adj_req(i, - &adj_req_sw, &adj_req_em); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP read adj req failed\n"); - edp_info->lt_info.lt_status = DP_LT_FAIL; - return ret; - } - - if ((adj_req_sw == VOLTAGE_LEVEL_3) || - (adj_req_em == PRE_EMPHASIS_LEVEL_3)) - ret = exynos_dp_reduce_link_rate(edp_info); - - if ((DRIVE_CURRENT_SET_0_GET(lt_ctl_val[i]) == - adj_req_sw) && - (PRE_EMPHASIS_SET_0_GET(lt_ctl_val[i]) == - adj_req_em)) { - edp_info->lt_info.cr_loop[i]++; - if (edp_info->lt_info.cr_loop[i] == MAX_CR_LOOP) - ret = exynos_dp_reduce_link_rate( - edp_info); - } - - lt_ctl_val[i] = 0; - lt_ctl_val[i] = adj_req_em << 3 | adj_req_sw; - - if ((adj_req_sw == VOLTAGE_LEVEL_3) || - (adj_req_em == PRE_EMPHASIS_LEVEL_3)) { - lt_ctl_val[i] |= MAX_DRIVE_CURRENT_REACH_3 | - MAX_PRE_EMPHASIS_REACH_3; - } - exynos_dp_set_lanex_pre_emphasis(lt_ctl_val[i], i); - } - - ret = exynos_dp_write_bytes_to_dpcd( - DPCD_TRAINING_LANE0_SET, 4, lt_ctl_val); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP write training pattern2 failed\n"); - edp_info->lt_info.lt_status = DP_LT_FAIL; - return ret; - } - } - - return ret; -} - -static unsigned int exynos_dp_process_equalizer_training(struct edp_device_info - *edp_info) -{ - unsigned int ret; - unsigned char lane_stat, adj_req_sw, adj_req_em, i; - unsigned char lt_ctl_val[DP_LANE_CNT_4] = {0,}; - unsigned char interlane_aligned = 0; - unsigned char f_bw; - unsigned char f_lane_cnt; - unsigned char sink_stat; - - mdelay(1); - - ret = exynos_dp_read_dpcd_lane_stat(edp_info, &lane_stat); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP read lane status failed\n"); - edp_info->lt_info.lt_status = DP_LT_FAIL; - return ret; - } - - printk(BIOS_DEBUG,"DP lane stat : %x\n", lane_stat); - - if (lane_stat & DP_LANE_STAT_CR_DONE) { - printk(BIOS_DEBUG, "DP_LANE_STAT_CR_DONE ok\n"); - ret = exynos_dp_read_byte_from_dpcd(DPCD_LN_ALIGN_UPDATED, - &sink_stat); - if (ret != EXYNOS_DP_SUCCESS) { - edp_info->lt_info.lt_status = DP_LT_FAIL; - printk(BIOS_ERR, "DP read DPCD_LN_ALIGN_UPDATED failed\n"); - return ret; - } - - interlane_aligned = (sink_stat & DPCD_INTERLANE_ALIGN_DONE); - printk(BIOS_DEBUG, "interlane_aligned: %d\n", interlane_aligned); - printk(BIOS_DEBUG, "Check %d lanes\n", edp_info->lane_cnt); - - for (i = 0; i < edp_info->lane_cnt; i++) { - ret = exynos_dp_read_dpcd_adj_req(i, - &adj_req_sw, &adj_req_em); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP read adj req 1 failed\n"); - edp_info->lt_info.lt_status = DP_LT_FAIL; - - return ret; - } - - lt_ctl_val[i] = 0; - lt_ctl_val[i] = adj_req_em << 3 | adj_req_sw; - - if ((adj_req_sw == VOLTAGE_LEVEL_3) || - (adj_req_em == PRE_EMPHASIS_LEVEL_3)) { - lt_ctl_val[i] |= MAX_DRIVE_CURRENT_REACH_3; - lt_ctl_val[i] |= MAX_PRE_EMPHASIS_REACH_3; - } - } - - if (((lane_stat&DP_LANE_STAT_CE_DONE) && - (lane_stat&DP_LANE_STAT_SYM_LOCK)) - && (interlane_aligned == DPCD_INTERLANE_ALIGN_DONE)) { - printk(BIOS_DEBUG,"DP Equalizer training succeed\n"); - - f_bw = exynos_dp_get_link_bandwidth(); - f_lane_cnt = exynos_dp_get_lane_count(); - - printk(BIOS_DEBUG,"DP final BandWidth : %x\n", f_bw); - printk(BIOS_DEBUG,"DP final Lane Count : %x\n", f_lane_cnt); - - edp_info->lt_info.lt_status = DP_LT_FINISHED; - - exynos_dp_equalizer_err_link(edp_info); - - } else { - edp_info->lt_info.ep_loop++; - - if (edp_info->lt_info.ep_loop > MAX_EQ_LOOP) { - if (edp_info->lane_bw == DP_LANE_BW_2_70) { - ret = exynos_dp_reduce_link_rate( - edp_info); - } else { - edp_info->lt_info.lt_status = - DP_LT_FAIL; - exynos_dp_equalizer_err_link(edp_info); - } - } else { - for (i = 0; i < edp_info->lane_cnt; i++) - exynos_dp_set_lanex_pre_emphasis( - lt_ctl_val[i], i); - - ret = exynos_dp_write_bytes_to_dpcd( - DPCD_TRAINING_LANE0_SET, - 4, lt_ctl_val); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP set lt pattern failed\n"); - edp_info->lt_info.lt_status = - DP_LT_FAIL; - exynos_dp_equalizer_err_link(edp_info); - } - } - } - } else if (edp_info->lane_bw == DP_LANE_BW_2_70) { - ret = exynos_dp_reduce_link_rate(edp_info); - } else { - edp_info->lt_info.lt_status = DP_LT_FAIL; - exynos_dp_equalizer_err_link(edp_info); - } - - return ret; -} - -static unsigned int exynos_dp_sw_link_training(struct edp_device_info *edp_info) -{ - /* the C compiler is almost smart enough to know this gets set. - * But not quite. - */ - unsigned int ret = 0; - int training_finished; - - /* Turn off unnecessary lane */ - if (edp_info->lane_cnt == 1) - exynos_dp_set_analog_power_down(CH1_BLOCK, 1); - - training_finished = 0; - - edp_info->lt_info.lt_status = DP_LT_START; - - /* Process here */ - while (!training_finished) { - switch (edp_info->lt_info.lt_status) { - case DP_LT_START: - ret = exynos_dp_link_start(edp_info); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP LT:link start failed\n"); - training_finished = 1; - } - break; - case DP_LT_CR: - ret = exynos_dp_process_clock_recovery(edp_info); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP LT:clock recovery failed\n"); - training_finished = 1; - } - break; - case DP_LT_ET: - ret = exynos_dp_process_equalizer_training(edp_info); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP LT:equalizer training failed\n"); - training_finished = 1; - } - break; - case DP_LT_FINISHED: - training_finished = 1; - break; - case DP_LT_FAIL: - printk(BIOS_ERR,"DP: %s: DP_LT_FAIL: failed\n", __func__); - training_finished = 1; - ret = -1; - } - } - - return ret; -} - -static unsigned int exynos_dp_set_link_train(struct edp_device_info *edp_info) -{ - unsigned int ret; - - exynos_dp_init_training(); - - ret = exynos_dp_sw_link_training(edp_info); - if (ret != EXYNOS_DP_SUCCESS) - printk(BIOS_ERR, "DP dp_sw_link_traning() failed\n"); - - return ret; -} - -static void exynos_dp_enable_scramble(unsigned int enable) -{ - unsigned char data; - - if (enable) { - exynos_dp_enable_scrambling(DP_ENABLE); - - exynos_dp_read_byte_from_dpcd(DPCD_TRAINING_PATTERN_SET, - &data); - exynos_dp_write_byte_to_dpcd(DPCD_TRAINING_PATTERN_SET, - (u8)(data & ~DPCD_SCRAMBLING_DISABLED)); - } else { - exynos_dp_enable_scrambling(DP_DISABLE); - exynos_dp_read_byte_from_dpcd(DPCD_TRAINING_PATTERN_SET, - &data); - exynos_dp_write_byte_to_dpcd(DPCD_TRAINING_PATTERN_SET, - (u8)(data | DPCD_SCRAMBLING_DISABLED)); - } -} - -static unsigned int exynos_dp_config_video(struct edp_device_info *edp_info) -{ - unsigned int ret = 0; - unsigned int retry_cnt; - - mdelay(1); - - if (edp_info->video_info.master_mode) { - printk(BIOS_ERR, - "DP does not support master mode: bailing out\n"); - return -1; - } else { - /* debug slave */ - exynos_dp_config_video_slave_mode(&edp_info->video_info); - } - - exynos_dp_set_video_color_format(&edp_info->video_info); - - ret = exynos_dp_get_pll_lock_status(); - if (ret != PLL_LOCKED) { - printk(BIOS_ERR, "DP PLL is not locked yet\n"); - return -1; - } - - if (edp_info->video_info.master_mode == 0) { - retry_cnt = 10; - while (retry_cnt) { - ret = exynos_dp_is_slave_video_stream_clock_on(); - if (ret != EXYNOS_DP_SUCCESS) { - if (retry_cnt == 0) { - printk(BIOS_ERR, "DP stream_clock_on failed\n"); - return ret; - } - retry_cnt--; - mdelay(1); - } else { - printk(BIOS_DEBUG, "DP stream_clock succeeds\n"); - break; - } - } - } - - /* Set to use the register calculated M/N video */ - exynos_dp_set_video_cr_mn(CALCULATED_M, 0, 0); - - /* For video bist, Video timing must be generated by register - * not clear if we still need this. We could take it out and it - * might appear to work, then fail strangely. - */ - exynos_dp_set_video_timing_mode(VIDEO_TIMING_FROM_CAPTURE); - - /* we need to be sure this is off. */ - exynos_dp_disable_video_bist(); - - /* Disable video mute */ - exynos_dp_enable_video_mute(DP_DISABLE); - - /* Configure video Master or Slave mode */ - exynos_dp_enable_video_master(edp_info->video_info.master_mode); - - /* Enable video */ - exynos_dp_start_video(); - - if (edp_info->video_info.master_mode == 0) { - retry_cnt = 500; - while (retry_cnt) { - ret = exynos_dp_is_video_stream_on(); - if (ret != EXYNOS_DP_SUCCESS) { - retry_cnt--; - if (retry_cnt == 0) { - printk(BIOS_ERR, "DP Timeout of video stream\n"); - } - } else { - printk(BIOS_DEBUG, "DP video stream is on\n"); - break; - } - /* this is a cheap operation, involving some register - * reads, and no AUX channel IO. A ms. delay is fine. - */ - mdelay(1); - } - } - - return ret; -} - -int exynos_init_dp(struct edp_device_info *edp_info) -{ - unsigned int ret; - - - dp_phy_control(1); - - ret = exynos_dp_init_dp(); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP exynos_dp_init_dp() failed\n"); - return ret; - } - - ret = exynos_dp_handle_edid(edp_info); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "EDP handle_edid fail\n"); - return ret; - } - - ret = exynos_dp_set_link_train(edp_info); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP link training fail\n"); - return ret; - } - printk(BIOS_DEBUG, "EDP link training ok\n"); - - exynos_dp_enable_scramble(DP_ENABLE); - exynos_dp_enable_rx_to_enhanced_mode(DP_ENABLE); - exynos_dp_enable_enhanced_mode(DP_ENABLE); - - exynos_dp_set_link_bandwidth(edp_info->lane_bw); - exynos_dp_set_lane_count(edp_info->lane_cnt); - - exynos_dp_init_video(); - ret = exynos_dp_config_video(edp_info); - - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "Exynos DP init failed\n"); - return ret; - } - printk(BIOS_DEBUG, "Exynos DP init done\n"); - - return ret; -} diff --git a/src/cpu/samsung/exynos5420/dp.h b/src/cpu/samsung/exynos5420/dp.h deleted file mode 100644 index 9131b0853c..0000000000 --- a/src/cpu/samsung/exynos5420/dp.h +++ /dev/null @@ -1,1430 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Register map for Exynos5 DP */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_DP_H -#define CPU_SAMSUNG_EXYNOS5420_DP_H - -#include "cpu.h" - -/* DSIM register map */ -struct exynos_dp { - u8 res1[0x10]; - u32 tx_version; - u32 tx_sw_reset; - u32 func_en1; - u32 func_en2; - u32 video_ctl1; - u32 video_ctl2; - u32 video_ctl3; - u32 video_ctl4; - u32 color_blue_cb; - u32 color_green_y; - u32 color_red_cr; - u32 video_ctl8; - u8 res2[0x4]; - u32 video_ctl10; - u32 total_ln_cfg_l; - u32 total_ln_cfg_h; - u32 active_ln_cfg_l; - u32 active_ln_cfg_h; - u32 vfp_cfg; - u32 vsw_cfg; - u32 vbp_cfg; - u32 total_pix_cfg_l; - u32 total_pix_cfg_h; - u32 active_pix_cfg_l; - u32 active_pix_cfg_h; - u32 hfp_cfg_l; - u32 hfp_cfg_h; - u32 hsw_cfg_l; - u32 hsw_cfg_h; - u32 hbp_cfg_l; - u32 hbp_cfg_h; - u32 video_status; - u32 total_ln_sta_l; - u32 total_ln_sta_h; - u32 active_ln_sta_l; - u32 active_ln_sta_h; - - u32 vfp_sta; - u32 vsw_sta; - u32 vbp_sta; - - u32 total_pix_sta_l; - u32 total_pix_sta_h; - u32 active_pix_sta_l; - u32 active_pix_sta_h; - - u32 hfp_sta_l; - u32 hfp_sta_h; - u32 hsw_sta_l; - u32 hsw_sta_h; - u32 hbp_sta_l; - u32 hbp_sta_h; - - u8 res3[0x288]; - - u32 lane_map; - u8 res4[0x10]; - u32 analog_ctl1; - u32 analog_ctl2; - u32 analog_ctl3; - - u32 pll_filter_ctl1; - u32 amp_tuning_ctl; - u8 res5[0xc]; - - u32 aux_hw_retry_ctl; - u8 res6[0x2c]; - u32 int_state; - u32 common_int_sta1; - u32 common_int_sta2; - u32 common_int_sta3; - u32 common_int_sta4; - u8 res7[0x8]; - - u32 int_sta; - u8 res8[0x1c]; - u32 int_ctl; - u8 res9[0x200]; - u32 sys_ctl1; - u32 sys_ctl2; - u32 sys_ctl3; - u32 sys_ctl4; - u32 vid_ctl; - u8 res10[0x2c]; - u32 pkt_send_ctl; - u8 res[0x4]; - u32 hdcp_ctl; - u8 res11[0x34]; - u32 link_bw_set; - - u32 lane_count_set; - u32 training_ptn_set; - u32 ln0_link_training_ctl; - u32 ln1_link_training_ctl; - u32 ln2_link_training_ctl; - u32 ln3_link_training_ctl; - u32 dn_spread_ctl; - u32 hw_link_training_ctl; - u8 res12[0x1c]; - - u32 debug_ctl; - u32 hpd_deglitch_l; - u32 hpd_deglitch_h; - - u8 res13[0x14]; - u32 link_debug_ctl; - - u8 res14[0x1c]; - - u32 m_vid0; - u32 m_vid1; - u32 m_vid2; - u32 n_vid0; - u32 n_vid1; - u32 n_vid2; - u32 m_vid_mon; - u32 pll_ctl; - u32 phy_pd; - u32 phy_test; - u8 res15[0x8]; - - u32 video_fifo_thrd; - u8 res16[0x8]; - u32 audio_margin; - - u32 dn_spread_ctl1; - u32 dn_spread_ctl2; - u8 res17[0x18]; - u32 m_cal_ctl; - u32 m_vid_gen_filter_th; - u8 res18[0x10]; - u32 m_aud_gen_filter_th; - u8 res50[0x4]; - - u32 aux_ch_sta; - u32 aux_err_num; - u32 aux_ch_defer_ctl; - u32 aux_rx_comm; - u32 buffer_data_ctl; - - u32 aux_ch_ctl1; - u32 aux_addr_7_0; - u32 aux_addr_15_8; - u32 aux_addr_19_16; - u32 aux_ch_ctl2; - u8 res19[0x18]; - u32 buf_data0; - u8 res20[0x3c]; - - u32 soc_general_ctl; - u8 res21[0x8c]; - u32 crc_con; - u32 crc_result; - u8 res22[0x8]; - - u32 common_int_mask1; - u32 common_int_mask2; - u32 common_int_mask3; - u32 common_int_mask4; - u32 int_sta_mask1; - u32 int_sta_mask2; - u32 int_sta_mask3; - u32 int_sta_mask4; - u32 int_sta_mask; - u32 crc_result2; - u32 scrambler_reset_cnt; - - u32 pn_inv; - u32 psr_config; - u32 psr_command0; - u32 psr_command1; - u32 psr_crc_mon0; - u32 psr_crc_mon1; - - u8 res24[0x30]; - u32 phy_bist_ctrl; - u8 res25[0xc]; - u32 phy_ctrl; - u8 res26[0x1c]; - u32 test_pattern_gen_en; - u32 test_pattern_gen_ctrl; -}; - -static struct exynos_dp * const exynos_dp0 = (void *)EXYNOS5_DP0_BASE; -static struct exynos_dp * const exynos_dp1 = (void *)EXYNOS5_DP1_BASE; - -/* For DP VIDEO CTL 1 */ -#define VIDEO_EN_MASK (0x01 << 7) -#define VIDEO_MUTE_MASK (0x01 << 6) - -/* For DP VIDEO CTL 4 */ -#define VIDEO_BIST_MASK (0x1 << 3) - -/* EXYNOS_DP_ANALOG_CTL_1 */ -#define SEL_BG_NEW_BANDGAP (0x0 << 6) -#define SEL_BG_INTERNAL_RESISTOR (0x1 << 6) -#define TX_TERMINAL_CTRL_73_OHM (0x0 << 4) -#define TX_TERMINAL_CTRL_61_OHM (0x1 << 4) -#define TX_TERMINAL_CTRL_50_OHM (0x2 << 4) -#define TX_TERMINAL_CTRL_45_OHM (0x3 << 4) -#define SWING_A_30PER_G_INCREASE (0x1 << 3) -#define SWING_A_30PER_G_NORMAL (0x0 << 3) - -/* EXYNOS_DP_ANALOG_CTL_2 */ -#define CPREG_BLEED (0x1 << 4) -#define SEL_24M (0x1 << 3) -#define TX_DVDD_BIT_1_0000V (0x3 << 0) -#define TX_DVDD_BIT_1_0625V (0x4 << 0) -#define TX_DVDD_BIT_1_1250V (0x5 << 0) - -/* EXYNOS_DP_ANALOG_CTL_3 */ -#define DRIVE_DVDD_BIT_1_0000V (0x3 << 5) -#define DRIVE_DVDD_BIT_1_0625V (0x4 << 5) -#define DRIVE_DVDD_BIT_1_1250V (0x5 << 5) -#define SEL_CURRENT_DEFAULT (0x0 << 3) -#define VCO_BIT_000_MICRO (0x0 << 0) -#define VCO_BIT_200_MICRO (0x1 << 0) -#define VCO_BIT_300_MICRO (0x2 << 0) -#define VCO_BIT_400_MICRO (0x3 << 0) -#define VCO_BIT_500_MICRO (0x4 << 0) -#define VCO_BIT_600_MICRO (0x5 << 0) -#define VCO_BIT_700_MICRO (0x6 << 0) -#define VCO_BIT_900_MICRO (0x7 << 0) - -/* EXYNOS_DP_PLL_FILTER_CTL_1 */ -#define PD_RING_OSC (0x1 << 6) -#define AUX_TERMINAL_CTRL_52_OHM (0x3 << 4) -#define AUX_TERMINAL_CTRL_69_OHM (0x2 << 4) -#define AUX_TERMINAL_CTRL_102_OHM (0x1 << 4) -#define AUX_TERMINAL_CTRL_200_OHM (0x0 << 4) -#define TX_CUR1_1X (0x0 << 2) -#define TX_CUR1_2X (0x1 << 2) -#define TX_CUR1_3X (0x2 << 2) -#define TX_CUR_1_MA (0x0 << 0) -#define TX_CUR_2_MA (0x1 << 0) -#define TX_CUR_3_MA (0x2 << 0) -#define TX_CUR_4_MA (0x3 << 0) - -/* EXYNOS_DP_PLL_FILTER_CTL_2 */ -#define CH3_AMP_0_MV (0x3 << 12) -#define CH2_AMP_0_MV (0x3 << 8) -#define CH1_AMP_0_MV (0x3 << 4) -#define CH0_AMP_0_MV (0x3 << 0) - -/* EXYNOS_DP_PLL_CTL */ -#define DP_PLL_PD (0x1 << 7) -#define DP_PLL_RESET (0x1 << 6) -#define DP_PLL_LOOP_BIT_DEFAULT (0x1 << 4) -#define DP_PLL_REF_BIT_1_1250V (0x5 << 0) -#define DP_PLL_REF_BIT_1_2500V (0x7 << 0) - -/* EXYNOS_DP_INT_CTL */ -#define SOFT_INT_CTRL (0x1 << 2) -#define INT_POL (0x1 << 0) - -/* DP TX SW RESET */ -#define RESET_DP_TX (0x01 << 0) - -/* DP FUNC_EN_1 */ -#define MASTER_VID_FUNC_EN_N (0x1 << 7) -#define SLAVE_VID_FUNC_EN_N (0x1 << 5) -#define AUD_FIFO_FUNC_EN_N (0x1 << 4) -#define AUD_FUNC_EN_N (0x1 << 3) -#define HDCP_FUNC_EN_N (0x1 << 2) -#define CRC_FUNC_EN_N (0x1 << 1) -#define SW_FUNC_EN_N (0x1 << 0) - -/* DP FUNC_EN_2 */ -#define SSC_FUNC_EN_N (0x1 << 7) -#define AUX_FUNC_EN_N (0x1 << 2) -#define SERDES_FIFO_FUNC_EN_N (0x1 << 1) -#define LS_CLK_DOMAIN_FUNC_EN_N (0x1 << 0) - -/* EXYNOS_DP_PHY_PD */ -#define PHY_PD (0x1 << 5) -#define AUX_PD (0x1 << 4) -#define CH3_PD (0x1 << 3) -#define CH2_PD (0x1 << 2) -#define CH1_PD (0x1 << 1) -#define CH0_PD (0x1 << 0) - -/* EXYNOS_DP_COMMON_INT_STA_1 */ -#define VSYNC_DET (0x1 << 7) -#define PLL_LOCK_CHG (0x1 << 6) -#define SPDIF_ERR (0x1 << 5) -#define SPDIF_UNSTBL (0x1 << 4) -#define VID_FORMAT_CHG (0x1 << 3) -#define AUD_CLK_CHG (0x1 << 2) -#define VID_CLK_CHG (0x1 << 1) -#define SW_INT (0x1 << 0) - -/* EXYNOS_DP_DEBUG_CTL */ -#define PLL_LOCK (0x1 << 4) -#define F_PLL_LOCK (0x1 << 3) -#define PLL_LOCK_CTRL (0x1 << 2) - -/* EXYNOS_DP_FUNC_EN_2 */ -#define SSC_FUNC_EN_N (0x1 << 7) -#define AUX_FUNC_EN_N (0x1 << 2) -#define SERDES_FIFO_FUNC_EN_N (0x1 << 1) -#define LS_CLK_DOMAIN_FUNC_EN_N (0x1 << 0) - -/* EXYNOS_DP_COMMON_INT_STA_4 */ -#define PSR_ACTIVE (0x1 << 7) -#define PSR_INACTIVE (0x1 << 6) -#define SPDIF_BI_PHASE_ERR (0x1 << 5) -#define HOTPLUG_CHG (0x1 << 2) -#define HPD_LOST (0x1 << 1) -#define PLUG (0x1 << 0) - -/* EXYNOS_DP_INT_STA */ -#define INT_HPD (0x1 << 6) -#define HW_TRAINING_FINISH (0x1 << 5) -#define RPLY_RECEIV (0x1 << 1) -#define AUX_ERR (0x1 << 0) - -/* EXYNOS_DP_SYS_CTL_3 */ -#define HPD_STATUS (0x1 << 6) -#define F_HPD (0x1 << 5) -#define HPD_CTRL (0x1 << 4) -#define HDCP_RDY (0x1 << 3) -#define STRM_VALID (0x1 << 2) -#define F_VALID (0x1 << 1) -#define VALID_CTRL (0x1 << 0) - -/* EXYNOS_DP_AUX_HW_RETRY_CTL */ -#define AUX_BIT_PERIOD_EXPECTED_DELAY(x) (((x) & 0x7) << 8) -#define AUX_HW_RETRY_INTERVAL_MASK (0x3 << 3) -#define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS (0x0 << 3) -#define AUX_HW_RETRY_INTERVAL_800_MICROSECONDS (0x1 << 3) -#define AUX_HW_RETRY_INTERVAL_1000_MICROSECONDS (0x2 << 3) -#define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS (0x3 << 3) -#define AUX_HW_RETRY_COUNT_SEL(x) (((x) & 0x7) << 0) - -/* EXYNOS_DP_AUX_CH_DEFER_CTL */ -#define DEFER_CTRL_EN (0x1 << 7) -#define DEFER_COUNT(x) (((x) & 0x7f) << 0) - -#define COMMON_INT_MASK_1 (0) -#define COMMON_INT_MASK_2 (0) -#define COMMON_INT_MASK_3 (0) -#define COMMON_INT_MASK_4 (0) -#define INT_STA_MASK (0) - -/* EXYNOS_DP_BUFFER_DATA_CTL */ -#define BUF_CLR (0x1 << 7) -#define BUF_DATA_COUNT(x) (((x) & 0x1f) << 0) - -/* EXYNOS_DP_AUX_ADDR_7_0 */ -#define AUX_ADDR_7_0(x) (((x) >> 0) & 0xff) - -/* EXYNOS_DP_AUX_ADDR_15_8 */ -#define AUX_ADDR_15_8(x) (((x) >> 8) & 0xff) - -/* EXYNOS_DP_AUX_ADDR_19_16 */ -#define AUX_ADDR_19_16(x) (((x) >> 16) & 0x0f) - -/* EXYNOS_DP_AUX_CH_CTL_1 */ -#define AUX_LENGTH(x) (((x - 1) & 0xf) << 4) -#define AUX_TX_COMM_MASK (0xf << 0) -#define AUX_TX_COMM_DP_TRANSACTION (0x1 << 3) -#define AUX_TX_COMM_I2C_TRANSACTION (0x0 << 3) -#define AUX_TX_COMM_MOT (0x1 << 2) -#define AUX_TX_COMM_WRITE (0x0 << 0) -#define AUX_TX_COMM_READ (0x1 << 0) - -/* EXYNOS_DP_AUX_CH_CTL_2 */ -#define ADDR_ONLY (0x1 << 1) -#define AUX_EN (0x1 << 0) - -/* EXYNOS_DP_AUX_CH_STA */ -#define AUX_BUSY (0x1 << 4) -#define AUX_STATUS_MASK (0xf << 0) - -/* EXYNOS_DP_AUX_RX_COMM */ -#define AUX_RX_COMM_I2C_DEFER (0x2 << 2) -#define AUX_RX_COMM_AUX_DEFER (0x2 << 0) - -/* EXYNOS_DP_PHY_TEST */ -#define MACRO_RST (0x1 << 5) -#define CH1_TEST (0x1 << 1) -#define CH0_TEST (0x1 << 0) - -/* EXYNOS_DP_TRAINING_PTN_SET */ -#define SCRAMBLER_TYPE (0x1 << 9) -#define HW_LINK_TRAINING_PATTERN (0x1 << 8) -#define SCRAMBLING_DISABLE (0x1 << 5) -#define SCRAMBLING_ENABLE (0x0 << 5) -#define LINK_QUAL_PATTERN_SET_MASK (0x3 << 2) -#define LINK_QUAL_PATTERN_SET_PRBS7 (0x3 << 2) -#define LINK_QUAL_PATTERN_SET_D10_2 (0x1 << 2) -#define LINK_QUAL_PATTERN_SET_DISABLE (0x0 << 2) -#define SW_TRAINING_PATTERN_SET_MASK (0x3 << 0) -#define SW_TRAINING_PATTERN_SET_PTN2 (0x2 << 0) -#define SW_TRAINING_PATTERN_SET_PTN1 (0x1 << 0) -#define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0) - -/* EXYNOS_DP_TOTAL_LINE_CFG */ -#define TOTAL_LINE_CFG_L(x) ((x) & 0xff) -#define TOTAL_LINE_CFG_H(x) ((((x) >> 8)) & 0xff) -#define ACTIVE_LINE_CFG_L(x) ((x) & 0xff) -#define ACTIVE_LINE_CFG_H(x) (((x) >> 8) & 0xff) -#define TOTAL_PIXEL_CFG_L(x) ((x) & 0xff) -#define TOTAL_PIXEL_CFG_H(x) ((((x) >> 8)) & 0xff) -#define ACTIVE_PIXEL_CFG_L(x) ((x) & 0xff) -#define ACTIVE_PIXEL_CFG_H(x) ((((x) >> 8)) & 0xff) - -#define H_F_PORCH_CFG_L(x) ((x) & 0xff) -#define H_F_PORCH_CFG_H(x) ((((x) >> 8)) & 0xff) -#define H_SYNC_PORCH_CFG_L(x) ((x) & 0xff) -#define H_SYNC_PORCH_CFG_H(x) ((((x) >> 8)) & 0xff) -#define H_B_PORCH_CFG_L(x) ((x) & 0xff) -#define H_B_PORCH_CFG_H(x) ((((x) >> 8)) & 0xff) - -/* EXYNOS_DP_LN0_LINK_TRAINING_CTL */ -#define MAX_PRE_EMPHASIS_REACH_0 (0x1 << 5) -#define PRE_EMPHASIS_SET_0_SET(x) (((x) & 0x3) << 3) -#define PRE_EMPHASIS_SET_0_GET(x) (((x) >> 3) & 0x3) -#define PRE_EMPHASIS_SET_0_MASK (0x3 << 3) -#define PRE_EMPHASIS_SET_0_SHIFT (3) -#define PRE_EMPHASIS_SET_0_LEVEL_3 (0x3 << 3) -#define PRE_EMPHASIS_SET_0_LEVEL_2 (0x2 << 3) -#define PRE_EMPHASIS_SET_0_LEVEL_1 (0x1 << 3) -#define PRE_EMPHASIS_SET_0_LEVEL_0 (0x0 << 3) -#define MAX_DRIVE_CURRENT_REACH_0 (0x1 << 2) -#define DRIVE_CURRENT_SET_0_MASK (0x3 << 0) -#define DRIVE_CURRENT_SET_0_SET(x) (((x) & 0x3) << 0) -#define DRIVE_CURRENT_SET_0_GET(x) (((x) >> 0) & 0x3) -#define DRIVE_CURRENT_SET_0_LEVEL_3 (0x3 << 0) -#define DRIVE_CURRENT_SET_0_LEVEL_2 (0x2 << 0) -#define DRIVE_CURRENT_SET_0_LEVEL_1 (0x1 << 0) -#define DRIVE_CURRENT_SET_0_LEVEL_0 (0x0 << 0) - -/* EXYNOS_DP_LN1_LINK_TRAINING_CTL */ -#define MAX_PRE_EMPHASIS_REACH_1 (0x1 << 5) -#define PRE_EMPHASIS_SET_1_SET(x) (((x) & 0x3) << 3) -#define PRE_EMPHASIS_SET_1_GET(x) (((x) >> 3) & 0x3) -#define PRE_EMPHASIS_SET_1_MASK (0x3 << 3) -#define PRE_EMPHASIS_SET_1_SHIFT (3) -#define PRE_EMPHASIS_SET_1_LEVEL_3 (0x3 << 3) -#define PRE_EMPHASIS_SET_1_LEVEL_2 (0x2 << 3) -#define PRE_EMPHASIS_SET_1_LEVEL_1 (0x1 << 3) -#define PRE_EMPHASIS_SET_1_LEVEL_0 (0x0 << 3) -#define MAX_DRIVE_CURRENT_REACH_1 (0x1 << 2) -#define DRIVE_CURRENT_SET_1_MASK (0x3 << 0) -#define DRIVE_CURRENT_SET_1_SET(x) (((x) & 0x3) << 0) -#define DRIVE_CURRENT_SET_1_GET(x) (((x) >> 0) & 0x3) -#define DRIVE_CURRENT_SET_1_LEVEL_3 (0x3 << 0) -#define DRIVE_CURRENT_SET_1_LEVEL_2 (0x2 << 0) -#define DRIVE_CURRENT_SET_1_LEVEL_1 (0x1 << 0) -#define DRIVE_CURRENT_SET_1_LEVEL_0 (0x0 << 0) - -/* EXYNOS_DP_LN2_LINK_TRAINING_CTL */ -#define MAX_PRE_EMPHASIS_REACH_2 (0x1 << 5) -#define PRE_EMPHASIS_SET_2_SET(x) (((x) & 0x3) << 3) -#define PRE_EMPHASIS_SET_2_GET(x) (((x) >> 3) & 0x3) -#define PRE_EMPHASIS_SET_2_MASK (0x3 << 3) -#define PRE_EMPHASIS_SET_2_SHIFT (3) -#define PRE_EMPHASIS_SET_2_LEVEL_3 (0x3 << 3) -#define PRE_EMPHASIS_SET_2_LEVEL_2 (0x2 << 3) -#define PRE_EMPHASIS_SET_2_LEVEL_1 (0x1 << 3) -#define PRE_EMPHASIS_SET_2_LEVEL_0 (0x0 << 3) -#define MAX_DRIVE_CURRENT_REACH_2 (0x1 << 2) -#define DRIVE_CURRENT_SET_2_MASK (0x3 << 0) -#define DRIVE_CURRENT_SET_2_SET(x) (((x) & 0x3) << 0) -#define DRIVE_CURRENT_SET_2_GET(x) (((x) >> 0) & 0x3) -#define DRIVE_CURRENT_SET_2_LEVEL_3 (0x3 << 0) -#define DRIVE_CURRENT_SET_2_LEVEL_2 (0x2 << 0) -#define DRIVE_CURRENT_SET_2_LEVEL_1 (0x1 << 0) -#define DRIVE_CURRENT_SET_2_LEVEL_0 (0x0 << 0) - -/* EXYNOS_DP_LN3_LINK_TRAINING_CTL */ -#define MAX_PRE_EMPHASIS_REACH_3 (0x1 << 5) -#define PRE_EMPHASIS_SET_3_SET(x) (((x) & 0x3) << 3) -#define PRE_EMPHASIS_SET_3_GET(x) (((x) >> 3) & 0x3) -#define PRE_EMPHASIS_SET_3_MASK (0x3 << 3) -#define PRE_EMPHASIS_SET_3_SHIFT (3) -#define PRE_EMPHASIS_SET_3_LEVEL_3 (0x3 << 3) -#define PRE_EMPHASIS_SET_3_LEVEL_2 (0x2 << 3) -#define PRE_EMPHASIS_SET_3_LEVEL_1 (0x1 << 3) -#define PRE_EMPHASIS_SET_3_LEVEL_0 (0x0 << 3) -#define MAX_DRIVE_CURRENT_REACH_3 (0x1 << 2) -#define DRIVE_CURRENT_SET_3_MASK (0x3 << 0) -#define DRIVE_CURRENT_SET_3_SET(x) (((x) & 0x3) << 0) -#define DRIVE_CURRENT_SET_3_GET(x) (((x) >> 0) & 0x3) -#define DRIVE_CURRENT_SET_3_LEVEL_3 (0x3 << 0) -#define DRIVE_CURRENT_SET_3_LEVEL_2 (0x2 << 0) -#define DRIVE_CURRENT_SET_3_LEVEL_1 (0x1 << 0) -#define DRIVE_CURRENT_SET_3_LEVEL_0 (0x0 << 0) - -/* EXYNOS_DP_VIDEO_CTL_10 */ -#define FORMAT_SEL (0x1 << 4) -#define INTERACE_SCAN_CFG (0x1 << 2) -#define INTERACE_SCAN_CFG_SHIFT (2) -#define VSYNC_POLARITY_CFG (0x1 << 1) -#define V_S_POLARITY_CFG_SHIFT (1) -#define HSYNC_POLARITY_CFG (0x1 << 0) -#define H_S_POLARITY_CFG_SHIFT (0) - -/* EXYNOS_DP_SOC_GENERAL_CTL */ -#define AUDIO_MODE_SPDIF_MODE (0x1 << 8) -#define AUDIO_MODE_MASTER_MODE (0x0 << 8) -#define MASTER_VIDEO_INTERLACE_EN (0x1 << 4) -#define VIDEO_MASTER_CLK_SEL (0x1 << 2) -#define VIDEO_MASTER_MODE_EN (0x1 << 1) -#define VIDEO_MODE_MASK (0x1 << 0) -#define VIDEO_MODE_SLAVE_MODE (0x1 << 0) -#define VIDEO_MODE_MASTER_MODE (0x0 << 0) - -/* EXYNOS_DP_VIDEO_CTL_1 */ -#define VIDEO_EN (0x1 << 7) -#define HDCP_VIDEO_MUTE (0x1 << 6) - -/* EXYNOS_DP_VIDEO_CTL_2 */ -#define IN_D_RANGE_MASK (0x1 << 7) -#define IN_D_RANGE_SHIFT (7) -#define IN_D_RANGE_CEA (0x1 << 7) -#define IN_D_RANGE_VESA (0x0 << 7) -#define IN_BPC_MASK (0x7 << 4) -#define IN_BPC_SHIFT (4) -#define IN_BPC_12_BITS (0x3 << 4) -#define IN_BPC_10_BITS (0x2 << 4) -#define IN_BPC_8_BITS (0x1 << 4) -#define IN_BPC_6_BITS (0x0 << 4) -#define IN_COLOR_F_MASK (0x3 << 0) -#define IN_COLOR_F_SHIFT (0) -#define IN_COLOR_F_YCBCR444 (0x2 << 0) -#define IN_COLOR_F_YCBCR422 (0x1 << 0) -#define IN_COLOR_F_RGB (0x0 << 0) - -/* EXYNOS_DP_VIDEO_CTL_3 */ -#define IN_YC_COEFFI_MASK (0x1 << 7) -#define IN_YC_COEFFI_SHIFT (7) -#define IN_YC_COEFFI_ITU709 (0x1 << 7) -#define IN_YC_COEFFI_ITU601 (0x0 << 7) -#define VID_CHK_UPDATE_TYPE_MASK (0x1 << 4) -#define VID_CHK_UPDATE_TYPE_SHIFT (4) -#define VID_CHK_UPDATE_TYPE_1 (0x1 << 4) -#define VID_CHK_UPDATE_TYPE_0 (0x0 << 4) - -/* EXYNOS_DP_TEST_PATTERN_GEN_EN */ -#define TEST_PATTERN_GEN_EN (0x1 << 0) -#define TEST_PATTERN_GEN_DIS (0x0 << 0) - -/* EXYNOS_DP_TEST_PATTERN_GEN_CTRL */ -#define TEST_PATTERN_MODE_COLOR_SQUARE (0x3 << 0) -#define TEST_PATTERN_MODE_BALCK_WHITE_V_LINES (0x2 << 0) -#define TEST_PATTERN_MODE_COLOR_RAMP (0x1 << 0) - -/* EXYNOS_DP_VIDEO_CTL_4 */ -#define BIST_EN (0x1 << 3) -#define BIST_WIDTH_MASK (0x1 << 2) -#define BIST_WIDTH_BAR_32_PIXEL (0x0 << 2) -#define BIST_WIDTH_BAR_64_PIXEL (0x1 << 2) -#define BIST_TYPE_MASK (0x3 << 0) -#define BIST_TYPE_COLOR_BAR (0x0 << 0) -#define BIST_TYPE_WHITE_GRAY_BLACK_BAR (0x1 << 0) -#define BIST_TYPE_MOBILE_WHITE_BAR (0x2 << 0) - -/* EXYNOS_DP_SYS_CTL_1 */ -#define DET_STA (0x1 << 2) -#define FORCE_DET (0x1 << 1) -#define DET_CTRL (0x1 << 0) - -/* EXYNOS_DP_SYS_CTL_2 */ -#define CHA_CRI(x) (((x) & 0xf) << 4) -#define CHA_STA (0x1 << 2) -#define FORCE_CHA (0x1 << 1) -#define CHA_CTRL (0x1 << 0) - -/* EXYNOS_DP_SYS_CTL_3 */ -#define HPD_STATUS (0x1 << 6) -#define F_HPD (0x1 << 5) -#define HPD_CTRL (0x1 << 4) -#define HDCP_RDY (0x1 << 3) -#define STRM_VALID (0x1 << 2) -#define F_VALID (0x1 << 1) -#define VALID_CTRL (0x1 << 0) - -/* EXYNOS_DP_SYS_CTL_4 */ -#define FIX_M_AUD (0x1 << 4) -#define ENHANCED (0x1 << 3) -#define FIX_M_VID (0x1 << 2) -#define M_VID_UPDATE_CTRL (0x3 << 0) - -/* EXYNOS_M_VID_X */ -#define M_VID0_CFG(x) ((x) & 0xff) -#define M_VID1_CFG(x) (((x) >> 8) & 0xff) -#define M_VID2_CFG(x) (((x) >> 16) & 0xff) - -/* EXYNOS_M_VID_X */ -#define N_VID0_CFG(x) ((x) & 0xff) -#define N_VID1_CFG(x) (((x) >> 8) & 0xff) -#define N_VID2_CFG(x) (((x) >> 16) & 0xff) - -/* DPCD_TRAINING_PATTERN_SET */ -#define DPCD_SCRAMBLING_DISABLED (0x1 << 5) -#define DPCD_SCRAMBLING_ENABLED (0x0 << 5) -#define DPCD_TRAINING_PATTERN_2 (0x2 << 0) -#define DPCD_TRAINING_PATTERN_1 (0x1 << 0) -#define DPCD_TRAINING_PATTERN_DISABLED (0x0 << 0) - -/* Definition for DPCD Register */ -#define DPCD_DPCD_REV (0x0000) -#define DPCD_MAX_LINK_RATE (0x0001) -#define DPCD_MAX_LANE_COUNT (0x0002) -#define DPCD_LINK_BW_SET (0x0100) -#define DPCD_LANE_COUNT_SET (0x0101) -#define DPCD_TRAINING_PATTERN_SET (0x0102) -#define DPCD_TRAINING_LANE0_SET (0x0103) -#define DPCD_LANE0_1_STATUS (0x0202) -#define DPCD_LN_ALIGN_UPDATED (0x0204) -#define DPCD_ADJUST_REQUEST_LANE0_1 (0x0206) -#define DPCD_ADJUST_REQUEST_LANE2_3 (0x0207) -#define DPCD_TEST_REQUEST (0x0218) -#define DPCD_TEST_RESPONSE (0x0260) -#define DPCD_TEST_EDID_CHECKSUM (0x0261) -#define DPCD_SINK_POWER_STATE (0x0600) - -/* DPCD_TEST_REQUEST */ -#define DPCD_TEST_EDID_READ (0x1 << 2) - -/* DPCD_TEST_RESPONSE */ -#define DPCD_TEST_EDID_CHECKSUM_WRITE (0x1 << 2) - -/* DPCD_SINK_POWER_STATE */ -#define DPCD_SET_POWER_STATE_D0 (0x1 << 0) -#define DPCD_SET_POWER_STATE_D4 (0x2 << 0) - -/* I2C EDID Chip ID, Slave Address */ -#define I2C_EDID_DEVICE_ADDR (0x50) -#define I2C_E_EDID_DEVICE_ADDR (0x30) -#define EDID_BLOCK_LENGTH (0x80) -#define EDID_HEADER_PATTERN (0x00) -#define EDID_EXTENSION_FLAG (0x7e) -#define EDID_CHECKSUM (0x7f) - -/* DPCD_LANE0_1_STATUS */ -#define DPCD_LANE1_SYMBOL_LOCKED (0x1 << 6) -#define DPCD_LANE1_CHANNEL_EQ_DONE (0x1 << 5) -#define DPCD_LANE1_CR_DONE (0x1 << 4) -#define DPCD_LANE0_SYMBOL_LOCKED (0x1 << 2) -#define DPCD_LANE0_CHANNEL_EQ_DONE (0x1 << 1) -#define DPCD_LANE0_CR_DONE (0x1 << 0) - -/* DPCD_ADJUST_REQUEST_LANE0_1 */ -#define DPCD_PRE_EMPHASIS_LANE1_MASK (0x3 << 6) -#define DPCD_PRE_EMPHASIS_LANE1(x) (((x) >> 6) & 0x3) -#define DPCD_PRE_EMPHASIS_LANE1_LEVEL_3 (0x3 << 6) -#define DPCD_PRE_EMPHASIS_LANE1_LEVEL_2 (0x2 << 6) -#define DPCD_PRE_EMPHASIS_LANE1_LEVEL_1 (0x1 << 6) -#define DPCD_PRE_EMPHASIS_LANE1_LEVEL_0 (0x0 << 6) -#define DPCD_VOLTAGE_SWING_LANE1_MASK (0x3 << 4) -#define DPCD_VOLTAGE_SWING_LANE1(x) (((x) >> 4) & 0x3) -#define DPCD_VOLTAGE_SWING_LANE1_LEVEL_3 (0x3 << 4) -#define DPCD_VOLTAGE_SWING_LANE1_LEVEL_2 (0x2 << 4) -#define DPCD_VOLTAGE_SWING_LANE1_LEVEL_1 (0x1 << 4) -#define DPCD_VOLTAGE_SWING_LANE1_LEVEL_0 (0x0 << 4) -#define DPCD_PRE_EMPHASIS_LANE0_MASK (0x3 << 2) -#define DPCD_PRE_EMPHASIS_LANE0(x) (((x) >> 2) & 0x3) -#define DPCD_PRE_EMPHASIS_LANE0_LEVEL_3 (0x3 << 2) -#define DPCD_PRE_EMPHASIS_LANE0_LEVEL_2 (0x2 << 2) -#define DPCD_PRE_EMPHASIS_LANE0_LEVEL_1 (0x1 << 2) -#define DPCD_PRE_EMPHASIS_LANE0_LEVEL_0 (0x0 << 2) -#define DPCD_VOLTAGE_SWING_LANE0_MASK (0x3 << 0) -#define DPCD_VOLTAGE_SWING_LANE0(x) (((x) >> 0) & 0x3) -#define DPCD_VOLTAGE_SWING_LANE0_LEVEL_3 (0x3 << 0) -#define DPCD_VOLTAGE_SWING_LANE0_LEVEL_2 (0x2 << 0) -#define DPCD_VOLTAGE_SWING_LANE0_LEVEL_1 (0x1 << 0) -#define DPCD_VOLTAGE_SWING_LANE0_LEVEL_0 (0x0 << 0) - -/* DPCD_ADJUST_REQUEST_LANE2_3 */ -#define DPCD_PRE_EMPHASIS_LANE2_MASK (0x3 << 6) -#define DPCD_PRE_EMPHASIS_LANE2(x) (((x) >> 6) & 0x3) -#define DPCD_PRE_EMPHASIS_LANE2_LEVEL_3 (0x3 << 6) -#define DPCD_PRE_EMPHASIS_LANE2_LEVEL_2 (0x2 << 6) -#define DPCD_PRE_EMPHASIS_LANE2_LEVEL_1 (0x1 << 6) -#define DPCD_PRE_EMPHASIS_LANE2_LEVEL_0 (0x0 << 6) -#define DPCD_VOLTAGE_SWING_LANE2_MASK (0x3 << 4) -#define DPCD_VOLTAGE_SWING_LANE2(x) (((x) >> 4) & 0x3) -#define DPCD_VOLTAGE_SWING_LANE2_LEVEL_3 (0x3 << 4) -#define DPCD_VOLTAGE_SWING_LANE2_LEVEL_2 (0x2 << 4) -#define DPCD_VOLTAGE_SWING_LANE2_LEVEL_1 (0x1 << 4) -#define DPCD_VOLTAGE_SWING_LANE2_LEVEL_0 (0x0 << 4) -#define DPCD_PRE_EMPHASIS_LANE3_MASK (0x3 << 2) -#define DPCD_PRE_EMPHASIS_LANE3(x) (((x) >> 2) & 0x3) -#define DPCD_PRE_EMPHASIS_LANE3_LEVEL_3 (0x3 << 2) -#define DPCD_PRE_EMPHASIS_LANE3_LEVEL_2 (0x2 << 2) -#define DPCD_PRE_EMPHASIS_LANE3_LEVEL_1 (0x1 << 2) -#define DPCD_PRE_EMPHASIS_LANE3_LEVEL_0 (0x0 << 2) -#define DPCD_VOLTAGE_SWING_LANE3_MASK (0x3 << 0) -#define DPCD_VOLTAGE_SWING_LANE3(x) (((x) >> 0) & 0x3) -#define DPCD_VOLTAGE_SWING_LANE3_LEVEL_3 (0x3 << 0) -#define DPCD_VOLTAGE_SWING_LANE3_LEVEL_2 (0x2 << 0) -#define DPCD_VOLTAGE_SWING_LANE3_LEVEL_1 (0x1 << 0) -#define DPCD_VOLTAGE_SWING_LANE3_LEVEL_0 (0x0 << 0) - -/* DPCD_LANE_COUNT_SET */ -#define DPCD_ENHANCED_FRAME_EN (0x1 << 7) -#define DPCD_LN_COUNT_SET(x) ((x) & 0x1f) - -/* DPCD_LANE_ALIGN__STATUS_UPDATED */ -#define DPCD_LINK_STATUS_UPDATED (0x1 << 7) -#define DPCD_DOWNSTREAM_PORT_STATUS_CHANGED (0x1 << 6) -#define DPCD_INTERLANE_ALIGN_DONE (0x1 << 0) - -/* DPCD_TRAINING_LANE0_SET */ -#define DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_3 (0x3 << 3) -#define DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_2 (0x2 << 3) -#define DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_1 (0x1 << 3) -#define DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 (0x0 << 3) -#define DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_3 (0x3 << 0) -#define DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_2 (0x2 << 0) -#define DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_1 (0x1 << 0) -#define DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0 (0x0 << 0) - -#define DPCD_REQ_ADJ_SWING (0x00) -#define DPCD_REQ_ADJ_EMPHASIS (0x01) - -#define DP_LANE_STAT_CR_DONE (0x01 << 0) -#define DP_LANE_STAT_CE_DONE (0x01 << 1) -#define DP_LANE_STAT_SYM_LOCK (0x01 << 2) - -struct exynos_fb { - u32 vidcon0; - u32 vidcon1; - u32 vidcon2; - u32 vidcon3; - u32 vidtcon0; - u32 vidtcon1; - u32 vidtcon2; - u32 vidtcon3; - u32 wincon0; - u32 wincon1; - u32 wincon2; - u32 wincon3; - u32 wincon4; - - u32 winshmap; - u32 res1; - - u32 winchmap2; - u32 vidosd0a; - u32 vidosd0b; - u32 vidosd0c; - u32 res2; - - u32 vidosd1a; - u32 vidosd1b; - u32 vidosd1c; - u32 vidosd1d; - - u32 vidosd2a; - u32 vidosd2b; - u32 vidosd2c; - u32 vidosd2d; - - u32 vidosd3a; - u32 vidosd3b; - u32 vidosd3c; - u32 res3; - - u32 vidosd4a; - u32 vidosd4b; - u32 vidosd4c; - u32 res4[5]; - - u32 vidw00add0b0; - u32 vidw00add0b1; - u32 vidw01add0b0; - u32 vidw01add0b1; - - u32 vidw02add0b0; - u32 vidw02add0b1; - u32 vidw03add0b0; - u32 vidw03add0b1; - u32 vidw04add0b0; - u32 vidw04add0b1; - u32 res5[2]; - - u32 vidw00add1b0; - u32 vidw00add1b1; - u32 vidw01add1b0; - u32 vidw01add1b1; - - u32 vidw02add1b0; - u32 vidw02add1b1; - u32 vidw03add1b0; - u32 vidw03add1b1; - - u32 vidw04add1b0; - u32 vidw04add1b1; - u32 res7[2]; - - u32 vidw00add2; - u32 vidw01add2; - u32 vidw02add2; - u32 vidw03add2; - u32 vidw04add2; - u32 res8[7]; - - u32 vidintcon0; - u32 vidintcon1; - u32 res9[1]; - - u32 w1keycon0; - u32 w1keycon1; - u32 w2keycon0; - u32 w2keycon1; - u32 w3keycon0; - u32 w3keycon1; - u32 w4keycon0; - u32 w4keycon1; - - u32 w1keyalpha; - u32 w2keyalpha; - u32 w3keyalpha; - u32 w4keyalpha; - - u32 dithmode; - u32 res10[2]; - - u32 win0map; - u32 win1map; - u32 win2map; - u32 win3map; - u32 win4map; - u32 res11[1]; - - u32 wpalcon_h; - u32 wpalcon_l; - - u32 trigcon; - u32 res12[2]; - - u32 i80ifcona0; - u32 i80ifcona1; - u32 i80ifconb0; - u32 i80ifconb1; - - u32 colorgaincon; - u32 res13[2]; - - u32 ldi_cmdcon0; - u32 ldi_cmdcon1; - u32 res14[1]; - - /* To be updated */ - - u8 res15[156]; - u32 dualrgb; - u8 res16[16]; - u32 dp_mie_clkcon; -}; - - -/* LCD IF register offset */ -#define EXYNOS5_LCD_IF_BASE_OFFSET 0x20000 - -static inline u32 exynos_fimd_get_base_offset(void) -{ - return EXYNOS5_LCD_IF_BASE_OFFSET/4; -} - -/* - * Register offsets -*/ -#define EXYNOS_WINCON(x) (x) -#define EXYNOS_VIDOSD(x) (x * 4) -#define EXYNOS_BUFFER_OFFSET(x) (x * 2) -#define EXYNOS_BUFFER_SIZE(x) (x) - -/* - * Bit Definitions -*/ - -/* VIDCON0 */ -#define EXYNOS_VIDCON0_DSI_DISABLE (0 << 30) -#define EXYNOS_VIDCON0_DSI_ENABLE (1 << 30) -#define EXYNOS_VIDCON0_SCAN_PROGRESSIVE (0 << 29) -#define EXYNOS_VIDCON0_SCAN_INTERLACE (1 << 29) -#define EXYNOS_VIDCON0_SCAN_MASK (1 << 29) -#define EXYNOS_VIDCON0_VIDOUT_RGB (0 << 26) -#define EXYNOS_VIDCON0_VIDOUT_ITU (1 << 26) -#define EXYNOS_VIDCON0_VIDOUT_I80LDI0 (2 << 26) -#define EXYNOS_VIDCON0_VIDOUT_I80LDI1 (3 << 26) -#define EXYNOS_VIDCON0_VIDOUT_WB_RGB (4 << 26) -#define EXYNOS_VIDCON0_VIDOUT_WB_I80LDI0 (6 << 26) -#define EXYNOS_VIDCON0_VIDOUT_WB_I80LDI1 (7 << 26) -#define EXYNOS_VIDCON0_VIDOUT_MASK (7 << 26) -#define EXYNOS_VIDCON0_PNRMODE_RGB_P (0 << 17) -#define EXYNOS_VIDCON0_PNRMODE_BGR_P (1 << 17) -#define EXYNOS_VIDCON0_PNRMODE_RGB_S (2 << 17) -#define EXYNOS_VIDCON0_PNRMODE_BGR_S (3 << 17) -#define EXYNOS_VIDCON0_PNRMODE_MASK (3 << 17) -#define EXYNOS_VIDCON0_PNRMODE_SHIFT (17) -#define EXYNOS_VIDCON0_CLKVALUP_ALWAYS (0 << 16) -#define EXYNOS_VIDCON0_CLKVALUP_START_FRAME (1 << 16) -#define EXYNOS_VIDCON0_CLKVALUP_MASK (1 << 16) -#define EXYNOS_VIDCON0_CLKVAL_F(x) (((x) & 0xff) << 6) -#define EXYNOS_VIDCON0_VCLKEN_NORMAL (0 << 5) -#define EXYNOS_VIDCON0_VCLKEN_FREERUN (1 << 5) -#define EXYNOS_VIDCON0_VCLKEN_MASK (1 << 5) -#define EXYNOS_VIDCON0_CLKDIR_DIRECTED (0 << 4) -#define EXYNOS_VIDCON0_CLKDIR_DIVIDED (1 << 4) -#define EXYNOS_VIDCON0_CLKDIR_MASK (1 << 4) -#define EXYNOS_VIDCON0_CLKSEL_HCLK (0 << 2) -#define EXYNOS_VIDCON0_CLKSEL_SCLK (1 << 2) -#define EXYNOS_VIDCON0_CLKSEL_MASK (1 << 2) -#define EXYNOS_VIDCON0_ENVID_ENABLE (1 << 1) -#define EXYNOS_VIDCON0_ENVID_DISABLE (0 << 1) -#define EXYNOS_VIDCON0_ENVID_F_ENABLE (1 << 0) -#define EXYNOS_VIDCON0_ENVID_F_DISABLE (0 << 0) - -/* VIDCON1 */ -#define EXYNOS_VIDCON1_IVCLK_FALLING_EDGE (0 << 7) -#define EXYNOS_VIDCON1_IVCLK_RISING_EDGE (1 << 7) -#define EXYNOS_VIDCON1_IHSYNC_NORMAL (0 << 6) -#define EXYNOS_VIDCON1_IHSYNC_INVERT (1 << 6) -#define EXYNOS_VIDCON1_IVSYNC_NORMAL (0 << 5) -#define EXYNOS_VIDCON1_IVSYNC_INVERT (1 << 5) -#define EXYNOS_VIDCON1_IVDEN_NORMAL (0 << 4) -#define EXYNOS_VIDCON1_IVDEN_INVERT (1 << 4) - -/* VIDCON2 */ -#define EXYNOS_VIDCON2_EN601_DISABLE (0 << 23) -#define EXYNOS_VIDCON2_EN601_ENABLE (1 << 23) -#define EXYNOS_VIDCON2_EN601_MASK (1 << 23) -#define EXYNOS_VIDCON2_WB_DISABLE (0 << 15) -#define EXYNOS_VIDCON2_WB_ENABLE (1 << 15) -#define EXYNOS_VIDCON2_WB_MASK (1 << 15) -#define EXYNOS_VIDCON2_TVFORMATSEL_HW (0 << 14) -#define EXYNOS_VIDCON2_TVFORMATSEL_SW (1 << 14) -#define EXYNOS_VIDCON2_TVFORMATSEL_MASK (1 << 14) -#define EXYNOS_VIDCON2_TVFORMATSEL_YUV422 (1 << 12) -#define EXYNOS_VIDCON2_TVFORMATSEL_YUV444 (2 << 12) -#define EXYNOS_VIDCON2_TVFORMATSEL_YUV_MASK (3 << 12) -#define EXYNOS_VIDCON2_ORGYUV_YCBCR (0 << 8) -#define EXYNOS_VIDCON2_ORGYUV_CBCRY (1 << 8) -#define EXYNOS_VIDCON2_ORGYUV_MASK (1 << 8) -#define EXYNOS_VIDCON2_YUVORD_CBCR (0 << 7) -#define EXYNOS_VIDCON2_YUVORD_CRCB (1 << 7) -#define EXYNOS_VIDCON2_YUVORD_MASK (1 << 7) - -/* PRTCON */ -#define EXYNOS_PRTCON_UPDATABLE (0 << 11) -#define EXYNOS_PRTCON_PROTECT (1 << 11) - -/* VIDTCON0 */ -#define EXYNOS_VIDTCON0_VBPDE(x) (((x) & 0xff) << 24) -#define EXYNOS_VIDTCON0_VBPD(x) (((x) & 0xff) << 16) -#define EXYNOS_VIDTCON0_VFPD(x) (((x) & 0xff) << 8) -#define EXYNOS_VIDTCON0_VSPW(x) (((x) & 0xff) << 0) - -/* VIDTCON1 */ -#define EXYNOS_VIDTCON1_VFPDE(x) (((x) & 0xff) << 24) -#define EXYNOS_VIDTCON1_HBPD(x) (((x) & 0xff) << 16) -#define EXYNOS_VIDTCON1_HFPD(x) (((x) & 0xff) << 8) -#define EXYNOS_VIDTCON1_HSPW(x) (((x) & 0xff) << 0) - -/* VIDTCON2 */ -#define EXYNOS_VIDTCON2_LINEVAL(x) (((x) & 0x7ff) << 11) -#define EXYNOS_VIDTCON2_HOZVAL(x) (((x) & 0x7ff) << 0) -#define EXYNOS_VIDTCON2_LINEVAL_E(x) ((((x) & 0x800) >> 11) << 23) -#define EXYNOS_VIDTCON2_HOZVAL_E(x) ((((x) & 0x800) >> 11) << 22) - -/* Window 0~4 Control - WINCONx */ -#define EXYNOS_WINCON_DATAPATH_DMA (0 << 22) -#define EXYNOS_WINCON_DATAPATH_LOCAL (1 << 22) -#define EXYNOS_WINCON_DATAPATH_MASK (1 << 22) -#define EXYNOS_WINCON_BUFSEL_0 (0 << 20) -#define EXYNOS_WINCON_BUFSEL_1 (1 << 20) -#define EXYNOS_WINCON_BUFSEL_MASK (1 << 20) -#define EXYNOS_WINCON_BUFSEL_SHIFT (20) -#define EXYNOS_WINCON_BUFAUTO_DISABLE (0 << 19) -#define EXYNOS_WINCON_BUFAUTO_ENABLE (1 << 19) -#define EXYNOS_WINCON_BUFAUTO_MASK (1 << 19) -#define EXYNOS_WINCON_BITSWP_DISABLE (0 << 18) -#define EXYNOS_WINCON_BITSWP_ENABLE (1 << 18) -#define EXYNOS_WINCON_BITSWP_SHIFT (18) -#define EXYNOS_WINCON_BYTESWP_DISABLE (0 << 17) -#define EXYNOS_WINCON_BYTESWP_ENABLE (1 << 17) -#define EXYNOS_WINCON_BYTESWP_SHIFT (17) -#define EXYNOS_WINCON_HAWSWP_DISABLE (0 << 16) -#define EXYNOS_WINCON_HAWSWP_ENABLE (1 << 16) -#define EXYNOS_WINCON_HAWSWP_SHIFT (16) -#define EXYNOS_WINCON_WSWP_DISABLE (0 << 15) -#define EXYNOS_WINCON_WSWP_ENABLE (1 << 15) -#define EXYNOS_WINCON_WSWP_SHIFT (15) -#define EXYNOS_WINCON_INRGB_RGB (0 << 13) -#define EXYNOS_WINCON_INRGB_YUV (1 << 13) -#define EXYNOS_WINCON_INRGB_MASK (1 << 13) -#define EXYNOS_WINCON_BURSTLEN_16WORD (0 << 9) -#define EXYNOS_WINCON_BURSTLEN_8WORD (1 << 9) -#define EXYNOS_WINCON_BURSTLEN_4WORD (2 << 9) -#define EXYNOS_WINCON_BURSTLEN_MASK (3 << 9) -#define EXYNOS_WINCON_ALPHA_MULTI_DISABLE (0 << 7) -#define EXYNOS_WINCON_ALPHA_MULTI_ENABLE (1 << 7) -#define EXYNOS_WINCON_BLD_PLANE (0 << 6) -#define EXYNOS_WINCON_BLD_PIXEL (1 << 6) -#define EXYNOS_WINCON_BLD_MASK (1 << 6) -#define EXYNOS_WINCON_BPPMODE_1BPP (0 << 2) -#define EXYNOS_WINCON_BPPMODE_2BPP (1 << 2) -#define EXYNOS_WINCON_BPPMODE_4BPP (2 << 2) -#define EXYNOS_WINCON_BPPMODE_8BPP_PAL (3 << 2) -#define EXYNOS_WINCON_BPPMODE_8BPP (4 << 2) -#define EXYNOS_WINCON_BPPMODE_16BPP_565 (5 << 2) -#define EXYNOS_WINCON_BPPMODE_16BPP_A555 (6 << 2) -#define EXYNOS_WINCON_BPPMODE_18BPP_666 (8 << 2) -#define EXYNOS_WINCON_BPPMODE_18BPP_A665 (9 << 2) -#define EXYNOS_WINCON_BPPMODE_24BPP_888 (0xb << 2) -#define EXYNOS_WINCON_BPPMODE_24BPP_A887 (0xc << 2) -#define EXYNOS_WINCON_BPPMODE_32BPP (0xd << 2) -#define EXYNOS_WINCON_BPPMODE_16BPP_A444 (0xe << 2) -#define EXYNOS_WINCON_BPPMODE_15BPP_555 (0xf << 2) -#define EXYNOS_WINCON_BPPMODE_MASK (0xf << 2) -#define EXYNOS_WINCON_BPPMODE_SHIFT (2) -#define EXYNOS_WINCON_ALPHA0_SEL (0 << 1) -#define EXYNOS_WINCON_ALPHA1_SEL (1 << 1) -#define EXYNOS_WINCON_ALPHA_SEL_MASK (1 << 1) -#define EXYNOS_WINCON_ENWIN_DISABLE (0 << 0) -#define EXYNOS_WINCON_ENWIN_ENABLE (1 << 0) - -/* WINCON1 special */ -#define EXYNOS_WINCON1_VP_DISABLE (0 << 24) -#define EXYNOS_WINCON1_VP_ENABLE (1 << 24) -#define EXYNOS_WINCON1_LOCALSEL_FIMC1 (0 << 23) -#define EXYNOS_WINCON1_LOCALSEL_VP (1 << 23) -#define EXYNOS_WINCON1_LOCALSEL_MASK (1 << 23) - -/* WINSHMAP */ -#define EXYNOS_WINSHMAP_PROTECT(x) (((x) & 0x1f) << 10) -#define EXYNOS_WINSHMAP_CH_ENABLE(x) (1 << (x)) -#define EXYNOS_WINSHMAP_CH_DISABLE(x) (1 << (x)) -#define EXYNOS_WINSHMAP_LOCAL_ENABLE(x) (0x20 << (x)) -#define EXYNOS_WINSHMAP_LOCAL_DISABLE(x) (0x20 << (x)) - -/* VIDOSDxA, VIDOSDxB */ -#define EXYNOS_VIDOSD_LEFT_X(x) (((x) & 0x7ff) << 11) -#define EXYNOS_VIDOSD_TOP_Y(x) (((x) & 0x7ff) << 0) -#define EXYNOS_VIDOSD_RIGHT_X(x) (((x) & 0x7ff) << 11) -#define EXYNOS_VIDOSD_BOTTOM_Y(x) (((x) & 0x7ff) << 0) -#define EXYNOS_VIDOSD_RIGHT_X_E(x) (((x) & 0x1) << 23) -#define EXYNOS_VIDOSD_BOTTOM_Y_E(x) (((x) & 0x1) << 22) - -/* VIDOSD0C, VIDOSDxD */ -#define EXYNOS_VIDOSD_SIZE(x) (((x) & 0xffffff) << 0) - -/* VIDOSDxC (1~4) */ -#define EXYNOS_VIDOSD_ALPHA0_R(x) (((x) & 0xf) << 20) -#define EXYNOS_VIDOSD_ALPHA0_G(x) (((x) & 0xf) << 16) -#define EXYNOS_VIDOSD_ALPHA0_B(x) (((x) & 0xf) << 12) -#define EXYNOS_VIDOSD_ALPHA1_R(x) (((x) & 0xf) << 8) -#define EXYNOS_VIDOSD_ALPHA1_G(x) (((x) & 0xf) << 4) -#define EXYNOS_VIDOSD_ALPHA1_B(x) (((x) & 0xf) << 0) -#define EXYNOS_VIDOSD_ALPHA0_SHIFT (12) -#define EXYNOS_VIDOSD_ALPHA1_SHIFT (0) - -/* Start Address */ -#define EXYNOS_VIDADDR_START_VBANK(x) (((x) & 0xff) << 24) -#define EXYNOS_VIDADDR_START_VBASEU(x) (((x) & 0xffffff) << 0) - -/* End Address */ -#define EXYNOS_VIDADDR_END_VBASEL(x) (((x) & 0xffffff) << 0) - -/* Buffer Size */ -#define EXYNOS_VIDADDR_OFFSIZE(x) (((x) & 0x1fff) << 13) -#define EXYNOS_VIDADDR_PAGEWIDTH(x) (((x) & 0x1fff) << 0) -#define EXYNOS_VIDADDR_OFFSIZE_E(x) ((((x) & 0x2000) >> 13) << 27) -#define EXYNOS_VIDADDR_PAGEWIDTH_E(x) ((((x) & 0x2000) >> 13) << 26) - -/* WIN Color Map */ -#define EXYNOS_WINMAP_COLOR(x) ((x) & 0xffffff) - -/* VIDINTCON0 */ -#define EXYNOS_VIDINTCON0_SYSMAINCON_DISABLE (0 << 19) -#define EXYNOS_VIDINTCON0_SYSMAINCON_ENABLE (1 << 19) -#define EXYNOS_VIDINTCON0_SYSSUBCON_DISABLE (0 << 18) -#define EXYNOS_VIDINTCON0_SYSSUBCON_ENABLE (1 << 18) -#define EXYNOS_VIDINTCON0_SYSIFDONE_DISABLE (0 << 17) -#define EXYNOS_VIDINTCON0_SYSIFDONE_ENABLE (1 << 17) -#define EXYNOS_VIDINTCON0_FRAMESEL0_BACK (0 << 15) -#define EXYNOS_VIDINTCON0_FRAMESEL0_VSYNC (1 << 15) -#define EXYNOS_VIDINTCON0_FRAMESEL0_ACTIVE (2 << 15) -#define EXYNOS_VIDINTCON0_FRAMESEL0_FRONT (3 << 15) -#define EXYNOS_VIDINTCON0_FRAMESEL0_MASK (3 << 15) -#define EXYNOS_VIDINTCON0_FRAMESEL1_NONE (0 << 13) -#define EXYNOS_VIDINTCON0_FRAMESEL1_BACK (1 << 13) -#define EXYNOS_VIDINTCON0_FRAMESEL1_VSYNC (2 << 13) -#define EXYNOS_VIDINTCON0_FRAMESEL1_FRONT (3 << 13) -#define EXYNOS_VIDINTCON0_INTFRMEN_DISABLE (0 << 12) -#define EXYNOS_VIDINTCON0_INTFRMEN_ENABLE (1 << 12) -#define EXYNOS_VIDINTCON0_FIFOSEL_WIN4 (1 << 11) -#define EXYNOS_VIDINTCON0_FIFOSEL_WIN3 (1 << 10) -#define EXYNOS_VIDINTCON0_FIFOSEL_WIN2 (1 << 9) -#define EXYNOS_VIDINTCON0_FIFOSEL_WIN1 (1 << 6) -#define EXYNOS_VIDINTCON0_FIFOSEL_WIN0 (1 << 5) -#define EXYNOS_VIDINTCON0_FIFOSEL_ALL (0x73 << 5) -#define EXYNOS_VIDINTCON0_FIFOSEL_MASK (0x73 << 5) -#define EXYNOS_VIDINTCON0_FIFOLEVEL_25 (0 << 2) -#define EXYNOS_VIDINTCON0_FIFOLEVEL_50 (1 << 2) -#define EXYNOS_VIDINTCON0_FIFOLEVEL_75 (2 << 2) -#define EXYNOS_VIDINTCON0_FIFOLEVEL_EMPTY (3 << 2) -#define EXYNOS_VIDINTCON0_FIFOLEVEL_FULL (4 << 2) -#define EXYNOS_VIDINTCON0_FIFOLEVEL_MASK (7 << 2) -#define EXYNOS_VIDINTCON0_INTFIFO_DISABLE (0 << 1) -#define EXYNOS_VIDINTCON0_INTFIFO_ENABLE (1 << 1) -#define EXYNOS_VIDINTCON0_INT_DISABLE (0 << 0) -#define EXYNOS_VIDINTCON0_INT_ENABLE (1 << 0) -#define EXYNOS_VIDINTCON0_INT_MASK (1 << 0) - -/* VIDINTCON1 */ -#define EXYNOS_VIDINTCON1_INTVPPEND (1 << 5) -#define EXYNOS_VIDINTCON1_INTI80PEND (1 << 2) -#define EXYNOS_VIDINTCON1_INTFRMPEND (1 << 1) -#define EXYNOS_VIDINTCON1_INTFIFOPEND (1 << 0) - -/* WINMAP */ -#define EXYNOS_WINMAP_ENABLE (1 << 24) - -/* WxKEYCON0 (1~4) */ -#define EXYNOS_KEYCON0_KEYBLEN_DISABLE (0 << 26) -#define EXYNOS_KEYCON0_KEYBLEN_ENABLE (1 << 26) -#define EXYNOS_KEYCON0_KEY_DISABLE (0 << 25) -#define EXYNOS_KEYCON0_KEY_ENABLE (1 << 25) -#define EXYNOS_KEYCON0_DIRCON_MATCH_FG (0 << 24) -#define EXYNOS_KEYCON0_DIRCON_MATCH_BG (1 << 24) -#define EXYNOS_KEYCON0_COMPKEY(x) (((x) & 0xffffff) << 0) - -/* WxKEYCON1 (1~4) */ -#define EXYNOS_KEYCON1_COLVAL(x) (((x) & 0xffffff) << 0) - -/* DUALRGB */ -#define EXYNOS_DUALRGB_BYPASS_SINGLE (0x00 << 0) -#define EXYNOS_DUALRGB_BYPASS_DUAL (0x01 << 0) -#define EXYNOS_DUALRGB_MIE_DUAL (0x10 << 0) -#define EXYNOS_DUALRGB_MIE_SINGLE (0x11 << 0) -#define EXYNOS_DUALRGB_LINESPLIT (0x0 << 2) -#define EXYNOS_DUALRGB_FRAMESPLIT (0x1 << 2) -#define EXYNOS_DUALRGB_SUB_CNT(x) ((x & 0xfff) << 4) -#define EXYNOS_DUALRGB_VDEN_EN_DISABLE (0x0 << 16) -#define EXYNOS_DUALRGB_VDEN_EN_ENABLE (0x1 << 16) -#define EXYNOS_DUALRGB_MAIN_CNT(x) ((x & 0xfff) << 18) - -/* I80IFCONA0 and I80IFCONA1 */ -#define EXYNOS_LCD_CS_SETUP(x) (((x) & 0xf) << 16) -#define EXYNOS_LCD_WR_SETUP(x) (((x) & 0xf) << 12) -#define EXYNOS_LCD_WR_ACT(x) (((x) & 0xf) << 8) -#define EXYNOS_LCD_WR_HOLD(x) (((x) & 0xf) << 4) -#define EXYNOS_RSPOL_LOW (0 << 2) -#define EXYNOS_RSPOL_HIGH (1 << 2) -#define EXYNOS_I80IFEN_DISABLE (0 << 0) -#define EXYNOS_I80IFEN_ENABLE (1 << 0) - -/* TRIGCON */ -#define EXYNOS_I80SOFT_TRIG_EN (1 << 0) -#define EXYNOS_I80START_TRIG (1 << 1) -#define EXYNOS_I80STATUS_TRIG_DONE (1 << 2) - -/* DP_MIE_CLKCON */ -#define EXYNOS_DP_MIE_DISABLE (0 << 0) -#define EXYNOS_DP_CLK_ENABLE (1 << 1) -#define EXYNOS_MIE_CLK_ENABLE (3 << 0) - -#define DP_TIMEOUT_LOOP_COUNT 1000 -#define MAX_CR_LOOP 5 -#define MAX_EQ_LOOP 4 - -#define EXYNOS_DP_SUCCESS 0 - -enum { - DP_DISABLE, - DP_ENABLE, -}; - -struct edp_disp_info { - char *name; - unsigned int h_total; - unsigned int h_res; - unsigned int h_sync_width; - unsigned int h_back_porch; - unsigned int h_front_porch; - unsigned int v_total; - unsigned int v_res; - unsigned int v_sync_width; - unsigned int v_back_porch; - unsigned int v_front_porch; - unsigned int v_sync_rate; -}; - -struct edp_link_train_info { - unsigned int lt_status; - unsigned int ep_loop; - unsigned int cr_loop[4]; -}; - -struct edp_video_info { - unsigned int master_mode; - unsigned int bist_mode; - unsigned int bist_pattern; - unsigned int h_sync_polarity; - unsigned int v_sync_polarity; - unsigned int interlaced; - unsigned int color_space; - unsigned int dynamic_range; - unsigned int ycbcr_coeff; - unsigned int color_depth; -}; - -struct edp_device_info { - struct edp_disp_info disp_info; - struct edp_link_train_info lt_info; - struct edp_video_info video_info; - - /*below info get from panel during training*/ - u8 lane_bw; - u8 lane_cnt; - u8 dpcd_rev; - /*support enhanced frame cap */ - u8 dpcd_efc; - u8 *raw_edid; -}; - -enum analog_power_block { - AUX_BLOCK, - CH0_BLOCK, - CH1_BLOCK, - CH2_BLOCK, - CH3_BLOCK, - ANALOG_TOTAL, - POWER_ALL -}; - -enum pll_status { - PLL_UNLOCKED = 0, - PLL_LOCKED -}; - -enum { - COLOR_RGB, - COLOR_YCBCR422, - COLOR_YCBCR444 -}; - -enum { - VESA, - CEA -}; - -enum { - COLOR_YCBCR601, - COLOR_YCBCR709 -}; - -enum { - COLOR_6, - COLOR_8, - COLOR_10, - COLOR_12 -}; - -enum { - DP_LANE_BW_1_62 = 0x06, - DP_LANE_BW_2_70 = 0x0a, -}; - -enum { - DP_LANE_CNT_1 = 1, - DP_LANE_CNT_2 = 2, - DP_LANE_CNT_4 = 4, -}; - -enum { - DP_DPCD_REV_10 = 0x10, - DP_DPCD_REV_11 = 0x11, -}; - -enum { - DP_LT_NONE, - DP_LT_START, - DP_LT_CR, - DP_LT_ET, - DP_LT_FINISHED, - DP_LT_FAIL, -}; - -enum { - PRE_EMPHASIS_LEVEL_0, - PRE_EMPHASIS_LEVEL_1, - PRE_EMPHASIS_LEVEL_2, - PRE_EMPHASIS_LEVEL_3, -}; - -enum { - PRBS7, - D10_2, - TRAINING_PTN1, - TRAINING_PTN2, - DP_NONE -}; - -enum { - VOLTAGE_LEVEL_0, - VOLTAGE_LEVEL_1, - VOLTAGE_LEVEL_2, - VOLTAGE_LEVEL_3, -}; - -enum pattern_type { - NO_PATTERN, - COLOR_RAMP, - BALCK_WHITE_V_LINES, - COLOR_SQUARE, - INVALID_PATTERN, - COLORBAR_32, - COLORBAR_64, - WHITE_GRAY_BALCKBAR_32, - WHITE_GRAY_BALCKBAR_64, - MOBILE_WHITEBAR_32, - MOBILE_WHITEBAR_64 -}; - -enum { - CALCULATED_M, - REGISTER_M -}; - -enum { - VIDEO_TIMING_FROM_CAPTURE, - VIDEO_TIMING_FROM_REGISTER -}; - - -struct exynos_dp_platform_data { - struct edp_device_info *edp_dev_info; -}; - - -int exynos_init_dp(struct edp_device_info *edp_info); - -void exynos_set_dp_platform_data(struct exynos_dp_platform_data *pd); - -void exynos_dp_disable_video_bist(void); -void exynos_dp_enable_video_mute(unsigned int enable); -void exynos_dp_reset(void); -void exynos_dp_enable_sw_func(unsigned int enable); -unsigned int exynos_dp_set_analog_power_down(unsigned int block, u32 enable); -unsigned int exynos_dp_get_pll_lock_status(void); -int exynos_dp_init_analog_func(void); -void exynos_dp_init_hpd(void); -void exynos_dp_init_aux(void); -void exynos_dp_config_interrupt(void); -unsigned int exynos_dp_get_plug_in_status(void); -unsigned int exynos_dp_detect_hpd(void); -unsigned int exynos_dp_start_aux_transaction(void); -unsigned int exynos_dp_write_byte_to_dpcd(u32 reg_addr, - u8 data); -unsigned int exynos_dp_read_byte_from_dpcd(u32 reg_addr, - u8 *data); -unsigned int exynos_dp_write_bytes_to_dpcd(u32 reg_addr, - unsigned int count, - u8 data[]); -u32 exynos_dp_read_bytes_from_dpcd( unsigned int reg_addr, - unsigned int count, - u8 data[]); -int exynos_dp_select_i2c_device( u32 device_addr, - u32 reg_addr); -int exynos_dp_read_byte_from_i2c(u32 device_addr, - u32 reg_addr, unsigned int *data); -int exynos_dp_read_bytes_from_i2c(u32 device_addr, - u32 reg_addr, unsigned int count, - u8 edid[]); -void exynos_dp_reset_macro(void); -void exynos_dp_set_link_bandwidth(u8 bwtype); -u8 exynos_dp_get_link_bandwidth(void); -void exynos_dp_set_lane_count(u8 count); -unsigned int exynos_dp_get_lane_count(void); -u8 exynos_dp_get_lanex_pre_emphasis(u8 lanecnt); -void exynos_dp_set_lane_pre_emphasis(unsigned int level, - u8 lanecnt); -void exynos_dp_set_lanex_pre_emphasis(u8 request_val, - u8 lanecnt); -void exynos_dp_set_training_pattern(unsigned int pattern); -void exynos_dp_enable_enhanced_mode(u8 enable); -void exynos_dp_enable_scrambling(unsigned int enable); -int exynos_dp_init_video(void); -void exynos_dp_config_video_slave_mode(struct edp_video_info *video_info); -void exynos_dp_set_video_color_format(struct edp_video_info *video_info); -int exynos_dp_config_video_bist(struct edp_device_info *edp_info); -unsigned int exynos_dp_is_slave_video_stream_clock_on(void); -void exynos_dp_set_video_cr_mn(unsigned int type, unsigned int m_value, - unsigned int n_value); -void exynos_dp_set_video_timing_mode(unsigned int type); -void exynos_dp_enable_video_master(unsigned int enable); -void exynos_dp_start_video(void); -unsigned int exynos_dp_is_video_stream_on(void); -void exynos_dp_set_base_addr(void); -void dp_phy_control(unsigned int enable); - -#endif diff --git a/src/cpu/samsung/exynos5420/dp_lowlevel.c b/src/cpu/samsung/exynos5420/dp_lowlevel.c deleted file mode 100644 index 2b2418ec21..0000000000 --- a/src/cpu/samsung/exynos5420/dp_lowlevel.c +++ /dev/null @@ -1,1192 +0,0 @@ -/* - * Copyright (C) 2012 Samsung Electronics - * - * Author: Donghwa Lee <dh09.lee@samsung.com> - * - * 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 <delay.h> -#include <stdlib.h> -#include <string.h> -#include <timer.h> -#include <arch/io.h> -#include <console/console.h> -#include "dp.h" -#include "fimd.h" -#include "i2c.h" -#include "power.h" -#include "sysreg.h" -#include "timer.h" - -/* FIXME: I think the DP controller shouldn't be hardcoded here... */ -static struct exynos_dp * const dp_regs = (void *)EXYNOS5_DP1_BASE; - -/* for debugging, it's nice to get control on a per-file basis. - * I had a bit of a discussion with myself (boring!) about - * how to do this and for the moment this is the easiest way. - * These debugging statements allowed me to find the final bugs. - */ - -#if 0 -static inline void fwadl(unsigned long l,void *v) { - writel(l, v); - printk(BIOS_SPEW, "W %p %p\n", v, (void *)l); -} -#define lwrite32(a,b) fwadl((unsigned long)(a), (void *)(b)) - -static inline unsigned long fradl(void *v) { - unsigned long l = readl(v); - printk(BIOS_SPEW, "R %p %p\n", v, (void *)l); - return l; -} - -#define lread32(a) fradl((void *)(a)) -#else -#define lwrite32(a,b) write32((unsigned long)(a), (void *)(b)) -#define lread32(a) read32((void *)(a)) -#endif - -static void exynos_dp_enable_video_input(u32 enable) -{ - u32 reg; - - reg = lread32(&dp_regs->video_ctl1); - reg &= ~VIDEO_EN_MASK; - - /* enable video input*/ - if (enable) - reg |= VIDEO_EN_MASK; - - lwrite32(reg, &dp_regs->video_ctl1); - - return; -} - -void exynos_dp_disable_video_bist(void) -{ - u32 reg; - reg = lread32(&dp_regs->video_ctl4); - reg &= ~VIDEO_BIST_MASK; - lwrite32(reg, &dp_regs->video_ctl4); -} - -void exynos_dp_enable_video_mute(unsigned int enable) -{ - u32 reg; - - reg = lread32(&dp_regs->video_ctl1); - reg &= ~(VIDEO_MUTE_MASK); - if (enable) - reg |= VIDEO_MUTE_MASK; - - lwrite32(reg, &dp_regs->video_ctl1); - - return; -} - - -static void exynos_dp_init_analog_param(void) -{ - u32 reg; - - /* - * Set termination - * Normal bandgap, Normal swing, Tx terminal registor 61 ohm - * 24M Phy clock, TX digital logic power is 100:1.0625V - */ - reg = SEL_BG_NEW_BANDGAP | TX_TERMINAL_CTRL_61_OHM | - SWING_A_30PER_G_NORMAL; - lwrite32(reg, &dp_regs->analog_ctl1); - - reg = SEL_24M | TX_DVDD_BIT_1_0625V; - lwrite32(reg, &dp_regs->analog_ctl2); - - /* - * Set power source for internal clk driver to 1.0625v. - * Select current reference of TX driver current to 00:Ipp/2+Ic/2. - * Set VCO range of PLL +- 0uA - */ - reg = DRIVE_DVDD_BIT_1_0625V | SEL_CURRENT_DEFAULT | VCO_BIT_000_MICRO; - lwrite32(reg, &dp_regs->analog_ctl3); - - /* - * Set AUX TX terminal resistor to 102 ohm - * Set AUX channel amplitude control - */ - reg = PD_RING_OSC | AUX_TERMINAL_CTRL_52_OHM | TX_CUR1_2X | TX_CUR_4_MA; - lwrite32(reg, &dp_regs->pll_filter_ctl1); - - /* - * PLL loop filter bandwidth - * For 2.7Gbps: 175KHz, For 1.62Gbps: 234KHz - * PLL digital power select: 1.2500V - */ - reg = CH3_AMP_0_MV | CH2_AMP_0_MV | CH1_AMP_0_MV | CH0_AMP_0_MV; - - lwrite32(reg, &dp_regs->amp_tuning_ctl); - - /* - * PLL loop filter bandwidth - * For 2.7Gbps: 175KHz, For 1.62Gbps: 234KHz - * PLL digital power select: 1.1250V - */ - reg = DP_PLL_LOOP_BIT_DEFAULT | DP_PLL_REF_BIT_1_1250V; - lwrite32(reg, &dp_regs->pll_ctl); -} - -static void exynos_dp_init_interrupt(void) -{ - /* Set interrupt registers to initial states */ - - /* - * Disable interrupt - * INT pin assertion polarity. It must be configured - * correctly according to ICU setting. - * 1 = assert high, 0 = assert low - */ - lwrite32(INT_POL, &dp_regs->int_ctl); - - /* Clear pending regisers */ - lwrite32(0xff, &dp_regs->common_int_sta1); - lwrite32(0xff, &dp_regs->common_int_sta2); - lwrite32(0xff, &dp_regs->common_int_sta3); - lwrite32(0xff, &dp_regs->common_int_sta4); - lwrite32(0xff, &dp_regs->int_sta); - - /* 0:mask,1: unmask */ - lwrite32(0x00, &dp_regs->int_sta_mask1); - lwrite32(0x00, &dp_regs->int_sta_mask2); - lwrite32(0x00, &dp_regs->int_sta_mask3); - lwrite32(0x00, &dp_regs->int_sta_mask4); - lwrite32(0x00, &dp_regs->int_sta_mask); -} - -void exynos_dp_reset(void) -{ - u32 reg_func_1; - - /*dp tx sw reset*/ - lwrite32(RESET_DP_TX, &dp_regs->tx_sw_reset); - - exynos_dp_enable_video_input(DP_DISABLE); - exynos_dp_disable_video_bist(); - exynos_dp_enable_video_mute(DP_DISABLE); - - /* software reset */ - reg_func_1 = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N | - AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N | - HDCP_FUNC_EN_N | SW_FUNC_EN_N; - - lwrite32(reg_func_1, &dp_regs->func_en1); - lwrite32(reg_func_1, &dp_regs->func_en2); - - mdelay(1); - - exynos_dp_init_analog_param(); - exynos_dp_init_interrupt(); - - return; -} - -void exynos_dp_enable_sw_func(unsigned int enable) -{ - u32 reg; - - reg = lread32(&dp_regs->func_en1); - reg &= ~(SW_FUNC_EN_N); - - if (!enable) - reg |= SW_FUNC_EN_N; - - lwrite32(reg, &dp_regs->func_en1); - - return; -} - -unsigned int exynos_dp_set_analog_power_down(unsigned int block, u32 enable) -{ - u32 reg; - - reg = lread32(&dp_regs->phy_pd); - switch (block) { - case AUX_BLOCK: - reg &= ~(AUX_PD); - if (enable) - reg |= AUX_PD; - break; - case CH0_BLOCK: - reg &= ~(CH0_PD); - if (enable) - reg |= CH0_PD; - break; - case CH1_BLOCK: - reg &= ~(CH1_PD); - if (enable) - reg |= CH1_PD; - break; - case CH2_BLOCK: - reg &= ~(CH2_PD); - if (enable) - reg |= CH2_PD; - break; - case CH3_BLOCK: - reg &= ~(CH3_PD); - if (enable) - reg |= CH3_PD; - break; - case ANALOG_TOTAL: - reg &= ~PHY_PD; - if (enable) - reg |= PHY_PD; - break; - case POWER_ALL: - reg &= ~(PHY_PD | AUX_PD | CH0_PD | CH1_PD | CH2_PD | - CH3_PD); - if (enable) - reg |= (PHY_PD | AUX_PD | CH0_PD | CH1_PD | - CH2_PD | CH3_PD); - break; - default: - printk(BIOS_ERR, "DP undefined block number : %d\n", block); - return -1; - } - - lwrite32(reg, &dp_regs->phy_pd); - - return 0; -} - -unsigned int exynos_dp_get_pll_lock_status(void) -{ - u32 reg; - - reg = lread32(&dp_regs->debug_ctl); - - if (reg & PLL_LOCK) - return PLL_LOCKED; - else - return PLL_UNLOCKED; -} - -static void exynos_dp_set_pll_power(unsigned int enable) -{ - u32 reg; - - reg = lread32(&dp_regs->pll_ctl); - reg &= ~(DP_PLL_PD); - - if (!enable) - reg |= DP_PLL_PD; - - lwrite32(reg, &dp_regs->pll_ctl); -} - -int exynos_dp_init_analog_func(void) -{ - int ret = EXYNOS_DP_SUCCESS; - unsigned int retry_cnt = 10; - u32 reg; - - /*Power On All Analog block */ - exynos_dp_set_analog_power_down(POWER_ALL, DP_DISABLE); - - reg = PLL_LOCK_CHG; - lwrite32(reg, &dp_regs->common_int_sta1); - - reg = lread32(&dp_regs->debug_ctl); - reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL); - lwrite32(reg, &dp_regs->debug_ctl); - - /*Assert DP PLL Reset*/ - reg = lread32(&dp_regs->pll_ctl); - reg |= DP_PLL_RESET; - lwrite32(reg, &dp_regs->pll_ctl); - - mdelay(1); - - /*Deassert DP PLL Reset*/ - reg = lread32(&dp_regs->pll_ctl); - reg &= ~(DP_PLL_RESET); - lwrite32(reg, &dp_regs->pll_ctl); - - exynos_dp_set_pll_power(DP_ENABLE); - - while (exynos_dp_get_pll_lock_status() == PLL_UNLOCKED) { - mdelay(1); - retry_cnt--; - if (retry_cnt == 0) { - printk(BIOS_ERR, "DP dp's pll lock failed : retry : %d\n", - retry_cnt); - return -1; - } - } - - printk(BIOS_DEBUG, "dp's pll lock success(%d)\n", retry_cnt); - - /* Enable Serdes FIFO function and Link symbol clock domain module */ - reg = lread32(&dp_regs->func_en2); - reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N - | AUX_FUNC_EN_N); - lwrite32(reg, &dp_regs->func_en2); - - return ret; -} - -void exynos_dp_init_hpd(void) -{ - u32 reg; - - /* Clear interrupts releated to Hot Plug Dectect */ - reg = HOTPLUG_CHG | HPD_LOST | PLUG; - lwrite32(reg, &dp_regs->common_int_sta4); - - reg = INT_HPD; - lwrite32(reg, &dp_regs->int_sta); - - reg = lread32(&dp_regs->sys_ctl3); - reg &= ~(F_HPD | HPD_CTRL); - lwrite32(reg, &dp_regs->sys_ctl3); - - return; -} - -static inline void exynos_dp_reset_aux(void) -{ - u32 reg; - - /* Disable AUX channel module */ - reg = lread32(&dp_regs->func_en2); - reg |= AUX_FUNC_EN_N; - lwrite32(reg, &dp_regs->func_en2); - - return; -} - -void exynos_dp_init_aux(void) -{ - u32 reg; - - /* Clear inerrupts related to AUX channel */ - reg = RPLY_RECEIV | AUX_ERR; - lwrite32(reg, &dp_regs->int_sta); - - exynos_dp_reset_aux(); - - /* Disable AUX transaction H/W retry */ - reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(3)| - AUX_HW_RETRY_INTERVAL_600_MICROSECONDS; - lwrite32(reg, &dp_regs->aux_hw_retry_ctl); - - /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */ - reg = DEFER_CTRL_EN | DEFER_COUNT(1); - lwrite32(reg, &dp_regs->aux_ch_defer_ctl); - - /* Enable AUX channel module */ - reg = lread32(&dp_regs->func_en2); - reg &= ~AUX_FUNC_EN_N; - lwrite32(reg, &dp_regs->func_en2); - - return; -} - -void exynos_dp_config_interrupt(void) -{ - u32 reg; - - /* 0: mask, 1: unmask */ - reg = COMMON_INT_MASK_1; - lwrite32(reg, &dp_regs->common_int_mask1); - - reg = COMMON_INT_MASK_2; - lwrite32(reg, &dp_regs->common_int_mask2); - - reg = COMMON_INT_MASK_3; - lwrite32(reg, &dp_regs->common_int_mask3); - - reg = COMMON_INT_MASK_4; - lwrite32(reg, &dp_regs->common_int_mask4); - - reg = INT_STA_MASK; - lwrite32(reg, &dp_regs->int_sta_mask); - - return; -} - -unsigned int exynos_dp_get_plug_in_status(void) -{ - u32 reg; - - reg = lread32(&dp_regs->sys_ctl3); - if (reg & HPD_STATUS) - return 0; - - return -1; -} - -unsigned int exynos_dp_detect_hpd(void) -{ - int timeout_loop = DP_TIMEOUT_LOOP_COUNT; - - mdelay(2); - - while (exynos_dp_get_plug_in_status() != 0) { - if (timeout_loop == 0) - return -1; - mdelay(1); - timeout_loop--; - } - - return EXYNOS_DP_SUCCESS; -} - -unsigned int exynos_dp_start_aux_transaction(void) -{ - u32 reg; - unsigned int ret = 0; - unsigned int retry_cnt; - - /* Enable AUX CH operation */ - reg = lread32(&dp_regs->aux_ch_ctl2); - reg |= AUX_EN; - lwrite32(reg, &dp_regs->aux_ch_ctl2); - - retry_cnt = 10; - while (retry_cnt) { - reg = lread32(&dp_regs->int_sta); - if (!(reg & RPLY_RECEIV)) { - if (retry_cnt == 0) { - printk(BIOS_ERR, "DP Reply Timeout!!\n"); - ret = -1; - return ret; - } - mdelay(1); - retry_cnt--; - } else - break; - } - - /* Clear interrupt source for AUX CH command reply */ - lwrite32(reg, &dp_regs->int_sta); - - /* Clear interrupt source for AUX CH access error */ - reg = lread32(&dp_regs->int_sta); - if (reg & AUX_ERR) { - printk(BIOS_ERR, "DP Aux Access Error\n"); - lwrite32(AUX_ERR, &dp_regs->int_sta); - ret = -1; - return ret; - } - - /* Check AUX CH error access status */ - reg = lread32(&dp_regs->aux_ch_sta); - if ((reg & AUX_STATUS_MASK) != 0) { - printk(BIOS_DEBUG, "DP AUX CH error happens: %x\n", reg & AUX_STATUS_MASK); - ret = -1; - return ret; - } - return EXYNOS_DP_SUCCESS; -} - -unsigned int exynos_dp_write_byte_to_dpcd(u32 reg_addr, u8 data) -{ - u32 reg; - unsigned int ret; - - /* Clear AUX CH data buffer */ - reg = BUF_CLR; - lwrite32(reg, &dp_regs->buffer_data_ctl); - - /* Select DPCD device address */ - reg = AUX_ADDR_7_0(reg_addr); - lwrite32(reg, &dp_regs->aux_addr_7_0); - reg = AUX_ADDR_15_8(reg_addr); - lwrite32(reg, &dp_regs->aux_addr_15_8); - reg = AUX_ADDR_19_16(reg_addr); - lwrite32(reg, &dp_regs->aux_addr_19_16); - - /* Write data buffer */ - reg = data; - lwrite32(reg, &dp_regs->buf_data0); - - /* - * Set DisplayPort transaction and write 1 byte - * If bit 3 is 1, DisplayPort transaction. - * If Bit 3 is 0, I2C transaction. - */ - reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; - lwrite32(reg, &dp_regs->aux_ch_ctl1); - - /* Start AUX transaction */ - ret = exynos_dp_start_aux_transaction(); - if (ret != EXYNOS_DP_SUCCESS) { - printk(BIOS_ERR, "DP Aux transaction failed\n"); - } - - return ret; -} - -unsigned int exynos_dp_read_byte_from_dpcd(u32 reg_addr, - unsigned char *data) -{ - u32 reg; - int retval; - - /* Clear AUX CH data buffer */ - reg = BUF_CLR; - lwrite32(reg, &dp_regs->buffer_data_ctl); - - /* Select DPCD device address */ - reg = AUX_ADDR_7_0(reg_addr); - lwrite32(reg, &dp_regs->aux_addr_7_0); - reg = AUX_ADDR_15_8(reg_addr); - lwrite32(reg, &dp_regs->aux_addr_15_8); - reg = AUX_ADDR_19_16(reg_addr); - lwrite32(reg, &dp_regs->aux_addr_19_16); - - /* - * Set DisplayPort transaction and read 1 byte - * If bit 3 is 1, DisplayPort transaction. - * If Bit 3 is 0, I2C transaction. - */ - reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; - lwrite32(reg, &dp_regs->aux_ch_ctl1); - - /* Start AUX transaction */ - retval = exynos_dp_start_aux_transaction(); - if (retval != EXYNOS_DP_SUCCESS) - printk(BIOS_DEBUG, "DP Aux Transaction fail!\n"); - - /* Read data buffer */ - reg = lread32(&dp_regs->buf_data0); - *data = (unsigned char)(reg & 0xff); - - return retval; -} - -unsigned int exynos_dp_write_bytes_to_dpcd(u32 reg_addr, - unsigned int count, - unsigned char data[]) -{ - u32 reg; - unsigned int start_offset; - unsigned int cur_data_count; - unsigned int cur_data_idx; - unsigned int retry_cnt; - unsigned int ret = 0; - - /* Clear AUX CH data buffer */ - reg = BUF_CLR; - lwrite32(reg, &dp_regs->buffer_data_ctl); - - start_offset = 0; - while (start_offset < count) { - /* Buffer size of AUX CH is 16 * 4bytes */ - if ((count - start_offset) > 16) - cur_data_count = 16; - else - cur_data_count = count - start_offset; - - retry_cnt = 5; - while (retry_cnt) { - /* Select DPCD device address */ - reg = AUX_ADDR_7_0(reg_addr + start_offset); - lwrite32(reg, &dp_regs->aux_addr_7_0); - reg = AUX_ADDR_15_8(reg_addr + start_offset); - lwrite32(reg, &dp_regs->aux_addr_15_8); - reg = AUX_ADDR_19_16(reg_addr + start_offset); - lwrite32(reg, &dp_regs->aux_addr_19_16); - - for (cur_data_idx = 0; cur_data_idx < cur_data_count; - cur_data_idx++) { - reg = data[start_offset + cur_data_idx]; - lwrite32(reg, (void *)((unsigned int)&dp_regs->buf_data0 + - (4 * cur_data_idx))); - } - /* - * Set DisplayPort transaction and write - * If bit 3 is 1, DisplayPort transaction. - * If Bit 3 is 0, I2C transaction. - */ - reg = AUX_LENGTH(cur_data_count) | - AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; - lwrite32(reg, &dp_regs->aux_ch_ctl1); - - /* Start AUX transaction */ - ret = exynos_dp_start_aux_transaction(); - if (ret != EXYNOS_DP_SUCCESS) { - if (retry_cnt == 0) { - printk(BIOS_ERR, "DP Aux Transaction failed\n"); - return ret; - } - retry_cnt--; - } else - break; - } - start_offset += cur_data_count; - } - - return ret; -} - -unsigned int exynos_dp_read_bytes_from_dpcd(u32 reg_addr, - unsigned int count, - unsigned char data[]) -{ - u32 reg; - unsigned int start_offset; - unsigned int cur_data_count; - unsigned int cur_data_idx; - unsigned int retry_cnt; - unsigned int ret = 0; - - /* Clear AUX CH data buffer */ - reg = BUF_CLR; - lwrite32(reg, &dp_regs->buffer_data_ctl); - - start_offset = 0; - while (start_offset < count) { - /* Buffer size of AUX CH is 16 * 4bytes */ - if ((count - start_offset) > 16) - cur_data_count = 16; - else - cur_data_count = count - start_offset; - - retry_cnt = 5; - while (retry_cnt) { - /* Select DPCD device address */ - reg = AUX_ADDR_7_0(reg_addr + start_offset); - lwrite32(reg, &dp_regs->aux_addr_7_0); - reg = AUX_ADDR_15_8(reg_addr + start_offset); - lwrite32(reg, &dp_regs->aux_addr_15_8); - reg = AUX_ADDR_19_16(reg_addr + start_offset); - lwrite32(reg, &dp_regs->aux_addr_19_16); - /* - * Set DisplayPort transaction and read - * If bit 3 is 1, DisplayPort transaction. - * If Bit 3 is 0, I2C transaction. - */ - reg = AUX_LENGTH(cur_data_count) | - AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; - lwrite32(reg, &dp_regs->aux_ch_ctl1); - - /* Start AUX transaction */ - ret = exynos_dp_start_aux_transaction(); - if (ret != EXYNOS_DP_SUCCESS) { - if (retry_cnt == 0) { - printk(BIOS_ERR, "DP Aux Transaction failed\n"); - return ret; - } - retry_cnt--; - } else - break; - } - - for (cur_data_idx = 0; cur_data_idx < cur_data_count; - cur_data_idx++) { - reg = lread32((void *)((u32)&dp_regs->buf_data0 + - 4 * cur_data_idx)); - data[start_offset + cur_data_idx] = (unsigned char)reg; - } - - start_offset += cur_data_count; - } - - return ret; -} - -int exynos_dp_select_i2c_device(u32 device_addr, - u32 reg_addr) -{ - u32 reg; - int retval; - - /* Set EDID device address */ - reg = device_addr; - lwrite32(reg, &dp_regs->aux_addr_7_0); - lwrite32(0x0, &dp_regs->aux_addr_15_8); - lwrite32(0x0, &dp_regs->aux_addr_19_16); - - /* Set offset from base address of EDID device */ - lwrite32(reg_addr, &dp_regs->buf_data0); - - /* - * Set I2C transaction and write address - * If bit 3 is 1, DisplayPort transaction. - * If Bit 3 is 0, I2C transaction. - */ - reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT | - AUX_TX_COMM_WRITE; - lwrite32(reg, &dp_regs->aux_ch_ctl1); - - /* Start AUX transaction */ - retval = exynos_dp_start_aux_transaction(); - if (retval != 0) - printk(BIOS_DEBUG, "%s: DP Aux Transaction fail!\n", __func__); - - return retval; -} - -int exynos_dp_read_byte_from_i2c(u32 device_addr, - u32 reg_addr, - unsigned int *data) -{ - u32 reg; - int i; - int retval; - - for (i = 0; i < 10; i++) { - /* Clear AUX CH data buffer */ - reg = BUF_CLR; - lwrite32(reg, &dp_regs->buffer_data_ctl); - - /* Select EDID device */ - retval = exynos_dp_select_i2c_device(device_addr, reg_addr); - if (retval != 0) { - printk(BIOS_DEBUG, "DP Select EDID device fail. retry !\n"); - continue; - } - - /* - * Set I2C transaction and read data - * If bit 3 is 1, DisplayPort transaction. - * If Bit 3 is 0, I2C transaction. - */ - reg = AUX_TX_COMM_I2C_TRANSACTION | - AUX_TX_COMM_READ; - lwrite32(reg, &dp_regs->aux_ch_ctl1); - - /* Start AUX transaction */ - retval = exynos_dp_start_aux_transaction(); - if (retval != EXYNOS_DP_SUCCESS) - printk(BIOS_DEBUG, "%s: DP Aux Transaction fail!\n", __func__); - } - - /* Read data */ - if (retval == 0) - *data = lread32(&dp_regs->buf_data0); - - return retval; -} - -int exynos_dp_read_bytes_from_i2c(u32 device_addr, - u32 reg_addr, unsigned int count, unsigned char edid[]) -{ - u32 reg; - unsigned int i, j; - unsigned int cur_data_idx; - unsigned int defer = 0; - int retval = 0; - - for (i = 0; i < count; i += 16) { /* use 16 burst */ - for (j = 0; j < 100; j++) { - /* Clear AUX CH data buffer */ - reg = BUF_CLR; - lwrite32(reg, &dp_regs->buffer_data_ctl); - - /* Set normal AUX CH command */ - reg = lread32(&dp_regs->aux_ch_ctl2); - reg &= ~ADDR_ONLY; - lwrite32(reg, &dp_regs->aux_ch_ctl2); - - /* - * If Rx sends defer, Tx sends only reads - * request without sending addres - */ - if (!defer) - retval = - exynos_dp_select_i2c_device(device_addr, - reg_addr + i); - else - defer = 0; - - if (retval == EXYNOS_DP_SUCCESS) { - /* - * Set I2C transaction and write data - * If bit 3 is 1, DisplayPort transaction. - * If Bit 3 is 0, I2C transaction. - */ - reg = AUX_LENGTH(16) | - AUX_TX_COMM_I2C_TRANSACTION | - AUX_TX_COMM_READ; - lwrite32(reg, &dp_regs->aux_ch_ctl1); - - /* Start AUX transaction */ - retval = exynos_dp_start_aux_transaction(); - if (retval == 0) - break; - else - printk(BIOS_ERR, "DP Aux Transaction fail!\n"); - } - /* Check if Rx sends defer */ - reg = lread32(&dp_regs->aux_rx_comm); - if (reg == AUX_RX_COMM_AUX_DEFER || - reg == AUX_RX_COMM_I2C_DEFER) { - printk(BIOS_ERR, "DP Defer: %d\n\n", reg); - defer = 1; - } - } - - for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) { - reg = lread32((void *)((u32)&dp_regs->buf_data0 - + 4 * cur_data_idx)); - edid[i + cur_data_idx] = (unsigned char)reg; - } - } - - return retval; -} - -void exynos_dp_reset_macro(void) -{ - u32 reg; - - reg = lread32(&dp_regs->phy_test); - reg |= MACRO_RST; - lwrite32(reg, &dp_regs->phy_test); - - /* 10 us is the minimum Macro reset time. */ - udelay(50); - - reg &= ~MACRO_RST; - lwrite32(reg, &dp_regs->phy_test); -} - -void exynos_dp_set_link_bandwidth(unsigned char bwtype) -{ - u32 reg; - - reg = (u32)bwtype; - - /* Set bandwidth to 2.7G or 1.62G */ - if ((bwtype == DP_LANE_BW_1_62) || (bwtype == DP_LANE_BW_2_70)) - lwrite32(reg, &dp_regs->link_bw_set); -} - -unsigned char exynos_dp_get_link_bandwidth(void) -{ - unsigned char ret; - u32 reg; - - reg = lread32(&dp_regs->link_bw_set); - ret = (unsigned char)reg; - - return ret; -} - -void exynos_dp_set_lane_count(unsigned char count) -{ - u32 reg; - - reg = (u32)count; - - if ((count == DP_LANE_CNT_1) || (count == DP_LANE_CNT_2) || - (count == DP_LANE_CNT_4)) - lwrite32(reg, &dp_regs->lane_count_set); -} - -unsigned int exynos_dp_get_lane_count(void) -{ - u32 reg; - - reg = lread32(&dp_regs->lane_count_set); - - return reg; -} - -unsigned char exynos_dp_get_lanex_pre_emphasis(unsigned char lanecnt) -{ - void *reg_list[DP_LANE_CNT_4] = { - &dp_regs->ln0_link_training_ctl, - &dp_regs->ln1_link_training_ctl, - &dp_regs->ln2_link_training_ctl, - &dp_regs->ln3_link_training_ctl, - }; - - return lread32(reg_list[lanecnt]); -} - -void exynos_dp_set_lanex_pre_emphasis(unsigned char request_val, - unsigned char lanecnt) -{ - void * reg_list[DP_LANE_CNT_4] = { - &dp_regs->ln0_link_training_ctl, - &dp_regs->ln1_link_training_ctl, - &dp_regs->ln2_link_training_ctl, - &dp_regs->ln3_link_training_ctl, - }; - - lwrite32(request_val, reg_list[lanecnt]); -} - -void exynos_dp_set_lane_pre_emphasis(unsigned int level, unsigned char lanecnt) -{ - unsigned char i; - u32 reg; - void *reg_list[DP_LANE_CNT_4] = { - &dp_regs->ln0_link_training_ctl, - &dp_regs->ln1_link_training_ctl, - &dp_regs->ln2_link_training_ctl, - &dp_regs->ln3_link_training_ctl, - }; - u32 reg_shift[DP_LANE_CNT_4] = { - PRE_EMPHASIS_SET_0_SHIFT, - PRE_EMPHASIS_SET_1_SHIFT, - PRE_EMPHASIS_SET_2_SHIFT, - PRE_EMPHASIS_SET_3_SHIFT - }; - - for (i = 0; i < lanecnt; i++) { - reg = level << reg_shift[i]; - lwrite32(reg, reg_list[i]); - } -} - -void exynos_dp_set_training_pattern(unsigned int pattern) -{ - u32 reg = 0; - - switch (pattern) { - case PRBS7: - reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7; - break; - case D10_2: - reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2; - break; - case TRAINING_PTN1: - reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1; - break; - case TRAINING_PTN2: - reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2; - break; - case DP_NONE: - reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_DISABLE | - SW_TRAINING_PATTERN_SET_NORMAL; - break; - default: - break; - } - - lwrite32(reg, &dp_regs->training_ptn_set); -} - -void exynos_dp_enable_enhanced_mode(unsigned char enable) -{ - u32 reg; - - reg = lread32(&dp_regs->sys_ctl4); - reg &= ~ENHANCED; - - if (enable) - reg |= ENHANCED; - - lwrite32(reg, &dp_regs->sys_ctl4); -} - -void exynos_dp_enable_scrambling(unsigned int enable) -{ - u32 reg; - - reg = lread32(&dp_regs->training_ptn_set); - reg &= ~(SCRAMBLING_DISABLE); - - if (!enable) - reg |= SCRAMBLING_DISABLE; - - lwrite32(reg, &dp_regs->training_ptn_set); -} -int exynos_dp_init_video(void) -{ - unsigned int reg; - - /* Clear VID_CLK_CHG[1] and VID_FORMAT_CHG[3] and VSYNC_DET[7] */ - reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG; - lwrite32(reg, &dp_regs->common_int_sta1); - - /* I_STRM__CLK detect : DE_CTL : Auto detect */ - reg &= ~DET_CTRL; - lwrite32(reg, &dp_regs->sys_ctl1); - return 0; -} - - -void exynos_dp_config_video_slave_mode(struct edp_video_info *video_info) -{ - u32 reg; - - /* Video Slave mode setting */ - reg = lread32(&dp_regs->func_en1); - reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N); - reg |= MASTER_VID_FUNC_EN_N; - lwrite32(reg, &dp_regs->func_en1); - - /* Configure Interlaced for slave mode video */ - reg = lread32(&dp_regs->video_ctl10); - reg &= ~INTERACE_SCAN_CFG; - reg |= (video_info->interlaced << INTERACE_SCAN_CFG_SHIFT); - printk(BIOS_SPEW, "interlaced %d\n", video_info->interlaced); - lwrite32(reg, &dp_regs->video_ctl10); - - /* Configure V sync polarity for slave mode video */ - reg = lread32(&dp_regs->video_ctl10); - reg &= ~VSYNC_POLARITY_CFG; - reg |= (video_info->v_sync_polarity << V_S_POLARITY_CFG_SHIFT); - lwrite32(reg, &dp_regs->video_ctl10); - - /* Configure H sync polarity for slave mode video */ - reg = lread32(&dp_regs->video_ctl10); - reg &= ~HSYNC_POLARITY_CFG; - reg |= (video_info->h_sync_polarity << H_S_POLARITY_CFG_SHIFT); - lwrite32(reg, &dp_regs->video_ctl10); - - /*Set video mode to slave mode */ - reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE; - lwrite32(reg, &dp_regs->soc_general_ctl); -} - -void exynos_dp_set_video_color_format(struct edp_video_info *video_info) -{ - u32 reg; - - /* Configure the input color depth, color space, dynamic range */ - reg = (video_info->dynamic_range << IN_D_RANGE_SHIFT) | - (video_info->color_depth << IN_BPC_SHIFT) | - (video_info->color_space << IN_COLOR_F_SHIFT); - lwrite32(reg, &dp_regs->video_ctl2); - - /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */ - reg = lread32(&dp_regs->video_ctl3); - reg &= ~IN_YC_COEFFI_MASK; - if (video_info->ycbcr_coeff) - reg |= IN_YC_COEFFI_ITU709; - else - reg |= IN_YC_COEFFI_ITU601; - lwrite32(reg, &dp_regs->video_ctl3); -} - -unsigned int exynos_dp_is_slave_video_stream_clock_on(void) -{ - u32 reg; - - /* Update Video stream clk detect status */ - reg = lread32(&dp_regs->sys_ctl1); - lwrite32(reg, &dp_regs->sys_ctl1); - - reg = lread32(&dp_regs->sys_ctl1); - - if (!(reg & DET_STA)) { - printk(BIOS_DEBUG, "DP Input stream clock not detected.\n"); - return -1; - } - - return EXYNOS_DP_SUCCESS; -} - -void exynos_dp_set_video_cr_mn(unsigned int type, unsigned int m_value, - unsigned int n_value) -{ - u32 reg; - - if (type == REGISTER_M) { - reg = lread32(&dp_regs->sys_ctl4); - reg |= FIX_M_VID; - lwrite32(reg, &dp_regs->sys_ctl4); - reg = M_VID0_CFG(m_value); - lwrite32(reg, &dp_regs->m_vid0); - reg = M_VID1_CFG(m_value); - lwrite32(reg, &dp_regs->m_vid1); - reg = M_VID2_CFG(m_value); - lwrite32(reg, &dp_regs->m_vid2); - - reg = N_VID0_CFG(n_value); - lwrite32(reg, &dp_regs->n_vid0); - reg = N_VID1_CFG(n_value); - lwrite32(reg, &dp_regs->n_vid1); - reg = N_VID2_CFG(n_value); - lwrite32(reg, &dp_regs->n_vid2); - } else { - reg = lread32(&dp_regs->sys_ctl4); - reg &= ~FIX_M_VID; - lwrite32(reg, &dp_regs->sys_ctl4); - } -} - -void exynos_dp_set_video_timing_mode(unsigned int type) -{ - u32 reg; - - reg = lread32(&dp_regs->video_ctl10); - reg &= ~FORMAT_SEL; - - if (type != VIDEO_TIMING_FROM_CAPTURE) - reg |= FORMAT_SEL; - - lwrite32(reg, &dp_regs->video_ctl10); -} - -void exynos_dp_enable_video_master(unsigned int enable) -{ - u32 reg; - - reg = lread32(&dp_regs->soc_general_ctl); - if (enable) { - reg &= ~VIDEO_MODE_MASK; - reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE; - } else { - reg &= ~VIDEO_MODE_MASK; - reg |= VIDEO_MODE_SLAVE_MODE; - } - - lwrite32(reg, &dp_regs->soc_general_ctl); -} - -void exynos_dp_start_video(void) -{ - u32 reg; - - /* Enable Video input and disable Mute */ - reg = lread32(&dp_regs->video_ctl1); - reg |= VIDEO_EN; - lwrite32(reg, &dp_regs->video_ctl1); -} - -unsigned int exynos_dp_is_video_stream_on(void) -{ - u32 reg; - - /* Update STRM_VALID */ - reg = lread32(&dp_regs->sys_ctl3); - lwrite32(reg, &dp_regs->sys_ctl3); - - reg = lread32(&dp_regs->sys_ctl3); - - if (!(reg & STRM_VALID)) - return -1; - - return EXYNOS_DP_SUCCESS; -} - -void dp_phy_control(unsigned int enable) -{ - u32 cfg; - - cfg = lread32(&exynos_power->dptx_phy_control); - if (enable) - cfg |= EXYNOS_DP_PHY_ENABLE; - else - cfg &= ~EXYNOS_DP_PHY_ENABLE; - lwrite32(cfg, &exynos_power->dptx_phy_control); -} diff --git a/src/cpu/samsung/exynos5420/dsim.h b/src/cpu/samsung/exynos5420/dsim.h deleted file mode 100644 index 25015a26ad..0000000000 --- a/src/cpu/samsung/exynos5420/dsim.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Register map for Exynos5 MIPI-DSIM */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_DSIM_H -#define CPU_SAMSUNG_EXYNOS5420_DSIM_H - -/* DSIM register map */ -struct exynos5_dsim { - unsigned int status; - unsigned int swrst; - unsigned int clkctrl; - unsigned int timeout; - unsigned int config; - unsigned int escmode; - unsigned int mdresol; - unsigned int mvporch; - unsigned int mhporch; - unsigned int msync; - unsigned int sdresol; - unsigned int intsrc; - unsigned int intmsk; - unsigned int pkthdr; - unsigned int payload; - unsigned int rxfifo; - unsigned int res1; - unsigned int fifoctrl; - unsigned int res2; - unsigned int pllctrl; - unsigned int plltmr; - unsigned int phyacchr; - unsigned int phyacchr1; -}; - -#define ENABLE 1 -#define DISABLE 0 - -#define DSIM_SWRST (1 << 0) -#define NUM_OF_DAT_LANE_IS_FOUR (3 << 5) -#define DATA_LANE_0_EN (1 << 0) -#define DATA_LANE_1_EN (1 << 1) -#define DATA_LANE_2_EN (1 << 2) -#define DATA_LANE_3_EN (1 << 3) -#define CLK_LANE_EN (1 << 4) -#define ENABLE_ALL_DATA_LANE DATA_LANE_0_EN | \ - DATA_LANE_1_EN | \ - DATA_LANE_2_EN | \ - DATA_LANE_3_EN -#define MAIN_PIX_FORMAT_OFFSET 12 -#define RGB_565_16_BIT 0x4 -#define VIDEO_MODE (1 << 25) -#define BURST_MODE (1 << 26) - - -#define DSIM_PHYACCHR_AFC_EN (1 << 14) -#define DSIM_PHYACCHR_AFC_CTL_OFFSET 5 - -#define DSIM_PLLCTRL_PMS_OFFSET 1 -#define DSIM_FREQ_BAND_OFFSET 24 - -#define LANE_ESC_CLK_EN_ALL (0x1f << 19) -#define BYTE_CLK_EN (1 << 24) -#define DSIM_ESC_CLK_EN (1 << 28) -#define TXREQUEST_HS_CLK_ON (1 << 31) - -#define LP_MODE_ENABLE (1 << 7) -#define STOP_STATE_CNT_OFFSET 21 - -#define MAIN_VBP_OFFSET 0 -#define STABLE_VFP_OFFSET 16 -#define CMD_ALLOW_OFFSET 28 - -#define MAIN_HBP_OFFSET 0 -#define MAIN_HFP_OFFSET 16 - -#define MAIN_HSA_OFFSET 0 -#define MAIN_VSA_OFFSET 22 - -#define MAIN_STANDBY (1 << 31) -#define MAIN_VRESOL_OFFSET 16 -#define MAIN_HRESOL_OFFSET 0 - -#define SFR_FIFO_EMPTY (1 << 29) - -#define DSIM_PLL_EN_SHIFT (1 << 23) -#define PLL_STABLE (1 << 31) - -#define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0) -#define DSIM_STOP_STATE_CLK (1 << 8) -#define DSIM_TX_READY_HS_CLK (1 << 10) - -#endif diff --git a/src/cpu/samsung/exynos5420/fimd.c b/src/cpu/samsung/exynos5420/fimd.c deleted file mode 100644 index 1e51712e53..0000000000 --- a/src/cpu/samsung/exynos5420/fimd.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * Copyright (C) 2012 Samsung Electronics - * - * Author: InKi Dae <inki.dae@samsung.com> - * Author: Donghwa Lee <dh09.lee@samsung.com> - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <delay.h> -#include <arch/io.h> -#include <console/console.h> -#include "clk.h" -#include "dp.h" -#include "fimd.h" -#include "periph.h" -#include "sysreg.h" -#include "timer.h" - -/* fairly useful debugging stuff. */ -#if 0 -static inline void fwadl(unsigned long l,void *v) { - writel(l, v); - printk(BIOS_SPEW, "W %p %p\n", v, (void *)l); -} -#define lwritel(a,b) fwadl((unsigned long)(a), (void *)(b)) - -static inline unsigned long fradl(void *v) { - unsigned long l = readl(v); - printk(BIOS_SPEW, "R %p %p\n", v, (void *)l); - return l; -} - -#define lreadl(a) fradl((void *)(a)) - -#else -#define lwritel(a,b) writel((unsigned long)(a), (void *)(b)) -#define lreadl(a) readl((void *)(a)) -#endif - -/* not sure where we want this so ... */ -static unsigned long get_lcd_clk(void) -{ - u32 pclk, sclk; - unsigned int sel; - unsigned int ratio; - - /* - * CLK_SRC_DISP10 - * CLKMUX_FIMD1 [4] - * 0: SCLK_RPLL - * 1: SCLK_SPLL - */ - sel = lreadl(&exynos_clock->clk_src_disp10); - sel &= (1 << 4); - - if (sel){ - sclk = get_pll_clk(SPLL); - } else { - sclk = get_pll_clk(RPLL); - } - - /* - * CLK_DIV_DISP10 - * FIMD1_RATIO [3:0] - */ - ratio = lreadl(&exynos_clock->clk_div_disp10); - ratio = ratio & 0xf; - - pclk = sclk / (ratio + 1); - - return pclk; -} - -static void exynos_fimd_set_dualrgb(vidinfo_t *vid, unsigned int enabled) -{ - unsigned int cfg = 0; - printk(BIOS_SPEW, "%s %s\n", __func__, enabled ? "enabled" : "not enabled"); - if (enabled) { - cfg = EXYNOS_DUALRGB_BYPASS_DUAL | EXYNOS_DUALRGB_LINESPLIT | - EXYNOS_DUALRGB_VDEN_EN_ENABLE; - - /* in case of Line Split mode, MAIN_CNT doesn't neet to set. */ - cfg |= EXYNOS_DUALRGB_SUB_CNT(vid->vl_col / 2) | - EXYNOS_DUALRGB_MAIN_CNT(0); - } - - lwritel(cfg, &FIMD_CTRL->dualrgb); -} - -static void exynos_fimd_set_dp_clkcon(unsigned int enabled) -{ - unsigned int cfg = 0; - - if (enabled){ - cfg = EXYNOS_DP_CLK_ENABLE; - } - - lwritel(cfg, &FIMD_CTRL->dp_mie_clkcon); -} - -static void exynos_fimd_set_par(vidinfo_t *vid, unsigned int win_id) -{ - unsigned int cfg = 0; - printk(BIOS_SPEW, "%s %d\n", __func__, win_id); - /* set window control */ - cfg = lreadl(&FIMD_CTRL->wincon0 + - EXYNOS_WINCON(win_id)); - - cfg &= ~(EXYNOS_WINCON_BITSWP_ENABLE | EXYNOS_WINCON_BYTESWP_ENABLE | - EXYNOS_WINCON_HAWSWP_ENABLE | EXYNOS_WINCON_WSWP_ENABLE | - EXYNOS_WINCON_BURSTLEN_MASK | EXYNOS_WINCON_BPPMODE_MASK | - EXYNOS_WINCON_INRGB_MASK | EXYNOS_WINCON_DATAPATH_MASK); - - /* DATAPATH is DMA */ - cfg |= EXYNOS_WINCON_DATAPATH_DMA; - - cfg |= EXYNOS_WINCON_HAWSWP_ENABLE; - - /* dma burst is 16 */ - cfg |= EXYNOS_WINCON_BURSTLEN_16WORD; - - cfg |= EXYNOS_WINCON_BPPMODE_16BPP_565; - - lwritel(cfg, &FIMD_CTRL->wincon0 + - EXYNOS_WINCON(win_id)); - - /* set window position to x=0, y=0*/ - cfg = EXYNOS_VIDOSD_LEFT_X(0) | EXYNOS_VIDOSD_TOP_Y(0); - lwritel(cfg, &FIMD_CTRL->vidosd0a + - EXYNOS_VIDOSD(win_id)); - - cfg = EXYNOS_VIDOSD_RIGHT_X(vid->vl_col - 1) | - EXYNOS_VIDOSD_BOTTOM_Y(vid->vl_row - 1) | - EXYNOS_VIDOSD_RIGHT_X_E(1) | - EXYNOS_VIDOSD_BOTTOM_Y_E(0); - - lwritel(cfg, &FIMD_CTRL->vidosd0b + - EXYNOS_VIDOSD(win_id)); - /* set window size for window0*/ - cfg = EXYNOS_VIDOSD_SIZE(vid->vl_col * vid->vl_row); - lwritel(cfg, &FIMD_CTRL->vidosd0c + - EXYNOS_VIDOSD(win_id)); -} - -static void exynos_fimd_set_buffer_address(vidinfo_t *vid, - void *screen_base, int win_id) -{ - u32 start_addr, end_addr; - printk(BIOS_SPEW, "%s %d\n", __func__, win_id); - start_addr = (u32)screen_base; - end_addr = start_addr + ((vid->vl_col * ((1<<vid->vl_bpix) / 8)) * - vid->vl_row); - - lwritel(start_addr, &FIMD_CTRL->vidw00add0b0 + - EXYNOS_BUFFER_OFFSET(win_id)); - lwritel(end_addr, &FIMD_CTRL->vidw00add1b0 + - EXYNOS_BUFFER_OFFSET(win_id)); -} - -static void exynos_fimd_set_clock(vidinfo_t *vid) -{ - unsigned int cfg = 0, div = 0, remainder = 0, remainder_div; - unsigned long pixel_clock; - unsigned long long src_clock; - printk(BIOS_SPEW, "%s\n", __func__); - if (vid->dual_lcd_enabled) { - pixel_clock = vid->vl_freq * - (vid->vl_hspw + vid->vl_hfpd + - vid->vl_hbpd + vid->vl_col / 2) * - (vid->vl_vspw + vid->vl_vfpd + - vid->vl_vbpd + vid->vl_row); - } else if (vid->interface_mode == FIMD_CPU_INTERFACE) { - pixel_clock = vid->vl_freq * - vid->vl_width * vid->vl_height * - (vid->cs_setup + vid->wr_setup + - vid->wr_act + vid->wr_hold + 1); - } else { - pixel_clock = vid->vl_freq * - (vid->vl_hspw + vid->vl_hfpd + - vid->vl_hbpd + vid->vl_col) * - (vid->vl_vspw + vid->vl_vfpd + - vid->vl_vbpd + vid->vl_row); - } - printk(BIOS_SPEW, "Pixel clock is %lx\n", pixel_clock); - - cfg = lreadl(&FIMD_CTRL->vidcon0); - cfg &= ~(EXYNOS_VIDCON0_CLKSEL_MASK | EXYNOS_VIDCON0_CLKVALUP_MASK | - EXYNOS_VIDCON0_CLKVAL_F(0xFF) | EXYNOS_VIDCON0_VCLKEN_MASK | - EXYNOS_VIDCON0_CLKDIR_MASK); - cfg |= (EXYNOS_VIDCON0_CLKSEL_SCLK | EXYNOS_VIDCON0_CLKVALUP_ALWAYS | - EXYNOS_VIDCON0_VCLKEN_NORMAL | EXYNOS_VIDCON0_CLKDIR_DIVIDED); - - src_clock = (unsigned long long) get_lcd_clk(); - - /* get quotient and remainder. */ - remainder = src_clock % pixel_clock; - src_clock /= pixel_clock; - - div = src_clock; - - remainder *= 10; - remainder_div = remainder / pixel_clock; - - /* round about one places of decimals. */ - if (remainder_div >= 5) - div++; - - /* in case of dual lcd mode. */ - if (vid->dual_lcd_enabled) - div--; - - cfg |= EXYNOS_VIDCON0_CLKVAL_F(div - 1); - lwritel(cfg, &FIMD_CTRL->vidcon0); -} - -void exynos_set_trigger(void) -{ - unsigned int cfg = 0; - printk(BIOS_SPEW, "%s\n", __func__); - cfg = lreadl(&FIMD_CTRL->trigcon); - - cfg |= (EXYNOS_I80SOFT_TRIG_EN | EXYNOS_I80START_TRIG); - - lwritel(cfg, &FIMD_CTRL->trigcon); -} - -int exynos_is_i80_frame_done(void) -{ - unsigned int cfg = 0; - int status; - printk(BIOS_SPEW, "%s\n", __func__); - cfg = lreadl(&FIMD_CTRL->trigcon); - - /* frame done func is valid only when TRIMODE[0] is set to 1. */ - status = (cfg & EXYNOS_I80STATUS_TRIG_DONE) == - EXYNOS_I80STATUS_TRIG_DONE; - - return status; -} - -static void exynos_fimd_lcd_on(void) -{ - unsigned int cfg = 0; - - printk(BIOS_SPEW, "%s\n", __func__); - /* display on */ - cfg = lreadl(&FIMD_CTRL->vidcon0); - cfg |= (EXYNOS_VIDCON0_ENVID_ENABLE | EXYNOS_VIDCON0_ENVID_F_ENABLE); - lwritel(cfg, &FIMD_CTRL->vidcon0); -} - -static void exynos_fimd_window_on(unsigned int win_id) -{ - unsigned int cfg = 0; - printk(BIOS_SPEW, "%s %d\n", __func__, win_id); - /* enable window */ - cfg = lreadl(&FIMD_CTRL->wincon0 + - EXYNOS_WINCON(win_id)); - cfg |= EXYNOS_WINCON_ENWIN_ENABLE; - lwritel(cfg, &FIMD_CTRL->wincon0 + - EXYNOS_WINCON(win_id)); - - cfg = lreadl(&FIMD_CTRL->winshmap); - cfg |= EXYNOS_WINSHMAP_CH_ENABLE(win_id); - lwritel(cfg, &FIMD_CTRL->winshmap); - cfg = lreadl(&FIMD_CTRL->winshmap); -} - -void exynos_fimd_lcd_off(void) -{ - unsigned int cfg = 0; - printk(BIOS_SPEW, "%s\n", __func__); - - cfg = lreadl(&FIMD_CTRL->vidcon0); - cfg &= (EXYNOS_VIDCON0_ENVID_DISABLE | EXYNOS_VIDCON0_ENVID_F_DISABLE); - lwritel(cfg, &FIMD_CTRL->vidcon0); -} - -void exynos_fimd_window_off(unsigned int win_id) -{ - unsigned int cfg = 0; - printk(BIOS_SPEW, "%s %d\n", __func__, win_id); - - cfg = lreadl(&FIMD_CTRL->wincon0 + - EXYNOS_WINCON(win_id)); - cfg &= EXYNOS_WINCON_ENWIN_DISABLE; - lwritel(cfg, &FIMD_CTRL->wincon0 + - EXYNOS_WINCON(win_id)); - - cfg = lreadl(&FIMD_CTRL->winshmap); - cfg &= ~EXYNOS_WINSHMAP_CH_DISABLE(win_id); - lwritel(cfg, &FIMD_CTRL->winshmap); -} - -static void exynos5_set_system_display(void) -{ - unsigned int cfg = 0; - - /* - * system register path set - * 0: MIE/MDNIE - * 1: FIMD Bypass - */ - cfg = lreadl(&exynos_sysreg->disp1blk_cfg); - cfg |= (1 << 15); - lwritel(cfg, &exynos_sysreg->disp1blk_cfg); -} - -void exynos_fimd_lcd_init(vidinfo_t *vid) -{ - unsigned int cfg = 0, rgb_mode; - unsigned int offset; - - offset = exynos_fimd_get_base_offset(); - printk(BIOS_SPEW, "%s\n", __func__); - exynos5_set_system_display(); - - rgb_mode = vid->rgb_mode; - - if (vid->interface_mode == FIMD_RGB_INTERFACE) { - printk(BIOS_SPEW, "%s FIMD_RGB_INTERFACE\n", __func__); - - cfg |= EXYNOS_VIDCON0_VIDOUT_RGB; - lwritel(cfg, &FIMD_CTRL->vidcon0); - - cfg = lreadl(&FIMD_CTRL->vidcon2); - cfg &= ~(EXYNOS_VIDCON2_WB_MASK | - EXYNOS_VIDCON2_TVFORMATSEL_MASK | - EXYNOS_VIDCON2_TVFORMATSEL_YUV_MASK); - cfg |= EXYNOS_VIDCON2_WB_DISABLE; - lwritel(cfg, &FIMD_CTRL->vidcon2); - - /* set polarity */ - cfg = 0; - if (!vid->vl_clkp) - cfg |= EXYNOS_VIDCON1_IVCLK_RISING_EDGE; - if (!vid->vl_hsp) - cfg |= EXYNOS_VIDCON1_IHSYNC_INVERT; - if (!vid->vl_vsp) - cfg |= EXYNOS_VIDCON1_IVSYNC_INVERT; - if (!vid->vl_dp) - cfg |= EXYNOS_VIDCON1_IVDEN_INVERT; - - lwritel(cfg, &FIMD_CTRL->vidcon1 + offset); - - /* set timing */ - cfg = EXYNOS_VIDTCON0_VFPD(vid->vl_vfpd - 1); - cfg |= EXYNOS_VIDTCON0_VBPD(vid->vl_vbpd - 1); - cfg |= EXYNOS_VIDTCON0_VSPW(vid->vl_vspw - 1); - lwritel(cfg, &FIMD_CTRL->vidtcon0 + offset); - - cfg = EXYNOS_VIDTCON1_HFPD(vid->vl_hfpd - 1); - cfg |= EXYNOS_VIDTCON1_HBPD(vid->vl_hbpd - 1); - cfg |= EXYNOS_VIDTCON1_HSPW(vid->vl_hspw - 1); - - lwritel(cfg, &FIMD_CTRL->vidtcon1 + offset); - - /* set lcd size */ - cfg = EXYNOS_VIDTCON2_HOZVAL(vid->vl_col - 1) | - EXYNOS_VIDTCON2_LINEVAL(vid->vl_row - 1) | - EXYNOS_VIDTCON2_HOZVAL_E(vid->vl_col - 1) | - EXYNOS_VIDTCON2_LINEVAL_E(vid->vl_row - 1); - - lwritel(cfg, &FIMD_CTRL->vidtcon2 + offset); - } - - /* set display mode */ - cfg = lreadl(&FIMD_CTRL->vidcon0); - cfg &= ~EXYNOS_VIDCON0_PNRMODE_MASK; - cfg |= (rgb_mode << EXYNOS_VIDCON0_PNRMODE_SHIFT); - lwritel(cfg, &FIMD_CTRL->vidcon0); - - /* set par */ - exynos_fimd_set_par(vid, vid->win_id); - - /* set memory address */ - exynos_fimd_set_buffer_address(vid, vid->screen_base, vid->win_id); - - /* set buffer size */ - cfg = EXYNOS_VIDADDR_PAGEWIDTH(vid->vl_col * (1<<vid->vl_bpix) / 8) | - EXYNOS_VIDADDR_PAGEWIDTH_E(vid->vl_col * (1<<vid->vl_bpix) / 8) | - EXYNOS_VIDADDR_OFFSIZE(0) | - EXYNOS_VIDADDR_OFFSIZE_E(0); - - lwritel(cfg, &FIMD_CTRL->vidw00add2 + - EXYNOS_BUFFER_SIZE(vid->win_id)); - - /* set clock */ - exynos_fimd_set_clock(vid); - - /* set rgb mode to dual lcd. */ - exynos_fimd_set_dualrgb(vid, vid->dual_lcd_enabled); - - /* display on */ - exynos_fimd_lcd_on(); - - /* window on */ - exynos_fimd_window_on(vid->win_id); - - exynos_fimd_set_dp_clkcon(vid->dp_enabled); - exynos5_set_system_display(); - printk(BIOS_SPEW, "%s: done\n", __func__); -} - -unsigned long exynos_fimd_calc_fbsize(vidinfo_t *vid) -{ - printk(BIOS_SPEW, "%s\n", __func__); - return vid->vl_col * vid->vl_row * ((1<<vid->vl_bpix) / 8); -} - -void exynos_fimd_lcd_disable(void) -{ - int i; - printk(BIOS_SPEW, "%s\n", __func__); - - for (i = 0; i < 4; i++) - exynos_fimd_window_off(i); -} diff --git a/src/cpu/samsung/exynos5420/fimd.h b/src/cpu/samsung/exynos5420/fimd.h deleted file mode 100644 index ce8773fd17..0000000000 --- a/src/cpu/samsung/exynos5420/fimd.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Register map for Exynos5 FIMD */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_FIMD_H -#define CPU_SAMSUNG_EXYNOS5420_FIMD_H - -#include "cpu.h" - -/* FIMD register map */ -struct exynos5_fimd { - /* This is an incomplete list. Add registers as and when required */ - u32 vidcon0; - u8 res1[0x1c]; - u32 wincon0; - u32 wincon1; - u32 wincon2; - u32 wincon3; - u32 wincon4; - u32 shadowcon; - u8 res2[0x8]; - u32 vidosd0a; - u32 vidosd0b; - u32 vidosd0c; - u8 res3[0x54]; - u32 vidw00add0b0; - u8 res4[0x2c]; - u32 vidw00add1b0; - u8 res5[0x2c]; - u32 vidw00add2; - u8 res6[0x3c]; - u32 w1keycon0; - u32 w1keycon1; - u32 w2keycon0; - u32 w2keycon1; - u32 w3keycon0; - u32 w3keycon1; - u32 w4keycon0; - u32 w4keycon1; - u8 res7[0x20]; - u32 win0map; - u8 res8[0xdc]; - u32 blendcon; - u8 res9[0x18]; - u32 dpclkcon; -}; - -#define W0_SHADOW_PROTECT (0x1 << 10) -#define COMPKEY_F 0xffffff -#define ENVID_F_ON (0x1 << 0) -#define ENVID_ON (0x1 << 1) -#define CLKVAL_F 0xb -#define CLKVAL_F_OFFSET 6 - -/* - * Structure containing display panel specific data for FIMD - */ -struct exynos5_fimd_panel { - unsigned int is_dp:1; /* Display Panel interface is eDP */ - unsigned int is_mipi:1; /* Display Panel interface is MIPI */ - unsigned int fixvclk:2; /* VCLK hold scheme at data underflow */ - - /* - * Polarity of the VCLK active edge - * 0-falling - * 1-rising - */ - unsigned int ivclk:1; - unsigned int clkval_f; /* Divider to create pixel clock */ - - unsigned int upper_margin; /* Vertical Backporch */ - unsigned int lower_margin; /* Vertical frontporch */ - unsigned int vsync; /* Vertical Sync Pulse Width */ - unsigned int left_margin; /* Horizontal Backporch */ - unsigned int right_margin; /* Horizontal Frontporch */ - unsigned int hsync; /* Horizontal Sync Pulse Width */ - unsigned int xres; /* X Resolution */ - unsigned int yres; /* Y Resopultion */ -}; - -/* LCDIF Register Map */ -struct exynos5_disp_ctrl { - u32 vidout_con; - u32 vidcon1; - u8 res1[0x8]; - u32 vidtcon0; - u32 vidtcon1; - u32 vidtcon2; - u32 vidtcon3; - u8 res2[0x184]; - u32 trigcon; -}; - -#define VCLK_RISING_EDGE (1 << 7) -#define VCLK_RUNNING (1 << 9) - -#define CHANNEL0_EN (1 << 0) - -#define VSYNC_PULSE_WIDTH_VAL 0x3 -#define VSYNC_PULSE_WIDTH_OFFSET 0 -#define V_FRONT_PORCH_VAL 0x3 -#define V_FRONT_PORCH_OFFSET 8 -#define V_BACK_PORCH_VAL 0x3 -#define V_BACK_PORCH_OFFSET 16 - -#define HSYNC_PULSE_WIDTH_VAL 0x3 -#define HSYNC_PULSE_WIDTH_OFFSET 0 -#define H_FRONT_PORCH_VAL 0x3 -#define H_FRONT_PORCH_OFFSET 8 -#define H_BACK_PORCH_VAL 0x3 -#define H_BACK_PORCH_OFFSET 16 - -#define HOZVAL_OFFSET 0 -#define LINEVAL_OFFSET 11 - -#define BPPMODE_F_RGB_16BIT_565 0x5 -#define BPPMODE_F_OFFSET 2 -#define ENWIN_F_ENABLE (1 << 0) -#define HALF_WORD_SWAP_EN (1 << 16) - -#define OSD_RIGHTBOTX_F_OFFSET 11 -#define OSD_RIGHTBOTY_F_OFFSET 0 - -#define FIMD_CTRL ((struct exynos_fb *)0x14400000) - -/* from u-boot fb.h. It needs to be merged with these dp structs maybe. */ -enum { - FIMD_RGB_INTERFACE = 1, - FIMD_CPU_INTERFACE = 2, -}; - -enum exynos_fb_rgb_mode_t { - MODE_RGB_P = 0, - MODE_BGR_P = 1, - MODE_RGB_S = 2, - MODE_BGR_S = 3, -}; - -typedef struct vidinfo { - u16 vl_col; /* Number of columns (i.e. 640) */ - u16 vl_row; /* Number of rows (i.e. 480) */ - u16 vl_width; /* Width of display area in millimeters */ - u16 vl_height; /* Height of display area in millimeters */ - - /* LCD configuration register */ - u8 vl_freq; /* Frequency */ - u8 vl_clkp; /* Clock polarity */ - u8 vl_oep; /* Output Enable polarity */ - u8 vl_hsp; /* Horizontal Sync polarity */ - u8 vl_vsp; /* Vertical Sync polarity */ - u8 vl_dp; /* Data polarity */ - u8 vl_bpix; /* Bits per pixel */ - - /* Horizontal control register. Timing from data sheet */ - u8 vl_hspw; /* Horz sync pulse width */ - u8 vl_hfpd; /* Wait before of line */ - u8 vl_hbpd; /* Wait end of line */ - - /* Vertical control register. */ - u8 vl_vspw; /* Vertical sync pulse width */ - u8 vl_vfpd; /* Wait before of frame */ - u8 vl_vbpd; /* Wait end of frame */ - u8 vl_cmd_allow_len; /* Wait end of frame */ - - unsigned int win_id; - unsigned int init_delay; - unsigned int power_on_delay; - unsigned int reset_delay; - unsigned int interface_mode; - unsigned int mipi_enabled; - unsigned int dp_enabled; - unsigned int cs_setup; - unsigned int wr_setup; - unsigned int wr_act; - unsigned int wr_hold; - unsigned int rgb_mode; - unsigned int resolution; - - /* parent clock name(MPLL, EPLL or VPLL) */ - unsigned int pclk_name; - /* ratio value for source clock from parent clock. */ - unsigned int sclk_div; - - unsigned int dual_lcd_enabled; - void *screen_base; - void *cmap; /* Points at 8 to 16 bit conversion map. */ -} vidinfo_t; - -/* fimd.c */ -void exynos_set_trigger(void); -int exynos_is_i80_frame_done(void); -void exynos_fimd_lcd_off(void); -void exynos_fimd_window_off(unsigned int win_id); -unsigned long exynos_fimd_calc_fbsize(vidinfo_t *vid); -void exynos_fimd_lcd_disable(void); -void exynos_fimd_lcd_init(vidinfo_t *vid); - -#endif diff --git a/src/cpu/samsung/exynos5420/gpio.c b/src/cpu/samsung/exynos5420/gpio.c deleted file mode 100644 index 2b65eda04e..0000000000 --- a/src/cpu/samsung/exynos5420/gpio.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2009 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <console/console.h> -#include <string.h> -#include <delay.h> -#include <assert.h> -#include "gpio.h" -#include "cpu.h" - -#define CON_MASK(x) (0xf << ((x) << 2)) -#define CON_SFR(x, v) ((v) << ((x) << 2)) - -#define DAT_MASK(x) (0x1 << (x)) -#define DAT_SET(x) (0x1 << (x)) - -#define PULL_MASK(x) (0x3 << ((x) << 1)) -#define PULL_MODE(x, v) ((v) << ((x) << 1)) - -#define DRV_MASK(x) (0x3 << ((x) << 1)) -#define DRV_SET(x, m) ((m) << ((x) << 1)) -#define RATE_MASK(x) (0x1 << (x + 16)) -#define RATE_SET(x) (0x1 << (x + 16)) - -struct gpio_info { - unsigned int reg_addr; /* Address of register for this part */ - unsigned int max_gpio; /* Maximum GPIO in this part */ -}; - -static const struct gpio_info gpio_data[EXYNOS_GPIO_NUM_PARTS] = { - { EXYNOS5420_GPIO_PART1_BASE, GPIO_MAX_PORT_PART_1 }, - { EXYNOS5420_GPIO_PART2_BASE, GPIO_MAX_PORT_PART_2 }, - { EXYNOS5420_GPIO_PART3_BASE, GPIO_MAX_PORT_PART_3 }, - { EXYNOS5420_GPIO_PART4_BASE, GPIO_MAX_PORT_PART_4 }, - { EXYNOS5420_GPIO_PART5_BASE, GPIO_MAX_PORT_PART_5 }, - { EXYNOS5420_GPIO_PART6_BASE, GPIO_MAX_PORT }, -}; - -/* This macro gets gpio pin offset from 0..7 */ -#define GPIO_BIT(x) ((x) & 0x7) - -static struct gpio_bank *gpio_get_bank(unsigned int gpio) -{ - const struct gpio_info *data; - unsigned int upto; - int i; - - for (i = upto = 0, data = gpio_data; i < EXYNOS_GPIO_NUM_PARTS; - i++, upto = data->max_gpio, data++) { - if (gpio < data->max_gpio) { - struct gpio_bank *bank; - - bank = (struct gpio_bank *)data->reg_addr; - bank += (gpio - upto) / GPIO_PER_BANK; - return bank; - } - } - - ASSERT(gpio < GPIO_MAX_PORT); /* ...which it will not be */ - return NULL; -} - -/* Common GPIO API - only available on Exynos5 */ -void gpio_cfg_pin(int gpio, int cfg) -{ - unsigned int value; - struct gpio_bank *bank = gpio_get_bank(gpio); - - value = readl(&bank->con); - value &= ~CON_MASK(GPIO_BIT(gpio)); - value |= CON_SFR(GPIO_BIT(gpio), cfg); - writel(value, &bank->con); -} - -static int gpio_get_cfg(int gpio) -{ - struct gpio_bank *bank = gpio_get_bank(gpio); - int shift = GPIO_BIT(gpio) << 2; - - return (readl(&bank->con) & CON_MASK(GPIO_BIT(gpio))) >> shift; -} - -void gpio_set_pull(int gpio, int mode) -{ - unsigned int value; - struct gpio_bank *bank = gpio_get_bank(gpio); - - value = readl(&bank->pull); - value &= ~PULL_MASK(GPIO_BIT(gpio)); - - switch (mode) { - case GPIO_PULL_DOWN: - case GPIO_PULL_UP: - value |= PULL_MODE(GPIO_BIT(gpio), mode); - break; - default: - break; - } - - writel(value, &bank->pull); -} - -void gpio_set_drv(int gpio, int mode) -{ - unsigned int value; - struct gpio_bank *bank = gpio_get_bank(gpio); - - value = readl(&bank->drv); - value &= ~DRV_MASK(GPIO_BIT(gpio)); - - switch (mode) { - case GPIO_DRV_1X: - case GPIO_DRV_2X: - case GPIO_DRV_3X: - case GPIO_DRV_4X: - value |= DRV_SET(GPIO_BIT(gpio), mode); - break; - default: - return; - } - - writel(value, &bank->drv); -} - -void gpio_set_rate(int gpio, int mode) -{ - unsigned int value; - struct gpio_bank *bank = gpio_get_bank(gpio); - - value = readl(&bank->drv); - value &= ~RATE_MASK(GPIO_BIT(gpio)); - - switch (mode) { - case GPIO_DRV_FAST: - case GPIO_DRV_SLOW: - value |= RATE_SET(GPIO_BIT(gpio)); - break; - default: - return; - } - - writel(value, &bank->drv); -} - -int gpio_direction_input(unsigned gpio) -{ - gpio_cfg_pin(gpio, GPIO_INPUT); - - return 0; -} - -int gpio_direction_output(unsigned gpio, int value) -{ - unsigned int val; - struct gpio_bank *bank = gpio_get_bank(gpio); - - val = readl(&bank->dat); - val &= ~DAT_MASK(GPIO_BIT(gpio)); - if (value) - val |= DAT_SET(GPIO_BIT(gpio)); - writel(val, &bank->dat); - - gpio_cfg_pin(gpio, GPIO_OUTPUT); - - return 0; -} - -int gpio_get_value(unsigned gpio) -{ - unsigned int value; - struct gpio_bank *bank = gpio_get_bank(gpio); - - value = readl(&bank->dat); - return !!(value & DAT_MASK(GPIO_BIT(gpio))); -} - -int gpio_set_value(unsigned gpio, int value) -{ - unsigned int val; - struct gpio_bank *bank = gpio_get_bank(gpio); - - val = readl(&bank->dat); - val &= ~DAT_MASK(GPIO_BIT(gpio)); - if (value) - val |= DAT_SET(GPIO_BIT(gpio)); - writel(val, &bank->dat); - - return 0; -} - -/* - * Add a delay here to give the lines time to settle - * TODO(dianders): 5us does not always work, 10 is stable, so use 15 to be safe - * Come back to this and sort out what the datasheet says - */ -#define GPIO_DELAY_US 15 - -#ifndef __BOOT_BLOCK__ -/* - * FIXME(dhendrix): These functions use udelay, which has dependencies on - * pwm code and timer code. These aren't necessary for the bootblock and - * bloat the image significantly. - */ -int gpio_read_mvl3(unsigned gpio) -{ - int high, low; - enum mvl3 value; - - if (gpio >= GPIO_MAX_PORT) - return -1; - - gpio_direction_input(gpio); - gpio_set_pull(gpio, GPIO_PULL_UP); - udelay(GPIO_DELAY_US); - high = gpio_get_value(gpio); - gpio_set_pull(gpio, GPIO_PULL_DOWN); - udelay(GPIO_DELAY_US); - low = gpio_get_value(gpio); - - if (high && low) /* external pullup */ - value = LOGIC_1; - else if (!high && !low) /* external pulldown */ - value = LOGIC_0; - else /* floating */ - value = LOGIC_Z; - - /* - * Check if line is externally pulled high and - * configure the internal pullup to match. For - * floating and pulldowns, the GPIO is already - * configured with an internal pulldown from the - * above test. - */ - if (value == LOGIC_1) - gpio_set_pull(gpio, GPIO_PULL_UP); - - return value; -} -#endif /* __BOOT_BLOCK__ */ - -/* - * Display Exynos GPIO information - */ -void gpio_info(void) -{ - unsigned gpio; - - for (gpio = 0; gpio < GPIO_MAX_PORT; gpio++) { - int cfg = gpio_get_cfg(gpio); - - printk(BIOS_INFO, "GPIO_%-3d: ", gpio); - if (cfg == GPIO_INPUT) - printk(BIOS_INFO, "input"); - else if (cfg == GPIO_OUTPUT) - printk(BIOS_INFO, "output"); - else - printk(BIOS_INFO, "func %d", cfg); - - if (cfg == GPIO_INPUT || cfg == GPIO_OUTPUT) - printk(BIOS_INFO, ", value = %d", gpio_get_value(gpio)); - printk(BIOS_INFO, "\n"); - } -} diff --git a/src/cpu/samsung/exynos5420/gpio.h b/src/cpu/samsung/exynos5420/gpio.h deleted file mode 100644 index 4cf8e57249..0000000000 --- a/src/cpu/samsung/exynos5420/gpio.h +++ /dev/null @@ -1,550 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_GPIO_H -#define CPU_SAMSUNG_EXYNOS5420_GPIO_H - -#include "cpu.h" - -struct gpio_bank { - unsigned int con; - unsigned int dat; - unsigned int pull; - unsigned int drv; - unsigned int pdn_con; - unsigned int pdn_pull; - unsigned char res1[8]; -}; - -/* GPIO pins per bank */ -#define GPIO_PER_BANK 8 - -/* Pin configurations */ -#define GPIO_INPUT 0x0 -#define GPIO_OUTPUT 0x1 -#define GPIO_IRQ 0xf -#define GPIO_FUNC(x) (x) - -/* Pull mode */ -#define GPIO_PULL_NONE 0x0 -#define GPIO_PULL_DOWN 0x1 -#define GPIO_PULL_UP 0x3 - -/* Drive Strength level */ -#define GPIO_DRV_1X 0x0 -#define GPIO_DRV_3X 0x1 -#define GPIO_DRV_2X 0x2 -#define GPIO_DRV_4X 0x3 -#define GPIO_DRV_FAST 0x0 -#define GPIO_DRV_SLOW 0x1 - -enum exynos5_gpio_port { - EXYNOS5_GPY7 = EXYNOS5420_GPIO_PART1_BASE + 0x0000, - - EXYNOS5_GPX0 = EXYNOS5420_GPIO_PART2_BASE + 0x0000, - EXYNOS5_GPX1 = EXYNOS5420_GPIO_PART2_BASE + 0x0020, - EXYNOS5_GPX2 = EXYNOS5420_GPIO_PART2_BASE + 0x0040, - EXYNOS5_GPX3 = EXYNOS5420_GPIO_PART2_BASE + 0x0060, - - EXYNOS5_GPC0 = EXYNOS5420_GPIO_PART3_BASE + 0x0000, - EXYNOS5_GPC1 = EXYNOS5420_GPIO_PART3_BASE + 0x0020, - EXYNOS5_GPC2 = EXYNOS5420_GPIO_PART3_BASE + 0x0040, - EXYNOS5_GPC3 = EXYNOS5420_GPIO_PART3_BASE + 0x0060, - EXYNOS5_GPC4 = EXYNOS5420_GPIO_PART3_BASE + 0x0080, - - EXYNOS5_GPD1 = EXYNOS5420_GPIO_PART3_BASE + 0x00a0, - - EXYNOS5_GPY0 = EXYNOS5420_GPIO_PART3_BASE + 0x00c0, - EXYNOS5_GPY1 = EXYNOS5420_GPIO_PART3_BASE + 0x00e0, - EXYNOS5_GPY2 = EXYNOS5420_GPIO_PART3_BASE + 0x0100, - EXYNOS5_GPY3 = EXYNOS5420_GPIO_PART3_BASE + 0x0120, - EXYNOS5_GPY4 = EXYNOS5420_GPIO_PART3_BASE + 0x0140, - EXYNOS5_GPY5 = EXYNOS5420_GPIO_PART3_BASE + 0x0160, - EXYNOS5_GPY6 = EXYNOS5420_GPIO_PART3_BASE + 0x0180, - - EXYNOS5_GPE0 = EXYNOS5420_GPIO_PART4_BASE + 0x0000, - EXYNOS5_GPE1 = EXYNOS5420_GPIO_PART4_BASE + 0x0020, - - EXYNOS5_GPF0 = EXYNOS5420_GPIO_PART4_BASE + 0x0040, - EXYNOS5_GPF1 = EXYNOS5420_GPIO_PART4_BASE + 0x0060, - - EXYNOS5_GPG0 = EXYNOS5420_GPIO_PART4_BASE + 0x0080, - EXYNOS5_GPG1 = EXYNOS5420_GPIO_PART4_BASE + 0x00a0, - EXYNOS5_GPG2 = EXYNOS5420_GPIO_PART4_BASE + 0x00c0, - - EXYNOS5_GPJ4 = EXYNOS5420_GPIO_PART4_BASE + 0x00e0, - - /* base == EXYNOS5420_GPIO_PART5_BASE */ - EXYNOS5_GPA0 = EXYNOS5420_GPIO_PART5_BASE + 0x0000, - EXYNOS5_GPA1 = EXYNOS5420_GPIO_PART5_BASE + 0x0020, - EXYNOS5_GPA2 = EXYNOS5420_GPIO_PART5_BASE + 0x0040, - - EXYNOS5_GPB0 = EXYNOS5420_GPIO_PART5_BASE + 0x0060, - EXYNOS5_GPB1 = EXYNOS5420_GPIO_PART5_BASE + 0x0080, - EXYNOS5_GPB2 = EXYNOS5420_GPIO_PART5_BASE + 0x00a0, - EXYNOS5_GPB3 = EXYNOS5420_GPIO_PART5_BASE + 0x00c0, - EXYNOS5_GPB4 = EXYNOS5420_GPIO_PART5_BASE + 0x00e0, - - EXYNOS5_GPH0 = EXYNOS5420_GPIO_PART5_BASE + 0x0100, - - /* base == EXYNOS5420_GPIO_PART6_BASE */ - EXYNOS5_GPZ0 = EXYNOS5420_GPIO_PART6_BASE + 0x0000, -}; - -enum { - /* GPIO banks are split into this many parts */ - EXYNOS_GPIO_NUM_PARTS = 6 -}; - -/* A list of valid GPIO numbers for the asm-generic/gpio.h interface */ -enum exynos5_gpio_pin { - /* GPIO_PART1_STARTS */ - GPIO_Y70, - GPIO_Y71, - GPIO_Y72, - GPIO_Y73, - GPIO_Y74, - GPIO_Y75, - GPIO_Y76, - GPIO_Y77, - - /* GPIO_PART2_STARTS */ - GPIO_MAX_PORT_PART_1, - GPIO_X00 = GPIO_MAX_PORT_PART_1, /* 0x08 */ - GPIO_X01, - GPIO_X02, - GPIO_X03, - GPIO_X04, - GPIO_X05, - GPIO_X06, - GPIO_X07, - GPIO_X10, - GPIO_X11, - GPIO_X12, - GPIO_X13, - GPIO_X14, - GPIO_X15, - GPIO_X16, - GPIO_X17, - GPIO_X20, - GPIO_X21, - GPIO_X22, - GPIO_X23, - GPIO_X24, - GPIO_X25, - GPIO_X26, - GPIO_X27, - GPIO_X30, - GPIO_X31, - GPIO_X32, - GPIO_X33, - GPIO_X34, - GPIO_X35, - GPIO_X36, - GPIO_X37, - - /* GPIO_PART3_STARTS */ - GPIO_MAX_PORT_PART_2, - GPIO_C00 = GPIO_MAX_PORT_PART_2, /* 0x28 */ - GPIO_C01, - GPIO_C02, - GPIO_C03, - GPIO_C04, - GPIO_C05, - GPIO_C06, - GPIO_C07, - GPIO_C10, - GPIO_C11, - GPIO_C12, - GPIO_C13, - GPIO_C14, - GPIO_C15, - GPIO_C16, - GPIO_C17, - GPIO_C20, - GPIO_C21, - GPIO_C22, - GPIO_C23, - GPIO_C24, - GPIO_C25, - GPIO_C26, - GPIO_C27, - GPIO_C30, - GPIO_C31, - GPIO_C32, - GPIO_C33, - GPIO_C34, - GPIO_C35, - GPIO_C36, - GPIO_C37, - GPIO_C40, - GPIO_C41, - GPIO_C42, - GPIO_C43, - GPIO_C44, - GPIO_C45, - GPIO_C46, - GPIO_C47, - - GPIO_D10, /* 0x50 */ - GPIO_D11, - GPIO_D12, - GPIO_D13, - GPIO_D14, - GPIO_D15, - GPIO_D16, - GPIO_D17, - - GPIO_Y00, /* 0x58 */ - GPIO_Y01, - GPIO_Y02, - GPIO_Y03, - GPIO_Y04, - GPIO_Y05, - GPIO_Y06, - GPIO_Y07, - GPIO_Y10, - GPIO_Y11, - GPIO_Y12, - GPIO_Y13, - GPIO_Y14, - GPIO_Y15, - GPIO_Y16, - GPIO_Y17, - GPIO_Y20, - GPIO_Y21, - GPIO_Y22, - GPIO_Y23, - GPIO_Y24, - GPIO_Y25, - GPIO_Y26, - GPIO_Y27, - GPIO_Y30, - GPIO_Y31, - GPIO_Y32, - GPIO_Y33, - GPIO_Y34, - GPIO_Y35, - GPIO_Y36, - GPIO_Y37, - GPIO_Y40, - GPIO_Y41, - GPIO_Y42, - GPIO_Y43, - GPIO_Y44, - GPIO_Y45, - GPIO_Y46, - GPIO_Y47, - GPIO_Y50, - GPIO_Y51, - GPIO_Y52, - GPIO_Y53, - GPIO_Y54, - GPIO_Y55, - GPIO_Y56, - GPIO_Y57, - GPIO_Y60, - GPIO_Y61, - GPIO_Y62, - GPIO_Y63, - GPIO_Y64, - GPIO_Y65, - GPIO_Y66, - GPIO_Y67, - - /* GPIO_PART4_STARTS */ - GPIO_MAX_PORT_PART_3, - GPIO_E00 = GPIO_MAX_PORT_PART_3, /* 0x90 */ - GPIO_E01, - GPIO_E02, - GPIO_E03, - GPIO_E04, - GPIO_E05, - GPIO_E06, - GPIO_E07, - GPIO_E10, - GPIO_E11, - GPIO_E12, - GPIO_E13, - GPIO_E14, - GPIO_E15, - GPIO_E16, - GPIO_E17, - - GPIO_F00, /* 0xa0 */ - GPIO_F01, - GPIO_F02, - GPIO_F03, - GPIO_F04, - GPIO_F05, - GPIO_F06, - GPIO_F07, - GPIO_F10, - GPIO_F11, - GPIO_F12, - GPIO_F13, - GPIO_F14, - GPIO_F15, - GPIO_F16, - GPIO_F17, - - GPIO_G00, /* 0xb0 */ - GPIO_G01, - GPIO_G02, - GPIO_G03, - GPIO_G04, - GPIO_G05, - GPIO_G06, - GPIO_G07, - GPIO_G10, - GPIO_G11, - GPIO_G12, - GPIO_G13, - GPIO_G14, - GPIO_G15, - GPIO_G16, - GPIO_G17, - GPIO_G20, - GPIO_G21, - GPIO_G22, - GPIO_G23, - GPIO_G24, - GPIO_G25, - GPIO_G26, - GPIO_G27, - - GPIO_J40, /* 0xc8 */ - GPIO_J41, - GPIO_J42, - GPIO_J43, - GPIO_J44, - GPIO_J45, - GPIO_J46, - GPIO_J47, - - /* GPIO_PART5_STARTS */ - GPIO_MAX_PORT_PART_4, - GPIO_A00 = GPIO_MAX_PORT_PART_4, /* 0xd0 */ - GPIO_A01, - GPIO_A02, - GPIO_A03, - GPIO_A04, - GPIO_A05, - GPIO_A06, - GPIO_A07, - GPIO_A10, - GPIO_A11, - GPIO_A12, - GPIO_A13, - GPIO_A14, - GPIO_A15, - GPIO_A16, - GPIO_A17, - GPIO_A20, - GPIO_A21, - GPIO_A22, - GPIO_A23, - GPIO_A24, - GPIO_A25, - GPIO_A26, - GPIO_A27, - - GPIO_B00, /* 0xe8 */ - GPIO_B01, - GPIO_B02, - GPIO_B03, - GPIO_B04, - GPIO_B05, - GPIO_B06, - GPIO_B07, - GPIO_B10, - GPIO_B11, - GPIO_B12, - GPIO_B13, - GPIO_B14, - GPIO_B15, - GPIO_B16, - GPIO_B17, - GPIO_B20, - GPIO_B21, - GPIO_B22, - GPIO_B23, - GPIO_B24, - GPIO_B25, - GPIO_B26, - GPIO_B27, - GPIO_B30, - GPIO_B31, - GPIO_B32, - GPIO_B33, - GPIO_B34, - GPIO_B35, - GPIO_B36, - GPIO_B37, - GPIO_B40, - GPIO_B41, - GPIO_B42, - GPIO_B43, - GPIO_B44, - GPIO_B45, - GPIO_B46, - GPIO_B47, - - GPIO_H00, /* 0x110 */ - GPIO_H01, - GPIO_H02, - GPIO_H03, - GPIO_H04, - GPIO_H05, - GPIO_H06, - GPIO_H07, - - /* GPIO_PART6_STARTS */ - GPIO_MAX_PORT_PART_5, - GPIO_Z00 = GPIO_MAX_PORT_PART_5, /* 0x118 */ - GPIO_Z01, - GPIO_Z02, - GPIO_Z03, - GPIO_Z04, - GPIO_Z05, - GPIO_Z06, - GPIO_Z07, - GPIO_MAX_PORT -}; - -/** - * Set GPIO pin configuration. - * - * @param gpio GPIO pin - * @param cfg Either GPIO_INPUT, GPIO_OUTPUT, or GPIO_IRQ - */ -void gpio_cfg_pin(int gpio, int cfg); - -/** - * Set GPIO pull mode. - * - * @param gpio GPIO pin - * @param mode Either GPIO_PULL_DOWN or GPIO_PULL_UP - */ -void gpio_set_pull(int gpio, int mode); - -/** - * Set GPIO drive strength level. - * - * @param gpio GPIO pin - * @param mode Either GPIO_DRV_1X, GPIO_DRV_2X, GPIO_DRV_3X, or GPIO_DRV_4X - */ -void gpio_set_drv(int gpio, int mode); - -/** - * Set GPIO drive rate. - * - * @param gpio GPIO pin - * @param mode Either GPIO_DRV_FAST or GPIO_DRV_SLOW - */ -void gpio_set_rate(int gpio, int mode); - -/* - * reads only a single GPIO - * - * @param gpio GPIO to read - * @return -1 if the value cannot be determined. Otherwise returns - * the corresponding MVL3 enum value. - */ -int gpio_read_mvl3(unsigned gpio); - -void gpio_info(void); - -/* - * Generic GPIO API for U-Boot - * - * GPIOs are numbered from 0 to GPIO_COUNT-1 which value is defined - * by the SOC/architecture. - * - * Each GPIO can be an input or output. If an input then its value can - * be read as 0 or 1. If an output then its value can be set to 0 or 1. - * If you try to write an input then the value is undefined. If you try - * to read an output, barring something very unusual, you will get - * back the value of the output that you previously set. - * - * In some cases the operation may fail, for example if the GPIO number - * is out of range, or the GPIO is not available because its pin is - * being used by another function. In that case, functions may return - * an error value of -1. - */ - -/** - * Make a GPIO an input. - * - * @param gpio GPIO number - * @return 0 if ok, -1 on error - */ -int gpio_direction_input(unsigned gpio); - -/** - * Make a GPIO an output, and set its value. - * - * @param gpio GPIO number - * @param value GPIO value (0 for low or 1 for high) - * @return 0 if ok, -1 on error - */ -int gpio_direction_output(unsigned gpio, int value); - -/** - * Get a GPIO's value. This will work whether the GPIO is an input - * or an output. - * - * @param gpio GPIO number - * @return 0 if low, 1 if high, -1 on error - */ -int gpio_get_value(unsigned gpio); - -/** - * Set an output GPIO's value. The GPIO must already be an output or - * this function may have no effect. - * - * @param gpio GPIO number - * @param value GPIO value (0 for low or 1 for high) - * @return 0 if ok, -1 on error - */ -int gpio_set_value(unsigned gpio, int value); - -/* - * Many-value logic (3 states). This can be used for inputs whereby presence - * of external pull-up or pull-down resistors can be added to overcome internal - * pull-ups/pull-downs and force a single value. - * - * Thus, external pull resistors can force a 0 or 1 and if the value changes - * along with internal pull-up/down enable then the input is floating. - * - * Vpd | Vpu | MVL - * ----------------- - * 0 | 0 | 0 - * ----------------- - * 0 | 1 | Z <-- floating input will follow internal pull up/down - * ----------------- - * 1 | 1 | 1 - */ -enum mvl3 { - LOGIC_0, - LOGIC_1, - LOGIC_Z, /* high impedence / tri-stated / floating */ -}; - -#endif /* CPU_SAMSUNG_EXYNOS5420_GPIO_H */ diff --git a/src/cpu/samsung/exynos5420/i2c.c b/src/cpu/samsung/exynos5420/i2c.c deleted file mode 100644 index 226862802a..0000000000 --- a/src/cpu/samsung/exynos5420/i2c.c +++ /dev/null @@ -1,706 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * (C) Copyright 2002 - * David Mueller, ELSOFT AG, d.mueller@elsoft.ch - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <console/console.h> -#include <delay.h> -#include <timer.h> -#include <arch/io.h> -#include <device/i2c.h> -#include "clk.h" -#include "i2c.h" -#include "pinmux.h" - -#define I2C_WRITE 0 -#define I2C_READ 1 - -#define I2C_OK 0 -#define I2C_NOK 1 -#define I2C_NACK 2 -#define I2C_NOK_LA 3 /* Lost arbitration */ -#define I2C_NOK_TOUT 4 /* time out */ - -/* HSI2C specific register description */ - -/* I2C_CTL Register bits */ -/* FIXME(dhendrix): do we really need to cast these as unsigned? */ -#define HSI2C_FUNC_MODE_I2C (1u << 0) -#define HSI2C_MASTER (1u << 3) -#define HSI2C_RXCHON (1u << 6) /* Write/Send */ -#define HSI2C_TXCHON (1u << 7) /* Read/Receive */ -#define HSI2C_SW_RST (1u << 31) - -/* I2C_FIFO_STAT Register bits */ -#define HSI2C_TX_FIFO_LEVEL (0x7f << 0) -#define HSI2C_TX_FIFO_FULL (1u << 7) -#define HSI2C_TX_FIFO_EMPTY (1u << 8) -#define HSI2C_RX_FIFO_LEVEL (0x7f << 16) -#define HSI2C_RX_FIFO_FULL (1u << 23) -#define HSI2C_RX_FIFO_EMPTY (1u << 24) - -/* I2C_FIFO_CTL Register bits */ -#define HSI2C_RXFIFO_EN (1u << 0) -#define HSI2C_TXFIFO_EN (1u << 1) -#define HSI2C_TXFIFO_TRIGGER_LEVEL (0x20 << 16) -#define HSI2C_RXFIFO_TRIGGER_LEVEL (0x20 << 4) - -/* I2C_TRAILING_CTL Register bits */ -#define HSI2C_TRAILING_COUNT (0xff) - -/* I2C_INT_EN Register bits */ -#define HSI2C_INT_TX_ALMOSTEMPTY_EN (1u << 0) -#define HSI2C_INT_RX_ALMOSTFULL_EN (1u << 1) -#define HSI2C_INT_TRAILING_EN (1u << 6) -#define HSI2C_INT_I2C_EN (1u << 9) - -/* I2C_CONF Register bits */ -#define HSI2C_AUTO_MODE (1u << 31) -#define HSI2C_10BIT_ADDR_MODE (1u << 30) -#define HSI2C_HS_MODE (1u << 29) - -/* I2C_AUTO_CONF Register bits */ -#define HSI2C_READ_WRITE (1u << 16) -#define HSI2C_STOP_AFTER_TRANS (1u << 17) -#define HSI2C_MASTER_RUN (1u << 31) - -/* I2C_TIMEOUT Register bits */ -#define HSI2C_TIMEOUT_EN (1u << 31) - -/* I2C_TRANS_STATUS register bits */ -#define HSI2C_MASTER_BUSY (1u << 17) -#define HSI2C_SLAVE_BUSY (1u << 16) -#define HSI2C_TIMEOUT_AUTO (1u << 4) -#define HSI2C_NO_DEV (1u << 3) -#define HSI2C_NO_DEV_ACK (1u << 2) -#define HSI2C_TRANS_ABORT (1u << 1) -#define HSI2C_TRANS_DONE (1u << 0) - -#define HSI2C_SLV_ADDR_MAS(x) ((x & 0x3ff) << 10) - -/* S3C I2C Controller bits */ -#define I2CSTAT_BSY 0x20 /* Busy bit */ -#define I2CSTAT_NACK 0x01 /* Nack bit */ -#define I2CCON_ACKGEN 0x80 /* Acknowledge generation */ -#define I2CCON_IRPND 0x10 /* Interrupt pending bit */ -#define I2C_MODE_MT 0xC0 /* Master Transmit Mode */ -#define I2C_MODE_MR 0x80 /* Master Receive Mode */ -#define I2C_START_STOP 0x20 /* START / STOP */ -#define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */ - -#define I2C_TIMEOUT_MS 1000 /* 1 second */ - -#define HSI2C_TIMEOUT 100 - -/* The timeouts we live by */ -enum { - I2C_XFER_TIMEOUT_MS = 35, /* xfer to complete */ - I2C_INIT_TIMEOUT_MS = 1000, /* bus free on init */ - I2C_IDLE_TIMEOUT_MS = 100, /* waiting for bus idle */ - I2C_STOP_TIMEOUT_US = 200, /* waiting for stop events */ -}; - -static struct s3c24x0_i2c_bus i2c_buses[] = { - { - .bus_num = 0, - .regs = (struct s3c24x0_i2c *)0x12c60000, - .periph_id = PERIPH_ID_I2C0, - }, - { - .bus_num = 1, - .regs = (struct s3c24x0_i2c *)0x12c70000, - .periph_id = PERIPH_ID_I2C1, - }, - { - .bus_num = 2, - .regs = (struct s3c24x0_i2c *)0x12c80000, - .periph_id = PERIPH_ID_I2C2, - }, - { - .bus_num = 3, - .regs = (struct s3c24x0_i2c *)0x12c90000, - .periph_id = PERIPH_ID_I2C3, - }, - /* I2C4-I2C10 are part of the USI block */ - { - .bus_num = 4, - .hsregs = (struct exynos5_hsi2c *)0x12ca0000, - .periph_id = PERIPH_ID_I2C4, - .is_highspeed = 1, - }, - { - .bus_num = 5, - .hsregs = (struct exynos5_hsi2c *)0x12cb0000, - .periph_id = PERIPH_ID_I2C5, - .is_highspeed = 1, - }, - { - .bus_num = 6, - .hsregs = (struct exynos5_hsi2c *)0x12cc0000, - .periph_id = PERIPH_ID_I2C6, - .is_highspeed = 1, - }, - { - .bus_num = 7, - .hsregs = (struct exynos5_hsi2c *)0x12cd0000, - .periph_id = PERIPH_ID_I2C7, - .is_highspeed = 1, - }, - { - .bus_num = 8, - .hsregs = (struct exynos5_hsi2c *)0x12e00000, - .periph_id = PERIPH_ID_I2C8, - .is_highspeed = 1, - }, - { - .bus_num = 9, - .hsregs = (struct exynos5_hsi2c *)0x12e10000, - .periph_id = PERIPH_ID_I2C9, - .is_highspeed = 1, - }, - { - .bus_num = 10, - .hsregs = (struct exynos5_hsi2c *)0x12e20000, - .periph_id = PERIPH_ID_I2C10, - .is_highspeed = 1, - }, -}; - -/* - * Wait til the byte transfer is completed. - * - * @param i2c- pointer to the appropriate i2c register bank. - * @return I2C_OK, if transmission was ACKED - * I2C_NACK, if transmission was NACKED - * I2C_NOK_TIMEOUT, if transaction did not complete in I2C_TIMEOUT_MS - */ - -static int WaitForXfer(struct s3c24x0_i2c *i2c) -{ - struct mono_time current, end; - - timer_monotonic_get(¤t); - end = current; - mono_time_add_usecs(&end, I2C_TIMEOUT_MS * 1000); - do { - if (read32(&i2c->iiccon) & I2CCON_IRPND) - return (read32(&i2c->iicstat) & I2CSTAT_NACK) ? - I2C_NACK : I2C_OK; - timer_monotonic_get(¤t); - } while (mono_time_before(¤t, &end)); - - printk(BIOS_ERR, "%s timed out\n", __func__); - return I2C_NOK_TOUT; -} - -static void ReadWriteByte(struct s3c24x0_i2c *i2c) -{ - writel(read32(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon); -} - -static void i2c_ch_init(struct s3c24x0_i2c_bus *bus, int speed, int slaveadd) -{ - unsigned long freq, pres = 16, div; - unsigned long val; - - freq = clock_get_periph_rate(bus->periph_id); - /* calculate prescaler and divisor values */ - if ((freq / pres / (16 + 1)) > speed) - /* set prescaler to 512 */ - pres = 512; - - div = 0; - while ((freq / pres / (div + 1)) > speed) - div++; - - /* set prescaler, divisor according to freq, also set ACKGEN, IRQ */ - val = (div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0); - write32(val, &bus->regs->iiccon); - - /* init to SLAVE RECEIVE mode and clear I2CADDn */ - write32(0, &bus->regs->iicstat); - write32(slaveadd, &bus->regs->iicadd); - /* program Master Transmit (and implicit STOP) */ - write32(I2C_MODE_MT | I2C_TXRX_ENA, &bus->regs->iicstat); -} - -static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus, - unsigned int bus_freq_hz) -{ - struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; - unsigned long clkin = clock_get_periph_rate(i2c_bus->periph_id); - unsigned int i = 0, utemp0 = 0, utemp1 = 0; - unsigned int t_ftl_cycle; - - /* FPCLK / FI2C = - * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE - * uTemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) - * uTemp1 = (TSCLK_L + TSCLK_H + 2) - * uTemp2 = TSCLK_L + TSCLK_H - */ - t_ftl_cycle = (read32(&hsregs->usi_conf) >> 16) & 0x7; - utemp0 = (clkin / bus_freq_hz) - 8 - 2 * t_ftl_cycle; - - /* CLK_DIV max is 256 */ - for (i = 0; i < 256; i++) { - utemp1 = utemp0 / (i + 1); - if ((utemp1 < 512) && (utemp1 > 4)) { - i2c_bus->clk_cycle = utemp1 - 2; - i2c_bus->clk_div = i; - return 0; - } - } - printk(BIOS_ERR, "%s: failed?\n", __func__); - return -1; -} - -static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus, - unsigned int bus_freq_hz) -{ - struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; - unsigned int t_sr_release; - unsigned int n_clkdiv; - unsigned int t_start_su, t_start_hd; - unsigned int t_stop_su; - unsigned int t_data_su, t_data_hd; - unsigned int t_scl_l, t_scl_h; - u32 i2c_timing_s1; - u32 i2c_timing_s2; - u32 i2c_timing_s3; - u32 i2c_timing_sla; - - hsi2c_get_clk_details(i2c_bus, bus_freq_hz); - - n_clkdiv = i2c_bus->clk_div; - t_scl_l = i2c_bus->clk_cycle / 2; - t_scl_h = i2c_bus->clk_cycle / 2; - t_start_su = t_scl_l; - t_start_hd = t_scl_l; - t_stop_su = t_scl_l; - t_data_su = t_scl_l / 2; - t_data_hd = t_scl_l / 2; - t_sr_release = i2c_bus->clk_cycle; - - i2c_timing_s1 = t_start_su << 24 | t_start_hd << 16 | t_stop_su << 8; - i2c_timing_s2 = t_data_su << 24 | t_scl_l << 8 | t_scl_h << 0; - i2c_timing_s3 = n_clkdiv << 16 | t_sr_release << 0; - i2c_timing_sla = t_data_hd << 0; - - write32(HSI2C_TRAILING_COUNT, &hsregs->usi_trailing_ctl); - - /* Clear to enable Timeout */ - clrsetbits_le32(&hsregs->usi_timeout, HSI2C_TIMEOUT_EN, 0); - - write32(read32(&hsregs->usi_conf) | HSI2C_AUTO_MODE, &hsregs->usi_conf); - - /* Currently operating in Fast speed mode. */ - write32(i2c_timing_s1, &hsregs->usi_timing_fs1); - write32(i2c_timing_s2, &hsregs->usi_timing_fs2); - write32(i2c_timing_s3, &hsregs->usi_timing_fs3); - write32(i2c_timing_sla, &hsregs->usi_timing_sla); - - /* Enable TXFIFO and RXFIFO */ - write32(HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN, &hsregs->usi_fifo_ctl); - - /* i2c_conf configure */ - write32(readl(&hsregs->usi_conf) | HSI2C_AUTO_MODE, &hsregs->usi_conf); -} - -/* SW reset for the high speed bus */ -static void i2c_reset(struct s3c24x0_i2c_bus *i2c_bus) -{ - struct exynos5_hsi2c *i2c = i2c_bus->hsregs; - u32 i2c_ctl; - - /* Set and clear the bit for reset */ - i2c_ctl = read32(&i2c->usi_ctl); - i2c_ctl |= HSI2C_SW_RST; - write32(i2c_ctl, &i2c->usi_ctl); - - i2c_ctl = read32(&i2c->usi_ctl); - i2c_ctl &= ~HSI2C_SW_RST; - write32(i2c_ctl, &i2c->usi_ctl); - - /* Initialize the configure registers */ - /* FIXME: This just assumes 100KHz as a default bus freq */ - hsi2c_ch_init(i2c_bus, 100000); -} - -void i2c_init(unsigned bus_num, int speed, int slaveadd) -{ - struct s3c24x0_i2c_bus *i2c; - - i2c = &i2c_buses[bus_num]; - - i2c_reset(i2c); - - if (i2c->is_highspeed) - hsi2c_ch_init(i2c, speed); - else - i2c_ch_init(i2c, speed, slaveadd); -} - -/* - * Check whether the transfer is complete. - * Return values: - * 0 - transfer not done - * 1 - transfer finished successfully - * -1 - transfer failed - */ -static int hsi2c_check_transfer(struct exynos5_hsi2c *i2c) -{ - uint32_t status = read32(&i2c->usi_trans_status); - if (status & (HSI2C_TRANS_ABORT | HSI2C_NO_DEV_ACK | - HSI2C_NO_DEV | HSI2C_TIMEOUT_AUTO)) { - if (status & HSI2C_TRANS_ABORT) - printk(BIOS_ERR, - "%s: Transaction aborted.\n", __func__); - if (status & HSI2C_NO_DEV_ACK) - printk(BIOS_ERR, - "%s: No ack from device.\n", __func__); - if (status & HSI2C_NO_DEV) - printk(BIOS_ERR, - "%s: No response from device.\n", __func__); - if (status & HSI2C_TIMEOUT_AUTO) - printk(BIOS_ERR, - "%s: Transaction time out.\n", __func__); - return -1; - } - return !(status & HSI2C_MASTER_BUSY); -} - -/* - * Wait for the transfer to finish. - * Return values: - * 0 - transfer not done - * 1 - transfer finished successfully - * -1 - transfer failed - */ -static int hsi2c_wait_for_transfer(struct exynos5_hsi2c *i2c) -{ - struct mono_time current, end; - - timer_monotonic_get(¤t); - end = current; - mono_time_add_usecs(&end, HSI2C_TIMEOUT * 1000); - while (mono_time_before(¤t, &end)) { - int ret = hsi2c_check_transfer(i2c); - if (ret) - return ret; - udelay(5); - timer_monotonic_get(¤t); - } - return 0; -} - -static int hsi2c_senddata(struct exynos5_hsi2c *i2c, const uint8_t *data, - int len) -{ - while (!hsi2c_check_transfer(i2c) && len) { - if (!(read32(&i2c->usi_fifo_stat) & HSI2C_TX_FIFO_FULL)) { - write32(*data++, &i2c->usi_txdata); - len--; - } - } - return len ? -1 : 0; -} - -static int hsi2c_recvdata(struct exynos5_hsi2c *i2c, uint8_t *data, int len) -{ - while (!hsi2c_check_transfer(i2c) && len) { - if (!(read32(&i2c->usi_fifo_stat) & HSI2C_RX_FIFO_EMPTY)) { - *data++ = read32(&i2c->usi_rxdata); - len--; - } - } - return len ? -1 : 0; -} - -static int hsi2c_write(struct exynos5_hsi2c *i2c, - unsigned char chip, - unsigned char addr[], - unsigned char alen, - const uint8_t data[], - unsigned short len) -{ - uint32_t i2c_auto_conf; - - if (hsi2c_wait_for_transfer(i2c) != 1) - return -1; - - /* chip address */ - write32(HSI2C_SLV_ADDR_MAS(chip), &i2c->i2c_addr); - - /* usi_ctl enable i2c func, master write configure */ - write32((HSI2C_TXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER), - &i2c->usi_ctl); - - /* auto_conf for write length and stop configure */ - i2c_auto_conf = ((len + alen) | HSI2C_STOP_AFTER_TRANS); - i2c_auto_conf &= ~HSI2C_READ_WRITE; - /* Master run, start xfer */ - i2c_auto_conf |= HSI2C_MASTER_RUN; - write32(i2c_auto_conf, &i2c->usi_auto_conf); - - if (hsi2c_senddata(i2c, addr, alen) || - hsi2c_senddata(i2c, data, len) || - hsi2c_wait_for_transfer(i2c) != 1) { - return -1; - } - - write32(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); - return 0; -} - -static int hsi2c_read(struct exynos5_hsi2c *i2c, - unsigned char chip, - unsigned char addr[], - unsigned char alen, - uint8_t data[], - unsigned short len, - int check) -{ - uint32_t i2c_auto_conf; - - /* start read */ - if (hsi2c_wait_for_transfer(i2c) != 1) - return -1; - - /* chip address */ - write32(HSI2C_SLV_ADDR_MAS(chip), &i2c->i2c_addr); - - /* usi_ctl enable i2c func, master write configure */ - write32((HSI2C_TXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER), - &i2c->usi_ctl); - - /* auto_conf */ - write32(alen | HSI2C_MASTER_RUN | HSI2C_STOP_AFTER_TRANS, - &i2c->usi_auto_conf); - - if (hsi2c_senddata(i2c, addr, alen) || - hsi2c_wait_for_transfer(i2c) != 1) { - return -1; - } - - /* usi_ctl enable i2c func, master WRITE configure */ - write32((HSI2C_RXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER), - &i2c->usi_ctl); - - /* auto_conf, length and stop configure */ - i2c_auto_conf = (len | HSI2C_STOP_AFTER_TRANS | HSI2C_READ_WRITE); - i2c_auto_conf |= HSI2C_MASTER_RUN; - /* Master run, start xfer */ - write32(i2c_auto_conf, &i2c->usi_auto_conf); - - if (hsi2c_recvdata(i2c, data, len) || - hsi2c_wait_for_transfer(i2c) != 1) { - return -1; - } - - write32(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); - return 0; -} - -/* - * cmd_type is 0 for write, 1 for read. - * - * addr_len can take any value from 0-255, it is only limited - * by the char, we could make it larger if needed. If it is - * 0 we skip the address write cycle. - */ -static int i2c_transfer(struct s3c24x0_i2c *i2c, - unsigned char cmd_type, - unsigned char chip, - unsigned char addr[], - unsigned char addr_len, - unsigned char data[], - unsigned short data_len) -{ - int i = 0, result; - struct mono_time current, end; - - if (data == 0 || data_len == 0) { - printk(BIOS_ERR, "i2c_transfer: bad call\n"); - return I2C_NOK; - } - - timer_monotonic_get(¤t); - end = current; - mono_time_add_usecs(&end, I2C_TIMEOUT_MS * 1000); - while (readl(&i2c->iicstat) & I2CSTAT_BSY) { - if (!mono_time_before(¤t, &end)){ - printk(BIOS_ERR, "%s timed out\n", __func__); - return I2C_NOK_TOUT; - } - timer_monotonic_get(¤t); - } - - write32(read32(&i2c->iiccon) | I2CCON_ACKGEN, &i2c->iiccon); - - /* Get the slave chip address going */ - write32(chip, &i2c->iicds); - if ((cmd_type == I2C_WRITE) || (addr && addr_len)) - write32(I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP, - &i2c->iicstat); - else - write32(I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP, - &i2c->iicstat); - - /* Wait for chip address to transmit. */ - result = WaitForXfer(i2c); - if (result != I2C_OK) - goto bailout; - - /* If register address needs to be transmitted - do it now. */ - if (addr && addr_len) { - while ((i < addr_len) && (result == I2C_OK)) { - write32(addr[i++], &i2c->iicds); - ReadWriteByte(i2c); - result = WaitForXfer(i2c); - } - i = 0; - if (result != I2C_OK) - goto bailout; - } - - switch (cmd_type) { - case I2C_WRITE: - while ((i < data_len) && (result == I2C_OK)) { - write32(data[i++], &i2c->iicds); - ReadWriteByte(i2c); - result = WaitForXfer(i2c); - } - break; - - case I2C_READ: - if (addr && addr_len) { - /* - * Register address has been sent, now send slave chip - * address again to start the actual read transaction. - */ - write32(chip, &i2c->iicds); - - /* Generate a re-START. */ - write32(I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP, - &i2c->iicstat); - ReadWriteByte(i2c); - result = WaitForXfer(i2c); - if (result != I2C_OK) - goto bailout; - } - - while ((i < data_len) && (result == I2C_OK)) { - /* disable ACK for final READ */ - if (i == data_len - 1) - write32(readl(&i2c->iiccon) - & ~I2CCON_ACKGEN, - &i2c->iiccon); - ReadWriteByte(i2c); - result = WaitForXfer(i2c); - data[i++] = read32(&i2c->iicds); - } - if (result == I2C_NACK) - result = I2C_OK; /* Normal terminated read. */ - break; - - default: - printk(BIOS_ERR, "i2c_transfer: bad call\n"); - result = I2C_NOK; - break; - } - -bailout: - /* Send STOP. */ - write32(I2C_MODE_MR | I2C_TXRX_ENA, &i2c->iicstat); - ReadWriteByte(i2c); - - return result; -} - -int i2c_read(unsigned bus, unsigned chip, unsigned addr, - unsigned alen, uint8_t *buf, unsigned len) -{ - struct s3c24x0_i2c_bus *i2c; - unsigned char xaddr[4]; - int ret; - - if (alen > 4) { - printk(BIOS_ERR, "I2C read: addr len %d not supported\n", alen); - return 1; - } - - if (alen > 0) { - xaddr[0] = (addr >> 24) & 0xFF; - xaddr[1] = (addr >> 16) & 0xFF; - xaddr[2] = (addr >> 8) & 0xFF; - xaddr[3] = addr & 0xFF; - } - - i2c = &i2c_buses[bus]; - if (i2c->is_highspeed) - ret = hsi2c_read(i2c->hsregs, chip, &xaddr[4 - alen], - alen, buf, len, 0); - else - ret = i2c_transfer(i2c->regs, I2C_READ, chip << 1, - &xaddr[4 - alen], alen, buf, len); - if (ret) { - i2c_reset(i2c); - printk(BIOS_ERR, "I2C read (bus %02x, chip addr %02x) failed: " - "%d\n", bus, chip, ret); - return 1; - } - return 0; -} - -int i2c_write(unsigned bus, unsigned chip, unsigned addr, - unsigned alen, const uint8_t *buf, unsigned len) -{ - struct s3c24x0_i2c_bus *i2c; - unsigned char xaddr[4]; - int ret; - - if (alen > 4) { - printk(BIOS_ERR, "I2C write: addr len %d not supported\n", - alen); - return 1; - } - - if (alen > 0) { - xaddr[0] = (addr >> 24) & 0xFF; - xaddr[1] = (addr >> 16) & 0xFF; - xaddr[2] = (addr >> 8) & 0xFF; - xaddr[3] = addr & 0xFF; - } - - i2c = &i2c_buses[bus]; - if (i2c->is_highspeed) - ret = hsi2c_write(i2c->hsregs, chip, &xaddr[4 - alen], - alen, buf, len); - else - ret = i2c_transfer(i2c->regs, I2C_WRITE, chip << 1, - &xaddr[4 - alen], alen, (void *)buf, len); - - - if (ret != 0) { - i2c_reset(i2c); - printk(BIOS_ERR, "I2C write (bus %02x, chip addr %02x) failed: " - "%d\n", bus, chip, ret); - return 1; - } - return 0; -} diff --git a/src/cpu/samsung/exynos5420/i2c.h b/src/cpu/samsung/exynos5420/i2c.h deleted file mode 100644 index e8fe8201db..0000000000 --- a/src/cpu/samsung/exynos5420/i2c.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_I2C_H -#define CPU_SAMSUNG_EXYNOS5420_I2C_H - -#include "periph.h" - -struct s3c24x0_i2c { - u32 iiccon; - u32 iicstat; - u32 iicadd; - u32 iicds; - u32 iiclc; -} __attribute__ ((packed)); - -struct exynos5_hsi2c { - u32 usi_ctl; - u32 usi_fifo_ctl; - u32 usi_trailing_ctl; - u32 usi_clk_ctl; - u32 usi_clk_slot; - u32 spi_ctl; - u32 uart_ctl; - u32 res1; - u32 usi_int_en; - u32 usi_int_stat; - u32 usi_modem_stat; - u32 usi_error_stat; - u32 usi_fifo_stat; - u32 usi_txdata; - u32 usi_rxdata; - u32 res2; - u32 usi_conf; - u32 usi_auto_conf; - u32 usi_timeout; - u32 usi_manual_cmd; - u32 usi_trans_status; - u32 usi_timing_hs1; - u32 usi_timing_hs2; - u32 usi_timing_hs3; - u32 usi_timing_fs1; - u32 usi_timing_fs2; - u32 usi_timing_fs3; - u32 usi_timing_sla; - u32 i2c_addr; -} __attribute__ ((packed)); - -struct s3c24x0_i2c_bus { - int bus_num; - struct s3c24x0_i2c *regs; - enum periph_id periph_id; - struct exynos5_hsi2c *hsregs; - int is_highspeed; /* High speed type, rather than I2C */ - int id; - unsigned clk_cycle; - unsigned clk_div; -}; - -void i2c_init(unsigned bus, int speed, int slaveadd); - -#endif /* CPU_SAMSUNG_EXYNOS5420_I2C_H */ diff --git a/src/cpu/samsung/exynos5420/i2s-regs.h b/src/cpu/samsung/exynos5420/i2s-regs.h deleted file mode 100644 index 28d2685c63..0000000000 --- a/src/cpu/samsung/exynos5420/i2s-regs.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Taken from the kernel code */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_I2S_REGS_H -#define CPU_SAMSUNG_EXYNOS5420_I2S_REGS_H - -#define I2SCON 0x0 -#define I2SMOD 0x4 -#define I2SFIC 0x8 -#define I2SPSR 0xc -#define I2STXD 0x10 -#define I2SRXD 0x14 -#define I2SFICS 0x18 -#define I2STXDS 0x1c -#define I2SAHB 0x20 -#define I2SSTR0 0x24 -#define I2SSIZE 0x28 -#define I2STRNCNT 0x2c -#define I2SLVL0ADDR 0x30 -#define I2SLVL1ADDR 0x34 -#define I2SLVL2ADDR 0x38 -#define I2SLVL3ADDR 0x3c - -#define CON_RSTCLR (1 << 31) -#define CON_FRXOFSTATUS (1 << 26) -#define CON_FRXORINTEN (1 << 25) -#define CON_FTXSURSTAT (1 << 24) -#define CON_FTXSURINTEN (1 << 23) -#define CON_TXSDMA_PAUSE (1 << 20) -#define CON_TXSDMA_ACTIVE (1 << 18) - -#define CON_FTXURSTATUS (1 << 17) -#define CON_FTXURINTEN (1 << 16) -#define CON_TXFIFO2_EMPTY (1 << 15) -#define CON_TXFIFO1_EMPTY (1 << 14) -#define CON_TXFIFO2_FULL (1 << 13) -#define CON_TXFIFO1_FULL (1 << 12) - -#define CON_LRINDEX (1 << 11) -#define CON_TXFIFO_EMPTY (1 << 10) -#define CON_RXFIFO_EMPTY (1 << 9) -#define CON_TXFIFO_FULL (1 << 8) -#define CON_RXFIFO_FULL (1 << 7) -#define CON_TXDMA_PAUSE (1 << 6) -#define CON_RXDMA_PAUSE (1 << 5) -#define CON_TXCH_PAUSE (1 << 4) -#define CON_RXCH_PAUSE (1 << 3) -#define CON_TXDMA_ACTIVE (1 << 2) -#define CON_RXDMA_ACTIVE (1 << 1) -#define CON_ACTIVE (1 << 0) - -#define MOD_OPCLK_CDCLK_OUT (0 << 30) -#define MOD_OPCLK_CDCLK_IN (1 << 30) -#define MOD_OPCLK_BCLK_OUT (2 << 30) -#define MOD_OPCLK_PCLK (3 << 30) -#define MOD_OPCLK_MASK (3 << 30) -#define MOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */ - -#define MOD_BLCS_SHIFT 26 -#define MOD_BLCS_16BIT (0 << MOD_BLCS_SHIFT) -#define MOD_BLCS_8BIT (1 << MOD_BLCS_SHIFT) -#define MOD_BLCS_24BIT (2 << MOD_BLCS_SHIFT) -#define MOD_BLCS_MASK (3 << MOD_BLCS_SHIFT) - -#define MOD_BLCP_SHIFT 24 -#define MOD_BLCP_16BIT (0 << MOD_BLCP_SHIFT) -#define MOD_BLCP_8BIT (1 << MOD_BLCP_SHIFT) -#define MOD_BLCP_24BIT (2 << MOD_BLCP_SHIFT) -#define MOD_BLCP_MASK (3 << MOD_BLCP_SHIFT) - -#define MOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */ -#define MOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */ -#define MOD_C1DD_HHALF (1 << 19) -#define MOD_C1DD_LHALF (1 << 18) -#define MOD_DC2_EN (1 << 17) -#define MOD_DC1_EN (1 << 16) -#define MOD_BLC_16BIT (0 << 13) -#define MOD_BLC_8BIT (1 << 13) -#define MOD_BLC_24BIT (2 << 13) -#define MOD_BLC_MASK (3 << 13) - -#define MOD_IMS_SYSMUX (1 << 10) -#define MOD_SLAVE (1 << 11) -#define MOD_TXONLY (0 << 8) -#define MOD_RXONLY (1 << 8) -#define MOD_TXRX (2 << 8) -#define MOD_MASK (3 << 8) -#define MOD_LR_LLOW (0 << 7) -#define MOD_LR_RLOW (1 << 7) -#define MOD_SDF_IIS (0 << 5) -#define MOD_SDF_MSB (1 << 5) -#define MOD_SDF_LSB (2 << 5) -#define MOD_SDF_MASK (3 << 5) -#define MOD_RCLK_256FS (0 << 3) -#define MOD_RCLK_512FS (1 << 3) -#define MOD_RCLK_384FS (2 << 3) -#define MOD_RCLK_768FS (3 << 3) -#define MOD_RCLK_MASK (3 << 3) -#define MOD_BCLK_32FS (0 << 1) -#define MOD_BCLK_48FS (1 << 1) -#define MOD_BCLK_16FS (2 << 1) -#define MOD_BCLK_24FS (3 << 1) -#define MOD_BCLK_MASK (3 << 1) -#define MOD_8BIT (1 << 0) - -#define MOD_CDCLKCON (1 << 12) - -#define PSR_PSREN (1 << 15) - -#define FIC_TXFLUSH (1 << 15) -#define FIC_RXFLUSH (1 << 7) - -#define AHB_INTENLVL0 (1 << 24) -#define AHB_LVL0INT (1 << 20) -#define AHB_CLRLVL0INT (1 << 16) -#define AHB_DMARLD (1 << 5) -#define AHB_INTMASK (1 << 3) -#define AHB_DMAEN (1 << 0) -#define AHB_LVLINTMASK (0xf << 20) - -#define I2SSIZE_TRNMSK (0xffff) -#define I2SSIZE_SHIFT (16) - -#endif /* CPU_SAMSUNG_EXYNOS5420_I2S_REGS_H */ diff --git a/src/cpu/samsung/exynos5420/mct.c b/src/cpu/samsung/exynos5420/mct.c deleted file mode 100644 index bbb90e49bb..0000000000 --- a/src/cpu/samsung/exynos5420/mct.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2012 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdint.h> -#include <arch/io.h> -#include "clk.h" - -uint64_t mct_raw_value(void) -{ - uint64_t upper = readl(&exynos_mct->g_cnt_u); - uint64_t lower = readl(&exynos_mct->g_cnt_l); - - return (upper << 32) | lower; -} - -void mct_start(void) -{ - writel(readl(&exynos_mct->g_tcon) | (0x1 << 8), - &exynos_mct->g_tcon); -} diff --git a/src/cpu/samsung/exynos5420/monotonic_timer.c b/src/cpu/samsung/exynos5420/monotonic_timer.c deleted file mode 100644 index 89ac416eb1..0000000000 --- a/src/cpu/samsung/exynos5420/monotonic_timer.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdint.h> -#include <timer.h> - -#include "clk.h" - -static const uint32_t clocks_per_usec = MCT_HZ/1000000; - -void timer_monotonic_get(struct mono_time *mt) -{ - /* We don't have to call mct_start() here - * because it was already called in the bootblock - */ - - mono_time_set_usecs(mt, mct_raw_value() / clocks_per_usec); -} diff --git a/src/cpu/samsung/exynos5420/periph.h b/src/cpu/samsung/exynos5420/periph.h deleted file mode 100644 index 94f150e6dd..0000000000 --- a/src/cpu/samsung/exynos5420/periph.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2012 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_PERIPH_H -#define CPU_SAMSUNG_EXYNOS5420_PERIPH_H - -/* - * Peripherals requiring clock/pinmux configuration. List will - * grow with support for more devices getting added. - * - * At present the order is arbitrary - we may be able to take advantage - * of some orthogonality later. - */ -enum periph_id { - PERIPH_ID_UART0, - PERIPH_ID_UART1, - PERIPH_ID_UART2, - PERIPH_ID_UART3, - PERIPH_ID_SDMMC0, - PERIPH_ID_SDMMC1, - PERIPH_ID_SDMMC2, - PERIPH_ID_SDMMC3, - - PERIPH_ID_SROMC = 9, - PERIPH_ID_SPI0, - PERIPH_ID_SPI1, - PERIPH_ID_SPI2, - PERIPH_ID_SPI3, - PERIPH_ID_SPI4, - PERIPH_ID_LCD, - PERIPH_ID_BACKLIGHT, - PERIPH_ID_I2C0, - PERIPH_ID_I2C1, - PERIPH_ID_I2C2, - PERIPH_ID_I2C3, - PERIPH_ID_I2C4, - PERIPH_ID_I2C5, - PERIPH_ID_I2C6, - PERIPH_ID_I2C7, - PERIPH_ID_I2C8, - PERIPH_ID_I2C9, - PERIPH_ID_I2C10, - PERIPH_ID_DPHPD, /* eDP hot plug detect */ - PERIPH_ID_PWM0, - PERIPH_ID_PWM1, - PERIPH_ID_PWM2, - PERIPH_ID_PWM3, - PERIPH_ID_PWM4, - PERIPH_ID_I2S1, - PERIPH_ID_SATA, - - PERIPH_ID_COUNT, - PERIPH_ID_NONE = -1, -}; - -#endif diff --git a/src/cpu/samsung/exynos5420/pinmux.c b/src/cpu/samsung/exynos5420/pinmux.c deleted file mode 100644 index 43a4332503..0000000000 --- a/src/cpu/samsung/exynos5420/pinmux.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <console/console.h> -#include <assert.h> -#include <stdlib.h> -#include "gpio.h" -#include "pinmux.h" - -static void exynos_pinmux_uart(int start, int count) -{ - int i; - - for (i = start; i < start + count; i++) { - gpio_set_pull(i, GPIO_PULL_NONE); - gpio_cfg_pin(i, GPIO_FUNC(0x2)); - } -} - -void exynos_pinmux_uart0(void) -{ - exynos_pinmux_uart(GPIO_A00, 4); -} - -void exynos_pinmux_uart1(void) -{ - exynos_pinmux_uart(GPIO_A04, 4); -} - -void exynos_pinmux_uart2(void) -{ - exynos_pinmux_uart(GPIO_A10, 4); -} - -void exynos_pinmux_uart3(void) -{ - exynos_pinmux_uart(GPIO_A14, 2); -} - -struct gpio { - enum exynos5_gpio_pin pin; - unsigned int func; - unsigned int pull; - unsigned int drv; -}; - -static void exynos_pinmux_sdmmc(struct gpio *gpios, int num_gpios) -{ - int i; - - for (i = 0; i < num_gpios; i++) { - gpio_set_drv(gpios[i].pin, gpios[i].drv); - gpio_set_pull(gpios[i].pin, gpios[i].pull); - gpio_cfg_pin(gpios[i].pin, GPIO_FUNC(gpios[i].func)); - } -} - -void exynos_pinmux_sdmmc0(void) -{ - struct gpio gpios[] = { - { GPIO_C00, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* CLK */ - { GPIO_C01, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* CMD */ - /* - * MMC0 is intended to be used for eMMC. The card detect - * pin is used as a VDDEN signal to power on the eMMC. The - * 5420 iROM makes this same assumption. - */ - { GPIO_C02, GPIO_OUTPUT, GPIO_PULL_NONE, GPIO_DRV_4X }, - { GPIO_C03, 0x2, GPIO_PULL_UP, GPIO_DRV_4X }, /* DATA[0] */ - { GPIO_C04, 0x2, GPIO_PULL_UP, GPIO_DRV_4X }, /* DATA[1] */ - { GPIO_C05, 0x2, GPIO_PULL_UP, GPIO_DRV_4X }, /* DATA[2] */ - { GPIO_C06, 0x2, GPIO_PULL_UP, GPIO_DRV_4X }, /* DATA[3] */ - - { GPIO_C30, 0x2, GPIO_PULL_UP, GPIO_DRV_4X }, /* DATA[4] */ - { GPIO_C31, 0x2, GPIO_PULL_UP, GPIO_DRV_4X }, /* DATA[5] */ - { GPIO_C32, 0x2, GPIO_PULL_UP, GPIO_DRV_4X }, /* DATA[6] */ - { GPIO_C33, 0x2, GPIO_PULL_UP, GPIO_DRV_4X }, /* DATA[7] */ - }; - - exynos_pinmux_sdmmc(&gpios[0], ARRAY_SIZE(gpios)); - - /* set VDDEN */ - gpio_set_value(GPIO_C02, 1); -} - -void exynos_pinmux_sdmmc1(void) -{ - struct gpio gpios[] = { - { GPIO_C10, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* CLK */ - { GPIO_C11, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* CMD */ - { GPIO_C12, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* CDn */ - { GPIO_C13, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* DATA[0] */ - { GPIO_C14, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* DATA[1] */ - { GPIO_C15, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* DATA[2] */ - { GPIO_C16, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* DATA[3] */ - - { GPIO_D14, 0x2, GPIO_PULL_UP, GPIO_DRV_4X }, /* DATA[4] */ - { GPIO_D15, 0x2, GPIO_PULL_UP, GPIO_DRV_4X }, /* DATA[5] */ - { GPIO_D16, 0x2, GPIO_PULL_UP, GPIO_DRV_4X }, /* DATA[6] */ - { GPIO_D17, 0x2, GPIO_PULL_UP, GPIO_DRV_4X }, /* DATA[7] */ - }; - - exynos_pinmux_sdmmc(&gpios[0], ARRAY_SIZE(gpios)); -} - -void exynos_pinmux_sdmmc2(void) -{ - struct gpio gpios[] = { - { GPIO_C20, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* CLK */ - { GPIO_C21, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* CMD */ - { GPIO_C22, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* CDn */ - { GPIO_C23, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* DATA[0] */ - { GPIO_C24, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* DATA[1] */ - { GPIO_C25, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* DATA[2] */ - { GPIO_C26, 0x2, GPIO_PULL_NONE, GPIO_DRV_4X }, /* DATA[3] */ - }; - - exynos_pinmux_sdmmc(&gpios[0], ARRAY_SIZE(gpios)); -} - -static void exynos_pinmux_spi(int start, int cfg) -{ - int i; - - for (i = start; i < start + 4; i++) { - gpio_cfg_pin(i, cfg); - gpio_set_pull(i, GPIO_PULL_NONE); - gpio_set_drv(i, GPIO_DRV_3X); - } -} - -void exynos_pinmux_spi0(void) -{ - exynos_pinmux_spi(GPIO_A20, 0x2); -} - -void exynos_pinmux_spi1(void) -{ - exynos_pinmux_spi(GPIO_A24, 0x2); -} - -void exynos_pinmux_spi2(void) -{ - exynos_pinmux_spi(GPIO_B11, 0x5); -} - -void exynos_pinmux_spi3(void) -{ - exynos_pinmux_spi(GPIO_F10, 0x2); -} - -void exynos_pinmux_spi4(void) -{ - int i; - - for (i = 0; i < 2; i++) { - gpio_cfg_pin(GPIO_F02 + i, GPIO_FUNC(0x4)); - gpio_cfg_pin(GPIO_E04 + i, GPIO_FUNC(0x4)); - } -} - -static void exynos_pinmux_i2c(int start, int func) -{ - gpio_cfg_pin(start, GPIO_FUNC(func)); - gpio_cfg_pin(start + 1, GPIO_FUNC(func)); - gpio_set_pull(start, GPIO_PULL_NONE); - gpio_set_pull(start + 1, GPIO_PULL_NONE); -} - -void exynos_pinmux_i2c0(void) -{ - exynos_pinmux_i2c(GPIO_B30, 0x2); -} - -void exynos_pinmux_i2c1(void) -{ - exynos_pinmux_i2c(GPIO_B32, 0x2); -} - -void exynos_pinmux_i2c2(void) -{ - exynos_pinmux_i2c(GPIO_A06, 0x3); -} - -void exynos_pinmux_i2c3(void) -{ - exynos_pinmux_i2c(GPIO_A12, 0x3); -} - -void exynos_pinmux_i2c4(void) -{ - exynos_pinmux_i2c(GPIO_A20, 0x3); -} - -void exynos_pinmux_i2c5(void) -{ - exynos_pinmux_i2c(GPIO_A22, 0x3); -} - -void exynos_pinmux_i2c6(void) -{ - exynos_pinmux_i2c(GPIO_B13, 0x4); -} - -void exynos_pinmux_i2c7(void) -{ - exynos_pinmux_i2c(GPIO_B22, 0x3); -} - -void exynos_pinmux_i2c8(void) -{ - exynos_pinmux_i2c(GPIO_B34, 0x2); -} - -void exynos_pinmux_i2c9(void) -{ - exynos_pinmux_i2c(GPIO_B36, 0x2); -} - -void exynos_pinmux_i2c10(void) -{ - exynos_pinmux_i2c(GPIO_B40, 0x2); -} - -void exynos_pinmux_dphpd(void) -{ - gpio_cfg_pin(GPIO_X07, GPIO_FUNC(0x3)); - gpio_set_pull(GPIO_X07, GPIO_PULL_NONE); -} diff --git a/src/cpu/samsung/exynos5420/pinmux.h b/src/cpu/samsung/exynos5420/pinmux.h deleted file mode 100644 index fc09fc95fb..0000000000 --- a/src/cpu/samsung/exynos5420/pinmux.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_PINMUX_H -#define CPU_SAMSUNG_EXYNOS5420_PINMUX_H - -void exynos_pinmux_uart0(void); -void exynos_pinmux_uart1(void); -void exynos_pinmux_uart2(void); -void exynos_pinmux_uart3(void); - -void exynos_pinmux_sdmmc0(void); -void exynos_pinmux_sdmmc1(void); -void exynos_pinmux_sdmmc2(void); -void exynos_pinmux_sdmmc3(void); - -void exynos_pinmux_spi0(void); -void exynos_pinmux_spi1(void); -void exynos_pinmux_spi2(void); -void exynos_pinmux_spi3(void); -void exynos_pinmux_spi4(void); - -void exynos_pinmux_i2c0(void); -void exynos_pinmux_i2c1(void); -void exynos_pinmux_i2c2(void); -void exynos_pinmux_i2c3(void); -void exynos_pinmux_i2c4(void); -void exynos_pinmux_i2c5(void); -void exynos_pinmux_i2c6(void); -void exynos_pinmux_i2c7(void); -void exynos_pinmux_i2c8(void); -void exynos_pinmux_i2c9(void); -void exynos_pinmux_i2c10(void); - -void exynos_pinmux_dphpd(void); - -#endif diff --git a/src/cpu/samsung/exynos5420/power.c b/src/cpu/samsung/exynos5420/power.c deleted file mode 100644 index ecaf208c9c..0000000000 --- a/src/cpu/samsung/exynos5420/power.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Power setup code for EXYNOS5 */ - -#include <arch/io.h> -#include <arch/hlt.h> -#include <console/console.h> -#include "dmc.h" -#include "power.h" -#include "setup.h" - -void ps_hold_setup(void) -{ - /* Set PS-Hold high */ - setbits_le32(&exynos_power->ps_hold_ctrl, - POWER_PS_HOLD_CONTROL_DATA_HIGH); -} - -void power_reset(void) -{ - /* Clear inform1 so there's no change we think we've got a wake reset */ - exynos_power->inform1 = 0; - - setbits_le32(&exynos_power->sw_reset, 1); -} - -/* This function never returns */ -void power_shutdown(void) -{ - clrbits_le32(&exynos_power->ps_hold_ctrl, - POWER_PS_HOLD_CONTROL_DATA_HIGH); - - hlt(); -} - -void power_enable_dp_phy(void) -{ - setbits_le32(&exynos_power->dptx_phy_control, EXYNOS_DP_PHY_ENABLE); -} - -void power_enable_hw_thermal_trip(void) -{ - /* Enable HW thermal trip */ - setbits_le32(&exynos_power->ps_hold_ctrl, POWER_ENABLE_HW_TRIP); -} - -uint32_t power_read_reset_status(void) -{ - return exynos_power->inform1; -} - -void power_exit_wakeup(void) -{ - typedef void (*resume_func)(void); - - ((resume_func)exynos_power->inform0)(); -} - -int power_init(void) -{ - ps_hold_setup(); - return 0; -} - -void power_enable_xclkout(void) -{ - /* use xxti for xclk out */ - clrsetbits_le32(&exynos_power->pmu_debug, PMU_DEBUG_CLKOUT_SEL_MASK, - PMU_DEBUG_XXTI); -} - -void power_release_uart_retention(void) -{ - writel(1 << 28, &exynos_power->padret_uart_opt); -} diff --git a/src/cpu/samsung/exynos5420/power.h b/src/cpu/samsung/exynos5420/power.h deleted file mode 100644 index fd1eac5768..0000000000 --- a/src/cpu/samsung/exynos5420/power.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Register map for Exynos5 PMU */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_POWER_H -#define CPU_SAMSUNG_EXYNOS5420_POWER_H - -#include "cpu.h" - -/* Enable HW thermal trip with PS_HOLD_CONTROL register ENABLE_HW_TRIP bit */ -void power_enable_hw_thermal_trip(void); - -#define MIPI_PHY1_CONTROL_ENABLE (1 << 0) -#define MIPI_PHY1_CONTROL_M_RESETN (1 << 2) - -#define POWER_USB_PHY_CTRL_EN (1 << 0) -#define POWER_PS_HOLD_CONTROL_DATA_HIGH (1 << 8) -#define POWER_ENABLE_HW_TRIP (1UL << 31) - -#define EXYNOS_DP_PHY_ENABLE (1 << 0) - -/* PMU_DEBUG bits [12:8] = 0x1000 selects XXTI clock source */ -#define PMU_DEBUG_XXTI 0x1000 -/* Mask bit[12:8] for xxti clock selection */ -#define PMU_DEBUG_CLKOUT_SEL_MASK 0x1f00 - -/* Power Management Unit register map */ -struct exynos5_power { - /* Add registers as and when required */ - uint32_t om_stat; /* 0x0000 */ - uint8_t reserved1[0x03fc]; - uint32_t sw_reset; /* 0x0400 */ - uint8_t reserved2[0x0300]; - uint32_t usb_drd0_phy_ctrl; /* 0x0704 */ - uint32_t usb_drd1_phy_ctrl; /* 0x0708 */ - uint32_t usb_host_phy_ctrl; /* 0x070c */ - uint8_t reserved3[0x4]; - uint32_t mipi_phy1_control; /* 0x0714 */ - uint8_t reserved4[0x8]; - uint32_t dptx_phy_control; /* 0x0720 */ - uint8_t reserved5[0xdc]; - uint32_t inform0; /* 0x0800 */ - uint32_t inform1; /* 0x0804 */ - uint8_t reserved6[0x0f8]; - uint32_t spare0; /* 0x0900 */ - uint8_t reserved7[0x0fc]; - uint32_t pmu_debug; /* 0x0a00 */ - uint8_t reserved8[0x15fc]; - struct { /* 0x2000 */ - uint32_t config; /* 0x00 */ - uint32_t status; /* 0x04 */ - uint8_t reserved[0x78]; - } arm_core[4]; - uint8_t reserved9[0xe04]; - uint32_t padret_dram_status; /* 0x3004 */ - uint8_t reservedA[0xe0]; - uint32_t padret_uart_opt; /* 0x30e8 */ - uint8_t reservedB[0xfc]; - uint32_t padret_dram_cblk_opt; /* 0x31e8 */ - uint8_t reservedC[0x120]; - uint32_t ps_hold_ctrl; /* 0x330c */ -} __attribute__ ((__packed__)); - -static struct exynos5_power * const exynos_power = (void*)EXYNOS5_POWER_BASE; - -/** - * Perform a software reset. - */ -void power_reset(void); - -/** - * Power off the system; it should never return. - */ -void power_shutdown(void); - -/* Enable DPTX PHY */ -void power_enable_dp_phy(void); - -/* Initialize the pmic voltages to power up the system */ -int power_init(void); - -/* Read the reset status. */ -uint32_t power_read_reset_status(void); - -/* Read the resume function and call it. */ -void power_exit_wakeup(void); - -/* pmu debug is used for xclkout, enable xclkout with source as XXTI */ -void power_enable_xclkout(void); - -/* Release UART retention on resume (only for debugging, may conflict with - * kernel). */ -void power_release_uart_retention(void); - -#endif diff --git a/src/cpu/samsung/exynos5420/setup.h b/src/cpu/samsung/exynos5420/setup.h deleted file mode 100644 index 63e40a8f0f..0000000000 --- a/src/cpu/samsung/exynos5420/setup.h +++ /dev/null @@ -1,888 +0,0 @@ - /* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Machine Specific Values for SMDK5420 board based on Exynos5 */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_SETUP_H -#define CPU_SAMSUNG_EXYNOS5420_SETUP_H - -struct exynos5_dmc; -enum ddr_mode; -struct exynos5_phy_control; - -#define NOT_AVAILABLE 0 -#define DATA_MASK 0xFFFFF - -#define ENABLE_BIT 0x1 -#define DISABLE_BIT 0x0 -#define CA_SWAP_EN (1 << 0) - -/* TZPC : Register Offsets */ -#define TZPC0_BASE 0x10100000 -#define TZPC1_BASE 0x10110000 -#define TZPC2_BASE 0x10120000 -#define TZPC3_BASE 0x10130000 -#define TZPC4_BASE 0x10140000 -#define TZPC5_BASE 0x10150000 -#define TZPC6_BASE 0x10160000 -#define TZPC7_BASE 0x10170000 -#define TZPC8_BASE 0x10180000 -#define TZPC9_BASE 0x10190000 - -#define APLL_FOUT (1 << 0) -#define KPLL_FOUT (1 << 0) - -#define CLK_DIV_CPERI1_VAL 0x3f3f0000 - -/* APLL_CON1 */ -#define APLL_CON1_VAL (0x0020f300) - -/* MPLL_CON1 */ -#define MPLL_CON1_VAL (0x0020f300) - -/* CPLL_CON1 */ -#define CPLL_CON1_VAL (0x0020f300) - -/* DPLL_CON1 */ -#define DPLL_CON1_VAL (0x0020f300) - -/* GPLL_CON1 */ -#define GPLL_CON1_VAL (NOT_AVAILABLE) - -/* EPLL_CON1, CON2 */ -#define EPLL_CON1_VAL 0x00000000 -#define EPLL_CON2_VAL 0x00000080 - -/* VPLL_CON1, CON2 */ -#define VPLL_CON1_VAL 0x0020f300 -#define VPLL_CON2_VAL NOT_AVAILABLE - -/* RPLL_CON1, CON2 */ -#define RPLL_CON1_VAL 0x00000000 -#define RPLL_CON2_VAL 0x00000080 - -/* BPLL_CON1 */ -#define BPLL_CON1_VAL 0x0020f300 - -/* SPLL_CON1 */ -#define SPLL_CON1_VAL 0x0020f300 - -/* IPLL_CON1 */ -#define IPLL_CON1_VAL 0x00000080 - -/* KPLL_CON1 */ -#define KPLL_CON1_VAL 0x200000 - -/* Set PLL */ -#define set_pll(mdiv, pdiv, sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv) - -/* CLK_SRC_CPU */ -/* 0 = MOUTAPLL, 1 = SCLKMPLL */ -#define MUX_HPM_SEL 1 -#define MUX_CPU_SEL 0 -#define MUX_APLL_SEL 1 - -#define CLK_SRC_CPU_VAL ((MUX_HPM_SEL << 20) \ - | (MUX_CPU_SEL << 16) \ - | (MUX_APLL_SEL)) - -/* MEMCONTROL register bit fields */ -#define DMC_MEMCONTROL_CLK_STOP_DISABLE (0 << 0) -#define DMC_MEMCONTROL_DPWRDN_DISABLE (0 << 1) -#define DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE (0 << 2) -#define DMC_MEMCONTROL_DSREF_DISABLE (0 << 5) -#define DMC_MEMCONTROL_DSREF_ENABLE (1 << 5) -#define DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(x) (x << 6) - -#define DMC_MEMCONTROL_MEM_TYPE_LPDDR3 (7 << 8) -#define DMC_MEMCONTROL_MEM_TYPE_DDR3 (6 << 8) -#define DMC_MEMCONTROL_MEM_TYPE_LPDDR2 (5 << 8) - -#define DMC_MEMCONTROL_MEM_WIDTH_32BIT (2 << 12) - -#define DMC_MEMCONTROL_NUM_CHIP_1 (0 << 16) -#define DMC_MEMCONTROL_NUM_CHIP_2 (1 << 16) - -#define DMC_MEMCONTROL_BL_8 (3 << 20) -#define DMC_MEMCONTROL_BL_4 (2 << 20) - -#define DMC_MEMCONTROL_PZQ_DISABLE (0 << 24) - -#define DMC_MEMCONTROL_MRR_BYTE_7_0 (0 << 25) -#define DMC_MEMCONTROL_MRR_BYTE_15_8 (1 << 25) -#define DMC_MEMCONTROL_MRR_BYTE_23_16 (2 << 25) -#define DMC_MEMCONTROL_MRR_BYTE_31_24 (3 << 25) - -/* MEMCONFIG0 register bit fields */ -#define DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED (1 << 12) -#define DMC_MEMCONFIG_CHIP_MAP_SPLIT (2 << 12) -#define DMC_MEMCONFIGx_CHIP_COL_10 (3 << 8) -#define DMC_MEMCONFIGx_CHIP_ROW_14 (2 << 4) -#define DMC_MEMCONFIGx_CHIP_ROW_15 (3 << 4) -#define DMC_MEMCONFIGx_CHIP_ROW_16 (4 << 4) -#define DMC_MEMCONFIGx_CHIP_BANK_8 (3 << 0) - -#define DMC_MEMBASECONFIG0_VAL DMC_MEMBASECONFIG_VAL(0x40) -#define DMC_MEMBASECONFIG1_VAL DMC_MEMBASECONFIG_VAL(0x80) - -#define DMC_PRECHCONFIG_VAL 0xFF000000 -#define DMC_PWRDNCONFIG_VAL 0xFFFF00FF - -#define DMC_CONCONTROL_RESET_VAL 0x0FFF0000 -#define DFI_INIT_START (1 << 28) -#define EMPTY (1 << 8) -#define AREF_EN (1 << 5) - -#define DFI_INIT_COMPLETE_CHO (1 << 2) -#define DFI_INIT_COMPLETE_CH1 (1 << 3) - -#define RDLVL_COMPLETE_CHO (1 << 14) -#define RDLVL_COMPLETE_CH1 (1 << 15) - -#define CLK_STOP_EN (1 << 0) -#define DPWRDN_EN (1 << 1) -#define DSREF_EN (1 << 5) - -/* COJCONTROL register bit fields */ -#define DMC_CONCONTROL_IO_PD_CON_DISABLE (0 << 3) -#define DMC_CONCONTROL_AREF_EN_DISABLE (0 << 5) -#define DMC_CONCONTROL_RD_FETCH_DISABLE (0x0 << 12) -#define DMC_CONCONTROL_TIMEOUT_LEVEL0 (0xFFF << 16) -#define DMC_CONCONTROL_DFI_INIT_START_DISABLE (0 << 28) - -/* CLK_FSYS */ -#define CLK_SRC_FSYS0_VAL 0x33033300 -#define CLK_DIV_FSYS0_VAL 0x0 -#define CLK_DIV_FSYS1_VAL 0x04f13c4f -#define CLK_DIV_FSYS2_VAL 0x041d0000 - -#define DMC_CONCONTROL_IO_PD_CON(x) (x << 6) - -/* CLK_DIV_CPU1 */ -#define HPM_RATIO 0x2 -#define COPY_RATIO 0x0 - -/* CLK_DIV_CPU1 = 0x00000003 */ -#define CLK_DIV_CPU1_VAL ((HPM_RATIO << 4) \ - | (COPY_RATIO)) - -/* CLK_SRC_CORE0 */ -#define CLK_SRC_CORE0_VAL 0x00000000 - -/* CLK_SRC_CORE1 */ -#define CLK_SRC_CORE1_VAL 0x100 - -/* CLK_DIV_CORE0 */ -#define CLK_DIV_CORE0_VAL 0x00120000 - -/* CLK_DIV_CORE1 */ -#define CLK_DIV_CORE1_VAL 0x07070700 - -/* CLK_DIV_SYSRGT */ -#define CLK_DIV_SYSRGT_VAL 0x00000111 - -/* CLK_DIV_ACP */ -#define CLK_DIV_ACP_VAL 0x12 - -/* CLK_DIV_SYSLFT */ -#define CLK_DIV_SYSLFT_VAL 0x00000311 - -/* CLK_SRC_CDREX */ -#define CLK_SRC_CDREX_VAL 0x00000001 -#define MUX_MCLK_CDR_MSPLL (1 << 4) -#define MUX_BPLL_SEL_FOUTBPLL (1 << 0) -#define BPLL_SEL_MASK 0x7 -#define FOUTBPLL 2 - -/* CLK_DIV_CDREX */ -#define CLK_DIV_CDREX0_VAL 0x30010100 -#define CLK_DIV_CDREX1_VAL 0x300 - -#define CLK_DIV_CDREX_VAL 0x17010100 - -/* CLK_DIV_CPU0_VAL */ -#define CLK_DIV_CPU0_VAL 0x01440020 - -/* CLK_SRC_TOP */ -#define CLK_SRC_TOP0_VAL 0x11101102 -#define CLK_SRC_TOP1_VAL 0x00200000 -#define CLK_SRC_TOP2_VAL 0x11101010 -#define CLK_SRC_TOP3_VAL 0x11111111 -#define CLK_SRC_TOP4_VAL 0x11110111 -#define CLK_SRC_TOP5_VAL 0x11111111 -#define CLK_SRC_TOP6_VAL 0x11110111 -#define CLK_SRC_TOP7_VAL 0x00022200 - -/* CLK_DIV_TOP */ -#define CLK_DIV_TOP0_VAL 0x22512211 -#define CLK_DIV_TOP1_VAL 0x13200900 -#define CLK_DIV_TOP2_VAL 0x11101110 - -/* APLL_LOCK */ -#define APLL_LOCK_VAL (0x320) -/* MPLL_LOCK */ -#define MPLL_LOCK_VAL (0x258) -/* BPLL_LOCK */ -#define BPLL_LOCK_VAL (0x258) -/* CPLL_LOCK */ -#define CPLL_LOCK_VAL (0x190) -/* DPLL_LOCK */ -#define DPLL_LOCK_VAL (0x190) -/* GPLL_LOCK */ -#define GPLL_LOCK_VAL NOT_AVAILABLE -/* IPLL_LOCK */ -#define IPLL_LOCK_VAL (0x320) -/* KPLL_LOCK */ -#define KPLL_LOCK_VAL (0x258) -/* SPLL_LOCK */ -#define SPLL_LOCK_VAL (0x320) -/* RPLL_LOCK */ -#define RPLL_LOCK_VAL (0x2328) -/* EPLL_LOCK */ -#define EPLL_LOCK_VAL (0x2328) -/* VPLL_LOCK */ -#define VPLL_LOCK_VAL (0x258) - -#define MUX_APLL_SEL_MASK (1 << 0) -#define MUX_MPLL_SEL_MASK (1 << 8) -#define MPLL_SEL_MOUT_MPLLFOUT (2 << 8) -#define MUX_CPLL_SEL_MASK (1 << 8) -#define MUX_EPLL_SEL_MASK (1 << 12) -#define MUX_VPLL_SEL_MASK (1 << 16) -#define MUX_GPLL_SEL_MASK (1 << 28) -#define MUX_BPLL_SEL_MASK (1 << 0) -#define MUX_HPM_SEL_MASK (1 << 20) -#define HPM_SEL_SCLK_MPLL (1 << 21) -#define PLL_LOCKED (1 << 29) -#define APLL_CON0_LOCKED (1 << 29) -#define MPLL_CON0_LOCKED (1 << 29) -#define BPLL_CON0_LOCKED (1 << 29) -#define CPLL_CON0_LOCKED (1 << 29) -#define EPLL_CON0_LOCKED (1 << 29) -#define GPLL_CON0_LOCKED (1 << 29) -#define VPLL_CON0_LOCKED (1 << 29) -#define CLK_REG_DISABLE 0x0 -#define TOP2_VAL 0x0110000 - -/* CLK_SRC_LEX */ -#define CLK_SRC_LEX_VAL 0x0 - -/* CLK_DIV_LEX */ -#define CLK_DIV_LEX_VAL 0x10 - -/* CLK_DIV_R0X */ -#define CLK_DIV_R0X_VAL 0x10 - -/* CLK_DIV_L0X */ -#define CLK_DIV_R1X_VAL 0x10 - -/* CLK_DIV_ISP2 */ -#define CLK_DIV_ISP2_VAL 0x1 - -/* CLK_SRC_KFC */ -#define SRC_KFC_HPM_SEL (1 << 15) - -/* CLK_SRC_KFC */ -#define CLK_SRC_KFC_VAL 0x00008001 - -/* CLK_DIV_KFC */ -#define CLK_DIV_KFC_VAL 0x03300110 - -/* CLK_DIV2_RATIO */ -#define CLK_DIV2_RATIO 0x10111150 - -/* CLK_DIV4_RATIO */ -#define CLK_DIV4_RATIO 0x00000003 - -/* CLK_DIV_G2D */ -#define CLK_DIV_G2D 0x00000010 - -/* CLK_SRC_PERIC0 */ -#define SPDIF_SEL 1 -#define PWM_SEL 3 -#define UART4_SEL 3 -#define UART3_SEL 3 -#define UART2_SEL 3 -#define UART1_SEL 3 -#define UART0_SEL 3 -/* SRC_CLOCK = SCLK_RPLL */ -#define CLK_SRC_PERIC0_VAL ((SPDIF_SEL << 28) \ - | (PWM_SEL << 24) \ - | (UART4_SEL << 20) \ - | (UART3_SEL << 16) \ - | (UART2_SEL << 12) \ - | (UART1_SEL << 8) \ - | (UART0_SEL << 4)) - -/* CLK_SRC_PERIC1 */ -/* SRC_CLOCK = SCLK_MPLL */ -#define SPI0_SEL 3 -#define SPI1_SEL 3 -#define SPI2_SEL 3 -/* SRC_CLOCK = SCLK_EPLL */ -#define AUDIO0_SEL 6 -#define AUDIO1_SEL 6 -#define AUDIO2_SEL 6 -#define CLK_SRC_PERIC1_VAL ((SPI2_SEL << 28) \ - | (SPI1_SEL << 24) \ - | (SPI0_SEL << 20) \ - | (AUDIO2_SEL << 16) \ - | (AUDIO2_SEL << 12) \ - | (AUDIO2_SEL << 8)) - -/* CLK_SRC_ISP */ -#define CLK_SRC_ISP_VAL 0x33366000 -#define CLK_DIV_ISP0_VAL 0x13131300 -#define CLK_DIV_ISP1_VAL 0xbb110202 - -/* SCLK_DIV_ISP - set SPI0/1 to 0xf = divide by 16 */ -#define SPI0_ISP_RATIO 0xf -#define SPI1_ISP_RATIO 0xf -#define SCLK_DIV_ISP_VAL (SPI1_ISP_RATIO << 12) \ - | (SPI0_ISP_RATIO << 0) - -/* CLK_DIV_PERIL0 */ -#define PWM_RATIO 8 -#define UART4_RATIO 9 -#define UART3_RATIO 9 -#define UART2_RATIO 9 -#define UART1_RATIO 9 -#define UART0_RATIO 9 - -#define CLK_DIV_PERIC0_VAL ((PWM_RATIO << 28) \ - | (UART4_RATIO << 24) \ - | (UART3_RATIO << 20) \ - | (UART2_RATIO << 16) \ - | (UART1_RATIO << 12) \ - | (UART0_RATIO << 8)) - -/* CLK_DIV_PERIC1 */ -#define SPI2_RATIO 0x1 -#define SPI1_RATIO 0x1 -#define SPI0_RATIO 0x1 -#define CLK_DIV_PERIC1_VAL ((SPI2_RATIO << 28) \ - | (SPI1_RATIO << 24) \ - | (SPI0_RATIO << 20)) - -/* CLK_DIV_PERIC2 */ -#define PCM2_RATIO 0x3 -#define PCM1_RATIO 0x3 -#define CLK_DIV_PERIC2_VAL ((PCM2_RATIO << 24) \ - | (PCM1_RATIO << 16)) - -/* CLK_DIV_PERIC3 */ -#define AUDIO2_RATIO 0x5 -#define AUDIO1_RATIO 0x5 -#define AUDIO0_RATIO 0x5 -#define CLK_DIV_PERIC3_VAL ((AUDIO2_RATIO << 28) \ - | (AUDIO1_RATIO << 24) \ - | (AUDIO0_RATIO << 20)) - -/* CLK_DIV_PERIC4 */ -#define SPI2_PRE_RATIO 0x3 -#define SPI1_PRE_RATIO 0x3 -#define SPI0_PRE_RATIO 0x3 -#define CLK_DIV_PERIC4_VAL ((SPI2_PRE_RATIO << 24) \ - | (SPI1_PRE_RATIO << 16) \ - | (SPI0_PRE_RATIO << 8)) - -/* CLK_DIV_FSYS2 */ -#define MMC2_RATIO_MASK 0xf -#define MMC2_RATIO_VAL 0x3 -#define MMC2_RATIO_OFFSET 0 - -#define MMC2_PRE_RATIO_MASK 0xff -#define MMC2_PRE_RATIO_VAL 0x9 -#define MMC2_PRE_RATIO_OFFSET 8 - -#define MMC3_RATIO_MASK 0xf -#define MMC3_RATIO_VAL 0x1 -#define MMC3_RATIO_OFFSET 16 - -#define MMC3_PRE_RATIO_MASK 0xff -#define MMC3_PRE_RATIO_VAL 0x0 -#define MMC3_PRE_RATIO_OFFSET 24 - -/* CLK_SRC_LEX */ -#define CLK_SRC_LEX_VAL 0x0 - -/* CLK_DIV_LEX */ -#define CLK_DIV_LEX_VAL 0x10 - -/* CLK_DIV_R0X */ -#define CLK_DIV_R0X_VAL 0x10 - -/* CLK_DIV_L0X */ -#define CLK_DIV_R1X_VAL 0x10 - -/* CLK_DIV_ISP2 */ -#define CLK_DIV_ISP2_VAL 0x1 - -/* CLK_SRC_DISP1_0 */ -#define CLK_SRC_DISP1_0_VAL 0x10006000 -#define CLK_DIV_DISP1_0_VAL 0x01050210 - -/* - * DIV_DISP1_0 - * For DP, divisor should be 2 - */ -#define CLK_DIV_DISP1_0_FIMD1 (2 << 0) - -/* CLK_GATE_IP_DISP1 */ -#define CLK_GATE_DP1_ALLOW (1 << 4) - -/* CLK_GATE_IP_SYSRGT */ -#define CLK_C2C_MASK (1 << 1) - -/* CLK_GATE_IP_ACP */ -#define CLK_SMMUG2D_MASK (1 << 7) -#define CLK_SMMUSSS_MASK (1 << 6) -#define CLK_SMMUMDMA_MASK (1 << 5) -#define CLK_ID_REMAPPER_MASK (1 << 4) -#define CLK_G2D_MASK (1 << 3) -#define CLK_SSS_MASK (1 << 2) -#define CLK_MDMA_MASK (1 << 1) -#define CLK_SECJTAG_MASK (1 << 0) - -/* CLK_GATE_BUS_SYSLFT */ -#define CLK_EFCLK_MASK (1 << 16) - -/* CLK_GATE_IP_ISP0 */ -#define CLK_UART_ISP_MASK (1 << 31) -#define CLK_WDT_ISP_MASK (1 << 30) -#define CLK_PWM_ISP_MASK (1 << 28) -#define CLK_MTCADC_ISP_MASK (1 << 27) -#define CLK_I2C1_ISP_MASK (1 << 26) -#define CLK_I2C0_ISP_MASK (1 << 25) -#define CLK_MPWM_ISP_MASK (1 << 24) -#define CLK_MCUCTL_ISP_MASK (1 << 23) -#define CLK_INT_COMB_ISP_MASK (1 << 22) -#define CLK_SMMU_MCUISP_MASK (1 << 13) -#define CLK_SMMU_SCALERP_MASK (1 << 12) -#define CLK_SMMU_SCALERC_MASK (1 << 11) -#define CLK_SMMU_FD_MASK (1 << 10) -#define CLK_SMMU_DRC_MASK (1 << 9) -#define CLK_SMMU_ISP_MASK (1 << 8) -#define CLK_GICISP_MASK (1 << 7) -#define CLK_ARM9S_MASK (1 << 6) -#define CLK_MCUISP_MASK (1 << 5) -#define CLK_SCALERP_MASK (1 << 4) -#define CLK_SCALERC_MASK (1 << 3) -#define CLK_FD_MASK (1 << 2) -#define CLK_DRC_MASK (1 << 1) -#define CLK_ISP_MASK (1 << 0) - -/* CLK_GATE_IP_ISP1 */ -#define CLK_SPI1_ISP_MASK (1 << 13) -#define CLK_SPI0_ISP_MASK (1 << 12) -#define CLK_SMMU3DNR_MASK (1 << 7) -#define CLK_SMMUDIS1_MASK (1 << 6) -#define CLK_SMMUDIS0_MASK (1 << 5) -#define CLK_SMMUODC_MASK (1 << 4) -#define CLK_3DNR_MASK (1 << 2) -#define CLK_DIS_MASK (1 << 1) -#define CLK_ODC_MASK (1 << 0) - -/* CLK_GATE_IP_GSCL */ -#define CLK_SMMUFIMC_LITE2_MASK (1 << 20) -#define CLK_SMMUFIMC_LITE1_MASK (1 << 12) -#define CLK_SMMUFIMC_LITE0_MASK (1 << 11) -#define CLK_SMMUGSCL3_MASK (1 << 10) -#define CLK_SMMUGSCL2_MASK (1 << 9) -#define CLK_SMMUGSCL1_MASK (1 << 8) -#define CLK_SMMUGSCL0_MASK (1 << 7) -#define CLK_GSCL_WRAP_B_MASK (1 << 6) -#define CLK_GSCL_WRAP_A_MASK (1 << 5) -#define CLK_CAMIF_TOP_MASK (1 << 4) -#define CLK_GSCL3_MASK (1 << 3) -#define CLK_GSCL2_MASK (1 << 2) -#define CLK_GSCL1_MASK (1 << 1) -#define CLK_GSCL0_MASK (1 << 0) - -/* CLK_GATE_IP_MFC */ -#define CLK_SMMUMFCR_MASK (1 << 2) -#define CLK_SMMUMFCL_MASK (1 << 1) -#define CLK_MFC_MASK (1 << 0) - -#define SCLK_MPWM_ISP_MASK (1 << 0) - -/* CLK_GATE_IP_DISP1 */ -#define CLK_SMMUTVX_MASK (1 << 9) -#define CLK_ASYNCTVX_MASK (1 << 7) -#define CLK_HDMI_MASK (1 << 6) -#define CLK_MIXER_MASK (1 << 5) -#define CLK_DSIM1_MASK (1 << 3) - -/* AUDIO CLK SEL */ -#define AUDIO0_SEL_EPLL (0x6 << 28) -#define AUDIO0_RATIO 0x5 -#define PCM0_RATIO 0x3 -#define DIV_MAU_VAL (PCM0_RATIO << 24 | AUDIO0_RATIO << 20) - -/* CLK_GATE_IP_GEN */ -#define CLK_SMMUMDMA1_MASK (1 << 9) -#define CLK_SMMUJPEG_MASK (1 << 7) -#define CLK_SMMUROTATOR_MASK (1 << 6) -#define CLK_MDMA1_MASK (1 << 4) -#define CLK_JPEG_MASK (1 << 2) -#define CLK_ROTATOR_MASK (1 << 1) - -/* CLK_GATE_IP_FSYS */ -#define CLK_WDT_IOP_MASK (1 << 30) -#define CLK_SMMUMCU_IOP_MASK (1 << 26) -#define CLK_SATA_PHY_I2C_MASK (1 << 25) -#define CLK_SATA_PHY_CTRL_MASK (1 << 24) -#define CLK_MCUCTL_MASK (1 << 23) -#define CLK_NFCON_MASK (1 << 22) -#define CLK_SMMURTIC_MASK (1 << 11) -#define CLK_RTIC_MASK (1 << 9) -#define CLK_MIPI_HSI_MASK (1 << 8) -#define CLK_USBOTG_MASK (1 << 7) -#define CLK_SATA_MASK (1 << 6) -#define CLK_PDMA1_MASK (1 << 2) -#define CLK_PDMA0_MASK (1 << 1) -#define CLK_MCU_IOP_MASK (1 << 0) - -/* CLK_GATE_IP_PERIC */ -#define CLK_HS_I2C3_MASK (1 << 31) -#define CLK_HS_I2C2_MASK (1 << 30) -#define CLK_HS_I2C1_MASK (1 << 29) -#define CLK_HS_I2C0_MASK (1 << 28) -#define CLK_AC97_MASK (1 << 27) -#define CLK_SPDIF_MASK (1 << 26) -#define CLK_PCM2_MASK (1 << 23) -#define CLK_PCM1_MASK (1 << 22) -#define CLK_I2S2_MASK (1 << 21) -#define CLK_I2S1_MASK (1 << 20) -#define CLK_SPI2_MASK (1 << 18) -#define CLK_SPI0_MASK (1 << 16) -#define CLK_I2CHDMI_MASK (1 << 14) -#define CLK_I2C7_MASK (1 << 13) -#define CLK_I2C6_MASK (1 << 12) -#define CLK_I2C5_MASK (1 << 11) -#define CLK_I2C4_MASK (1 << 10) -#define CLK_I2C3_MASK (1 << 9) -#define CLK_I2C2_MASK (1 << 8) -#define CLK_I2C1_MASK (1 << 7) -#define CLK_I2C0_MASK (1 << 6) - -/* CLK_GATE_IP_PERIS */ -#define CLK_RTC_MASK (1 << 20) -#define CLK_TZPC9_MASK (1 << 15) -#define CLK_TZPC8_MASK (1 << 14) -#define CLK_TZPC7_MASK (1 << 13) -#define CLK_TZPC6_MASK (1 << 12) -#define CLK_TZPC5_MASK (1 << 11) -#define CLK_TZPC4_MASK (1 << 10) -#define CLK_TZPC3_MASK (1 << 9) -#define CLK_TZPC2_MASK (1 << 8) -#define CLK_TZPC1_MASK (1 << 7) -#define CLK_TZPC0_MASK (1 << 6) -#define CLK_CHIPID_MASK (1 << 0) - -/* CLK_GATE_BLOCK */ -#define CLK_ACP_MASK (1 << 7) - -/* CLK_GATE_IP_CDREX */ -#define CLK_TZASC_DRBXW_MASK (1 << 23) -#define CLK_TZASC_DRBXR_MASK (1 << 22) -#define CLK_TZASC_XLBXW_MASK (1 << 21) -#define CLK_TZASC_XLBXR_MASK (1 << 20) -#define CLK_TZASC_XR1BXW_MASK (1 << 19) -#define CLK_TZASC_XR1BXR_MASK (1 << 18) -#define CLK_DPHY1_MASK (1 << 5) -#define CLK_DPHY0_MASK (1 << 4) - -/* - * TZPC Register Value : - * R0SIZE: 0x0 : Size of secured ram - */ -#define R0SIZE 0x0 - -/* - * TZPC Decode Protection Register Value : - * DECPROTXSET: 0xFF : Set Decode region to non-secure - */ -#define DECPROTXSET 0xFF - -#define LPDDR3PHY_CTRL_PHY_RESET (1 << 0) -#define LPDDR3PHY_CTRL_PHY_RESET_OFF (0 << 0) - -/* FIXME(dhendrix): misleading name. The reset value is 0x17021a40, bits 12:11 -+ default to 0x3 which indicates LPDDR3. We want DDR3, so we use 0x1. */ -#define PHY_CON0_RESET_VAL 0x17020a40 -#define P0_CMD_EN (1 << 14) -#define BYTE_RDLVL_EN (1 << 13) -#define CTRL_SHGATE (1 << 8) - -#define PHY_CON1_RESET_VAL 0x09210100 -#define RDLVL_PASS_ADJ_VAL 0x6 -#define RDLVL_PASS_ADJ_OFFSET 16 -#define CTRL_GATEDURADJ_MASK (0xf << 20) -#define READ_LEVELLING_DDR3 0x0100 - -#define PHY_CON2_RESET_VAL 0x00010004 -#define INIT_DESKEW_EN (1 << 6) -#define DLL_DESKEW_EN (1 << 12) -#define RDLVL_GATE_EN (1 << 24) -#define RDLVL_EN (1 << 25) -#define RDLVL_INCR_ADJ (0x1 << 16) - -/* DREX_PAUSE */ -#define DREX_PAUSE_EN (1 << 0) - -#define BYPASS_EN (1 << 22) - -/********-----MEMMORY VAL----------***/ -#define PHY_CON0_VAL 0x17021A00 - -#define PHY_CON12_RESET_VAL 0x10100070 -#define PHY_CON12_VAL 0x10107F50 -#define CTRL_START (1 << 6) -#define CTRL_DLL_ON (1 << 5) -#define CTRL_FORCE_MASK (0x7F << 8) -#define CTRL_LOCK_COARSE_MASK (0x7F << 10) - - -#define CTRL_OFFSETD_RESET_VAL 0x8 -#define CTRL_OFFSETD_VAL 0x7F - -#define CTRL_OFFSETR0 0x7F -#define CTRL_OFFSETR1 0x7F -#define CTRL_OFFSETR2 0x7F -#define CTRL_OFFSETR3 0x7F -#define PHY_CON4_VAL (CTRL_OFFSETR0 << 0 | \ - CTRL_OFFSETR1 << 8 | \ - CTRL_OFFSETR2 << 16 | \ - CTRL_OFFSETR3 << 24) -#define PHY_CON4_RESET_VAL 0x08080808 - -#define CTRL_OFFSETW0 0x7F -#define CTRL_OFFSETW1 0x7F -#define CTRL_OFFSETW2 0x7F -#define CTRL_OFFSETW3 0x7F -#define PHY_CON6_VAL (CTRL_OFFSETW0 << 0 | \ - CTRL_OFFSETW1 << 8 | \ - CTRL_OFFSETW2 << 16 | \ - CTRL_OFFSETW3 << 24) -#define PHY_CON6_RESET_VAL 0x08080808 - -#define PHY_CON14_RESET_VAL 0x001F0000 -#define CTRL_PULLD_DQS 0xF -#define CTRL_PULLD_DQS_OFFSET 0 - -/*ZQ Configurations */ -#define PHY_CON16_RESET_VAL 0x08000304 - -#define ZQ_CLK_EN (1 << 27) -#define ZQ_CLK_DIV_EN (1 << 18) -#define ZQ_MANUAL_MODE_OFFSET 2 -#define ZQ_LONG_CALIBRATION 0x1 -#define ZQ_MANUAL_STR (1 << 1) -#define ZQ_DONE (1 << 0) -#define ZQ_MODE_DDS_OFFSET 24 - -#define LONG_CALIBRATION (ZQ_LONG_CALIBRATION << ZQ_MANUAL_MODE_OFFSET) - -#define CTRL_RDLVL_GATE_ENABLE 1 -#define CTRL_RDLVL_GATE_DISABLE 0 - -#define CTRL_RDLVL_DATA_ENABLE (1 << 1) -/* Direct Command */ -#define DIRECT_CMD_NOP 0x07000000 -#define DIRECT_CMD_PALL 0x01000000 -#define DIRECT_CMD_ZQINIT 0x0a000000 -#define DIRECT_CMD_CHANNEL_SHIFT 28 -#define DIRECT_CMD_CHIP_SHIFT 20 -#define DIRECT_CMD_BANK_SHIFT 16 -#define DIRECT_CMD_REFA (5 << 24) -#define DIRECT_CMD_MRS1 0x71C00 -#define DIRECT_CMD_MRS2 0x10BFC -#define DIRECT_CMD_MRS3 0x0050C -#define DIRECT_CMD_MRS4 0x00868 -#define DIRECT_CMD_MRS5 0x00C04 - -/* Drive Strength */ -#define IMPEDANCE_48_OHM 4 -#define IMPEDANCE_40_OHM 5 -#define IMPEDANCE_34_OHM 6 -#define IMPEDANCE_30_OHM 7 -#define PHY_CON39_VAL_48_OHM 0x09240924 -#define PHY_CON39_VAL_40_OHM 0x0B6D0B6D -#define PHY_CON39_VAL_34_OHM 0x0DB60DB6 -#define PHY_CON39_VAL_30_OHM 0x0FFF0FFF - - -#define CTRL_BSTLEN_OFFSET 8 -#define CTRL_RDLAT_OFFSET 0 - -#define CMD_DEFAULT_LPDDR3 0xF -#define CMD_DEFUALT_OFFSET 0 -#define T_WRDATA_EN 0x7 -#define T_WRDATA_EN_DDR3 0x8 /* FIXME(dhendrix): 6 for DDR3? see T_wrdata_en */ -#define T_WRDATA_EN_OFFSET 16 -#define T_WRDATA_EN_MASK 0x1f - -#define PHY_CON31_VAL 0x0C183060 -#define PHY_CON32_VAL 0x60C18306 -#define PHY_CON33_VAL 0x00000030 - -#define PHY_CON31_RESET_VAL 0x0 -#define PHY_CON32_RESET_VAL 0x0 -#define PHY_CON33_RESET_VAL 0x0 - -#define SL_DLL_DYN_CON_EN (1 << 1) -#define FP_RESYNC (1 << 3) -#define CTRL_START (1 << 6) - -#define DMC_AREF_EN (1 << 5) -#define DMC_CONCONTROL_EMPTY (1 << 8) -#define DFI_INIT_START (1 << 28) - -#define DMC_MEMCONTROL_VAL 0x00312700 -#define CLK_STOP_EN (1 << 0) -#define DPWRDN_EN (1 << 1) -#define DSREF_EN (1 << 5) - -/* AXI base address mask */ -#define DMC_CHIP_MASK_256MB 0x7f0 -#define DMC_CHIP_MASK_512MB 0x7e0 -#define DMC_CHIP_MASK_1GB 0x7c0 -#define DMC_CHIP_MASK_2GB 0x780 -#define DMC_CHIP_MASK_4GB 0x700 - -#define MEMCONFIG_VAL 0x1323 -#define PRECHCONFIG_DEFAULT_VAL 0xFF000000 -#define PWRDNCONFIG_DEFAULT_VAL 0xFFFF00FF - -#define DFI_INIT_COMPLETE (1 << 3) - -#define BRBRSVCONTROL_VAL 0x00000033 -#define BRBRSVCONFIG_VAL 0x88778877 - -/* Clock Gating Control (CGCONTROL) register */ -#define MEMIF_CG_EN (1 << 3) /* Memory interface clock gating */ -#define SCG_CG_EN (1 << 2) /* Scheduler clock gating */ -#define BUSIF_WR_CG_EN (1 << 1) /* Bus interface write channel clock gating */ -#define BUSIF_RD_CG_EN (1 << 0) /* Bus interface read channel clock gating */ -#define DMC_INTERNAL_CG (MEMIF_CG_EN | SCG_CG_EN | \ - BUSIF_WR_CG_EN | BUSIF_RD_CG_EN) - -/* DMC PHY Control0 register */ -#define PHY_CONTROL0_RESET_VAL 0x0 -#define MEM_TERM_EN (1 << 31) /* Termination enable for memory */ -#define PHY_TERM_EN (1 << 30) /* Termination enable for PHY */ -#define DMC_CTRL_SHGATE (1 << 29) /* Duration of DQS gating signal */ -#define CTRL_ATGATE (1 << 6) -#define FP_RSYNC (1 << 3) /* Force DLL resyncronization */ - -/* Driver strength for CK, CKE, CS & CA */ -#define IMP_OUTPUT_DRV_40_OHM 0x5 -#define IMP_OUTPUT_DRV_30_OHM 0x7 -#define DA_3_DS_OFFSET 25 -#define DA_2_DS_OFFSET 22 -#define DA_1_DS_OFFSET 19 -#define DA_0_DS_OFFSET 16 -#define CA_CK_DRVR_DS_OFFSET 9 -#define CA_CKE_DRVR_DS_OFFSET 6 -#define CA_CS_DRVR_DS_OFFSET 3 -#define CA_ADR_DRVR_DS_OFFSET 0 - -#define PHY_CON42_CTRL_BSTLEN_SHIFT 8 -#define PHY_CON42_CTRL_RDLAT_SHIFT 0 - -struct mem_timings; - -/* Errors that we can encourter in low-level setup */ -enum { - SETUP_ERR_OK, - SETUP_ERR_RDLV_COMPLETE_TIMEOUT = -1, - SETUP_ERR_ZQ_CALIBRATION_FAILURE = -2, -}; - -/* Functions common between LPDDR2 and DDR3 */ - -/* CPU info initialization code */ -void cpu_info_init(void); - -void mem_ctrl_init(void); -/* - * Memory variant specific initialization code - * - * @param mem Memory timings for this memory type. - * @param mem_iv_size Memory interleaving size is a configurable parameter - * which the DMC uses to decide how to split a memory - * chunk into smaller chunks to support concurrent - * accesses; may vary across boards. - * @param mem_reset Reset memory during initialization. - * @return 0 if ok, SETUP_ERR_... if there is a problem - */ -int ddr3_mem_ctrl_init(struct mem_timings *mem, int interleave_size, int reset); - -/* Memory variant specific initialization code for LPDDR3 */ -int lpddr3_mem_ctrl_init(int reset); - -/* - * Configure ZQ I/O interface - * - * @param mem Memory timings for this memory type. - * @param phy0_ctrl Pointer to struct containing PHY0 control reg - * @param phy1_ctrl Pointer to struct containing PHY1 control reg - * @return 0 if ok, -1 on error - */ -int dmc_config_zq(struct mem_timings *mem, - struct exynos5_phy_control *phy0_ctrl, - struct exynos5_phy_control *phy1_ctrl); - -/* - * Send NOP and MRS/EMRS Direct commands - * - * @param mem Memory timings for this memory type. - * @param dmc Pointer to struct of DMC registers - */ -void dmc_config_mrs(struct mem_timings *mem, struct exynos5_dmc *dmc); - -/* - * Send PALL Direct commands - * - * @param mem Memory timings for this memory type. - * @param dmc Pointer to struct of DMC registers - */ -void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc); - -/* - * Configure the memconfig and membaseconfig registers - * - * @param mem Memory timings for this memory type. - * @param exynos5_dmc Pointer to struct of DMC registers - */ -void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc); - -/* Set the PS-Hold drive value */ -void ps_hold_setup(void); -/* - * Reset the DLL. This function is common between DDR3 and LPDDR2. - * However, the reset value is different. So we are passing a flag - * ddr_mode to distinguish between LPDDR2 and DDR3. - * - * @param exynos5_dmc Pointer to struct of DMC registers - * @param ddr_mode Type of DDR memory - */ -void update_reset_dll(struct exynos5_dmc *, enum ddr_mode); -#endif diff --git a/src/cpu/samsung/exynos5420/smp.c b/src/cpu/samsung/exynos5420/smp.c deleted file mode 100644 index 6fc2fb01ea..0000000000 --- a/src/cpu/samsung/exynos5420/smp.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdlib.h> -#include <string.h> -#include <types.h> -#include <arch/cpu.h> -#include <arch/io.h> - -#include "cpu.h" -#include "power.h" - -/* ACTLR, L2CTLR L2ACTLR constants used in SMP core power up. */ - -#define ACTLR_SMP (1 << 6) - -#define L2CTLR_ECC_PARITY (1 << 21) -#define L2CTLR_DATA_RAM_LATENCY_MASK (7 << 0) -#define L2CTLR_TAG_RAM_LATENCY_MASK (7 << 6) -#define L2CTLR_DATA_RAM_LATENCY_CYCLES_3 (2 << 0) -#define L2CTLR_TAG_RAM_LATENCY_CYCLES_3 (2 << 6) - -#define L2ACTLR_DISABLE_CLEAN_EVICT_PUSH_EXTERNAL (1 << 3) -#define L2ACTLR_ENABLE_HAZARD_DETECT_TIMEOUT (1 << 7) -#define L2ACTLR_FORCE_L2_LOGIC_CLOCK_ENABLE_ACTIVE (1 << 27) - -/* Part number in CPU ID (MPIDR). */ -#define PART_NUMBER_CORTEX_A15 (0xc0f) - -/* State of CPU cores in Exynos 5420. */ -#define CORE_STATE_RESET (1 << 0) -#define CORE_STATE_SECONDARY_RESET (1 << 1) -#define CORE_STATE_SWITCH_CLUSTER (1 << 4) - -/* The default address to re-power on a code. */ -#define CORE_RESET_INIT_ADDRESS ((void*)0x00000000) - -/* Vectors in BL1 (0x02020000 = base of iRAM). */ -#define VECTOR_CORE_SEV_HANDLER ((void*)(intptr_t)0x02020004) -#define VECTOR_LOW_POWER_FLAG ((void*)(intptr_t)0x02020028) -#define VECTOR_LOW_POWER_ADDRESS ((void*)(intptr_t)0x0202002C) - -/* The data structure for the "CPU state" memory page (shared with kernel) - * controlling cores in active cluster. Kernel will put starting address for one - * core in "hotplug_address" before power on. Note the address is hard-coded in - * kernel (EXYNOS5420_PA_SYSRAM_NS = 0x02073000). */ -volatile struct exynos5420_cpu_states -{ - uint32_t _reserved[2]; /* RESV, +0x00 */ - uint32_t resume_address; /* REG0, +0x08 */ - uint32_t resume_flag; /* REG1, +0x0C */ - uint32_t _reg2; /* REG2, +0x10 */ - uint32_t _reg3; /* REG3, +0x14 */ - uint32_t switch_address; /* REG4, +0x18, cluster switching */ - uint32_t hotplug_address; /* REG5, +0x1C, core hotplug */ - uint32_t _reg6; /* REG6, +0x20 */ - uint32_t c2_address; /* REG7, +0x24, C2 state change */ - - /* Managed per core status for active cluster, offset: +0x28~0x38 */ - uint32_t cpu_states[4]; - - /* Managed per core GIC status for active cluster, offset: 0x38~0x48 */ - uint32_t cpu_gic_states[4]; -} *exynos_cpu_states = (volatile struct exynos5420_cpu_states*)0x02073000; - -/* When leaving core handlers and jump to hot-plug address (or cluster - * switching), we are not sure if the destination is Thumb or ARM mode. - * So a BX command is required. - */ -inline static void jump_bx(void *address) -{ - asm volatile ("bx %0" : : "r"(address)); - /* never returns. */ -} - -/* Extracts arbitrary bits from a 32-bit unsigned int. */ -inline static uint32_t get_bits(uint32_t value, uint32_t start, uint32_t len) -{ - return ((value << (sizeof(value) * 8 - len - start)) >> - (sizeof(value) * 8 - len)); -} - -/* Waits the referenced address to be ready (non-zero) and then jump into it. */ -static void wait_and_jump(volatile uint32_t* reference) -{ - while (!*reference) { - wfe(); - } - jump_bx((void*)*reference); -} - -/* Configures L2 Control Register to use 3 cycles for DATA/TAG RAM latency. */ -static void configure_l2ctlr(void) -{ - uint32_t val; - - val = read_l2ctlr(); - val &= ~(L2CTLR_DATA_RAM_LATENCY_MASK | L2CTLR_TAG_RAM_LATENCY_MASK); - val |= (L2CTLR_DATA_RAM_LATENCY_CYCLES_3 | L2CTLR_TAG_RAM_LATENCY_CYCLES_3 | - L2CTLR_ECC_PARITY); - write_l2ctlr(val); -} - -/* Configures L2 Auxiliary Control Register for Cortex A15. */ -static void configure_l2actlr(void) -{ - uint32_t val; - - val = read_l2actlr(); - val |= (L2ACTLR_DISABLE_CLEAN_EVICT_PUSH_EXTERNAL | - L2ACTLR_ENABLE_HAZARD_DETECT_TIMEOUT | - L2ACTLR_FORCE_L2_LOGIC_CLOCK_ENABLE_ACTIVE); - write_l2actlr(val); -} - -/* Initializes the CPU states to reset state. */ -static void init_exynos_cpu_states(void) { - memset((void*)exynos_cpu_states, 0, sizeof(*exynos_cpu_states)); - exynos_cpu_states->cpu_states[0] = CORE_STATE_RESET; - exynos_cpu_states->cpu_states[1] = CORE_STATE_SECONDARY_RESET; - exynos_cpu_states->cpu_states[2] = CORE_STATE_SECONDARY_RESET; - exynos_cpu_states->cpu_states[3] = CORE_STATE_SECONDARY_RESET; -} - -/* - * Ensures that the L2 logic has been used within the previous 256 cycles - * before modifying the ACTLR.SMP bit. This is required during boot before - * MMU has been enabled, or during a specified reset or power down sequence. - */ -static void enable_smp(void) -{ - uint32_t actlr, val; - - /* Enable SMP mode */ - actlr = read_actlr(); - actlr |= ACTLR_SMP; - - /* Dummy read to assure L2 access */ - val = readl(&exynos_power->inform0); - val &= 0; - actlr |= val; - - write_actlr(actlr); - dsb(); - isb(); -} - -/* Starts the core and jumps to correct location by its state. */ -static void core_start_execution(void) -{ - u32 cpu_id, cpu_state; - - enable_smp(); - set_system_mode(); - - cpu_id = read_mpidr() & 0x3; /* up to 4 processors for one cluster. */ - cpu_state = exynos_cpu_states->cpu_states[cpu_id]; - - if (cpu_state & CORE_STATE_SWITCH_CLUSTER) { - wait_and_jump(&exynos_cpu_states->switch_address); - /* never returns. */ - } - - /* Standard Exynos suspend/resume. */ - if (exynos_power->inform1) { - exynos_power->inform1 = 0; - jump_bx((void*)exynos_power->inform0); - /* never returns. */ - } - - if (cpu_state & CORE_STATE_RESET) { - /* For Reset, U-Boot jumps to its starting address; - * on Coreboot, seems ok to ignore for now. */ - } - wait_and_jump(&exynos_cpu_states->hotplug_address); - /* never returns. */ -} - -/* The entry point for hotplug-in and cluster switching. */ -static void low_power_start(void) -{ - uint32_t sctlr, reg_val; - - /* On warm reset, because iRAM is not cleared, all cores will enter - * low_power_start, not the initial address. So we need to check reset - * status again, and jump to 0x0 in that case. */ - reg_val = readl(&exynos_power->spare0); - if (reg_val != RST_FLAG_VAL) { - writel(0x0, VECTOR_LOW_POWER_FLAG); - jump_bx(CORE_RESET_INIT_ADDRESS); - /* restart cpu execution and never returns. */ - } - - /* Workaround for iROM EVT1. A7 core execution may flow into incorrect - * path, bypassing first jump address and makes final jump address 0x0, - * so we try to make any core set again low_power_start address, if that - * becomes zero. */ - reg_val = readl(VECTOR_CORE_SEV_HANDLER); - if (reg_val != (intptr_t)low_power_start) { - writel((intptr_t)low_power_start, VECTOR_CORE_SEV_HANDLER); - dsb(); - /* ask all cores to power on again. */ - sev(); - } - - set_system_mode(); - - /* Whenever a Cortex A-15 core powers on, iROM resets its L2 cache - * so we need to configure again. */ - if (get_bits(read_midr(), 4, 12) == PART_NUMBER_CORTEX_A15) { - configure_l2ctlr(); - configure_l2actlr(); - } - - /* Invalidate L1 & TLB */ - tlbiall(); - iciallu(); - - /* Disable MMU stuff and caches */ - sctlr = read_sctlr(); - sctlr &= ~(SCTLR_V | SCTLR_M | SCTLR_C); - sctlr |= (SCTLR_I | SCTLR_Z | SCTLR_A); - write_sctlr(sctlr); - - core_start_execution(); - /* The core should not return. But in order to prevent unexpected - * errors, a WFI command will help to put CPU back to idle state. */ - wfi(); -} - -/* Callback to shutdown a core, safe to be set as hot-plug address. */ -static void power_down_core(void) -{ - uint32_t mpidr, core_id; - - /* MPIDR: 0~2=ID, 8~11=cluster. On Exynos 5420, cluster will be only 0 - * or 1. */ - mpidr = read_mpidr(); - core_id = get_bits(mpidr, 0, 2) | (get_bits(mpidr, 8, 4) << 2); - - /* Set the status of the core to low. - * S5E5420A User Manual, 8.8.1.202, ARM_CORE0_CONFIGURATION, two bits to - * control power state in each power down level. - */ - writel(0x0, &exynos_power->arm_core[core_id].config); - - /* S5E5420A User Manual, 8.4.2.5, after ARM_CORE*_CONFIGURATION has been - * set to zero, PMU will detect and wait for WFI then run power-down - * sequence. */ - wfi(); -} - -/* Configures the CPU states shard memory page and then shutdown all cores. */ -static void configure_secondary_cores(void) -{ - if (get_bits(read_midr(), 4, 12) == PART_NUMBER_CORTEX_A15) { - configure_l2ctlr(); - configure_l2actlr(); - } - - /* Currently we use power_down_core as callback for each core to - * shutdown itself, but it is also ok to directly set ARM_CORE*_CONFIG - * to zero by CPU0 because every secondary cores should be already in - * WFI state (in bootblock). The power_down_core will be more helpful - * when we want to use SMP inside firmware. */ - - /* Clear boot reg (hotplug address) in cpu states */ - writel(0, (void*)&exynos_cpu_states->hotplug_address); - - /* set low_power flag and address */ - writel((intptr_t)low_power_start, VECTOR_LOW_POWER_ADDRESS); - writel(RST_FLAG_VAL, VECTOR_LOW_POWER_FLAG); - writel(RST_FLAG_VAL, &exynos_power->spare0); - - /* On next SEV, shutdown all cores. */ - writel((intptr_t)power_down_core, VECTOR_CORE_SEV_HANDLER); - - /* Ask all cores in WFE mode to shutdown. */ - dsb(); - sev(); -} - -/* Configures the SMP cores on Exynos 5420 SOC (and shutdown all secondary - * cores) */ -void exynos5420_config_smp(void) -{ - init_exynos_cpu_states(); - configure_secondary_cores(); -} - diff --git a/src/cpu/samsung/exynos5420/spi.c b/src/cpu/samsung/exynos5420/spi.c deleted file mode 100644 index c6c08e925c..0000000000 --- a/src/cpu/samsung/exynos5420/spi.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2011 Samsung Electronics - * Copyright 2013 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <console/console.h> -#include <arch/io.h> -#include <stdlib.h> -#include <assert.h> -#include <spi_flash.h> - -#include "cpu.h" -#include "spi.h" - -#define EXYNOS_SPI_MAX_TRANSFER_BYTES (65535) - -#if defined(CONFIG_DEBUG_SPI) && CONFIG_DEBUG_SPI -# define DEBUG_SPI(x,...) printk(BIOS_DEBUG, "EXYNOS_SPI: " x) -#else -# define DEBUG_SPI(x,...) -#endif - -struct exynos_spi_slave { - struct spi_slave slave; - struct exynos_spi *regs; - unsigned int fifo_size; - uint8_t half_duplex; - uint8_t frame_header; /* header byte to detect in half-duplex mode. */ -}; - -/* TODO(hungte) Move the SPI param list to per-board configuration, probably - * Kconfig or mainboard.c */ -static struct exynos_spi_slave exynos_spi_slaves[3] = { - // SPI 0 - { - .slave = { .bus = 0, }, - .regs = (void *)EXYNOS5_SPI0_BASE, - }, - // SPI 1 - { - .slave = { .bus = 1, .rw = SPI_READ_FLAG, }, - .regs = (void *)EXYNOS5_SPI1_BASE, - .fifo_size = 64, - .half_duplex = 0, - }, - // SPI 2 - { - .slave = { .bus = 2, - .rw = SPI_READ_FLAG | SPI_WRITE_FLAG, }, - .regs = (void *)EXYNOS5_SPI2_BASE, - .fifo_size = 64, - .half_duplex = 1, - .frame_header = 0xec, - }, -}; - -static inline struct exynos_spi_slave *to_exynos_spi(struct spi_slave *slave) -{ - return container_of(slave, struct exynos_spi_slave, slave); -} - -void spi_init(void) -{ - printk(BIOS_INFO, "Exynos SPI driver initiated.\n"); -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) -{ - ASSERT(bus >= 0 && bus < 3); - return &(exynos_spi_slaves[bus].slave); -} - -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - return bus > 0 && bus < 3; -} - -void spi_cs_activate(struct spi_slave *slave) -{ - struct exynos_spi *regs = to_exynos_spi(slave)->regs; - // TODO(hungte) Add some delay if too many transactions happen at once. - clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); -} - -void spi_cs_deactivate(struct spi_slave *slave) -{ - struct exynos_spi *regs = to_exynos_spi(slave)->regs; - setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); -} - -static inline void exynos_spi_soft_reset(struct exynos_spi *regs) -{ - /* The soft reset clears only FIFO and status register. - * All special function registers are not changed. */ - setbits_le32(®s->ch_cfg, SPI_CH_RST); - clrbits_le32(®s->ch_cfg, SPI_CH_RST); -} - -static inline void exynos_spi_flush_fifo(struct exynos_spi *regs) -{ - /* - * Flush spi tx, rx fifos and reset the SPI controller - * and clear rx/tx channel - */ - clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON); - clrbits_le32(®s->ch_cfg, SPI_CH_HS_EN); - exynos_spi_soft_reset(regs); - setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON); -} - -static void exynos_spi_request_bytes(struct exynos_spi *regs, int count, - int width) -{ - uint32_t mode_word = SPI_MODE_CH_WIDTH_WORD | SPI_MODE_BUS_WIDTH_WORD, - swap_word = (SPI_TX_SWAP_EN | SPI_RX_SWAP_EN | - SPI_TX_BYTE_SWAP | SPI_RX_BYTE_SWAP | - SPI_TX_HWORD_SWAP | SPI_RX_HWORD_SWAP); - - /* For word address we need to swap bytes */ - if (width == sizeof(uint32_t)) { - setbits_le32(®s->mode_cfg, mode_word); - setbits_le32(®s->swap_cfg, swap_word); - count /= width; - } else { - /* Select byte access and clear the swap configuration */ - clrbits_le32(®s->mode_cfg, mode_word); - writel(0, ®s->swap_cfg); - } - - exynos_spi_soft_reset(regs); - - if (count) { - ASSERT(count < (1 << 16)); - writel(count | SPI_PACKET_CNT_EN, ®s->pkt_cnt); - } else { - writel(0, ®s->pkt_cnt); - } -} - -static int spi_rx_tx(struct spi_slave *slave, uint8_t *rxp, int rx_bytes, - const uint8_t *txp, int tx_bytes) -{ - struct exynos_spi_slave *espi = to_exynos_spi(slave); - struct exynos_spi *regs = espi->regs; - - int step; - int todo = MAX(rx_bytes, tx_bytes); - int wait_for_frame_header = espi->half_duplex; - - ASSERT(todo < EXYNOS_SPI_MAX_TRANSFER_BYTES); - - /* Select transfer mode. */ - if (espi->half_duplex) { - step = 1; - } else if ((rx_bytes | tx_bytes | (uintptr_t)rxp |(uintptr_t)txp) & 3) { - printk(BIOS_CRIT, "%s: WARNING: tranfer mode decreased to 1B\n", - __func__); - step = 1; - } else { - step = sizeof(uint32_t); - } - - exynos_spi_request_bytes(regs, espi->half_duplex ? 0 : todo, step); - - /* Note: Some device, like ChromeOS EC, tries to work in half-duplex - * mode and sends a large amount of data (larger than FIFO size). - * Printing lots of debug messages or doing extra delay in the loop - * below may cause rx buffer to overflow and getting unexpected data - * error. - */ - while (rx_bytes || tx_bytes) { - int temp; - uint32_t spi_sts = readl(®s->spi_sts); - int rx_lvl = (spi_sts >> SPI_RX_LVL_OFFSET) & SPI_FIFO_LVL_MASK, - tx_lvl = (spi_sts >> SPI_TX_LVL_OFFSET) & SPI_FIFO_LVL_MASK; - int min_tx = ((tx_bytes || !espi->half_duplex) ? - (espi->fifo_size / 2) : 1); - - // TODO(hungte) Abort if timeout happens in half-duplex mode. - - /* - * Don't completely fill the txfifo, since we don't want our - * rxfifo to overflow, and it may already contain data. - */ - while (tx_lvl < min_tx) { - if (tx_bytes) { - if (step == sizeof(uint32_t)) { - temp = *((uint32_t *)txp); - txp += sizeof(uint32_t); - } else { - temp = *txp++; - } - tx_bytes -= step; - } else { - temp = -1; - } - writel(temp, ®s->tx_data); - tx_lvl += step; - } - - while ((rx_lvl >= step) && rx_bytes) { - temp = readl(®s->rx_data); - rx_lvl -= step; - if (wait_for_frame_header) { - if ((temp & 0xff) == espi->frame_header) { - wait_for_frame_header = 0; - } - break; /* Restart the outer loop. */ - } - if (step == sizeof(uint32_t)) { - *((uint32_t *)rxp) = temp; - rxp += sizeof(uint32_t); - } else { - *rxp++ = temp; - } - rx_bytes -= step; - } - } - return 0; -} - -int spi_claim_bus(struct spi_slave *slave) -{ - struct exynos_spi_slave *espi = to_exynos_spi(slave); - struct exynos_spi *regs = espi->regs; - - exynos_spi_flush_fifo(regs); - - // Select Active High Clock, Format A (SCP 30.2.1.8). - clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L | SPI_CH_CPHA_B); - - // Set FeedBack Clock Selection. - writel(SPI_FB_DELAY_180, ®s->fb_clk); - - // HIGH speed is required for Tx/Rx to work in 50MHz (SCP 30.2.1.6). - if (espi->half_duplex) { - clrbits_le32(®s->ch_cfg, SPI_CH_HS_EN); - printk(BIOS_DEBUG, "%s: LOW speed.\n", __func__); - } else { - setbits_le32(®s->ch_cfg, SPI_CH_HS_EN); - printk(BIOS_DEBUG, "%s: HIGH speed.\n", __func__); - } - return 0; -} - -int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int out_bytes, - void *din, unsigned int in_bytes) -{ - uint8_t *out_ptr = (uint8_t *)dout, *in_ptr = (uint8_t *)din; - int offset, todo, len; - int ret = 0; - - len = MAX(out_bytes, in_bytes); - - /* - * Exynos SPI limits each transfer to (2^16-1=65535) bytes. To keep - * things simple (especially for word-width transfer mode), allow a - * maximum of (2^16-4=65532) bytes. We could allow more in word mode, - * but the performance difference is small. - */ - spi_cs_activate(slave); - for (offset = 0; !ret && (offset < len); offset += todo) { - todo = min(len - offset, (1 << 16) - 4); - ret = spi_rx_tx(slave, in_ptr, MIN(in_bytes, todo), out_ptr, - MIN(out_bytes, todo)); - // Adjust remaining bytes and pointers. - if (in_bytes >= todo) { - in_bytes -= todo; - in_ptr += todo; - } else { - in_bytes = 0; - in_ptr = NULL; - } - if (out_bytes >= todo) { - out_bytes -= todo; - out_ptr += todo; - } else { - out_bytes = 0; - out_ptr = NULL; - } - } - spi_cs_deactivate(slave); - - return ret; -} - -static int exynos_spi_read(struct spi_slave *slave, void *dest, uint32_t len, - uint32_t off) -{ - struct exynos_spi *regs = to_exynos_spi(slave)->regs; - int rv; - - // TODO(hungte) Merge the "read address" command into spi_xfer calls - // (full-duplex mode). - - spi_cs_activate(slave); - - // Specify read address (in word-width mode). - ASSERT(off < (1 << 24)); - exynos_spi_request_bytes(regs, sizeof(off), sizeof(off)); - writel(htonl((SF_READ_DATA_CMD << 24) | off), ®s->tx_data); - while (!(readl(®s->spi_sts) & SPI_ST_TX_DONE)) { - /* Wait for TX done */ - } - - // Now, safe to transfer. - rv = spi_xfer(slave, NULL, 0, dest, len * 8); - spi_cs_deactivate(slave); - - return (rv == 0) ? len : -1; -} - -void spi_release_bus(struct spi_slave *slave) -{ - struct exynos_spi *regs = to_exynos_spi(slave)->regs; - /* Reset swap mode to make sure no one relying on default values (Ex, - * payload or kernel) will go wrong. */ - clrbits_le32(®s->mode_cfg, (SPI_MODE_CH_WIDTH_WORD | - SPI_MODE_BUS_WIDTH_WORD)); - writel(0, ®s->swap_cfg); - exynos_spi_flush_fifo(regs); -} - -// SPI as CBFS media. -struct exynos_spi_media { - struct spi_slave *slave; - struct cbfs_simple_buffer buffer; -}; - -static int exynos_spi_cbfs_open(struct cbfs_media *media) -{ - struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; - DEBUG_SPI("exynos_spi_cbfs_open\n"); - return spi_claim_bus(spi->slave); -} - -static int exynos_spi_cbfs_close(struct cbfs_media *media) -{ - struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; - DEBUG_SPI("exynos_spi_cbfs_close\n"); - spi_release_bus(spi->slave); - return 0; -} - -static size_t exynos_spi_cbfs_read(struct cbfs_media *media, void *dest, - size_t offset, size_t count) -{ - struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; - int bytes; - DEBUG_SPI("exynos_spi_cbfs_read(%u)\n", count); - bytes = exynos_spi_read(spi->slave, dest, count, offset); - return bytes; -} - -static void *exynos_spi_cbfs_map(struct cbfs_media *media, size_t offset, - size_t count) -{ - struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; - DEBUG_SPI("exynos_spi_cbfs_map\n"); - // exynos: spi_rx_tx may work in 4 byte-width-transmission mode and - // requires buffer memory address to be aligned. - if (count % 4) - count += 4 - (count % 4); - return cbfs_simple_buffer_map(&spi->buffer, media, offset, count); -} - -static void *exynos_spi_cbfs_unmap(struct cbfs_media *media, - const void *address) -{ - struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; - DEBUG_SPI("exynos_spi_cbfs_unmap\n"); - return cbfs_simple_buffer_unmap(&spi->buffer, address); -} - -int initialize_exynos_spi_cbfs_media(struct cbfs_media *media, - void *buffer_address, - size_t buffer_size) -{ - // TODO Replace static variable to support multiple streams. - static struct exynos_spi_media context; - static struct exynos_spi_slave *eslave = &exynos_spi_slaves[1]; - DEBUG_SPI("initialize_exynos_spi_cbfs_media\n"); - - context.slave = &eslave->slave; - context.buffer.allocated = context.buffer.last_allocate = 0; - context.buffer.buffer = buffer_address; - context.buffer.size = buffer_size; - media->context = (void*)&context; - media->open = exynos_spi_cbfs_open; - media->close = exynos_spi_cbfs_close; - media->read = exynos_spi_cbfs_read; - media->map = exynos_spi_cbfs_map; - media->unmap = exynos_spi_cbfs_unmap; - - return 0; -} diff --git a/src/cpu/samsung/exynos5420/spi.h b/src/cpu/samsung/exynos5420/spi.h deleted file mode 100644 index 94b4fdaace..0000000000 --- a/src/cpu/samsung/exynos5420/spi.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_SPI_H -#define CPU_SAMSUNG_EXYNOS5420_SPI_H - -/* This driver serves as a CBFS media source. */ -#include <cbfs.h> - -/* SPI peripheral register map; padded to 64KB */ -struct exynos_spi { - unsigned int ch_cfg; /* 0x00 */ - unsigned char reserved0[4]; - unsigned int mode_cfg; /* 0x08 */ - unsigned int cs_reg; /* 0x0c */ - unsigned char reserved1[4]; - unsigned int spi_sts; /* 0x14 */ - unsigned int tx_data; /* 0x18 */ - unsigned int rx_data; /* 0x1c */ - unsigned int pkt_cnt; /* 0x20 */ - unsigned char reserved2[4]; - unsigned int swap_cfg; /* 0x28 */ - unsigned int fb_clk; /* 0x2c */ - unsigned char padding[0xffd0]; -}; - -#define EXYNOS_SPI_MAX_FREQ 50000000 - -#define SPI_TIMEOUT_MS 10 - -#define SF_READ_DATA_CMD 0x3 - -/* SPI_CHCFG */ -#define SPI_CH_HS_EN (1 << 6) -#define SPI_CH_RST (1 << 5) -#define SPI_SLAVE_MODE (1 << 4) -#define SPI_CH_CPOL_L (1 << 3) -#define SPI_CH_CPHA_B (1 << 2) -#define SPI_RX_CH_ON (1 << 1) -#define SPI_TX_CH_ON (1 << 0) - -/* SPI_MODECFG */ -#define SPI_MODE_CH_WIDTH_WORD (0x2 << 29) -#define SPI_MODE_BUS_WIDTH_WORD (0x2 << 17) - -/* SPI_CSREG */ -#define SPI_SLAVE_SIG_INACT (1 << 0) - -/* SPI_STS */ -#define SPI_ST_TX_DONE (1 << 25) -#define SPI_FIFO_LVL_MASK 0x1ff -#define SPI_TX_LVL_OFFSET 6 -#define SPI_RX_LVL_OFFSET 15 - -/* Feedback Delay */ -#define SPI_CLK_BYPASS (0 << 0) -#define SPI_FB_DELAY_90 (1 << 0) -#define SPI_FB_DELAY_180 (2 << 0) -#define SPI_FB_DELAY_270 (3 << 0) - -/* Packet Count */ -#define SPI_PACKET_CNT_EN (1 << 16) - -/* Swap config */ -#define SPI_TX_SWAP_EN (1 << 0) -#define SPI_TX_BYTE_SWAP (1 << 2) -#define SPI_TX_HWORD_SWAP (1 << 3) -#define SPI_TX_BYTE_SWAP (1 << 2) -#define SPI_RX_SWAP_EN (1 << 4) -#define SPI_RX_BYTE_SWAP (1 << 6) -#define SPI_RX_HWORD_SWAP (1 << 7) - -/* Serve as CBFS media source */ -int initialize_exynos_spi_cbfs_media(struct cbfs_media *media, - void *buffer_address, - size_t buffer_size); -#endif diff --git a/src/cpu/samsung/exynos5420/sysreg.h b/src/cpu/samsung/exynos5420/sysreg.h deleted file mode 100644 index fa25def318..0000000000 --- a/src/cpu/samsung/exynos5420/sysreg.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Register map for Exynos5 sysreg */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_SYSREG_H -#define CPU_SAMSUNG_EXYNOS5420_SYSREG_H - -#include "cpu.h" - -/* sysreg map */ -struct exynos5_sysreg { - /* Add registers as and when required */ - unsigned char res1[0x214]; - unsigned int disp1blk_cfg; - unsigned char res2[0x18]; - unsigned int usb20_phy_cfg; -}; - -static struct exynos5_sysreg * const exynos_sysreg = - (void *)EXYNOS5_SYSREG_BASE; - -#define FIMDBYPASS_DISP1 (1 << 15) -#define USB20_PHY_CFG_EN (1 << 0) - -#endif diff --git a/src/cpu/samsung/exynos5420/timer.c b/src/cpu/samsung/exynos5420/timer.c deleted file mode 100644 index ae13342c92..0000000000 --- a/src/cpu/samsung/exynos5420/timer.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2009 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <console/console.h> -#include <timer.h> -#include <delay.h> -#include <thread.h> -#include "clk.h" - -void init_timer(void) -{ - /* Nothing to do because we manually - * call mct_start() in the bootblock - */ -} - -/* delay x useconds */ -void udelay(unsigned usec) -{ - struct mono_time current, end; - - if (!thread_yield_microseconds(usec)) - return; - - timer_monotonic_get(¤t); - end = current; - mono_time_add_usecs(&end, usec); - - if (mono_time_after(¤t, &end)) { - printk(BIOS_EMERG, "udelay: 0x%08x is impossibly large\n", - usec); - /* There's not much we can do if usec is too big. Use a long, - * paranoid delay value and hope for the best... */ - end = current; - mono_time_add_usecs(&end, USECS_PER_SEC); - } - - while (mono_time_before(¤t, &end)) - timer_monotonic_get(¤t); -} diff --git a/src/cpu/samsung/exynos5420/tmu.c b/src/cpu/samsung/exynos5420/tmu.c deleted file mode 100644 index 1b04b6cb42..0000000000 --- a/src/cpu/samsung/exynos5420/tmu.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * Copyright 2013 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* EXYNOS - Thermal Management Unit */ - -#include <console/console.h> -#include <arch/io.h> -#include "power.h" -#include "tmu.h" - -#define TRIMINFO_RELOAD 1 -#define CORE_EN 1 -#define THERM_TRIP_EN (1 << 12) - -#define INTEN_RISE0 1 -#define INTEN_RISE1 (1 << 4) -#define INTEN_RISE2 (1 << 8) -#define INTEN_FALL0 (1 << 16) -#define INTEN_FALL1 (1 << 20) -#define INTEN_FALL2 (1 << 24) - -#define TRIM_INFO_MASK 0xff - -#define INTCLEAR_RISE0 1 -#define INTCLEAR_RISE1 (1 << 4) -#define INTCLEAR_RISE2 (1 << 8) -#define INTCLEAR_FALL0 (1 << 16) -#define INTCLEAR_FALL1 (1 << 20) -#define INTCLEAR_FALL2 (1 << 24) -#define INTCLEARALL (INTCLEAR_RISE0 | INTCLEAR_RISE1 | \ - INTCLEAR_RISE2 | INTCLEAR_FALL0 | \ - INTCLEAR_FALL1 | INTCLEAR_FALL2) - -struct tmu_info exynos5420_tmu_info = { - .tmu_base = 0x10060000, - .tmu_mux = 6, - .data = { - .ts = { - .min_val = 25, - .max_val = 125, - .start_warning = 95, - .start_tripping = 105, - .hardware_tripping = 110, - }, - .efuse_min_value = 40, - .efuse_value = 55, - .efuse_max_value = 100, - .slope = 0x10008802, - }, - .dc_value = 25, -}; - -/* - * After reading temperature code from register, compensating - * its value and calculating celsius temperatue, - * get current temperatue. - * - * @return current temperature of the chip as sensed by TMU - */ -static int get_cur_temp(struct tmu_info *info) -{ - int cur_temp; - struct tmu_reg *reg = (struct tmu_reg *)info->tmu_base; - - /* Temperature code range between min 25 and max 125 */ - cur_temp = readl(®->current_temp) & 0xff; - - /* Calibrate current temperature */ - if (cur_temp) - cur_temp = cur_temp - info->te1 + info->dc_value; - - return cur_temp; -} - -/* - * Monitors status of the TMU device and exynos temperature - * - * @info TMU info - * @temp pointer to the current temperature value - * @return enum tmu_status_t value, code indicating event to execute - */ -enum tmu_status_t tmu_monitor(struct tmu_info *info, int *temp) -{ - if (info->tmu_state == TMU_STATUS_INIT) - return -1; - - int cur_temp; - struct tmu_data *data = &info->data; - - /* Read current temperature of the SOC */ - cur_temp = get_cur_temp(info); - *temp = cur_temp; - - /* Temperature code lies between min 25 and max 125 */ - if (cur_temp >= data->ts.start_tripping && - cur_temp <= data->ts.max_val) - return TMU_STATUS_TRIPPED; - else if (cur_temp >= data->ts.start_warning) - return TMU_STATUS_WARNING; - else if (cur_temp < data->ts.start_warning && - cur_temp >= data->ts.min_val) - return TMU_STATUS_NORMAL; - /* Temperature code does not lie between min 25 and max 125 */ - else { - info->tmu_state = TMU_STATUS_INIT; - printk(BIOS_DEBUG, "EXYNOS_TMU: Thermal reading failed\n"); - return -1; - } - return 0; -} - -/* - * Calibrate and calculate threshold values and - * enable interrupt levels - * - * @param info pointer to the tmu_info struct - */ -static void tmu_setup_parameters(struct tmu_info *info) -{ - unsigned int te_temp, con; - unsigned int warning_code, trip_code, hwtrip_code; - unsigned int cooling_temp; - unsigned int rising_value; - struct tmu_data *data = &info->data; - struct tmu_reg *reg = (struct tmu_reg *)info->tmu_base; - - /* Must reload for using efuse value at EXYNOS */ - writel(TRIMINFO_RELOAD, ®->triminfo_control); - - /* Get the compensation parameter */ - te_temp = readl(®->triminfo); - info->te1 = te_temp & TRIM_INFO_MASK; - info->te2 = ((te_temp >> 8) & TRIM_INFO_MASK); - - if ((data->efuse_min_value > info->te1) || - (info->te1 > data->efuse_max_value) - || (info->te2 != 0)) - info->te1 = data->efuse_value; - - /* Get RISING & FALLING Threshold value */ - warning_code = data->ts.start_warning - + info->te1 - info->dc_value; - trip_code = data->ts.start_tripping - + info->te1 - info->dc_value; - hwtrip_code = data->ts.hardware_tripping - + info->te1 - info->dc_value; - - cooling_temp = 0; - - rising_value = ((warning_code << 8) | - (trip_code << 16) | - (hwtrip_code << 24)); - - /* Set interrupt level */ - writel(rising_value, ®->threshold_temp_rise); - writel(cooling_temp, ®->threshold_temp_fall); - - /* - * Need to init all register settings after getting parameter info - * [28:23] vref [11:8] slope - Tuning parameter - * - * WARNING: this slope value writes into many bits in the tmu_control - * register, with the default FDT value of 268470274 (0x10008802) - * we are using this essentially sets the default register setting - * from the TRM for tmu_control. - * TODO(bhthompson): rewrite this code such that we are not performing - * a hard wipe of tmu_control and re verify functionality. - */ - writel(data->slope, ®->tmu_control); - - writel(INTCLEARALL, ®->intclear); - /* TMU core enable */ - con = readl(®->tmu_control); - con |= (info->tmu_mux << 20) | THERM_TRIP_EN | CORE_EN; - - writel(con, ®->tmu_control); - - /* Enable HW thermal trip */ - power_enable_hw_thermal_trip(); - - /* LEV1 LEV2 interrupt enable */ - writel(INTEN_RISE1 | INTEN_RISE2, ®->inten); -} - -/* - * Initialize TMU device - * - * @return int value, 0 for success - */ -int tmu_init(struct tmu_info *info) -{ - info->tmu_state = TMU_STATUS_INIT; - - tmu_setup_parameters(info); - info->tmu_state = TMU_STATUS_NORMAL; - - return 0; -} diff --git a/src/cpu/samsung/exynos5420/tmu.h b/src/cpu/samsung/exynos5420/tmu.h deleted file mode 100644 index cf81b9ad33..0000000000 --- a/src/cpu/samsung/exynos5420/tmu.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* EXYNOS - Thermal Management Unit */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_TMU_H -#define CPU_SAMSUNG_EXYNOS5420_TMU_H - -struct tmu_reg { - unsigned triminfo; - unsigned rsvd1; - unsigned rsvd2; - unsigned rsvd3; - unsigned rsvd4; - unsigned triminfo_control; - unsigned rsvd5; - unsigned rsvd6; - unsigned tmu_control; - unsigned rsvd7; - unsigned tmu_status; - unsigned sampling_internal; - unsigned counter_value0; - unsigned counter_value1; - unsigned rsvd8; - unsigned rsvd9; - unsigned current_temp; - unsigned rsvd10; - unsigned rsvd11; - unsigned rsvd12; - unsigned threshold_temp_rise; - unsigned threshold_temp_fall; - unsigned rsvd13; - unsigned rsvd14; - unsigned past_temp3_0; - unsigned past_temp7_4; - unsigned past_temp11_8; - unsigned past_temp15_12; - unsigned inten; - unsigned intstat; - unsigned intclear; - unsigned rsvd15; - unsigned emul_con; -}; - -enum tmu_status_t { - TMU_STATUS_INIT = 0, - TMU_STATUS_NORMAL, - TMU_STATUS_WARNING, - TMU_STATUS_TRIPPED, -}; - -/* Tmeperature threshold values for various thermal events */ -struct temperature_params { - /* minimum value in temperature code range */ - unsigned int min_val; - /* maximum value in temperature code range */ - unsigned int max_val; - /* temperature threshold to start warning */ - unsigned int start_warning; - /* temperature threshold CPU tripping */ - unsigned int start_tripping; - /* temperature threshold for HW tripping */ - unsigned int hardware_tripping; -}; - -/* Pre-defined values and thresholds for calibration of current temperature */ -struct tmu_data { - /* pre-defined temperature thresholds */ - struct temperature_params ts; - /* pre-defined efuse range minimum value */ - unsigned int efuse_min_value; - /* pre-defined efuse value for temperature calibration */ - unsigned int efuse_value; - /* pre-defined efuse range maximum value */ - unsigned int efuse_max_value; - /* current temperature sensing slope */ - unsigned int slope; -}; - -/* TMU device specific details and status */ -struct tmu_info { - /* base Address for the TMU */ - unsigned tmu_base; - /* mux Address for the TMU */ - int tmu_mux; - /* pre-defined values for calibration and thresholds */ - struct tmu_data data; - /* value required for triminfo_25 calibration */ - unsigned int te1; - /* value required for triminfo_85 calibration */ - unsigned int te2; - /* TMU DC value for threshold calculation */ - int dc_value; - /* enum value indicating status of the TMU */ - int tmu_state; -}; - -extern struct tmu_info *tmu_info; - -/* - * Monitors status of the TMU device and exynos temperature - * - * @info pointer to TMU info struct - * @temp pointer to the current temperature value - * @return enum tmu_status_t value, code indicating event to execute - * and -1 on error - */ -enum tmu_status_t tmu_monitor(struct tmu_info *info, int *temp); - -/* - * Initialize TMU device - * - * @info pointer to TMU info struct - * @return int value, 0 for success - */ -int tmu_init(struct tmu_info *info); - -#endif /* CPU_SAMSUNG_EXYNOS5420_TMU_H */ diff --git a/src/cpu/samsung/exynos5420/trustzone.c b/src/cpu/samsung/exynos5420/trustzone.c deleted file mode 100644 index 7b1489a1a6..0000000000 --- a/src/cpu/samsung/exynos5420/trustzone.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <arch/io.h> -#include "trustzone.h" - -/* Setting TZPC[TrustZone Protection Controller] - * We pretty much disable it all, as the kernel - * expects it that way -- and that's not the default. - */ -void trustzone_init(void) -{ - struct exynos_tzpc *tzpc; - unsigned int addr; - - for (addr = TZPC10_BASE; addr <= TZPC9_BASE; addr += TZPC_BASE_OFFSET) { - tzpc = (struct exynos_tzpc *)addr; - if (addr == TZPC0_BASE) - writel(R0SIZE, &tzpc->r0size); - writel(DECPROTXSET, &tzpc->decprot0set); - writel(DECPROTXSET, &tzpc->decprot1set); - writel(DECPROTXSET, &tzpc->decprot2set); - writel(DECPROTXSET, &tzpc->decprot3set); - } -} diff --git a/src/cpu/samsung/exynos5420/trustzone.h b/src/cpu/samsung/exynos5420/trustzone.h deleted file mode 100644 index 69e683aeba..0000000000 --- a/src/cpu/samsung/exynos5420/trustzone.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_TRUSTZONE_H -#define CPU_SAMSUNG_EXYNOS5420_TRUSTZONE_H - -#include <stdint.h> - -/* Distance between each Trust Zone PC register set */ -#define TZPC_BASE_OFFSET 0x10000 -/* TZPC : Register Offsets */ -#define TZPC0_BASE 0x10100000 -#define TZPC1_BASE 0x10110000 -#define TZPC2_BASE 0x10120000 -#define TZPC3_BASE 0x10130000 -#define TZPC4_BASE 0x10140000 -#define TZPC5_BASE 0x10150000 -#define TZPC6_BASE 0x10160000 -#define TZPC7_BASE 0x10170000 -#define TZPC8_BASE 0x10180000 -#define TZPC9_BASE 0x10190000 -#define TZPC10_BASE 0x100E0000 -#define TZPC11_BASE 0x100F0000 - -/* - * TZPC Register Value : - * R0SIZE: 0x0 : Size of secured ram - */ -#define R0SIZE 0x0 - -/* - * TZPC Decode Protection Register Value : - * DECPROTXSET: 0xFF : Set Decode region to non-secure - */ -#define DECPROTXSET 0xFF - -struct exynos_tzpc { - u32 r0size; - u8 res1[0x7FC]; - u32 decprot0stat; - u32 decprot0set; - u32 decprot0clr; - u32 decprot1stat; - u32 decprot1set; - u32 decprot1clr; - u32 decprot2stat; - u32 decprot2set; - u32 decprot2clr; - u32 decprot3stat; - u32 decprot3set; - u32 decprot3clr; - u8 res2[0x7B0]; - u32 periphid0; - u32 periphid1; - u32 periphid2; - u32 periphid3; - u32 pcellid0; - u32 pcellid1; - u32 pcellid2; - u32 pcellid3; -}; - -void trustzone_init(void); - -#endif /* CPU_SAMSUNG_EXYNOS5420_TRUSTZONE_H */ diff --git a/src/cpu/samsung/exynos5420/uart.c b/src/cpu/samsung/exynos5420/uart.c deleted file mode 100644 index be96d5b86c..0000000000 --- a/src/cpu/samsung/exynos5420/uart.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2009 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <types.h> -#include <console/uart.h> -#include <arch/io.h> -#include <boot/coreboot_tables.h> -#include "uart.h" -#include "clk.h" -#include "cpu.h" -#include "periph.h" -#include "uart.h" - -#define RX_FIFO_COUNT_MASK 0xff -#define RX_FIFO_FULL_MASK (1 << 8) -#define TX_FIFO_FULL_MASK (1 << 24) - - -/* - * The coefficient, used to calculate the baudrate on S5P UARTs is - * calculated as - * C = UBRDIV * 16 + number_of_set_bits_in_UDIVSLOT - * however, section 31.6.11 of the datasheet doesn't recomment using 1 for 1, - * 3 for 2, ... (2^n - 1) for n, instead, they suggest using these constants: - */ -static const int udivslot[] = { - 0, - 0x0080, - 0x0808, - 0x0888, - 0x2222, - 0x4924, - 0x4a52, - 0x54aa, - 0x5555, - 0xd555, - 0xd5d5, - 0xddd5, - 0xdddd, - 0xdfdd, - 0xdfdf, - 0xffdf, -}; - -static void serial_setbrg_dev(struct s5p_uart *uart) -{ - u32 uclk; - u32 val; - - // All UARTs share the same clock. - uclk = clock_get_periph_rate(PERIPH_ID_UART3); - val = uclk / default_baudrate(); - - writel(val / 16 - 1, &uart->ubrdiv); - - /* - * FIXME(dhendrix): the original uart.h had a "br_rest" value which - * does not seem relevant to the exynos5420... not entirely sure - * where/if we need to worry about it here - */ -#if 0 - if (s5p_uart_divslot()) - writel(udivslot[val % 16], &uart->rest.slot); - else - writeb(val % 16, &uart->rest.value); -#endif -} - -/* - * Initialise the serial port with the given baudrate. The settings - * are always 8 data bits, no parity, 1 stop bit, no start bits. - */ -static void exynos5_init_dev(struct s5p_uart *uart) -{ - /* enable FIFOs */ - writel(0x1, &uart->ufcon); - writel(0, &uart->umcon); - /* 8N1 */ - writel(0x3, &uart->ulcon); - /* No interrupts, no DMA, pure polling */ - writel(0x245, &uart->ucon); - - serial_setbrg_dev(uart); -} - -static int exynos5_uart_err_check(struct s5p_uart *uart, int op) -{ - unsigned int mask; - - /* - * UERSTAT - * Break Detect [3] - * Frame Err [2] : receive operation - * Parity Err [1] : receive operation - * Overrun Err [0] : receive operation - */ - if (op) - mask = 0x8; - else - mask = 0xf; - - return readl(&uart->uerstat) & mask; -} - -/* - * Read a single byte from the serial port. Returns 1 on success, 0 - * otherwise. When the function is succesfull, the character read is - * written into its argument c. - */ -static unsigned char exynos5_uart_rx_byte(struct s5p_uart *uart) -{ - /* wait for character to arrive */ - while (!(readl(&uart->ufstat) & (RX_FIFO_COUNT_MASK | - RX_FIFO_FULL_MASK))) { - if (exynos5_uart_err_check(uart, 0)) - return 0; - } - - return readb(&uart->urxh) & 0xff; -} - -/* - * Output a single byte to the serial port. - */ -static void exynos5_uart_tx_byte(struct s5p_uart *uart, unsigned char data) -{ - /* wait for room in the tx FIFO */ - while ((readl(&uart->ufstat) & TX_FIFO_FULL_MASK)) { - if (exynos5_uart_err_check(uart, 1)) - return; - } - - writeb(data, &uart->utxh); -} - -unsigned int uart_platform_base(int idx) -{ - if (idx < 4) - return 0x12c00000 + idx * 0x10000; - else - return 0; -} - -void uart_init(int idx) -{ - struct s5p_uart *uart = uart_platform_baseptr(idx); - exynos5_init_dev(uart); -} - -unsigned char uart_rx_byte(int idx) -{ - struct s5p_uart *uart = uart_platform_baseptr(idx); - return exynos5_uart_rx_byte(uart); -} - -void uart_tx_byte(int idx, unsigned char data) -{ - struct s5p_uart *uart = uart_platform_baseptr(idx); - exynos5_uart_tx_byte(uart, data); -} - -void uart_tx_flush(int idx) -{ - /* Exynos5250 implements this too. */ -} - -#ifndef __PRE_RAM__ -void uart_fill_lb(void *data) -{ - struct lb_serial serial; - serial.type = LB_SERIAL_TYPE_MEMORY_MAPPED; - serial.baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE); - serial.baud = default_baudrate(); - lb_add_serial(&serial, data); - - lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM, data); -} -#endif diff --git a/src/cpu/samsung/exynos5420/uart.h b/src/cpu/samsung/exynos5420/uart.h deleted file mode 100644 index 72a5789b6d..0000000000 --- a/src/cpu/samsung/exynos5420/uart.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2012 Google Inc. - * Copyright (C) 2009 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_UART_H -#define CPU_SAMSUNG_EXYNOS5420_UART_H - -/* baudrate rest value */ -union br_rest { - unsigned short slot; /* udivslot */ - unsigned char value; /* ufracval */ -}; - -struct s5p_uart { - unsigned int ulcon; - unsigned int ucon; - unsigned int ufcon; - unsigned int umcon; - unsigned int utrstat; - unsigned int uerstat; - unsigned int ufstat; - unsigned int umstat; - unsigned char utxh; - unsigned char res1[3]; - unsigned char urxh; - unsigned char res2[3]; - unsigned int ubrdiv; - union br_rest rest; - unsigned char res3[0xffd0]; -}; - -#endif diff --git a/src/cpu/samsung/exynos5420/usb.c b/src/cpu/samsung/exynos5420/usb.c deleted file mode 100644 index 84a6f4ca4c..0000000000 --- a/src/cpu/samsung/exynos5420/usb.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * Copyright 2013 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <delay.h> -#include <arch/io.h> -#include <console/console.h> -#include <device/device.h> -#include "gpio.h" -#include "power.h" -#include "sysreg.h" -#include "usb.h" - -static void reset_dwc3(struct exynos5_usb_drd_dwc3 *dwc3) -{ - setbits_le32(&dwc3->ctl, 0x1 << 11); /* core soft reset */ - setbits_le32(&dwc3->usb3pipectl, 0x1 << 31); /* PHY soft reset */ - setbits_le32(&dwc3->usb2phycfg, 0x1 << 31); /* PHY soft reset */ -} - -void reset_usb_drd0_dwc3() -{ - printk(BIOS_DEBUG, "Starting DWC3 reset for USB DRD0\n"); - reset_dwc3(exynos_usb_drd0_dwc3); -} - -void reset_usb_drd1_dwc3() -{ - printk(BIOS_DEBUG, "Starting DWC3 reset for USB DRD1\n"); - reset_dwc3(exynos_usb_drd1_dwc3); -} - -static void setup_dwc3(struct exynos5_usb_drd_dwc3 *dwc3) -{ - if (!(dwc3->ctl & 0x1 << 11) || - !(dwc3->usb3pipectl & 0x1 << 31) || - !(dwc3->usb2phycfg & 0x1 << 31)) { - printk(BIOS_ERR, "DWC3 at %p not in reset (you need to call " - "reset_usb_drdX_dwc3() first)!\n", dwc3); - } - - /* Set relevant registers to default values (clearing all reset bits) */ - - writel(0x1 << 24 | /* activate PHY low power states */ - 0x4 << 19 | /* low power delay value */ - 0x1 << 18 | /* activate PHY low power delay */ - 0x1 << 17 | /* enable SuperSpeed PHY suspend */ - 0x1 << 1 | /* default Tx deemphasis value */ - 0, &dwc3->usb3pipectl); - - /* Configure PHY clock turnaround for 8-bit UTMI+, disable suspend */ - writel(0x9 << 10 | /* PHY clock turnaround for 8-bit UTMI+ */ - 0x1 << 8 | /* enable PHY sleep in L1 */ - 0x1 << 6 | /* enable PHY suspend */ - 0, &dwc3->usb2phycfg); - - writel(0x5dc << 19 | /* suspend clock scale for 24MHz */ - 0x1 << 16 | /* retry SS three times (bugfix from U-Boot) */ - 0x1 << 12 | /* port capability HOST */ - 0, &dwc3->ctl); -} - -void setup_usb_drd0_dwc3() -{ - setup_dwc3(exynos_usb_drd0_dwc3); - printk(BIOS_DEBUG, "DWC3 setup for USB DRD0 finished\n"); -} - -void setup_usb_drd1_dwc3() -{ - setup_dwc3(exynos_usb_drd1_dwc3); - printk(BIOS_DEBUG, "DWC3 setup for USB DRD1 finished\n"); -} - -static void setup_drd_phy(struct exynos5_usb_drd_phy *phy) -{ - /* Set all PHY registers to default values */ - - /* XHCI Version 1.0, Frame Length adjustment 30 MHz */ - setbits_le32(&phy->linksystem, 0x1 << 27 | 0x20 << 1); - - /* Disable OTG, ID0 and DRVVBUS, do not force sleep/suspend */ - writel(1 << 6, &phy->utmi); - - writel(0x88 << 23 | /* spread spectrum refclk selector */ - 0x1 << 20 | /* enable spread spectrum */ - 0x1 << 19 | /* enable prescaler refclk */ - 0x68 << 11 | /* multiplier for 24MHz refclk */ - 0x5 << 5 | /* select 24MHz refclk (weird, from U-Boot) */ - 0x1 << 4 | /* power supply in normal operating mode */ - 0x3 << 2 | /* use external refclk (undocumented on 5420?)*/ - 0x1 << 1 | /* force port reset */ - 0x1 << 0 | /* normal operating mode */ - 0, &phy->clkrst); - - writel(0x9 << 26 | /* LOS level */ - 0x3 << 22 | /* TX VREF tune */ - 0x1 << 20 | /* TX rise tune */ - 0x1 << 18 | /* TX res tune */ - 0x3 << 13 | /* TX HS X Vtune */ - 0x3 << 9 | /* TX FS/LS tune */ - 0x3 << 6 | /* SQRX tune */ - 0x4 << 3 | /* OTG tune */ - 0x4 << 0 | /* comp disc tune */ - 0, &phy->param0); - - writel(0x7f << 19 | /* reserved */ - 0x7f << 12 | /* Tx launch amplitude */ - 0x20 << 6 | /* Tx deemphasis 6dB */ - 0x1c << 0 | /* Tx deemphasis 3.5dB (value from U-Boot) */ - 0, &phy->param1); - - /* disable all test features */ - writel(0, &phy->test); - - /* UTMI clock select? ("must be 0x1") */ - writel(0x1 << 2, &phy->utmiclksel); - - /* Samsung magic, undocumented (from U-Boot) */ - writel(0x0, &phy->resume); - - udelay(10); - clrbits_le32(&phy->clkrst, 0x1 << 1); /* deassert port reset */ -} - -void setup_usb_drd0_phy() -{ - printk(BIOS_DEBUG, "Powering up USB DRD0 PHY\n"); - setbits_le32(&exynos_power->usb_drd0_phy_ctrl, POWER_USB_PHY_CTRL_EN); - setup_drd_phy(exynos_usb_drd0_phy); -} - -void setup_usb_drd1_phy() -{ - printk(BIOS_DEBUG, "Powering up USB DRD1 PHY\n"); - setbits_le32(&exynos_power->usb_drd1_phy_ctrl, POWER_USB_PHY_CTRL_EN); - setup_drd_phy(exynos_usb_drd1_phy); -} - -void setup_usb_host_phy(int hsic_gpio) -{ - unsigned int hostphy_ctrl0; - - setbits_le32(&exynos_sysreg->usb20_phy_cfg, USB20_PHY_CFG_EN); - setbits_le32(&exynos_power->usb_host_phy_ctrl, POWER_USB_PHY_CTRL_EN); - - printk(BIOS_DEBUG, "Powering up USB HOST PHY (%s HSIC)\n", - hsic_gpio ? "with" : "without"); - - hostphy_ctrl0 = readl(&exynos_usb_host_phy->usbphyctrl0); - hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK | - HOST_CTRL0_COMMONON_N | - /* HOST Phy setting */ - HOST_CTRL0_PHYSWRST | - HOST_CTRL0_PHYSWRSTALL | - HOST_CTRL0_SIDDQ | - HOST_CTRL0_FORCESUSPEND | - HOST_CTRL0_FORCESLEEP); - hostphy_ctrl0 |= (/* Setting up the ref freq */ - CLK_24MHZ << 16 | - /* HOST Phy setting */ - HOST_CTRL0_LINKSWRST | - HOST_CTRL0_UTMISWRST); - writel(hostphy_ctrl0, &exynos_usb_host_phy->usbphyctrl0); - udelay(10); - clrbits_le32(&exynos_usb_host_phy->usbphyctrl0, - HOST_CTRL0_LINKSWRST | - HOST_CTRL0_UTMISWRST); - udelay(20); - - /* EHCI Ctrl setting */ - setbits_le32(&exynos_usb_host_phy->ehcictrl, - EHCICTRL_ENAINCRXALIGN | - EHCICTRL_ENAINCR4 | - EHCICTRL_ENAINCR8 | - EHCICTRL_ENAINCR16); - - /* HSIC USB Hub initialization. */ - if (hsic_gpio) { - gpio_direction_output(hsic_gpio, 0); - udelay(100); - gpio_direction_output(hsic_gpio, 1); - udelay(5000); - - clrbits_le32(&exynos_usb_host_phy->hsicphyctrl1, - HOST_CTRL0_SIDDQ | - HOST_CTRL0_FORCESLEEP | - HOST_CTRL0_FORCESUSPEND); - setbits_le32(&exynos_usb_host_phy->hsicphyctrl1, - HOST_CTRL0_PHYSWRST); - udelay(10); - clrbits_le32(&exynos_usb_host_phy->hsicphyctrl1, - HOST_CTRL0_PHYSWRST); - } - - /* At this point we need to wait for 50ms before talking to - * the USB controller (PHY clock and power setup time) - * By the time we are actually in the payload, these 50ms - * will have passed. - */ -} diff --git a/src/cpu/samsung/exynos5420/usb.h b/src/cpu/samsung/exynos5420/usb.h deleted file mode 100644 index b3c2a33fd6..0000000000 --- a/src/cpu/samsung/exynos5420/usb.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Samsung Electronics - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_USB_H -#define CPU_SAMSUNG_EXYNOS5420_USB_H - -#include "cpu.h" - -#define CLK_24MHZ 5 - -#define HOST_CTRL0_PHYSWRSTALL (1 << 31) -#define HOST_CTRL0_COMMONON_N (1 << 9) -#define HOST_CTRL0_SIDDQ (1 << 6) -#define HOST_CTRL0_FORCESLEEP (1 << 5) -#define HOST_CTRL0_FORCESUSPEND (1 << 4) -#define HOST_CTRL0_WORDINTERFACE (1 << 3) -#define HOST_CTRL0_UTMISWRST (1 << 2) -#define HOST_CTRL0_LINKSWRST (1 << 1) -#define HOST_CTRL0_PHYSWRST (1 << 0) - -#define HOST_CTRL0_FSEL_MASK (7 << 16) - -#define EHCICTRL_ENAINCRXALIGN (1 << 29) -#define EHCICTRL_ENAINCR4 (1 << 28) -#define EHCICTRL_ENAINCR8 (1 << 27) -#define EHCICTRL_ENAINCR16 (1 << 26) - -/* Register map for PHY control */ -struct exynos5_usb_host_phy { - uint32_t usbphyctrl0; - uint32_t usbphytune0; - uint8_t reserved1[8]; - uint32_t hsicphyctrl1; - uint32_t hsicphytune1; - uint8_t reserved2[8]; - uint32_t hsicphyctrl2; - uint32_t hsicphytune2; - uint8_t reserved3[8]; - uint32_t ehcictrl; - uint32_t ohcictrl; - uint32_t usbotgsys; - uint8_t reserved4[4]; - uint32_t usbotgtune; -}; - -static struct exynos5_usb_host_phy * const exynos_usb_host_phy = - (void *)EXYNOS5_USB_HOST_PHY_BASE; - -struct exynos5_usb_drd_phy { - uint8_t reserved1[4]; - uint32_t linksystem; - uint32_t utmi; - uint32_t pipe; - uint32_t clkrst; - uint32_t reg0; - uint32_t reg1; - uint32_t param0; - uint32_t param1; - uint32_t term; - uint32_t test; - uint32_t adp; - uint32_t utmiclksel; - uint32_t resume; - uint8_t reserved2[8]; - uint32_t linkhcbelt; - uint32_t linkport; -}; - -static struct exynos5_usb_drd_phy * const exynos_usb_drd0_phy = - (void *)EXYNOS5420_USB_DRD0_PHY_BASE; -static struct exynos5_usb_drd_phy * const exynos_usb_drd1_phy = - (void *)EXYNOS5420_USB_DRD1_PHY_BASE; - -struct exynos5_usb_drd_dwc3 { - uint32_t sbuscfg0; - uint32_t sbuscfg1; - uint32_t txthrcfg; - uint32_t rxthrcfg; - uint32_t ctl; - uint32_t evten; - uint32_t sts; - uint8_t reserved0[4]; - uint32_t snpsid; - uint32_t gpio; - uint32_t uid; - uint32_t uctl; - uint64_t buserraddr; - uint64_t prtbimap; - uint8_t reserved1[32]; - uint32_t dbgfifospace; - uint32_t dbgltssm; - uint32_t dbglnmcc; - uint32_t dbgbmu; - uint32_t dbglspmux; - uint32_t dbglsp; - uint32_t dbgepinfo0; - uint32_t dbgepinfo1; - uint64_t prtbimap_hs; - uint64_t prtbimap_fs; - uint8_t reserved2[112]; - uint32_t usb2phycfg; - uint8_t reserved3[60]; - uint32_t usb2i2cctl; - uint8_t reserved4[60]; - uint32_t usb2phyacc; - uint8_t reserved5[60]; - uint32_t usb3pipectl; - uint8_t reserved6[60]; -}; - -static struct exynos5_usb_drd_dwc3 * const exynos_usb_drd0_dwc3 = - (void *)EXYNOS5420_USB_DRD0_DWC3_BASE; -static struct exynos5_usb_drd_dwc3 * const exynos_usb_drd1_dwc3 = - (void *)EXYNOS5420_USB_DRD1_DWC3_BASE; - -/* Leave hsic_gpio at 0 to not enable HSIC. */ -void setup_usb_host_phy(int hsic_gpio); - -void setup_usb_drd0_phy(void); -void setup_usb_drd1_phy(void); - -/* Call reset_ before setup_, ensure at least 100ms pass in between. */ -void reset_usb_drd0_dwc3(void); -void reset_usb_drd1_dwc3(void); -void setup_usb_drd0_dwc3(void); -void setup_usb_drd1_dwc3(void); - -#endif diff --git a/src/cpu/samsung/exynos5420/wakeup.c b/src/cpu/samsung/exynos5420/wakeup.c deleted file mode 100644 index 753afd9591..0000000000 --- a/src/cpu/samsung/exynos5420/wakeup.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <arch/cache.h> -#include <console/console.h> -#include "power.h" -#include "wakeup.h" - -void wakeup(void) -{ - if (wakeup_need_reset()) - power_reset(); - - power_init(); /* Ensure ps_hold_setup() for early wakeup. */ - dcache_mmu_disable(); - icache_invalidate_all(); - power_exit_wakeup(); - /* Should never return. If we do, reset. */ - power_reset(); -} - -int get_wakeup_state(void) -{ - uint32_t status = power_read_reset_status(); - - /* DIDLE/LPA can be resumed without clock reset (ex, bootblock), - * and SLEEP requires resetting clock (should be done in ROM stage). - */ - - if (status == S5P_CHECK_DIDLE || status == S5P_CHECK_LPA) - return WAKEUP_DIRECT; - - if (status == S5P_CHECK_SLEEP) - return WAKEUP_NEED_CLOCK_RESET; - - return IS_NOT_WAKEUP; -} - -void wakeup_enable_uart(void) -{ - power_release_uart_retention(); -} diff --git a/src/cpu/samsung/exynos5420/wakeup.h b/src/cpu/samsung/exynos5420/wakeup.h deleted file mode 100644 index 27ce8e2f2d..0000000000 --- a/src/cpu/samsung/exynos5420/wakeup.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CPU_SAMSUNG_EXYNOS5420_WAKEUP_H -#define CPU_SAMSUNG_EXYNOS5420_WAKEUP_H - -/* Power Down Modes */ -#define S5P_CHECK_SLEEP 0x00000BAD -#define S5P_CHECK_DIDLE 0xBAD00000 -#define S5P_CHECK_LPA 0xABAD0000 - -enum { - // A normal boot (not suspend/resume) - IS_NOT_WAKEUP, - // A wake up event that can be resumed any time - WAKEUP_DIRECT, - // A wake up event that must be resumed only after - // clock and memory controllers are re-initialized - WAKEUP_NEED_CLOCK_RESET, -}; - -int wakeup_need_reset(void); -int get_wakeup_state(void); -void wakeup(void); -void wakeup_enable_uart(void); - -#endif /* CPU_SAMSUNG_EXYNOS5420_WAKEUP_H */ |