1*858d4976Smaxims@google.com /* 2*858d4976Smaxims@google.com * Copyright 2017 Google, Inc 3*858d4976Smaxims@google.com * 4*858d4976Smaxims@google.com * SPDX-License-Identifier: GPL-2.0 5*858d4976Smaxims@google.com */ 6*858d4976Smaxims@google.com 7*858d4976Smaxims@google.com #include <common.h> 8*858d4976Smaxims@google.com #include <dm.h> 9*858d4976Smaxims@google.com #include <misc.h> 10*858d4976Smaxims@google.com #include <reset.h> 11*858d4976Smaxims@google.com #include <reset-uclass.h> 12*858d4976Smaxims@google.com #include <wdt.h> 13*858d4976Smaxims@google.com #include <asm/io.h> 14*858d4976Smaxims@google.com #include <asm/arch/scu_ast2500.h> 15*858d4976Smaxims@google.com #include <asm/arch/wdt.h> 16*858d4976Smaxims@google.com 17*858d4976Smaxims@google.com DECLARE_GLOBAL_DATA_PTR; 18*858d4976Smaxims@google.com 19*858d4976Smaxims@google.com struct ast2500_reset_priv { 20*858d4976Smaxims@google.com /* WDT used to perform resets. */ 21*858d4976Smaxims@google.com struct udevice *wdt; 22*858d4976Smaxims@google.com struct ast2500_scu *scu; 23*858d4976Smaxims@google.com }; 24*858d4976Smaxims@google.com 25*858d4976Smaxims@google.com static int ast2500_ofdata_to_platdata(struct udevice *dev) 26*858d4976Smaxims@google.com { 27*858d4976Smaxims@google.com struct ast2500_reset_priv *priv = dev_get_priv(dev); 28*858d4976Smaxims@google.com int ret; 29*858d4976Smaxims@google.com 30*858d4976Smaxims@google.com ret = uclass_get_device_by_phandle(UCLASS_WDT, dev, "aspeed,wdt", 31*858d4976Smaxims@google.com &priv->wdt); 32*858d4976Smaxims@google.com if (ret) { 33*858d4976Smaxims@google.com debug("%s: can't find WDT for reset controller", __func__); 34*858d4976Smaxims@google.com return ret; 35*858d4976Smaxims@google.com } 36*858d4976Smaxims@google.com 37*858d4976Smaxims@google.com return 0; 38*858d4976Smaxims@google.com } 39*858d4976Smaxims@google.com 40*858d4976Smaxims@google.com static int ast2500_reset_assert(struct reset_ctl *reset_ctl) 41*858d4976Smaxims@google.com { 42*858d4976Smaxims@google.com struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev); 43*858d4976Smaxims@google.com u32 reset_mode, reset_mask; 44*858d4976Smaxims@google.com bool reset_sdram; 45*858d4976Smaxims@google.com int ret; 46*858d4976Smaxims@google.com 47*858d4976Smaxims@google.com /* 48*858d4976Smaxims@google.com * To reset SDRAM, a specifal flag in SYSRESET register 49*858d4976Smaxims@google.com * needs to be enabled first 50*858d4976Smaxims@google.com */ 51*858d4976Smaxims@google.com reset_mode = ast_reset_mode_from_flags(reset_ctl->id); 52*858d4976Smaxims@google.com reset_mask = ast_reset_mask_from_flags(reset_ctl->id); 53*858d4976Smaxims@google.com reset_sdram = reset_mode == WDT_CTRL_RESET_SOC && 54*858d4976Smaxims@google.com (reset_mask & WDT_RESET_SDRAM); 55*858d4976Smaxims@google.com 56*858d4976Smaxims@google.com if (reset_sdram) { 57*858d4976Smaxims@google.com ast_scu_unlock(priv->scu); 58*858d4976Smaxims@google.com setbits_le32(&priv->scu->sysreset_ctrl1, 59*858d4976Smaxims@google.com SCU_SYSRESET_SDRAM_WDT); 60*858d4976Smaxims@google.com ret = wdt_expire_now(priv->wdt, reset_ctl->id); 61*858d4976Smaxims@google.com clrbits_le32(&priv->scu->sysreset_ctrl1, 62*858d4976Smaxims@google.com SCU_SYSRESET_SDRAM_WDT); 63*858d4976Smaxims@google.com ast_scu_lock(priv->scu); 64*858d4976Smaxims@google.com } else { 65*858d4976Smaxims@google.com ret = wdt_expire_now(priv->wdt, reset_ctl->id); 66*858d4976Smaxims@google.com } 67*858d4976Smaxims@google.com 68*858d4976Smaxims@google.com return ret; 69*858d4976Smaxims@google.com } 70*858d4976Smaxims@google.com 71*858d4976Smaxims@google.com static int ast2500_reset_request(struct reset_ctl *reset_ctl) 72*858d4976Smaxims@google.com { 73*858d4976Smaxims@google.com debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, 74*858d4976Smaxims@google.com reset_ctl->dev, reset_ctl->id); 75*858d4976Smaxims@google.com 76*858d4976Smaxims@google.com return 0; 77*858d4976Smaxims@google.com } 78*858d4976Smaxims@google.com 79*858d4976Smaxims@google.com static int ast2500_reset_probe(struct udevice *dev) 80*858d4976Smaxims@google.com { 81*858d4976Smaxims@google.com struct ast2500_reset_priv *priv = dev_get_priv(dev); 82*858d4976Smaxims@google.com 83*858d4976Smaxims@google.com priv->scu = ast_get_scu(); 84*858d4976Smaxims@google.com 85*858d4976Smaxims@google.com return 0; 86*858d4976Smaxims@google.com } 87*858d4976Smaxims@google.com 88*858d4976Smaxims@google.com static const struct udevice_id ast2500_reset_ids[] = { 89*858d4976Smaxims@google.com { .compatible = "aspeed,ast2500-reset" }, 90*858d4976Smaxims@google.com { } 91*858d4976Smaxims@google.com }; 92*858d4976Smaxims@google.com 93*858d4976Smaxims@google.com struct reset_ops ast2500_reset_ops = { 94*858d4976Smaxims@google.com .rst_assert = ast2500_reset_assert, 95*858d4976Smaxims@google.com .request = ast2500_reset_request, 96*858d4976Smaxims@google.com }; 97*858d4976Smaxims@google.com 98*858d4976Smaxims@google.com U_BOOT_DRIVER(ast2500_reset) = { 99*858d4976Smaxims@google.com .name = "ast2500_reset", 100*858d4976Smaxims@google.com .id = UCLASS_RESET, 101*858d4976Smaxims@google.com .of_match = ast2500_reset_ids, 102*858d4976Smaxims@google.com .probe = ast2500_reset_probe, 103*858d4976Smaxims@google.com .ops = &ast2500_reset_ops, 104*858d4976Smaxims@google.com .ofdata_to_platdata = ast2500_ofdata_to_platdata, 105*858d4976Smaxims@google.com .priv_auto_alloc_size = sizeof(struct ast2500_reset_priv), 106*858d4976Smaxims@google.com }; 107