18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2013-2016 Freescale Semiconductor Inc. 48c2ecf20Sopenharmony_ci * Copyright 2016-2018 NXP 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/fsl/mc.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include "dprtc.h" 108c2ecf20Sopenharmony_ci#include "dprtc-cmd.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/** 138c2ecf20Sopenharmony_ci * dprtc_open() - Open a control session for the specified object. 148c2ecf20Sopenharmony_ci * @mc_io: Pointer to MC portal's I/O object 158c2ecf20Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 168c2ecf20Sopenharmony_ci * @dprtc_id: DPRTC unique ID 178c2ecf20Sopenharmony_ci * @token: Returned token; use in subsequent API calls 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * This function can be used to open a control session for an 208c2ecf20Sopenharmony_ci * already created object; an object may have been declared in 218c2ecf20Sopenharmony_ci * the DPL or by calling the dprtc_create function. 228c2ecf20Sopenharmony_ci * This function returns a unique authentication token, 238c2ecf20Sopenharmony_ci * associated with the specific object ID and the specific MC 248c2ecf20Sopenharmony_ci * portal; this token must be used in all subsequent commands for 258c2ecf20Sopenharmony_ci * this specific object 268c2ecf20Sopenharmony_ci * 278c2ecf20Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_ciint dprtc_open(struct fsl_mc_io *mc_io, 308c2ecf20Sopenharmony_ci u32 cmd_flags, 318c2ecf20Sopenharmony_ci int dprtc_id, 328c2ecf20Sopenharmony_ci u16 *token) 338c2ecf20Sopenharmony_ci{ 348c2ecf20Sopenharmony_ci struct dprtc_cmd_open *cmd_params; 358c2ecf20Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 368c2ecf20Sopenharmony_ci int err; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPRTC_CMDID_OPEN, 398c2ecf20Sopenharmony_ci cmd_flags, 408c2ecf20Sopenharmony_ci 0); 418c2ecf20Sopenharmony_ci cmd_params = (struct dprtc_cmd_open *)cmd.params; 428c2ecf20Sopenharmony_ci cmd_params->dprtc_id = cpu_to_le32(dprtc_id); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci err = mc_send_command(mc_io, &cmd); 458c2ecf20Sopenharmony_ci if (err) 468c2ecf20Sopenharmony_ci return err; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci *token = mc_cmd_hdr_read_token(&cmd); 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci return 0; 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci/** 548c2ecf20Sopenharmony_ci * dprtc_close() - Close the control session of the object 558c2ecf20Sopenharmony_ci * @mc_io: Pointer to MC portal's I/O object 568c2ecf20Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 578c2ecf20Sopenharmony_ci * @token: Token of DPRTC object 588c2ecf20Sopenharmony_ci * 598c2ecf20Sopenharmony_ci * After this function is called, no further operations are 608c2ecf20Sopenharmony_ci * allowed on the object without opening a new control session. 618c2ecf20Sopenharmony_ci * 628c2ecf20Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 638c2ecf20Sopenharmony_ci */ 648c2ecf20Sopenharmony_ciint dprtc_close(struct fsl_mc_io *mc_io, 658c2ecf20Sopenharmony_ci u32 cmd_flags, 668c2ecf20Sopenharmony_ci u16 token) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPRTC_CMDID_CLOSE, cmd_flags, 718c2ecf20Sopenharmony_ci token); 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci return mc_send_command(mc_io, &cmd); 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci/** 778c2ecf20Sopenharmony_ci * dprtc_set_irq_enable() - Set overall interrupt state. 788c2ecf20Sopenharmony_ci * @mc_io: Pointer to MC portal's I/O object 798c2ecf20Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 808c2ecf20Sopenharmony_ci * @token: Token of DPRTC object 818c2ecf20Sopenharmony_ci * @irq_index: The interrupt index to configure 828c2ecf20Sopenharmony_ci * @en: Interrupt state - enable = 1, disable = 0 838c2ecf20Sopenharmony_ci * 848c2ecf20Sopenharmony_ci * Allows GPP software to control when interrupts are generated. 858c2ecf20Sopenharmony_ci * Each interrupt can have up to 32 causes. The enable/disable control's the 868c2ecf20Sopenharmony_ci * overall interrupt state. if the interrupt is disabled no causes will cause 878c2ecf20Sopenharmony_ci * an interrupt. 888c2ecf20Sopenharmony_ci * 898c2ecf20Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 908c2ecf20Sopenharmony_ci */ 918c2ecf20Sopenharmony_ciint dprtc_set_irq_enable(struct fsl_mc_io *mc_io, 928c2ecf20Sopenharmony_ci u32 cmd_flags, 938c2ecf20Sopenharmony_ci u16 token, 948c2ecf20Sopenharmony_ci u8 irq_index, 958c2ecf20Sopenharmony_ci u8 en) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci struct dprtc_cmd_set_irq_enable *cmd_params; 988c2ecf20Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPRTC_CMDID_SET_IRQ_ENABLE, 1018c2ecf20Sopenharmony_ci cmd_flags, 1028c2ecf20Sopenharmony_ci token); 1038c2ecf20Sopenharmony_ci cmd_params = (struct dprtc_cmd_set_irq_enable *)cmd.params; 1048c2ecf20Sopenharmony_ci cmd_params->irq_index = irq_index; 1058c2ecf20Sopenharmony_ci cmd_params->en = en; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci return mc_send_command(mc_io, &cmd); 1088c2ecf20Sopenharmony_ci} 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci/** 1118c2ecf20Sopenharmony_ci * dprtc_get_irq_enable() - Get overall interrupt state 1128c2ecf20Sopenharmony_ci * @mc_io: Pointer to MC portal's I/O object 1138c2ecf20Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1148c2ecf20Sopenharmony_ci * @token: Token of DPRTC object 1158c2ecf20Sopenharmony_ci * @irq_index: The interrupt index to configure 1168c2ecf20Sopenharmony_ci * @en: Returned interrupt state - enable = 1, disable = 0 1178c2ecf20Sopenharmony_ci * 1188c2ecf20Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 1198c2ecf20Sopenharmony_ci */ 1208c2ecf20Sopenharmony_ciint dprtc_get_irq_enable(struct fsl_mc_io *mc_io, 1218c2ecf20Sopenharmony_ci u32 cmd_flags, 1228c2ecf20Sopenharmony_ci u16 token, 1238c2ecf20Sopenharmony_ci u8 irq_index, 1248c2ecf20Sopenharmony_ci u8 *en) 1258c2ecf20Sopenharmony_ci{ 1268c2ecf20Sopenharmony_ci struct dprtc_rsp_get_irq_enable *rsp_params; 1278c2ecf20Sopenharmony_ci struct dprtc_cmd_get_irq *cmd_params; 1288c2ecf20Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 1298c2ecf20Sopenharmony_ci int err; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPRTC_CMDID_GET_IRQ_ENABLE, 1328c2ecf20Sopenharmony_ci cmd_flags, 1338c2ecf20Sopenharmony_ci token); 1348c2ecf20Sopenharmony_ci cmd_params = (struct dprtc_cmd_get_irq *)cmd.params; 1358c2ecf20Sopenharmony_ci cmd_params->irq_index = irq_index; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci err = mc_send_command(mc_io, &cmd); 1388c2ecf20Sopenharmony_ci if (err) 1398c2ecf20Sopenharmony_ci return err; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci rsp_params = (struct dprtc_rsp_get_irq_enable *)cmd.params; 1428c2ecf20Sopenharmony_ci *en = rsp_params->en; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci return 0; 1458c2ecf20Sopenharmony_ci} 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci/** 1488c2ecf20Sopenharmony_ci * dprtc_set_irq_mask() - Set interrupt mask. 1498c2ecf20Sopenharmony_ci * @mc_io: Pointer to MC portal's I/O object 1508c2ecf20Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1518c2ecf20Sopenharmony_ci * @token: Token of DPRTC object 1528c2ecf20Sopenharmony_ci * @irq_index: The interrupt index to configure 1538c2ecf20Sopenharmony_ci * @mask: Event mask to trigger interrupt; 1548c2ecf20Sopenharmony_ci * each bit: 1558c2ecf20Sopenharmony_ci * 0 = ignore event 1568c2ecf20Sopenharmony_ci * 1 = consider event for asserting IRQ 1578c2ecf20Sopenharmony_ci * 1588c2ecf20Sopenharmony_ci * Every interrupt can have up to 32 causes and the interrupt model supports 1598c2ecf20Sopenharmony_ci * masking/unmasking each cause independently 1608c2ecf20Sopenharmony_ci * 1618c2ecf20Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 1628c2ecf20Sopenharmony_ci */ 1638c2ecf20Sopenharmony_ciint dprtc_set_irq_mask(struct fsl_mc_io *mc_io, 1648c2ecf20Sopenharmony_ci u32 cmd_flags, 1658c2ecf20Sopenharmony_ci u16 token, 1668c2ecf20Sopenharmony_ci u8 irq_index, 1678c2ecf20Sopenharmony_ci u32 mask) 1688c2ecf20Sopenharmony_ci{ 1698c2ecf20Sopenharmony_ci struct dprtc_cmd_set_irq_mask *cmd_params; 1708c2ecf20Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPRTC_CMDID_SET_IRQ_MASK, 1738c2ecf20Sopenharmony_ci cmd_flags, 1748c2ecf20Sopenharmony_ci token); 1758c2ecf20Sopenharmony_ci cmd_params = (struct dprtc_cmd_set_irq_mask *)cmd.params; 1768c2ecf20Sopenharmony_ci cmd_params->mask = cpu_to_le32(mask); 1778c2ecf20Sopenharmony_ci cmd_params->irq_index = irq_index; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci return mc_send_command(mc_io, &cmd); 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci/** 1838c2ecf20Sopenharmony_ci * dprtc_get_irq_mask() - Get interrupt mask. 1848c2ecf20Sopenharmony_ci * @mc_io: Pointer to MC portal's I/O object 1858c2ecf20Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1868c2ecf20Sopenharmony_ci * @token: Token of DPRTC object 1878c2ecf20Sopenharmony_ci * @irq_index: The interrupt index to configure 1888c2ecf20Sopenharmony_ci * @mask: Returned event mask to trigger interrupt 1898c2ecf20Sopenharmony_ci * 1908c2ecf20Sopenharmony_ci * Every interrupt can have up to 32 causes and the interrupt model supports 1918c2ecf20Sopenharmony_ci * masking/unmasking each cause independently 1928c2ecf20Sopenharmony_ci * 1938c2ecf20Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 1948c2ecf20Sopenharmony_ci */ 1958c2ecf20Sopenharmony_ciint dprtc_get_irq_mask(struct fsl_mc_io *mc_io, 1968c2ecf20Sopenharmony_ci u32 cmd_flags, 1978c2ecf20Sopenharmony_ci u16 token, 1988c2ecf20Sopenharmony_ci u8 irq_index, 1998c2ecf20Sopenharmony_ci u32 *mask) 2008c2ecf20Sopenharmony_ci{ 2018c2ecf20Sopenharmony_ci struct dprtc_rsp_get_irq_mask *rsp_params; 2028c2ecf20Sopenharmony_ci struct dprtc_cmd_get_irq *cmd_params; 2038c2ecf20Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 2048c2ecf20Sopenharmony_ci int err; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPRTC_CMDID_GET_IRQ_MASK, 2078c2ecf20Sopenharmony_ci cmd_flags, 2088c2ecf20Sopenharmony_ci token); 2098c2ecf20Sopenharmony_ci cmd_params = (struct dprtc_cmd_get_irq *)cmd.params; 2108c2ecf20Sopenharmony_ci cmd_params->irq_index = irq_index; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci err = mc_send_command(mc_io, &cmd); 2138c2ecf20Sopenharmony_ci if (err) 2148c2ecf20Sopenharmony_ci return err; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci rsp_params = (struct dprtc_rsp_get_irq_mask *)cmd.params; 2178c2ecf20Sopenharmony_ci *mask = le32_to_cpu(rsp_params->mask); 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci return 0; 2208c2ecf20Sopenharmony_ci} 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci/** 2238c2ecf20Sopenharmony_ci * dprtc_get_irq_status() - Get the current status of any pending interrupts. 2248c2ecf20Sopenharmony_ci * 2258c2ecf20Sopenharmony_ci * @mc_io: Pointer to MC portal's I/O object 2268c2ecf20Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2278c2ecf20Sopenharmony_ci * @token: Token of DPRTC object 2288c2ecf20Sopenharmony_ci * @irq_index: The interrupt index to configure 2298c2ecf20Sopenharmony_ci * @status: Returned interrupts status - one bit per cause: 2308c2ecf20Sopenharmony_ci * 0 = no interrupt pending 2318c2ecf20Sopenharmony_ci * 1 = interrupt pending 2328c2ecf20Sopenharmony_ci * 2338c2ecf20Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 2348c2ecf20Sopenharmony_ci */ 2358c2ecf20Sopenharmony_ciint dprtc_get_irq_status(struct fsl_mc_io *mc_io, 2368c2ecf20Sopenharmony_ci u32 cmd_flags, 2378c2ecf20Sopenharmony_ci u16 token, 2388c2ecf20Sopenharmony_ci u8 irq_index, 2398c2ecf20Sopenharmony_ci u32 *status) 2408c2ecf20Sopenharmony_ci{ 2418c2ecf20Sopenharmony_ci struct dprtc_cmd_get_irq_status *cmd_params; 2428c2ecf20Sopenharmony_ci struct dprtc_rsp_get_irq_status *rsp_params; 2438c2ecf20Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 2448c2ecf20Sopenharmony_ci int err; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPRTC_CMDID_GET_IRQ_STATUS, 2478c2ecf20Sopenharmony_ci cmd_flags, 2488c2ecf20Sopenharmony_ci token); 2498c2ecf20Sopenharmony_ci cmd_params = (struct dprtc_cmd_get_irq_status *)cmd.params; 2508c2ecf20Sopenharmony_ci cmd_params->status = cpu_to_le32(*status); 2518c2ecf20Sopenharmony_ci cmd_params->irq_index = irq_index; 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci err = mc_send_command(mc_io, &cmd); 2548c2ecf20Sopenharmony_ci if (err) 2558c2ecf20Sopenharmony_ci return err; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci rsp_params = (struct dprtc_rsp_get_irq_status *)cmd.params; 2588c2ecf20Sopenharmony_ci *status = le32_to_cpu(rsp_params->status); 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci return 0; 2618c2ecf20Sopenharmony_ci} 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci/** 2648c2ecf20Sopenharmony_ci * dprtc_clear_irq_status() - Clear a pending interrupt's status 2658c2ecf20Sopenharmony_ci * 2668c2ecf20Sopenharmony_ci * @mc_io: Pointer to MC portal's I/O object 2678c2ecf20Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2688c2ecf20Sopenharmony_ci * @token: Token of DPRTC object 2698c2ecf20Sopenharmony_ci * @irq_index: The interrupt index to configure 2708c2ecf20Sopenharmony_ci * @status: Bits to clear (W1C) - one bit per cause: 2718c2ecf20Sopenharmony_ci * 0 = don't change 2728c2ecf20Sopenharmony_ci * 1 = clear status bit 2738c2ecf20Sopenharmony_ci * 2748c2ecf20Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 2758c2ecf20Sopenharmony_ci */ 2768c2ecf20Sopenharmony_ciint dprtc_clear_irq_status(struct fsl_mc_io *mc_io, 2778c2ecf20Sopenharmony_ci u32 cmd_flags, 2788c2ecf20Sopenharmony_ci u16 token, 2798c2ecf20Sopenharmony_ci u8 irq_index, 2808c2ecf20Sopenharmony_ci u32 status) 2818c2ecf20Sopenharmony_ci{ 2828c2ecf20Sopenharmony_ci struct dprtc_cmd_clear_irq_status *cmd_params; 2838c2ecf20Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPRTC_CMDID_CLEAR_IRQ_STATUS, 2868c2ecf20Sopenharmony_ci cmd_flags, 2878c2ecf20Sopenharmony_ci token); 2888c2ecf20Sopenharmony_ci cmd_params = (struct dprtc_cmd_clear_irq_status *)cmd.params; 2898c2ecf20Sopenharmony_ci cmd_params->irq_index = irq_index; 2908c2ecf20Sopenharmony_ci cmd_params->status = cpu_to_le32(status); 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci return mc_send_command(mc_io, &cmd); 2938c2ecf20Sopenharmony_ci} 294