blob: 44492864b4ef2555f32035d53b3082a6bc1d24e6 [file] [log] [blame]
/* Copyright (c) 2012-2014,2017-2019 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <debug.h>
#include <list.h>
#include <bits.h>
#ifndef __DEVICE_TREE__
#define __DEVICE_TREE__
#define DEV_TREE_SUCCESS 0
#define DEV_TREE_MAGIC 0x54444351 /* "QCDT" */
#define DEV_TREE_MAGIC_LEN 4
#define DEV_TREE_VERSION_V1 1
#define DEV_TREE_VERSION_V2 2
#define DEV_TREE_VERSION_V3 3
#define DEV_TREE_HEADER_SIZE 12
#define DTB_MAGIC 0xedfe0dd0
#define DTB_OFFSET 0x2C
#define DTB_PAD_SIZE 1024
#define DTBO_TABLE_MAGIC 0xD7B7AB1E
#define DTBO_CUSTOM_MAX 4
#define PLATFORM_FOUNDRY_SHIFT 16
#define SOC_MASK (0xffff)
#define VARIANT_MASK (0x000000ff)
#define VARIANT_MINOR_MASK (0x0000ff00)
#define VARIANT_MAJOR_MASK (0x00ff0000)
#define PMIC_MODEL_MASK (0x000000ff)
#define PMIC_REV_MASK (0xffffff00)
#define PMIC_SHIFT_IDX (2)
#define PLATFORM_SUBTYPE_SHIFT_ID (0x18)
#define FOUNDRY_ID_MASK (0x00ff0000)
#define MAX_SUPPORTED_DTBO_IMG_BUF (8388608) /* 8MB 8 * 1024 * 1024 */
#define DTBO_IMG_BUF (10485760) /* 10MB 10 * 1024 * 1024 */
#define MAX_SUPPORTED_VBMETA_IMG_BUF (65536) /* 64 KB 64 * 1024 */
/*
* For DTB V1: The DTB entries would be of the format
* qcom,msm-id = <msm8974, CDP, rev_1>; (3 * sizeof(uint32_t))
* For DTB V2: The DTB entries would be of the format
* qcom,msm-id = <msm8974, rev_1>; (2 * sizeof(uint32_t))
* qcom,board-id = <CDP, subtype_ID>; (2 * sizeof(uint32_t))
* The macros below are defined based on these.
*/
#define DT_ENTRY_V1_SIZE 0xC
#define PLAT_ID_SIZE 0x8
#define BOARD_ID_SIZE 0x8
#define PMIC_ID_SIZE 0x8
typedef enum {
NONE_MATCH,
PMIC_MATCH_BEST_REV_IDX0,
PMIC_MATCH_EXACT_REV_IDX0,
PMIC_MATCH_BEST_REV_IDX1,
PMIC_MATCH_EXACT_REV_IDX1,
PMIC_MATCH_BEST_REV_IDX2,
PMIC_MATCH_EXACT_REV_IDX2,
PMIC_MATCH_BEST_REV_IDX3,
PMIC_MATCH_EXACT_REV_IDX3,
VARIANT_MINOR_BEST_MATCH,
VARIANT_MINOR_EXACT_MATCH,
VARIANT_MAJOR_BEST_MATCH,
VARIANT_MAJOR_EXACT_MATCH,
VERSION_BEST_MATCH,
VERSION_EXACT_MATCH,
FOUNDRYID_DEFAULT_MATCH,
FOUNDRYID_EXACT_MATCH,
PMIC_MATCH_DEFAULT_MODEL_IDX0,
PMIC_MATCH_EXACT_MODEL_IDX0,
PMIC_MATCH_DEFAULT_MODEL_IDX1,
PMIC_MATCH_EXACT_MODEL_IDX1,
PMIC_MATCH_DEFAULT_MODEL_IDX2,
PMIC_MATCH_EXACT_MODEL_IDX2,
PMIC_MATCH_DEFAULT_MODEL_IDX3,
PMIC_MATCH_EXACT_MODEL_IDX3,
SUBTYPE_DEFAULT_MATCH,
SUBTYPE_EXACT_MATCH,
VARIANT_MATCH,
SOC_MATCH,
MAX_MATCH,
}dt_match_params;
#define TOTAL_MATCH_BITS 6
#define ALL_BITS_SET (BIT (SOC_MATCH) | BIT (VARIANT_MATCH) | \
BIT (SUBTYPE_EXACT_MATCH) | BIT (FOUNDRYID_EXACT_MATCH) \
| BIT (PMIC_MATCH_EXACT_MODEL_IDX0) | \
BIT (PMIC_MATCH_EXACT_MODEL_IDX1))
typedef enum {
PMIC_IDX0,
PMIC_IDX1,
PMIC_IDX2,
PMIC_IDX3,
MAX_PMIC_IDX,
}pmic_indexes;
typedef struct dt_info
{
uint32_t dt_platform_id;
uint32_t dt_soc_rev;
uint32_t dt_foundry_id;
uint32_t dt_variant_id;
uint32_t dt_variant_major;
uint32_t dt_variant_minor;
uint32_t dt_platform_subtype;
uint32_t dt_pmic_model[MAX_PMIC_IDX];
uint32_t dt_pmic_rev[MAX_PMIC_IDX];
uint32_t dt_match_val;
void *dtb;
}dt_info;
typedef struct pmic_info
{
uint32_t dt_pmic_model[MAX_PMIC_IDX];
uint32_t dt_pmic_rev[MAX_PMIC_IDX];
uint32_t dt_match_val;
}pmic_info;
struct dt_entry_v2
{
uint32_t platform_id;
uint32_t variant_id;
uint32_t board_hw_subtype;
uint32_t soc_rev;
uint32_t offset;
uint32_t size;
};
struct dt_entry
{
uint32_t platform_id;
uint32_t variant_id;
uint32_t board_hw_subtype;
uint32_t soc_rev;
uint32_t pmic_rev[4];
uint32_t offset;
uint32_t size;
uint32_t idx;
};
struct dt_table
{
uint32_t magic;
uint32_t version;
uint32_t num_entries;
};
struct plat_id
{
uint32_t platform_id;
uint32_t soc_rev;
};
struct board_id
{
uint32_t variant_id;
uint32_t platform_subtype;
};
struct pmic_id
{
uint32_t pmic_version[4];
};
struct dt_mem_node_info
{
uint32_t offset;
uint32_t mem_info_cnt;
uint32_t addr_cell_size;
uint32_t size_cell_size;
};
enum dt_entry_info
{
DTB_FOUNDRY = 0,
DTB_SOC,
DTB_MAJOR_MINOR,
DTB_PMIC0,
DTB_PMIC1,
DTB_PMIC2,
DTB_PMIC3,
DTB_PMIC_MODEL,
DTB_PANEL_TYPE,
DTB_BOOT_DEVICE,
};
enum dt_err_codes
{
DT_OP_SUCCESS,
DT_OP_FAILURE = -1,
};
typedef struct dt_entry_node {
struct list_node node;
struct dt_entry * dt_entry_m;
}dt_node;
struct dtbo_table_hdr {
uint32_t magic; //dtb table magic
uint32_t total_size; //Includes dt_table_hdr + all dt_table_entry and all dtb/dtbo
uint32_t hdr_size; //sizeof(dt_table_hdr)
uint32_t dt_entry_size; //sizeof(dt_table_entry)
uint32_t dt_entry_count; //number of dt_table_entry
uint32_t dt_entry_offset; //offset to the first dt_table_entry
uint32_t page_size; //flash pagesize we assume
uint32_t reserved[1]; //must zeros
};
struct dtbo_table_entry {
uint32_t dt_size;
uint32_t dt_offset; //offset from head of dt_table_hdr
uint32_t id; //optional, must zero if unused
uint32_t revision; //optional, must zero if unused
uint32_t custom[DTBO_CUSTOM_MAX]; //optional, must zero if unused
};
typedef enum dtbo_error
{
DTBO_ERROR = 0,
DTBO_NOT_SUPPORTED = 1,
DTBO_SUCCESS = 2
}dtbo_error;
dtbo_error load_validate_dtbo_image(void **dtbo_img, uint32_t *dtbo_img_size);
void get_recovery_dtbo_info(uint32_t *dtbo_size, void **dtbo_buf);
int dev_tree_validate(struct dt_table *table, unsigned int page_size, uint32_t *dt_hdr_size);
int dev_tree_get_entry_info(struct dt_table *table, struct dt_entry *dt_entry_info);
int update_device_tree(void *fdt, const char *, void *, unsigned);
int dev_tree_add_mem_info(void *fdt, uint32_t offset, uint64_t size, uint64_t addr);
void *dev_tree_appended(void *kernel, uint32_t kernel_size, uint32_t dtb_offset, void *tags);
int get_dtbo_idx (void);
int get_dtb_idx (void);
#endif