diff options
author | xiaobo gu <xiaobo.gu@amlogic.com> | 2019-04-02 19:42:18 +0800 |
---|---|---|
committer | Dongjin Kim <tobetter@gmail.com> | 2019-05-16 13:21:14 +0900 |
commit | 29e150af16b1499c997a19d6fe47ca15af5226a6 (patch) | |
tree | c898fe9554f0741d75a7ae528444c36eff337dc5 | |
parent | 8bb65b9be4b5d1564528629c10bde86949e37951 (diff) | |
download | u-boot-odroid-c1-29e150af16b1499c997a19d6fe47ca15af5226a6.tar.gz |
tm2: add ab301 config [1/1]
PD#SWPL-6678
Problem:
new board ab301 need add config
Solution:
add new config ab301
Verify:
test pass on ab301
Change-Id: Ifcd2b0933fa3bd8861c32f0ae216b1573112538d
Signed-off-by: xiaobo gu <xiaobo.gu@amlogic.com>
21 files changed, 5763 insertions, 0 deletions
diff --git a/board/amlogic/Kconfig b/board/amlogic/Kconfig index c790e370a6..7536e54b30 100644 --- a/board/amlogic/Kconfig +++ b/board/amlogic/Kconfig @@ -236,6 +236,10 @@ config TM2_SKT_V1 bool "Support amlogic tm2 skt v1 board" default n +config TM2_AB301_V1 + bool "Support amlogic tm2 ab301 v1 board" + default n + config PXP_EMULATOR bool "Support pxp environment" default n @@ -499,6 +503,10 @@ if TM2_SKT_V1 source "board/amlogic/tm2_skt_v1/Kconfig" endif +if TM2_AB301_V1 +source "board/amlogic/tm2_ab301_v1/Kconfig" +endif + if ODROID_C2 source "board/hardkernel/odroidc2/Kconfig" endif diff --git a/board/amlogic/configs/tm2_ab301_v1.h b/board/amlogic/configs/tm2_ab301_v1.h new file mode 100644 index 0000000000..d7370b4d30 --- /dev/null +++ b/board/amlogic/configs/tm2_ab301_v1.h @@ -0,0 +1,666 @@ +/* + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include <asm/arch/cpu.h> + +#define CONFIG_SYS_GENERIC_BOARD 1 +#ifndef CONFIG_AML_MESON +#warning "include warning" +#endif + +/* + * platform power init config + */ +#define CONFIG_PLATFORM_POWER_INIT +#define CONFIG_VCCK_INIT_VOLTAGE 800 // VCCK power up voltage +#define CONFIG_VDDEE_INIT_VOLTAGE 800 // VDDEE power up voltage +#define CONFIG_VDDEE_SLEEP_VOLTAGE 731 // VDDEE suspend voltage + +/* configs for CEC */ +#define CONFIG_CEC_OSD_NAME "AML_TV" +#define CONFIG_CEC_WAKEUP +/*if use bt-wakeup,open it*/ +#define CONFIG_BT_WAKEUP +/*if use wifi-wakeup,open it*/ +//#define CONFIG_WIFI_WAKEUP +/* SMP Definitinos */ +#define CPU_RELEASE_ADDR secondary_boot_func + +/* config saradc*/ +#define CONFIG_CMD_SARADC 1 +#define CONFIG_SARADC_CH 2 + +/* Bootloader Control Block function + That is used for recovery and the bootloader to talk to each other + */ +#define CONFIG_BOOTLOADER_CONTROL_BLOCK + +/*a/b update */ +#define CONFIG_CMD_BOOTCTOL_AVB + +/* Serial config */ +#define CONFIG_CONS_INDEX 2 +#define CONFIG_BAUDRATE 115200 +#define CONFIG_AML_MESON_SERIAL 1 +#define CONFIG_SERIAL_MULTI 1 + +//Enable ir remote wake up for bl30 +#define CONFIG_IR_REMOTE_POWER_UP_KEY_VAL1 0xef10fe01 //amlogic tv ir --- power +#define CONFIG_IR_REMOTE_POWER_UP_KEY_VAL2 0XBB44FB04 //amlogic tv ir --- ch+ +#define CONFIG_IR_REMOTE_POWER_UP_KEY_VAL3 0xF20DFE01 //amlogic tv ir --- ch- +#define CONFIG_IR_REMOTE_POWER_UP_KEY_VAL4 0XBA45BD02 //amlogic small ir--- power +#define CONFIG_IR_REMOTE_POWER_UP_KEY_VAL5 0xe51afb04 +#define CONFIG_IR_REMOTE_POWER_UP_KEY_VAL6 0xFFFFFFFF +#define CONFIG_IR_REMOTE_POWER_UP_KEY_VAL7 0xFFFFFFFF +#define CONFIG_IR_REMOTE_POWER_UP_KEY_VAL8 0xFFFFFFFF +#define CONFIG_IR_REMOTE_POWER_UP_KEY_VAL9 0xFFFFFFFF + +/*config the default parameters for adc power key*/ +#define CONFIG_ADC_POWER_KEY_CHAN 2 /*channel range: 0-7*/ +#define CONFIG_ADC_POWER_KEY_VAL 0 /*sample value range: 0-1023*/ + +/* args/envs */ +#define CONFIG_SYS_MAXARGS 64 +#define CONFIG_EXTRA_ENV_SETTINGS \ + "firstboot=1\0"\ + "upgrade_step=0\0"\ + "jtag=disable\0"\ + "loadaddr=1080000\0"\ + "model_name=FHD\0" \ + "panel_type=lvds_1\0" \ + "outputmode=1080p60hz\0" \ + "hdmimode=1080p60hz\0" \ + "cvbsmode=576cvbs\0" \ + "display_width=1920\0" \ + "display_height=1080\0" \ + "display_bpp=16\0" \ + "display_color_index=16\0" \ + "display_layer=osd0\0" \ + "display_color_fg=0xffff\0" \ + "display_color_bg=0\0" \ + "dtb_mem_addr=0x1000000\0" \ + "fb_addr=0x3d800000\0" \ + "fb_width=1920\0" \ + "fb_height=1080\0" \ + "frac_rate_policy=1\0" \ + "usb_burning=update 1000\0" \ + "fdt_high=0x20000000\0"\ + "try_auto_burn=update 700 750;\0"\ + "sdcburncfg=aml_sdc_burn.ini\0"\ + "sdc_burning=sdc_burn ${sdcburncfg}\0"\ + "wipe_data=successful\0"\ + "wipe_cache=successful\0"\ + "EnableSelinux=enforcing\0" \ + "recovery_part=recovery\0"\ + "recovery_offset=0\0"\ + "cvbs_drv=0\0"\ + "lock=10001000\0"\ + "osd_reverse=0\0"\ + "video_reverse=0\0"\ + "active_slot=normal\0"\ + "boot_part=boot\0"\ + "powermode=standby\0"\ + "Irq_check_en=0\0"\ + "fs_type=""rootfstype=ramfs""\0"\ + "initargs="\ + "init=/init console=ttyS0,115200 no_console_suspend earlycon=aml-uart,0xff803000 printk.devkmsg=on ramoops.pstore_en=1 ramoops.record_size=0x8000 ramoops.console_size=0x4000 "\ + "\0"\ + "upgrade_check="\ + "echo upgrade_step=${upgrade_step}; "\ + "if itest ${upgrade_step} == 3; then "\ + "run init_display; run storeargs; run update;"\ + "else fi;"\ + "\0"\ + "storeargs="\ + "setenv bootargs ${initargs} ${fs_type} logo=${display_layer},loaded,${fb_addr} powermode=${powermode} vout=${outputmode},enable panel_type=${panel_type} hdmimode=${hdmimode} cvbsmode=${cvbsmode} osd_reverse=${osd_reverse} video_reverse=${video_reverse} androidboot.selinux=${EnableSelinux} androidboot.firstboot=${firstboot} jtag=${jtag}; "\ + "setenv bootargs ${bootargs} androidboot.hardware=amlogic;"\ + "run cmdline_keys;"\ + "\0"\ + "switch_bootmode="\ + "get_rebootmode;"\ + "if test ${reboot_mode} = factory_reset; then "\ + "run recovery_from_flash;"\ + "else if test ${reboot_mode} = update; then "\ + "run update;"\ + "else if test ${reboot_mode} = cold_boot; then "\ + /*"run try_auto_burn;uboot wake up "*/\ + /*"echo powermode=${powermode}; "\ + "if test ${powermode} = standby; then "\ + "setMtkBT;systemoff; "\ + "else if test ${powermode} = on; then "\ + "run try_auto_burn; "\ + "fi; fi; "\*/\ + "else if test ${reboot_mode} = fastboot; then "\ + "fastboot;"\ + "fi;fi;fi;fi;"\ + "\0" \ + "storeboot="\ + "get_system_as_root_mode;"\ + "echo system_mode: ${system_mode};"\ + "if test ${system_mode} = 1; then "\ + "setenv fs_type ""ro rootwait skip_initramfs"";"\ + "run storeargs;"\ + "fi;"\ + "get_valid_slot;"\ + "get_avb_mode;"\ + "echo active_slot: ${active_slot} avb2: ${avb2};"\ + "if test ${active_slot} != normal; then "\ + "setenv bootargs ${bootargs} androidboot.slot_suffix=${active_slot};"\ + "fi;"\ + "if test ${avb2} = 0; then "\ + "if test ${active_slot} = _a; then "\ + "setenv bootargs ${bootargs} root=/dev/mmcblk0p23;"\ + "else if test ${active_slot} = _b; then "\ + "setenv bootargs ${bootargs} root=/dev/mmcblk0p24;"\ + "fi;fi;"\ + "fi;"\ + "if imgread kernel ${boot_part} ${loadaddr}; then bootm ${loadaddr}; fi;"\ + "run update;"\ + "\0"\ + "factory_reset_poweroff_protect="\ + "echo wipe_data=${wipe_data}; echo wipe_cache=${wipe_cache};"\ + "if test ${wipe_data} = failed; then "\ + "run init_display; run storeargs;"\ + "if mmcinfo; then "\ + "run recovery_from_sdcard;"\ + "fi;"\ + "if usb start 0; then "\ + "run recovery_from_udisk;"\ + "fi;"\ + "run recovery_from_flash;"\ + "fi; "\ + "if test ${wipe_cache} = failed; then "\ + "run init_display; run storeargs;"\ + "if mmcinfo; then "\ + "run recovery_from_sdcard;"\ + "fi;"\ + "if usb start 0; then "\ + "run recovery_from_udisk;"\ + "fi;"\ + "run recovery_from_flash;"\ + "fi; \0" \ + "update="\ + /*first usb burning, second sdc_burn, third ext-sd autoscr/recovery, last udisk autoscr/recovery*/\ + "run usb_burning; "\ + "run sdc_burning; "\ + "if mmcinfo; then "\ + "run recovery_from_sdcard;"\ + "fi;"\ + "if usb start 0; then "\ + "run recovery_from_udisk;"\ + "fi;"\ + "run recovery_from_flash;"\ + "\0"\ + "recovery_from_sdcard="\ + "if fatload mmc 0 ${loadaddr} aml_autoscript; then autoscr ${loadaddr}; fi;"\ + "if fatload mmc 0 ${loadaddr} recovery.img; then "\ + "if fatload mmc 0 ${dtb_mem_addr} dtb.img; then echo sd dtb.img loaded; fi;"\ + "wipeisb; "\ + "bootm ${loadaddr};fi;"\ + "\0"\ + "recovery_from_udisk="\ + "if fatload usb 0 ${loadaddr} aml_autoscript; then autoscr ${loadaddr}; fi;"\ + "if fatload usb 0 ${loadaddr} recovery.img; then "\ + "if fatload usb 0 ${dtb_mem_addr} dtb.img; then echo udisk dtb.img loaded; fi;"\ + "wipeisb; "\ + "bootm ${loadaddr};fi;"\ + "\0"\ + "recovery_from_flash="\ + "get_valid_slot;"\ + "echo active_slot: ${active_slot};"\ + "if test ${active_slot} = normal; then "\ + "setenv bootargs ${bootargs} aml_dt=${aml_dt} recovery_part={recovery_part} recovery_offset={recovery_offset};"\ + "if itest ${upgrade_step} == 3; then "\ + "if ext4load mmc 1:2 ${dtb_mem_addr} /recovery/dtb.img; then echo cache dtb.img loaded; fi;"\ + "if ext4load mmc 1:2 ${loadaddr} /recovery/recovery.img; then echo cache recovery.img loaded; wipeisb; bootm ${loadaddr}; fi;"\ + "else fi;"\ + "if imgread kernel ${recovery_part} ${loadaddr} ${recovery_offset}; then wipeisb; bootm ${loadaddr}; fi;"\ + "else "\ + "setenv bootargs ${bootargs} aml_dt=${aml_dt} recovery_part=${boot_part} recovery_offset=${recovery_offset};"\ + "if imgread kernel ${boot_part} ${loadaddr}; then bootm ${loadaddr}; fi;"\ + "fi;"\ + "\0"\ + "init_display="\ + "osd open;osd clear;imgread pic logo bootup $loadaddr;bmp display $bootup_offset;bmp scale;vout output ${outputmode}"\ + "\0"\ + "cmdline_keys="\ + "if keyman init 0x1234; then "\ + "if keyman read usid ${loadaddr} str; then "\ + "setenv bootargs ${bootargs} androidboot.serialno=${usid};"\ + "setenv serial ${usid};"\ + "else "\ + "setenv bootargs ${bootargs} androidboot.serialno=1234567890;"\ + "setenv serial 1234567890;"\ + "fi;"\ + "if keyman read mac ${loadaddr} str; then "\ + "setenv bootargs ${bootargs} mac=${mac} androidboot.mac=${mac};"\ + "fi;"\ + "if keyman read deviceid ${loadaddr} str; then "\ + "setenv bootargs ${bootargs} androidboot.deviceid=${deviceid};"\ + "fi;"\ + "fi;"\ + "\0"\ + "bcb_cmd="\ + "get_rebootmode;"\ + "get_valid_slot;"\ + "\0"\ + "upgrade_key="\ + "if gpio input GPIOAO_3; then "\ + "echo detect upgrade key; run update;"\ + "fi;"\ + "\0"\ + "irremote_update="\ + "if irkey 2500000 0xe31cfb04 0xb748fb04; then "\ + "echo read irkey ok!; " \ + "if itest ${irkey_value} == 0xe31cfb04; then " \ + "run update;" \ + "else if itest ${irkey_value} == 0xb748fb04; then " \ + "run update;\n" \ + "fi;fi;" \ + "fi;\0" \ + +#define CONFIG_PREBOOT \ + "mw ff638630 0 2;"\ + "run bcb_cmd; "\ + "run factory_reset_poweroff_protect;"\ + "run upgrade_check;"\ + "run init_display;"\ + "run storeargs;"\ + "bcb uboot-command;"\ + "run switch_bootmode;" + + +#define CONFIG_BOOTCOMMAND "run storeboot" + +//#define CONFIG_ENV_IS_NOWHERE 1 +#define CONFIG_ENV_SIZE (64*1024) +#define CONFIG_FIT 1 +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_ANDROID_BOOT_IMAGE 1 +#define CONFIG_ANDROID_IMG 1 +#define CONFIG_SYS_BOOTM_LEN (64<<20) /* Increase max gunzip size*/ + +/* cpu */ +#define CONFIG_CPU_CLK 1200 //MHz. Range: 360-2000, should be multiple of 24 + +/* ATTENTION */ +/* DDR configs move to board/amlogic/[board]/firmware/timing.c */ + +#define CONFIG_NR_DRAM_BANKS 1 +/* ddr functions */ +#define CONFIG_DDR_FULL_TEST 0 //0:disable, 1:enable. ddr full test +#define CONFIG_CMD_DDR_D2PLL 0 //0:disable, 1:enable. d2pll cmd +#define CONFIG_CMD_DDR_TEST 0 //0:disable, 1:enable. ddrtest cmd +#define CONFIG_DDR_LOW_POWER 0 //0:disable, 1:enable. ddr clk gate for lp +#define CONFIG_DDR_ZQ_PD 0 //0:disable, 1:enable. ddr zq power down +#define CONFIG_DDR_USE_EXT_VREF 0 //0:disable, 1:enable. ddr use external vref +#define CONFIG_DDR4_TIMING_TEST 0 //0:disable, 1:enable. ddr4 timing test function +#define CONFIG_DDR_PLL_BYPASS 0 //0:disable, 1:enable. ddr pll bypass function +#define CONFIG_DDR_NONSEC_SCRAMBLE 0 //0:disable, 1:enable. non-sec region scramble function + +/* storage: emmc/nand/sd */ +#define CONFIG_STORE_COMPATIBLE 1 +#define CONFIG_ENV_OVERWRITE +#define CONFIG_CMD_SAVEENV +/* fixme, need fix*/ + +#if (defined(CONFIG_ENV_IS_IN_AMLNAND) || defined(CONFIG_ENV_IS_IN_MMC)) && defined(CONFIG_STORE_COMPATIBLE) +#error env in amlnand/mmc already be compatible; +#endif + +/* +* storage +* |---------|---------| +* | | +* emmc<--Compatible-->nand +* |-------|-------| +* | | +* MTD<-Exclusive->NFTL +*/ +/* axg only support slc nand */ +/* swither for mtd nand which is for slc only. */ +/* support for mtd */ +//#define CONFIG_AML_MTD 1 +/* support for nftl */ +//#define CONFIG_AML_NAND 1 + +#if defined(CONFIG_AML_NAND) && defined(CONFIG_AML_MTD) +#error CONFIG_AML_NAND/CONFIG_AML_MTD can not support at the sametime; +#endif + +#ifdef CONFIG_AML_MTD + +/* bootlaoder is construct by bl2 and fip + * when DISCRETE_BOOTLOADER is enabled, bl2 & fip + * will not be stored continuously, and nand layout + * would be bl2|rsv|fip|normal, but not + * bl2|fip|rsv|noraml anymore + */ +#define CONFIG_DISCRETE_BOOTLOADER + +#ifdef CONFIG_DISCRETE_BOOTLOADER +#define CONFIG_TPL_SIZE_PER_COPY 0x200000 +#define CONFIG_TPL_COPY_NUM 4 +#define CONFIG_TPL_PART_NAME "tpl" +/* for bl2, restricted by romboot */ +#define CONFIG_BL2_COPY_NUM 8 +#endif /* CONFIG_DISCRETE_BOOTLOADER */ + +#define CONFIG_CMD_NAND 1 +#define CONFIG_MTD_DEVICE y +/* mtd parts of ourown.*/ +#define CONFIFG_AML_MTDPART 1 +/* mtd parts by env default way.*/ +/* +#define MTDIDS_NAME_STR "aml_nand.0" +#define MTDIDS_DEFAULT "nand1=" MTDIDS_NAME_STR +#define MTDPARTS_DEFAULT "mtdparts=" MTDIDS_NAME_STR ":" \ + "3M@8192K(logo)," \ + "10M(recovery)," \ + "8M(kernel)," \ + "40M(rootfs)," \ + "-(data)" +*/ +#define CONFIG_CMD_UBI +#define CONFIG_CMD_UBIFS +#define CONFIG_RBTREE +#define CONFIG_CMD_NAND_TORTURE 1 +#define CONFIG_CMD_MTDPARTS 1 +#define CONFIG_MTD_PARTITIONS 1 +#define CONFIG_SYS_MAX_NAND_DEVICE 2 +#define CONFIG_SYS_NAND_BASE_LIST {0} +#endif +/* endof CONFIG_AML_MTD */ +#define CONFIG_AML_SD_EMMC 1 +#ifdef CONFIG_AML_SD_EMMC + #define CONFIG_GENERIC_MMC 1 + #define CONFIG_CMD_MMC 1 + #define CONFIG_CMD_GPT 1 + #define CONFIG_SYS_MMC_ENV_DEV 1 + #define CONFIG_EMMC_DDR52_EN 0 + #define CONFIG_EMMC_DDR52_CLK 35000000 +#endif +#define CONFIG_PARTITIONS 1 +#define CONFIG_SYS_NO_FLASH 1 + +/* meson SPI */ +#define CONFIG_AML_SPIFC +#define CONFIG_AML_SPICC +#if defined CONFIG_AML_SPIFC || defined CONFIG_AML_SPICC + #define CONFIG_OF_SPI + #define CONFIG_DM_SPI + #define CONFIG_CMD_SPI +#endif +/* SPI flash config */ +#ifdef CONFIG_AML_SPIFC + #define CONFIG_SPI_FLASH + #define CONFIG_DM_SPI_FLASH + #define CONFIG_CMD_SF + /* SPI flash surpport list */ + #define CONFIG_SPI_FLASH_ATMEL + #define CONFIG_SPI_FLASH_EON + #define CONFIG_SPI_FLASH_GIGADEVICE + #define CONFIG_SPI_FLASH_MACRONIX + #define CONFIG_SPI_FLASH_SPANSION + #define CONFIG_SPI_FLASH_STMICRO + #define CONFIG_SPI_FLASH_SST + #define CONFIG_SPI_FLASH_WINBOND + #define CONFIG_SPI_FRAM_RAMTRON + #define CONFIG_SPI_M95XXX + #define CONFIG_SPI_FLASH_ESMT + /* SPI nand flash support */ + #define CONFIG_SPI_NAND + #define CONFIG_BL2_SIZE (64 * 1024) +#endif + +#if defined CONFIG_AML_MTD || defined CONFIG_SPI_NAND + #define CONFIG_CMD_NAND 1 + #define CONFIG_MTD_DEVICE y + #define CONFIG_RBTREE + #define CONFIG_CMD_NAND_TORTURE 1 + #define CONFIG_CMD_MTDPARTS 1 + #define CONFIG_MTD_PARTITIONS 1 + #define CONFIG_SYS_MAX_NAND_DEVICE 2 + #define CONFIG_SYS_NAND_BASE_LIST {0} +#endif + +/* vpu */ +#define CONFIG_AML_VPU 1 +//#define CONFIG_VPU_CLK_LEVEL_DFT 7 + +/* DISPLAY & HDMITX */ +//#define CONFIG_AML_HDMITX20 1 +#define CONFIG_AML_CANVAS 1 +#define CONFIG_AML_VOUT 1 +#define CONFIG_AML_OSD 1 +#define CONFIG_OSD_SCALE_ENABLE 1 +#define CONFIG_CMD_BMP 1 + +#if defined(CONFIG_AML_VOUT) +//#define CONFIG_AML_CVBS 1 +#endif + +#define CONFIG_AML_LCD 1 +#define CONFIG_AML_LCD_TABLET 1 +#define CONFIG_AML_LCD_TV 1 +//#define CONFIG_AML_LCD_EXTERN 1 + +#define CONFIG_AML_LOCAL_DIMMING +#define CONFIG_AML_LOCAL_DIMMING_GLOBAL + +/* USB + * Enable CONFIG_MUSB_HCD for Host functionalities MSC, keyboard + * Enable CONFIG_MUSB_UDD for Device functionalities. + */ +/* #define CONFIG_MUSB_UDC 1 */ +#define CONFIG_CMD_USB 1 +#if defined(CONFIG_CMD_USB) + #define CONFIG_GXL_XHCI_BASE 0xff500000 + #define CONFIG_GXL_USB_PHY2_BASE 0xffe09000 + #define CONFIG_GXL_USB_PHY3_BASE 0xffe09080 + #define CONFIG_USB_PHY_20 0xff636000 + #define CONFIG_USB_PHY_21 0xff63A000 + #define CONFIG_USB_PHY_22 0xff658000 + #define CONFIG_USB_STORAGE 1 + #define CONFIG_USB_XHCI 1 + #define CONFIG_USB_XHCI_AMLOGIC_V2 1 + #define CONFIG_USB_GPIO_PWR GPIOEE(GPIOH_6) + #define CONFIG_USB_GPIO_PWR_NAME "GPIOH_6" + #define CONFIG_USB_AMLOGIC_PHY_V2 1 + #define CONFIG_USB_U2_PORT_NUM 3 + //#define CONFIG_RTK_USB_BT 1 + //#define CONFIG_USB_XHCI_AMLOGIC_USB3_V2 1 +#endif //#if defined(CONFIG_CMD_USB) + +#define CONFIG_TXLX_USB 1 +#define CONFIG_USB_DEVICE_V2 1 +#define USB_PHY2_PLL_PARAMETER_1 0x09400414 +#define USB_PHY2_PLL_PARAMETER_2 0x927e0000 +#define USB_PHY2_PLL_PARAMETER_3 0xAC5F69E5 + +//UBOOT fastboot config +#define CONFIG_CMD_FASTBOOT 1 +#define CONFIG_FASTBOOT_FLASH_MMC_DEV 1 +#define CONFIG_FASTBOOT_FLASH 1 +#define CONFIG_USB_GADGET 1 +#define CONFIG_USBDOWNLOAD_GADGET 1 +#define CONFIG_SYS_CACHELINE_SIZE 64 +#define CONFIG_FASTBOOT_MAX_DOWN_SIZE 0x8000000 +#define CONFIG_DEVICE_PRODUCT "marconi" + +//UBOOT Facotry usb/sdcard burning config +#define CONFIG_AML_V2_FACTORY_BURN 1 //support facotry usb burning +#define CONFIG_AML_FACTORY_BURN_LOCAL_UPGRADE 1 //support factory sdcard burning +#define CONFIG_POWER_KEY_NOT_SUPPORTED_FOR_BURN 1 //There isn't power-key for factory sdcard burning +#define CONFIG_SD_BURNING_SUPPORT_UI 1 //Displaying upgrading progress bar when sdcard/udisk burning + +#define CONFIG_AML_SECURITY_KEY 1 +#define CONFIG_UNIFY_KEY_MANAGE 1 + +/* net */ +#define CONFIG_CMD_NET 1 +#if defined(CONFIG_CMD_NET) + #define CONFIG_DESIGNWARE_ETH 1 + #define CONFIG_PHYLIB 1 + #define CONFIG_NET_MULTI 1 + #define CONFIG_CMD_PING 1 + #define CONFIG_CMD_DHCP 1 + #define CONFIG_CMD_RARP 1 + #define CONFIG_HOSTNAME arm_gxbb +// #define CONFIG_RANDOM_ETHADDR 1 /* use random eth addr, or default */ + #define CONFIG_ETHADDR 00:15:18:01:81:31 /* Ethernet address */ + #define CONFIG_IPADDR 10.18.9.97 /* Our ip address */ + #define CONFIG_GATEWAYIP 10.18.9.1 /* Our getway ip address */ + #define CONFIG_SERVERIP 10.18.9.113 /* Tftp server ip address */ + #define CONFIG_NETMASK 255.255.255.0 +#endif /* (CONFIG_CMD_NET) */ + +/* other devices */ +/* I2C DM driver*/ +//#define CONFIG_DM_I2C + +#if defined(CONFIG_DM_I2C) +#define CONFIG_SYS_I2C_MESON 1 +#else +#define CONFIG_SYS_I2C_AML 1 +#define CONFIG_SYS_I2C_SPEED 400000 +#endif + +/* PWM DM driver*/ +#define CONFIG_DM_PWM +#define CONFIG_PWM_MESON + +#define CONFIG_EFUSE 1 + +/* commands */ +#define CONFIG_CMD_CACHE 1 +#define CONFIG_CMD_BOOTI 1 +#define CONFIG_CMD_EFUSE 1 +#define CONFIG_CMD_I2C 1 +#define CONFIG_CMD_MEMORY 1 +#define CONFIG_CMD_FAT 1 +#define CONFIG_CMD_GPIO 1 +#define CONFIG_CMD_RUN +#define CONFIG_CMD_REBOOT 1 +#define CONFIG_CMD_ECHO 1 +#define CONFIG_CMD_JTAG 1 +#define CONFIG_CMD_AUTOSCRIPT 1 +#define CONFIG_CMD_MISC 1 +#define CONFIG_CMD_PLLTEST 1 +#define CONFIG_CMD_INI 1 + +/*file system*/ +#define CONFIG_DOS_PARTITION 1 +#define CONFIG_EFI_PARTITION 1 +#define CONFIG_AML_PARTITION 1 +#define CONFIG_MMC 1 +#define CONFIG_FS_FAT 1 +#define CONFIG_FS_EXT4 1 +#define CONFIG_LZO 1 + +#define CONFIG_MDUMP_COMPRESS 1 +#define CONFIG_EXT4_WRITE 1 +#define CONFIG_CMD_EXT4 1 +#define CONFIG_CMD_EXT4_WRITE 1 + +/* Cache Definitions */ +//#define CONFIG_SYS_DCACHE_OFF +//#define CONFIG_SYS_ICACHE_OFF + +/* other functions */ +#define CONFIG_NEED_BL301 1 +#define CONFIG_NEED_BL32 1 +#define CONFIG_CMD_RSVMEM 1 +#define CONFIG_FIP_IMG_SUPPORT 1 +#define CONFIG_BOOTDELAY 1 //delay 1s +#define CONFIG_SYS_LONGHELP 1 +#define CONFIG_CMD_MISC 1 +#define CONFIG_CMD_ITEST 1 +#define CONFIG_CMD_CPU_TEMP 1 +#define CONFIG_SYS_MEM_TOP_HIDE 0x08000000 //hide 128MB for kernel reserve +#define CONFIG_CMD_LOADB 1 +//#define CONFIG_MULTI_DTB 1 + +/* debug mode defines */ +//#define CONFIG_DEBUG_MODE 1 +#ifdef CONFIG_DEBUG_MODE +#define CONFIG_DDR_CLK_DEBUG 636 +#define CONFIG_CPU_CLK_DEBUG 600 +#endif + +//support secure boot +#define CONFIG_AML_SECURE_UBOOT 1 + +#if defined(CONFIG_AML_SECURE_UBOOT) + +//for SRAM size limitation just disable NAND +//as the socket board default has no NAND +//#undef CONFIG_AML_NAND + +//unify build for generate encrypted bootloader "u-boot.bin.encrypt" +#define CONFIG_AML_CRYPTO_UBOOT 1 + +//unify build for generate encrypted kernel image +//SRC : "board/amlogic/(board)/boot.img" +//DST : "fip/boot.img.encrypt" +//#define CONFIG_AML_CRYPTO_IMG 1 + +#endif //CONFIG_AML_SECURE_UBOOT + +#define CONFIG_SECURE_STORAGE 1 + +/* USB port for MT7668. */ +#define BT_USB_PORT_NUM 1 + +//build with uboot auto test +//#define CONFIG_AML_UBOOT_AUTO_TEST 1 + +//board customer ID +//#define CONFIG_CUSTOMER_ID (0x6472616F624C4D41) + +#if defined(CONFIG_CUSTOMER_ID) + #undef CONFIG_AML_CUSTOMER_ID + #define CONFIG_AML_CUSTOMER_ID CONFIG_CUSTOMER_ID +#endif + +/* Choose One of Ethernet Type */ +#undef CONFIG_ETHERNET_NONE +#define ETHERNET_INTERNAL_PHY +#undef ETHERNET_EXTERNAL_PHY + +#define CONFIG_CMD_AML_MTEST 1 +#if defined(CONFIG_CMD_AML_MTEST) +#if !defined(CONFIG_SYS_MEM_TOP_HIDE) +#error CONFIG_CMD_AML_MTEST depends on CONFIG_SYS_MEM_TOP_HIDE; +#endif +#if !(CONFIG_SYS_MEM_TOP_HIDE) +#error CONFIG_SYS_MEM_TOP_HIDE should not be zero; +#endif +#endif + +//to support TLV which can support to transfer info from BL2 to BL3X +//#define CONFIG_AML_SUPPORT_TLV + +//DDR address to contain info from BL2 to BL3X +//#define AML_BL2_TMASTER_DDR_ADDR (0x3000000) + +#endif + diff --git a/board/amlogic/defconfigs/tm2_ab301_v1_defconfig b/board/amlogic/defconfigs/tm2_ab301_v1_defconfig new file mode 100644 index 0000000000..71b59e989c --- /dev/null +++ b/board/amlogic/defconfigs/tm2_ab301_v1_defconfig @@ -0,0 +1,7 @@ +CONFIG_ARM=y +CONFIG_TARGET_MESON_TM2=y +CONFIG_TM2_AB301_V1=y +CONFIG_DM=y +CONFIG_DM_GPIO=y +CONFIG_AML_GPIO=y +CONFIG_MTK_BT_USB=y diff --git a/board/amlogic/tm2_ab301_v1/Kconfig b/board/amlogic/tm2_ab301_v1/Kconfig new file mode 100644 index 0000000000..30c9338289 --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/Kconfig @@ -0,0 +1,28 @@ +if TARGET_MESON_TM2 + +config SYS_CPU + string + default "armv8" + +config SYS_BOARD + string + default "tm2_ab301_v1" + +config SYS_VENDOR + string + default "amlogic" + +config SYS_SOC + string + default "tm2" + +config SYS_CONFIG_NAME + default "tm2_ab301_v1" + +config MTK_BT_USB + bool "enable mtk bt usb function" + default n + help + select this item will enable mtk bt usb device + +endif diff --git a/board/amlogic/tm2_ab301_v1/Makefile b/board/amlogic/tm2_ab301_v1/Makefile new file mode 100644 index 0000000000..9cd0dda96a --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/Makefile @@ -0,0 +1,10 @@ + +obj-y += $(BOARD).o eth_setup.o +obj-$(CONFIG_AML_LCD) += lcd.o + +ifeq ($(CONFIG_MTK_BT_USB),y) +obj-y += ./mtk-bt/LD_btmtk_usb.o +obj-y += ./mtk-bt/LD_usbbt.o +obj-y += ./mtk-bt/cmd_btmtk.o +obj-y += ./mtk-bt/fs_platform.o +endif
\ No newline at end of file diff --git a/board/amlogic/tm2_ab301_v1/aml-user-key.sig b/board/amlogic/tm2_ab301_v1/aml-user-key.sig Binary files differnew file mode 100644 index 0000000000..2ceabc16e0 --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/aml-user-key.sig diff --git a/board/amlogic/tm2_ab301_v1/eth_setup.c b/board/amlogic/tm2_ab301_v1/eth_setup.c new file mode 100644 index 0000000000..33b5db15b9 --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/eth_setup.c @@ -0,0 +1,50 @@ + +/* + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <common.h> +#include <malloc.h> +#include <errno.h> +#include <environment.h> +#include <fdt_support.h> +#include <libfdt.h> +#include <asm/arch/eth_setup.h> +/* + * + *setup eth device board socket + * + */ +struct eth_board_socket* eth_board_setup(char *name){ + struct eth_board_socket* new_board; + new_board= (struct eth_board_socket*) malloc(sizeof(struct eth_board_socket)); + if (NULL == new_board) return NULL; + if (name != NULL) { + new_board->name=(char*)malloc(strlen(name)); + strncpy(new_board->name,name,strlen(name)); + }else{ + new_board->name="gxb"; + } + + new_board->eth_pinmux_setup=NULL ; + new_board->eth_clock_configure=NULL; + new_board->eth_hw_reset=NULL; + return new_board; +} +//pinmux HHI_GCLK_MPEG1[bit 3] +// diff --git a/board/amlogic/tm2_ab301_v1/firmware/ramdump.c b/board/amlogic/tm2_ab301_v1/firmware/ramdump.c new file mode 100644 index 0000000000..e03dcd299e --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/firmware/ramdump.c @@ -0,0 +1,45 @@ + +#ifdef CONFIG_MDUMP_COMPRESS +#include "ramdump.h" + +struct ram_compress_full __ramdump_data = { + .store_phy_addr = (void *)CONFIG_COMPRESSED_DATA_ADDR, + .full_memsize = CONFIG_DDR_TOTAL_SIZE, + .section_count = CONFIG_COMPRESS_SECTION, + .sections = { + { + /* memory afer compressed data address */ + .phy_addr = (void *)CONFIG_COMPRESSED_DATA_ADDR, + .section_size = CONFIG_DDR_TOTAL_SIZE - + CONFIG_COMPRESSED_DATA_ADDR, + .section_index = 4, + .compress_type = RAM_COMPRESS_NORMAL, + }, + { + /* memory before bl2 */ + .phy_addr = (void *)CONFIG_COMPRESS_START_ADDR, + .section_size = CONFIG_BL2_IGNORE_ADDR - + CONFIG_COMPRESS_START_ADDR, + .section_index = 1, + .compress_type = RAM_COMPRESS_NORMAL, + }, + { + /* memory in reserved bl2 */ + .phy_addr = (void *)CONFIG_BL2_IGNORE_ADDR, + .section_size = CONFIG_BL2_IGNORE_SIZE, + .section_index = 2, + .compress_type = RAM_COMPRESS_SET, + .set_value = 0x0, + }, + { + /* segment 4: normal compress */ + .phy_addr = (void *)CONFIG_SEG4_ADDR, + .section_size = CONFIG_COMPRESSED_DATA_ADDR - + CONFIG_SEG4_ADDR, + .section_index = 3, + .compress_type = RAM_COMPRESS_NORMAL, + } + }, +}; +#endif /* CONFIG_MDUMP_COMPRESS */ + diff --git a/board/amlogic/tm2_ab301_v1/firmware/ramdump.h b/board/amlogic/tm2_ab301_v1/firmware/ramdump.h new file mode 100644 index 0000000000..1abd5fff96 --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/firmware/ramdump.h @@ -0,0 +1,75 @@ +#ifndef __RAM_DUMP_H__ +#define __RAM_DUMP_H__ + +#include <config.h> +#ifdef CONFIG_MDUMP_COMPRESS +#define CONFIG_COMPRESS_SECTION 4 + +#if CONFIG_COMPRESS_SECTION > 8 +#error ---> CONFIG_COMPRESS_SECTION out of range, max should be 8 +#endif +/* + * Full Memory lay out for RAM compress: + * + * DDR_TOP -> +--------+ + * | | + * | | + * | 4 | + * | | + * | | + * |~~~~~~~~| <- store compressing data + * |~~~~~~~~| + * |~~~~~~~~| + * |~~~~~~~~| + * |~~~~~~~~| + * |~~~~~~~~| + * |~~~~~~~~| + * |~~~~~~~~| + * |~~~~~~~~| + * COMPRESSED_DATA -> +--------+ + * | | + * | 3 | + * | | + * BL2_IGNORE_END -> +--------+ -- IGNORE_SIZE + * |||||||||| + * ||||2||||| + * |||||||||| + * BL2_IGNORE_ADDR -> +--------+ + * | | + * | 1 | + * | | + * COMPRESS_START_ADDR -> +--------+ + */ +#define CONFIG_DDR_TOTAL_SIZE (CONFIG_DDR_SIZE << 20) +#define CONFIG_COMPRESSED_DATA_ADDR (0x08000000) +#define CONFIG_COMPRESSED_DATA_ADDR1 (0x08000000) + +#define CONFIG_COMPRESS_START_ADDR (0x00000000) +#define CONFIG_BL2_IGNORE_ADDR (0x05000000) +#define CONFIG_BL2_IGNORE_SIZE (0x00300000) +#define CONFIG_SEG4_ADDR (CONFIG_BL2_IGNORE_ADDR + \ + CONFIG_BL2_IGNORE_SIZE) + +enum { + RAM_COMPRESS_NORMAL = 1, + RAM_COMPRESS_COPY = 2, + RAM_COMPRESS_SET = 3 /* set ram content to same vale */ +}; + +struct ram_compress_section { + void *phy_addr; + unsigned int section_size; + unsigned int section_index : 8; + unsigned int compress_type : 8; + unsigned int set_value : 16; +}; + +struct ram_compress_full { + void *store_phy_addr; + unsigned int full_memsize; + unsigned int section_count; + struct ram_compress_section sections[CONFIG_COMPRESS_SECTION]; +}; + +#endif +#endif /* __RAM_DUMP_H__ */ diff --git a/board/amlogic/tm2_ab301_v1/firmware/scp_task/pwm_ctrl.h b/board/amlogic/tm2_ab301_v1/firmware/scp_task/pwm_ctrl.h new file mode 100644 index 0000000000..ba015539c7 --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/firmware/scp_task/pwm_ctrl.h @@ -0,0 +1,39 @@ +/* +*table for Dynamic Voltage/Frequency Scaling +*/ +#ifndef __PWM_CTRL_H__ +#define __PWM_CTRL_H__ + +static int pwm_voltage_table_ee[][2] = { + { 0x1c0000, 681}, + { 0x1b0001, 691}, + { 0x1a0002, 701}, + { 0x190003, 711}, + { 0x180004, 721}, + { 0x170005, 731}, + { 0x160006, 741}, + { 0x150007, 751}, + { 0x140008, 761}, + { 0x130009, 772}, + { 0x12000a, 782}, + { 0x11000b, 792}, + { 0x10000c, 802}, + { 0x0f000d, 812}, + { 0x0e000e, 822}, + { 0x0d000f, 832}, + { 0x0c0010, 842}, + { 0x0b0011, 852}, + { 0x0a0012, 862}, + { 0x090013, 872}, + { 0x080014, 882}, + { 0x070015, 892}, + { 0x060016, 902}, + { 0x050017, 912}, + { 0x040018, 922}, + { 0x030019, 932}, + { 0x02001a, 942}, + { 0x01001b, 952}, + { 0x00001c, 962} +}; + +#endif //__PWM_CTRL_H__ diff --git a/board/amlogic/tm2_ab301_v1/firmware/scp_task/pwr_ctrl.c b/board/amlogic/tm2_ab301_v1/firmware/scp_task/pwr_ctrl.c new file mode 100644 index 0000000000..0a1b98d53b --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/firmware/scp_task/pwr_ctrl.c @@ -0,0 +1,224 @@ + +/* + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <gpio.h> +#include "pwm_ctrl.h" +#ifdef CONFIG_CEC_WAKEUP +#include <cec_tx_reg.h> +#endif + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +static void set_vddee_voltage(unsigned int target_voltage) +{ + unsigned int to; + + for (to = 0; to < ARRAY_SIZE(pwm_voltage_table_ee); to++) { + if (pwm_voltage_table_ee[to][1] >= target_voltage) { + break; + } + } + + if (to >= ARRAY_SIZE(pwm_voltage_table_ee)) { + to = ARRAY_SIZE(pwm_voltage_table_ee) - 1; + } + + writel(pwm_voltage_table_ee[to][0],AO_PWM_PWM_B); +} +static void power_off_ddr(unsigned int flag) +{ + if (flag) { + /*set test_n high to power on VDDQ1.5*/ + writel(readl(AO_GPIO_TEST_N) | (1 << 31), AO_GPIO_TEST_N); + writel(readl(AO_GPIO_TEST_N) & (~(0xf << 8)), AO_GPIO_TEST_N); + } else { + /*set test_n low to power off VDDQ1.5*/ + writel(readl(AO_GPIO_TEST_N) & (~(1 << 31)), AO_GPIO_TEST_N); + writel(readl(AO_GPIO_TEST_N) & (~(0xf << 8)), AO_GPIO_TEST_N); + + } +} + +static void power_off_at_24M(unsigned int suspend_from) +{ + /*set gpiaoao_2 low to power off VDDCPU*/ + writel(readl(AO_GPIO_O) & (~(1 << 2)), AO_GPIO_O); + writel(readl(AO_GPIO_O_EN_N) & (~(1 << 2)), AO_GPIO_O_EN_N); + writel(readl(AO_RTI_PINMUX_REG0) & (~(0xf << 8)), AO_RTI_PINMUX_REG0); + _udelay(100); + + if (suspend_from == SYS_POWEROFF) { + /*if poweroff set gpioao_3 low to power off VCC 5V*/ + writel(readl(AO_GPIO_O) & (~(1 << 3)), AO_GPIO_O); + writel(readl(AO_GPIO_O_EN_N) & (~(1 << 3)), AO_GPIO_O_EN_N); + writel(readl(AO_RTI_PINMUX_REG0) & (~(0xf << 12)), AO_RTI_PINMUX_REG0); + } + + /*step down ee voltage*/ + set_vddee_voltage(CONFIG_VDDEE_SLEEP_VOLTAGE); + if (suspend_from == SYS_POWEROFF) { + power_off_ddr(0); + } +} + +static void power_on_at_24M(unsigned int suspend_from) +{ + + /*step up ee voltage*/ + set_vddee_voltage(CONFIG_VDDEE_INIT_VOLTAGE); + _udelay(100); + + /*set gpiaoao_2 high to power on VDDCPU*/ + writel(readl(AO_GPIO_O) | (1 << 2), AO_GPIO_O); + writel(readl(AO_GPIO_O_EN_N) & (~(1 << 2)), AO_GPIO_O_EN_N); + writel(readl(AO_RTI_PINMUX_REG0) & (~(0xf << 8)), AO_RTI_PINMUX_REG0); + _udelay(100); + + /*set gpioao_3 high to power on VCC 5V*/ + writel(readl(AO_GPIO_O) | (1 << 3), AO_GPIO_O); + writel(readl(AO_GPIO_O_EN_N) & (~(1 << 3)), AO_GPIO_O_EN_N); + writel(readl(AO_RTI_PINMUX_REG0) & (~(0xf << 12)), AO_RTI_PINMUX_REG0); + _udelay(10000); + if (suspend_from == SYS_POWEROFF) { + power_off_ddr(1); + } + +} + +void get_wakeup_source(void *response, unsigned int suspend_from) +{ + struct wakeup_info *p = (struct wakeup_info *)response; + unsigned val; + unsigned i = 0; + + p->status = RESPONSE_OK; + val = (POWER_KEY_WAKEUP_SRC | AUTO_WAKEUP_SRC | REMOTE_WAKEUP_SRC | + ETH_PHY_WAKEUP_SRC | BT_WAKEUP_SRC | CECB_WAKEUP_SRC); + +#ifdef CONFIG_WIFI_WAKEUP + if (suspend_from != SYS_POWEROFF) + val |= WIFI_WAKEUP_SRC; +#endif + +#ifdef CONFIG_BT_WAKEUP + if (1/*suspend_from != SYS_POWEROFF*/) + val |= BT_WAKEUP_SRC; +#endif + + p->sources = val; + p->gpio_info_count = i; + +#ifdef CONFIG_WIFI_WAKEUP + if (suspend_from != SYS_POWEROFF) { + struct wakeup_gpio_info *gpio; + gpio = &(p->gpio_info[i]); + gpio->wakeup_id = WIFI_WAKEUP; + gpio->gpio_in_idx = GPIOC_12; + gpio->gpio_in_ao = 0; + gpio->gpio_out_idx = -1; + gpio->gpio_out_ao = 0; + gpio->irq = IRQ_GPIO1_NUM; + gpio->trig_type = GPIO_IRQ_FALLING_EDGE; + p->gpio_info_count = ++i; + } +#endif +#ifdef CONFIG_BT_WAKEUP + if (1/*suspend_from != SYS_POWEROFF*/) { + struct wakeup_gpio_info *gpio; + gpio = &(p->gpio_info[i]); + gpio->wakeup_id = BT_WAKEUP; + gpio->gpio_in_idx = GPIOC_14; + gpio->gpio_in_ao = 0; + gpio->gpio_out_idx = -1; + gpio->gpio_out_ao = 0; + gpio->irq = IRQ_GPIO1_NUM; + gpio->trig_type = GPIO_IRQ_FALLING_EDGE; + p->gpio_info_count = ++i; + } +#endif +} +extern void __switch_idle_task(void); + +static unsigned int detect_key(unsigned int suspend_from) +{ + int exit_reason = 0; + unsigned *irq = (unsigned *)WAKEUP_SRC_IRQ_ADDR_BASE; + init_remote(); +#ifdef CONFIG_CEC_WAKEUP + if (hdmi_cec_func_config & 0x1) { + remote_cec_hw_reset(); + cec_node_init(); + } +#endif + + do { + #ifdef CONFIG_CEC_WAKEUP + if (irq[IRQ_AO_CECB] == IRQ_AO_CEC2_NUM) { + irq[IRQ_AO_CECB] = 0xFFFFFFFF; + if (cec_power_on_check()) + exit_reason = CEC_WAKEUP; + } + #endif + if (irq[IRQ_AO_IR_DEC] == IRQ_AO_IR_DEC_NUM) { + irq[IRQ_AO_IR_DEC] = 0xFFFFFFFF; + if (remote_detect_key()) + exit_reason = REMOTE_WAKEUP; + } + if (irq[IRQ_VRTC] == IRQ_VRTC_NUM) { + irq[IRQ_VRTC] = 0xFFFFFFFF; + exit_reason = RTC_WAKEUP; + } +#ifdef CONFIG_WIFI_WAKEUP + if (irq[IRQ_GPIO1] == IRQ_GPIO1_NUM) { + irq[IRQ_GPIO1] = 0xFFFFFFFF; + if (suspend_from) { + if ( !(readl(PREG_PAD_GPIO3_EN_N) & (0x01 << 11)) + && (readl(PREG_PAD_GPIO3_O) & (0x01 << 11)) + && !(readl(PREG_PAD_GPIO3_I) & (0x01 << 12))) + exit_reason = WIFI_WAKEUP; + } + } +#endif +#ifdef CONFIG_BT_WAKEUP + if (irq[IRQ_GPIO1] == IRQ_GPIO1_NUM) { + irq[IRQ_GPIO1] = 0xFFFFFFFF; + if (1/*suspend_from*/) { + if ( (readl(PREG_PAD_GPIO3_EN_N) & (0x01 << 14)) + && !(readl(PREG_PAD_GPIO3_I) & (0x01 << 14))) + exit_reason = BT_WAKEUP; + } + } +#endif + if (exit_reason) + break; + else + __switch_idle_task(); + } while (1); + + return exit_reason; +} + +static void pwr_op_init(struct pwr_op *pwr_op) +{ + pwr_op->power_off_at_24M = power_off_at_24M; + pwr_op->power_on_at_24M = power_on_at_24M; + pwr_op->detect_key = detect_key; + pwr_op->get_wakeup_source = get_wakeup_source; +} diff --git a/board/amlogic/tm2_ab301_v1/firmware/timing.c b/board/amlogic/tm2_ab301_v1/firmware/timing.c new file mode 100644 index 0000000000..d54911624e --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/firmware/timing.c @@ -0,0 +1,650 @@ + +/* + * board/amlogic/txl_skt_v1/firmware/timing.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <asm/arch/secure_apb.h> +#include <asm/arch/timing.h> +#include <asm/arch/ddr_define.h> + + + +/* ddr config support multiple configs for boards which use same bootloader: + * config steps: + * 1. add a new data struct in __ddr_setting[] + * 2. config correct board_id, ddr_type, freq, etc.. + */ + + +/* CAUTION!! */ +/* Confirm ddr configs with hardware designer, + * if you don't know how to config, then don't edit it + */ + +/* Key configs */ +/* + * board_id: check hardware adc config + * dram_rank_config: + * #define CONFIG_DDR_CHL_AUTO 0xF + * #define CONFIG_DDR0_16BIT_CH0 0x1 + * #define CONFIG_DDR0_16BIT_RANK01_CH0 0x4 + * #define CONFIG_DDR0_32BIT_RANK0_CH0 0x2 + * #define CONFIG_DDR0_32BIT_RANK01_CH01 0x3 + * #define CONFIG_DDR0_32BIT_16BIT_RANK0_CH0 0x5 + * #define CONFIG_DDR0_32BIT_16BIT_RANK01_CH0 0x6 + * DramType: + * #define CONFIG_DDR_TYPE_DDR3 0 + * #define CONFIG_DDR_TYPE_DDR4 1 + * #define CONFIG_DDR_TYPE_LPDDR4 2 + * #define CONFIG_DDR_TYPE_LPDDR3 3 + * DRAMFreq: + * {pstate0, pstate1, pstate2, pstate3} //more than one pstate means use dynamic freq + * + */ + +ddr_set_t __ddr_setting[] = { +{ + //tl1 ref(T309) lpddr4 + .board_id = CONFIG_BOARD_ID_MASK, + .version = 1, + //.dram_rank_config = CONFIG_DDR0_32BIT_RANK01_CH0, + .dram_rank_config = CONFIG_DDR0_32BIT_RANK0_CH0, + .ddr_rfc_type = DDR_RFC_TYPE_LPDDR4_8Gbx1, + .DramType = CONFIG_DDR_TYPE_LPDDR4, + .DRAMFreq = {1200, 0, 0, 0}, + .ddr_base_addr = CFG_DDR_BASE_ADDR, + .ddr_start_offset = CFG_DDR_START_OFFSET, + .DisabledDbyte = 0xf0, + .Is2Ttiming = 0, + .HdtCtrl = 0xa, + .dram_cs0_size_MB = 1024,//1024, + .dram_cs1_size_MB = 0,//1024, + .training_SequenceCtrl = {0x131f,0x61}, //ddr3 0x21f 0x31f + .phy_odt_config_rank = {0x30,0x30,0x30,0x30}, // // Odt pattern for accesses //targeting rank 0. [3:0] is used //for write ODT [7:4] is used for //read ODT + .dfi_odt_config = 0x0808, + .PllBypassEn = 0, //bit0-ps0,bit1-ps1 + .ddr_rdbi_wr_enable = 0x3, + .clk_drv_ohm = 60, + .cs_drv_ohm = 40, + .ac_drv_ohm = 60, + .soc_data_drv_ohm_p = 48, + .soc_data_drv_ohm_n = 48, + .soc_data_odt_ohm_p = 0, + .soc_data_odt_ohm_n = 60, + .dram_data_drv_ohm = 48, //lpddr4 sdram only240/1-6 + .dram_data_odt_ohm = 120, + .dram_ac_odt_ohm = 120,// 120, + .lpddr4_dram_vout_voltage_1_3_2_5_setting =0,///1, 1/3vddq 0 2/5 vddq + .soc_clk_slew_rate = 0x3ff,//0x253, + .soc_cs_slew_rate = 0x100,//0x253, + .soc_ac_slew_rate = 0x100,//0x253, + .soc_data_slew_rate = 0x1ff, + .vref_output_permil = 260,//200, + .vref_receiver_permil = 0, + .vref_dram_permil = 0, + //.vref_reverse = 0, + //.ac_trace_delay = {32-5,0,0,0,0,0,0x0,00}, + //.ac_pinmux = {00,00}, + .ddr_dmc_remap = { + [0] = ( 5 | 6 << 5 | 7 << 10 | 8<< 15 | 9<< 20 | 10 << 25 ), + [1] = ( 11| 0 << 5 | 0 << 10 | 15 << 15 | 16 << 20 | 17 << 25 ), + [2] = ( 18| 19 << 5 | 20 << 10 | 21 << 15 | 22 << 20 | 23 << 25 ), + [3] = ( 24| 25 << 5 | 26 << 10 | 27 << 15 | 28 << 20 | 29 << 25 ), + [4] = ( 30| 12 << 5 | 13 << 10 | 14<< 15 | 0 << 20 | 0 << 25 ), + }, + .ddr_lpddr34_ca_remap = {00,00}, + //.ddr_lpddr34_dq_remap = {4,5,6,7,0,2,3,1, 15,14,13,12,11,9,10,8, 4,5,6,7,0,2,3,1, 15,14,13,12,11,9,10,8,}, + .ddr_lpddr34_dq_remap = {4,5,6,7,0,2,3,1, 15,14,13,12,11,9,10,8, 20,18,17,16,23,22,19,21, 30,31,25,24,26,28,29,27}, + .dram_rtt_nom_wr_park = {00,00}, + .pll_ssc_mode = (1<<20) | (1<<8) | (2<<4) | 0,//center_ssc_1000ppm + .ddr_func = DDR_FUNC, + .magic = DRAM_CFG_MAGIC, + .diagnose = CONFIG_DIAGNOSE_DISABLE, + .bitTimeControl_2d = 1, //training time setting,=1,200ms;=7,2s +}, +{ + /// tl1 ref(x301) ddr3 + .board_id =CONFIG_BOARD_ID_MASK, + .version = 1, + .dram_rank_config = CONFIG_DDR0_32BIT_RANK01_CH0, + .DramType = CONFIG_DDR_TYPE_DDR3, + .DRAMFreq = {1056, 0, 0, 0}, + .ddr_base_addr = CFG_DDR_BASE_ADDR, + .ddr_start_offset = CFG_DDR_START_OFFSET, + .DisabledDbyte = 0xf0, + .Is2Ttiming = 1, + .HdtCtrl = 0xc8,//0xC8, + .dram_cs0_size_MB = 1024, + .dram_cs1_size_MB = 1024,// 1024, + .training_SequenceCtrl = {0x31f,0}, //ddr3 0x21f 0x31f + .phy_odt_config_rank = {0x23,0x13,0x30,0x30}, // // Odt pattern for accesses //targeting rank 0. [3:0] is used //for write ODT [7:4] is used for //read ODT + .dfi_odt_config = 0x0d0d, + .PllBypassEn = 0, //bit0-ps0,bit1-ps1 + .ddr_rdbi_wr_enable = 0, + .clk_drv_ohm = 40, + .cs_drv_ohm = 40, + .ac_drv_ohm = 60, + .soc_data_drv_ohm_p = 40, + .soc_data_drv_ohm_n = 40, + .soc_data_odt_ohm_p = 48,//120, //48, ddr3 will use odt_ohm_p value + .soc_data_odt_ohm_n = 0,//120, + .dram_data_drv_ohm = 40, //ddr4 sdram only 34 or 48, skt board use 34 better + .dram_data_odt_ohm = 40, + .dram_ac_odt_ohm = 0, + .dram_data_wr_odt_ohm = 120, + .soc_clk_slew_rate = 0x300, + .soc_cs_slew_rate = 0x300, + .soc_ac_slew_rate = 0x300, + .soc_data_slew_rate = 0x200, + .vref_output_permil = 500, + .vref_receiver_permil = 500, //700, + .vref_dram_permil = 500, //700, +// .vref_reverse = 0, +// .ac_trace_delay = {32,32-10,32,32,32+10,32,32,32,32,32-10}, +// .ac_trace_delay = {32-10,32-15,32,32,32,32,32,32,32,32-10}, + .ac_trace_delay = {32-15,32-20,32-10,32,32,32,32,32,32-10,32-15}, + //{00,00}, + .ac_pinmux = {00,00}, +#if 1 + .ddr_dmc_remap = { + [0] = ( 5 | 7 << 5 | 8 << 10 | 9 << 15 | 10 << 20 | 11 << 25 ), + [1] = ( 12| 0 << 5 | 0 << 10 | 14 << 15 | 15 << 20 | 16 << 25 ), + [2] = ( 17| 18 << 5 | 19 << 10 | 21 << 15 | 22 << 20 | 23 << 25 ), + [3] = ( 24| 25 << 5 | 26 << 10 | 27 << 15 | 28 << 20 | 29 << 25 ), + [4] = ( 30| 13 << 5 | 20 << 10 | 6 << 15 | 0 << 20 | 0 << 25 ), + }, +#else + //16bit + .ddr_dmc_remap = { + [0] = ( 0 | 5 << 5 | 6<< 10 | 7 << 15 | 8 << 20 | 9 << 25 ), + [1] = ( 10| 0 << 5 | 0 << 10 | 14 << 15 | 15 << 20 | 16 << 25 ), + [2] = ( 17|( 18 << 5) |( 19 << 10) |( 20 << 15) |( 21 << 20) | (22 << 25 )), + [3] = ( 23| 24 << 5 | 25 << 10 | 26 << 15 | 27 << 20 | 28 << 25 ), + [4] = ( 29| 11<< 5 | 12 << 10 | 13<< 15 | 0 << 20 | 0 << 25 ), + }, +#endif + .ddr_lpddr34_ca_remap = {00,00}, + .ddr_lpddr34_dq_remap = {00,00}, + .dram_rtt_nom_wr_park = {00,00}, + + + .pll_ssc_mode = (1<<20) | (1<<8) | (2<<4) | 0,//center_ssc_1000ppm + .ddr_func = DDR_FUNC, + .magic = DRAM_CFG_MAGIC, +}, +//*/ +{ + /* tl1 skt (x309) ddr4 */ + .board_id = CONFIG_BOARD_ID_MASK, + .version = 1, + .dram_rank_config = CONFIG_DDR0_32BIT_RANK0_CH0, + .DramType = CONFIG_DDR_TYPE_DDR4, + .DRAMFreq = {1200, 0, 0, 0}, + .ddr_rfc_type = DDR_RFC_TYPE_DDR4_2Gbx8, + .ddr_base_addr = CFG_DDR_BASE_ADDR, + .ddr_start_offset = CFG_DDR_START_OFFSET, + .DisabledDbyte = 0xf0, + .Is2Ttiming = 1, + .HdtCtrl = 0xC8, + .dram_cs0_size_MB = 0xffff, + .dram_cs1_size_MB = 0, + .training_SequenceCtrl = {0x31f,0x61}, //ddr3 0x21f 0x31f + .phy_odt_config_rank = {0x23,0x13,0x30,0x30}, // // Odt pattern for accesses //targeting rank 0. [3:0] is used //for write ODT [7:4] is used for //read ODT + .dfi_odt_config = 0x0d0d, + .PllBypassEn = 0, //bit0-ps0,bit1-ps1 + .ddr_rdbi_wr_enable = 0x1,//bit 0 read-dbi,bit 1 write dbi + .clk_drv_ohm = 40, + .cs_drv_ohm = 40, + .ac_drv_ohm = 40, + .soc_data_drv_ohm_p = 48, + .soc_data_drv_ohm_n = 48, + .soc_data_odt_ohm_p = 60, + .soc_data_odt_ohm_n = 0, + .dram_data_drv_ohm = 48,//48, //34, //ddr4 sdram only 34 or 48, skt board use 34 better + .dram_data_odt_ohm = 48, //60, + .dram_ac_odt_ohm = 0, + .soc_clk_slew_rate = 0x3ff, + .soc_cs_slew_rate = 0x3ff, + .soc_ac_slew_rate = 0x3ff, + .soc_data_slew_rate = 0x2ff, + .vref_output_permil = 500, + .vref_receiver_permil = 0, + .vref_dram_permil = 0, + //.vref_reverse = 0, + //.ac_trace_delay ={0x0,0x0},// {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40}, + .ac_trace_delay = {32+10,32+10,32+10,32+10,32,32+10,32+10,32+10,32+10,32+10}, + .ddr_dmc_remap = { + [0] = ( 5 | 7 << 5 | 8 << 10 | 9 << 15 | 10 << 20 | 11 << 25 ), + [1] = ( 12| 0 << 5 | 0 << 10 | 14 << 15 | 15 << 20 | 16 << 25 ), + [2] = ( 17| 18 << 5 | 19 << 10 | 21 << 15 | 22 << 20 | 23 << 25 ), + [3] = ( 24| 25 << 5 | 26 << 10 | 27 << 15 | 28 << 20 | 29 << 25 ), + [4] = ( 30| 13 << 5 | 20 << 10 | 6 << 15 | 0 << 20 | 0 << 25 ), + }, + .ddr_lpddr34_ca_remap = {00,00}, + .ddr_lpddr34_dq_remap = {00,00}, + .dram_rtt_nom_wr_park = {00,00}, + + /* pll ssc config: + * + * pll_ssc_mode = (1<<20) | (1<<8) | ([strength] << 4) | [mode], + * ppm = strength * 500 + * mode: 0=center, 1=up, 2=down + * + * eg: + * 1. config 1000ppm center ss. then mode=0, strength=2 + * .pll_ssc_mode = (1<<20) | (1<<8) | (2 << 4) | 0, + * 2. config 3000ppm down ss. then mode=2, strength=6 + * .pll_ssc_mode = (1<<20) | (1<<8) | (6 << 4) | 2, + */ + .pll_ssc_mode = (1<<20) | (1<<8) | (2<<4) | 0,//center_ssc_1000ppm + .ddr_func = DDR_FUNC, + .magic = DRAM_CFG_MAGIC, + .slt_test_function={0x0,0x0}, //{0x1,0x0},enable slt 4 DRAMFreq test;{0x0,0x0},disable slt 4 DRAMFreq test; +}, +/* +{ + // g12a skt (u209) ddr3 + .board_id = CONFIG_BOARD_ID_MASK, + .version = 1, + .dram_rank_config = CONFIG_DDR0_32BIT_RANK0_CH0, + .DramType = CONFIG_DDR_TYPE_DDR3, + .DRAMFreq = {912, 0, 0, 0}, + .ddr_base_addr = CFG_DDR_BASE_ADDR, + .ddr_start_offset = CFG_DDR_START_OFFSET, + .DisabledDbyte = 0xf0, + .Is2Ttiming = 1, + .HdtCtrl = 0x5,//0xC8, + .dram_cs0_size_MB = 1024, + .dram_cs1_size_MB =0,// 1024, + .training_SequenceCtrl = {0x31f,0}, //ddr3 0x21f 0x31f + .phy_odt_config_rank = {0x30,0x30,0x30,0x30}, // // Odt pattern for accesses //targeting rank 0. [3:0] is used //for write ODT [7:4] is used for //read ODT + .dfi_odt_config = 0x0c0c, + .PllBypassEn = 0, //bit0-ps0,bit1-ps1 + .ddr_rdbi_wr_enable = 0, + .clk_drv_ohm = 40, + .cs_drv_ohm = 40, + .ac_drv_ohm = 40, + .soc_data_drv_ohm_p = 34, + .soc_data_drv_ohm_n = 34, + .soc_data_odt_ohm_p = 60, //48, + .soc_data_odt_ohm_n = 0, + .dram_data_drv_ohm = 34, //ddr4 sdram only 34 or 48, skt board use 34 better + .dram_data_odt_ohm = 60, + .dram_ac_odt_ohm = 0, + .soc_clk_slew_rate = 0x300, + .soc_cs_slew_rate = 0x300, + .soc_ac_slew_rate = 0x300, + .soc_data_slew_rate = 0x200, + .vref_output_permil = 500, + .vref_receiver_permil = 500, //700, + .vref_dram_permil = 500, //700, +// .vref_reverse = 0, + .ac_trace_delay = {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40}, + //{00,00}, + .ac_pinmux = {00,00}, +#if 1 + .ddr_dmc_remap = { + [0] = ( 5 | 7 << 5 | 8 << 10 | 9 << 15 | 10 << 20 | 11 << 25 ), + [1] = ( 12| 0 << 5 | 0 << 10 | 14 << 15 | 15 << 20 | 16 << 25 ), + [2] = ( 17| 18 << 5 | 19 << 10 | 21 << 15 | 22 << 20 | 23 << 25 ), + [3] = ( 24| 25 << 5 | 26 << 10 | 27 << 15 | 28 << 20 | 29 << 25 ), + [4] = ( 30| 13 << 5 | 20 << 10 | 6 << 15 | 0 << 20 | 0 << 25 ), + }, +#else + //16bit + .ddr_dmc_remap = { + [0] = ( 0 | 5 << 5 | 6<< 10 | 7 << 15 | 8 << 20 | 9 << 25 ), + [1] = ( 10| 0 << 5 | 0 << 10 | 14 << 15 | 15 << 20 | 16 << 25 ), + [2] = ( 17|( 18 << 5) |( 19 << 10) |( 20 << 15) |( 21 << 20) | (22 << 25 )), + [3] = ( 23| 24 << 5 | 25 << 10 | 26 << 15 | 27 << 20 | 28 << 25 ), + [4] = ( 29| 11<< 5 | 12 << 10 | 13<< 15 | 0 << 20 | 0 << 25 ), + }, +#endif + .ddr_lpddr34_ca_remap = {00,00}, + .ddr_lpddr34_dq_remap = {00,00}, + .dram_rtt_nom_wr_park = {00,00}, + + + .pll_ssc_mode = (1<<20) | (1<<8) | (2<<4) | 0,//center_ssc_1000ppm + .ddr_func = DDR_FUNC, + .magic = DRAM_CFG_MAGIC, +}, + +{ + //g12a skt (u209) lpddr4 + .board_id = CONFIG_BOARD_ID_MASK, + .version = 1, + //.dram_rank_config = CONFIG_DDR0_32BIT_RANK01_CH0, + .dram_rank_config = CONFIG_DDR0_32BIT_RANK01_CH01, + .ddr_rfc_type = DDR_RFC_TYPE_LPDDR4_4Gbx1, + .DramType = CONFIG_DDR_TYPE_LPDDR4, + .DRAMFreq = {1392, 0, 0, 0}, + .ddr_base_addr = CFG_DDR_BASE_ADDR, + .ddr_start_offset = CFG_DDR_START_OFFSET, + .DisabledDbyte = 0xf0, + .Is2Ttiming = 0, + .HdtCtrl = 0xa, + .dram_cs0_size_MB = 1024,//1024, + .dram_cs1_size_MB = 1024,//1024, + .training_SequenceCtrl = {0x131f,0x61}, //ddr3 0x21f 0x31f + .phy_odt_config_rank = {0x30,0x30,0x30,0x30}, // // Odt pattern for accesses //targeting rank 0. [3:0] is used //for write ODT [7:4] is used for //read ODT + .dfi_odt_config = 0x0808, + .PllBypassEn = 0, //bit0-ps0,bit1-ps1 + .ddr_rdbi_wr_enable = 0, + .clk_drv_ohm = 40, + .cs_drv_ohm = 40, + .ac_drv_ohm = 40, + .soc_data_drv_ohm_p = 40, + .soc_data_drv_ohm_n = 40, + .soc_data_odt_ohm_p = 0, + .soc_data_odt_ohm_n = 120, + .dram_data_drv_ohm = 40, //lpddr4 sdram only240/1-6 + .dram_data_odt_ohm = 120, + .dram_ac_odt_ohm = 120, + .soc_clk_slew_rate = 0x3ff,//0x253, + .soc_cs_slew_rate = 0x100,//0x253, + .soc_ac_slew_rate = 0x100,//0x253, + .soc_data_slew_rate = 0x1ff, + .vref_output_permil = 350,//200, + .vref_receiver_permil = 200, + .vref_dram_permil = 350, + //.vref_reverse = 0, + .ac_trace_delay = {00,0x0,0,0,0,0,0x0,00}, + .ac_pinmux = {00,00}, + .ddr_dmc_remap = { + [0] = ( 5 | 6 << 5 | 7 << 10 | 8<< 15 | 9<< 20 | 10 << 25 ), + [1] = ( 11| 0 << 5 | 0 << 10 | 15 << 15 | 16 << 20 | 17 << 25 ), + [2] = ( 18| 19 << 5 | 20 << 10 | 21 << 15 | 22 << 20 | 23 << 25 ), + [3] = ( 24| 25 << 5 | 26 << 10 | 27 << 15 | 28 << 20 | 29 << 25 ), + [4] = ( 30| 12 << 5 | 13 << 10 | 14<< 15 | 0 << 20 | 0 << 25 ), + }, + .ddr_lpddr34_ca_remap = {00,00}, + .ddr_lpddr34_dq_remap = {3,2,0,1,7,6,5,4,14,13,12,15,8,9,11,10,20,21,22,23,16,17,19,18,24,25,28,26,31,30,27,29}, + .dram_rtt_nom_wr_park = {00,00}, + .pll_ssc_mode = (1<<20) | (1<<8) | (2<<4) | 0,//center_ssc_1000ppm + .ddr_func = DDR_FUNC, + .magic = DRAM_CFG_MAGIC, + .diagnose = CONFIG_DIAGNOSE_DISABLE, +}, +{ + // g12a Y2 dongle + .board_id = CONFIG_BOARD_ID_MASK, + .version = 1, + //.dram_rank_config = CONFIG_DDR0_32BIT_RANK01_CH0, + .dram_rank_config = CONFIG_DDR0_32BIT_RANK0_CH01, + .ddr_rfc_type = DDR_RFC_TYPE_LPDDR4_4Gbx1, + .DramType = CONFIG_DDR_TYPE_LPDDR4, + .DRAMFreq = {1392, 0, 0, 0}, + .ddr_base_addr = CFG_DDR_BASE_ADDR, + .ddr_start_offset = CFG_DDR_START_OFFSET, + .DisabledDbyte = 0xf0, + .Is2Ttiming = 0, + .HdtCtrl = 0xa, + .dram_cs0_size_MB = 1536,//1024, + .dram_cs1_size_MB = 0,//1024, + .training_SequenceCtrl = {0x131f,0x61}, //ddr3 0x21f 0x31f + .phy_odt_config_rank = {0x30,0x30,0x30,0x30}, // // Odt pattern for accesses //targeting rank 0. [3:0] is used //for write ODT [7:4] is used for //read ODT + .dfi_odt_config = 0x0808, + .PllBypassEn = 0, //bit0-ps0,bit1-ps1 + .ddr_rdbi_wr_enable = 0, + .clk_drv_ohm = 40, + .cs_drv_ohm = 40, + .ac_drv_ohm = 40, + .soc_data_drv_ohm_p = 40, + .soc_data_drv_ohm_n = 40, + .soc_data_odt_ohm_p = 0, + .soc_data_odt_ohm_n = 120, + .dram_data_drv_ohm = 40, //lpddr4 sdram only240/1-6 + .dram_data_odt_ohm = 120, + .dram_ac_odt_ohm = 120, + .soc_clk_slew_rate = 0x3ff,//0x253, + .soc_cs_slew_rate = 0x100,//0x253, + .soc_ac_slew_rate = 0x100,//0x253, + .soc_data_slew_rate = 0x1ff, + .vref_output_permil = 350,//200, + .vref_receiver_permil = 200, + .vref_dram_permil = 350, + //.vref_reverse = 0, + .ac_trace_delay = {00,0x0,0,0,0,0,0x0,00}, + .ac_pinmux = {00,00}, + .ddr_dmc_remap = { + [0] = ( 5 | 6 << 5 | 7 << 10 | 8<< 15 | 9<< 20 | 10 << 25 ), + [1] = ( 11| 0 << 5 | 0 << 10 | 15 << 15 | 16 << 20 | 17 << 25 ), + [2] = ( 18| 19 << 5 | 20 << 10 | 21 << 15 | 22 << 20 | 23 << 25 ), + [3] = ( 24| 25 << 5 | 26 << 10 | 27 << 15 | 28 << 20 | 29 << 25 ), + [4] = ( 30| 12 << 5 | 13 << 10 | 14<< 15 | 0 << 20 | 0 << 25 ), + }, + .ddr_lpddr34_ca_remap = {00,00}, + .ddr_lpddr34_dq_remap = {00,00}, + .dram_rtt_nom_wr_park = {00,00}, + .pll_ssc_mode = (1<<20) | (1<<8) | (2<<4) | 0,//center_ssc_1000ppm + .ddr_func = DDR_FUNC, + .magic = DRAM_CFG_MAGIC, +}, +{ + // lpddr3 + .board_id = CONFIG_BOARD_ID_MASK, + .version = 1, + //.dram_rank_config = CONFIG_DDR0_32BIT_RANK01_CH0, + .dram_rank_config = CONFIG_DDR0_32BIT_RANK01_CH0, + .ddr_rfc_type = DDR_RFC_TYPE_LPDDR4_4Gbx1, + .DramType = CONFIG_DDR_TYPE_LPDDR3, + .DRAMFreq = {600, 0, 0, 0}, + .ddr_base_addr = CFG_DDR_BASE_ADDR, + .ddr_start_offset = CFG_DDR_START_OFFSET, + .DisabledDbyte = 0xf0, + .Is2Ttiming = 0, + .HdtCtrl = 0xa,//0xa, + .dram_cs0_size_MB = 1024,//1024, + .dram_cs1_size_MB = 1024,//1024, + .training_SequenceCtrl = {0x131f,0}, //ddr3 0x21f 0x31f + .phy_odt_config_rank = {0x30,0x30,0x30,0x30}, // // Odt pattern for accesses //targeting rank 0. [3:0] is used //for write ODT [7:4] is used for //read ODT + .dfi_odt_config = 0x00c, + .PllBypassEn = 0, //bit0-ps0,bit1-ps1 + .ddr_rdbi_wr_enable = 0, + .pll_ssc_mode = (1<<20) | (1<<8) | (2<<4) | 0,//center_ssc_1000ppm + .clk_drv_ohm = 40, + .cs_drv_ohm = 40, + .ac_drv_ohm = 40, + .soc_data_drv_ohm_p = 40, + .soc_data_drv_ohm_n = 40, + .soc_data_odt_ohm_p = 60, + .soc_data_odt_ohm_n = 0, + .dram_data_drv_ohm = 30, // + .dram_data_odt_ohm = 120, + .dram_ac_odt_ohm = 0, + .soc_clk_slew_rate = 0x3ff,//0x253, + .soc_cs_slew_rate = 0x3ff,//0x253, + .soc_ac_slew_rate = 0x3ff,//0x253, + .soc_data_slew_rate = 0x2ff, + .vref_output_permil = 800,//200, + .vref_receiver_permil = 700,//875, //700 for drv 40 odt 60 is better ,why? + .vref_dram_permil = 500,//875, + //.vref_reverse = 0, + .ac_trace_delay = {0x10,0x0,0x10-6,0x10-6,0x10-6,0x0,0x0,0x0,0x0,0x0}, + .ac_pinmux = {00,00}, + .ddr_dmc_remap = { + [0] = ( 5 | 6 << 5 | 7 << 10 | 8<< 15 | 9<< 20 | 10 << 25 ), + [1] = ( 11| 29 << 5 | 0 << 10 | 15 << 15 | 16 << 20 | 17 << 25 ), + [2] = ( 18| 19 << 5 | 20 << 10 | 21 << 15 | 22 << 20 | 23 << 25 ), + [3] = ( 24| 25 << 5 | 26 << 10 | 27 << 15 | 28 << 20 | 30 << 25 ), + [4] = ( 31| 12 << 5 | 13 << 10 | 14<< 15 | 0 << 20 | 0 << 25 ), + }, + .ddr_lpddr34_ca_remap = {21/8,8/8,31/8,1/8},// {2,7,1,4,5,6,0,3,9,8}, + .ddr_lpddr34_dq_remap = {1,2,7,4,0,3,5,6,8,12,14,9,11,10,15,13,21,22,16,17,23,20,19,18,31,29,26,27,30,28,25,24}, + //{21,22,16,17,23,20,19,18,8,12,14,9,11,10,15,13,31,29,26,27,30,28,25,24,1,2,7,4,0,3,5,6}, + .dram_rtt_nom_wr_park = {00,00}, + .ddr_func = DDR_FUNC, + .magic = DRAM_CFG_MAGIC, + .diagnose = CONFIG_DIAGNOSE_DISABLE, +}, +*/ +}; + +pll_set_t __pll_setting = { + .cpu_clk = CONFIG_CPU_CLK / 24 * 24, +#ifdef CONFIG_PXP_EMULATOR + .pxp = 1, +#else + .pxp = 0, +#endif + .spi_ctrl = 0, + .lCustomerID = CONFIG_AML_CUSTOMER_ID, +#ifdef CONFIG_DEBUG_MODE + .debug_mode = CONFIG_DEBUG_MODE, + .ddr_clk_debug = CONFIG_DDR_CLK_DEBUG, + .cpu_clk_debug = CONFIG_CPU_CLK_DEBUG, +#endif + +#ifdef CONFIG_AML_SUPPORT_TLV + .nCFGTAddr = AML_BL2_TMASTER_DDR_ADDR, +#endif + +}; + +ddr_reg_t __ddr_reg[] = { + /* demo, user defined override register */ + {0xaabbccdd, 0, 0, 0, 0, 0}, + {0x11223344, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0}, +}; + +#define VCCK_VAL CONFIG_VCCK_INIT_VOLTAGE +#define VDDEE_VAL CONFIG_VDDEE_INIT_VOLTAGE +/* VCCK PWM table */ +#if (VCCK_VAL == 800) + #define VCCK_VAL_REG 0x0018000A +#elif (VCCK_VAL == 810) + #define VCCK_VAL_REG 0x0017000B +#elif (VCCK_VAL == 820) + #define VCCK_VAL_REG 0x0016000C +#elif (VCCK_VAL == 830) + #define VCCK_VAL_REG 0x0015000D +#elif (VCCK_VAL == 840) + #define VCCK_VAL_REG 0x0014000E +#elif (VCCK_VAL == 850) + #define VCCK_VAL_REG 0x0013000F +#elif (VCCK_VAL == 860) + #define VCCK_VAL_REG 0x00120010 +#elif (VCCK_VAL == 870) + #define VCCK_VAL_REG 0x00110011 +#elif (VCCK_VAL == 880) + #define VCCK_VAL_REG 0x00100012 +#elif (VCCK_VAL == 890) + #define VCCK_VAL_REG 0x000F0013 +#elif (VCCK_VAL == 900) + #define VCCK_VAL_REG 0x000E0014 +#elif (VCCK_VAL == 910) + #define VCCK_VAL_REG 0x000D0015 +#elif (VCCK_VAL == 920) + #define VCCK_VAL_REG 0x000C0016 +#elif (VCCK_VAL == 930) + #define VCCK_VAL_REG 0x000B0017 +#elif (VCCK_VAL == 940) + #define VCCK_VAL_REG 0x000A0018 +#elif (VCCK_VAL == 950) + #define VCCK_VAL_REG 0x00090019 +#elif (VCCK_VAL == 960) + #define VCCK_VAL_REG 0x0008001A +#elif (VCCK_VAL == 970) + #define VCCK_VAL_REG 0x0007001B +#elif (VCCK_VAL == 980) + #define VCCK_VAL_REG 0x0006001C +#elif (VCCK_VAL == 990) + #define VCCK_VAL_REG 0x0005001D +#elif (VCCK_VAL == 1000) + #define VCCK_VAL_REG 0x0004001E +#elif (VCCK_VAL == 1010) + #define VCCK_VAL_REG 0x0003001F +#else + #error "VCCK val out of range\n" +#endif + +/* VDDEE PWM table */ +#if (VDDEE_VAL == 740) + #define VDDEE_VAL_REG 0x00120000 +#elif (VDDEE_VAL == 750) + #define VDDEE_VAL_REG 0x00110001 +#elif (VDDEE_VAL == 760) + #define VDDEE_VAL_REG 0x00100002 +#elif (VDDEE_VAL == 770) + #define VDDEE_VAL_REG 0x000f0003 +#elif (VDDEE_VAL == 780) + #define VDDEE_VAL_REG 0x000e0004 +#elif (VDDEE_VAL == 790) + #define VDDEE_VAL_REG 0x000d0005 +#elif (VDDEE_VAL == 800) + #define VDDEE_VAL_REG 0x000c0006 +#elif (VDDEE_VAL == 810) + #define VDDEE_VAL_REG 0x000b0007 +#elif (VDDEE_VAL == 820) + #define VDDEE_VAL_REG 0x000a0008 +#elif (VDDEE_VAL == 830) + #define VDDEE_VAL_REG 0x00090009 +#elif (VDDEE_VAL == 840) + #define VDDEE_VAL_REG 0x0008000a +#elif (VDDEE_VAL == 850) + #define VDDEE_VAL_REG 0x0007000b +#elif (VDDEE_VAL == 860) + #define VDDEE_VAL_REG 0x0006000c +#elif (VDDEE_VAL == 870) + #define VDDEE_VAL_REG 0x0005000d +#elif (VDDEE_VAL == 880) + #define VDDEE_VAL_REG 0x0004000e +#elif (VDDEE_VAL == 890) + #define VDDEE_VAL_REG 0x0003000f +#elif (VDDEE_VAL == 900) + #define VDDEE_VAL_REG 0x00020010 +#elif (VDDEE_VAL == 910) + #define VDDEE_VAL_REG 0x00010011 +#elif (VDDEE_VAL == 920) + #define VDDEE_VAL_REG 0x00000012 +#else + #error "VDDEE val out of range\n" +#endif + +/* for PWM use */ +/* PWM driver check http://scgit.amlogic.com:8080/#/c/38093/ */ +#define GPIO_O_EN_N_REG3 ((0xff634400 + (0x19 << 2))) +#define GPIO_O_REG3 ((0xff634400 + (0x1a << 2))) +#define GPIO_I_REG3 ((0xff634400 + (0x1b << 2))) +#define AO_PIN_MUX_REG0 ((0xff800000 + (0x05 << 2))) +#define AO_PIN_MUX_REG1 ((0xff800000 + (0x06 << 2))) + +bl2_reg_t __bl2_reg[] = { + /* demo, user defined override register */ + /* eg: PWM init */ + + /* PWM_AO_D */ + /* VCCK_VAL_REG: check PWM table */ + {AO_PWM_PWM_D, VCCK_VAL_REG, 0xffffffff, 0, BL2_INIT_STAGE_1, 0}, + {AO_PWM_MISC_REG_CD, ((1 << 23) | (1 << 1)), (0x7f << 16), 0, BL2_INIT_STAGE_1, 0}, + {AO_PIN_MUX_REG1, (3 << 20), (0xF << 20), 0, BL2_INIT_STAGE_1, 0}, + /* PWM_AO_B */ + /* VDDEE_VAL_REG: check PWM table */ + {AO_PWM_PWM_B, VDDEE_VAL_REG, 0xffffffff, 0, BL2_INIT_STAGE_1, 0}, + {AO_PWM_MISC_REG_AB, ((1 << 23) | (1 << 1)), (0x7f << 16), 0, BL2_INIT_STAGE_1, 0}, + {AO_PIN_MUX_REG1, (3 << 16), (0xF << 16), 0, BL2_INIT_STAGE_1, 0}, + /* Enable 5V_EN ,set gpioao_3 low --> several millisecond--set high in board_init*/ + {AO_GPIO_O_EN_N, (0 << 3), (1 << 3), 0, BL2_INIT_STAGE_1, 0}, + {AO_GPIO_O, (0 << 3), (1 << 3), 0, BL2_INIT_STAGE_1, 0}, + /* Enable VCCK GPIOAO_2*/ + {AO_GPIO_O_EN_N, (0 << 2), (1 << 2), 0, BL2_INIT_STAGE_1, 0}, + {AO_GPIO_O, (1 << 2), (1 << 2), 0, BL2_INIT_STAGE_1, 0}, +}; diff --git a/board/amlogic/tm2_ab301_v1/lcd.c b/board/amlogic/tm2_ab301_v1/lcd.c new file mode 100644 index 0000000000..c40d6bb692 --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/lcd.c @@ -0,0 +1,615 @@ +/* + * AMLOGIC LCD panel driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the named License, + * or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <common.h> +#include <amlogic/aml_lcd.h> +#ifdef CONFIG_AML_LOCAL_DIMMING +#include <amlogic/aml_ldim.h> +#endif + +static char lcd_cpu_gpio[LCD_CPU_GPIO_NUM_MAX][LCD_CPU_GPIO_NAME_MAX] = { + "GPIOAO_4", + "invalid", /* ending flag */ +}; + +static struct lcd_power_step_s lcd_power_on_step[] = { + {LCD_POWER_TYPE_CPU, 0,1,20,}, /* panel vcc */ + {LCD_POWER_TYPE_SIGNAL,0,0,0,}, + {LCD_POWER_TYPE_MAX, 0,0,0,}, /* ending flag */ +}; +static struct lcd_power_step_s lcd_power_off_step[] = { + {LCD_POWER_TYPE_SIGNAL,0,0,0,}, + {LCD_POWER_TYPE_CPU, 0,0,200,}, /* panel vcc */ + {LCD_POWER_TYPE_MAX, 0,0,0,}, /* ending flag */ +}; + +static struct lcd_power_step_s lcd_power_on_step_p2p[] = { + {LCD_POWER_TYPE_CPU, 0,1,20,}, /* panel vcc */ + {LCD_POWER_TYPE_EXTERN,0,0,100,}, /* init external voltage */ + {LCD_POWER_TYPE_SIGNAL,0,0,0,}, + {LCD_POWER_TYPE_MAX, 0,0,0,}, /* ending flag */ +}; +static struct lcd_power_step_s lcd_power_off_step_p2p[] = { + {LCD_POWER_TYPE_SIGNAL,0,0,0,}, + {LCD_POWER_TYPE_CPU, 0,0,200,}, /* panel vcc */ + {LCD_POWER_TYPE_MAX, 0,0,0,}, /* ending flag */ +}; + +static char lcd_bl_gpio[BL_GPIO_NUM_MAX][LCD_CPU_GPIO_NAME_MAX] = { + "GPIOAO_11", + "GPIOZ_5", + "GPIOZ_6", + "invalid", /* ending flag */ +}; + +#ifdef CONFIG_AML_LOCAL_DIMMING +static char lcd_bl_ldim_gpio[BL_GPIO_NUM_MAX][LCD_CPU_GPIO_NAME_MAX] = { + "GPIOH_10", /* LD_EN */ + "GPIOZ_5", /* DIMMING_PWM */ + "GPIOZ_6", /* LD_EN2 */ + "invalid", /* ending flag */ +}; +#endif + +struct ext_lcd_config_s ext_lcd_config[LCD_NUM_MAX] = { + {/* normal*/ + "lvds_0",LCD_LVDS,8, + /* basic timing */ + 1920,1080,2200,1125,44,148,0,5,36,0, + /* clk_attr */ + 0,0,1,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + /* lvds_attr */ + 1,1,0,0,0,0xf,0x0,Rsv_val,Rsv_val,Rsv_val, + /* power step */ + lcd_power_on_step, lcd_power_off_step, + /* backlight */ + 60,255,10,128,128, + BL_CTRL_PWM,0,1,0,200,200, + BL_PWM_POSITIVE,BL_PWM_C,180,100,25,1,0, + Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + Rsv_val,Rsv_val,Rsv_val,Rsv_val, + 10,10,Rsv_val}, + + {/* for HDMI convert*/ + "lvds_1",LCD_LVDS,8, + /* basic timing */ + 1920,1080,2200,1125,44,148,0,5,36,0, + /* clk_attr */ + 1,0,1,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + /* lvds_attr */ + 1,1,0,0,0,0xf,0x0,Rsv_val,Rsv_val,Rsv_val, + /* power step */ + lcd_power_on_step, lcd_power_off_step, + /* backlight */ + 60,255,10,128,128, + BL_CTRL_MAX,0,1,0,200,200, + BL_PWM_POSITIVE,BL_PWM_C,180,100,25,1,0, + Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + Rsv_val,Rsv_val,Rsv_val,Rsv_val, + 10,10,Rsv_val}, + + {/*public 2-region vx1 : 3840x2160@60hz 8lane */ + "vbyone_0",LCD_VBYONE,10, + /* basic timing */ + 3840,2160,4400,2250,33,477,0,6,81,0, + /* clk_attr */ + 2,0,1,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + /* vbyone_attr */ + 8,2,4,4,0xf,0x1,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + /* power step */ + lcd_power_on_step, lcd_power_off_step, + /* backlight */ + 60,255,10,128,128, + BL_CTRL_PWM,0,1,0,200,200, + BL_PWM_POSITIVE,BL_PWM_C,180,100,25,1,0, + Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + Rsv_val,Rsv_val,Rsv_val,Rsv_val, + 10,10,Rsv_val}, + + {/*public 1-region vx1 : 3840x2160@60hz 8lane */ + "vbyone_1",LCD_VBYONE,10, + /* basic timing */ + 3840,2160,4400,2250,33,477,0,6,81,0, + /* clk_attr */ + 2,0,1,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + /* vbyone_attr */ + 8,1,4,4,0xf,0x1,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + /* power step */ + lcd_power_on_step, lcd_power_off_step, + /* backlight */ + 60,255,10,128,128, + BL_CTRL_PWM,0,1,0,200,200, + BL_PWM_POSITIVE,BL_PWM_C,180,100,25,1,0, + Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + Rsv_val,Rsv_val,Rsv_val,Rsv_val, + 10,10,Rsv_val}, + + {/*public p2p ceds : 3840x2160@60hz 12lane */ + "p2p_0",LCD_P2P,8, + /* basic timing */ + 3840,2160,5000,2250,16,29,0,6,81,0, + /* clk_attr */ + 2,0,1,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + /* p2p attr */ + 0x0,12,0x76543210,0xba98,0,0,0xf,0x1,Rsv_val,Rsv_val, + /* power step */ + lcd_power_on_step_p2p, lcd_power_off_step_p2p, + /* backlight */ + 60,255,10,128,128, + BL_CTRL_MAX,0,1,0,200,200, + BL_PWM_POSITIVE,BL_PWM_C,180,100,25,1,0, + Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + Rsv_val,Rsv_val,Rsv_val,Rsv_val, + 10,10,Rsv_val}, + + {/*public p2p ceds : 3840x2160@60hz 6lane */ + "p2p_1",LCD_P2P,8, + /* basic timing */ + 3840,2160,5000,2250,16,29,0,6,81,0, + /* clk_attr */ + 2,0,1,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + /* p2p attr */ + 0x0,6,0x76543210,0xba98,0,0,0xf,0x1,Rsv_val,Rsv_val, + /* power step */ + lcd_power_on_step_p2p, lcd_power_off_step_p2p, + /* backlight */ + 60,255,10,128,128, + BL_CTRL_MAX,0,1,0,200,200, + BL_PWM_POSITIVE,BL_PWM_C,180,100,25,1,0, + Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + Rsv_val,Rsv_val,Rsv_val,Rsv_val, + 10,10,Rsv_val}, + + {/*public p2p chpi : 3840x2160@60hz 6lane */ + "p2p_2",LCD_P2P,8, + /* basic timing */ + 3840,2160,4400,2250,16,29,0,6,81,0, + /* clk_attr */ + 2,0,1,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + /* p2p attr */ + 0x10,6,0x76543210,0xba98,0,0,0xf,0x1,Rsv_val,Rsv_val, + /* power step */ + lcd_power_on_step_p2p, lcd_power_off_step_p2p, + /* backlight */ + 60,255,10,128,128, + BL_CTRL_MAX,0,1,0,200,200, + BL_PWM_POSITIVE,BL_PWM_C,180,100,25,1,0, + Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + Rsv_val,Rsv_val,Rsv_val,Rsv_val, + 10,10,Rsv_val}, + + {/*public p2p chpi : 3840x2160@60hz 12lane */ + "p2p_3",LCD_P2P,8, + /* basic timing */ + 3840,2160,4400,2250,16,29,0,6,81,0, + /* clk_attr */ + 2,0,1,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + /* p2p attr */ + 0x10,12,0x76543210,0xba98,0,0,0xf,0x1,Rsv_val,Rsv_val, + /* power step */ + lcd_power_on_step_p2p, lcd_power_off_step_p2p, + /* backlight */ + 60,255,10,128,128, + BL_CTRL_MAX,0,1,0,200,200, + BL_PWM_POSITIVE,BL_PWM_C,180,100,25,1,0, + Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + Rsv_val,Rsv_val,Rsv_val,Rsv_val, + 10,10,Rsv_val}, + + {/* 1920*1080*/ + "mlvds_0",LCD_MLVDS,8, + /* basic timing */ + 1920,1080,2200,1125,44,148,0,5,36,0, + /* clk_attr */ + 2,0,1,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + /* minilvds_attr */ + 6,0x76543210,0xba98,0x660,0,0,0xf,0x0,Rsv_val,Rsv_val, + /* power step */ + lcd_power_on_step, lcd_power_off_step, + /* backlight */ + 60,255,10,128,128, + BL_CTRL_MAX,0,1,0,200,200, + BL_PWM_POSITIVE,BL_PWM_C,180,100,25,1,0, + Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + Rsv_val,Rsv_val,Rsv_val,Rsv_val, + 10,10,Rsv_val}, + + {/* 1366*768*/ + "mlvds_1",LCD_MLVDS,8, + /* basic timing */ + 1366,768,1560,806,56,64,0,3,28,0, + /* clk_attr */ + 2,0,1,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + /* minilvds_attr */ + 6,0x76543210,0xba98,0x660,0,0,0xf,0x0,Rsv_val,Rsv_val, + /* power step */ + lcd_power_on_step, lcd_power_off_step, + /* backlight */ + 60,255,10,128,128, + BL_CTRL_MAX,0,1,0,200,200, + BL_PWM_POSITIVE,BL_PWM_C,180,100,25,1,0, + Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val,Rsv_val, + Rsv_val,Rsv_val,Rsv_val,Rsv_val, + 10,10,Rsv_val}, + + {.panel_type = "invalid"}, +}; + +static struct lcd_pinmux_ctrl_s lcd_pinmux_ctrl[LCD_PINMX_MAX] = { + { + .name = "lcd_vbyone_pin", //GPIOH_15/16 + .pinmux_set = {{8, 0x30000000}, {9, 0x00000003}, {LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{8, 0xf0000000}, {9, 0x0000000f}, {LCD_PINMUX_END, 0x0}}, + }, + { + .name = "lcd_minilvds_pin", //GPIOH_0~15 + .pinmux_set = {{7, 0x11111111}, {8, 0x11111111}, {LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{7, 0xffffffff}, {8, 0xffffffff}, {LCD_PINMUX_END, 0x0}}, + }, + { + .name = "lcd_p2p_pin", //GPIOH_0~19 + .pinmux_set = {{7, 0x11111111}, {8, 0x11111111}, {9, 0x11111}, {LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{7, 0xffffffff}, {8, 0xffffffff}, {9, 0xfffff}, {LCD_PINMUX_END, 0x0}}, + }, + { + .name = "invalid", + }, +}; + +static struct lcd_pinmux_ctrl_s bl_pinmux_ctrl[BL_PINMUX_MAX] = { + { + .name = "bl_pwm_on_pin", //GPIOZ_5 + .pinmux_set = {{2, 0x00400000}, {LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{2, 0x00f00000}, {LCD_PINMUX_END, 0x0}}, + }, + { + .name = "bl_pwm_vs_on_pin", //GPIOZ_5 + .pinmux_set = {{2, 0x00300000}, {LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{2, 0x00f00000}, {LCD_PINMUX_END, 0x0}}, + }, + { + .name = "bl_pwm_combo_0_on_pin", //GPIOZ_5 + .pinmux_set = {{2, 0x00400000}, {LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{2, 0x00f00000}, {LCD_PINMUX_END, 0x0}}, + }, + { + .name = "bl_pwm_combo_1_on_pin", //GPIOZ_6 + .pinmux_set = {{2, 0x04000000}, {LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{2, 0x0f000000}, {LCD_PINMUX_END, 0x0}}, + }, + { + .name = "bl_pwm_combo_0_vs_on_pin", //GPIOZ_5 + .pinmux_set = {{2, 0x00300000}, {LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{2, 0x00f00000}, {LCD_PINMUX_END, 0x0}}, + }, + { + .name = "bl_pwm_combo_1_vs_on_pin", //GPIOZ_6 + .pinmux_set = {{2, 0x03000000}, {LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{2, 0x0f000000}, {LCD_PINMUX_END, 0x0}}, + }, + { + .name = "invalid", + }, +}; + +#ifdef CONFIG_AML_LOCAL_DIMMING +static struct lcd_pinmux_ctrl_s ldim_pinmux_ctrl[] = { + { + .name = "ldim_pwm_pin", //GPIOZ_5 + .pinmux_set = {{2, 0x00400000}, {LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{2, 0x00f00000}, {LCD_PINMUX_END, 0x0}}, + }, + { + .name = "ldim_pwm_vs_pin", //GPIOZ_5 + .pinmux_set = {{2, 0x00300000}, {LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{2, 0x00f00000}, {LCD_PINMUX_END, 0x0}}, + }, + { + .name = "analog_pwm_pin", //GPIOZ_6 + .pinmux_set = {{2, 0x04000000}, {LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{2, 0x0f000000}, {LCD_PINMUX_END, 0x0}}, + }, + { + .name = "invalid", + .pinmux_set = {{LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{LCD_PINMUX_END, 0x0}}, + }, +}; +#endif + +static struct vbyone_config_s lcd_vbyone_config = { + .lane_count = 8, + .byte_mode = 4, + .region_num = 2, + .color_fmt = 4, +}; + +static struct lvds_config_s lcd_lvds_config = { + .lvds_repack = 1, //0=JEDIA mode, 1=VESA mode + .dual_port = 1, //0=single port, 1=double port + .pn_swap = 0, //0=normal, 1=swap + .port_swap = 0, //0=normal, 1=swap + .lane_reverse = 0, //0=normal, 1=swap +}; + +static struct mlvds_config_s lcd_mlvds_config = { + .channel_num = 6, + .channel_sel0 = 0x45603012, + .channel_sel1 = 0x0, + .clk_phase = 0x0, + .pn_swap = 0, //0=normal, 1=swap + .bit_swap = 0, //0=normal, 1=swap +}; + +static struct p2p_config_s lcd_p2p_config = { + .p2p_type = 0, + .lane_num = 12, + .channel_sel0 = 0x76543210, + .channel_sel1 = 0xba98, + .pn_swap = 0, //0=normal, 1=swap + .bit_swap = 0, //0=normal, 1=swap +}; + +static struct lcd_power_ctrl_s lcd_power_ctrl = { + .power_on_step = { + { + .type = LCD_POWER_TYPE_MAX, /* ending flag */ + }, + }, + .power_off_step = { + { + .type = LCD_POWER_TYPE_MAX, /* ending flag */ + }, + }, +}; + +struct lcd_config_s lcd_config_dft = { + .lcd_mode = LCD_MODE_TV, + .lcd_key_valid = 0, + .lcd_basic = { + .model_name = "default", + .lcd_type = LCD_TYPE_MAX, + .lcd_bits = 8, + .h_active = 1920, + .v_active = 1080, + .h_period = 2200, + .v_period = 1125, + + .screen_width = 16, + .screen_height = 9, + }, + + .lcd_timing = { + .clk_auto = 1, + .lcd_clk = 60, + .ss_level = 0, + .fr_adjust_type = 0, + + .hsync_width = 44, + .hsync_bp = 148, + .hsync_pol = 0, + .vsync_width = 5, + .vsync_bp = 36, + .vsync_pol = 0, + }, + + .lcd_control = { + .lvds_config = &lcd_lvds_config, + .vbyone_config = &lcd_vbyone_config, + .mlvds_config = &lcd_mlvds_config, + .p2p_config = &lcd_p2p_config, + }, + .lcd_power = &lcd_power_ctrl, + + .pinctrl_ver = 2, + .lcd_pinmux = lcd_pinmux_ctrl, + .pinmux_set = {{LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{LCD_PINMUX_END, 0x0}}, +}; + +#ifdef CONFIG_AML_LCD_EXTERN +static char lcd_ext_gpio[LCD_EXTERN_GPIO_NUM_MAX][LCD_EXTERN_GPIO_LEN_MAX] = { + "invalid", /* ending flag */ +}; + +static unsigned char init_on_table[LCD_EXTERN_INIT_ON_MAX] = { + 0xc0, 2, 0x01, 0x2b, + 0xc0, 2, 0x02, 0x05, + 0xc0, 2, 0x03, 0x00, + 0xc0, 2, 0x04, 0x00, + 0xc0, 2, 0x05, 0x0c, + 0xc0, 2, 0x06, 0x04, + 0xc0, 2, 0x07, 0x21, + 0xc0, 2, 0x08, 0x0f, + 0xc0, 2, 0x09, 0x04, + 0xc0, 2, 0x0a, 0x00, + 0xc0, 2, 0x0b, 0x04, + 0xc0, 2, 0xff, 0x00, + 0xfd, 1, 100 /* delay 100ms */ + + 0xc1, 2, 0x01, 0xca, + 0xc1, 2, 0x02, 0x3b, + 0xc1, 2, 0x03, 0x33, + 0xc1, 2, 0x04, 0x05, + 0xc1, 2, 0x05, 0x2c, + 0xc1, 2, 0x06, 0xf2, + 0xc1, 2, 0x07, 0x9c, + 0xc1, 2, 0x08, 0x1b, + 0xc1, 2, 0x09, 0x82, + 0xc1, 2, 0x0a, 0x3d, + 0xc1, 2, 0x0b, 0x20, + 0xc1, 2, 0x0c, 0x11, + 0xc1, 2, 0x0d, 0xc4, + 0xc1, 2, 0x0e, 0x1a, + 0xc1, 2, 0x0f, 0x31, + 0xc1, 2, 0x10, 0x4c, + 0xc1, 2, 0x11, 0x12, + 0xc1, 2, 0x12, 0x90, + 0xc1, 2, 0x13, 0xf7, + 0xc1, 2, 0x14, 0x0c, + 0xc1, 2, 0x15, 0x20, + 0xc1, 2, 0x16, 0x13, + 0xff, 0, /* ending */ +}; + +static unsigned char init_off_table[LCD_EXTERN_INIT_OFF_MAX] = { + 0xff, 0, /* ending */ +}; + +struct lcd_extern_common_s ext_common_dft = { + .lcd_ext_key_valid = 0, + .lcd_ext_num = 1, + .pinmux_set = {{LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{LCD_PINMUX_END, 0x0}}, +}; +struct lcd_extern_config_s ext_config_dtf[LCD_EXTERN_NUM_MAX] = { + { + .index = 0, + .name = "i2c_ANX6862_7911", + .type = LCD_EXTERN_I2C, /* LCD_EXTERN_I2C, LCD_EXTERN_SPI, LCD_EXTERN_MAX */ + .status = 1, /* 0=disable, 1=enable */ + .i2c_addr = 0x20, /* 7bit i2c address */ + .i2c_addr2 = 0x74, /* 7bit i2c address, 0xff for none */ + .i2c_bus = LCD_EXTERN_I2C_BUS_1, /* LCD_EXTERN_I2C_BUS_0/1/2/3/4 */ + .cmd_size = 0xff, + .table_init_on = init_on_table, + .table_init_off = init_off_table, + }, + { + .index = LCD_EXTERN_INDEX_INVALID, + }, +}; +#endif + +struct bl_config_s bl_config_dft = { + .name = "default", + .bl_key_valid = 0, + + .level_default = 100, + .level_min = 10, + .level_max = 255, + .level_mid = 128, + .level_mid_mapping = 128, + .level = 0, + + .method = BL_CTRL_MAX, + .power_on_delay = 200, + .power_off_delay = 200, + + .en_gpio = 0xff, + .en_gpio_on = 1, + .en_gpio_off = 0, + + .bl_pwm = NULL, + .bl_pwm_combo0 = NULL, + .bl_pwm_combo1 = NULL, + .pwm_on_delay = 10, + .pwm_off_delay = 10, + + .bl_extern_index = 0xff, + + .pinctrl_ver = 2, + .bl_pinmux = bl_pinmux_ctrl, + .pinmux_set = {{LCD_PINMUX_END, 0x0}}, + .pinmux_clr = {{LCD_PINMUX_END, 0x0}}, +}; + +#ifdef CONFIG_AML_LOCAL_DIMMING +static unsigned char ldim_init_on[LDIM_INIT_ON_MAX]; +static unsigned char ldim_init_off[LDIM_INIT_OFF_MAX]; +struct ldim_dev_config_s ldim_config_dft = { + .type = LDIM_DEV_TYPE_NORMAL, + .cs_hold_delay = 0, + .cs_clk_delay = 0, + .en_gpio = 0xff, + .en_gpio_on = 1, + .en_gpio_off = 0, + .lamp_err_gpio = 0xff, + .fault_check = 0, + .write_check = 0, + .dim_min = 0x7f, /* min 3% duty */ + .dim_max = 0xfff, + .init_loaded = 0, + .cmd_size = 0xff, + .init_on = ldim_init_on, + .init_off = ldim_init_off, + .init_on_cnt = sizeof(ldim_init_on), + .init_off_cnt = sizeof(ldim_init_off), + .ldim_pwm_config = { + .index = 0, + .pwm_method = BL_PWM_POSITIVE, + .pwm_port = BL_PWM_MAX, + .pwm_duty_max = 100, + .pwm_duty_min = 0, + }, + .analog_pwm_config = { + .index = 1, + .pwm_method = BL_PWM_POSITIVE, + .pwm_port = BL_PWM_MAX, + .pwm_duty_max = 100, + .pwm_duty_min = 20, + }, + .pinctrl_ver = 1, + .ldim_pinmux = ldim_pinmux_ctrl, +}; +#endif + +void lcd_config_bsp_init(void) +{ + int i, j; + + for (i = 0; i < LCD_CPU_GPIO_NUM_MAX; i++) { + if (strcmp(lcd_cpu_gpio[i], "invalid") == 0) + break; + strcpy(lcd_power_ctrl.cpu_gpio[i], lcd_cpu_gpio[i]); + } + for (j = i; j < LCD_CPU_GPIO_NUM_MAX; j++) + strcpy(lcd_power_ctrl.cpu_gpio[j], "invalid"); + for (i = 0; i < BL_GPIO_NUM_MAX; i++) { + if (strcmp(lcd_bl_gpio[i], "invalid") == 0) + break; + strcpy(bl_config_dft.gpio_name[i], lcd_bl_gpio[i]); + } + for (j = i; j < BL_GPIO_NUM_MAX; j++) + strcpy(bl_config_dft.gpio_name[j], "invalid"); + +#ifdef CONFIG_AML_LCD_EXTERN + for (i = 0; i < LCD_EXTERN_NUM_MAX; i++) { + if (ext_config_dtf[i].index == LCD_EXTERN_INDEX_INVALID) + break; + } + ext_common_dft.lcd_ext_num = i; + + for (i = 0; i < LCD_EXTERN_GPIO_NUM_MAX; i++) { + if (strcmp(lcd_ext_gpio[i], "invalid") == 0) + break; + strcpy(ext_common_dft.gpio_name[i], lcd_ext_gpio[i]); + } + for (j = i; j < LCD_EXTERN_GPIO_NUM_MAX; j++) + strcpy(ext_common_dft.gpio_name[j], "invalid"); + +#endif +#ifdef CONFIG_AML_LOCAL_DIMMING + strcpy(ldim_config_dft.name, "invalid"); + strcpy(ldim_config_dft.pinmux_name, "invalid"); + for (i = 0; i < BL_GPIO_NUM_MAX; i++) { + if (strcmp(lcd_bl_ldim_gpio[i], "invalid") == 0) + break; + strcpy(ldim_config_dft.gpio_name[i], lcd_bl_ldim_gpio[i]); + } + for (j = i; j < BL_GPIO_NUM_MAX; j++) + strcpy(ldim_config_dft.gpio_name[j], "invalid"); +#endif +} diff --git a/board/amlogic/tm2_ab301_v1/mtk-bt/LD_btmtk_usb.c b/board/amlogic/tm2_ab301_v1/mtk-bt/LD_btmtk_usb.c new file mode 100644 index 0000000000..a67d229749 --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/mtk-bt/LD_btmtk_usb.c @@ -0,0 +1,1532 @@ +/* +* Copyright (c) 2014 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +/** steve wang 2015/11/26 */ +//--------------------------------------------------------------------------- +#include "LD_usbbt.h" +#include "LD_btmtk_usb.h" +#include "errno.h" + +//- Local Configuration ----------------------------------------------------- +#define LD_VERSION "1.2.0.1" + +#define BUFFER_SIZE (1024 * 4) /* Size of RX Queue */ +#define BT_SEND_HCI_CMD_BEFORE_SUSPEND 1 +#define LD_SUPPORT_FW_DUMP 0 +#define LD_BT_ALLOC_BUF 0 +#define LD_NOT_FIX_BUILD_WARN 0 + +#define FIDX 0x5A /* Unify WoBLE APCF Filtering Index */ + +#ifndef strtol +#define strtol simple_strtol +#endif + +//--------------------------------------------------------------------------- +static char driver_version[64] = { 0 }; +static unsigned char probe_counter = 0; +static volatile int metaMode; +static volatile int metaCount; +/* 0: False; 1: True */ +static int isbtready; +static int isUsbDisconnet; +static volatile int is_assert = 0; + +//--------------------------------------------------------------------------- +static inline int is_mt7630(struct LD_btmtk_usb_data *data) +{ + return ((data->chip_id & 0xffff0000) == 0x76300000); +} + +//--------------------------------------------------------------------------- +static inline int is_mt7650(struct LD_btmtk_usb_data *data) +{ + return ((data->chip_id & 0xffff0000) == 0x76500000); +} + +//--------------------------------------------------------------------------- +static inline int is_mt7632(struct LD_btmtk_usb_data *data) +{ + return ((data->chip_id & 0xffff0000) == 0x76320000); +} + +//--------------------------------------------------------------------------- +static inline int is_mt7662(struct LD_btmtk_usb_data *data) +{ + return ((data->chip_id & 0xffff0000) == 0x76620000); +} + +//--------------------------------------------------------------------------- +static inline int is_mt7662T(struct LD_btmtk_usb_data *data) +{ + return ((data->chip_id & 0xffffffff) == 0x76620100); +} + +//--------------------------------------------------------------------------- +static inline int is_mt7632T(struct LD_btmtk_usb_data *data) +{ + return ((data->chip_id & 0xffffffff) == 0x76320100); +} + +//--------------------------------------------------------------------------- +static inline int is_mt7668(struct LD_btmtk_usb_data *data) +{ + return ((data->chip_id & 0xffff) == 0x7668); +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_io_read32(struct LD_btmtk_usb_data *data, u32 reg, u32 *val) +{ + u8 request = data->r_request; + int ret; + + ret = data->hcif->usb_control_msg(data->udev, MTKBT_CTRL_RX_EP, request, + DEVICE_VENDOR_REQUEST_IN, 0, (u16)reg, data->io_buf, sizeof(u32), + CONTROL_TIMEOUT_JIFFIES); + + if (ret < 0) + { + *val = 0xffffffff; + usb_debug("error(%d), reg=%x, value=%x\n", ret, reg, *val); + return ret; + } + + os_memmove(val, data->io_buf, sizeof(u32)); + *val = le32_to_cpu(*val); + return 0; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_io_read32_7668(struct LD_btmtk_usb_data *data, u32 reg, u32 *val) +{ + int ret = -1; + __le16 reg_high; + __le16 reg_low; + + reg_high = ((reg >> 16) & 0xFFFF); + reg_low = (reg & 0xFFFF); + + ret = data->hcif->usb_control_msg(data->udev, MTKBT_CTRL_RX_EP, 0x63, + DEVICE_VENDOR_REQUEST_IN, reg_high, reg_low, data->io_buf, sizeof(u32), + CONTROL_TIMEOUT_JIFFIES); + if (ret < 0) { + *val = 0xFFFFFFFF; + usb_debug("error(%d), reg=%X, value=%X\n", ret, reg, *val); + return ret; + } + + os_memmove(val, data->io_buf, sizeof(u32)); + *val = le32_to_cpu(*val); + return 0; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_io_write32(struct LD_btmtk_usb_data *data, u32 reg, u32 val) +{ + u16 value, index; + u8 request = data->w_request; + mtkbt_dev_t *udev = data->udev; + int ret; + + index = (u16) reg; + value = val & 0x0000ffff; + + ret = data->hcif->usb_control_msg(udev, MTKBT_CTRL_TX_EP, request, DEVICE_VENDOR_REQUEST_OUT, + value, index, NULL, 0, CONTROL_TIMEOUT_JIFFIES); + + if (ret < 0) + { + usb_debug("error(%d), reg=%x, value=%x\n", ret, reg, val); + return ret; + } + + index = (u16) (reg + 2); + value = (val & 0xffff0000) >> 16; + + ret = data->hcif->usb_control_msg(udev, MTKBT_CTRL_TX_EP, request, DEVICE_VENDOR_REQUEST_OUT, + value, index, NULL, 0, CONTROL_TIMEOUT_JIFFIES); + + if (ret < 0) + { + usb_debug("error(%d), reg=%x, value=%x\n", ret, reg, val); + return ret; + } + if (ret > 0) + { + ret = 0; + } + return ret; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_send_wmt_cmd(struct LD_btmtk_usb_data *data, const u8 *cmd, + const int cmd_len, const u8 *event, const int event_len, u32 delay, u8 retry) +{ + int ret = -1; + BOOL check = FALSE; + + if (!data || !data->hcif || !data->io_buf || !cmd) { + usb_debug("incorrect cmd pointer\n"); + return -1; + } + if (event != NULL && event_len > 0) + check = TRUE; + + /* send WMT command */ + ret = data->hcif->usb_control_msg(data->udev, MTKBT_CTRL_TX_EP, 0x01, + DEVICE_CLASS_REQUEST_OUT, 0x30, 0x00, (void *)cmd, cmd_len, + CONTROL_TIMEOUT_JIFFIES); + if (ret < 0) { + usb_debug("command send failed(%d)\n", ret); + return ret; + } + + if (event_len == -1) { + /* If event_len is -1, DO NOT read event, since FW wouldn't feedback */ + return 0; + } + +retry_get: + MTK_MDELAY(delay); + + /* check WMT event */ + ret = data->hcif->usb_control_msg(data->udev, MTKBT_CTRL_RX_EP, 0x01, + DEVICE_VENDOR_REQUEST_IN, 0x30, 0x00, data->io_buf, LD_BT_MAX_EVENT_SIZE, + CONTROL_TIMEOUT_JIFFIES); + if (ret < 0) { + usb_debug("event get failed(%d)\n", ret); + if (check == TRUE) return ret; + else return 0; + } + + if (check == TRUE) { + if (ret >= event_len && memcmp(event, data->io_buf, event_len) == 0) { + return ret; + } else if (retry > 0) { + usb_debug("retry to get event(%d)\n", retry); + retry--; + goto retry_get; + } else { + usb_debug("can't get expect event\n"); + } + } + return -1; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_send_hci_cmd(struct LD_btmtk_usb_data *data, const u8 *cmd, + const int cmd_len, const u8 *event, const int event_len) +{ + /** @RETURN + * length if event compare successfully., + * 0 if doesn't check event., + * < 0 if error. + */ +#define USB_CTRL_IO_TIMO 100 +#define USB_INTR_MSG_TIMO 2000 + int ret = -1; + int len = 0; + int i = 0; + u8 retry = 0; + BOOL check = FALSE; + + if (!data || !data->hcif || !data->io_buf || !cmd) { + usb_debug("incorrect cmd pointer\n"); + return -1; + } + if (event != NULL && event_len > 0) + check = TRUE; + + /* send HCI command */ + ret = data->hcif->usb_control_msg(data->udev, MTKBT_CTRL_TX_EP, 0, + DEVICE_CLASS_REQUEST_OUT, 0, 0, (u8 *)cmd, cmd_len, USB_CTRL_IO_TIMO); + if (ret < 0) { + usb_debug("send command failed: %d\n", ret); + return ret; + } + + if (event_len == -1) { + /* If event_len is -1, DO NOT read event, since FW wouldn't feedback */ + return 0; + } + + /* check HCI event */ + do { + ret = data->hcif->usb_interrupt_msg(data->udev, MTKBT_INTR_EP, data->io_buf, + LD_BT_MAX_EVENT_SIZE, &len, USB_INTR_MSG_TIMO); + if (ret < 0) { + usb_debug("event get failed: %d\n", ret); + if (check == TRUE) return ret; + else return 0; + } + + if (check == TRUE) { + if (len >= event_len) { + for (i = 0; i < event_len; i++) { + if (event[i] != data->io_buf[i]) + break; + } + } else { + usb_debug("event length is not match(%d/%d)\n", len, event_len); + } + if (i != event_len) { + usb_debug("got unknown event(%d)\n", len); + } else { + return len; /* actually read length */ + } + MTK_MDELAY(10); + ++retry; + } + usb_debug("try get event again\n"); + } while (retry < 3); + return -1; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_send_hci_suspend_cmd(struct LD_btmtk_usb_data *data) +{ + int ret = -1; + /* mtkbt_dev_t *udev = data->udev; */ +#if SUPPORT_HISENSE_WoBLE + u8 cmd[] = {0xC9, 0xFC, 0x02, 0x01, 0x0D}; // for Hisense WoBLE + + usb_debug("issue wake up command for Hisense\n"); +#else + u8 cmd[] = {0xC9, 0xFC, 0x0D, 0x01, 0x0E, 0x00, 0x05, 0x43, + 0x52, 0x4B, 0x54, 0x4D, 0x20, 0x04, 0x32, 0x00}; + + usb_debug("issue wake up command for '0E: MTK WoBLE Ver2'\n"); +#endif + + ret = btmtk_usb_send_hci_cmd(data, cmd, sizeof(cmd), NULL, -1); + if (ret < 0) { + usb_debug("error(%d)\n", ret); + return ret; + } + usb_debug("send suspend cmd OK\n"); + return 0; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_send_hci_reset_cmd(struct LD_btmtk_usb_data *data) +{ + u8 cmd[] = { 0x03, 0x0C, 0x00 }; + u8 event[] = { 0x0E, 0x04, 0x01, 0x03, 0x0C, 0x00 }; + int ret = -1; + + ret = btmtk_usb_send_hci_cmd(data, cmd, sizeof(cmd), event, sizeof(event)); + if (ret < 0) { + usb_debug("failed(%d)\n", ret); + } else { + usb_debug("OK\n"); + } + + return ret; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_send_hci_set_ce_cmd(struct LD_btmtk_usb_data *data) +{ + u8 cmd[] = { 0xD1, 0xFC, 0x04, 0x0C, 0x07, 0x41, 0x00 }; + u8 event[] = { 0x0E, 0x08, 0x01, 0xD1, 0xFC, 0x00 }; + int ret = -1; + + ret = btmtk_usb_send_hci_cmd(data, cmd, sizeof(cmd), event, sizeof(event)); + if (ret < 0) { + usb_debug("failed(%d)\n", ret); + + } else if (ret == sizeof(event) + 4) { + if (data->io_buf[6] & 0x01) { + usb_debug("warning, 0x41070c[0] is 1!\n"); + ret = 0; + } else { + u8 cmd2[11] = { 0xD0, 0xFC, 0x08, 0x0C, 0x07, 0x41, 0x00 }; + + cmd2[7] = data->io_buf[6] | 0x01; + cmd2[8] = data->io_buf[7]; + cmd2[9] = data->io_buf[8]; + cmd2[10] = data->io_buf[9]; + + ret = btmtk_usb_send_hci_cmd(data, cmd2, sizeof(cmd2), NULL, 0); + if (ret < 0) { + usb_debug("write 0x41070C failed(%d)\n", ret); + } else { + usb_debug("OK"); + ret = 0; + } + } + } else { + usb_debug("failed, incorrect response length(%d)\n", ret); + return -1; + } + + return ret; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_send_check_rom_patch_result_cmd(struct LD_btmtk_usb_data *data) +{ + /* Send HCI Reset */ + { + int ret = 0; + unsigned char buf[8] = { 0 }; + buf[0] = 0xD1; + buf[1] = 0xFC; + buf[2] = 0x04; + buf[3] = 0x00; + buf[4] = 0xE2; + buf[5] = 0x40; + buf[6] = 0x00; + ret = data->hcif->usb_control_msg(data->udev, MTKBT_CTRL_TX_EP,0x0, DEVICE_CLASS_REQUEST_OUT, + 0x00, 0x00, buf, 0x07, 100); + if (ret < 0) + { + usb_debug("error1(%d)\n", ret); + return ret; + } + } + /* Get response of HCI reset */ + { + int ret = 0; + unsigned char buf[LD_BT_MAX_EVENT_SIZE] = { 0 }; + int actual_length = 0; + ret = data->hcif->usb_interrupt_msg(data->udev, MTKBT_INTR_EP, buf, LD_BT_MAX_EVENT_SIZE, + &actual_length, 2000); + if (ret < 0) + { + usb_debug("error2(%d)\n", ret); + return ret; + } + usb_debug("Check rom patch result : "); + + if (buf[6] == 0 && buf[7] == 0 && buf[8] == 0 && buf[9] == 0) + { + usb_debug("NG\n"); + } + else + { + usb_debug("OK\n"); + } + } + return 0; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_switch_iobase(struct LD_btmtk_usb_data *data, int base) +{ + int ret = 0; + + switch (base) + { + case SYSCTL: + data->w_request = 0x42; + data->r_request = 0x47; + break; + case WLAN: + data->w_request = 0x02; + data->r_request = 0x07; + break; + + default: + return -EINVAL; + } + + return ret; +} + +//--------------------------------------------------------------------------- +static void btmtk_usb_cap_init(struct LD_btmtk_usb_data *data) +{ + btmtk_usb_io_read32(data, 0x00, &data->chip_id); + if (data->chip_id == 0) + btmtk_usb_io_read32_7668(data, 0x80000008, &data->chip_id); + + //usb_debug("chip id = %x\n", data->chip_id); + + if (is_mt7630(data) || is_mt7650(data)) { + data->need_load_fw = 1; + data->need_load_rom_patch = 0; + data->fw_header_image = NULL; + data->fw_bin_file_name = (unsigned char*)strdup("mtk/mt7650.bin"); + data->fw_len = 0; + + } else if (is_mt7662T(data) || is_mt7632T(data)) { + usb_debug("btmtk:This is 7662T chip\n"); + data->need_load_fw = 0; + data->need_load_rom_patch = 1; + data->rom_patch_bin_file_name = os_kzalloc(32, MTK_GFP_ATOMIC); + if (!data->rom_patch_bin_file_name) { + usb_debug("Can't allocate memory (32)\n"); + return; + } + os_memcpy(data->rom_patch_bin_file_name, "mt7662t_patch_e1_hdr.bin", 24); + data->rom_patch_offset = 0xBC000; + data->rom_patch_len = 0; + + } else if (is_mt7632(data) || is_mt7662(data)) { + usb_debug("btmtk:This is 7662 chip\n"); + data->need_load_fw = 0; + data->need_load_rom_patch = 1; + data->rom_patch_bin_file_name = os_kzalloc(32, MTK_GFP_ATOMIC); + if (!data->rom_patch_bin_file_name) { + usb_debug("Can't allocate memory (32)\n"); + return; + } + os_memcpy(data->rom_patch_bin_file_name, "mt7662_patch_e3_hdr.bin", 23); + data->rom_patch_offset = 0x90000; + data->rom_patch_len = 0; + + } else if (is_mt7668(data)) { + unsigned int chip_ver = 0; + + data->need_load_fw = 0; + data->need_load_rom_patch = 1; + data->rom_patch_bin_file_name = os_kzalloc(32, MTK_GFP_ATOMIC); + if (!data->rom_patch_bin_file_name) { + usb_debug("Can't allocate memory (32)\n"); + return; + } + btmtk_usb_io_read32_7668(data, 0x80000000, &chip_ver); + if (chip_ver == 0x8A00) { + usb_debug("btmtk:This is 7668 E1 chip\n"); + os_memcpy(data->rom_patch_bin_file_name, "mt7668_patch_e1_hdr.bin", 23); + } else if (chip_ver == 0x8B10) { + usb_debug("btmtk:This is 7668 E2 chip\n"); + os_memcpy(data->rom_patch_bin_file_name, "mt7668_patch_e2_hdr.bin", 23); + } else { + usb_debug("btmtk: Can't recognize version 0x%04X\n", chip_ver); + if (data->rom_patch_bin_file_name) os_kfree(data->rom_patch_bin_file_name); + } + data->chip_id |= chip_ver << 16; + data->rom_patch_offset = 0x2000000; + data->rom_patch_len = 0; + + } else { + usb_debug("unknow chip(%x)\n", data->chip_id); + } +} + +#if CRC_CHECK +//--------------------------------------------------------------------------- +static u16 checksume16(u8 *pData, int len) +{ + int sum = 0; + + while (len > 1) + { + sum += *((u16 *) pData); + + pData = pData + 2; + + if (sum & 0x80000000) + { + sum = (sum & 0xFFFF) + (sum >> 16); + } + len -= 2; + } + + if (len) + sum += *((u8 *) pData); + + while (sum >> 16) + { + sum = (sum & 0xFFFF) + (sum >> 16); + } + + return ~sum; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_chk_crc(struct LD_btmtk_usb_data *data, u32 checksum_len) +{ + int ret = 0; + mtkbt_dev_t *udev = data->udev; + + usb_debug("\n"); + + os_memmove(data->io_buf, &data->rom_patch_offset, 4); + os_memmove(&data->io_buf[4], &checksum_len, 4); + + ret = data->hcif->usb_control_msg(udev, MTKBT_CTRL_TX_EP,0x1, DEVICE_VENDOR_REQUEST_OUT, + 0x20, 0x00, data->io_buf, 8, CONTROL_TIMEOUT_JIFFIES); + + if (ret < 0) + { + usb_debug("error(%d)\n", ret); + } + + return ret; +} + +//--------------------------------------------------------------------------- +static u16 btmtk_usb_get_crc(struct LD_btmtk_usb_data *data) +{ + int ret = 0; + mtkbt_dev_t *udev = data->udev; + u16 crc, count = 0; + + usb_debug("\n"); + + while (1) + { + ret = + data->hcif->usb_control_msg(udev, MTKBT_CTRL_RX_EP, 0x01, DEVICE_VENDOR_REQUEST_IN, + 0x21, 0x00, data->io_buf, 2, CONTROL_TIMEOUT_JIFFIES); + + if (ret < 0) + { + crc = 0xFFFF; + usb_debug("error(%d)\n", ret); + } + + os_memmove(&crc, data->io_buf, 2); + + crc = le16_to_cpu(crc); + + if (crc != 0xFFFF) + break; + + MTK_MDELAY(100); + + if (count++ > 100) + { + usb_debug("Query CRC over %d times\n", count); + break; + } + } + + return crc; +} +#endif /* CRC_CHECK */ + +//--------------------------------------------------------------------------- +static int btmtk_usb_send_wmt_reset_cmd(struct LD_btmtk_usb_data *data) +{ + /* reset command */ + u8 cmd[] = { 0x6F, 0xFC, 0x05, 0x01, 0x07, 0x01, 0x00, 0x04 }; + u8 event[] = { 0xE4, 0x05, 0x02, 0x07, 0x01, 0x00, 0x00 }; + int ret = -1; + + ret = btmtk_usb_send_wmt_cmd(data, cmd, sizeof(cmd), event, sizeof(event), 20, 0); + if (ret < 0) { + usb_debug("Check reset wmt result : NG\n"); + } else { + usb_debug("Check reset wmt result : OK\n"); + ret = 0; + } + + return ret; +} + +//--------------------------------------------------------------------------- +static u16 btmtk_usb_get_rom_patch_result(struct LD_btmtk_usb_data *data) +{ + int ret = 0; + + ret = data->hcif->usb_control_msg(data->udev, MTKBT_CTRL_RX_EP, 0x01, + DEVICE_VENDOR_REQUEST_IN, 0x30, 0x00, data->io_buf, 7, + CONTROL_TIMEOUT_JIFFIES); + + if (ret < 0) + { + usb_debug("error(%d)\n", ret); + } + + if (data->io_buf[0] == 0xe4 && + data->io_buf[1] == 0x05 && + data->io_buf[2] == 0x02 && + data->io_buf[3] == 0x01 && + data->io_buf[4] == 0x01 && + data->io_buf[5] == 0x00 && + data->io_buf[6] == 0x00) + { + //usb_debug("Get rom patch result : OK\n"); + } + else + { + usb_debug("Get rom patch result : NG\n"); + } + return ret; +} + +//--------------------------------------------------------------------------- +#define SHOW_FW_DETAILS(s) \ + usb_debug("%s = %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", s, \ + tmp_str[0], tmp_str[1], tmp_str[2], tmp_str[3], \ + tmp_str[4], tmp_str[5], tmp_str[6], tmp_str[7], \ + tmp_str[8], tmp_str[9], tmp_str[10], tmp_str[11], \ + tmp_str[12], tmp_str[13], tmp_str[14], tmp_str[15]) + +//--------------------------------------------------------------------------- +static int btmtk_usb_load_rom_patch(struct LD_btmtk_usb_data *data) +{ + u32 loop = 0; + u32 value; + s32 sent_len; + int ret = 0; + u32 patch_len = 0; + u32 cur_len = 0; + int real_len = 0; + int first_block = 1; + unsigned char phase; + void *buf; + char *pos; + unsigned char *tmp_str; + + //usb_debug("begin\n"); +load_patch_protect: + btmtk_usb_switch_iobase(data, WLAN); + btmtk_usb_io_read32(data, SEMAPHORE_03, &value); + loop++; + + if ((value & 0x01) == 0x00) + { + if (loop < 1000) + { + MTK_MDELAY(1); + goto load_patch_protect; + } + else + { + usb_debug("btmtk_usb_load_rom_patch ERR! Can't get semaphore! Continue\n"); + } + } + + btmtk_usb_switch_iobase(data, SYSCTL); + + btmtk_usb_io_write32(data, 0x1c, 0x30); + + btmtk_usb_switch_iobase(data, WLAN); + + /* check ROM patch if upgrade */ + if ((MT_REV_GTE(data, mt7662, REV_MT76x2E3)) || (MT_REV_GTE(data, mt7632, REV_MT76x2E3))) + { + btmtk_usb_io_read32(data, CLOCK_CTL, &value); + if ((value & 0x01) == 0x01) + { + usb_debug("btmtk_usb_load_rom_patch : no need to load rom patch\n"); + btmtk_usb_send_hci_reset_cmd(data); + goto error; + } + } + else + { + btmtk_usb_io_read32(data, COM_REG0, &value); + if ((value & 0x02) == 0x02) + { + usb_debug("btmtk_usb_load_rom_patch : no need to load rom patch\n"); + btmtk_usb_send_hci_reset_cmd(data); + goto error; + } + } + + buf = os_kzalloc(UPLOAD_PATCH_UNIT, MTK_GFP_ATOMIC); + if (!buf) + { + ret = -ENOMEM; + goto error; + } + + pos = buf; + + LD_load_code_from_bin(&data->rom_patch, (char *)data->rom_patch_bin_file_name, NULL, + data->udev, &data->rom_patch_len); + + if (!data->rom_patch) + { + usb_debug("please assign a rom patch(/system/etc/firmware/%s)or(/lib/firmware/%s)\n", + data->rom_patch_bin_file_name, + data->rom_patch_bin_file_name); + ret = -1; + goto error; + } + + tmp_str = data->rom_patch; + SHOW_FW_DETAILS("FW Version"); + SHOW_FW_DETAILS("build Time"); + + tmp_str = data->rom_patch + 16; + usb_debug("platform = %c%c%c%c\n", tmp_str[0], tmp_str[1], tmp_str[2], tmp_str[3]); + + tmp_str = data->rom_patch + 20; + usb_debug("HW/SW version = %c%c%c%c\n", tmp_str[0], tmp_str[1], tmp_str[2], tmp_str[3]); + + tmp_str = data->rom_patch + 24; + usb_debug("Patch version = %c%c%c%c\n", tmp_str[0], tmp_str[1], tmp_str[2], tmp_str[3]); + + usb_debug("\nloading rom patch...\n"); + + cur_len = 0x00; + patch_len = data->rom_patch_len - PATCH_INFO_SIZE; + + /* loading rom patch */ + while (1) + { + s32 sent_len_max = UPLOAD_PATCH_UNIT - PATCH_HEADER_SIZE; + real_len = 0; + sent_len = + (patch_len - cur_len) >= sent_len_max ? sent_len_max : (patch_len - cur_len); + + //usb_debug("patch_len = %d\n", patch_len); + //usb_debug("cur_len = %d\n", cur_len); + //usb_debug("sent_len = %d\n", sent_len); + + if (sent_len > 0) + { + if (first_block == 1) + { + if (sent_len < sent_len_max) + phase = PATCH_PHASE3; + else + phase = PATCH_PHASE1; + first_block = 0; + } + else if (sent_len == sent_len_max) + { + if (patch_len - cur_len == sent_len_max) + phase = PATCH_PHASE3; + else + phase = PATCH_PHASE2; + } + else + { + phase = PATCH_PHASE3; + } + + /* prepare HCI header */ + pos[0] = 0x6F; + pos[1] = 0xFC; + pos[2] = (sent_len + 5) & 0xFF; + pos[3] = ((sent_len + 5) >> 8) & 0xFF; + + /* prepare WMT header */ + pos[4] = 0x01; + pos[5] = 0x01; + pos[6] = (sent_len + 1) & 0xFF; + pos[7] = ((sent_len + 1) >> 8) & 0xFF; + + pos[8] = phase; + + os_memcpy(&pos[9], data->rom_patch + PATCH_INFO_SIZE + cur_len, sent_len); + + //usb_debug("sent_len + PATCH_HEADER_SIZE = %d, phase = %d\n", + //sent_len + PATCH_HEADER_SIZE, phase); + + ret = data->hcif->usb_bulk_msg(data->udev, MTKBT_BULK_TX_EP, buf, sent_len + PATCH_HEADER_SIZE, &real_len, 0); + + if (ret) + { + usb_debug("upload rom_patch err: %d\n", ret); + goto error; + } + + MTK_MDELAY(1); + + cur_len += sent_len; + + } + else + { + usb_debug("loading rom patch... Done\n"); + break; + } + } + + MTK_MDELAY(20); + ret = btmtk_usb_get_rom_patch_result(data); + MTK_MDELAY(20); + + /* Send Checksum request */ + #if CRC_CHECK + int total_checksum = checksume16(data->rom_patch + PATCH_INFO_SIZE, patch_len); + btmtk_usb_chk_crc(data, patch_len); + MTK_MDELAY(20); + if (total_checksum != btmtk_usb_get_crc(data)) + { + usb_debug("checksum fail!, local(0x%x) <> fw(0x%x)\n", total_checksum, + btmtk_usb_get_crc(data)); + ret = -1; + goto error; + } + else + { + usb_debug("crc match!\n"); + } + #endif + MTK_MDELAY(20); + /* send check rom patch result request */ + btmtk_usb_send_check_rom_patch_result_cmd(data); + MTK_MDELAY(20); + /* CHIP_RESET */ + ret = btmtk_usb_send_wmt_reset_cmd(data); + MTK_MDELAY(20); + /* BT_RESET */ + btmtk_usb_send_hci_reset_cmd(data); + /* for WoBLE/WoW low power */ + btmtk_usb_send_hci_set_ce_cmd(data); + + error: + btmtk_usb_io_write32(data, SEMAPHORE_03, 0x1); + //usb_debug("end\n"); + return ret; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_send_wmt_power_on_cmd_7668(struct LD_btmtk_usb_data *data) +{ + u8 count = 0; /* retry 3 times */ + u8 cmd[] = { 0x6F, 0xFC, 0x06, 0x01, 0x06, 0x02, 0x00, 0x00, 0x01 }; + u8 event[] = { 0xE4, 0x05, 0x02, 0x06, 0x01, 0x00 }; /* event[6] is key */ + int ret = -1; /* if successful, 0 */ + + do { + ret = btmtk_usb_send_wmt_cmd(data, cmd, sizeof(cmd), event, sizeof(event), 100, 10); + if (ret < 0) { + usb_debug("failed(%d)\n", ret); + } else if (ret == sizeof(event) + 1) { + switch (data->io_buf[6]) { + case 0: /* successful */ + usb_debug("OK\n"); + ret = 0; + break; + case 2: /* retry */ + usb_debug("Try again\n"); + continue; + default: + usb_debug("Unknown result: %02X\n", data->io_buf[6]); + return -1; + } + } else { + usb_debug("failed, incorrect response length(%d)\n", ret); + return -1; + } + } while (++count < 3 && ret > 0); + + return ret; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_send_hci_tci_set_sleep_cmd_7668(struct LD_btmtk_usb_data *data) +{ + u8 cmd[] = { 0x7A, 0xFC, 0x07, 0x05, 0x40, 0x06, 0x40, 0x06, 0x00, 0x00 }; + u8 event[] = { 0x0E, 0x04, 0x01, 0x7A, 0xFC, 0x00 }; + int ret = -1; /* if successful, 0 */ + + ret = btmtk_usb_send_hci_cmd(data, cmd, sizeof(cmd), event, sizeof(event)); + if (ret < 0) { + usb_debug("failed(%d)\n", ret); + } else { + usb_debug("OK\n"); + ret = 0; + } + + return ret; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_get_vendor_cap(struct LD_btmtk_usb_data *data) +{ + u8 cmd[] = { 0x53, 0xFD, 0x00 }; + u8 event[6] = { 0x0E, 0x12, 0x01, 0x53, 0xFD, 0x00, /* ... */ }; + int ret = -1; + + // TODO: should not compare whole event + ret = btmtk_usb_send_hci_cmd(data, cmd, sizeof(cmd), event, sizeof(event)); + if (ret < 0) { + usb_debug("Failed(%d)\n", ret); + } else { + usb_debug("OK\n"); + ret = 0; + } + + return ret; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_send_read_bdaddr(struct LD_btmtk_usb_data *data) +{ + u8 cmd[] = { 0x09, 0x10, 0x00 }; + u8 event[] = { 0x0E, 0x0A, 0x01, 0x09, 0x10, 0x00, /* 6 bytes are BDADDR */ }; + int ret = -1; + + ret = btmtk_usb_send_hci_cmd(data, cmd, sizeof(cmd), event, sizeof(event)); + if (ret < 0 || ret != 12 /* Event actual length */) { + usb_debug("Failed(%d)\n", ret); + return ret; + } + + os_memcpy(data->local_addr, data->io_buf + 6, BD_ADDR_LEN); + usb_debug("ADDR: %02X-%02X-%02X-%02X-%02X-%02X\n", + data->local_addr[5], data->local_addr[4], data->local_addr[3], + data->local_addr[2], data->local_addr[1], data->local_addr[0]); + ret = 0; + + return ret; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_set_apcf(struct LD_btmtk_usb_data *data, BOOL bin_file) +{ + int i = 0, ret = -1; + // Legacy RC pattern + u8 manufacture_data[] = { 0x57, 0xFD, 0x27, 0x06, 0x00, FIDX, + 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x52, 0x4B, 0x54, 0x4D, /* manufacturer data */ + 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /* mask */ + u8 filter_cmd[] = { 0x57, 0xFD, 0x0A, 0x01, 0x00, FIDX, 0x20, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x00 }; + u8 event[] = { 0x0E, 0x07, 0x01, 0x57, 0xFD, 0x00, /* ... */ }; + + if (bin_file) { + if (data->wake_dev_len) { + /* wake_on_ble.conf using 90(0x5A-FIDX) as filter_index */ + u8 pos = 0; + u8 broadcast_addr[] = { 0x57, 0xFD, 0x0A, 0x02, 0x00, FIDX, + 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, // ADDRESS + 0x00 }; // 0: Public, 1: Random + u8 adv_pattern[] = { 0x57, 0xFD, 0x15, 0x06, 0x00, FIDX, + 0x71, 0x01, // VID + 0x04, 0x11, // PID + 0x00, 0x00, 0x00, 0x00, // IR key code + 0x00, // sequence number + 0xFF, 0xFF, // mask~ + 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, + 0x00 }; + + // BDADDR + for (i = 0; i < data->wake_dev[1]; i++) { + broadcast_addr[11] = data->wake_dev[2 + i * BD_ADDR_LEN + 0]; + broadcast_addr[10] = data->wake_dev[2 + i * BD_ADDR_LEN + 1]; + broadcast_addr[9] = data->wake_dev[2 + i * BD_ADDR_LEN + 2]; + broadcast_addr[8] = data->wake_dev[2 + i * BD_ADDR_LEN + 3]; + broadcast_addr[7] = data->wake_dev[2 + i * BD_ADDR_LEN + 4]; + broadcast_addr[6] = data->wake_dev[2 + i * BD_ADDR_LEN + 5]; + ret = btmtk_usb_send_hci_cmd(data, broadcast_addr, sizeof(broadcast_addr), + event, sizeof(event)); + if (ret < 0) { + usb_debug("Set broadcast address fail\n"); + continue; + } + // mask broadcast address as a filter condition + filter_cmd[6] = 0x21; + } + usb_debug("There are %d broadcast address filter(s) from %s\n", i, WAKE_DEV_RECORD); + + /** VID/PID in conf is LITTLE endian, but PID in ADV is BIG endian */ + pos = 2 + data->wake_dev[1] * 6; + for (i = 0; i < data->wake_dev[pos]; i++) { + adv_pattern[6] = data->wake_dev[pos + (i * 4) + 1]; + adv_pattern[7] = data->wake_dev[pos + (i * 4) + 2]; + adv_pattern[9] = data->wake_dev[pos + (i * 4) + 3]; + adv_pattern[8] = data->wake_dev[pos + (i * 4) + 4]; + ret = btmtk_usb_send_hci_cmd(data, adv_pattern, sizeof(adv_pattern), + event, sizeof(event)); + if (ret < 0) { + usb_debug("Set advertising patten fail\n"); + return ret; + } + } + usb_debug("There are %d manufacture data filter(s) from %s\n", i, WAKE_DEV_RECORD); + + // Filtering parameters + ret = btmtk_usb_send_hci_cmd(data, filter_cmd, sizeof(filter_cmd), + event, sizeof(event)); + if (ret < 0) { + usb_debug("Set filtering parm fail\n"); + return ret; + } + + // if wake_on_ble.conf exist, no need use default woble_setting.bin + } else { + // woble_setting.bin + usb_debug("Set APCF filter from woble_setting.bin\n"); + for (i = 0; i < APCF_SETTING_COUNT; i++) { + if (!data->apcf_cmd[i].len) + continue; + ret = btmtk_usb_send_hci_cmd(data, data->apcf_cmd[i].value, data->apcf_cmd[i].len, + event, sizeof(event)); + if (ret < 0) { + usb_debug("Set apcf_cmd[%d] data fail\n", i); + return ret; + } + } + } + + } else { + // Use default + usb_debug("Using default APCF filter\n"); + os_memcpy(manufacture_data + 9, data->local_addr, BD_ADDR_LEN); + ret = btmtk_usb_send_hci_cmd(data, manufacture_data, + sizeof(manufacture_data), event, sizeof(event)); + if (ret < 0) { + usb_debug("Set manufacture data fail\n"); + return ret; + } + + ret = btmtk_usb_send_hci_cmd(data, filter_cmd, sizeof(filter_cmd), + event, sizeof(event)); + if (ret < 0) { + usb_debug("Set manufacture data fail\n"); + return ret; + } + } + return 0; +} + +//--------------------------------------------------------------------------- +static BOOL btmtk_usb_check_need_load_patch_7668(struct LD_btmtk_usb_data *data) +{ + /* TRUE: need load patch., FALSE: do not need */ + u8 cmd[] = { 0x6F, 0xFC, 0x05, 0x01, 0x17, 0x01, 0x00, 0x01 }; + u8 event[] = { 0xE4, 0x05, 0x02, 0x17, 0x01, 0x00, /* 0x02 */ }; /* event[6] is key */ + int ret = -1; + + ret = btmtk_usb_send_wmt_cmd(data, cmd, sizeof(cmd), event, sizeof(event), 20, 0); + /* can't get correct event, need load patch */ + if (ret < 0) { + usb_debug("check need load patch or not fail(%d)", ret); + return TRUE; + } + + if (ret == sizeof(event) + 1 && (data->io_buf[6] == 0x00 || data->io_buf[6] == 0x01)) + return FALSE; /* Do not need */ + + return TRUE; +} + +//--------------------------------------------------------------------------- +static int btmtk_usb_load_rom_patch_7668(struct LD_btmtk_usb_data *data) +{ + int ret = 0; + int first_block = 1; + int real_len = 0; + void *buf = NULL; + char *tmp_str = NULL; + u8 *pos = NULL; + u8 phase = 0; + u32 cur_len = 0; + u32 patch_len = 0; + s32 sent_len = 0; + + //usb_debug("begin\n"); + if (btmtk_usb_check_need_load_patch_7668(data) == FALSE) { + usb_debug("No need to load rom patch\n"); + return btmtk_usb_send_wmt_reset_cmd(data); + } + + buf = os_kzalloc(UPLOAD_PATCH_UNIT, MTK_GFP_ATOMIC); + if (!buf) { + return -ENOMEM; + } + + pos = buf; + LD_load_code_from_bin(&data->rom_patch, (char *)data->rom_patch_bin_file_name, NULL, + data->udev, &data->rom_patch_len); + if (!data->rom_patch || !data->rom_patch_len) { + usb_debug("please assign a rom patch(/system/etc/firmware/%s) or (/lib/firmware/%s)\n", + data->rom_patch_bin_file_name, data->rom_patch_bin_file_name); + return -1; + } + + tmp_str = (char *)data->rom_patch; + SHOW_FW_DETAILS("FW Version"); + SHOW_FW_DETAILS("build Time"); + + tmp_str = (char *)data->rom_patch + 16; + usb_debug("platform = %c%c%c%c\n", tmp_str[0], tmp_str[1], tmp_str[2], tmp_str[3]); + + tmp_str = (char *)data->rom_patch + 20; + usb_debug("HW/SW version = %c%c%c%c\n", tmp_str[0], tmp_str[1], tmp_str[2], tmp_str[3]); + + tmp_str = (char *)data->rom_patch + 24; + patch_len = data->rom_patch_len - PATCH_INFO_SIZE; + //usb_debug("patch_len = %d\n", patch_len); + usb_debug("loading rom patch...\n"); + + /* loading rom patch */ + while (1) { + s32 sent_len_max = UPLOAD_PATCH_UNIT - PATCH_HEADER_SIZE; + + real_len = 0; + sent_len = (patch_len - cur_len) >= sent_len_max ? sent_len_max : (patch_len - cur_len); + if (sent_len > 0) { + if (first_block == 1) { + if (sent_len < sent_len_max) + phase = PATCH_PHASE3; + else + phase = PATCH_PHASE1; + first_block = 0; + } else if (sent_len == sent_len_max) { + if (patch_len - cur_len == sent_len_max) + phase = PATCH_PHASE3; + else + phase = PATCH_PHASE2; + } else { + phase = PATCH_PHASE3; + } + + /* prepare HCI header */ + pos[0] = 0x6F; + pos[1] = 0xFC; + pos[2] = (sent_len + 5) & 0xFF; + pos[3] = ((sent_len + 5) >> 8) & 0xFF; + + /* prepare WMT header */ + pos[4] = 0x01; + pos[5] = 0x01; + pos[6] = (sent_len + 1) & 0xFF; + pos[7] = ((sent_len + 1) >> 8) & 0xFF; + + pos[8] = phase; + + os_memcpy(&pos[9], data->rom_patch + PATCH_INFO_SIZE + cur_len, sent_len); + //usb_debug("sent_len = %d, cur_len = %d, phase = %d\n", sent_len, cur_len, phase); + + ret = data->hcif->usb_bulk_msg(data->udev, MTKBT_BULK_TX_EP, buf, + sent_len + PATCH_HEADER_SIZE, &real_len, 0); + if (ret) { + usb_debug("upload rom_patch err: %d\n", ret); + return -1; + } + cur_len += sent_len; + MTK_MDELAY(1); + btmtk_usb_get_rom_patch_result(data); + MTK_MDELAY(1); + + } else { + usb_debug("loading rom patch... Done\n"); + break; + } + os_memset(buf, 0, UPLOAD_PATCH_UNIT); + } + MTK_MDELAY(20); + /* CHIP_RESET */ + ret = btmtk_usb_send_wmt_reset_cmd(data); + MTK_MDELAY(20); + + //usb_debug("end\n"); + return ret; +} + +//--------------------------------------------------------------------------- +void btmtk_usb_woble_setting_parsing(struct LD_btmtk_usb_data *data, woble_setting_type type) +{ +#define ONE_BYTE_HEX_MAX_LEN 8 + int i = 0; + char *cmd = NULL; + char *head = NULL; + char *next_cmd = NULL; + char prefix[32] = {0}; + u8 tmp_len = 0; + u8 tmp[128] = {0}; + long int set_addr = 0; + long int addr_pos = 0; + + switch (type) { + case TYPE_APCF_CMD: + cmd = "APCF"; + break; + default: + usb_debug("Incorrect Type\n"); + return; + } + + for (i = 0; i < APCF_SETTING_COUNT; ++i) { + snprintf(prefix, sizeof(prefix), "%s%02d:", cmd, i); + head = strstr((char *)data->woble_setting, prefix); + + if (head) { + head += strlen(prefix); /* move to first numeral */ + next_cmd = strstr(head, ":"); // next command start position + + tmp_len = 0; + memset(tmp, 0, sizeof(tmp)); + do { + tmp[tmp_len++] = strtol(head, &head, 0); + + // for next one + head = strstr(head, "0x"); + if (next_cmd && head > next_cmd) + break; // command end + } while (tmp_len < sizeof(tmp)); + + if (tmp_len) { + int j = 0; // FOR DEBUG + + /* Save command */ + data->apcf_cmd[i].value = os_kzalloc(tmp_len, MTK_GFP_ATOMIC); + os_memcpy(data->apcf_cmd[i].value, tmp, tmp_len); + data->apcf_cmd[i].len = tmp_len; + + if (type == TYPE_APCF_CMD) { + /* Check need BD address or not */ + snprintf(prefix, sizeof(prefix), "%s_ADD_MAC%02d:", cmd, i); + head = strstr((char *)data->woble_setting, prefix); + head += strlen(prefix); + set_addr = strtol(head, &head, 0); + + if (set_addr == 1) { + snprintf(prefix, sizeof(prefix), "%s_ADD_MAC_LOCATION%02d:", cmd, i); + head = strstr((char *)data->woble_setting, prefix); + head += strlen(prefix); + addr_pos = strtol(head, &head, 0); + + if (addr_pos) + os_memcpy(data->apcf_cmd[i].value + addr_pos, + data->local_addr, BD_ADDR_LEN); + } + } + // FOR DEBUG + usb_debug("Load for APCF settings only\n"); + usb_debug("%02X:", i); + for (j = 0; j < data->apcf_cmd[i].len; j++) + printf(" %02X", data->apcf_cmd[i].value[j]); + printf("\n"); + } + } + } +} + +//--------------------------------------------------------------------------- +int btmtk_usb_load_woble_setting(struct LD_btmtk_usb_data *data) +{ + int i = 0; + BOOL woble_setting_bin = FALSE; + BOOL wake_on_ble_conf = FALSE; + + if (!data) + return -EINVAL; + + /* For woble_setting.bin */ + data->woble_setting = NULL; + data->woble_setting_len = 0; + + LD_load_code_from_bin(&data->woble_setting, WOBLE_SETTING_FILE_NAME, NULL, + data->udev, &data->woble_setting_len); + if (data->woble_setting == NULL || data->woble_setting_len == 0) { + usb_debug("Please make sure %s in the /system/etc(lib)/firmware\n", + WOBLE_SETTING_FILE_NAME); + woble_setting_bin = FALSE; + } else { + btmtk_usb_woble_setting_parsing(data, TYPE_APCF_CMD); + for (i = 0; i < APCF_SETTING_COUNT; i++) + if (data->apcf_cmd[i].len) + break; + if (i == APCF_SETTING_COUNT) { + woble_setting_bin = FALSE; + if (data->woble_setting) { + data->woble_setting_len = 0; + os_kfree(data->woble_setting); + data->woble_setting = NULL; + } + } else { + woble_setting_bin = TRUE; + } + } + + /* For wake_on_ble.conf */ + data->wake_dev = NULL; + data->wake_dev_len = 0; + + LD_load_code_from_bin(&data->wake_dev, WAKE_DEV_RECORD, WAKE_DEV_RECORD_PATH, + data->udev, &data->wake_dev_len); + if (data->wake_dev == NULL || data->wake_dev_len == 0) { + usb_debug("There is no DEVICE RECORD for wake-up\n"); + wake_on_ble_conf = FALSE; + } else { + // content check + if (data->wake_dev[0] != data->wake_dev_len || data->wake_dev_len < 3) { + usb_debug("Incorrect total length on %s\n", WAKE_DEV_RECORD); + data->wake_dev_len = 0; + os_kfree(data->wake_dev); + data->wake_dev = NULL; + wake_on_ble_conf = FALSE; + } else { + wake_on_ble_conf = TRUE; + } + } + + if (woble_setting_bin == FALSE && wake_on_ble_conf == FALSE) + return -ENOENT; + return 0; +} + +//--------------------------------------------------------------------------- +int btmtk_usb_set_unify_woble(struct LD_btmtk_usb_data *data) +{ + int ret = -1; + // Filter Index: 0x5B + /*u8 cmd[] = { 0xC9, 0xFC, 0x1F, 0x01, 0x20, 0x02, 0x00, 0x01, 0x02, 0x01, + 0x01, 0x05, 0x10, 0x09, 0x00, 0xC0, 0x00, 0x02, 0x40, FIDX, 0x04, + 0x11, 0x12, 0x00, 0x00, 0x02, 0x42, 0x15, 0x02, 0x25, 0x00, 0x02, + 0x41, 0x19 };*/ + + u8 cmd[] = { 0xC9, 0xFC, 0x14, 0x01, 0x20, 0x02, 0x00, 0x01, + 0x02, 0x01, 0x00, 0x05, 0x10, 0x01, 0x00, 0x40, 0x06, + 0x02, 0x40, 0x5A, 0x02, 0x41, 0x0F }; + u8 event[] = { 0xE6, 0x02, 0x08, 0x00 }; + + usb_debug("%s: APCF filtering index: %d\n", __func__, FIDX); + ret = btmtk_usb_send_hci_cmd(data, cmd, sizeof(cmd), event, sizeof(event)); + if (ret < 0) + usb_debug("Failed(%d)\n", ret); + return ret; +} + +//--------------------------------------------------------------------------- +void LD_btmtk_usb_SetWoble(mtkbt_dev_t *dev) +{ + struct LD_btmtk_usb_data *data = BT_INST(dev)->priv_data; + int ret = -1; + + usb_debug("\n"); + if (!data) { + usb_debug("btmtk data NULL!\n"); + return; + } + + if (is_mt7668(data)) { + /* Power on sequence */ + btmtk_usb_send_wmt_power_on_cmd_7668(data); + btmtk_usb_send_hci_tci_set_sleep_cmd_7668(data); + btmtk_usb_send_hci_reset_cmd(data); + + /* Unify WoBLE flow */ + btmtk_usb_get_vendor_cap(data); + btmtk_usb_send_read_bdaddr(data); + ret = btmtk_usb_load_woble_setting(data); + if (ret) { + usb_debug("Using lagecy WoBLE setting(%d)!!!\n", ret); + btmtk_usb_set_apcf(data, FALSE); + } else + btmtk_usb_set_apcf(data, TRUE); + btmtk_usb_set_unify_woble(data); + } else { + btmtk_usb_send_hci_suspend_cmd(data); + } + + // Clean & free buffer + if (data->woble_setting) { + int i = 0; + os_kfree(data->woble_setting); + data->woble_setting = NULL; + data->woble_setting_len = 0; + for (i = 0; i < APCF_SETTING_COUNT; i++) { + os_kfree(data->apcf_cmd[i].value); + data->apcf_cmd[i].len = 0; + } + } + if (data->wake_dev) { + os_kfree(data->wake_dev); + data->wake_dev = NULL; + data->wake_dev_len = 0; + } + + return; +} + +//--------------------------------------------------------------------------- +int LD_btmtk_usb_probe(mtkbt_dev_t *dev) +{ + struct LD_btmtk_usb_data *data; + int err = 0; + + usb_debug("=========================================\n"); + usb_debug("Mediatek Bluetooth USB driver ver %s\n", LD_VERSION); + usb_debug("=========================================\n"); + os_memcpy(driver_version, LD_VERSION, sizeof(LD_VERSION)); + probe_counter++; + isbtready = 0; + is_assert = 0; + //usb_debug("LD_btmtk_usb_probe begin\n"); + usb_debug("probe_counter = %d\n", probe_counter); + + data = (struct LD_btmtk_usb_data *)os_kzalloc(sizeof(*data), MTK_GFP_ATOMIC); + if (!data) { + usb_debug("[ERR] end Error 1\n"); + return -ENOMEM; + } + + data->hcif = BT_INST(dev)->hci_if; + + data->cmdreq_type = USB_TYPE_CLASS; + + data->udev = dev; + + data->meta_tx = 0; + + data->io_buf = os_kmalloc(LD_BT_MAX_EVENT_SIZE, MTK_GFP_ATOMIC); + + btmtk_usb_switch_iobase(data, WLAN); + + /* clayton: according to the chip id, load f/w or rom patch */ + btmtk_usb_cap_init(data); + + if (data->need_load_rom_patch) { + if (is_mt7668(data)) + err = btmtk_usb_load_rom_patch_7668(data); + else + err = btmtk_usb_load_rom_patch(data); + //btmtk_usb_send_hci_suspend_cmd(data); + if (err < 0) { + if (data->io_buf) os_kfree(data->io_buf); + if (data->rom_patch_bin_file_name) os_kfree(data->rom_patch_bin_file_name); + os_kfree(data); + usb_debug("[ERR] end Error 2\n"); + return err; + } + } + + // Clean & free buffer + if (data->rom_patch_bin_file_name) + os_kfree(data->rom_patch_bin_file_name); + + + isUsbDisconnet = 0; + BT_INST(dev)->priv_data = data; + isbtready = 1; + + //usb_debug("btmtk_usb_probe end\n"); + return 0; +} + +//--------------------------------------------------------------------------- +void LD_btmtk_usb_disconnect(mtkbt_dev_t *dev) +{ + struct LD_btmtk_usb_data *data = BT_INST(dev)->priv_data; + + usb_debug("\n"); + + if (!data) + return; + + isbtready = 0; + metaCount = 0; + + if (data->need_load_rom_patch) + os_kfree(data->rom_patch); + + if (data->need_load_fw) + os_kfree(data->fw_image); + + usb_debug("unregister bt irq\n"); + + isUsbDisconnet = 1; + usb_debug("btmtk: stop all URB\n"); + os_kfree(data->io_buf); + os_kfree(data); +} + +//--------------------------------------------------------------------------- diff --git a/board/amlogic/tm2_ab301_v1/mtk-bt/LD_btmtk_usb.h b/board/amlogic/tm2_ab301_v1/mtk-bt/LD_btmtk_usb.h new file mode 100644 index 0000000000..68e90c5fa6 --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/mtk-bt/LD_btmtk_usb.h @@ -0,0 +1,127 @@ +#ifndef __LD_BTMTK_USB_H__ +#define __LD_BTMTK_USB_H__ + +#include "LD_usbbt.h" + +/* Memory map for MTK BT */ +/* SYS Control */ +#define SYSCTL 0x400000 + +/* WLAN */ +#define WLAN 0x410000 + +/* MCUCTL */ +#define CLOCK_CTL 0x0708 +#define INT_LEVEL 0x0718 +#define COM_REG0 0x0730 +#define SEMAPHORE_00 0x07B0 +#define SEMAPHORE_01 0x07B4 +#define SEMAPHORE_02 0x07B8 +#define SEMAPHORE_03 0x07BC + +/* Chip definition */ + +#define CONTROL_TIMEOUT_JIFFIES (300) +#define DEVICE_VENDOR_REQUEST_OUT 0x40 +#define DEVICE_VENDOR_REQUEST_IN 0xc0 +#define DEVICE_CLASS_REQUEST_OUT 0x20 +#define DEVICE_CLASS_REQUEST_IN 0xa0 + +#define BTUSB_MAX_ISOC_FRAMES 10 +#define BTUSB_INTR_RUNNING 0 +#define BTUSB_BULK_RUNNING 1 +#define BTUSB_ISOC_RUNNING 2 +#define BTUSB_SUSPENDING 3 +#define BTUSB_DID_ISO_RESUME 4 + +/* ROM Patch */ +#define PATCH_HCI_HEADER_SIZE 4 +#define PATCH_WMT_HEADER_SIZE 5 +#define PATCH_HEADER_SIZE (PATCH_HCI_HEADER_SIZE + PATCH_WMT_HEADER_SIZE) +#define UPLOAD_PATCH_UNIT 2048 +#define PATCH_INFO_SIZE 30 +#define PATCH_PHASE1 1 +#define PATCH_PHASE2 2 +#define PATCH_PHASE3 3 + +#define LD_BT_MAX_EVENT_SIZE 260 +#define BD_ADDR_LEN 6 + +#define WAKE_DEV_RECORD "wake_on_ble.conf" +#define WAKE_DEV_RECORD_PATH "/data/misc/bluedroid" +#define WOBLE_SETTING_FILE_NAME "woble_setting.bin" +#define APCF_SETTING_COUNT 10 + +typedef enum { + TYPE_APCF_CMD, +} woble_setting_type; + +struct apcf_cmd_tlv { + //u8 type + u8 len; + u8 *value; +}; + +struct LD_btmtk_usb_data { + mtkbt_dev_t *udev; /* store the usb device informaiton */ + + unsigned long flags; + int meta_tx; + HC_IF *hcif; + + u8 cmdreq_type; + + unsigned int sco_num; + int isoc_altsetting; + int suspend_count; + + /* request for different io operation */ + u8 w_request; + u8 r_request; + + /* io buffer for usb control transfer */ + unsigned char *io_buf; + + unsigned char *fw_image; + unsigned char *fw_header_image; + unsigned char *fw_bin_file_name; + + unsigned char *rom_patch; + unsigned char *rom_patch_header_image; + unsigned char *rom_patch_bin_file_name; + u32 chip_id; + u8 need_load_fw; + u8 need_load_rom_patch; + u32 rom_patch_offset; + u32 rom_patch_len; + u32 fw_len; + + u8 local_addr[BD_ADDR_LEN]; + u8 *woble_setting; + u32 woble_setting_len; + u8 *wake_dev; /* ADDR:NAP-UAP-LAP, VID/PID:Both Little endian */ + u32 wake_dev_len; + struct apcf_cmd_tlv apcf_cmd[APCF_SETTING_COUNT]; +}; + + +int LD_btmtk_usb_probe(mtkbt_dev_t *dev); +void LD_btmtk_usb_disconnect(mtkbt_dev_t *dev); +void LD_btmtk_usb_SetWoble(mtkbt_dev_t *dev); + +#define REV_MT76x2E3 0x0022 + +#define MT_REV_LT(_data, _chip, _rev) \ + is_##_chip(_data) && (((_data)->chip_id & 0x0000ffff) < (_rev)) + +#define MT_REV_GTE(_data, _chip, _rev) \ + is_##_chip(_data) && (((_data)->chip_id & 0x0000ffff) >= (_rev)) + +/* + * Load code method + */ +enum LOAD_CODE_METHOD { + BIN_FILE_METHOD, + HEADER_METHOD, +}; +#endif diff --git a/board/amlogic/tm2_ab301_v1/mtk-bt/LD_usbbt.c b/board/amlogic/tm2_ab301_v1/mtk-bt/LD_usbbt.c new file mode 100644 index 0000000000..1aa46e13aa --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/mtk-bt/LD_usbbt.c @@ -0,0 +1,448 @@ +#include <command.h> +#include <common.h> +#include <usb.h> +#include <stdio_dev.h> +#include "LD_usbbt.h" +#include "LD_btmtk_usb.h" + +/* Reset BT-module */ +extern void reset_mt7668(void); + +os_usb_vid_pid array_mtk_vid_pid[] = { + {0x0E8D, 0x7668, "MTK7668"}, // 7668 + {0x0E8D, 0x76A0, "MTK7662T"}, // 7662T + {0x0E8D, 0x76A1, "MTK7632T"}, // 7632T +}; + +int max_mtk_wifi_id = (sizeof(array_mtk_vid_pid) / sizeof(array_mtk_vid_pid[0])); +os_usb_vid_pid *pmtk_wifi = &array_mtk_vid_pid[0]; + +static mtkbt_dev_t *g_DrvData = NULL; + +/* Amlogic need do adaptation. */ +extern int vfs_mount(char *volume); +extern unsigned long vfs_getsize(char *filedir); +extern int vfs_read(void* addr,char* filedir,unsigned int offset,unsigned int size ); + +VOID *os_memcpy(VOID *dst, const VOID *src, UINT32 len) +{ + return memcpy(dst, src, len); +} + +VOID *os_memmove(VOID *dest, const void *src,UINT32 len) +{ + return memmove(dest, src, len); +} + +VOID *os_memset(VOID *s, int c, size_t n) +{ + return memset(s,c,n); +} + +VOID *os_kzalloc(size_t size, unsigned int flags) +{ + VOID *ptr = malloc(size); + + os_memset(ptr, 0, size); + return ptr; +} + +void LD_load_code_from_bin(unsigned char **image, char *bin_name, char *path, mtkbt_dev_t *dev, u32 *code_len) +{ + char mtk_patch_bin_patch[128] = "\0"; + + /** implement by MTK + * path: /system/etc/firmware/mt76XX_patch_eX_hdr.bin + * If argument "path" is NULL, access "/system/etc/firmware" directly like as request_firmware + * if argument "path" is not NULL, so far only support directory "userdata" + * NOTE: latest vfs_mount seems decided this time access directory + */ + if (path == NULL && vfs_mount("system") != 0) { + usb_debug("vfs_mount - system fail\n"); + return; + } else if (path != NULL && vfs_mount("userdata") != 0) { + usb_debug("vfs_mount - userdata fail\n"); + return; + } + + if (path) { + snprintf(mtk_patch_bin_patch, sizeof(mtk_patch_bin_patch), "%s/%s", path, bin_name); + printf("File: %s\n", mtk_patch_bin_patch); + } else { + snprintf(mtk_patch_bin_patch, sizeof(mtk_patch_bin_patch), "%s/%s", "/vendor/firmware", bin_name); + printf("mtk_patch_bin_patch: %s\n", mtk_patch_bin_patch); + } + *code_len = vfs_getsize(mtk_patch_bin_patch); + if (*code_len == 0) { + usb_debug("Get file size fail\n"); + return; + } + + // malloc buffer to store bt patch file data + *image = malloc(*code_len); + if (vfs_read(*image, mtk_patch_bin_patch, 0, *code_len) != 0) + { + usb_debug("vfs_read fail\n"); + return; + } + usb_debug("Load file OK\n"); + //usb_dump((unsigned int)*image, 0x200); //Amlogic had better dump the first segment of fw data. + return; +} + +static int usb_bt_bulk_msg( + mtkbt_dev_t *dev, + u32 epType, + u8 *data, + int size, + int* realsize, + int timeout /* not used */ +) +{ + int ret =0 ; + if (dev == NULL || dev->udev == NULL || dev->bulk_tx_ep == NULL) + { + usb_debug("bulk out error 00\n"); + return -1; + } + + //usb_debug("[usb_bt_bulk_msg]ep_addr:%x\n", dev->bulk_tx_ep->bEndpointAddress); + //usb_debug("[usb_bt_bulk_msg]ep_maxpkt:%x\n", dev->bulk_tx_ep->wMaxPacketSize); + + if (epType == MTKBT_BULK_TX_EP) + { + ret = usb_bulk_msg(dev->udev,usb_sndbulkpipe(dev->udev,dev->bulk_tx_ep->bEndpointAddress),data,size,realsize,2000); + + if (ret) + { + usb_debug("bulk out error 01\n"); + return -1; + } + + if (*realsize == size) + { + //usb_debug("bulk out success 01,size =0x%x\n",size); + return 0; + } + else + { + usb_debug("bulk out fail 02,size =0x%x,realsize =0x%x\n",size,*realsize); + } + } + return -1; +} + +static int usb_bt_control_msg( + mtkbt_dev_t *dev, + u32 epType, + u8 request, + u8 requesttype, + u16 value, + u16 index, + u8 *data, + int data_length, + int timeout /* not used */ +) +{ + int ret = -1; + if (epType == MTKBT_CTRL_TX_EP) + { + ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), request, + requesttype, value, index, data, data_length,timeout); + } + else if (epType == MTKBT_CTRL_RX_EP) + { + ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), request, + requesttype, value, index, data, data_length,timeout); + } + else + { + usb_debug("control message wrong Type =0x%x\n",epType); + } + + if (ret < 0) + { + usb_debug("Err1(%d)\n", ret); + return ret; + } + return ret; +} + +static int usb_bt_interrupt_msg( + mtkbt_dev_t *dev, + u32 epType, + u8 *data, + int size, + int* realsize, + int timeout /* unit of 1ms */ +) +{ + int ret = -1; + + usb_debug("epType = 0x%x\n",epType); + + if (epType == MTKBT_INTR_EP) + { + ret = usb_submit_int_msg(dev->udev,usb_rcvintpipe(dev->udev,dev->intr_ep->bEndpointAddress),data,size,realsize,timeout); + } + + if (ret < 0 ) + { + usb_debug("Err1(%d)\n", ret); + return ret; + } + usb_debug("ret = 0x%x\n",ret); + return ret; +} + +static HC_IF usbbt_host_interface = +{ + usb_bt_bulk_msg, + usb_bt_control_msg, + usb_bt_interrupt_msg, +}; + +static void Ldbtusb_diconnect (btusbdev_t *dev) +{ + LD_btmtk_usb_disconnect(g_DrvData); + + if (g_DrvData) + { + os_kfree(g_DrvData); + } + g_DrvData = NULL; +} + +static int Ldbtusb_SetWoble(btusbdev_t *dev) +{ + if (!g_DrvData) + { + usb_debug("usb set woble fail ,because no drv data\n"); + return -1; + } + else + { + LD_btmtk_usb_SetWoble(g_DrvData); + usb_debug("usb set woble end\n"); + } + return 0; +} + +int Ldbtusb_connect (btusbdev_t *dev) +{ + int ret = 0; + + struct usb_endpoint_descriptor *ep_desc; + struct usb_interface *iface; + int i; + iface = &dev->config.if_desc[0]; + + if (g_DrvData == NULL) + { + g_DrvData = os_kmalloc(sizeof(mtkbt_dev_t),MTK_GFP_ATOMIC); + + if (!g_DrvData) + { + usb_debug("Not enough memory for mtkbt virtual usb device.\n"); + return -1; + } + else + { + os_memset(g_DrvData,0,sizeof(mtkbt_dev_t)); + g_DrvData->udev = dev; + g_DrvData->connect = Ldbtusb_connect; + g_DrvData->disconnect = Ldbtusb_diconnect; + g_DrvData->SetWoble = Ldbtusb_SetWoble; + } + } + else + { + return -1; + } + + for (i = 0; i < iface->desc.bNumEndpoints; i++) + { + ep_desc = &iface->ep_desc[i]; + + if ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) + { + if (ep_desc->bEndpointAddress & USB_DIR_IN) + { + g_DrvData->bulk_rx_ep = ep_desc; + } + else + { + g_DrvData->bulk_tx_ep = ep_desc; + } + continue; + } + + /* is it an interrupt endpoint? */ + if ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) + { + g_DrvData->intr_ep = ep_desc; + continue; + } + } + if (!g_DrvData->intr_ep || !g_DrvData->bulk_tx_ep || !g_DrvData->bulk_rx_ep) + { + os_kfree(g_DrvData); + g_DrvData = NULL; + usb_debug("btmtk_usb_probe end Error 3\n"); + return -1; + } + + /* Init HostController interface */ + g_DrvData->hci_if = &usbbt_host_interface; + + /* btmtk init */ + ret = LD_btmtk_usb_probe(g_DrvData); + + if (ret != 0) + { + usb_debug("usb probe fail\n"); + if (g_DrvData) + { + os_kfree(g_DrvData); + } + g_DrvData = NULL; + return -1; + } + else + { + usb_debug("usbbt probe success\n"); + } + return ret; +} + +static int checkUsbDevicePort(struct usb_device* udev, u16 vendorID, u16 productID, u8 port) +{ + struct usb_device* pdev = NULL; + int i; +#if defined (CONFIG_USB_PREINIT) + usb_stop(port); + if (usb_post_init(port) == 0) +#else + /* Attention: + * if BT_USB_PORT_NUM is defined, + * Amlogic can only initialize MTK7668 USB port, but NOT all ports. + */ + usb_stop(); + if (usb_init() == 0) //if (usb_init(port) == 0) +#endif + { + /* get device */ + for (i=0; i<USB_MAX_DEVICE; i++) { + pdev = usb_get_dev_index(i); + printf("pdev->descriptor.idVendor=0x%x; pdev->descriptor.idProduct=0x%x\n",pdev->descriptor.idVendor,pdev->descriptor.idProduct); + if ((pdev != NULL) && (pdev->descriptor.idVendor == vendorID) && (pdev->descriptor.idProduct == productID)) // MTK 7662 + { + usb_debug("OK\n"); + memcpy(udev, pdev, sizeof(struct usb_device)); + return 0 ; + } + } + } + return -1; +} + +static int findUsbDevice(struct usb_device* udev) +{ + int ret = -1; + u8 idx = 0; + u8 i = 0; + usb_debug("IN\n"); + if (udev == NULL) + { + usb_error("udev can not be NULL\n"); + return -1; + } + +#ifdef BT_USB_PORT_NUM + /* check mtk bt usb port */ + idx = BT_USB_PORT_NUM; + usb_debug("find mtk bt usb device from usb port[%d]\n", idx); + while (i < 1 /*max_mtk_wifi_id*/) { + ret = checkUsbDevicePort(udev, (pmtk_wifi + i)->vid, (pmtk_wifi + i)->pid, idx); + if (ret == 0) break; + i++; + } + if (ret == 0) + { + return 0; + } +#else + // not find mt bt usb device from given usb port, so poll every usb port. + char portNumStr[10] = "\0"; + #if defined(ENABLE_FIFTH_EHC) + const char u8UsbPortCount = 5; + #elif defined(ENABLE_FOURTH_EHC) + const char u8UsbPortCount = 4; + #elif defined(ENABLE_THIRD_EHC) + const char u8UsbPortCount = 3; + #elif defined(ENABLE_SECOND_EHC) + const char u8UsbPortCount = 2; + #else + const char u8UsbPortCount = 1; + #endif + for (idx = 0; idx < u8UsbPortCount; idx++) + { + i = 0; + while (i < max_mtk_wifi_id) { + ret = checkUsbDevicePort(udev, (pmtk_wifi + i)->vid, (pmtk_wifi + i)->pid, idx); + if (ret == 0) break; + i++; + } + if (ret == 0) + { + // set bt_usb_port to store mt bt usb device port + snprintf(portNumStr, sizeof(portNumStr), "%d", idx); + setenv(BT_USB_PORT, portNumStr); + saveenv(); + return 0; + } + } +#endif + + usb_error("Not find usb device\n"); + return -1; +} + +int do_setMtkBT( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int ret = 0; + struct usb_device udev; + memset(&udev, 0, sizeof(struct usb_device)); + usb_debug("IN\n"); + if (argc < 1) + { + cmd_usage(cmdtp); + return -1; + } + + /* Reset BT-module */ + reset_mt7668(); + + // MTK USB controller + ret = findUsbDevice(&udev); + if (ret != 0) + { + usb_error("find bt usb device failed\n"); + return -1; + } + ret = Ldbtusb_connect(&udev); + if (ret != 0) + { + usb_error("connect to bt usb device failed\n"); + return -1; + } + ret = Ldbtusb_SetWoble(&udev); + if (ret != 0) + { + usb_error("set bt usb device woble cmd failed\n"); + return -1; + } + usb_debug("OK\n"); + return ret; +} + diff --git a/board/amlogic/tm2_ab301_v1/mtk-bt/LD_usbbt.h b/board/amlogic/tm2_ab301_v1/mtk-bt/LD_usbbt.h new file mode 100644 index 0000000000..3fcf8d89d8 --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/mtk-bt/LD_usbbt.h @@ -0,0 +1,129 @@ +/* + * This file is part of the libpayload project. + * + * Copyright (C) 2008-2010 coresystems GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __LD_USBBT_H__ +#define __LD_USBBT_H__ +#include <common.h> +#include <malloc.h> +#include <usb.h> + +#define MTKBT_CTRL_TX_EP 0 +#define MTKBT_CTRL_RX_EP 1 +#define MTKBT_INTR_EP 2 +#define MTKBT_BULK_TX_EP 3 +#define MTKBT_BULK_RX_EP 4 + +#define MTK_GFP_ATOMIC 1 + +#define CRC_CHECK 0 + +#define BTLDER "[BT-LOADER] " +#define USB_TYPE_STANDARD (0x00 << 5) +#define USB_TYPE_CLASS (0x01 << 5) +#define USB_TYPE_VENDOR (0x02 << 5) +#define USB_TYPE_RESERVED (0x03 << 5) + +#define USB_DEBUG + +#ifdef USB_DEBUG +#define usb_debug(fmt,...) printf("%s: "fmt, __func__, ##__VA_ARGS__) +#else +#define usb_debug(fmt,...) +#endif + +#define usb_error(fmt,...) \ + printf("%s: "fmt, __func__, ##__VA_ARGS__) + +#define os_kmalloc(size,flags) malloc(size) +#define os_kfree(ptr) free(ptr) + +#define MTK_UDELAY(x) udelay(x) +#define MTK_MDELAY(x) mdelay(x) + + +//#define btusbdev_t struct usb_interface +#define btusbdev_t struct usb_device + +#undef NULL +#define NULL ((void *)0) +#define s32 signed int +#ifndef TRUE + #define TRUE 1 +#endif +#ifndef FALSE + #define FALSE 0 +#endif + +#ifndef VOID +#define VOID void +#endif + +typedef unsigned int UINT32; +typedef signed int INT32; +typedef unsigned char UINT8; +typedef unsigned long ULONG; +typedef unsigned char BOOL; + +typedef struct __USBBT_DEVICE__ mtkbt_dev_t; + +typedef struct { + int (*usb_bulk_msg) (mtkbt_dev_t *dev, u32 epType, u8 *data, int size, int* realsize, int timeout); + int (*usb_control_msg) (mtkbt_dev_t *dev, u32 epType, u8 request, u8 requesttype, u16 value, u16 index, + u8 *data, int data_length, int timeout); + int (*usb_interrupt_msg)(mtkbt_dev_t *dev, u32 epType, u8 *data, int size, int* realsize, int timeout); +} HC_IF; + +struct __USBBT_DEVICE__ +{ + void *priv_data; + btusbdev_t* intf; + struct usb_device *udev; + struct usb_endpoint_descriptor *intr_ep; + struct usb_endpoint_descriptor *bulk_tx_ep; + struct usb_endpoint_descriptor *bulk_rx_ep; + struct usb_endpoint_descriptor *isoc_tx_ep; + struct usb_endpoint_descriptor *isoc_rx_ep; + HC_IF *hci_if; + int (*connect)(btusbdev_t *dev); + void (*disconnect)(btusbdev_t *dev); + int (*SetWoble)(btusbdev_t *dev); +};//mtkbt_dev_t; + +#define BT_INST(dev) (dev) + +int Ldbtusb_connect (btusbdev_t *dev); +VOID *os_memcpy(VOID *dst, const VOID *src, UINT32 len); +VOID *os_memmove(VOID *dest, const void *src,UINT32 len); +VOID *os_memset(VOID *s, int c, size_t n); +VOID *os_kzalloc(size_t size, unsigned int flags); + +void LD_load_code_from_bin(unsigned char **image, char *bin_name, char *path, mtkbt_dev_t *dev,u32 *code_len); + +int do_setMtkBT( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +#endif diff --git a/board/amlogic/tm2_ab301_v1/mtk-bt/cmd_btmtk.c b/board/amlogic/tm2_ab301_v1/mtk-bt/cmd_btmtk.c new file mode 100644 index 0000000000..c287cab663 --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/mtk-bt/cmd_btmtk.c @@ -0,0 +1,40 @@ +#include <command.h> +#include <common.h> +#include "LD_usbbt.h" + +extern int fwGetFileSize(const char *file_path); +extern int fwReadFileToBuffer(const char *file_path, unsigned char data_buf[]); + +int vfs_mount(char *volume) +{ + return 0; +} + +/* Amlogic need to implement. */ +unsigned long vfs_getsize(char *filedir) +{ + int fileSize = 0; + fileSize = fwGetFileSize(filedir); + if (fileSize > 0) + { + printf("vfs_getsize %s size is %d\n", filedir, fileSize); + return fileSize; + } + + printf("vfs_getsize %s failed\n", filedir); + return 0; +} + +/* Amlogic need to implement. */ +int vfs_read(void *addr, char *filedir, unsigned int offset, unsigned int size) +{ + int ret = -1; + ret = fwReadFileToBuffer(filedir, addr); + if (ret > 0) + { + printf("vfs_read load %s to buffer success\n", filedir); + return 0; + } + printf("vfs_read load %s failed\n", filedir); + return -1; +} diff --git a/board/amlogic/tm2_ab301_v1/mtk-bt/errno.h b/board/amlogic/tm2_ab301_v1/mtk-bt/errno.h new file mode 100644 index 0000000000..5a4806deba --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/mtk-bt/errno.h @@ -0,0 +1,131 @@ +#ifndef _GENERIC_ERRNO_H +#define _GENERIC_ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + +#endif diff --git a/board/amlogic/tm2_ab301_v1/mtk-bt/fs_platform.c b/board/amlogic/tm2_ab301_v1/mtk-bt/fs_platform.c new file mode 100644 index 0000000000..33a7ac38d4 --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/mtk-bt/fs_platform.c @@ -0,0 +1,141 @@ +#include <command.h> +#include <common.h> +#include <emmc_partitions.h> +#include <fs.h> + +#define CS_BLCOK_DEV_INTERFACE "mmc" +#define CS_BLCOK_DEV_MARJOR_NUM "1" +#define CC_MAX_INI_FILE_NAME_LEN (512) +#define CC_MAX_INI_FILE_LINE_LEN (256) + +/*File functions*/ +static int splitFilePath(const char *file_path, char part_name[], char file_name[], const char *ext_name) { + int i = 0; + char *tmp_start_ptr = NULL; + char *tmp_end_ptr = NULL; + + if (file_path == NULL) { + printf("%s, file_path is NULL!!!\n", __FUNCTION__); + return -1; + } + + tmp_start_ptr = strchr((char*)file_path,'/'); + if (tmp_start_ptr != file_path) { + printf("%s, we need one abstract file path!!! %s.\n", __FUNCTION__, file_path); + return -1; + } + + tmp_end_ptr = strchr(tmp_start_ptr + 1,'/'); + if (tmp_end_ptr == NULL) { + printf("%s, there is only partition name in the path!!!\n", __FUNCTION__); + return -1; + } + + strncpy(part_name, tmp_start_ptr + 1, tmp_end_ptr - tmp_start_ptr - 1); + part_name[tmp_end_ptr - tmp_start_ptr - 1] = '\0'; + /*ALOGD("%s, partition name is %s\n", __FUNCTION__, part_name);*/ + + tmp_start_ptr = tmp_end_ptr; + + i = 0; + while (*tmp_end_ptr && i < CC_MAX_INI_FILE_NAME_LEN) { + tmp_end_ptr++; + i++; + } + if (i >= CC_MAX_INI_FILE_NAME_LEN) { + printf("%s, file path is too long (%d)!!!\n", __FUNCTION__, i); + return -1; + } + + strncpy(file_name, tmp_start_ptr, i); + file_name[i] = '\0'; + /*ALOGD("%s, file name is %s\n", __FUNCTION__, file_name);*/ + + if (ext_name != NULL) { + if (strlen(ext_name) > 0) { + while (tmp_end_ptr != tmp_start_ptr && *tmp_end_ptr != '.') { + tmp_end_ptr--; + } + + if (*tmp_end_ptr != '.') { + printf("%s, the file path \"%s\" doesn't have ext name!!!\n", __FUNCTION__, file_path); + return -1; + } else { + if (strncmp(tmp_end_ptr + 1, ext_name, 128)) { + printf("%s, the ext name of file path \"%s\" not equal to the special ext name \"%s\"!!!\n", __FUNCTION__, file_path, ext_name); + return -1; + } + } + } + } + + return 0; +} + +static int setBlockDevice_fs(const char *part_name) { + int part_no = 0; + char part_buf[128] = {0}; + char tmp_buf[128] = {0}; + printf("set blk\n"); + part_no = get_partition_num_by_name((char *)part_name); + /*printf("%s, part_no is %d\n", __FUNCTION__, part_no);*/ + if (part_no >= 0) { + strcpy(part_buf, CS_BLCOK_DEV_MARJOR_NUM); + strcat(part_buf, ":"); + + sprintf(tmp_buf, "%x", part_no); + strcat(part_buf, tmp_buf); + + return fs_set_blk_dev(CS_BLCOK_DEV_INTERFACE, part_buf, FS_TYPE_EXT); + } + printf("set blk done\n"); + return -1; +} + +int fwGetFileSize(const char *file_path) { + loff_t file_size = 0; + char part_name[CC_MAX_INI_FILE_NAME_LEN]; + char file_name[CC_MAX_INI_FILE_NAME_LEN]; + + memset((void *)part_name, 0, CC_MAX_INI_FILE_NAME_LEN); + memset((void *)file_name, 0, CC_MAX_INI_FILE_NAME_LEN); + if (splitFilePath(file_path, part_name, file_name, NULL) < 0) { + return -1; + } + printf("setBlockDevice_fs start ....\n"); + if (setBlockDevice_fs(part_name) < 0) { + return -1; + } + printf("setBlockDevice_fs %s end ....\n",file_name); + if (fs_size(file_name, &file_size)) { + return -1; + } + printf("setBlockDevice_fs %s end ....\n",file_name); + return file_size; +} + +int fwReadFileToBuffer(const char *file_path,unsigned char data_buf[]) { + + int tmp_ret = -1; + loff_t rd_cnt = 0; + char part_name[CC_MAX_INI_FILE_NAME_LEN]; + char file_name[CC_MAX_INI_FILE_NAME_LEN]; + + memset((void *)part_name, 0, CC_MAX_INI_FILE_NAME_LEN); + memset((void *)file_name, 0, CC_MAX_INI_FILE_NAME_LEN); + if (splitFilePath(file_path, part_name, file_name, NULL) < 0) { + return -1; + } + + if (setBlockDevice_fs(part_name) < 0) { + return -1; + } + + tmp_ret = fs_read(file_name, (unsigned long)data_buf, 0, 0, &rd_cnt); + if (tmp_ret < 0) { + return -1; + } + + flush_dcache_range((unsigned long )data_buf, (unsigned long )data_buf + rd_cnt); + return rd_cnt; +} diff --git a/board/amlogic/tm2_ab301_v1/tm2_ab301_v1.c b/board/amlogic/tm2_ab301_v1/tm2_ab301_v1.c new file mode 100644 index 0000000000..2a71ca978c --- /dev/null +++ b/board/amlogic/tm2_ab301_v1/tm2_ab301_v1.c @@ -0,0 +1,798 @@ + +/* + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <common.h> +#include <malloc.h> +#include <errno.h> +#include <environment.h> +#include <fdt_support.h> +#include <libfdt.h> +#include <asm/cpu_id.h> +#include <asm/arch/secure_apb.h> +#ifdef CONFIG_SYS_I2C_AML +#include <aml_i2c.h> +#endif +#ifdef CONFIG_SYS_I2C_MESON +#include <amlogic/i2c.h> +#endif +#ifdef CONFIG_PWM_MESON +#include <pwm.h> +#include <amlogic/pwm.h> +#endif +#include <dm.h> +#ifdef CONFIG_AML_VPU +#include <vpu.h> +#endif +#include <vpp.h> +#ifdef CONFIG_AML_V2_FACTORY_BURN +#include <amlogic/aml_v2_burning.h> +#endif// #ifdef CONFIG_AML_V2_FACTORY_BURN +#ifdef CONFIG_AML_HDMITX20 +#include <amlogic/hdmi.h> +#endif +#ifdef CONFIG_AML_LCD +#include <amlogic/aml_lcd.h> +#endif +#include <asm/arch/eth_setup.h> +#include <phy.h> +#include <linux/mtd/partitions.h> +#include <linux/sizes.h> +#include <asm-generic/gpio.h> +#include <dm.h> +#ifdef CONFIG_AML_SPIFC +#include <amlogic/spifc.h> +#endif +#ifdef CONFIG_AML_SPICC +#include <amlogic/spicc.h> +#endif + +DECLARE_GLOBAL_DATA_PTR; + +//new static eth setup +struct eth_board_socket* eth_board_skt; + + +int serial_set_pin_port(unsigned long port_base) +{ + //UART in "Always On Module" + //GPIOAO_0==tx,GPIOAO_1==rx + //setbits_le32(P_AO_RTI_PIN_MUX_REG,3<<11); + return 0; +} + +int dram_init(void) +{ + gd->ram_size = PHYS_SDRAM_1_SIZE; + return 0; +} + +/* secondary_boot_func + * this function should be write with asm, here, is is only for compiling pass + * */ +void secondary_boot_func(void) +{ +} +#ifdef ETHERNET_INTERNAL_PHY +void internalPhyConfig(struct phy_device *phydev) +{ +} + +static int dwmac_meson_cfg_pll(void) +{ + writel(0x39C0040A, P_ETH_PLL_CTL0); + writel(0x927E0000, P_ETH_PLL_CTL1); + writel(0xAC5F49E5, P_ETH_PLL_CTL2); + writel(0x00000000, P_ETH_PLL_CTL3); + udelay(200); + writel(0x19C0040A, P_ETH_PLL_CTL0); + return 0; +} + +static int dwmac_meson_cfg_analog(void) +{ + /*Analog*/ + writel(0x20200000, P_ETH_PLL_CTL5); + writel(0x0000c002, P_ETH_PLL_CTL6); + writel(0x00000023, P_ETH_PLL_CTL7); + + return 0; +} + +static int dwmac_meson_cfg_ctrl(void) +{ + /*config phyid should between a 0~0xffffffff*/ + /*please don't use 44000181, this has been used by internal phy*/ + writel(0x33000180, P_ETH_PHY_CNTL0); + + /*use_phy_smi | use_phy_ip | co_clkin from eth_phy_top*/ + writel(0x260, P_ETH_PHY_CNTL2); + + writel(0x74043, P_ETH_PHY_CNTL1); + writel(0x34043, P_ETH_PHY_CNTL1); + writel(0x74043, P_ETH_PHY_CNTL1); + return 0; +} + +static void setup_net_chip(void) +{ + eth_aml_reg0_t eth_reg0; + + eth_reg0.d32 = 0; + eth_reg0.b.phy_intf_sel = 4; + eth_reg0.b.rx_clk_rmii_invert = 0; + eth_reg0.b.rgmii_tx_clk_src = 0; + eth_reg0.b.rgmii_tx_clk_phase = 0; + eth_reg0.b.rgmii_tx_clk_ratio = 4; + eth_reg0.b.phy_ref_clk_enable = 1; + eth_reg0.b.clk_rmii_i_invert = 1; + eth_reg0.b.clk_en = 1; + eth_reg0.b.adj_enable = 1; + eth_reg0.b.adj_setup = 0; + eth_reg0.b.adj_delay = 9; + eth_reg0.b.adj_skew = 0; + eth_reg0.b.cali_start = 0; + eth_reg0.b.cali_rise = 0; + eth_reg0.b.cali_sel = 0; + eth_reg0.b.rgmii_rx_reuse = 0; + eth_reg0.b.eth_urgent = 0; + setbits_le32(P_PREG_ETH_REG0, eth_reg0.d32);// rmii mode + + dwmac_meson_cfg_pll(); + dwmac_meson_cfg_analog(); + dwmac_meson_cfg_ctrl(); + + /* eth core clock */ + setbits_le32(HHI_GCLK_MPEG1, (0x1 << 3)); + /* eth phy clock */ + setbits_le32(HHI_GCLK_MPEG0, (0x1 << 4)); + + /* eth phy pll, clk50m */ + setbits_le32(HHI_FIX_PLL_CNTL3, (0x1 << 5)); + + /* power on memory */ + clrbits_le32(HHI_MEM_PD_REG0, (1 << 3) | (1<<2)); +} +#endif + +#ifdef ETHERNET_EXTERNAL_PHY + +static int dwmac_meson_cfg_drive_strength(void) +{ + writel(0xaaaaaaa5, P_PAD_DS_REG4A); + return 0; +} + +static void setup_net_chip_ext(void) +{ + eth_aml_reg0_t eth_reg0; + writel(0x11111111, P_PERIPHS_PIN_MUX_6); + writel(0x111111, P_PERIPHS_PIN_MUX_7); + + eth_reg0.d32 = 0; + eth_reg0.b.phy_intf_sel = 1; + eth_reg0.b.rx_clk_rmii_invert = 0; + eth_reg0.b.rgmii_tx_clk_src = 0; + eth_reg0.b.rgmii_tx_clk_phase = 1; + eth_reg0.b.rgmii_tx_clk_ratio = 4; + eth_reg0.b.phy_ref_clk_enable = 1; + eth_reg0.b.clk_rmii_i_invert = 0; + eth_reg0.b.clk_en = 1; + eth_reg0.b.adj_enable = 0; + eth_reg0.b.adj_setup = 0; + eth_reg0.b.adj_delay = 0; + eth_reg0.b.adj_skew = 0; + eth_reg0.b.cali_start = 0; + eth_reg0.b.cali_rise = 0; + eth_reg0.b.cali_sel = 0; + eth_reg0.b.rgmii_rx_reuse = 0; + eth_reg0.b.eth_urgent = 0; + setbits_le32(P_PREG_ETH_REG0, eth_reg0.d32);// rmii mode + + setbits_le32(HHI_GCLK_MPEG1, 0x1 << 3); + /* power on memory */ + clrbits_le32(HHI_MEM_PD_REG0, (1 << 3) | (1<<2)); +} +#endif +extern struct eth_board_socket* eth_board_setup(char *name); +extern int designware_initialize(ulong base_addr, u32 interface); + +int board_eth_init(bd_t *bis) +{ +#ifdef CONFIG_ETHERNET_NONE + return 0; +#endif + +#ifdef ETHERNET_EXTERNAL_PHY + dwmac_meson_cfg_drive_strength(); + setup_net_chip_ext(); +#endif +#ifdef ETHERNET_INTERNAL_PHY + setup_net_chip(); +#endif + udelay(1000); + designware_initialize(ETH_BASE, PHY_INTERFACE_MODE_RMII); + return 0; +} + +#if CONFIG_AML_SD_EMMC +#include <mmc.h> +#include <asm/arch/sd_emmc.h> +static int sd_emmc_init(unsigned port) +{ + switch (port) + { + case SDIO_PORT_A: + break; + case SDIO_PORT_B: + //todo add card detect + /* check card detect */ + clrbits_le32(P_PERIPHS_PIN_MUX_9, 0xF << 24); + setbits_le32(P_PREG_PAD_GPIO1_EN_N, 1 << 6); + setbits_le32(P_PAD_PULL_UP_EN_REG1, 1 << 6); + setbits_le32(P_PAD_PULL_UP_REG1, 1 << 6); + break; + case SDIO_PORT_C: + //enable pull up + //clrbits_le32(P_PAD_PULL_UP_REG3, 0xff<<0); + break; + default: + break; + } + + return cpu_sd_emmc_init(port); +} + +extern unsigned sd_debug_board_1bit_flag; + + +static void sd_emmc_pwr_prepare(unsigned port) +{ + cpu_sd_emmc_pwr_prepare(port); +} + +static void sd_emmc_pwr_on(unsigned port) +{ + switch (port) + { + case SDIO_PORT_A: + break; + case SDIO_PORT_B: +// clrbits_le32(P_PREG_PAD_GPIO5_O,(1<<31)); //CARD_8 +// clrbits_le32(P_PREG_PAD_GPIO5_EN_N,(1<<31)); + /// @todo NOT FINISH + break; + case SDIO_PORT_C: + break; + default: + break; + } + return; +} +static void sd_emmc_pwr_off(unsigned port) +{ + /// @todo NOT FINISH + switch (port) + { + case SDIO_PORT_A: + break; + case SDIO_PORT_B: +// setbits_le32(P_PREG_PAD_GPIO5_O,(1<<31)); //CARD_8 +// clrbits_le32(P_PREG_PAD_GPIO5_EN_N,(1<<31)); + break; + case SDIO_PORT_C: + break; + default: + break; + } + return; +} + +// #define CONFIG_TSD 1 +static void board_mmc_register(unsigned port) +{ + struct aml_card_sd_info *aml_priv=cpu_sd_emmc_get(port); + if (aml_priv == NULL) + return; + + aml_priv->sd_emmc_init=sd_emmc_init; + aml_priv->sd_emmc_detect=sd_emmc_detect; + aml_priv->sd_emmc_pwr_off=sd_emmc_pwr_off; + aml_priv->sd_emmc_pwr_on=sd_emmc_pwr_on; + aml_priv->sd_emmc_pwr_prepare=sd_emmc_pwr_prepare; + aml_priv->desc_buf = malloc(NEWSD_MAX_DESC_MUN*(sizeof(struct sd_emmc_desc_info))); + + if (NULL == aml_priv->desc_buf) + printf(" desc_buf Dma alloc Fail!\n"); + else + printf("aml_priv->desc_buf = 0x%p\n",aml_priv->desc_buf); + + sd_emmc_register(aml_priv); +} +int board_mmc_init(bd_t *bis) +{ +#ifdef CONFIG_VLSI_EMULATOR + //board_mmc_register(SDIO_PORT_A); +#else + //board_mmc_register(SDIO_PORT_B); +#endif + board_mmc_register(SDIO_PORT_B); + board_mmc_register(SDIO_PORT_C); +// board_mmc_register(SDIO_PORT_B1); + return 0; +} + +#ifdef CONFIG_SYS_I2C_AML +#if 0 +static void board_i2c_set_pinmux(void){ + /*********************************************/ + /* | I2C_Master_AO |I2C_Slave | */ + /*********************************************/ + /* | I2C_SCK | I2C_SCK_SLAVE | */ + /* GPIOAO_4 | [AO_PIN_MUX: 6] | [AO_PIN_MUX: 2] | */ + /*********************************************/ + /* | I2C_SDA | I2C_SDA_SLAVE | */ + /* GPIOAO_5 | [AO_PIN_MUX: 5] | [AO_PIN_MUX: 1] | */ + /*********************************************/ + + //disable all other pins which share with I2C_SDA_AO & I2C_SCK_AO + clrbits_le32(P_AO_RTI_PIN_MUX_REG, ((1<<2)|(1<<24)|(1<<1)|(1<<23))); + //enable I2C MASTER AO pins + setbits_le32(P_AO_RTI_PIN_MUX_REG, + (MESON_I2C_MASTER_AO_GPIOAO_4_BIT | MESON_I2C_MASTER_AO_GPIOAO_5_BIT)); + + udelay(10); +}; +#endif +struct aml_i2c_platform g_aml_i2c_plat = { + .wait_count = 1000000, + .wait_ack_interval = 5, + .wait_read_interval = 5, + .wait_xfer_interval = 5, + .master_no = AML_I2C_MASTER_AO, + .use_pio = 0, + .master_i2c_speed = AML_I2C_SPPED_400K, + .master_ao_pinmux = { + .scl_reg = (unsigned long)MESON_I2C_MASTER_AO_GPIOAO_4_REG, + .scl_bit = MESON_I2C_MASTER_AO_GPIOAO_4_BIT, + .sda_reg = (unsigned long)MESON_I2C_MASTER_AO_GPIOAO_5_REG, + .sda_bit = MESON_I2C_MASTER_AO_GPIOAO_5_BIT, + } +}; +#if 0 +static void board_i2c_init(void) +{ + //set I2C pinmux with PCB board layout + board_i2c_set_pinmux(); + + //Amlogic I2C controller initialized + //note: it must be call before any I2C operation + aml_i2c_init(); + + udelay(10); +} +#endif +#endif +#endif + +#if defined(CONFIG_BOARD_EARLY_INIT_F) +int board_early_init_f(void){ + /*add board early init function here*/ + return 0; +} +#endif + +#ifdef CONFIG_USB_XHCI_AMLOGIC_V2 +#include <asm/arch/usb-v2.h> +#include <asm/arch/gpio.h> +#define CONFIG_GXL_USB_U2_PORT_NUM CONFIG_USB_U2_PORT_NUM + +#ifdef CONFIG_USB_XHCI_AMLOGIC_USB3_V2 +#define CONFIG_GXL_USB_U3_PORT_NUM 1 +#else +#define CONFIG_GXL_USB_U3_PORT_NUM 0 +#endif +#if 0 +static void gpio_set_vbus_power(char is_power_on) +{ + int ret; + + ret = gpio_request(CONFIG_USB_GPIO_PWR, + CONFIG_USB_GPIO_PWR_NAME); + if (ret && ret != -EBUSY) { + printf("gpio: requesting pin %u failed\n", + CONFIG_USB_GPIO_PWR); + return; + } + + if (is_power_on) { + gpio_direction_output(CONFIG_USB_GPIO_PWR, 1); + } else { + gpio_direction_output(CONFIG_USB_GPIO_PWR, 0); + } +} +#endif +struct amlogic_usb_config g_usb_config_GXL_skt={ + CONFIG_GXL_XHCI_BASE, + USB_ID_MODE_HARDWARE, + NULL,//gpio_set_vbus_power,//gpio_set_vbus_power, //set_vbus_power + CONFIG_GXL_USB_PHY2_BASE, + CONFIG_GXL_USB_PHY3_BASE, + CONFIG_GXL_USB_U2_PORT_NUM, + CONFIG_GXL_USB_U3_PORT_NUM, + .usb_phy2_pll_base_addr = { + CONFIG_USB_PHY_20, + CONFIG_USB_PHY_21, + CONFIG_USB_PHY_22, + } +}; + +#endif /*CONFIG_USB_XHCI_AMLOGIC*/ + +#ifdef CONFIG_AML_HDMITX20 +static void hdmi_tx_set_hdmi_5v(void) +{ +} +#endif + +/* + * mtd nand partition table, only care the size! + * offset will be calculated by nand driver. + */ +#ifdef CONFIG_AML_MTD +static struct mtd_partition normal_partition_info[] = { +#ifdef CONFIG_DISCRETE_BOOTLOADER + /* MUST NOT CHANGE this part unless u know what you are doing! + * inherent parition for descrete bootloader to store fip + * size is determind by TPL_SIZE_PER_COPY*TPL_COPY_NUM + * name must be same with TPL_PART_NAME + */ + { + .name = "tpl", + .offset = 0, + .size = 0, + }, +#endif + { + .name = "logo", + .offset = 0, + .size = 2*SZ_1M, + }, + { + .name = "recovery", + .offset = 0, + .size = 16*SZ_1M, + }, + { + .name = "boot", + .offset = 0, + .size = 16*SZ_1M, + }, + { + .name = "system", + .offset = 0, + .size = 64*SZ_1M, + }, + /* last partition get the rest capacity */ + { + .name = "data", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; +struct mtd_partition *get_aml_mtd_partition(void) +{ + return normal_partition_info; +} +int get_aml_partition_count(void) +{ + return ARRAY_SIZE(normal_partition_info); +} +#endif /* CONFIG_AML_MTD */ + +#ifdef CONFIG_AML_SPIFC +/* + * BOOT_3: NOR_HOLDn:reg0[15:12]=3 + * BOOT_4: NOR_D:reg0[19:16]=3 + * BOOT_5: NOR_Q:reg0[23:20]=3 + * BOOT_6: NOR_C:reg0[27:24]=3 + * BOOT_7: NOR_WPn:reg0[31:28]=3 + * BOOT_13: NOR_CS:reg1[23:20]=3 + */ +#define SPIFC_NUM_CS 1 +static int spifc_cs_gpios[SPIFC_NUM_CS] = {GPIOEE(BOOT_13)}; + +static int spifc_pinctrl_enable(void *pinctrl, bool enable) +{ + unsigned int val; + + val = readl(P_PERIPHS_PIN_MUX_0); + val &= ~(0xfffff << 12); + if (enable) + val |= 0x33333 << 12; + writel(val, P_PERIPHS_PIN_MUX_0); + + val = readl(P_PERIPHS_PIN_MUX_1); + val &= ~(0xf << 20); + writel(val, P_PERIPHS_PIN_MUX_1); + return 0; +} + +static const struct spifc_platdata spifc_platdata = { + .reg = 0xffd14000, + .mem_map = 0xf6000000, + .pinctrl_enable = spifc_pinctrl_enable, + .num_chipselect = SPIFC_NUM_CS, + .cs_gpios = spifc_cs_gpios, +}; + +U_BOOT_DEVICE(spifc) = { + .name = "spifc", + .platdata = &spifc_platdata, +}; +#endif /* CONFIG_AML_SPIFC */ + +#ifdef CONFIG_AML_SPICC +/* generic config in arch gpio/clock.c */ +extern int spicc0_clk_set_rate(int rate); +extern int spicc0_clk_enable(bool enable); +extern int spicc0_pinctrl_enable(bool enable); + +static const struct spicc_platdata spicc0_platdata = { + .compatible = "amlogic,meson-g12a-spicc", + .reg = (void __iomem *)0xffd13000, + .clk_rate = 666666666, + .clk_set_rate = spicc0_clk_set_rate, + .clk_enable = spicc0_clk_enable, + .pinctrl_enable = spicc0_pinctrl_enable, + /* case one slave without cs: {"no_cs", 0} */ + .cs_gpio_names = {"GPIOH_20", 0}, +}; + +U_BOOT_DEVICE(spicc0) = { + .name = "spicc", + .platdata = &spicc0_platdata, +}; +#endif /* CONFIG_AML_SPICC */ + +extern void aml_pwm_cal_init(int mode); + +#ifdef CONFIG_SYS_I2C_MESON +static const struct meson_i2c_platdata i2c_data[] = { + { 0, 0xffd1f000, 166666666, 3, 15, 100000 }, + { 1, 0xffd1e000, 166666666, 3, 15, 100000 }, + { 2, 0xffd1d000, 166666666, 3, 15, 100000 }, + { 3, 0xffd1c000, 166666666, 3, 15, 100000 }, + { 4, 0xff805000, 166666666, 3, 15, 100000 }, +}; + +U_BOOT_DEVICES(meson_i2cs) = { + { "i2c_meson", &i2c_data[0] }, + { "i2c_meson", &i2c_data[1] }, + { "i2c_meson", &i2c_data[2] }, + { "i2c_meson", &i2c_data[3] }, + { "i2c_meson", &i2c_data[4] }, +}; + +/* + *GPIOAO_10//I2C_SDA_AO + *GPIOAO_11//I2C_SCK_AO + *pinmux configuration seperated with i2c controller configuration + * config it when you use + */ +void set_i2c_ao_pinmux(void) +{ + return; +} +#endif /*end CONFIG_SYS_I2C_MESON*/ + +#ifdef CONFIG_PWM_MESON +static const struct meson_pwm_platdata pwm_data[] = { + { PWM_AB, 0xffd1b000, IS_DOUBLE_CHANNEL, IS_BLINK }, + { PWM_CD, 0xffd1a000, IS_DOUBLE_CHANNEL, IS_BLINK }, + { PWM_EF, 0xffd19000, IS_DOUBLE_CHANNEL, IS_BLINK }, + { PWMAO_AB, 0xff807000, IS_DOUBLE_CHANNEL, IS_BLINK }, + { PWMAO_CD, 0xff802000, IS_DOUBLE_CHANNEL, IS_BLINK }, +}; + +U_BOOT_DEVICES(meson_pwm) = { + { "amlogic,general-pwm", &pwm_data[0] }, + { "amlogic,general-pwm", &pwm_data[1] }, + { "amlogic,general-pwm", &pwm_data[2] }, + { "amlogic,general-pwm", &pwm_data[3] }, + { "amlogic,general-pwm", &pwm_data[4] }, +}; +#endif /*end CONFIG_PWM_MESON*/ + +int board_init(void) +{ + int val; + + /* For usb reboot sequence,set GPIOAO_2 low in bl2_stage_init, set high here */ + val = readl(AO_GPIO_O); + val |= 1 << 3; + writel(val, AO_GPIO_O); + //Please keep CONFIG_AML_V2_FACTORY_BURN at first place of board_init + //As NOT NEED other board init If USB BOOT MODE +#ifdef CONFIG_AML_V2_FACTORY_BURN + if ((0x1b8ec003 != readl(P_PREG_STICKY_REG2)) && (0x1b8ec004 != readl(P_PREG_STICKY_REG2))) { + aml_try_factory_usb_burning(0, gd->bd); + } +#endif// #ifdef CONFIG_AML_V2_FACTORY_BURN +#ifdef CONFIG_USB_XHCI_AMLOGIC_V2 + board_usb_pll_disable(&g_usb_config_GXL_skt); + board_usb_init(&g_usb_config_GXL_skt,BOARD_USB_MODE_HOST); +#endif /*CONFIG_USB_XHCI_AMLOGIC*/ + +#if 0 + aml_pwm_cal_init(0); +#endif// +#ifdef CONFIG_AML_NAND + extern int amlnf_init(unsigned char flag); + amlnf_init(0); +#endif +#ifdef CONFIG_SYS_I2C_MESON + set_i2c_ao_pinmux(); +#endif + return 0; +} + +#ifdef CONFIG_BOARD_LATE_INIT +/* Reset BT-module */ +void reset_mt7668(void) +{ + /* Reset BT-module by reset-pin -- GPIOAO_5 */ + clrbits_le32(P_AO_GPIO_O_EN_N, 1 << 5); + clrbits_le32(P_AO_GPIO_O_EN_N, 1 << 21); + mdelay(200); + setbits_le32(P_AO_GPIO_O_EN_N, 1 << 21); + mdelay(100); +} +int board_late_init(void) +{ + //update env before anyone using it + run_command("get_rebootmode; echo reboot_mode=${reboot_mode}; "\ + "if test ${reboot_mode} = factory_reset; then "\ + "defenv_reserv;setenv upgrade_step 2;save; fi;", 0); + run_command("if itest ${upgrade_step} == 1; then "\ + "defenv_reserv; setenv upgrade_step 2; saveenv; fi;", 0); + /*add board late init function here*/ +#ifndef DTB_BIND_KERNEL + int ret; + ret = run_command("store dtb read $dtb_mem_addr", 1); + if (ret) { + printf("%s(): [store dtb read $dtb_mem_addr] fail\n", __func__); +#ifdef CONFIG_DTB_MEM_ADDR + char cmd[64]; + printf("load dtb to %x\n", CONFIG_DTB_MEM_ADDR); + sprintf(cmd, "store dtb read %x", CONFIG_DTB_MEM_ADDR); + ret = run_command(cmd, 1); + if (ret) { + printf("%s(): %s fail\n", __func__, cmd); + } +#endif + } +#elif defined(CONFIG_DTB_MEM_ADDR) + { + char cmd[128]; + int ret; + if (!getenv("dtb_mem_addr")) { + sprintf(cmd, "setenv dtb_mem_addr 0x%x", CONFIG_DTB_MEM_ADDR); + run_command(cmd, 0); + } + sprintf(cmd, "imgread dtb boot ${dtb_mem_addr}"); + ret = run_command(cmd, 0); + if (ret) { + printf("%s(): cmd[%s] fail, ret=%d\n", __func__, cmd, ret); + } + } +#endif// #ifndef DTB_BIND_KERNEL + + /* load unifykey */ + run_command("keyunify init 0x1234", 0); +#ifdef CONFIG_AML_VPU + vpu_probe(); +#endif + vpp_init(); + + run_command("ini_model", 0); +#ifdef CONFIG_AML_HDMITX20 + hdmi_tx_set_hdmi_5v(); + hdmi_tx_init(); +#endif +#ifdef CONFIG_AML_CVBS + run_command("cvbs init", 0); +#endif +#ifdef CONFIG_AML_LCD + lcd_probe(); +#endif + +#ifdef CONFIG_AML_V2_FACTORY_BURN + if (0x1b8ec003 == readl(P_PREG_STICKY_REG2)) + aml_try_factory_usb_burning(1, gd->bd); + aml_try_factory_sdcard_burning(0, gd->bd); +#endif// #ifdef CONFIG_AML_V2_FACTORY_BURN + + return 0; +} +#endif + +#ifdef CONFIG_AML_TINY_USBTOOL +int usb_get_update_result(void) +{ + unsigned long upgrade_step; + upgrade_step = simple_strtoul (getenv ("upgrade_step"), NULL, 16); + printf("upgrade_step = %d\n", (int)upgrade_step); + if (upgrade_step == 1) + { + run_command("defenv", 1); + run_command("setenv upgrade_step 2", 1); + run_command("saveenv", 1); + return 0; + } + else + { + return -1; + } +} +#endif + +phys_size_t get_effective_memsize(void) +{ + // >>16 -> MB, <<20 -> real size, so >>16<<20 = <<4 +#if defined(CONFIG_SYS_MEM_TOP_HIDE) + return (((readl(AO_SEC_GP_CFG0)) & 0xFFFF0000) << 4) - CONFIG_SYS_MEM_TOP_HIDE; +#else + return (((readl(AO_SEC_GP_CFG0)) & 0xFFFF0000) << 4); +#endif +} + +#ifdef CONFIG_MULTI_DTB +int checkhw(char * name) +{ + char loc_name[64] = {0}; + + /* add your logic code here */ + + + /* set aml_dt */ + strcpy(name, loc_name); + setenv("aml_dt", loc_name); + return 0; +} +#endif + +extern int do_setMtkBT( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +U_BOOT_CMD( + setMtkBT, CONFIG_SYS_MAXARGS, 1, do_setMtkBT, + "load MTK BT driver, and set woble\n", + NULL +); + +const char * const _env_args_reserve_[] = +{ + "aml_dt", + "firstboot", + "lock", + "upgrade_step", + "model_name", + + NULL//Keep NULL be last to tell END +}; + |