18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Purna Chandra Mandal, purna.mandal@microchip.com 48c2ecf20Sopenharmony_ci * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci#include <linux/init.h> 78c2ecf20Sopenharmony_ci#include <linux/io.h> 88c2ecf20Sopenharmony_ci#include <linux/of_platform.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <asm/mach-pic32/pic32.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include "pic32mzda.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#define PIC32_CFGCON 0x0000 158c2ecf20Sopenharmony_ci#define PIC32_DEVID 0x0020 168c2ecf20Sopenharmony_ci#define PIC32_SYSKEY 0x0030 178c2ecf20Sopenharmony_ci#define PIC32_CFGEBIA 0x00c0 188c2ecf20Sopenharmony_ci#define PIC32_CFGEBIC 0x00d0 198c2ecf20Sopenharmony_ci#define PIC32_CFGCON2 0x00f0 208c2ecf20Sopenharmony_ci#define PIC32_RCON 0x1240 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic void __iomem *pic32_conf_base; 238c2ecf20Sopenharmony_cistatic DEFINE_SPINLOCK(config_lock); 248c2ecf20Sopenharmony_cistatic u32 pic32_reset_status; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistatic u32 pic32_conf_get_reg_field(u32 offset, u32 rshift, u32 mask) 278c2ecf20Sopenharmony_ci{ 288c2ecf20Sopenharmony_ci u32 v; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci v = readl(pic32_conf_base + offset); 318c2ecf20Sopenharmony_ci v >>= rshift; 328c2ecf20Sopenharmony_ci v &= mask; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci return v; 358c2ecf20Sopenharmony_ci} 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistatic u32 pic32_conf_modify_atomic(u32 offset, u32 mask, u32 set) 388c2ecf20Sopenharmony_ci{ 398c2ecf20Sopenharmony_ci u32 v; 408c2ecf20Sopenharmony_ci unsigned long flags; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci spin_lock_irqsave(&config_lock, flags); 438c2ecf20Sopenharmony_ci v = readl(pic32_conf_base + offset); 448c2ecf20Sopenharmony_ci v &= ~mask; 458c2ecf20Sopenharmony_ci v |= (set & mask); 468c2ecf20Sopenharmony_ci writel(v, pic32_conf_base + offset); 478c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&config_lock, flags); 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci return 0; 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ciint pic32_enable_lcd(void) 538c2ecf20Sopenharmony_ci{ 548c2ecf20Sopenharmony_ci return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), BIT(31)); 558c2ecf20Sopenharmony_ci} 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ciint pic32_disable_lcd(void) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), 0); 608c2ecf20Sopenharmony_ci} 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ciint pic32_set_lcd_mode(int mode) 638c2ecf20Sopenharmony_ci{ 648c2ecf20Sopenharmony_ci u32 mask = mode ? BIT(30) : 0; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(30), mask); 678c2ecf20Sopenharmony_ci} 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ciint pic32_set_sdhci_adma_fifo_threshold(u32 rthrsh, u32 wthrsh) 708c2ecf20Sopenharmony_ci{ 718c2ecf20Sopenharmony_ci u32 clr, set; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci clr = (0x3ff << 4) | (0x3ff << 16); 748c2ecf20Sopenharmony_ci set = (rthrsh << 4) | (wthrsh << 16); 758c2ecf20Sopenharmony_ci return pic32_conf_modify_atomic(PIC32_CFGCON2, clr, set); 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_civoid pic32_syskey_unlock_debug(const char *func, const ulong line) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci void __iomem *syskey = pic32_conf_base + PIC32_SYSKEY; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci pr_debug("%s: called from %s:%lu\n", __func__, func, line); 838c2ecf20Sopenharmony_ci writel(0x00000000, syskey); 848c2ecf20Sopenharmony_ci writel(0xAA996655, syskey); 858c2ecf20Sopenharmony_ci writel(0x556699AA, syskey); 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistatic u32 pic32_get_device_id(void) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci return pic32_conf_get_reg_field(PIC32_DEVID, 0, 0x0fffffff); 918c2ecf20Sopenharmony_ci} 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic u32 pic32_get_device_version(void) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci return pic32_conf_get_reg_field(PIC32_DEVID, 28, 0xf); 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ciu32 pic32_get_boot_status(void) 998c2ecf20Sopenharmony_ci{ 1008c2ecf20Sopenharmony_ci return pic32_reset_status; 1018c2ecf20Sopenharmony_ci} 1028c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pic32_get_boot_status); 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_civoid __init pic32_config_init(void) 1058c2ecf20Sopenharmony_ci{ 1068c2ecf20Sopenharmony_ci pic32_conf_base = ioremap(PIC32_BASE_CONFIG, 0x110); 1078c2ecf20Sopenharmony_ci if (!pic32_conf_base) 1088c2ecf20Sopenharmony_ci panic("pic32: config base not mapped"); 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci /* Boot Status */ 1118c2ecf20Sopenharmony_ci pic32_reset_status = readl(pic32_conf_base + PIC32_RCON); 1128c2ecf20Sopenharmony_ci writel(-1, PIC32_CLR(pic32_conf_base + PIC32_RCON)); 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci /* Device Inforation */ 1158c2ecf20Sopenharmony_ci pr_info("Device Id: 0x%08x, Device Ver: 0x%04x\n", 1168c2ecf20Sopenharmony_ci pic32_get_device_id(), 1178c2ecf20Sopenharmony_ci pic32_get_device_version()); 1188c2ecf20Sopenharmony_ci} 119