Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-samsung
- Assorted updates
This commit is contained in:
@@ -2,7 +2,7 @@ if ARCH_EXYNOS
|
||||
|
||||
config BOARD_COMMON
|
||||
def_bool y
|
||||
depends on !TARGET_SMDKV310 && !TARGET_ARNDALE && !TARGET_E850_96
|
||||
depends on !TARGET_SMDKV310 && !TARGET_ARNDALE && !TARGET_EXYNOS_MOBILE && !TARGET_E850_96
|
||||
|
||||
config SPI_BOOTING
|
||||
bool
|
||||
@@ -252,6 +252,14 @@ config TARGET_E850_96
|
||||
endchoice
|
||||
endif
|
||||
|
||||
config TARGET_EXYNOS_MOBILE
|
||||
bool "Samsung Exynos Generic Boards (for mobile devices)"
|
||||
select ARM64
|
||||
select BOARD_EARLY_INIT_F
|
||||
select CLK_EXYNOS
|
||||
select LINUX_KERNEL_IMAGE_HEADER
|
||||
select OF_CONTROL
|
||||
|
||||
config SYS_SOC
|
||||
default "exynos"
|
||||
|
||||
@@ -277,5 +285,6 @@ source "board/samsung/smdk5420/Kconfig"
|
||||
source "board/samsung/espresso7420/Kconfig"
|
||||
source "board/samsung/axy17lte/Kconfig"
|
||||
source "board/samsung/e850-96/Kconfig"
|
||||
source "board/samsung/exynos-mobile/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# Copyright (C) 2024, Linaro Limited
|
||||
# Sam Protsenko <semen.protsenko@linaro.org>
|
||||
|
||||
obj-y := e850-96.o fw.o acpm.o pmic.o
|
||||
obj-y := e850-96.o fw.o acpm.o pmic.o bootdev.o
|
||||
|
||||
99
board/samsung/e850-96/bootdev.c
Normal file
99
board/samsung/e850-96/bootdev.c
Normal file
@@ -0,0 +1,99 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2025 Linaro Ltd.
|
||||
* Author: Sam Protsenko <semen.protsenko@linaro.org>
|
||||
*
|
||||
* Routines for checking current boot device.
|
||||
*/
|
||||
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <vsprintf.h>
|
||||
#include "bootdev.h"
|
||||
|
||||
/* Flag from BL2 bootloader in RAM */
|
||||
#define BL2_TAG_ADDR 0x80000000 /* DRAM base */
|
||||
#define BL2_TAG 0xabcdef
|
||||
|
||||
/* Boot device info location in iRAM (only accessible from EL3) */
|
||||
#define IRAM_BASE 0x02020000
|
||||
#define BOOTDEVICE_INFO_ADDR (IRAM_BASE + 0x64)
|
||||
|
||||
/* SMC call for getting boot device information from EL3 monitor */
|
||||
#define SMC_CMD_CHECK_SECOND_BOOT -233
|
||||
|
||||
/* Boot device constants for the encoded boot device info value */
|
||||
#define BD_NO_DEVICE 0x0
|
||||
#define BD_UFS 0x1
|
||||
#define BD_EMMC 0x2
|
||||
#define BD_ERROR 0x3
|
||||
#define BD_USB 0x4
|
||||
#define BD_SDMMC 0x5
|
||||
#define BD_UFS_CARD 0x6
|
||||
#define BD_SPI 0x7
|
||||
|
||||
/* If BL2 bootloader wasn't executed, it means U-Boot is running via JTAG */
|
||||
static bool bootdev_is_jtag_session(void)
|
||||
{
|
||||
u32 bl2_tag_val = *(u32 *)BL2_TAG_ADDR;
|
||||
|
||||
return bl2_tag_val != BL2_TAG;
|
||||
}
|
||||
|
||||
/* Obtain boot device information encoded in 32-bit value */
|
||||
static u32 bootdev_get_info(void)
|
||||
{
|
||||
u32 info;
|
||||
|
||||
/*
|
||||
* On regular boot U-Boot is executed by BL2 bootloader, and is running
|
||||
* in EL1 mode, so the boot device information has to be obtained via
|
||||
* SMC call from EL3 software (EL3 monitor), which can read that info
|
||||
* from the protected iRAM memory. If U-Boot is running via TRACE32 JTAG
|
||||
* (in EL3 mode), read the boot device info directly from iRAM, as EL3
|
||||
* software might not be available.
|
||||
*/
|
||||
if (bootdev_is_jtag_session()) {
|
||||
info = *(u32 *)BOOTDEVICE_INFO_ADDR;
|
||||
} else {
|
||||
struct arm_smccc_res res;
|
||||
|
||||
arm_smccc_smc(SMC_CMD_CHECK_SECOND_BOOT, 0, 0, 0, 0, 0, 0, 0,
|
||||
&res);
|
||||
info = (u32)res.a2;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
enum bootdev bootdev_get_current(void)
|
||||
{
|
||||
u32 info, magic, order, dev;
|
||||
|
||||
info = bootdev_get_info();
|
||||
magic = info >> 24;
|
||||
order = info & 0xf;
|
||||
dev = (info >> (4 * order)) & 0xf;
|
||||
|
||||
if (magic != 0xcb)
|
||||
panic("Abnormal boot");
|
||||
|
||||
switch (dev) {
|
||||
case BD_UFS:
|
||||
return BOOTDEV_UFS;
|
||||
case BD_EMMC:
|
||||
return BOOTDEV_EMMC;
|
||||
case BD_USB:
|
||||
return BOOTDEV_USB;
|
||||
case BD_SDMMC:
|
||||
return BOOTDEV_SD;
|
||||
default:
|
||||
return BOOTDEV_ERROR;
|
||||
}
|
||||
|
||||
return BOOTDEV_ERROR;
|
||||
}
|
||||
|
||||
bool bootdev_is_usb(void)
|
||||
{
|
||||
return bootdev_get_current() == BOOTDEV_USB;
|
||||
}
|
||||
23
board/samsung/e850-96/bootdev.h
Normal file
23
board/samsung/e850-96/bootdev.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2025 Linaro Ltd.
|
||||
* Sam Protsenko <semen.protsenko@linaro.org>
|
||||
*/
|
||||
|
||||
#ifndef __E850_96_BOOTDEV_H
|
||||
#define __E850_96_BOOTDEV_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
enum bootdev {
|
||||
BOOTDEV_ERROR,
|
||||
BOOTDEV_SD,
|
||||
BOOTDEV_EMMC,
|
||||
BOOTDEV_USB,
|
||||
BOOTDEV_UFS,
|
||||
};
|
||||
|
||||
enum bootdev bootdev_get_current(void);
|
||||
bool bootdev_is_usb(void);
|
||||
|
||||
#endif /* __E850_96_BOOTDEV_H */
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <net.h>
|
||||
#include <usb.h>
|
||||
#include <asm/io.h>
|
||||
#include "bootdev.h"
|
||||
#include "fw.h"
|
||||
#include "pmic.h"
|
||||
|
||||
@@ -31,6 +32,10 @@
|
||||
#define EMMC_DEV_NUM 0
|
||||
#define EMMC_ESP_PART 1
|
||||
|
||||
/* Firmware size */
|
||||
#define LDFW_MAX_SIZE SZ_4M
|
||||
#define SP_MAX_SIZE SZ_1M
|
||||
|
||||
struct efi_fw_image fw_images[] = {
|
||||
{
|
||||
.image_type_id = E850_96_FWBL1_IMAGE_GUID,
|
||||
@@ -77,16 +82,6 @@ static struct acpm acpm = {
|
||||
.ipc_ch = EXYNOS850_IPC_AP_I3C,
|
||||
};
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
return fdtdec_setup_mem_size_base();
|
||||
}
|
||||
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
return fdtdec_setup_memory_banksize();
|
||||
}
|
||||
|
||||
/* Read the unique SoC ID from OTP registers */
|
||||
static u64 get_chip_id(void)
|
||||
{
|
||||
@@ -137,11 +132,34 @@ static void setup_ethaddr(void)
|
||||
eth_env_set_enetaddr("ethaddr", mac_addr);
|
||||
}
|
||||
|
||||
static void load_firmware_usb(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
printf("Loading LDFW firmware (over USB)...\n");
|
||||
err = load_image_usb(USB_DN_IMAGE_LDFW, LDFW_NWD_ADDR, LDFW_MAX_SIZE);
|
||||
if (err) {
|
||||
printf("ERROR: LDFW loading failed (%d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
err = init_ldfw(LDFW_NWD_ADDR);
|
||||
if (err) {
|
||||
printf("ERROR: LDFW init failed (%d)\n", err);
|
||||
/* Do not return, still need to download SP */
|
||||
}
|
||||
|
||||
printf("Loading SP firmware (over USB)...\n");
|
||||
err = load_image_usb(USB_DN_IMAGE_SP, LDFW_NWD_ADDR, SP_MAX_SIZE);
|
||||
if (err)
|
||||
printf("ERROR: SP loading failed (%d)\n", err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call this in board_late_init() to avoid probing block devices before
|
||||
* efi_init_early().
|
||||
*/
|
||||
void load_firmware(void)
|
||||
static void load_firmware_blk(void)
|
||||
{
|
||||
const char *ifname;
|
||||
ulong dev, part;
|
||||
@@ -161,16 +179,41 @@ void load_firmware(void)
|
||||
}
|
||||
|
||||
printf("Loading LDFW firmware (from %s %ld)...\n", ifname, dev);
|
||||
err = load_ldfw(ifname, dev, part, LDFW_NWD_ADDR);
|
||||
if (err)
|
||||
err = load_ldfw_from_blk(ifname, dev, part, LDFW_NWD_ADDR);
|
||||
if (err) {
|
||||
printf("ERROR: LDFW loading failed (%d)\n", err);
|
||||
return;
|
||||
}
|
||||
err = init_ldfw(LDFW_NWD_ADDR);
|
||||
if (err)
|
||||
printf("ERROR: LDFW init failed (%d)\n", err);
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
return fdtdec_setup_mem_size_base();
|
||||
}
|
||||
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
return fdtdec_setup_memory_banksize();
|
||||
}
|
||||
|
||||
int board_late_init(void)
|
||||
{
|
||||
setup_serial();
|
||||
setup_ethaddr();
|
||||
load_firmware();
|
||||
|
||||
if (bootdev_is_usb())
|
||||
load_firmware_usb();
|
||||
else
|
||||
load_firmware_blk();
|
||||
|
||||
if (bootdev_is_usb()) {
|
||||
env_set("bootcmd", "echo \"Entering DFU mode...\"; "
|
||||
"dfu 0 mmc 0");
|
||||
env_set("bootdelay", "0");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -11,14 +11,19 @@
|
||||
#include <linux/arm-smccc.h>
|
||||
#include "fw.h"
|
||||
|
||||
#define LDFW_RAW_PART "ldfw"
|
||||
#define LDFW_FAT_PATH "/EFI/firmware/ldfw.bin"
|
||||
#define LDFW_RAW_PART "ldfw"
|
||||
#define LDFW_FAT_PATH "/EFI/firmware/ldfw.bin"
|
||||
#define LDFW_MAGIC 0x10adab1e
|
||||
|
||||
#define LDFW_MAGIC 0x10adab1e
|
||||
#define SMC_CMD_LOAD_LDFW -0x500
|
||||
#define SDM_HW_RESET_STATUS 0x1230
|
||||
#define SDM_SW_RESET_STATUS 0x1231
|
||||
#define SB_ERROR_PREFIX 0xfdaa0000
|
||||
/* SMC command for providing LDFW to EL3 monitor */
|
||||
#define SMC_CMD_LOAD_LDFW -0x500
|
||||
/* SMC command for loading some binary over USB */
|
||||
#define SMC_CMD_LOAD_IMAGE_BY_USB -0x512
|
||||
|
||||
/* Error codes for SMC_CMD_LOAD_LDFW */
|
||||
#define SDM_HW_RESET_STATUS 0x1230
|
||||
#define SDM_SW_RESET_STATUS 0x1231
|
||||
#define SB_ERROR_PREFIX 0xfdaa0000
|
||||
|
||||
struct ldfw_header {
|
||||
u32 magic;
|
||||
@@ -94,7 +99,27 @@ static int read_fw_from_raw(const char *ifname, int dev, const char *part_name,
|
||||
}
|
||||
|
||||
/**
|
||||
* load_ldfw - Load the loadable firmware (LDFW)
|
||||
* load_image_usb - Load some binary over USB during USB boot
|
||||
* @type: Image type
|
||||
* @addr: Memory address where the image should be downloaded to
|
||||
* @size: Image size
|
||||
*
|
||||
* Return: 0 on success or a negative value on error.
|
||||
*/
|
||||
int load_image_usb(enum usb_dn_image type, phys_addr_t addr, phys_size_t size)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
|
||||
arm_smccc_smc(SMC_CMD_LOAD_IMAGE_BY_USB, (u64)type, addr, size,
|
||||
0, 0, 0, 0, &res);
|
||||
if (res.a0)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* load_ldfw_from_blk - Load the loadable firmware (LDFW) from block device
|
||||
* @ifname: Interface name of the block device to load the firmware from
|
||||
* @dev: Device number
|
||||
* @part: Partition number
|
||||
@@ -102,24 +127,37 @@ static int read_fw_from_raw(const char *ifname, int dev, const char *part_name,
|
||||
*
|
||||
* Return: 0 on success or a negative value on error.
|
||||
*/
|
||||
int load_ldfw(const char *ifname, int dev, int part, phys_addr_t addr)
|
||||
int load_ldfw_from_blk(const char *ifname, int dev, int part, phys_addr_t addr)
|
||||
{
|
||||
struct ldfw_header *hdr;
|
||||
struct arm_smccc_res res;
|
||||
void *buf = (void *)addr;
|
||||
u64 size = 0;
|
||||
int err, i;
|
||||
int err;
|
||||
|
||||
/* First try to read LDFW from EFI partition, then from the raw one */
|
||||
err = read_fw_from_fat(ifname, dev, part, LDFW_FAT_PATH, buf);
|
||||
if (err) {
|
||||
err = read_fw_from_raw(ifname, dev, LDFW_RAW_PART, buf);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (err)
|
||||
return read_fw_from_raw(ifname, dev, LDFW_RAW_PART, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* init_ldfw - Provide the LDFW (loaded to RAM) to EL3 monitor to make use of it
|
||||
* @addr: Memory address where LDFW resides
|
||||
*
|
||||
* EL3 monitor will copy the LDFW from the provided Normal World memory @addr to
|
||||
* Secure World location, and start using it.
|
||||
*
|
||||
* Return: 0 on success or a negative value on error.
|
||||
*/
|
||||
int init_ldfw(phys_addr_t addr)
|
||||
{
|
||||
struct ldfw_header *hdr;
|
||||
struct arm_smccc_res res;
|
||||
u64 size = 0;
|
||||
int err, i;
|
||||
|
||||
/* Validate LDFW by magic number in its header */
|
||||
hdr = buf;
|
||||
hdr = (struct ldfw_header *)addr;
|
||||
if (hdr->magic != LDFW_MAGIC) {
|
||||
debug("%s: Wrong LDFW magic; is LDFW flashed?\n", __func__);
|
||||
return -EINVAL;
|
||||
|
||||
@@ -9,6 +9,14 @@
|
||||
|
||||
#include <asm/types.h>
|
||||
|
||||
int load_ldfw(const char *ifname, int dev, int part, phys_addr_t addr);
|
||||
/* Image types for downloading over USB */
|
||||
enum usb_dn_image {
|
||||
USB_DN_IMAGE_LDFW = 1, /* Loadable Firmware */
|
||||
USB_DN_IMAGE_SP = 2, /* Secure Payload (tzsw.img) */
|
||||
};
|
||||
|
||||
int load_image_usb(enum usb_dn_image type, phys_addr_t addr, phys_size_t size);
|
||||
int load_ldfw_from_blk(const char *ifname, int dev, int part, phys_addr_t addr);
|
||||
int init_ldfw(phys_addr_t addr);
|
||||
|
||||
#endif /* __E850_96_FW_H */
|
||||
|
||||
18
board/samsung/exynos-mobile/Kconfig
Normal file
18
board/samsung/exynos-mobile/Kconfig
Normal file
@@ -0,0 +1,18 @@
|
||||
if TARGET_EXYNOS_MOBILE
|
||||
|
||||
config ENV_SOURCE_FILE
|
||||
default "exynos-mobile"
|
||||
|
||||
config LNX_KRNL_IMG_TEXT_OFFSET_BASE
|
||||
default TEXT_BASE
|
||||
|
||||
config SYS_BOARD
|
||||
default "exynos-mobile"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "exynos-mobile"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "samsung"
|
||||
|
||||
endif # TARGET_EXYNOS_MOBILE
|
||||
6
board/samsung/exynos-mobile/MAINTAINERS
Normal file
6
board/samsung/exynos-mobile/MAINTAINERS
Normal file
@@ -0,0 +1,6 @@
|
||||
Exynos Generic Boards (for mobile devices)
|
||||
M: Kaustabh Chakraborty <kauschluss@disroot.org>
|
||||
S: Maintained
|
||||
F: board/samsung/exynos-mobile/
|
||||
F: configs/exynos-mobile_defconfig
|
||||
F: include/configs/exynos-mobile.h
|
||||
5
board/samsung/exynos-mobile/Makefile
Normal file
5
board/samsung/exynos-mobile/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Copyright (C) 2025 Kaustabh Chakraborty <kauschluss@disroot.org>
|
||||
|
||||
obj-y := exynos-mobile.o
|
||||
7
board/samsung/exynos-mobile/debug-exynos7870.config
Normal file
7
board/samsung/exynos-mobile/debug-exynos7870.config
Normal file
@@ -0,0 +1,7 @@
|
||||
CONFIG_DEBUG_UART=y
|
||||
CONFIG_DEBUG_UART_BASE=0x13820000
|
||||
CONFIG_DEBUG_UART_CLOCK=133250000
|
||||
CONFIG_DEBUG_UART_S5P=y
|
||||
CONFIG_LOG=y
|
||||
CONFIG_LOG_CONSOLE=y
|
||||
CONFIG_LOG_MAX_LEVEL=8
|
||||
403
board/samsung/exynos-mobile/exynos-mobile.c
Normal file
403
board/samsung/exynos-mobile/exynos-mobile.c
Normal file
@@ -0,0 +1,403 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Samsung Exynos Generic Board Source (for mobile devices)
|
||||
*
|
||||
* Copyright (c) 2025 Kaustabh Chakraborty <kauschluss@disroot.org>
|
||||
*/
|
||||
|
||||
#include <asm/armv8/mmu.h>
|
||||
#include <blk.h>
|
||||
#include <bootflow.h>
|
||||
#include <ctype.h>
|
||||
#include <dm/ofnode.h>
|
||||
#include <env.h>
|
||||
#include <errno.h>
|
||||
#include <init.h>
|
||||
#include <limits.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <lmb.h>
|
||||
#include <part.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define lmb_alloc(size, addr) \
|
||||
lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE)
|
||||
|
||||
struct exynos_board_info {
|
||||
const char *name;
|
||||
const char *chip;
|
||||
const u64 *const dram_bank_bases;
|
||||
|
||||
char serial[64];
|
||||
|
||||
int (*const match)(struct exynos_board_info *);
|
||||
const char *match_model;
|
||||
const u8 match_max_rev;
|
||||
};
|
||||
|
||||
/*
|
||||
* The memory mapping includes all DRAM banks, along with the
|
||||
* peripheral block, and a sentinel at the end. This is filled in
|
||||
* dynamically.
|
||||
*/
|
||||
static struct mm_region exynos_mem_map[CONFIG_NR_DRAM_BANKS + 2] = {
|
||||
{
|
||||
/* Peripheral MMIO block */
|
||||
.virt = 0x10000000UL,
|
||||
.phys = 0x10000000UL,
|
||||
.size = 0x10000000UL,
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
|
||||
PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN,
|
||||
},
|
||||
};
|
||||
|
||||
struct mm_region *mem_map = exynos_mem_map;
|
||||
|
||||
static const u64 exynos7870_common_dram_bank_bases[CONFIG_NR_DRAM_BANKS] = {
|
||||
0x40000000, 0x80000000, 0x100000000,
|
||||
};
|
||||
|
||||
static const char *exynos_prev_bl_get_bootargs(void)
|
||||
{
|
||||
void *prev_bl_fdt_base = (void *)get_prev_bl_fdt_addr();
|
||||
int chosen_node_offset, ret;
|
||||
const struct fdt_property *bootargs_prop;
|
||||
|
||||
ret = fdt_check_header(prev_bl_fdt_base);
|
||||
if (ret < 0) {
|
||||
log_err("%s: FDT is invalid (FDT_ERR %d)\n", __func__, ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = fdt_path_offset(prev_bl_fdt_base, "/chosen");
|
||||
chosen_node_offset = ret;
|
||||
if (ret < 0) {
|
||||
log_err("%s: /chosen node not found (FDT_ERR %d)\n", __func__,
|
||||
ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bootargs_prop = fdt_get_property(prev_bl_fdt_base, chosen_node_offset,
|
||||
"bootargs", &ret);
|
||||
if (!bootargs_prop) {
|
||||
log_err("%s: /chosen/bootargs property not found (FDT_ERR %d)\n",
|
||||
__func__, ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bootargs_prop->data;
|
||||
}
|
||||
|
||||
static int exynos7870_fdt_match(struct exynos_board_info *board_info)
|
||||
{
|
||||
const char *prev_bl_bootargs;
|
||||
int val, ret;
|
||||
|
||||
prev_bl_bootargs = exynos_prev_bl_get_bootargs();
|
||||
if (!prev_bl_bootargs)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Read the cmdline property which stores the
|
||||
* bootloader/firmware version. An example value of the option
|
||||
* can be: "J600GDXU3ARH5". This can be used to verify the model
|
||||
* of the device.
|
||||
*/
|
||||
ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.bootloader", &val);
|
||||
if (ret < 0) {
|
||||
log_err("%s: unable to find property for bootloader version (%d)\n",
|
||||
__func__, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strncmp(prev_bl_bootargs + val, board_info->match_model,
|
||||
strlen(board_info->match_model)))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Read the cmdline property which stores the hardware revision.
|
||||
* This is required to allow selecting one of multiple dtbs
|
||||
* available of a single device, varying in hardware changes in
|
||||
* different revisions.
|
||||
*/
|
||||
ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.revision", &val);
|
||||
if (ret < 0)
|
||||
ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.hw_rev", &val);
|
||||
if (ret < 0) {
|
||||
log_err("%s: unable to find property for bootloader revision (%d)\n",
|
||||
__func__, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strtoul(prev_bl_bootargs + val, NULL, 10) > board_info->match_max_rev)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Read the cmdline property which stores the serial number.
|
||||
* Store this in the board info struct.
|
||||
*/
|
||||
ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.serialno", &val);
|
||||
if (ret > 0)
|
||||
strlcpy(board_info->serial, prev_bl_bootargs + val, ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This array is used for matching the models and revisions with the
|
||||
* devicetree used by U-Boot. This allows a single U-Boot to work on
|
||||
* multiple devices.
|
||||
*
|
||||
* Entries are kept in lexicographical order of board SoCs, followed by
|
||||
* board names.
|
||||
*/
|
||||
static struct exynos_board_info exynos_board_info_match[] = {
|
||||
{
|
||||
/* Samsung Galaxy A2 Core */
|
||||
.name = "a2corelte",
|
||||
.chip = "exynos7870",
|
||||
.dram_bank_bases = exynos7870_common_dram_bank_bases,
|
||||
.match = exynos7870_fdt_match,
|
||||
.match_model = "A260",
|
||||
.match_max_rev = U8_MAX,
|
||||
}, {
|
||||
/* Samsung Galaxy J6 */
|
||||
.name = "j6lte",
|
||||
.chip = "exynos7870",
|
||||
.dram_bank_bases = exynos7870_common_dram_bank_bases,
|
||||
.match = exynos7870_fdt_match,
|
||||
.match_model = "J600",
|
||||
.match_max_rev = U8_MAX,
|
||||
}, {
|
||||
/* Samsung Galaxy J7 Prime */
|
||||
.name = "on7xelte",
|
||||
.chip = "exynos7870",
|
||||
.dram_bank_bases = exynos7870_common_dram_bank_bases,
|
||||
.match = exynos7870_fdt_match,
|
||||
.match_model = "G610",
|
||||
.match_max_rev = U8_MAX,
|
||||
},
|
||||
};
|
||||
|
||||
static void exynos_parse_dram_banks(const struct exynos_board_info *board_info,
|
||||
const void *fdt_base)
|
||||
{
|
||||
u64 mem_addr, mem_size = 0;
|
||||
u32 na, ns, i, j;
|
||||
int offset;
|
||||
|
||||
if (fdt_check_header(fdt_base) < 0)
|
||||
return;
|
||||
|
||||
/* #address-cells and #size-cells as defined in the fdt root. */
|
||||
na = fdt_address_cells(fdt_base, 0);
|
||||
ns = fdt_size_cells(fdt_base, 0);
|
||||
|
||||
fdt_for_each_subnode(offset, fdt_base, 0) {
|
||||
if (strncmp(fdt_get_name(fdt_base, offset, NULL), "memory", 6))
|
||||
continue;
|
||||
|
||||
for (i = 0; ; i++) {
|
||||
mem_addr = fdtdec_get_addr_size_fixed(fdt_base, offset,
|
||||
"reg", i, na, ns,
|
||||
&mem_size, false);
|
||||
if (mem_addr == FDT_ADDR_T_NONE)
|
||||
break;
|
||||
|
||||
if (!mem_size)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < CONFIG_NR_DRAM_BANKS; j++) {
|
||||
if (board_info->dram_bank_bases[j] != mem_addr)
|
||||
continue;
|
||||
|
||||
mem_map[j + 1].phys = mem_addr;
|
||||
mem_map[j + 1].virt = mem_addr;
|
||||
mem_map[j + 1].size = mem_size;
|
||||
mem_map[j + 1].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
|
||||
PTE_BLOCK_INNER_SHARE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int exynos_fastboot_setup(void)
|
||||
{
|
||||
struct blk_desc *blk_dev;
|
||||
struct disk_partition info = {0};
|
||||
char buf[128];
|
||||
phys_addr_t addr;
|
||||
int offset, i, j;
|
||||
|
||||
/* Allocate and define buffer address for fastboot interface. */
|
||||
if (lmb_alloc(CONFIG_FASTBOOT_BUF_SIZE, &addr)) {
|
||||
log_err("%s: failed to allocate fastboot buffer\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
env_set_hex("fastboot_addr_r", addr);
|
||||
|
||||
blk_dev = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
|
||||
if (!blk_dev) {
|
||||
log_err("%s: required mmc device not available\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
strcpy(buf, "fastboot_partition_alias_");
|
||||
offset = strlen(buf);
|
||||
|
||||
for (i = 1; i < CONFIG_EFI_PARTITION_ENTRIES_NUMBERS; i++) {
|
||||
if (part_get_info(blk_dev, i, &info))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* The partition name must be lowercase (stored in buf[]),
|
||||
* as is expected in all fastboot partitions ...
|
||||
*/
|
||||
strlcpy(buf + offset, info.name, sizeof(buf) - offset);
|
||||
for (j = offset; buf[j]; j++)
|
||||
buf[j] = tolower(buf[j]);
|
||||
if (!strcmp(buf + offset, info.name))
|
||||
continue;
|
||||
/*
|
||||
* ... However, if that isn't the case, a fastboot
|
||||
* partition alias must be defined to establish it.
|
||||
*/
|
||||
env_set(buf, info.name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_fit_config_name_match(const char *name)
|
||||
{
|
||||
struct exynos_board_info *board_info;
|
||||
char buf[128];
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Iterate over exynos_board_info_match[] to select the
|
||||
* appropriate board info struct. If not found, exit.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(exynos_board_info_match); i++) {
|
||||
board_info = exynos_board_info_match + i;
|
||||
snprintf(buf, sizeof(buf), "%s-%s", board_info->chip,
|
||||
board_info->name);
|
||||
|
||||
if (!strcmp(name, buf))
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE(exynos_board_info_match))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Execute match logic for the target board. This is separated
|
||||
* as the process may be different for multiple boards.
|
||||
*/
|
||||
ret = board_info->match(board_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Store the correct board info struct in gd->board_type to
|
||||
* allow other functions to access it.
|
||||
*/
|
||||
gd->board_type = (ulong)board_info;
|
||||
log_debug("%s: device detected: %s\n", __func__, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
ofnode timer_node;
|
||||
|
||||
/*
|
||||
* In a lot of Exynos devices, the previous bootloader does not
|
||||
* set CNTFRQ_EL0 properly. However, the timer node in
|
||||
* devicetree has the correct frequency, use that instead.
|
||||
*/
|
||||
timer_node = ofnode_by_compatible(ofnode_null(), "arm,armv8-timer");
|
||||
gd->arch.timer_rate_hz = ofnode_read_u32_default(timer_node,
|
||||
"clock-frequency", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
const struct exynos_board_info *board_info;
|
||||
|
||||
if (!gd->board_type)
|
||||
return -ENODATA;
|
||||
board_info = (const struct exynos_board_info *)gd->board_type;
|
||||
|
||||
exynos_parse_dram_banks(board_info, gd->fdt_blob);
|
||||
/*
|
||||
* Some devices have multiple variants based on the amount of
|
||||
* memory and internal storage. The lowest bank base has been
|
||||
* observed to have the same memory range in all board variants.
|
||||
* For variants with more memory, the previous bootloader should
|
||||
* overlay the devicetree with the required extra memory ranges.
|
||||
*/
|
||||
exynos_parse_dram_banks(board_info, (const void *)get_prev_bl_fdt_addr());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Select the largest RAM bank for U-Boot. */
|
||||
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
|
||||
if (gd->ram_size < mem_map[i + 1].size) {
|
||||
gd->ram_base = mem_map[i + 1].phys;
|
||||
gd->ram_size = mem_map[i + 1].size;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
|
||||
gd->bd->bi_dram[i].start = mem_map[i + 1].phys;
|
||||
gd->bd->bi_dram[i].size = mem_map[i + 1].size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int misc_init_r(void)
|
||||
{
|
||||
const struct exynos_board_info *board_info;
|
||||
char buf[128];
|
||||
|
||||
if (!gd->board_type)
|
||||
return -ENODATA;
|
||||
board_info = (const struct exynos_board_info *)gd->board_type;
|
||||
|
||||
env_set("platform", board_info->chip);
|
||||
env_set("board", board_info->name);
|
||||
|
||||
if (strlen(board_info->serial))
|
||||
env_set("serial#", board_info->serial);
|
||||
|
||||
/* EFI booting requires the path to correct dtb, specify it here. */
|
||||
snprintf(buf, sizeof(buf), "exynos/%s-%s.dtb", board_info->chip,
|
||||
board_info->name);
|
||||
env_set("fdtfile", buf);
|
||||
|
||||
return exynos_fastboot_setup();
|
||||
}
|
||||
18
board/samsung/exynos-mobile/exynos-mobile.env
Normal file
18
board/samsung/exynos-mobile/exynos-mobile.env
Normal file
@@ -0,0 +1,18 @@
|
||||
stdin=serial,button-kbd
|
||||
stdout=serial,vidconsole
|
||||
stderr=serial,vidconsole
|
||||
|
||||
bootdelay=0
|
||||
bootcmd=bootefi bootmgr; pause; bootmenu
|
||||
|
||||
fastbootcmd=echo "Fastboot Mode";
|
||||
fastboot -l $fastboot_addr_r usb 0
|
||||
|
||||
bootmenu_0=Continue Boot=boot
|
||||
bootmenu_1=Enter Fastboot Mode=run fastbootcmd
|
||||
bootmenu_2=UEFI Maintenance Menu=eficonfig
|
||||
bootmenu_3=Reboot=reset
|
||||
bootmenu_4=Power Off=poweroff
|
||||
|
||||
button_cmd_0_name=Volume Down Key
|
||||
button_cmd_0=bootmenu
|
||||
72
configs/exynos-mobile_defconfig
Normal file
72
configs/exynos-mobile_defconfig
Normal file
@@ -0,0 +1,72 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SKIP_LOWLEVEL_INIT=y
|
||||
CONFIG_COUNTER_FREQUENCY=26000000
|
||||
CONFIG_POSITION_INDEPENDENT=y
|
||||
CONFIG_ARCH_EXYNOS=y
|
||||
CONFIG_SYS_MALLOC_LEN=0x2000000
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x16000
|
||||
CONFIG_TARGET_EXYNOS_MOBILE=y
|
||||
CONFIG_NR_DRAM_BANKS=3
|
||||
CONFIG_DEFAULT_DEVICE_TREE="exynos/exynos7870-a2corelte"
|
||||
CONFIG_SYS_BOOTM_LEN=0x2000000
|
||||
CONFIG_SYS_LOAD_ADDR=0x80000000
|
||||
CONFIG_ARMV8_CNTFRQ_BROKEN=y
|
||||
# CONFIG_PSCI_RESET is not set
|
||||
CONFIG_BUTTON_CMD=y
|
||||
CONFIG_SAVE_PREV_BL_FDT_ADDR=y
|
||||
CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR=y
|
||||
CONFIG_SYS_PBSIZE=1024
|
||||
CONFIG_BOARD_TYPES=y
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
CONFIG_MISC_INIT_R=y
|
||||
CONFIG_HUSH_PARSER=y
|
||||
CONFIG_CMD_BOOTMENU=y
|
||||
CONFIG_CMD_POWEROFF=y
|
||||
CONFIG_CMD_FS_GENERIC=y
|
||||
CONFIG_EFI_PARTITION=y
|
||||
CONFIG_OF_UPSTREAM=y
|
||||
CONFIG_OF_LIST="exynos/exynos7870-a2corelte exynos/exynos7870-j6lte exynos/exynos7870-on7xelte"
|
||||
CONFIG_MULTI_DTB_FIT=y
|
||||
CONFIG_BUTTON=y
|
||||
CONFIG_BUTTON_REMAP_PHONE_KEYS=y
|
||||
CONFIG_CLK=y
|
||||
CONFIG_CLK_CCF=y
|
||||
CONFIG_CLK_EXYNOS7870=y
|
||||
CONFIG_USB_FUNCTION_FASTBOOT=y
|
||||
CONFIG_FASTBOOT_BUF_ADDR=0xdead0000
|
||||
CONFIG_FASTBOOT_FLASH=y
|
||||
CONFIG_FASTBOOT_FLASH_MMC_DEV=0
|
||||
CONFIG_SYS_I2C_S3C24X0=y
|
||||
CONFIG_BUTTON_KEYBOARD=y
|
||||
CONFIG_MISC=y
|
||||
CONFIG_MMC_BROKEN_CD=y
|
||||
CONFIG_MMC_IO_VOLTAGE=y
|
||||
CONFIG_MMC_UHS_SUPPORT=y
|
||||
CONFIG_MMC_HS400_SUPPORT=y
|
||||
CONFIG_MMC_DW=y
|
||||
CONFIG_PHY=y
|
||||
CONFIG_PHY_EXYNOS_USBDRD=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_EXYNOS78x0=y
|
||||
CONFIG_DM_PMIC=y
|
||||
CONFIG_PMIC_S2MPS11=y
|
||||
CONFIG_DM_REGULATOR=y
|
||||
CONFIG_DM_REGULATOR_FIXED=y
|
||||
CONFIG_DM_REGULATOR_S2MPS11=y
|
||||
CONFIG_SOC_SAMSUNG=y
|
||||
CONFIG_EXYNOS_PMU=y
|
||||
CONFIG_SYSRESET=y
|
||||
CONFIG_SYSRESET_CMD_POWEROFF=y
|
||||
CONFIG_SYSRESET_SYSCON=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_DM_USB_GADGET=y
|
||||
CONFIG_USB_DWC3=y
|
||||
CONFIG_USB_DWC3_GENERIC=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_GADGET_MANUFACTURER="Samsung"
|
||||
CONFIG_USB_GADGET_VENDOR_NUM=0x04e8
|
||||
CONFIG_USB_GADGET_PRODUCT_NUM=0x6602
|
||||
CONFIG_VIDEO=y
|
||||
CONFIG_VIDEO_SIMPLE=y
|
||||
CONFIG_FS_EXT4=y
|
||||
CONFIG_FS_FAT=y
|
||||
45
doc/board/samsung/exynos-mobile.rst
Normal file
45
doc/board/samsung/exynos-mobile.rst
Normal file
@@ -0,0 +1,45 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
.. sectionauthor:: Kaustabh Chakraborty <kauschluss@disroot.org>
|
||||
|
||||
Samsung Exynos Generic ARMv8 Boards (for mobile devices)
|
||||
========================================================
|
||||
|
||||
Overview
|
||||
--------
|
||||
This document describes how to build and run U-Boot for Samsung Exynos generic
|
||||
boards. Boards are expected to boot with a primary bootloader, such as S-BOOT or
|
||||
S-LK, which hands off control to U-Boot. Presently, only ARMv8 devices are
|
||||
supported.
|
||||
|
||||
The U-Boot image is built with all device tree blobs packed in a single FIT
|
||||
image. During boot, it uses simple heuristics to detect the target board, and
|
||||
subsequently the appropriate FDT is selected.
|
||||
|
||||
Installation
|
||||
------------
|
||||
Building
|
||||
^^^^^^^^
|
||||
If a cross-compiler is required, install it and set it up like so:
|
||||
|
||||
.. prompt:: bash $
|
||||
|
||||
export CROSS_COMPILE=aarch64-linux-gnu-
|
||||
|
||||
Then, run the following commands to build U-Boot:
|
||||
|
||||
.. prompt:: bash $
|
||||
|
||||
make O=.output exynos-mobile_defconfig
|
||||
make O=.output -j$(nproc)
|
||||
|
||||
If successful, the U-Boot binary will be present in ``.output/u-boot.bin``.
|
||||
|
||||
Preparation and Flashing
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Since U-Boot supports multiple boards, and devices have different requirements,
|
||||
this step will vary depending on your target.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
exynos-mobile/exynos7870
|
||||
85
doc/board/samsung/exynos-mobile/exynos7870.rst
Normal file
85
doc/board/samsung/exynos-mobile/exynos7870.rst
Normal file
@@ -0,0 +1,85 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
.. sectionauthor:: Kaustabh Chakraborty <kauschluss@disroot.org>
|
||||
|
||||
Samsung Exynos 7870 Boards
|
||||
==========================
|
||||
|
||||
Preparation
|
||||
-----------
|
||||
Create the following device tree (named ``stub.dts``)
|
||||
|
||||
.. code-block:: devicetree
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
compatible = "samsung,exynos7870";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
|
||||
model_info-chip = <7870>;
|
||||
model_info-hw_rev = <0>;
|
||||
model_info-hw_rev_end = <255>;
|
||||
|
||||
chosen {
|
||||
};
|
||||
|
||||
memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x80000000 0x0>;
|
||||
};
|
||||
|
||||
memory@100000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x1 0x00000000 0x0>;
|
||||
};
|
||||
};
|
||||
|
||||
The chosen node and memory ranges are populated by S-BOOT. A certain device
|
||||
model may have multiple variants, with differing amounts of RAM and storage. The
|
||||
RAM capacity information is graciously provided by S-BOOT's device tree
|
||||
overlays.
|
||||
|
||||
Compile it to a device tree blob, then pack it in the QCDT format [1]_ using
|
||||
``dtbTool-exynos`` [2]_ by issuing the following commands:
|
||||
|
||||
.. prompt:: bash $
|
||||
|
||||
dtc -I dts -O dtb -o stub.dtb stub.dts
|
||||
dtbTool-exynos -o stub-dt.img stub.dtb
|
||||
|
||||
Finally, use ``mkbootimg`` by osm0sis [3]_ to generate the boot image:
|
||||
|
||||
.. prompt:: bash $
|
||||
|
||||
mkbootimg -o u-boot.img \
|
||||
--kernel .output/u-boot.bin \
|
||||
--dt stub-dt.img
|
||||
|
||||
Offsets are not provided to ``mkbootimg`` as S-BOOT ignores them.
|
||||
|
||||
Flashing
|
||||
--------
|
||||
If flashing for the first time, it must be done via Samsung's Download (Odin)
|
||||
mode. Heimdall [4]_ can be used for flashing, like so:
|
||||
|
||||
.. prompt:: bash $
|
||||
|
||||
heimdall flash --BOOT u-boot.img
|
||||
|
||||
However, if U-Boot is already installed, you may also use its fastboot interface
|
||||
for flashing. Boot into the boot menu by holding the volume down key. Enable
|
||||
fastboot mode from there, connect the device to your host, then run:
|
||||
|
||||
.. prompt:: bash $
|
||||
|
||||
fastboot flash boot u-boot.img
|
||||
|
||||
To flash an OS image in internal storage, fastboot is a reliable option.
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] https://wiki.postmarketos.org/wiki/QCDT
|
||||
.. [2] https://github.com/dsankouski/dtbtool-exynos
|
||||
.. [3] https://github.com/osm0sis/mkbootimg
|
||||
.. [4] https://git.sr.ht/~grimler/Heimdall
|
||||
@@ -8,4 +8,5 @@ Samsung
|
||||
|
||||
axy17lte
|
||||
e850-96
|
||||
exynos-mobile
|
||||
n1
|
||||
|
||||
@@ -594,12 +594,13 @@ ulong clk_set_rate(struct clk *clk, ulong rate)
|
||||
if (!clk_valid(clk))
|
||||
return 0;
|
||||
ops = clk_dev_ops(clk->dev);
|
||||
clk_get_priv(clk, &clkp);
|
||||
|
||||
/* Try to find parents which can set rate */
|
||||
while (!ops->set_rate) {
|
||||
struct clk *parent;
|
||||
|
||||
if (!(clk->flags & CLK_SET_RATE_PARENT))
|
||||
if (!(clkp->flags & CLK_SET_RATE_PARENT))
|
||||
return -ENOSYS;
|
||||
|
||||
parent = clk_get_parent(clk);
|
||||
@@ -608,10 +609,9 @@ ulong clk_set_rate(struct clk *clk, ulong rate)
|
||||
|
||||
clk = parent;
|
||||
ops = clk_dev_ops(clk->dev);
|
||||
clk_get_priv(clk, &clkp);
|
||||
}
|
||||
|
||||
/* get private clock struct used for cache */
|
||||
clk_get_priv(clk, &clkp);
|
||||
/* Clean up cached rates for us and all child clocks */
|
||||
clk_clean_rate_cache(clkp);
|
||||
|
||||
|
||||
@@ -15,6 +15,13 @@ config CLK_EXYNOS7420
|
||||
This enables common clock driver support for platforms based
|
||||
on Samsung Exynos7420 SoC.
|
||||
|
||||
config CLK_EXYNOS7870
|
||||
bool "Clock driver for Samsung's Exynos7870 SoC"
|
||||
select CLK_CCF
|
||||
help
|
||||
This enables common clock driver support for platforms based
|
||||
on Samsung Exynos7870 SoC.
|
||||
|
||||
config CLK_EXYNOS850
|
||||
bool "Clock driver for Samsung's Exynos850 SoC"
|
||||
select CLK_CCF
|
||||
|
||||
@@ -9,4 +9,5 @@
|
||||
|
||||
obj-$(CONFIG_$(PHASE_)CLK_CCF) += clk.o clk-pll.o
|
||||
obj-$(CONFIG_CLK_EXYNOS7420) += clk-exynos7420.o
|
||||
obj-$(CONFIG_CLK_EXYNOS7870) += clk-exynos7870.o
|
||||
obj-$(CONFIG_CLK_EXYNOS850) += clk-exynos850.o
|
||||
|
||||
929
drivers/clk/exynos/clk-exynos7870.c
Normal file
929
drivers/clk/exynos/clk-exynos7870.c
Normal file
@@ -0,0 +1,929 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Samsung Exynos7870 clock driver.
|
||||
* Copyright (C) 2015 Samsung Electronics Co., Ltd.
|
||||
* Author: Kaustabh Chakraborty <kauschluss@disroot.org>
|
||||
*/
|
||||
|
||||
#include "linux/clk-provider.h"
|
||||
#include <dm.h>
|
||||
#include <asm/io.h>
|
||||
#include <dt-bindings/clock/samsung,exynos7870-cmu.h>
|
||||
#include "clk.h"
|
||||
|
||||
enum exynos7870_cmu_id {
|
||||
CMU_MIF,
|
||||
CMU_FSYS,
|
||||
CMU_PERI,
|
||||
};
|
||||
|
||||
/*
|
||||
* Register offsets for CMU_MIF (0x10460000)
|
||||
*/
|
||||
#define PLL_LOCKTIME_MIF_MEM_PLL 0x0000
|
||||
#define PLL_LOCKTIME_MIF_MEDIA_PLL 0x0020
|
||||
#define PLL_LOCKTIME_MIF_BUS_PLL 0x0040
|
||||
#define PLL_CON0_MIF_MEM_PLL 0x0100
|
||||
#define PLL_CON0_MIF_MEDIA_PLL 0x0120
|
||||
#define PLL_CON0_MIF_BUS_PLL 0x0140
|
||||
#define CLK_CON_GAT_MIF_MUX_MEM_PLL 0x0200
|
||||
#define CLK_CON_GAT_MIF_MUX_MEM_PLL_CON 0x0200
|
||||
#define CLK_CON_GAT_MIF_MUX_MEDIA_PLL 0x0204
|
||||
#define CLK_CON_GAT_MIF_MUX_MEDIA_PLL_CON 0x0204
|
||||
#define CLK_CON_GAT_MIF_MUX_BUS_PLL 0x0208
|
||||
#define CLK_CON_GAT_MIF_MUX_BUS_PLL_CON 0x0208
|
||||
#define CLK_CON_GAT_MIF_MUX_BUSD 0x0220
|
||||
#define CLK_CON_MUX_MIF_BUSD 0x0220
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_ISP_VRA 0x0264
|
||||
#define CLK_CON_MUX_MIF_CMU_ISP_VRA 0x0264
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_ISP_CAM 0x0268
|
||||
#define CLK_CON_MUX_MIF_CMU_ISP_CAM 0x0268
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_ISP_ISP 0x026c
|
||||
#define CLK_CON_MUX_MIF_CMU_ISP_ISP 0x026c
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_DISPAUD_BUS 0x0270
|
||||
#define CLK_CON_MUX_MIF_CMU_DISPAUD_BUS 0x0270
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_DISPAUD_DECON_VCLK 0x0274
|
||||
#define CLK_CON_MUX_MIF_CMU_DISPAUD_DECON_VCLK 0x0274
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_DISPAUD_DECON_ECLK 0x0278
|
||||
#define CLK_CON_MUX_MIF_CMU_DISPAUD_DECON_ECLK 0x0278
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_MFCMSCL_MSCL 0x027c
|
||||
#define CLK_CON_MUX_MIF_CMU_MFCMSCL_MSCL 0x027c
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_MFCMSCL_MFC 0x0280
|
||||
#define CLK_CON_MUX_MIF_CMU_MFCMSCL_MFC 0x0280
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_BUS 0x0284
|
||||
#define CLK_CON_MUX_MIF_CMU_FSYS_BUS 0x0284
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC0 0x0288
|
||||
#define CLK_CON_MUX_MIF_CMU_FSYS_MMC0 0x0288
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC1 0x028c
|
||||
#define CLK_CON_MUX_MIF_CMU_FSYS_MMC1 0x028c
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC2 0x0290
|
||||
#define CLK_CON_MUX_MIF_CMU_FSYS_MMC2 0x0290
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_USB20DRD_REFCLK 0x029c
|
||||
#define CLK_CON_MUX_MIF_CMU_FSYS_USB20DRD_REFCLK 0x029c
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_PERI_BUS 0x02a0
|
||||
#define CLK_CON_MUX_MIF_CMU_PERI_BUS 0x02a0
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_PERI_UART1 0x02a4
|
||||
#define CLK_CON_MUX_MIF_CMU_PERI_UART1 0x02a4
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_PERI_UART2 0x02a8
|
||||
#define CLK_CON_MUX_MIF_CMU_PERI_UART2 0x02a8
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_PERI_UART0 0x02ac
|
||||
#define CLK_CON_MUX_MIF_CMU_PERI_UART0 0x02ac
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI2 0x02b0
|
||||
#define CLK_CON_MUX_MIF_CMU_PERI_SPI2 0x02b0
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI1 0x02b4
|
||||
#define CLK_CON_MUX_MIF_CMU_PERI_SPI1 0x02b4
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI0 0x02b8
|
||||
#define CLK_CON_MUX_MIF_CMU_PERI_SPI0 0x02b8
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI3 0x02bc
|
||||
#define CLK_CON_MUX_MIF_CMU_PERI_SPI3 0x02bc
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI4 0x02c0
|
||||
#define CLK_CON_MUX_MIF_CMU_PERI_SPI4 0x02c0
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_ISP_SENSOR0 0x02c4
|
||||
#define CLK_CON_MUX_MIF_CMU_ISP_SENSOR0 0x02c4
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_ISP_SENSOR1 0x02c8
|
||||
#define CLK_CON_MUX_MIF_CMU_ISP_SENSOR1 0x02c8
|
||||
#define CLK_CON_GAT_MIF_MUX_CMU_ISP_SENSOR2 0x02cc
|
||||
#define CLK_CON_MUX_MIF_CMU_ISP_SENSOR2 0x02cc
|
||||
#define CLK_CON_DIV_MIF_BUSD 0x0420
|
||||
#define CLK_CON_DIV_MIF_APB 0x0424
|
||||
#define CLK_CON_DIV_MIF_HSI2C 0x0430
|
||||
#define CLK_CON_DIV_MIF_CMU_G3D_SWITCH 0x0460
|
||||
#define CLK_CON_DIV_MIF_CMU_ISP_VRA 0x0464
|
||||
#define CLK_CON_DIV_MIF_CMU_ISP_CAM 0x0468
|
||||
#define CLK_CON_DIV_MIF_CMU_ISP_ISP 0x046c
|
||||
#define CLK_CON_DIV_MIF_CMU_DISPAUD_BUS 0x0470
|
||||
#define CLK_CON_DIV_MIF_CMU_DISPAUD_DECON_VCLK 0x0474
|
||||
#define CLK_CON_DIV_MIF_CMU_DISPAUD_DECON_ECLK 0x0478
|
||||
#define CLK_CON_DIV_MIF_CMU_MFCMSCL_MSCL 0x047c
|
||||
#define CLK_CON_DIV_MIF_CMU_MFCMSCL_MFC 0x0480
|
||||
#define CLK_CON_DIV_MIF_CMU_FSYS_BUS 0x0484
|
||||
#define CLK_CON_DIV_MIF_CMU_FSYS_MMC0 0x0488
|
||||
#define CLK_CON_DIV_MIF_CMU_FSYS_MMC1 0x048c
|
||||
#define CLK_CON_DIV_MIF_CMU_FSYS_MMC2 0x0490
|
||||
#define CLK_CON_DIV_MIF_CMU_FSYS_USB20DRD_REFCLK 0x049c
|
||||
#define CLK_CON_DIV_MIF_CMU_PERI_BUS 0x04a0
|
||||
#define CLK_CON_DIV_MIF_CMU_PERI_UART1 0x04a4
|
||||
#define CLK_CON_DIV_MIF_CMU_PERI_UART2 0x04a8
|
||||
#define CLK_CON_DIV_MIF_CMU_PERI_UART0 0x04ac
|
||||
#define CLK_CON_DIV_MIF_CMU_PERI_SPI2 0x04b0
|
||||
#define CLK_CON_DIV_MIF_CMU_PERI_SPI1 0x04b4
|
||||
#define CLK_CON_DIV_MIF_CMU_PERI_SPI0 0x04b8
|
||||
#define CLK_CON_DIV_MIF_CMU_PERI_SPI3 0x04bc
|
||||
#define CLK_CON_DIV_MIF_CMU_PERI_SPI4 0x04c0
|
||||
#define CLK_CON_DIV_MIF_CMU_ISP_SENSOR0 0x04c4
|
||||
#define CLK_CON_DIV_MIF_CMU_ISP_SENSOR1 0x04c8
|
||||
#define CLK_CON_DIV_MIF_CMU_ISP_SENSOR2 0x04cc
|
||||
#define CLK_CON_GAT_MIF_WRAP_ADC_IF_OSC_SYS 0x080c
|
||||
#define CLK_CON_GAT_MIF_HSI2C_AP_PCLKS 0x0828
|
||||
#define CLK_CON_GAT_MIF_HSI2C_CP_PCLKS 0x0828
|
||||
#define CLK_CON_GAT_MIF_WRAP_ADC_IF_PCLK_S0 0x0828
|
||||
#define CLK_CON_GAT_MIF_WRAP_ADC_IF_PCLK_S1 0x0828
|
||||
#define CLK_CON_GAT_MIF_CP_PCLK_HSI2C 0x0840
|
||||
#define CLK_CON_GAT_MIF_CP_PCLK_HSI2C_BAT_0 0x0840
|
||||
#define CLK_CON_GAT_MIF_CP_PCLK_HSI2C_BAT_1 0x0840
|
||||
#define CLK_CON_GAT_MIF_HSI2C_AP_PCLKM 0x0840
|
||||
#define CLK_CON_GAT_MIF_HSI2C_CP_PCLKM 0x0840
|
||||
#define CLK_CON_GAT_MIF_HSI2C_IPCLK 0x0840
|
||||
#define CLK_CON_GAT_MIF_HSI2C_ITCLK 0x0840
|
||||
#define CLK_CON_GAT_MIF_CMU_G3D_SWITCH 0x0860
|
||||
#define CLK_CON_GAT_MIF_CMU_ISP_VRA 0x0864
|
||||
#define CLK_CON_GAT_MIF_CMU_ISP_CAM 0x0868
|
||||
#define CLK_CON_GAT_MIF_CMU_ISP_ISP 0x086c
|
||||
#define CLK_CON_GAT_MIF_CMU_DISPAUD_BUS 0x0870
|
||||
#define CLK_CON_GAT_MIF_CMU_DISPAUD_DECON_VCLK 0x0874
|
||||
#define CLK_CON_GAT_MIF_CMU_DISPAUD_DECON_ECLK 0x0878
|
||||
#define CLK_CON_GAT_MIF_CMU_MFCMSCL_MSCL 0x087c
|
||||
#define CLK_CON_GAT_MIF_CMU_MFCMSCL_MFC 0x0880
|
||||
#define CLK_CON_GAT_MIF_CMU_FSYS_BUS 0x0884
|
||||
#define CLK_CON_GAT_MIF_CMU_FSYS_MMC0 0x0888
|
||||
#define CLK_CON_GAT_MIF_CMU_FSYS_MMC1 0x088c
|
||||
#define CLK_CON_GAT_MIF_CMU_FSYS_MMC2 0x0890
|
||||
#define CLK_CON_GAT_MIF_CMU_FSYS_USB20DRD_REFCLK 0x089c
|
||||
#define CLK_CON_GAT_MIF_CMU_PERI_BUS 0x08a0
|
||||
#define CLK_CON_GAT_MIF_CMU_PERI_UART1 0x08a4
|
||||
#define CLK_CON_GAT_MIF_CMU_PERI_UART2 0x08a8
|
||||
#define CLK_CON_GAT_MIF_CMU_PERI_UART0 0x08ac
|
||||
#define CLK_CON_GAT_MIF_CMU_PERI_SPI2 0x08b0
|
||||
#define CLK_CON_GAT_MIF_CMU_PERI_SPI1 0x08b4
|
||||
#define CLK_CON_GAT_MIF_CMU_PERI_SPI0 0x08b8
|
||||
#define CLK_CON_GAT_MIF_CMU_PERI_SPI3 0x08bc
|
||||
#define CLK_CON_GAT_MIF_CMU_PERI_SPI4 0x08c0
|
||||
#define CLK_CON_GAT_MIF_CMU_ISP_SENSOR0 0x08c4
|
||||
#define CLK_CON_GAT_MIF_CMU_ISP_SENSOR1 0x08c8
|
||||
#define CLK_CON_GAT_MIF_CMU_ISP_SENSOR2 0x08cc
|
||||
|
||||
static const struct samsung_pll_clock mif_pll_clks[] = {
|
||||
PLL(pll_1417x, CLK_FOUT_MIF_BUS_PLL, "fout_mif_bus_pll", "oscclk",
|
||||
PLL_CON0_MIF_BUS_PLL),
|
||||
PLL(pll_1417x, CLK_FOUT_MIF_MEDIA_PLL, "fout_mif_media_pll", "oscclk",
|
||||
PLL_CON0_MIF_MEDIA_PLL),
|
||||
PLL(pll_1417x, CLK_FOUT_MIF_MEM_PLL, "fout_mif_mem_pll", "oscclk",
|
||||
PLL_CON0_MIF_MEM_PLL),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock mif_pll_gate_clks[] = {
|
||||
GATE(CLK_GOUT_MIF_MUX_BUS_PLL_CON,
|
||||
"gout_mif_mux_bus_pll_con", "fout_mif_bus_pll",
|
||||
CLK_CON_GAT_MIF_MUX_BUS_PLL_CON, 12,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_MEDIA_PLL_CON,
|
||||
"gout_mif_mux_media_pll_con", "fout_mif_media_pll",
|
||||
CLK_CON_GAT_MIF_MUX_MEDIA_PLL_CON, 12,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_MEM_PLL_CON,
|
||||
"gout_mif_mux_mem_pll_con", "fout_mif_mem_pll",
|
||||
CLK_CON_GAT_MIF_MUX_MEM_PLL_CON, 12,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_BUS_PLL,
|
||||
"gout_mif_mux_bus_pll", "gout_mif_mux_bus_pll_con",
|
||||
CLK_CON_GAT_MIF_MUX_BUS_PLL, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_MEM_PLL,
|
||||
"gout_mif_mux_mem_pll", "gout_mif_mux_mem_pll_con",
|
||||
CLK_CON_GAT_MIF_MUX_MEM_PLL, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_MEDIA_PLL,
|
||||
"gout_mif_mux_media_pll", "gout_mif_mux_media_pll_con",
|
||||
CLK_CON_GAT_MIF_MUX_MEDIA_PLL, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_fixed_factor_clock mif_fixed_factor_clks[] = {
|
||||
FFACTOR(0, "ffac_mif_mux_bus_pll_div2", "gout_mif_mux_bus_pll_con",
|
||||
1, 2, 0),
|
||||
FFACTOR(0, "ffac_mif_mux_media_pll_div2", "gout_mif_mux_media_pll_con",
|
||||
1, 2, 0),
|
||||
FFACTOR(0, "ffac_mif_mux_mem_pll_div2", "gout_mif_mux_mem_pll_con",
|
||||
1, 2, 0),
|
||||
};
|
||||
|
||||
/* List of parent clocks for muxes in CMU_MIF */
|
||||
PNAME(mout_mif_busd_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"ffac_mif_mux_media_pll_div2",
|
||||
"ffac_mif_mux_mem_pll_div2" };
|
||||
PNAME(mout_mif_cmu_fsys_bus_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"ffac_mif_mux_media_pll_div2" };
|
||||
PNAME(mout_mif_cmu_fsys_mmc0_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"ffac_mif_mux_media_pll_div2" };
|
||||
PNAME(mout_mif_cmu_fsys_mmc1_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"ffac_mif_mux_media_pll_div2" };
|
||||
PNAME(mout_mif_cmu_fsys_mmc2_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"ffac_mif_mux_media_pll_div2" };
|
||||
PNAME(mout_mif_cmu_fsys_usb20drd_refclk_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"ffac_mif_mux_media_pll_div2" };
|
||||
PNAME(mout_mif_cmu_peri_bus_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"ffac_mif_mux_media_pll_div2" };
|
||||
PNAME(mout_mif_cmu_peri_spi0_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"oscclk" };
|
||||
PNAME(mout_mif_cmu_peri_spi1_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"oscclk" };
|
||||
PNAME(mout_mif_cmu_peri_spi2_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"oscclk" };
|
||||
PNAME(mout_mif_cmu_peri_spi3_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"oscclk" };
|
||||
PNAME(mout_mif_cmu_peri_spi4_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"oscclk" };
|
||||
PNAME(mout_mif_cmu_peri_uart2_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"ffac_mif_mux_media_pll_div2" };
|
||||
PNAME(mout_mif_cmu_peri_uart0_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"ffac_mif_mux_media_pll_div2" };
|
||||
PNAME(mout_mif_cmu_peri_uart1_p) = { "ffac_mif_mux_bus_pll_div2",
|
||||
"ffac_mif_mux_media_pll_div2" };
|
||||
|
||||
static const struct samsung_mux_clock mif_mux_clks[] = {
|
||||
MUX(CLK_MOUT_MIF_BUSD,
|
||||
"mout_mif_busd", mout_mif_busd_p,
|
||||
CLK_CON_MUX_MIF_BUSD, 12, 2),
|
||||
MUX(CLK_MOUT_MIF_CMU_FSYS_BUS,
|
||||
"mout_mif_cmu_fsys_bus", mout_mif_cmu_fsys_bus_p,
|
||||
CLK_CON_MUX_MIF_CMU_FSYS_BUS, 12, 1),
|
||||
MUX(CLK_MOUT_MIF_CMU_FSYS_MMC0,
|
||||
"mout_mif_cmu_fsys_mmc0", mout_mif_cmu_fsys_mmc0_p,
|
||||
CLK_CON_MUX_MIF_CMU_FSYS_MMC0, 12, 1),
|
||||
MUX(CLK_MOUT_MIF_CMU_FSYS_MMC1,
|
||||
"mout_mif_cmu_fsys_mmc1", mout_mif_cmu_fsys_mmc1_p,
|
||||
CLK_CON_MUX_MIF_CMU_FSYS_MMC1, 12, 1),
|
||||
MUX(CLK_MOUT_MIF_CMU_FSYS_MMC2,
|
||||
"mout_mif_cmu_fsys_mmc2", mout_mif_cmu_fsys_mmc2_p,
|
||||
CLK_CON_MUX_MIF_CMU_FSYS_MMC2, 12, 1),
|
||||
MUX(CLK_MOUT_MIF_CMU_FSYS_USB20DRD_REFCLK,
|
||||
"mout_mif_cmu_fsys_usb20drd_refclk", mout_mif_cmu_fsys_usb20drd_refclk_p,
|
||||
CLK_CON_MUX_MIF_CMU_FSYS_USB20DRD_REFCLK, 12, 1),
|
||||
MUX(CLK_MOUT_MIF_CMU_PERI_BUS,
|
||||
"mout_mif_cmu_peri_bus", mout_mif_cmu_peri_bus_p,
|
||||
CLK_CON_MUX_MIF_CMU_PERI_BUS, 12, 1),
|
||||
MUX(CLK_MOUT_MIF_CMU_PERI_SPI0,
|
||||
"mout_mif_cmu_peri_spi0", mout_mif_cmu_peri_spi0_p,
|
||||
CLK_CON_MUX_MIF_CMU_PERI_SPI0, 12, 1),
|
||||
MUX(CLK_MOUT_MIF_CMU_PERI_SPI1,
|
||||
"mout_mif_cmu_peri_spi1", mout_mif_cmu_peri_spi1_p,
|
||||
CLK_CON_MUX_MIF_CMU_PERI_SPI1, 12, 1),
|
||||
MUX(CLK_MOUT_MIF_CMU_PERI_SPI2,
|
||||
"mout_mif_cmu_peri_spi2", mout_mif_cmu_peri_spi2_p,
|
||||
CLK_CON_MUX_MIF_CMU_PERI_SPI2, 12, 1),
|
||||
MUX(CLK_MOUT_MIF_CMU_PERI_SPI3,
|
||||
"mout_mif_cmu_peri_spi3", mout_mif_cmu_peri_spi3_p,
|
||||
CLK_CON_MUX_MIF_CMU_PERI_SPI3, 12, 1),
|
||||
MUX(CLK_MOUT_MIF_CMU_PERI_SPI4,
|
||||
"mout_mif_cmu_peri_spi4", mout_mif_cmu_peri_spi4_p,
|
||||
CLK_CON_MUX_MIF_CMU_PERI_SPI4, 12, 1),
|
||||
MUX(CLK_MOUT_MIF_CMU_PERI_UART0,
|
||||
"mout_mif_cmu_peri_uart0", mout_mif_cmu_peri_uart0_p,
|
||||
CLK_CON_MUX_MIF_CMU_PERI_UART0, 12, 1),
|
||||
MUX(CLK_MOUT_MIF_CMU_PERI_UART1,
|
||||
"mout_mif_cmu_peri_uart1", mout_mif_cmu_peri_uart1_p,
|
||||
CLK_CON_MUX_MIF_CMU_PERI_UART1, 12, 1),
|
||||
MUX(CLK_MOUT_MIF_CMU_PERI_UART2,
|
||||
"mout_mif_cmu_peri_uart2", mout_mif_cmu_peri_uart2_p,
|
||||
CLK_CON_MUX_MIF_CMU_PERI_UART2, 12, 1),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock mif_mux_gate_clks[] = {
|
||||
GATE(CLK_GOUT_MIF_MUX_BUSD,
|
||||
"gout_mif_mux_busd", "mout_mif_busd",
|
||||
CLK_CON_GAT_MIF_MUX_BUSD, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_BUS,
|
||||
"gout_mif_mux_cmu_fsys_bus", "mout_mif_cmu_fsys_bus",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_FSYS_BUS, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_MMC0,
|
||||
"gout_mif_mux_cmu_fsys_mmc0", "mout_mif_cmu_fsys_mmc0",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC0, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_MMC1,
|
||||
"gout_mif_mux_cmu_fsys_mmc1", "mout_mif_cmu_fsys_mmc1",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC1, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_MMC2,
|
||||
"gout_mif_mux_cmu_fsys_mmc2", "mout_mif_cmu_fsys_mmc2",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC2, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_USB20DRD_REFCLK,
|
||||
"gout_mif_mux_cmu_fsys_usb20drd_refclk", "mout_mif_cmu_fsys_usb20drd_refclk",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_FSYS_USB20DRD_REFCLK, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_PERI_BUS,
|
||||
"gout_mif_mux_cmu_peri_bus", "mout_mif_cmu_peri_bus",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_PERI_BUS, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI0,
|
||||
"gout_mif_mux_cmu_peri_spi0", "mout_mif_cmu_peri_spi0",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI0, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI1,
|
||||
"gout_mif_mux_cmu_peri_spi1", "mout_mif_cmu_peri_spi1",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI1, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI2,
|
||||
"gout_mif_mux_cmu_peri_spi2", "mout_mif_cmu_peri_spi2",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI2, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI3,
|
||||
"gout_mif_mux_cmu_peri_spi3", "mout_mif_cmu_peri_spi3",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI3, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI4,
|
||||
"gout_mif_mux_cmu_peri_spi4", "mout_mif_cmu_peri_spi4",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI4, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_PERI_UART0,
|
||||
"gout_mif_mux_cmu_peri_uart0", "mout_mif_cmu_peri_uart0",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_PERI_UART0, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_PERI_UART1,
|
||||
"gout_mif_mux_cmu_peri_uart1", "mout_mif_cmu_peri_uart1",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_PERI_UART1, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_MUX_CMU_PERI_UART2,
|
||||
"gout_mif_mux_cmu_peri_uart2", "mout_mif_cmu_peri_uart2",
|
||||
CLK_CON_GAT_MIF_MUX_CMU_PERI_UART2, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_div_clock mif_div_clks[] = {
|
||||
DIV(CLK_DOUT_MIF_HSI2C,
|
||||
"dout_mif_hsi2c", "ffac_mif_mux_media_pll_div2",
|
||||
CLK_CON_DIV_MIF_HSI2C, 0, 4),
|
||||
DIV(CLK_DOUT_MIF_BUSD,
|
||||
"dout_mif_busd", "gout_mif_mux_busd",
|
||||
CLK_CON_DIV_MIF_BUSD, 0, 4),
|
||||
DIV(CLK_DOUT_MIF_CMU_FSYS_BUS,
|
||||
"dout_mif_cmu_fsys_bus", "gout_mif_mux_cmu_fsys_bus",
|
||||
CLK_CON_DIV_MIF_CMU_FSYS_BUS, 0, 4),
|
||||
DIV(CLK_DOUT_MIF_CMU_FSYS_MMC0,
|
||||
"dout_mif_cmu_fsys_mmc0", "gout_mif_mux_cmu_fsys_mmc0",
|
||||
CLK_CON_DIV_MIF_CMU_FSYS_MMC0, 0, 10),
|
||||
DIV(CLK_DOUT_MIF_CMU_FSYS_MMC1,
|
||||
"dout_mif_cmu_fsys_mmc1", "gout_mif_mux_cmu_fsys_mmc1",
|
||||
CLK_CON_DIV_MIF_CMU_FSYS_MMC1, 0, 10),
|
||||
DIV(CLK_DOUT_MIF_CMU_FSYS_MMC2,
|
||||
"dout_mif_cmu_fsys_mmc2", "gout_mif_mux_cmu_fsys_mmc2",
|
||||
CLK_CON_DIV_MIF_CMU_FSYS_MMC2, 0, 10),
|
||||
DIV(CLK_DOUT_MIF_CMU_FSYS_USB20DRD_REFCLK,
|
||||
"dout_mif_cmu_fsys_usb20drd_refclk", "gout_mif_mux_cmu_fsys_usb20drd_refclk",
|
||||
CLK_CON_DIV_MIF_CMU_FSYS_USB20DRD_REFCLK, 0, 4),
|
||||
DIV(CLK_DOUT_MIF_CMU_PERI_BUS,
|
||||
"dout_mif_cmu_peri_bus", "gout_mif_mux_cmu_peri_bus",
|
||||
CLK_CON_DIV_MIF_CMU_PERI_BUS, 0, 4),
|
||||
DIV(CLK_DOUT_MIF_CMU_PERI_SPI0,
|
||||
"dout_mif_cmu_peri_spi0", "gout_mif_mux_cmu_peri_spi0",
|
||||
CLK_CON_DIV_MIF_CMU_PERI_SPI0, 0, 6),
|
||||
DIV(CLK_DOUT_MIF_CMU_PERI_SPI1,
|
||||
"dout_mif_cmu_peri_spi1", "gout_mif_mux_cmu_peri_spi1",
|
||||
CLK_CON_DIV_MIF_CMU_PERI_SPI1, 0, 6),
|
||||
DIV(CLK_DOUT_MIF_CMU_PERI_SPI2,
|
||||
"dout_mif_cmu_peri_spi2", "gout_mif_mux_cmu_peri_spi2",
|
||||
CLK_CON_DIV_MIF_CMU_PERI_SPI2, 0, 6),
|
||||
DIV(CLK_DOUT_MIF_CMU_PERI_SPI3,
|
||||
"dout_mif_cmu_peri_spi3", "gout_mif_mux_cmu_peri_spi3",
|
||||
CLK_CON_DIV_MIF_CMU_PERI_SPI3, 0, 6),
|
||||
DIV(CLK_DOUT_MIF_CMU_PERI_SPI4,
|
||||
"dout_mif_cmu_peri_spi4", "gout_mif_mux_cmu_peri_spi4",
|
||||
CLK_CON_DIV_MIF_CMU_PERI_SPI4, 0, 6),
|
||||
DIV(CLK_DOUT_MIF_CMU_PERI_UART0,
|
||||
"dout_mif_cmu_peri_uart0", "gout_mif_mux_cmu_peri_uart0",
|
||||
CLK_CON_DIV_MIF_CMU_PERI_UART0, 0, 4),
|
||||
DIV(CLK_DOUT_MIF_CMU_PERI_UART1,
|
||||
"dout_mif_cmu_peri_uart1", "gout_mif_mux_cmu_peri_uart1",
|
||||
CLK_CON_DIV_MIF_CMU_PERI_UART1, 0, 4),
|
||||
DIV(CLK_DOUT_MIF_CMU_PERI_UART2,
|
||||
"dout_mif_cmu_peri_uart2", "gout_mif_mux_cmu_peri_uart2",
|
||||
CLK_CON_DIV_MIF_CMU_PERI_UART2, 0, 4),
|
||||
DIV(CLK_DOUT_MIF_APB,
|
||||
"dout_mif_apb", "dout_mif_busd",
|
||||
CLK_CON_DIV_MIF_APB, 0, 2),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock mif_gate_clks[] = {
|
||||
GATE(CLK_GOUT_MIF_WRAP_ADC_IF_OSC_SYS,
|
||||
"gout_mif_wrap_adc_if_osc_sys", "oscclk",
|
||||
CLK_CON_GAT_MIF_WRAP_ADC_IF_OSC_SYS, 3,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_HSI2C_AP_PCLKS,
|
||||
"gout_mif_hsi2c_ap_pclks", "dout_mif_apb",
|
||||
CLK_CON_GAT_MIF_HSI2C_AP_PCLKS, 14,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_HSI2C_CP_PCLKS,
|
||||
"gout_mif_hsi2c_cp_pclks", "dout_mif_apb",
|
||||
CLK_CON_GAT_MIF_HSI2C_CP_PCLKS, 15,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_WRAP_ADC_IF_PCLK_S0,
|
||||
"gout_mif_wrap_adc_if_pclk_s0", "dout_mif_apb",
|
||||
CLK_CON_GAT_MIF_WRAP_ADC_IF_PCLK_S0, 20,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_WRAP_ADC_IF_PCLK_S1,
|
||||
"gout_mif_wrap_adc_if_pclk_s1", "dout_mif_apb",
|
||||
CLK_CON_GAT_MIF_WRAP_ADC_IF_PCLK_S1, 21,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_FSYS_BUS,
|
||||
"gout_mif_cmu_fsys_bus", "dout_mif_cmu_fsys_bus",
|
||||
CLK_CON_GAT_MIF_CMU_FSYS_BUS, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_FSYS_MMC0,
|
||||
"gout_mif_cmu_fsys_mmc0", "dout_mif_cmu_fsys_mmc0",
|
||||
CLK_CON_GAT_MIF_CMU_FSYS_MMC0, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_FSYS_MMC1,
|
||||
"gout_mif_cmu_fsys_mmc1", "dout_mif_cmu_fsys_mmc1",
|
||||
CLK_CON_GAT_MIF_CMU_FSYS_MMC1, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_FSYS_MMC2,
|
||||
"gout_mif_cmu_fsys_mmc2", "dout_mif_cmu_fsys_mmc2",
|
||||
CLK_CON_GAT_MIF_CMU_FSYS_MMC2, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_FSYS_USB20DRD_REFCLK,
|
||||
"gout_mif_cmu_fsys_usb20drd_refclk", "dout_mif_cmu_fsys_usb20drd_refclk",
|
||||
CLK_CON_GAT_MIF_CMU_FSYS_USB20DRD_REFCLK, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_PERI_BUS,
|
||||
"gout_mif_cmu_peri_bus", "dout_mif_cmu_peri_bus",
|
||||
CLK_CON_GAT_MIF_CMU_PERI_BUS, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_PERI_SPI0,
|
||||
"gout_mif_cmu_peri_spi0", "dout_mif_cmu_peri_spi0",
|
||||
CLK_CON_GAT_MIF_CMU_PERI_SPI0, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_PERI_SPI1,
|
||||
"gout_mif_cmu_peri_spi1", "dout_mif_cmu_peri_spi1",
|
||||
CLK_CON_GAT_MIF_CMU_PERI_SPI1, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_PERI_SPI2,
|
||||
"gout_mif_cmu_peri_spi2", "dout_mif_cmu_peri_spi2",
|
||||
CLK_CON_GAT_MIF_CMU_PERI_SPI2, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_PERI_SPI3,
|
||||
"gout_mif_cmu_peri_spi3", "dout_mif_cmu_peri_spi3",
|
||||
CLK_CON_GAT_MIF_CMU_PERI_SPI3, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_PERI_SPI4,
|
||||
"gout_mif_cmu_peri_spi4", "dout_mif_cmu_peri_spi4",
|
||||
CLK_CON_GAT_MIF_CMU_PERI_SPI4, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_PERI_UART0,
|
||||
"gout_mif_cmu_peri_uart0", "dout_mif_cmu_peri_uart0",
|
||||
CLK_CON_GAT_MIF_CMU_PERI_UART0, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_PERI_UART1,
|
||||
"gout_mif_cmu_peri_uart1", "dout_mif_cmu_peri_uart1",
|
||||
CLK_CON_GAT_MIF_CMU_PERI_UART1, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CMU_PERI_UART2,
|
||||
"gout_mif_cmu_peri_uart2", "dout_mif_cmu_peri_uart2",
|
||||
CLK_CON_GAT_MIF_CMU_PERI_UART2, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CP_PCLK_HSI2C,
|
||||
"gout_mif_cp_pclk_hsi2c", "dout_mif_hsi2c",
|
||||
CLK_CON_GAT_MIF_CP_PCLK_HSI2C, 6,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CP_PCLK_HSI2C_BAT_0,
|
||||
"gout_mif_cp_pclk_hsi2c_bat_0", "dout_mif_hsi2c",
|
||||
CLK_CON_GAT_MIF_CP_PCLK_HSI2C_BAT_0, 4,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_CP_PCLK_HSI2C_BAT_1,
|
||||
"gout_mif_cp_pclk_hsi2c_bat_1", "dout_mif_hsi2c",
|
||||
CLK_CON_GAT_MIF_CP_PCLK_HSI2C_BAT_1, 5,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_HSI2C_AP_PCLKM,
|
||||
"gout_mif_hsi2c_ap_pclkm", "dout_mif_hsi2c",
|
||||
CLK_CON_GAT_MIF_HSI2C_AP_PCLKM, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_HSI2C_CP_PCLKM,
|
||||
"gout_mif_hsi2c_cp_pclkm", "dout_mif_hsi2c",
|
||||
CLK_CON_GAT_MIF_HSI2C_CP_PCLKM, 1,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_HSI2C_IPCLK,
|
||||
"gout_mif_hsi2c_ipclk", "dout_mif_hsi2c",
|
||||
CLK_CON_GAT_MIF_HSI2C_IPCLK, 2,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_MIF_HSI2C_ITCLK,
|
||||
"gout_mif_hsi2c_itclk", "dout_mif_hsi2c",
|
||||
CLK_CON_GAT_MIF_HSI2C_ITCLK, 3,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_clk_group mif_cmu_clks[] = {
|
||||
{ S_CLK_PLL, mif_pll_clks, ARRAY_SIZE(mif_pll_clks) },
|
||||
{ S_CLK_GATE, mif_pll_gate_clks, ARRAY_SIZE(mif_pll_gate_clks) },
|
||||
{ S_CLK_FFACTOR, mif_fixed_factor_clks, ARRAY_SIZE(mif_fixed_factor_clks) },
|
||||
{ S_CLK_MUX, mif_mux_clks, ARRAY_SIZE(mif_mux_clks) },
|
||||
{ S_CLK_GATE, mif_mux_gate_clks, ARRAY_SIZE(mif_mux_gate_clks) },
|
||||
{ S_CLK_DIV, mif_div_clks, ARRAY_SIZE(mif_div_clks) },
|
||||
{ S_CLK_GATE, mif_gate_clks, ARRAY_SIZE(mif_gate_clks) },
|
||||
};
|
||||
|
||||
static int exynos7870_cmu_mif_probe(struct udevice *dev)
|
||||
{
|
||||
return samsung_register_cmu(dev, CMU_MIF, mif_cmu_clks,
|
||||
exynos7870_cmu_mif);
|
||||
}
|
||||
|
||||
static const struct udevice_id exynos7870_cmu_mif_ids[] = {
|
||||
{ .compatible = "samsung,exynos7870-cmu-mif" },
|
||||
{ }
|
||||
};
|
||||
|
||||
SAMSUNG_CLK_OPS(exynos7870_cmu_mif, CMU_MIF);
|
||||
|
||||
U_BOOT_DRIVER(exynos7870_cmu_mif) = {
|
||||
.name = "exynos7870-cmu-mif",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = exynos7870_cmu_mif_ids,
|
||||
.ops = &exynos7870_cmu_mif_clk_ops,
|
||||
.probe = exynos7870_cmu_mif_probe,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
/*
|
||||
* Register offsets for CMU_FSYS (0x13730000)
|
||||
*/
|
||||
#define PLL_LOCKTIME_FSYS_USB_PLL 0x0000
|
||||
#define PLL_CON0_FSYS_USB_PLL 0x0100
|
||||
#define CLK_CON_GAT_FSYS_MUX_USB_PLL 0x0200
|
||||
#define CLK_CON_GAT_FSYS_MUX_USB_PLL_CON 0x0200
|
||||
#define CLK_CON_GAT_FSYS_MUX_USB20DRD_PHYCLOCK_USER 0x0230
|
||||
#define CLK_CON_GAT_FSYS_MUX_USB20DRD_PHYCLOCK_USER_CON 0x0230
|
||||
#define CLK_CON_GAT_FSYS_BUSP3_HCLK 0x0804
|
||||
#define CLK_CON_GAT_FSYS_MMC0_ACLK 0x0804
|
||||
#define CLK_CON_GAT_FSYS_MMC1_ACLK 0x0804
|
||||
#define CLK_CON_GAT_FSYS_MMC2_ACLK 0x0804
|
||||
#define CLK_CON_GAT_FSYS_PDMA0_ACLK_PDMA0 0x0804
|
||||
#define CLK_CON_GAT_FSYS_PPMU_ACLK 0x0804
|
||||
#define CLK_CON_GAT_FSYS_PPMU_PCLK 0x0804
|
||||
#define CLK_CON_GAT_FSYS_SROMC_HCLK 0x0804
|
||||
#define CLK_CON_GAT_FSYS_UPSIZER_BUS1_ACLK 0x0804
|
||||
#define CLK_CON_GAT_FSYS_USB20DRD_ACLK_HSDRD 0x0804
|
||||
#define CLK_CON_GAT_FSYS_USB20DRD_HCLK_USB20_CTRL 0x0804
|
||||
#define CLK_CON_GAT_FSYS_USB20DRD_HSDRD_REF_CLK 0x0828
|
||||
|
||||
static const struct samsung_fixed_rate_clock fsys_fixed_rate_clks[] = {
|
||||
FRATE(0, "frat_fsys_usb20drd_phyclock", 60000000),
|
||||
};
|
||||
|
||||
static const struct samsung_pll_clock fsys_pll_clks[] = {
|
||||
PLL(pll_1417x, CLK_FOUT_FSYS_USB_PLL, "fout_fsys_usb_pll", "oscclk",
|
||||
PLL_CON0_FSYS_USB_PLL),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock fsys_gate_clks[] = {
|
||||
GATE(CLK_GOUT_FSYS_BUSP3_HCLK,
|
||||
"gout_fsys_busp3_hclk", "bus",
|
||||
CLK_CON_GAT_FSYS_BUSP3_HCLK, 2,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_UPSIZER_BUS1_ACLK,
|
||||
"gout_fsys_upsizer_bus1_aclk", "bus",
|
||||
CLK_CON_GAT_FSYS_UPSIZER_BUS1_ACLK, 12,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_PPMU_ACLK,
|
||||
"gout_fsys_ppmu_aclk", "bus",
|
||||
CLK_CON_GAT_FSYS_PPMU_ACLK, 17,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_PPMU_PCLK,
|
||||
"gout_fsys_ppmu_pclk", "bus",
|
||||
CLK_CON_GAT_FSYS_PPMU_PCLK, 18,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_USB20DRD_HSDRD_REF_CLK,
|
||||
"gout_fsys_usb20drd_hsdrd_ref_clk", "usb20drd",
|
||||
CLK_CON_GAT_FSYS_USB20DRD_HSDRD_REF_CLK, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_MUX_USB20DRD_PHYCLOCK_USER_CON,
|
||||
"gout_fsys_mux_usb20drd_phyclock_user_con", "frat_fsys_usb20drd_phyclock",
|
||||
CLK_CON_GAT_FSYS_MUX_USB20DRD_PHYCLOCK_USER_CON, 12,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_MUX_USB_PLL_CON,
|
||||
"gout_fsys_mux_usb_pll_con", "fout_fsys_usb_pll",
|
||||
CLK_CON_GAT_FSYS_MUX_USB_PLL_CON, 12,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_MMC0_ACLK,
|
||||
"gout_fsys_mmc0_aclk", "gout_fsys_busp3_hclk",
|
||||
CLK_CON_GAT_FSYS_MMC0_ACLK, 8,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_MMC1_ACLK,
|
||||
"gout_fsys_mmc1_aclk", "gout_fsys_busp3_hclk",
|
||||
CLK_CON_GAT_FSYS_MMC1_ACLK, 9,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_MMC2_ACLK,
|
||||
"gout_fsys_mmc2_aclk", "gout_fsys_busp3_hclk",
|
||||
CLK_CON_GAT_FSYS_MMC2_ACLK, 10,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_USB20DRD_ACLK_HSDRD,
|
||||
"gout_fsys_usb20drd_aclk_hsdrd", "gout_fsys_busp3_hclk",
|
||||
CLK_CON_GAT_FSYS_USB20DRD_ACLK_HSDRD, 20,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_SROMC_HCLK,
|
||||
"gout_fsys_sromc_hclk", "gout_fsys_busp3_hclk",
|
||||
CLK_CON_GAT_FSYS_SROMC_HCLK, 6,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_USB20DRD_HCLK_USB20_CTRL,
|
||||
"gout_fsys_usb20drd_hclk_usb20_ctrl", "gout_fsys_busp3_hclk",
|
||||
CLK_CON_GAT_FSYS_USB20DRD_HCLK_USB20_CTRL, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_MUX_USB_PLL,
|
||||
"gout_fsys_mux_usb_pll", "gout_fsys_mux_usb_pll_con",
|
||||
CLK_CON_GAT_FSYS_MUX_USB_PLL, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_MUX_USB20DRD_PHYCLOCK_USER,
|
||||
"gout_fsys_mux_usb20drd_phyclock_user", "gout_fsys_mux_usb20drd_phyclock_user_con",
|
||||
CLK_CON_GAT_FSYS_MUX_USB20DRD_PHYCLOCK_USER, 21,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_FSYS_PDMA0_ACLK_PDMA0,
|
||||
"gout_fsys_pdma0_aclk_pdma0", "gout_fsys_upsizer_bus1_aclk",
|
||||
CLK_CON_GAT_FSYS_PDMA0_ACLK_PDMA0, 7,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_clk_group fsys_cmu_clks[] = {
|
||||
{ S_CLK_FRATE, fsys_fixed_rate_clks, ARRAY_SIZE(fsys_fixed_rate_clks) },
|
||||
{ S_CLK_PLL, fsys_pll_clks, ARRAY_SIZE(fsys_pll_clks) },
|
||||
{ S_CLK_GATE, fsys_gate_clks, ARRAY_SIZE(fsys_gate_clks) },
|
||||
};
|
||||
|
||||
static int exynos7870_cmu_fsys_probe(struct udevice *dev)
|
||||
{
|
||||
return samsung_register_cmu(dev, CMU_FSYS, fsys_cmu_clks,
|
||||
exynos7870_cmu_fsys);
|
||||
}
|
||||
|
||||
static const struct udevice_id exynos7870_cmu_fsys_ids[] = {
|
||||
{ .compatible = "samsung,exynos7870-cmu-fsys" },
|
||||
{ }
|
||||
};
|
||||
|
||||
SAMSUNG_CLK_OPS(exynos7870_cmu_fsys, CMU_FSYS);
|
||||
|
||||
U_BOOT_DRIVER(exynos7870_cmu_fsys) = {
|
||||
.name = "exynos7870-cmu-fsys",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = exynos7870_cmu_fsys_ids,
|
||||
.ops = &exynos7870_cmu_fsys_clk_ops,
|
||||
.probe = exynos7870_cmu_fsys_probe,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
/*
|
||||
* Register offsets for CMU_PERI (0x101f0000)
|
||||
*/
|
||||
#define CLK_CON_GAT_PERI_PWM_MOTOR_OSCCLK 0x0800
|
||||
#define CLK_CON_GAT_PERI_TMU_CLK 0x0800
|
||||
#define CLK_CON_GAT_PERI_TMU_CPUCL0_CLK 0x0800
|
||||
#define CLK_CON_GAT_PERI_TMU_CPUCL1_CLK 0x0800
|
||||
#define CLK_CON_GAT_PERI_BUSP1_PERIC0_HCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_GPIO2_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_GPIO5_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_GPIO6_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_GPIO7_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_HSI2C1_IPCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_HSI2C2_IPCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_HSI2C3_IPCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_HSI2C4_IPCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_HSI2C5_IPCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_HSI2C6_IPCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_I2C0_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_I2C1_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_I2C2_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_I2C3_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_I2C4_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_I2C5_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_I2C6_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_I2C7_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_I2C8_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_MCT_PCLK 0x0810
|
||||
#define CLK_CON_GAT_PERI_PWM_MOTOR_PCLK_S0 0x0810
|
||||
#define CLK_CON_GAT_PERI_SFRIF_TMU_CPUCL0_PCLK 0x0814
|
||||
#define CLK_CON_GAT_PERI_SFRIF_TMU_CPUCL1_PCLK 0x0814
|
||||
#define CLK_CON_GAT_PERI_SFRIF_TMU_PCLK 0x0814
|
||||
#define CLK_CON_GAT_PERI_SPI0_PCLK 0x0814
|
||||
#define CLK_CON_GAT_PERI_SPI1_PCLK 0x0814
|
||||
#define CLK_CON_GAT_PERI_SPI2_PCLK 0x0814
|
||||
#define CLK_CON_GAT_PERI_SPI3_PCLK 0x0814
|
||||
#define CLK_CON_GAT_PERI_SPI4_PCLK 0x0814
|
||||
#define CLK_CON_GAT_PERI_UART0_PCLK 0x0814
|
||||
#define CLK_CON_GAT_PERI_UART1_PCLK 0x0814
|
||||
#define CLK_CON_GAT_PERI_UART2_PCLK 0x0814
|
||||
#define CLK_CON_GAT_PERI_WDT_CPUCL0_PCLK 0x0814
|
||||
#define CLK_CON_GAT_PERI_WDT_CPUCL1_PCLK 0x0814
|
||||
#define CLK_CON_GAT_PERI_UART1_EXT_UCLK 0x0830
|
||||
#define CLK_CON_GAT_PERI_UART2_EXT_UCLK 0x0834
|
||||
#define CLK_CON_GAT_PERI_UART0_EXT_UCLK 0x0838
|
||||
#define CLK_CON_GAT_PERI_SPI2_SPI_EXT_CLK 0x083c
|
||||
#define CLK_CON_GAT_PERI_SPI1_SPI_EXT_CLK 0x0840
|
||||
#define CLK_CON_GAT_PERI_SPI0_SPI_EXT_CLK 0x0844
|
||||
#define CLK_CON_GAT_PERI_SPI3_SPI_EXT_CLK 0x0848
|
||||
#define CLK_CON_GAT_PERI_SPI4_SPI_EXT_CLK 0x084c
|
||||
|
||||
static const struct samsung_gate_clock peri_gate_clks[] = {
|
||||
GATE(CLK_GOUT_PERI_PWM_MOTOR_OSCCLK,
|
||||
"gout_peri_pwm_motor_oscclk", "oscclk",
|
||||
CLK_CON_GAT_PERI_PWM_MOTOR_OSCCLK, 2,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_TMU_CLK,
|
||||
"gout_peri_tmu_clk", "oscclk",
|
||||
CLK_CON_GAT_PERI_TMU_CLK, 6,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_TMU_CPUCL0_CLK,
|
||||
"gout_peri_tmu_cpucl0_clk", "oscclk",
|
||||
CLK_CON_GAT_PERI_TMU_CPUCL0_CLK, 4,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_TMU_CPUCL1_CLK,
|
||||
"gout_peri_tmu_cpucl1_clk", "oscclk",
|
||||
CLK_CON_GAT_PERI_TMU_CPUCL1_CLK, 5,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_BUSP1_PERIC0_HCLK,
|
||||
"gout_peri_busp1_peric0_hclk", "bus",
|
||||
CLK_CON_GAT_PERI_BUSP1_PERIC0_HCLK, 3,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_GPIO2_PCLK,
|
||||
"gout_peri_gpio2_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_GPIO2_PCLK, 7,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_GPIO5_PCLK,
|
||||
"gout_peri_gpio5_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_GPIO5_PCLK, 8,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_GPIO6_PCLK,
|
||||
"gout_peri_gpio6_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_GPIO6_PCLK, 9,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_GPIO7_PCLK,
|
||||
"gout_peri_gpio7_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_GPIO7_PCLK, 10,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_HSI2C5_IPCLK,
|
||||
"gout_peri_hsi2c5_ipclk", "bus",
|
||||
CLK_CON_GAT_PERI_HSI2C5_IPCLK, 15,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_HSI2C6_IPCLK,
|
||||
"gout_peri_hsi2c6_ipclk", "bus",
|
||||
CLK_CON_GAT_PERI_HSI2C6_IPCLK, 16,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_MCT_PCLK,
|
||||
"gout_peri_mct_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_MCT_PCLK, 26,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_PWM_MOTOR_PCLK_S0,
|
||||
"gout_peri_pwm_motor_pclk_s0", "bus",
|
||||
CLK_CON_GAT_PERI_PWM_MOTOR_PCLK_S0, 29,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_SFRIF_TMU_CPUCL0_PCLK,
|
||||
"gout_peri_sfrif_tmu_cpucl0_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_SFRIF_TMU_CPUCL0_PCLK, 1,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_SFRIF_TMU_CPUCL1_PCLK,
|
||||
"gout_peri_sfrif_tmu_cpucl1_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_SFRIF_TMU_CPUCL1_PCLK, 2,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_SFRIF_TMU_PCLK,
|
||||
"gout_peri_sfrif_tmu_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_SFRIF_TMU_PCLK, 3,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_SPI0_PCLK,
|
||||
"gout_peri_spi0_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_SPI0_PCLK, 6,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_SPI1_PCLK,
|
||||
"gout_peri_spi1_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_SPI1_PCLK, 5,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_SPI2_PCLK,
|
||||
"gout_peri_spi2_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_SPI2_PCLK, 4,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_SPI3_PCLK,
|
||||
"gout_peri_spi3_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_SPI3_PCLK, 7,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_SPI4_PCLK,
|
||||
"gout_peri_spi4_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_SPI4_PCLK, 8,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_WDT_CPUCL0_PCLK,
|
||||
"gout_peri_wdt_cpucl0_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_WDT_CPUCL0_PCLK, 13,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_WDT_CPUCL1_PCLK,
|
||||
"gout_peri_wdt_cpucl1_pclk", "bus",
|
||||
CLK_CON_GAT_PERI_WDT_CPUCL1_PCLK, 14,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_SPI0_SPI_EXT_CLK,
|
||||
"gout_peri_spi0_spi_ext_clk", "spi0",
|
||||
CLK_CON_GAT_PERI_SPI0_SPI_EXT_CLK, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_SPI1_SPI_EXT_CLK,
|
||||
"gout_peri_spi1_spi_ext_clk", "spi1",
|
||||
CLK_CON_GAT_PERI_SPI1_SPI_EXT_CLK, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_SPI2_SPI_EXT_CLK,
|
||||
"gout_peri_spi2_spi_ext_clk", "spi2",
|
||||
CLK_CON_GAT_PERI_SPI2_SPI_EXT_CLK, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_SPI3_SPI_EXT_CLK,
|
||||
"gout_peri_spi3_spi_ext_clk", "spi3",
|
||||
CLK_CON_GAT_PERI_SPI3_SPI_EXT_CLK, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_SPI4_SPI_EXT_CLK,
|
||||
"gout_peri_spi4_spi_ext_clk", "spi4",
|
||||
CLK_CON_GAT_PERI_SPI4_SPI_EXT_CLK, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_UART0_EXT_UCLK,
|
||||
"gout_peri_uart0_ext_uclk", "uart0",
|
||||
CLK_CON_GAT_PERI_UART0_EXT_UCLK, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_UART1_EXT_UCLK,
|
||||
"gout_peri_uart1_ext_uclk", "uart1",
|
||||
CLK_CON_GAT_PERI_UART1_EXT_UCLK, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_UART2_EXT_UCLK,
|
||||
"gout_peri_uart2_ext_uclk", "uart2",
|
||||
CLK_CON_GAT_PERI_UART2_EXT_UCLK, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_HSI2C1_IPCLK,
|
||||
"gout_peri_hsi2c1_ipclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_HSI2C1_IPCLK, 11,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_HSI2C2_IPCLK,
|
||||
"gout_peri_hsi2c2_ipclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_HSI2C2_IPCLK, 12,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_HSI2C3_IPCLK,
|
||||
"gout_peri_hsi2c3_ipclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_HSI2C3_IPCLK, 13,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_HSI2C4_IPCLK,
|
||||
"gout_peri_hsi2c4_ipclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_HSI2C4_IPCLK, 14,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_I2C0_PCLK,
|
||||
"gout_peri_i2c0_pclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_I2C0_PCLK, 21,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_I2C1_PCLK,
|
||||
"gout_peri_i2c1_pclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_I2C1_PCLK, 23,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_I2C2_PCLK,
|
||||
"gout_peri_i2c2_pclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_I2C2_PCLK, 22,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_I2C3_PCLK,
|
||||
"gout_peri_i2c3_pclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_I2C3_PCLK, 20,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_I2C4_PCLK,
|
||||
"gout_peri_i2c4_pclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_I2C4_PCLK, 17,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_I2C5_PCLK,
|
||||
"gout_peri_i2c5_pclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_I2C5_PCLK, 18,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_I2C6_PCLK,
|
||||
"gout_peri_i2c6_pclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_I2C6_PCLK, 19,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_I2C7_PCLK,
|
||||
"gout_peri_i2c7_pclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_I2C7_PCLK, 24,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_I2C8_PCLK,
|
||||
"gout_peri_i2c8_pclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_I2C8_PCLK, 25,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_UART0_PCLK,
|
||||
"gout_peri_uart0_pclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_UART0_PCLK, 10,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_UART1_PCLK,
|
||||
"gout_peri_uart1_pclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_UART1_PCLK, 11,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_PERI_UART2_PCLK,
|
||||
"gout_peri_uart2_pclk", "gout_peri_busp1_peric0_hclk",
|
||||
CLK_CON_GAT_PERI_UART2_PCLK, 12,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_clk_group peri_cmu_clks[] = {
|
||||
{ S_CLK_GATE, peri_gate_clks, ARRAY_SIZE(peri_gate_clks) },
|
||||
};
|
||||
|
||||
static int exynos7870_cmu_peri_probe(struct udevice *dev)
|
||||
{
|
||||
return samsung_register_cmu(dev, CMU_PERI, peri_cmu_clks,
|
||||
exynos7870_cmu_peri);
|
||||
}
|
||||
|
||||
static const struct udevice_id exynos7870_cmu_peri_ids[] = {
|
||||
{ .compatible = "samsung,exynos7870-cmu-peri" },
|
||||
{ }
|
||||
};
|
||||
|
||||
SAMSUNG_CLK_OPS(exynos7870_cmu_peri, CMU_PERI);
|
||||
|
||||
U_BOOT_DRIVER(exynos7870_cmu_peri) = {
|
||||
.name = "exynos7870-cmu-peri",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = exynos7870_cmu_peri_ids,
|
||||
.ops = &exynos7870_cmu_peri_clk_ops,
|
||||
.probe = exynos7870_cmu_peri_probe,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
@@ -117,6 +117,7 @@ static struct clk *_samsung_clk_register_pll(void __iomem *base,
|
||||
|
||||
switch (pll_clk->type) {
|
||||
case pll_0822x:
|
||||
case pll_1417x:
|
||||
drv_name = UBOOT_DM_CLK_SAMSUNG_PLL0822X;
|
||||
break;
|
||||
case pll_0831x:
|
||||
@@ -136,7 +137,8 @@ static struct clk *_samsung_clk_register_pll(void __iomem *base,
|
||||
return clk;
|
||||
}
|
||||
|
||||
void samsung_clk_register_pll(void __iomem *base, unsigned int cmu_id,
|
||||
void samsung_clk_register_pll(struct udevice *dev, void __iomem *base,
|
||||
unsigned int cmu_id,
|
||||
const struct samsung_pll_clock *clk_list,
|
||||
unsigned int nr_clk)
|
||||
{
|
||||
|
||||
@@ -20,9 +20,11 @@ struct samsung_pll_clock;
|
||||
enum samsung_pll_type {
|
||||
pll_0822x,
|
||||
pll_0831x,
|
||||
pll_1417x,
|
||||
};
|
||||
|
||||
void samsung_clk_register_pll(void __iomem *base, unsigned int cmu_id,
|
||||
void samsung_clk_register_pll(struct udevice *dev, void __iomem *base,
|
||||
unsigned int cmu_id,
|
||||
const struct samsung_pll_clock *clk_list,
|
||||
unsigned int nr_clk);
|
||||
|
||||
|
||||
@@ -10,7 +10,62 @@
|
||||
#include <dm.h>
|
||||
#include "clk.h"
|
||||
|
||||
static void samsung_clk_register_mux(void __iomem *base, unsigned int cmu_id,
|
||||
int samsung_clk_request(struct clk *clk)
|
||||
{
|
||||
struct clk *c;
|
||||
int ret;
|
||||
|
||||
ret = clk_get_by_id(clk->id, &c);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk->dev = c->dev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
samsung_clk_register_fixed_rate(struct udevice *dev, void __iomem *base,
|
||||
unsigned int cmu_id,
|
||||
const struct samsung_fixed_rate_clock *clk_list,
|
||||
unsigned int nr_clk)
|
||||
{
|
||||
unsigned int cnt;
|
||||
|
||||
for (cnt = 0; cnt < nr_clk; cnt++) {
|
||||
struct clk *clk;
|
||||
const struct samsung_fixed_rate_clock *m;
|
||||
unsigned long clk_id;
|
||||
|
||||
m = &clk_list[cnt];
|
||||
clk = clk_register_fixed_rate(NULL, m->name, m->fixed_rate);
|
||||
clk_id = SAMSUNG_TO_CLK_ID(cmu_id, m->id);
|
||||
clk_dm(clk_id, clk);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
samsung_clk_register_fixed_factor(struct udevice *dev, void __iomem *base,
|
||||
unsigned int cmu_id,
|
||||
const struct samsung_fixed_factor_clock *clk_list,
|
||||
unsigned int nr_clk)
|
||||
{
|
||||
unsigned int cnt;
|
||||
|
||||
for (cnt = 0; cnt < nr_clk; cnt++) {
|
||||
struct clk *clk;
|
||||
const struct samsung_fixed_factor_clock *m;
|
||||
unsigned long clk_id;
|
||||
|
||||
m = &clk_list[cnt];
|
||||
clk = clk_register_fixed_factor(dev, m->name, m->parent_name,
|
||||
m->flags, m->mult, m->div);
|
||||
clk_id = SAMSUNG_TO_CLK_ID(cmu_id, m->id);
|
||||
clk_dm(clk_id, clk);
|
||||
}
|
||||
}
|
||||
|
||||
static void samsung_clk_register_mux(struct udevice *dev, void __iomem *base,
|
||||
unsigned int cmu_id,
|
||||
const struct samsung_mux_clock *clk_list,
|
||||
unsigned int nr_clk)
|
||||
{
|
||||
@@ -22,15 +77,17 @@ static void samsung_clk_register_mux(void __iomem *base, unsigned int cmu_id,
|
||||
unsigned long clk_id;
|
||||
|
||||
m = &clk_list[cnt];
|
||||
clk = clk_register_mux(NULL, m->name, m->parent_names,
|
||||
m->num_parents, m->flags, base + m->offset, m->shift,
|
||||
m->width, m->mux_flags);
|
||||
clk = clk_register_mux(dev, m->name, m->parent_names,
|
||||
m->num_parents, m->flags,
|
||||
base + m->offset, m->shift, m->width,
|
||||
m->mux_flags);
|
||||
clk_id = SAMSUNG_TO_CLK_ID(cmu_id, m->id);
|
||||
clk_dm(clk_id, clk);
|
||||
}
|
||||
}
|
||||
|
||||
static void samsung_clk_register_div(void __iomem *base, unsigned int cmu_id,
|
||||
static void samsung_clk_register_div(struct udevice *dev, void __iomem *base,
|
||||
unsigned int cmu_id,
|
||||
const struct samsung_div_clock *clk_list,
|
||||
unsigned int nr_clk)
|
||||
{
|
||||
@@ -42,15 +99,16 @@ static void samsung_clk_register_div(void __iomem *base, unsigned int cmu_id,
|
||||
unsigned long clk_id;
|
||||
|
||||
d = &clk_list[cnt];
|
||||
clk = clk_register_divider(NULL, d->name, d->parent_name,
|
||||
d->flags, base + d->offset, d->shift,
|
||||
d->width, d->div_flags);
|
||||
clk = clk_register_divider(dev, d->name, d->parent_name,
|
||||
d->flags, base + d->offset, d->shift,
|
||||
d->width, d->div_flags);
|
||||
clk_id = SAMSUNG_TO_CLK_ID(cmu_id, d->id);
|
||||
clk_dm(clk_id, clk);
|
||||
}
|
||||
}
|
||||
|
||||
static void samsung_clk_register_gate(void __iomem *base, unsigned int cmu_id,
|
||||
static void samsung_clk_register_gate(struct udevice *dev, void __iomem *base,
|
||||
unsigned int cmu_id,
|
||||
const struct samsung_gate_clock *clk_list,
|
||||
unsigned int nr_clk)
|
||||
{
|
||||
@@ -62,19 +120,21 @@ static void samsung_clk_register_gate(void __iomem *base, unsigned int cmu_id,
|
||||
unsigned long clk_id;
|
||||
|
||||
g = &clk_list[cnt];
|
||||
clk = clk_register_gate(NULL, g->name, g->parent_name,
|
||||
g->flags, base + g->offset, g->bit_idx,
|
||||
g->gate_flags, NULL);
|
||||
clk = clk_register_gate(dev, g->name, g->parent_name,
|
||||
g->flags, base + g->offset, g->bit_idx,
|
||||
g->gate_flags, NULL);
|
||||
clk_id = SAMSUNG_TO_CLK_ID(cmu_id, g->id);
|
||||
clk_dm(clk_id, clk);
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*samsung_clk_register_fn)(void __iomem *base, unsigned int cmu_id,
|
||||
const void *clk_list,
|
||||
typedef void (*samsung_clk_register_fn)(struct udevice *dev, void __iomem *base,
|
||||
unsigned int cmu_id, const void *clk_list,
|
||||
unsigned int nr_clk);
|
||||
|
||||
static const samsung_clk_register_fn samsung_clk_register_fns[] = {
|
||||
[S_CLK_FRATE] = (samsung_clk_register_fn)samsung_clk_register_fixed_rate,
|
||||
[S_CLK_FFACTOR] = (samsung_clk_register_fn)samsung_clk_register_fixed_factor,
|
||||
[S_CLK_MUX] = (samsung_clk_register_fn)samsung_clk_register_mux,
|
||||
[S_CLK_DIV] = (samsung_clk_register_fn)samsung_clk_register_div,
|
||||
[S_CLK_GATE] = (samsung_clk_register_fn)samsung_clk_register_gate,
|
||||
@@ -91,16 +151,17 @@ static const samsung_clk_register_fn samsung_clk_register_fns[] = {
|
||||
* Having the array of clock groups @clk_groups makes it possible to keep a
|
||||
* correct clocks registration order.
|
||||
*/
|
||||
static void samsung_cmu_register_clocks(void __iomem *base, unsigned int cmu_id,
|
||||
const struct samsung_clk_group *clk_groups,
|
||||
unsigned int nr_groups)
|
||||
static void samsung_cmu_register_clocks(struct udevice *dev, void __iomem *base,
|
||||
unsigned int cmu_id,
|
||||
const struct samsung_clk_group *clk_groups,
|
||||
unsigned int nr_groups)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < nr_groups; i++) {
|
||||
const struct samsung_clk_group *g = &clk_groups[i];
|
||||
|
||||
samsung_clk_register_fns[g->type](base, cmu_id,
|
||||
samsung_clk_register_fns[g->type](dev, base, cmu_id,
|
||||
g->clk_list, g->nr_clk);
|
||||
}
|
||||
}
|
||||
@@ -124,7 +185,7 @@ int samsung_cmu_register_one(struct udevice *dev, unsigned int cmu_id,
|
||||
if (!base)
|
||||
return -EINVAL;
|
||||
|
||||
samsung_cmu_register_clocks(base, cmu_id, clk_groups, nr_groups);
|
||||
samsung_cmu_register_clocks(dev, base, cmu_id, clk_groups, nr_groups);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -9,10 +9,13 @@
|
||||
#ifndef __EXYNOS_CLK_H
|
||||
#define __EXYNOS_CLK_H
|
||||
|
||||
#include <clk.h>
|
||||
#include <errno.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include "clk-pll.h"
|
||||
|
||||
int samsung_clk_request(struct clk *clk);
|
||||
|
||||
#define _SAMSUNG_CLK_OPS(_name, _cmu) \
|
||||
static int _name##_of_xlate(struct clk *clk, \
|
||||
struct ofnode_phandle_args *args) \
|
||||
@@ -37,6 +40,7 @@ static const struct clk_ops _name##_clk_ops = { \
|
||||
.enable = ccf_clk_enable, \
|
||||
.disable = ccf_clk_disable, \
|
||||
.of_xlate = _name##_of_xlate, \
|
||||
.request = samsung_clk_request, \
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,6 +62,53 @@ static const struct clk_ops _name##_clk_ops = { \
|
||||
*/
|
||||
#define SAMSUNG_TO_CLK_ID(_cmu, _id) (((_cmu) << 8) | ((_id) & 0xff))
|
||||
|
||||
/**
|
||||
* struct samsung_fixed_rate_clock - information about fixed-rate clock
|
||||
* @id: platform specific id of the clock
|
||||
* @name: name of this fixed-rate clock
|
||||
* @fixed_rate: fixed clock rate of this clock
|
||||
*/
|
||||
struct samsung_fixed_rate_clock {
|
||||
unsigned int id;
|
||||
const char *name;
|
||||
unsigned long fixed_rate;
|
||||
};
|
||||
|
||||
#define FRATE(_id, cname, frate) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.name = cname, \
|
||||
.fixed_rate = frate, \
|
||||
}
|
||||
|
||||
/**
|
||||
* struct samsung_fixed_factor_clock - information about fixed-factor clock
|
||||
* @id: platform specific id of the clock
|
||||
* @name: name of this fixed-factor clock
|
||||
* @parent_name: parent clock name
|
||||
* @mult: fixed multiplication factor
|
||||
* @div: fixed division factor
|
||||
* @flags: optional fixed-factor clock flags
|
||||
*/
|
||||
struct samsung_fixed_factor_clock {
|
||||
unsigned int id;
|
||||
const char *name;
|
||||
const char *parent_name;
|
||||
unsigned long mult;
|
||||
unsigned long div;
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
#define FFACTOR(_id, cname, pname, m, d, f) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.name = cname, \
|
||||
.parent_name = pname, \
|
||||
.mult = m, \
|
||||
.div = d, \
|
||||
.flags = f, \
|
||||
}
|
||||
|
||||
/**
|
||||
* struct samsung_mux_clock - information about mux clock
|
||||
* @id: platform specific id of the clock
|
||||
@@ -206,6 +257,8 @@ struct samsung_pll_clock {
|
||||
}
|
||||
|
||||
enum samsung_clock_type {
|
||||
S_CLK_FRATE,
|
||||
S_CLK_FFACTOR,
|
||||
S_CLK_MUX,
|
||||
S_CLK_DIV,
|
||||
S_CLK_GATE,
|
||||
|
||||
@@ -319,7 +319,7 @@ static int gpio_exynos_bind(struct udevice *parent)
|
||||
base = dev_read_addr_ptr(parent);
|
||||
for (node = fdt_first_subnode(blob, dev_of_offset(parent)), bank = base;
|
||||
node > 0;
|
||||
node = fdt_next_subnode(blob, node), bank++) {
|
||||
node = fdt_next_subnode(blob, node)) {
|
||||
struct exynos_gpio_plat *plat;
|
||||
struct udevice *dev;
|
||||
fdt_addr_t reg;
|
||||
@@ -341,9 +341,8 @@ static int gpio_exynos_bind(struct udevice *parent)
|
||||
if (reg != FDT_ADDR_T_NONE)
|
||||
bank = (struct s5p_gpio_bank *)((ulong)base + reg);
|
||||
|
||||
plat->bank = bank;
|
||||
|
||||
debug("dev at %p: %s\n", bank, plat->bank_name);
|
||||
plat->bank = bank++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <log.h>
|
||||
#include <dm.h>
|
||||
#include <dm/lists.h>
|
||||
#include <errno.h>
|
||||
#include <asm/io.h>
|
||||
#include "pinctrl-exynos.h"
|
||||
@@ -178,3 +179,13 @@ int exynos_pinctrl_probe(struct udevice *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exynos_pinctrl_bind(struct udevice *dev)
|
||||
{
|
||||
/*
|
||||
* Attempt to bind the Exynos GPIO driver. The GPIOs and
|
||||
* pin controller descriptors are found in the same OF node.
|
||||
*/
|
||||
return device_bind_driver_to_node(dev, "gpio_exynos", "gpio-banks",
|
||||
dev_ofnode(dev), NULL);
|
||||
}
|
||||
|
||||
@@ -97,5 +97,6 @@ void exynos_pinctrl_setup_peri(struct exynos_pinctrl_config_data *conf,
|
||||
int exynos_pinctrl_set_state(struct udevice *dev,
|
||||
struct udevice *config);
|
||||
int exynos_pinctrl_probe(struct udevice *dev);
|
||||
int exynos_pinctrl_bind(struct udevice *dev);
|
||||
|
||||
#endif /* __PINCTRL_EXYNOS_H_ */
|
||||
|
||||
@@ -114,4 +114,5 @@ U_BOOT_DRIVER(pinctrl_exynos7420) = {
|
||||
.priv_auto = sizeof(struct exynos_pinctrl_priv),
|
||||
.ops = &exynos7420_pinctrl_ops,
|
||||
.probe = exynos_pinctrl_probe,
|
||||
.bind = exynos_pinctrl_bind,
|
||||
};
|
||||
|
||||
@@ -45,6 +45,11 @@ static const struct samsung_pin_bank_data exynos78x0_pin_banks2[] = {
|
||||
EXYNOS_PIN_BANK(4, 0x040, "gpz2"),
|
||||
};
|
||||
|
||||
/* pin banks of exynos78x0 pin-controller 3 (ESE) */
|
||||
static const struct samsung_pin_bank_data exynos78x0_pin_banks3[] = {
|
||||
EXYNOS_PIN_BANK(5, 0x000, "gpc7"),
|
||||
};
|
||||
|
||||
/* pin banks of exynos78x0 pin-controller 4 (FSYS) */
|
||||
static const struct samsung_pin_bank_data exynos78x0_pin_banks4[] = {
|
||||
EXYNOS_PIN_BANK(3, 0x000, "gpr0"),
|
||||
@@ -54,6 +59,11 @@ static const struct samsung_pin_bank_data exynos78x0_pin_banks4[] = {
|
||||
EXYNOS_PIN_BANK(6, 0x080, "gpr4"),
|
||||
};
|
||||
|
||||
/* pin banks of exynos78x0 pin-controller 5 (NFC) */
|
||||
static const struct samsung_pin_bank_data exynos78x0_pin_banks5[] = {
|
||||
EXYNOS_PIN_BANK(4, 0x000, "gpc2"),
|
||||
};
|
||||
|
||||
/* pin banks of exynos78x0 pin-controller 6 (TOP) */
|
||||
static const struct samsung_pin_bank_data exynos78x0_pin_banks6[] = {
|
||||
EXYNOS_PIN_BANK(4, 0x000, "gpb0"),
|
||||
@@ -77,6 +87,11 @@ static const struct samsung_pin_bank_data exynos78x0_pin_banks6[] = {
|
||||
EXYNOS_PIN_BANK(5, 0x240, "gpf4"),
|
||||
};
|
||||
|
||||
/* pin banks of exynos7870 pin-controller 7 (TOUCH) */
|
||||
static const struct samsung_pin_bank_data exynos78x0_pin_banks7[] = {
|
||||
EXYNOS_PIN_BANK(3, 0x000, "gpc3"),
|
||||
};
|
||||
|
||||
const struct samsung_pin_ctrl exynos78x0_pin_ctrl[] = {
|
||||
{
|
||||
/* pin-controller instance 0 Alive data */
|
||||
@@ -102,9 +117,53 @@ const struct samsung_pin_ctrl exynos78x0_pin_ctrl[] = {
|
||||
{/* list terminator */}
|
||||
};
|
||||
|
||||
/*
|
||||
* In Exynos7870, the CCORE block is named as MIF instead. As the
|
||||
* pinctrl blocks are sorted in lexical order of their names, the
|
||||
* order isn't the same as Exynos7880.
|
||||
*/
|
||||
const struct samsung_pin_ctrl exynos7870_pin_ctrl[] = {
|
||||
{
|
||||
/* pin-controller instance 0 Alive data */
|
||||
.pin_banks = exynos78x0_pin_banks0,
|
||||
.nr_banks = ARRAY_SIZE(exynos78x0_pin_banks0),
|
||||
}, {
|
||||
/* pin-controller instance 1 DISPAUD data */
|
||||
.pin_banks = exynos78x0_pin_banks2,
|
||||
.nr_banks = ARRAY_SIZE(exynos78x0_pin_banks2),
|
||||
}, {
|
||||
/* pin-controller instance 2 ESE data */
|
||||
.pin_banks = exynos78x0_pin_banks3,
|
||||
.nr_banks = ARRAY_SIZE(exynos78x0_pin_banks3),
|
||||
}, {
|
||||
/* pin-controller instance 3 FSYS data */
|
||||
.pin_banks = exynos78x0_pin_banks4,
|
||||
.nr_banks = ARRAY_SIZE(exynos78x0_pin_banks4),
|
||||
}, {
|
||||
/* pin-controller instance 4 MIF data */
|
||||
.pin_banks = exynos78x0_pin_banks1,
|
||||
.nr_banks = ARRAY_SIZE(exynos78x0_pin_banks1),
|
||||
}, {
|
||||
/* pin-controller instance 5 NFC data */
|
||||
.pin_banks = exynos78x0_pin_banks5,
|
||||
.nr_banks = ARRAY_SIZE(exynos78x0_pin_banks5),
|
||||
}, {
|
||||
/* pin-controller instance 6 TOP data */
|
||||
.pin_banks = exynos78x0_pin_banks6,
|
||||
.nr_banks = ARRAY_SIZE(exynos78x0_pin_banks6),
|
||||
}, {
|
||||
/* pin-controller instance 7 TOUCH data */
|
||||
.pin_banks = exynos78x0_pin_banks7,
|
||||
.nr_banks = ARRAY_SIZE(exynos78x0_pin_banks7),
|
||||
},
|
||||
{/* list terminator */}
|
||||
};
|
||||
|
||||
static const struct udevice_id exynos78x0_pinctrl_ids[] = {
|
||||
{ .compatible = "samsung,exynos78x0-pinctrl",
|
||||
.data = (ulong)exynos78x0_pin_ctrl },
|
||||
{ .compatible = "samsung,exynos7870-pinctrl",
|
||||
.data = (ulong)exynos7870_pin_ctrl },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -115,4 +174,5 @@ U_BOOT_DRIVER(pinctrl_exynos78x0) = {
|
||||
.priv_auto = sizeof(struct exynos_pinctrl_priv),
|
||||
.ops = &exynos78x0_pinctrl_ops,
|
||||
.probe = exynos_pinctrl_probe,
|
||||
.bind = exynos_pinctrl_bind,
|
||||
};
|
||||
|
||||
@@ -122,4 +122,5 @@ U_BOOT_DRIVER(pinctrl_exynos850) = {
|
||||
.priv_auto = sizeof(struct exynos_pinctrl_priv),
|
||||
.ops = &exynos850_pinctrl_ops,
|
||||
.probe = exynos_pinctrl_probe,
|
||||
.bind = exynos_pinctrl_bind,
|
||||
};
|
||||
|
||||
@@ -258,6 +258,7 @@ static const struct dm_serial_ops s5p_serial_ops = {
|
||||
static const struct udevice_id s5p_serial_ids[] = {
|
||||
{ .compatible = "samsung,exynos4210-uart", .data = PORT_S5P },
|
||||
{ .compatible = "samsung,exynos850-uart", .data = PORT_S5P },
|
||||
{ .compatible = "samsung,exynos8895-uart", .data = PORT_S5P },
|
||||
{ .compatible = "apple,s5l-uart", .data = PORT_S5L },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -85,6 +85,9 @@ static int exynos_pmu_probe(struct udevice *dev)
|
||||
}
|
||||
|
||||
static const struct udevice_id exynos_pmu_ids[] = {
|
||||
{
|
||||
.compatible = "samsung,exynos7-pmu",
|
||||
},
|
||||
{
|
||||
.compatible = "samsung,exynos850-pmu",
|
||||
.data = (ulong)&exynos850_pmu_data
|
||||
|
||||
14
include/configs/exynos-mobile.h
Normal file
14
include/configs/exynos-mobile.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Samsung Exynos Generic Board Configuration (for mobile devices)
|
||||
*
|
||||
* Copyright (C) 2025 Kaustabh Chakraborty <kauschluss@disroot.org>
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_EXYNOS_MOBILE_H
|
||||
#define __CONFIG_EXYNOS_MOBILE_H
|
||||
|
||||
#define CPU_RELEASE_ADDR secondary_boot_addr
|
||||
#define CFG_SYS_BAUDRATE_TABLE {9600, 115200}
|
||||
|
||||
#endif /* __CONFIG_EXYNOS_MOBILE_H */
|
||||
@@ -139,7 +139,6 @@
|
||||
#endif
|
||||
|
||||
#define CFG_EXTRA_ENV_SETTINGS \
|
||||
"fdt_high=0xffffffff\0" \
|
||||
"initrd_high=0xffffffff\0" \
|
||||
"rootdev=" __stringify(CONFIG_ROOT_DEV) "\0" \
|
||||
"rootpart=" __stringify(CONFIG_ROOT_PART) "\0" \
|
||||
|
||||
Reference in New Issue
Block a user