399 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef _FIREWIRE_OHCI_H3#define _FIREWIRE_OHCI_H4 5/* OHCI register map */6 7#define OHCI1394_Version 0x0008#define OHCI1394_GUID_ROM 0x0049#define OHCI1394_ATRetries 0x00810#define OHCI1394_CSRData 0x00C11#define OHCI1394_CSRCompareData 0x01012#define OHCI1394_CSRControl 0x01413#define OHCI1394_ConfigROMhdr 0x01814#define OHCI1394_BusID 0x01C15#define OHCI1394_BusOptions 0x02016#define OHCI1394_GUIDHi 0x02417#define OHCI1394_GUIDLo 0x02818#define OHCI1394_ConfigROMmap 0x03419#define OHCI1394_PostedWriteAddressLo 0x03820#define OHCI1394_PostedWriteAddressHi 0x03C21#define OHCI1394_VendorID 0x04022#define OHCI1394_HCControlSet 0x05023#define OHCI1394_HCControlClear 0x05424#define OHCI1394_HCControl_BIBimageValid 0x8000000025#define OHCI1394_HCControl_noByteSwapData 0x4000000026#define OHCI1394_HCControl_programPhyEnable 0x0080000027#define OHCI1394_HCControl_aPhyEnhanceEnable 0x0040000028#define OHCI1394_HCControl_LPS 0x0008000029#define OHCI1394_HCControl_postedWriteEnable 0x0004000030#define OHCI1394_HCControl_linkEnable 0x0002000031#define OHCI1394_HCControl_softReset 0x0001000032#define OHCI1394_SelfIDBuffer 0x06433#define OHCI1394_SelfIDCount 0x06834#define OHCI1394_IRMultiChanMaskHiSet 0x07035#define OHCI1394_IRMultiChanMaskHiClear 0x07436#define OHCI1394_IRMultiChanMaskLoSet 0x07837#define OHCI1394_IRMultiChanMaskLoClear 0x07C38#define OHCI1394_IntEventSet 0x08039#define OHCI1394_IntEventClear 0x08440#define OHCI1394_IntMaskSet 0x08841#define OHCI1394_IntMaskClear 0x08C42#define OHCI1394_IsoXmitIntEventSet 0x09043#define OHCI1394_IsoXmitIntEventClear 0x09444#define OHCI1394_IsoXmitIntMaskSet 0x09845#define OHCI1394_IsoXmitIntMaskClear 0x09C46#define OHCI1394_IsoRecvIntEventSet 0x0A047#define OHCI1394_IsoRecvIntEventClear 0x0A448#define OHCI1394_IsoRecvIntMaskSet 0x0A849#define OHCI1394_IsoRecvIntMaskClear 0x0AC50#define OHCI1394_InitialBandwidthAvailable 0x0B051#define OHCI1394_InitialChannelsAvailableHi 0x0B452#define OHCI1394_InitialChannelsAvailableLo 0x0B853#define OHCI1394_FairnessControl 0x0DC54#define OHCI1394_LinkControlSet 0x0E055#define OHCI1394_LinkControlClear 0x0E456#define OHCI1394_LinkControl_rcvSelfID (1 << 9)57#define OHCI1394_LinkControl_rcvPhyPkt (1 << 10)58#define OHCI1394_LinkControl_cycleTimerEnable (1 << 20)59#define OHCI1394_LinkControl_cycleMaster (1 << 21)60#define OHCI1394_LinkControl_cycleSource (1 << 22)61#define OHCI1394_NodeID 0x0E862#define OHCI1394_NodeID_idValid 0x8000000063#define OHCI1394_NodeID_root 0x4000000064#define OHCI1394_NodeID_nodeNumber 0x0000003f65#define OHCI1394_NodeID_busNumber 0x0000ffc066#define OHCI1394_PhyControl 0x0EC67#define OHCI1394_PhyControl_Read(addr) (((addr) << 8) | 0x00008000)68#define OHCI1394_PhyControl_ReadDone 0x8000000069#define OHCI1394_PhyControl_ReadData(r) (((r) & 0x00ff0000) >> 16)70#define OHCI1394_PhyControl_Write(addr, data) (((addr) << 8) | (data) | 0x00004000)71#define OHCI1394_PhyControl_WritePending 0x0000400072#define OHCI1394_IsochronousCycleTimer 0x0F073#define OHCI1394_AsReqFilterHiSet 0x10074#define OHCI1394_AsReqFilterHiClear 0x10475#define OHCI1394_AsReqFilterLoSet 0x10876#define OHCI1394_AsReqFilterLoClear 0x10C77#define OHCI1394_PhyReqFilterHiSet 0x11078#define OHCI1394_PhyReqFilterHiClear 0x11479#define OHCI1394_PhyReqFilterLoSet 0x11880#define OHCI1394_PhyReqFilterLoClear 0x11C81#define OHCI1394_PhyUpperBound 0x12082 83#define OHCI1394_AsReqTrContextBase 0x18084#define OHCI1394_AsReqTrContextControlSet 0x18085#define OHCI1394_AsReqTrContextControlClear 0x18486#define OHCI1394_AsReqTrCommandPtr 0x18C87 88#define OHCI1394_AsRspTrContextBase 0x1A089#define OHCI1394_AsRspTrContextControlSet 0x1A090#define OHCI1394_AsRspTrContextControlClear 0x1A491#define OHCI1394_AsRspTrCommandPtr 0x1AC92 93#define OHCI1394_AsReqRcvContextBase 0x1C094#define OHCI1394_AsReqRcvContextControlSet 0x1C095#define OHCI1394_AsReqRcvContextControlClear 0x1C496#define OHCI1394_AsReqRcvCommandPtr 0x1CC97 98#define OHCI1394_AsRspRcvContextBase 0x1E099#define OHCI1394_AsRspRcvContextControlSet 0x1E0100#define OHCI1394_AsRspRcvContextControlClear 0x1E4101#define OHCI1394_AsRspRcvCommandPtr 0x1EC102 103/* Isochronous transmit registers */104#define OHCI1394_IsoXmitContextBase(n) (0x200 + 16 * (n))105#define OHCI1394_IsoXmitContextControlSet(n) (0x200 + 16 * (n))106#define OHCI1394_IsoXmitContextControlClear(n) (0x204 + 16 * (n))107#define OHCI1394_IsoXmitCommandPtr(n) (0x20C + 16 * (n))108 109/* Isochronous receive registers */110#define OHCI1394_IsoRcvContextBase(n) (0x400 + 32 * (n))111#define OHCI1394_IsoRcvContextControlSet(n) (0x400 + 32 * (n))112#define OHCI1394_IsoRcvContextControlClear(n) (0x404 + 32 * (n))113#define OHCI1394_IsoRcvCommandPtr(n) (0x40C + 32 * (n))114#define OHCI1394_IsoRcvContextMatch(n) (0x410 + 32 * (n))115 116/* Interrupts Mask/Events */117#define OHCI1394_reqTxComplete 0x00000001118#define OHCI1394_respTxComplete 0x00000002119#define OHCI1394_ARRQ 0x00000004120#define OHCI1394_ARRS 0x00000008121#define OHCI1394_RQPkt 0x00000010122#define OHCI1394_RSPkt 0x00000020123#define OHCI1394_isochTx 0x00000040124#define OHCI1394_isochRx 0x00000080125#define OHCI1394_postedWriteErr 0x00000100126#define OHCI1394_lockRespErr 0x00000200127#define OHCI1394_selfIDComplete 0x00010000128#define OHCI1394_busReset 0x00020000129#define OHCI1394_regAccessFail 0x00040000130#define OHCI1394_phy 0x00080000131#define OHCI1394_cycleSynch 0x00100000132#define OHCI1394_cycle64Seconds 0x00200000133#define OHCI1394_cycleLost 0x00400000134#define OHCI1394_cycleInconsistent 0x00800000135#define OHCI1394_unrecoverableError 0x01000000136#define OHCI1394_cycleTooLong 0x02000000137#define OHCI1394_phyRegRcvd 0x04000000138#define OHCI1394_masterIntEnable 0x80000000139 140#define OHCI1394_evt_no_status 0x0141#define OHCI1394_evt_long_packet 0x2142#define OHCI1394_evt_missing_ack 0x3143#define OHCI1394_evt_underrun 0x4144#define OHCI1394_evt_overrun 0x5145#define OHCI1394_evt_descriptor_read 0x6146#define OHCI1394_evt_data_read 0x7147#define OHCI1394_evt_data_write 0x8148#define OHCI1394_evt_bus_reset 0x9149#define OHCI1394_evt_timeout 0xa150#define OHCI1394_evt_tcode_err 0xb151#define OHCI1394_evt_reserved_b 0xc152#define OHCI1394_evt_reserved_c 0xd153#define OHCI1394_evt_unknown 0xe154#define OHCI1394_evt_flushed 0xf155 156 157// Asynchronous Transmit DMA.158//159// The content of first two quadlets of data for AT DMA is different from the header for IEEE 1394160// asynchronous packet.161 162#define OHCI1394_AT_DATA_Q0_srcBusID_MASK 0x00800000163#define OHCI1394_AT_DATA_Q0_srcBusID_SHIFT 23164#define OHCI1394_AT_DATA_Q0_spd_MASK 0x00070000165#define OHCI1394_AT_DATA_Q0_spd_SHIFT 16166#define OHCI1394_AT_DATA_Q0_tLabel_MASK 0x0000fc00167#define OHCI1394_AT_DATA_Q0_tLabel_SHIFT 10168#define OHCI1394_AT_DATA_Q0_rt_MASK 0x00000300169#define OHCI1394_AT_DATA_Q0_rt_SHIFT 8170#define OHCI1394_AT_DATA_Q0_tCode_MASK 0x000000f0171#define OHCI1394_AT_DATA_Q0_tCode_SHIFT 4172#define OHCI1394_AT_DATA_Q1_destinationId_MASK 0xffff0000173#define OHCI1394_AT_DATA_Q1_destinationId_SHIFT 16174#define OHCI1394_AT_DATA_Q1_destinationOffsetHigh_MASK 0x0000ffff175#define OHCI1394_AT_DATA_Q1_destinationOffsetHigh_SHIFT 0176#define OHCI1394_AT_DATA_Q1_rCode_MASK 0x0000f000177#define OHCI1394_AT_DATA_Q1_rCode_SHIFT 12178 179static inline bool ohci1394_at_data_get_src_bus_id(const __le32 *data)180{181 return !!((data[0] & OHCI1394_AT_DATA_Q0_srcBusID_MASK) >> OHCI1394_AT_DATA_Q0_srcBusID_SHIFT);182}183 184static inline void ohci1394_at_data_set_src_bus_id(__le32 *data, bool src_bus_id)185{186 data[0] &= cpu_to_le32(~OHCI1394_AT_DATA_Q0_srcBusID_MASK);187 data[0] |= cpu_to_le32((src_bus_id << OHCI1394_AT_DATA_Q0_srcBusID_SHIFT) & OHCI1394_AT_DATA_Q0_srcBusID_MASK);188}189 190static inline unsigned int ohci1394_at_data_get_speed(const __le32 *data)191{192 return (le32_to_cpu(data[0]) & OHCI1394_AT_DATA_Q0_spd_MASK) >> OHCI1394_AT_DATA_Q0_spd_SHIFT;193}194 195static inline void ohci1394_at_data_set_speed(__le32 *data, unsigned int scode)196{197 data[0] &= cpu_to_le32(~OHCI1394_AT_DATA_Q0_spd_MASK);198 data[0] |= cpu_to_le32((scode << OHCI1394_AT_DATA_Q0_spd_SHIFT) & OHCI1394_AT_DATA_Q0_spd_MASK);199}200 201static inline unsigned int ohci1394_at_data_get_tlabel(const __le32 *data)202{203 return (le32_to_cpu(data[0]) & OHCI1394_AT_DATA_Q0_tLabel_MASK) >> OHCI1394_AT_DATA_Q0_tLabel_SHIFT;204}205 206static inline void ohci1394_at_data_set_tlabel(__le32 *data, unsigned int tlabel)207{208 data[0] &= cpu_to_le32(~OHCI1394_AT_DATA_Q0_tLabel_MASK);209 data[0] |= cpu_to_le32((tlabel << OHCI1394_AT_DATA_Q0_tLabel_SHIFT) & OHCI1394_AT_DATA_Q0_tLabel_MASK);210}211 212static inline unsigned int ohci1394_at_data_get_retry(const __le32 *data)213{214 return (le32_to_cpu(data[0]) & OHCI1394_AT_DATA_Q0_rt_MASK) >> OHCI1394_AT_DATA_Q0_rt_SHIFT;215}216 217static inline void ohci1394_at_data_set_retry(__le32 *data, unsigned int retry)218{219 data[0] &= cpu_to_le32(~OHCI1394_AT_DATA_Q0_rt_MASK);220 data[0] |= cpu_to_le32((retry << OHCI1394_AT_DATA_Q0_rt_SHIFT) & OHCI1394_AT_DATA_Q0_rt_MASK);221}222 223static inline unsigned int ohci1394_at_data_get_tcode(const __le32 *data)224{225 return (le32_to_cpu(data[0]) & OHCI1394_AT_DATA_Q0_tCode_MASK) >> OHCI1394_AT_DATA_Q0_tCode_SHIFT;226}227 228static inline void ohci1394_at_data_set_tcode(__le32 *data, unsigned int tcode)229{230 data[0] &= cpu_to_le32(~OHCI1394_AT_DATA_Q0_tCode_MASK);231 data[0] |= cpu_to_le32((tcode << OHCI1394_AT_DATA_Q0_tCode_SHIFT) & OHCI1394_AT_DATA_Q0_tCode_MASK);232}233 234static inline unsigned int ohci1394_at_data_get_destination_id(const __le32 *data)235{236 return (le32_to_cpu(data[1]) & OHCI1394_AT_DATA_Q1_destinationId_MASK) >> OHCI1394_AT_DATA_Q1_destinationId_SHIFT;237}238 239static inline void ohci1394_at_data_set_destination_id(__le32 *data, unsigned int destination_id)240{241 data[1] &= cpu_to_le32(~OHCI1394_AT_DATA_Q1_destinationId_MASK);242 data[1] |= cpu_to_le32((destination_id << OHCI1394_AT_DATA_Q1_destinationId_SHIFT) & OHCI1394_AT_DATA_Q1_destinationId_MASK);243}244 245static inline u64 ohci1394_at_data_get_destination_offset(const __le32 *data)246{247 u64 hi = (u64)((le32_to_cpu(data[1]) & OHCI1394_AT_DATA_Q1_destinationOffsetHigh_MASK) >> OHCI1394_AT_DATA_Q1_destinationOffsetHigh_SHIFT);248 u64 lo = (u64)le32_to_cpu(data[2]);249 return (hi << 32) | lo;250}251 252static inline void ohci1394_at_data_set_destination_offset(__le32 *data, u64 offset)253{254 u32 hi = (u32)(offset >> 32);255 u32 lo = (u32)(offset & 0x00000000ffffffff);256 data[1] &= cpu_to_le32(~OHCI1394_AT_DATA_Q1_destinationOffsetHigh_MASK);257 data[1] |= cpu_to_le32((hi << OHCI1394_AT_DATA_Q1_destinationOffsetHigh_SHIFT) & OHCI1394_AT_DATA_Q1_destinationOffsetHigh_MASK);258 data[2] = cpu_to_le32(lo);259}260 261static inline unsigned int ohci1394_at_data_get_rcode(const __le32 *data)262{263 return (le32_to_cpu(data[1]) & OHCI1394_AT_DATA_Q1_rCode_MASK) >> OHCI1394_AT_DATA_Q1_rCode_SHIFT;264}265 266static inline void ohci1394_at_data_set_rcode(__le32 *data, unsigned int rcode)267{268 data[1] &= cpu_to_le32(~OHCI1394_AT_DATA_Q1_rCode_MASK);269 data[1] |= cpu_to_le32((rcode << OHCI1394_AT_DATA_Q1_rCode_SHIFT) & OHCI1394_AT_DATA_Q1_rCode_MASK);270}271 272// Isochronous Transmit DMA.273//274// The content of first two quadlets of data for IT DMA is different from the header for IEEE 1394275// isochronous packet.276 277#define OHCI1394_IT_DATA_Q0_spd_MASK 0x00070000278#define OHCI1394_IT_DATA_Q0_spd_SHIFT 16279#define OHCI1394_IT_DATA_Q0_tag_MASK 0x0000c000280#define OHCI1394_IT_DATA_Q0_tag_SHIFT 14281#define OHCI1394_IT_DATA_Q0_chanNum_MASK 0x00003f00282#define OHCI1394_IT_DATA_Q0_chanNum_SHIFT 8283#define OHCI1394_IT_DATA_Q0_tcode_MASK 0x000000f0284#define OHCI1394_IT_DATA_Q0_tcode_SHIFT 4285#define OHCI1394_IT_DATA_Q0_sy_MASK 0x0000000f286#define OHCI1394_IT_DATA_Q0_sy_SHIFT 0287#define OHCI1394_IT_DATA_Q1_dataLength_MASK 0xffff0000288#define OHCI1394_IT_DATA_Q1_dataLength_SHIFT 16289 290static inline unsigned int ohci1394_it_data_get_speed(const __le32 *data)291{292 return (le32_to_cpu(data[0]) & OHCI1394_IT_DATA_Q0_spd_MASK) >> OHCI1394_IT_DATA_Q0_spd_SHIFT;293}294 295static inline void ohci1394_it_data_set_speed(__le32 *data, unsigned int scode)296{297 data[0] &= cpu_to_le32(~OHCI1394_IT_DATA_Q0_spd_MASK);298 data[0] |= cpu_to_le32((scode << OHCI1394_IT_DATA_Q0_spd_SHIFT) & OHCI1394_IT_DATA_Q0_spd_MASK);299}300 301static inline unsigned int ohci1394_it_data_get_tag(const __le32 *data)302{303 return (le32_to_cpu(data[0]) & OHCI1394_IT_DATA_Q0_tag_MASK) >> OHCI1394_IT_DATA_Q0_tag_SHIFT;304}305 306static inline void ohci1394_it_data_set_tag(__le32 *data, unsigned int tag)307{308 data[0] &= cpu_to_le32(~OHCI1394_IT_DATA_Q0_tag_MASK);309 data[0] |= cpu_to_le32((tag << OHCI1394_IT_DATA_Q0_tag_SHIFT) & OHCI1394_IT_DATA_Q0_tag_MASK);310}311 312static inline unsigned int ohci1394_it_data_get_channel(const __le32 *data)313{314 return (le32_to_cpu(data[0]) & OHCI1394_IT_DATA_Q0_chanNum_MASK) >> OHCI1394_IT_DATA_Q0_chanNum_SHIFT;315}316 317static inline void ohci1394_it_data_set_channel(__le32 *data, unsigned int channel)318{319 data[0] &= cpu_to_le32(~OHCI1394_IT_DATA_Q0_chanNum_MASK);320 data[0] |= cpu_to_le32((channel << OHCI1394_IT_DATA_Q0_chanNum_SHIFT) & OHCI1394_IT_DATA_Q0_chanNum_MASK);321}322 323static inline unsigned int ohci1394_it_data_get_tcode(const __le32 *data)324{325 return (le32_to_cpu(data[0]) & OHCI1394_IT_DATA_Q0_tcode_MASK) >> OHCI1394_IT_DATA_Q0_tcode_SHIFT;326}327 328static inline void ohci1394_it_data_set_tcode(__le32 *data, unsigned int tcode)329{330 data[0] &= cpu_to_le32(~OHCI1394_IT_DATA_Q0_tcode_MASK);331 data[0] |= cpu_to_le32((tcode << OHCI1394_IT_DATA_Q0_tcode_SHIFT) & OHCI1394_IT_DATA_Q0_tcode_MASK);332}333 334static inline unsigned int ohci1394_it_data_get_sync(const __le32 *data)335{336 return (le32_to_cpu(data[0]) & OHCI1394_IT_DATA_Q0_sy_MASK) >> OHCI1394_IT_DATA_Q0_sy_SHIFT;337}338 339static inline void ohci1394_it_data_set_sync(__le32 *data, unsigned int sync)340{341 data[0] &= cpu_to_le32(~OHCI1394_IT_DATA_Q0_sy_MASK);342 data[0] |= cpu_to_le32((sync << OHCI1394_IT_DATA_Q0_sy_SHIFT) & OHCI1394_IT_DATA_Q0_sy_MASK);343}344 345static inline unsigned int ohci1394_it_data_get_data_length(const __le32 *data)346{347 return (le32_to_cpu(data[1]) & OHCI1394_IT_DATA_Q1_dataLength_MASK) >> OHCI1394_IT_DATA_Q1_dataLength_SHIFT;348}349 350static inline void ohci1394_it_data_set_data_length(__le32 *data, unsigned int data_length)351{352 data[1] &= cpu_to_le32(~OHCI1394_IT_DATA_Q1_dataLength_MASK);353 data[1] |= cpu_to_le32((data_length << OHCI1394_IT_DATA_Q1_dataLength_SHIFT) & OHCI1394_IT_DATA_Q1_dataLength_MASK);354}355 356// Self-ID DMA.357 358#define OHCI1394_SelfIDCount_selfIDError_MASK 0x80000000359#define OHCI1394_SelfIDCount_selfIDError_SHIFT 31360#define OHCI1394_SelfIDCount_selfIDGeneration_MASK 0x00ff0000361#define OHCI1394_SelfIDCount_selfIDGeneration_SHIFT 16362#define OHCI1394_SelfIDCount_selfIDSize_MASK 0x000007fc363#define OHCI1394_SelfIDCount_selfIDSize_SHIFT 2364 365static inline bool ohci1394_self_id_count_is_error(u32 value)366{367 return !!((value & OHCI1394_SelfIDCount_selfIDError_MASK) >> OHCI1394_SelfIDCount_selfIDError_SHIFT);368}369 370static inline u8 ohci1394_self_id_count_get_generation(u32 value)371{372 return (value & OHCI1394_SelfIDCount_selfIDGeneration_MASK) >> OHCI1394_SelfIDCount_selfIDGeneration_SHIFT;373}374 375// In 1394 OHCI specification, the maximum size of self ID stream is 504 quadlets376// (= 63 devices * 4 self ID packets * 2 quadlets). The selfIDSize field accommodates it and its377// additional first quadlet, since the field is 9 bits (0x1ff = 511).378static inline u32 ohci1394_self_id_count_get_size(u32 value)379{380 return (value & OHCI1394_SelfIDCount_selfIDSize_MASK) >> OHCI1394_SelfIDCount_selfIDSize_SHIFT;381}382 383#define OHCI1394_SELF_ID_RECEIVE_Q0_GENERATION_MASK 0x00ff0000384#define OHCI1394_SELF_ID_RECEIVE_Q0_GENERATION_SHIFT 16385#define OHCI1394_SELF_ID_RECEIVE_Q0_TIMESTAMP_MASK 0x0000ffff386#define OHCI1394_SELF_ID_RECEIVE_Q0_TIMESTAMP_SHIFT 0387 388static inline u8 ohci1394_self_id_receive_q0_get_generation(u32 quadlet0)389{390 return (quadlet0 & OHCI1394_SELF_ID_RECEIVE_Q0_GENERATION_MASK) >> OHCI1394_SELF_ID_RECEIVE_Q0_GENERATION_SHIFT;391}392 393static inline u16 ohci1394_self_id_receive_q0_get_timestamp(u32 quadlet0)394{395 return (quadlet0 & OHCI1394_SELF_ID_RECEIVE_Q0_TIMESTAMP_MASK) >> OHCI1394_SELF_ID_RECEIVE_Q0_TIMESTAMP_SHIFT;396}397 398#endif /* _FIREWIRE_OHCI_H */399