Neither is true.
In go, *all* arguments are passed by value. If the argument is a struct, then the struct is copied. If the argument is a pointer, then the pointer is copied.
Ignoring methods for a moment, just consider these simple functions:
func Display1(z Zoo) { ... }
func Display2(z *Zoo) { ... }
v := Zoo{....}
Display1(v) # v is copied
vp := &Zoo
Display2(vp) # vp is copied
These are identical, consistent behaviours.
So now onto "pointer to function". You are thinking like C. In Go there is no meaningful "pointer to function", there are just "function values":
Internally of course, a function value will contain some sort of pointer to the code, just as a string value contains a pointer to the string, and a slice value contains a pointer to the slice backing array. (In the latter two cases the pointer may be nil if the len or cap is zero, and the overall value is still valid). When you pass a string or a slice to a function, you are copying this structure with its embedded pointer/len/cap, These pointers are implementation details, and are not directly accessible to the user program - at least not in a "safe" way.
Whether the function takes zero arguments, one or more arguments, whether those arguments are structs or pointers or chans or whatever, affects the *type* of the value and hence how you call it, but otherwise a function value is just a value.
So finally we get to methods:
If you take a method value (pf := gz.Display), you are just getting a function value, where the special first argument of the function has been bound ("curried") to some value.
If the method takes a "Zoo" receiver, then the value is bound to a copy of the Zoo value. If the method takes a "*Zoo" receiver, then the value is bound to a copy of the pointer-to-Zoo value. Again, this is 100% consistent. The function always receives a copy of the value, of the type of the argument.
There is just one bit of magic, which is the automatic referencing and dereferencing. Very roughly speaking: if a method takes a *Zoo but you apply it to a Zoo value, or vice versa, the value is converted from Zoo to pointer-to-Zoo or vice versa as required.
But the value which is received by the method is always of the type it declares: func (z Zoo) Display() always takes a copy of a Zoo value, and func (z *Zoo) Display() always takes a copy of a pointer-to-Zoo value. The value is always copied, and this is done at the time the method value is created, not the time at which it is called (which may be never, or may be many times).