Indeed if you convert the text string to codepoints and the codepoints back to a string the newlines are present. I’m not sure understand why they don’t show up otherwise.
It’s the HTML rendering that suppresses newlines. You can add them server-side…
let $value := request:parameter($p)
return <tr><td>{
for $line in tokenize($value, char('\n'))
return ($line, <br/>)
}</td><td>
…or return the result inside a pre tag:
<td><pre>{
request:parameter($p)
}</pre></td>