^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-1.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Renesas USB driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2011 Renesas Solutions Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "pipe.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define usbhsp_addr_offset(p) ((usbhs_pipe_number(p) - 1) * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define usbhsp_flags_set(p, f) ((p)->flags |= USBHS_PIPE_FLAGS_##f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define usbhsp_flags_clr(p, f) ((p)->flags &= ~USBHS_PIPE_FLAGS_##f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define usbhsp_flags_has(p, f) ((p)->flags & USBHS_PIPE_FLAGS_##f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define usbhsp_flags_init(p) do {(p)->flags = 0; } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * for debug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static char *usbhsp_pipe_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) [USB_ENDPOINT_XFER_CONTROL] = "DCP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) [USB_ENDPOINT_XFER_BULK] = "BULK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) [USB_ENDPOINT_XFER_INT] = "INT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) [USB_ENDPOINT_XFER_ISOC] = "ISO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) char *usbhs_pipe_name(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return usbhsp_pipe_name[usbhs_pipe_type(pipe)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static struct renesas_usbhs_driver_pipe_config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *usbhsp_get_pipe_config(struct usbhs_priv *priv, int pipe_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct renesas_usbhs_driver_pipe_config *pipe_configs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) usbhs_get_dparam(priv, pipe_configs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return &pipe_configs[pipe_num];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * DCPCTR/PIPEnCTR functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static void usbhsp_pipectrl_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int offset = usbhsp_addr_offset(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (usbhs_pipe_is_dcp(pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) usbhs_bset(priv, DCPCTR, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) usbhs_bset(priv, PIPEnCTR + offset, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static u16 usbhsp_pipectrl_get(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int offset = usbhsp_addr_offset(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (usbhs_pipe_is_dcp(pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return usbhs_read(priv, DCPCTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return usbhs_read(priv, PIPEnCTR + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * DCP/PIPE functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static void __usbhsp_pipe_xxx_set(struct usbhs_pipe *pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) u16 dcp_reg, u16 pipe_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) u16 mask, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (usbhs_pipe_is_dcp(pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) usbhs_bset(priv, dcp_reg, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) usbhs_bset(priv, pipe_reg, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static u16 __usbhsp_pipe_xxx_get(struct usbhs_pipe *pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u16 dcp_reg, u16 pipe_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (usbhs_pipe_is_dcp(pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return usbhs_read(priv, dcp_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return usbhs_read(priv, pipe_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * DCPCFG/PIPECFG functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) __usbhsp_pipe_xxx_set(pipe, DCPCFG, PIPECFG, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static u16 usbhsp_pipe_cfg_get(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return __usbhsp_pipe_xxx_get(pipe, DCPCFG, PIPECFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * PIPEnTRN/PIPEnTRE functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static void usbhsp_pipe_trn_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct device *dev = usbhs_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int num = usbhs_pipe_number(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * It is impossible to calculate address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * since PIPEnTRN addresses were mapped randomly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define CASE_PIPExTRN(a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) case 0x ## a: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) reg = PIPE ## a ## TRN; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) switch (num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) CASE_PIPExTRN(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) CASE_PIPExTRN(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) CASE_PIPExTRN(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) CASE_PIPExTRN(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) CASE_PIPExTRN(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) CASE_PIPExTRN(B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) CASE_PIPExTRN(C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) CASE_PIPExTRN(D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) CASE_PIPExTRN(E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) CASE_PIPExTRN(F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) CASE_PIPExTRN(9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) CASE_PIPExTRN(A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) dev_err(dev, "unknown pipe (%d)\n", num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) __usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static void usbhsp_pipe_tre_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct device *dev = usbhs_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int num = usbhs_pipe_number(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * It is impossible to calculate address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * since PIPEnTRE addresses were mapped randomly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define CASE_PIPExTRE(a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case 0x ## a: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) reg = PIPE ## a ## TRE; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) switch (num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) CASE_PIPExTRE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) CASE_PIPExTRE(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) CASE_PIPExTRE(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) CASE_PIPExTRE(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) CASE_PIPExTRE(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) CASE_PIPExTRE(B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) CASE_PIPExTRE(C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) CASE_PIPExTRE(D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) CASE_PIPExTRE(E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) CASE_PIPExTRE(F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) CASE_PIPExTRE(9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) CASE_PIPExTRE(A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) dev_err(dev, "unknown pipe (%d)\n", num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) __usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * PIPEBUF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (usbhs_pipe_is_dcp(pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) __usbhsp_pipe_xxx_set(pipe, 0, PIPEBUF, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * DCPMAXP/PIPEMAXP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static void usbhsp_pipe_maxp_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) __usbhsp_pipe_xxx_set(pipe, DCPMAXP, PIPEMAXP, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * pipe control functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static void usbhsp_pipe_select(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * On pipe, this is necessary before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * accesses to below registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * PIPESEL : usbhsp_pipe_select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * PIPECFG : usbhsp_pipe_cfg_xxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * PIPEBUF : usbhsp_pipe_buf_xxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * PIPEMAXP : usbhsp_pipe_maxp_xxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * PIPEPERI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * if pipe is dcp, no pipe is selected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * it is no problem, because dcp have its register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) usbhs_write(priv, PIPESEL, 0xF & usbhs_pipe_number(pipe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int timeout = 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) u16 mask = usbhs_mod_is_host(priv) ? (CSSTS | PID_MASK) : PID_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * make sure....
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * Modify these bits when CSSTS = 0, PID = NAK, and no pipe number is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * specified by the CURPIPE bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * When changing the setting of this bit after changing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * the PID bits for the selected pipe from BUF to NAK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * check that CSSTS = 0 and PBUSY = 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * CURPIPE bit = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * see also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * "Operation"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * - "Pipe Control"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * - "Pipe Control Registers Switching Procedure"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) usbhs_write(priv, CFIFOSEL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) usbhs_pipe_disable(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (!(usbhsp_pipectrl_get(pipe) & mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) } while (timeout--);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) val = usbhsp_pipectrl_get(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (val & BSTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) bool usbhs_pipe_contains_transmittable_data(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* Do not support for DCP pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (usbhs_pipe_is_dcp(pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) val = usbhsp_pipectrl_get(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (val & INBUFM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * PID ctrl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static void __usbhsp_pid_try_nak_if_stall(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) u16 pid = usbhsp_pipectrl_get(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) pid &= PID_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * "Pipe n Control Register" - "PID"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) switch (pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) case PID_STALL11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) case PID_STALL10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) void usbhs_pipe_disable(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) int timeout = 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* see "Pipe n Control Register" - "PID" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) __usbhsp_pid_try_nak_if_stall(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) val = usbhsp_pipectrl_get(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) val &= PBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) } while (timeout--);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) void usbhs_pipe_enable(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* see "Pipe n Control Register" - "PID" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) __usbhsp_pid_try_nak_if_stall(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) usbhsp_pipectrl_set(pipe, PID_MASK, PID_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) void usbhs_pipe_stall(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) u16 pid = usbhsp_pipectrl_get(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) pid &= PID_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * "Pipe n Control Register" - "PID"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) switch (pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case PID_NAK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case PID_BUF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int usbhs_pipe_is_stall(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) u16 pid = usbhsp_pipectrl_get(pipe) & PID_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return (int)(pid == PID_STALL10 || pid == PID_STALL11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (!usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * clear and disable transfer counter for IN/OUT pipe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) usbhsp_pipe_tre_set(pipe, TRCLR | TRENB, TRCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * Only IN direction bulk pipe can use transfer count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * Without using this function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * received data will break if it was large data size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * see PIPEnTRN/PIPEnTRE for detail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (usbhs_pipe_is_dir_in(pipe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) int maxp = usbhs_pipe_get_maxpacket(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) usbhsp_pipe_trn_set(pipe, 0xffff, DIV_ROUND_UP(len, maxp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) usbhsp_pipe_tre_set(pipe, TRENB, TRENB); /* enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * pipe setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static int usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, int is_host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int dir_in, u16 *pipecfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) u16 type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) u16 bfre = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) u16 dblb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) u16 cntmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) u16 dir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) u16 epnum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) u16 shtnak = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static const u16 type_array[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) [USB_ENDPOINT_XFER_BULK] = TYPE_BULK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) [USB_ENDPOINT_XFER_INT] = TYPE_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) [USB_ENDPOINT_XFER_ISOC] = TYPE_ISO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (usbhs_pipe_is_dcp(pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * PIPECFG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * - "Register Descriptions" - "PIPECFG" register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * - "Features" - "Pipe configuration"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * - "Operation" - "Pipe Control"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* TYPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) type = type_array[usbhs_pipe_type(pipe)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* BFRE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) bfre = 0; /* FIXME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /* DBLB: see usbhs_pipe_config_update() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /* CNTMD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) cntmd = 0; /* FIXME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /* DIR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (dir_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) usbhsp_flags_set(pipe, IS_DIR_HOST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (!!is_host ^ !!dir_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) dir |= DIR_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (!dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) usbhsp_flags_set(pipe, IS_DIR_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /* SHTNAK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) !dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) shtnak = SHTNAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) /* EPNUM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) epnum = 0; /* see usbhs_pipe_config_update() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) *pipecfg = type |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) bfre |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) dblb |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) cntmd |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) dir |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) shtnak |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) epnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct device *dev = usbhs_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) int pipe_num = usbhs_pipe_number(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) u16 buff_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) u16 bufnmb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) u16 bufnmb_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct renesas_usbhs_driver_pipe_config *pipe_config =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) usbhsp_get_pipe_config(priv, pipe_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * PIPEBUF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * - "Register Descriptions" - "PIPEBUF" register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * - "Features" - "Pipe configuration"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * - "Operation" - "FIFO Buffer Memory"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * - "Operation" - "Pipe Control"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) buff_size = pipe_config->bufsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) bufnmb = pipe_config->bufnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* change buff_size to register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) bufnmb_cnt = (buff_size / 64) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) dev_dbg(dev, "pipe : %d : buff_size 0x%x: bufnmb 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) pipe_num, buff_size, bufnmb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return (0x1f & bufnmb_cnt) << 10 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) (0xff & bufnmb) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) u16 epnum, u16 maxp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int pipe_num = usbhs_pipe_number(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct renesas_usbhs_driver_pipe_config *pipe_config =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) usbhsp_get_pipe_config(priv, pipe_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) u16 dblb = pipe_config->double_buf ? DBLB : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (devsel > 0xA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct device *dev = usbhs_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) dev_err(dev, "devsel error %d\n", devsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) devsel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) usbhsp_pipe_barrier(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) pipe->maxp = maxp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) usbhsp_pipe_select(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) usbhsp_pipe_maxp_set(pipe, 0xFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) (devsel << 12) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) maxp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (!usbhs_pipe_is_dcp(pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) usbhsp_pipe_cfg_set(pipe, 0x000F | DBLB, epnum | dblb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * pipe control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * usbhs_pipe_config_update()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * usbhs_dcp_malloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return pipe->maxp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return usbhsp_flags_has(pipe, IS_DIR_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return usbhsp_flags_has(pipe, IS_DIR_HOST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) int usbhs_pipe_is_running(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return usbhsp_flags_has(pipe, IS_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) void usbhs_pipe_running(struct usbhs_pipe *pipe, int running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) usbhsp_flags_set(pipe, IS_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) usbhsp_flags_clr(pipe, IS_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int sequence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) u16 mask = (SQCLR | SQSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * 0 : data0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * 1 : data1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * -1 : no change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) switch (sequence) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) val = SQCLR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) val = SQSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) usbhsp_pipectrl_set(pipe, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static int usbhs_pipe_get_data_sequence(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return !!(usbhsp_pipectrl_get(pipe) & SQMON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) void usbhs_pipe_clear(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (usbhs_pipe_is_dcp(pipe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) usbhs_fifo_clear_dcp(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) usbhsp_pipectrl_set(pipe, ACLRM, ACLRM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) usbhsp_pipectrl_set(pipe, ACLRM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) /* Should call usbhsp_pipe_select() before */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) void usbhs_pipe_clear_without_sequence(struct usbhs_pipe *pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) int needs_bfre, int bfre_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) int sequence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) usbhsp_pipe_select(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) sequence = usbhs_pipe_get_data_sequence(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (needs_bfre)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) usbhsp_pipe_cfg_set(pipe, BFRE, bfre_enable ? BFRE : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) usbhs_pipe_clear(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) usbhs_pipe_data_sequence(pipe, sequence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) void usbhs_pipe_config_change_bfre(struct usbhs_pipe *pipe, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (usbhs_pipe_is_dcp(pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) usbhsp_pipe_select(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /* check if the driver needs to change the BFRE value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (!(enable ^ !!(usbhsp_pipe_cfg_get(pipe) & BFRE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) usbhs_pipe_clear_without_sequence(pipe, 1, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct usbhs_pipe *pos, *pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * find target pipe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) pipe = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) usbhs_for_each_pipe_with_dcp(pos, priv, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (!usbhs_pipe_type_is(pos, type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (usbhsp_flags_has(pos, IS_USED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) pipe = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (!pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * initialize pipe flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) usbhsp_flags_init(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) usbhsp_flags_set(pipe, IS_USED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static void usbhsp_put_pipe(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) usbhsp_flags_init(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) void usbhs_pipe_init(struct usbhs_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int (*dma_map_ctrl)(struct device *dma_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct usbhs_pkt *pkt, int map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct usbhs_pipe *pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) usbhsp_flags_init(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) pipe->fifo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) pipe->mod_private = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) INIT_LIST_HEAD(&pipe->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /* pipe force init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) usbhs_pipe_clear(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) info->dma_map_ctrl = dma_map_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) int endpoint_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) int dir_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct device *dev = usbhs_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct usbhs_pipe *pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) int is_host = usbhs_mod_is_host(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) u16 pipecfg, pipebuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) pipe = usbhsp_get_pipe(priv, endpoint_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (!pipe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) dev_err(dev, "can't get pipe (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) usbhsp_pipe_name[endpoint_type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) INIT_LIST_HEAD(&pipe->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) usbhs_pipe_disable(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /* make sure pipe is not busy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) ret = usbhsp_pipe_barrier(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) dev_err(dev, "pipe setup failed %d\n", usbhs_pipe_number(pipe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (usbhsp_setup_pipecfg(pipe, is_host, dir_in, &pipecfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) dev_err(dev, "can't setup pipe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) pipebuf = usbhsp_setup_pipebuff(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) usbhsp_pipe_select(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) usbhs_pipe_clear(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) usbhs_pipe_sequence_data0(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) dev_dbg(dev, "enable pipe %d : %s (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) usbhs_pipe_number(pipe),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) usbhs_pipe_name(pipe),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) usbhs_pipe_is_dir_in(pipe) ? "in" : "out");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * epnum / maxp are still not set to this pipe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * call usbhs_pipe_config_update() after this function !!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) void usbhs_pipe_free(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) usbhsp_pipe_select(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) usbhsp_pipe_cfg_set(pipe, 0xFFFF, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) usbhsp_put_pipe(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (pipe->fifo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) pipe->fifo->pipe = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) pipe->fifo = fifo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (fifo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) fifo->pipe = pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * dcp control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct usbhs_pipe *pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) pipe = usbhsp_get_pipe(priv, USB_ENDPOINT_XFER_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (!pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) INIT_LIST_HEAD(&pipe->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * call usbhs_pipe_config_update() after this function !!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) WARN_ON(!usbhs_pipe_is_dcp(pipe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) usbhs_pipe_enable(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (!usbhs_mod_is_host(priv)) /* funconly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) usbhsp_pipectrl_set(pipe, CCPL, CCPL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) void usbhs_dcp_dir_for_host(struct usbhs_pipe *pipe, int dir_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) usbhsp_pipe_cfg_set(pipe, DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) dir_out ? DIR_OUT : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * pipe module function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) int usbhs_pipe_probe(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct usbhs_pipe *pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) struct device *dev = usbhs_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) struct renesas_usbhs_driver_pipe_config *pipe_configs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) usbhs_get_dparam(priv, pipe_configs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) int pipe_size = usbhs_get_dparam(priv, pipe_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /* This driver expects 1st pipe is DCP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (pipe_configs[0].type != USB_ENDPOINT_XFER_CONTROL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) dev_err(dev, "1st PIPE is not DCP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) info->pipe = kcalloc(pipe_size, sizeof(struct usbhs_pipe),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (!info->pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) info->size = pipe_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * init pipe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) pipe->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) usbhs_pipe_type(pipe) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) pipe_configs[i].type & USB_ENDPOINT_XFERTYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) dev_dbg(dev, "pipe %x\t: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) i, usbhsp_pipe_name[pipe_configs[i].type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) void usbhs_pipe_remove(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) kfree(info->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }